first commit
Security: Sync from Public / sync-from-public (push) Has been cancelled
Test: Benchmark Nightly / build (push) Has been cancelled
Test: Benchmark Nightly / Notify Cats on failure (push) Has been cancelled
CI: Python / Checks (push) Has been cancelled
Test: Evals Python / Workflow Comparison Python (push) Has been cancelled
Util: Check Docs URLs / check-docs-urls (push) Has been cancelled
Test: Visual Storybook / Cloudflare Pages (push) Has been cancelled
Test: E2E Performance / build-and-test-performance (push) Has been cancelled
Test: Workflows Nightly / Run Workflow Tests (push) Has been cancelled
Util: Cleanup CI Docker Images / Delete stale CI images (push) Has been cancelled
Test: Benchmark Destroy Env / build (push) Has been cancelled
Util: Update Node Popularity / update-popularity (push) Has been cancelled
Test: E2E Coverage Weekly / Coverage Tests (push) Has been cancelled

This commit is contained in:
2026-03-17 16:22:57 +03:30
commit 3d5eaf9445
15349 changed files with 2847338 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
const path = require('path');
const { mkdir, writeFile } = require('fs/promises');
const packageDir = process.cwd();
const distDir = path.join(packageDir, 'dist');
const writeJSON = async (file, data) => {
const filePath = path.resolve(distDir, file);
await mkdir(path.dirname(filePath), { recursive: true });
const payload = Array.isArray(data)
? `[\n${data.map((entry) => JSON.stringify(entry)).join(',\n')}\n]`
: JSON.stringify(data, null, 2);
await writeFile(filePath, payload, { encoding: 'utf-8' });
};
module.exports = {
packageDir,
writeJSON,
};
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env node
const glob = require('fast-glob');
const pLimit = require('p-limit');
const { cp } = require('fs/promises');
const { packageDir } = require('./common');
const limiter = pLimit(20);
const staticFiles = glob.sync(
['{nodes,credentials}/**/*.{png,svg}', 'nodes/**/__schema__/**/*.json'],
{
cwd: packageDir,
},
);
(async () => {
await Promise.all(
staticFiles.map((path) =>
limiter(() => {
return cp(path, `dist/${path}`, { recursive: true });
}),
),
);
})();
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/env node
const { LoggerProxy } = require('n8n-workflow');
const { PackageDirectoryLoader } = require('../dist/nodes-loader/package-directory-loader');
const { packageDir, writeJSON } = require('./common');
LoggerProxy.init(console);
function findReferencedMethods(obj, refs = {}, latestName = '') {
for (const key in obj) {
if (key === 'name' && 'group' in obj) {
latestName = obj[key];
}
if (typeof obj[key] === 'object') {
findReferencedMethods(obj[key], refs, latestName);
}
if (key === 'loadOptionsMethod') {
refs[latestName] = refs[latestName]
? [...new Set([...refs[latestName], obj[key]])]
: [obj[key]];
}
}
return refs;
}
(async () => {
const loader = new PackageDirectoryLoader(packageDir);
await loader.loadAll();
const loaderNodeTypes = Object.values(loader.nodeTypes);
const definedMethods = loaderNodeTypes.reduce((acc, cur) => {
loader.getVersionedNodeTypeAll(cur.type).forEach((type) => {
const methods = type.description?.__loadOptionsMethods;
if (!methods) return;
const { name } = type.description;
if (acc[name]) {
acc[name] = [...new Set([...acc[name], ...methods])];
return;
}
acc[name] = methods;
});
return acc;
}, {});
const nodeTypes = loaderNodeTypes
.map(({ type }) => type)
.flatMap((nodeType) =>
loader.getVersionedNodeTypeAll(nodeType).map((item) => {
const { __loadOptionsMethods, ...rest } = item.description;
return rest;
}),
);
const knownCredentials = loader.known.credentials;
const credentialTypes = Object.values(loader.credentialTypes).map(({ type }) => type);
const referencedMethods = findReferencedMethods(nodeTypes);
await Promise.all([
writeJSON('known/nodes.json', loader.known.nodes),
writeJSON('known/credentials.json', loader.known.credentials),
writeJSON('types/credentials.json', credentialTypes),
writeJSON('types/nodes.json', nodeTypes),
writeJSON('methods/defined.json', definedMethods),
writeJSON('methods/referenced.json', referencedMethods),
]);
})();
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env node
const path = require('path');
const fs = require('fs');
const {
generateNodeDefinitions,
} = require('@n8n/workflow-sdk/dist/generate-types/generate-node-defs-cli');
const cwd = process.cwd();
const nodesJsonPath = path.join(cwd, 'dist', 'types', 'nodes.json');
const outputDir = path.join(cwd, 'dist', 'node-definitions');
const packageJsonPath = path.join(cwd, 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
generateNodeDefinitions({
nodesJsonPath,
outputDir,
packageName: packageJson.name,
}).catch((error) => {
console.error('Node definition generation failed:', error);
process.exit(1);
});
+99
View File
@@ -0,0 +1,99 @@
#!/usr/bin/env node
const {
existsSync,
promises: { writeFile },
} = require('fs');
const path = require('path');
const { packageDir } = require('./common');
const ALLOWED_HEADER_KEYS = ['displayName', 'description'];
const PURPLE_ANSI_COLOR_CODE = 35;
function getNodeTranslationPaths() {
const nodeDistPaths = require(`${packageDir}/package.json`).n8n.nodes;
const { N8N_DEFAULT_LOCALE: locale } = process.env;
return nodeDistPaths.reduce((acc, cur) => {
const nodeTranslationPath = path.join(
packageDir,
cur.split('/').slice(1, -1).join('/'),
'translations',
locale,
toTranslationFile(cur),
);
if (existsSync(nodeTranslationPath)) {
acc.push(nodeTranslationPath);
}
return acc;
}, []);
}
function getHeaders(nodeTranslationPaths) {
return nodeTranslationPaths.reduce((acc, cur) => {
const { header } = require(cur);
const nodeType = cur.split('/').pop().replace('.json', '');
if (isValidHeader(header, ALLOWED_HEADER_KEYS)) {
acc[nodeType] = header;
}
return acc;
}, {});
}
// ----------------------------------
// helpers
// ----------------------------------
function toTranslationFile(distPath) {
const raw = distPath.split('/').pop().replace('.node', '') + 'on';
return raw.charAt(0).toLowerCase() + raw.slice(1);
}
function isValidHeader(header, allowedHeaderKeys) {
if (!header) return false;
const headerKeys = Object.keys(header);
return headerKeys.length > 0 && headerKeys.every((key) => allowedHeaderKeys.includes(key));
}
function writeDistFile(data, distPath) {
writeFile(distPath, `module.exports = ${JSON.stringify(data, null, 2)}`);
}
const log = (string, { bulletPoint } = { bulletPoint: false }) => {
if (bulletPoint) {
process.stdout.write(colorize(PURPLE_ANSI_COLOR_CODE, `- ${string}\n`));
return;
}
process.stdout.write(`${string}\n`);
};
const colorize = (ansiColorCode, string) =>
['\033[', ansiColorCode, 'm', string, '\033[0m'].join('');
/**
* Write node translation headers to single file at `/dist/nodes/headers.js`.
*/
const { N8N_DEFAULT_LOCALE: locale } = process.env;
log(`Default locale set to: ${colorize(PURPLE_ANSI_COLOR_CODE, locale || 'en')}`);
if (!locale || locale === 'en') {
log('No translation required - Skipping translations build...');
return;
}
const nodeTranslationPaths = getNodeTranslationPaths();
const headers = getHeaders(nodeTranslationPaths);
const headersDistPath = path.join(packageDir, 'dist', 'nodes', 'headers.js');
writeDistFile(headers, headersDistPath);
log('Headers file written to:');
log(headersDistPath, { bulletPoint: true });