n8n/packages/cli/scripts/build.mjs
yehorkardash 64079ad98c
feat(core): Agents as first class entities support (no-changelog) (#28017)
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Michael Drury <michael.drury@n8n.io>
Co-authored-by: Arvin A <51036481+DeveloperTheExplorer@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Arvin Ansari <arvin.ansari@n8n.io>
Co-authored-by: bjorger <50590409+bjorger@users.noreply.github.com>
Co-authored-by: Eugene <eugene@n8n.io>
Co-authored-by: Michael Drury <me@michaeldrury.co.uk>
Co-authored-by: Robin Braumann <robin.braumann@n8n.io>
Co-authored-by: Rob Hough <robhough180@gmail.com>
2026-05-06 15:44:44 +00:00

87 lines
2.8 KiB
JavaScript

import path from 'path';
import { writeFileSync, existsSync, mkdirSync } from 'fs';
import { fileURLToPath } from 'url';
import shell from 'shelljs';
import { rawTimeZones } from '@vvo/tzdb';
import glob from 'fast-glob';
import { buildAgentLibraryBundle } from './bundle-agent-library.mjs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const ROOT_DIR = path.resolve(__dirname, '..');
const SPEC_FILENAME = 'openapi.yml';
const SPEC_THEME_FILENAME = 'swagger-theme.css';
const publicApiEnabled = process.env.N8N_PUBLIC_API_DISABLED !== 'true';
generateUserManagementEmailTemplates();
generateTimezoneData();
await buildAgentLibraryBundle();
if (publicApiEnabled) {
createPublicApiDirectory();
copySwaggerTheme();
bundleOpenApiSpecs();
}
function generateUserManagementEmailTemplates() {
const sourceDir = path.resolve(ROOT_DIR, 'src', 'user-management', 'email', 'templates');
const destinationDir = path.resolve(ROOT_DIR, 'dist', 'user-management', 'email', 'templates');
shell.mkdir('-p', destinationDir);
const templates = glob.sync('*.mjml', { cwd: sourceDir });
templates.forEach((template) => {
if (template.startsWith('_')) return;
const source = path.resolve(sourceDir, template);
const destination = path.resolve(destinationDir, template.replace(/\.mjml$/, '.handlebars'));
const command = `pnpm mjml --output "${destination}" "${source}"`;
shell.exec(command, { silent: false });
});
shell.cp(path.resolve(sourceDir, 'n8n-logo.png'), destinationDir);
}
function createPublicApiDirectory() {
const publicApiDirectory = path.resolve(ROOT_DIR, 'dist', 'public-api', 'v1');
if (!existsSync(publicApiDirectory)) {
console.log('Creating directory', publicApiDirectory);
mkdirSync(publicApiDirectory, { recursive: true });
}
}
function copySwaggerTheme() {
const swaggerTheme = {
source: path.resolve(ROOT_DIR, 'src', 'public-api', SPEC_THEME_FILENAME),
destination: path.resolve(ROOT_DIR, 'dist', 'public-api'),
};
shell.cp('-r', swaggerTheme.source, swaggerTheme.destination);
}
function bundleOpenApiSpecs() {
const publicApiDir = path.resolve(ROOT_DIR, 'src', 'public-api');
shell
.find(publicApiDir)
.reduce((acc, cur) => {
return cur.endsWith(SPEC_FILENAME) ? [...acc, path.relative('./src', cur)] : acc;
}, [])
.forEach((specPath) => {
const distSpecPath = path.resolve(ROOT_DIR, 'dist', specPath);
const command = `pnpm openapi bundle "src/${specPath}" --output "${distSpecPath}"`;
shell.exec(command, { silent: true });
});
}
function generateTimezoneData() {
const timezones = ['Etc/UTC', 'Etc/GMT', ...rawTimeZones.map((tz) => tz.name)];
const data = timezones.sort().reduce((acc, name) => {
acc[name] = name.replaceAll('_', ' ');
return acc;
}, {});
writeFileSync(path.resolve(ROOT_DIR, 'dist/timezones.json'), JSON.stringify({ data }));
}