@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
|
@@ -54,10 +54,10 @@ describe("get", () => {
|
|
|
54
54
|
const message2 = query.get({ where: { id: "first-message" } })!
|
|
55
55
|
|
|
56
56
|
expect(
|
|
57
|
-
(message1.variants.find((v) => v.languageTag === "en")!.pattern![0]! as Text).value
|
|
57
|
+
(message1.variants.find((v) => v.languageTag === "en")!.pattern![0]! as Text).value
|
|
58
58
|
).toBe("Hello World 2")
|
|
59
59
|
expect(
|
|
60
|
-
(message2.variants.find((v) => v.languageTag === "en")!.pattern![0]! as Text).value
|
|
60
|
+
(message2.variants.find((v) => v.languageTag === "en")!.pattern![0]! as Text).value
|
|
61
61
|
).toBe("Hello World")
|
|
62
62
|
})
|
|
63
63
|
})
|
|
@@ -94,7 +94,7 @@ describe("getAll", () => {
|
|
|
94
94
|
(
|
|
95
95
|
Object.values(query.getAll()!)[0]!.variants.find((v) => v.languageTag === "en")!
|
|
96
96
|
.pattern![0]! as Text
|
|
97
|
-
).value
|
|
97
|
+
).value
|
|
98
98
|
).toBe("Hello World")
|
|
99
99
|
})
|
|
100
100
|
})
|
|
@@ -194,13 +194,13 @@ describe("reactivity", () => {
|
|
|
194
194
|
expect(message).toBeDefined()
|
|
195
195
|
expect(
|
|
196
196
|
(message?.variants.find((variant) => variant.languageTag === "en")?.pattern[0] as Text)
|
|
197
|
-
.value
|
|
197
|
+
.value
|
|
198
198
|
).toBe("before")
|
|
199
199
|
|
|
200
200
|
query.update({ where: { id: "1" }, data: createMessage("1", { en: "after" }) })
|
|
201
201
|
expect(
|
|
202
202
|
(message?.variants.find((variant) => variant.languageTag === "en")?.pattern[0] as Text)
|
|
203
|
-
.value
|
|
203
|
+
.value
|
|
204
204
|
).toBe("after")
|
|
205
205
|
})
|
|
206
206
|
})
|
|
@@ -217,13 +217,13 @@ describe("reactivity", () => {
|
|
|
217
217
|
expect(message).toBeDefined()
|
|
218
218
|
expect(
|
|
219
219
|
(message?.variants.find((variant) => variant.languageTag === "en")?.pattern[0] as Text)
|
|
220
|
-
.value
|
|
220
|
+
.value
|
|
221
221
|
).toBe("before")
|
|
222
222
|
|
|
223
223
|
query.upsert({ where: { id: "1" }, data: createMessage("1", { en: "after" }) })
|
|
224
224
|
expect(
|
|
225
225
|
(message?.variants.find((variant) => variant.languageTag === "en")?.pattern[0] as Text)
|
|
226
|
-
.value
|
|
226
|
+
.value
|
|
227
227
|
).toBe("after")
|
|
228
228
|
})
|
|
229
229
|
})
|
|
@@ -254,14 +254,14 @@ describe("reactivity", () => {
|
|
|
254
254
|
expect(message).toBeDefined()
|
|
255
255
|
expect(
|
|
256
256
|
(message!.variants.find((variant) => variant.languageTag === "en")?.pattern[0] as Text)
|
|
257
|
-
.value
|
|
257
|
+
.value
|
|
258
258
|
).toBe("before")
|
|
259
259
|
|
|
260
260
|
setMessages([createMessage("1", { en: "after" })])
|
|
261
261
|
expect(message).toBeDefined()
|
|
262
262
|
expect(
|
|
263
263
|
(message!.variants.find((variant) => variant.languageTag === "en")?.pattern[0] as Text)
|
|
264
|
-
.value
|
|
264
|
+
.value
|
|
265
265
|
).toBe("after")
|
|
266
266
|
})
|
|
267
267
|
})
|
|
@@ -301,7 +301,7 @@ describe("reactivity", () => {
|
|
|
301
301
|
(
|
|
302
302
|
Object.values(messages!)![0]!.variants.find((variant) => variant.languageTag === "en")!
|
|
303
303
|
.pattern[0]! as Text
|
|
304
|
-
).value
|
|
304
|
+
).value
|
|
305
305
|
).toBe("before")
|
|
306
306
|
|
|
307
307
|
query.update({ where: { id: "1" }, data: createMessage("1", { en: "after" }) })
|
|
@@ -310,7 +310,7 @@ describe("reactivity", () => {
|
|
|
310
310
|
(
|
|
311
311
|
Object.values(messages!)![0]!.variants.find((variant) => variant.languageTag === "en")!
|
|
312
312
|
.pattern[0]! as Text
|
|
313
|
-
).value
|
|
313
|
+
).value
|
|
314
314
|
).toBe("after")
|
|
315
315
|
})
|
|
316
316
|
})
|
|
@@ -329,7 +329,7 @@ describe("reactivity", () => {
|
|
|
329
329
|
(
|
|
330
330
|
Object.values(messages!)![0]!.variants.find((variant) => variant.languageTag === "en")!
|
|
331
331
|
.pattern[0]! as Text
|
|
332
|
-
).value
|
|
332
|
+
).value
|
|
333
333
|
).toBe("before")
|
|
334
334
|
|
|
335
335
|
query.upsert({ where: { id: "1" }, data: createMessage("1", { en: "after" }) })
|
|
@@ -337,7 +337,7 @@ describe("reactivity", () => {
|
|
|
337
337
|
(
|
|
338
338
|
Object.values(messages!)![0]!.variants.find((variant) => variant.languageTag === "en")!
|
|
339
339
|
.pattern[0]! as Text
|
|
340
|
-
).value
|
|
340
|
+
).value
|
|
341
341
|
).toBe("after")
|
|
342
342
|
})
|
|
343
343
|
})
|
|
@@ -385,7 +385,7 @@ describe("reactivity", () => {
|
|
|
385
385
|
(
|
|
386
386
|
Object.values(messages!)![0]!.variants.find((variant) => variant.languageTag === "en")!
|
|
387
387
|
.pattern[0]! as Text
|
|
388
|
-
).value
|
|
388
|
+
).value
|
|
389
389
|
).toBe("before")
|
|
390
390
|
|
|
391
391
|
setMessages([createMessage("1", { en: "after" })])
|
|
@@ -394,9 +394,22 @@ describe("reactivity", () => {
|
|
|
394
394
|
(
|
|
395
395
|
Object.values(messages!)![0]!.variants.find((variant) => variant.languageTag === "en")!
|
|
396
396
|
.pattern[0]! as Text
|
|
397
|
-
).value
|
|
397
|
+
).value
|
|
398
398
|
).toBe("after")
|
|
399
399
|
})
|
|
400
|
+
|
|
401
|
+
it("should not mutate messages signal outside the query when using the query", async () => {
|
|
402
|
+
const [inputMessages] = createSignal<Message[]>([createMessage("1", { en: "before" })])
|
|
403
|
+
const query = createMessagesQuery(inputMessages)
|
|
404
|
+
|
|
405
|
+
let messages: Readonly<Message[]> | undefined = undefined
|
|
406
|
+
await createChangeListener(() => (messages = query.getAll()))
|
|
407
|
+
expect(Object.values(messages!)).toHaveLength(1)
|
|
408
|
+
|
|
409
|
+
query.create({ data: createMessage("2", { en: "" }) })
|
|
410
|
+
|
|
411
|
+
expect(inputMessages().length).toBe(1)
|
|
412
|
+
})
|
|
400
413
|
})
|
|
401
414
|
})
|
|
402
415
|
|
|
@@ -421,11 +434,11 @@ it("instances should not share state", async () => {
|
|
|
421
434
|
query1.update({ where: { id: "1" }, data: createMessage("1", { en: "after" }) })
|
|
422
435
|
expect(
|
|
423
436
|
(message1!.variants.find((variant) => variant.languageTag === "en")!.pattern[0]! as Text)
|
|
424
|
-
.value
|
|
437
|
+
.value
|
|
425
438
|
).toBe("after")
|
|
426
439
|
expect(
|
|
427
440
|
(message2!.variants.find((variant) => variant.languageTag === "en")!.pattern[0]! as Text)
|
|
428
|
-
.value
|
|
441
|
+
.value
|
|
429
442
|
).toBe("before")
|
|
430
443
|
|
|
431
444
|
query1.delete({ where: { id: "1" } })
|
|
@@ -8,7 +8,7 @@ import type { InlangProject, MessageQueryApi } from "./api.js"
|
|
|
8
8
|
* Creates a reactive query API for messages.
|
|
9
9
|
*/
|
|
10
10
|
export function createMessagesQuery(
|
|
11
|
-
messages: () => Array<Message
|
|
11
|
+
messages: () => Array<Message>
|
|
12
12
|
): InlangProject["query"]["messages"] {
|
|
13
13
|
// @ts-expect-error
|
|
14
14
|
const index = new ReactiveMap<string, Message>()
|
|
@@ -31,7 +31,7 @@ export function createMessagesQuery(
|
|
|
31
31
|
get: Object.assign(get, {
|
|
32
32
|
subscribe: (
|
|
33
33
|
args: Parameters<MessageQueryApi["get"]["subscribe"]>[0],
|
|
34
|
-
callback: Parameters<MessageQueryApi["get"]["subscribe"]>[1]
|
|
34
|
+
callback: Parameters<MessageQueryApi["get"]["subscribe"]>[1]
|
|
35
35
|
) => createSubscribable(() => get(args)).subscribe(callback),
|
|
36
36
|
}) as any,
|
|
37
37
|
includedMessageIds: createSubscribable(() => {
|
package/src/loadProject.test.ts
CHANGED
|
@@ -53,7 +53,7 @@ const exampleMessages: Message[] = [
|
|
|
53
53
|
variants: [
|
|
54
54
|
{
|
|
55
55
|
languageTag: "en",
|
|
56
|
-
match:
|
|
56
|
+
match: [],
|
|
57
57
|
pattern: [
|
|
58
58
|
{
|
|
59
59
|
type: "Text",
|
|
@@ -69,7 +69,7 @@ const exampleMessages: Message[] = [
|
|
|
69
69
|
variants: [
|
|
70
70
|
{
|
|
71
71
|
languageTag: "en",
|
|
72
|
-
match:
|
|
72
|
+
match: [],
|
|
73
73
|
pattern: [
|
|
74
74
|
{
|
|
75
75
|
type: "Text",
|
|
@@ -363,7 +363,7 @@ describe("functionality", () => {
|
|
|
363
363
|
sourceLanguageTag: "en",
|
|
364
364
|
languageTags: ["en"],
|
|
365
365
|
modules: ["plugin.js", "lintRule.js"],
|
|
366
|
-
} satisfies ProjectSettings)
|
|
366
|
+
} satisfies ProjectSettings)
|
|
367
367
|
)
|
|
368
368
|
|
|
369
369
|
const _import: ImportFunction = async (name) => {
|
|
@@ -411,7 +411,7 @@ describe("functionality", () => {
|
|
|
411
411
|
sourceLanguageTag: "en",
|
|
412
412
|
languageTags: ["en"],
|
|
413
413
|
modules: ["plugin.js", "lintRule.js"],
|
|
414
|
-
} satisfies ProjectSettings)
|
|
414
|
+
} satisfies ProjectSettings)
|
|
415
415
|
)
|
|
416
416
|
const _import: ImportFunction = async (name) => {
|
|
417
417
|
return {
|
|
@@ -428,7 +428,7 @@ describe("functionality", () => {
|
|
|
428
428
|
await new Promise((resolve) => setTimeout(resolve, 510))
|
|
429
429
|
|
|
430
430
|
expect(
|
|
431
|
-
project.query.messageLintReports.get({ where: { messageId: "some-message" } })
|
|
431
|
+
project.query.messageLintReports.get({ where: { messageId: "some-message" } })
|
|
432
432
|
).toHaveLength(1)
|
|
433
433
|
})
|
|
434
434
|
})
|
|
@@ -491,7 +491,7 @@ describe("functionality", () => {
|
|
|
491
491
|
"plugin.project.json": {
|
|
492
492
|
pathPattern: "./resources/{languageTag}.json",
|
|
493
493
|
},
|
|
494
|
-
})
|
|
494
|
+
})
|
|
495
495
|
)
|
|
496
496
|
|
|
497
497
|
await fs.mkdir("./resources")
|
|
@@ -526,7 +526,7 @@ describe("functionality", () => {
|
|
|
526
526
|
variants: [
|
|
527
527
|
{
|
|
528
528
|
languageTag: "en",
|
|
529
|
-
match:
|
|
529
|
+
match: [],
|
|
530
530
|
pattern: [
|
|
531
531
|
{
|
|
532
532
|
type: "Text",
|
|
@@ -536,7 +536,7 @@ describe("functionality", () => {
|
|
|
536
536
|
},
|
|
537
537
|
{
|
|
538
538
|
languageTag: "de",
|
|
539
|
-
match:
|
|
539
|
+
match: [],
|
|
540
540
|
pattern: [
|
|
541
541
|
{
|
|
542
542
|
type: "Text",
|
|
@@ -556,7 +556,7 @@ describe("functionality", () => {
|
|
|
556
556
|
variants: [
|
|
557
557
|
{
|
|
558
558
|
languageTag: "en",
|
|
559
|
-
match:
|
|
559
|
+
match: [],
|
|
560
560
|
pattern: [
|
|
561
561
|
{
|
|
562
562
|
type: "Text",
|
|
@@ -567,7 +567,7 @@ describe("functionality", () => {
|
|
|
567
567
|
|
|
568
568
|
{
|
|
569
569
|
languageTag: "de",
|
|
570
|
-
match:
|
|
570
|
+
match: [],
|
|
571
571
|
pattern: [
|
|
572
572
|
{
|
|
573
573
|
type: "Text",
|
|
@@ -594,7 +594,7 @@ describe("functionality", () => {
|
|
|
594
594
|
variants: [
|
|
595
595
|
{
|
|
596
596
|
languageTag: "en",
|
|
597
|
-
match:
|
|
597
|
+
match: [],
|
|
598
598
|
pattern: [
|
|
599
599
|
{
|
|
600
600
|
type: "Text",
|
|
@@ -604,7 +604,7 @@ describe("functionality", () => {
|
|
|
604
604
|
},
|
|
605
605
|
{
|
|
606
606
|
languageTag: "de",
|
|
607
|
-
match:
|
|
607
|
+
match: [],
|
|
608
608
|
pattern: [
|
|
609
609
|
{
|
|
610
610
|
type: "Text",
|
|
@@ -620,7 +620,7 @@ describe("functionality", () => {
|
|
|
620
620
|
variants: [
|
|
621
621
|
{
|
|
622
622
|
languageTag: "en",
|
|
623
|
-
match:
|
|
623
|
+
match: [],
|
|
624
624
|
pattern: [
|
|
625
625
|
{
|
|
626
626
|
type: "Text",
|
|
@@ -630,7 +630,7 @@ describe("functionality", () => {
|
|
|
630
630
|
},
|
|
631
631
|
{
|
|
632
632
|
languageTag: "de",
|
|
633
|
-
match:
|
|
633
|
+
match: [],
|
|
634
634
|
pattern: [
|
|
635
635
|
{
|
|
636
636
|
type: "Text",
|
package/src/loadProject.ts
CHANGED
|
@@ -47,7 +47,9 @@ export const loadProject = async (args: {
|
|
|
47
47
|
loadSettings({ settingsFilePath: args.settingsFilePath, nodeishFs: args.nodeishFs })
|
|
48
48
|
.then((settings) => {
|
|
49
49
|
setSettings(settings)
|
|
50
|
-
|
|
50
|
+
// rename settings to get a convenient access to the data in Posthog
|
|
51
|
+
const project_settings = settings
|
|
52
|
+
args._capture?.("SDK used settings", { project_settings })
|
|
51
53
|
})
|
|
52
54
|
.catch((err) => {
|
|
53
55
|
markInitAsFailed(err)
|
|
@@ -56,7 +58,7 @@ export const loadProject = async (args: {
|
|
|
56
58
|
// TODO: create FS watcher and update settings on change
|
|
57
59
|
|
|
58
60
|
const writeSettingsToDisk = skipFirst((settings: ProjectSettings) =>
|
|
59
|
-
_writeSettingsToDisk({ nodeishFs: args.nodeishFs, settings })
|
|
61
|
+
_writeSettingsToDisk({ nodeishFs: args.nodeishFs, settings })
|
|
60
62
|
)
|
|
61
63
|
|
|
62
64
|
const setSettings = (settings: ProjectSettings): Result<void, ProjectSettingsInvalidError> => {
|
|
@@ -113,14 +115,14 @@ export const loadProject = async (args: {
|
|
|
113
115
|
_resolvedModules.resolvedPluginApi.loadMessages({
|
|
114
116
|
languageTags: settingsValue!.languageTags,
|
|
115
117
|
sourceLanguageTag: settingsValue!.sourceLanguageTag,
|
|
116
|
-
})
|
|
118
|
+
})
|
|
117
119
|
)
|
|
118
120
|
.then((messages) => {
|
|
119
121
|
setMessages(messages)
|
|
120
122
|
markInitAsComplete()
|
|
121
123
|
})
|
|
122
124
|
.catch((err) =>
|
|
123
|
-
markInitAsFailed(new PluginLoadMessagesError("Error in load messages", { cause: err }))
|
|
125
|
+
markInitAsFailed(new PluginLoadMessagesError("Error in load messages", { cause: err }))
|
|
124
126
|
)
|
|
125
127
|
})
|
|
126
128
|
|
|
@@ -139,7 +141,7 @@ export const loadProject = async (args: {
|
|
|
139
141
|
"Unknown module. You stumbled on a bug in inlang's source code. Please open an issue.",
|
|
140
142
|
// default to warning, see https://github.com/inlang/monorepo/issues/1254
|
|
141
143
|
level: settingsValue["messageLintRuleLevels"]?.[rule.id] ?? "warning",
|
|
142
|
-
} satisfies InstalledMessageLintRule)
|
|
144
|
+
} satisfies InstalledMessageLintRule)
|
|
143
145
|
) satisfies Array<InstalledMessageLintRule>
|
|
144
146
|
}
|
|
145
147
|
|
|
@@ -164,7 +166,7 @@ export const loadProject = async (args: {
|
|
|
164
166
|
messages,
|
|
165
167
|
settings as () => ProjectSettings,
|
|
166
168
|
installedMessageLintRules,
|
|
167
|
-
resolvedModules
|
|
169
|
+
resolvedModules
|
|
168
170
|
)
|
|
169
171
|
|
|
170
172
|
const debouncedSave = skipFirst(
|
|
@@ -185,8 +187,8 @@ export const loadProject = async (args: {
|
|
|
185
187
|
setMessages(newMessages)
|
|
186
188
|
}
|
|
187
189
|
},
|
|
188
|
-
{ atBegin: false }
|
|
189
|
-
)
|
|
190
|
+
{ atBegin: false }
|
|
191
|
+
)
|
|
190
192
|
)
|
|
191
193
|
|
|
192
194
|
createEffect(() => {
|
|
@@ -224,14 +226,14 @@ const loadSettings = async (args: {
|
|
|
224
226
|
nodeishFs: NodeishFilesystemSubset
|
|
225
227
|
}) => {
|
|
226
228
|
const { data: settingsFile, error: settingsFileError } = await tryCatch(
|
|
227
|
-
async () => await args.nodeishFs.readFile(args.settingsFilePath, { encoding: "utf-8" })
|
|
229
|
+
async () => await args.nodeishFs.readFile(args.settingsFilePath, { encoding: "utf-8" })
|
|
228
230
|
)
|
|
229
231
|
if (settingsFileError)
|
|
230
232
|
throw new ProjectSettingsFileNotFoundError(
|
|
231
233
|
`Could not locate settings file in (${args.settingsFilePath}).`,
|
|
232
234
|
{
|
|
233
235
|
cause: settingsFileError,
|
|
234
|
-
}
|
|
236
|
+
}
|
|
235
237
|
)
|
|
236
238
|
|
|
237
239
|
const json = tryCatch(() => JSON.parse(settingsFile!))
|
|
@@ -263,14 +265,14 @@ const _writeSettingsToDisk = async (args: {
|
|
|
263
265
|
}) => {
|
|
264
266
|
const { data: serializedSettings, error: serializeSettingsError } = tryCatch(() =>
|
|
265
267
|
// TODO: this will probably not match the original formatting
|
|
266
|
-
JSON.stringify(args.settings, undefined, 2)
|
|
268
|
+
JSON.stringify(args.settings, undefined, 2)
|
|
267
269
|
)
|
|
268
270
|
if (serializeSettingsError) {
|
|
269
271
|
throw serializeSettingsError
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
const { error: writeSettingsError } = await tryCatch(async () =>
|
|
273
|
-
args.nodeishFs.writeFile("./project.inlang.json", serializedSettings)
|
|
275
|
+
args.nodeishFs.writeFile("./project.inlang.json", serializedSettings)
|
|
274
276
|
)
|
|
275
277
|
|
|
276
278
|
if (writeSettingsError) {
|
|
@@ -292,7 +294,7 @@ const createAwaitable = () => {
|
|
|
292
294
|
return [promise, resolve!, reject!] as [
|
|
293
295
|
awaitable: Promise<void>,
|
|
294
296
|
resolve: () => void,
|
|
295
|
-
reject: (e: unknown) => void
|
|
297
|
+
reject: (e: unknown) => void
|
|
296
298
|
]
|
|
297
299
|
}
|
|
298
300
|
|
package/src/messages/errors.ts
CHANGED
|
@@ -3,7 +3,7 @@ export class MessageVariantDoesNotExistError extends Error {
|
|
|
3
3
|
|
|
4
4
|
constructor(messageId: string, languageTag: string) {
|
|
5
5
|
super(
|
|
6
|
-
`For message '${messageId}' and '${languageTag}', there doesn't exist a variant for this specific matchers
|
|
6
|
+
`For message '${messageId}' and '${languageTag}', there doesn't exist a variant for this specific matchers.`
|
|
7
7
|
)
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -12,7 +12,7 @@ export class MessageVariantAlreadyExistsError extends Error {
|
|
|
12
12
|
|
|
13
13
|
constructor(messageId: string, languageTag: string) {
|
|
14
14
|
super(
|
|
15
|
-
`For message '${messageId}' and '${languageTag}', there already exists a variant for this specific matchers
|
|
15
|
+
`For message '${messageId}' and '${languageTag}', there already exists a variant for this specific matchers.`
|
|
16
16
|
)
|
|
17
17
|
}
|
|
18
18
|
}
|