@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.
Files changed (42) hide show
  1. package/dist/adapter/solidAdapter.test.js +6 -6
  2. package/dist/createMessagesQuery.test.js +9 -0
  3. package/dist/loadProject.d.ts.map +1 -1
  4. package/dist/loadProject.js +8 -4
  5. package/dist/loadProject.test.js +14 -15
  6. package/dist/messages/variant.d.ts +4 -4
  7. package/dist/messages/variant.d.ts.map +1 -1
  8. package/dist/messages/variant.js +55 -55
  9. package/dist/messages/variant.test.js +102 -45
  10. package/dist/resolve-modules/plugins/resolvePlugins.d.ts.map +1 -1
  11. package/dist/resolve-modules/plugins/resolvePlugins.js +3 -5
  12. package/dist/resolve-modules/plugins/resolvePlugins.test.js +79 -49
  13. package/dist/resolve-modules/plugins/types.d.ts +4 -5
  14. package/dist/resolve-modules/plugins/types.d.ts.map +1 -1
  15. package/dist/test-utilities/createMessage.d.ts +1 -1
  16. package/dist/test-utilities/createMessage.js +1 -1
  17. package/dist/test-utilities/createMessage.test.js +4 -4
  18. package/package.json +1 -1
  19. package/src/adapter/solidAdapter.test.ts +14 -14
  20. package/src/adapter/solidAdapter.ts +1 -1
  21. package/src/api.ts +2 -2
  22. package/src/createMessageLintReportsQuery.ts +4 -4
  23. package/src/createMessagesQuery.test.ts +30 -17
  24. package/src/createMessagesQuery.ts +2 -2
  25. package/src/lint/message/lintMessages.ts +1 -1
  26. package/src/lint/message/lintSingleMessage.test.ts +1 -1
  27. package/src/lint/message/lintSingleMessage.ts +2 -2
  28. package/src/loadProject.test.ts +24 -27
  29. package/src/loadProject.ts +20 -16
  30. package/src/messages/errors.ts +2 -2
  31. package/src/messages/variant.test.ts +113 -49
  32. package/src/messages/variant.ts +73 -67
  33. package/src/parseConfig.ts +2 -2
  34. package/src/resolve-modules/import.test.ts +2 -2
  35. package/src/resolve-modules/import.ts +1 -1
  36. package/src/resolve-modules/message-lint-rules/resolveMessageLintRules.ts +1 -1
  37. package/src/resolve-modules/plugins/resolvePlugins.test.ts +96 -64
  38. package/src/resolve-modules/plugins/resolvePlugins.ts +19 -21
  39. package/src/resolve-modules/plugins/types.ts +4 -8
  40. package/src/resolve-modules/resolveModules.ts +4 -4
  41. package/src/test-utilities/createMessage.test.ts +7 -7
  42. package/src/test-utilities/createMessage.ts +1 -1
@@ -14,18 +14,18 @@ import {
14
14
  * (if it exists).
15
15
  *
16
16
  * @example
17
- * const variant = getVariant(message, { where: { languageTag: "en", selectors: { gender: "male" }}});
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
- selectors?: Variant["match"]
24
+ match?: Variant["match"]
25
25
  }
26
- },
26
+ }
27
27
  ): Variant | undefined {
28
- const variant = matchMostSpecificVariant(message, args.where.languageTag, args.where.selectors)
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: resolveSelector(copy.selectors, args.data.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", selectors: { gender: "male" }, pattern: []})
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
- selectors: Record<string, string>
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.selectors)
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", selectors: { gender: "male" })
110
+ * const variant = matchVariant(message, languageTag: "en", match: ["male"])
112
111
  */
113
112
  const matchVariant = (
114
113
  message: Message,
115
114
  languageTag: LanguageTag,
116
- selectors: Record<string, string>,
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
- for (const [key, value] of Object.entries(variant.match)) {
128
- if (resolvedSelectors[key] !== value) {
129
- isMatch = false
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
- selectors?: Record<string, string>,
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
- for (const [key, value] of Object.entries(variant.match)) {
164
- if (resolvedSelectors[key] !== value && value !== "*") {
165
- isMatch = false
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 && selectors) {
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
- currentKeys: Message["selectors"],
174
- variant: Variant,
178
+ selectorIndex: number,
179
+ selectorLength: number,
180
+ variant: Variant
175
181
  ) {
176
- if (currentKeys[0]?.name) {
177
- const key = variant.match[currentKeys[0].name]
178
- if (key) {
179
- if (currentKeys.length === 1) {
180
- currentIndex[key] = variant
181
- } else {
182
- if (!currentIndex[key]) {
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 && !selectors) {
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, Object.values(resolvedSelectors))
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
  }
@@ -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({
@@ -35,7 +35,7 @@ async function $import(
35
35
  * Required to import from a local path.
36
36
  */
37
37
  readFile: NodeishFilesystemSubset["readFile"]
38
- },
38
+ }
39
39
  ): Promise<any> {
40
40
  let moduleAsText: string
41
41
 
@@ -12,7 +12,7 @@ export const resolveMessageLintRules = (args: { messageLintRules: Array<MessageL
12
12
  result.errors.push(
13
13
  new MessageLintRuleIsInvalidError(`Couldn't parse lint rule "${rule.id}"`, {
14
14
  module: "not implemented",
15
- }),
15
+ })
16
16
  )
17
17
  continue
18
18
  } else {
@@ -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
- describe("generally", () => {
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: {},
29
- nodeishFs: {} as any,
30
- })
32
+ expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidIdError)
33
+ })
31
34
 
32
- expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidIdError)
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
- 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: {},
51
- nodeishFs: {} as any,
52
- })
54
+ expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidSchemaError)
55
+ })
53
56
 
54
- expect(resolved.errors[0]).toBeInstanceOf(PluginHasInvalidSchemaError)
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
- 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: {},
68
- nodeishFs: {} as any,
69
- })
71
+ expect(resolved.errors[0]).toBeInstanceOf(PluginUsesReservedNamespaceError)
72
+ })
70
73
 
71
- expect(resolved.errors[0]).toBeInstanceOf(PluginUsesReservedNamespaceError)
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
- languageTags: ["en"],
93
- sourceLanguageTag: "en",
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 kebap-case and contain a namespace like project.my-plugin.`,
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?.[plugin.id] ?? {},
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?.[plugin.id] ?? {},
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