mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
feat: Adds community scanner package (#18946)
Co-authored-by: Elias Meire <elias@meire.dev>
This commit is contained in:
1
packages/@n8n/scan-community-package/.gitignore
vendored
Normal file
1
packages/@n8n/scan-community-package/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
7
packages/@n8n/scan-community-package/README.md
Normal file
7
packages/@n8n/scan-community-package/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## n8n community-package static analysis tool
|
||||
|
||||
### How to use this
|
||||
|
||||
```
|
||||
$ npx @n8n/scan-community-package n8n-nodes-PACKAGE
|
||||
```
|
||||
17
packages/@n8n/scan-community-package/package.json
Normal file
17
packages/@n8n/scan-community-package/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@n8n/scan-community-package",
|
||||
"version": "0.1.2",
|
||||
"description": "Static code analyser for n8n community packages",
|
||||
"license": "none",
|
||||
"bin": "scanner/cli.mjs",
|
||||
"files": [
|
||||
"scanner"
|
||||
],
|
||||
"dependencies": {
|
||||
"eslint": "catalog:",
|
||||
"fast-glob": "catalog:",
|
||||
"axios": "catalog:",
|
||||
"semver": "^7.5.4",
|
||||
"tmp": "0.2.4"
|
||||
}
|
||||
}
|
||||
36
packages/@n8n/scan-community-package/scanner/cli.mjs
Executable file
36
packages/@n8n/scan-community-package/scanner/cli.mjs
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
if (args.length < 1) {
|
||||
console.error(
|
||||
"Usage: npx @n8n/scan-community-package <package-name>[@version]",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
import { resolvePackage, analyzePackageByName } from "./scanner.mjs";
|
||||
|
||||
const packageSpec = args[0];
|
||||
const { packageName, version } = resolvePackage(packageSpec);
|
||||
try {
|
||||
const result = await analyzePackageByName(packageName, version);
|
||||
|
||||
if (result.passed) {
|
||||
console.log(
|
||||
`✅ Package ${packageName}@${result.version} has passed all security checks`,
|
||||
);
|
||||
} else {
|
||||
console.log(
|
||||
`❌ Package ${packageName}@${result.version} has failed security checks`,
|
||||
);
|
||||
console.log(`Reason: ${result.message}`);
|
||||
|
||||
if (result.details) {
|
||||
console.log("\nDetails:");
|
||||
console.log(result.details);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Analysis failed:", error);
|
||||
process.exit(1);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
const restrictedGlobals = [
|
||||
"clearInterval",
|
||||
"clearTimeout",
|
||||
"global",
|
||||
"process",
|
||||
"setInterval",
|
||||
"setTimeout",
|
||||
];
|
||||
|
||||
const allowedModules = [
|
||||
"n8n-workflow",
|
||||
"lodash",
|
||||
"moment",
|
||||
"p-limit",
|
||||
"luxon",
|
||||
"zod",
|
||||
"crypto",
|
||||
"node:crypto"
|
||||
];
|
||||
|
||||
const isModuleAllowed = (modulePath) => {
|
||||
// Allow relative paths
|
||||
if (modulePath.startsWith("./") || modulePath.startsWith("../")) return true;
|
||||
|
||||
// Extract module name from imports that might contain additional path
|
||||
const moduleName = modulePath.startsWith("@")
|
||||
? modulePath.split("/").slice(0, 2).join("/")
|
||||
: modulePath.split("/")[0];
|
||||
return allowedModules.includes(moduleName);
|
||||
};
|
||||
|
||||
/** @type {import('@types/eslint').ESLint.Plugin} */
|
||||
const plugin = {
|
||||
rules: {
|
||||
"no-restricted-globals": {
|
||||
create(context) {
|
||||
return {
|
||||
Identifier(node) {
|
||||
if (
|
||||
restrictedGlobals.includes(node.name) &&
|
||||
(!node.parent ||
|
||||
node.parent.type !== "MemberExpression" ||
|
||||
node.parent.object === node)
|
||||
) {
|
||||
context.report({
|
||||
node,
|
||||
message: `Use of restricted global '${node.name}' is not allowed`,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
"no-restricted-imports": {
|
||||
create(context) {
|
||||
return {
|
||||
ImportDeclaration(node) {
|
||||
const modulePath = node.source.value;
|
||||
if (!isModuleAllowed(modulePath)) {
|
||||
context.report({
|
||||
node,
|
||||
message: `Import of '${modulePath}' is not allowed.`,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
CallExpression(node) {
|
||||
if (
|
||||
node.callee.name === "require" &&
|
||||
node.arguments.length > 0 &&
|
||||
node.arguments[0].type === "Literal"
|
||||
) {
|
||||
const modulePath = node.arguments[0].value;
|
||||
if (!isModuleAllowed(modulePath)) {
|
||||
context.report({
|
||||
node,
|
||||
message: `Require of '${modulePath}' is not allowed.`,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default plugin;
|
||||
183
packages/@n8n/scan-community-package/scanner/scanner.mjs
Normal file
183
packages/@n8n/scan-community-package/scanner/scanner.mjs
Normal file
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { ESLint } from "eslint";
|
||||
import { execSync } from "child_process";
|
||||
import tmp from "tmp";
|
||||
import semver from "semver";
|
||||
import axios from "axios";
|
||||
import glob from "fast-glob";
|
||||
import { fileURLToPath } from "url";
|
||||
import { defineConfig } from "eslint/config";
|
||||
|
||||
import plugin from "./eslint-plugin.mjs";
|
||||
|
||||
const { stdout } = process;
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const TEMP_DIR = tmp.dirSync({ unsafeCleanup: true }).name;
|
||||
const registry = "https://registry.npmjs.org/";
|
||||
|
||||
export const resolvePackage = (packageSpec) => {
|
||||
let packageName, version;
|
||||
if (packageSpec.startsWith("@")) {
|
||||
if (packageSpec.includes("@", 1)) {
|
||||
// Handle scoped packages with versions
|
||||
const lastAtIndex = packageSpec.lastIndexOf("@");
|
||||
return {
|
||||
packageName: packageSpec.substring(0, lastAtIndex),
|
||||
version: packageSpec.substring(lastAtIndex + 1),
|
||||
};
|
||||
} else {
|
||||
// Handle scoped packages without version
|
||||
return { packageName: packageSpec, version: null };
|
||||
}
|
||||
}
|
||||
// Handle regular packages
|
||||
const parts = packageSpec.split("@");
|
||||
return { packageName: parts[0], version: parts[1] || null };
|
||||
};
|
||||
|
||||
const downloadAndExtractPackage = async (packageName, version) => {
|
||||
try {
|
||||
// Download the tarball
|
||||
execSync(`npm -q pack ${packageName}@${version}`, { cwd: TEMP_DIR });
|
||||
const tarballName = fs
|
||||
.readdirSync(TEMP_DIR)
|
||||
.find((file) => file.endsWith(".tgz"));
|
||||
if (!tarballName) {
|
||||
throw new Error("Tarball not found");
|
||||
}
|
||||
|
||||
// Unpack the tarball
|
||||
const packageDir = path.join(TEMP_DIR, `${packageName}-${version}`);
|
||||
fs.mkdirSync(packageDir, { recursive: true });
|
||||
execSync(`tar -xzf ${tarballName} -C ${packageDir} --strip-components=1`, {
|
||||
cwd: TEMP_DIR,
|
||||
});
|
||||
fs.unlinkSync(path.join(TEMP_DIR, tarballName));
|
||||
|
||||
return packageDir;
|
||||
} catch (error) {
|
||||
console.error(`\nFailed to download package: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const analyzePackage = async (packageDir) => {
|
||||
const { default: eslintPlugin } = await import("./eslint-plugin.mjs");
|
||||
const eslint = new ESLint({
|
||||
cwd: packageDir,
|
||||
allowInlineConfig: false,
|
||||
overrideConfigFile: true,
|
||||
overrideConfig: defineConfig([
|
||||
{
|
||||
plugins: {
|
||||
"n8n-community-packages": plugin,
|
||||
},
|
||||
rules: {
|
||||
"n8n-community-packages/no-restricted-globals": "error",
|
||||
"n8n-community-packages/no-restricted-imports": "error",
|
||||
},
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: "commonjs",
|
||||
},
|
||||
},
|
||||
},
|
||||
]),
|
||||
});
|
||||
|
||||
try {
|
||||
const jsFiles = glob.sync("**/*.js", {
|
||||
cwd: packageDir,
|
||||
absolute: true,
|
||||
ignore: ["node_modules/**"],
|
||||
});
|
||||
|
||||
if (jsFiles.length === 0) {
|
||||
return { passed: true, message: "No JavaScript files found to analyze" };
|
||||
}
|
||||
|
||||
const results = await eslint.lintFiles(jsFiles);
|
||||
const violations = results.filter((result) => result.errorCount > 0);
|
||||
|
||||
if (violations.length > 0) {
|
||||
const formatter = await eslint.loadFormatter("stylish");
|
||||
const formattedResults = await formatter.format(results);
|
||||
return {
|
||||
passed: false,
|
||||
message: "ESLint violations found",
|
||||
details: formattedResults,
|
||||
};
|
||||
}
|
||||
|
||||
return { passed: true };
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return {
|
||||
passed: false,
|
||||
message: `Analysis failed: ${error.message}`,
|
||||
error,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const analyzePackageByName = async (packageName, version) => {
|
||||
try {
|
||||
let exactVersion = version;
|
||||
|
||||
// If version is a range, get the latest matching version
|
||||
if (version && semver.validRange(version) && !semver.valid(version)) {
|
||||
const { data } = await axios.get(`${registry}/${packageName}`);
|
||||
const versions = Object.keys(data.versions);
|
||||
exactVersion = semver.maxSatisfying(versions, version);
|
||||
|
||||
if (!exactVersion) {
|
||||
throw new Error(`No version found matching ${version}`);
|
||||
}
|
||||
}
|
||||
|
||||
// If no version specified, get the latest
|
||||
if (!exactVersion) {
|
||||
const { data } = await axios.get(`${registry}/${packageName}`);
|
||||
exactVersion = data["dist-tags"].latest;
|
||||
}
|
||||
|
||||
const label = `${packageName}@${exactVersion}`;
|
||||
|
||||
stdout.write(`Downloading ${label}...`);
|
||||
const packageDir = await downloadAndExtractPackage(
|
||||
packageName,
|
||||
exactVersion,
|
||||
);
|
||||
if (stdout.TTY){
|
||||
stdout.clearLine(0);
|
||||
stdout.cursorTo(0);
|
||||
}
|
||||
stdout.write(`✅ Downloaded ${label} \n`);
|
||||
|
||||
stdout.write(`Analyzing ${label}...`);
|
||||
const analysisResult = await analyzePackage(packageDir);
|
||||
if (stdout.TTY) {
|
||||
stdout.clearLine(0);
|
||||
stdout.cursorTo(0);
|
||||
}
|
||||
stdout.write(`✅ Analyzed ${label} \n`);
|
||||
|
||||
return {
|
||||
packageName,
|
||||
version: exactVersion,
|
||||
...analysisResult,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Failed to analyze ${packageName}@${version}:`, error);
|
||||
return {
|
||||
packageName,
|
||||
version,
|
||||
passed: false,
|
||||
message: `Analysis failed: ${error.message}`,
|
||||
};
|
||||
}
|
||||
};
|
||||
62
pnpm-lock.yaml
generated
62
pnpm-lock.yaml
generated
@@ -1002,7 +1002,7 @@ importers:
|
||||
version: 4.3.0
|
||||
'@getzep/zep-cloud':
|
||||
specifier: 1.0.12
|
||||
version: 1.0.12(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.30(e7c2f10ddf33088da1e6affdf0fc6c0a))
|
||||
version: 1.0.12(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.30(316b19288832115574731e049dc7676a))
|
||||
'@getzep/zep-js':
|
||||
specifier: 0.9.0
|
||||
version: 0.9.0
|
||||
@@ -1029,7 +1029,7 @@ importers:
|
||||
version: 0.3.4(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(encoding@0.1.13)
|
||||
'@langchain/community':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.50(7d9026709e640c92cdf2ea22646a0399)
|
||||
version: 0.3.50(ccee17333f80550b1303d83de2b6f79a)
|
||||
'@langchain/core':
|
||||
specifier: 'catalog:'
|
||||
version: 0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67))
|
||||
@@ -1146,7 +1146,7 @@ importers:
|
||||
version: 23.0.1
|
||||
langchain:
|
||||
specifier: 0.3.30
|
||||
version: 0.3.30(e7c2f10ddf33088da1e6affdf0fc6c0a)
|
||||
version: 0.3.30(316b19288832115574731e049dc7676a)
|
||||
lodash:
|
||||
specifier: 'catalog:'
|
||||
version: 4.17.21
|
||||
@@ -1252,6 +1252,24 @@ importers:
|
||||
specifier: workspace:*
|
||||
version: link:../typescript-config
|
||||
|
||||
packages/@n8n/scan-community-package:
|
||||
dependencies:
|
||||
axios:
|
||||
specifier: 'catalog:'
|
||||
version: 1.8.3
|
||||
eslint:
|
||||
specifier: 'catalog:'
|
||||
version: 9.29.0(jiti@1.21.7)
|
||||
fast-glob:
|
||||
specifier: 'catalog:'
|
||||
version: 3.2.12
|
||||
semver:
|
||||
specifier: ^7.5.4
|
||||
version: 7.7.2
|
||||
tmp:
|
||||
specifier: 0.2.4
|
||||
version: 0.2.4
|
||||
|
||||
packages/@n8n/storybook:
|
||||
devDependencies:
|
||||
'@chromatic-com/storybook':
|
||||
@@ -19109,7 +19127,7 @@ snapshots:
|
||||
'@gar/promisify@1.1.3':
|
||||
optional: true
|
||||
|
||||
'@getzep/zep-cloud@1.0.12(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.30(e7c2f10ddf33088da1e6affdf0fc6c0a))':
|
||||
'@getzep/zep-cloud@1.0.12(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.30(316b19288832115574731e049dc7676a))':
|
||||
dependencies:
|
||||
form-data: 4.0.4
|
||||
node-fetch: 2.7.0(encoding@0.1.13)
|
||||
@@ -19118,7 +19136,7 @@ snapshots:
|
||||
zod: 3.25.67
|
||||
optionalDependencies:
|
||||
'@langchain/core': 0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67))
|
||||
langchain: 0.3.30(e7c2f10ddf33088da1e6affdf0fc6c0a)
|
||||
langchain: 0.3.30(316b19288832115574731e049dc7676a)
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
@@ -19672,7 +19690,7 @@ snapshots:
|
||||
- aws-crt
|
||||
- encoding
|
||||
|
||||
'@langchain/community@0.3.50(7d9026709e640c92cdf2ea22646a0399)':
|
||||
'@langchain/community@0.3.50(ccee17333f80550b1303d83de2b6f79a)':
|
||||
dependencies:
|
||||
'@browserbasehq/stagehand': 1.9.0(@playwright/test@1.54.2)(deepmerge@4.3.1)(dotenv@16.6.1)(encoding@0.1.13)(openai@5.12.2(ws@8.18.3)(zod@3.25.67))(zod@3.25.67)
|
||||
'@ibm-cloud/watsonx-ai': 1.1.2
|
||||
@@ -19684,7 +19702,7 @@ snapshots:
|
||||
flat: 5.0.2
|
||||
ibm-cloud-sdk-core: 5.3.2
|
||||
js-yaml: 4.1.0
|
||||
langchain: 0.3.30(e7c2f10ddf33088da1e6affdf0fc6c0a)
|
||||
langchain: 0.3.30(316b19288832115574731e049dc7676a)
|
||||
langsmith: 0.3.55(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67))
|
||||
openai: 5.12.2(ws@8.18.3)(zod@3.25.67)
|
||||
uuid: 10.0.0
|
||||
@@ -19698,7 +19716,7 @@ snapshots:
|
||||
'@aws-sdk/credential-provider-node': 3.808.0
|
||||
'@azure/storage-blob': 12.26.0
|
||||
'@browserbasehq/sdk': 2.6.0(encoding@0.1.13)
|
||||
'@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.30(e7c2f10ddf33088da1e6affdf0fc6c0a))
|
||||
'@getzep/zep-cloud': 1.0.12(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(encoding@0.1.13)(langchain@0.3.30(316b19288832115574731e049dc7676a))
|
||||
'@getzep/zep-js': 0.9.0
|
||||
'@google-ai/generativelanguage': 2.6.0(encoding@0.1.13)
|
||||
'@google-cloud/storage': 7.12.1(encoding@0.1.13)
|
||||
@@ -20761,7 +20779,7 @@ snapshots:
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
redoc: 2.4.0(core-js@3.40.0)(encoding@0.1.13)(mobx@6.12.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(styled-components@6.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0))
|
||||
semver: 7.6.0
|
||||
semver: 7.7.2
|
||||
simple-websocket: 9.1.0
|
||||
styled-components: 6.1.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
|
||||
yargs: 17.0.1
|
||||
@@ -23465,7 +23483,7 @@ snapshots:
|
||||
|
||||
axios-retry@4.5.0(axios@1.11.0(debug@4.4.1)):
|
||||
dependencies:
|
||||
axios: 1.11.0(debug@4.3.6)
|
||||
axios: 1.11.0(debug@4.4.1)
|
||||
is-retry-allowed: 2.2.0
|
||||
|
||||
axios-retry@4.5.0(axios@1.11.0):
|
||||
@@ -23819,7 +23837,7 @@ snapshots:
|
||||
ioredis: 5.3.2
|
||||
lodash: 4.17.21
|
||||
msgpackr: 1.11.2
|
||||
semver: 7.6.0
|
||||
semver: 7.7.2
|
||||
uuid: 8.3.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -25532,7 +25550,7 @@ snapshots:
|
||||
|
||||
eslint-import-resolver-node@0.3.9:
|
||||
dependencies:
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
is-core-module: 2.16.1
|
||||
resolve: 1.22.10
|
||||
transitivePeerDependencies:
|
||||
@@ -25556,7 +25574,7 @@ snapshots:
|
||||
|
||||
eslint-module-utils@2.12.1(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.9.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@4.4.3)(eslint@9.29.0(jiti@1.21.7)):
|
||||
dependencies:
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
optionalDependencies:
|
||||
'@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.9.2)
|
||||
eslint: 9.29.0(jiti@1.21.7)
|
||||
@@ -25595,7 +25613,7 @@ snapshots:
|
||||
array.prototype.findlastindex: 1.2.6
|
||||
array.prototype.flat: 1.3.3
|
||||
array.prototype.flatmap: 1.3.3
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
doctrine: 2.1.0
|
||||
eslint: 9.29.0(jiti@1.21.7)
|
||||
eslint-import-resolver-node: 0.3.9
|
||||
@@ -26550,7 +26568,7 @@ snapshots:
|
||||
array-parallel: 0.1.3
|
||||
array-series: 0.1.5
|
||||
cross-spawn: 7.0.6
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -26901,7 +26919,7 @@ snapshots:
|
||||
'@types/debug': 4.1.12
|
||||
'@types/node': 20.19.10
|
||||
'@types/tough-cookie': 4.0.5
|
||||
axios: 1.11.0(debug@4.3.6)
|
||||
axios: 1.11.0(debug@4.4.1)
|
||||
camelcase: 6.3.0
|
||||
debug: 4.4.1(supports-color@8.1.1)
|
||||
dotenv: 16.6.1
|
||||
@@ -26911,7 +26929,7 @@ snapshots:
|
||||
isstream: 0.1.2
|
||||
jsonwebtoken: 9.0.2
|
||||
mime-types: 2.1.35
|
||||
retry-axios: 2.6.0(axios@1.11.0(debug@4.4.1))
|
||||
retry-axios: 2.6.0(axios@1.11.0)
|
||||
tough-cookie: 4.1.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -27038,7 +27056,7 @@ snapshots:
|
||||
fengari: 0.1.4
|
||||
fengari-interop: 0.1.3(fengari@0.1.4)
|
||||
ioredis: 5.3.2
|
||||
semver: 7.6.0
|
||||
semver: 7.7.2
|
||||
|
||||
ioredis@5.3.2:
|
||||
dependencies:
|
||||
@@ -28164,7 +28182,7 @@ snapshots:
|
||||
|
||||
kuler@2.0.0: {}
|
||||
|
||||
langchain@0.3.30(e7c2f10ddf33088da1e6affdf0fc6c0a):
|
||||
langchain@0.3.30(316b19288832115574731e049dc7676a):
|
||||
dependencies:
|
||||
'@langchain/core': 0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67))
|
||||
'@langchain/openai': 0.6.7(@langchain/core@0.3.68(@opentelemetry/api@1.9.0)(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.67)))(ws@8.18.3)
|
||||
@@ -29955,7 +29973,7 @@ snapshots:
|
||||
|
||||
pdf-parse@1.1.1:
|
||||
dependencies:
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
node-ensure: 0.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -30918,7 +30936,7 @@ snapshots:
|
||||
onetime: 5.1.2
|
||||
signal-exit: 3.0.7
|
||||
|
||||
retry-axios@2.6.0(axios@1.11.0(debug@4.4.1)):
|
||||
retry-axios@2.6.0(axios@1.11.0):
|
||||
dependencies:
|
||||
axios: 1.11.0(debug@4.3.6)
|
||||
|
||||
@@ -30945,7 +30963,7 @@ snapshots:
|
||||
|
||||
rhea@1.0.24:
|
||||
dependencies:
|
||||
debug: 3.2.7(supports-color@8.1.1)
|
||||
debug: 3.2.7(supports-color@5.5.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
|
||||
Reference in New Issue
Block a user