@sebbro/paraglide-lite 0.1.0 → 0.1.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.
- package/dist/bundler-plugins/per-locale-build/index.js +5 -3
- package/dist/bundler-plugins/per-locale-build/index.js.map +1 -1
- package/dist/bundler-plugins/per-locale-build/vite-environments.js +12 -7
- package/dist/bundler-plugins/per-locale-build/vite-environments.js.map +1 -1
- package/dist/bundler-plugins/plugin-core.d.ts +38 -2
- package/dist/bundler-plugins/plugin-core.js +198 -11
- package/dist/bundler-plugins/plugin-core.js.map +1 -1
- package/dist/bundler-plugins/rolldown.test.js +15 -6
- package/dist/bundler-plugins/rolldown.test.js.map +1 -1
- package/dist/bundler-plugins/unplugin.js +5 -0
- package/dist/bundler-plugins/unplugin.js.map +1 -1
- package/dist/bundler-plugins/unplugin.test.js +67 -0
- package/dist/bundler-plugins/unplugin.test.js.map +1 -1
- package/dist/bundler-plugins/virtual-modules.test.js +64 -1
- package/dist/bundler-plugins/virtual-modules.test.js.map +1 -1
- package/dist/cli/commands/compile/command.js +8 -1
- package/dist/cli/commands/compile/command.js.map +1 -1
- package/dist/cli/commands/compile/command.test.js +51 -0
- package/dist/cli/commands/compile/command.test.js.map +1 -1
- package/dist/compiler/compile-annotation.d.ts +2 -2
- package/dist/compiler/compile-annotation.js +9 -9
- package/dist/compiler/compile-annotation.js.map +1 -1
- package/dist/compiler/compile-local-variable.d.ts +2 -1
- package/dist/compiler/compile-local-variable.js +4 -4
- package/dist/compiler/compile-local-variable.js.map +1 -1
- package/dist/compiler/compile-local-variable.test.js +82 -0
- package/dist/compiler/compile-local-variable.test.js.map +1 -1
- package/dist/compiler/compile-message.js +10 -2
- package/dist/compiler/compile-message.js.map +1 -1
- package/dist/compiler/compile-message.test.js +132 -2
- package/dist/compiler/compile-message.test.js.map +1 -1
- package/dist/compiler/compile-pattern.js +4 -2
- package/dist/compiler/compile-pattern.js.map +1 -1
- package/dist/compiler/compile-pattern.test.js +31 -0
- package/dist/compiler/compile-pattern.test.js.map +1 -1
- package/dist/compiler/compile.bench.js +1 -1
- package/dist/compiler/compile.bench.js.map +1 -1
- package/dist/compiler/compile.test.js +14 -0
- package/dist/compiler/compile.test.js.map +1 -1
- package/dist/compiler/compiler-options.d.ts +9 -1
- package/dist/compiler/compiler-options.js.map +1 -1
- package/dist/compiler/emit-message-dts.d.ts +18 -0
- package/dist/compiler/emit-message-dts.js +166 -0
- package/dist/compiler/emit-message-dts.js.map +1 -0
- package/dist/compiler/emit-message-dts.test.d.ts +1 -0
- package/dist/compiler/emit-message-dts.test.js +283 -0
- package/dist/compiler/emit-message-dts.test.js.map +1 -0
- package/dist/compiler/runtime/create-runtime.d.ts +1 -0
- package/dist/compiler/runtime/create-runtime.js +11 -0
- package/dist/compiler/runtime/create-runtime.js.map +1 -1
- package/dist/compiler/runtime/exec-url-pattern.d.ts +9 -0
- package/dist/compiler/runtime/exec-url-pattern.js +31 -0
- package/dist/compiler/runtime/exec-url-pattern.js.map +1 -0
- package/dist/compiler/runtime/extract-locale-from-url.js +9 -4
- package/dist/compiler/runtime/extract-locale-from-url.js.map +1 -1
- package/dist/compiler/runtime/generate-static-localized-urls.js +13 -6
- package/dist/compiler/runtime/generate-static-localized-urls.js.map +1 -1
- package/dist/compiler/runtime/generate-static-localized-urls.test.js +38 -0
- package/dist/compiler/runtime/generate-static-localized-urls.test.js.map +1 -1
- package/dist/compiler/runtime/host-routing.d.ts +3 -3
- package/dist/compiler/runtime/host-routing.js +2 -2
- package/dist/compiler/runtime/host-routing.js.map +1 -1
- package/dist/compiler/runtime/host-routing.test.js +79 -0
- package/dist/compiler/runtime/host-routing.test.js.map +1 -1
- package/dist/compiler/runtime/localize-href.bench.d.ts +1 -0
- package/dist/compiler/runtime/localize-href.bench.js +68 -0
- package/dist/compiler/runtime/localize-href.bench.js.map +1 -0
- package/dist/compiler/runtime/localize-href.test.js +35 -0
- package/dist/compiler/runtime/localize-href.test.js.map +1 -1
- package/dist/compiler/runtime/localize-url.d.ts +14 -0
- package/dist/compiler/runtime/localize-url.js +338 -19
- package/dist/compiler/runtime/localize-url.js.map +1 -1
- package/dist/compiler/runtime/localize-url.test.js +139 -0
- package/dist/compiler/runtime/localize-url.test.js.map +1 -1
- package/dist/compiler/runtime/normalize-trailing-slash.d.ts +10 -0
- package/dist/compiler/runtime/normalize-trailing-slash.js +23 -0
- package/dist/compiler/runtime/normalize-trailing-slash.js.map +1 -0
- package/dist/compiler/runtime/route-strategy.js +4 -2
- package/dist/compiler/runtime/route-strategy.js.map +1 -1
- package/dist/compiler/runtime/should-redirect.js +4 -1
- package/dist/compiler/runtime/should-redirect.js.map +1 -1
- package/dist/compiler/runtime/should-redirect.test.js +26 -2
- package/dist/compiler/runtime/should-redirect.test.js.map +1 -1
- package/dist/compiler/runtime/type.d.ts +1 -0
- package/dist/compiler/runtime/type.js.map +1 -1
- package/dist/compiler/runtime/url-pattern.d.ts +11 -0
- package/dist/compiler/runtime/url-pattern.js +39 -1
- package/dist/compiler/runtime/url-pattern.js.map +1 -1
- package/dist/compiler/runtime/variables.d.ts +9 -3
- package/dist/compiler/runtime/variables.js +7 -1
- package/dist/compiler/runtime/variables.js.map +1 -1
- package/dist/compiler/server/create-server-file.js +18 -4
- package/dist/compiler/server/create-server-file.js.map +1 -1
- package/dist/compiler/server/create-server-file.test.js +76 -0
- package/dist/compiler/server/create-server-file.test.js.map +1 -1
- package/dist/compiler/server/middleware.js +6 -2
- package/dist/compiler/server/middleware.js.map +1 -1
- package/dist/compiler/server/middleware.test.js +30 -0
- package/dist/compiler/server/middleware.test.js.map +1 -1
- package/dist/compiler/strip-jsdoc.d.ts +9 -0
- package/dist/compiler/strip-jsdoc.js +19 -0
- package/dist/compiler/strip-jsdoc.js.map +1 -0
- package/dist/compiler/strip-jsdoc.test.d.ts +1 -0
- package/dist/compiler/strip-jsdoc.test.js +95 -0
- package/dist/compiler/strip-jsdoc.test.js.map +1 -0
- package/dist/compiler/variable-access.d.ts +2 -0
- package/dist/compiler/variable-access.js +6 -0
- package/dist/compiler/variable-access.js.map +1 -1
- package/dist/index.test.d.ts +1 -0
- package/dist/index.test.js +9 -0
- package/dist/index.test.js.map +1 -0
- package/dist/messages/load-messages.js +4 -5
- package/dist/messages/load-messages.js.map +1 -1
- package/dist/services/env-variables/index.js +1 -1
- package/dist/services/env-variables/index.js.map +1 -1
- package/dist/services/file-handling/write-output.bench.d.ts +1 -0
- package/dist/services/file-handling/write-output.bench.js +24 -0
- package/dist/services/file-handling/write-output.bench.js.map +1 -0
- package/dist/services/file-handling/write-output.d.ts +5 -0
- package/dist/services/file-handling/write-output.js +54 -9
- package/dist/services/file-handling/write-output.js.map +1 -1
- package/dist/services/file-handling/write-output.test.js +27 -0
- package/dist/services/file-handling/write-output.test.js.map +1 -1
- package/dist/services/logger/index.js +2 -0
- package/dist/services/logger/index.js.map +1 -1
- package/package.json +86 -86
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile-pattern.test.js","sourceRoot":"","sources":["../../src/compiler/compile-pattern.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"vitest\";\nimport { compilePattern } from \"./compile-pattern.js\";\nimport type { Pattern } from \"../messages/ast.js\";\n\ntest(\"should compile a text only pattern\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"Hello\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\texpect(code).toBe(\"`Hello`\");\n});\n\ntest(\"should compile a pattern with multiple VariableReference's\", () => {\n\tconst pattern: Pattern = [\n\t\t{ type: \"text\", value: \"Hello \" },\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: {\n\t\t\t\ttype: \"variable-reference\",\n\t\t\t\tname: \"name\",\n\t\t\t},\n\t\t},\n\t\t{ type: \"text\", value: \"! You have \" },\n\t\t{ type: \"expression\", arg: { type: \"variable-reference\", name: \"count\" } },\n\t\t{ type: \"text\", value: \" messages.\" },\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [\n\t\t\t{ type: \"input-variable\", name: \"name\" },\n\t\t\t{ type: \"input-variable\", name: \"count\" },\n\t\t],\n\t});\n\n\texpect(code).toBe(\"`Hello ${i?.name}! You have ${i?.count} messages.`\");\n});\n\ntest(\"uses bracket notation for input variables with non-identifier names\", () => {\n\tconst pattern: Pattern = [\n\t\t{ type: \"text\", value: \"Half \" },\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: {\n\t\t\t\ttype: \"variable-reference\",\n\t\t\t\tname: \"half!\",\n\t\t\t},\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"half!\" }],\n\t});\n\n\texpect(code).toBe('`Half ${i?.[\"half!\"]}`');\n});\n\ntest(\"should escape backticks\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"`Hello world`\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\texpect(code).toBe(\"`\\\\`Hello world\\\\``\");\n});\n\ntest(\"should escape backslashes\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"\\\\Hello world\\\\\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\n\texpect(code).toBe(\"`\\\\\\\\Hello world\\\\\\\\`\");\n});\n\ntest(\"should escape escaped backticks\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"\\\\`Hello world\\\\`\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\n\texpect(code).toBe(\"`\\\\\\\\\\\\`Hello world\\\\\\\\\\\\``\");\n});\n\ntest(\"should escape variable interpolation ( ${} )\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"${name\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\n\texpect(code).toBe(\"`\\\\${name`\");\n});\n\ntest(\"it can reference local variables\", () => {\n\tconst { code } = compilePattern({\n\t\tpattern: [\n\t\t\t{ type: \"text\", value: \"Hello \" },\n\t\t\t{\n\t\t\t\ttype: \"expression\",\n\t\t\t\targ: {\n\t\t\t\t\ttype: \"variable-reference\",\n\t\t\t\t\tname: \"name\",\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tdeclarations: [\n\t\t\t{\n\t\t\t\ttype: \"local-variable\",\n\t\t\t\tname: \"name\",\n\t\t\t\tvalue: {\n\t\t\t\t\ttype: \"expression\",\n\t\t\t\t\targ: { type: \"literal\", value: \"Peter\" },\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(code).toBe(\"`Hello ${name}`\");\n});\n\ntest(\"plain string mode strips markup wrappers\", () => {\n\tconst pattern: Pattern = [\n\t\t{ type: \"text\", value: \"Hello \" },\n\t\t{ type: \"markup-start\", name: \"b\" },\n\t\t{ type: \"expression\", arg: { type: \"variable-reference\", name: \"name\" } },\n\t\t{ type: \"markup-end\", name: \"b\" },\n\t\t{ type: \"text\", value: \"!\" },\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"name\" }],\n\t});\n\n\texpect(code).toBe(\"`Hello ${i?.name}!`\");\n});\n\ntest(\"compiles a pattern expression annotation to a registry call\", () => {\n\t// https://github.com/opral/paraglide-js/issues/694\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"count\" },\n\t\t\tannotation: { type: \"function-reference\", name: \"number\", options: [] },\n\t\t},\n\t\t{ type: \"text\", value: \" views\" },\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"count\" }],\n\t\tlocale: \"en\",\n\t});\n\n\texpect(code).toBe('`${registry.number(\"en\", i?.count, {})} views`');\n});\n\ntest(\"compiles pattern expression annotation options like local variable annotations\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"price\" },\n\t\t\tannotation: {\n\t\t\t\ttype: \"function-reference\",\n\t\t\t\tname: \"number\",\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"minimumFractionDigits\",\n\t\t\t\t\t\tvalue: { type: \"literal\", value: \"2\" },\n\t\t\t\t\t},\n\t\t\t\t\t{ name: \"style\", value: { type: \"literal\", value: \"percent\" } },\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"price\" }],\n\t\tlocale: \"de\",\n\t});\n\n\texpect(code).toBe(\n\t\t'`${registry.number(\"de\", i?.price, { minimumFractionDigits: 2, style: \"percent\" })}`'\n\t);\n});\n\ntest(\"parts mode compiles pattern expression annotations to registry calls\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"count\" },\n\t\t\tannotation: { type: \"function-reference\", name: \"number\", options: [] },\n\t\t},\n\t\t{ type: \"text\", value: \" views\" },\n\t];\n\n\tconst { code } = compilePattern({\n\t\tmode: \"parts\",\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"count\" }],\n\t\tlocale: \"en\",\n\t});\n\n\texpect(code).toBe(\n\t\t'[{ type: \"text\", value: String(registry.number(\"en\", i?.count, {})) }, { type: \"text\", value: \" views\" }]'\n\t);\n});\n\ntest(\"falls back to plain interpolation for unknown formatters\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"name\" },\n\t\t\tannotation: {\n\t\t\t\ttype: \"function-reference\",\n\t\t\t\tname: \"uppercase\",\n\t\t\t\toptions: [],\n\t\t\t},\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"name\" }],\n\t\tlocale: \"en\",\n\t});\n\n\texpect(code).toBe(\"`${i?.name}`\");\n});\n\ntest(\"throws when a pattern annotation is compiled without a locale\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"count\" },\n\t\t\tannotation: { type: \"function-reference\", name: \"number\", options: [] },\n\t\t},\n\t];\n\n\texpect(() =>\n\t\tcompilePattern({\n\t\t\tpattern,\n\t\t\tdeclarations: [{ type: \"input-variable\", name: \"count\" }],\n\t\t})\n\t).toThrow('requires a locale to compile the formatter \"number\"');\n});\n\ntest(\"validates relativetime options on pattern annotations\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"days\" },\n\t\t\tannotation: {\n\t\t\t\ttype: \"function-reference\",\n\t\t\t\tname: \"relativetime\",\n\t\t\t\toptions: [],\n\t\t\t},\n\t\t},\n\t];\n\n\texpect(() =>\n\t\tcompilePattern({\n\t\t\tpattern,\n\t\t\tdeclarations: [{ type: \"input-variable\", name: \"days\" }],\n\t\t\tlocale: \"en\",\n\t\t})\n\t).toThrow('The \"relativetime\" formatter requires a \"unit\" option.');\n});\n\ntest(\"parts mode compiles text, markup, options and attributes\", () => {\n\tconst pattern: Pattern = [\n\t\t{ type: \"text\", value: \"Read \" },\n\t\t{\n\t\t\ttype: \"markup-start\",\n\t\t\tname: \"link\",\n\t\t\toptions: [\n\t\t\t\t{ name: \"to\", value: { type: \"literal\", value: \"/docs\" } },\n\t\t\t\t{\n\t\t\t\t\tname: \"rel\",\n\t\t\t\t\tvalue: { type: \"variable-reference\", name: \"relationship\" },\n\t\t\t\t},\n\t\t\t],\n\t\t\tattributes: [\n\t\t\t\t{ name: \"track\", value: true },\n\t\t\t\t{ name: \"variant\", value: { type: \"literal\", value: \"hero\" } },\n\t\t\t],\n\t\t},\n\t\t{ type: \"text\", value: \"docs\" },\n\t\t{\n\t\t\ttype: \"markup-end\",\n\t\t\tname: \"link\",\n\t\t\toptions: [{ name: \"to\", value: { type: \"literal\", value: \"/docs\" } }],\n\t\t\tattributes: [{ name: \"track\", value: true }],\n\t\t},\n\t\t{\n\t\t\ttype: \"markup-standalone\",\n\t\t\tname: \"icon\",\n\t\t\toptions: [{ name: \"name\", value: { type: \"literal\", value: \"arrow\" } }],\n\t\t\tattributes: [{ name: \"filled\", value: true }],\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tmode: \"parts\",\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"relationship\" }],\n\t});\n\n\texpect(code).toBe(\n\t\t'[{ type: \"text\", value: \"Read \" }, { type: \"markup-start\", name: \"link\", options: { \"to\": \"/docs\", \"rel\": i?.relationship }, attributes: { \"track\": true, \"variant\": \"hero\" } }, { type: \"text\", value: \"docs\" }, { type: \"markup-end\", name: \"link\", options: { \"to\": \"/docs\" }, attributes: { \"track\": true } }, { type: \"markup-standalone\", name: \"icon\", options: { \"name\": \"arrow\" }, attributes: { \"filled\": true } }]'\n\t);\n});\n"]}
|
|
1
|
+
{"version":3,"file":"compile-pattern.test.js","sourceRoot":"","sources":["../../src/compiler/compile-pattern.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { test, expect } from \"vitest\";\nimport { compilePattern } from \"./compile-pattern.js\";\nimport type { Pattern } from \"../messages/ast.js\";\n\ntest(\"should compile a text only pattern\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"Hello\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\texpect(code).toBe(\"`Hello`\");\n});\n\ntest(\"should compile a pattern with multiple VariableReference's\", () => {\n\tconst pattern: Pattern = [\n\t\t{ type: \"text\", value: \"Hello \" },\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: {\n\t\t\t\ttype: \"variable-reference\",\n\t\t\t\tname: \"name\",\n\t\t\t},\n\t\t},\n\t\t{ type: \"text\", value: \"! You have \" },\n\t\t{ type: \"expression\", arg: { type: \"variable-reference\", name: \"count\" } },\n\t\t{ type: \"text\", value: \" messages.\" },\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [\n\t\t\t{ type: \"input-variable\", name: \"name\" },\n\t\t\t{ type: \"input-variable\", name: \"count\" },\n\t\t],\n\t});\n\n\texpect(code).toBe(\"`Hello ${i?.name}! You have ${i?.count} messages.`\");\n});\n\ntest(\"uses bracket notation for input variables with non-identifier names\", () => {\n\tconst pattern: Pattern = [\n\t\t{ type: \"text\", value: \"Half \" },\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: {\n\t\t\t\ttype: \"variable-reference\",\n\t\t\t\tname: \"half!\",\n\t\t\t},\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"half!\" }],\n\t});\n\n\texpect(code).toBe('`Half ${i?.[\"half!\"]}`');\n});\n\ntest(\"should escape backticks\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"`Hello world`\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\texpect(code).toBe(\"`\\\\`Hello world\\\\``\");\n});\n\ntest(\"should escape backslashes\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"\\\\Hello world\\\\\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\n\texpect(code).toBe(\"`\\\\\\\\Hello world\\\\\\\\`\");\n});\n\ntest(\"should escape escaped backticks\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"\\\\`Hello world\\\\`\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\n\texpect(code).toBe(\"`\\\\\\\\\\\\`Hello world\\\\\\\\\\\\``\");\n});\n\ntest(\"should escape variable interpolation ( ${} )\", () => {\n\tconst pattern: Pattern = [{ type: \"text\", value: \"${name\" }];\n\tconst { code } = compilePattern({ pattern, declarations: [] });\n\n\texpect(code).toBe(\"`\\\\${name`\");\n});\n\ntest(\"it can reference local variables\", () => {\n\tconst { code } = compilePattern({\n\t\tpattern: [\n\t\t\t{ type: \"text\", value: \"Hello \" },\n\t\t\t{\n\t\t\t\ttype: \"expression\",\n\t\t\t\targ: {\n\t\t\t\t\ttype: \"variable-reference\",\n\t\t\t\t\tname: \"name\",\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tdeclarations: [\n\t\t\t{\n\t\t\t\ttype: \"local-variable\",\n\t\t\t\tname: \"name\",\n\t\t\t\tvalue: {\n\t\t\t\t\ttype: \"expression\",\n\t\t\t\t\targ: { type: \"literal\", value: \"Peter\" },\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t});\n\n\texpect(code).toBe(\"`Hello ${name}`\");\n});\n\ntest(\"plain string mode strips markup wrappers\", () => {\n\tconst pattern: Pattern = [\n\t\t{ type: \"text\", value: \"Hello \" },\n\t\t{ type: \"markup-start\", name: \"b\" },\n\t\t{ type: \"expression\", arg: { type: \"variable-reference\", name: \"name\" } },\n\t\t{ type: \"markup-end\", name: \"b\" },\n\t\t{ type: \"text\", value: \"!\" },\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"name\" }],\n\t});\n\n\texpect(code).toBe(\"`Hello ${i?.name}!`\");\n});\n\ntest(\"compiles a pattern expression annotation to a registry call\", () => {\n\t// https://github.com/opral/paraglide-js/issues/694\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"count\" },\n\t\t\tannotation: { type: \"function-reference\", name: \"number\", options: [] },\n\t\t},\n\t\t{ type: \"text\", value: \" views\" },\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"count\" }],\n\t\tlocale: \"en\",\n\t});\n\n\texpect(code).toBe('`${registry.number(\"en\", i?.count, {})} views`');\n});\n\ntest(\"compiles pattern expression annotation options like local variable annotations\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"price\" },\n\t\t\tannotation: {\n\t\t\t\ttype: \"function-reference\",\n\t\t\t\tname: \"number\",\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"minimumFractionDigits\",\n\t\t\t\t\t\tvalue: { type: \"literal\", value: \"2\" },\n\t\t\t\t\t},\n\t\t\t\t\t{ name: \"style\", value: { type: \"literal\", value: \"percent\" } },\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"price\" }],\n\t\tlocale: \"de\",\n\t});\n\n\texpect(code).toBe(\n\t\t'`${registry.number(\"de\", i?.price, { minimumFractionDigits: 2, style: \"percent\" })}`'\n\t);\n});\n\ntest(\"compiles pattern annotation options that reference local variables\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"price\" },\n\t\t\tannotation: {\n\t\t\t\ttype: \"function-reference\",\n\t\t\t\tname: \"number\",\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"minimumFractionDigits\",\n\t\t\t\t\t\tvalue: { type: \"variable-reference\", name: \"digits\" },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [\n\t\t\t{ type: \"input-variable\", name: \"price\" },\n\t\t\t{\n\t\t\t\ttype: \"local-variable\",\n\t\t\t\tname: \"digits\",\n\t\t\t\tvalue: { type: \"expression\", arg: { type: \"literal\", value: \"2\" } },\n\t\t\t},\n\t\t],\n\t\tlocale: \"en\",\n\t});\n\n\texpect(code).toBe(\n\t\t'`${registry.number(\"en\", i?.price, { minimumFractionDigits: digits })}`'\n\t);\n});\n\ntest(\"parts mode compiles pattern expression annotations to registry calls\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"count\" },\n\t\t\tannotation: { type: \"function-reference\", name: \"number\", options: [] },\n\t\t},\n\t\t{ type: \"text\", value: \" views\" },\n\t];\n\n\tconst { code } = compilePattern({\n\t\tmode: \"parts\",\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"count\" }],\n\t\tlocale: \"en\",\n\t});\n\n\texpect(code).toBe(\n\t\t'[{ type: \"text\", value: String(registry.number(\"en\", i?.count, {})) }, { type: \"text\", value: \" views\" }]'\n\t);\n});\n\ntest(\"falls back to plain interpolation for unknown formatters\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"name\" },\n\t\t\tannotation: {\n\t\t\t\ttype: \"function-reference\",\n\t\t\t\tname: \"uppercase\",\n\t\t\t\toptions: [],\n\t\t\t},\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"name\" }],\n\t\tlocale: \"en\",\n\t});\n\n\texpect(code).toBe(\"`${i?.name}`\");\n});\n\ntest(\"throws when a pattern annotation is compiled without a locale\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"count\" },\n\t\t\tannotation: { type: \"function-reference\", name: \"number\", options: [] },\n\t\t},\n\t];\n\n\texpect(() =>\n\t\tcompilePattern({\n\t\t\tpattern,\n\t\t\tdeclarations: [{ type: \"input-variable\", name: \"count\" }],\n\t\t})\n\t).toThrow('requires a locale to compile the formatter \"number\"');\n});\n\ntest(\"validates relativetime options on pattern annotations\", () => {\n\tconst pattern: Pattern = [\n\t\t{\n\t\t\ttype: \"expression\",\n\t\t\targ: { type: \"variable-reference\", name: \"days\" },\n\t\t\tannotation: {\n\t\t\t\ttype: \"function-reference\",\n\t\t\t\tname: \"relativetime\",\n\t\t\t\toptions: [],\n\t\t\t},\n\t\t},\n\t];\n\n\texpect(() =>\n\t\tcompilePattern({\n\t\t\tpattern,\n\t\t\tdeclarations: [{ type: \"input-variable\", name: \"days\" }],\n\t\t\tlocale: \"en\",\n\t\t})\n\t).toThrow('The \"relativetime\" formatter requires a \"unit\" option.');\n});\n\ntest(\"parts mode compiles text, markup, options and attributes\", () => {\n\tconst pattern: Pattern = [\n\t\t{ type: \"text\", value: \"Read \" },\n\t\t{\n\t\t\ttype: \"markup-start\",\n\t\t\tname: \"link\",\n\t\t\toptions: [\n\t\t\t\t{ name: \"to\", value: { type: \"literal\", value: \"/docs\" } },\n\t\t\t\t{\n\t\t\t\t\tname: \"rel\",\n\t\t\t\t\tvalue: { type: \"variable-reference\", name: \"relationship\" },\n\t\t\t\t},\n\t\t\t],\n\t\t\tattributes: [\n\t\t\t\t{ name: \"track\", value: true },\n\t\t\t\t{ name: \"variant\", value: { type: \"literal\", value: \"hero\" } },\n\t\t\t],\n\t\t},\n\t\t{ type: \"text\", value: \"docs\" },\n\t\t{\n\t\t\ttype: \"markup-end\",\n\t\t\tname: \"link\",\n\t\t\toptions: [{ name: \"to\", value: { type: \"literal\", value: \"/docs\" } }],\n\t\t\tattributes: [{ name: \"track\", value: true }],\n\t\t},\n\t\t{\n\t\t\ttype: \"markup-standalone\",\n\t\t\tname: \"icon\",\n\t\t\toptions: [{ name: \"name\", value: { type: \"literal\", value: \"arrow\" } }],\n\t\t\tattributes: [{ name: \"filled\", value: true }],\n\t\t},\n\t];\n\n\tconst { code } = compilePattern({\n\t\tmode: \"parts\",\n\t\tpattern,\n\t\tdeclarations: [{ type: \"input-variable\", name: \"relationship\" }],\n\t});\n\n\texpect(code).toBe(\n\t\t'[{ type: \"text\", value: \"Read \" }, { type: \"markup-start\", name: \"link\", options: { \"to\": \"/docs\", \"rel\": i?.relationship }, attributes: { \"track\": true, \"variant\": \"hero\" } }, { type: \"text\", value: \"docs\" }, { type: \"markup-end\", name: \"link\", options: { \"to\": \"/docs\" }, attributes: { \"track\": true } }, { type: \"markup-standalone\", name: \"icon\", options: { \"name\": \"arrow\" }, attributes: { \"filled\": true } }]'\n\t);\n});\n"]}
|
|
@@ -76,7 +76,7 @@ for (const { messages, locales: localeCount, compareBaseline } of SCALES) {
|
|
|
76
76
|
// Upstream inlang SDK baseline is ~20s/iter at 10k×10 — keep it only at
|
|
77
77
|
// the small scale where the comparison is still practical.
|
|
78
78
|
if (compareBaseline) {
|
|
79
|
-
bench(`published @inlang/paraglide-js@2.
|
|
79
|
+
bench(`published @inlang/paraglide-js@2.25.0 (${label}, inlang SDK)`, async () => {
|
|
80
80
|
const fs = createBaselineProjectFs(messages, locales);
|
|
81
81
|
await compileBaseline({
|
|
82
82
|
project: "/project.inlang",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.bench.js","sourceRoot":"","sources":["../../src/compiler/compile.bench.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { bench } from \"vitest\";\nimport { memfs } from \"memfs\";\nimport { compile as compileLocal } from \"./compile.js\";\nimport { compile as compileBaseline } from \"@inlang/paraglide-js-baseline\";\nimport { createTestFsWithMessages } from \"./test-helpers.js\";\n\nconst require = createRequire(import.meta.url);\n\nfunction createMockMessages(numMessages: number, locale: string) {\n\treturn Object.fromEntries(\n\t\tArray.from({ length: numMessages }, (_, i) => [\n\t\t\t`message_${i}`,\n\t\t\t`Hello world {username} (${locale})`,\n\t\t])\n\t);\n}\n\nfunction createLocales(count: number): string[] {\n\treturn Array.from({ length: count }, (_, i) =>\n\t\ti === 0 ? \"en\" : `l${String(i).padStart(2, \"0\")}`\n\t);\n}\n\nfunction createBaselineProjectFs(numMessages: number, locales: string[]) {\n\tconst pluginPath = require.resolve(\"@inlang/plugin-message-format\");\n\tconst pluginSource = readFileSync(pluginPath, \"utf8\");\n\tconst files: Record<string, string> = {\n\t\t\"/plugin.js\": pluginSource,\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: locales[0],\n\t\t\tlocales,\n\t\t\tmodules: [\"/plugin.js\"],\n\t\t\t\"plugin.inlang.messageFormat\": {\n\t\t\t\tpathPattern: \"/{locale}.json\",\n\t\t\t},\n\t\t}),\n\t};\n\tfor (const locale of locales) {\n\t\tfiles[`/${locale}.json`] = JSON.stringify(\n\t\t\tcreateMockMessages(numMessages, locale)\n\t\t);\n\t}\n\n\treturn memfs(files).fs as unknown as typeof import(\"node:fs\");\n}\n\nfunction createLocalMessageFs(numMessages: number, locales: string[]) {\n\treturn createTestFsWithMessages({\n\t\tmessages: Object.fromEntries(\n\t\t\tlocales.map((locale) => [\n\t\t\t\tlocale,\n\t\t\t\tcreateMockMessages(numMessages, locale),\n\t\t\t])\n\t\t),\n\t\tpathPattern: \"/{locale}.json\",\n\t});\n}\n\nconst SCALES = [\n\t{ messages: 1_000, locales: 1, compareBaseline: true },\n\t{ messages: 10_000, locales: 10, compareBaseline: false },\n] as const;\n\nfor (const { messages, locales: localeCount, compareBaseline } of SCALES) {\n\tconst locales = createLocales(localeCount);\n\tconst label = `${messages} messages × ${localeCount} locales`;\n\t// Fewer samples at the large scale so the suite stays practical.\n\tconst time = localeCount === 1 ? 1500 : 3000;\n\n\tbench(\n\t\t`local compile (${label}, emitFiles: true)`,\n\t\tasync () => {\n\t\t\tconst fs = createLocalMessageFs(messages, locales);\n\n\t\t\tawait compileLocal({\n\t\t\t\tmessages: \"/{locale}.json\",\n\t\t\t\tlocales,\n\t\t\t\tbaseLocale: locales[0]!,\n\t\t\t\toutdir: `/output-local-${messages}-${localeCount}`,\n\t\t\t\tfs,\n\t\t\t});\n\t\t},\n\t\t{ time }\n\t);\n\n\tbench(\n\t\t`local compile (${label}, emitFiles: false / virtual)`,\n\t\tasync () => {\n\t\t\tconst fs = createLocalMessageFs(messages, locales);\n\n\t\t\tawait compileLocal({\n\t\t\t\tmessages: \"/{locale}.json\",\n\t\t\t\tlocales,\n\t\t\t\tbaseLocale: locales[0]!,\n\t\t\t\toutdir: `/output-virtual-${messages}-${localeCount}`,\n\t\t\t\temitFiles: false,\n\t\t\t\tfs,\n\t\t\t});\n\t\t},\n\t\t{ time }\n\t);\n\n\t// Upstream inlang SDK baseline is ~20s/iter at 10k×10 — keep it only at\n\t// the small scale where the comparison is still practical.\n\tif (compareBaseline) {\n\t\tbench(\n\t\t\t`published @inlang/paraglide-js@2.
|
|
1
|
+
{"version":3,"file":"compile.bench.js","sourceRoot":"","sources":["../../src/compiler/compile.bench.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { bench } from \"vitest\";\nimport { memfs } from \"memfs\";\nimport { compile as compileLocal } from \"./compile.js\";\nimport { compile as compileBaseline } from \"@inlang/paraglide-js-baseline\";\nimport { createTestFsWithMessages } from \"./test-helpers.js\";\n\nconst require = createRequire(import.meta.url);\n\nfunction createMockMessages(numMessages: number, locale: string) {\n\treturn Object.fromEntries(\n\t\tArray.from({ length: numMessages }, (_, i) => [\n\t\t\t`message_${i}`,\n\t\t\t`Hello world {username} (${locale})`,\n\t\t])\n\t);\n}\n\nfunction createLocales(count: number): string[] {\n\treturn Array.from({ length: count }, (_, i) =>\n\t\ti === 0 ? \"en\" : `l${String(i).padStart(2, \"0\")}`\n\t);\n}\n\nfunction createBaselineProjectFs(numMessages: number, locales: string[]) {\n\tconst pluginPath = require.resolve(\"@inlang/plugin-message-format\");\n\tconst pluginSource = readFileSync(pluginPath, \"utf8\");\n\tconst files: Record<string, string> = {\n\t\t\"/plugin.js\": pluginSource,\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: locales[0],\n\t\t\tlocales,\n\t\t\tmodules: [\"/plugin.js\"],\n\t\t\t\"plugin.inlang.messageFormat\": {\n\t\t\t\tpathPattern: \"/{locale}.json\",\n\t\t\t},\n\t\t}),\n\t};\n\tfor (const locale of locales) {\n\t\tfiles[`/${locale}.json`] = JSON.stringify(\n\t\t\tcreateMockMessages(numMessages, locale)\n\t\t);\n\t}\n\n\treturn memfs(files).fs as unknown as typeof import(\"node:fs\");\n}\n\nfunction createLocalMessageFs(numMessages: number, locales: string[]) {\n\treturn createTestFsWithMessages({\n\t\tmessages: Object.fromEntries(\n\t\t\tlocales.map((locale) => [\n\t\t\t\tlocale,\n\t\t\t\tcreateMockMessages(numMessages, locale),\n\t\t\t])\n\t\t),\n\t\tpathPattern: \"/{locale}.json\",\n\t});\n}\n\nconst SCALES = [\n\t{ messages: 1_000, locales: 1, compareBaseline: true },\n\t{ messages: 10_000, locales: 10, compareBaseline: false },\n] as const;\n\nfor (const { messages, locales: localeCount, compareBaseline } of SCALES) {\n\tconst locales = createLocales(localeCount);\n\tconst label = `${messages} messages × ${localeCount} locales`;\n\t// Fewer samples at the large scale so the suite stays practical.\n\tconst time = localeCount === 1 ? 1500 : 3000;\n\n\tbench(\n\t\t`local compile (${label}, emitFiles: true)`,\n\t\tasync () => {\n\t\t\tconst fs = createLocalMessageFs(messages, locales);\n\n\t\t\tawait compileLocal({\n\t\t\t\tmessages: \"/{locale}.json\",\n\t\t\t\tlocales,\n\t\t\t\tbaseLocale: locales[0]!,\n\t\t\t\toutdir: `/output-local-${messages}-${localeCount}`,\n\t\t\t\tfs,\n\t\t\t});\n\t\t},\n\t\t{ time }\n\t);\n\n\tbench(\n\t\t`local compile (${label}, emitFiles: false / virtual)`,\n\t\tasync () => {\n\t\t\tconst fs = createLocalMessageFs(messages, locales);\n\n\t\t\tawait compileLocal({\n\t\t\t\tmessages: \"/{locale}.json\",\n\t\t\t\tlocales,\n\t\t\t\tbaseLocale: locales[0]!,\n\t\t\t\toutdir: `/output-virtual-${messages}-${localeCount}`,\n\t\t\t\temitFiles: false,\n\t\t\t\tfs,\n\t\t\t});\n\t\t},\n\t\t{ time }\n\t);\n\n\t// Upstream inlang SDK baseline is ~20s/iter at 10k×10 — keep it only at\n\t// the small scale where the comparison is still practical.\n\tif (compareBaseline) {\n\t\tbench(\n\t\t\t`published @inlang/paraglide-js@2.25.0 (${label}, inlang SDK)`,\n\t\t\tasync () => {\n\t\t\t\tconst fs = createBaselineProjectFs(messages, locales);\n\n\t\t\t\tawait compileBaseline({\n\t\t\t\t\tproject: \"/project.inlang\",\n\t\t\t\t\toutdir: `/output-baseline-${messages}-${localeCount}`,\n\t\t\t\t\tfs,\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ time }\n\t\t);\n\t}\n}\n"]}
|
|
@@ -63,4 +63,18 @@ test("applies strategy from compiler options to runtime output", async () => {
|
|
|
63
63
|
expect(runtime).toContain('"url"');
|
|
64
64
|
expect(runtime).toContain('"cookie"');
|
|
65
65
|
});
|
|
66
|
+
test("runtime output strips sourcemap references", async () => {
|
|
67
|
+
const fs = createTestFsWithMessages({
|
|
68
|
+
messages: { en: { hello: "Hello" }, de: { hello: "Hallo" } },
|
|
69
|
+
});
|
|
70
|
+
await compile({
|
|
71
|
+
...defaultCompileOptions,
|
|
72
|
+
outdir: "/output",
|
|
73
|
+
fs,
|
|
74
|
+
});
|
|
75
|
+
const runtimeFile = await fs.promises.readFile("/output/runtime.js", "utf8");
|
|
76
|
+
const serverFile = await fs.promises.readFile("/output/server.js", "utf8");
|
|
77
|
+
expect(runtimeFile).not.toMatch(/sourceMappingURL=/);
|
|
78
|
+
expect(serverFile).not.toMatch(/sourceMappingURL=/);
|
|
79
|
+
});
|
|
66
80
|
//# sourceMappingURL=compile.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile.test.js","sourceRoot":"","sources":["../../src/compiler/compile.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { memfs } from \"memfs\";\nimport { test, expect, vi } from \"vitest\";\nimport { compile } from \"./compile.js\";\nimport type { Runtime } from \"./runtime/type.js\";\nimport { createTestFsWithMessages, defaultCompileOptions } from \"./test-helpers.js\";\nimport consola from \"consola\";\n\ntest(\"loads message files and compiles them\", async () => {\n\tconst fs = createTestFsWithMessages({\n\t\tmessages: {\n\t\t\ten: { hello: \"Hello\" },\n\t\t\tde: { hello: \"Hallo\" },\n\t\t\tfr: { hello: \"Bonjour\" },\n\t\t},\n\t});\n\n\tawait compile({\n\t\tmessages: defaultCompileOptions.messages,\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tbaseLocale: \"en\",\n\t\toutdir: \"/output\",\n\t\tfs,\n\t});\n\n\tconst files = await fs.promises.readdir(\"/output\");\n\texpect(files).toEqual(\n\t\texpect.arrayContaining([\"runtime.js\", \"server.js\", \"messages.js\"])\n\t);\n});\n\ntest(\"cleans the output directory\", async () => {\n\tconst fs = memfs({\n\t\t\"/output/old-file.js\": \"old\",\n\t\t\"/messages/en.json\": JSON.stringify({ hello: \"Hello\" }),\n\t\t\"/messages/de.json\": JSON.stringify({ hello: \"Hallo\" }),\n\t}).fs as unknown as typeof import(\"node:fs\");\n\n\tawait compile({\n\t\tmessages: \"/messages/{locale}.json\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tbaseLocale: \"en\",\n\t\toutdir: \"/output\",\n\t\tfs,\n\t\tcleanOutdir: true,\n\t});\n\n\tawait expect(fs.promises.readFile(\"/output/old-file.js\", \"utf8\")).rejects.toThrow();\n});\n\ntest(\"deduplicates concurrent compilations\", async () => {\n\tconst fs = createTestFsWithMessages({\n\t\tmessages: { en: { hello: \"Hello\" }, de: { hello: \"Hallo\" } },\n\t});\n\n\tconst compileSpy = vi.fn(compile);\n\tconsola.mockTypes(() => vi.fn());\n\n\tawait Promise.all([\n\t\tcompile({ ...defaultCompileOptions, outdir: \"/output\", fs }),\n\t\tcompile({ ...defaultCompileOptions, outdir: \"/output\", fs }),\n\t]);\n\n\tvoid compileSpy;\n});\n\ntest(\"applies strategy from compiler options to runtime output\", async () => {\n\tconst fs = createTestFsWithMessages({\n\t\tmessages: { en: { hello: \"Hello\" }, de: { hello: \"Hallo\" } },\n\t});\n\n\tawait compile({\n\t\t...defaultCompileOptions,\n\t\toutdir: \"/output\",\n\t\tfs,\n\t\tstrategy: [\"url\", \"cookie\", \"baseLocale\"] as Runtime[\"strategy\"],\n\t});\n\n\tconst runtime = await fs.promises.readFile(\"/output/runtime.js\", \"utf8\");\n\texpect(runtime).toContain('\"url\"');\n\texpect(runtime).toContain('\"cookie\"');\n});\n"]}
|
|
1
|
+
{"version":3,"file":"compile.test.js","sourceRoot":"","sources":["../../src/compiler/compile.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { memfs } from \"memfs\";\nimport { test, expect, vi } from \"vitest\";\nimport { compile } from \"./compile.js\";\nimport type { Runtime } from \"./runtime/type.js\";\nimport { createTestFsWithMessages, defaultCompileOptions } from \"./test-helpers.js\";\nimport consola from \"consola\";\n\ntest(\"loads message files and compiles them\", async () => {\n\tconst fs = createTestFsWithMessages({\n\t\tmessages: {\n\t\t\ten: { hello: \"Hello\" },\n\t\t\tde: { hello: \"Hallo\" },\n\t\t\tfr: { hello: \"Bonjour\" },\n\t\t},\n\t});\n\n\tawait compile({\n\t\tmessages: defaultCompileOptions.messages,\n\t\tlocales: [\"en\", \"de\", \"fr\"],\n\t\tbaseLocale: \"en\",\n\t\toutdir: \"/output\",\n\t\tfs,\n\t});\n\n\tconst files = await fs.promises.readdir(\"/output\");\n\texpect(files).toEqual(\n\t\texpect.arrayContaining([\"runtime.js\", \"server.js\", \"messages.js\"])\n\t);\n});\n\ntest(\"cleans the output directory\", async () => {\n\tconst fs = memfs({\n\t\t\"/output/old-file.js\": \"old\",\n\t\t\"/messages/en.json\": JSON.stringify({ hello: \"Hello\" }),\n\t\t\"/messages/de.json\": JSON.stringify({ hello: \"Hallo\" }),\n\t}).fs as unknown as typeof import(\"node:fs\");\n\n\tawait compile({\n\t\tmessages: \"/messages/{locale}.json\",\n\t\tlocales: [\"en\", \"de\"],\n\t\tbaseLocale: \"en\",\n\t\toutdir: \"/output\",\n\t\tfs,\n\t\tcleanOutdir: true,\n\t});\n\n\tawait expect(fs.promises.readFile(\"/output/old-file.js\", \"utf8\")).rejects.toThrow();\n});\n\ntest(\"deduplicates concurrent compilations\", async () => {\n\tconst fs = createTestFsWithMessages({\n\t\tmessages: { en: { hello: \"Hello\" }, de: { hello: \"Hallo\" } },\n\t});\n\n\tconst compileSpy = vi.fn(compile);\n\tconsola.mockTypes(() => vi.fn());\n\n\tawait Promise.all([\n\t\tcompile({ ...defaultCompileOptions, outdir: \"/output\", fs }),\n\t\tcompile({ ...defaultCompileOptions, outdir: \"/output\", fs }),\n\t]);\n\n\tvoid compileSpy;\n});\n\ntest(\"applies strategy from compiler options to runtime output\", async () => {\n\tconst fs = createTestFsWithMessages({\n\t\tmessages: { en: { hello: \"Hello\" }, de: { hello: \"Hallo\" } },\n\t});\n\n\tawait compile({\n\t\t...defaultCompileOptions,\n\t\toutdir: \"/output\",\n\t\tfs,\n\t\tstrategy: [\"url\", \"cookie\", \"baseLocale\"] as Runtime[\"strategy\"],\n\t});\n\n\tconst runtime = await fs.promises.readFile(\"/output/runtime.js\", \"utf8\");\n\texpect(runtime).toContain('\"url\"');\n\texpect(runtime).toContain('\"cookie\"');\n});\n\ntest(\"runtime output strips sourcemap references\", async () => {\n\tconst fs = createTestFsWithMessages({\n\t\tmessages: { en: { hello: \"Hello\" }, de: { hello: \"Hallo\" } },\n\t});\n\n\tawait compile({\n\t\t...defaultCompileOptions,\n\t\toutdir: \"/output\",\n\t\tfs,\n\t});\n\n\tconst runtimeFile = await fs.promises.readFile(\"/output/runtime.js\", \"utf8\");\n\tconst serverFile = await fs.promises.readFile(\"/output/server.js\", \"utf8\");\n\n\texpect(runtimeFile).not.toMatch(/sourceMappingURL=/);\n\texpect(serverFile).not.toMatch(/sourceMappingURL=/);\n});\n"]}
|
|
@@ -122,7 +122,7 @@ export type CompilerOptions = {
|
|
|
122
122
|
* server-side takes the globalVariable (because cookie is unavailable),
|
|
123
123
|
* whereas both fallback to the base locale if not available.
|
|
124
124
|
*
|
|
125
|
-
* Custom strategies with the pattern `custom-[A-Za-z0-
|
|
125
|
+
* Custom strategies with the pattern `custom-[A-Za-z0-9_-]+` are supported.
|
|
126
126
|
*
|
|
127
127
|
* @default ["cookie", "globalVariable", "baseLocale"]
|
|
128
128
|
*/
|
|
@@ -367,6 +367,14 @@ export type CompilerOptions = {
|
|
|
367
367
|
* @see RoutingConfig
|
|
368
368
|
*/
|
|
369
369
|
routing?: RoutingConfig;
|
|
370
|
+
/**
|
|
371
|
+
* Controls trailing slash canonicalization for localized URLs.
|
|
372
|
+
*
|
|
373
|
+
* Canonicalization happens before URL pattern matching and after URL
|
|
374
|
+
* localization. If omitted, Paraglide keeps its existing trailing slash
|
|
375
|
+
* behavior.
|
|
376
|
+
*/
|
|
377
|
+
trailingSlash?: "always" | "never";
|
|
370
378
|
/**
|
|
371
379
|
* Whether to include an eslint-disable comment at the top of each .js file.
|
|
372
380
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler-options.js","sourceRoot":"","sources":["../../src/compiler/compiler-options.ts"],"names":[],"mappings":"AAgCA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,QAAQ,EAAE,0BAA0B;IACpC,OAAO,EAAE,CAAC,IAAI,CAAC;IACf,UAAU,EAAE,IAAI;IAChB,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,IAAI;IACnB,2BAA2B,EAAE,IAAI;IACjC,kBAAkB,EAAE,IAAI;IACxB,UAAU,EAAE,IAAI;IAChB,kBAAkB,EAAE,KAAK;IACzB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,wBAAwB,EAAE,KAAK;IAC/B,qCAAqC,EAAE,KAAK;IAC5C,eAAe,EAAE,kBAAkB;IACnC,QAAQ,EAAE,+BAA+B;IACzC,QAAQ,EAAE,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,CAAC;IACpD,UAAU,EAAE,kBAAkB;IAC9B,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG;IAChC,YAAY,EAAE,EAAE;CAC4B,CAAC","sourcesContent":["import type { Runtime } from \"./runtime/type.js\";\n\nexport type RouteStrategy =\n\t| {\n\t\t\t/**\n\t\t\t * URLPattern-compatible matcher.\n\t\t\t */\n\t\t\tmatch: string;\n\t\t\t/**\n\t\t\t * Strategy override for matching requests.\n\t\t\t */\n\t\t\tstrategy: Runtime[\"strategy\"];\n\t\t\t/**\n\t\t\t * Prevent mutually exclusive configuration (`exclude` + `strategy`).\n\t\t\t */\n\t\t\texclude?: never;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * URLPattern-compatible matcher.\n\t\t\t */\n\t\t\tmatch: string;\n\t\t\t/**\n\t\t\t * Exclude matching requests from i18n middleware behavior.\n\t\t\t */\n\t\t\texclude: true;\n\t\t\t/**\n\t\t\t * Prevent mutually exclusive configuration (`exclude` + `strategy`).\n\t\t\t */\n\t\t\tstrategy?: never;\n\t };\n\nexport const defaultCompilerOptions = {\n\tmessages: \"./messages/{locale}.json\",\n\tlocales: [\"en\"],\n\tbaseLocale: \"en\",\n\toutputStructure: \"message-modules\",\n\temitGitIgnore: true,\n\tincludeEslintDisableComment: true,\n\temitPrettierIgnore: true,\n\temitReadme: true,\n\temitTsDeclarations: false,\n\temitFiles: true,\n\tcleanOutdir: true,\n\tdisableAsyncLocalStorage: false,\n\texperimentalMiddlewareLocaleSplitting: false,\n\tlocalStorageKey: \"PARAGLIDE_LOCALE\",\n\tisServer: \"typeof window === 'undefined'\",\n\tstrategy: [\"cookie\", \"globalVariable\", \"baseLocale\"],\n\tcookieName: \"PARAGLIDE_LOCALE\",\n\tcookieMaxAge: 60 * 60 * 24 * 400,\n\tcookieDomain: \"\",\n} as const satisfies Partial<CompilerOptions>;\n\n/**\n * Per-host URL routing rule.\n *\n * Path shape is always `/{locale}/{path}`, except the host `baseLocale`\n * which is bare (`/{path}`).\n */\nexport type HostRoutingRule = {\n\t/**\n\t * Locale served without a path prefix on this host.\n\t *\n\t * @example\n\t * // fin.example.com/ → fi, fin.example.com/en → en\n\t * baseLocale: \"fi\"\n\t */\n\tbaseLocale?: string;\n\t/**\n\t * Locales allowed on this host. Defaults to all project locales.\n\t */\n\tlocales?: string[];\n};\n\n/**\n * Hostname → routing rule map.\n *\n * Use `\"*\"` as the fallback for hosts that are not listed.\n *\n * @example\n * ```ts\n * routing: {\n * \"fin.example.com\": { baseLocale: \"fi\" },\n * \"app.example.com\": { baseLocale: \"sv\", locales: [\"sv\", \"en\", \"pt-PT\"] },\n * \"*\": { baseLocale: \"en\" },\n * }\n * ```\n */\nexport type RoutingConfig = Record<string, HostRoutingRule>;\n\nexport type CompilerOptions = {\n\t/**\n\t * Path pattern to locale message files. Must contain `{locale}`.\n\t *\n\t * @example \"./messages/{locale}.json\"\n\t */\n\tmessages: string;\n\t/**\n\t * Locales to compile.\n\t */\n\tlocales: string[];\n\t/**\n\t * Default locale used for fallbacks.\n\t */\n\tbaseLocale: string;\n\t/**\n\t * The path to the output directory.\n\t *\n\t * @example\n\t * ```diff\n\t * await compile({\n\t * messages: \"./messages/{locale}.json\",\n\t * + outdir: \"./src/paraglide\"\n\t * })\n\t * ```\n\t */\n\toutdir: string;\n\t/**\n\t * The strategy to use for getting the locale.\n\t *\n\t * The order of the strategy defines the precedence of matches.\n\t *\n\t * For example, in `['url', 'cookie', 'baseLocale']`, the locale will be\n\t * first tried to be detected in the url, then in a cookie, and finally\n\t * fallback to the base locale.\n\t *\n\t * The default ensures that the browser takes a cookie approach,\n\t * server-side takes the globalVariable (because cookie is unavailable),\n\t * whereas both fallback to the base locale if not available.\n\t *\n\t * Custom strategies with the pattern `custom-[A-Za-z0-9]+` are supported.\n\t *\n\t * @default [\"cookie\", \"globalVariable\", \"baseLocale\"]\n\t */\n\tstrategy?: Runtime[\"strategy\"];\n\t/**\n\t * Route-level strategy overrides.\n\t *\n\t * Routes are matched in declaration order. The first matching rule wins.\n\t * `match` uses URLPattern syntax and therefore requires the global URLPattern API\n\t * (polyfill older targets; see https://paraglidejs.com/i18n-routing#urlpattern-compatibility).\n\t *\n\t * - `strategy`: Override locale resolution for the matched route.\n\t * - `exclude: true`: Skip i18n middleware behavior for the matched route.\n\t *\n\t * @example\n\t * ```ts\n\t * routeStrategies: [\n\t * { match: \"/dashboard/:path(.*)?\", strategy: [\"cookie\", \"baseLocale\"] },\n\t * { match: \"/api/:path(.*)?\", exclude: true }\n\t * ]\n\t * ```\n\t */\n\trouteStrategies?: RouteStrategy[];\n\t/**\n\t * Whether or not to use experimental middleware locale splitting.\n\t *\n\t * ⚠️ This feature is experimental and only works in SSR/SSG environment\n\t * without client-side routing. Do not rely on this feature for production.\n\t *\n\t * This feature is part of the exploration of per locale splitting. The\n\t * issue is ongoing and can be followed here [#88](https://github.com/opral/inlang-paraglide-js/issues/88).\n\t *\n\t * - The client bundle will tree-shake all messages (have close to 0kb JS).\n\t * - The server middleware will inject the used messages into the HTML.\n\t * - The client will re-trieve the messages from the injected HTML.\n\t *\n\t * @default false\n\t */\n\texperimentalMiddlewareLocaleSplitting?: boolean;\n\t/**\n\t * The name of the localStorage key to use for the localStorage strategy.\n\t *\n\t * @default 'PARAGLIDE_LOCALE'\n\t */\n\tlocalStorageKey?: string;\n\t/**\n\t * Tree-shaking flag if the code is running on the server.\n\t *\n\t * Dependent on the bundler, this flag must be adapted to\n\t * enable tree-shaking.\n\t *\n\t * @example\n\t * // vite\n\t * isServer: \"import.meta.env.SSR\"\n\t *\n\t * @default typeof window === \"undefined\"\n\t */\n\tisServer?: string;\n\t/**\n\t * Compile-time locale constant used for per-locale tree-shaking.\n\t *\n\t * This is experimental and opt-in. It should be a JavaScript expression\n\t * (not a quoted literal) that resolves to a locale or `undefined` at build time.\n\t * You can pass a string literal (e.g. `\"de\"`) for programmatic builds, or an\n\t * injected env/define expression for bundler-driven builds.\n\t *\n\t * High-level flow for per-locale builds:\n\t *\n\t * client request (/)\n\t * |\n\t * v\n\t * +----------------------+\n\t * | detect locale |\n\t * | (cookie/Accept-L) |\n\t * | pick build prefix |\n\t * +----------------------+\n\t * | if \"de\"\n\t * v\n\t * serve dist/de/... <----> serve dist/en/...\n\t * (HTML + assets) (HTML + assets)\n\t *\n\t * @see https://github.com/opral/paraglide-js/issues/88#issuecomment-3634754638\n\t *\n\t * @example\n\t * // Vite define\n\t * experimentalStaticLocale: \"typeof __PARAGLIDE_STATIC_LOCALE__ === 'undefined' ? undefined : __PARAGLIDE_STATIC_LOCALE__\"\n\t *\n\t * @example\n\t * // Programmatic compile (literal)\n\t * experimentalStaticLocale: '\"de\"'\n\t */\n\texperimentalStaticLocale?: string;\n\t/**\n\t * The name of the cookie to use for the cookie strategy.\n\t *\n\t * @default 'PARAGLIDE_LOCALE'\n\t */\n\tcookieName?: string;\n\t/**\n\t * The max-age in seconds of the cookie until it expires.\n\t *\n\t * @default 60 * 60 * 24 * 400\n\t */\n\tcookieMaxAge?: number;\n\t/**\n\t * The host to which the cookie will be sent.\n\t * If undefined or empty, the domain attribute is omitted from the cookie, scoping it to the exact current domain only (no subdomains).\n\t * If specified, the cookie will be available to the specified domain and all its subdomains.\n\t *\n\t * Use this when you need cookies to be shared across subdomains (e.g., between `app.example.com` and `api.example.com`).\n\t * The default behavior (no domain) ensures better compatibility with server-side cookies that don't specify a domain attribute.\n\t *\n\t * @example\n\t * ```ts\n\t * // Default: exact domain only (compatible with server-side cookies)\n\t * cookieDomain: undefined // Cookie: \"PARAGLIDE_LOCALE=en; path=/; max-age=34560000\"\n\t *\n\t * // Subdomain sharing: available across all subdomains\n\t * cookieDomain: \"example.com\" // Cookie: \"PARAGLIDE_LOCALE=en; path=/; max-age=34560000; domain=example.com\"\n\t * ```\n\t *\n\t * @default \"\" (no domain attribute, exact domain only)\n\t */\n\tcookieDomain?: string;\n\t/**\n\t * The `additionalFiles` option is an array of paths to additional files that should be copied to the output directory.\n\t *\n\t * @example\n\t *\n\t * ```diff\n\t * await compile({\n\t * project: \"./project.inlang\",\n\t * outdir: \"./src/paraglide\",\n\t * additionalFiles: [\n\t * + \"my-file.js\": \"console.log('hello')\"\n\t * ]\n\t * })\n\t * ```\n\t *\n\t * The output will look like this:\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - my-file.js\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t */\n\tadditionalFiles?: Record<string, string>;\n\t/**\n\t * If `emitPrettierIgnore` is set to `true` a `.prettierignore` file will be emitted in the output directory. Defaults to `true`.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - .prettierignore\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * @default true\n\t */\n\temitPrettierIgnore?: boolean;\n\t/**\n\t * If `emitReadme` is set to `true` a `README.md` file will be emitted in the output directory. Defaults to `true`.\n\t *\n\t * The README helps LLMs understand the compiled output.\n\t * See https://llmstxt.org/ for format guidelines.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - README.md\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * @default true\n\t */\n\temitReadme?: boolean;\n\t/**\n\t * Emit `.d.ts` files for the generated output using the TypeScript compiler.\n\t *\n\t * Useful when `allowJs: true` cannot be set in your `tsconfig.json`\n\t * (e.g., due to project constraints or conflicting compiler options), or when\n\t * an editor language server caches stale JSDoc types for generated messages.\n\t *\n\t * Requires `typescript` to be resolvable in your toolchain.\n\t *\n\t * **Note:** Enabling this option reduces compiler speed because TypeScript\n\t * needs to generate declaration files for all output modules.\n\t *\n\t * **Note:** With TypeScript 5/6 the declarations are generated in-process.\n\t * TypeScript 7+ no longer provides the compiler API, so its `tsc` CLI is\n\t * invoked in a child process instead; the emitted declarations are\n\t * semantically equivalent but differ cosmetically between the two.\n\t *\n\t * @example\n\t * ```ts\n\t * await compile({\n\t * project: \"./project.inlang\",\n\t * outdir: \"./src/paraglide\",\n\t * emitTsDeclarations: true,\n\t * });\n\t * ```\n\t *\n\t * @default false\n\t */\n\temitTsDeclarations?: boolean;\n\t/**\n\t * Controls which compiled files are written to `outdir`.\n\t *\n\t * - `true` — write the full output tree (default). Required for the CLI\n\t * and for bundlers that cannot load virtual modules (webpack, etc.).\n\t * - `\"types\"` — write `.d.ts` plus meta files (`.gitignore`,\n\t * `.prettierignore`, `README.md`, `messages/package.json`). Generated\n\t * `.js` is served from memory by the Vite/Rolldown plugins.\n\t * - `false` — write nothing except `.d.ts` when `emitTsDeclarations` is\n\t * enabled. Generated `.js` is virtual only.\n\t *\n\t * @default true\n\t */\n\temitFiles?: true | false | \"types\";\n\t/**\n\t * Custom URL patterns for advanced i18n routing (translated pathnames, domains, etc.).\n\t *\n\t * Uses the global [URLPattern](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API) API.\n\t * Default locale-prefix routing and {@link CompilerOptions.routing} do not need URLPattern.\n\t * For older browsers/runtimes, load a polyfill (e.g. `import \"urlpattern-polyfill\"`) before the\n\t * generated runtime. See https://paraglidejs.com/i18n-routing#urlpattern-compatibility\n\t *\n\t * https://paraglidejs.com/strategy#url\n\t */\n\turlPatterns?: Runtime[\"urlPatterns\"];\n\t/**\n\t * Fast per-host locale prefix routing (no URLPattern).\n\t *\n\t * When set, Paraglide uses string path ops instead of `urlPatterns`.\n\t * Do not combine with `urlPatterns`.\n\t *\n\t * @see RoutingConfig\n\t */\n\trouting?: RoutingConfig;\n\t/**\n\t * Whether to include an eslint-disable comment at the top of each .js file.\n\t *\n\t * @default true\n\t */\n\tincludeEslintDisableComment?: boolean;\n\t/**\n\t * Replaces AsyncLocalStorage with a synchronous implementation.\n\t *\n\t * Leave AsyncLocalStorage enabled by default. This option is a\n\t * compatibility fallback for runtimes that do not provide\n\t * AsyncLocalStorage or `node:async_hooks`.\n\t *\n\t * ⚠️ WARNING: Only use this option when your runtime also guarantees\n\t * request isolation. Disabling AsyncLocalStorage in multi-request\n\t * server environments risks cross-request pollution where state from\n\t * one request could leak into another concurrent request.\n\t */\n\tdisableAsyncLocalStorage?: boolean;\n\t/**\n\t * If `emitGitIgnore` is set to `true` a `.gitignore` file will be emitted in the output directory. Defaults to `true`.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - .gitignore\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * @default true\n\t */\n\temitGitIgnore?: boolean;\n\t/**\n\t * The `outputStructure` defines how modules are structured in the output.\n\t *\n\t * - `message-modules` - Each module is a message. This is the default.\n\t * - `locale-modules` - Each module is a locale.\n\t *\n\t * It is recommended to use `locale-modules` for development and `message-modules` for production.\n\t * Bundlers speed up the dev mode by bypassing bundling which can lead to many http requests\n\t * during the dev mode with `message-modules`. See https://github.com/opral/inlang-paraglide-js/issues/486.\n\t *\n\t * **`message-modules`**\n\t *\n\t * Messages have their own module which eases tree-shaking for bundlers.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - blue_elephant_tree/\n\t * + - index.js\n\t * + - en.js\n\t * + - fr.js\n\t * + - sky_phone_bottle/\n\t * + - index.js\n\t * + - en.js\n\t * + - fr.js\n\t * - ...\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * **`locale-modules`**\n\t *\n\t * Messages are bundled in a per locale module. Bundlers often struggle with tree-shaking this structure,\n\t * which can lead to more inefficient tree-shaking and larger bundle sizes compared to `message-modules`.\n\t *\n\t * The benefit are substantially fewer files which is needed in large projects.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - de.js\n\t * + - en.js\n\t * + - fr.js\n\t * - ...\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * @default \"message-modules\"\n\t */\n\toutputStructure?: \"locale-modules\" | \"message-modules\";\n\t/**\n\t * Whether to clean the output directory before writing the new files.\n\t *\n\t * @default true\n\t */\n\tcleanOutdir?: boolean;\n\n\t/**\n\t * The file system to use. Defaults to `await import('node:fs')`.\n\t *\n\t * Useful for testing the paraglide compiler by mocking the fs.\n\t */\n\tfs?: any;\n};\n"]}
|
|
1
|
+
{"version":3,"file":"compiler-options.js","sourceRoot":"","sources":["../../src/compiler/compiler-options.ts"],"names":[],"mappings":"AAgCA,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,QAAQ,EAAE,0BAA0B;IACpC,OAAO,EAAE,CAAC,IAAI,CAAC;IACf,UAAU,EAAE,IAAI;IAChB,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,IAAI;IACnB,2BAA2B,EAAE,IAAI;IACjC,kBAAkB,EAAE,IAAI;IACxB,UAAU,EAAE,IAAI;IAChB,kBAAkB,EAAE,KAAK;IACzB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,wBAAwB,EAAE,KAAK;IAC/B,qCAAqC,EAAE,KAAK;IAC5C,eAAe,EAAE,kBAAkB;IACnC,QAAQ,EAAE,+BAA+B;IACzC,QAAQ,EAAE,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,CAAC;IACpD,UAAU,EAAE,kBAAkB;IAC9B,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAG;IAChC,YAAY,EAAE,EAAE;CAC4B,CAAC","sourcesContent":["import type { Runtime } from \"./runtime/type.js\";\n\nexport type RouteStrategy =\n\t| {\n\t\t\t/**\n\t\t\t * URLPattern-compatible matcher.\n\t\t\t */\n\t\t\tmatch: string;\n\t\t\t/**\n\t\t\t * Strategy override for matching requests.\n\t\t\t */\n\t\t\tstrategy: Runtime[\"strategy\"];\n\t\t\t/**\n\t\t\t * Prevent mutually exclusive configuration (`exclude` + `strategy`).\n\t\t\t */\n\t\t\texclude?: never;\n\t }\n\t| {\n\t\t\t/**\n\t\t\t * URLPattern-compatible matcher.\n\t\t\t */\n\t\t\tmatch: string;\n\t\t\t/**\n\t\t\t * Exclude matching requests from i18n middleware behavior.\n\t\t\t */\n\t\t\texclude: true;\n\t\t\t/**\n\t\t\t * Prevent mutually exclusive configuration (`exclude` + `strategy`).\n\t\t\t */\n\t\t\tstrategy?: never;\n\t };\n\nexport const defaultCompilerOptions = {\n\tmessages: \"./messages/{locale}.json\",\n\tlocales: [\"en\"],\n\tbaseLocale: \"en\",\n\toutputStructure: \"message-modules\",\n\temitGitIgnore: true,\n\tincludeEslintDisableComment: true,\n\temitPrettierIgnore: true,\n\temitReadme: true,\n\temitTsDeclarations: false,\n\temitFiles: true,\n\tcleanOutdir: true,\n\tdisableAsyncLocalStorage: false,\n\texperimentalMiddlewareLocaleSplitting: false,\n\tlocalStorageKey: \"PARAGLIDE_LOCALE\",\n\tisServer: \"typeof window === 'undefined'\",\n\tstrategy: [\"cookie\", \"globalVariable\", \"baseLocale\"],\n\tcookieName: \"PARAGLIDE_LOCALE\",\n\tcookieMaxAge: 60 * 60 * 24 * 400,\n\tcookieDomain: \"\",\n} as const satisfies Partial<CompilerOptions>;\n\n/**\n * Per-host URL routing rule.\n *\n * Path shape is always `/{locale}/{path}`, except the host `baseLocale`\n * which is bare (`/{path}`).\n */\nexport type HostRoutingRule = {\n\t/**\n\t * Locale served without a path prefix on this host.\n\t *\n\t * @example\n\t * // fin.example.com/ → fi, fin.example.com/en → en\n\t * baseLocale: \"fi\"\n\t */\n\tbaseLocale?: string;\n\t/**\n\t * Locales allowed on this host. Defaults to all project locales.\n\t */\n\tlocales?: string[];\n};\n\n/**\n * Hostname → routing rule map.\n *\n * Use `\"*\"` as the fallback for hosts that are not listed.\n *\n * @example\n * ```ts\n * routing: {\n * \"fin.example.com\": { baseLocale: \"fi\" },\n * \"app.example.com\": { baseLocale: \"sv\", locales: [\"sv\", \"en\", \"pt-PT\"] },\n * \"*\": { baseLocale: \"en\" },\n * }\n * ```\n */\nexport type RoutingConfig = Record<string, HostRoutingRule>;\n\nexport type CompilerOptions = {\n\t/**\n\t * Path pattern to locale message files. Must contain `{locale}`.\n\t *\n\t * @example \"./messages/{locale}.json\"\n\t */\n\tmessages: string;\n\t/**\n\t * Locales to compile.\n\t */\n\tlocales: string[];\n\t/**\n\t * Default locale used for fallbacks.\n\t */\n\tbaseLocale: string;\n\t/**\n\t * The path to the output directory.\n\t *\n\t * @example\n\t * ```diff\n\t * await compile({\n\t * messages: \"./messages/{locale}.json\",\n\t * + outdir: \"./src/paraglide\"\n\t * })\n\t * ```\n\t */\n\toutdir: string;\n\t/**\n\t * The strategy to use for getting the locale.\n\t *\n\t * The order of the strategy defines the precedence of matches.\n\t *\n\t * For example, in `['url', 'cookie', 'baseLocale']`, the locale will be\n\t * first tried to be detected in the url, then in a cookie, and finally\n\t * fallback to the base locale.\n\t *\n\t * The default ensures that the browser takes a cookie approach,\n\t * server-side takes the globalVariable (because cookie is unavailable),\n\t * whereas both fallback to the base locale if not available.\n\t *\n\t * Custom strategies with the pattern `custom-[A-Za-z0-9_-]+` are supported.\n\t *\n\t * @default [\"cookie\", \"globalVariable\", \"baseLocale\"]\n\t */\n\tstrategy?: Runtime[\"strategy\"];\n\t/**\n\t * Route-level strategy overrides.\n\t *\n\t * Routes are matched in declaration order. The first matching rule wins.\n\t * `match` uses URLPattern syntax and therefore requires the global URLPattern API\n\t * (polyfill older targets; see https://paraglidejs.com/i18n-routing#urlpattern-compatibility).\n\t *\n\t * - `strategy`: Override locale resolution for the matched route.\n\t * - `exclude: true`: Skip i18n middleware behavior for the matched route.\n\t *\n\t * @example\n\t * ```ts\n\t * routeStrategies: [\n\t * { match: \"/dashboard/:path(.*)?\", strategy: [\"cookie\", \"baseLocale\"] },\n\t * { match: \"/api/:path(.*)?\", exclude: true }\n\t * ]\n\t * ```\n\t */\n\trouteStrategies?: RouteStrategy[];\n\t/**\n\t * Whether or not to use experimental middleware locale splitting.\n\t *\n\t * ⚠️ This feature is experimental and only works in SSR/SSG environment\n\t * without client-side routing. Do not rely on this feature for production.\n\t *\n\t * This feature is part of the exploration of per locale splitting. The\n\t * issue is ongoing and can be followed here [#88](https://github.com/opral/inlang-paraglide-js/issues/88).\n\t *\n\t * - The client bundle will tree-shake all messages (have close to 0kb JS).\n\t * - The server middleware will inject the used messages into the HTML.\n\t * - The client will re-trieve the messages from the injected HTML.\n\t *\n\t * @default false\n\t */\n\texperimentalMiddlewareLocaleSplitting?: boolean;\n\t/**\n\t * The name of the localStorage key to use for the localStorage strategy.\n\t *\n\t * @default 'PARAGLIDE_LOCALE'\n\t */\n\tlocalStorageKey?: string;\n\t/**\n\t * Tree-shaking flag if the code is running on the server.\n\t *\n\t * Dependent on the bundler, this flag must be adapted to\n\t * enable tree-shaking.\n\t *\n\t * @example\n\t * // vite\n\t * isServer: \"import.meta.env.SSR\"\n\t *\n\t * @default typeof window === \"undefined\"\n\t */\n\tisServer?: string;\n\t/**\n\t * Compile-time locale constant used for per-locale tree-shaking.\n\t *\n\t * This is experimental and opt-in. It should be a JavaScript expression\n\t * (not a quoted literal) that resolves to a locale or `undefined` at build time.\n\t * You can pass a string literal (e.g. `\"de\"`) for programmatic builds, or an\n\t * injected env/define expression for bundler-driven builds.\n\t *\n\t * High-level flow for per-locale builds:\n\t *\n\t * client request (/)\n\t * |\n\t * v\n\t * +----------------------+\n\t * | detect locale |\n\t * | (cookie/Accept-L) |\n\t * | pick build prefix |\n\t * +----------------------+\n\t * | if \"de\"\n\t * v\n\t * serve dist/de/... <----> serve dist/en/...\n\t * (HTML + assets) (HTML + assets)\n\t *\n\t * @see https://github.com/opral/paraglide-js/issues/88#issuecomment-3634754638\n\t *\n\t * @example\n\t * // Vite define\n\t * experimentalStaticLocale: \"typeof __PARAGLIDE_STATIC_LOCALE__ === 'undefined' ? undefined : __PARAGLIDE_STATIC_LOCALE__\"\n\t *\n\t * @example\n\t * // Programmatic compile (literal)\n\t * experimentalStaticLocale: '\"de\"'\n\t */\n\texperimentalStaticLocale?: string;\n\t/**\n\t * The name of the cookie to use for the cookie strategy.\n\t *\n\t * @default 'PARAGLIDE_LOCALE'\n\t */\n\tcookieName?: string;\n\t/**\n\t * The max-age in seconds of the cookie until it expires.\n\t *\n\t * @default 60 * 60 * 24 * 400\n\t */\n\tcookieMaxAge?: number;\n\t/**\n\t * The host to which the cookie will be sent.\n\t * If undefined or empty, the domain attribute is omitted from the cookie, scoping it to the exact current domain only (no subdomains).\n\t * If specified, the cookie will be available to the specified domain and all its subdomains.\n\t *\n\t * Use this when you need cookies to be shared across subdomains (e.g., between `app.example.com` and `api.example.com`).\n\t * The default behavior (no domain) ensures better compatibility with server-side cookies that don't specify a domain attribute.\n\t *\n\t * @example\n\t * ```ts\n\t * // Default: exact domain only (compatible with server-side cookies)\n\t * cookieDomain: undefined // Cookie: \"PARAGLIDE_LOCALE=en; path=/; max-age=34560000\"\n\t *\n\t * // Subdomain sharing: available across all subdomains\n\t * cookieDomain: \"example.com\" // Cookie: \"PARAGLIDE_LOCALE=en; path=/; max-age=34560000; domain=example.com\"\n\t * ```\n\t *\n\t * @default \"\" (no domain attribute, exact domain only)\n\t */\n\tcookieDomain?: string;\n\t/**\n\t * The `additionalFiles` option is an array of paths to additional files that should be copied to the output directory.\n\t *\n\t * @example\n\t *\n\t * ```diff\n\t * await compile({\n\t * project: \"./project.inlang\",\n\t * outdir: \"./src/paraglide\",\n\t * additionalFiles: [\n\t * + \"my-file.js\": \"console.log('hello')\"\n\t * ]\n\t * })\n\t * ```\n\t *\n\t * The output will look like this:\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - my-file.js\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t */\n\tadditionalFiles?: Record<string, string>;\n\t/**\n\t * If `emitPrettierIgnore` is set to `true` a `.prettierignore` file will be emitted in the output directory. Defaults to `true`.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - .prettierignore\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * @default true\n\t */\n\temitPrettierIgnore?: boolean;\n\t/**\n\t * If `emitReadme` is set to `true` a `README.md` file will be emitted in the output directory. Defaults to `true`.\n\t *\n\t * The README helps LLMs understand the compiled output.\n\t * See https://llmstxt.org/ for format guidelines.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - README.md\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * @default true\n\t */\n\temitReadme?: boolean;\n\t/**\n\t * Emit `.d.ts` files for the generated output using the TypeScript compiler.\n\t *\n\t * Useful when `allowJs: true` cannot be set in your `tsconfig.json`\n\t * (e.g., due to project constraints or conflicting compiler options), or when\n\t * an editor language server caches stale JSDoc types for generated messages.\n\t *\n\t * Requires `typescript` to be resolvable in your toolchain.\n\t *\n\t * **Note:** Enabling this option reduces compiler speed because TypeScript\n\t * needs to generate declaration files for all output modules.\n\t *\n\t * **Note:** With TypeScript 5/6 the declarations are generated in-process.\n\t * TypeScript 7+ no longer provides the compiler API, so its `tsc` CLI is\n\t * invoked in a child process instead; the emitted declarations are\n\t * semantically equivalent but differ cosmetically between the two.\n\t *\n\t * @example\n\t * ```ts\n\t * await compile({\n\t * project: \"./project.inlang\",\n\t * outdir: \"./src/paraglide\",\n\t * emitTsDeclarations: true,\n\t * });\n\t * ```\n\t *\n\t * @default false\n\t */\n\temitTsDeclarations?: boolean;\n\t/**\n\t * Controls which compiled files are written to `outdir`.\n\t *\n\t * - `true` — write the full output tree (default). Required for the CLI\n\t * and for bundlers that cannot load virtual modules (webpack, etc.).\n\t * - `\"types\"` — write `.d.ts` plus meta files (`.gitignore`,\n\t * `.prettierignore`, `README.md`, `messages/package.json`). Generated\n\t * `.js` is served from memory by the Vite/Rolldown plugins.\n\t * - `false` — write nothing except `.d.ts` when `emitTsDeclarations` is\n\t * enabled. Generated `.js` is virtual only.\n\t *\n\t * @default true\n\t */\n\temitFiles?: true | false | \"types\";\n\t/**\n\t * Custom URL patterns for advanced i18n routing (translated pathnames, domains, etc.).\n\t *\n\t * Uses the global [URLPattern](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API) API.\n\t * Default locale-prefix routing and {@link CompilerOptions.routing} do not need URLPattern.\n\t * For older browsers/runtimes, load a polyfill (e.g. `import \"urlpattern-polyfill\"`) before the\n\t * generated runtime. See https://paraglidejs.com/i18n-routing#urlpattern-compatibility\n\t *\n\t * https://paraglidejs.com/strategy#url\n\t */\n\turlPatterns?: Runtime[\"urlPatterns\"];\n\t/**\n\t * Fast per-host locale prefix routing (no URLPattern).\n\t *\n\t * When set, Paraglide uses string path ops instead of `urlPatterns`.\n\t * Do not combine with `urlPatterns`.\n\t *\n\t * @see RoutingConfig\n\t */\n\trouting?: RoutingConfig;\n\t/**\n\t * Controls trailing slash canonicalization for localized URLs.\n\t *\n\t * Canonicalization happens before URL pattern matching and after URL\n\t * localization. If omitted, Paraglide keeps its existing trailing slash\n\t * behavior.\n\t */\n\ttrailingSlash?: \"always\" | \"never\";\n\t/**\n\t * Whether to include an eslint-disable comment at the top of each .js file.\n\t *\n\t * @default true\n\t */\n\tincludeEslintDisableComment?: boolean;\n\t/**\n\t * Replaces AsyncLocalStorage with a synchronous implementation.\n\t *\n\t * Leave AsyncLocalStorage enabled by default. This option is a\n\t * compatibility fallback for runtimes that do not provide\n\t * AsyncLocalStorage or `node:async_hooks`.\n\t *\n\t * ⚠️ WARNING: Only use this option when your runtime also guarantees\n\t * request isolation. Disabling AsyncLocalStorage in multi-request\n\t * server environments risks cross-request pollution where state from\n\t * one request could leak into another concurrent request.\n\t */\n\tdisableAsyncLocalStorage?: boolean;\n\t/**\n\t * If `emitGitIgnore` is set to `true` a `.gitignore` file will be emitted in the output directory. Defaults to `true`.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - .gitignore\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * @default true\n\t */\n\temitGitIgnore?: boolean;\n\t/**\n\t * The `outputStructure` defines how modules are structured in the output.\n\t *\n\t * - `message-modules` - Each module is a message. This is the default.\n\t * - `locale-modules` - Each module is a locale.\n\t *\n\t * It is recommended to use `locale-modules` for development and `message-modules` for production.\n\t * Bundlers speed up the dev mode by bypassing bundling which can lead to many http requests\n\t * during the dev mode with `message-modules`. See https://github.com/opral/inlang-paraglide-js/issues/486.\n\t *\n\t * **`message-modules`**\n\t *\n\t * Messages have their own module which eases tree-shaking for bundlers.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - blue_elephant_tree/\n\t * + - index.js\n\t * + - en.js\n\t * + - fr.js\n\t * + - sky_phone_bottle/\n\t * + - index.js\n\t * + - en.js\n\t * + - fr.js\n\t * - ...\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * **`locale-modules`**\n\t *\n\t * Messages are bundled in a per locale module. Bundlers often struggle with tree-shaking this structure,\n\t * which can lead to more inefficient tree-shaking and larger bundle sizes compared to `message-modules`.\n\t *\n\t * The benefit are substantially fewer files which is needed in large projects.\n\t *\n\t * ```diff\n\t * - outdir/\n\t * - messages/\n\t * + - de.js\n\t * + - en.js\n\t * + - fr.js\n\t * - ...\n\t * - messages.js\n\t * - runtime.js\n\t * ```\n\t *\n\t * @default \"message-modules\"\n\t */\n\toutputStructure?: \"locale-modules\" | \"message-modules\";\n\t/**\n\t * Whether to clean the output directory before writing the new files.\n\t *\n\t * @default true\n\t */\n\tcleanOutdir?: boolean;\n\n\t/**\n\t * The file system to use. Defaults to `await import('node:fs')`.\n\t *\n\t * Useful for testing the paraglide compiler by mocking the fs.\n\t */\n\tfs?: any;\n};\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ParaglideSettings } from "../messages/ast.js";
|
|
2
|
+
import { type CompiledBundleWithMessages } from "./compile-bundle.js";
|
|
3
|
+
/**
|
|
4
|
+
* Hand-rolled `.d.ts` for message modules (no TypeScript compiler).
|
|
5
|
+
*
|
|
6
|
+
* Covers:
|
|
7
|
+
* - `messages.js`
|
|
8
|
+
* - `messages/_index.js`
|
|
9
|
+
* - locale-modules: `messages/{locale}.js`
|
|
10
|
+
* - message-modules: `messages/{id}.js`
|
|
11
|
+
*
|
|
12
|
+
* Runtime / server / registry declarations still go through `emitTsDeclarations`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function emitMessageDeclarations(args: {
|
|
15
|
+
compiledBundles: CompiledBundleWithMessages[];
|
|
16
|
+
settings: Pick<ParaglideSettings, "locales" | "baseLocale">;
|
|
17
|
+
outputStructure: "locale-modules" | "message-modules";
|
|
18
|
+
}): Record<string, string>;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { escapeForDoubleQuoteString } from "../services/codegen/escape.js";
|
|
2
|
+
import { buildMarkupSchemaType, bundleHasMarkup, toBundleInputTypeAliasName, } from "./compile-bundle.js";
|
|
3
|
+
import { inputsType } from "./jsdoc-types.js";
|
|
4
|
+
import { toSafeModuleId } from "./safe-module-id.js";
|
|
5
|
+
/**
|
|
6
|
+
* Hand-rolled `.d.ts` for message modules (no TypeScript compiler).
|
|
7
|
+
*
|
|
8
|
+
* Covers:
|
|
9
|
+
* - `messages.js`
|
|
10
|
+
* - `messages/_index.js`
|
|
11
|
+
* - locale-modules: `messages/{locale}.js`
|
|
12
|
+
* - message-modules: `messages/{id}.js`
|
|
13
|
+
*
|
|
14
|
+
* Runtime / server / registry declarations still go through `emitTsDeclarations`.
|
|
15
|
+
*/
|
|
16
|
+
export function emitMessageDeclarations(args) {
|
|
17
|
+
const { compiledBundles, settings, outputStructure } = args;
|
|
18
|
+
const locales = settings.locales;
|
|
19
|
+
const localesUnion = locales.length === 0
|
|
20
|
+
? "never"
|
|
21
|
+
: locales.map((locale) => `"${escapeForDoubleQuoteString(locale)}"`).join(" | ");
|
|
22
|
+
const optionsType = `{ locale?: ${localesUnion} }`;
|
|
23
|
+
const declarations = {
|
|
24
|
+
"messages.d.ts": [
|
|
25
|
+
`export * from "./messages/_index.js";`,
|
|
26
|
+
`export * as m from "./messages/_index.js";`,
|
|
27
|
+
``,
|
|
28
|
+
].join("\n"),
|
|
29
|
+
};
|
|
30
|
+
if (outputStructure === "message-modules") {
|
|
31
|
+
Object.assign(declarations, emitMessageModulesDeclarations(compiledBundles, optionsType));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
Object.assign(declarations, emitLocaleModulesDeclarations(compiledBundles, locales, optionsType));
|
|
35
|
+
}
|
|
36
|
+
return declarations;
|
|
37
|
+
}
|
|
38
|
+
function emitMessageModulesDeclarations(compiledBundles, optionsType) {
|
|
39
|
+
const declarations = {};
|
|
40
|
+
const indexExports = [];
|
|
41
|
+
for (const compiled of compiledBundles) {
|
|
42
|
+
const safeModuleId = toSafeModuleId(compiled.bundle.node.id);
|
|
43
|
+
const filename = `messages/${safeModuleId}.d.ts`;
|
|
44
|
+
declarations[filename] = emitBundleDispatcherDts(compiled, optionsType);
|
|
45
|
+
indexExports.push(`export * from "./${safeModuleId}.js";`);
|
|
46
|
+
}
|
|
47
|
+
declarations["messages/_index.d.ts"] = [
|
|
48
|
+
...indexExports,
|
|
49
|
+
`export type LocalizedString = import("../runtime.js").LocalizedString;`,
|
|
50
|
+
``,
|
|
51
|
+
].join("\n");
|
|
52
|
+
return declarations;
|
|
53
|
+
}
|
|
54
|
+
function emitLocaleModulesDeclarations(compiledBundles, locales, optionsType) {
|
|
55
|
+
const declarations = {};
|
|
56
|
+
// Shared index: all message dispatchers
|
|
57
|
+
const indexParts = [];
|
|
58
|
+
const inputTypeAliases = new Map();
|
|
59
|
+
for (const compiled of compiledBundles) {
|
|
60
|
+
const { inputTypeAliasName, inputTypeDefinition } = bundleTypeParts(compiled);
|
|
61
|
+
inputTypeAliases.set(inputTypeAliasName, inputTypeDefinition);
|
|
62
|
+
indexParts.push(emitBundleDispatcherDtsBody(compiled, optionsType, {
|
|
63
|
+
// Index file declares aliases once at the bottom via export type
|
|
64
|
+
emitInputTypeAlias: false,
|
|
65
|
+
emitLocalizedStringAlias: false,
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
const typeAliases = [
|
|
69
|
+
`export type LocalizedString = import("../runtime.js").LocalizedString;`,
|
|
70
|
+
...[...inputTypeAliases.entries()].map(([name, def]) => `export type ${name} = ${def};`),
|
|
71
|
+
];
|
|
72
|
+
declarations["messages/_index.d.ts"] = [...indexParts, ...typeAliases, ``].join("\n");
|
|
73
|
+
// Per-locale implementation modules
|
|
74
|
+
for (const locale of locales) {
|
|
75
|
+
const safeLocale = toSafeModuleId(locale);
|
|
76
|
+
const lines = [];
|
|
77
|
+
const localeInputAliases = new Map();
|
|
78
|
+
for (const compiled of compiledBundles) {
|
|
79
|
+
const { safeModuleId, inputTypeAliasName, inputTypeDefinition, hasMarkup } = bundleTypeParts(compiled);
|
|
80
|
+
localeInputAliases.set(inputTypeAliasName, inputTypeDefinition);
|
|
81
|
+
// Match JSDoc on locale message functions: inputs always present in the type.
|
|
82
|
+
if (hasMarkup) {
|
|
83
|
+
lines.push(`export const ${safeModuleId}: ((inputs: ${inputTypeAliasName}) => LocalizedString) & { parts: (inputs: ${inputTypeAliasName}) => import("../runtime.js").MessagePart[] };`);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
lines.push(`export const ${safeModuleId}: (inputs: ${inputTypeAliasName}) => LocalizedString;`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
declarations[`messages/${safeLocale}.d.ts`] = [
|
|
90
|
+
`export type LocalizedString = import("../runtime.js").LocalizedString;`,
|
|
91
|
+
...[...localeInputAliases.entries()].map(([name, def]) => `export type ${name} = ${def};`),
|
|
92
|
+
...lines,
|
|
93
|
+
``,
|
|
94
|
+
].join("\n");
|
|
95
|
+
}
|
|
96
|
+
return declarations;
|
|
97
|
+
}
|
|
98
|
+
function nestedBundle(compiled) {
|
|
99
|
+
// compileBundle stores the full BundleNested on `.node` even though the
|
|
100
|
+
// public Compiled<> type is typed as the shallow Bundle shape.
|
|
101
|
+
return compiled.bundle.node;
|
|
102
|
+
}
|
|
103
|
+
function bundleTypeParts(compiled) {
|
|
104
|
+
const bundle = nestedBundle(compiled);
|
|
105
|
+
const bundleId = bundle.id;
|
|
106
|
+
const safeModuleId = toSafeModuleId(bundleId);
|
|
107
|
+
const isSafeId = safeModuleId === bundleId;
|
|
108
|
+
const inputs = bundle.declarations?.filter((decl) => decl.type === "input-variable") ??
|
|
109
|
+
[];
|
|
110
|
+
const inputTypeAliasName = compiled.inputTypeAliasName ?? toBundleInputTypeAliasName(safeModuleId);
|
|
111
|
+
const inputTypeDefinition = inputsType(inputs, compiled.matchTypes);
|
|
112
|
+
const hasMarkup = bundleHasMarkup(bundle);
|
|
113
|
+
const markupSchemaType = buildMarkupSchemaType(bundle, compiled.matchTypes);
|
|
114
|
+
const hasInputs = inputs.length > 0;
|
|
115
|
+
return {
|
|
116
|
+
bundleId,
|
|
117
|
+
safeModuleId,
|
|
118
|
+
isSafeId,
|
|
119
|
+
inputs,
|
|
120
|
+
inputTypeAliasName,
|
|
121
|
+
inputTypeDefinition,
|
|
122
|
+
hasMarkup,
|
|
123
|
+
markupSchemaType,
|
|
124
|
+
hasInputs,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Full `.d.ts` file for a single message-module dispatcher.
|
|
129
|
+
*/
|
|
130
|
+
function emitBundleDispatcherDts(compiled, optionsType) {
|
|
131
|
+
const body = emitBundleDispatcherDtsBody(compiled, optionsType, {
|
|
132
|
+
emitInputTypeAlias: true,
|
|
133
|
+
emitLocalizedStringAlias: true,
|
|
134
|
+
});
|
|
135
|
+
return body + (body.endsWith("\n") ? "" : "\n");
|
|
136
|
+
}
|
|
137
|
+
function emitBundleDispatcherDtsBody(compiled, optionsType, opts) {
|
|
138
|
+
const { bundleId, safeModuleId, isSafeId, inputTypeAliasName, inputTypeDefinition, hasMarkup, markupSchemaType, hasInputs, } = bundleTypeParts(compiled);
|
|
139
|
+
const inputsParam = hasInputs
|
|
140
|
+
? `inputs: ${inputTypeAliasName}`
|
|
141
|
+
: `inputs?: ${inputTypeAliasName}`;
|
|
142
|
+
const callSignature = `(${inputsParam}, options?: ${optionsType}) => LocalizedString`;
|
|
143
|
+
const partsSignature = `(${inputsParam}, options?: ${optionsType}) => import("../runtime.js").MessagePart[]`;
|
|
144
|
+
const metadataType = `import("../runtime.js").MessageMetadata<${inputTypeAliasName}, ${optionsType}, ${markupSchemaType}>`;
|
|
145
|
+
const valueType = hasMarkup
|
|
146
|
+
? `(${callSignature}) & { parts: ${partsSignature} } & ${metadataType}`
|
|
147
|
+
: `(${callSignature}) & ${metadataType}`;
|
|
148
|
+
const lines = [];
|
|
149
|
+
if (opts.emitLocalizedStringAlias) {
|
|
150
|
+
lines.push(`export type LocalizedString = import("../runtime.js").LocalizedString;`);
|
|
151
|
+
}
|
|
152
|
+
if (opts.emitInputTypeAlias) {
|
|
153
|
+
lines.push(`export type ${inputTypeAliasName} = ${inputTypeDefinition};`);
|
|
154
|
+
}
|
|
155
|
+
if (isSafeId) {
|
|
156
|
+
lines.push(`export const ${safeModuleId}: ${valueType};`);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
// Match TypeScript 7: declare const + quoted export alias
|
|
160
|
+
lines.push(`declare const ${safeModuleId}: ${valueType};`);
|
|
161
|
+
lines.push(`export { ${safeModuleId} as "${escapeForDoubleQuoteString(bundleId)}" };`);
|
|
162
|
+
}
|
|
163
|
+
lines.push(``);
|
|
164
|
+
return lines.join("\n");
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=emit-message-dts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit-message-dts.js","sourceRoot":"","sources":["../../src/compiler/emit-message-dts.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BundleNested, ParaglideSettings } from \"../messages/ast.js\";\nimport { escapeForDoubleQuoteString } from \"../services/codegen/escape.js\";\nimport {\n\tbuildMarkupSchemaType,\n\tbundleHasMarkup,\n\ttoBundleInputTypeAliasName,\n\ttype CompiledBundleWithMessages,\n} from \"./compile-bundle.js\";\nimport { inputsType } from \"./jsdoc-types.js\";\nimport { toSafeModuleId } from \"./safe-module-id.js\";\n\n/**\n * Hand-rolled `.d.ts` for message modules (no TypeScript compiler).\n *\n * Covers:\n * - `messages.js`\n * - `messages/_index.js`\n * - locale-modules: `messages/{locale}.js`\n * - message-modules: `messages/{id}.js`\n *\n * Runtime / server / registry declarations still go through `emitTsDeclarations`.\n */\nexport function emitMessageDeclarations(args: {\n\tcompiledBundles: CompiledBundleWithMessages[];\n\tsettings: Pick<ParaglideSettings, \"locales\" | \"baseLocale\">;\n\toutputStructure: \"locale-modules\" | \"message-modules\";\n}): Record<string, string> {\n\tconst { compiledBundles, settings, outputStructure } = args;\n\tconst locales = settings.locales;\n\tconst localesUnion =\n\t\tlocales.length === 0\n\t\t\t? \"never\"\n\t\t\t: locales.map((locale) => `\"${escapeForDoubleQuoteString(locale)}\"`).join(\" | \");\n\tconst optionsType = `{ locale?: ${localesUnion} }`;\n\n\tconst declarations: Record<string, string> = {\n\t\t\"messages.d.ts\": [\n\t\t\t`export * from \"./messages/_index.js\";`,\n\t\t\t`export * as m from \"./messages/_index.js\";`,\n\t\t\t``,\n\t\t].join(\"\\n\"),\n\t};\n\n\tif (outputStructure === \"message-modules\") {\n\t\tObject.assign(\n\t\t\tdeclarations,\n\t\t\temitMessageModulesDeclarations(compiledBundles, optionsType)\n\t\t);\n\t} else {\n\t\tObject.assign(\n\t\t\tdeclarations,\n\t\t\temitLocaleModulesDeclarations(compiledBundles, locales, optionsType)\n\t\t);\n\t}\n\n\treturn declarations;\n}\n\nfunction emitMessageModulesDeclarations(\n\tcompiledBundles: CompiledBundleWithMessages[],\n\toptionsType: string\n): Record<string, string> {\n\tconst declarations: Record<string, string> = {};\n\tconst indexExports: string[] = [];\n\n\tfor (const compiled of compiledBundles) {\n\t\tconst safeModuleId = toSafeModuleId(compiled.bundle.node.id);\n\t\tconst filename = `messages/${safeModuleId}.d.ts`;\n\t\tdeclarations[filename] = emitBundleDispatcherDts(compiled, optionsType);\n\t\tindexExports.push(`export * from \"./${safeModuleId}.js\";`);\n\t}\n\n\tdeclarations[\"messages/_index.d.ts\"] = [\n\t\t...indexExports,\n\t\t`export type LocalizedString = import(\"../runtime.js\").LocalizedString;`,\n\t\t``,\n\t].join(\"\\n\");\n\n\treturn declarations;\n}\n\nfunction emitLocaleModulesDeclarations(\n\tcompiledBundles: CompiledBundleWithMessages[],\n\tlocales: string[],\n\toptionsType: string\n): Record<string, string> {\n\tconst declarations: Record<string, string> = {};\n\n\t// Shared index: all message dispatchers\n\tconst indexParts: string[] = [];\n\tconst inputTypeAliases = new Map<string, string>();\n\n\tfor (const compiled of compiledBundles) {\n\t\tconst { inputTypeAliasName, inputTypeDefinition } =\n\t\t\tbundleTypeParts(compiled);\n\t\tinputTypeAliases.set(inputTypeAliasName, inputTypeDefinition);\n\t\tindexParts.push(\n\t\t\temitBundleDispatcherDtsBody(compiled, optionsType, {\n\t\t\t\t// Index file declares aliases once at the bottom via export type\n\t\t\t\temitInputTypeAlias: false,\n\t\t\t\temitLocalizedStringAlias: false,\n\t\t\t})\n\t\t);\n\t}\n\n\tconst typeAliases = [\n\t\t`export type LocalizedString = import(\"../runtime.js\").LocalizedString;`,\n\t\t...[...inputTypeAliases.entries()].map(\n\t\t\t([name, def]) => `export type ${name} = ${def};`\n\t\t),\n\t];\n\n\tdeclarations[\"messages/_index.d.ts\"] = [...indexParts, ...typeAliases, ``].join(\n\t\t\"\\n\"\n\t);\n\n\t// Per-locale implementation modules\n\tfor (const locale of locales) {\n\t\tconst safeLocale = toSafeModuleId(locale);\n\t\tconst lines: string[] = [];\n\t\tconst localeInputAliases = new Map<string, string>();\n\n\t\tfor (const compiled of compiledBundles) {\n\t\t\tconst { safeModuleId, inputTypeAliasName, inputTypeDefinition, hasMarkup } =\n\t\t\t\tbundleTypeParts(compiled);\n\t\t\tlocaleInputAliases.set(inputTypeAliasName, inputTypeDefinition);\n\n\t\t\t// Match JSDoc on locale message functions: inputs always present in the type.\n\t\t\tif (hasMarkup) {\n\t\t\t\tlines.push(\n\t\t\t\t\t`export const ${safeModuleId}: ((inputs: ${inputTypeAliasName}) => LocalizedString) & { parts: (inputs: ${inputTypeAliasName}) => import(\"../runtime.js\").MessagePart[] };`\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tlines.push(\n\t\t\t\t\t`export const ${safeModuleId}: (inputs: ${inputTypeAliasName}) => LocalizedString;`\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tdeclarations[`messages/${safeLocale}.d.ts`] = [\n\t\t\t`export type LocalizedString = import(\"../runtime.js\").LocalizedString;`,\n\t\t\t...[...localeInputAliases.entries()].map(\n\t\t\t\t([name, def]) => `export type ${name} = ${def};`\n\t\t\t),\n\t\t\t...lines,\n\t\t\t``,\n\t\t].join(\"\\n\");\n\t}\n\n\treturn declarations;\n}\n\nfunction nestedBundle(compiled: CompiledBundleWithMessages): BundleNested {\n\t// compileBundle stores the full BundleNested on `.node` even though the\n\t// public Compiled<> type is typed as the shallow Bundle shape.\n\treturn compiled.bundle.node as BundleNested;\n}\n\nfunction bundleTypeParts(compiled: CompiledBundleWithMessages) {\n\tconst bundle = nestedBundle(compiled);\n\tconst bundleId = bundle.id;\n\tconst safeModuleId = toSafeModuleId(bundleId);\n\tconst isSafeId = safeModuleId === bundleId;\n\tconst inputs =\n\t\tbundle.declarations?.filter((decl) => decl.type === \"input-variable\") ??\n\t\t[];\n\tconst inputTypeAliasName =\n\t\tcompiled.inputTypeAliasName ?? toBundleInputTypeAliasName(safeModuleId);\n\tconst inputTypeDefinition = inputsType(inputs, compiled.matchTypes);\n\tconst hasMarkup = bundleHasMarkup(bundle);\n\tconst markupSchemaType = buildMarkupSchemaType(bundle, compiled.matchTypes);\n\tconst hasInputs = inputs.length > 0;\n\n\treturn {\n\t\tbundleId,\n\t\tsafeModuleId,\n\t\tisSafeId,\n\t\tinputs,\n\t\tinputTypeAliasName,\n\t\tinputTypeDefinition,\n\t\thasMarkup,\n\t\tmarkupSchemaType,\n\t\thasInputs,\n\t};\n}\n\n/**\n * Full `.d.ts` file for a single message-module dispatcher.\n */\nfunction emitBundleDispatcherDts(\n\tcompiled: CompiledBundleWithMessages,\n\toptionsType: string\n): string {\n\tconst body = emitBundleDispatcherDtsBody(compiled, optionsType, {\n\t\temitInputTypeAlias: true,\n\t\temitLocalizedStringAlias: true,\n\t});\n\treturn body + (body.endsWith(\"\\n\") ? \"\" : \"\\n\");\n}\n\nfunction emitBundleDispatcherDtsBody(\n\tcompiled: CompiledBundleWithMessages,\n\toptionsType: string,\n\topts: {\n\t\temitInputTypeAlias: boolean;\n\t\temitLocalizedStringAlias: boolean;\n\t}\n): string {\n\tconst {\n\t\tbundleId,\n\t\tsafeModuleId,\n\t\tisSafeId,\n\t\tinputTypeAliasName,\n\t\tinputTypeDefinition,\n\t\thasMarkup,\n\t\tmarkupSchemaType,\n\t\thasInputs,\n\t} = bundleTypeParts(compiled);\n\n\tconst inputsParam = hasInputs\n\t\t? `inputs: ${inputTypeAliasName}`\n\t\t: `inputs?: ${inputTypeAliasName}`;\n\n\tconst callSignature = `(${inputsParam}, options?: ${optionsType}) => LocalizedString`;\n\tconst partsSignature = `(${inputsParam}, options?: ${optionsType}) => import(\"../runtime.js\").MessagePart[]`;\n\tconst metadataType = `import(\"../runtime.js\").MessageMetadata<${inputTypeAliasName}, ${optionsType}, ${markupSchemaType}>`;\n\n\tconst valueType = hasMarkup\n\t\t? `(${callSignature}) & { parts: ${partsSignature} } & ${metadataType}`\n\t\t: `(${callSignature}) & ${metadataType}`;\n\n\tconst lines: string[] = [];\n\n\tif (opts.emitLocalizedStringAlias) {\n\t\tlines.push(\n\t\t\t`export type LocalizedString = import(\"../runtime.js\").LocalizedString;`\n\t\t);\n\t}\n\tif (opts.emitInputTypeAlias) {\n\t\tlines.push(`export type ${inputTypeAliasName} = ${inputTypeDefinition};`);\n\t}\n\n\tif (isSafeId) {\n\t\tlines.push(`export const ${safeModuleId}: ${valueType};`);\n\t} else {\n\t\t// Match TypeScript 7: declare const + quoted export alias\n\t\tlines.push(`declare const ${safeModuleId}: ${valueType};`);\n\t\tlines.push(\n\t\t\t`export { ${safeModuleId} as \"${escapeForDoubleQuoteString(bundleId)}\" };`\n\t\t);\n\t}\n\n\tlines.push(``);\n\treturn lines.join(\"\\n\");\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|