@astroscope/i18n 0.5.0 → 0.6.0
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/dist/babel-plugin-C8O9spUS.js +120 -0
- package/dist/babel-plugin-C8O9spUS.js.map +1 -0
- package/dist/client/directives/idle.d.ts +4 -9
- package/dist/client/directives/idle.d.ts.map +1 -0
- package/dist/client/directives/idle.js +13 -21
- package/dist/client/directives/idle.js.map +1 -0
- package/dist/client/directives/load.d.ts +4 -9
- package/dist/client/directives/load.d.ts.map +1 -0
- package/dist/client/directives/load.js +9 -14
- package/dist/client/directives/load.js.map +1 -0
- package/dist/client/directives/media.d.ts +4 -9
- package/dist/client/directives/media.d.ts.map +1 -0
- package/dist/client/directives/media.js +16 -24
- package/dist/client/directives/media.js.map +1 -0
- package/dist/client/directives/only.d.ts +4 -11
- package/dist/client/directives/only.d.ts.map +1 -0
- package/dist/client/directives/only.js +9 -14
- package/dist/client/directives/only.js.map +1 -0
- package/dist/client/directives/utils.d.ts +3 -4
- package/dist/client/directives/utils.d.ts.map +1 -0
- package/dist/client/directives/utils.js +32 -7
- package/dist/client/directives/utils.js.map +1 -0
- package/dist/client/directives/visible.d.ts +4 -9
- package/dist/client/directives/visible.d.ts.map +1 -0
- package/dist/client/directives/visible.js +22 -29
- package/dist/client/directives/visible.js.map +1 -0
- package/dist/client/translate.d.ts +5 -4
- package/dist/client/translate.d.ts.map +1 -0
- package/dist/client/translate.js +68 -41
- package/dist/client/translate.js.map +1 -0
- package/dist/compiler-DjYjJc0V.js +45 -0
- package/dist/compiler-DjYjJc0V.js.map +1 -0
- package/dist/context-CNd4O0Pf.js +247 -0
- package/dist/context-CNd4O0Pf.js.map +1 -0
- package/dist/extraction/index.d.ts +12 -17
- package/dist/extraction/index.d.ts.map +1 -0
- package/dist/extraction/index.js +3 -11
- package/dist/i18n-DzmH9JmE.d.ts +79 -0
- package/dist/i18n-DzmH9JmE.d.ts.map +1 -0
- package/dist/index.d.ts +37 -33
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +163 -148
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +6 -6
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +2 -10
- package/dist/manifest-D883_BIS.js +43 -0
- package/dist/manifest-D883_BIS.js.map +1 -0
- package/dist/rich-CHisXE-A.js +87 -0
- package/dist/rich-CHisXE-A.js.map +1 -0
- package/dist/{rich-CQUhdwBc.d.ts → rich-CqNMP3tk.d.ts} +4 -2
- package/dist/rich-CqNMP3tk.d.ts.map +1 -0
- package/dist/server/translate.d.ts +5 -3
- package/dist/server/translate.d.ts.map +1 -0
- package/dist/server/translate.js +75 -64
- package/dist/server/translate.js.map +1 -0
- package/dist/state-DeudhdeT.js +20 -0
- package/dist/state-DeudhdeT.js.map +1 -0
- package/dist/{types-ChMT6Vbd.d.ts → types-BfyoJsoB.d.ts} +11 -10
- package/dist/types-BfyoJsoB.d.ts.map +1 -0
- package/dist/types-Bo4jMK8g.d.ts +20 -0
- package/dist/types-Bo4jMK8g.d.ts.map +1 -0
- package/dist/{types-DNRFj1XA.d.ts → types-C98CcjtN.d.ts} +13 -11
- package/dist/types-C98CcjtN.d.ts.map +1 -0
- package/dist/url-B8334XSD.js +36 -0
- package/dist/url-B8334XSD.js.map +1 -0
- package/dist/vite-plugin-DVUlcvEH.js +421 -0
- package/dist/vite-plugin-DVUlcvEH.js.map +1 -0
- package/package.json +13 -12
- package/dist/babel-plugin-GOB6FMZ2.js +0 -119
- package/dist/chunk-33JVAFGQ.js +0 -44
- package/dist/chunk-4A5BKHFN.js +0 -16
- package/dist/chunk-7MSGHEST.js +0 -31
- package/dist/chunk-FYKC3DAZ.js +0 -36
- package/dist/chunk-LXW5WYBS.js +0 -298
- package/dist/chunk-PACQPCSW.js +0 -479
- package/dist/chunk-VGPVG5JP.js +0 -73
- package/dist/i18n-B--L7OQk.d.ts +0 -76
- package/dist/types-B_8vAmvv.d.ts +0 -18
- package/dist/types-BeDFfFIL.d.ts +0 -7
package/dist/chunk-PACQPCSW.js
DELETED
|
@@ -1,479 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getGlobalState,
|
|
3
|
-
getManifest
|
|
4
|
-
} from "./chunk-FYKC3DAZ.js";
|
|
5
|
-
import {
|
|
6
|
-
chunkIdToName
|
|
7
|
-
} from "./chunk-4A5BKHFN.js";
|
|
8
|
-
|
|
9
|
-
// src/extraction/vite-plugin.ts
|
|
10
|
-
import fs2 from "fs";
|
|
11
|
-
import path2 from "path";
|
|
12
|
-
import MagicString from "magic-string";
|
|
13
|
-
|
|
14
|
-
// src/extraction/extract.ts
|
|
15
|
-
var TS_EXTENSIONS = [".ts", ".tsx"];
|
|
16
|
-
var JSX_EXTENSIONS = [".jsx", ".tsx"];
|
|
17
|
-
var JS_EXTENSIONS = [".js", ".jsx"];
|
|
18
|
-
var BABEL_EXTENSIONS = [...TS_EXTENSIONS, ...JS_EXTENSIONS];
|
|
19
|
-
var ALL_EXTENSIONS = [...BABEL_EXTENSIONS, ".astro"];
|
|
20
|
-
async function extractKeysFromFile(options) {
|
|
21
|
-
const { filename, code, logger, stripFallbacks = false, onKeyExtracted } = options;
|
|
22
|
-
const keys = [];
|
|
23
|
-
const [{ transformAsync }, { i18nExtractPlugin }] = await Promise.all([
|
|
24
|
-
import("@babel/core"),
|
|
25
|
-
import("./babel-plugin-GOB6FMZ2.js")
|
|
26
|
-
]);
|
|
27
|
-
const isTypeScript = TS_EXTENSIONS.some((ext) => filename.endsWith(ext)) || filename.endsWith(".astro");
|
|
28
|
-
const isJSX = JSX_EXTENSIONS.some((ext) => filename.endsWith(ext));
|
|
29
|
-
const result = await transformAsync(code, {
|
|
30
|
-
filename,
|
|
31
|
-
sourceMaps: stripFallbacks,
|
|
32
|
-
// only need source maps when transforming
|
|
33
|
-
babelrc: false,
|
|
34
|
-
configFile: false,
|
|
35
|
-
parserOpts: {
|
|
36
|
-
plugins: [...isTypeScript ? ["typescript"] : [], ...isJSX ? ["jsx"] : []]
|
|
37
|
-
},
|
|
38
|
-
plugins: [
|
|
39
|
-
[
|
|
40
|
-
i18nExtractPlugin,
|
|
41
|
-
{
|
|
42
|
-
stripFallbacks,
|
|
43
|
-
onKeyExtracted: (key) => {
|
|
44
|
-
keys.push(key);
|
|
45
|
-
onKeyExtracted?.(key);
|
|
46
|
-
},
|
|
47
|
-
logger
|
|
48
|
-
}
|
|
49
|
-
]
|
|
50
|
-
]
|
|
51
|
-
});
|
|
52
|
-
return {
|
|
53
|
-
keys,
|
|
54
|
-
code: result?.code ?? null,
|
|
55
|
-
map: result?.map
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// src/extraction/key-store.ts
|
|
60
|
-
var KeyStore = class {
|
|
61
|
-
constructor(logger, consistency = "warn") {
|
|
62
|
-
this.logger = logger;
|
|
63
|
-
this.consistency = consistency;
|
|
64
|
-
}
|
|
65
|
-
logger;
|
|
66
|
-
consistency;
|
|
67
|
-
/** All key occurrences (may have duplicates) */
|
|
68
|
-
occurrences = [];
|
|
69
|
-
/** Tracks reported inconsistencies to avoid duplicate warnings */
|
|
70
|
-
reportedInconsistencies = /* @__PURE__ */ new Set();
|
|
71
|
-
/** Whether an error-level inconsistency was found (for build failure) */
|
|
72
|
-
hasInconsistencyError = false;
|
|
73
|
-
fileToKeys = /* @__PURE__ */ new Map();
|
|
74
|
-
filesWithI18n = /* @__PURE__ */ new Set();
|
|
75
|
-
/**
|
|
76
|
-
* Add key occurrences for a file, replacing any existing occurrences for that file.
|
|
77
|
-
*/
|
|
78
|
-
addFileKeys(filename, keys) {
|
|
79
|
-
const newKeyStrings = keys.map((k) => k.key);
|
|
80
|
-
const oldKeys = this.fileToKeys.get(filename);
|
|
81
|
-
if (oldKeys) {
|
|
82
|
-
const uniqueNew = [...new Set(newKeyStrings)];
|
|
83
|
-
const uniqueOld = [...new Set(oldKeys)];
|
|
84
|
-
const added = uniqueNew.filter((k) => !uniqueOld.includes(k));
|
|
85
|
-
const removed = uniqueOld.filter((k) => !uniqueNew.includes(k));
|
|
86
|
-
const file = filename.split("/").pop();
|
|
87
|
-
if (added.length > 0 || removed.length > 0) {
|
|
88
|
-
const parts = [];
|
|
89
|
-
if (added.length > 0) parts.push(`+${added.length}`);
|
|
90
|
-
if (removed.length > 0) parts.push(`-${removed.length}`);
|
|
91
|
-
this.logger.info(`hmr: ${parts.join(" ")} key(s) in ${file}`);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (oldKeys) {
|
|
95
|
-
for (let i = this.occurrences.length - 1; i >= 0; i--) {
|
|
96
|
-
if (this.occurrences[i]?.file === filename) {
|
|
97
|
-
this.occurrences.splice(i, 1);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
this.filesWithI18n.add(filename);
|
|
102
|
-
if (this.consistency !== "off") {
|
|
103
|
-
this.checkConsistency(keys);
|
|
104
|
-
}
|
|
105
|
-
if (keys.length > 0) {
|
|
106
|
-
this.occurrences.push(...keys);
|
|
107
|
-
}
|
|
108
|
-
this.fileToKeys.set(filename, newKeyStrings);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Check new keys for inconsistencies with existing occurrences.
|
|
112
|
-
*/
|
|
113
|
-
checkConsistency(newKeys) {
|
|
114
|
-
const existingByKey = /* @__PURE__ */ new Map();
|
|
115
|
-
for (const occ of this.occurrences) {
|
|
116
|
-
if (!existingByKey.has(occ.key)) {
|
|
117
|
-
existingByKey.set(occ.key, occ);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
for (const newKey of newKeys) {
|
|
121
|
-
const existing = existingByKey.get(newKey.key);
|
|
122
|
-
if (!existing) continue;
|
|
123
|
-
const inconsistencies = this.findInconsistencies(newKey, existing);
|
|
124
|
-
for (const inc of inconsistencies) {
|
|
125
|
-
this.reportInconsistency(inc);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Compare two occurrences and find any metadata inconsistencies.
|
|
131
|
-
*/
|
|
132
|
-
findInconsistencies(a, b) {
|
|
133
|
-
const result = [];
|
|
134
|
-
const locA = `${a.file}:${a.line}`;
|
|
135
|
-
const locB = `${b.file}:${b.line}`;
|
|
136
|
-
if (a.meta.fallback !== b.meta.fallback) {
|
|
137
|
-
result.push({
|
|
138
|
-
key: a.key,
|
|
139
|
-
field: "fallback",
|
|
140
|
-
locations: [locA, locB],
|
|
141
|
-
values: [a.meta.fallback, b.meta.fallback]
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
if (a.meta.description !== b.meta.description) {
|
|
145
|
-
result.push({
|
|
146
|
-
key: a.key,
|
|
147
|
-
field: "description",
|
|
148
|
-
locations: [locA, locB],
|
|
149
|
-
values: [a.meta.description ?? "(none)", b.meta.description ?? "(none)"]
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
const varsA = this.serializeVariables(a.meta);
|
|
153
|
-
const varsB = this.serializeVariables(b.meta);
|
|
154
|
-
if (varsA !== varsB) {
|
|
155
|
-
result.push({
|
|
156
|
-
key: a.key,
|
|
157
|
-
field: "variables",
|
|
158
|
-
locations: [locA, locB],
|
|
159
|
-
values: [varsA || "(none)", varsB || "(none)"]
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
return result;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Serialize variables for comparison.
|
|
166
|
-
*/
|
|
167
|
-
serializeVariables(meta) {
|
|
168
|
-
if (!meta.variables) return "";
|
|
169
|
-
const sorted = {};
|
|
170
|
-
for (const key of Object.keys(meta.variables).sort()) {
|
|
171
|
-
sorted[key] = meta.variables[key];
|
|
172
|
-
}
|
|
173
|
-
return JSON.stringify(sorted);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Report an inconsistency via logger.
|
|
177
|
-
*/
|
|
178
|
-
reportInconsistency(inc) {
|
|
179
|
-
const incKey = `${inc.key}:${inc.field}`;
|
|
180
|
-
if (this.reportedInconsistencies.has(incKey)) return;
|
|
181
|
-
this.reportedInconsistencies.add(incKey);
|
|
182
|
-
const message = `inconsistent ${inc.field} for key "${inc.key}"
|
|
183
|
-
${inc.locations[0]}: ${JSON.stringify(inc.values[0])}
|
|
184
|
-
${inc.locations[1]}: ${JSON.stringify(inc.values[1])}`;
|
|
185
|
-
if (this.consistency === "error") {
|
|
186
|
-
this.logger.error(message);
|
|
187
|
-
this.hasInconsistencyError = true;
|
|
188
|
-
} else {
|
|
189
|
-
this.logger.warn(message);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Check if any error-level inconsistencies were found.
|
|
194
|
-
* Call this at the end of build to determine if it should fail.
|
|
195
|
-
*/
|
|
196
|
-
get hasErrors() {
|
|
197
|
-
return this.hasInconsistencyError;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Get deduplicated keys with all file locations merged.
|
|
201
|
-
* Last occurrence's meta wins for each key.
|
|
202
|
-
*/
|
|
203
|
-
get extractedKeys() {
|
|
204
|
-
const keyMap = /* @__PURE__ */ new Map();
|
|
205
|
-
for (const occurrence of this.occurrences) {
|
|
206
|
-
const existing = keyMap.get(occurrence.key);
|
|
207
|
-
const fileLocation = `${occurrence.file}:${occurrence.line}`;
|
|
208
|
-
if (existing) {
|
|
209
|
-
if (!existing.files.includes(fileLocation)) {
|
|
210
|
-
existing.files.push(fileLocation);
|
|
211
|
-
}
|
|
212
|
-
existing.meta = occurrence.meta;
|
|
213
|
-
} else {
|
|
214
|
-
keyMap.set(occurrence.key, {
|
|
215
|
-
key: occurrence.key,
|
|
216
|
-
meta: occurrence.meta,
|
|
217
|
-
files: [fileLocation]
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return Array.from(keyMap.values());
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Get count of unique keys.
|
|
225
|
-
*/
|
|
226
|
-
get uniqueKeyCount() {
|
|
227
|
-
return new Set(this.occurrences.map((k) => k.key)).size;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Merge another store's data into this one.
|
|
231
|
-
*/
|
|
232
|
-
merge(other) {
|
|
233
|
-
for (const [file, keys] of other.fileToKeys) {
|
|
234
|
-
this.fileToKeys.set(file, keys);
|
|
235
|
-
}
|
|
236
|
-
for (const file of other.filesWithI18n) {
|
|
237
|
-
this.filesWithI18n.add(file);
|
|
238
|
-
}
|
|
239
|
-
if (this.consistency !== "off") {
|
|
240
|
-
this.checkConsistency(other.occurrences);
|
|
241
|
-
}
|
|
242
|
-
this.occurrences.push(...other.occurrences);
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Internal access to occurrences (for merge)
|
|
246
|
-
*/
|
|
247
|
-
get occurrencesList() {
|
|
248
|
-
return this.occurrences;
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
// src/extraction/scan.ts
|
|
253
|
-
import fs from "fs";
|
|
254
|
-
import path from "path";
|
|
255
|
-
var GLOB_PATTERN = `src/**/*.{${ALL_EXTENSIONS.map((e) => e.slice(1)).join(",")}}`;
|
|
256
|
-
async function compileAstro(code, filename) {
|
|
257
|
-
try {
|
|
258
|
-
const { transform } = await import("@astrojs/compiler");
|
|
259
|
-
const result = await transform(code, { filename });
|
|
260
|
-
return result.code;
|
|
261
|
-
} catch {
|
|
262
|
-
return null;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
async function scan(options) {
|
|
266
|
-
const { projectRoot, logger, consistency } = options;
|
|
267
|
-
const store = new KeyStore(logger, consistency);
|
|
268
|
-
const files = [];
|
|
269
|
-
for await (const entry of fs.promises.glob(GLOB_PATTERN, {
|
|
270
|
-
cwd: projectRoot,
|
|
271
|
-
exclude: (name) => name === "node_modules"
|
|
272
|
-
})) {
|
|
273
|
-
files.push(path.resolve(projectRoot, entry));
|
|
274
|
-
}
|
|
275
|
-
const results = await Promise.all(
|
|
276
|
-
files.map(async (file) => {
|
|
277
|
-
let code = await fs.promises.readFile(file, "utf-8");
|
|
278
|
-
if (!code.includes("@astroscope/i18n/translate")) {
|
|
279
|
-
return { file, keys: null };
|
|
280
|
-
}
|
|
281
|
-
if (file.endsWith(".astro")) {
|
|
282
|
-
const compiled = await compileAstro(code, file);
|
|
283
|
-
if (!compiled) {
|
|
284
|
-
return { file, keys: null };
|
|
285
|
-
}
|
|
286
|
-
code = compiled;
|
|
287
|
-
}
|
|
288
|
-
const result = await extractKeysFromFile({
|
|
289
|
-
filename: file,
|
|
290
|
-
code,
|
|
291
|
-
logger,
|
|
292
|
-
stripFallbacks: false
|
|
293
|
-
});
|
|
294
|
-
return { file, keys: result.keys.length > 0 ? result.keys : null };
|
|
295
|
-
})
|
|
296
|
-
);
|
|
297
|
-
for (const { file, keys } of results) {
|
|
298
|
-
if (keys) {
|
|
299
|
-
store.addFileKeys(file, keys);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
return store;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
// src/extraction/vite-plugin.ts
|
|
306
|
-
var VIRTUAL_MODULE_ID = "virtual:@astroscope/i18n/manifest";
|
|
307
|
-
var isVirtualModuleId = (id) => id === VIRTUAL_MODULE_ID || id.startsWith(`${VIRTUAL_MODULE_ID}?`);
|
|
308
|
-
var RESOLVED_VIRTUAL_MODULE_ID = `\0${VIRTUAL_MODULE_ID}`;
|
|
309
|
-
var isResolvedVirtualModuleId = (id) => id === RESOLVED_VIRTUAL_MODULE_ID || id.startsWith(`\0${VIRTUAL_MODULE_ID}?`);
|
|
310
|
-
var MANIFEST_FILE_NAME = "i18n-manifest.json";
|
|
311
|
-
function i18nVitePlugin(options) {
|
|
312
|
-
const { logger, consistency } = options;
|
|
313
|
-
const store = new KeyStore(logger, consistency);
|
|
314
|
-
const syncGlobalState = () => {
|
|
315
|
-
const state = getGlobalState();
|
|
316
|
-
state.extractedKeys = store.extractedKeys;
|
|
317
|
-
state.version++;
|
|
318
|
-
};
|
|
319
|
-
let isBuild = false;
|
|
320
|
-
let projectRoot = "";
|
|
321
|
-
return {
|
|
322
|
-
name: "@astroscope/i18n/extract",
|
|
323
|
-
enforce: "pre",
|
|
324
|
-
configResolved(config) {
|
|
325
|
-
const state = getGlobalState();
|
|
326
|
-
state.projectRoot = config.root;
|
|
327
|
-
isBuild = config.command === "build";
|
|
328
|
-
projectRoot = config.root;
|
|
329
|
-
},
|
|
330
|
-
async configureServer(server) {
|
|
331
|
-
if (server.config.isProduction || isBuild) {
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
const result = await scan({ projectRoot, logger, consistency });
|
|
335
|
-
store.merge(result);
|
|
336
|
-
syncGlobalState();
|
|
337
|
-
logger.info(`dev mode: scanned ${result.fileToKeys.size} files, found ${result.uniqueKeyCount} keys`);
|
|
338
|
-
},
|
|
339
|
-
resolveId(id) {
|
|
340
|
-
if (isVirtualModuleId(id)) {
|
|
341
|
-
return `\0${id}`;
|
|
342
|
-
}
|
|
343
|
-
},
|
|
344
|
-
load(id) {
|
|
345
|
-
if (isResolvedVirtualModuleId(id)) {
|
|
346
|
-
if (isBuild) {
|
|
347
|
-
return `
|
|
348
|
-
import { readFileSync } from 'node:fs';
|
|
349
|
-
import { fileURLToPath } from 'node:url';
|
|
350
|
-
import { dirname, join } from 'node:path';
|
|
351
|
-
|
|
352
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
353
|
-
const manifestJson = JSON.parse(readFileSync(join(__dirname, '${MANIFEST_FILE_NAME}'), 'utf-8'));
|
|
354
|
-
|
|
355
|
-
export const manifest = manifestJson;
|
|
356
|
-
export function getManifest() { return manifestJson; }
|
|
357
|
-
`;
|
|
358
|
-
}
|
|
359
|
-
return `
|
|
360
|
-
import { getManifest as _getManifest } from '@astroscope/i18n/extraction';
|
|
361
|
-
export const manifest = { keys: [], chunks: {} };
|
|
362
|
-
export function getManifest() { return _getManifest(); }
|
|
363
|
-
`;
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
async transform(code, filename) {
|
|
367
|
-
if (!ALL_EXTENSIONS.some((ext) => filename.endsWith(ext))) {
|
|
368
|
-
return null;
|
|
369
|
-
}
|
|
370
|
-
if (filename.includes("node_modules")) {
|
|
371
|
-
return null;
|
|
372
|
-
}
|
|
373
|
-
if (!code.includes("@astroscope/i18n/translate")) {
|
|
374
|
-
return null;
|
|
375
|
-
}
|
|
376
|
-
const result = await extractKeysFromFile({
|
|
377
|
-
filename,
|
|
378
|
-
code,
|
|
379
|
-
logger,
|
|
380
|
-
stripFallbacks: isBuild
|
|
381
|
-
});
|
|
382
|
-
store.addFileKeys(filename, result.keys);
|
|
383
|
-
syncGlobalState();
|
|
384
|
-
if (isBuild && result.code) {
|
|
385
|
-
return { code: result.code, map: result.map };
|
|
386
|
-
}
|
|
387
|
-
return null;
|
|
388
|
-
},
|
|
389
|
-
generateBundle(_, bundle) {
|
|
390
|
-
const state = getGlobalState();
|
|
391
|
-
state.chunkManifest = {};
|
|
392
|
-
state.importsManifest = {};
|
|
393
|
-
const chunksWithI18n = /* @__PURE__ */ new Set();
|
|
394
|
-
const chunkNameToFileName = /* @__PURE__ */ new Map();
|
|
395
|
-
const directImports = /* @__PURE__ */ new Map();
|
|
396
|
-
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
397
|
-
if (chunk.type === "chunk" && chunk.moduleIds) {
|
|
398
|
-
const keys = /* @__PURE__ */ new Set();
|
|
399
|
-
let hasI18nModule = false;
|
|
400
|
-
for (const moduleId of chunk.moduleIds) {
|
|
401
|
-
const moduleKeys = store.fileToKeys.get(moduleId);
|
|
402
|
-
moduleKeys?.forEach((k) => keys.add(k));
|
|
403
|
-
if (store.filesWithI18n.has(moduleId)) {
|
|
404
|
-
hasI18nModule = true;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
const chunkName = chunkIdToName(fileName.replace(/\.js$/, ""));
|
|
408
|
-
if (keys.size) {
|
|
409
|
-
state.chunkManifest[chunkName] = Array.from(keys);
|
|
410
|
-
}
|
|
411
|
-
if (hasI18nModule) {
|
|
412
|
-
chunksWithI18n.add(chunkName);
|
|
413
|
-
}
|
|
414
|
-
chunkNameToFileName.set(chunkName, fileName);
|
|
415
|
-
const imports = [];
|
|
416
|
-
for (const importedFile of chunk.imports) {
|
|
417
|
-
const baseName = importedFile.replace(/^.*\//, "").replace(/\.js$/, "");
|
|
418
|
-
const importedChunkName = chunkIdToName(baseName);
|
|
419
|
-
imports.push(importedChunkName);
|
|
420
|
-
}
|
|
421
|
-
directImports.set(chunkName, imports);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
const flattenImports = (chunkName, visited) => {
|
|
425
|
-
if (visited.has(chunkName)) return [];
|
|
426
|
-
visited.add(chunkName);
|
|
427
|
-
const result = /* @__PURE__ */ new Set();
|
|
428
|
-
const imports = directImports.get(chunkName) ?? [];
|
|
429
|
-
for (const imported of imports) {
|
|
430
|
-
if (state.chunkManifest[imported]) {
|
|
431
|
-
result.add(imported);
|
|
432
|
-
}
|
|
433
|
-
for (const descendant of flattenImports(imported, visited)) {
|
|
434
|
-
result.add(descendant);
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
visited.delete(chunkName);
|
|
438
|
-
return Array.from(result);
|
|
439
|
-
};
|
|
440
|
-
for (const chunkName of directImports.keys()) {
|
|
441
|
-
const flattened = flattenImports(chunkName, /* @__PURE__ */ new Set());
|
|
442
|
-
if (flattened.length > 0) {
|
|
443
|
-
state.importsManifest[chunkName] = flattened;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
447
|
-
if (chunk.type !== "chunk") continue;
|
|
448
|
-
const chunkName = chunkIdToName(fileName.replace(/\.js$/, ""));
|
|
449
|
-
if (!chunksWithI18n.has(chunkName)) continue;
|
|
450
|
-
const loaderCode = `if(typeof window!=='undefined'&&window.__i18n__){const _=window.__i18n__,h=_.hashes[${JSON.stringify(chunkName)}];if(h)await import(\`/_i18n/\${_.locale}/${chunkName}.\${h}.js\`);}`;
|
|
451
|
-
const s = new MagicString(chunk.code);
|
|
452
|
-
s.prepend(loaderCode);
|
|
453
|
-
chunk.code = s.toString();
|
|
454
|
-
if (chunk.map) {
|
|
455
|
-
chunk.map = s.generateMap({ hires: true });
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
logger.info(`manifest: ${Object.keys(state.chunkManifest).length} chunks, ${store.uniqueKeyCount} keys`);
|
|
459
|
-
if (consistency === "error" && store.hasErrors) {
|
|
460
|
-
throw new Error("i18n: build failed due to translation key inconsistencies");
|
|
461
|
-
}
|
|
462
|
-
},
|
|
463
|
-
writeBundle(outputOptions) {
|
|
464
|
-
if (this.environment.name === "client" && outputOptions.dir) {
|
|
465
|
-
const chunksDir = path2.resolve(outputOptions.dir, "..", "server", "chunks");
|
|
466
|
-
const manifestPath = path2.join(chunksDir, MANIFEST_FILE_NAME);
|
|
467
|
-
if (fs2.existsSync(chunksDir)) {
|
|
468
|
-
fs2.writeFileSync(manifestPath, JSON.stringify(getManifest()));
|
|
469
|
-
} else {
|
|
470
|
-
logger.error(`server chunks directory not found, cannot write manifest to ${manifestPath}`);
|
|
471
|
-
}
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
export {
|
|
478
|
-
i18nVitePlugin
|
|
479
|
-
};
|
package/dist/chunk-VGPVG5JP.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
// src/shared/meta.ts
|
|
2
|
-
function normalizeMeta(meta) {
|
|
3
|
-
return typeof meta === "string" ? { fallback: meta } : meta;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
// src/shared/rich.ts
|
|
7
|
-
var REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.element");
|
|
8
|
-
var REACT_TRANSITIONAL_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for("react.transitional.element");
|
|
9
|
-
function isReactElement(value) {
|
|
10
|
-
if (typeof value !== "object" || value === null || !("$$typeof" in value)) {
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
13
|
-
const type = value.$$typeof;
|
|
14
|
-
return type === REACT_ELEMENT_TYPE || type === REACT_TRANSITIONAL_ELEMENT_TYPE;
|
|
15
|
-
}
|
|
16
|
-
function addKeyIfNeeded(element, key) {
|
|
17
|
-
if (isReactElement(element) && element.key === null) {
|
|
18
|
-
return { ...element, key };
|
|
19
|
-
}
|
|
20
|
-
return element;
|
|
21
|
-
}
|
|
22
|
-
function isMarkupPart(part) {
|
|
23
|
-
return part.type === "markup";
|
|
24
|
-
}
|
|
25
|
-
function partsToNodes(parts, components) {
|
|
26
|
-
const result = [];
|
|
27
|
-
const stack = [];
|
|
28
|
-
let keyIndex = 0;
|
|
29
|
-
for (const part of parts) {
|
|
30
|
-
const target = stack.length > 0 ? stack[stack.length - 1].children : result;
|
|
31
|
-
if (isMarkupPart(part)) {
|
|
32
|
-
if (part.kind === "open") {
|
|
33
|
-
stack.push({ name: part.name, children: [] });
|
|
34
|
-
} else if (part.kind === "close") {
|
|
35
|
-
const frame = stack.pop();
|
|
36
|
-
if (!frame) {
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
const component = components[frame.name];
|
|
40
|
-
const parent = stack.length > 0 ? stack[stack.length - 1].children : result;
|
|
41
|
-
if (component) {
|
|
42
|
-
parent.push(addKeyIfNeeded(component(frame.children), `rich-${keyIndex++}`));
|
|
43
|
-
} else {
|
|
44
|
-
parent.push(...frame.children);
|
|
45
|
-
}
|
|
46
|
-
} else if (part.kind === "standalone") {
|
|
47
|
-
const component = components[part.name];
|
|
48
|
-
if (component) {
|
|
49
|
-
target.push(addKeyIfNeeded(component([]), `rich-${keyIndex++}`));
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
} else if (part.type === "text") {
|
|
53
|
-
target.push(part.value);
|
|
54
|
-
} else if (part.type === "bidiIsolation") {
|
|
55
|
-
} else {
|
|
56
|
-
if ("value" in part && part.value !== void 0 && part.value !== null) {
|
|
57
|
-
const stringValue = String(part.value);
|
|
58
|
-
target.push(stringValue);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
while (stack.length > 0) {
|
|
63
|
-
const frame = stack.pop();
|
|
64
|
-
const parent = stack.length > 0 ? stack[stack.length - 1].children : result;
|
|
65
|
-
parent.push(...frame.children);
|
|
66
|
-
}
|
|
67
|
-
return result;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export {
|
|
71
|
-
normalizeMeta,
|
|
72
|
-
partsToNodes
|
|
73
|
-
};
|
package/dist/i18n-B--L7OQk.d.ts
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { E as ExtractionManifest } from './types-ChMT6Vbd.js';
|
|
2
|
-
import { T as TranslationMeta, C as CompiledTranslations, R as RawTranslations } from './types-DNRFj1XA.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Fallback behavior when translation is missing
|
|
6
|
-
*/
|
|
7
|
-
type FallbackBehavior = 'key' | 'fallback' | 'throw' | ((key: string, meta?: TranslationMeta | undefined) => string);
|
|
8
|
-
/**
|
|
9
|
-
* Request-scoped i18n context
|
|
10
|
-
*/
|
|
11
|
-
type I18nContext = {
|
|
12
|
-
locale: string;
|
|
13
|
-
translations: CompiledTranslations;
|
|
14
|
-
rawTranslations: RawTranslations;
|
|
15
|
-
fallback: FallbackBehavior;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
type I18nConfig = {
|
|
19
|
-
locales: string[];
|
|
20
|
-
defaultLocale?: string | undefined;
|
|
21
|
-
fallback?: FallbackBehavior | undefined;
|
|
22
|
-
};
|
|
23
|
-
type NormalizedConfig = {
|
|
24
|
-
locales: string[];
|
|
25
|
-
defaultLocale: string;
|
|
26
|
-
fallback: FallbackBehavior;
|
|
27
|
-
};
|
|
28
|
-
declare class I18nSingleton {
|
|
29
|
-
private config;
|
|
30
|
-
private rawCache;
|
|
31
|
-
private mergedCache;
|
|
32
|
-
private compiledCache;
|
|
33
|
-
private hashCache;
|
|
34
|
-
private scriptCache;
|
|
35
|
-
private chunkCache;
|
|
36
|
-
private manifestGetter;
|
|
37
|
-
private manifestVersion;
|
|
38
|
-
configure(config: I18nConfig): Promise<void>;
|
|
39
|
-
isConfigured(): boolean;
|
|
40
|
-
getConfig(): NormalizedConfig;
|
|
41
|
-
setTranslations(locale: string, raw: RawTranslations): void;
|
|
42
|
-
getTranslations(locale: string): RawTranslations;
|
|
43
|
-
getCompiledTranslations(locale: string): CompiledTranslations;
|
|
44
|
-
/**
|
|
45
|
-
* Get the extraction manifest (keys + chunks).
|
|
46
|
-
* - keys: translation keys extracted from codebase with metadata
|
|
47
|
-
* - chunks: mapping of chunk names to their translation keys
|
|
48
|
-
*/
|
|
49
|
-
getManifest(): ExtractionManifest;
|
|
50
|
-
getHashes(locale: string): Record<string, string>;
|
|
51
|
-
/**
|
|
52
|
-
* Get the encoded chunk response body for a locale/chunk combination.
|
|
53
|
-
* Cached to avoid repeated JSON.stringify and encoding on each request.
|
|
54
|
-
* Returns undefined if chunk not found in manifest.
|
|
55
|
-
*/
|
|
56
|
-
getChunkBody(locale: string, chunkName: string): Uint8Array | undefined;
|
|
57
|
-
/**
|
|
58
|
-
* Get the inline script for I18nScript component.
|
|
59
|
-
* Cached per locale, invalidated when translations change.
|
|
60
|
-
*/
|
|
61
|
-
getClientScript(locale: string): string;
|
|
62
|
-
private createClientScript;
|
|
63
|
-
/**
|
|
64
|
-
* Clear translations for specified locale(s).
|
|
65
|
-
* @param locales - Locale(s) to clear, or all if not specified
|
|
66
|
-
*/
|
|
67
|
-
clear(locales?: string | string[] | undefined): void;
|
|
68
|
-
/**
|
|
69
|
-
* invalidate derived caches when the extraction manifest has changed (dev mode HMR)
|
|
70
|
-
*/
|
|
71
|
-
private invalidateIfManifestChanged;
|
|
72
|
-
private resolveLocales;
|
|
73
|
-
}
|
|
74
|
-
declare const i18n: I18nSingleton;
|
|
75
|
-
|
|
76
|
-
export { type FallbackBehavior as F, type I18nConfig as I, type I18nContext as a, i18n as i };
|
package/dist/types-B_8vAmvv.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Consistency check level for translation keys.
|
|
3
|
-
* Controls behavior when the same key has different fallbacks/variables across files.
|
|
4
|
-
*
|
|
5
|
-
* - 'warn' (default): Log a warning but continue
|
|
6
|
-
* - 'error': Fail the build
|
|
7
|
-
* - 'off': Disable consistency checking
|
|
8
|
-
*/
|
|
9
|
-
type ConsistencyCheckLevel = 'off' | 'warn' | 'error';
|
|
10
|
-
interface I18nOptions {
|
|
11
|
-
/**
|
|
12
|
-
* How to handle inconsistent translation keys (same key with different fallbacks/variables).
|
|
13
|
-
* @default 'warn'
|
|
14
|
-
*/
|
|
15
|
-
consistency?: ConsistencyCheckLevel | undefined;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export type { ConsistencyCheckLevel as C, I18nOptions as I };
|