import path from 'path'; import { writeFileSync } from 'fs'; import { fileURLToPath } from 'url'; import shell from 'shelljs'; import { rawTimeZones } from '@vvo/tzdb'; import glob from 'fast-glob'; 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(); if (publicApiEnabled) { 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 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 = rawTimeZones.reduce((acc, tz) => { acc[tz.name] = tz.name.replaceAll('_', ' '); return acc; }, {}); writeFileSync(path.resolve(ROOT_DIR, 'dist/timezones.json'), JSON.stringify({ data: timezones })); }