n8n-nodes-browser-smart-automation 0.1.1 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/McpClientTool/McpClientTool.node.js +2 -13
- package/dist/McpClientTool/McpClientTool.node.js.map +1 -1
- package/dist/McpClientTool/utils.js +1 -1
- package/dist/McpClientTool/utils.js.map +1 -1
- package/dist/McpTrigger/McpTrigger.node.js +1 -1
- package/dist/McpTrigger/McpTrigger.node.js.map +1 -1
- package/dist/shared/N8nBinaryLoader.js +203 -0
- package/dist/shared/N8nBinaryLoader.js.map +1 -0
- package/dist/shared/N8nJsonLoader.js +89 -0
- package/dist/shared/N8nJsonLoader.js.map +1 -0
- package/dist/shared/N8nTool.js +106 -0
- package/dist/shared/N8nTool.js.map +1 -0
- package/dist/shared/embeddingInputValidation.js +55 -0
- package/dist/shared/embeddingInputValidation.js.map +1 -0
- package/dist/shared/helpers.js +220 -13
- package/dist/shared/helpers.js.map +1 -1
- package/dist/shared/httpProxyAgent.js +40 -2
- package/dist/shared/httpProxyAgent.js.map +1 -1
- package/dist/shared/logWrapper.js +347 -2
- package/dist/shared/logWrapper.js.map +1 -1
- package/dist/shared/schemaParsing.js +47 -4
- package/dist/shared/schemaParsing.js.map +1 -1
- package/dist/shared/sharedFields.js +142 -7
- package/dist/shared/sharedFields.js.map +1 -1
- package/dist/shared/typesN8nTool.js +17 -0
- package/dist/shared/typesN8nTool.js.map +1 -0
- package/dist/shared/utils.js +1 -1
- package/dist/shared/utils.js.map +1 -1
- package/package.json +23 -7
- package/jest.config.js +0 -24
- package/nodes/McpClient/McpClient.node.ts +0 -327
- package/nodes/McpClient/__test__/McpClient.node.test.ts +0 -221
- package/nodes/McpClient/__test__/utils.test.ts +0 -302
- package/nodes/McpClient/listSearch.ts +0 -48
- package/nodes/McpClient/resourceMapping.ts +0 -48
- package/nodes/McpClient/utils.ts +0 -281
- package/nodes/McpClientTool/McpClientTool.node.ts +0 -468
- package/nodes/McpClientTool/__test__/McpClientTool.node.test.ts +0 -730
- package/nodes/McpClientTool/loadOptions.ts +0 -45
- package/nodes/McpClientTool/types.ts +0 -1
- package/nodes/McpClientTool/utils.ts +0 -116
- package/nodes/McpTrigger/FlushingTransport.ts +0 -61
- package/nodes/McpTrigger/McpServer.ts +0 -317
- package/nodes/McpTrigger/McpTrigger.node.ts +0 -204
- package/nodes/McpTrigger/__test__/FlushingTransport.test.ts +0 -102
- package/nodes/McpTrigger/__test__/McpServer.test.ts +0 -532
- package/nodes/McpTrigger/__test__/McpTrigger.node.test.ts +0 -171
- package/nodes/shared/__test__/utils.test.ts +0 -318
- package/nodes/shared/descriptions.ts +0 -65
- package/nodes/shared/helpers.ts +0 -31
- package/nodes/shared/httpProxyAgent.ts +0 -11
- package/nodes/shared/logWrapper.ts +0 -13
- package/nodes/shared/schemaParsing.ts +0 -9
- package/nodes/shared/sharedFields.ts +0 -20
- package/nodes/shared/types.ts +0 -12
- package/nodes/shared/utils.ts +0 -296
- package/officail/package.json +0 -255
- package/tsconfig.json +0 -32
- package/tsup.config.ts +0 -13
|
@@ -18,24 +18,159 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var sharedFields_exports = {};
|
|
20
20
|
__export(sharedFields_exports, {
|
|
21
|
-
|
|
21
|
+
getBatchingOptionFields: () => getBatchingOptionFields,
|
|
22
|
+
getConnectionHintNoticeField: () => getConnectionHintNoticeField,
|
|
23
|
+
getTemplateNoticeField: () => getTemplateNoticeField,
|
|
24
|
+
metadataFilterField: () => metadataFilterField
|
|
22
25
|
});
|
|
23
26
|
module.exports = __toCommonJS(sharedFields_exports);
|
|
27
|
+
var import_n8n_workflow = require("n8n-workflow");
|
|
28
|
+
const metadataFilterField = {
|
|
29
|
+
displayName: "Metadata Filter",
|
|
30
|
+
name: "metadata",
|
|
31
|
+
type: "fixedCollection",
|
|
32
|
+
description: "Metadata to filter the document by",
|
|
33
|
+
typeOptions: {
|
|
34
|
+
multipleValues: true
|
|
35
|
+
},
|
|
36
|
+
default: {},
|
|
37
|
+
placeholder: "Add filter field",
|
|
38
|
+
options: [
|
|
39
|
+
{
|
|
40
|
+
name: "metadataValues",
|
|
41
|
+
displayName: "Fields to Set",
|
|
42
|
+
values: [
|
|
43
|
+
{
|
|
44
|
+
displayName: "Name",
|
|
45
|
+
name: "name",
|
|
46
|
+
type: "string",
|
|
47
|
+
default: "",
|
|
48
|
+
required: true
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
displayName: "Value",
|
|
52
|
+
name: "value",
|
|
53
|
+
type: "string",
|
|
54
|
+
default: ""
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
};
|
|
60
|
+
function getTemplateNoticeField(templateId) {
|
|
61
|
+
return {
|
|
62
|
+
displayName: `Save time with an <a href="/templates/${templateId}" target="_blank">example</a> of how this node works`,
|
|
63
|
+
name: "notice",
|
|
64
|
+
type: "notice",
|
|
65
|
+
default: ""
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function getBatchingOptionFields(displayOptions, defaultBatchSize = 5) {
|
|
69
|
+
return {
|
|
70
|
+
displayName: "Batch Processing",
|
|
71
|
+
name: "batching",
|
|
72
|
+
type: "collection",
|
|
73
|
+
placeholder: "Add Batch Processing Option",
|
|
74
|
+
description: "Batch processing options for rate limiting",
|
|
75
|
+
default: {},
|
|
76
|
+
options: [
|
|
77
|
+
{
|
|
78
|
+
displayName: "Batch Size",
|
|
79
|
+
name: "batchSize",
|
|
80
|
+
default: defaultBatchSize,
|
|
81
|
+
type: "number",
|
|
82
|
+
description: "How many items to process in parallel. This is useful for rate limiting, but might impact the log output ordering."
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
displayName: "Delay Between Batches",
|
|
86
|
+
name: "delayBetweenBatches",
|
|
87
|
+
default: 0,
|
|
88
|
+
type: "number",
|
|
89
|
+
description: "Delay in milliseconds between batches. This is useful for rate limiting."
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
displayOptions
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const connectionsString = {
|
|
96
|
+
[import_n8n_workflow.NodeConnectionTypes.AiAgent]: {
|
|
97
|
+
// Root AI view
|
|
98
|
+
connection: "",
|
|
99
|
+
locale: "AI Agent"
|
|
100
|
+
},
|
|
101
|
+
[import_n8n_workflow.NodeConnectionTypes.AiChain]: {
|
|
102
|
+
// Root AI view
|
|
103
|
+
connection: "",
|
|
104
|
+
locale: "AI Chain"
|
|
105
|
+
},
|
|
106
|
+
[import_n8n_workflow.NodeConnectionTypes.AiDocument]: {
|
|
107
|
+
connection: import_n8n_workflow.NodeConnectionTypes.AiDocument,
|
|
108
|
+
locale: "Document Loader"
|
|
109
|
+
},
|
|
110
|
+
[import_n8n_workflow.NodeConnectionTypes.AiVectorStore]: {
|
|
111
|
+
connection: import_n8n_workflow.NodeConnectionTypes.AiVectorStore,
|
|
112
|
+
locale: "Vector Store"
|
|
113
|
+
},
|
|
114
|
+
[import_n8n_workflow.NodeConnectionTypes.AiRetriever]: {
|
|
115
|
+
connection: import_n8n_workflow.NodeConnectionTypes.AiRetriever,
|
|
116
|
+
locale: "Vector Store Retriever"
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
function determineArticle(nextWord) {
|
|
120
|
+
const vowels = /^[aeiouAEIOU]/;
|
|
121
|
+
return vowels.test(nextWord) ? "an" : "a";
|
|
122
|
+
}
|
|
123
|
+
const getConnectionParameterString = (connectionType) => {
|
|
124
|
+
if (connectionType === "") return "data-action-parameter-creatorview='AI'";
|
|
125
|
+
return `data-action-parameter-connectiontype='${connectionType}'`;
|
|
126
|
+
};
|
|
127
|
+
const getAhref = (connectionType) => `<a class="test" data-action='openSelectiveNodeCreator'${getConnectionParameterString(
|
|
128
|
+
connectionType.connection
|
|
129
|
+
)}'>${connectionType.locale}</a>`;
|
|
24
130
|
function getConnectionHintNoticeField(connectionTypes) {
|
|
131
|
+
const groupedConnections = /* @__PURE__ */ new Map();
|
|
132
|
+
connectionTypes.forEach((connectionType) => {
|
|
133
|
+
const connectionString = connectionsString[connectionType].connection;
|
|
134
|
+
const localeString = connectionsString[connectionType].locale;
|
|
135
|
+
if (!groupedConnections.has(connectionString)) {
|
|
136
|
+
groupedConnections.set(connectionString, [localeString]);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
groupedConnections.get(connectionString)?.push(localeString);
|
|
140
|
+
});
|
|
141
|
+
let displayName;
|
|
142
|
+
if (groupedConnections.size === 1) {
|
|
143
|
+
const [[connection, locales]] = Array.from(groupedConnections);
|
|
144
|
+
displayName = `This node must be connected to ${determineArticle(locales[0])} ${locales[0].toLowerCase().replace(
|
|
145
|
+
/^ai /,
|
|
146
|
+
"AI "
|
|
147
|
+
)}. <a data-action='openSelectiveNodeCreator' ${getConnectionParameterString(
|
|
148
|
+
connection
|
|
149
|
+
)}>Insert one</a>`;
|
|
150
|
+
} else {
|
|
151
|
+
const ahrefs = Array.from(groupedConnections, ([connection, locales]) => {
|
|
152
|
+
const locale = locales.length > 1 ? locales.map((localeString, index, { length }) => {
|
|
153
|
+
return (index === 0 ? `${determineArticle(localeString)} ` : "") + (index < length - 1 ? `${localeString} or ` : localeString);
|
|
154
|
+
}).join("") : `${determineArticle(locales[0])} ${locales[0]}`;
|
|
155
|
+
return getAhref({ connection, locale });
|
|
156
|
+
});
|
|
157
|
+
displayName = `This node needs to be connected to ${ahrefs.join(" or ")}.`;
|
|
158
|
+
}
|
|
25
159
|
return {
|
|
26
|
-
displayName
|
|
160
|
+
displayName,
|
|
27
161
|
name: "notice",
|
|
28
162
|
type: "notice",
|
|
29
163
|
default: "",
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"@version": [{ _cnd: { gte: 1 } }]
|
|
33
|
-
}
|
|
164
|
+
typeOptions: {
|
|
165
|
+
containerClass: "ndv-connection-hint-notice"
|
|
34
166
|
}
|
|
35
167
|
};
|
|
36
168
|
}
|
|
37
169
|
// Annotate the CommonJS export names for ESM import in node:
|
|
38
170
|
0 && (module.exports = {
|
|
39
|
-
|
|
171
|
+
getBatchingOptionFields,
|
|
172
|
+
getConnectionHintNoticeField,
|
|
173
|
+
getTemplateNoticeField,
|
|
174
|
+
metadataFilterField
|
|
40
175
|
});
|
|
41
176
|
//# sourceMappingURL=sharedFields.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../nodes/shared/sharedFields.ts"],"sourcesContent":["import type { INodeProperties } from 'n8n-workflow';\n\n
|
|
1
|
+
{"version":3,"sources":["../../nodes/shared/sharedFields.ts"],"sourcesContent":["import { NodeConnectionTypes } from 'n8n-workflow';\nimport type { IDisplayOptions, INodeProperties } from 'n8n-workflow';\n\nexport const metadataFilterField: INodeProperties = {\n\tdisplayName: 'Metadata Filter',\n\tname: 'metadata',\n\ttype: 'fixedCollection',\n\tdescription: 'Metadata to filter the document by',\n\ttypeOptions: {\n\t\tmultipleValues: true,\n\t},\n\tdefault: {},\n\tplaceholder: 'Add filter field',\n\toptions: [\n\t\t{\n\t\t\tname: 'metadataValues',\n\t\t\tdisplayName: 'Fields to Set',\n\t\t\tvalues: [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Name',\n\t\t\t\t\tname: 'name',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: '',\n\t\t\t\t\trequired: true,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Value',\n\t\t\t\t\tname: 'value',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: '',\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t],\n};\n\nexport function getTemplateNoticeField(templateId: number): INodeProperties {\n\treturn {\n\t\tdisplayName: `Save time with an <a href=\"/templates/${templateId}\" target=\"_blank\">example</a> of how this node works`,\n\t\tname: 'notice',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t};\n}\n\nexport function getBatchingOptionFields(\n\tdisplayOptions: IDisplayOptions | undefined,\n\tdefaultBatchSize: number = 5,\n): INodeProperties {\n\treturn {\n\t\tdisplayName: 'Batch Processing',\n\t\tname: 'batching',\n\t\ttype: 'collection',\n\t\tplaceholder: 'Add Batch Processing Option',\n\t\tdescription: 'Batch processing options for rate limiting',\n\t\tdefault: {},\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Batch Size',\n\t\t\t\tname: 'batchSize',\n\t\t\t\tdefault: defaultBatchSize,\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription:\n\t\t\t\t\t'How many items to process in parallel. This is useful for rate limiting, but might impact the log output ordering.',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Delay Between Batches',\n\t\t\t\tname: 'delayBetweenBatches',\n\t\t\t\tdefault: 0,\n\t\t\t\ttype: 'number',\n\t\t\t\tdescription: 'Delay in milliseconds between batches. This is useful for rate limiting.',\n\t\t\t},\n\t\t],\n\t\tdisplayOptions,\n\t};\n}\n\nconst connectionsString = {\n\t[NodeConnectionTypes.AiAgent]: {\n\t\t// Root AI view\n\t\tconnection: '',\n\t\tlocale: 'AI Agent',\n\t},\n\t[NodeConnectionTypes.AiChain]: {\n\t\t// Root AI view\n\t\tconnection: '',\n\t\tlocale: 'AI Chain',\n\t},\n\t[NodeConnectionTypes.AiDocument]: {\n\t\tconnection: NodeConnectionTypes.AiDocument,\n\t\tlocale: 'Document Loader',\n\t},\n\t[NodeConnectionTypes.AiVectorStore]: {\n\t\tconnection: NodeConnectionTypes.AiVectorStore,\n\t\tlocale: 'Vector Store',\n\t},\n\t[NodeConnectionTypes.AiRetriever]: {\n\t\tconnection: NodeConnectionTypes.AiRetriever,\n\t\tlocale: 'Vector Store Retriever',\n\t},\n};\n\ntype AllowedConnectionTypes =\n\t| typeof NodeConnectionTypes.AiAgent\n\t| typeof NodeConnectionTypes.AiChain\n\t| typeof NodeConnectionTypes.AiDocument\n\t| typeof NodeConnectionTypes.AiVectorStore\n\t| typeof NodeConnectionTypes.AiRetriever;\n\nfunction determineArticle(nextWord: string): string {\n\t// check if the next word starts with a vowel sound\n\tconst vowels = /^[aeiouAEIOU]/;\n\treturn vowels.test(nextWord) ? 'an' : 'a';\n}\nconst getConnectionParameterString = (connectionType: string) => {\n\tif (connectionType === '') return \"data-action-parameter-creatorview='AI'\";\n\n\treturn `data-action-parameter-connectiontype='${connectionType}'`;\n};\nconst getAhref = (connectionType: { connection: string; locale: string }) =>\n\t`<a class=\"test\" data-action='openSelectiveNodeCreator'${getConnectionParameterString(\n\t\tconnectionType.connection,\n\t)}'>${connectionType.locale}</a>`;\n\nexport function getConnectionHintNoticeField(\n\tconnectionTypes: AllowedConnectionTypes[],\n): INodeProperties {\n\tconst groupedConnections = new Map<string, string[]>();\n\n\t// group connection types by their 'connection' value\n\t// to not create multiple links\n\tconnectionTypes.forEach((connectionType) => {\n\t\tconst connectionString = connectionsString[connectionType].connection;\n\t\tconst localeString = connectionsString[connectionType].locale;\n\n\t\tif (!groupedConnections.has(connectionString)) {\n\t\t\tgroupedConnections.set(connectionString, [localeString]);\n\t\t\treturn;\n\t\t}\n\n\t\tgroupedConnections.get(connectionString)?.push(localeString);\n\t});\n\n\tlet displayName;\n\n\tif (groupedConnections.size === 1) {\n\t\tconst [[connection, locales]] = Array.from(groupedConnections);\n\n\t\tdisplayName = `This node must be connected to ${determineArticle(locales[0])} ${locales[0]\n\t\t\t.toLowerCase()\n\t\t\t.replace(\n\t\t\t\t/^ai /,\n\t\t\t\t'AI ',\n\t\t\t)}. <a data-action='openSelectiveNodeCreator' ${getConnectionParameterString(\n\t\t\tconnection,\n\t\t)}>Insert one</a>`;\n\t} else {\n\t\tconst ahrefs = Array.from(groupedConnections, ([connection, locales]) => {\n\t\t\t// If there are multiple locales, join them with ' or '\n\t\t\t// use determineArticle to insert the correct article\n\t\t\tconst locale =\n\t\t\t\tlocales.length > 1\n\t\t\t\t\t? locales\n\t\t\t\t\t\t\t.map((localeString, index, { length }) => {\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t(index === 0 ? `${determineArticle(localeString)} ` : '') +\n\t\t\t\t\t\t\t\t\t(index < length - 1 ? `${localeString} or ` : localeString)\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.join('')\n\t\t\t\t\t: `${determineArticle(locales[0])} ${locales[0]}`;\n\t\t\treturn getAhref({ connection, locale });\n\t\t});\n\n\t\tdisplayName = `This node needs to be connected to ${ahrefs.join(' or ')}.`;\n\t}\n\n\treturn {\n\t\tdisplayName,\n\t\tname: 'notice',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t\ttypeOptions: {\n\t\t\tcontainerClass: 'ndv-connection-hint-notice',\n\t\t},\n\t};\n}"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var typesN8nTool_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(typesN8nTool_exports);
|
|
17
|
+
//# sourceMappingURL=typesN8nTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../nodes/shared/typesN8nTool.ts"],"sourcesContent":["import type { z } from 'zod';\n\nexport type OpenAICompatibleCredential = { apiKey: string; url: string };\n\nexport type ZodObjectAny = z.ZodObject<any, any, any, any>;"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/dist/shared/utils.js
CHANGED
|
@@ -29,7 +29,7 @@ var import_client = require("@modelcontextprotocol/sdk/client/index.js");
|
|
|
29
29
|
var import_sse = require("@modelcontextprotocol/sdk/client/sse.js");
|
|
30
30
|
var import_streamableHttp = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
31
31
|
var import_n8n_workflow = require("n8n-workflow");
|
|
32
|
-
var import_httpProxyAgent = require("
|
|
32
|
+
var import_httpProxyAgent = require("./httpProxyAgent");
|
|
33
33
|
async function getAllTools(client, cursor) {
|
|
34
34
|
const { tools, nextCursor } = await client.listTools({ cursor });
|
|
35
35
|
if (nextCursor) {
|
package/dist/shared/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../nodes/shared/utils.ts"],"sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\n// import type { ClientOAuth2TokenData } from '@n8n/client-oauth2';\n\nexport interface ClientOAuth2TokenData {\n\taccess_token: string;\n\texpires_in: number;\n\trefresh_token?: string;\n\ttoken_type: string;\n}\nimport type {\n\tIExecuteFunctions,\n\tILoadOptionsFunctions,\n\tINode,\n\tISupplyDataFunctions,\n\tResult,\n} from 'n8n-workflow';\nimport { createResultError, createResultOk, NodeOperationError } from 'n8n-workflow';\n\nimport { proxyFetch } from '@utils/httpProxyAgent';\n\nimport type { McpAuthenticationOption, McpServerTransport, McpTool } from './types';\n\nexport async function getAllTools(client: Client, cursor?: string): Promise<McpTool[]> {\n\tconst { tools, nextCursor } = await client.listTools({ cursor });\n\n\tif (nextCursor) {\n\t\treturn (tools as McpTool[]).concat(await getAllTools(client, nextCursor));\n\t}\n\n\treturn tools as McpTool[];\n}\n\nfunction safeCreateUrl(url: string, baseUrl?: string | URL): Result<URL, Error> {\n\ttry {\n\t\treturn createResultOk(new URL(url, baseUrl));\n\t} catch (error) {\n\t\treturn createResultError(error);\n\t}\n}\n\nfunction normalizeAndValidateUrl(input: string): Result<URL, Error> {\n\tconst withProtocol = !/^https?:\\/\\//i.test(input) ? `https://${input}` : input;\n\tconst parsedUrl = safeCreateUrl(withProtocol);\n\n\tif (!parsedUrl.ok) {\n\t\treturn createResultError(parsedUrl.error);\n\t}\n\n\treturn parsedUrl;\n}\n\nfunction errorHasCode(error: unknown, code: number): boolean {\n\treturn (\n\t\t!!error &&\n\t\ttypeof error === 'object' &&\n\t\t(('code' in error && Number(error.code) === code) ||\n\t\t\t('message' in error &&\n\t\t\t\ttypeof error.message === 'string' &&\n\t\t\t\terror.message.includes(code.toString())))\n\t);\n}\n\nfunction isUnauthorizedError(error: unknown): boolean {\n\treturn errorHasCode(error, 401);\n}\n\nfunction isForbiddenError(error: unknown): boolean {\n\treturn errorHasCode(error, 403);\n}\n\ntype OnUnauthorizedHandler = (\n\theaders?: Record<string, string>,\n) => Promise<Record<string, string> | null>;\n\ntype ConnectMcpClientError =\n\t| { type: 'invalid_url'; error: Error }\n\t| { type: 'connection'; error: Error }\n\t| { type: 'auth'; error: Error };\n\nexport function mapToNodeOperationError(\n\tnode: INode,\n\terror: ConnectMcpClientError,\n): NodeOperationError {\n\tswitch (error.type) {\n\t\tcase 'invalid_url':\n\t\t\treturn new NodeOperationError(node, error.error, {\n\t\t\t\tmessage: 'Could not connect to your MCP server. The provided URL is invalid.',\n\t\t\t});\n\t\tcase 'auth':\n\t\t\treturn new NodeOperationError(node, error.error, {\n\t\t\t\tmessage: 'Could not connect to your MCP server. Authentication failed.',\n\t\t\t});\n\t\tcase 'connection':\n\t\tdefault:\n\t\t\treturn new NodeOperationError(node, error.error, {\n\t\t\t\tmessage: 'Could not connect to your MCP server',\n\t\t\t});\n\t}\n}\n\nexport async function connectMcpClient({\n\theaders,\n\tserverTransport,\n\tendpointUrl,\n\tname,\n\tversion,\n\tonUnauthorized,\n}: {\n\tserverTransport: McpServerTransport;\n\tendpointUrl: string;\n\theaders?: Record<string, string>;\n\tname: string;\n\tversion: number;\n\tonUnauthorized?: OnUnauthorizedHandler;\n}): Promise<Result<Client, ConnectMcpClientError>> {\n\tconst endpoint = normalizeAndValidateUrl(endpointUrl);\n\n\tif (!endpoint.ok) {\n\t\treturn createResultError({ type: 'invalid_url', error: endpoint.error });\n\t}\n\n\tconst client = new Client({ name, version: version.toString() }, { capabilities: {} });\n\n\tif (serverTransport === 'httpStreamable') {\n\t\ttry {\n\t\t\tconst transport = new StreamableHTTPClientTransport(endpoint.result, {\n\t\t\t\trequestInit: { headers },\n\t\t\t\tfetch: proxyFetch,\n\t\t\t});\n\t\t\tawait client.connect(transport);\n\t\t\treturn createResultOk(client);\n\t\t} catch (error) {\n\t\t\tif (onUnauthorized && isUnauthorizedError(error)) {\n\t\t\t\tconst newHeaders = await onUnauthorized(headers);\n\t\t\t\tif (newHeaders) {\n\t\t\t\t\t// Don't pass `onUnauthorized` to avoid possible infinite recursion\n\t\t\t\t\treturn await connectMcpClient({\n\t\t\t\t\t\theaders: newHeaders,\n\t\t\t\t\t\tserverTransport,\n\t\t\t\t\t\tendpointUrl,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tversion,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isUnauthorizedError(error) || isForbiddenError(error)) {\n\t\t\t\treturn createResultError({ type: 'auth', error: error as Error });\n\t\t\t} else {\n\t\t\t\treturn createResultError({ type: 'connection', error: error as Error });\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\tconst sseTransport = new SSEClientTransport(endpoint.result, {\n\t\t\teventSourceInit: {\n\t\t\t\tfetch: async (url, init) =>\n\t\t\t\t\tawait proxyFetch(url, {\n\t\t\t\t\t\t...init,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t...headers,\n\t\t\t\t\t\t\tAccept: 'text/event-stream',\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t},\n\t\t\tfetch: proxyFetch,\n\t\t\trequestInit: { headers },\n\t\t});\n\t\tawait client.connect(sseTransport);\n\t\treturn createResultOk(client);\n\t} catch (error) {\n\t\tif (onUnauthorized && isUnauthorizedError(error)) {\n\t\t\tconst newHeaders = await onUnauthorized(headers);\n\t\t\tif (newHeaders) {\n\t\t\t\t// Don't pass `onUnauthorized` to avoid possible infinite recursion\n\t\t\t\treturn await connectMcpClient({\n\t\t\t\t\theaders: newHeaders,\n\t\t\t\t\tserverTransport,\n\t\t\t\t\tendpointUrl,\n\t\t\t\t\tname,\n\t\t\t\t\tversion,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (isUnauthorizedError(error) || isForbiddenError(error)) {\n\t\t\treturn createResultError({ type: 'auth', error: error as Error });\n\t\t} else {\n\t\t\treturn createResultError({ type: 'connection', error: error as Error });\n\t\t}\n\t}\n}\n\nexport async function getAuthHeaders(\n\tctx: Pick<IExecuteFunctions, 'getCredentials'>,\n\tauthentication: McpAuthenticationOption,\n): Promise<{ headers?: Record<string, string> }> {\n\tswitch (authentication) {\n\t\tcase 'headerAuth': {\n\t\t\tconst header = await ctx\n\t\t\t\t.getCredentials<{ name: string; value: string }>('httpHeaderAuth')\n\t\t\t\t.catch(() => null);\n\n\t\t\tif (!header) return {};\n\n\t\t\treturn { headers: { [header.name]: header.value } };\n\t\t}\n\t\tcase 'bearerAuth': {\n\t\t\tconst result = await ctx\n\t\t\t\t.getCredentials<{ token: string }>('httpBearerAuth')\n\t\t\t\t.catch(() => null);\n\n\t\t\tif (!result) return {};\n\n\t\t\treturn { headers: { Authorization: `Bearer ${result.token}` } };\n\t\t}\n\t\tcase 'mcpOAuth2Api': {\n\t\t\tconst result = await ctx\n\t\t\t\t.getCredentials<{ oauthTokenData: { access_token: string } }>('mcpOAuth2Api')\n\t\t\t\t.catch(() => null);\n\n\t\t\tif (!result) return {};\n\n\t\t\treturn { headers: { Authorization: `Bearer ${result.oauthTokenData.access_token}` } };\n\t\t}\n\t\tcase 'multipleHeadersAuth': {\n\t\t\tconst result = await ctx\n\t\t\t\t.getCredentials<{ headers: { values: Array<{ name: string; value: string }> } }>(\n\t\t\t\t\t'httpMultipleHeadersAuth',\n\t\t\t\t)\n\t\t\t\t.catch(() => null);\n\n\t\t\tif (!result) return {};\n\n\t\t\treturn {\n\t\t\t\theaders: result.headers.values.reduce(\n\t\t\t\t\t(acc, cur) => {\n\t\t\t\t\t\tacc[cur.name] = cur.value;\n\t\t\t\t\t\treturn acc;\n\t\t\t\t\t},\n\t\t\t\t\t{} as Record<string, string>,\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t\tcase 'none':\n\t\tdefault: {\n\t\t\treturn {};\n\t\t}\n\t}\n}\n\n/**\n * Tries to refresh the OAuth2 token, storing them in the database if successful\n * @param ctx - The execution context\n * @param authentication - The authentication method\n * @param headers - The headers to refresh\n * @returns The refreshed headers or null if the authentication method is not oAuth2Api or has failed\n */\nexport async function tryRefreshOAuth2Token(\n\tctx: IExecuteFunctions | ISupplyDataFunctions | ILoadOptionsFunctions,\n\tauthentication: McpAuthenticationOption,\n\theaders?: Record<string, string>,\n) {\n\tif (authentication !== 'mcpOAuth2Api') {\n\t\treturn null;\n\t}\n\n\tlet access_token: string | null = null;\n\ttry {\n\t\tconst result = (await ctx.helpers.refreshOAuth2Token.call(\n\t\t\tctx,\n\t\t\t'mcpOAuth2Api',\n\t\t)) as ClientOAuth2TokenData;\n\t\taccess_token = result?.access_token;\n\t} catch (error) {\n\t\treturn null;\n\t}\n\n\tif (!access_token) {\n\t\treturn null;\n\t}\n\n\tif (!headers) {\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${access_token}`,\n\t\t};\n\t}\n\n\treturn {\n\t\t...headers,\n\t\tAuthorization: `Bearer ${access_token}`,\n\t};\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../nodes/shared/utils.ts"],"sourcesContent":["import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport type { ClientOAuth2TokenData } from '@n8n/client-oauth2';\nimport type {\n\tIExecuteFunctions,\n\tILoadOptionsFunctions,\n\tINode,\n\tISupplyDataFunctions,\n\tResult,\n} from 'n8n-workflow';\nimport { createResultError, createResultOk, NodeOperationError } from 'n8n-workflow';\n\nimport { proxyFetch } from './httpProxyAgent';\n\nimport type { McpAuthenticationOption, McpServerTransport, McpTool } from './types';\n\nexport async function getAllTools(client: Client, cursor?: string): Promise<McpTool[]> {\n\tconst { tools, nextCursor } = await client.listTools({ cursor });\n\n\tif (nextCursor) {\n\t\treturn (tools as McpTool[]).concat(await getAllTools(client, nextCursor));\n\t}\n\n\treturn tools as McpTool[];\n}\n\nfunction safeCreateUrl(url: string, baseUrl?: string | URL): Result<URL, Error> {\n\ttry {\n\t\treturn createResultOk(new URL(url, baseUrl));\n\t} catch (error) {\n\t\treturn createResultError(error);\n\t}\n}\n\nfunction normalizeAndValidateUrl(input: string): Result<URL, Error> {\n\tconst withProtocol = !/^https?:\\/\\//i.test(input) ? `https://${input}` : input;\n\tconst parsedUrl = safeCreateUrl(withProtocol);\n\n\tif (!parsedUrl.ok) {\n\t\treturn createResultError(parsedUrl.error);\n\t}\n\n\treturn parsedUrl;\n}\n\nfunction errorHasCode(error: unknown, code: number): boolean {\n\treturn (\n\t\t!!error &&\n\t\ttypeof error === 'object' &&\n\t\t(('code' in error && Number(error.code) === code) ||\n\t\t\t('message' in error &&\n\t\t\t\ttypeof error.message === 'string' &&\n\t\t\t\terror.message.includes(code.toString())))\n\t);\n}\n\nfunction isUnauthorizedError(error: unknown): boolean {\n\treturn errorHasCode(error, 401);\n}\n\nfunction isForbiddenError(error: unknown): boolean {\n\treturn errorHasCode(error, 403);\n}\n\ntype OnUnauthorizedHandler = (\n\theaders?: Record<string, string>,\n) => Promise<Record<string, string> | null>;\n\ntype ConnectMcpClientError =\n\t| { type: 'invalid_url'; error: Error }\n\t| { type: 'connection'; error: Error }\n\t| { type: 'auth'; error: Error };\n\nexport function mapToNodeOperationError(\n\tnode: INode,\n\terror: ConnectMcpClientError,\n): NodeOperationError {\n\tswitch (error.type) {\n\t\tcase 'invalid_url':\n\t\t\treturn new NodeOperationError(node, error.error, {\n\t\t\t\tmessage: 'Could not connect to your MCP server. The provided URL is invalid.',\n\t\t\t});\n\t\tcase 'auth':\n\t\t\treturn new NodeOperationError(node, error.error, {\n\t\t\t\tmessage: 'Could not connect to your MCP server. Authentication failed.',\n\t\t\t});\n\t\tcase 'connection':\n\t\tdefault:\n\t\t\treturn new NodeOperationError(node, error.error, {\n\t\t\t\tmessage: 'Could not connect to your MCP server',\n\t\t\t});\n\t}\n}\n\nexport async function connectMcpClient({\n\theaders,\n\tserverTransport,\n\tendpointUrl,\n\tname,\n\tversion,\n\tonUnauthorized,\n}: {\n\tserverTransport: McpServerTransport;\n\tendpointUrl: string;\n\theaders?: Record<string, string>;\n\tname: string;\n\tversion: number;\n\tonUnauthorized?: OnUnauthorizedHandler;\n}): Promise<Result<Client, ConnectMcpClientError>> {\n\tconst endpoint = normalizeAndValidateUrl(endpointUrl);\n\n\tif (!endpoint.ok) {\n\t\treturn createResultError({ type: 'invalid_url', error: endpoint.error });\n\t}\n\n\tconst client = new Client({ name, version: version.toString() }, { capabilities: {} });\n\n\tif (serverTransport === 'httpStreamable') {\n\t\ttry {\n\t\t\tconst transport = new StreamableHTTPClientTransport(endpoint.result, {\n\t\t\t\trequestInit: { headers },\n\t\t\t\tfetch: proxyFetch,\n\t\t\t});\n\t\t\tawait client.connect(transport);\n\t\t\treturn createResultOk(client);\n\t\t} catch (error) {\n\t\t\tif (onUnauthorized && isUnauthorizedError(error)) {\n\t\t\t\tconst newHeaders = await onUnauthorized(headers);\n\t\t\t\tif (newHeaders) {\n\t\t\t\t\t// Don't pass `onUnauthorized` to avoid possible infinite recursion\n\t\t\t\t\treturn await connectMcpClient({\n\t\t\t\t\t\theaders: newHeaders,\n\t\t\t\t\t\tserverTransport,\n\t\t\t\t\t\tendpointUrl,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tversion,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isUnauthorizedError(error) || isForbiddenError(error)) {\n\t\t\t\treturn createResultError({ type: 'auth', error: error as Error });\n\t\t\t} else {\n\t\t\t\treturn createResultError({ type: 'connection', error: error as Error });\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\tconst sseTransport = new SSEClientTransport(endpoint.result, {\n\t\t\teventSourceInit: {\n\t\t\t\tfetch: async (url, init) =>\n\t\t\t\t\tawait proxyFetch(url, {\n\t\t\t\t\t\t...init,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t...headers,\n\t\t\t\t\t\t\tAccept: 'text/event-stream',\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t},\n\t\t\tfetch: proxyFetch,\n\t\t\trequestInit: { headers },\n\t\t});\n\t\tawait client.connect(sseTransport);\n\t\treturn createResultOk(client);\n\t} catch (error) {\n\t\tif (onUnauthorized && isUnauthorizedError(error)) {\n\t\t\tconst newHeaders = await onUnauthorized(headers);\n\t\t\tif (newHeaders) {\n\t\t\t\t// Don't pass `onUnauthorized` to avoid possible infinite recursion\n\t\t\t\treturn await connectMcpClient({\n\t\t\t\t\theaders: newHeaders,\n\t\t\t\t\tserverTransport,\n\t\t\t\t\tendpointUrl,\n\t\t\t\t\tname,\n\t\t\t\t\tversion,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (isUnauthorizedError(error) || isForbiddenError(error)) {\n\t\t\treturn createResultError({ type: 'auth', error: error as Error });\n\t\t} else {\n\t\t\treturn createResultError({ type: 'connection', error: error as Error });\n\t\t}\n\t}\n}\n\nexport async function getAuthHeaders(\n\tctx: Pick<IExecuteFunctions, 'getCredentials'>,\n\tauthentication: McpAuthenticationOption,\n): Promise<{ headers?: Record<string, string> }> {\n\tswitch (authentication) {\n\t\tcase 'headerAuth': {\n\t\t\tconst header = await ctx\n\t\t\t\t.getCredentials<{ name: string; value: string }>('httpHeaderAuth')\n\t\t\t\t.catch(() => null);\n\n\t\t\tif (!header) return {};\n\n\t\t\treturn { headers: { [header.name]: header.value } };\n\t\t}\n\t\tcase 'bearerAuth': {\n\t\t\tconst result = await ctx\n\t\t\t\t.getCredentials<{ token: string }>('httpBearerAuth')\n\t\t\t\t.catch(() => null);\n\n\t\t\tif (!result) return {};\n\n\t\t\treturn { headers: { Authorization: `Bearer ${result.token}` } };\n\t\t}\n\t\tcase 'mcpOAuth2Api': {\n\t\t\tconst result = await ctx\n\t\t\t\t.getCredentials<{ oauthTokenData: { access_token: string } }>('mcpOAuth2Api')\n\t\t\t\t.catch(() => null);\n\n\t\t\tif (!result) return {};\n\n\t\t\treturn { headers: { Authorization: `Bearer ${result.oauthTokenData.access_token}` } };\n\t\t}\n\t\tcase 'multipleHeadersAuth': {\n\t\t\tconst result = await ctx\n\t\t\t\t.getCredentials<{ headers: { values: Array<{ name: string; value: string }> } }>(\n\t\t\t\t\t'httpMultipleHeadersAuth',\n\t\t\t\t)\n\t\t\t\t.catch(() => null);\n\n\t\t\tif (!result) return {};\n\n\t\t\treturn {\n\t\t\t\theaders: result.headers.values.reduce(\n\t\t\t\t\t(acc, cur) => {\n\t\t\t\t\t\tacc[cur.name] = cur.value;\n\t\t\t\t\t\treturn acc;\n\t\t\t\t\t},\n\t\t\t\t\t{} as Record<string, string>,\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t\tcase 'none':\n\t\tdefault: {\n\t\t\treturn {};\n\t\t}\n\t}\n}\n\n/**\n * Tries to refresh the OAuth2 token, storing them in the database if successful\n * @param ctx - The execution context\n * @param authentication - The authentication method\n * @param headers - The headers to refresh\n * @returns The refreshed headers or null if the authentication method is not oAuth2Api or has failed\n */\nexport async function tryRefreshOAuth2Token(\n\tctx: IExecuteFunctions | ISupplyDataFunctions | ILoadOptionsFunctions,\n\tauthentication: McpAuthenticationOption,\n\theaders?: Record<string, string>,\n) {\n\tif (authentication !== 'mcpOAuth2Api') {\n\t\treturn null;\n\t}\n\n\tlet access_token: string | null = null;\n\ttry {\n\t\tconst result = (await ctx.helpers.refreshOAuth2Token.call(\n\t\t\tctx,\n\t\t\t'mcpOAuth2Api',\n\t\t)) as ClientOAuth2TokenData;\n\t\taccess_token = result?.access_token;\n\t} catch (error) {\n\t\treturn null;\n\t}\n\n\tif (!access_token) {\n\t\treturn null;\n\t}\n\n\tif (!headers) {\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${access_token}`,\n\t\t};\n\t}\n\n\treturn {\n\t\t...headers,\n\t\tAuthorization: `Bearer ${access_token}`,\n\t};\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-browser-smart-automation",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "n8n nodes for Smart Browser Automation via MCP",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package"
|
|
@@ -15,6 +15,13 @@
|
|
|
15
15
|
],
|
|
16
16
|
"credentials": []
|
|
17
17
|
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"nodes/mcp.svg",
|
|
21
|
+
"nodes/mcp.dark.svg",
|
|
22
|
+
"package.json",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
18
25
|
"scripts": {
|
|
19
26
|
"build": "tsup",
|
|
20
27
|
"dev": "tsc --watch",
|
|
@@ -23,24 +30,33 @@
|
|
|
23
30
|
"test": "jest"
|
|
24
31
|
},
|
|
25
32
|
"dependencies": {
|
|
26
|
-
"@langchain/
|
|
27
|
-
"@langchain/core": "
|
|
28
|
-
"@modelcontextprotocol/sdk": "
|
|
33
|
+
"@langchain/community": "1.0.5",
|
|
34
|
+
"@langchain/core": "1.1.0",
|
|
35
|
+
"@modelcontextprotocol/sdk": "1.24.0",
|
|
36
|
+
"@n8n/client-oauth2": "^1.0.0-rc.0",
|
|
37
|
+
"@n8n/json-schema-to-zod": "^1.6.0",
|
|
38
|
+
"generate-schema": "2.6.0",
|
|
39
|
+
"json-schema": "^0.4.0",
|
|
29
40
|
"n8n-workflow": "*",
|
|
30
|
-
"
|
|
31
|
-
"
|
|
41
|
+
"proxy-from-env": "1.1.0",
|
|
42
|
+
"undici": "6.21.3",
|
|
43
|
+
"zod": "3.25.67",
|
|
44
|
+
"zod-to-json-schema": "3.23.3"
|
|
32
45
|
},
|
|
33
46
|
"devDependencies": {
|
|
47
|
+
"@babel/core": "^7.28.5",
|
|
48
|
+
"@babel/preset-env": "^7.28.5",
|
|
34
49
|
"@types/jest": "^30.0.0",
|
|
35
50
|
"@types/json-schema": "^7.0.15",
|
|
36
51
|
"@types/node": "^20.10.0",
|
|
37
52
|
"@types/uuid": "^11.0.0",
|
|
53
|
+
"babel-jest": "^30.2.0",
|
|
38
54
|
"eslint": "^8.56.0",
|
|
39
55
|
"jest": "^30.2.0",
|
|
40
56
|
"jest-mock-extended": "^4.0.0",
|
|
41
57
|
"n8n-nodes-base": "^1.0.0",
|
|
42
58
|
"ts-jest": "^29.4.6",
|
|
43
|
-
"tsup": "^8.5.
|
|
59
|
+
"tsup": "^8.5.0",
|
|
44
60
|
"typescript": "^5.3.3"
|
|
45
61
|
}
|
|
46
62
|
}
|
package/jest.config.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/** @type {import('jest').Config} */
|
|
2
|
-
module.exports = {
|
|
3
|
-
preset: 'ts-jest',
|
|
4
|
-
testEnvironment: 'node',
|
|
5
|
-
collectCoverageFrom: ['nodes/**/*.ts', '!nodes/**/__test__/**', '!nodes/**/*.test.ts'],
|
|
6
|
-
testMatch: ['**/__test__/**/*.test.ts'],
|
|
7
|
-
transform: {
|
|
8
|
-
'^.+\\.ts$': ['ts-jest', {
|
|
9
|
-
tsconfig: {
|
|
10
|
-
...require('./tsconfig.json').compilerOptions,
|
|
11
|
-
sourceMap: true,
|
|
12
|
-
types: ['jest', 'node'],
|
|
13
|
-
},
|
|
14
|
-
}],
|
|
15
|
-
},
|
|
16
|
-
moduleNameMapper: {
|
|
17
|
-
'^@utils/(.*)$': '<rootDir>/nodes/shared/$1',
|
|
18
|
-
},
|
|
19
|
-
globals: {
|
|
20
|
-
'ts-jest': {
|
|
21
|
-
isolatedModules: true,
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
};
|