@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
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
|
}
|
|
@@ -12,7 +12,7 @@ describe("$import", async () => {
|
|
|
12
12
|
export function hello() {
|
|
13
13
|
return "hello";
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
`
|
|
16
16
|
)
|
|
17
17
|
|
|
18
18
|
// mock module in a directory
|
|
@@ -23,7 +23,7 @@ describe("$import", async () => {
|
|
|
23
23
|
export function hello() {
|
|
24
24
|
return "world";
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
`
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
const _import = createImport({
|
|
@@ -11,65 +11,98 @@ import {
|
|
|
11
11
|
PluginsDoNotProvideLoadOrSaveMessagesError,
|
|
12
12
|
} from "./errors.js"
|
|
13
13
|
import type { Plugin } from "@inlang/plugin"
|
|
14
|
+
import type { ProjectSettings } from "@inlang/project-settings"
|
|
15
|
+
|
|
16
|
+
it("should return an error if a plugin uses an invalid id", async () => {
|
|
17
|
+
const mockPlugin: Plugin = {
|
|
18
|
+
// @ts-expect-error - invalid id
|
|
19
|
+
id: "no-namespace",
|
|
20
|
+
description: { en: "My plugin description" },
|
|
21
|
+
displayName: { en: "My plugin" },
|
|
22
|
+
loadMessages: () => undefined as any,
|
|
23
|
+
saveMessages: () => undefined as any,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const resolved = await resolvePlugins({
|
|
27
|
+
plugins: [mockPlugin],
|
|
28
|
+
settings: {} as any as any,
|
|
29
|
+
nodeishFs: {} as any,
|
|
30
|
+
})
|
|
14
31
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const mockPlugin: Plugin = {
|
|
18
|
-
// @ts-expect-error - invalid id
|
|
19
|
-
id: "no-namespace",
|
|
20
|
-
description: { en: "My plugin description" },
|
|
21
|
-
displayName: { en: "My plugin" },
|
|
22
|
-
loadMessages: () => undefined as any,
|
|
23
|
-
saveMessages: () => undefined as any,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const resolved = await resolvePlugins({
|
|
27
|
-
plugins: [mockPlugin],
|
|
28
|
-
settings: {},
|
|
29
|
-
nodeishFs: {} as any,
|
|
30
|
-
})
|
|
32
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidIdError)
|
|
33
|
+
})
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
it("should return an error if a plugin uses APIs that are not available", async () => {
|
|
36
|
+
const mockPlugin: Plugin = {
|
|
37
|
+
id: "plugin.namespace.undefinedApi",
|
|
38
|
+
description: { en: "My plugin description" },
|
|
39
|
+
displayName: { en: "My plugin" },
|
|
40
|
+
// @ts-expect-error the key is not available in type
|
|
41
|
+
nonExistentKey: {
|
|
42
|
+
nonexistentOptions: "value",
|
|
43
|
+
},
|
|
44
|
+
loadMessages: () => undefined as any,
|
|
45
|
+
saveMessages: () => undefined as any,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const resolved = await resolvePlugins({
|
|
49
|
+
plugins: [mockPlugin],
|
|
50
|
+
settings: {} as any,
|
|
51
|
+
nodeishFs: {} as any,
|
|
33
52
|
})
|
|
34
53
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
id: "plugin.namespace.undefinedApi",
|
|
38
|
-
description: { en: "My plugin description" },
|
|
39
|
-
displayName: { en: "My plugin" },
|
|
40
|
-
// @ts-expect-error the key is not available in type
|
|
41
|
-
nonExistentKey: {
|
|
42
|
-
nonexistentOptions: "value",
|
|
43
|
-
},
|
|
44
|
-
loadMessages: () => undefined as any,
|
|
45
|
-
saveMessages: () => undefined as any,
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const resolved = await resolvePlugins({
|
|
49
|
-
plugins: [mockPlugin],
|
|
50
|
-
settings: {},
|
|
51
|
-
nodeishFs: {} as any,
|
|
52
|
-
})
|
|
54
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidSchemaError)
|
|
55
|
+
})
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
it("should not initialize a plugin that uses the 'inlang' namespace except for inlang whitelisted plugins", async () => {
|
|
58
|
+
const mockPlugin: Plugin = {
|
|
59
|
+
id: "plugin.inlang.notWhitelisted",
|
|
60
|
+
description: { en: "My plugin description" },
|
|
61
|
+
displayName: { en: "My plugin" },
|
|
62
|
+
loadMessages: () => undefined as any,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const resolved = await resolvePlugins({
|
|
66
|
+
plugins: [mockPlugin],
|
|
67
|
+
settings: {} as any,
|
|
68
|
+
nodeishFs: {} as any,
|
|
55
69
|
})
|
|
56
70
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
id: "plugin.inlang.notWhitelisted",
|
|
60
|
-
description: { en: "My plugin description" },
|
|
61
|
-
displayName: { en: "My plugin" },
|
|
62
|
-
loadMessages: () => undefined as any,
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const resolved = await resolvePlugins({
|
|
66
|
-
plugins: [mockPlugin],
|
|
67
|
-
settings: {},
|
|
68
|
-
nodeishFs: {} as any,
|
|
69
|
-
})
|
|
71
|
+
expect(resolved.errors[0]).toBeInstanceOf(PluginUsesReservedNamespaceError)
|
|
72
|
+
})
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
it("should expose the project settings including the plugin settings", async () => {
|
|
75
|
+
const settings: ProjectSettings = {
|
|
76
|
+
sourceLanguageTag: "en",
|
|
77
|
+
languageTags: ["en", "de"],
|
|
78
|
+
modules: [],
|
|
79
|
+
"plugin.namespace.placeholder": {
|
|
80
|
+
myPluginSetting: "value",
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
const mockPlugin: Plugin = {
|
|
84
|
+
id: "plugin.namespace.placeholder",
|
|
85
|
+
description: { en: "My plugin description" },
|
|
86
|
+
displayName: { en: "My plugin" },
|
|
87
|
+
saveMessages: async ({ settings }) => {
|
|
88
|
+
expect(settings).toStrictEqual(settings)
|
|
89
|
+
},
|
|
90
|
+
addCustomApi: ({ settings }) => {
|
|
91
|
+
expect(settings).toStrictEqual(settings)
|
|
92
|
+
return {}
|
|
93
|
+
},
|
|
94
|
+
loadMessages: async ({ settings }) => {
|
|
95
|
+
expect(settings).toStrictEqual(settings)
|
|
96
|
+
return []
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
const resolved = await resolvePlugins({
|
|
100
|
+
plugins: [mockPlugin],
|
|
101
|
+
settings: settings,
|
|
102
|
+
nodeishFs: {} as any,
|
|
72
103
|
})
|
|
104
|
+
await resolved.data.loadMessages!({ settings })
|
|
105
|
+
await resolved.data.saveMessages!({ settings, messages: [] })
|
|
73
106
|
})
|
|
74
107
|
|
|
75
108
|
describe("loadMessages", () => {
|
|
@@ -83,15 +116,14 @@ describe("loadMessages", () => {
|
|
|
83
116
|
|
|
84
117
|
const resolved = await resolvePlugins({
|
|
85
118
|
plugins: [mockPlugin],
|
|
86
|
-
settings: {},
|
|
119
|
+
settings: {} as any,
|
|
87
120
|
nodeishFs: {} as any,
|
|
88
121
|
})
|
|
89
122
|
|
|
90
123
|
expect(
|
|
91
124
|
await resolved.data.loadMessages!({
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}),
|
|
125
|
+
settings: {} as any,
|
|
126
|
+
})
|
|
95
127
|
).toEqual([{ id: "test", expressions: [], selectors: [], variants: [] }])
|
|
96
128
|
})
|
|
97
129
|
|
|
@@ -112,7 +144,7 @@ describe("loadMessages", () => {
|
|
|
112
144
|
const resolved = await resolvePlugins({
|
|
113
145
|
plugins: [mockPlugin, mockPlugin2],
|
|
114
146
|
nodeishFs: {} as any,
|
|
115
|
-
settings: {},
|
|
147
|
+
settings: {} as any,
|
|
116
148
|
})
|
|
117
149
|
|
|
118
150
|
expect(resolved.errors[0]).toBeInstanceOf(PluginLoadMessagesFunctionAlreadyDefinedError)
|
|
@@ -129,7 +161,7 @@ describe("loadMessages", () => {
|
|
|
129
161
|
const resolved = await resolvePlugins({
|
|
130
162
|
plugins: [mockPlugin],
|
|
131
163
|
nodeishFs: {} as any,
|
|
132
|
-
settings: {},
|
|
164
|
+
settings: {} as any,
|
|
133
165
|
})
|
|
134
166
|
|
|
135
167
|
expect(resolved.errors).toHaveLength(1)
|
|
@@ -150,7 +182,7 @@ describe("saveMessages", () => {
|
|
|
150
182
|
const resolved = await resolvePlugins({
|
|
151
183
|
plugins: [mockPlugin],
|
|
152
184
|
nodeishFs: {} as any,
|
|
153
|
-
settings: {},
|
|
185
|
+
settings: {} as any,
|
|
154
186
|
})
|
|
155
187
|
|
|
156
188
|
expect(resolved.errors).toHaveLength(0)
|
|
@@ -173,7 +205,7 @@ describe("saveMessages", () => {
|
|
|
173
205
|
|
|
174
206
|
const resolved = await resolvePlugins({
|
|
175
207
|
plugins: [mockPlugin, mockPlugin2],
|
|
176
|
-
settings: {},
|
|
208
|
+
settings: {} as any,
|
|
177
209
|
nodeishFs: {} as any,
|
|
178
210
|
})
|
|
179
211
|
|
|
@@ -191,7 +223,7 @@ describe("saveMessages", () => {
|
|
|
191
223
|
const resolved = await resolvePlugins({
|
|
192
224
|
plugins: [mockPlugin],
|
|
193
225
|
nodeishFs: {} as any,
|
|
194
|
-
settings: {},
|
|
226
|
+
settings: {} as any,
|
|
195
227
|
})
|
|
196
228
|
expect(resolved.errors).toHaveLength(1)
|
|
197
229
|
expect(resolved.errors[0]).toBeInstanceOf(PluginsDoNotProvideLoadOrSaveMessagesError)
|
|
@@ -214,7 +246,7 @@ describe("addCustomApi", () => {
|
|
|
214
246
|
|
|
215
247
|
const resolved = await resolvePlugins({
|
|
216
248
|
plugins: [mockPlugin],
|
|
217
|
-
settings: {},
|
|
249
|
+
settings: {} as any,
|
|
218
250
|
nodeishFs: {} as any,
|
|
219
251
|
})
|
|
220
252
|
|
|
@@ -249,7 +281,7 @@ describe("addCustomApi", () => {
|
|
|
249
281
|
|
|
250
282
|
const resolved = await resolvePlugins({
|
|
251
283
|
plugins: [mockPlugin, mockPlugin2],
|
|
252
|
-
settings: {},
|
|
284
|
+
settings: {} as any,
|
|
253
285
|
nodeishFs: {} as any,
|
|
254
286
|
})
|
|
255
287
|
|
|
@@ -269,7 +301,7 @@ describe("addCustomApi", () => {
|
|
|
269
301
|
|
|
270
302
|
const resolved = await resolvePlugins({
|
|
271
303
|
plugins: [mockPlugin],
|
|
272
|
-
settings: {},
|
|
304
|
+
settings: {} as any,
|
|
273
305
|
nodeishFs: {} as any,
|
|
274
306
|
})
|
|
275
307
|
|
|
@@ -292,13 +324,13 @@ describe("addCustomApi", () => {
|
|
|
292
324
|
|
|
293
325
|
const resolved = await resolvePlugins({
|
|
294
326
|
plugins: [mockPlugin],
|
|
295
|
-
settings: {},
|
|
327
|
+
settings: {} as any,
|
|
296
328
|
nodeishFs: {} as any,
|
|
297
329
|
})
|
|
298
330
|
|
|
299
331
|
expect(resolved.data.customApi).toHaveProperty("app.inlang.placeholder")
|
|
300
332
|
expect(
|
|
301
|
-
(resolved.data.customApi?.["app.inlang.placeholder"] as any).messageReferenceMatcher()
|
|
333
|
+
(resolved.data.customApi?.["app.inlang.placeholder"] as any).messageReferenceMatcher()
|
|
302
334
|
).toEqual({
|
|
303
335
|
hello: "world",
|
|
304
336
|
})
|
|
@@ -44,9 +44,9 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
44
44
|
if (hasInvalidId) {
|
|
45
45
|
result.errors.push(
|
|
46
46
|
new PluginHasInvalidIdError(
|
|
47
|
-
`Plugin ${plugin.id} has an invalid id "${plugin.id}". It must be
|
|
48
|
-
{ plugin: plugin.id }
|
|
49
|
-
)
|
|
47
|
+
`Plugin ${plugin.id} has an invalid id "${plugin.id}". It must be camelCase and contain a namespace like plugin.namespace.myPlugin.`,
|
|
48
|
+
{ plugin: plugin.id }
|
|
49
|
+
)
|
|
50
50
|
)
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -57,8 +57,8 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
57
57
|
`Plugin ${plugin.id} uses reserved namespace 'inlang'.`,
|
|
58
58
|
{
|
|
59
59
|
plugin: plugin.id,
|
|
60
|
-
}
|
|
61
|
-
)
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
62
|
)
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -70,8 +70,8 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
70
70
|
{
|
|
71
71
|
plugin: plugin.id,
|
|
72
72
|
cause: errors,
|
|
73
|
-
}
|
|
74
|
-
)
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
75
|
)
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -80,8 +80,8 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
80
80
|
result.errors.push(
|
|
81
81
|
new PluginLoadMessagesFunctionAlreadyDefinedError(
|
|
82
82
|
`Plugin ${plugin.id} defines the loadMessages function, but it was already defined by another plugin.`,
|
|
83
|
-
{ plugin: plugin.id }
|
|
84
|
-
)
|
|
83
|
+
{ plugin: plugin.id }
|
|
84
|
+
)
|
|
85
85
|
)
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -89,8 +89,8 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
89
89
|
result.errors.push(
|
|
90
90
|
new PluginSaveMessagesFunctionAlreadyDefinedError(
|
|
91
91
|
`Plugin ${plugin.id} defines the saveMessages function, but it was already defined by another plugin.`,
|
|
92
|
-
{ plugin: plugin.id }
|
|
93
|
-
)
|
|
92
|
+
{ plugin: plugin.id }
|
|
93
|
+
)
|
|
94
94
|
)
|
|
95
95
|
}
|
|
96
96
|
|
|
@@ -99,8 +99,8 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
99
99
|
// TODO: why do we call this function 2 times (here for validation and later for retrieving the actual value)?
|
|
100
100
|
const { data: customApi, error } = tryCatch(() =>
|
|
101
101
|
plugin.addCustomApi!({
|
|
102
|
-
settings: args.settings
|
|
103
|
-
})
|
|
102
|
+
settings: args.settings,
|
|
103
|
+
})
|
|
104
104
|
)
|
|
105
105
|
if (error) {
|
|
106
106
|
// @ts-ignore
|
|
@@ -111,8 +111,8 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
111
111
|
result.errors.push(
|
|
112
112
|
new PluginReturnedInvalidCustomApiError(
|
|
113
113
|
`Plugin ${plugin.id} defines the addCustomApi function, but it does not return an object.`,
|
|
114
|
-
{ plugin: plugin.id, cause: error }
|
|
115
|
-
)
|
|
114
|
+
{ plugin: plugin.id, cause: error }
|
|
115
|
+
)
|
|
116
116
|
)
|
|
117
117
|
}
|
|
118
118
|
}
|
|
@@ -130,7 +130,6 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
130
130
|
result.data.loadMessages = (_args) =>
|
|
131
131
|
plugin.loadMessages!({
|
|
132
132
|
..._args,
|
|
133
|
-
settings: args.settings?.[plugin.id] ?? {},
|
|
134
133
|
nodeishFs: args.nodeishFs,
|
|
135
134
|
})
|
|
136
135
|
}
|
|
@@ -139,7 +138,6 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
139
138
|
result.data.saveMessages = (_args) =>
|
|
140
139
|
plugin.saveMessages!({
|
|
141
140
|
..._args,
|
|
142
|
-
settings: args.settings?.[plugin.id] ?? {},
|
|
143
141
|
nodeishFs: args.nodeishFs,
|
|
144
142
|
})
|
|
145
143
|
}
|
|
@@ -147,8 +145,8 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
147
145
|
if (typeof plugin.addCustomApi === "function") {
|
|
148
146
|
const { data: customApi } = tryCatch(() =>
|
|
149
147
|
plugin.addCustomApi!({
|
|
150
|
-
settings: args.settings
|
|
151
|
-
})
|
|
148
|
+
settings: args.settings,
|
|
149
|
+
})
|
|
152
150
|
)
|
|
153
151
|
if (customApi) {
|
|
154
152
|
result.data.customApi = deepmerge(result.data.customApi, customApi)
|
|
@@ -164,8 +162,8 @@ export const resolvePlugins: ResolvePluginsFunction = async (args) => {
|
|
|
164
162
|
result.errors.push(
|
|
165
163
|
new PluginsDoNotProvideLoadOrSaveMessagesError(
|
|
166
164
|
"It seems you did not install any plugin that handles messages. Please add one to make inlang work. See https://inlang.com/documentation/plugins/registry.",
|
|
167
|
-
{ plugin: undefined }
|
|
168
|
-
)
|
|
165
|
+
{ plugin: undefined }
|
|
166
|
+
)
|
|
169
167
|
)
|
|
170
168
|
}
|
|
171
169
|
|