angular-intlayer 9.0.0-canary.10 → 9.0.0-canary.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,14 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
3
  let node_path = require("node:path");
4
- let _intlayer_config_node = require("@intlayer/config/node");
5
- let _intlayer_config_utils = require("@intlayer/config/utils");
6
- let _intlayer_chokidar_build = require("@intlayer/chokidar/build");
7
- let _intlayer_chokidar_cli = require("@intlayer/chokidar/cli");
8
- let _intlayer_chokidar_watcher = require("@intlayer/chokidar/watcher");
9
4
  let _intlayer_config_envVars = require("@intlayer/config/envVars");
10
5
  let _intlayer_config_logger = require("@intlayer/config/logger");
6
+ let _intlayer_config_node = require("@intlayer/config/node");
7
+ let _intlayer_config_utils = require("@intlayer/config/utils");
11
8
  let _intlayer_dictionaries_entry = require("@intlayer/dictionaries-entry");
9
+ let _intlayer_engine_build = require("@intlayer/engine/build");
10
+ let _intlayer_engine_cli = require("@intlayer/engine/cli");
11
+ let _intlayer_engine_watcher = require("@intlayer/engine/watcher");
12
12
 
13
13
  //#region src/esbuild/plugin.ts
14
14
  /**
@@ -48,7 +48,7 @@ const intlayerEsbuildPlugin = (options) => {
48
48
  baseDir,
49
49
  ...options?.configOptions
50
50
  });
51
- (0, _intlayer_chokidar_cli.logConfigDetails)({
51
+ (0, _intlayer_engine_cli.logConfigDetails)({
52
52
  baseDir,
53
53
  ...options?.configOptions
54
54
  });
@@ -79,7 +79,7 @@ const intlayerEsbuildPlugin = (options) => {
79
79
  const escapedFrom = from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
80
80
  build.onResolve({ filter: new RegExp(`^${escapedFrom}$`) }, () => ({ path: to }));
81
81
  }
82
- if (!preparePromise) preparePromise = (0, _intlayer_chokidar_build.prepareIntlayer)(config, {
82
+ if (!preparePromise) preparePromise = (0, _intlayer_engine_build.prepareIntlayer)(config, {
83
83
  clean: isProduction,
84
84
  cacheTimeoutMs: isProduction ? 1e3 * 30 : 1e3 * 60 * 60,
85
85
  env: isProduction ? "prod" : "dev"
@@ -88,7 +88,7 @@ const intlayerEsbuildPlugin = (options) => {
88
88
  build.onStart(async () => {
89
89
  if ((options?.watch ?? !isBuildMode) && !watcherStarted) {
90
90
  watcherStarted = true;
91
- await (0, _intlayer_chokidar_watcher.watch)({ configuration: config });
91
+ await (0, _intlayer_engine_watcher.watch)({ configuration: config });
92
92
  }
93
93
  });
94
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs","names":[],"sources":["../../../src/esbuild/plugin.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { watch } from '@intlayer/chokidar/watcher';\nimport {\n formatNodeTypeToEnvVar,\n getConfigEnvVars,\n} from '@intlayer/config/envVars';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { getAlias, getUnusedNodeTypesAsync } from '@intlayer/config/utils';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\n\n// Minimal subset of the esbuild Plugin interface to avoid a hard dependency on\n// the `esbuild` package for type resolution. The shape is compatible with\n// esbuild >=0.17, `@angular-builders/custom-esbuild`, and NX esbuild builders.\nexport interface EsbuildPluginBuild {\n initialOptions: {\n alias?: Record<string, string>;\n define?: Record<string, string>;\n minify?: boolean;\n watch?: unknown;\n /** Absolute working directory of the esbuild context (set by Angular's builder). */\n absWorkingDir?: string;\n };\n onStart(callback: () => void | Promise<void>): void;\n /** Intercept module resolution — works even for imports inside node_modules. */\n onResolve(\n options: { filter: RegExp; namespace?: string },\n callback: (args: {\n path: string;\n importer: string;\n namespace: string;\n resolveDir: string;\n }) => { path: string; namespace?: string } | null | undefined\n ): void;\n}\n\nexport interface EsbuildPlugin {\n name: string;\n setup(build: EsbuildPluginBuild): void | Promise<void>;\n}\n\nexport type IntlayerEsbuildPluginOptions = {\n configOptions?: GetConfigurationOptions;\n /**\n * Whether to start the Intlayer file watcher for dictionary regeneration.\n * - `true`: always start the watcher (useful for `ng serve`)\n * - `false`: never start the watcher (useful for `ng build`)\n * - `undefined` (default): auto-detect based on the build context\n * (skips the watcher when a production build is detected)\n */\n watch?: boolean;\n};\n\n/**\n * esbuild plugin that integrates Intlayer into the Angular (or any esbuild-based) build process.\n *\n * Handles:\n * 1. Injecting `alias` entries so `@intlayer/dictionaries-entry` etc. resolve to\n * the generated files under `.intlayer/`.\n * 2. Defining `process.env.*` tree-shaking constants for production builds.\n * 3. Running `prepareIntlayer` (dictionary generation) before the first build.\n * 4. Starting the chokidar file-watcher in dev / serve mode.\n *\n * Compatible with:\n * - `@angular-builders/custom-esbuild` (`application` or `browser-esbuild` builder)\n * - NX `@nx/angular:browser-esbuild`\n * - Any raw esbuild setup that accepts the standard `Plugin` interface\n *\n * @example\n * ```ts\n * // esbuild.plugins.ts (referenced from angular.json \"plugins\" option)\n * import { intlayerEsbuildPlugin } from 'angular-intlayer/esbuild';\n * export default [intlayerEsbuildPlugin()];\n * ```\n */\nexport const intlayerEsbuildPlugin = (\n options?: IntlayerEsbuildPluginOptions\n): EsbuildPlugin => {\n // All Node.js-heavy initialization (getConfiguration, getAlias, …) is deferred\n // into setup() so it runs in esbuild's Node.js context, not at module-evaluation\n // time. @angular/build loads the plugin file through Vite's SSR module runner\n // (ESM) where CommonJS globals like __filename are undefined. Calling\n // getConfiguration() here would trigger: buildSync → worker threads →\n // __filename → ReferenceError, crashing the plugin before setup() ever runs.\n let config: ReturnType<typeof getConfiguration> | null = null;\n let alias: Record<string, string> | null = null;\n\n // Shared across parallel setup() calls (Angular spawns one per bundle context).\n let preparePromise: Promise<void> | null = null;\n let watcherStarted = false;\n // Once any esbuild context (browser or server) detects a production build,\n // suppress the watcher for all contexts so `ng build` can exit cleanly.\n let isBuildMode = false;\n\n return {\n name: 'intlayer',\n\n async setup(build) {\n if (!config) {\n const baseDir =\n build.initialOptions.absWorkingDir ??\n options?.configOptions?.baseDir ??\n process.cwd();\n\n config = getConfiguration({ baseDir, ...options?.configOptions });\n logConfigDetails({ baseDir, ...options?.configOptions });\n\n alias = getAlias({\n configuration: config,\n formatter: (value: string) => join(config!.system.baseDir, value),\n });\n }\n\n const appLogger = getAppLogger(config);\n const nodeEnvDefine =\n build.initialOptions.define?.['process.env.NODE_ENV'];\n\n // Angular's esbuild builder doesn't set `minify` or `process.env.NODE_ENV`\n // on initialOptions — it handles optimisation through its own pipeline.\n // Instead, Angular defines `ngDevMode` as `\"false\"` in production builds.\n const isProduction =\n nodeEnvDefine === '\"production\"' ||\n nodeEnvDefine === \"'production'\" ||\n build.initialOptions.minify === true ||\n build.initialOptions.define?.['ngDevMode'] === 'false';\n\n if (isProduction) {\n isBuildMode = true;\n }\n\n const envVars: Record<string, string> = {\n INTLAYER: 'true',\n NODE_ENV: isProduction ? 'production' : 'development',\n };\n\n if (isProduction) {\n const dictionaries = getDictionaries(config);\n if (Object.keys(dictionaries).length === 0) {\n appLogger('No dictionaries found. Please check your configuration.', {\n isVerbose: true,\n });\n }\n\n const unusedNodeTypes = await getUnusedNodeTypesAsync(dictionaries);\n Object.assign(\n envVars,\n formatNodeTypeToEnvVar(unusedNodeTypes),\n getConfigEnvVars(config)\n );\n }\n\n build.initialOptions.alias = {\n ...alias,\n ...(build.initialOptions.alias ?? {}),\n };\n\n for (const [from, to] of Object.entries(alias!)) {\n const escapedFrom = from.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n build.onResolve({ filter: new RegExp(`^${escapedFrom}$`) }, () => ({\n path: to,\n }));\n }\n\n if (!preparePromise) {\n preparePromise = prepareIntlayer(config, {\n clean: isProduction,\n cacheTimeoutMs: isProduction ? 1000 * 30 : 1000 * 60 * 60,\n env: isProduction ? 'prod' : 'dev',\n });\n }\n\n await preparePromise;\n\n build.onStart(async () => {\n // Determine whether the watcher should run:\n // 1. Explicit option from the caller takes precedence\n // 2. If any esbuild context detected a production build, skip\n // 3. esbuild's own watch mode is a positive signal\n const shouldWatch = options?.watch ?? !isBuildMode;\n\n if (shouldWatch && !watcherStarted) {\n watcherStarted = true;\n\n await watch({ configuration: config! });\n }\n });\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFA,MAAa,yBACX,YACkB;CAOlB,IAAI,SAAqD;CACzD,IAAI,QAAuC;CAG3C,IAAI,iBAAuC;CAC3C,IAAI,iBAAiB;CAGrB,IAAI,cAAc;AAElB,QAAO;EACL,MAAM;EAEN,MAAM,MAAM,OAAO;AACjB,OAAI,CAAC,QAAQ;IACX,MAAM,UACJ,MAAM,eAAe,iBACrB,SAAS,eAAe,WACxB,QAAQ,KAAK;AAEf,yDAA0B;KAAE;KAAS,GAAG,SAAS;KAAe,CAAC;AACjE,iDAAiB;KAAE;KAAS,GAAG,SAAS;KAAe,CAAC;AAExD,iDAAiB;KACf,eAAe;KACf,YAAY,8BAAuB,OAAQ,OAAO,SAAS,MAAM;KAClE,CAAC;;GAGJ,MAAM,sDAAyB,OAAO;GACtC,MAAM,gBACJ,MAAM,eAAe,SAAS;GAKhC,MAAM,eACJ,kBAAkB,oBAClB,kBAAkB,kBAClB,MAAM,eAAe,WAAW,QAChC,MAAM,eAAe,SAAS,iBAAiB;AAEjD,OAAI,aACF,eAAc;GAGhB,MAAM,UAAkC;IACtC,UAAU;IACV,UAAU,eAAe,eAAe;IACzC;AAED,OAAI,cAAc;IAChB,MAAM,iEAA+B,OAAO;AAC5C,QAAI,OAAO,KAAK,aAAa,CAAC,WAAW,EACvC,WAAU,2DAA2D,EACnE,WAAW,MACZ,CAAC;IAGJ,MAAM,kBAAkB,0DAA8B,aAAa;AACnE,WAAO,OACL,8DACuB,gBAAgB,iDACtB,OAAO,CACzB;;AAGH,SAAM,eAAe,QAAQ;IAC3B,GAAG;IACH,GAAI,MAAM,eAAe,SAAS,EAAE;IACrC;AAED,QAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,MAAO,EAAE;IAC/C,MAAM,cAAc,KAAK,QAAQ,uBAAuB,OAAO;AAE/D,UAAM,UAAU,EAAE,QAAQ,IAAI,OAAO,IAAI,YAAY,GAAG,EAAE,SAAS,EACjE,MAAM,IACP,EAAE;;AAGL,OAAI,CAAC,eACH,gEAAiC,QAAQ;IACvC,OAAO;IACP,gBAAgB,eAAe,MAAO,KAAK,MAAO,KAAK;IACvD,KAAK,eAAe,SAAS;IAC9B,CAAC;AAGJ,SAAM;AAEN,SAAM,QAAQ,YAAY;AAOxB,SAFoB,SAAS,SAAS,CAAC,gBAEpB,CAAC,gBAAgB;AAClC,sBAAiB;AAEjB,iDAAY,EAAE,eAAe,QAAS,CAAC;;KAEzC;;EAEL"}
1
+ {"version":3,"file":"plugin.cjs","names":[],"sources":["../../../src/esbuild/plugin.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport {\n formatNodeTypeToEnvVar,\n getConfigEnvVars,\n} from '@intlayer/config/envVars';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { getAlias, getUnusedNodeTypesAsync } from '@intlayer/config/utils';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { prepareIntlayer } from '@intlayer/engine/build';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport { watch } from '@intlayer/engine/watcher';\n\n// Minimal subset of the esbuild Plugin interface to avoid a hard dependency on\n// the `esbuild` package for type resolution. The shape is compatible with\n// esbuild >=0.17, `@angular-builders/custom-esbuild`, and NX esbuild builders.\nexport interface EsbuildPluginBuild {\n initialOptions: {\n alias?: Record<string, string>;\n define?: Record<string, string>;\n minify?: boolean;\n watch?: unknown;\n /** Absolute working directory of the esbuild context (set by Angular's builder). */\n absWorkingDir?: string;\n };\n onStart(callback: () => void | Promise<void>): void;\n /** Intercept module resolution — works even for imports inside node_modules. */\n onResolve(\n options: { filter: RegExp; namespace?: string },\n callback: (args: {\n path: string;\n importer: string;\n namespace: string;\n resolveDir: string;\n }) => { path: string; namespace?: string } | null | undefined\n ): void;\n}\n\nexport interface EsbuildPlugin {\n name: string;\n setup(build: EsbuildPluginBuild): void | Promise<void>;\n}\n\nexport type IntlayerEsbuildPluginOptions = {\n configOptions?: GetConfigurationOptions;\n /**\n * Whether to start the Intlayer file watcher for dictionary regeneration.\n * - `true`: always start the watcher (useful for `ng serve`)\n * - `false`: never start the watcher (useful for `ng build`)\n * - `undefined` (default): auto-detect based on the build context\n * (skips the watcher when a production build is detected)\n */\n watch?: boolean;\n};\n\n/**\n * esbuild plugin that integrates Intlayer into the Angular (or any esbuild-based) build process.\n *\n * Handles:\n * 1. Injecting `alias` entries so `@intlayer/dictionaries-entry` etc. resolve to\n * the generated files under `.intlayer/`.\n * 2. Defining `process.env.*` tree-shaking constants for production builds.\n * 3. Running `prepareIntlayer` (dictionary generation) before the first build.\n * 4. Starting the chokidar file-watcher in dev / serve mode.\n *\n * Compatible with:\n * - `@angular-builders/custom-esbuild` (`application` or `browser-esbuild` builder)\n * - NX `@nx/angular:browser-esbuild`\n * - Any raw esbuild setup that accepts the standard `Plugin` interface\n *\n * @example\n * ```ts\n * // esbuild.plugins.ts (referenced from angular.json \"plugins\" option)\n * import { intlayerEsbuildPlugin } from 'angular-intlayer/esbuild';\n * export default [intlayerEsbuildPlugin()];\n * ```\n */\nexport const intlayerEsbuildPlugin = (\n options?: IntlayerEsbuildPluginOptions\n): EsbuildPlugin => {\n // All Node.js-heavy initialization (getConfiguration, getAlias, …) is deferred\n // into setup() so it runs in esbuild's Node.js context, not at module-evaluation\n // time. @angular/build loads the plugin file through Vite's SSR module runner\n // (ESM) where CommonJS globals like __filename are undefined. Calling\n // getConfiguration() here would trigger: buildSync → worker threads →\n // __filename → ReferenceError, crashing the plugin before setup() ever runs.\n let config: ReturnType<typeof getConfiguration> | null = null;\n let alias: Record<string, string> | null = null;\n\n // Shared across parallel setup() calls (Angular spawns one per bundle context).\n let preparePromise: Promise<void> | null = null;\n let watcherStarted = false;\n // Once any esbuild context (browser or server) detects a production build,\n // suppress the watcher for all contexts so `ng build` can exit cleanly.\n let isBuildMode = false;\n\n return {\n name: 'intlayer',\n\n async setup(build) {\n if (!config) {\n const baseDir =\n build.initialOptions.absWorkingDir ??\n options?.configOptions?.baseDir ??\n process.cwd();\n\n config = getConfiguration({ baseDir, ...options?.configOptions });\n logConfigDetails({ baseDir, ...options?.configOptions });\n\n alias = getAlias({\n configuration: config,\n formatter: (value: string) => join(config!.system.baseDir, value),\n });\n }\n\n const appLogger = getAppLogger(config);\n const nodeEnvDefine =\n build.initialOptions.define?.['process.env.NODE_ENV'];\n\n // Angular's esbuild builder doesn't set `minify` or `process.env.NODE_ENV`\n // on initialOptions — it handles optimisation through its own pipeline.\n // Instead, Angular defines `ngDevMode` as `\"false\"` in production builds.\n const isProduction =\n nodeEnvDefine === '\"production\"' ||\n nodeEnvDefine === \"'production'\" ||\n build.initialOptions.minify === true ||\n build.initialOptions.define?.['ngDevMode'] === 'false';\n\n if (isProduction) {\n isBuildMode = true;\n }\n\n const envVars: Record<string, string> = {\n INTLAYER: 'true',\n NODE_ENV: isProduction ? 'production' : 'development',\n };\n\n if (isProduction) {\n const dictionaries = getDictionaries(config);\n if (Object.keys(dictionaries).length === 0) {\n appLogger('No dictionaries found. Please check your configuration.', {\n isVerbose: true,\n });\n }\n\n const unusedNodeTypes = await getUnusedNodeTypesAsync(dictionaries);\n Object.assign(\n envVars,\n formatNodeTypeToEnvVar(unusedNodeTypes),\n getConfigEnvVars(config)\n );\n }\n\n build.initialOptions.alias = {\n ...alias,\n ...(build.initialOptions.alias ?? {}),\n };\n\n for (const [from, to] of Object.entries(alias!)) {\n const escapedFrom = from.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n build.onResolve({ filter: new RegExp(`^${escapedFrom}$`) }, () => ({\n path: to,\n }));\n }\n\n if (!preparePromise) {\n preparePromise = prepareIntlayer(config, {\n clean: isProduction,\n cacheTimeoutMs: isProduction ? 1000 * 30 : 1000 * 60 * 60,\n env: isProduction ? 'prod' : 'dev',\n });\n }\n\n await preparePromise;\n\n build.onStart(async () => {\n // Determine whether the watcher should run:\n // 1. Explicit option from the caller takes precedence\n // 2. If any esbuild context detected a production build, skip\n // 3. esbuild's own watch mode is a positive signal\n const shouldWatch = options?.watch ?? !isBuildMode;\n\n if (shouldWatch && !watcherStarted) {\n watcherStarted = true;\n\n await watch({ configuration: config! });\n }\n });\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFA,MAAa,yBACX,YACkB;CAOlB,IAAI,SAAqD;CACzD,IAAI,QAAuC;CAG3C,IAAI,iBAAuC;CAC3C,IAAI,iBAAiB;CAGrB,IAAI,cAAc;AAElB,QAAO;EACL,MAAM;EAEN,MAAM,MAAM,OAAO;AACjB,OAAI,CAAC,QAAQ;IACX,MAAM,UACJ,MAAM,eAAe,iBACrB,SAAS,eAAe,WACxB,QAAQ,KAAK;AAEf,yDAA0B;KAAE;KAAS,GAAG,SAAS;KAAe,CAAC;AACjE,+CAAiB;KAAE;KAAS,GAAG,SAAS;KAAe,CAAC;AAExD,iDAAiB;KACf,eAAe;KACf,YAAY,8BAAuB,OAAQ,OAAO,SAAS,MAAM;KAClE,CAAC;;GAGJ,MAAM,sDAAyB,OAAO;GACtC,MAAM,gBACJ,MAAM,eAAe,SAAS;GAKhC,MAAM,eACJ,kBAAkB,oBAClB,kBAAkB,kBAClB,MAAM,eAAe,WAAW,QAChC,MAAM,eAAe,SAAS,iBAAiB;AAEjD,OAAI,aACF,eAAc;GAGhB,MAAM,UAAkC;IACtC,UAAU;IACV,UAAU,eAAe,eAAe;IACzC;AAED,OAAI,cAAc;IAChB,MAAM,iEAA+B,OAAO;AAC5C,QAAI,OAAO,KAAK,aAAa,CAAC,WAAW,EACvC,WAAU,2DAA2D,EACnE,WAAW,MACZ,CAAC;IAGJ,MAAM,kBAAkB,0DAA8B,aAAa;AACnE,WAAO,OACL,8DACuB,gBAAgB,iDACtB,OAAO,CACzB;;AAGH,SAAM,eAAe,QAAQ;IAC3B,GAAG;IACH,GAAI,MAAM,eAAe,SAAS,EAAE;IACrC;AAED,QAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,MAAO,EAAE;IAC/C,MAAM,cAAc,KAAK,QAAQ,uBAAuB,OAAO;AAE/D,UAAM,UAAU,EAAE,QAAQ,IAAI,OAAO,IAAI,YAAY,GAAG,EAAE,SAAS,EACjE,MAAM,IACP,EAAE;;AAGL,OAAI,CAAC,eACH,8DAAiC,QAAQ;IACvC,OAAO;IACP,gBAAgB,eAAe,MAAO,KAAK,MAAO,KAAK;IACvD,KAAK,eAAe,SAAS;IAC9B,CAAC;AAGJ,SAAM;AAEN,SAAM,QAAQ,YAAY;AAOxB,SAFoB,SAAS,SAAS,CAAC,gBAEpB,CAAC,gBAAgB;AAClC,sBAAiB;AAEjB,+CAAY,EAAE,eAAe,QAAS,CAAC;;KAEzC;;EAEL"}
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
- let node_module = require("node:module");
4
3
  let node_path = require("node:path");
5
4
  let _intlayer_config_node = require("@intlayer/config/node");
6
5
  let _intlayer_config_utils = require("@intlayer/config/utils");
6
+ let node_module = require("node:module");
7
7
  let _intlayer_webpack = require("@intlayer/webpack");
8
8
  let defu = require("defu");
9
9
 
@@ -1,12 +1,12 @@
1
1
  import { join } from "node:path";
2
2
  import { getConfiguration } from "@intlayer/config/node";
3
3
  import { getAlias, getUnusedNodeTypesAsync } from "@intlayer/config/utils";
4
- import { prepareIntlayer } from "@intlayer/chokidar/build";
5
- import { logConfigDetails } from "@intlayer/chokidar/cli";
6
- import { watch } from "@intlayer/chokidar/watcher";
7
4
  import { formatNodeTypeToEnvVar, getConfigEnvVars } from "@intlayer/config/envVars";
8
5
  import { getAppLogger } from "@intlayer/config/logger";
9
6
  import { getDictionaries } from "@intlayer/dictionaries-entry";
7
+ import { prepareIntlayer } from "@intlayer/engine/build";
8
+ import { logConfigDetails } from "@intlayer/engine/cli";
9
+ import { watch } from "@intlayer/engine/watcher";
10
10
 
11
11
  //#region src/esbuild/plugin.ts
12
12
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","names":[],"sources":["../../../src/esbuild/plugin.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { watch } from '@intlayer/chokidar/watcher';\nimport {\n formatNodeTypeToEnvVar,\n getConfigEnvVars,\n} from '@intlayer/config/envVars';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { getAlias, getUnusedNodeTypesAsync } from '@intlayer/config/utils';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\n\n// Minimal subset of the esbuild Plugin interface to avoid a hard dependency on\n// the `esbuild` package for type resolution. The shape is compatible with\n// esbuild >=0.17, `@angular-builders/custom-esbuild`, and NX esbuild builders.\nexport interface EsbuildPluginBuild {\n initialOptions: {\n alias?: Record<string, string>;\n define?: Record<string, string>;\n minify?: boolean;\n watch?: unknown;\n /** Absolute working directory of the esbuild context (set by Angular's builder). */\n absWorkingDir?: string;\n };\n onStart(callback: () => void | Promise<void>): void;\n /** Intercept module resolution — works even for imports inside node_modules. */\n onResolve(\n options: { filter: RegExp; namespace?: string },\n callback: (args: {\n path: string;\n importer: string;\n namespace: string;\n resolveDir: string;\n }) => { path: string; namespace?: string } | null | undefined\n ): void;\n}\n\nexport interface EsbuildPlugin {\n name: string;\n setup(build: EsbuildPluginBuild): void | Promise<void>;\n}\n\nexport type IntlayerEsbuildPluginOptions = {\n configOptions?: GetConfigurationOptions;\n /**\n * Whether to start the Intlayer file watcher for dictionary regeneration.\n * - `true`: always start the watcher (useful for `ng serve`)\n * - `false`: never start the watcher (useful for `ng build`)\n * - `undefined` (default): auto-detect based on the build context\n * (skips the watcher when a production build is detected)\n */\n watch?: boolean;\n};\n\n/**\n * esbuild plugin that integrates Intlayer into the Angular (or any esbuild-based) build process.\n *\n * Handles:\n * 1. Injecting `alias` entries so `@intlayer/dictionaries-entry` etc. resolve to\n * the generated files under `.intlayer/`.\n * 2. Defining `process.env.*` tree-shaking constants for production builds.\n * 3. Running `prepareIntlayer` (dictionary generation) before the first build.\n * 4. Starting the chokidar file-watcher in dev / serve mode.\n *\n * Compatible with:\n * - `@angular-builders/custom-esbuild` (`application` or `browser-esbuild` builder)\n * - NX `@nx/angular:browser-esbuild`\n * - Any raw esbuild setup that accepts the standard `Plugin` interface\n *\n * @example\n * ```ts\n * // esbuild.plugins.ts (referenced from angular.json \"plugins\" option)\n * import { intlayerEsbuildPlugin } from 'angular-intlayer/esbuild';\n * export default [intlayerEsbuildPlugin()];\n * ```\n */\nexport const intlayerEsbuildPlugin = (\n options?: IntlayerEsbuildPluginOptions\n): EsbuildPlugin => {\n // All Node.js-heavy initialization (getConfiguration, getAlias, …) is deferred\n // into setup() so it runs in esbuild's Node.js context, not at module-evaluation\n // time. @angular/build loads the plugin file through Vite's SSR module runner\n // (ESM) where CommonJS globals like __filename are undefined. Calling\n // getConfiguration() here would trigger: buildSync → worker threads →\n // __filename → ReferenceError, crashing the plugin before setup() ever runs.\n let config: ReturnType<typeof getConfiguration> | null = null;\n let alias: Record<string, string> | null = null;\n\n // Shared across parallel setup() calls (Angular spawns one per bundle context).\n let preparePromise: Promise<void> | null = null;\n let watcherStarted = false;\n // Once any esbuild context (browser or server) detects a production build,\n // suppress the watcher for all contexts so `ng build` can exit cleanly.\n let isBuildMode = false;\n\n return {\n name: 'intlayer',\n\n async setup(build) {\n if (!config) {\n const baseDir =\n build.initialOptions.absWorkingDir ??\n options?.configOptions?.baseDir ??\n process.cwd();\n\n config = getConfiguration({ baseDir, ...options?.configOptions });\n logConfigDetails({ baseDir, ...options?.configOptions });\n\n alias = getAlias({\n configuration: config,\n formatter: (value: string) => join(config!.system.baseDir, value),\n });\n }\n\n const appLogger = getAppLogger(config);\n const nodeEnvDefine =\n build.initialOptions.define?.['process.env.NODE_ENV'];\n\n // Angular's esbuild builder doesn't set `minify` or `process.env.NODE_ENV`\n // on initialOptions — it handles optimisation through its own pipeline.\n // Instead, Angular defines `ngDevMode` as `\"false\"` in production builds.\n const isProduction =\n nodeEnvDefine === '\"production\"' ||\n nodeEnvDefine === \"'production'\" ||\n build.initialOptions.minify === true ||\n build.initialOptions.define?.['ngDevMode'] === 'false';\n\n if (isProduction) {\n isBuildMode = true;\n }\n\n const envVars: Record<string, string> = {\n INTLAYER: 'true',\n NODE_ENV: isProduction ? 'production' : 'development',\n };\n\n if (isProduction) {\n const dictionaries = getDictionaries(config);\n if (Object.keys(dictionaries).length === 0) {\n appLogger('No dictionaries found. Please check your configuration.', {\n isVerbose: true,\n });\n }\n\n const unusedNodeTypes = await getUnusedNodeTypesAsync(dictionaries);\n Object.assign(\n envVars,\n formatNodeTypeToEnvVar(unusedNodeTypes),\n getConfigEnvVars(config)\n );\n }\n\n build.initialOptions.alias = {\n ...alias,\n ...(build.initialOptions.alias ?? {}),\n };\n\n for (const [from, to] of Object.entries(alias!)) {\n const escapedFrom = from.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n build.onResolve({ filter: new RegExp(`^${escapedFrom}$`) }, () => ({\n path: to,\n }));\n }\n\n if (!preparePromise) {\n preparePromise = prepareIntlayer(config, {\n clean: isProduction,\n cacheTimeoutMs: isProduction ? 1000 * 30 : 1000 * 60 * 60,\n env: isProduction ? 'prod' : 'dev',\n });\n }\n\n await preparePromise;\n\n build.onStart(async () => {\n // Determine whether the watcher should run:\n // 1. Explicit option from the caller takes precedence\n // 2. If any esbuild context detected a production build, skip\n // 3. esbuild's own watch mode is a positive signal\n const shouldWatch = options?.watch ?? !isBuildMode;\n\n if (shouldWatch && !watcherStarted) {\n watcherStarted = true;\n\n await watch({ configuration: config! });\n }\n });\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFA,MAAa,yBACX,YACkB;CAOlB,IAAI,SAAqD;CACzD,IAAI,QAAuC;CAG3C,IAAI,iBAAuC;CAC3C,IAAI,iBAAiB;CAGrB,IAAI,cAAc;AAElB,QAAO;EACL,MAAM;EAEN,MAAM,MAAM,OAAO;AACjB,OAAI,CAAC,QAAQ;IACX,MAAM,UACJ,MAAM,eAAe,iBACrB,SAAS,eAAe,WACxB,QAAQ,KAAK;AAEf,aAAS,iBAAiB;KAAE;KAAS,GAAG,SAAS;KAAe,CAAC;AACjE,qBAAiB;KAAE;KAAS,GAAG,SAAS;KAAe,CAAC;AAExD,YAAQ,SAAS;KACf,eAAe;KACf,YAAY,UAAkB,KAAK,OAAQ,OAAO,SAAS,MAAM;KAClE,CAAC;;GAGJ,MAAM,YAAY,aAAa,OAAO;GACtC,MAAM,gBACJ,MAAM,eAAe,SAAS;GAKhC,MAAM,eACJ,kBAAkB,oBAClB,kBAAkB,kBAClB,MAAM,eAAe,WAAW,QAChC,MAAM,eAAe,SAAS,iBAAiB;AAEjD,OAAI,aACF,eAAc;GAGhB,MAAM,UAAkC;IACtC,UAAU;IACV,UAAU,eAAe,eAAe;IACzC;AAED,OAAI,cAAc;IAChB,MAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAI,OAAO,KAAK,aAAa,CAAC,WAAW,EACvC,WAAU,2DAA2D,EACnE,WAAW,MACZ,CAAC;IAGJ,MAAM,kBAAkB,MAAM,wBAAwB,aAAa;AACnE,WAAO,OACL,SACA,uBAAuB,gBAAgB,EACvC,iBAAiB,OAAO,CACzB;;AAGH,SAAM,eAAe,QAAQ;IAC3B,GAAG;IACH,GAAI,MAAM,eAAe,SAAS,EAAE;IACrC;AAED,QAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,MAAO,EAAE;IAC/C,MAAM,cAAc,KAAK,QAAQ,uBAAuB,OAAO;AAE/D,UAAM,UAAU,EAAE,QAAQ,IAAI,OAAO,IAAI,YAAY,GAAG,EAAE,SAAS,EACjE,MAAM,IACP,EAAE;;AAGL,OAAI,CAAC,eACH,kBAAiB,gBAAgB,QAAQ;IACvC,OAAO;IACP,gBAAgB,eAAe,MAAO,KAAK,MAAO,KAAK;IACvD,KAAK,eAAe,SAAS;IAC9B,CAAC;AAGJ,SAAM;AAEN,SAAM,QAAQ,YAAY;AAOxB,SAFoB,SAAS,SAAS,CAAC,gBAEpB,CAAC,gBAAgB;AAClC,sBAAiB;AAEjB,WAAM,MAAM,EAAE,eAAe,QAAS,CAAC;;KAEzC;;EAEL"}
1
+ {"version":3,"file":"plugin.mjs","names":[],"sources":["../../../src/esbuild/plugin.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport {\n formatNodeTypeToEnvVar,\n getConfigEnvVars,\n} from '@intlayer/config/envVars';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { getAlias, getUnusedNodeTypesAsync } from '@intlayer/config/utils';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { prepareIntlayer } from '@intlayer/engine/build';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport { watch } from '@intlayer/engine/watcher';\n\n// Minimal subset of the esbuild Plugin interface to avoid a hard dependency on\n// the `esbuild` package for type resolution. The shape is compatible with\n// esbuild >=0.17, `@angular-builders/custom-esbuild`, and NX esbuild builders.\nexport interface EsbuildPluginBuild {\n initialOptions: {\n alias?: Record<string, string>;\n define?: Record<string, string>;\n minify?: boolean;\n watch?: unknown;\n /** Absolute working directory of the esbuild context (set by Angular's builder). */\n absWorkingDir?: string;\n };\n onStart(callback: () => void | Promise<void>): void;\n /** Intercept module resolution — works even for imports inside node_modules. */\n onResolve(\n options: { filter: RegExp; namespace?: string },\n callback: (args: {\n path: string;\n importer: string;\n namespace: string;\n resolveDir: string;\n }) => { path: string; namespace?: string } | null | undefined\n ): void;\n}\n\nexport interface EsbuildPlugin {\n name: string;\n setup(build: EsbuildPluginBuild): void | Promise<void>;\n}\n\nexport type IntlayerEsbuildPluginOptions = {\n configOptions?: GetConfigurationOptions;\n /**\n * Whether to start the Intlayer file watcher for dictionary regeneration.\n * - `true`: always start the watcher (useful for `ng serve`)\n * - `false`: never start the watcher (useful for `ng build`)\n * - `undefined` (default): auto-detect based on the build context\n * (skips the watcher when a production build is detected)\n */\n watch?: boolean;\n};\n\n/**\n * esbuild plugin that integrates Intlayer into the Angular (or any esbuild-based) build process.\n *\n * Handles:\n * 1. Injecting `alias` entries so `@intlayer/dictionaries-entry` etc. resolve to\n * the generated files under `.intlayer/`.\n * 2. Defining `process.env.*` tree-shaking constants for production builds.\n * 3. Running `prepareIntlayer` (dictionary generation) before the first build.\n * 4. Starting the chokidar file-watcher in dev / serve mode.\n *\n * Compatible with:\n * - `@angular-builders/custom-esbuild` (`application` or `browser-esbuild` builder)\n * - NX `@nx/angular:browser-esbuild`\n * - Any raw esbuild setup that accepts the standard `Plugin` interface\n *\n * @example\n * ```ts\n * // esbuild.plugins.ts (referenced from angular.json \"plugins\" option)\n * import { intlayerEsbuildPlugin } from 'angular-intlayer/esbuild';\n * export default [intlayerEsbuildPlugin()];\n * ```\n */\nexport const intlayerEsbuildPlugin = (\n options?: IntlayerEsbuildPluginOptions\n): EsbuildPlugin => {\n // All Node.js-heavy initialization (getConfiguration, getAlias, …) is deferred\n // into setup() so it runs in esbuild's Node.js context, not at module-evaluation\n // time. @angular/build loads the plugin file through Vite's SSR module runner\n // (ESM) where CommonJS globals like __filename are undefined. Calling\n // getConfiguration() here would trigger: buildSync → worker threads →\n // __filename → ReferenceError, crashing the plugin before setup() ever runs.\n let config: ReturnType<typeof getConfiguration> | null = null;\n let alias: Record<string, string> | null = null;\n\n // Shared across parallel setup() calls (Angular spawns one per bundle context).\n let preparePromise: Promise<void> | null = null;\n let watcherStarted = false;\n // Once any esbuild context (browser or server) detects a production build,\n // suppress the watcher for all contexts so `ng build` can exit cleanly.\n let isBuildMode = false;\n\n return {\n name: 'intlayer',\n\n async setup(build) {\n if (!config) {\n const baseDir =\n build.initialOptions.absWorkingDir ??\n options?.configOptions?.baseDir ??\n process.cwd();\n\n config = getConfiguration({ baseDir, ...options?.configOptions });\n logConfigDetails({ baseDir, ...options?.configOptions });\n\n alias = getAlias({\n configuration: config,\n formatter: (value: string) => join(config!.system.baseDir, value),\n });\n }\n\n const appLogger = getAppLogger(config);\n const nodeEnvDefine =\n build.initialOptions.define?.['process.env.NODE_ENV'];\n\n // Angular's esbuild builder doesn't set `minify` or `process.env.NODE_ENV`\n // on initialOptions — it handles optimisation through its own pipeline.\n // Instead, Angular defines `ngDevMode` as `\"false\"` in production builds.\n const isProduction =\n nodeEnvDefine === '\"production\"' ||\n nodeEnvDefine === \"'production'\" ||\n build.initialOptions.minify === true ||\n build.initialOptions.define?.['ngDevMode'] === 'false';\n\n if (isProduction) {\n isBuildMode = true;\n }\n\n const envVars: Record<string, string> = {\n INTLAYER: 'true',\n NODE_ENV: isProduction ? 'production' : 'development',\n };\n\n if (isProduction) {\n const dictionaries = getDictionaries(config);\n if (Object.keys(dictionaries).length === 0) {\n appLogger('No dictionaries found. Please check your configuration.', {\n isVerbose: true,\n });\n }\n\n const unusedNodeTypes = await getUnusedNodeTypesAsync(dictionaries);\n Object.assign(\n envVars,\n formatNodeTypeToEnvVar(unusedNodeTypes),\n getConfigEnvVars(config)\n );\n }\n\n build.initialOptions.alias = {\n ...alias,\n ...(build.initialOptions.alias ?? {}),\n };\n\n for (const [from, to] of Object.entries(alias!)) {\n const escapedFrom = from.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n build.onResolve({ filter: new RegExp(`^${escapedFrom}$`) }, () => ({\n path: to,\n }));\n }\n\n if (!preparePromise) {\n preparePromise = prepareIntlayer(config, {\n clean: isProduction,\n cacheTimeoutMs: isProduction ? 1000 * 30 : 1000 * 60 * 60,\n env: isProduction ? 'prod' : 'dev',\n });\n }\n\n await preparePromise;\n\n build.onStart(async () => {\n // Determine whether the watcher should run:\n // 1. Explicit option from the caller takes precedence\n // 2. If any esbuild context detected a production build, skip\n // 3. esbuild's own watch mode is a positive signal\n const shouldWatch = options?.watch ?? !isBuildMode;\n\n if (shouldWatch && !watcherStarted) {\n watcherStarted = true;\n\n await watch({ configuration: config! });\n }\n });\n },\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFA,MAAa,yBACX,YACkB;CAOlB,IAAI,SAAqD;CACzD,IAAI,QAAuC;CAG3C,IAAI,iBAAuC;CAC3C,IAAI,iBAAiB;CAGrB,IAAI,cAAc;AAElB,QAAO;EACL,MAAM;EAEN,MAAM,MAAM,OAAO;AACjB,OAAI,CAAC,QAAQ;IACX,MAAM,UACJ,MAAM,eAAe,iBACrB,SAAS,eAAe,WACxB,QAAQ,KAAK;AAEf,aAAS,iBAAiB;KAAE;KAAS,GAAG,SAAS;KAAe,CAAC;AACjE,qBAAiB;KAAE;KAAS,GAAG,SAAS;KAAe,CAAC;AAExD,YAAQ,SAAS;KACf,eAAe;KACf,YAAY,UAAkB,KAAK,OAAQ,OAAO,SAAS,MAAM;KAClE,CAAC;;GAGJ,MAAM,YAAY,aAAa,OAAO;GACtC,MAAM,gBACJ,MAAM,eAAe,SAAS;GAKhC,MAAM,eACJ,kBAAkB,oBAClB,kBAAkB,kBAClB,MAAM,eAAe,WAAW,QAChC,MAAM,eAAe,SAAS,iBAAiB;AAEjD,OAAI,aACF,eAAc;GAGhB,MAAM,UAAkC;IACtC,UAAU;IACV,UAAU,eAAe,eAAe;IACzC;AAED,OAAI,cAAc;IAChB,MAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAI,OAAO,KAAK,aAAa,CAAC,WAAW,EACvC,WAAU,2DAA2D,EACnE,WAAW,MACZ,CAAC;IAGJ,MAAM,kBAAkB,MAAM,wBAAwB,aAAa;AACnE,WAAO,OACL,SACA,uBAAuB,gBAAgB,EACvC,iBAAiB,OAAO,CACzB;;AAGH,SAAM,eAAe,QAAQ;IAC3B,GAAG;IACH,GAAI,MAAM,eAAe,SAAS,EAAE;IACrC;AAED,QAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,MAAO,EAAE;IAC/C,MAAM,cAAc,KAAK,QAAQ,uBAAuB,OAAO;AAE/D,UAAM,UAAU,EAAE,QAAQ,IAAI,OAAO,IAAI,YAAY,GAAG,EAAE,SAAS,EACjE,MAAM,IACP,EAAE;;AAGL,OAAI,CAAC,eACH,kBAAiB,gBAAgB,QAAQ;IACvC,OAAO;IACP,gBAAgB,eAAe,MAAO,KAAK,MAAO,KAAK;IACvD,KAAK,eAAe,SAAS;IAC9B,CAAC;AAGJ,SAAM;AAEN,SAAM,QAAQ,YAAY;AAOxB,SAFoB,SAAS,SAAS,CAAC,gBAEpB,CAAC,gBAAgB;AAClC,sBAAiB;AAEjB,WAAM,MAAM,EAAE,eAAe,QAAS,CAAC;;KAEzC;;EAEL"}
@@ -0,0 +1,4 @@
1
+ import { LocalesValues as LocalesValues$1 } from "@intlayer/types/module_augmentation";
2
+ import { Dictionary } from "@intlayer/types/dictionary";
3
+ import { Locale } from "@intlayer/types/allLocales";
4
+ export { type Locale, type LocalesValues$1 as LocalesValues };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "angular-intlayer",
3
- "version": "9.0.0-canary.10",
3
+ "version": "9.0.0-canary.12",
4
4
  "private": false,
5
5
  "description": "Easily internationalize i18n your Angular applications with type-safe multilingual content management.",
6
6
  "keywords": [
@@ -119,13 +119,13 @@
119
119
  "@babel/core": "^7.26.9",
120
120
  "@babel/plugin-syntax-import-attributes": "7.28.6",
121
121
  "@babel/preset-env": "7.29.2",
122
- "@intlayer/chokidar": "9.0.0-canary.10",
123
- "@intlayer/config": "9.0.0-canary.10",
124
- "@intlayer/core": "9.0.0-canary.10",
125
- "@intlayer/dictionaries-entry": "9.0.0-canary.10",
126
- "@intlayer/editor": "9.0.0-canary.10",
127
- "@intlayer/types": "9.0.0-canary.10",
128
- "@intlayer/webpack": "9.0.0-canary.10",
122
+ "@intlayer/config": "9.0.0-canary.12",
123
+ "@intlayer/core": "9.0.0-canary.12",
124
+ "@intlayer/dictionaries-entry": "9.0.0-canary.12",
125
+ "@intlayer/editor": "9.0.0-canary.12",
126
+ "@intlayer/engine": "9.0.0-canary.12",
127
+ "@intlayer/types": "9.0.0-canary.12",
128
+ "@intlayer/webpack": "9.0.0-canary.12",
129
129
  "babel-loader": "10.1.1",
130
130
  "defu": "6.1.7"
131
131
  },