@inlang/sdk 0.7.0 → 0.9.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.
- package/dist/adapter/solidAdapter.test.js +6 -6
- package/dist/createMessagesQuery.test.js +9 -0
- package/dist/loadProject.d.ts.map +1 -1
- package/dist/loadProject.js +8 -4
- package/dist/loadProject.test.js +14 -15
- package/dist/messages/variant.d.ts +4 -4
- package/dist/messages/variant.d.ts.map +1 -1
- package/dist/messages/variant.js +55 -55
- package/dist/messages/variant.test.js +102 -45
- package/dist/resolve-modules/plugins/resolvePlugins.d.ts.map +1 -1
- package/dist/resolve-modules/plugins/resolvePlugins.js +3 -5
- package/dist/resolve-modules/plugins/resolvePlugins.test.js +79 -49
- package/dist/resolve-modules/plugins/types.d.ts +4 -5
- package/dist/resolve-modules/plugins/types.d.ts.map +1 -1
- package/dist/test-utilities/createMessage.d.ts +1 -1
- package/dist/test-utilities/createMessage.js +1 -1
- package/dist/test-utilities/createMessage.test.js +4 -4
- package/package.json +1 -1
- package/src/adapter/solidAdapter.test.ts +14 -14
- package/src/adapter/solidAdapter.ts +1 -1
- package/src/api.ts +2 -2
- package/src/createMessageLintReportsQuery.ts +4 -4
- package/src/createMessagesQuery.test.ts +30 -17
- package/src/createMessagesQuery.ts +2 -2
- package/src/lint/message/lintMessages.ts +1 -1
- package/src/lint/message/lintSingleMessage.test.ts +1 -1
- package/src/lint/message/lintSingleMessage.ts +2 -2
- package/src/loadProject.test.ts +24 -27
- package/src/loadProject.ts +20 -16
- package/src/messages/errors.ts +2 -2
- package/src/messages/variant.test.ts +113 -49
- package/src/messages/variant.ts +73 -67
- package/src/parseConfig.ts +2 -2
- package/src/resolve-modules/import.test.ts +2 -2
- package/src/resolve-modules/import.ts +1 -1
- package/src/resolve-modules/message-lint-rules/resolveMessageLintRules.ts +1 -1
- package/src/resolve-modules/plugins/resolvePlugins.test.ts +96 -64
- package/src/resolve-modules/plugins/resolvePlugins.ts +19 -21
- package/src/resolve-modules/plugins/types.ts +4 -8
- package/src/resolve-modules/resolveModules.ts +4 -4
- package/src/test-utilities/createMessage.test.ts +7 -7
- package/src/test-utilities/createMessage.ts +1 -1
|
@@ -8,7 +8,7 @@ describe("getVariant", () => {
|
|
|
8
8
|
const variant = getVariant(mockMessage, {
|
|
9
9
|
where: {
|
|
10
10
|
languageTag: "en",
|
|
11
|
-
|
|
11
|
+
match: ["female", "1"],
|
|
12
12
|
},
|
|
13
13
|
});
|
|
14
14
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -21,7 +21,7 @@ describe("getVariant", () => {
|
|
|
21
21
|
const variant = getVariant(mockMessage, {
|
|
22
22
|
where: {
|
|
23
23
|
languageTag: "en",
|
|
24
|
-
|
|
24
|
+
match: ["female", "0"],
|
|
25
25
|
},
|
|
26
26
|
});
|
|
27
27
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -29,7 +29,7 @@ describe("getVariant", () => {
|
|
|
29
29
|
value: "{$hostName} invites {$guestName} and {$guestsOther} other people to her party.",
|
|
30
30
|
});
|
|
31
31
|
});
|
|
32
|
-
test("it should
|
|
32
|
+
test("it should not throw error if selector is empty and match", () => {
|
|
33
33
|
const mockMessage = {
|
|
34
34
|
id: "mockMessage",
|
|
35
35
|
selectors: [],
|
|
@@ -37,21 +37,44 @@ describe("getVariant", () => {
|
|
|
37
37
|
{
|
|
38
38
|
languageTag: "en",
|
|
39
39
|
pattern: [{ type: "Text", value: "Gender male" }],
|
|
40
|
-
match:
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
match: [],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
languageTag: "de",
|
|
44
|
+
pattern: [{ type: "Text", value: "Veraltete Übersetzung" }],
|
|
45
|
+
match: [],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
const variant = getVariant(mockMessage, {
|
|
50
|
+
where: {
|
|
51
|
+
languageTag: "en",
|
|
52
|
+
match: [],
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
expect(variant).toBeDefined();
|
|
56
|
+
});
|
|
57
|
+
test("it should not throw error if selector is empty, return undefined", () => {
|
|
58
|
+
const mockMessage = {
|
|
59
|
+
id: "mockMessage",
|
|
60
|
+
selectors: [],
|
|
61
|
+
variants: [
|
|
62
|
+
{
|
|
63
|
+
languageTag: "en",
|
|
64
|
+
pattern: [{ type: "Text", value: "Gender male" }],
|
|
65
|
+
match: ["male", "*"],
|
|
43
66
|
},
|
|
44
67
|
{
|
|
45
68
|
languageTag: "de",
|
|
46
69
|
pattern: [{ type: "Text", value: "Veraltete Übersetzung" }],
|
|
47
|
-
match:
|
|
70
|
+
match: ["*", "*"],
|
|
48
71
|
},
|
|
49
72
|
],
|
|
50
73
|
};
|
|
51
74
|
const variant = getVariant(mockMessage, {
|
|
52
75
|
where: {
|
|
53
76
|
languageTag: "fr",
|
|
54
|
-
|
|
77
|
+
match: ["*", "*"],
|
|
55
78
|
},
|
|
56
79
|
});
|
|
57
80
|
expect(variant).toBeUndefined();
|
|
@@ -61,7 +84,7 @@ describe("getVariant", () => {
|
|
|
61
84
|
const variant = getVariant(mockMessage, {
|
|
62
85
|
where: {
|
|
63
86
|
languageTag: "en",
|
|
64
|
-
|
|
87
|
+
match: ["*", "0"],
|
|
65
88
|
},
|
|
66
89
|
});
|
|
67
90
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -74,7 +97,7 @@ describe("getVariant", () => {
|
|
|
74
97
|
const variant = getVariant(mockMessage, {
|
|
75
98
|
where: {
|
|
76
99
|
languageTag: "en",
|
|
77
|
-
|
|
100
|
+
match: ["*", "*"],
|
|
78
101
|
},
|
|
79
102
|
});
|
|
80
103
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -87,7 +110,7 @@ describe("getVariant", () => {
|
|
|
87
110
|
const variant = getVariant(mockMessage, {
|
|
88
111
|
where: {
|
|
89
112
|
languageTag: "en",
|
|
90
|
-
|
|
113
|
+
match: ["trans", "2"],
|
|
91
114
|
},
|
|
92
115
|
});
|
|
93
116
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -97,7 +120,7 @@ describe("getVariant", () => {
|
|
|
97
120
|
const variant2 = getVariant(mockMessage, {
|
|
98
121
|
where: {
|
|
99
122
|
languageTag: "en",
|
|
100
|
-
|
|
123
|
+
match: ["male", "8"],
|
|
101
124
|
},
|
|
102
125
|
});
|
|
103
126
|
expect(variant2?.pattern[0]).toStrictEqual({
|
|
@@ -108,12 +131,12 @@ describe("getVariant", () => {
|
|
|
108
131
|
test("should return undefined of no variant matches", () => {
|
|
109
132
|
const mockMessage = getMockMessage();
|
|
110
133
|
mockMessage.variants = [
|
|
111
|
-
...mockMessage.variants.filter((v) => v.languageTag === "en" && (v.match
|
|
134
|
+
...mockMessage.variants.filter((v) => v.languageTag === "en" && (v.match[0] !== "*" || v.match[1] !== "*")),
|
|
112
135
|
];
|
|
113
136
|
const variant = getVariant(mockMessage, {
|
|
114
137
|
where: {
|
|
115
138
|
languageTag: "en",
|
|
116
|
-
|
|
139
|
+
match: ["*", "*"],
|
|
117
140
|
},
|
|
118
141
|
});
|
|
119
142
|
expect(variant).toBeUndefined();
|
|
@@ -123,17 +146,18 @@ describe("getVariant", () => {
|
|
|
123
146
|
const variant = getVariant(mockMessage, {
|
|
124
147
|
where: {
|
|
125
148
|
languageTag: "de",
|
|
126
|
-
|
|
149
|
+
match: ["female", "1"],
|
|
127
150
|
},
|
|
128
151
|
});
|
|
129
152
|
expect(variant).toBeUndefined();
|
|
130
153
|
});
|
|
131
|
-
test("should return
|
|
154
|
+
test("should return undefined variant if no selector defined", () => {
|
|
132
155
|
const mockMessage = {};
|
|
156
|
+
mockMessage.selectors = [];
|
|
133
157
|
mockMessage.variants = [
|
|
134
158
|
{
|
|
135
159
|
languageTag: "en",
|
|
136
|
-
match:
|
|
160
|
+
match: ["*", "*"],
|
|
137
161
|
pattern: [
|
|
138
162
|
{
|
|
139
163
|
type: "Text",
|
|
@@ -145,13 +169,46 @@ describe("getVariant", () => {
|
|
|
145
169
|
const variant = getVariant(mockMessage, {
|
|
146
170
|
where: {
|
|
147
171
|
languageTag: "en",
|
|
148
|
-
|
|
172
|
+
match: ["*", "*"],
|
|
149
173
|
},
|
|
150
174
|
});
|
|
151
|
-
// should return
|
|
152
|
-
expect(variant
|
|
175
|
+
// should return undefined
|
|
176
|
+
expect(variant).toBeUndefined();
|
|
177
|
+
});
|
|
178
|
+
test("should match catch all if the number of matches and selectors do not match", () => {
|
|
179
|
+
const mockMessage = getMockMessage();
|
|
180
|
+
const variant1 = getVariant(mockMessage, {
|
|
181
|
+
where: {
|
|
182
|
+
languageTag: "en",
|
|
183
|
+
match: ["12"],
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
// should return catch all
|
|
187
|
+
expect(variant1?.pattern[0]).toStrictEqual({
|
|
153
188
|
type: "Text",
|
|
154
|
-
value: "
|
|
189
|
+
value: "{$hostName} invites {$guestName} and {$guestsOther} other people to their party.",
|
|
190
|
+
});
|
|
191
|
+
const variant2 = getVariant(mockMessage, {
|
|
192
|
+
where: {
|
|
193
|
+
languageTag: "en",
|
|
194
|
+
match: ["12", "*", "23"],
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
// should return catch all
|
|
198
|
+
expect(variant2?.pattern[0]).toStrictEqual({
|
|
199
|
+
type: "Text",
|
|
200
|
+
value: "{$hostName} invites {$guestName} and {$guestsOther} other people to their party.",
|
|
201
|
+
});
|
|
202
|
+
const variant3 = getVariant(mockMessage, {
|
|
203
|
+
where: {
|
|
204
|
+
languageTag: "en",
|
|
205
|
+
match: [],
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
// should return catch all
|
|
209
|
+
expect(variant3?.pattern[0]).toStrictEqual({
|
|
210
|
+
type: "Text",
|
|
211
|
+
value: "{$hostName} invites {$guestName} and {$guestsOther} other people to their party.",
|
|
155
212
|
});
|
|
156
213
|
});
|
|
157
214
|
});
|
|
@@ -160,36 +217,36 @@ describe("createVariant", () => {
|
|
|
160
217
|
const mockMessage = getMockMessage();
|
|
161
218
|
const newVariant = {
|
|
162
219
|
languageTag: "en",
|
|
163
|
-
match:
|
|
220
|
+
match: ["female", "0"],
|
|
164
221
|
pattern: [],
|
|
165
222
|
};
|
|
166
223
|
const message = createVariant(mockMessage, {
|
|
167
224
|
data: newVariant,
|
|
168
225
|
});
|
|
169
226
|
// should return the female variant
|
|
170
|
-
expect(message.data.variants.find((v) => v.languageTag === "en" && v.match
|
|
227
|
+
expect(message.data.variants.find((v) => v.languageTag === "en" && v.match[0] === "female" && v.match[1] === "0")?.pattern).toStrictEqual([]);
|
|
171
228
|
});
|
|
172
229
|
test("should create a variant, also if matcher are not full defined", () => {
|
|
173
230
|
const mockMessage = getMockMessage();
|
|
174
231
|
mockMessage.variants = [
|
|
175
|
-
...mockMessage.variants.filter((v) => v.languageTag === "en" && (v.match
|
|
232
|
+
...mockMessage.variants.filter((v) => v.languageTag === "en" && (v.match[0] !== "*" || v.match[1] !== "*")),
|
|
176
233
|
];
|
|
177
234
|
const message = createVariant(mockMessage, {
|
|
178
235
|
data: {
|
|
179
236
|
languageTag: "en",
|
|
180
|
-
match:
|
|
237
|
+
match: ["*", "*"],
|
|
181
238
|
pattern: [],
|
|
182
239
|
},
|
|
183
240
|
});
|
|
184
241
|
// should return the female variant
|
|
185
|
-
expect(message.data.variants.find((v) => v.languageTag === "en" && v.match
|
|
242
|
+
expect(message.data.variants.find((v) => v.languageTag === "en" && v.match[0] === "*" && v.match[1] === "*")?.pattern).toStrictEqual([]);
|
|
186
243
|
});
|
|
187
244
|
test("should return error if variant matches", () => {
|
|
188
245
|
const mockMessage = getMockMessage();
|
|
189
246
|
const variant = createVariant(mockMessage, {
|
|
190
247
|
data: {
|
|
191
248
|
languageTag: "en",
|
|
192
|
-
match:
|
|
249
|
+
match: ["male", "1"],
|
|
193
250
|
pattern: [],
|
|
194
251
|
},
|
|
195
252
|
});
|
|
@@ -202,7 +259,7 @@ describe("createVariant", () => {
|
|
|
202
259
|
const variant = createVariant(mockMessage, {
|
|
203
260
|
data: {
|
|
204
261
|
languageTag: "de",
|
|
205
|
-
match:
|
|
262
|
+
match: ["female", "1"],
|
|
206
263
|
pattern: [],
|
|
207
264
|
},
|
|
208
265
|
});
|
|
@@ -217,34 +274,34 @@ describe("updateVariant", () => {
|
|
|
217
274
|
const message = updateVariantPattern(mockMessage, {
|
|
218
275
|
where: {
|
|
219
276
|
languageTag: "en",
|
|
220
|
-
|
|
277
|
+
match: ["female", "1"],
|
|
221
278
|
},
|
|
222
279
|
data: [],
|
|
223
280
|
});
|
|
224
281
|
// should return the female variant
|
|
225
|
-
expect(message.data.variants.find((v) => v.languageTag === "en" && v.match
|
|
282
|
+
expect(message.data.variants.find((v) => v.languageTag === "en" && v.match[0] === "female" && v.match[1] === "1")?.pattern).toStrictEqual([]);
|
|
226
283
|
});
|
|
227
284
|
test("should update a variant, also if matcher are not full defined", () => {
|
|
228
285
|
const mockMessage = getMockMessage();
|
|
229
286
|
const message = updateVariantPattern(mockMessage, {
|
|
230
287
|
where: {
|
|
231
288
|
languageTag: "en",
|
|
232
|
-
|
|
289
|
+
match: ["*", "*"],
|
|
233
290
|
},
|
|
234
291
|
data: [],
|
|
235
292
|
});
|
|
236
293
|
// should return the female variant
|
|
237
|
-
expect(message.data.variants.find((v) => v.languageTag === "en" && v.match
|
|
294
|
+
expect(message.data.variants.find((v) => v.languageTag === "en" && v.match[0] === "*" && v.match[1] === "*")?.pattern).toStrictEqual([]);
|
|
238
295
|
});
|
|
239
296
|
test("should return error if no variant matches", () => {
|
|
240
297
|
const mockMessage = getMockMessage();
|
|
241
298
|
mockMessage.variants = [
|
|
242
|
-
...mockMessage.variants.filter((v) => v.languageTag === "en" && (v.match
|
|
299
|
+
...mockMessage.variants.filter((v) => v.languageTag === "en" && (v.match[0] !== "*" || v.match[1] !== "*")),
|
|
243
300
|
];
|
|
244
301
|
const variant = updateVariantPattern(mockMessage, {
|
|
245
302
|
where: {
|
|
246
303
|
languageTag: "en",
|
|
247
|
-
|
|
304
|
+
match: ["*", "*"],
|
|
248
305
|
},
|
|
249
306
|
data: [],
|
|
250
307
|
});
|
|
@@ -257,7 +314,7 @@ describe("updateVariant", () => {
|
|
|
257
314
|
const variant = updateVariantPattern(mockMessage, {
|
|
258
315
|
where: {
|
|
259
316
|
languageTag: "de",
|
|
260
|
-
|
|
317
|
+
match: ["*", "*"],
|
|
261
318
|
},
|
|
262
319
|
data: [],
|
|
263
320
|
});
|
|
@@ -276,7 +333,7 @@ const getMockMessage = () => {
|
|
|
276
333
|
variants: [
|
|
277
334
|
{
|
|
278
335
|
languageTag: "en",
|
|
279
|
-
match:
|
|
336
|
+
match: ["female", "1"],
|
|
280
337
|
pattern: [
|
|
281
338
|
{
|
|
282
339
|
type: "Text",
|
|
@@ -286,7 +343,7 @@ const getMockMessage = () => {
|
|
|
286
343
|
},
|
|
287
344
|
{
|
|
288
345
|
languageTag: "en",
|
|
289
|
-
match:
|
|
346
|
+
match: ["female", "2"],
|
|
290
347
|
pattern: [
|
|
291
348
|
{
|
|
292
349
|
type: "Text",
|
|
@@ -296,7 +353,7 @@ const getMockMessage = () => {
|
|
|
296
353
|
},
|
|
297
354
|
{
|
|
298
355
|
languageTag: "en",
|
|
299
|
-
match:
|
|
356
|
+
match: ["female", "*"],
|
|
300
357
|
pattern: [
|
|
301
358
|
{
|
|
302
359
|
type: "Text",
|
|
@@ -306,7 +363,7 @@ const getMockMessage = () => {
|
|
|
306
363
|
},
|
|
307
364
|
{
|
|
308
365
|
languageTag: "en",
|
|
309
|
-
match:
|
|
366
|
+
match: ["male", "1"],
|
|
310
367
|
pattern: [
|
|
311
368
|
{
|
|
312
369
|
type: "Text",
|
|
@@ -316,7 +373,7 @@ const getMockMessage = () => {
|
|
|
316
373
|
},
|
|
317
374
|
{
|
|
318
375
|
languageTag: "en",
|
|
319
|
-
match:
|
|
376
|
+
match: ["male", "2"],
|
|
320
377
|
pattern: [
|
|
321
378
|
{
|
|
322
379
|
type: "Text",
|
|
@@ -326,7 +383,7 @@ const getMockMessage = () => {
|
|
|
326
383
|
},
|
|
327
384
|
{
|
|
328
385
|
languageTag: "en",
|
|
329
|
-
match:
|
|
386
|
+
match: ["male", "*"],
|
|
330
387
|
pattern: [
|
|
331
388
|
{
|
|
332
389
|
type: "Text",
|
|
@@ -336,7 +393,7 @@ const getMockMessage = () => {
|
|
|
336
393
|
},
|
|
337
394
|
{
|
|
338
395
|
languageTag: "en",
|
|
339
|
-
match:
|
|
396
|
+
match: ["*", "0"],
|
|
340
397
|
pattern: [
|
|
341
398
|
{
|
|
342
399
|
type: "Text",
|
|
@@ -346,7 +403,7 @@ const getMockMessage = () => {
|
|
|
346
403
|
},
|
|
347
404
|
{
|
|
348
405
|
languageTag: "en",
|
|
349
|
-
match:
|
|
406
|
+
match: ["*", "1"],
|
|
350
407
|
pattern: [
|
|
351
408
|
{
|
|
352
409
|
type: "Text",
|
|
@@ -356,7 +413,7 @@ const getMockMessage = () => {
|
|
|
356
413
|
},
|
|
357
414
|
{
|
|
358
415
|
languageTag: "en",
|
|
359
|
-
match:
|
|
416
|
+
match: ["*", "2"],
|
|
360
417
|
pattern: [
|
|
361
418
|
{
|
|
362
419
|
type: "Text",
|
|
@@ -366,7 +423,7 @@ const getMockMessage = () => {
|
|
|
366
423
|
},
|
|
367
424
|
{
|
|
368
425
|
languageTag: "en",
|
|
369
|
-
match:
|
|
426
|
+
match: ["*", "*"],
|
|
370
427
|
pattern: [
|
|
371
428
|
{
|
|
372
429
|
type: "Text",
|
|
@@ -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;AAuBxD,eAAO,MAAM,cAAc,EAAE,
|
|
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;AAuBxD,eAAO,MAAM,cAAc,EAAE,sBAkJ5B,CAAA"}
|
|
@@ -27,7 +27,7 @@ export const resolvePlugins = async (args) => {
|
|
|
27
27
|
// -- INVALID ID in META --
|
|
28
28
|
const hasInvalidId = errors.some((error) => error.path === "/id");
|
|
29
29
|
if (hasInvalidId) {
|
|
30
|
-
result.errors.push(new PluginHasInvalidIdError(`Plugin ${plugin.id} has an invalid id "${plugin.id}". It must be
|
|
30
|
+
result.errors.push(new PluginHasInvalidIdError(`Plugin ${plugin.id} has an invalid id "${plugin.id}". It must be camelCase and contain a namespace like plugin.namespace.myPlugin.`, { plugin: plugin.id }));
|
|
31
31
|
}
|
|
32
32
|
// -- USES RESERVED NAMESPACE --
|
|
33
33
|
if (plugin.id.includes("inlang") && !whitelistedPlugins.includes(plugin.id)) {
|
|
@@ -53,7 +53,7 @@ export const resolvePlugins = async (args) => {
|
|
|
53
53
|
if (typeof plugin.addCustomApi === "function") {
|
|
54
54
|
// TODO: why do we call this function 2 times (here for validation and later for retrieving the actual value)?
|
|
55
55
|
const { data: customApi, error } = tryCatch(() => plugin.addCustomApi({
|
|
56
|
-
settings: args.settings
|
|
56
|
+
settings: args.settings,
|
|
57
57
|
}));
|
|
58
58
|
if (error) {
|
|
59
59
|
// @ts-ignore
|
|
@@ -74,20 +74,18 @@ export const resolvePlugins = async (args) => {
|
|
|
74
74
|
if (typeof plugin.loadMessages === "function") {
|
|
75
75
|
result.data.loadMessages = (_args) => plugin.loadMessages({
|
|
76
76
|
..._args,
|
|
77
|
-
settings: args.settings?.[plugin.id] ?? {},
|
|
78
77
|
nodeishFs: args.nodeishFs,
|
|
79
78
|
});
|
|
80
79
|
}
|
|
81
80
|
if (typeof plugin.saveMessages === "function") {
|
|
82
81
|
result.data.saveMessages = (_args) => plugin.saveMessages({
|
|
83
82
|
..._args,
|
|
84
|
-
settings: args.settings?.[plugin.id] ?? {},
|
|
85
83
|
nodeishFs: args.nodeishFs,
|
|
86
84
|
});
|
|
87
85
|
}
|
|
88
86
|
if (typeof plugin.addCustomApi === "function") {
|
|
89
87
|
const { data: customApi } = tryCatch(() => plugin.addCustomApi({
|
|
90
|
-
settings: args.settings
|
|
88
|
+
settings: args.settings,
|
|
91
89
|
}));
|
|
92
90
|
if (customApi) {
|
|
93
91
|
result.data.customApi = deepmerge(result.data.customApi, customApi);
|
|
@@ -2,56 +2,87 @@
|
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
3
|
import { resolvePlugins } from "./resolvePlugins.js";
|
|
4
4
|
import { PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginHasInvalidIdError, PluginUsesReservedNamespaceError, PluginReturnedInvalidCustomApiError, PluginHasInvalidSchemaError, PluginsDoNotProvideLoadOrSaveMessagesError, } from "./errors.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
nodeishFs: {},
|
|
19
|
-
});
|
|
20
|
-
expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidIdError);
|
|
5
|
+
it("should return an error if a plugin uses an invalid id", async () => {
|
|
6
|
+
const mockPlugin = {
|
|
7
|
+
// @ts-expect-error - invalid id
|
|
8
|
+
id: "no-namespace",
|
|
9
|
+
description: { en: "My plugin description" },
|
|
10
|
+
displayName: { en: "My plugin" },
|
|
11
|
+
loadMessages: () => undefined,
|
|
12
|
+
saveMessages: () => undefined,
|
|
13
|
+
};
|
|
14
|
+
const resolved = await resolvePlugins({
|
|
15
|
+
plugins: [mockPlugin],
|
|
16
|
+
settings: {},
|
|
17
|
+
nodeishFs: {},
|
|
21
18
|
});
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
19
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidIdError);
|
|
20
|
+
});
|
|
21
|
+
it("should return an error if a plugin uses APIs that are not available", async () => {
|
|
22
|
+
const mockPlugin = {
|
|
23
|
+
id: "plugin.namespace.undefinedApi",
|
|
24
|
+
description: { en: "My plugin description" },
|
|
25
|
+
displayName: { en: "My plugin" },
|
|
26
|
+
// @ts-expect-error the key is not available in type
|
|
27
|
+
nonExistentKey: {
|
|
28
|
+
nonexistentOptions: "value",
|
|
29
|
+
},
|
|
30
|
+
loadMessages: () => undefined,
|
|
31
|
+
saveMessages: () => undefined,
|
|
32
|
+
};
|
|
33
|
+
const resolved = await resolvePlugins({
|
|
34
|
+
plugins: [mockPlugin],
|
|
35
|
+
settings: {},
|
|
36
|
+
nodeishFs: {},
|
|
40
37
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
38
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidSchemaError);
|
|
39
|
+
});
|
|
40
|
+
it("should not initialize a plugin that uses the 'inlang' namespace except for inlang whitelisted plugins", async () => {
|
|
41
|
+
const mockPlugin = {
|
|
42
|
+
id: "plugin.inlang.notWhitelisted",
|
|
43
|
+
description: { en: "My plugin description" },
|
|
44
|
+
displayName: { en: "My plugin" },
|
|
45
|
+
loadMessages: () => undefined,
|
|
46
|
+
};
|
|
47
|
+
const resolved = await resolvePlugins({
|
|
48
|
+
plugins: [mockPlugin],
|
|
49
|
+
settings: {},
|
|
50
|
+
nodeishFs: {},
|
|
51
|
+
});
|
|
52
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginUsesReservedNamespaceError);
|
|
53
|
+
});
|
|
54
|
+
it("should expose the project settings including the plugin settings", async () => {
|
|
55
|
+
const settings = {
|
|
56
|
+
sourceLanguageTag: "en",
|
|
57
|
+
languageTags: ["en", "de"],
|
|
58
|
+
modules: [],
|
|
59
|
+
"plugin.namespace.placeholder": {
|
|
60
|
+
myPluginSetting: "value",
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
const mockPlugin = {
|
|
64
|
+
id: "plugin.namespace.placeholder",
|
|
65
|
+
description: { en: "My plugin description" },
|
|
66
|
+
displayName: { en: "My plugin" },
|
|
67
|
+
saveMessages: async ({ settings }) => {
|
|
68
|
+
expect(settings).toStrictEqual(settings);
|
|
69
|
+
},
|
|
70
|
+
addCustomApi: ({ settings }) => {
|
|
71
|
+
expect(settings).toStrictEqual(settings);
|
|
72
|
+
return {};
|
|
73
|
+
},
|
|
74
|
+
loadMessages: async ({ settings }) => {
|
|
75
|
+
expect(settings).toStrictEqual(settings);
|
|
76
|
+
return [];
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const resolved = await resolvePlugins({
|
|
80
|
+
plugins: [mockPlugin],
|
|
81
|
+
settings: settings,
|
|
82
|
+
nodeishFs: {},
|
|
54
83
|
});
|
|
84
|
+
await resolved.data.loadMessages({ settings });
|
|
85
|
+
await resolved.data.saveMessages({ settings, messages: [] });
|
|
55
86
|
});
|
|
56
87
|
describe("loadMessages", () => {
|
|
57
88
|
it("should load messages from a local source", async () => {
|
|
@@ -67,8 +98,7 @@ describe("loadMessages", () => {
|
|
|
67
98
|
nodeishFs: {},
|
|
68
99
|
});
|
|
69
100
|
expect(await resolved.data.loadMessages({
|
|
70
|
-
|
|
71
|
-
sourceLanguageTag: "en",
|
|
101
|
+
settings: {},
|
|
72
102
|
})).toEqual([{ id: "test", expressions: [], selectors: [], variants: [] }]);
|
|
73
103
|
});
|
|
74
104
|
it("should collect an error if function is defined twice in multiple plugins", async () => {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type { LanguageTag } from "@inlang/language-tag";
|
|
2
1
|
import type { NodeishFilesystem as LisaNodeishFilesystem } from "@lix-js/fs";
|
|
3
2
|
import type { PluginReturnedInvalidCustomApiError, PluginLoadMessagesFunctionAlreadyDefinedError, PluginSaveMessagesFunctionAlreadyDefinedError, PluginHasInvalidIdError, PluginHasInvalidSchemaError, PluginUsesReservedNamespaceError, PluginsDoNotProvideLoadOrSaveMessagesError } from "./errors.js";
|
|
4
3
|
import type { Message } from "@inlang/message";
|
|
5
|
-
import type { JSONObject } from "@inlang/json-types";
|
|
6
4
|
import type { CustomApiInlangIdeExtension, Plugin } from "@inlang/plugin";
|
|
5
|
+
import type { ProjectSettings } from "@inlang/project-settings";
|
|
7
6
|
/**
|
|
8
7
|
* The filesystem is a subset of project lisa's nodeish filesystem.
|
|
9
8
|
*
|
|
@@ -15,7 +14,7 @@ export type NodeishFilesystemSubset = Pick<LisaNodeishFilesystem, "readFile" | "
|
|
|
15
14
|
*/
|
|
16
15
|
export type ResolvePluginsFunction = (args: {
|
|
17
16
|
plugins: Array<Plugin>;
|
|
18
|
-
settings:
|
|
17
|
+
settings: ProjectSettings;
|
|
19
18
|
nodeishFs: NodeishFilesystemSubset;
|
|
20
19
|
}) => Promise<{
|
|
21
20
|
data: ResolvedPluginApi;
|
|
@@ -26,10 +25,10 @@ export type ResolvePluginsFunction = (args: {
|
|
|
26
25
|
*/
|
|
27
26
|
export type ResolvedPluginApi = {
|
|
28
27
|
loadMessages: (args: {
|
|
29
|
-
|
|
30
|
-
sourceLanguageTag: LanguageTag;
|
|
28
|
+
settings: ProjectSettings;
|
|
31
29
|
}) => Promise<Message[]> | Message[];
|
|
32
30
|
saveMessages: (args: {
|
|
31
|
+
settings: ProjectSettings;
|
|
33
32
|
messages: Message[];
|
|
34
33
|
}) => Promise<void> | void;
|
|
35
34
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/resolve-modules/plugins/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,IAAI,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAC5E,OAAO,KAAK,EACX,mCAAmC,EACnC,6CAA6C,EAC7C,6CAA6C,EAC7C,uBAAuB,EACvB,2BAA2B,EAC3B,gCAAgC,EAChC,0CAA0C,EAC1C,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE/D;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACzC,qBAAqB,EACrB,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAC9C,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE;IAC3C,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACtB,QAAQ,EAAE,eAAe,CAAA;IACzB,SAAS,EAAE,uBAAuB,CAAA;CAClC,KAAK,OAAO,CAAC;IACb,IAAI,EAAE,iBAAiB,CAAA;IACvB,MAAM,EAAE,KAAK,CACV,mCAAmC,GACnC,6CAA6C,GAC7C,6CAA6C,GAC7C,uBAAuB,GACvB,2BAA2B,GAC3B,gCAAgC,GAChC,0CAA0C,CAC5C,CAAA;CACD,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC/B,YAAY,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,eAAe,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,CAAA;IACrF,YAAY,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,eAAe,CAAC;QAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAChG;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,EAAE,MAAM,CAAC,OAAO,MAAM,IAAI,MAAM,EAAE,GAAG,WAAW,MAAM,IAAI,MAAM,EAAE,EAAE,OAAO,CAAC,GAAG;QACvF,yBAAyB,CAAC,EAAE,2BAA2B,CAAA;KACvD,CAAA;CACD,CAAA"}
|