@angular/build 22.2.0-next.4 → 22.2.0-next.6
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.
- package/package.json +13 -12
- package/src/builders/application/build-action.js +47 -39
- package/src/builders/application/build-action.js.map +1 -1
- package/src/builders/application/execute-build.js +1 -1
- package/src/builders/application/execute-build.js.map +1 -1
- package/src/builders/application/execute-post-bundle.js +2 -5
- package/src/builders/application/execute-post-bundle.js.map +1 -1
- package/src/builders/application/i18n.js +20 -10
- package/src/builders/application/i18n.js.map +1 -1
- package/src/builders/application/index.js +2 -2
- package/src/builders/application/index.js.map +1 -1
- package/src/builders/application/results.d.ts +3 -2
- package/src/builders/application/setup-bundling.js +3 -1
- package/src/builders/application/setup-bundling.js.map +1 -1
- package/src/builders/dev-server/vite/index.js +4 -7
- package/src/builders/dev-server/vite/index.js.map +1 -1
- package/src/builders/dev-server/vite/server.js +1 -1
- package/src/builders/dev-server/vite/server.js.map +1 -1
- package/src/builders/dev-server/vite/utils.d.ts +1 -1
- package/src/builders/dev-server/vite/utils.js +9 -4
- package/src/builders/dev-server/vite/utils.js.map +1 -1
- package/src/builders/extract-i18n/application-extraction.js +6 -5
- package/src/builders/extract-i18n/application-extraction.js.map +1 -1
- package/src/builders/karma/application_builder.js +1 -1
- package/src/builders/karma/application_builder.js.map +1 -1
- package/src/builders/karma/assets-middleware.d.ts +2 -2
- package/src/builders/karma/assets-middleware.js +5 -2
- package/src/builders/karma/assets-middleware.js.map +1 -1
- package/src/builders/karma/progress-reporter.js +7 -5
- package/src/builders/karma/progress-reporter.js.map +1 -1
- package/src/builders/karma/utils.d.ts +2 -1
- package/src/builders/karma/utils.js +2 -2
- package/src/builders/karma/utils.js.map +1 -1
- package/src/builders/unit-test/builder.js +1 -1
- package/src/builders/unit-test/options.d.ts +1 -0
- package/src/builders/unit-test/options.js +2 -1
- package/src/builders/unit-test/options.js.map +1 -1
- package/src/builders/unit-test/runners/vitest/build-options.js +5 -6
- package/src/builders/unit-test/runners/vitest/build-options.js.map +1 -1
- package/src/builders/unit-test/runners/vitest/executor.js +4 -4
- package/src/builders/unit-test/runners/vitest/executor.js.map +1 -1
- package/src/builders/unit-test/schema.d.ts +7 -0
- package/src/builders/unit-test/schema.js.map +1 -1
- package/src/builders/unit-test/schema.json +5 -0
- package/src/private.d.ts +1 -1
- package/src/private.js +4 -3
- package/src/private.js.map +1 -1
- package/src/tools/angular/compilation/angular-compilation.d.ts +3 -8
- package/src/tools/angular/compilation/angular-compilation.js +2 -88
- package/src/tools/angular/compilation/angular-compilation.js.map +1 -1
- package/src/tools/angular/compilation/aot-compilation.d.ts +5 -5
- package/src/tools/angular/compilation/aot-compilation.js +9 -13
- package/src/tools/angular/compilation/aot-compilation.js.map +1 -1
- package/src/tools/angular/compilation/compiler-options.d.ts +24 -0
- package/src/tools/angular/compilation/compiler-options.js +135 -0
- package/src/tools/angular/compilation/compiler-options.js.map +1 -0
- package/src/tools/angular/compilation/index.d.ts +1 -1
- package/src/tools/angular/compilation/index.js +1 -3
- package/src/tools/angular/compilation/index.js.map +1 -1
- package/src/tools/angular/compilation/jit-compilation.d.ts +5 -5
- package/src/tools/angular/compilation/jit-compilation.js +8 -15
- package/src/tools/angular/compilation/jit-compilation.js.map +1 -1
- package/src/tools/angular/compilation/parallel-compilation.d.ts +2 -7
- package/src/tools/angular/compilation/parallel-compilation.js +39 -41
- package/src/tools/angular/compilation/parallel-compilation.js.map +1 -1
- package/src/tools/angular/compilation/parallel-worker.d.ts +2 -2
- package/src/tools/angular/compilation/parallel-worker.js +79 -63
- package/src/tools/angular/compilation/parallel-worker.js.map +1 -1
- package/src/tools/angular/compilation/typescript-compilation.d.ts +24 -0
- package/src/tools/angular/compilation/typescript-compilation.js +107 -0
- package/src/tools/angular/compilation/typescript-compilation.js.map +1 -0
- package/src/tools/angular/linker/oxc-linker.d.ts +13 -17
- package/src/tools/angular/linker/oxc-linker.js +27 -89
- package/src/tools/angular/linker/oxc-linker.js.map +1 -1
- package/src/tools/esbuild/angular/compilation-state.d.ts +23 -3
- package/src/tools/esbuild/angular/compilation-state.js +51 -13
- package/src/tools/esbuild/angular/compilation-state.js.map +1 -1
- package/src/tools/esbuild/angular/compiler-plugin.js +36 -101
- package/src/tools/esbuild/angular/compiler-plugin.js.map +1 -1
- package/src/tools/esbuild/angular/component-stylesheets.d.ts +3 -3
- package/src/tools/esbuild/angular/component-stylesheets.js +42 -15
- package/src/tools/esbuild/angular/component-stylesheets.js.map +1 -1
- package/src/tools/esbuild/application-code-bundle.js +5 -9
- package/src/tools/esbuild/application-code-bundle.js.map +1 -1
- package/src/tools/esbuild/bundler-context.d.ts +4 -4
- package/src/tools/esbuild/bundler-context.js +93 -27
- package/src/tools/esbuild/bundler-context.js.map +1 -1
- package/src/tools/esbuild/bundler-execution-result.d.ts +1 -0
- package/src/tools/esbuild/bundler-execution-result.js +2 -2
- package/src/tools/esbuild/bundler-execution-result.js.map +1 -1
- package/src/tools/esbuild/cache.d.ts +10 -0
- package/src/tools/esbuild/cache.js +18 -0
- package/src/tools/esbuild/cache.js.map +1 -1
- package/src/tools/esbuild/i18n-inliner-worker.d.ts +82 -37
- package/src/tools/esbuild/i18n-inliner-worker.js +134 -97
- package/src/tools/esbuild/i18n-inliner-worker.js.map +1 -1
- package/src/tools/esbuild/i18n-inliner.d.ts +42 -11
- package/src/tools/esbuild/i18n-inliner.js +335 -121
- package/src/tools/esbuild/i18n-inliner.js.map +1 -1
- package/src/tools/esbuild/i18n-locale-plugin.d.ts +32 -0
- package/src/tools/esbuild/i18n-locale-plugin.js +112 -103
- package/src/tools/esbuild/i18n-locale-plugin.js.map +1 -1
- package/src/tools/esbuild/i18n-translation-encoder.d.ts +21 -0
- package/src/tools/esbuild/i18n-translation-encoder.js +92 -0
- package/src/tools/esbuild/i18n-translation-encoder.js.map +1 -0
- package/src/tools/esbuild/i18n-translation-reader.d.ts +41 -0
- package/src/tools/esbuild/i18n-translation-reader.js +164 -0
- package/src/tools/esbuild/i18n-translation-reader.js.map +1 -0
- package/src/tools/esbuild/javascript-transformer-worker.js +41 -47
- package/src/tools/esbuild/javascript-transformer-worker.js.map +1 -1
- package/src/tools/esbuild/javascript-transformer.js +53 -1
- package/src/tools/esbuild/javascript-transformer.js.map +1 -1
- package/src/tools/esbuild/load-result-cache.d.ts +1 -0
- package/src/tools/esbuild/load-result-cache.js +24 -11
- package/src/tools/esbuild/load-result-cache.js.map +1 -1
- package/src/tools/esbuild/sqlite-cache-store.d.ts +8 -0
- package/src/tools/esbuild/sqlite-cache-store.js +19 -7
- package/src/tools/esbuild/sqlite-cache-store.js.map +1 -1
- package/src/tools/esbuild/stylesheets/sass-language.js +19 -14
- package/src/tools/esbuild/stylesheets/sass-language.js.map +1 -1
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.d.ts +1 -1
- package/src/tools/esbuild/utils.d.ts +1 -1
- package/src/tools/esbuild/utils.js.map +1 -1
- package/src/tools/oxc/oxc-transform.d.ts +3 -0
- package/src/tools/oxc/oxc-transform.js +103 -124
- package/src/tools/oxc/oxc-transform.js.map +1 -1
- package/src/tools/oxc/traversal.d.ts +32 -0
- package/src/tools/oxc/traversal.js +299 -0
- package/src/tools/oxc/traversal.js.map +1 -0
- package/src/tools/sass/rebasing-importer.d.ts +8 -14
- package/src/tools/sass/rebasing-importer.js +18 -24
- package/src/tools/sass/rebasing-importer.js.map +1 -1
- package/src/tools/sass/sass-service.d.ts +11 -38
- package/src/tools/sass/sass-service.js +124 -187
- package/src/tools/sass/sass-service.js.map +1 -1
- package/src/utils/environment-options.d.ts +12 -0
- package/src/utils/environment-options.js +20 -12
- package/src/utils/environment-options.js.map +1 -1
- package/src/utils/i18n-options.d.ts +2 -1
- package/src/utils/i18n-options.js.map +1 -1
- package/src/utils/normalize-cache.d.ts +11 -1
- package/src/utils/normalize-cache.js +6 -3
- package/src/utils/normalize-cache.js.map +1 -1
- package/src/utils/purge-cache.js +24 -13
- package/src/utils/purge-cache.js.map +1 -1
- package/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.d.ts +1 -1
- package/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.js +12 -9
- package/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.js.map +1 -1
- package/src/utils/server-rendering/esm-in-memory-loader/utils.d.ts +8 -0
- package/src/utils/server-rendering/esm-in-memory-loader/utils.js +30 -0
- package/src/utils/server-rendering/esm-in-memory-loader/utils.js.map +1 -1
- package/src/utils/server-rendering/prerender.d.ts +2 -1
- package/src/utils/server-rendering/prerender.js +83 -30
- package/src/utils/server-rendering/prerender.js.map +1 -1
- package/src/utils/server-rendering/render-worker.d.ts +10 -5
- package/src/utils/server-rendering/render-worker.js +31 -7
- package/src/utils/server-rendering/render-worker.js.map +1 -1
- package/src/utils/test-files.d.ts +2 -2
- package/src/utils/test-files.js +3 -3
- package/src/utils/test-files.js.map +1 -1
- package/src/tools/angular/compilation/noop-compilation.d.ts +0 -15
- package/src/tools/angular/compilation/noop-compilation.js +0 -27
- package/src/tools/angular/compilation/noop-compilation.js.map +0 -1
- package/src/tools/sass/worker.d.ts +0 -63
- package/src/tools/sass/worker.js +0 -202
- package/src/tools/sass/worker.js.map +0 -1
- /package/src/tools/{esbuild/angular → angular/compilation}/diagnostics.d.ts +0 -0
- /package/src/tools/{esbuild/angular → angular/compilation}/diagnostics.js +0 -0
- /package/src/tools/{esbuild/angular → angular/compilation}/diagnostics.js.map +0 -0
|
@@ -14,6 +14,38 @@ export declare const LOCALE_DATA_NAMESPACE = "angular:locale/data";
|
|
|
14
14
|
* The base module location used to search for locale specific data.
|
|
15
15
|
*/
|
|
16
16
|
export declare const LOCALE_DATA_BASE_MODULE = "@angular/common/locales/global";
|
|
17
|
+
/**
|
|
18
|
+
* Result of resolving locale data for a given locale tag.
|
|
19
|
+
*/
|
|
20
|
+
export interface LocaleDataResolution {
|
|
21
|
+
path?: string;
|
|
22
|
+
warning?: string;
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Result of loading locale data for a given locale tag.
|
|
27
|
+
*/
|
|
28
|
+
export interface LoadedLocaleData {
|
|
29
|
+
code?: string;
|
|
30
|
+
warning?: string;
|
|
31
|
+
error?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolves the path to the Angular locale data file for a given locale tag.
|
|
35
|
+
*
|
|
36
|
+
* @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US").
|
|
37
|
+
* @param projectResolve A function that attempts to resolve a path string to an absolute file path.
|
|
38
|
+
* @returns Resolution result with file path, or warning/error diagnostics if applicable.
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveLocaleDataPath(rawLocaleTag: string, projectResolve: (potentialPath: string) => string | undefined): LocaleDataResolution;
|
|
41
|
+
/**
|
|
42
|
+
* Loads the Angular global locale data script for a specified locale tag.
|
|
43
|
+
*
|
|
44
|
+
* @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US").
|
|
45
|
+
* @param projectRoot Optional project root for module resolution.
|
|
46
|
+
* @returns A promise resolving to the loaded locale data script code and any diagnostic warnings.
|
|
47
|
+
*/
|
|
48
|
+
export declare function loadLocaleData(rawLocaleTag: string, projectRoot?: string): Promise<LoadedLocaleData>;
|
|
17
49
|
/**
|
|
18
50
|
* Creates an esbuild plugin that resolves Angular locale data files from `@angular/common`.
|
|
19
51
|
*
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.LOCALE_DATA_BASE_MODULE = exports.LOCALE_DATA_NAMESPACE = void 0;
|
|
11
|
+
exports.resolveLocaleDataPath = resolveLocaleDataPath;
|
|
12
|
+
exports.loadLocaleData = loadLocaleData;
|
|
11
13
|
exports.createAngularLocaleDataPlugin = createAngularLocaleDataPlugin;
|
|
14
|
+
const promises_1 = require("node:fs/promises");
|
|
12
15
|
const resolve_project_1 = require("../../utils/resolve-project");
|
|
13
16
|
/**
|
|
14
17
|
* The internal namespace used by generated locale import statements and Angular locale data plugin.
|
|
@@ -18,6 +21,91 @@ exports.LOCALE_DATA_NAMESPACE = 'angular:locale/data';
|
|
|
18
21
|
* The base module location used to search for locale specific data.
|
|
19
22
|
*/
|
|
20
23
|
exports.LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global';
|
|
24
|
+
const localeDataCache = new Map();
|
|
25
|
+
/**
|
|
26
|
+
* Resolves the path to the Angular locale data file for a given locale tag.
|
|
27
|
+
*
|
|
28
|
+
* @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US").
|
|
29
|
+
* @param projectResolve A function that attempts to resolve a path string to an absolute file path.
|
|
30
|
+
* @returns Resolution result with file path, or warning/error diagnostics if applicable.
|
|
31
|
+
*/
|
|
32
|
+
function resolveLocaleDataPath(rawLocaleTag, projectResolve) {
|
|
33
|
+
let partialLocaleTag;
|
|
34
|
+
try {
|
|
35
|
+
const locale = new Intl.Locale(rawLocaleTag);
|
|
36
|
+
partialLocaleTag = locale.baseName;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {
|
|
40
|
+
error: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
let exact = true;
|
|
44
|
+
while (partialLocaleTag) {
|
|
45
|
+
// Angular embeds the `en`/`en-US` locale into the framework and it does not need to be included again here.
|
|
46
|
+
if (partialLocaleTag === 'en' || partialLocaleTag === 'en-US') {
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
const potentialPath = `${exports.LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`;
|
|
50
|
+
try {
|
|
51
|
+
const resolvedPath = projectResolve(potentialPath);
|
|
52
|
+
if (resolvedPath) {
|
|
53
|
+
return {
|
|
54
|
+
path: resolvedPath,
|
|
55
|
+
warning: exact
|
|
56
|
+
? undefined
|
|
57
|
+
: `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch { }
|
|
62
|
+
// Remove the last subtag and try again with a less specific locale.
|
|
63
|
+
const parts = partialLocaleTag.split('-');
|
|
64
|
+
partialLocaleTag = parts.slice(0, -1).join('-');
|
|
65
|
+
exact = false;
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
warning: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Loads the Angular global locale data script for a specified locale tag.
|
|
73
|
+
*
|
|
74
|
+
* @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US").
|
|
75
|
+
* @param projectRoot Optional project root for module resolution.
|
|
76
|
+
* @returns A promise resolving to the loaded locale data script code and any diagnostic warnings.
|
|
77
|
+
*/
|
|
78
|
+
function loadLocaleData(rawLocaleTag, projectRoot) {
|
|
79
|
+
let cached = localeDataCache.get(rawLocaleTag);
|
|
80
|
+
if (!cached) {
|
|
81
|
+
cached = (async () => {
|
|
82
|
+
const projectResolve = (0, resolve_project_1.createProjectResolver)(projectRoot ?? process.cwd());
|
|
83
|
+
const resolution = resolveLocaleDataPath(rawLocaleTag, (potentialPath) => {
|
|
84
|
+
try {
|
|
85
|
+
return projectResolve(potentialPath);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
if (resolution.error) {
|
|
92
|
+
return { error: resolution.error };
|
|
93
|
+
}
|
|
94
|
+
if (resolution.path) {
|
|
95
|
+
try {
|
|
96
|
+
const code = await (0, promises_1.readFile)(resolution.path, 'utf8');
|
|
97
|
+
return { code, warning: resolution.warning };
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
return { error: `Failed to read locale data file: ${e.message}` };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { warning: resolution.warning };
|
|
104
|
+
})();
|
|
105
|
+
localeDataCache.set(rawLocaleTag, cached);
|
|
106
|
+
}
|
|
107
|
+
return cached;
|
|
108
|
+
}
|
|
21
109
|
/**
|
|
22
110
|
* Creates an esbuild plugin that resolves Angular locale data files from `@angular/common`.
|
|
23
111
|
*
|
|
@@ -28,119 +116,40 @@ function createAngularLocaleDataPlugin() {
|
|
|
28
116
|
name: 'angular-locale-data',
|
|
29
117
|
setup(build) {
|
|
30
118
|
build.onResolve({ filter: /^angular:locale\/data:/ }, async ({ path }) => {
|
|
31
|
-
// Extract the locale from the path
|
|
32
119
|
const rawLocaleTag = path.split(':', 3)[2];
|
|
33
|
-
|
|
34
|
-
let
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
120
|
+
const { absWorkingDir } = build.initialOptions;
|
|
121
|
+
let projectResolve;
|
|
122
|
+
const resolution = resolveLocaleDataPath(rawLocaleTag, (potentialPath) => {
|
|
123
|
+
projectResolve ??= (0, resolve_project_1.createProjectResolver)(absWorkingDir ?? process.cwd());
|
|
124
|
+
try {
|
|
125
|
+
return projectResolve(potentialPath);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
if (resolution.error) {
|
|
40
132
|
return {
|
|
41
133
|
path: rawLocaleTag,
|
|
42
134
|
namespace: exports.LOCALE_DATA_NAMESPACE,
|
|
43
|
-
errors: [
|
|
44
|
-
{
|
|
45
|
-
text: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`,
|
|
46
|
-
},
|
|
47
|
-
],
|
|
135
|
+
errors: [{ text: resolution.error }],
|
|
48
136
|
};
|
|
49
137
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
path: rawLocaleTag,
|
|
59
|
-
namespace: exports.LOCALE_DATA_NAMESPACE,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
// Attempt to resolve the locale tag data within the Angular base module location
|
|
63
|
-
const potentialPath = `${exports.LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`;
|
|
64
|
-
// If packages are configured to be external then leave the original angular locale import path.
|
|
65
|
-
// This happens when using the development server with caching enabled to allow Vite prebundling to work.
|
|
66
|
-
// There currently is no option on the esbuild resolve function to resolve while disabling the option.
|
|
67
|
-
// NOTE: If esbuild eventually allows controlling the external package options in a build.resolve call, this
|
|
68
|
-
// workaround can be removed.
|
|
69
|
-
let result;
|
|
70
|
-
const { packages, absWorkingDir } = build.initialOptions;
|
|
71
|
-
if (packages === 'external' && absWorkingDir) {
|
|
72
|
-
projectResolve ??= (0, resolve_project_1.createProjectResolver)(absWorkingDir);
|
|
73
|
-
try {
|
|
74
|
-
projectResolve(potentialPath);
|
|
75
|
-
result = {
|
|
76
|
-
errors: [],
|
|
77
|
-
warnings: [],
|
|
78
|
-
external: true,
|
|
79
|
-
sideEffects: true,
|
|
80
|
-
namespace: '',
|
|
81
|
-
suffix: '',
|
|
82
|
-
pluginData: undefined,
|
|
83
|
-
path: potentialPath,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
catch { }
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
result = await build.resolve(potentialPath, {
|
|
90
|
-
kind: 'import-statement',
|
|
91
|
-
resolveDir: absWorkingDir,
|
|
92
|
-
});
|
|
93
|
-
if (result && result.external && absWorkingDir) {
|
|
94
|
-
projectResolve ??= (0, resolve_project_1.createProjectResolver)(absWorkingDir);
|
|
95
|
-
try {
|
|
96
|
-
const resolvedPath = projectResolve(potentialPath);
|
|
97
|
-
result = {
|
|
98
|
-
...result,
|
|
99
|
-
external: false,
|
|
100
|
-
path: resolvedPath,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
catch { }
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
if (result?.path) {
|
|
107
|
-
if (exact) {
|
|
108
|
-
return result;
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
return {
|
|
112
|
-
...result,
|
|
113
|
-
warnings: [
|
|
114
|
-
...result.warnings,
|
|
115
|
-
{
|
|
116
|
-
location: null,
|
|
117
|
-
text: `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`,
|
|
118
|
-
},
|
|
119
|
-
],
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
// Remove the last subtag and try again with a less specific locale.
|
|
124
|
-
// Usually the match is exact so the string splitting here is not done until actually needed after the exact
|
|
125
|
-
// match fails to resolve.
|
|
126
|
-
const parts = partialLocaleTag.split('-');
|
|
127
|
-
partialLocaleTag = parts.slice(0, -1).join('-');
|
|
128
|
-
exact = false;
|
|
138
|
+
if (!resolution.path) {
|
|
139
|
+
return {
|
|
140
|
+
path: rawLocaleTag,
|
|
141
|
+
namespace: exports.LOCALE_DATA_NAMESPACE,
|
|
142
|
+
warnings: resolution.warning
|
|
143
|
+
? [{ location: null, text: resolution.warning }]
|
|
144
|
+
: undefined,
|
|
145
|
+
};
|
|
129
146
|
}
|
|
130
|
-
// Not found so issue a warning and use an empty loader. Framework built-in `en-US` data will be used.
|
|
131
|
-
// This retains existing behavior as in the Webpack-based builder.
|
|
132
147
|
return {
|
|
133
|
-
path:
|
|
134
|
-
|
|
135
|
-
warnings: [
|
|
136
|
-
{
|
|
137
|
-
location: null,
|
|
138
|
-
text: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`,
|
|
139
|
-
},
|
|
140
|
-
],
|
|
148
|
+
path: resolution.path,
|
|
149
|
+
warnings: resolution.warning ? [{ location: null, text: resolution.warning }] : undefined,
|
|
141
150
|
};
|
|
142
151
|
});
|
|
143
|
-
// Locales that cannot be found will be loaded as empty content
|
|
152
|
+
// Locales that cannot be found or are en/en-US will be loaded as empty content
|
|
144
153
|
build.onLoad({ filter: /./, namespace: exports.LOCALE_DATA_NAMESPACE }, () => ({
|
|
145
154
|
contents: '',
|
|
146
155
|
loader: 'empty',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n-locale-plugin.js","sourceRoot":"","sources":["i18n-locale-plugin.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;
|
|
1
|
+
{"version":3,"file":"i18n-locale-plugin.js","sourceRoot":"","sources":["i18n-locale-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import type { ɵParsedTranslation } from '@angular/localize';
|
|
9
|
+
/**
|
|
10
|
+
* Magic header identifier for i18n SharedArrayBuffer translation tables ('I18N').
|
|
11
|
+
*/
|
|
12
|
+
export declare const I18N_MAGIC_ID = 1227962446;
|
|
13
|
+
/**
|
|
14
|
+
* Encodes a JavaScript translation dictionary into a contiguous SharedArrayBuffer.
|
|
15
|
+
* The buffer contains a header, a sorted index table (by key for fast O(log N) binary search),
|
|
16
|
+
* and a UTF-8 string pool.
|
|
17
|
+
*
|
|
18
|
+
* @param translation The translation dictionary object.
|
|
19
|
+
* @returns A SharedArrayBuffer containing the binary encoded translation catalog.
|
|
20
|
+
*/
|
|
21
|
+
export declare function encodeTranslationToBuffer<T = ɵParsedTranslation>(translation: Record<string, T>): SharedArrayBuffer;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.I18N_MAGIC_ID = void 0;
|
|
11
|
+
exports.encodeTranslationToBuffer = encodeTranslationToBuffer;
|
|
12
|
+
/**
|
|
13
|
+
* Magic header identifier for i18n SharedArrayBuffer translation tables ('I18N').
|
|
14
|
+
*/
|
|
15
|
+
exports.I18N_MAGIC_ID = 0x4931384e;
|
|
16
|
+
/**
|
|
17
|
+
* Encodes a JavaScript translation dictionary into a contiguous SharedArrayBuffer.
|
|
18
|
+
* The buffer contains a header, a sorted index table (by key for fast O(log N) binary search),
|
|
19
|
+
* and a UTF-8 string pool.
|
|
20
|
+
*
|
|
21
|
+
* @param translation The translation dictionary object.
|
|
22
|
+
* @returns A SharedArrayBuffer containing the binary encoded translation catalog.
|
|
23
|
+
*/
|
|
24
|
+
function encodeTranslationToBuffer(translation) {
|
|
25
|
+
const encoder = new TextEncoder();
|
|
26
|
+
const entries = Object.entries(translation);
|
|
27
|
+
const entryCount = entries.length;
|
|
28
|
+
// Pre-encode string keys and JSON-serialized string values
|
|
29
|
+
const encodedEntries = new Array(entryCount);
|
|
30
|
+
let stringPoolByteSize = 0;
|
|
31
|
+
for (let i = 0; i < entryCount; i++) {
|
|
32
|
+
const [key, val] = entries[i];
|
|
33
|
+
const keyBytes = encoder.encode(key);
|
|
34
|
+
const valBytes = encoder.encode(JSON.stringify(val));
|
|
35
|
+
encodedEntries[i] = { keyBytes, valBytes };
|
|
36
|
+
stringPoolByteSize += keyBytes.byteLength + valBytes.byteLength;
|
|
37
|
+
}
|
|
38
|
+
// Sort entries lexicographically by UTF-8 byte comparison.
|
|
39
|
+
// Lexicographical byte comparison matches the binary search reader's byte comparison,
|
|
40
|
+
// ensuring deterministic and zero-allocation lookups across all runtimes regardless of UTF-16 surrogate pairs.
|
|
41
|
+
encodedEntries.sort((a, b) => {
|
|
42
|
+
const aBytes = a.keyBytes;
|
|
43
|
+
const bBytes = b.keyBytes;
|
|
44
|
+
const minLen = Math.min(aBytes.length, bBytes.length);
|
|
45
|
+
for (let i = 0; i < minLen; i++) {
|
|
46
|
+
const diff = aBytes[i] - bBytes[i];
|
|
47
|
+
if (diff !== 0) {
|
|
48
|
+
return diff;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return aBytes.length - bBytes.length;
|
|
52
|
+
});
|
|
53
|
+
const indexByteSize = entryCount * 16;
|
|
54
|
+
const headerByteSize = 16;
|
|
55
|
+
const stringPoolOffset = headerByteSize + indexByteSize;
|
|
56
|
+
const totalByteSize = stringPoolOffset + stringPoolByteSize;
|
|
57
|
+
const buffer = new SharedArrayBuffer(totalByteSize);
|
|
58
|
+
// Set up views over the SharedArrayBuffer
|
|
59
|
+
const uint32Header = new Uint32Array(buffer, 0, 4);
|
|
60
|
+
const uint32Index = new Uint32Array(buffer, headerByteSize, entryCount * 4);
|
|
61
|
+
const uint8Pool = new Uint8Array(buffer, stringPoolOffset);
|
|
62
|
+
// Write Header: Magic, EntryCount, IndexOffset, StringPoolOffset
|
|
63
|
+
uint32Header[0] = exports.I18N_MAGIC_ID;
|
|
64
|
+
uint32Header[1] = entryCount;
|
|
65
|
+
uint32Header[2] = headerByteSize;
|
|
66
|
+
uint32Header[3] = stringPoolOffset;
|
|
67
|
+
// Write Index Table and String Pool entries
|
|
68
|
+
let currentPoolOffset = 0;
|
|
69
|
+
for (let i = 0; i < entryCount; i++) {
|
|
70
|
+
const { keyBytes, valBytes } = encodedEntries[i];
|
|
71
|
+
const keyOffset = currentPoolOffset;
|
|
72
|
+
const keyLen = keyBytes.byteLength;
|
|
73
|
+
uint8Pool.set(keyBytes, keyOffset);
|
|
74
|
+
currentPoolOffset += keyLen;
|
|
75
|
+
const valOffset = currentPoolOffset;
|
|
76
|
+
const valLen = valBytes.byteLength;
|
|
77
|
+
uint8Pool.set(valBytes, valOffset);
|
|
78
|
+
currentPoolOffset += valLen;
|
|
79
|
+
// Index entry format (4 uint32 words / 16 bytes):
|
|
80
|
+
// [0]: keyOffset (uint32)
|
|
81
|
+
// [1]: keyLength (uint32)
|
|
82
|
+
// [2]: valOffset (uint32)
|
|
83
|
+
// [3]: valLength (uint32)
|
|
84
|
+
const idx = i * 4;
|
|
85
|
+
uint32Index[idx] = keyOffset;
|
|
86
|
+
uint32Index[idx + 1] = keyLen;
|
|
87
|
+
uint32Index[idx + 2] = valOffset;
|
|
88
|
+
uint32Index[idx + 3] = valLen;
|
|
89
|
+
}
|
|
90
|
+
return buffer;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=i18n-translation-encoder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n-translation-encoder.js","sourceRoot":"","sources":["i18n-translation-encoder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
7
|
+
*/
|
|
8
|
+
import type { ɵParsedTranslation } from '@angular/localize';
|
|
9
|
+
/**
|
|
10
|
+
* A zero-copy reader that queries translation messages directly from a SharedArrayBuffer
|
|
11
|
+
* using binary search over a sorted key index.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SharedTranslationDictionary<T = ɵParsedTranslation> {
|
|
14
|
+
private readonly entryCount;
|
|
15
|
+
private readonly uint32Index;
|
|
16
|
+
private readonly uint8Pool;
|
|
17
|
+
private readonly decoder;
|
|
18
|
+
private readonly encoder;
|
|
19
|
+
private readonly lazyCache;
|
|
20
|
+
constructor(buffer: SharedArrayBuffer);
|
|
21
|
+
/**
|
|
22
|
+
* Looks up a translation message by key.
|
|
23
|
+
* Performs a binary search over the index table if not previously cached in the lazy cache.
|
|
24
|
+
*
|
|
25
|
+
* @param targetKey The message key ID to search for.
|
|
26
|
+
* @returns The parsed translation message, or undefined if not found.
|
|
27
|
+
*/
|
|
28
|
+
get(targetKey: string): T | undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates a JavaScript object Proxy wrapping a SharedTranslationDictionary so it can be passed
|
|
32
|
+
* directly to `@angular/localize` inliner functions as a standard translation Record.
|
|
33
|
+
*
|
|
34
|
+
* Traps `get`, `has`, and `getOwnPropertyDescriptor` to fulfill all `@angular/localize` `translate()`
|
|
35
|
+
* lookup requirements (`translations[id]`, `translations[legacyId]`, `Object.hasOwn(translations, id)`).
|
|
36
|
+
* The `ownKeys` trap is intentionally omitted so keys are not eagerly decoded upfront upon reflection.
|
|
37
|
+
*
|
|
38
|
+
* @param buffer The SharedArrayBuffer containing binary encoded translation catalog.
|
|
39
|
+
* @returns A Proxy object that intercepts property reads and queries the SharedTranslationDictionary.
|
|
40
|
+
*/
|
|
41
|
+
export declare function createSharedTranslationProxy<T = ɵParsedTranslation>(buffer: SharedArrayBuffer): Record<string, T>;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.SharedTranslationDictionary = void 0;
|
|
11
|
+
exports.createSharedTranslationProxy = createSharedTranslationProxy;
|
|
12
|
+
const i18n_translation_encoder_1 = require("./i18n-translation-encoder");
|
|
13
|
+
/**
|
|
14
|
+
* Sentinel value used to cache non-existent message key lookups in lazyCache.
|
|
15
|
+
*/
|
|
16
|
+
const NOT_FOUND = Symbol('NOT_FOUND');
|
|
17
|
+
/**
|
|
18
|
+
* Compares a target key's UTF-8 byte array against a byte sequence in the string pool.
|
|
19
|
+
* Lexicographical byte comparison of UTF-8 sequences matches UTF-16 code-unit string comparison
|
|
20
|
+
* used when encoding the sorted index table.
|
|
21
|
+
*/
|
|
22
|
+
function compareBytes(target, pool, poolOffset, keyLen) {
|
|
23
|
+
if (poolOffset < 0 || poolOffset + keyLen > pool.length) {
|
|
24
|
+
return 1;
|
|
25
|
+
}
|
|
26
|
+
const minLen = Math.min(target.length, keyLen);
|
|
27
|
+
for (let i = 0; i < minLen; i++) {
|
|
28
|
+
const diff = target[i] - pool[poolOffset + i];
|
|
29
|
+
if (diff !== 0) {
|
|
30
|
+
return diff;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return target.length - keyLen;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A zero-copy reader that queries translation messages directly from a SharedArrayBuffer
|
|
37
|
+
* using binary search over a sorted key index.
|
|
38
|
+
*/
|
|
39
|
+
class SharedTranslationDictionary {
|
|
40
|
+
entryCount;
|
|
41
|
+
uint32Index;
|
|
42
|
+
uint8Pool;
|
|
43
|
+
decoder = new TextDecoder();
|
|
44
|
+
encoder = new TextEncoder();
|
|
45
|
+
lazyCache = new Map();
|
|
46
|
+
constructor(buffer) {
|
|
47
|
+
if (buffer.byteLength < 16) {
|
|
48
|
+
throw new Error('Invalid SharedArrayBuffer translation header: buffer too small.');
|
|
49
|
+
}
|
|
50
|
+
const uint32Header = new Uint32Array(buffer, 0, 4);
|
|
51
|
+
if (uint32Header[0] !== i18n_translation_encoder_1.I18N_MAGIC_ID) {
|
|
52
|
+
throw new Error('Invalid SharedArrayBuffer translation header magic identifier.');
|
|
53
|
+
}
|
|
54
|
+
this.entryCount = uint32Header[1];
|
|
55
|
+
const headerByteSize = uint32Header[2];
|
|
56
|
+
const stringPoolOffset = uint32Header[3];
|
|
57
|
+
if (headerByteSize < 16 ||
|
|
58
|
+
headerByteSize % 4 !== 0 ||
|
|
59
|
+
headerByteSize + this.entryCount * 16 > buffer.byteLength ||
|
|
60
|
+
stringPoolOffset < headerByteSize + this.entryCount * 16 ||
|
|
61
|
+
stringPoolOffset > buffer.byteLength) {
|
|
62
|
+
throw new Error('Invalid SharedArrayBuffer translation header offsets.');
|
|
63
|
+
}
|
|
64
|
+
this.uint32Index = new Uint32Array(buffer, headerByteSize, this.entryCount * 4);
|
|
65
|
+
this.uint8Pool = new Uint8Array(buffer, stringPoolOffset);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Looks up a translation message by key.
|
|
69
|
+
* Performs a binary search over the index table if not previously cached in the lazy cache.
|
|
70
|
+
*
|
|
71
|
+
* @param targetKey The message key ID to search for.
|
|
72
|
+
* @returns The parsed translation message, or undefined if not found.
|
|
73
|
+
*/
|
|
74
|
+
get(targetKey) {
|
|
75
|
+
const cached = this.lazyCache.get(targetKey);
|
|
76
|
+
if (cached !== undefined) {
|
|
77
|
+
return cached === NOT_FOUND ? undefined : cached;
|
|
78
|
+
}
|
|
79
|
+
const targetBytes = this.encoder.encode(targetKey);
|
|
80
|
+
let low = 0;
|
|
81
|
+
let high = this.entryCount - 1;
|
|
82
|
+
while (low <= high) {
|
|
83
|
+
const mid = (low + high) >>> 1;
|
|
84
|
+
const idx = mid * 4;
|
|
85
|
+
const keyOffset = this.uint32Index[idx];
|
|
86
|
+
const keyLen = this.uint32Index[idx + 1];
|
|
87
|
+
const cmp = compareBytes(targetBytes, this.uint8Pool, keyOffset, keyLen);
|
|
88
|
+
if (cmp === 0) {
|
|
89
|
+
const valOffset = this.uint32Index[idx + 2];
|
|
90
|
+
const valLen = this.uint32Index[idx + 3];
|
|
91
|
+
if (valOffset < 0 || valOffset + valLen > this.uint8Pool.length) {
|
|
92
|
+
this.lazyCache.set(targetKey, NOT_FOUND);
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
const valBytes = this.uint8Pool.subarray(valOffset, valOffset + valLen);
|
|
96
|
+
const valJson = this.decoder.decode(valBytes);
|
|
97
|
+
try {
|
|
98
|
+
const val = JSON.parse(valJson);
|
|
99
|
+
this.lazyCache.set(targetKey, val);
|
|
100
|
+
return val;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
this.lazyCache.set(targetKey, NOT_FOUND);
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (cmp < 0) {
|
|
108
|
+
high = mid - 1;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
low = mid + 1;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
this.lazyCache.set(targetKey, NOT_FOUND);
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.SharedTranslationDictionary = SharedTranslationDictionary;
|
|
119
|
+
/**
|
|
120
|
+
* Creates a JavaScript object Proxy wrapping a SharedTranslationDictionary so it can be passed
|
|
121
|
+
* directly to `@angular/localize` inliner functions as a standard translation Record.
|
|
122
|
+
*
|
|
123
|
+
* Traps `get`, `has`, and `getOwnPropertyDescriptor` to fulfill all `@angular/localize` `translate()`
|
|
124
|
+
* lookup requirements (`translations[id]`, `translations[legacyId]`, `Object.hasOwn(translations, id)`).
|
|
125
|
+
* The `ownKeys` trap is intentionally omitted so keys are not eagerly decoded upfront upon reflection.
|
|
126
|
+
*
|
|
127
|
+
* @param buffer The SharedArrayBuffer containing binary encoded translation catalog.
|
|
128
|
+
* @returns A Proxy object that intercepts property reads and queries the SharedTranslationDictionary.
|
|
129
|
+
*/
|
|
130
|
+
function createSharedTranslationProxy(buffer) {
|
|
131
|
+
const dictionary = new SharedTranslationDictionary(buffer);
|
|
132
|
+
return new Proxy({}, {
|
|
133
|
+
get(target, prop) {
|
|
134
|
+
if (typeof prop === 'string') {
|
|
135
|
+
const value = dictionary.get(prop);
|
|
136
|
+
if (value !== undefined) {
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return Reflect.get(target, prop);
|
|
141
|
+
},
|
|
142
|
+
has(target, prop) {
|
|
143
|
+
if (typeof prop === 'string' && dictionary.get(prop) !== undefined) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
return Reflect.has(target, prop);
|
|
147
|
+
},
|
|
148
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
149
|
+
if (typeof prop === 'string') {
|
|
150
|
+
const val = dictionary.get(prop);
|
|
151
|
+
if (val !== undefined) {
|
|
152
|
+
return {
|
|
153
|
+
enumerable: true,
|
|
154
|
+
configurable: true,
|
|
155
|
+
writable: false,
|
|
156
|
+
value: val,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=i18n-translation-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"i18n-translation-reader.js","sourceRoot":"","sources":["i18n-translation-reader.ts"],"names":[],"mappings":"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"}
|