@inlang/sdk 0.17.0 → 0.19.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 +16 -15
  2. package/dist/createNodeishFsWithAbsolutePaths.d.ts +2 -2
  3. package/dist/createNodeishFsWithAbsolutePaths.d.ts.map +1 -1
  4. package/dist/createNodeishFsWithAbsolutePaths.js +5 -4
  5. package/dist/createNodeishFsWithAbsolutePaths.test.js +5 -4
  6. package/dist/createNodeishFsWithWatcher.d.ts +12 -0
  7. package/dist/createNodeishFsWithWatcher.d.ts.map +1 -0
  8. package/dist/createNodeishFsWithWatcher.js +52 -0
  9. package/dist/createNodeishFsWithWatcher.test.d.ts +2 -0
  10. package/dist/createNodeishFsWithWatcher.test.d.ts.map +1 -0
  11. package/dist/createNodeishFsWithWatcher.test.js +32 -0
  12. package/dist/isAbsolutePath.test.js +1 -1
  13. package/dist/loadProject.d.ts +4 -4
  14. package/dist/loadProject.d.ts.map +1 -1
  15. package/dist/loadProject.js +45 -24
  16. package/dist/loadProject.test.js +175 -74
  17. package/dist/migrations/migrateToDirectory.d.ts +10 -0
  18. package/dist/migrations/migrateToDirectory.d.ts.map +1 -0
  19. package/dist/migrations/migrateToDirectory.js +46 -0
  20. package/dist/migrations/migrateToDirectory.test.d.ts +2 -0
  21. package/dist/migrations/migrateToDirectory.test.d.ts.map +1 -0
  22. package/dist/migrations/migrateToDirectory.test.js +48 -0
  23. package/dist/resolve-modules/plugins/resolvePlugins.js +1 -1
  24. package/dist/resolve-modules/plugins/resolvePlugins.test.js +2 -1
  25. package/dist/resolve-modules/plugins/types.d.ts +2 -1
  26. package/dist/resolve-modules/plugins/types.d.ts.map +1 -1
  27. package/dist/resolve-modules/validateModuleSettings.test.js +1 -1
  28. package/package.json +56 -56
  29. package/src/adapter/solidAdapter.test.ts +16 -15
  30. package/src/createNodeishFsWithAbsolutePaths.test.ts +5 -4
  31. package/src/createNodeishFsWithAbsolutePaths.ts +9 -5
  32. package/src/createNodeishFsWithWatcher.test.ts +40 -0
  33. package/src/createNodeishFsWithWatcher.ts +58 -0
  34. package/src/isAbsolutePath.test.ts +1 -1
  35. package/src/loadProject.test.ts +206 -75
  36. package/src/loadProject.ts +61 -31
  37. package/src/migrations/migrateToDirectory.test.ts +54 -0
  38. package/src/migrations/migrateToDirectory.ts +59 -0
  39. package/src/resolve-modules/plugins/resolvePlugins.test.ts +2 -1
  40. package/src/resolve-modules/plugins/resolvePlugins.ts +1 -1
  41. package/src/resolve-modules/plugins/types.ts +5 -2
  42. package/src/resolve-modules/validateModuleSettings.test.ts +1 -1
@@ -1,7 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
2
  import { describe, it, expect, vi } from "vitest"
3
3
  import { loadProject } from "./loadProject.js"
4
- import type { ProjectSettings, Plugin, MessageLintRule, Message } from "./versionedInterfaces.js"
4
+ import type {
5
+ ProjectSettings,
6
+ Plugin,
7
+ MessageLintRule,
8
+ Message,
9
+ NodeishFilesystemSubset,
10
+ } from "./versionedInterfaces.js"
5
11
  import type { ImportFunction } from "./resolve-modules/index.js"
6
12
  import type { InlangModule } from "@inlang/module"
7
13
  import {
@@ -10,7 +16,7 @@ import {
10
16
  ProjectSettingsFileNotFoundError,
11
17
  ProjectSettingsInvalidError,
12
18
  } from "./errors.js"
13
- import { createNodeishMemoryFs } from "@lix-js/fs"
19
+ import { createNodeishMemoryFs, normalizePath } from "@lix-js/fs"
14
20
  import { createMessage } from "./test-utilities/createMessage.js"
15
21
  import { tryCatch } from "@inlang/result"
16
22
 
@@ -99,13 +105,52 @@ const _import: ImportFunction = async (name) =>
99
105
 
100
106
  // ------------------------------------------------------------------------------------------------
101
107
 
108
+ /**
109
+ * Dear Developers,
110
+ *
111
+ * Inlang projects (folders) are not like .vscode, .git, or .github folders. Treat em
112
+ * like files: they can be renamed and moved around.
113
+ */
114
+ it("should throw if a project (path) does not have a name", async () => {
115
+ const fs = createNodeishMemoryFs()
116
+ const project = await tryCatch(() =>
117
+ loadProject({
118
+ projectPath: "/source-code/.inlang",
119
+ nodeishFs: fs,
120
+ _import,
121
+ })
122
+ )
123
+ expect(project.error).toBeInstanceOf(LoadProjectInvalidArgument)
124
+ })
125
+
126
+ it("should throw if a project path does not end with .inlang", async () => {
127
+ const fs = createNodeishMemoryFs()
128
+
129
+ const invalidPaths = [
130
+ "/source-code/frontend.inlang/settings",
131
+ "/source-code/frontend.inlang/settings.json",
132
+ "/source-code/frontend.inlang.md",
133
+ ]
134
+
135
+ for (const invalidPath of invalidPaths) {
136
+ const project = await tryCatch(() =>
137
+ loadProject({
138
+ projectPath: invalidPath,
139
+ nodeishFs: fs,
140
+ _import,
141
+ })
142
+ )
143
+ expect(project.error).toBeInstanceOf(LoadProjectInvalidArgument)
144
+ }
145
+ })
146
+
102
147
  describe("initialization", () => {
103
- it("should throw if settingsFilePath is not an absolute path", async () => {
148
+ it("should throw if projectPath is not an absolute path", async () => {
104
149
  const fs = createNodeishMemoryFs()
105
150
 
106
151
  const result = await tryCatch(() =>
107
152
  loadProject({
108
- settingsFilePath: "relative/path",
153
+ projectPath: "relative/path",
109
154
  nodeishFs: fs,
110
155
  _import,
111
156
  })
@@ -116,12 +161,12 @@ describe("initialization", () => {
116
161
 
117
162
  it("should resolve from a windows path", async () => {
118
163
  const fs = createNodeishMemoryFs()
119
- fs.mkdir("C:\\Users\\user\\project", { recursive: true })
120
- fs.writeFile("C:\\Users\\user\\project\\project.inlang.json", JSON.stringify(settings))
164
+ fs.mkdir("C:\\Users\\user\\project.inlang", { recursive: true })
165
+ fs.writeFile("C:\\Users\\user\\project.inlang\\settings.json", JSON.stringify(settings))
121
166
 
122
167
  const result = await tryCatch(() =>
123
168
  loadProject({
124
- settingsFilePath: "C:\\Users\\user\\project\\project.inlang.json",
169
+ projectPath: "C:\\Users\\user\\project.inlang",
125
170
  nodeishFs: fs,
126
171
  _import,
127
172
  })
@@ -137,7 +182,7 @@ describe("initialization", () => {
137
182
  fs.mkdir("/user/project", { recursive: true })
138
183
 
139
184
  const project = await loadProject({
140
- settingsFilePath: "/user/project/test.json",
185
+ projectPath: "/user/non-existend-project.inlang",
141
186
  nodeishFs: fs,
142
187
  _import,
143
188
  })
@@ -147,11 +192,11 @@ describe("initialization", () => {
147
192
 
148
193
  it("should return an error if settings file is not a valid JSON", async () => {
149
194
  const fs = await createNodeishMemoryFs()
150
- await fs.mkdir("/user/project", { recursive: true })
151
- await fs.writeFile("/user/project/project.inlang.json", "invalid json")
195
+ await fs.mkdir("/user/project.inlang", { recursive: true })
196
+ await fs.writeFile("/user/project.inlang/settings.json", "invalid json")
152
197
 
153
198
  const project = await loadProject({
154
- settingsFilePath: "/user/project/project.inlang.json",
199
+ projectPath: "/user/project.inlang",
155
200
  nodeishFs: fs,
156
201
  _import,
157
202
  })
@@ -161,11 +206,11 @@ describe("initialization", () => {
161
206
 
162
207
  it("should return an error if settings file is does not match schema", async () => {
163
208
  const fs = await createNodeishMemoryFs()
164
- await fs.mkdir("/user/project", { recursive: true })
165
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify({}))
209
+ await fs.mkdir("/user/project.inlang", { recursive: true })
210
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify({}))
166
211
 
167
212
  const project = await loadProject({
168
- settingsFilePath: "/user/project/project.inlang.json",
213
+ projectPath: "/user/project.inlang",
169
214
  nodeishFs: fs,
170
215
  _import,
171
216
  })
@@ -175,10 +220,10 @@ describe("initialization", () => {
175
220
 
176
221
  it("should return the parsed settings", async () => {
177
222
  const fs = await createNodeishMemoryFs()
178
- await fs.mkdir("/user/project", { recursive: true })
179
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
223
+ await fs.mkdir("/user/project.inlang", { recursive: true })
224
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
180
225
  const project = await loadProject({
181
- settingsFilePath: "/user/project/project.inlang.json",
226
+ projectPath: "/user/project.inlang",
182
227
  nodeishFs: fs,
183
228
  _import,
184
229
  })
@@ -189,16 +234,16 @@ describe("initialization", () => {
189
234
  it("should not re-write the settings to disk when initializing", async () => {
190
235
  const fs = await createNodeishMemoryFs()
191
236
  const settingsWithDeifferentFormatting = JSON.stringify(settings, undefined, 4)
192
- await fs.mkdir("/user/project", { recursive: true })
193
- await fs.writeFile("/user/project/project.inlang.json", settingsWithDeifferentFormatting)
237
+ await fs.mkdir("/user/project.inlang", { recursive: true })
238
+ await fs.writeFile("/user/project.inlang/settings.json", settingsWithDeifferentFormatting)
194
239
 
195
240
  const project = await loadProject({
196
- settingsFilePath: "/user/project/project.inlang.json",
241
+ projectPath: "/user/project.inlang",
197
242
  nodeishFs: fs,
198
243
  _import,
199
244
  })
200
245
 
201
- const settingsOnDisk = await fs.readFile("/user/project/project.inlang.json", {
246
+ const settingsOnDisk = await fs.readFile("/user/project.inlang/settings.json", {
202
247
  encoding: "utf-8",
203
248
  })
204
249
  expect(settingsOnDisk).toBe(settingsWithDeifferentFormatting)
@@ -207,7 +252,7 @@ describe("initialization", () => {
207
252
  // TODO: how can we await `setsettings` correctly
208
253
  await new Promise((resolve) => setTimeout(resolve, 0))
209
254
 
210
- const newsettingsOnDisk = await fs.readFile("/user/project/project.inlang.json", {
255
+ const newsettingsOnDisk = await fs.readFile("/user/project.inlang/settings.json", {
211
256
  encoding: "utf-8",
212
257
  })
213
258
  expect(newsettingsOnDisk).not.toBe(settingsWithDeifferentFormatting)
@@ -222,11 +267,11 @@ describe("initialization", () => {
222
267
  } satisfies InlangModule)
223
268
 
224
269
  const fs = createNodeishMemoryFs()
225
- await fs.mkdir("/user/project", { recursive: true })
226
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
270
+ await fs.mkdir("/user/project.inlang", { recursive: true })
271
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
227
272
 
228
273
  const project = await loadProject({
229
- settingsFilePath: "/user/project/project.inlang.json",
274
+ projectPath: "/user/project.inlang",
230
275
  nodeishFs: fs,
231
276
  _import: $badImport,
232
277
  })
@@ -255,10 +300,10 @@ describe("functionality", () => {
255
300
  describe("settings", () => {
256
301
  it("should return the settings", async () => {
257
302
  const fs = await createNodeishMemoryFs()
258
- await fs.mkdir("/user/project", { recursive: true })
259
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
303
+ await fs.mkdir("/user/project.inlang", { recursive: true })
304
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
260
305
  const project = await loadProject({
261
- settingsFilePath: "/user/project/project.inlang.json",
306
+ projectPath: "/user/project.inlang",
262
307
  nodeishFs: fs,
263
308
  _import,
264
309
  })
@@ -268,10 +313,10 @@ describe("functionality", () => {
268
313
 
269
314
  it("should set a new settings", async () => {
270
315
  const fs = await createNodeishMemoryFs()
271
- await fs.mkdir("/user/project", { recursive: true })
272
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
316
+ await fs.mkdir("/user/project.inlang", { recursive: true })
317
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
273
318
  const project = await loadProject({
274
- settingsFilePath: "/user/project/project.inlang.json",
319
+ projectPath: "/user/project.inlang",
275
320
  nodeishFs: fs,
276
321
  _import,
277
322
  })
@@ -292,12 +337,12 @@ describe("functionality", () => {
292
337
  })
293
338
 
294
339
  describe("setSettings", () => {
295
- it("should fail if settings is not valid", async () => {
340
+ it("should fail if settings are not valid", async () => {
296
341
  const fs = await createNodeishMemoryFs()
297
- await fs.mkdir("/user/project", { recursive: true })
298
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
342
+ await fs.mkdir("/user/project.inlang", { recursive: true })
343
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
299
344
  const project = await loadProject({
300
- settingsFilePath: "/user/project/project.inlang.json",
345
+ projectPath: "/user/project.inlang",
301
346
  nodeishFs: fs,
302
347
  _import,
303
348
  })
@@ -309,7 +354,7 @@ describe("functionality", () => {
309
354
 
310
355
  it("should throw an error if sourceLanguageTag is not in languageTags", async () => {
311
356
  const fs = await createNodeishMemoryFs()
312
- await fs.mkdir("/user/project", { recursive: true })
357
+ await fs.mkdir("/user/project.inlang", { recursive: true })
313
358
 
314
359
  const settings: ProjectSettings = {
315
360
  sourceLanguageTag: "en",
@@ -317,10 +362,10 @@ describe("functionality", () => {
317
362
  modules: [],
318
363
  }
319
364
 
320
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
365
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
321
366
 
322
367
  const project = await loadProject({
323
- settingsFilePath: "/user/project/project.inlang.json",
368
+ projectPath: "/user/project.inlang",
324
369
  nodeishFs: fs,
325
370
  _import,
326
371
  })
@@ -331,25 +376,25 @@ describe("functionality", () => {
331
376
 
332
377
  it("should write settings to disk", async () => {
333
378
  const fs = await createNodeishMemoryFs()
334
- await fs.mkdir("/user/project", { recursive: true })
335
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
379
+ await fs.mkdir("/user/project.inlang", { recursive: true })
380
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
336
381
  const project = await loadProject({
337
- settingsFilePath: "/user/project/project.inlang.json",
382
+ projectPath: "/user/project.inlang",
338
383
  nodeishFs: fs,
339
384
  _import,
340
385
  })
341
386
 
342
- const before = await fs.readFile("/user/project/project.inlang.json", { encoding: "utf-8" })
387
+ const before = await fs.readFile("/user/project.inlang/settings.json", { encoding: "utf-8" })
343
388
  expect(before).toBeDefined()
344
389
 
345
- const result = project.setSettings({ ...settings, languageTags: ["en"] })
390
+ const result = project.setSettings({ ...settings, languageTags: ["en", "nl", "de"] })
346
391
  expect(result.data).toBeUndefined()
347
392
  expect(result.error).toBeUndefined()
348
393
 
349
394
  // TODO: how to wait for fs.writeFile to finish?
350
- await new Promise((resolve) => setTimeout(resolve, 0))
395
+ await new Promise((resolve) => setTimeout(resolve, 50))
351
396
 
352
- const after = await fs.readFile("/user/project/project.inlang.json", { encoding: "utf-8" })
397
+ const after = await fs.readFile("/user/project.inlang/settings.json", { encoding: "utf-8" })
353
398
  expect(after).toBeDefined()
354
399
  expect(after).not.toBe(before)
355
400
  })
@@ -363,10 +408,10 @@ describe("functionality", () => {
363
408
  languageTags: ["en"],
364
409
  modules: ["plugin.js", "lintRule.js"],
365
410
  }
366
- await fs.mkdir("/user/project", { recursive: true })
367
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
411
+ await fs.mkdir("/user/project.inlang", { recursive: true })
412
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
368
413
  const project = await loadProject({
369
- settingsFilePath: "/user/project/project.inlang.json",
414
+ projectPath: "/user/project.inlang",
370
415
  nodeishFs: fs,
371
416
  _import,
372
417
  })
@@ -396,11 +441,11 @@ describe("functionality", () => {
396
441
  modules: ["plugin.js", "lintRule.js"],
397
442
  }
398
443
 
399
- await fs.mkdir("/user/project", { recursive: true })
400
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
444
+ await fs.mkdir("/user/project.inlang", { recursive: true })
445
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
401
446
 
402
447
  const project = await loadProject({
403
- settingsFilePath: "/user/project/project.inlang.json",
448
+ projectPath: "/user/project.inlang",
404
449
  nodeishFs: fs,
405
450
  _import,
406
451
  })
@@ -431,9 +476,9 @@ describe("functionality", () => {
431
476
  saveMessages: () => undefined,
432
477
  }
433
478
  const fs = await createNodeishMemoryFs()
434
- await fs.mkdir("/user/project", { recursive: true })
479
+ await fs.mkdir("/user/project.inlang", { recursive: true })
435
480
  await fs.writeFile(
436
- "/user/project/project.inlang.json",
481
+ "/user/project.inlang/settings.json",
437
482
  JSON.stringify({
438
483
  sourceLanguageTag: "en",
439
484
  languageTags: ["en"],
@@ -447,7 +492,7 @@ describe("functionality", () => {
447
492
  } satisfies InlangModule
448
493
  }
449
494
  const project = await loadProject({
450
- settingsFilePath: "/user/project/project.inlang.json",
495
+ projectPath: "/user/project.inlang",
451
496
  nodeishFs: fs,
452
497
  _import,
453
498
  })
@@ -482,9 +527,9 @@ describe("functionality", () => {
482
527
  saveMessages: () => undefined,
483
528
  }
484
529
  const fs = await createNodeishMemoryFs()
485
- await fs.mkdir("/user/project", { recursive: true })
530
+ await fs.mkdir("/user/project.inlang", { recursive: true })
486
531
  await fs.writeFile(
487
- "/user/project/project.inlang.json",
532
+ "/user/project.inlang/settings.json",
488
533
  JSON.stringify({
489
534
  sourceLanguageTag: "en",
490
535
  languageTags: ["en"],
@@ -498,7 +543,7 @@ describe("functionality", () => {
498
543
  }
499
544
 
500
545
  const project = await loadProject({
501
- settingsFilePath: "/user/project/project.inlang.json",
546
+ projectPath: "/user/project.inlang",
502
547
  nodeishFs: fs,
503
548
  _import,
504
549
  })
@@ -514,10 +559,10 @@ describe("functionality", () => {
514
559
  describe("errors", () => {
515
560
  it("should return the errors", async () => {
516
561
  const fs = await createNodeishMemoryFs()
517
- await fs.mkdir("/user/project", { recursive: true })
518
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
562
+ await fs.mkdir("/user/project.inlang", { recursive: true })
563
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
519
564
  const project = await loadProject({
520
- settingsFilePath: "/user/project/project.inlang.json",
565
+ projectPath: "/user/project.inlang",
521
566
  nodeishFs: fs,
522
567
  _import,
523
568
  })
@@ -530,10 +575,10 @@ describe("functionality", () => {
530
575
  describe("customApi", () => {
531
576
  it("should return the app specific api", async () => {
532
577
  const fs = await createNodeishMemoryFs()
533
- await fs.mkdir("/user/project", { recursive: true })
534
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
578
+ await fs.mkdir("/user/project.inlang", { recursive: true })
579
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
535
580
  const project = await loadProject({
536
- settingsFilePath: "/user/project/project.inlang.json",
581
+ projectPath: "/user/project.inlang",
537
582
  nodeishFs: fs,
538
583
  _import,
539
584
  })
@@ -547,10 +592,10 @@ describe("functionality", () => {
547
592
  describe("messages", () => {
548
593
  it("should return the messages", async () => {
549
594
  const fs = await createNodeishMemoryFs()
550
- await fs.mkdir("/user/project", { recursive: true })
551
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
595
+ await fs.mkdir("/user/project.inlang", { recursive: true })
596
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
552
597
  const project = await loadProject({
553
- settingsFilePath: "/user/project/project.inlang.json",
598
+ projectPath: "/user/project.inlang",
554
599
  nodeishFs: fs,
555
600
  _import,
556
601
  })
@@ -572,8 +617,8 @@ describe("functionality", () => {
572
617
  },
573
618
  }
574
619
 
575
- await fs.mkdir("/user/project", { recursive: true })
576
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
620
+ await fs.mkdir("/user/project.inlang", { recursive: true })
621
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
577
622
 
578
623
  await fs.mkdir("./resources")
579
624
 
@@ -595,7 +640,7 @@ describe("functionality", () => {
595
640
  }
596
641
 
597
642
  const project = await loadProject({
598
- settingsFilePath: "/user/project/project.inlang.json",
643
+ projectPath: "/user/project.inlang",
599
644
  nodeishFs: fs,
600
645
  _import,
601
646
  })
@@ -750,7 +795,8 @@ describe("functionality", () => {
750
795
  },
751
796
  }
752
797
 
753
- await fs.writeFile("./project.inlang.json", JSON.stringify(settings))
798
+ await fs.mkdir("./project.inlang", { recursive: true })
799
+ await fs.writeFile("./project.inlang/settings.json", JSON.stringify(settings))
754
800
 
755
801
  const mockSaveFn = vi.fn()
756
802
 
@@ -774,7 +820,7 @@ describe("functionality", () => {
774
820
  }
775
821
 
776
822
  const project = await loadProject({
777
- settingsFilePath: "/project.inlang.json",
823
+ projectPath: "/project.inlang",
778
824
  nodeishFs: fs,
779
825
  _import,
780
826
  })
@@ -794,7 +840,7 @@ describe("functionality", () => {
794
840
  await fs.mkdir("/user/project", { recursive: true })
795
841
  await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
796
842
  const project = await loadProject({
797
- settingsFilePath: "/user/project/project.inlang.json",
843
+ projectPath: "/user/project/project.inlang.json",
798
844
  nodeishFs: fs,
799
845
  _import,
800
846
  })
@@ -813,10 +859,10 @@ describe("functionality", () => {
813
859
  modules: ["lintRule.js"],
814
860
  }
815
861
  const fs = createNodeishMemoryFs()
816
- await fs.mkdir("/user/project", { recursive: true })
817
- await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings))
862
+ await fs.mkdir("/user/project.inlang", { recursive: true })
863
+ await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings))
818
864
  const project = await loadProject({
819
- settingsFilePath: "/user/project/project.inlang.json",
865
+ projectPath: "/user/project.inlang",
820
866
  nodeishFs: fs,
821
867
  _import: async () => ({
822
868
  default: mockMessageLintRule,
@@ -826,4 +872,89 @@ describe("functionality", () => {
826
872
  project.query.messageLintReports.getAll.subscribe((r) => expect(r).toEqual([]))
827
873
  })
828
874
  })
875
+
876
+ describe("watcher", () => {
877
+ it("changing files in resources should trigger callback of message query", async () => {
878
+ const fs = createNodeishMemoryFs()
879
+
880
+ const messages = {
881
+ $schema: "https://inlang.com/schema/inlang-message-format",
882
+ data: [
883
+ {
884
+ id: "test",
885
+ selectors: [],
886
+ variants: [
887
+ {
888
+ match: [],
889
+ languageTag: "en",
890
+ pattern: [
891
+ {
892
+ type: "Text",
893
+ value: "test",
894
+ },
895
+ ],
896
+ },
897
+ ],
898
+ },
899
+ ],
900
+ }
901
+
902
+ await fs.writeFile("./messages.json", JSON.stringify(messages))
903
+
904
+ const getMessages = async (customFs: NodeishFilesystemSubset) => {
905
+ const file = await customFs.readFile("./messages.json", { encoding: "utf-8" })
906
+ return JSON.parse(file.toString()).data
907
+ }
908
+
909
+ const mockMessageFormatPlugin: Plugin = {
910
+ id: "plugin.inlang.messageFormat",
911
+ description: { en: "Mock plugin description" },
912
+ displayName: { en: "Mock Plugin" },
913
+
914
+ loadMessages: async (args) => await getMessages(args.nodeishFs),
915
+ saveMessages: () => undefined as any,
916
+ }
917
+
918
+ const settings: ProjectSettings = {
919
+ sourceLanguageTag: "en",
920
+ languageTags: ["en"],
921
+ modules: ["plugin.js"],
922
+ "plugin.inlang.messageFormat": {
923
+ filePath: "./messages.json",
924
+ },
925
+ }
926
+
927
+ await fs.mkdir("./project.inlang", { recursive: true })
928
+ await fs.writeFile("./project.inlang/settings.json", JSON.stringify(settings))
929
+
930
+ // establish watcher
931
+ const project = await loadProject({
932
+ projectPath: normalizePath("/project.inlang"),
933
+ nodeishFs: fs,
934
+ _import: async () => ({
935
+ default: mockMessageFormatPlugin,
936
+ }),
937
+ })
938
+
939
+ let counter = 0
940
+
941
+ project.query.messages.getAll.subscribe(() => {
942
+ counter = counter + 1
943
+ })
944
+
945
+ expect(counter).toBe(1)
946
+
947
+ // change file
948
+ await fs.writeFile("./messages.json", JSON.stringify(messages))
949
+ await new Promise((resolve) => setTimeout(resolve, 0))
950
+
951
+ expect(counter).toBe(2)
952
+
953
+ // change file
954
+ await fs.writeFile("./messages.json", JSON.stringify(messages))
955
+ await new Promise((resolve) => setTimeout(resolve, 0))
956
+
957
+ expect(counter).toBe(3)
958
+ })
959
+ })
829
960
  })