@analogjs/platform 2.5.0-beta.16 → 2.5.0-beta.18

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/platform",
3
- "version": "2.5.0-beta.16",
3
+ "version": "2.5.0-beta.18",
4
4
  "description": "The fullstack meta-framework for Angular",
5
5
  "type": "module",
6
6
  "author": "Brandon Roberts <robertsbt@gmail.com>",
@@ -29,8 +29,8 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "nitropack": "^2.13.1",
32
- "@analogjs/vite-plugin-angular": "^2.5.0-beta.16",
33
- "@analogjs/vite-plugin-nitro": "^2.5.0-beta.16",
32
+ "@analogjs/vite-plugin-angular": "^2.5.0-beta.18",
33
+ "@analogjs/vite-plugin-nitro": "^2.5.0-beta.18",
34
34
  "vitefu": "^1.1.2"
35
35
  },
36
36
  "peerDependencies": {
@@ -0,0 +1,33 @@
1
+ import { Plugin } from 'vite';
2
+ import { I18nOptions } from './options.js';
3
+ /**
4
+ * Vite plugin that extracts i18n messages from compiled JavaScript output.
5
+ *
6
+ * After the client build completes, this plugin scans all `.js` files in the
7
+ * output directory for `$localize` tagged template literals and extracts the
8
+ * message IDs and source text. It then writes the extracted messages to a
9
+ * translation source file.
10
+ *
11
+ * Uses `@angular/localize/tools` MessageExtractor when available,
12
+ * falling back to a regex-based extractor.
13
+ */
14
+ export declare function i18nExtractPlugin(i18nOptions: I18nOptions): Plugin;
15
+ export interface ExtractedMessage {
16
+ id: string;
17
+ text: string;
18
+ description?: string;
19
+ }
20
+ /**
21
+ * Regex-based fallback extractor for when @angular/localize/tools is not available.
22
+ *
23
+ * Parses `$localize` tagged template literals to extract message IDs and text.
24
+ * Handles the common forms:
25
+ * $localize`:@@messageId:text`
26
+ * $localize`:description@@messageId:text`
27
+ * $localize`text`
28
+ */
29
+ export declare function extractWithRegex(files: string[]): ExtractedMessage[];
30
+ /**
31
+ * Serializes extracted messages into the specified format.
32
+ */
33
+ export declare function serializeMessages(messages: ExtractedMessage[], format: string, sourceLocale: string): string;
@@ -0,0 +1,288 @@
1
+ import { resolve, dirname, extname } from 'node:path';
2
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync, } from 'node:fs';
3
+ const FORMAT_EXTENSIONS = {
4
+ json: '.json',
5
+ xliff: '.xlf',
6
+ xliff2: '.xlf',
7
+ xmb: '.xmb',
8
+ };
9
+ /**
10
+ * Vite plugin that extracts i18n messages from compiled JavaScript output.
11
+ *
12
+ * After the client build completes, this plugin scans all `.js` files in the
13
+ * output directory for `$localize` tagged template literals and extracts the
14
+ * message IDs and source text. It then writes the extracted messages to a
15
+ * translation source file.
16
+ *
17
+ * Uses `@angular/localize/tools` MessageExtractor when available,
18
+ * falling back to a regex-based extractor.
19
+ */
20
+ export function i18nExtractPlugin(i18nOptions) {
21
+ let config;
22
+ let isSSRBuild = false;
23
+ const extractConfig = i18nOptions.extract;
24
+ if (!extractConfig) {
25
+ return { name: 'analog-i18n-extract-noop' };
26
+ }
27
+ const format = extractConfig.format ?? 'json';
28
+ return {
29
+ name: 'analog-i18n-extract',
30
+ apply: 'build',
31
+ configResolved(resolvedConfig) {
32
+ config = resolvedConfig;
33
+ isSSRBuild = !!config.build.ssr;
34
+ },
35
+ async closeBundle() {
36
+ // Only run on the client build, not SSR
37
+ if (isSSRBuild) {
38
+ return;
39
+ }
40
+ const outDir = resolve(config.root, config.build.outDir);
41
+ const jsFiles = collectJsFiles(outDir);
42
+ const filesWithLocalize = jsFiles.filter((file) => {
43
+ const content = readFileSync(file, 'utf-8');
44
+ return content.includes('$localize');
45
+ });
46
+ if (filesWithLocalize.length === 0) {
47
+ return;
48
+ }
49
+ let messages;
50
+ try {
51
+ messages = await extractWithLocalizeTools(filesWithLocalize, config.root);
52
+ }
53
+ catch {
54
+ // @angular/localize/tools not available, use regex fallback
55
+ messages = extractWithRegex(filesWithLocalize);
56
+ }
57
+ if (messages.length === 0) {
58
+ return;
59
+ }
60
+ const ext = FORMAT_EXTENSIONS[format] ?? '.json';
61
+ const defaultOutFile = `src/i18n/messages${ext}`;
62
+ const outFile = resolve(config.root, extractConfig.outFile ?? defaultOutFile);
63
+ mkdirSync(dirname(outFile), { recursive: true });
64
+ const output = serializeMessages(messages, format, i18nOptions.defaultLocale);
65
+ writeFileSync(outFile, output, 'utf-8');
66
+ console.log(`\n[@analogjs/platform] Extracted ${messages.length} i18n message(s) to ${outFile}\n`);
67
+ },
68
+ };
69
+ }
70
+ /**
71
+ * Extracts messages using @angular/localize/tools MessageExtractor.
72
+ * Throws if the package is not installed.
73
+ */
74
+ async function extractWithLocalizeTools(files, basePath) {
75
+ // @ts-ignore - @angular/localize/tools is an optional dependency
76
+ const localizeTools = await import('@angular/localize/tools');
77
+ const { MessageExtractor, ɵParsedMessage } = localizeTools;
78
+ const fs = {
79
+ readFile: (path) => readFileSync(path, 'utf-8'),
80
+ readFileBuffer: (path) => readFileSync(path),
81
+ relative: (from, to) => {
82
+ const { relative } = require('node:path');
83
+ return relative(from, to);
84
+ },
85
+ resolve: (...paths) => resolve(...paths),
86
+ exists: (path) => {
87
+ try {
88
+ statSync(path);
89
+ return true;
90
+ }
91
+ catch {
92
+ return false;
93
+ }
94
+ },
95
+ dirname: (path) => dirname(path),
96
+ };
97
+ const logger = {
98
+ debug: () => { },
99
+ info: () => { },
100
+ warn: (msg) => console.warn(msg),
101
+ error: (msg) => console.error(msg),
102
+ level: 0,
103
+ };
104
+ const extractor = new MessageExtractor(fs, logger, {
105
+ basePath,
106
+ useSourceMaps: false,
107
+ });
108
+ const messages = [];
109
+ for (const file of files) {
110
+ try {
111
+ const extracted = extractor.extractMessages(file);
112
+ if (extracted?.messages) {
113
+ for (const msg of extracted.messages) {
114
+ messages.push({
115
+ id: msg.id || msg.customId || msg.messageString,
116
+ text: msg.messageString || msg.text || '',
117
+ description: msg.description,
118
+ });
119
+ }
120
+ }
121
+ }
122
+ catch {
123
+ // Skip files that can't be parsed
124
+ }
125
+ }
126
+ return messages;
127
+ }
128
+ /**
129
+ * Regex-based fallback extractor for when @angular/localize/tools is not available.
130
+ *
131
+ * Parses `$localize` tagged template literals to extract message IDs and text.
132
+ * Handles the common forms:
133
+ * $localize`:@@messageId:text`
134
+ * $localize`:description@@messageId:text`
135
+ * $localize`text`
136
+ */
137
+ export function extractWithRegex(files) {
138
+ const messages = [];
139
+ const seen = new Set();
140
+ // Match $localize`...` or $localize(__makeTemplateObject([...], [...]))
141
+ // The tagged template form: $localize`:[description@@]id:text`
142
+ const taggedTemplateRegex = /\$localize\s*`([^`]*)`/g;
143
+ // Match the metadata block: :[@description@@]id:
144
+ const metadataRegex = /^:((?:([^@]*)@@)?([^:]*)):(.*)$/s;
145
+ for (const file of files) {
146
+ const content = readFileSync(file, 'utf-8');
147
+ let match;
148
+ taggedTemplateRegex.lastIndex = 0;
149
+ while ((match = taggedTemplateRegex.exec(content)) !== null) {
150
+ const body = match[1];
151
+ const metaMatch = metadataRegex.exec(body);
152
+ let id;
153
+ let text;
154
+ let description;
155
+ if (metaMatch) {
156
+ description = metaMatch[2]?.trim() || undefined;
157
+ id = metaMatch[3];
158
+ text = metaMatch[4];
159
+ }
160
+ else {
161
+ // No metadata block — use the text as both id and text
162
+ text = body;
163
+ id = body;
164
+ }
165
+ if (id && !seen.has(id)) {
166
+ seen.add(id);
167
+ messages.push({ id, text, description });
168
+ }
169
+ }
170
+ }
171
+ return messages;
172
+ }
173
+ /**
174
+ * Serializes extracted messages into the specified format.
175
+ */
176
+ export function serializeMessages(messages, format, sourceLocale) {
177
+ switch (format) {
178
+ case 'xliff':
179
+ return serializeXliff1(messages, sourceLocale);
180
+ case 'xliff2':
181
+ return serializeXliff2(messages, sourceLocale);
182
+ case 'xmb':
183
+ return serializeXmb(messages);
184
+ case 'json':
185
+ default:
186
+ return serializeJson(messages);
187
+ }
188
+ }
189
+ function serializeJson(messages) {
190
+ const obj = {};
191
+ for (const msg of messages) {
192
+ obj[msg.id] = msg.text;
193
+ }
194
+ return JSON.stringify(obj, null, 2) + '\n';
195
+ }
196
+ function serializeXliff1(messages, sourceLocale) {
197
+ const units = messages
198
+ .map((msg) => {
199
+ const note = msg.description
200
+ ? `\n <note>${escapeXml(msg.description)}</note>`
201
+ : '';
202
+ return ` <trans-unit id="${escapeXml(msg.id)}" datatype="html">
203
+ <source>${escapeXml(msg.text)}</source>${note}
204
+ </trans-unit>`;
205
+ })
206
+ .join('\n');
207
+ return `<?xml version="1.0" encoding="UTF-8"?>
208
+ <xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
209
+ <file source-language="${sourceLocale}" datatype="plaintext" original="ng2.template">
210
+ <body>
211
+ ${units}
212
+ </body>
213
+ </file>
214
+ </xliff>
215
+ `;
216
+ }
217
+ function serializeXliff2(messages, sourceLocale) {
218
+ const units = messages
219
+ .map((msg) => {
220
+ const notes = msg.description
221
+ ? `\n <notes><note>${escapeXml(msg.description)}</note></notes>`
222
+ : '';
223
+ return ` <unit id="${escapeXml(msg.id)}">${notes}
224
+ <segment>
225
+ <source>${escapeXml(msg.text)}</source>
226
+ </segment>
227
+ </unit>`;
228
+ })
229
+ .join('\n');
230
+ return `<?xml version="1.0" encoding="UTF-8"?>
231
+ <xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="${sourceLocale}">
232
+ <file id="ngi18n" original="ng.template">
233
+ ${units}
234
+ </file>
235
+ </xliff>
236
+ `;
237
+ }
238
+ function serializeXmb(messages) {
239
+ const msgs = messages
240
+ .map((msg) => {
241
+ const desc = msg.description
242
+ ? ` desc="${escapeXml(msg.description)}"`
243
+ : '';
244
+ return ` <msg id="${escapeXml(msg.id)}"${desc}>${escapeXml(msg.text)}</msg>`;
245
+ })
246
+ .join('\n');
247
+ return `<?xml version="1.0" encoding="UTF-8"?>
248
+ <!DOCTYPE messagebundle [
249
+ <!ELEMENT messagebundle (msg)*>
250
+ <!ELEMENT msg (#PCDATA)>
251
+ <!ATTLIST msg id CDATA #REQUIRED>
252
+ <!ATTLIST msg desc CDATA #IMPLIED>
253
+ ]>
254
+ <messagebundle>
255
+ ${msgs}
256
+ </messagebundle>
257
+ `;
258
+ }
259
+ function escapeXml(str) {
260
+ return str
261
+ .replace(/&/g, '&amp;')
262
+ .replace(/</g, '&lt;')
263
+ .replace(/>/g, '&gt;')
264
+ .replace(/"/g, '&quot;');
265
+ }
266
+ /**
267
+ * Recursively collects all .js files from a directory.
268
+ */
269
+ function collectJsFiles(dir) {
270
+ const files = [];
271
+ try {
272
+ const entries = readdirSync(dir, { withFileTypes: true });
273
+ for (const entry of entries) {
274
+ const fullPath = resolve(dir, entry.name);
275
+ if (entry.isDirectory()) {
276
+ files.push(...collectJsFiles(fullPath));
277
+ }
278
+ else if (entry.isFile() && extname(entry.name) === '.js') {
279
+ files.push(fullPath);
280
+ }
281
+ }
282
+ }
283
+ catch {
284
+ // Directory doesn't exist yet (e.g., first build)
285
+ }
286
+ return files;
287
+ }
288
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaTE4bi1leHRyYWN0LXBsdWdpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL3BsYXRmb3JtL3NyYy9saWIvaTE4bi1leHRyYWN0LXBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdEQsT0FBTyxFQUNMLFlBQVksRUFDWixhQUFhLEVBQ2IsU0FBUyxFQUNULFdBQVcsRUFDWCxRQUFRLEdBQ1QsTUFBTSxTQUFTLENBQUM7QUFJakIsTUFBTSxpQkFBaUIsR0FBMkI7SUFDaEQsSUFBSSxFQUFFLE9BQU87SUFDYixLQUFLLEVBQUUsTUFBTTtJQUNiLE1BQU0sRUFBRSxNQUFNO0lBQ2QsR0FBRyxFQUFFLE1BQU07Q0FDWixDQUFDO0FBRUY7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxXQUF3QjtJQUN4RCxJQUFJLE1BQXNCLENBQUM7SUFDM0IsSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDO0lBRXZCLE1BQU0sYUFBYSxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUM7SUFDMUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ25CLE9BQU8sRUFBRSxJQUFJLEVBQUUsMEJBQTBCLEVBQVksQ0FBQztJQUN4RCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUM7SUFFOUMsT0FBTztRQUNMLElBQUksRUFBRSxxQkFBcUI7UUFDM0IsS0FBSyxFQUFFLE9BQU87UUFFZCxjQUFjLENBQUMsY0FBYztZQUMzQixNQUFNLEdBQUcsY0FBYyxDQUFDO1lBQ3hCLFVBQVUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFDbEMsQ0FBQztRQUVELEtBQUssQ0FBQyxXQUFXO1lBQ2Ysd0NBQXdDO1lB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
@@ -1,10 +1,10 @@
1
1
  export declare const V18_X_NX_DEVKIT = "^20.0.0";
2
2
  export declare const V18_X_NX_ANGULAR = "^20.0.0";
3
- export declare const V18_X_ANALOG_JS_CONTENT = "^2.5.0-beta.16";
4
- export declare const V18_X_ANALOG_JS_ROUTER = "^2.5.0-beta.16";
3
+ export declare const V18_X_ANALOG_JS_CONTENT = "^2.5.0-beta.18";
4
+ export declare const V18_X_ANALOG_JS_ROUTER = "^2.5.0-beta.18";
5
5
  export declare const V18_X_ANALOG_JS_TRPC = "~0.4.0";
6
- export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^2.5.0-beta.16";
7
- export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^2.5.0-beta.16";
6
+ export declare const V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^2.5.0-beta.18";
7
+ export declare const V18_X_ANALOG_JS_VITEST_ANGULAR = "^2.5.0-beta.18";
8
8
  export declare const V18_X_TRPC_CLIENT = "^10.25.0";
9
9
  export declare const V18_X_TRPC_SERVER = "^10.25.0";
10
10
  export declare const V18_X_ISOMORPHIC_FETCH = "^3.0.0";
@@ -20,7 +20,7 @@ export declare const V18_X_TAILWINDCSS = "^4.1.4";
20
20
  export declare const V18_X_TAILWINDCSS_VITE = "^4.1.4";
21
21
  export declare const V18_X_POSTCSS = "^8.5.3";
22
22
  export declare const V18_X_AUTOPREFIXER = "^10.4.0";
23
- export declare const V18_X_ANALOG_JS_PLATFORM = "^2.5.0-beta.16";
23
+ export declare const V18_X_ANALOG_JS_PLATFORM = "^2.5.0-beta.18";
24
24
  export declare const V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = "^19.0.0";
25
25
  export declare const V18_X_NX_VITE = "^21.0.0";
26
26
  export declare const V18_X_NX_LINTER = "^21.0.0";
@@ -5,11 +5,11 @@ exports.V18_X_ZOD = exports.V18_X_VITEST = exports.V18_X_VITE_TSCONFIG_PATHS = e
5
5
  // dependencies
6
6
  exports.V18_X_NX_DEVKIT = '^20.0.0';
7
7
  exports.V18_X_NX_ANGULAR = '^20.0.0';
8
- exports.V18_X_ANALOG_JS_CONTENT = '^2.5.0-beta.16';
9
- exports.V18_X_ANALOG_JS_ROUTER = '^2.5.0-beta.16';
8
+ exports.V18_X_ANALOG_JS_CONTENT = '^2.5.0-beta.18';
9
+ exports.V18_X_ANALOG_JS_ROUTER = '^2.5.0-beta.18';
10
10
  exports.V18_X_ANALOG_JS_TRPC = '~0.4.0';
11
- exports.V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^2.5.0-beta.16';
12
- exports.V18_X_ANALOG_JS_VITEST_ANGULAR = '^2.5.0-beta.16';
11
+ exports.V18_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^2.5.0-beta.18';
12
+ exports.V18_X_ANALOG_JS_VITEST_ANGULAR = '^2.5.0-beta.18';
13
13
  exports.V18_X_TRPC_CLIENT = '^10.25.0';
14
14
  exports.V18_X_TRPC_SERVER = '^10.25.0';
15
15
  exports.V18_X_ISOMORPHIC_FETCH = '^3.0.0';
@@ -26,7 +26,7 @@ exports.V18_X_TAILWINDCSS_VITE = '^4.1.4';
26
26
  exports.V18_X_POSTCSS = '^8.5.3';
27
27
  exports.V18_X_AUTOPREFIXER = '^10.4.0';
28
28
  // devDependencies
29
- exports.V18_X_ANALOG_JS_PLATFORM = '^2.5.0-beta.16';
29
+ exports.V18_X_ANALOG_JS_PLATFORM = '^2.5.0-beta.18';
30
30
  exports.V18_X_ANGULAR_DEVKIT_BUILD_ANGULAR = '^19.0.0';
31
31
  exports.V18_X_NX_VITE = '^21.0.0';
32
32
  exports.V18_X_NX_LINTER = '^21.0.0';
@@ -1,13 +1,13 @@
1
- export declare const V19_X_ANALOG_JS_ROUTER = "^2.5.0-beta.16";
2
- export declare const V19_X_ANALOG_JS_CONTENT = "^2.5.0-beta.16";
1
+ export declare const V19_X_ANALOG_JS_ROUTER = "^2.5.0-beta.18";
2
+ export declare const V19_X_ANALOG_JS_CONTENT = "^2.5.0-beta.18";
3
3
  export declare const V19_X_MARKED = "^15.0.7";
4
4
  export declare const V19_X_MARKED_GFM_HEADING_ID = "^4.1.1";
5
5
  export declare const V19_X_MARKED_HIGHLIGHT = "^2.2.1";
6
6
  export declare const V19_X_MARKED_MANGLE = "^1.1.10";
7
7
  export declare const V19_X_PRISMJS = "^1.29.0";
8
- export declare const V19_X_ANALOG_JS_PLATFORM = "^2.5.0-beta.16";
9
- export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^2.5.0-beta.16";
10
- export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^2.5.0-beta.16";
8
+ export declare const V19_X_ANALOG_JS_PLATFORM = "^2.5.0-beta.18";
9
+ export declare const V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = "^2.5.0-beta.18";
10
+ export declare const V19_X_ANALOG_JS_VITEST_ANGULAR = "^2.5.0-beta.18";
11
11
  export declare const V19_X_NX_ANGULAR = "^22.0.0";
12
12
  export declare const V19_X_NX_VITE = "^22.0.0";
13
13
  export declare const V19_X_JSDOM = "^22.0.0";
@@ -2,17 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NX_X_LATEST_VITEST = exports.NX_X_LATEST_VITE = exports.V19_X_VITE = exports.V19_X_VITEST = exports.V19_X_VITE_TSCONFIG_PATHS = exports.V19_X_JSDOM = exports.V19_X_NX_VITE = exports.V19_X_NX_ANGULAR = exports.V19_X_ANALOG_JS_VITEST_ANGULAR = exports.V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = exports.V19_X_ANALOG_JS_PLATFORM = exports.V19_X_PRISMJS = exports.V19_X_MARKED_MANGLE = exports.V19_X_MARKED_HIGHLIGHT = exports.V19_X_MARKED_GFM_HEADING_ID = exports.V19_X_MARKED = exports.V19_X_ANALOG_JS_CONTENT = exports.V19_X_ANALOG_JS_ROUTER = void 0;
4
4
  // V19_X
5
- exports.V19_X_ANALOG_JS_ROUTER = '^2.5.0-beta.16';
6
- exports.V19_X_ANALOG_JS_CONTENT = '^2.5.0-beta.16';
5
+ exports.V19_X_ANALOG_JS_ROUTER = '^2.5.0-beta.18';
6
+ exports.V19_X_ANALOG_JS_CONTENT = '^2.5.0-beta.18';
7
7
  exports.V19_X_MARKED = '^15.0.7';
8
8
  exports.V19_X_MARKED_GFM_HEADING_ID = '^4.1.1';
9
9
  exports.V19_X_MARKED_HIGHLIGHT = '^2.2.1';
10
10
  exports.V19_X_MARKED_MANGLE = '^1.1.10';
11
11
  exports.V19_X_PRISMJS = '^1.29.0';
12
12
  // devDependencies
13
- exports.V19_X_ANALOG_JS_PLATFORM = '^2.5.0-beta.16';
14
- exports.V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^2.5.0-beta.16';
15
- exports.V19_X_ANALOG_JS_VITEST_ANGULAR = '^2.5.0-beta.16';
13
+ exports.V19_X_ANALOG_JS_PLATFORM = '^2.5.0-beta.18';
14
+ exports.V19_X_ANALOG_JS_VITE_PLUGIN_ANGULAR = '^2.5.0-beta.18';
15
+ exports.V19_X_ANALOG_JS_VITEST_ANGULAR = '^2.5.0-beta.18';
16
16
  exports.V19_X_NX_ANGULAR = '^22.0.0';
17
17
  exports.V19_X_NX_VITE = '^22.0.0';
18
18
  exports.V19_X_JSDOM = '^22.0.0';
@@ -23,6 +23,32 @@ export interface PrerenderOptions {
23
23
  /** List of functions that run for each route after pre-rendering is complete. */
24
24
  postRenderingHooks?: ((routes: PrerenderRoute) => Promise<void>)[];
25
25
  }
26
+ export interface I18nOptions {
27
+ /**
28
+ * The default/source locale for the application.
29
+ */
30
+ defaultLocale: string;
31
+ /**
32
+ * List of supported locale identifiers (e.g. ['en', 'fr', 'de']).
33
+ */
34
+ locales: string[];
35
+ /**
36
+ * Extract i18n messages from the build output.
37
+ * When enabled, writes a translation source file after the client build.
38
+ */
39
+ extract?: {
40
+ /**
41
+ * Output format for extracted messages.
42
+ * @default 'json'
43
+ */
44
+ format?: 'json' | 'xliff' | 'xliff2' | 'xmb';
45
+ /**
46
+ * Output file path for extracted messages, relative to project root.
47
+ * @default 'src/i18n/messages.{format extension}'
48
+ */
49
+ outFile?: string;
50
+ };
51
+ }
26
52
  export interface Options {
27
53
  ssr?: boolean;
28
54
  ssrBuildDir?: string;
@@ -81,5 +107,11 @@ export interface Options {
81
107
  * File replacements
82
108
  */
83
109
  fileReplacements?: PluginOptions['fileReplacements'];
110
+ /**
111
+ * Configuration for runtime i18n support.
112
+ * When set, enables locale detection on SSR and provides
113
+ * the LOCALE injection token.
114
+ */
115
+ i18n?: I18nOptions;
84
116
  }
85
117
  export { PrerenderContentDir, PrerenderContentFile };
@@ -8,6 +8,7 @@ import { ssrXhrBuildPlugin } from './ssr/ssr-xhr-plugin.js';
8
8
  import { depsPlugin } from './deps-plugin.js';
9
9
  import { injectHTMLPlugin } from './ssr/inject-html-plugin.js';
10
10
  import { serverModePlugin } from '../server-mode-plugin.js';
11
+ import { i18nExtractPlugin } from './i18n-extract-plugin.js';
11
12
  export function platformPlugin(opts = {}) {
12
13
  const isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];
13
14
  const { ...platformOptions } = {
@@ -57,6 +58,9 @@ export function platformPlugin(opts = {}) {
57
58
  serverModePlugin(),
58
59
  ssrXhrBuildPlugin(),
59
60
  clearClientPageEndpointsPlugin(),
61
+ ...(platformOptions.i18n?.extract
62
+ ? [i18nExtractPlugin(platformOptions.i18n)]
63
+ : []),
60
64
  ];
61
65
  }
62
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhdGZvcm0tcGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcGxhdGZvcm0vc3JjL2xpYi9wbGF0Zm9ybS1wbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxlQUFlLE1BQU0sNkJBQTZCLENBQUM7QUFDMUQsT0FBTyxPQUFPLE1BQU0sK0JBQStCLENBQUM7QUFHcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDakYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTVELE1BQU0sVUFBVSxjQUFjLENBQUMsT0FBZ0IsRUFBRTtJQUMvQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLE1BQU0sSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM3RSxNQUFNLEVBQUUsR0FBRyxlQUFlLEVBQUUsR0FBRztRQUM3QixHQUFHLEVBQUUsSUFBSTtRQUNULEdBQUcsSUFBSTtLQUNSLENBQUM7SUFFRixJQUFJLFlBQVksR0FBRyxlQUFlLEVBQUUsS0FBSyxDQUFDO0lBRTFDLElBQUksWUFBWSxFQUFFLFVBQVUsRUFBRSxDQUFDO1FBQzdCLFlBQVksR0FBRztZQUNiLEdBQUcsWUFBWTtZQUNmLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQyxNQUFNLENBQ3JELENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxFQUFFO2dCQUNmLE9BQU87b0JBQ0wsR0FBRyxNQUFNO29CQUNULENBQUMsSUFBSSxDQUFDLEVBQUU7d0JBQ04sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO3dCQUNmLE9BQU8sRUFBRTs0QkFDUCxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPOzRCQUN2QixpQkFBaUIsRUFDZixNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTO3lCQUM1QztxQkFDVDtpQkFDRixDQUFDO1lBQ0osQ0FBQyxFQUNELFlBQVksQ0FBQyxVQUFVLENBQ3hCO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPO1FBQ0wsR0FBRyxlQUFlLENBQUMsZUFBZSxFQUFFLFlBQVksQ0FBQztRQUNqRCxHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLEVBQUUsRUFBRSxHQUFHLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3pFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDL0MsR0FBRyxZQUFZLENBQUMsZUFBZSxDQUFDO1FBQ2hDLEdBQUcsYUFBYSxDQUFDLGVBQWUsRUFBRSxPQUFPLEVBQUUsZUFBZSxDQUFDO1FBQzNELEdBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxLQUFLLEtBQUs7WUFDdkIsQ0FBQyxDQUFDLEVBQUU7WUFDSixDQUFDLENBQUMsT0FBTyxDQUFDO2dCQUNOLEdBQUcsRUFBRSxlQUFlLENBQUMsR0FBRztnQkFDeEIsYUFBYSxFQUFFLGVBQWUsQ0FBQyxhQUFhO2dCQUM1QyxtQkFBbUIsRUFBRSxlQUFlLENBQUMsbUJBQW1CLElBQUksS0FBSztnQkFDakUsT0FBTyxFQUFFO29CQUNQLEdBQUcsQ0FBQyxlQUFlLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztvQkFDbEMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxtQkFBbUIsSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQ2hELENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxHQUFHLE9BQU8sZUFBZSxDQUN2QztpQkFDRjtnQkFDRCxxQkFBcUIsRUFBRSxlQUFlLENBQUMscUJBQXFCO2dCQUM1RCxVQUFVLEVBQUUsZUFBZSxDQUFDLFVBQVU7Z0JBQ3RDLHFCQUFxQixFQUFFLGVBQWUsQ0FBQyxxQkFBcUI7Z0JBQzVELGdCQUFnQixFQUFFLGVBQWUsQ0FBQyxnQkFBZ0I7Z0JBQ2xELEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQzthQUN0QixDQUFDLENBQVM7UUFDZixnQkFBZ0IsRUFBRTtRQUNsQixpQkFBaUIsRUFBWTtRQUM3Qiw4QkFBOEIsRUFBWTtLQUMzQyxDQUFDO0FBQ0osQ0FBQyJ9
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhdGZvcm0tcGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcGxhdGZvcm0vc3JjL2xpYi9wbGF0Zm9ybS1wbHVnaW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxlQUFlLE1BQU0sNkJBQTZCLENBQUM7QUFDMUQsT0FBTyxPQUFPLE1BQU0sK0JBQStCLENBQUM7QUFHcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDakYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTdELE1BQU0sVUFBVSxjQUFjLENBQUMsT0FBZ0IsRUFBRTtJQUMvQyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLE1BQU0sSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM3RSxNQUFNLEVBQUUsR0FBRyxlQUFlLEVBQUUsR0FBRztRQUM3QixHQUFHLEVBQUUsSUFBSTtRQUNULEdBQUcsSUFBSTtLQUNSLENBQUM7SUFFRixJQUFJLFlBQVksR0FBRyxlQUFlLEVBQUUsS0FBSyxDQUFDO0lBRTFDLElBQUksWUFB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