@inlang/paraglide-js 2.29.0 → 2.29.2

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.
Files changed (34) hide show
  1. package/dist/compiler/compile-bundle.js +58 -12
  2. package/dist/compiler/compile-bundle.js.map +1 -1
  3. package/dist/compiler/compile-bundle.test.js +208 -26
  4. package/dist/compiler/compile-bundle.test.js.map +1 -1
  5. package/dist/compiler/compile-lifecycle.test.js +83 -0
  6. package/dist/compiler/compile-lifecycle.test.js.map +1 -1
  7. package/dist/compiler/compile-message.d.ts +9 -0
  8. package/dist/compiler/compile-message.js +29 -12
  9. package/dist/compiler/compile-message.js.map +1 -1
  10. package/dist/compiler/compile-project.js +6 -1
  11. package/dist/compiler/compile-project.js.map +1 -1
  12. package/dist/compiler/compile-project.test.js +157 -0
  13. package/dist/compiler/compile-project.test.js.map +1 -1
  14. package/dist/compiler/compile.js +12 -0
  15. package/dist/compiler/compile.js.map +1 -1
  16. package/dist/compiler/compiler-options.d.ts +5 -2
  17. package/dist/compiler/compiler-options.js.map +1 -1
  18. package/dist/compiler/emit-ts-declarations.d.ts +4 -1
  19. package/dist/compiler/emit-ts-declarations.js +18 -11
  20. package/dist/compiler/emit-ts-declarations.js.map +1 -1
  21. package/dist/compiler/emit-ts-declarations.native.test.d.ts +1 -0
  22. package/dist/compiler/emit-ts-declarations.native.test.js +86 -0
  23. package/dist/compiler/emit-ts-declarations.native.test.js.map +1 -0
  24. package/dist/compiler/emit-ts-declarations.test.js +3 -0
  25. package/dist/compiler/emit-ts-declarations.test.js.map +1 -1
  26. package/dist/compiler/resolve-tsc-js-path.d.ts +6 -0
  27. package/dist/compiler/resolve-tsc-js-path.js +34 -1
  28. package/dist/compiler/resolve-tsc-js-path.js.map +1 -1
  29. package/dist/compiler/resolve-tsc-js-path.test.d.ts +1 -0
  30. package/dist/compiler/resolve-tsc-js-path.test.js +31 -0
  31. package/dist/compiler/resolve-tsc-js-path.test.js.map +1 -0
  32. package/dist/services/env-variables/index.js +1 -1
  33. package/dist/services/env-variables/index.js.map +1 -1
  34. package/package.json +1 -1
@@ -108,7 +108,12 @@ export const compileProject = async (args) => {
108
108
  }
109
109
  }
110
110
  if (optionsWithDefaults.emitTsDeclarations) {
111
- const declarations = await emitTsDeclarations(output);
111
+ // Additional JavaScript can import project dependencies. Keep the
112
+ // compiler API's project-relative resolution: the native CLI stages
113
+ // files in an OS temporary directory, outside the project's packages.
114
+ const declarations = await emitTsDeclarations(output, {
115
+ allowNativeAlias: !Object.keys(optionsWithDefaults.additionalFiles ?? {}).some((fileName) => fileName.endsWith(".js")),
116
+ });
112
117
  Object.assign(output, declarations);
113
118
  }
114
119
  return output;
@@ -1 +1 @@
1
- {"version":3,"file":"compile-project.js","sourceRoot":"","sources":["../../src/compiler/compile-project.ts"],"names":[],"mappings":"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","sourcesContent":["import { compileBundle } from \"./compile-bundle.js\";\nimport { selectBundleNested, type InlangProject } from \"@inlang/sdk\";\nimport { lookup } from \"../services/lookup.js\";\nimport * as localeModules from \"./output-structure/locale-modules.js\";\nimport * as messageModules from \"./output-structure/message-modules.js\";\nimport {\n\tdefaultCompilerOptions,\n\ttype CompilerOptions,\n} from \"./compiler-options.js\";\nimport { createRuntimeFile } from \"./runtime/create-runtime.js\";\nimport { createServerFile } from \"./server/create-server-file.js\";\nimport { createRegistry } from \"./registry.js\";\nimport { emitTsDeclarations } from \"./emit-ts-declarations.js\";\nimport { createReadme } from \"./create-readme.js\";\nimport { perLocaleBuildStaticLocaleExpression } from \"./per-locale-build.js\";\n\nconst outputStructures = {\n\t\"locale-modules\": localeModules,\n\t\"message-modules\": messageModules,\n};\n\n/**\n * Takes an inlang project and compiles it into a set of files.\n *\n * Use this function for more programmatic control than `compile()`.\n * You can adjust the output structure and get the compiled files as a return value.\n *\n * @example\n * const output = await compileProject({ project, projectPath: \"./project.inlang\" });\n * await writeOutput('path', output, fs.promises);\n */\nexport const compileProject = async (args: {\n\tproject: InlangProject;\n\tprojectPath?: string;\n\tcompilerOptions?: Omit<CompilerOptions, \"fs\" | \"project\" | \"outdir\">;\n}): Promise<Record<string, string>> => {\n\tconst optionsWithDefaults = {\n\t\t...defaultCompilerOptions,\n\t\t...args.compilerOptions,\n\t};\n\tawait ensureURLPatternAvailable();\n\tvalidateRouteStrategyMatchers(optionsWithDefaults.routeStrategies);\n\n\tconst settings = await args.project.settings.get();\n\tconst bundles = await selectBundleNested(args.project.db).execute();\n\n\t//Maps each language to it's fallback\n\t//If there is no fallback, it will be undefined\n\tconst fallbackMap = getFallbackMap(settings.locales, settings.baseLocale);\n\n\tconst outputStructure = outputStructures[optionsWithDefaults.outputStructure];\n\n\tconst compiledBundles = bundles.map((bundle) =>\n\t\tcompileBundle({\n\t\t\tbundle,\n\t\t\tfallbackMap,\n\t\t\tinlineMessages: optionsWithDefaults.outputStructure === \"message-modules\",\n\t\t\tmessageReferenceExpression: outputStructure.messageReferenceExpression,\n\t\t\tsettings,\n\t\t\texperimentalMiddlewareLocaleSplitting:\n\t\t\t\toptionsWithDefaults.experimentalMiddlewareLocaleSplitting,\n\t\t\texperimentalStaticLocale: optionsWithDefaults.experimentalStaticLocale,\n\t\t})\n\t);\n\n\tconst output: Record<string, string> = {\n\t\t[\"runtime.js\"]: createRuntimeFile({\n\t\t\tbaseLocale: settings.baseLocale,\n\t\t\tlocales: settings.locales,\n\t\t\tcompilerOptions: optionsWithDefaults,\n\t\t}),\n\t\t[\"server.js\"]: createServerFile({\n\t\t\tcompiledBundles,\n\t\t\tcompilerOptions: optionsWithDefaults,\n\t\t}),\n\t\t[\"registry.js\"]: createRegistry(),\n\t\t[\"messages.js\"]: [\n\t\t\t\"export * from './messages/_index.js'\",\n\t\t\t\"// enabling auto-import by exposing all messages as m\",\n\t\t\t\"export * as m from './messages/_index.js'\",\n\t\t].join(\"\\n\"),\n\t};\n\n\t// generate the output modules\n\tObject.assign(\n\t\toutput,\n\t\toutputStructure.generateOutput(\n\t\t\tcompiledBundles,\n\t\t\tsettings,\n\t\t\tfallbackMap,\n\t\t\toptionsWithDefaults.experimentalMiddlewareLocaleSplitting\n\t\t)\n\t);\n\n\tif (optionsWithDefaults.emitGitIgnore) {\n\t\toutput[\".gitignore\"] = ignoreDirectory;\n\t}\n\n\tif (optionsWithDefaults.emitPrettierIgnore) {\n\t\toutput[\".prettierignore\"] = ignoreDirectory;\n\t}\n\n\tif (optionsWithDefaults.emitReadme) {\n\t\toutput[\"README.md\"] = createReadme({\n\t\t\tprojectPath: args.projectPath,\n\t\t\tgitignored: optionsWithDefaults.emitGitIgnore,\n\t\t});\n\t}\n\n\t// Declare the generated message modules side-effect-free so bundlers can drop\n\t// unused re-exports from the `m` barrel per entry, instead of bundling every\n\t// message used anywhere in the app into one shared chunk that every entry\n\t// downloads. Scoped to `messages/` so `runtime.js` (one level up, which has\n\t// real side effects) is unaffected. This also lets locale-specialized builds\n\t// discard the unselected locale modules before Rolldown creates source maps.\n\t//\n\t// `type: \"module\"` is required: this package.json creates a new module scope\n\t// for `messages/`, and a package.json without a `type` field defaults to\n\t// CommonJS in Node — even when the consuming project is `type: \"module\"`.\n\t// Without it, the generated ESM `.js` files in `messages/` would be treated\n\t// as CommonJS and fail to resolve.\n\t// See https://github.com/opral/paraglide-js/issues/668\n\tif (\n\t\toptionsWithDefaults.outputStructure === \"message-modules\" ||\n\t\toptionsWithDefaults.experimentalStaticLocale ===\n\t\t\tperLocaleBuildStaticLocaleExpression\n\t) {\n\t\toutput[\"messages/package.json\"] =\n\t\t\tJSON.stringify({ type: \"module\", sideEffects: false }, undefined, \"\\t\") +\n\t\t\t\"\\n\";\n\t}\n\n\tfor (const [filename, content] of Object.entries(\n\t\toptionsWithDefaults.additionalFiles ?? {}\n\t)) {\n\t\toutput[filename] = content;\n\t}\n\n\tfor (const [filename, content] of Object.entries(output)) {\n\t\tif (optionsWithDefaults.includeEslintDisableComment) {\n\t\t\tif (filename.endsWith(\".js\")) {\n\t\t\t\toutput[filename] = `/* eslint-disable */\\n${content}`;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (optionsWithDefaults.emitTsDeclarations) {\n\t\tconst declarations = await emitTsDeclarations(output);\n\t\tObject.assign(output, declarations);\n\t}\n\n\treturn output;\n};\n\nexport function getFallbackMap<T extends string>(\n\tlocales: T[],\n\tbaseLocale: NoInfer<T>\n): Record<T, T | undefined> {\n\treturn Object.fromEntries(\n\t\tlocales.map((lang) => {\n\t\t\tif (lang === baseLocale) return [lang, undefined];\n\t\t\tconst fallbackLanguage = lookup(lang, {\n\t\t\t\tlocales: locales.filter((l) => l !== lang),\n\t\t\t\tbaseLocale,\n\t\t\t});\n\n\t\t\tif (lang === fallbackLanguage) return [lang, undefined];\n\t\t\telse return [lang, fallbackLanguage];\n\t\t})\n\t) as Record<T, T | undefined>;\n}\n\nconst ignoreDirectory = `# ignore everything because the directory is auto-generated by inlang paraglide-js\n# for more info visit https://paraglidejs.com\n*\n`;\n\nasync function ensureURLPatternAvailable() {\n\ttry {\n\t\tnew URLPattern({ pathname: \"/:path(.*)?\" });\n\t} catch {\n\t\tawait import(\"urlpattern-polyfill\");\n\t}\n}\n\nfunction validateRouteStrategyMatchers(\n\trouteStrategies: CompilerOptions[\"routeStrategies\"]\n) {\n\tif (!routeStrategies?.length) {\n\t\treturn;\n\t}\n\n\tfor (const [index, routeStrategy] of routeStrategies.entries()) {\n\t\ttry {\n\t\t\tnew URLPattern(routeStrategy.match, \"https://example.com\");\n\t\t} catch (error) {\n\t\t\tconst details = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid routeStrategies[${index}].match \"${routeStrategy.match}\". URLPattern parsing failed: ${details}`\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"compile-project.js","sourceRoot":"","sources":["../../src/compiler/compile-project.ts"],"names":[],"mappings":"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","sourcesContent":["import { compileBundle } from \"./compile-bundle.js\";\nimport { selectBundleNested, type InlangProject } from \"@inlang/sdk\";\nimport { lookup } from \"../services/lookup.js\";\nimport * as localeModules from \"./output-structure/locale-modules.js\";\nimport * as messageModules from \"./output-structure/message-modules.js\";\nimport {\n\tdefaultCompilerOptions,\n\ttype CompilerOptions,\n} from \"./compiler-options.js\";\nimport { createRuntimeFile } from \"./runtime/create-runtime.js\";\nimport { createServerFile } from \"./server/create-server-file.js\";\nimport { createRegistry } from \"./registry.js\";\nimport { emitTsDeclarations } from \"./emit-ts-declarations.js\";\nimport { createReadme } from \"./create-readme.js\";\nimport { perLocaleBuildStaticLocaleExpression } from \"./per-locale-build.js\";\n\nconst outputStructures = {\n\t\"locale-modules\": localeModules,\n\t\"message-modules\": messageModules,\n};\n\n/**\n * Takes an inlang project and compiles it into a set of files.\n *\n * Use this function for more programmatic control than `compile()`.\n * You can adjust the output structure and get the compiled files as a return value.\n *\n * @example\n * const output = await compileProject({ project, projectPath: \"./project.inlang\" });\n * await writeOutput('path', output, fs.promises);\n */\nexport const compileProject = async (args: {\n\tproject: InlangProject;\n\tprojectPath?: string;\n\tcompilerOptions?: Omit<CompilerOptions, \"fs\" | \"project\" | \"outdir\">;\n}): Promise<Record<string, string>> => {\n\tconst optionsWithDefaults = {\n\t\t...defaultCompilerOptions,\n\t\t...args.compilerOptions,\n\t};\n\tawait ensureURLPatternAvailable();\n\tvalidateRouteStrategyMatchers(optionsWithDefaults.routeStrategies);\n\n\tconst settings = await args.project.settings.get();\n\tconst bundles = await selectBundleNested(args.project.db).execute();\n\n\t//Maps each language to it's fallback\n\t//If there is no fallback, it will be undefined\n\tconst fallbackMap = getFallbackMap(settings.locales, settings.baseLocale);\n\n\tconst outputStructure = outputStructures[optionsWithDefaults.outputStructure];\n\n\tconst compiledBundles = bundles.map((bundle) =>\n\t\tcompileBundle({\n\t\t\tbundle,\n\t\t\tfallbackMap,\n\t\t\tinlineMessages: optionsWithDefaults.outputStructure === \"message-modules\",\n\t\t\tmessageReferenceExpression: outputStructure.messageReferenceExpression,\n\t\t\tsettings,\n\t\t\texperimentalMiddlewareLocaleSplitting:\n\t\t\t\toptionsWithDefaults.experimentalMiddlewareLocaleSplitting,\n\t\t\texperimentalStaticLocale: optionsWithDefaults.experimentalStaticLocale,\n\t\t})\n\t);\n\n\tconst output: Record<string, string> = {\n\t\t[\"runtime.js\"]: createRuntimeFile({\n\t\t\tbaseLocale: settings.baseLocale,\n\t\t\tlocales: settings.locales,\n\t\t\tcompilerOptions: optionsWithDefaults,\n\t\t}),\n\t\t[\"server.js\"]: createServerFile({\n\t\t\tcompiledBundles,\n\t\t\tcompilerOptions: optionsWithDefaults,\n\t\t}),\n\t\t[\"registry.js\"]: createRegistry(),\n\t\t[\"messages.js\"]: [\n\t\t\t\"export * from './messages/_index.js'\",\n\t\t\t\"// enabling auto-import by exposing all messages as m\",\n\t\t\t\"export * as m from './messages/_index.js'\",\n\t\t].join(\"\\n\"),\n\t};\n\n\t// generate the output modules\n\tObject.assign(\n\t\toutput,\n\t\toutputStructure.generateOutput(\n\t\t\tcompiledBundles,\n\t\t\tsettings,\n\t\t\tfallbackMap,\n\t\t\toptionsWithDefaults.experimentalMiddlewareLocaleSplitting\n\t\t)\n\t);\n\n\tif (optionsWithDefaults.emitGitIgnore) {\n\t\toutput[\".gitignore\"] = ignoreDirectory;\n\t}\n\n\tif (optionsWithDefaults.emitPrettierIgnore) {\n\t\toutput[\".prettierignore\"] = ignoreDirectory;\n\t}\n\n\tif (optionsWithDefaults.emitReadme) {\n\t\toutput[\"README.md\"] = createReadme({\n\t\t\tprojectPath: args.projectPath,\n\t\t\tgitignored: optionsWithDefaults.emitGitIgnore,\n\t\t});\n\t}\n\n\t// Declare the generated message modules side-effect-free so bundlers can drop\n\t// unused re-exports from the `m` barrel per entry, instead of bundling every\n\t// message used anywhere in the app into one shared chunk that every entry\n\t// downloads. Scoped to `messages/` so `runtime.js` (one level up, which has\n\t// real side effects) is unaffected. This also lets locale-specialized builds\n\t// discard the unselected locale modules before Rolldown creates source maps.\n\t//\n\t// `type: \"module\"` is required: this package.json creates a new module scope\n\t// for `messages/`, and a package.json without a `type` field defaults to\n\t// CommonJS in Node — even when the consuming project is `type: \"module\"`.\n\t// Without it, the generated ESM `.js` files in `messages/` would be treated\n\t// as CommonJS and fail to resolve.\n\t// See https://github.com/opral/paraglide-js/issues/668\n\tif (\n\t\toptionsWithDefaults.outputStructure === \"message-modules\" ||\n\t\toptionsWithDefaults.experimentalStaticLocale ===\n\t\t\tperLocaleBuildStaticLocaleExpression\n\t) {\n\t\toutput[\"messages/package.json\"] =\n\t\t\tJSON.stringify({ type: \"module\", sideEffects: false }, undefined, \"\\t\") +\n\t\t\t\"\\n\";\n\t}\n\n\tfor (const [filename, content] of Object.entries(\n\t\toptionsWithDefaults.additionalFiles ?? {}\n\t)) {\n\t\toutput[filename] = content;\n\t}\n\n\tfor (const [filename, content] of Object.entries(output)) {\n\t\tif (optionsWithDefaults.includeEslintDisableComment) {\n\t\t\tif (filename.endsWith(\".js\")) {\n\t\t\t\toutput[filename] = `/* eslint-disable */\\n${content}`;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (optionsWithDefaults.emitTsDeclarations) {\n\t\t// Additional JavaScript can import project dependencies. Keep the\n\t\t// compiler API's project-relative resolution: the native CLI stages\n\t\t// files in an OS temporary directory, outside the project's packages.\n\t\tconst declarations = await emitTsDeclarations(output, {\n\t\t\tallowNativeAlias: !Object.keys(\n\t\t\t\toptionsWithDefaults.additionalFiles ?? {}\n\t\t\t).some((fileName) => fileName.endsWith(\".js\")),\n\t\t});\n\t\tObject.assign(output, declarations);\n\t}\n\n\treturn output;\n};\n\nexport function getFallbackMap<T extends string>(\n\tlocales: T[],\n\tbaseLocale: NoInfer<T>\n): Record<T, T | undefined> {\n\treturn Object.fromEntries(\n\t\tlocales.map((lang) => {\n\t\t\tif (lang === baseLocale) return [lang, undefined];\n\t\t\tconst fallbackLanguage = lookup(lang, {\n\t\t\t\tlocales: locales.filter((l) => l !== lang),\n\t\t\t\tbaseLocale,\n\t\t\t});\n\n\t\t\tif (lang === fallbackLanguage) return [lang, undefined];\n\t\t\telse return [lang, fallbackLanguage];\n\t\t})\n\t) as Record<T, T | undefined>;\n}\n\nconst ignoreDirectory = `# ignore everything because the directory is auto-generated by inlang paraglide-js\n# for more info visit https://paraglidejs.com\n*\n`;\n\nasync function ensureURLPatternAvailable() {\n\ttry {\n\t\tnew URLPattern({ pathname: \"/:path(.*)?\" });\n\t} catch {\n\t\tawait import(\"urlpattern-polyfill\");\n\t}\n}\n\nfunction validateRouteStrategyMatchers(\n\trouteStrategies: CompilerOptions[\"routeStrategies\"]\n) {\n\tif (!routeStrategies?.length) {\n\t\treturn;\n\t}\n\n\tfor (const [index, routeStrategy] of routeStrategies.entries()) {\n\t\ttry {\n\t\t\tnew URLPattern(routeStrategy.match, \"https://example.com\");\n\t\t} catch (error) {\n\t\t\tconst details = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid routeStrategies[${index}].match \"${routeStrategy.match}\". URLPattern parsing failed: ${details}`\n\t\t\t);\n\t\t}\n\t}\n}\n"]}
@@ -181,6 +181,163 @@ test("inlines static text and retains only fallback helpers under strict checkJs
181
181
  expect(m.plain_greeting({}, { locale: "de" })).toBe("Hallo");
182
182
  expect(m.plain_greeting({}, { locale: "de-AT" })).toBe("Hallo");
183
183
  });
184
+ test("inlines messages with inputs and plurals under strict checkJs", async () => {
185
+ const project = await loadProjectInMemory({
186
+ blob: await newProject({
187
+ settings: {
188
+ baseLocale: "en",
189
+ locales: ["en", "de", "de-AT"],
190
+ },
191
+ }),
192
+ });
193
+ const text = (value) => [{ type: "text", value }];
194
+ await insertBundleNested(project.db, createBundleNested({
195
+ id: "welcome",
196
+ declarations: [{ type: "input-variable", name: "name" }],
197
+ messages: ["Hello", "Hallo"].map((greeting, index) => ({
198
+ locale: index === 0 ? "en" : "de",
199
+ variants: [
200
+ {
201
+ pattern: [
202
+ { type: "text", value: `${greeting} ` },
203
+ {
204
+ type: "expression",
205
+ arg: { type: "variable-reference", name: "name" },
206
+ },
207
+ ],
208
+ },
209
+ ],
210
+ })),
211
+ }));
212
+ await insertBundleNested(project.db, createBundleNested({
213
+ id: "cats",
214
+ declarations: [
215
+ { type: "input-variable", name: "count" },
216
+ {
217
+ type: "local-variable",
218
+ name: "countPlural",
219
+ value: {
220
+ type: "expression",
221
+ arg: { type: "variable-reference", name: "count" },
222
+ annotation: {
223
+ type: "function-reference",
224
+ name: "plural",
225
+ options: [],
226
+ },
227
+ },
228
+ },
229
+ ],
230
+ // de-AT has its own plural, so every locale declares `countPlural`.
231
+ messages: [
232
+ ["en", "One cat", " cats"],
233
+ ["de", "Eine Katze", " Katzen"],
234
+ ["de-AT", "Ein Katzerl", " Katzerl"],
235
+ ].map(([locale, one, other]) => ({
236
+ locale: locale,
237
+ selectors: [{ type: "variable-reference", name: "countPlural" }],
238
+ variants: [
239
+ {
240
+ matches: [
241
+ { type: "literal-match", key: "countPlural", value: "one" },
242
+ ],
243
+ pattern: text(one),
244
+ },
245
+ {
246
+ matches: [{ type: "catchall-match", key: "countPlural" }],
247
+ pattern: [
248
+ {
249
+ type: "expression",
250
+ arg: { type: "variable-reference", name: "count" },
251
+ },
252
+ { type: "text", value: other },
253
+ ],
254
+ },
255
+ ],
256
+ })),
257
+ }));
258
+ // The only declared input is never read, so the dispatcher marks it used.
259
+ await insertBundleNested(project.db, createBundleNested({
260
+ id: "unit_label",
261
+ declarations: [
262
+ { type: "input-variable", name: "unused" },
263
+ {
264
+ type: "local-variable",
265
+ name: "unit",
266
+ value: {
267
+ type: "expression",
268
+ arg: { type: "literal", value: "kg" },
269
+ },
270
+ },
271
+ ],
272
+ messages: [
273
+ ["en", "Weight in "],
274
+ ["de", "Gewicht in "],
275
+ ["de-AT", "Gewicht in "],
276
+ ].map(([locale, label]) => ({
277
+ locale: locale,
278
+ variants: [
279
+ {
280
+ pattern: [
281
+ { type: "text", value: label },
282
+ {
283
+ type: "expression",
284
+ arg: { type: "variable-reference", name: "unit" },
285
+ },
286
+ ],
287
+ },
288
+ ],
289
+ })),
290
+ }));
291
+ const output = await compileProject({
292
+ project,
293
+ compilerOptions: { outputStructure: "message-modules" },
294
+ });
295
+ // Only the message that de-AT's missing-locale alias calls keeps its function.
296
+ expect(output["messages/welcome.js"]).not.toContain("const en_welcome =");
297
+ expect(output["messages/welcome.js"]).toContain("const de_welcome =");
298
+ expect(output["messages/cats.js"]).not.toMatch(/const \w+_cats =/);
299
+ expect(output["messages/unit_label.js"]).not.toMatch(/const \w+_unit_label =/);
300
+ const tsProject = await typescriptProject({
301
+ useInMemoryFileSystem: true,
302
+ compilerOptions: {
303
+ outDir: "dist",
304
+ declaration: true,
305
+ allowJs: true,
306
+ checkJs: true,
307
+ noImplicitAny: true,
308
+ noUnusedLocals: true,
309
+ noUnusedParameters: true,
310
+ noImplicitReturns: true,
311
+ noImplicitThis: true,
312
+ noUncheckedIndexedAccess: true,
313
+ noPropertyAccessFromIndexSignature: true,
314
+ module: ts.ModuleKind.Node16,
315
+ strict: true,
316
+ },
317
+ });
318
+ for (const [fileName, code] of Object.entries(output)) {
319
+ if (fileName.endsWith(".js") || fileName.endsWith(".ts")) {
320
+ tsProject.createSourceFile(fileName, code);
321
+ }
322
+ }
323
+ const diagnostics = ts
324
+ .getPreEmitDiagnostics(tsProject.createProgram())
325
+ .map((d) => `${d.file?.fileName}: ${ts.flattenDiagnosticMessageText(d.messageText, "\n")}`)
326
+ .filter((text) => !text.includes("Cannot find module 'async_hooks'"));
327
+ expect(diagnostics).toEqual([]);
328
+ const { m } = await importCode(await bundleCode(output, `export * as m from "./paraglide/messages.js"`));
329
+ expect(m.welcome({ name: "Ada" }, { locale: "en" })).toBe("Hello Ada");
330
+ expect(m.welcome({ name: "Ada" }, { locale: "de" })).toBe("Hallo Ada");
331
+ expect(m.welcome({ name: "Ada" }, { locale: "de-AT" })).toBe("Hallo Ada");
332
+ expect(m.cats({ count: 1 }, { locale: "en" })).toBe("One cat");
333
+ expect(m.cats({ count: 3 }, { locale: "en" })).toBe("3 cats");
334
+ expect(m.cats({ count: 3 }, { locale: "de" })).toBe("3 Katzen");
335
+ expect(m.cats({ count: 1 }, { locale: "de" })).toBe("Eine Katze");
336
+ expect(m.cats({ count: 1 }, { locale: "de-AT" })).toBe("Ein Katzerl");
337
+ expect(m.cats({ count: 3 }, { locale: "de-AT" })).toBe("3 Katzerl");
338
+ expect(m.unit_label({ unused: 1 }, { locale: "en" })).toBe("Weight in kg");
339
+ expect(m.unit_label({ unused: 1 }, { locale: "de-AT" })).toBe("Gewicht in kg");
340
+ });
184
341
  test("emitPrettierIgnore", async () => {
185
342
  const project = await loadProjectInMemory({
186
343
  blob: await newProject({