@inlang/sdk 0.18.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.
- package/dist/adapter/solidAdapter.test.js +16 -15
- package/dist/createNodeishFsWithAbsolutePaths.d.ts +2 -2
- package/dist/createNodeishFsWithAbsolutePaths.d.ts.map +1 -1
- package/dist/createNodeishFsWithAbsolutePaths.js +4 -4
- package/dist/createNodeishFsWithAbsolutePaths.test.js +4 -4
- package/dist/createNodeishFsWithWatcher.d.ts +1 -1
- package/dist/createNodeishFsWithWatcher.d.ts.map +1 -1
- package/dist/createNodeishFsWithWatcher.js +6 -4
- package/dist/isAbsolutePath.test.js +1 -1
- package/dist/loadProject.d.ts +4 -4
- package/dist/loadProject.d.ts.map +1 -1
- package/dist/loadProject.js +23 -17
- package/dist/loadProject.test.js +108 -75
- package/dist/migrations/migrateToDirectory.d.ts +10 -0
- package/dist/migrations/migrateToDirectory.d.ts.map +1 -0
- package/dist/migrations/migrateToDirectory.js +46 -0
- package/dist/migrations/migrateToDirectory.test.d.ts +2 -0
- package/dist/migrations/migrateToDirectory.test.d.ts.map +1 -0
- package/dist/migrations/migrateToDirectory.test.js +48 -0
- package/dist/resolve-modules/validateModuleSettings.test.js +1 -1
- package/package.json +56 -56
- package/src/adapter/solidAdapter.test.ts +16 -15
- package/src/createNodeishFsWithAbsolutePaths.test.ts +4 -4
- package/src/createNodeishFsWithAbsolutePaths.ts +5 -5
- package/src/createNodeishFsWithWatcher.ts +6 -4
- package/src/isAbsolutePath.test.ts +1 -1
- package/src/loadProject.test.ts +116 -75
- package/src/loadProject.ts +36 -22
- package/src/migrations/migrateToDirectory.test.ts +54 -0
- package/src/migrations/migrateToDirectory.ts +59 -0
- package/src/resolve-modules/validateModuleSettings.test.ts +1 -1
package/dist/loadProject.test.js
CHANGED
|
@@ -80,11 +80,42 @@ const _import = async (name) => ({
|
|
|
80
80
|
default: name === "plugin.js" ? mockPlugin : mockMessageLintRule,
|
|
81
81
|
});
|
|
82
82
|
// ------------------------------------------------------------------------------------------------
|
|
83
|
+
/**
|
|
84
|
+
* Dear Developers,
|
|
85
|
+
*
|
|
86
|
+
* Inlang projects (folders) are not like .vscode, .git, or .github folders. Treat em
|
|
87
|
+
* like files: they can be renamed and moved around.
|
|
88
|
+
*/
|
|
89
|
+
it("should throw if a project (path) does not have a name", async () => {
|
|
90
|
+
const fs = createNodeishMemoryFs();
|
|
91
|
+
const project = await tryCatch(() => loadProject({
|
|
92
|
+
projectPath: "/source-code/.inlang",
|
|
93
|
+
nodeishFs: fs,
|
|
94
|
+
_import,
|
|
95
|
+
}));
|
|
96
|
+
expect(project.error).toBeInstanceOf(LoadProjectInvalidArgument);
|
|
97
|
+
});
|
|
98
|
+
it("should throw if a project path does not end with .inlang", async () => {
|
|
99
|
+
const fs = createNodeishMemoryFs();
|
|
100
|
+
const invalidPaths = [
|
|
101
|
+
"/source-code/frontend.inlang/settings",
|
|
102
|
+
"/source-code/frontend.inlang/settings.json",
|
|
103
|
+
"/source-code/frontend.inlang.md",
|
|
104
|
+
];
|
|
105
|
+
for (const invalidPath of invalidPaths) {
|
|
106
|
+
const project = await tryCatch(() => loadProject({
|
|
107
|
+
projectPath: invalidPath,
|
|
108
|
+
nodeishFs: fs,
|
|
109
|
+
_import,
|
|
110
|
+
}));
|
|
111
|
+
expect(project.error).toBeInstanceOf(LoadProjectInvalidArgument);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
83
114
|
describe("initialization", () => {
|
|
84
|
-
it("should throw if
|
|
115
|
+
it("should throw if projectPath is not an absolute path", async () => {
|
|
85
116
|
const fs = createNodeishMemoryFs();
|
|
86
117
|
const result = await tryCatch(() => loadProject({
|
|
87
|
-
|
|
118
|
+
projectPath: "relative/path",
|
|
88
119
|
nodeishFs: fs,
|
|
89
120
|
_import,
|
|
90
121
|
}));
|
|
@@ -93,10 +124,10 @@ describe("initialization", () => {
|
|
|
93
124
|
});
|
|
94
125
|
it("should resolve from a windows path", async () => {
|
|
95
126
|
const fs = createNodeishMemoryFs();
|
|
96
|
-
fs.mkdir("C:\\Users\\user\\project", { recursive: true });
|
|
97
|
-
fs.writeFile("C:\\Users\\user\\project
|
|
127
|
+
fs.mkdir("C:\\Users\\user\\project.inlang", { recursive: true });
|
|
128
|
+
fs.writeFile("C:\\Users\\user\\project.inlang\\settings.json", JSON.stringify(settings));
|
|
98
129
|
const result = await tryCatch(() => loadProject({
|
|
99
|
-
|
|
130
|
+
projectPath: "C:\\Users\\user\\project.inlang",
|
|
100
131
|
nodeishFs: fs,
|
|
101
132
|
_import,
|
|
102
133
|
}));
|
|
@@ -108,7 +139,7 @@ describe("initialization", () => {
|
|
|
108
139
|
const fs = createNodeishMemoryFs();
|
|
109
140
|
fs.mkdir("/user/project", { recursive: true });
|
|
110
141
|
const project = await loadProject({
|
|
111
|
-
|
|
142
|
+
projectPath: "/user/non-existend-project.inlang",
|
|
112
143
|
nodeishFs: fs,
|
|
113
144
|
_import,
|
|
114
145
|
});
|
|
@@ -116,10 +147,10 @@ describe("initialization", () => {
|
|
|
116
147
|
});
|
|
117
148
|
it("should return an error if settings file is not a valid JSON", async () => {
|
|
118
149
|
const fs = await createNodeishMemoryFs();
|
|
119
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
120
|
-
await fs.writeFile("/user/project
|
|
150
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
151
|
+
await fs.writeFile("/user/project.inlang/settings.json", "invalid json");
|
|
121
152
|
const project = await loadProject({
|
|
122
|
-
|
|
153
|
+
projectPath: "/user/project.inlang",
|
|
123
154
|
nodeishFs: fs,
|
|
124
155
|
_import,
|
|
125
156
|
});
|
|
@@ -127,10 +158,10 @@ describe("initialization", () => {
|
|
|
127
158
|
});
|
|
128
159
|
it("should return an error if settings file is does not match schema", async () => {
|
|
129
160
|
const fs = await createNodeishMemoryFs();
|
|
130
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
131
|
-
await fs.writeFile("/user/project
|
|
161
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
162
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify({}));
|
|
132
163
|
const project = await loadProject({
|
|
133
|
-
|
|
164
|
+
projectPath: "/user/project.inlang",
|
|
134
165
|
nodeishFs: fs,
|
|
135
166
|
_import,
|
|
136
167
|
});
|
|
@@ -138,10 +169,10 @@ describe("initialization", () => {
|
|
|
138
169
|
});
|
|
139
170
|
it("should return the parsed settings", async () => {
|
|
140
171
|
const fs = await createNodeishMemoryFs();
|
|
141
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
142
|
-
await fs.writeFile("/user/project
|
|
172
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
173
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
143
174
|
const project = await loadProject({
|
|
144
|
-
|
|
175
|
+
projectPath: "/user/project.inlang",
|
|
145
176
|
nodeishFs: fs,
|
|
146
177
|
_import,
|
|
147
178
|
});
|
|
@@ -150,21 +181,21 @@ describe("initialization", () => {
|
|
|
150
181
|
it("should not re-write the settings to disk when initializing", async () => {
|
|
151
182
|
const fs = await createNodeishMemoryFs();
|
|
152
183
|
const settingsWithDeifferentFormatting = JSON.stringify(settings, undefined, 4);
|
|
153
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
154
|
-
await fs.writeFile("/user/project
|
|
184
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
185
|
+
await fs.writeFile("/user/project.inlang/settings.json", settingsWithDeifferentFormatting);
|
|
155
186
|
const project = await loadProject({
|
|
156
|
-
|
|
187
|
+
projectPath: "/user/project.inlang",
|
|
157
188
|
nodeishFs: fs,
|
|
158
189
|
_import,
|
|
159
190
|
});
|
|
160
|
-
const settingsOnDisk = await fs.readFile("/user/project
|
|
191
|
+
const settingsOnDisk = await fs.readFile("/user/project.inlang/settings.json", {
|
|
161
192
|
encoding: "utf-8",
|
|
162
193
|
});
|
|
163
194
|
expect(settingsOnDisk).toBe(settingsWithDeifferentFormatting);
|
|
164
195
|
project.setSettings(project.settings());
|
|
165
196
|
// TODO: how can we await `setsettings` correctly
|
|
166
197
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
167
|
-
const newsettingsOnDisk = await fs.readFile("/user/project
|
|
198
|
+
const newsettingsOnDisk = await fs.readFile("/user/project.inlang/settings.json", {
|
|
168
199
|
encoding: "utf-8",
|
|
169
200
|
});
|
|
170
201
|
expect(newsettingsOnDisk).not.toBe(settingsWithDeifferentFormatting);
|
|
@@ -176,10 +207,10 @@ describe("initialization", () => {
|
|
|
176
207
|
default: {},
|
|
177
208
|
});
|
|
178
209
|
const fs = createNodeishMemoryFs();
|
|
179
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
180
|
-
await fs.writeFile("/user/project
|
|
210
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
211
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
181
212
|
const project = await loadProject({
|
|
182
|
-
|
|
213
|
+
projectPath: "/user/project.inlang",
|
|
183
214
|
nodeishFs: fs,
|
|
184
215
|
_import: $badImport,
|
|
185
216
|
});
|
|
@@ -204,10 +235,10 @@ describe("functionality", () => {
|
|
|
204
235
|
describe("settings", () => {
|
|
205
236
|
it("should return the settings", async () => {
|
|
206
237
|
const fs = await createNodeishMemoryFs();
|
|
207
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
208
|
-
await fs.writeFile("/user/project
|
|
238
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
239
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
209
240
|
const project = await loadProject({
|
|
210
|
-
|
|
241
|
+
projectPath: "/user/project.inlang",
|
|
211
242
|
nodeishFs: fs,
|
|
212
243
|
_import,
|
|
213
244
|
});
|
|
@@ -215,10 +246,10 @@ describe("functionality", () => {
|
|
|
215
246
|
});
|
|
216
247
|
it("should set a new settings", async () => {
|
|
217
248
|
const fs = await createNodeishMemoryFs();
|
|
218
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
219
|
-
await fs.writeFile("/user/project
|
|
249
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
250
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
220
251
|
const project = await loadProject({
|
|
221
|
-
|
|
252
|
+
projectPath: "/user/project.inlang",
|
|
222
253
|
nodeishFs: fs,
|
|
223
254
|
_import,
|
|
224
255
|
});
|
|
@@ -235,12 +266,12 @@ describe("functionality", () => {
|
|
|
235
266
|
});
|
|
236
267
|
});
|
|
237
268
|
describe("setSettings", () => {
|
|
238
|
-
it("should fail if settings
|
|
269
|
+
it("should fail if settings are not valid", async () => {
|
|
239
270
|
const fs = await createNodeishMemoryFs();
|
|
240
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
241
|
-
await fs.writeFile("/user/project
|
|
271
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
272
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
242
273
|
const project = await loadProject({
|
|
243
|
-
|
|
274
|
+
projectPath: "/user/project.inlang",
|
|
244
275
|
nodeishFs: fs,
|
|
245
276
|
_import,
|
|
246
277
|
});
|
|
@@ -250,15 +281,15 @@ describe("functionality", () => {
|
|
|
250
281
|
});
|
|
251
282
|
it("should throw an error if sourceLanguageTag is not in languageTags", async () => {
|
|
252
283
|
const fs = await createNodeishMemoryFs();
|
|
253
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
284
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
254
285
|
const settings = {
|
|
255
286
|
sourceLanguageTag: "en",
|
|
256
287
|
languageTags: ["de"],
|
|
257
288
|
modules: [],
|
|
258
289
|
};
|
|
259
|
-
await fs.writeFile("/user/project
|
|
290
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
260
291
|
const project = await loadProject({
|
|
261
|
-
|
|
292
|
+
projectPath: "/user/project.inlang",
|
|
262
293
|
nodeishFs: fs,
|
|
263
294
|
_import,
|
|
264
295
|
});
|
|
@@ -267,21 +298,21 @@ describe("functionality", () => {
|
|
|
267
298
|
});
|
|
268
299
|
it("should write settings to disk", async () => {
|
|
269
300
|
const fs = await createNodeishMemoryFs();
|
|
270
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
271
|
-
await fs.writeFile("/user/project
|
|
301
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
302
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
272
303
|
const project = await loadProject({
|
|
273
|
-
|
|
304
|
+
projectPath: "/user/project.inlang",
|
|
274
305
|
nodeishFs: fs,
|
|
275
306
|
_import,
|
|
276
307
|
});
|
|
277
|
-
const before = await fs.readFile("/user/project
|
|
308
|
+
const before = await fs.readFile("/user/project.inlang/settings.json", { encoding: "utf-8" });
|
|
278
309
|
expect(before).toBeDefined();
|
|
279
|
-
const result = project.setSettings({ ...settings, languageTags: ["en"] });
|
|
310
|
+
const result = project.setSettings({ ...settings, languageTags: ["en", "nl", "de"] });
|
|
280
311
|
expect(result.data).toBeUndefined();
|
|
281
312
|
expect(result.error).toBeUndefined();
|
|
282
313
|
// TODO: how to wait for fs.writeFile to finish?
|
|
283
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
284
|
-
const after = await fs.readFile("/user/project
|
|
314
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
315
|
+
const after = await fs.readFile("/user/project.inlang/settings.json", { encoding: "utf-8" });
|
|
285
316
|
expect(after).toBeDefined();
|
|
286
317
|
expect(after).not.toBe(before);
|
|
287
318
|
});
|
|
@@ -294,10 +325,10 @@ describe("functionality", () => {
|
|
|
294
325
|
languageTags: ["en"],
|
|
295
326
|
modules: ["plugin.js", "lintRule.js"],
|
|
296
327
|
};
|
|
297
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
298
|
-
await fs.writeFile("/user/project
|
|
328
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
329
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
299
330
|
const project = await loadProject({
|
|
300
|
-
|
|
331
|
+
projectPath: "/user/project.inlang",
|
|
301
332
|
nodeishFs: fs,
|
|
302
333
|
_import,
|
|
303
334
|
});
|
|
@@ -322,10 +353,10 @@ describe("functionality", () => {
|
|
|
322
353
|
languageTags: ["en"],
|
|
323
354
|
modules: ["plugin.js", "lintRule.js"],
|
|
324
355
|
};
|
|
325
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
326
|
-
await fs.writeFile("/user/project
|
|
356
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
357
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
327
358
|
const project = await loadProject({
|
|
328
|
-
|
|
359
|
+
projectPath: "/user/project.inlang",
|
|
329
360
|
nodeishFs: fs,
|
|
330
361
|
_import,
|
|
331
362
|
});
|
|
@@ -353,8 +384,8 @@ describe("functionality", () => {
|
|
|
353
384
|
saveMessages: () => undefined,
|
|
354
385
|
};
|
|
355
386
|
const fs = await createNodeishMemoryFs();
|
|
356
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
357
|
-
await fs.writeFile("/user/project
|
|
387
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
388
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify({
|
|
358
389
|
sourceLanguageTag: "en",
|
|
359
390
|
languageTags: ["en"],
|
|
360
391
|
modules: ["plugin.js", "lintRule.js"],
|
|
@@ -365,7 +396,7 @@ describe("functionality", () => {
|
|
|
365
396
|
};
|
|
366
397
|
};
|
|
367
398
|
const project = await loadProject({
|
|
368
|
-
|
|
399
|
+
projectPath: "/user/project.inlang",
|
|
369
400
|
nodeishFs: fs,
|
|
370
401
|
_import,
|
|
371
402
|
});
|
|
@@ -395,8 +426,8 @@ describe("functionality", () => {
|
|
|
395
426
|
saveMessages: () => undefined,
|
|
396
427
|
};
|
|
397
428
|
const fs = await createNodeishMemoryFs();
|
|
398
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
399
|
-
await fs.writeFile("/user/project
|
|
429
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
430
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify({
|
|
400
431
|
sourceLanguageTag: "en",
|
|
401
432
|
languageTags: ["en"],
|
|
402
433
|
modules: ["plugin.js", "lintRule.js"],
|
|
@@ -407,7 +438,7 @@ describe("functionality", () => {
|
|
|
407
438
|
};
|
|
408
439
|
};
|
|
409
440
|
const project = await loadProject({
|
|
410
|
-
|
|
441
|
+
projectPath: "/user/project.inlang",
|
|
411
442
|
nodeishFs: fs,
|
|
412
443
|
_import,
|
|
413
444
|
});
|
|
@@ -418,10 +449,10 @@ describe("functionality", () => {
|
|
|
418
449
|
describe("errors", () => {
|
|
419
450
|
it("should return the errors", async () => {
|
|
420
451
|
const fs = await createNodeishMemoryFs();
|
|
421
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
422
|
-
await fs.writeFile("/user/project
|
|
452
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
453
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
423
454
|
const project = await loadProject({
|
|
424
|
-
|
|
455
|
+
projectPath: "/user/project.inlang",
|
|
425
456
|
nodeishFs: fs,
|
|
426
457
|
_import,
|
|
427
458
|
});
|
|
@@ -433,10 +464,10 @@ describe("functionality", () => {
|
|
|
433
464
|
describe("customApi", () => {
|
|
434
465
|
it("should return the app specific api", async () => {
|
|
435
466
|
const fs = await createNodeishMemoryFs();
|
|
436
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
437
|
-
await fs.writeFile("/user/project
|
|
467
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
468
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
438
469
|
const project = await loadProject({
|
|
439
|
-
|
|
470
|
+
projectPath: "/user/project.inlang",
|
|
440
471
|
nodeishFs: fs,
|
|
441
472
|
_import,
|
|
442
473
|
});
|
|
@@ -448,10 +479,10 @@ describe("functionality", () => {
|
|
|
448
479
|
describe("messages", () => {
|
|
449
480
|
it("should return the messages", async () => {
|
|
450
481
|
const fs = await createNodeishMemoryFs();
|
|
451
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
452
|
-
await fs.writeFile("/user/project
|
|
482
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
483
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
453
484
|
const project = await loadProject({
|
|
454
|
-
|
|
485
|
+
projectPath: "/user/project.inlang",
|
|
455
486
|
nodeishFs: fs,
|
|
456
487
|
_import,
|
|
457
488
|
});
|
|
@@ -469,8 +500,8 @@ describe("functionality", () => {
|
|
|
469
500
|
pathPattern: "./resources/{languageTag}.json",
|
|
470
501
|
},
|
|
471
502
|
};
|
|
472
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
473
|
-
await fs.writeFile("/user/project
|
|
503
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
504
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
474
505
|
await fs.mkdir("./resources");
|
|
475
506
|
const mockSaveFn = vi.fn();
|
|
476
507
|
const _mockPlugin = {
|
|
@@ -486,7 +517,7 @@ describe("functionality", () => {
|
|
|
486
517
|
};
|
|
487
518
|
};
|
|
488
519
|
const project = await loadProject({
|
|
489
|
-
|
|
520
|
+
projectPath: "/user/project.inlang",
|
|
490
521
|
nodeishFs: fs,
|
|
491
522
|
_import,
|
|
492
523
|
});
|
|
@@ -631,7 +662,8 @@ describe("functionality", () => {
|
|
|
631
662
|
pathPattern: "./resources/{languageTag}.json",
|
|
632
663
|
},
|
|
633
664
|
};
|
|
634
|
-
await fs.
|
|
665
|
+
await fs.mkdir("./project.inlang", { recursive: true });
|
|
666
|
+
await fs.writeFile("./project.inlang/settings.json", JSON.stringify(settings));
|
|
635
667
|
const mockSaveFn = vi.fn();
|
|
636
668
|
const _mockPlugin = {
|
|
637
669
|
id: "plugin.placeholder.name",
|
|
@@ -650,7 +682,7 @@ describe("functionality", () => {
|
|
|
650
682
|
};
|
|
651
683
|
};
|
|
652
684
|
const project = await loadProject({
|
|
653
|
-
|
|
685
|
+
projectPath: "/project.inlang",
|
|
654
686
|
nodeishFs: fs,
|
|
655
687
|
_import,
|
|
656
688
|
});
|
|
@@ -666,7 +698,7 @@ describe("functionality", () => {
|
|
|
666
698
|
await fs.mkdir("/user/project", { recursive: true });
|
|
667
699
|
await fs.writeFile("/user/project/project.inlang.json", JSON.stringify(settings));
|
|
668
700
|
const project = await loadProject({
|
|
669
|
-
|
|
701
|
+
projectPath: "/user/project/project.inlang.json",
|
|
670
702
|
nodeishFs: fs,
|
|
671
703
|
_import,
|
|
672
704
|
});
|
|
@@ -686,10 +718,10 @@ describe("functionality", () => {
|
|
|
686
718
|
modules: ["lintRule.js"],
|
|
687
719
|
};
|
|
688
720
|
const fs = createNodeishMemoryFs();
|
|
689
|
-
await fs.mkdir("/user/project", { recursive: true });
|
|
690
|
-
await fs.writeFile("/user/project
|
|
721
|
+
await fs.mkdir("/user/project.inlang", { recursive: true });
|
|
722
|
+
await fs.writeFile("/user/project.inlang/settings.json", JSON.stringify(settings));
|
|
691
723
|
const project = await loadProject({
|
|
692
|
-
|
|
724
|
+
projectPath: "/user/project.inlang",
|
|
693
725
|
nodeishFs: fs,
|
|
694
726
|
_import: async () => ({
|
|
695
727
|
default: mockMessageLintRule,
|
|
@@ -743,10 +775,11 @@ describe("functionality", () => {
|
|
|
743
775
|
filePath: "./messages.json",
|
|
744
776
|
},
|
|
745
777
|
};
|
|
746
|
-
await fs.
|
|
778
|
+
await fs.mkdir("./project.inlang", { recursive: true });
|
|
779
|
+
await fs.writeFile("./project.inlang/settings.json", JSON.stringify(settings));
|
|
747
780
|
// establish watcher
|
|
748
781
|
const project = await loadProject({
|
|
749
|
-
|
|
782
|
+
projectPath: normalizePath("/project.inlang"),
|
|
750
783
|
nodeishFs: fs,
|
|
751
784
|
_import: async () => ({
|
|
752
785
|
default: mockMessageFormatPlugin,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NodeishFilesystem } from "@lix-js/fs";
|
|
2
|
+
/**
|
|
3
|
+
* Migrates to the new project directory structure
|
|
4
|
+
* https://github.com/inlang/monorepo/issues/1678
|
|
5
|
+
*/
|
|
6
|
+
export declare const maybeMigrateToDirectory: (args: {
|
|
7
|
+
nodeishFs: NodeishFilesystem;
|
|
8
|
+
projectPath: string;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
//# sourceMappingURL=migrateToDirectory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrateToDirectory.d.ts","sourceRoot":"","sources":["../../src/migrations/migrateToDirectory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,SAAgB;IACnD,SAAS,EAAE,iBAAiB,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;CACnB,kBA0BA,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { tryCatch } from "@inlang/result";
|
|
2
|
+
/**
|
|
3
|
+
* Migrates to the new project directory structure
|
|
4
|
+
* https://github.com/inlang/monorepo/issues/1678
|
|
5
|
+
*/
|
|
6
|
+
export const maybeMigrateToDirectory = async (args) => {
|
|
7
|
+
// the migration assumes that the projectPath ends with project.inlang
|
|
8
|
+
if (args.projectPath.endsWith("project.inlang") === false) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
// we assume that stat will throw when the directory does not exist
|
|
12
|
+
const projectDirectory = await tryCatch(() => args.nodeishFs.stat(args.projectPath));
|
|
13
|
+
// the migration has already been conducted.
|
|
14
|
+
if (projectDirectory.data) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const settingsFile = await tryCatch(() => args.nodeishFs.readFile(args.projectPath + ".json", { encoding: "utf-8" }));
|
|
18
|
+
// the settings file does not exist or something else is wrong, let loadProject handle it
|
|
19
|
+
if (settingsFile.error) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
await args.nodeishFs.mkdir(args.projectPath);
|
|
23
|
+
await args.nodeishFs.writeFile(`${args.projectPath}/settings.json`, settingsFile.data);
|
|
24
|
+
await args.nodeishFs.writeFile(args.projectPath + ".README.md", readme);
|
|
25
|
+
};
|
|
26
|
+
const readme = `
|
|
27
|
+
# DELETE THE \`project.inlang.json\` FILE
|
|
28
|
+
|
|
29
|
+
The \`project.inlang.json\` file is now contained in a project directory e.g. \`project.inlang/settings.json\`.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## What you need to do
|
|
33
|
+
|
|
34
|
+
1. Update the inlang CLI (if you use it) to use the new path \`project.inlang\` instead of \`project.inlang.json\`.
|
|
35
|
+
2. Delete the \`project.inlang.json\` file.
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## Why is this happening?
|
|
39
|
+
|
|
40
|
+
See this RFC https://docs.google.com/document/d/1OYyA1wYfQRbIJOIBDliYoWjiUlkFBNxH_U2R4WpVRZ4/edit#heading=h.pecv6xb7ial6
|
|
41
|
+
and the following GitHub issue for more information https://github.com/inlang/monorepo/issues/1678.
|
|
42
|
+
|
|
43
|
+
- Monorepo support https://github.com/inlang/monorepo/discussions/258.
|
|
44
|
+
- Required for many other future features like caching, first class offline support, and more.
|
|
45
|
+
- Stablize the inlang project format.
|
|
46
|
+
`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrateToDirectory.test.d.ts","sourceRoot":"","sources":["../../src/migrations/migrateToDirectory.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { test, expect, vi } from "vitest";
|
|
2
|
+
import { maybeMigrateToDirectory } from "./migrateToDirectory.js";
|
|
3
|
+
import { createNodeishMemoryFs } from "@lix-js/fs";
|
|
4
|
+
test("it should return if the settings file has an error (let loadProject handle it)", async () => {
|
|
5
|
+
const projectPath = "./project.inlang";
|
|
6
|
+
const mockFs = {
|
|
7
|
+
stat: vi.fn(() => { }),
|
|
8
|
+
readFile: vi.fn(() => {
|
|
9
|
+
throw Error();
|
|
10
|
+
}),
|
|
11
|
+
};
|
|
12
|
+
await maybeMigrateToDirectory({ nodeishFs: mockFs, projectPath });
|
|
13
|
+
// something goes wrong in readFile
|
|
14
|
+
expect(mockFs.readFile).toHaveBeenCalled();
|
|
15
|
+
});
|
|
16
|
+
test("it should create the project directory if it does not exist and a project settings file exists", async () => {
|
|
17
|
+
const projectPath = "./project.inlang";
|
|
18
|
+
const mockFs = {
|
|
19
|
+
readFile: vi.fn(() => `{
|
|
20
|
+
"sourceLanguageTag": "en",
|
|
21
|
+
"languageTags": ["en", "de"],
|
|
22
|
+
"modules": []
|
|
23
|
+
}`),
|
|
24
|
+
stat: vi.fn(() => {
|
|
25
|
+
throw Error();
|
|
26
|
+
}),
|
|
27
|
+
mkdir: vi.fn(),
|
|
28
|
+
writeFile: vi.fn(),
|
|
29
|
+
};
|
|
30
|
+
await maybeMigrateToDirectory({ nodeishFs: mockFs, projectPath });
|
|
31
|
+
expect(mockFs.mkdir).toHaveBeenCalled();
|
|
32
|
+
expect(mockFs.writeFile).toHaveBeenCalled();
|
|
33
|
+
});
|
|
34
|
+
test("it should write the settings file to the new path", async () => {
|
|
35
|
+
const fs = createNodeishMemoryFs();
|
|
36
|
+
const mockSettings = {
|
|
37
|
+
sourceLanguageTag: "en",
|
|
38
|
+
languageTags: ["en", "de"],
|
|
39
|
+
modules: [],
|
|
40
|
+
};
|
|
41
|
+
await fs.writeFile("./project.inlang.json", JSON.stringify(mockSettings));
|
|
42
|
+
await maybeMigrateToDirectory({ nodeishFs: fs, projectPath: "./project.inlang" });
|
|
43
|
+
const migratedSettingsFile = await fs.readFile("./project.inlang/settings.json", {
|
|
44
|
+
encoding: "utf-8",
|
|
45
|
+
});
|
|
46
|
+
expect(migratedSettingsFile).toEqual(JSON.stringify(mockSettings));
|
|
47
|
+
expect(await fs.stat("./project.inlang.README.md")).toBeDefined();
|
|
48
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
2
|
import { expect, test } from "vitest";
|
|
3
|
-
import { Plugin, MessageLintRule } from "
|
|
3
|
+
import { Plugin, MessageLintRule } from "../index.js";
|
|
4
4
|
// import { createNodeishMemoryFs } from "@lix-js/fs"
|
|
5
5
|
import { Type } from "@sinclair/typebox";
|
|
6
6
|
import { validatedModuleSettings } from "./validatedModuleSettings.js";
|