From 04efefb6a6f75ba67c0772280d93c492f478ccb9 Mon Sep 17 00:00:00 2001 From: OlegIvaniv Date: Thu, 14 Sep 2023 09:04:16 +0200 Subject: [PATCH] feat(core): Add support for Supabase Vector Store (#7152) Github issue / Community forum post (link here to close automatically): Signed-off-by: Oleg Ivaniv --- .../VectorStoreSupabaseInsert.node.ts | 116 +++++++++++++++++ .../VectorStoreSupabaseInsert/supabase.svg | 15 +++ .../VectorStoreSupabaseLoad.node.ts | 111 ++++++++++++++++ .../VectorStoreSupabaseLoad/supabase.svg | 15 +++ packages/@n8n/nodes-langchain/package.json | 5 +- pnpm-lock.yaml | 119 ++++++++++++++++-- 6 files changed, 369 insertions(+), 12 deletions(-) create mode 100644 packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseInsert/VectorStoreSupabaseInsert.node.ts create mode 100644 packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseInsert/supabase.svg create mode 100644 packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseLoad/VectorStoreSupabaseLoad.node.ts create mode 100644 packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseLoad/supabase.svg diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseInsert/VectorStoreSupabaseInsert.node.ts b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseInsert/VectorStoreSupabaseInsert.node.ts new file mode 100644 index 0000000000000..d19217db11fb8 --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseInsert/VectorStoreSupabaseInsert.node.ts @@ -0,0 +1,116 @@ +import type { + IExecuteFunctions, + INodeType, + INodeTypeDescription, + INodeExecutionData, +} from 'n8n-workflow'; +import type { Embeddings } from 'langchain/embeddings/base'; +import type { Document } from 'langchain/document'; +import { createClient } from '@supabase/supabase-js'; +import { SupabaseVectorStore } from 'langchain/vectorstores/supabase'; + +import { N8nJsonLoader } from '../../../utils/N8nJsonLoader'; +import { N8nBinaryLoader } from '../../../utils/N8nBinaryLoader'; +export class VectorStoreSupabaseInsert implements INodeType { + description: INodeTypeDescription = { + displayName: 'Supabase: Insert', + name: 'vectorStoreSupabaseInsert', + icon: 'file:supabase.svg', + group: ['transform'], + version: 1, + description: + 'Insert data into Supabase Vector Store index [https://supabase.com/docs/guides/ai/langchain]', + defaults: { + name: 'Supabase: Insert', + }, + codex: { + categories: ['AI'], + subcategories: { + AI: ['Vector Stores'], + }, + }, + credentials: [ + { + name: 'supabaseApi', + required: true, + }, + ], + inputs: [ + 'main', + { + displayName: 'Document', + maxConnections: 1, + type: 'document', + required: true, + }, + { + displayName: 'Embedding', + maxConnections: 1, + type: 'embedding', + required: true, + }, + ], + outputs: ['main'], + properties: [ + { + displayName: + 'Please reffer to the Supabase documentation for more information on how to setup your database as a Vector Store. https://supabase.com/docs/guides/ai/langchain', + name: 'setupNotice', + type: 'notice', + default: '', + }, + { + displayName: 'Table Name', + name: 'tableName', + type: 'string', + default: '', + required: true, + description: 'Name of the table to insert into', + }, + { + displayName: 'Query Name', + name: 'queryName', + type: 'string', + default: 'match_documents', + required: true, + description: 'Name of the query to use for matching documents', + }, + ], + }; + + async execute(this: IExecuteFunctions): Promise { + this.logger.verbose('Executing data for Supabase Insert Vector Store'); + + const items = this.getInputData(0); + const tableName = this.getNodeParameter('tableName', 0) as string; + const queryName = this.getNodeParameter('queryName', 0) as string; + const credentials = await this.getCredentials('supabaseApi'); + + const documentInput = (await this.getInputConnectionData('document', 0)) as + | N8nJsonLoader + | Array>>; + + const embeddings = (await this.getInputConnectionData('embedding', 0)) as Embeddings; + const client = createClient(credentials.host as string, credentials.serviceRole as string); + + let processedDocuments: Document[]; + + if (documentInput instanceof N8nJsonLoader || documentInput instanceof N8nBinaryLoader) { + processedDocuments = await documentInput.process(items); + } else { + processedDocuments = documentInput; + } + + await SupabaseVectorStore.fromDocuments(processedDocuments, embeddings, { + client, + tableName, + queryName, + }); + + const serializedDocuments = processedDocuments.map(({ metadata, pageContent }) => ({ + json: { metadata, pageContent }, + })); + + return this.prepareOutputData(serializedDocuments); + } +} diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseInsert/supabase.svg b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseInsert/supabase.svg new file mode 100644 index 0000000000000..ad802ac16ae9e --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseInsert/supabase.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseLoad/VectorStoreSupabaseLoad.node.ts b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseLoad/VectorStoreSupabaseLoad.node.ts new file mode 100644 index 0000000000000..83be7017ce00a --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseLoad/VectorStoreSupabaseLoad.node.ts @@ -0,0 +1,111 @@ +import type { + IExecuteFunctions, + INodeType, + INodeTypeDescription, + IDataObject, + SupplyData, +} from 'n8n-workflow'; +import type { Embeddings } from 'langchain/embeddings/base'; +import { createClient } from '@supabase/supabase-js'; +import { SupabaseVectorStore } from 'langchain/vectorstores/supabase'; + +import { logWrapper } from '../../../utils/logWrapper'; +export class VectorStoreSupabaseLoad implements INodeType { + description: INodeTypeDescription = { + displayName: 'Supabase: Load', + name: 'vectorStoreSupabaseLoad', + icon: 'file:supabase.svg', + group: ['transform'], + version: 1, + description: 'Load data from Supabase Vector Store index', + defaults: { + name: 'Supabase: Load', + }, + codex: { + categories: ['AI'], + subcategories: { + AI: ['Vector Stores'], + }, + }, + credentials: [ + { + name: 'supabaseApi', + required: true, + }, + ], + inputs: [ + { + displayName: 'Embedding', + maxConnections: 1, + type: 'embedding', + required: true, + }, + ], + outputs: ['vectorStore'], + outputNames: ['Vector Store'], + properties: [ + { + displayName: 'Table Name', + name: 'tableName', + type: 'string', + default: '', + required: true, + description: 'Name of the table to load from', + }, + { + displayName: 'Query Name', + name: 'queryName', + type: 'string', + default: 'match_documents', + required: true, + description: 'Name of the query to use for matching documents', + }, + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + options: [ + { + displayName: 'Metadata Filter', + name: 'filter', + type: 'string', + typeOptions: { + editor: 'json', + editorLanguage: 'json', + }, + default: '', + }, + ], + }, + ], + }; + + async supplyData(this: IExecuteFunctions): Promise { + this.logger.verbose('Supply Supabase Load Vector Store'); + + const tableName = this.getNodeParameter('tableName', 0) as string; + const queryName = this.getNodeParameter('queryName', 0) as string; + const options = this.getNodeParameter('options', 0, {}) as { + filter?: IDataObject; + }; + + const credentials = await this.getCredentials('supabaseApi'); + const embeddings = (await this.getInputConnectionData('embedding', 0)) as Embeddings; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const client = createClient(credentials.host as string, credentials.serviceRole as string); + + const vectorStore = await SupabaseVectorStore.fromExistingIndex(embeddings, { + client, + tableName, + queryName, + filter: options.filter, + }); + + return { + response: logWrapper(vectorStore, this), + }; + } +} diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseLoad/supabase.svg b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseLoad/supabase.svg new file mode 100644 index 0000000000000..ad802ac16ae9e --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreSupabaseLoad/supabase.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/packages/@n8n/nodes-langchain/package.json b/packages/@n8n/nodes-langchain/package.json index 4be407275319d..4aab50e7491da 100644 --- a/packages/@n8n/nodes-langchain/package.json +++ b/packages/@n8n/nodes-langchain/package.json @@ -77,7 +77,9 @@ "dist/nodes/retrievers/RetrieverVectorStore/RetrieverVectorStore.node.js", "dist/nodes/vector_store/InMemoryVectorStore/InMemoryVectorStore.node.js", "dist/nodes/vector_store/VectorStorePineconeInsert/VectorStorePineconeInsert.node.js", - "dist/nodes/vector_store/VectorStorePineconeLoad/VectorStorePineconeLoad.node.js" + "dist/nodes/vector_store/VectorStorePineconeLoad/VectorStorePineconeLoad.node.js", + "dist/nodes/vector_store/VectorStoreSupabaseInsert/VectorStoreSupabaseInsert.node.js", + "dist/nodes/vector_store/VectorStoreSupabaseLoad/VectorStoreSupabaseLoad.node.js" ] }, "devDependencies": { @@ -93,6 +95,7 @@ "@gxl/epub-parser": "^2.0.4", "@huggingface/inference": "2.6.1", "@pinecone-database/pinecone": "^0.1.6", + "@supabase/supabase-js": "^2.33.2", "@types/temp": "^0.9.1", "@xata.io/cli": "^0.13.4", "@xata.io/client": "^0.26.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 24c102f1a92b4..18c59d05ed40f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -152,6 +152,9 @@ importers: '@pinecone-database/pinecone': specifier: ^0.1.6 version: 0.1.6 + '@supabase/supabase-js': + specifier: ^2.33.2 + version: 2.33.2 '@types/temp': specifier: ^0.9.1 version: 0.9.1 @@ -175,7 +178,7 @@ importers: version: 1.1.1 langchain: specifier: ^0.0.136 - version: 0.0.136(@huggingface/inference@2.6.1)(@pinecone-database/pinecone@0.1.6)(@xata.io/client@0.26.3)(cohere-ai@6.2.2)(html-to-text@9.0.5)(ignore@5.2.4)(mammoth@1.6.0)(pdf-parse@1.1.1)(pg@8.11.3)(typeorm@0.3.17) + version: 0.0.136(@huggingface/inference@2.6.1)(@pinecone-database/pinecone@0.1.6)(@supabase/supabase-js@2.33.2)(@xata.io/client@0.26.3)(cohere-ai@6.2.2)(html-to-text@9.0.5)(ignore@5.2.4)(mammoth@1.6.0)(pdf-parse@1.1.1)(pg@8.11.3)(typeorm@0.3.17) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -8203,6 +8206,60 @@ packages: - supports-color dev: true + /@supabase/functions-js@2.1.5: + resolution: {integrity: sha512-BNzC5XhCzzCaggJ8s53DP+WeHHGT/NfTsx2wUSSGKR2/ikLFQTBCDzMvGz/PxYMqRko/LwncQtKXGOYp1PkPaw==} + dependencies: + '@supabase/node-fetch': 2.6.14 + dev: false + + /@supabase/gotrue-js@2.51.0: + resolution: {integrity: sha512-9bXV38OTd4tNHukwPDkfYNLyoGuzKeNPRaQ675rsv4JV7YCTliGLJiDadTCZjsMo2v1gVDDUtrJHF8kIxxPP1w==} + dependencies: + '@supabase/node-fetch': 2.6.14 + dev: false + + /@supabase/node-fetch@2.6.14: + resolution: {integrity: sha512-w/Tsd22e/5fAeoxqQ4P2MX6EyF+iM6rc9kmlMVFkHuG0rAltt2TLhFbDJfemnHbtvnazWaRfy5KnFU/SYT37dQ==} + engines: {node: 4.x || >=6.0.0} + dependencies: + whatwg-url: 5.0.0 + dev: false + + /@supabase/postgrest-js@1.8.4: + resolution: {integrity: sha512-ELjpvhb04wILUiJz9zIsTSwaz9LQNlX+Ig5/LgXQ7k68qQI6NqHVn+ISRNt53DngUIyOnLHjeqqIRHBZ7zpgGA==} + dependencies: + '@supabase/node-fetch': 2.6.14 + dev: false + + /@supabase/realtime-js@2.7.4: + resolution: {integrity: sha512-FzSzs1k9ruh/uds5AJ95Nc3beiMCCIhougExJ3O98CX1LMLAKUKFy5FivKLvcNhXnNfUEL0XUfGMb4UH2J7alg==} + dependencies: + '@types/phoenix': 1.6.1 + '@types/websocket': 1.0.6 + websocket: 1.0.34 + transitivePeerDependencies: + - supports-color + dev: false + + /@supabase/storage-js@2.5.4: + resolution: {integrity: sha512-yspHD19I9uQUgfTh0J94+/r/g6hnhdQmw6Y7OWqr/EbnL6uvicGV1i1UDkkmeUHqfF9Mbt2sLtuxRycYyKv2ew==} + dependencies: + '@supabase/node-fetch': 2.6.14 + dev: false + + /@supabase/supabase-js@2.33.2: + resolution: {integrity: sha512-r+xCaERasxI0fMqOTp4zwur200X6HCjif48WKIcWrZgtzdtyP6CsP6J3rwZWfR/mR5MN0qLdK0SGA0QCgxS3Nw==} + dependencies: + '@supabase/functions-js': 2.1.5 + '@supabase/gotrue-js': 2.51.0 + '@supabase/node-fetch': 2.6.14 + '@supabase/postgrest-js': 1.8.4 + '@supabase/realtime-js': 2.7.4 + '@supabase/storage-js': 2.5.4 + transitivePeerDependencies: + - supports-color + dev: false + /@sxzz/popperjs-es@2.11.7: resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} dev: false @@ -8840,6 +8897,10 @@ packages: '@types/express': 4.17.14 dev: true + /@types/phoenix@1.6.1: + resolution: {integrity: sha512-g2/8Ogi2zfiS25jdGT5iDSo5yjruhhXaOuOJCkOxMW28w16VxFvjtAXjBNRo7WlRS4+UXAMj3mK46UwieNM/5g==} + dev: false + /@types/pretty-hrtime@1.0.1: resolution: {integrity: sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==} dev: true @@ -9112,6 +9173,12 @@ packages: resolution: {integrity: sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg==} dev: true + /@types/websocket@1.0.6: + resolution: {integrity: sha512-JXkliwz93B2cMWOI1ukElQBPN88vMg3CruvW4KVSKpflt3NyNCJImnhIuB/f97rG7kakqRJGFiwkA895Kn02Dg==} + dependencies: + '@types/node': 18.17.12 + dev: false + /@types/whatwg-url@8.2.2: resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==} dependencies: @@ -11235,6 +11302,13 @@ packages: ieee754: 1.2.1 dev: false + /bufferutil@4.0.7: + resolution: {integrity: sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==} + engines: {node: '>=6.14.2'} + dependencies: + node-gyp-build: 4.6.1 + dev: false + /buildcheck@0.0.6: resolution: {integrity: sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==} engines: {node: '>=10.0.0'} @@ -12476,7 +12550,6 @@ packages: dependencies: es5-ext: 0.10.62 type: 1.2.0 - dev: true /dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} @@ -13380,7 +13453,6 @@ packages: es6-iterator: 2.0.3 es6-symbol: 3.1.3 next-tick: 1.1.0 - dev: true /es6-iterator@2.0.3: resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} @@ -13388,7 +13460,6 @@ packages: d: 1.0.1 es5-ext: 0.10.62 es6-symbol: 3.1.3 - dev: true /es6-object-assign@1.1.0: resolution: {integrity: sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==} @@ -13399,7 +13470,6 @@ packages: dependencies: d: 1.0.1 ext: 1.7.0 - dev: true /es6-weak-map@2.0.3: resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} @@ -14302,7 +14372,6 @@ packages: resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} dependencies: type: 2.7.2 - dev: true /extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} @@ -17736,7 +17805,7 @@ packages: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} dev: false - /langchain@0.0.136(@huggingface/inference@2.6.1)(@pinecone-database/pinecone@0.1.6)(@xata.io/client@0.26.3)(cohere-ai@6.2.2)(html-to-text@9.0.5)(ignore@5.2.4)(mammoth@1.6.0)(pdf-parse@1.1.1)(pg@8.11.3)(typeorm@0.3.17): + /langchain@0.0.136(@huggingface/inference@2.6.1)(@pinecone-database/pinecone@0.1.6)(@supabase/supabase-js@2.33.2)(@xata.io/client@0.26.3)(cohere-ai@6.2.2)(html-to-text@9.0.5)(ignore@5.2.4)(mammoth@1.6.0)(pdf-parse@1.1.1)(pg@8.11.3)(typeorm@0.3.17): resolution: {integrity: sha512-gqh83F6XQMbKuxMvBKPlRQ7npxJEQk6jY/A5A2xXvwjFaxTIWxcZ4WxAEeaDoF7MAyjmJSyO8eUa4qAzRx3HgQ==} engines: {node: '>=18'} peerDependencies: @@ -17973,6 +18042,7 @@ packages: '@anthropic-ai/sdk': 0.5.10 '@huggingface/inference': 2.6.1 '@pinecone-database/pinecone': 0.1.6 + '@supabase/supabase-js': 2.33.2 '@xata.io/client': 0.26.3(typescript@5.2.2) ansi-styles: 5.2.0 binary-extensions: 2.2.0 @@ -19436,7 +19506,6 @@ packages: /next-tick@1.1.0: resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - dev: true /nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} @@ -19534,6 +19603,11 @@ packages: dev: false optional: true + /node-gyp-build@4.6.1: + resolution: {integrity: sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ==} + hasBin: true + dev: false + /node-gyp@8.4.1: resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} engines: {node: '>= 10.12.0'} @@ -24290,11 +24364,9 @@ packages: /type@1.2.0: resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} - dev: true /type@2.7.2: resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - dev: true /typed-array-buffer@1.0.0: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} @@ -24334,7 +24406,6 @@ packages: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} dependencies: is-typedarray: 1.0.0 - dev: true /typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} @@ -24831,6 +24902,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + dependencies: + node-gyp-build: 4.6.1 + dev: false + /utf7@1.0.2: resolution: {integrity: sha512-qQrPtYLLLl12NF4DrM9CvfkxkYI97xOb5dsnGZHE3teFr0tWiEZ9UdgMPczv24vl708cYMpe6mGXGHrotIp3Bw==} dependencies: @@ -25472,6 +25550,20 @@ packages: - uglify-js dev: true + /websocket@1.0.34: + resolution: {integrity: sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==} + engines: {node: '>=4.0.0'} + dependencies: + bufferutil: 4.0.7 + debug: 2.6.9 + es5-ext: 0.10.62 + typedarray-to-buffer: 3.1.5 + utf-8-validate: 5.0.10 + yaeti: 0.0.6 + transitivePeerDependencies: + - supports-color + dev: false + /whatwg-encoding@1.0.5: resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} dependencies: @@ -25868,6 +25960,11 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + /yaeti@0.0.6: + resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==} + engines: {node: '>=0.10.32'} + dev: false + /yallist@2.1.2: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}