@inlang/sdk 0.7.0 → 0.8.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 +5 -5
- package/dist/createMessagesQuery.test.js +9 -0
- package/dist/loadProject.d.ts.map +1 -1
- package/dist/loadProject.js +3 -1
- package/dist/loadProject.test.js +10 -10
- 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/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 +13 -13
- 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 +14 -14
- package/src/loadProject.ts +15 -13
- 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 +2 -2
- package/src/resolve-modules/plugins/resolvePlugins.ts +16 -16
- 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
|
@@ -15,7 +15,7 @@ describe("getVariant", () => {
|
|
|
15
15
|
const variant = getVariant(mockMessage, {
|
|
16
16
|
where: {
|
|
17
17
|
languageTag: "en",
|
|
18
|
-
|
|
18
|
+
match: ["female", "1"],
|
|
19
19
|
},
|
|
20
20
|
})
|
|
21
21
|
|
|
@@ -31,7 +31,7 @@ describe("getVariant", () => {
|
|
|
31
31
|
const variant = getVariant(mockMessage, {
|
|
32
32
|
where: {
|
|
33
33
|
languageTag: "en",
|
|
34
|
-
|
|
34
|
+
match: ["female", "0"],
|
|
35
35
|
},
|
|
36
36
|
})
|
|
37
37
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -40,7 +40,7 @@ describe("getVariant", () => {
|
|
|
40
40
|
})
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
-
test("it should
|
|
43
|
+
test("it should not throw error if selector is empty and match", () => {
|
|
44
44
|
const mockMessage: Message = {
|
|
45
45
|
id: "mockMessage",
|
|
46
46
|
selectors: [],
|
|
@@ -48,21 +48,45 @@ describe("getVariant", () => {
|
|
|
48
48
|
{
|
|
49
49
|
languageTag: "en",
|
|
50
50
|
pattern: [{ type: "Text", value: "Gender male" }],
|
|
51
|
-
match:
|
|
52
|
-
gender: "male",
|
|
53
|
-
},
|
|
51
|
+
match: [],
|
|
54
52
|
},
|
|
55
53
|
{
|
|
56
54
|
languageTag: "de",
|
|
57
55
|
pattern: [{ type: "Text", value: "Veraltete Übersetzung" }],
|
|
58
|
-
match:
|
|
56
|
+
match: [],
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
}
|
|
60
|
+
const variant = getVariant(mockMessage, {
|
|
61
|
+
where: {
|
|
62
|
+
languageTag: "en",
|
|
63
|
+
match: [],
|
|
64
|
+
},
|
|
65
|
+
})
|
|
66
|
+
expect(variant).toBeDefined()
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
test("it should not throw error if selector is empty, return undefined", () => {
|
|
70
|
+
const mockMessage: Message = {
|
|
71
|
+
id: "mockMessage",
|
|
72
|
+
selectors: [],
|
|
73
|
+
variants: [
|
|
74
|
+
{
|
|
75
|
+
languageTag: "en",
|
|
76
|
+
pattern: [{ type: "Text", value: "Gender male" }],
|
|
77
|
+
match: ["male", "*"],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
languageTag: "de",
|
|
81
|
+
pattern: [{ type: "Text", value: "Veraltete Übersetzung" }],
|
|
82
|
+
match: ["*", "*"],
|
|
59
83
|
},
|
|
60
84
|
],
|
|
61
85
|
}
|
|
62
86
|
const variant = getVariant(mockMessage, {
|
|
63
87
|
where: {
|
|
64
88
|
languageTag: "fr",
|
|
65
|
-
|
|
89
|
+
match: ["*", "*"],
|
|
66
90
|
},
|
|
67
91
|
})
|
|
68
92
|
expect(variant).toBeUndefined()
|
|
@@ -74,7 +98,7 @@ describe("getVariant", () => {
|
|
|
74
98
|
const variant = getVariant(mockMessage, {
|
|
75
99
|
where: {
|
|
76
100
|
languageTag: "en",
|
|
77
|
-
|
|
101
|
+
match: ["*", "0"],
|
|
78
102
|
},
|
|
79
103
|
})
|
|
80
104
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -89,7 +113,7 @@ describe("getVariant", () => {
|
|
|
89
113
|
const variant = getVariant(mockMessage, {
|
|
90
114
|
where: {
|
|
91
115
|
languageTag: "en",
|
|
92
|
-
|
|
116
|
+
match: ["*", "*"],
|
|
93
117
|
},
|
|
94
118
|
})
|
|
95
119
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -104,7 +128,7 @@ describe("getVariant", () => {
|
|
|
104
128
|
const variant = getVariant(mockMessage, {
|
|
105
129
|
where: {
|
|
106
130
|
languageTag: "en",
|
|
107
|
-
|
|
131
|
+
match: ["trans", "2"],
|
|
108
132
|
},
|
|
109
133
|
})
|
|
110
134
|
expect(variant?.pattern[0]).toStrictEqual({
|
|
@@ -115,7 +139,7 @@ describe("getVariant", () => {
|
|
|
115
139
|
const variant2 = getVariant(mockMessage, {
|
|
116
140
|
where: {
|
|
117
141
|
languageTag: "en",
|
|
118
|
-
|
|
142
|
+
match: ["male", "8"],
|
|
119
143
|
},
|
|
120
144
|
})
|
|
121
145
|
expect(variant2?.pattern[0]).toStrictEqual({
|
|
@@ -128,14 +152,14 @@ describe("getVariant", () => {
|
|
|
128
152
|
const mockMessage: Message = getMockMessage()
|
|
129
153
|
mockMessage.variants = [
|
|
130
154
|
...mockMessage.variants!.filter(
|
|
131
|
-
(v) => v.languageTag === "en" && (v.match
|
|
155
|
+
(v) => v.languageTag === "en" && (v.match[0] !== "*" || v.match[1] !== "*")
|
|
132
156
|
),
|
|
133
157
|
]
|
|
134
158
|
|
|
135
159
|
const variant = getVariant(mockMessage, {
|
|
136
160
|
where: {
|
|
137
161
|
languageTag: "en",
|
|
138
|
-
|
|
162
|
+
match: ["*", "*"],
|
|
139
163
|
},
|
|
140
164
|
})
|
|
141
165
|
expect(variant).toBeUndefined()
|
|
@@ -147,18 +171,19 @@ describe("getVariant", () => {
|
|
|
147
171
|
const variant = getVariant(mockMessage, {
|
|
148
172
|
where: {
|
|
149
173
|
languageTag: "de",
|
|
150
|
-
|
|
174
|
+
match: ["female", "1"],
|
|
151
175
|
},
|
|
152
176
|
})
|
|
153
177
|
expect(variant).toBeUndefined()
|
|
154
178
|
})
|
|
155
179
|
|
|
156
|
-
test("should return
|
|
180
|
+
test("should return undefined variant if no selector defined", () => {
|
|
157
181
|
const mockMessage: Message = {} as any
|
|
182
|
+
mockMessage.selectors = []
|
|
158
183
|
mockMessage.variants = [
|
|
159
184
|
{
|
|
160
185
|
languageTag: "en",
|
|
161
|
-
match:
|
|
186
|
+
match: ["*", "*"],
|
|
162
187
|
pattern: [
|
|
163
188
|
{
|
|
164
189
|
type: "Text",
|
|
@@ -171,13 +196,52 @@ describe("getVariant", () => {
|
|
|
171
196
|
const variant = getVariant(mockMessage, {
|
|
172
197
|
where: {
|
|
173
198
|
languageTag: "en",
|
|
174
|
-
|
|
199
|
+
match: ["*", "*"],
|
|
175
200
|
},
|
|
176
201
|
})
|
|
177
|
-
// should return
|
|
178
|
-
expect(variant
|
|
202
|
+
// should return undefined
|
|
203
|
+
expect(variant).toBeUndefined()
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
test("should match catch all if the number of matches and selectors do not match", () => {
|
|
207
|
+
const mockMessage: Message = getMockMessage()
|
|
208
|
+
|
|
209
|
+
const variant1 = getVariant(mockMessage, {
|
|
210
|
+
where: {
|
|
211
|
+
languageTag: "en",
|
|
212
|
+
match: ["12"],
|
|
213
|
+
},
|
|
214
|
+
})
|
|
215
|
+
|
|
216
|
+
// should return catch all
|
|
217
|
+
expect(variant1?.pattern[0]).toStrictEqual({
|
|
179
218
|
type: "Text",
|
|
180
|
-
value: "
|
|
219
|
+
value: "{$hostName} invites {$guestName} and {$guestsOther} other people to their party.",
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
const variant2 = getVariant(mockMessage, {
|
|
223
|
+
where: {
|
|
224
|
+
languageTag: "en",
|
|
225
|
+
match: ["12", "*", "23"],
|
|
226
|
+
},
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
// should return catch all
|
|
230
|
+
expect(variant2?.pattern[0]).toStrictEqual({
|
|
231
|
+
type: "Text",
|
|
232
|
+
value: "{$hostName} invites {$guestName} and {$guestsOther} other people to their party.",
|
|
233
|
+
})
|
|
234
|
+
const variant3 = getVariant(mockMessage, {
|
|
235
|
+
where: {
|
|
236
|
+
languageTag: "en",
|
|
237
|
+
match: [],
|
|
238
|
+
},
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
// should return catch all
|
|
242
|
+
expect(variant3?.pattern[0]).toStrictEqual({
|
|
243
|
+
type: "Text",
|
|
244
|
+
value: "{$hostName} invites {$guestName} and {$guestsOther} other people to their party.",
|
|
181
245
|
})
|
|
182
246
|
})
|
|
183
247
|
})
|
|
@@ -188,7 +252,7 @@ describe("createVariant", () => {
|
|
|
188
252
|
|
|
189
253
|
const newVariant: Variant = {
|
|
190
254
|
languageTag: "en",
|
|
191
|
-
match:
|
|
255
|
+
match: ["female", "0"],
|
|
192
256
|
pattern: [],
|
|
193
257
|
}
|
|
194
258
|
const message = createVariant(mockMessage, {
|
|
@@ -197,8 +261,8 @@ describe("createVariant", () => {
|
|
|
197
261
|
// should return the female variant
|
|
198
262
|
expect(
|
|
199
263
|
message.data!.variants.find(
|
|
200
|
-
(v) => v.languageTag === "en" && v.match
|
|
201
|
-
)?.pattern
|
|
264
|
+
(v) => v.languageTag === "en" && v.match[0] === "female" && v.match[1] === "0"
|
|
265
|
+
)?.pattern
|
|
202
266
|
).toStrictEqual([])
|
|
203
267
|
})
|
|
204
268
|
|
|
@@ -206,22 +270,22 @@ describe("createVariant", () => {
|
|
|
206
270
|
const mockMessage: Message = getMockMessage()
|
|
207
271
|
mockMessage.variants = [
|
|
208
272
|
...mockMessage.variants!.filter(
|
|
209
|
-
(v) => v.languageTag === "en" && (v.match
|
|
273
|
+
(v) => v.languageTag === "en" && (v.match[0] !== "*" || v.match[1] !== "*")
|
|
210
274
|
),
|
|
211
275
|
]
|
|
212
276
|
|
|
213
277
|
const message = createVariant(mockMessage, {
|
|
214
278
|
data: {
|
|
215
279
|
languageTag: "en",
|
|
216
|
-
match:
|
|
280
|
+
match: ["*", "*"],
|
|
217
281
|
pattern: [],
|
|
218
282
|
},
|
|
219
283
|
})
|
|
220
284
|
// should return the female variant
|
|
221
285
|
expect(
|
|
222
286
|
message.data!.variants.find(
|
|
223
|
-
(v) => v.languageTag === "en" && v.match
|
|
224
|
-
)?.pattern
|
|
287
|
+
(v) => v.languageTag === "en" && v.match[0] === "*" && v.match[1] === "*"
|
|
288
|
+
)?.pattern
|
|
225
289
|
).toStrictEqual([])
|
|
226
290
|
})
|
|
227
291
|
|
|
@@ -231,7 +295,7 @@ describe("createVariant", () => {
|
|
|
231
295
|
const variant = createVariant(mockMessage, {
|
|
232
296
|
data: {
|
|
233
297
|
languageTag: "en",
|
|
234
|
-
match:
|
|
298
|
+
match: ["male", "1"],
|
|
235
299
|
pattern: [],
|
|
236
300
|
},
|
|
237
301
|
})
|
|
@@ -246,7 +310,7 @@ describe("createVariant", () => {
|
|
|
246
310
|
const variant = createVariant(mockMessage, {
|
|
247
311
|
data: {
|
|
248
312
|
languageTag: "de",
|
|
249
|
-
match:
|
|
313
|
+
match: ["female", "1"],
|
|
250
314
|
pattern: [],
|
|
251
315
|
},
|
|
252
316
|
})
|
|
@@ -263,15 +327,15 @@ describe("updateVariant", () => {
|
|
|
263
327
|
const message = updateVariantPattern(mockMessage, {
|
|
264
328
|
where: {
|
|
265
329
|
languageTag: "en",
|
|
266
|
-
|
|
330
|
+
match: ["female", "1"],
|
|
267
331
|
},
|
|
268
332
|
data: [],
|
|
269
333
|
})
|
|
270
334
|
// should return the female variant
|
|
271
335
|
expect(
|
|
272
336
|
message.data!.variants.find(
|
|
273
|
-
(v) => v.languageTag === "en" && v.match
|
|
274
|
-
)?.pattern
|
|
337
|
+
(v) => v.languageTag === "en" && v.match[0] === "female" && v.match[1] === "1"
|
|
338
|
+
)?.pattern
|
|
275
339
|
).toStrictEqual([])
|
|
276
340
|
})
|
|
277
341
|
|
|
@@ -281,15 +345,15 @@ describe("updateVariant", () => {
|
|
|
281
345
|
const message = updateVariantPattern(mockMessage, {
|
|
282
346
|
where: {
|
|
283
347
|
languageTag: "en",
|
|
284
|
-
|
|
348
|
+
match: ["*", "*"],
|
|
285
349
|
},
|
|
286
350
|
data: [],
|
|
287
351
|
})
|
|
288
352
|
// should return the female variant
|
|
289
353
|
expect(
|
|
290
354
|
message.data!.variants.find(
|
|
291
|
-
(v) => v.languageTag === "en" && v.match
|
|
292
|
-
)?.pattern
|
|
355
|
+
(v) => v.languageTag === "en" && v.match[0] === "*" && v.match[1] === "*"
|
|
356
|
+
)?.pattern
|
|
293
357
|
).toStrictEqual([])
|
|
294
358
|
})
|
|
295
359
|
|
|
@@ -298,14 +362,14 @@ describe("updateVariant", () => {
|
|
|
298
362
|
|
|
299
363
|
mockMessage.variants = [
|
|
300
364
|
...mockMessage.variants!.filter(
|
|
301
|
-
(v) => v.languageTag === "en" && (v.match
|
|
365
|
+
(v) => v.languageTag === "en" && (v.match[0] !== "*" || v.match[1] !== "*")
|
|
302
366
|
),
|
|
303
367
|
]
|
|
304
368
|
|
|
305
369
|
const variant = updateVariantPattern(mockMessage, {
|
|
306
370
|
where: {
|
|
307
371
|
languageTag: "en",
|
|
308
|
-
|
|
372
|
+
match: ["*", "*"],
|
|
309
373
|
},
|
|
310
374
|
data: [],
|
|
311
375
|
})
|
|
@@ -320,7 +384,7 @@ describe("updateVariant", () => {
|
|
|
320
384
|
const variant = updateVariantPattern(mockMessage, {
|
|
321
385
|
where: {
|
|
322
386
|
languageTag: "de",
|
|
323
|
-
|
|
387
|
+
match: ["*", "*"],
|
|
324
388
|
},
|
|
325
389
|
data: [],
|
|
326
390
|
})
|
|
@@ -340,7 +404,7 @@ const getMockMessage = (): Message => {
|
|
|
340
404
|
variants: [
|
|
341
405
|
{
|
|
342
406
|
languageTag: "en",
|
|
343
|
-
match:
|
|
407
|
+
match: ["female", "1"],
|
|
344
408
|
pattern: [
|
|
345
409
|
{
|
|
346
410
|
type: "Text",
|
|
@@ -350,7 +414,7 @@ const getMockMessage = (): Message => {
|
|
|
350
414
|
},
|
|
351
415
|
{
|
|
352
416
|
languageTag: "en",
|
|
353
|
-
match:
|
|
417
|
+
match: ["female", "2"],
|
|
354
418
|
pattern: [
|
|
355
419
|
{
|
|
356
420
|
type: "Text",
|
|
@@ -360,7 +424,7 @@ const getMockMessage = (): Message => {
|
|
|
360
424
|
},
|
|
361
425
|
{
|
|
362
426
|
languageTag: "en",
|
|
363
|
-
match:
|
|
427
|
+
match: ["female", "*"],
|
|
364
428
|
pattern: [
|
|
365
429
|
{
|
|
366
430
|
type: "Text",
|
|
@@ -370,7 +434,7 @@ const getMockMessage = (): Message => {
|
|
|
370
434
|
},
|
|
371
435
|
{
|
|
372
436
|
languageTag: "en",
|
|
373
|
-
match:
|
|
437
|
+
match: ["male", "1"],
|
|
374
438
|
pattern: [
|
|
375
439
|
{
|
|
376
440
|
type: "Text",
|
|
@@ -380,7 +444,7 @@ const getMockMessage = (): Message => {
|
|
|
380
444
|
},
|
|
381
445
|
{
|
|
382
446
|
languageTag: "en",
|
|
383
|
-
match:
|
|
447
|
+
match: ["male", "2"],
|
|
384
448
|
pattern: [
|
|
385
449
|
{
|
|
386
450
|
type: "Text",
|
|
@@ -390,7 +454,7 @@ const getMockMessage = (): Message => {
|
|
|
390
454
|
},
|
|
391
455
|
{
|
|
392
456
|
languageTag: "en",
|
|
393
|
-
match:
|
|
457
|
+
match: ["male", "*"],
|
|
394
458
|
pattern: [
|
|
395
459
|
{
|
|
396
460
|
type: "Text",
|
|
@@ -400,7 +464,7 @@ const getMockMessage = (): Message => {
|
|
|
400
464
|
},
|
|
401
465
|
{
|
|
402
466
|
languageTag: "en",
|
|
403
|
-
match:
|
|
467
|
+
match: ["*", "0"],
|
|
404
468
|
pattern: [
|
|
405
469
|
{
|
|
406
470
|
type: "Text",
|
|
@@ -410,7 +474,7 @@ const getMockMessage = (): Message => {
|
|
|
410
474
|
},
|
|
411
475
|
{
|
|
412
476
|
languageTag: "en",
|
|
413
|
-
match:
|
|
477
|
+
match: ["*", "1"],
|
|
414
478
|
pattern: [
|
|
415
479
|
{
|
|
416
480
|
type: "Text",
|
|
@@ -420,7 +484,7 @@ const getMockMessage = (): Message => {
|
|
|
420
484
|
},
|
|
421
485
|
{
|
|
422
486
|
languageTag: "en",
|
|
423
|
-
match:
|
|
487
|
+
match: ["*", "2"],
|
|
424
488
|
pattern: [
|
|
425
489
|
{
|
|
426
490
|
type: "Text",
|
|
@@ -430,7 +494,7 @@ const getMockMessage = (): Message => {
|
|
|
430
494
|
},
|
|
431
495
|
{
|
|
432
496
|
languageTag: "en",
|
|
433
|
-
match:
|
|
497
|
+
match: ["*", "*"],
|
|
434
498
|
pattern: [
|
|
435
499
|
{
|
|
436
500
|
type: "Text",
|
package/src/messages/variant.ts
CHANGED
|
@@ -14,18 +14,18 @@ import {
|
|
|
14
14
|
* (if it exists).
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
|
-
* const variant = getVariant(message, { where: { languageTag: "en",
|
|
17
|
+
* const variant = getVariant(message, { where: { languageTag: "en", match: ["male"]}});
|
|
18
18
|
*/
|
|
19
19
|
export function getVariant(
|
|
20
20
|
message: Message,
|
|
21
21
|
args: {
|
|
22
22
|
where: {
|
|
23
23
|
languageTag: LanguageTag
|
|
24
|
-
|
|
24
|
+
match?: Variant["match"]
|
|
25
25
|
}
|
|
26
|
-
}
|
|
26
|
+
}
|
|
27
27
|
): Variant | undefined {
|
|
28
|
-
const variant = matchMostSpecificVariant(message, args.where.languageTag, args.where.
|
|
28
|
+
const variant = matchMostSpecificVariant(message, args.where.languageTag, args.where.match)
|
|
29
29
|
if (variant) {
|
|
30
30
|
//! do not return a reference to the message in a resource
|
|
31
31
|
//! modifications to the returned message will leak into the
|
|
@@ -47,7 +47,7 @@ export function createVariant(
|
|
|
47
47
|
message: Message,
|
|
48
48
|
args: {
|
|
49
49
|
data: Variant
|
|
50
|
-
}
|
|
50
|
+
}
|
|
51
51
|
): Result<Message, MessageVariantAlreadyExistsError> {
|
|
52
52
|
const copy = structuredClone(message)
|
|
53
53
|
|
|
@@ -56,10 +56,9 @@ export function createVariant(
|
|
|
56
56
|
return { error: new MessageVariantAlreadyExistsError(message.id, args.data.languageTag) }
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
// need to resolve selectors to match length and order of message selectors
|
|
60
59
|
copy.variants.push({
|
|
61
60
|
...args.data,
|
|
62
|
-
match:
|
|
61
|
+
match: args.data.match,
|
|
63
62
|
})
|
|
64
63
|
return { data: copy }
|
|
65
64
|
}
|
|
@@ -70,22 +69,22 @@ export function createVariant(
|
|
|
70
69
|
* All actions are immutable.
|
|
71
70
|
*
|
|
72
71
|
* @example
|
|
73
|
-
* const message = updateVariant(message, { languageTag: "en",
|
|
72
|
+
* const message = updateVariant(message, { languageTag: "en", match: ["male"], pattern: []})
|
|
74
73
|
*/
|
|
75
74
|
export function updateVariantPattern(
|
|
76
75
|
message: Message,
|
|
77
76
|
args: {
|
|
78
77
|
where: {
|
|
79
78
|
languageTag: LanguageTag
|
|
80
|
-
|
|
79
|
+
match: Variant["match"]
|
|
81
80
|
}
|
|
82
81
|
data: Variant["pattern"]
|
|
83
|
-
}
|
|
82
|
+
}
|
|
84
83
|
): Result<Message, MessageVariantDoesNotExistError | MessagePatternsForLanguageTagDoNotExistError> {
|
|
85
84
|
const copy = structuredClone(message)
|
|
86
85
|
|
|
87
86
|
const containsLanguageTag = message.variants.some(
|
|
88
|
-
(variant) => variant.languageTag === args.where.languageTag
|
|
87
|
+
(variant) => variant.languageTag === args.where.languageTag
|
|
89
88
|
)
|
|
90
89
|
if (!containsLanguageTag) {
|
|
91
90
|
return {
|
|
@@ -93,7 +92,7 @@ export function updateVariantPattern(
|
|
|
93
92
|
}
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
const variant = matchVariant(copy, args.where.languageTag, args.where.
|
|
95
|
+
const variant = matchVariant(copy, args.where.languageTag, args.where.match)
|
|
97
96
|
if (variant === undefined) {
|
|
98
97
|
return { error: new MessageVariantDoesNotExistError(message.id, args.where.languageTag) }
|
|
99
98
|
}
|
|
@@ -108,27 +107,31 @@ export function updateVariantPattern(
|
|
|
108
107
|
* Returns the specific variant defined by selectors or undefined
|
|
109
108
|
*
|
|
110
109
|
* @example
|
|
111
|
-
* const variant = matchVariant(message, languageTag: "en",
|
|
110
|
+
* const variant = matchVariant(message, languageTag: "en", match: ["male"])
|
|
112
111
|
*/
|
|
113
112
|
const matchVariant = (
|
|
114
113
|
message: Message,
|
|
115
114
|
languageTag: LanguageTag,
|
|
116
|
-
|
|
115
|
+
match: Variant["match"]
|
|
117
116
|
): Variant | undefined => {
|
|
118
|
-
// resolve preferenceSelectors to match length and order of message selectors
|
|
119
|
-
const resolvedSelectors = resolveSelector(message.selectors, selectors)
|
|
120
|
-
|
|
121
117
|
const languageVariants = message.variants.filter((variant) => variant.languageTag === languageTag)
|
|
122
118
|
if (languageVariants.length === 0) return undefined
|
|
123
119
|
|
|
124
120
|
for (const variant of languageVariants) {
|
|
125
121
|
let isMatch = true
|
|
126
122
|
//check if vaiant is a match
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
if (variant.match.length > 0) {
|
|
124
|
+
variant.match.map((value, index) => {
|
|
125
|
+
if (match && match[index] !== value) {
|
|
126
|
+
isMatch = false
|
|
127
|
+
}
|
|
128
|
+
})
|
|
131
129
|
}
|
|
130
|
+
|
|
131
|
+
if (!message.selectors || !match || match.length !== message.selectors.length) {
|
|
132
|
+
isMatch = false
|
|
133
|
+
}
|
|
134
|
+
|
|
132
135
|
if (isMatch) {
|
|
133
136
|
return variant
|
|
134
137
|
}
|
|
@@ -145,13 +148,9 @@ const matchVariant = (
|
|
|
145
148
|
const matchMostSpecificVariant = (
|
|
146
149
|
message: Message,
|
|
147
150
|
languageTag: LanguageTag,
|
|
148
|
-
|
|
151
|
+
match?: Variant["match"]
|
|
149
152
|
): Variant | undefined => {
|
|
150
|
-
// make selector undefined if empty object
|
|
151
|
-
selectors = JSON.stringify(selectors) === "{}" ? undefined : selectors
|
|
152
|
-
|
|
153
153
|
// resolve preferenceSelectors to match length and order of message selectors
|
|
154
|
-
const resolvedSelectors = resolveSelector(message.selectors, selectors)
|
|
155
154
|
const index: Record<string, any> = {}
|
|
156
155
|
|
|
157
156
|
for (const variant of message.variants) {
|
|
@@ -159,44 +158,70 @@ const matchMostSpecificVariant = (
|
|
|
159
158
|
|
|
160
159
|
let isMatch = true
|
|
161
160
|
|
|
161
|
+
// if slector and stored match are not the same throw error
|
|
162
|
+
if (variant.match.length !== message.selectors.length) {
|
|
163
|
+
return undefined
|
|
164
|
+
}
|
|
165
|
+
|
|
162
166
|
//check if variant is a match
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
+
if (variant.match.length > 0) {
|
|
168
|
+
variant.match.map((value, index) => {
|
|
169
|
+
if (match && match[index] !== value && value !== "*") {
|
|
170
|
+
isMatch = false
|
|
171
|
+
}
|
|
172
|
+
})
|
|
167
173
|
}
|
|
168
|
-
if (isMatch &&
|
|
169
|
-
// add variant to nested index
|
|
174
|
+
if (isMatch && match && match.length > 0) {
|
|
170
175
|
// eslint-disable-next-line no-inner-declarations
|
|
171
176
|
function recursiveAddToIndex(
|
|
172
177
|
currentIndex: Record<string, any>,
|
|
173
|
-
|
|
174
|
-
|
|
178
|
+
selectorIndex: number,
|
|
179
|
+
selectorLength: number,
|
|
180
|
+
variant: Variant
|
|
175
181
|
) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
currentIndex[key] = {}
|
|
184
|
-
}
|
|
185
|
-
recursiveAddToIndex(currentIndex[key], currentKeys.slice(1), variant)
|
|
182
|
+
const key = variant.match[selectorIndex]
|
|
183
|
+
if (key) {
|
|
184
|
+
if (selectorIndex === 1) {
|
|
185
|
+
currentIndex[key] = variant
|
|
186
|
+
} else {
|
|
187
|
+
if (!currentIndex[key]) {
|
|
188
|
+
currentIndex[key] = {}
|
|
186
189
|
}
|
|
190
|
+
recursiveAddToIndex(currentIndex[key], selectorIndex + 1, selectorLength, variant)
|
|
187
191
|
}
|
|
188
192
|
}
|
|
189
193
|
}
|
|
190
|
-
recursiveAddToIndex(index, message.selectors, variant)
|
|
191
|
-
} else if (isMatch && !
|
|
194
|
+
recursiveAddToIndex(index, 0, message.selectors ? message.selectors.length - 1 : 0, variant)
|
|
195
|
+
} else if (isMatch && !match) {
|
|
192
196
|
return variant
|
|
193
197
|
}
|
|
194
198
|
}
|
|
195
199
|
|
|
200
|
+
// if number of selectors and numver of required match is not the same match catch all
|
|
201
|
+
if (!message.selectors || !match || match.length !== message.selectors.length) {
|
|
202
|
+
const catchAllMatcher: Array<string> = []
|
|
203
|
+
const selectorCount = message.selectors.length
|
|
204
|
+
catchAllMatcher.push("*")
|
|
205
|
+
for (let i = 0; i < selectorCount - 1; i++) {
|
|
206
|
+
catchAllMatcher.push("*")
|
|
207
|
+
}
|
|
208
|
+
return message.variants.find(
|
|
209
|
+
(v) =>
|
|
210
|
+
v.languageTag === languageTag && JSON.stringify(v.match) === JSON.stringify(catchAllMatcher)
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// if selector is empty match empty variant match
|
|
215
|
+
if (message.selectors && message.selectors.length === 0) {
|
|
216
|
+
return message.variants.find(
|
|
217
|
+
(v) => v.languageTag === languageTag && JSON.stringify(v.match) === "[]"
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
|
|
196
221
|
//find the most specific variant
|
|
197
222
|
const findOptimalMatch = (
|
|
198
223
|
index: Record<string, any>,
|
|
199
|
-
selectors: string[]
|
|
224
|
+
selectors: string[]
|
|
200
225
|
): Variant | undefined => {
|
|
201
226
|
const keys = Object.keys(index)
|
|
202
227
|
|
|
@@ -218,24 +243,5 @@ const matchMostSpecificVariant = (
|
|
|
218
243
|
return undefined
|
|
219
244
|
}
|
|
220
245
|
|
|
221
|
-
return findOptimalMatch(index,
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Returns resolved selector.
|
|
226
|
-
* -> Adds all possible selectors, if not defined it adds '*'. Order is determined by messageSelectors
|
|
227
|
-
*
|
|
228
|
-
* @example
|
|
229
|
-
* const variant = resolveSelector(["gender","count"], selector: {count: "2"})
|
|
230
|
-
*/
|
|
231
|
-
const resolveSelector = (
|
|
232
|
-
messageSelectors: Message["selectors"],
|
|
233
|
-
selectors?: Record<string, string>,
|
|
234
|
-
): Record<string, string> => {
|
|
235
|
-
const resolvedSelectors: Record<string, string> = {}
|
|
236
|
-
if (!selectors) return {}
|
|
237
|
-
for (const messageSelector of messageSelectors) {
|
|
238
|
-
resolvedSelectors[messageSelector.name] = selectors[messageSelector.name] ?? "*"
|
|
239
|
-
}
|
|
240
|
-
return resolvedSelectors
|
|
246
|
+
return findOptimalMatch(index, match || [])
|
|
241
247
|
}
|
package/src/parseConfig.ts
CHANGED
|
@@ -16,7 +16,7 @@ export class ParseConfigError extends Error {
|
|
|
16
16
|
const ConfigCompiler = TypeCompiler.Compile(ProjectSettings)
|
|
17
17
|
|
|
18
18
|
export const parseSettings = (
|
|
19
|
-
config: ProjectSettings
|
|
19
|
+
config: ProjectSettings
|
|
20
20
|
): Result<ProjectSettings, ParseConfigError> => {
|
|
21
21
|
if (ConfigCompiler.Check(config)) {
|
|
22
22
|
return {
|
|
@@ -27,7 +27,7 @@ export const parseSettings = (
|
|
|
27
27
|
return {
|
|
28
28
|
error: new ParseConfigError(
|
|
29
29
|
"The inlang config is not valid.",
|
|
30
|
-
[...ConfigCompiler.Errors(config)].toString()
|
|
30
|
+
[...ConfigCompiler.Errors(config)].toString()
|
|
31
31
|
),
|
|
32
32
|
data: undefined as never,
|
|
33
33
|
}
|