@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.
- package/dist/api.d.ts +2 -13
- package/dist/api.d.ts.map +1 -1
- package/dist/createNewProject.test.js +1 -3
- package/dist/loadProject.d.ts.map +1 -1
- package/dist/loadProject.js +67 -32
- package/dist/loadProject.test.js +6 -2
- package/dist/persistence/batchedIO.d.ts +11 -0
- package/dist/persistence/batchedIO.d.ts.map +1 -0
- package/dist/persistence/batchedIO.js +49 -0
- package/dist/persistence/batchedIO.test.d.ts +2 -0
- package/dist/persistence/batchedIO.test.d.ts.map +1 -0
- package/dist/persistence/batchedIO.test.js +56 -0
- package/dist/persistence/filelock/acquireFileLock.d.ts.map +1 -1
- package/dist/persistence/filelock/acquireFileLock.js +3 -1
- package/dist/persistence/filelock/releaseLock.d.ts.map +1 -1
- package/dist/persistence/filelock/releaseLock.js +2 -1
- package/dist/persistence/store.d.ts +107 -0
- package/dist/persistence/store.d.ts.map +1 -0
- package/dist/persistence/store.js +99 -0
- package/dist/persistence/store.test.d.ts +2 -0
- package/dist/persistence/store.test.d.ts.map +1 -0
- package/dist/persistence/store.test.js +79 -0
- package/dist/persistence/storeApi.d.ts +22 -0
- package/dist/persistence/storeApi.d.ts.map +1 -0
- package/dist/persistence/storeApi.js +1 -0
- package/dist/reactivity/solid.test.js +1 -6
- package/dist/resolve-modules/plugins/resolvePlugins.d.ts.map +1 -1
- package/dist/resolve-modules/plugins/resolvePlugins.js +3 -10
- package/dist/test-utilities/sleep.d.ts +4 -0
- package/dist/test-utilities/sleep.d.ts.map +1 -0
- package/dist/test-utilities/sleep.js +9 -0
- package/dist/v2/helper.d.ts +131 -0
- package/dist/v2/helper.d.ts.map +1 -0
- package/dist/v2/helper.js +75 -0
- package/dist/v2/helper.test.d.ts +2 -0
- package/dist/v2/helper.test.d.ts.map +1 -0
- package/dist/v2/{createMessageBundle.test.js → helper.test.js} +1 -1
- package/dist/v2/index.d.ts +2 -0
- package/dist/v2/index.d.ts.map +1 -1
- package/dist/v2/index.js +2 -1
- package/dist/v2/mocks/index.d.ts +3 -0
- package/dist/v2/mocks/index.d.ts.map +1 -0
- package/dist/v2/mocks/index.js +2 -0
- package/dist/v2/mocks/multipleMatcher/bundle.d.ts +3 -0
- package/dist/v2/mocks/multipleMatcher/bundle.d.ts.map +1 -0
- package/dist/v2/mocks/multipleMatcher/bundle.js +194 -0
- package/dist/v2/mocks/multipleMatcher/bundle.test.d.ts +2 -0
- package/dist/v2/mocks/multipleMatcher/bundle.test.d.ts.map +1 -0
- package/dist/v2/mocks/multipleMatcher/bundle.test.js +10 -0
- package/dist/v2/mocks/plural/bundle.d.ts +1 -1
- package/dist/v2/mocks/plural/bundle.d.ts.map +1 -1
- package/dist/v2/mocks/plural/bundle.js +1 -1
- package/dist/v2/mocks/plural/bundle.test.js +6 -6
- package/dist/v2/shim.d.ts +12 -0
- package/dist/v2/shim.d.ts.map +1 -0
- package/dist/v2/shim.js +151 -0
- package/dist/v2/shim.test.d.ts +2 -0
- package/dist/v2/shim.test.d.ts.map +1 -0
- package/dist/v2/shim.test.js +49 -0
- package/dist/v2/stubQueryApi.d.ts +9 -0
- package/dist/v2/stubQueryApi.d.ts.map +1 -0
- package/dist/v2/stubQueryApi.js +38 -0
- package/dist/v2/types.d.ts +110 -0
- package/dist/v2/types.d.ts.map +1 -1
- package/dist/v2/types.js +9 -0
- package/package.json +6 -5
- package/src/api.ts +2 -13
- package/src/createNewProject.test.ts +1 -4
- package/src/loadProject.test.ts +6 -2
- package/src/loadProject.ts +86 -45
- package/src/persistence/batchedIO.test.ts +63 -0
- package/src/persistence/batchedIO.ts +64 -0
- package/src/persistence/filelock/acquireFileLock.ts +5 -2
- package/src/persistence/filelock/releaseLock.ts +2 -1
- package/src/persistence/store.test.ts +102 -0
- package/src/persistence/store.ts +119 -0
- package/src/persistence/storeApi.ts +19 -0
- package/src/reactivity/solid.test.ts +1 -8
- package/src/resolve-modules/plugins/resolvePlugins.ts +4 -13
- package/src/test-utilities/sleep.ts +11 -0
- package/src/v2/{createMessageBundle.test.ts → helper.test.ts} +1 -1
- package/src/v2/helper.ts +98 -0
- package/src/v2/index.ts +2 -0
- package/src/v2/mocks/index.ts +2 -0
- package/src/v2/mocks/multipleMatcher/bundle.test.ts +11 -0
- package/src/v2/mocks/multipleMatcher/bundle.ts +196 -0
- package/src/v2/mocks/plural/bundle.test.ts +6 -6
- package/src/v2/mocks/plural/bundle.ts +1 -1
- package/src/v2/shim.test.ts +56 -0
- package/src/v2/shim.ts +173 -0
- package/src/v2/stubQueryApi.ts +43 -0
- package/src/v2/types.ts +17 -0
- package/dist/persistence/plugin.d.ts +0 -31
- package/dist/persistence/plugin.d.ts.map +0 -1
- package/dist/persistence/plugin.js +0 -42
- package/dist/persistence/plugin.test.d.ts +0 -2
- package/dist/persistence/plugin.test.d.ts.map +0 -1
- package/dist/persistence/plugin.test.js +0 -49
- package/dist/v2/createMessageBundle.d.ts +0 -25
- package/dist/v2/createMessageBundle.d.ts.map +0 -1
- package/dist/v2/createMessageBundle.js +0 -36
- package/dist/v2/createMessageBundle.test.d.ts +0 -2
- package/dist/v2/createMessageBundle.test.d.ts.map +0 -1
- package/src/persistence/plugin.test.ts +0 -60
- package/src/persistence/plugin.ts +0 -56
- 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;
|
|
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
|
-
|
|
89
|
-
|
|
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 @@
|
|
|
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 @@
|
|
|
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 "./
|
|
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", () => {
|
package/dist/v2/index.d.ts
CHANGED
package/dist/v2/index.d.ts.map
CHANGED
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 +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,
|
|
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"}
|