@inlang/sdk 0.35.5 → 0.35.7

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 (106) hide show
  1. package/dist/api.d.ts +2 -13
  2. package/dist/api.d.ts.map +1 -1
  3. package/dist/createNewProject.test.js +1 -3
  4. package/dist/loadProject.d.ts.map +1 -1
  5. package/dist/loadProject.js +67 -32
  6. package/dist/loadProject.test.js +6 -2
  7. package/dist/persistence/batchedIO.d.ts +11 -0
  8. package/dist/persistence/batchedIO.d.ts.map +1 -0
  9. package/dist/persistence/batchedIO.js +49 -0
  10. package/dist/persistence/batchedIO.test.d.ts +2 -0
  11. package/dist/persistence/batchedIO.test.d.ts.map +1 -0
  12. package/dist/persistence/batchedIO.test.js +56 -0
  13. package/dist/persistence/filelock/acquireFileLock.d.ts.map +1 -1
  14. package/dist/persistence/filelock/acquireFileLock.js +3 -1
  15. package/dist/persistence/filelock/releaseLock.d.ts.map +1 -1
  16. package/dist/persistence/filelock/releaseLock.js +2 -1
  17. package/dist/persistence/store.d.ts +107 -0
  18. package/dist/persistence/store.d.ts.map +1 -0
  19. package/dist/persistence/store.js +99 -0
  20. package/dist/persistence/store.test.d.ts +2 -0
  21. package/dist/persistence/store.test.d.ts.map +1 -0
  22. package/dist/persistence/store.test.js +79 -0
  23. package/dist/persistence/storeApi.d.ts +22 -0
  24. package/dist/persistence/storeApi.d.ts.map +1 -0
  25. package/dist/persistence/storeApi.js +1 -0
  26. package/dist/reactivity/solid.test.js +1 -6
  27. package/dist/resolve-modules/plugins/resolvePlugins.d.ts.map +1 -1
  28. package/dist/resolve-modules/plugins/resolvePlugins.js +3 -10
  29. package/dist/test-utilities/sleep.d.ts +4 -0
  30. package/dist/test-utilities/sleep.d.ts.map +1 -0
  31. package/dist/test-utilities/sleep.js +9 -0
  32. package/dist/v2/helper.d.ts +131 -0
  33. package/dist/v2/helper.d.ts.map +1 -0
  34. package/dist/v2/helper.js +75 -0
  35. package/dist/v2/helper.test.d.ts +2 -0
  36. package/dist/v2/helper.test.d.ts.map +1 -0
  37. package/dist/v2/{createMessageBundle.test.js → helper.test.js} +1 -1
  38. package/dist/v2/index.d.ts +2 -0
  39. package/dist/v2/index.d.ts.map +1 -1
  40. package/dist/v2/index.js +2 -1
  41. package/dist/v2/mocks/index.d.ts +3 -0
  42. package/dist/v2/mocks/index.d.ts.map +1 -0
  43. package/dist/v2/mocks/index.js +2 -0
  44. package/dist/v2/mocks/multipleMatcher/bundle.d.ts +3 -0
  45. package/dist/v2/mocks/multipleMatcher/bundle.d.ts.map +1 -0
  46. package/dist/v2/mocks/multipleMatcher/bundle.js +194 -0
  47. package/dist/v2/mocks/multipleMatcher/bundle.test.d.ts +2 -0
  48. package/dist/v2/mocks/multipleMatcher/bundle.test.d.ts.map +1 -0
  49. package/dist/v2/mocks/multipleMatcher/bundle.test.js +10 -0
  50. package/dist/v2/mocks/plural/bundle.d.ts +1 -1
  51. package/dist/v2/mocks/plural/bundle.d.ts.map +1 -1
  52. package/dist/v2/mocks/plural/bundle.js +1 -1
  53. package/dist/v2/mocks/plural/bundle.test.js +6 -6
  54. package/dist/v2/shim.d.ts +12 -0
  55. package/dist/v2/shim.d.ts.map +1 -0
  56. package/dist/v2/shim.js +151 -0
  57. package/dist/v2/shim.test.d.ts +2 -0
  58. package/dist/v2/shim.test.d.ts.map +1 -0
  59. package/dist/v2/shim.test.js +49 -0
  60. package/dist/v2/stubQueryApi.d.ts +9 -0
  61. package/dist/v2/stubQueryApi.d.ts.map +1 -0
  62. package/dist/v2/stubQueryApi.js +38 -0
  63. package/dist/v2/types.d.ts +110 -0
  64. package/dist/v2/types.d.ts.map +1 -1
  65. package/dist/v2/types.js +9 -0
  66. package/package.json +6 -5
  67. package/src/api.ts +2 -13
  68. package/src/createNewProject.test.ts +1 -4
  69. package/src/loadProject.test.ts +6 -2
  70. package/src/loadProject.ts +86 -45
  71. package/src/persistence/batchedIO.test.ts +63 -0
  72. package/src/persistence/batchedIO.ts +64 -0
  73. package/src/persistence/filelock/acquireFileLock.ts +5 -2
  74. package/src/persistence/filelock/releaseLock.ts +2 -1
  75. package/src/persistence/store.test.ts +102 -0
  76. package/src/persistence/store.ts +119 -0
  77. package/src/persistence/storeApi.ts +19 -0
  78. package/src/reactivity/solid.test.ts +1 -8
  79. package/src/resolve-modules/plugins/resolvePlugins.ts +4 -13
  80. package/src/test-utilities/sleep.ts +11 -0
  81. package/src/v2/{createMessageBundle.test.ts → helper.test.ts} +1 -1
  82. package/src/v2/helper.ts +98 -0
  83. package/src/v2/index.ts +2 -0
  84. package/src/v2/mocks/index.ts +2 -0
  85. package/src/v2/mocks/multipleMatcher/bundle.test.ts +11 -0
  86. package/src/v2/mocks/multipleMatcher/bundle.ts +196 -0
  87. package/src/v2/mocks/plural/bundle.test.ts +6 -6
  88. package/src/v2/mocks/plural/bundle.ts +1 -1
  89. package/src/v2/shim.test.ts +56 -0
  90. package/src/v2/shim.ts +173 -0
  91. package/src/v2/stubQueryApi.ts +43 -0
  92. package/src/v2/types.ts +17 -0
  93. package/dist/persistence/plugin.d.ts +0 -31
  94. package/dist/persistence/plugin.d.ts.map +0 -1
  95. package/dist/persistence/plugin.js +0 -42
  96. package/dist/persistence/plugin.test.d.ts +0 -2
  97. package/dist/persistence/plugin.test.d.ts.map +0 -1
  98. package/dist/persistence/plugin.test.js +0 -49
  99. package/dist/v2/createMessageBundle.d.ts +0 -25
  100. package/dist/v2/createMessageBundle.d.ts.map +0 -1
  101. package/dist/v2/createMessageBundle.js +0 -36
  102. package/dist/v2/createMessageBundle.test.d.ts +0 -2
  103. package/dist/v2/createMessageBundle.test.d.ts.map +0 -1
  104. package/src/persistence/plugin.test.ts +0 -60
  105. package/src/persistence/plugin.ts +0 -56
  106. package/src/v2/createMessageBundle.ts +0 -43
@@ -0,0 +1,79 @@
1
+ import { test, expect } from "vitest";
2
+ import { createNodeishMemoryFs } from "../test-utilities/index.js";
3
+ import { createMessageBundle, createMessage, injectJSONNewlines, addSlots } from "../v2/helper.js";
4
+ import { openStore, readJSON, writeJSON } from "./store.js";
5
+ const locales = ["en", "de"];
6
+ const mockMessages = [
7
+ createMessageBundle({
8
+ id: "first_message",
9
+ messages: [
10
+ createMessage({
11
+ locale: "en",
12
+ text: "If this fails I will be sad",
13
+ }),
14
+ ],
15
+ }),
16
+ createMessageBundle({
17
+ id: "second_message",
18
+ messages: [
19
+ createMessage({ locale: "en", text: "Let's see if this works" }),
20
+ createMessage({ locale: "de", text: "Mal sehen ob das funktioniert" }),
21
+ ],
22
+ }),
23
+ ];
24
+ test("roundtrip readJSON/writeJSON", async () => {
25
+ const nodeishFs = createNodeishMemoryFs();
26
+ const projectPath = "/test/project.inlang";
27
+ const filePath = projectPath + "/messages.json";
28
+ const persistedMessages = injectJSONNewlines(JSON.stringify(mockMessages.map((bundle) => addSlots(bundle, locales))));
29
+ await nodeishFs.mkdir(projectPath, { recursive: true });
30
+ await nodeishFs.writeFile(filePath, persistedMessages);
31
+ const firstMessageLoad = await readJSON({
32
+ filePath,
33
+ nodeishFs: nodeishFs,
34
+ });
35
+ expect(firstMessageLoad).toStrictEqual(mockMessages);
36
+ await writeJSON({
37
+ filePath,
38
+ nodeishFs,
39
+ messages: firstMessageLoad,
40
+ locales,
41
+ });
42
+ const afterRoundtrip = await nodeishFs.readFile(filePath, { encoding: "utf-8" });
43
+ expect(afterRoundtrip).toStrictEqual(persistedMessages);
44
+ const messagesAfterRoundtrip = await readJSON({
45
+ filePath,
46
+ nodeishFs,
47
+ });
48
+ expect(messagesAfterRoundtrip).toStrictEqual(firstMessageLoad);
49
+ });
50
+ test("openStore does minimal CRUD on messageBundles", async () => {
51
+ const nodeishFs = createNodeishMemoryFs();
52
+ const projectPath = "/test/project.inlang";
53
+ const filePath = projectPath + "/messages.json";
54
+ const persistedMessages = JSON.stringify(mockMessages);
55
+ await nodeishFs.mkdir(projectPath, { recursive: true });
56
+ await nodeishFs.writeFile(filePath, persistedMessages);
57
+ const store = await openStore({ projectPath, nodeishFs, locales });
58
+ const messages = await store.messageBundles.getAll();
59
+ expect(messages).toStrictEqual(mockMessages);
60
+ const firstMessageBundle = await store.messageBundles.get({ id: "first_message" });
61
+ expect(firstMessageBundle).toStrictEqual(mockMessages[0]);
62
+ const modifedMessageBundle = structuredClone(firstMessageBundle);
63
+ const newMessage = createMessage({ locale: "de", text: "Wenn dies schiefläuft, bin ich sauer" });
64
+ modifedMessageBundle.messages.push(newMessage);
65
+ await store.messageBundles.set({ data: modifedMessageBundle });
66
+ const setMessageBundle = await store.messageBundles.get({ id: "first_message" });
67
+ expect(setMessageBundle).toStrictEqual(modifedMessageBundle);
68
+ // no need to sleep here
69
+ // with batchedIO, the set should await until the write is done
70
+ const messagesAfterRoundtrip = await readJSON({
71
+ filePath,
72
+ nodeishFs,
73
+ });
74
+ const expected = [setMessageBundle, ...mockMessages.slice(1)];
75
+ expect(messagesAfterRoundtrip).toStrictEqual(expected);
76
+ await store.messageBundles.delete({ id: "first_message" });
77
+ const messagesAfterDelete = await store.messageBundles.getAll();
78
+ expect(messagesAfterDelete).toStrictEqual(mockMessages.slice(1));
79
+ });
@@ -0,0 +1,22 @@
1
+ import type * as V2 from "../v2/types.js";
2
+ /**
3
+ * WIP async V2 store interface
4
+ * E.g. `await project.store.messageBundles.get({ id: "..." })`
5
+ **/
6
+ export type StoreApi = {
7
+ messageBundles: Store<V2.MessageBundle>;
8
+ };
9
+ export interface Store<T> {
10
+ reload: () => Promise<void>;
11
+ get: (args: {
12
+ id: string;
13
+ }) => Promise<T | undefined>;
14
+ set: (args: {
15
+ data: T;
16
+ }) => Promise<void>;
17
+ delete: (args: {
18
+ id: string;
19
+ }) => Promise<void>;
20
+ getAll: () => Promise<T[]>;
21
+ }
22
+ //# sourceMappingURL=storeApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storeApi.d.ts","sourceRoot":"","sources":["../../src/persistence/storeApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAEzC;;;IAGI;AACJ,MAAM,MAAM,QAAQ,GAAG;IACtB,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,CAAA;CACvC,CAAA;AAED,MAAM,WAAW,KAAK,CAAC,CAAC;IAEvB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAE3B,GAAG,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IACrD,GAAG,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzC,MAAM,EAAE,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,CAAA;CAC1B"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,12 +1,7 @@
1
1
  import { describe, it, expect } from "vitest";
2
+ import { sleep, delay } from "../test-utilities/sleep.js";
2
3
  import { createRoot, createSignal, createEffect, createMemo, createResource, untrack, } from "./solid.js";
3
4
  import { ReactiveMap } from "./map.js";
4
- function sleep(ms) {
5
- return new Promise((resolve) => setTimeout(resolve, ms));
6
- }
7
- function delay(v, ms) {
8
- return new Promise((resolve) => setTimeout(() => resolve(v), ms));
9
- }
10
5
  describe("vitest", () => {
11
6
  it("waits for the result of an async function", async () => {
12
7
  const rval = await delay(42, 1);
@@ -1 +1 @@
1
- {"version":3,"file":"resolvePlugins.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/resolvePlugins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAwBxD,eAAO,MAAM,cAAc,EAAE,sBAgH5B,CAAA"}
1
+ {"version":3,"file":"resolvePlugins.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/resolvePlugins.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAoBxD,eAAO,MAAM,cAAc,EAAE,sBA2G5B,CAAA"}
@@ -1,5 +1,4 @@
1
1
  import { Plugin } from "@inlang/plugin";
2
- import { loadMessages as sdkLoadMessages, saveMessages as sdkSaveMessages, } from "../../persistence/plugin.js";
3
2
  import { PluginReturnedInvalidCustomApiError, PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginsDoNotProvideLoadOrSaveMessagesError, PluginHasInvalidIdError, PluginHasInvalidSchemaError, } from "./errors.js";
4
3
  import { deepmerge } from "deepmerge-ts";
5
4
  import { TypeCompiler } from "@sinclair/typebox/compiler";
@@ -84,15 +83,9 @@ export const resolvePlugins = async (args) => {
84
83
  }
85
84
  }
86
85
  // --- LOADMESSAGE / SAVEMESSAGE NOT DEFINED ---
87
- if (experimentalPersistence) {
88
- debug("Override load/save for experimental persistence");
89
- // @ts-ignore - type mismatch error
90
- result.data.loadMessages = sdkLoadMessages;
91
- // @ts-ignore - type mismatch error
92
- result.data.saveMessages = sdkSaveMessages;
93
- }
94
- else if (typeof result.data.loadMessages !== "function" ||
95
- typeof result.data.saveMessages !== "function") {
86
+ if (!experimentalPersistence &&
87
+ (typeof result.data.loadMessages !== "function" ||
88
+ typeof result.data.saveMessages !== "function")) {
96
89
  result.errors.push(new PluginsDoNotProvideLoadOrSaveMessagesError());
97
90
  }
98
91
  return result;
@@ -0,0 +1,4 @@
1
+ export declare function sleep(ms: number): Promise<unknown>;
2
+ export declare function delay(v: unknown, ms: number): Promise<unknown>;
3
+ export declare function fail(ms: number): Promise<unknown>;
4
+ //# sourceMappingURL=sleep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../../src/test-utilities/sleep.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,oBAE/B;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAE3C;AAED,wBAAgB,IAAI,CAAC,EAAE,EAAE,MAAM,oBAE9B"}
@@ -0,0 +1,9 @@
1
+ export function sleep(ms) {
2
+ return new Promise((resolve) => setTimeout(resolve, ms));
3
+ }
4
+ export function delay(v, ms) {
5
+ return new Promise((resolve) => setTimeout(() => resolve(v), ms));
6
+ }
7
+ export function fail(ms) {
8
+ return new Promise((resolve, reject) => setTimeout(() => reject(new Error("fail")), ms));
9
+ }
@@ -0,0 +1,131 @@
1
+ import { LanguageTag, MessageBundle, MessageBundleWithSlots, Message, MessageSlot, Text } from "./types.js";
2
+ /**
3
+ * create v2 MessageBundle
4
+ * @example createMessageBundle({
5
+ * id: "greeting",
6
+ * messages: [
7
+ * createMessage({locale: "en", text: "Hello world!"})
8
+ * createMessage({locale: "de", text: "Hallo Welt!"})
9
+ * ]
10
+ * })
11
+ */
12
+ export declare function createMessageBundle(args: {
13
+ id: string;
14
+ messages: Message[];
15
+ alias?: MessageBundle["alias"];
16
+ }): MessageBundle;
17
+ /**
18
+ * create v2 Messsage AST with text-only pattern
19
+ * @example createMessage({locale: "en", text: "Hello world"})
20
+ */
21
+ export declare function createMessage(args: {
22
+ locale: LanguageTag;
23
+ text: string;
24
+ match?: Array<string>;
25
+ }): Message;
26
+ export declare function toTextElement(text: string): Text;
27
+ /**
28
+ * create MessageSlot for a locale (only used for persistence)
29
+ */
30
+ export declare function createMessageSlot(locale: LanguageTag): MessageSlot;
31
+ /**
32
+ * return structuredClone with message slots for all locales not yet present
33
+ */
34
+ export declare function addSlots(messageBundle: MessageBundle, locales: string[]): MessageBundleWithSlots;
35
+ /**
36
+ * remove empty message slots without first creating a structured clone
37
+ */
38
+ export declare function removeSlots(messageBundle: MessageBundleWithSlots): {
39
+ id: string;
40
+ alias: Record<string, string>;
41
+ messages: {
42
+ selectors: {
43
+ annotation?: {
44
+ type: "function";
45
+ name: string;
46
+ options: {
47
+ name: string;
48
+ value: {
49
+ type: "literal";
50
+ value: string;
51
+ } | {
52
+ type: "variable";
53
+ name: string;
54
+ };
55
+ }[];
56
+ } | undefined;
57
+ type: "expression";
58
+ arg: {
59
+ type: "literal";
60
+ value: string;
61
+ } | {
62
+ type: "variable";
63
+ name: string;
64
+ };
65
+ }[];
66
+ variants: {
67
+ match: string[];
68
+ pattern: ({
69
+ type: "text";
70
+ value: string;
71
+ } | {
72
+ annotation?: {
73
+ type: "function";
74
+ name: string;
75
+ options: {
76
+ name: string;
77
+ value: {
78
+ type: "literal";
79
+ value: string;
80
+ } | {
81
+ type: "variable";
82
+ name: string;
83
+ };
84
+ }[];
85
+ } | undefined;
86
+ type: "expression";
87
+ arg: {
88
+ type: "literal";
89
+ value: string;
90
+ } | {
91
+ type: "variable";
92
+ name: string;
93
+ };
94
+ })[];
95
+ }[];
96
+ locale: string;
97
+ declarations: {
98
+ type: "input";
99
+ name: string;
100
+ value: {
101
+ annotation?: {
102
+ type: "function";
103
+ name: string;
104
+ options: {
105
+ name: string;
106
+ value: {
107
+ type: "literal";
108
+ value: string;
109
+ } | {
110
+ type: "variable";
111
+ name: string;
112
+ };
113
+ }[];
114
+ } | undefined;
115
+ type: "expression";
116
+ arg: {
117
+ type: "literal";
118
+ value: string;
119
+ } | {
120
+ type: "variable";
121
+ name: string;
122
+ };
123
+ };
124
+ }[];
125
+ }[];
126
+ };
127
+ /**
128
+ * Add newlines between bundles and messages to avoid merge conflicts
129
+ */
130
+ export declare function injectJSONNewlines(json: string): string;
131
+ //# sourceMappingURL=helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/v2/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,aAAa,EACb,sBAAsB,EACtB,OAAO,EACP,WAAW,EACX,IAAI,EACJ,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACzC,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CAC9B,GAAG,aAAa,CAMhB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IACnC,MAAM,EAAE,WAAW,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CACrB,GAAG,OAAO,CAOV;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKhD;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAKlE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,aAAa,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,sBAAsB,CAMhG;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,aAAa,EAAE,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGhE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvD"}
@@ -0,0 +1,75 @@
1
+ import { LanguageTag, MessageBundle, MessageBundleWithSlots, Message, MessageSlot, Text, } from "./types.js";
2
+ /**
3
+ * create v2 MessageBundle
4
+ * @example createMessageBundle({
5
+ * id: "greeting",
6
+ * messages: [
7
+ * createMessage({locale: "en", text: "Hello world!"})
8
+ * createMessage({locale: "de", text: "Hallo Welt!"})
9
+ * ]
10
+ * })
11
+ */
12
+ export function createMessageBundle(args) {
13
+ return {
14
+ id: args.id,
15
+ alias: args.alias ?? {},
16
+ messages: args.messages,
17
+ };
18
+ }
19
+ /**
20
+ * create v2 Messsage AST with text-only pattern
21
+ * @example createMessage({locale: "en", text: "Hello world"})
22
+ */
23
+ export function createMessage(args) {
24
+ return {
25
+ locale: args.locale,
26
+ declarations: [],
27
+ selectors: [],
28
+ variants: [{ match: args.match ? args.match : [], pattern: [toTextElement(args.text ?? "")] }],
29
+ };
30
+ }
31
+ export function toTextElement(text) {
32
+ return {
33
+ type: "text",
34
+ value: text,
35
+ };
36
+ }
37
+ // ****************************
38
+ // WIP experimental persistence
39
+ // ****************************
40
+ /**
41
+ * create MessageSlot for a locale (only used for persistence)
42
+ */
43
+ export function createMessageSlot(locale) {
44
+ return {
45
+ locale,
46
+ slot: true,
47
+ };
48
+ }
49
+ /**
50
+ * return structuredClone with message slots for all locales not yet present
51
+ */
52
+ export function addSlots(messageBundle, locales) {
53
+ const bundle = structuredClone(messageBundle);
54
+ bundle.messages = locales.map((locale) => {
55
+ return bundle.messages.find((message) => message.locale === locale) ?? createMessageSlot(locale);
56
+ });
57
+ return bundle;
58
+ }
59
+ /**
60
+ * remove empty message slots without first creating a structured clone
61
+ */
62
+ export function removeSlots(messageBundle) {
63
+ messageBundle.messages = messageBundle.messages.filter((message) => !("slot" in message));
64
+ return messageBundle;
65
+ }
66
+ /**
67
+ * Add newlines between bundles and messages to avoid merge conflicts
68
+ */
69
+ export function injectJSONNewlines(json) {
70
+ return json
71
+ .replace(/\{"id":"/g, '\n\n\n\n{"id":"')
72
+ .replace(/"messages":\[\{"locale":"/g, '"messages":[\n\n\n\n{"locale":"')
73
+ .replace(/\}\]\}\]\},\{"locale":"/g, '}]}]},\n\n\n\n{"locale":"')
74
+ .replace(/"slot":true\},\{"locale":/g, '"slot":true},\n\n\n\n{"locale":');
75
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=helper.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.test.d.ts","sourceRoot":"","sources":["../../src/v2/helper.test.ts"],"names":[],"mappings":""}
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
- import { createMessageBundle, createMessage } from "./createMessageBundle.js";
2
+ import { createMessageBundle, createMessage } from "./helper.js";
3
3
  import { MessageBundle } from "./types.js";
4
4
  import { Value } from "@sinclair/typebox/value";
5
5
  describe("createMessageBundle", () => {
@@ -1,2 +1,4 @@
1
1
  export type * from "./types.js";
2
+ export * from "./helper.js";
3
+ export * from "./shim.js";
2
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/v2/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/v2/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA"}
package/dist/v2/index.js CHANGED
@@ -1 +1,2 @@
1
- export {};
1
+ export * from "./helper.js";
2
+ export * from "./shim.js";
@@ -0,0 +1,3 @@
1
+ export * from "./plural/bundle.js";
2
+ export * from "./multipleMatcher/bundle.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/v2/mocks/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,6BAA6B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from "./plural/bundle.js";
2
+ export * from "./multipleMatcher/bundle.js";
@@ -0,0 +1,3 @@
1
+ import type { MessageBundle } from "../../types.js";
2
+ export declare const multipleMatcherBundle: MessageBundle;
3
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../../../src/v2/mocks/multipleMatcher/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,eAAO,MAAM,qBAAqB,EAAE,aAiMnC,CAAA"}
@@ -0,0 +1,194 @@
1
+ export const multipleMatcherBundle = {
2
+ id: "mock-bundle-human-id",
3
+ alias: {
4
+ default: "mock-bundle-alias",
5
+ },
6
+ messages: [
7
+ {
8
+ locale: "en",
9
+ declarations: [],
10
+ selectors: [
11
+ {
12
+ type: "expression",
13
+ arg: {
14
+ type: "variable",
15
+ name: "count",
16
+ },
17
+ annotation: { type: "function", name: "plural", options: [] },
18
+ },
19
+ ],
20
+ variants: [
21
+ {
22
+ match: ["one"],
23
+ pattern: [
24
+ {
25
+ type: "text",
26
+ value: "Show ",
27
+ },
28
+ {
29
+ type: "expression",
30
+ arg: {
31
+ type: "variable",
32
+ name: "count",
33
+ },
34
+ },
35
+ {
36
+ type: "text",
37
+ value: " message.",
38
+ },
39
+ ],
40
+ },
41
+ {
42
+ match: ["many"],
43
+ pattern: [
44
+ {
45
+ type: "text",
46
+ value: "Show ",
47
+ },
48
+ {
49
+ type: "expression",
50
+ arg: {
51
+ type: "variable",
52
+ name: "count",
53
+ },
54
+ },
55
+ {
56
+ type: "text",
57
+ value: " messages.",
58
+ },
59
+ ],
60
+ },
61
+ {
62
+ match: ["*"],
63
+ pattern: [
64
+ {
65
+ type: "text",
66
+ value: "Show ",
67
+ },
68
+ {
69
+ type: "expression",
70
+ arg: {
71
+ type: "variable",
72
+ name: "count",
73
+ },
74
+ },
75
+ ],
76
+ },
77
+ ],
78
+ },
79
+ {
80
+ locale: "de",
81
+ declarations: [],
82
+ selectors: [
83
+ {
84
+ type: "expression",
85
+ arg: {
86
+ type: "variable",
87
+ name: "count",
88
+ },
89
+ annotation: { type: "function", name: "plural", options: [] },
90
+ },
91
+ {
92
+ type: "expression",
93
+ arg: {
94
+ type: "variable",
95
+ name: "formal",
96
+ },
97
+ annotation: { type: "function", name: "bool", options: [] },
98
+ },
99
+ ],
100
+ variants: [
101
+ {
102
+ match: ["one", "formal"],
103
+ pattern: [
104
+ {
105
+ type: "text",
106
+ value: "Zeigen Sie bitte Ihre Nachricht.",
107
+ },
108
+ ],
109
+ },
110
+ {
111
+ match: ["one", "informal"],
112
+ pattern: [
113
+ {
114
+ type: "text",
115
+ value: "Zeigen Deine Nachricht.",
116
+ },
117
+ ],
118
+ },
119
+ {
120
+ match: ["many", "formal"],
121
+ pattern: [
122
+ {
123
+ type: "text",
124
+ value: "Zeigen Sie bitte Ihre ",
125
+ },
126
+ {
127
+ type: "expression",
128
+ arg: {
129
+ type: "variable",
130
+ name: "count",
131
+ },
132
+ },
133
+ {
134
+ type: "text",
135
+ value: " Nachrichten.",
136
+ },
137
+ ],
138
+ },
139
+ {
140
+ match: ["many", "informal"],
141
+ pattern: [
142
+ {
143
+ type: "text",
144
+ value: "Zeigen Deine ",
145
+ },
146
+ {
147
+ type: "expression",
148
+ arg: {
149
+ type: "variable",
150
+ name: "count",
151
+ },
152
+ },
153
+ {
154
+ type: "text",
155
+ value: " Nachrichten.",
156
+ },
157
+ ],
158
+ },
159
+ {
160
+ match: ["many", "*"],
161
+ pattern: [
162
+ {
163
+ type: "expression",
164
+ arg: {
165
+ type: "variable",
166
+ name: "count",
167
+ },
168
+ },
169
+ {
170
+ type: "text",
171
+ value: " Nachrichten zeigen.",
172
+ },
173
+ ],
174
+ },
175
+ {
176
+ match: ["*"],
177
+ pattern: [
178
+ {
179
+ type: "text",
180
+ value: "Zeige ",
181
+ },
182
+ {
183
+ type: "expression",
184
+ arg: {
185
+ type: "variable",
186
+ name: "count",
187
+ },
188
+ },
189
+ ],
190
+ },
191
+ ],
192
+ },
193
+ ],
194
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bundle.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.test.d.ts","sourceRoot":"","sources":["../../../../src/v2/mocks/multipleMatcher/bundle.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { multipleMatcherBundle } from "./bundle.js";
3
+ import { MessageBundle } from "../../types.js";
4
+ import { Value } from "@sinclair/typebox/value";
5
+ describe("mock plural messageBundle", () => {
6
+ it("is valid", () => {
7
+ const messageBundle = multipleMatcherBundle;
8
+ expect(Value.Check(MessageBundle, messageBundle)).toBe(true);
9
+ });
10
+ });
@@ -1,3 +1,3 @@
1
1
  import type { MessageBundle } from "../../types.js";
2
- export declare const bundle: MessageBundle;
2
+ export declare const pluralBundle: MessageBundle;
3
3
  //# sourceMappingURL=bundle.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../../../src/v2/mocks/plural/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,eAAO,MAAM,MAAM,EAAE,aA2IpB,CAAA"}
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../../../../src/v2/mocks/plural/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,eAAO,MAAM,YAAY,EAAE,aA2I1B,CAAA"}