refactor(core): Use use up-to-date timezone data (#10073)

Co-authored-by: Danny Martini <danny@n8n.io>
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2024-07-16 18:46:12 +02:00 committed by GitHub
parent 3bbeae47f3
commit 5e57b0d71e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 42 additions and 35 deletions

View file

@ -74,6 +74,7 @@
"@types/ws": "^8.5.4", "@types/ws": "^8.5.4",
"@types/xml2js": "^0.4.14", "@types/xml2js": "^0.4.14",
"@types/yamljs": "^0.2.31", "@types/yamljs": "^0.2.31",
"@vvo/tzdb": "^6.141.0",
"chokidar": "^3.5.2", "chokidar": "^3.5.2",
"concurrently": "^8.2.0", "concurrently": "^8.2.0",
"ioredis-mock": "^8.8.1", "ioredis-mock": "^8.8.1",
@ -116,7 +117,6 @@
"flat": "5.0.2", "flat": "5.0.2",
"flatted": "3.2.7", "flatted": "3.2.7",
"formidable": "3.5.1", "formidable": "3.5.1",
"google-timezones-json": "1.1.0",
"handlebars": "4.7.8", "handlebars": "4.7.8",
"helmet": "7.1.0", "helmet": "7.1.0",
"infisical-node": "1.3.0", "infisical-node": "1.3.0",

View file

@ -1,6 +1,8 @@
import path from 'path'; import path from 'path';
import { writeFileSync } from 'fs';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import shell from 'shelljs'; import shell from 'shelljs';
import { rawTimeZones } from '@vvo/tzdb';
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
@ -12,41 +14,50 @@ const SPEC_THEME_FILENAME = 'swaggerTheme.css';
const publicApiEnabled = process.env.N8N_PUBLIC_API_DISABLED !== 'true'; const publicApiEnabled = process.env.N8N_PUBLIC_API_DISABLED !== 'true';
copyUserManagementEmailTemplates(); copyUserManagementEmailTemplates();
generateTimezoneData();
if (publicApiEnabled) { if (publicApiEnabled) {
copySwaggerTheme(); copySwaggerTheme();
bundleOpenApiSpecs(); bundleOpenApiSpecs();
} }
function copyUserManagementEmailTemplates(rootDir = ROOT_DIR) { function copyUserManagementEmailTemplates() {
const templates = { const templates = {
source: path.resolve(rootDir, 'src', 'UserManagement', 'email', 'templates'), source: path.resolve(ROOT_DIR, 'src', 'UserManagement', 'email', 'templates'),
destination: path.resolve(rootDir, 'dist', 'UserManagement', 'email'), destination: path.resolve(ROOT_DIR, 'dist', 'UserManagement', 'email'),
}; };
shell.cp('-r', templates.source, templates.destination); shell.cp('-r', templates.source, templates.destination);
} }
function copySwaggerTheme(rootDir = ROOT_DIR, themeFilename = SPEC_THEME_FILENAME) { function copySwaggerTheme() {
const swaggerTheme = { const swaggerTheme = {
source: path.resolve(rootDir, 'src', 'PublicApi', themeFilename), source: path.resolve(ROOT_DIR, 'src', 'PublicApi', SPEC_THEME_FILENAME),
destination: path.resolve(rootDir, 'dist', 'PublicApi'), destination: path.resolve(ROOT_DIR, 'dist', 'PublicApi'),
}; };
shell.cp('-r', swaggerTheme.source, swaggerTheme.destination); shell.cp('-r', swaggerTheme.source, swaggerTheme.destination);
} }
function bundleOpenApiSpecs(rootDir = ROOT_DIR, specFileName = SPEC_FILENAME) { function bundleOpenApiSpecs() {
const publicApiDir = path.resolve(rootDir, 'src', 'PublicApi'); const publicApiDir = path.resolve(ROOT_DIR, 'src', 'PublicApi');
shell shell
.find(publicApiDir) .find(publicApiDir)
.reduce((acc, cur) => { .reduce((acc, cur) => {
return cur.endsWith(specFileName) ? [...acc, path.relative('./src', cur)] : acc; return cur.endsWith(SPEC_FILENAME) ? [...acc, path.relative('./src', cur)] : acc;
}, []) }, [])
.forEach((specPath) => { .forEach((specPath) => {
const distSpecPath = path.resolve(rootDir, 'dist', specPath); const distSpecPath = path.resolve(ROOT_DIR, 'dist', specPath);
const command = `pnpm openapi bundle src/${specPath} --output ${distSpecPath}`; const command = `pnpm openapi bundle src/${specPath} --output ${distSpecPath}`;
shell.exec(command, { silent: true }); 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 }));
}

View file

@ -1,5 +1,6 @@
import { Container, Service } from 'typedi'; import { Container, Service } from 'typedi';
import { exec as callbackExec } from 'child_process'; import { exec as callbackExec } from 'child_process';
import { resolve } from 'path';
import { access as fsAccess } from 'fs/promises'; import { access as fsAccess } from 'fs/promises';
import { promisify } from 'util'; import { promisify } from 'util';
import cookieParser from 'cookie-parser'; import cookieParser from 'cookie-parser';
@ -9,12 +10,10 @@ import { GlobalConfig } from '@n8n/config';
import { InstanceSettings } from 'n8n-core'; import { InstanceSettings } from 'n8n-core';
import type { IN8nUISettings } from 'n8n-workflow'; import type { IN8nUISettings } from 'n8n-workflow';
// @ts-expect-error missing types
import timezones from 'google-timezones-json';
import config from '@/config'; import config from '@/config';
import { import {
CLI_DIR,
EDITOR_UI_DIST_DIR, EDITOR_UI_DIST_DIR,
inDevelopment, inDevelopment,
inE2ETests, inE2ETests,
@ -229,11 +228,8 @@ export class Server extends AbstractServer {
// ---------------------------------------- // ----------------------------------------
// Returns all the available timezones // Returns all the available timezones
this.app.get( const tzDataFile = resolve(CLI_DIR, 'dist/timezones.json');
`/${this.restEndpoint}/options/timezones`, this.app.get(`/${this.restEndpoint}/options/timezones`, (_, res) => res.sendFile(tzDataFile));
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
ResponseHelper.send(async () => timezones),
);
// ---------------------------------------- // ----------------------------------------
// Settings // Settings

View file

@ -643,9 +643,6 @@ importers:
formidable: formidable:
specifier: 3.5.1 specifier: 3.5.1
version: 3.5.1 version: 3.5.1
google-timezones-json:
specifier: 1.1.0
version: 1.1.0
handlebars: handlebars:
specifier: 4.7.8 specifier: 4.7.8
version: 4.7.8 version: 4.7.8
@ -875,6 +872,9 @@ importers:
'@types/yamljs': '@types/yamljs':
specifier: ^0.2.31 specifier: ^0.2.31
version: 0.2.31 version: 0.2.31
'@vvo/tzdb':
specifier: ^6.141.0
version: 6.141.0
chokidar: chokidar:
specifier: 3.5.2 specifier: 3.5.2
version: 3.5.2 version: 3.5.2
@ -5803,6 +5803,9 @@ packages:
'@vueuse/shared@9.13.0': '@vueuse/shared@9.13.0':
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
'@vvo/tzdb@6.141.0':
resolution: {integrity: sha512-vpuv8Eo75WwW6oHygfSSJ8J2AIADlqoHu9HmKxD8Ey/hmRhxt0+/nEGbzBy/Y/Q1qsdgDj3kP3NRLr2082VzgA==}
'@xata.io/client@0.28.4': '@xata.io/client@0.28.4':
resolution: {integrity: sha512-B02WHIA/ViHya84XvH6JCo13rd5h4S5vVyY2aYi6fIcjDIbCpsSLJ4oGWpdodovRYeAZy9Go4OhdyZwMIRC4BQ==} resolution: {integrity: sha512-B02WHIA/ViHya84XvH6JCo13rd5h4S5vVyY2aYi6fIcjDIbCpsSLJ4oGWpdodovRYeAZy9Go4OhdyZwMIRC4BQ==}
peerDependencies: peerDependencies:
@ -8202,9 +8205,6 @@ packages:
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
hasBin: true hasBin: true
google-timezones-json@1.1.0:
resolution: {integrity: sha512-6BmBx9gJVALV2jsfMks8PwmkWT5ip3+bmMyTgXu4PY+G8nKjHi61yrL7rSXpMYRsIzUXhVKpj+MnjhnwG9nung==}
gopd@1.0.1: gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
@ -19244,6 +19244,8 @@ snapshots:
- '@vue/composition-api' - '@vue/composition-api'
- vue - vue
'@vvo/tzdb@6.141.0': {}
'@xata.io/client@0.28.4(typescript@5.5.2)': '@xata.io/client@0.28.4(typescript@5.5.2)':
dependencies: dependencies:
typescript: 5.5.2 typescript: 5.5.2
@ -21217,7 +21219,7 @@ snapshots:
eslint-import-resolver-node@0.3.9: eslint-import-resolver-node@0.3.9:
dependencies: dependencies:
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@5.5.0)
is-core-module: 2.13.1 is-core-module: 2.13.1
resolve: 1.22.8 resolve: 1.22.8
transitivePeerDependencies: transitivePeerDependencies:
@ -21242,7 +21244,7 @@ snapshots:
eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): eslint-module-utils@2.8.0(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0):
dependencies: dependencies:
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@5.5.0)
optionalDependencies: optionalDependencies:
'@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.5.2) '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.5.2)
eslint: 8.57.0 eslint: 8.57.0
@ -21262,7 +21264,7 @@ snapshots:
array.prototype.findlastindex: 1.2.3 array.prototype.findlastindex: 1.2.3
array.prototype.flat: 1.3.2 array.prototype.flat: 1.3.2
array.prototype.flatmap: 1.3.2 array.prototype.flatmap: 1.3.2
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@5.5.0)
doctrine: 2.1.0 doctrine: 2.1.0
eslint: 8.57.0 eslint: 8.57.0
eslint-import-resolver-node: 0.3.9 eslint-import-resolver-node: 0.3.9
@ -21792,7 +21794,7 @@ snapshots:
follow-redirects@1.15.6(debug@3.2.7): follow-redirects@1.15.6(debug@3.2.7):
optionalDependencies: optionalDependencies:
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@5.5.0)
follow-redirects@1.15.6(debug@4.3.4): follow-redirects@1.15.6(debug@4.3.4):
optionalDependencies: optionalDependencies:
@ -22133,7 +22135,7 @@ snapshots:
array-parallel: 0.1.3 array-parallel: 0.1.3
array-series: 0.1.5 array-series: 0.1.5
cross-spawn: 4.0.2 cross-spawn: 4.0.2
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@5.5.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -22186,8 +22188,6 @@ snapshots:
dependencies: dependencies:
node-forge: 1.3.1 node-forge: 1.3.1
google-timezones-json@1.1.0: {}
gopd@1.0.1: gopd@1.0.1:
dependencies: dependencies:
get-intrinsic: 1.2.4 get-intrinsic: 1.2.4
@ -24898,7 +24898,7 @@ snapshots:
pdf-parse@1.1.1: pdf-parse@1.1.1:
dependencies: dependencies:
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@5.5.0)
node-ensure: 0.0.0 node-ensure: 0.0.0
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -25780,7 +25780,7 @@ snapshots:
rhea@1.0.24: rhea@1.0.24:
dependencies: dependencies:
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@5.5.0)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -26154,7 +26154,7 @@ snapshots:
binascii: 0.0.2 binascii: 0.0.2
bn.js: 5.2.1 bn.js: 5.2.1
browser-request: 0.3.3 browser-request: 0.3.3
debug: 3.2.7(supports-color@8.1.1) debug: 3.2.7(supports-color@5.5.0)
expand-tilde: 2.0.2 expand-tilde: 2.0.2
extend: 3.0.2 extend: 3.0.2
fast-xml-parser: 4.2.7 fast-xml-parser: 4.2.7