@inlang/paraglide-js 2.25.4 → 2.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +2 -1
  2. package/dist/bundler-plugins/per-locale-build/vite-environments.test.js +2 -2
  3. package/dist/bundler-plugins/per-locale-build/vite-environments.test.js.map +1 -1
  4. package/dist/cli/commands/init/command.js +19 -1
  5. package/dist/cli/commands/init/command.js.map +1 -1
  6. package/dist/cli/defaults.js +2 -2
  7. package/dist/cli/defaults.js.map +1 -1
  8. package/dist/cli/steps/add-inlang-check.d.ts +19 -0
  9. package/dist/cli/steps/add-inlang-check.js +60 -0
  10. package/dist/cli/steps/add-inlang-check.js.map +1 -0
  11. package/dist/cli/steps/add-inlang-check.test.d.ts +1 -0
  12. package/dist/cli/steps/add-inlang-check.test.js +88 -0
  13. package/dist/cli/steps/add-inlang-check.test.js.map +1 -0
  14. package/dist/cli/steps/agents-md-suggestion.d.ts +11 -0
  15. package/dist/cli/steps/agents-md-suggestion.js +19 -0
  16. package/dist/cli/steps/agents-md-suggestion.js.map +1 -0
  17. package/dist/cli/steps/agents-md-suggestion.test.d.ts +1 -0
  18. package/dist/cli/steps/agents-md-suggestion.test.js +36 -0
  19. package/dist/cli/steps/agents-md-suggestion.test.js.map +1 -0
  20. package/dist/cli/steps/maybe-add-machine-translation.js +3 -2
  21. package/dist/cli/steps/maybe-add-machine-translation.js.map +1 -1
  22. package/dist/cli/steps/maybe-add-sherlock.js +1 -1
  23. package/dist/cli/steps/maybe-add-sherlock.js.map +1 -1
  24. package/dist/cli/utils.d.ts +9 -0
  25. package/dist/cli/utils.js +15 -0
  26. package/dist/cli/utils.js.map +1 -1
  27. package/dist/compiler/compile-annotation.d.ts +48 -1
  28. package/dist/compiler/compile-annotation.js +238 -10
  29. package/dist/compiler/compile-annotation.js.map +1 -1
  30. package/dist/compiler/compile-bundle.d.ts +3 -2
  31. package/dist/compiler/compile-bundle.js +30 -1
  32. package/dist/compiler/compile-bundle.js.map +1 -1
  33. package/dist/compiler/compile-bundle.test.js +18 -18
  34. package/dist/compiler/compile-bundle.test.js.map +1 -1
  35. package/dist/compiler/compile-local-variable.d.ts +3 -0
  36. package/dist/compiler/compile-local-variable.js +5 -2
  37. package/dist/compiler/compile-local-variable.js.map +1 -1
  38. package/dist/compiler/compile-local-variable.test.js +44 -4
  39. package/dist/compiler/compile-local-variable.test.js.map +1 -1
  40. package/dist/compiler/compile-message.d.ts +29 -1
  41. package/dist/compiler/compile-message.exact-number.test.d.ts +1 -0
  42. package/dist/compiler/compile-message.exact-number.test.js +786 -0
  43. package/dist/compiler/compile-message.exact-number.test.js.map +1 -0
  44. package/dist/compiler/compile-message.js +162 -66
  45. package/dist/compiler/compile-message.js.map +1 -1
  46. package/dist/compiler/compile-message.locals.test.d.ts +1 -0
  47. package/dist/compiler/compile-message.locals.test.js +498 -0
  48. package/dist/compiler/compile-message.locals.test.js.map +1 -0
  49. package/dist/compiler/compile-message.test.js +111 -20
  50. package/dist/compiler/compile-message.test.js.map +1 -1
  51. package/dist/compiler/compile-pattern.d.ts +5 -0
  52. package/dist/compiler/compile-pattern.js +6 -18
  53. package/dist/compiler/compile-pattern.js.map +1 -1
  54. package/dist/compiler/compile-pattern.test.js +165 -1
  55. package/dist/compiler/compile-pattern.test.js.map +1 -1
  56. package/dist/compiler/compile-project.js +4 -1
  57. package/dist/compiler/compile-project.js.map +1 -1
  58. package/dist/compiler/compile-project.test.js +1013 -31
  59. package/dist/compiler/compile-project.test.js.map +1 -1
  60. package/dist/compiler/compile.test.js +1 -1
  61. package/dist/compiler/compile.test.js.map +1 -1
  62. package/dist/compiler/create-readme.d.ts +4 -1
  63. package/dist/compiler/create-readme.js +33 -125
  64. package/dist/compiler/create-readme.js.map +1 -1
  65. package/dist/compiler/emit-ts-declarations.interop.test.js +2 -2
  66. package/dist/compiler/emit-ts-declarations.interop.test.js.map +1 -1
  67. package/dist/compiler/emit-ts-declarations.test.js +4 -4
  68. package/dist/compiler/emit-ts-declarations.test.js.map +1 -1
  69. package/dist/compiler/index.d.ts +1 -1
  70. package/dist/compiler/index.js +1 -1
  71. package/dist/compiler/index.js.map +1 -1
  72. package/dist/compiler/input-alias.d.ts +21 -0
  73. package/dist/compiler/input-alias.js +42 -0
  74. package/dist/compiler/input-alias.js.map +1 -0
  75. package/dist/compiler/input-alias.test.d.ts +1 -0
  76. package/dist/compiler/input-alias.test.js +58 -0
  77. package/dist/compiler/input-alias.test.js.map +1 -0
  78. package/dist/compiler/message-locals.d.ts +46 -0
  79. package/dist/compiler/message-locals.js +129 -0
  80. package/dist/compiler/message-locals.js.map +1 -0
  81. package/dist/compiler/output-structure/locale-modules.js +7 -1
  82. package/dist/compiler/output-structure/locale-modules.js.map +1 -1
  83. package/dist/compiler/output-structure/locale-modules.test.js +35 -0
  84. package/dist/compiler/output-structure/locale-modules.test.js.map +1 -1
  85. package/dist/compiler/output-structure/message-modules.js +5 -3
  86. package/dist/compiler/output-structure/message-modules.js.map +1 -1
  87. package/dist/compiler/output-structure/message-modules.test.js +35 -0
  88. package/dist/compiler/output-structure/message-modules.test.js.map +1 -1
  89. package/dist/compiler/registry.d.ts +12 -0
  90. package/dist/compiler/registry.js +97 -28
  91. package/dist/compiler/registry.js.map +1 -1
  92. package/dist/compiler/runtime/create-runtime.js +24 -1
  93. package/dist/compiler/runtime/create-runtime.js.map +1 -1
  94. package/dist/compiler/runtime/extract-locale-from-url.js +11 -4
  95. package/dist/compiler/runtime/extract-locale-from-url.js.map +1 -1
  96. package/dist/compiler/runtime/generate-static-localized-urls.js +5 -3
  97. package/dist/compiler/runtime/generate-static-localized-urls.js.map +1 -1
  98. package/dist/compiler/runtime/localize-url.js +25 -54
  99. package/dist/compiler/runtime/localize-url.js.map +1 -1
  100. package/dist/compiler/runtime/route-strategy.js +9 -3
  101. package/dist/compiler/runtime/route-strategy.js.map +1 -1
  102. package/dist/compiler/runtime/type.test.js +9 -0
  103. package/dist/compiler/runtime/type.test.js.map +1 -1
  104. package/dist/compiler/runtime/url-pattern-cache.d.ts +11 -0
  105. package/dist/compiler/runtime/url-pattern-cache.js +42 -0
  106. package/dist/compiler/runtime/url-pattern-cache.js.map +1 -0
  107. package/dist/compiler/runtime/url-pattern-index.d.ts +24 -0
  108. package/dist/compiler/runtime/url-pattern-index.differential.test.d.ts +1 -0
  109. package/dist/compiler/runtime/url-pattern-index.differential.test.js +152 -0
  110. package/dist/compiler/runtime/url-pattern-index.differential.test.js.map +1 -0
  111. package/dist/compiler/runtime/url-pattern-index.js +168 -0
  112. package/dist/compiler/runtime/url-pattern-index.js.map +1 -0
  113. package/dist/compiler/runtime/url-pattern-index.test.d.ts +1 -0
  114. package/dist/compiler/runtime/url-pattern-index.test.js +262 -0
  115. package/dist/compiler/runtime/url-pattern-index.test.js.map +1 -0
  116. package/dist/compiler/server/create-server-file.js +25 -1
  117. package/dist/compiler/server/create-server-file.js.map +1 -1
  118. package/dist/compiler/server/create-server-file.test.js +20 -2
  119. package/dist/compiler/server/create-server-file.test.js.map +1 -1
  120. package/dist/compiler/server/middleware.js +29 -4
  121. package/dist/compiler/server/middleware.js.map +1 -1
  122. package/dist/services/env-variables/index.js +1 -1
  123. package/dist/services/env-variables/index.js.map +1 -1
  124. package/package.json +3 -3
@@ -1,5 +1,5 @@
1
1
  import { test, expect } from "vitest";
2
- import { compileMessage } from "./compile-message.js";
2
+ import { compileMessage, } from "./compile-message.js";
3
3
  import { createRegistry } from "./registry.js";
4
4
  test("compiles a message with a single variant", async () => {
5
5
  const declarations = [];
@@ -662,7 +662,7 @@ test("only emits input arguments when inputs exist", async () => {
662
662
  // https://github.com/opral/inlang-paraglide-js/issues/379
663
663
  test("compiles messages that use plural()", async () => {
664
664
  const declarations = [
665
- { type: "input-variable", name: "date" },
665
+ { type: "input-variable", name: "count" },
666
666
  {
667
667
  type: "local-variable",
668
668
  name: "countPlural",
@@ -706,8 +706,9 @@ test("compiles messages that use plural()", async () => {
706
706
  const compiled = compileMessage(declarations, message, variants);
707
707
  const { plural_test } = await import("data:text/javascript;base64," +
708
708
  // bundling the registry inline to avoid managing module imports here
709
- btoa(createRegistry()) +
710
- btoa("export const plural_test = " + compiled.code.replace("registry.", "")));
709
+ btoa(createRegistry() +
710
+ "export const plural_test = " +
711
+ compiled.code.replace("registry.", "")));
711
712
  expect(plural_test({ count: 1 })).toBe("There is one cat.");
712
713
  expect(plural_test({ count: 2 })).toBe("There are many cats.");
713
714
  // INTL.plural will match "other" for undefined
@@ -790,8 +791,9 @@ test("compiles messages that use plural() with ordinal type", async () => {
790
791
  ];
791
792
  const compiled = compileMessage(declarations, message, variants);
792
793
  const { ordinal_test } = await import("data:text/javascript;base64," +
793
- btoa(createRegistry()) +
794
- btoa("export const ordinal_test = " + compiled.code.replace("registry.", "")));
794
+ btoa(createRegistry() +
795
+ "export const ordinal_test = " +
796
+ compiled.code.replace("registry.", "")));
795
797
  expect(ordinal_test({ count: 1 })).toBe("1st place");
796
798
  expect(ordinal_test({ count: 2 })).toBe("2nd place");
797
799
  expect(ordinal_test({ count: 3 })).toBe("3rd place");
@@ -839,8 +841,9 @@ test("compiles messages that use number()", async () => {
839
841
  const compiled = compileMessage(declarations, message, variants);
840
842
  const { number_test } = await import("data:text/javascript;base64," +
841
843
  // bundling the registry inline to avoid managing module imports here
842
- btoa(createRegistry()) +
843
- btoa("export const number_test = " + compiled.code.replace("registry.", "")));
844
+ btoa(createRegistry() +
845
+ "export const number_test = " +
846
+ compiled.code.replace("registry.", "")));
844
847
  return number_test;
845
848
  };
846
849
  const enMessage = await createMessage("en");
@@ -899,8 +902,9 @@ test("compiles messages that use number() with options", async () => {
899
902
  const compiled = compileMessage(declarations, message, variants);
900
903
  const { number_test } = await import("data:text/javascript;base64," +
901
904
  // bundling the registry inline to avoid managing module imports here
902
- btoa(createRegistry()) +
903
- btoa("export const number_test = " + compiled.code.replace("registry.", "")));
905
+ btoa(createRegistry() +
906
+ "export const number_test = " +
907
+ compiled.code.replace("registry.", "")));
904
908
  return number_test;
905
909
  };
906
910
  const enMessage = await createMessage("en");
@@ -950,15 +954,20 @@ test("compiles messages that use datetime()", async () => {
950
954
  const compiled = compileMessage(declarations, message, variants);
951
955
  const { datetime_test } = await import("data:text/javascript;base64," +
952
956
  // bundling the registry inline to avoid managing module imports here
953
- btoa(createRegistry()) +
954
- btoa("export const datetime_test =" +
957
+ btoa(createRegistry() +
958
+ "export const datetime_test =" +
955
959
  compiled.code.replace("registry.", "")));
956
960
  return datetime_test;
957
961
  };
958
962
  const enMessage = await createMessage("en");
959
963
  const deMessage = await createMessage("de");
960
- expect(enMessage({ date: "2022-04-01" })).toMatch(/Today is \d{1,2}\/\d{1,2}\/2022\./);
961
- expect(deMessage({ date: "2022-04-01" })).toMatch(/Today is \d{1,2}\.\d{1,2}\.2022\./);
964
+ // MessageFormat 2's default: dateStyle=medium timeStyle=short. Compared
965
+ // with Intl to avoid the timezone affecting the unit test.
966
+ const date = new Date("2022-04-01");
967
+ const options = { dateStyle: "medium", timeStyle: "short" };
968
+ expect(enMessage({ date: "2022-04-01" })).toBe(`Today is ${new Intl.DateTimeFormat("en", options).format(date)}.`);
969
+ expect(enMessage({ date: "2022-04-01" })).toMatch(/Today is (Mar 31|Apr 1), 2022, \d{1,2}:\d{2}\s[AP]M\./);
970
+ expect(deMessage({ date: "2022-04-01" })).toBe(`Today is ${new Intl.DateTimeFormat("de", options).format(date)}.`);
962
971
  });
963
972
  test("compiles messages that use datetime a function with options", async () => {
964
973
  const createMessage = async (locale) => {
@@ -1005,8 +1014,8 @@ test("compiles messages that use datetime a function with options", async () =>
1005
1014
  const compiled = compileMessage(declarations, message, variants);
1006
1015
  const { datetime_test } = await import("data:text/javascript;base64," +
1007
1016
  // bundling the registry inline to avoid managing module imports here
1008
- btoa(createRegistry()) +
1009
- btoa("export const datetime_test = " +
1017
+ btoa(createRegistry() +
1018
+ "export const datetime_test = " +
1010
1019
  compiled.code.replace("registry.", "")));
1011
1020
  return datetime_test;
1012
1021
  };
@@ -1062,8 +1071,8 @@ test("compiles messages that use relativetime() with options", async () => {
1062
1071
  const compiled = compileMessage(declarations, message, variants);
1063
1072
  const { relative_time_test } = await import("data:text/javascript;base64," +
1064
1073
  // bundling the registry inline to avoid managing module imports here
1065
- btoa(createRegistry()) +
1066
- btoa("export const relative_time_test = " +
1074
+ btoa(createRegistry() +
1075
+ "export const relative_time_test = " +
1067
1076
  compiled.code.replace("registry.", "")));
1068
1077
  return relative_time_test;
1069
1078
  };
@@ -1120,8 +1129,8 @@ test("compiles messages that use relativetime() with dynamic units", async () =>
1120
1129
  const compiled = compileMessage(declarations, message, variants);
1121
1130
  const { relative_time_test } = await import("data:text/javascript;base64," +
1122
1131
  // bundling the registry inline to avoid managing module imports here
1123
- btoa(createRegistry()) +
1124
- btoa("export const relative_time_test = " +
1132
+ btoa(createRegistry() +
1133
+ "export const relative_time_test = " +
1125
1134
  compiled.code.replace("registry.", "")));
1126
1135
  expect(relative_time_test({ duration: -3, unit: "hour" })).toBe("Updated 3 hr. ago.");
1127
1136
  });
@@ -1187,4 +1196,86 @@ test("does not throw when input is omitted for multi-variant message", async ()
1187
1196
  expect(() => status_message()).not.toThrow();
1188
1197
  expect(status_message()).toBe("Unknown status");
1189
1198
  });
1199
+ // `selectBundleNested()` of `@inlang/sdk` 4 returns `bundle_id` on messages,
1200
+ // the plugin `Message` shape has `bundleId`. Without a catch-all variant, the
1201
+ // message falls back to the bundle id with either.
1202
+ test.each([
1203
+ { shape: "plugin Message (bundleId)", ids: { bundleId: "item_count" } },
1204
+ { shape: "database row (bundle_id)", ids: { bundle_id: "item_count" } },
1205
+ ])("falls back to the bundle id for a $shape", async ({ ids }) => {
1206
+ const declarations = [
1207
+ { type: "input-variable", name: "count" },
1208
+ ];
1209
+ const message = {
1210
+ ...ids,
1211
+ id: "item_count_en",
1212
+ locale: "en",
1213
+ selectors: [{ type: "variable-reference", name: "count" }],
1214
+ };
1215
+ const variants = [
1216
+ {
1217
+ id: "item_count_en_one",
1218
+ matches: [{ type: "literal-match", key: "count", value: "one" }],
1219
+ pattern: [{ type: "text", value: "One item" }],
1220
+ },
1221
+ {
1222
+ id: "item_count_en_two",
1223
+ matches: [{ type: "literal-match", key: "count", value: "two" }],
1224
+ pattern: [{ type: "text", value: "Two items" }],
1225
+ },
1226
+ ];
1227
+ const markupVariants = [
1228
+ {
1229
+ id: "item_count_en_one",
1230
+ matches: [{ type: "literal-match", key: "count", value: "one" }],
1231
+ pattern: [
1232
+ { type: "markup-start", name: "b" },
1233
+ { type: "text", value: "One item" },
1234
+ { type: "markup-end", name: "b" },
1235
+ ],
1236
+ },
1237
+ {
1238
+ id: "item_count_en_two",
1239
+ matches: [{ type: "literal-match", key: "count", value: "two" }],
1240
+ pattern: [{ type: "text", value: "Two items" }],
1241
+ },
1242
+ ];
1243
+ const compiled = compileMessage(declarations, message, variants);
1244
+ const compiledMarkup = compileMessage(declarations, message, markupVariants);
1245
+ const { item_count, item_count_markup } = await import("data:text/javascript;base64," +
1246
+ btoa(`export const item_count = ${compiled.code}\nexport const item_count_markup = ${compiledMarkup.code}`));
1247
+ expect(item_count({ count: "one" })).toBe("One item");
1248
+ expect(item_count({ count: "other" })).toBe("item_count");
1249
+ expect(item_count_markup({ count: "other" })).toBe("item_count");
1250
+ expect(item_count_markup.parts({ count: "other" })).toEqual([
1251
+ { type: "text", value: "item_count" },
1252
+ ]);
1253
+ });
1254
+ test("throws for a message without a bundle id instead of compiling undefined", () => {
1255
+ expect(() => compileMessage([], { id: "orphan", locale: "en", selectors: [] }, [
1256
+ { id: "1", matches: [], pattern: [{ type: "text", value: "Hi" }] },
1257
+ ])).toThrow(/has no bundle id/);
1258
+ });
1259
+ test("escapes the bundle id in the fallback of messages without a catch-all variant", async () => {
1260
+ const bundleId = 'quote"and\\backslash';
1261
+ const compiled = compileMessage([{ type: "input-variable", name: "count" }], {
1262
+ bundleId,
1263
+ id: "m",
1264
+ locale: "en",
1265
+ selectors: [{ type: "variable-reference", name: "count" }],
1266
+ }, [
1267
+ {
1268
+ id: "one",
1269
+ matches: [{ type: "literal-match", key: "count", value: "one" }],
1270
+ pattern: [{ type: "text", value: "One" }],
1271
+ },
1272
+ {
1273
+ id: "two",
1274
+ matches: [{ type: "literal-match", key: "count", value: "two" }],
1275
+ pattern: [{ type: "text", value: "Two" }],
1276
+ },
1277
+ ]);
1278
+ const { m } = await import("data:text/javascript;base64," + btoa(`export const m = ${compiled.code}`));
1279
+ expect(m({ count: "three" })).toBe(bundleId);
1280
+ });
1190
1281
  //# sourceMappingURL=compile-message.test.js.map