@inlang/sdk 2.2.2 → 2.4.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 (31) hide show
  1. package/dist/json-schema/settings.js +1 -1
  2. package/dist/json-schema/settings.js.map +1 -1
  3. package/dist/project/loadProjectFromDirectory.d.ts.map +1 -1
  4. package/dist/project/loadProjectFromDirectory.js +28 -3
  5. package/dist/project/loadProjectFromDirectory.js.map +1 -1
  6. package/dist/project/loadProjectFromDirectory.test.js +53 -0
  7. package/dist/project/loadProjectFromDirectory.test.js.map +1 -1
  8. package/dist/project/loadProjectInMemory.d.ts +2 -0
  9. package/dist/project/loadProjectInMemory.d.ts.map +1 -1
  10. package/dist/project/loadProjectInMemory.js +1 -0
  11. package/dist/project/loadProjectInMemory.js.map +1 -1
  12. package/dist/project/newProject.d.ts.map +1 -1
  13. package/dist/project/newProject.js +6 -2
  14. package/dist/project/newProject.js.map +1 -1
  15. package/dist/project/newProject.test.js +10 -3
  16. package/dist/project/newProject.test.js.map +1 -1
  17. package/dist/project/saveProjectToDirectory.d.ts.map +1 -1
  18. package/dist/project/saveProjectToDirectory.js +1 -1
  19. package/dist/project/saveProjectToDirectory.js.map +1 -1
  20. package/dist/project/saveProjectToDirectory.test.js.map +1 -1
  21. package/dist/services/env-variables/index.js +1 -1
  22. package/dist/services/env-variables/index.js.map +1 -1
  23. package/package.json +4 -3
  24. package/src/json-schema/settings.ts +1 -1
  25. package/src/project/loadProjectFromDirectory.test.ts +66 -0
  26. package/src/project/loadProjectFromDirectory.ts +34 -3
  27. package/src/project/loadProjectInMemory.ts +3 -1
  28. package/src/project/newProject.test.ts +11 -3
  29. package/src/project/newProject.ts +7 -2
  30. package/src/project/saveProjectToDirectory.test.ts +39 -39
  31. package/src/project/saveProjectToDirectory.ts +4 -1
@@ -1 +1 @@
1
- {"version":3,"file":"loadProjectFromDirectory.test.js","sourceRoot":"/","sources":["project/loadProjectFromDirectory.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\nimport { beforeEach, describe, expect, test, vi } from \"vitest\";\nimport { ProjectSettings } from \"../json-schema/settings.js\";\nimport { Volume } from \"memfs\";\nimport nodePath from \"node:path\";\nimport {\n\tloadProjectFromDirectory,\n\tResourceFileImportError,\n\tWarningDeprecatedLintRule,\n} from \"./loadProjectFromDirectory.js\";\nimport { selectBundleNested } from \"../query-utilities/selectBundleNested.js\";\nimport { Text } from \"../json-schema/pattern.js\";\nimport type { InlangPlugin } from \"../plugin/schema.js\";\nimport type {\n\tMessageV1,\n\tVariantV1,\n} from \"../json-schema/old-v1-message/schemaV1.js\";\nimport { saveProjectToDirectory } from \"./saveProjectToDirectory.js\";\nimport { insertBundleNested } from \"../query-utilities/insertBundleNested.js\";\n\ntest(\"plugin.loadMessages and plugin.saveMessages must not be configured together with import export\", async () => {\n\tconst mockLegacyPlugin: InlangPlugin = {\n\t\tkey: \"mock-legacy-plugin\",\n\t\tloadMessages: async () => {\n\t\t\treturn [];\n\t\t},\n\t\tsaveMessages: async () => {},\n\t};\n\n\tconst mockLegacyPlugin2: InlangPlugin = {\n\t\tkey: \"mock-legacy-plugin-2\",\n\t\tloadMessages: async () => {\n\t\t\treturn [];\n\t\t},\n\t\tsaveMessages: async () => {},\n\t};\n\n\tconst mockImportExportPlugin: InlangPlugin = {\n\t\tkey: \"mock-import-export-plugin\",\n\t\texportFiles: () => {\n\t\t\treturn [];\n\t\t},\n\t\timportFiles: () => {\n\t\t\treturn {} as any;\n\t\t},\n\t};\n\n\tawait expect(\n\t\t(async () => {\n\t\t\tawait loadProjectFromDirectory({\n\t\t\t\tfs: Volume.fromJSON({\n\t\t\t\t\t\"./project.inlang/settings.json\": JSON.stringify({\n\t\t\t\t\t\tbaseLocale: \"en\",\n\t\t\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t\t\t\tmodules: [],\n\t\t\t\t\t} satisfies ProjectSettings),\n\t\t\t\t}) as any,\n\t\t\t\tpath: \"./project.inlang\",\n\t\t\t\tprovidePlugins: [\n\t\t\t\t\tmockLegacyPlugin,\n\t\t\t\t\tmockLegacyPlugin2,\n\t\t\t\t\tmockImportExportPlugin,\n\t\t\t\t],\n\t\t\t});\n\t\t})()\n\t).rejects.toThrowError();\n\n\tawait expect(\n\t\t(async () => {\n\t\t\tawait loadProjectFromDirectory({\n\t\t\t\tfs: Volume.fromJSON({\n\t\t\t\t\t\"./project.inlang/settings.json\": JSON.stringify({\n\t\t\t\t\t\tbaseLocale: \"en\",\n\t\t\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t\t\t\tmodules: [],\n\t\t\t\t\t} satisfies ProjectSettings),\n\t\t\t\t}) as any,\n\t\t\t\tpath: \"./project.inlang\",\n\t\t\t\tprovidePlugins: [\n\t\t\t\t\tmockLegacyPlugin,\n\t\t\t\t\tmockLegacyPlugin2,\n\t\t\t\t\tmockImportExportPlugin,\n\t\t\t\t],\n\t\t\t});\n\t\t})()\n\t).rejects.toThrowError();\n});\n\ntest(\"plugin.loadMessages and plugin.saveMessages should work for legacy purposes\", async () => {\n\tconst mockLegacyPlugin: InlangPlugin = {\n\t\tid: \"mock-legacy-plugin\",\n\t\t// @ts-expect-error - id is deprecated, key can be undefined\n\t\tkey: undefined,\n\t\tloadMessages: async ({ nodeishFs, settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern as string;\n\n\t\t\tconst messages: MessageV1[] = [];\n\n\t\t\t// @ts-expect-error - language tag is always given by the sdk v2\n\t\t\tfor (const languageTag of settings.languageTags) {\n\t\t\t\tconst data = await nodeishFs.readFile(\n\t\t\t\t\tpathPattern.replace(\"{languageTag}\", languageTag)\n\t\t\t\t);\n\n\t\t\t\tfor (const [key, value] of Object.entries(\n\t\t\t\t\tJSON.parse(data.toString())\n\t\t\t\t)) {\n\t\t\t\t\tconst exisitngMessage = messages.find(\n\t\t\t\t\t\t(message) => message.id === key\n\t\t\t\t\t);\n\t\t\t\t\tconst variant = {\n\t\t\t\t\t\tlanguageTag: languageTag,\n\t\t\t\t\t\tmatch: [],\n\t\t\t\t\t\tpattern: [{ type: \"Text\", value: value }],\n\t\t\t\t\t} as VariantV1;\n\t\t\t\t\tif (exisitngMessage !== undefined) {\n\t\t\t\t\t\texisitngMessage.variants.push(variant);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmessages.push({\n\t\t\t\t\t\t\talias: {},\n\t\t\t\t\t\t\tid: key,\n\t\t\t\t\t\t\tselectors: [],\n\t\t\t\t\t\t\tvariants: [variant],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn messages;\n\t\t},\n\t\tsaveMessages: async ({ messages, nodeishFs, settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern as string;\n\t\t\tfor (const languageTag of settings.languageTags!) {\n\t\t\t\tconst messagesInLanguage = {} as Record<string, string>;\n\t\t\t\tfor (const message of messages) {\n\t\t\t\t\tconst variantsInLanguage = message.variants.filter(\n\t\t\t\t\t\t(variant) => variant.languageTag === languageTag\n\t\t\t\t\t);\n\t\t\t\t\tif (variantsInLanguage.length > 1) {\n\t\t\t\t\t\t// data will get lost during export => throw?\n\t\t\t\t\t} else if (variantsInLanguage.length === 1) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tvariantsInLanguage[0]!.pattern.length != 1 ||\n\t\t\t\t\t\t\tvariantsInLanguage[0]!.pattern[0]?.type !== \"Text\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// throw?\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmessagesInLanguage[message.id] = (\n\t\t\t\t\t\t\tvariantsInLanguage[0]!.pattern[0]! as any\n\t\t\t\t\t\t).value;\n\t\t\t\t\t}\n\t\t\t\t\t// else no-op\n\t\t\t\t}\n\t\t\t\tawait nodeishFs.writeFile(\n\t\t\t\t\tpathPattern.replace(\"{languageTag}\", languageTag),\n\t\t\t\t\tJSON.stringify(messagesInLanguage, null, 2)\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t};\n\tconst mockRepo = {\n\t\t\"./README.md\": \"# Hello World\",\n\t\t\"./src/index.js\": \"console.log('Hello World')\",\n\t\t\"./src/translations/en.json\": JSON.stringify({\n\t\t\tkey1: \"value1\",\n\t\t\tkey2: \"value2\",\n\t\t}),\n\t\t\"./src/translations/de.json\": JSON.stringify({\n\t\t\tkey1: \"wert1\",\n\t\t\tkey2: \"wert2\",\n\t\t}),\n\t\t\"./project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tmodules: [\"./mock-module.js\"],\n\t\t\t\"plugin.mock-plugin\": {\n\t\t\t\tpathPattern: \"./src/translations/{languageTag}.json\",\n\t\t\t},\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tlet project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"./project.inlang\",\n\t\tprovidePlugins: [mockLegacyPlugin],\n\t});\n\n\tawait insertBundleNested(project.db, {\n\t\tid: \"key-id\",\n\t\tmessages: [\n\t\t\t{\n\t\t\t\tid: \"mock-message\",\n\t\t\t\tbundleId: \"mock-bundle\",\n\t\t\t\tlocale: \"en\",\n\t\t\t\tselectors: [],\n\t\t\t\tvariants: [\n\t\t\t\t\t{\n\t\t\t\t\t\tmessageId: \"mock-message\",\n\t\t\t\t\t\tpattern: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\tvalue: \"JOJO\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tawait saveProjectToDirectory({\n\t\tfs: fs.promises as any,\n\t\tpath: \"./project.inlang\",\n\t\tproject,\n\t});\n\n\tproject = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"./project.inlang\",\n\t\tprovidePlugins: [mockLegacyPlugin],\n\t});\n\n\tconst bundles = await selectBundleNested(project.db).execute();\n\n\tconst bundlesOrdered = bundles.sort((a, b) => a.id.localeCompare(b.id));\n\n\texpect(bundles.length).toBe(3);\n\texpect(bundlesOrdered[0]?.messages[0]?.locale).toBe(\"en\");\n\texpect(\n\t\t(bundlesOrdered[0]?.messages[0]?.variants[0]?.pattern[0] as Text)?.value\n\t).toBe(\"JOJO\");\n\n\t// TODO fix\n\t// expect(bundlesOrdered[0]?.messages[9]?.locale).toBe(\"en\");\n\t// expect(\n\t// \t(bundlesOrdered[0]?.messages[1]?.variants[0]?.pattern[0] as Text)?.value\n\t// ).toBe(\"wert1\");\n\n\t// expect(bundlesOrdered[1]?.messages[0]?.locale).toBe(\"en\");\n\t// expect(\n\t// \t(bundlesOrdered[1]?.messages[0]?.variants[0]?.pattern[0] as Text)?.value\n\t// ).toBe(\"value2\");\n\n\t// expect(bundlesOrdered[1]?.messages[1]?.locale).toBe(\"de\");\n\t// expect(\n\t// \t(bundlesOrdered[1]?.messages[1]?.variants[0]?.pattern[0] as Text)?.value\n\t// ).toBe(\"wert2\");\n});\n\nconst mockSettings = {\n\tbaseLocale: \"en\",\n\tlocales: [\"en\", \"de\"],\n\tmodules: [],\n} satisfies ProjectSettings;\n\nconst mockDirectory = {\n\t\"/project.inlang/cache/plugin/29j49j2\": \"cache value\",\n\t\"/project.inlang/.gitignore\": \"git value\",\n\t\"/project.inlang/prettierrc.json\": \"prettier value\",\n\t\"/project.inlang/README.md\": \"readme value\",\n\t\"/project.inlang/settings.json\": JSON.stringify(mockSettings),\n};\n\ndescribe(\"it should keep files between the inlang directory and lix in sync\", async () => {\n\ttest(\"files from directory should be available via lix after project has been loaded from directory\", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\tconst files = await project.lix.db.selectFrom(\"file\").selectAll().execute();\n\n\t\texpect(files.length).toBe(\n\t\t\t5 + 1 /* the db.sqlite file */ + 1 /* project_id */\n\t\t);\n\n\t\tconst filesByPath = files.reduce((acc, file) => {\n\t\t\tacc[file.path] = new TextDecoder().decode(file.data);\n\t\t\treturn acc;\n\t\t}, {} as any);\n\n\t\texpect(filesByPath[\"/cache/plugin/29j49j2\"]).toBe(\"cache value\");\n\t\texpect(filesByPath[\"/.gitignore\"]).toBe(\"git value\");\n\t\texpect(filesByPath[\"/prettierrc.json\"]).toBe(\"prettier value\");\n\t\texpect(filesByPath[\"/README.md\"]).toBe(\"readme value\");\n\t\texpect(filesByPath[\"/settings.json\"]).toBe(JSON.stringify(mockSettings));\n\t});\n\n\t// the test doesn't work on non-windows systems\n\t// mocking the node:path to use backlashes has no effect\n\ttest.skip(\"files from directory should be available via lix if the OS uses backlashes as folder separators\", async () => {\n\t\tconst mockWindowsDirectory = {\n\t\t\t\"\\\\project.inlang\\\\cache\\\\plugin\\\\29j49j2\": \"cache value\",\n\t\t\t\"\\\\project.inlang\\\\.gitignore\": \"git value\",\n\t\t\t\"\\\\project.inlang\\\\prettierrc.json\": \"prettier value\",\n\t\t\t\"\\\\project.inlang\\\\README.md\": \"readme value\",\n\t\t\t\"\\\\project.inlang\\\\settings.json\": JSON.stringify(mockSettings),\n\t\t};\n\n\t\t// Temporarily set the platform to win32\n\t\tObject.defineProperty(process, \"platform\", {\n\t\t\tvalue: \"win32\",\n\t\t});\n\n\t\tObject.defineProperty(nodePath, \"sep\", {\n\t\t\tvalue: \"\\\\\",\n\t\t});\n\n\t\tconst fs = Volume.fromJSON(mockWindowsDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"\\\\project.inlang\",\n\t\t});\n\n\t\tconst files = await project.lix.db.selectFrom(\"file\").selectAll().execute();\n\n\t\texpect(files.length).toBe(\n\t\t\t5 + 1 /* the db.sqlite file */ + 1 /* project_id */\n\t\t);\n\n\t\tconst filesByPath = files.reduce((acc, file) => {\n\t\t\tacc[file.path] = new TextDecoder().decode(file.data);\n\t\t\treturn acc;\n\t\t}, {} as any);\n\n\t\texpect(filesByPath[\"/cache/plugin/29j49j2\"]).toBe(\"cache value\");\n\t\texpect(filesByPath[\"/.gitignore\"]).toBe(\"git value\");\n\t\texpect(filesByPath[\"/prettierrc.json\"]).toBe(\"prettier value\");\n\t\texpect(filesByPath[\"/README.md\"]).toBe(\"readme value\");\n\t\texpect(filesByPath[\"/settings.json\"]).toBe(JSON.stringify(mockSettings));\n\t});\n\n\ttest(\"file created in fs should be avaialable in lix \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\tfs.writeFileSync(\n\t\t\t\"/project.inlang/file-created-on-fs.txt\",\n\t\t\t\"value written by fs\",\n\t\t\t{\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t}\n\t\t);\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\n\t\tconst randomFileInLix = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/file-created-on-fs.txt\")\n\t\t\t.executeTakeFirstOrThrow();\n\n\t\texpect(new TextDecoder().decode(randomFileInLix.data)).toBe(\n\t\t\t\"value written by fs\"\n\t\t);\n\t});\n\n\ttest(\"file updated in fs should be avaialable in lix \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\t// \"changes to a file on disk should reflect in lix\n\t\tfs.writeFileSync(\n\t\t\t\"/project.inlang/settings.json\",\n\t\t\tJSON.stringify({\n\t\t\t\t...mockSettings,\n\t\t\t\tbaseLocale: \"brand-new-locale-written-to-fs-file\",\n\t\t\t})\n\t\t);\n\n\t\t// console.log(\"wrting fs settings\");\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\t\tconst fileInLix = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/settings.json\")\n\t\t\t.executeTakeFirstOrThrow();\n\n\t\tconst settingsAfterUpdateOnDisk = JSON.parse(\n\t\t\tnew TextDecoder().decode(fileInLix.data)\n\t\t);\n\n\t\texpect(settingsAfterUpdateOnDisk.baseLocale).toBe(\n\t\t\t\"brand-new-locale-written-to-fs-file\"\n\t\t);\n\t});\n\n\ttest(\"file deleted in fs should be droped from lix \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\tconst filesInLixBefore = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/README.md\")\n\t\t\t.execute();\n\n\t\texpect(filesInLixBefore.length).toBe(1);\n\n\t\t// \"changes to a file on disk should reflect in lix\n\t\tfs.unlinkSync(\"/project.inlang/README.md\");\n\n\t\t// console.log(\"wrting fs settings\");\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\t\tconst fileInLixAfter = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/README.md\")\n\t\t\t.execute();\n\n\t\texpect(fileInLixAfter.length).toBe(0);\n\t});\n\n\ttest(\"file created in lix should be avaialable in fs \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\tawait project.lix.db\n\t\t\t.insertInto(\"file\")\n\t\t\t.values({\n\t\t\t\tpath: \"/file-created-in.lix.txt\",\n\t\t\t\tdata: new TextEncoder().encode(\"random value lix\"),\n\t\t\t})\n\t\t\t.execute();\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\n\t\tconst randomFileOnDiskContent = fs\n\t\t\t.readFileSync(\"/project.inlang/file-created-in.lix.txt\")\n\t\t\t.toString();\n\t\texpect(randomFileOnDiskContent).toBe(\"random value lix\");\n\t});\n\n\ttest(\"file updated in lix should be avaialable in fs \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\t// console.log(\"wrting lix settings\");\n\t\t// changes to a file in lix should reflect in the project directory\n\t\tawait project.lix.db\n\t\t\t.updateTable(\"file\")\n\t\t\t.where(\"path\", \"=\", \"/settings.json\")\n\t\t\t.set({\n\t\t\t\tdata: new TextEncoder().encode(\n\t\t\t\t\tJSON.stringify({ ...mockSettings, baseLocale: \"brand-new-locale2\" })\n\t\t\t\t),\n\t\t\t})\n\t\t\t.execute();\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\n\t\tconst fileOnDisk = fs.readFileSync(\"/project.inlang/settings.json\");\n\t\tconst settings = JSON.parse(fileOnDisk.toString());\n\n\t\texpect(settings.baseLocale).toBe(\"brand-new-locale2\");\n\t});\n\n\ttest(\"file deleted in lix should be gone in fs as awell\", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\t// console.log(\"wrting lix settings\");\n\t\t// changes to a file in lix should reflect in the project directory\n\t\tawait project.lix.db\n\t\t\t.deleteFrom(\"file\")\n\t\t\t.where(\"path\", \"=\", \"/.gitignore\")\n\t\t\t.execute();\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\n\t\tconst fileExistsOnDisk = fs.existsSync(\"/project.inlang/.gitignore\");\n\n\t\texpect(fileExistsOnDisk).toBe(false);\n\t});\n\n\ttest(\"file updated in fs and lix (conflicting) should result in the fs state\", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\t// console.log(\"wrting fs settings simultanous\");\n\t\t// changes to a file on disk and lix at the same time should lead to the fs version\n\t\tfs.writeFileSync(\n\t\t\t\"/project.inlang/settings.json\",\n\t\t\tJSON.stringify({ ...mockSettings, baseLocale: \"fs-version\" })\n\t\t);\n\n\t\t// console.log(\"wrting lix settings simultanous\");\n\t\tawait project.lix.db\n\t\t\t.updateTable(\"file\")\n\t\t\t.where(\"path\", \"=\", \"/settings.json\")\n\t\t\t.set({\n\t\t\t\tdata: new TextEncoder().encode(\n\t\t\t\t\tJSON.stringify({ ...mockSettings, baseLocale: \"lix-version\" })\n\t\t\t\t),\n\t\t\t})\n\t\t\t.execute();\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, 1010));\n\n\t\tconst fileOnDiskUpdated = fs.readFileSync(\"/project.inlang/settings.json\");\n\t\tconst settingsUpdated = JSON.parse(fileOnDiskUpdated.toString());\n\n\t\texpect(settingsUpdated.baseLocale).toBe(\"fs-version\");\n\n\t\tconst fileInLixUpdated = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/settings.json\")\n\t\t\t.executeTakeFirstOrThrow();\n\n\t\tconst settingsAfterUpdateOnDiskAndLix = JSON.parse(\n\t\t\tnew TextDecoder().decode(fileInLixUpdated.data)\n\t\t);\n\n\t\texpect(settingsAfterUpdateOnDiskAndLix.baseLocale).toBe(\"fs-version\");\n\t});\n});\n\ntest(\"errors from importing translation files should be shown\", async () => {\n\tconst mock = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mock);\n\n\tconst proxiedFs = new Proxy(fs, {\n\t\tget: (target, prop) => {\n\t\t\tif (prop === \"promises\") {\n\t\t\t\t// Intercept the 'promises' object\n\t\t\t\treturn new Proxy(target.promises, {\n\t\t\t\t\tget: (promisesTarget, promisesProp) => {\n\t\t\t\t\t\tif (promisesProp === \"readFile\") {\n\t\t\t\t\t\t\t// @ts-expect-error - we are mocking the fs\n\t\t\t\t\t\t\treturn (path, ...args) => {\n\t\t\t\t\t\t\t\tif (path.endsWith(\"some-file.json\")) {\n\t\t\t\t\t\t\t\t\tthrow new Error(\"MOCK ERROR\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn promisesTarget.readFile(path, ...args);\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn Reflect.get(promisesTarget, promisesProp);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn Reflect.get(target, prop);\n\t\t},\n\t});\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\timportFiles: async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t},\n\t\ttoBeImportedFiles: async () => {\n\t\t\treturn [{ path: \"./some-file.json\", locale: \"mock\" }];\n\t\t},\n\t};\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: proxiedFs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\tconst errors = await project.errors.get();\n\t// TODO deactivated for now - we need to proxy fs.promises or change the signature of loadProject\n\texpect(errors).toHaveLength(1);\n\texpect(errors[0]).toBeInstanceOf(ResourceFileImportError);\n});\n\n// it happens often that a resource file doesn't exist yet on import\ntest(\"errors from importing translation files that are ENOENT should not be shown\", async () => {\n\tconst mock = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mock);\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\timportFiles: async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t},\n\t\ttoBeImportedFiles: async () => {\n\t\t\treturn [{ path: \"./some-non-existing-file.json\", locale: \"mock\" }];\n\t\t},\n\t};\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\tconst errors = await project.errors.get();\n\texpect(errors).toHaveLength(0);\n});\n\n// it happens often that a resource file doesn't exist yet on import\ntest(\"it should pass toBeImportedMetadata on import\", async () => {\n\tconst mock = {\n\t\t\"/foo/en.json\": JSON.stringify({}),\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mock);\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\ttoBeImportedFiles: async () => {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: \"/foo/en.json\",\n\t\t\t\t\tlocale: \"mock\",\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tfoo: \"bar\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\t\t},\n\t\timportFiles: async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t},\n\t};\n\n\tconst toBeSpy = vi.spyOn(mockPlugin, \"toBeImportedFiles\");\n\tconst importSpy = vi.spyOn(mockPlugin, \"importFiles\");\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\texpect(toBeSpy).toHaveBeenCalled();\n\n\texpect(importSpy).toHaveBeenCalledWith(\n\t\texpect.objectContaining({\n\t\t\tfiles: [\n\t\t\t\texpect.objectContaining({\n\t\t\t\t\ttoBeImportedFilesMetadata: {\n\t\t\t\t\t\tfoo: \"bar\",\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t);\n});\n\ntest(\"it should provide plugins from disk for backwards compatibility but warn that those plugins are not portable\", async () => {\n\tconst mockRepo = {\n\t\t\"/local-plugins/mock-plugin.js\": \"export default { key: 'mock-plugin' }\",\n\t\t\"/local-plugins/mock-rule.js\":\n\t\t\t\"export default { id: 'messageLintRule.mock }\",\n\t\t\"/website/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tmodules: [\n\t\t\t\t\"../local-plugins/mock-plugin.js\",\n\t\t\t\t\"../local-plugins/mock-rule.js\",\n\t\t\t],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/website/project.inlang\",\n\t});\n\n\tconst plugins = await project.plugins.get();\n\tconst errors = await project.errors.get();\n\tconst settings = await project.settings.get();\n\n\texpect(plugins.length).toBe(1);\n\texpect(plugins[0]?.key).toBe(\"mock-plugin\");\n\n\texpect(errors.length).toBe(1);\n\texpect(errors[0]).toBeInstanceOf(WarningDeprecatedLintRule);\n\n\t// it should not remove the module from the settings\n\t// else roundtrips would not work\n\texpect(settings.modules?.[0]).toBe(\"../local-plugins/mock-plugin.js\");\n});\n\n// https://github.com/opral/inlang-sdk/issues/174\ntest(\"plugin calls that use fs should be intercepted to use an absolute path\", async () => {\n\tprocess.cwd = () => \"/\";\n\n\tconst mockRepo = {\n\t\t\"/messages/en.json\": JSON.stringify({\n\t\t\tkey1: \"value1\",\n\t\t\tkey2: \"value2\",\n\t\t}),\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t\"plugin.mock-plugin\": {\n\t\t\t\tpathPattern: \"./messages/{locale}.json\",\n\t\t\t},\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\tloadMessages: async ({ nodeishFs, settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern.replace(\n\t\t\t\t\"{locale}\",\n\t\t\t\t\"en\"\n\t\t\t) as string;\n\t\t\tconst file = await nodeishFs.readFile(pathPattern);\n\t\t\t// reading the file should be possible without an error\n\t\t\texpect(file.toString()).toBe(\n\t\t\t\tJSON.stringify({\n\t\t\t\t\tkey1: \"value1\",\n\t\t\t\t\tkey2: \"value2\",\n\t\t\t\t})\n\t\t\t);\n\t\t\treturn [];\n\t\t},\n\t\tsaveMessages: async ({ nodeishFs, settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern.replace(\n\t\t\t\t\"{locale}\",\n\t\t\t\t\"en\"\n\t\t\t) as string;\n\t\t\tconst file = new TextEncoder().encode(\n\t\t\t\tJSON.stringify({\n\t\t\t\t\tkey1: \"value1\",\n\t\t\t\t\tkey2: \"value2\",\n\t\t\t\t\tkey3: \"value3\",\n\t\t\t\t})\n\t\t\t);\n\t\t\tawait nodeishFs.writeFile(pathPattern, file.buffer as ArrayBuffer);\n\t\t},\n\t\ttoBeImportedFiles: async ({ settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern.replace(\n\t\t\t\t\"{locale}\",\n\t\t\t\t\"en\"\n\t\t\t) as string;\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: pathPattern,\n\t\t\t\t\tlocale: \"en\",\n\t\t\t\t},\n\t\t\t];\n\t\t},\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst loadMessagesSpy = vi.spyOn(mockPlugin, \"loadMessages\");\n\tconst saveMessagesSpy = vi.spyOn(mockPlugin, \"saveMessages\");\n\tconst toBeImportedFilesSpy = vi.spyOn(mockPlugin, \"toBeImportedFiles\");\n\tconst fsReadFileSpy = vi.spyOn(fs.promises, \"readFile\");\n\tconst fsWriteFileSpy = vi.spyOn(fs.promises, \"writeFile\");\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\texpect(loadMessagesSpy).toHaveBeenCalled();\n\texpect(fsReadFileSpy).toHaveBeenCalledWith(\"/messages/en.json\", undefined);\n\n\t// todo test that saveMessages works too.\n\t// await project.db.insertInto(\"bundle\").defaultValues().execute();\n\n\t// const translationFile = await fs.readFile(\"/messages/en.json\", \"utf-8\");\n\n\t// expect(translationFile).toBe(\n\t// \tJSON.stringify({\n\t// \t\tkey1: \"value1\",\n\t// \t\tkey2: \"value2\",\n\t// \t\tkey3: \"value3\",\n\t// \t})\n\t// );\n\n\t// expect(fsWriteFileSpy).toHaveBeenCalledWith(\n\t// \t\"/messages/en.json\",\n\t// \tJSON.stringify({\n\t// \t\tkey1: \"value1\",\n\t// \t\tkey2: \"value2\",\n\t// \t\tkey3: \"value3\",\n\t// \t}),\n\t// \t\"utf-8\"\n\t// );\n\n\t// expect(saveMessagesSpy).toHaveBeenCalled();\n\t// expect(toBeImportedFilesSpy).toHaveBeenCalled();\n});\n\ntest(\"it can import plugins via http\", async () => {\n\tconst mockRepo = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\"],\n\t\t\tmodules: [\"https://example.com/plugin.js\"],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst mockPluginModule = `export default {\n\t\t\tkey: \"mock-plugin\"\t\n\t\t}`;\n\n\tglobal.fetch = vi.fn(() => Promise.resolve(new Response(mockPluginModule)));\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t});\n\n\tconst plugins = await project.plugins.get();\n\n\texpect(global.fetch).toHaveBeenCalledWith(\"https://example.com/plugin.js\");\n\texpect(plugins.length).toBe(1);\n\n\tconst pluginCache = await project.lix.db\n\t\t.selectFrom(\"file\")\n\t\t.selectAll()\n\t\t.where(\"path\", \"like\", \"/cache/plugins/%\")\n\t\t.execute();\n\n\texpect(\n\t\tpluginCache.some(\n\t\t\t(file) => new TextDecoder().decode(file.data) === mockPluginModule\n\t\t),\n\t\t\"expecting the plugin to be cached\"\n\t).toBe(true);\n});\n\ntest(\"plugins that provide both loadMessages and importFiles should be allowed and the importFiles should be called\", async () => {\n\tconst mockRepo = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\tloadMessages: vi.fn(async () => []),\n\t\timportFiles: vi.fn(async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t}),\n\t};\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\texpect(mockPlugin.importFiles).toHaveBeenCalled();\n\texpect(mockPlugin.loadMessages).not.toHaveBeenCalled();\n});\n\ntest(\"providing multiple plugins that have legacy loadMessages and saveMessages function should be possible if they have import/export functions\", async () => {\n\tconst mockRepo = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst mockPlugin1: InlangPlugin = {\n\t\tkey: \"mock-plugin1\",\n\t\tloadMessages: vi.fn(async () => []),\n\t\timportFiles: vi.fn(async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t}),\n\t};\n\n\tconst mockPlugin2: InlangPlugin = {\n\t\tkey: \"mock-plugin2\",\n\t\tloadMessages: vi.fn(async () => []),\n\t\timportFiles: vi.fn(async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t}),\n\t};\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin1, mockPlugin2],\n\t});\n\n\texpect(mockPlugin1.importFiles).toHaveBeenCalled();\n\texpect(mockPlugin1.loadMessages).not.toHaveBeenCalled();\n\n\texpect(mockPlugin2.importFiles).toHaveBeenCalled();\n\texpect(mockPlugin2.loadMessages).not.toHaveBeenCalled();\n});\n"]}
1
+ {"version":3,"file":"loadProjectFromDirectory.test.js","sourceRoot":"/","sources":["project/loadProjectFromDirectory.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n\nimport { beforeEach, describe, expect, test, vi } from \"vitest\";\nimport { ProjectSettings } from \"../json-schema/settings.js\";\nimport { Volume } from \"memfs\";\nimport nodePath from \"node:path\";\nimport {\n\tloadProjectFromDirectory,\n\tResourceFileImportError,\n\tWarningDeprecatedLintRule,\n} from \"./loadProjectFromDirectory.js\";\nimport { selectBundleNested } from \"../query-utilities/selectBundleNested.js\";\nimport { Text } from \"../json-schema/pattern.js\";\nimport type { InlangPlugin } from \"../plugin/schema.js\";\nimport type {\n\tMessageV1,\n\tVariantV1,\n} from \"../json-schema/old-v1-message/schemaV1.js\";\nimport { saveProjectToDirectory } from \"./saveProjectToDirectory.js\";\nimport { insertBundleNested } from \"../query-utilities/insertBundleNested.js\";\n\ntest(\"plugin.loadMessages and plugin.saveMessages must not be configured together with import export\", async () => {\n\tconst mockLegacyPlugin: InlangPlugin = {\n\t\tkey: \"mock-legacy-plugin\",\n\t\tloadMessages: async () => {\n\t\t\treturn [];\n\t\t},\n\t\tsaveMessages: async () => {},\n\t};\n\n\tconst mockLegacyPlugin2: InlangPlugin = {\n\t\tkey: \"mock-legacy-plugin-2\",\n\t\tloadMessages: async () => {\n\t\t\treturn [];\n\t\t},\n\t\tsaveMessages: async () => {},\n\t};\n\n\tconst mockImportExportPlugin: InlangPlugin = {\n\t\tkey: \"mock-import-export-plugin\",\n\t\texportFiles: () => {\n\t\t\treturn [];\n\t\t},\n\t\timportFiles: () => {\n\t\t\treturn {} as any;\n\t\t},\n\t};\n\n\tawait expect(\n\t\t(async () => {\n\t\t\tawait loadProjectFromDirectory({\n\t\t\t\tfs: Volume.fromJSON({\n\t\t\t\t\t\"./project.inlang/settings.json\": JSON.stringify({\n\t\t\t\t\t\tbaseLocale: \"en\",\n\t\t\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t\t\t\tmodules: [],\n\t\t\t\t\t} satisfies ProjectSettings),\n\t\t\t\t}) as any,\n\t\t\t\tpath: \"./project.inlang\",\n\t\t\t\tprovidePlugins: [\n\t\t\t\t\tmockLegacyPlugin,\n\t\t\t\t\tmockLegacyPlugin2,\n\t\t\t\t\tmockImportExportPlugin,\n\t\t\t\t],\n\t\t\t});\n\t\t})()\n\t).rejects.toThrowError();\n\n\tawait expect(\n\t\t(async () => {\n\t\t\tawait loadProjectFromDirectory({\n\t\t\t\tfs: Volume.fromJSON({\n\t\t\t\t\t\"./project.inlang/settings.json\": JSON.stringify({\n\t\t\t\t\t\tbaseLocale: \"en\",\n\t\t\t\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t\t\t\tmodules: [],\n\t\t\t\t\t} satisfies ProjectSettings),\n\t\t\t\t}) as any,\n\t\t\t\tpath: \"./project.inlang\",\n\t\t\t\tprovidePlugins: [\n\t\t\t\t\tmockLegacyPlugin,\n\t\t\t\t\tmockLegacyPlugin2,\n\t\t\t\t\tmockImportExportPlugin,\n\t\t\t\t],\n\t\t\t});\n\t\t})()\n\t).rejects.toThrowError();\n});\n\ntest(\"plugin.loadMessages and plugin.saveMessages should work for legacy purposes\", async () => {\n\tconst mockLegacyPlugin: InlangPlugin = {\n\t\tid: \"mock-legacy-plugin\",\n\t\t// @ts-expect-error - id is deprecated, key can be undefined\n\t\tkey: undefined,\n\t\tloadMessages: async ({ nodeishFs, settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern as string;\n\n\t\t\tconst messages: MessageV1[] = [];\n\n\t\t\t// @ts-expect-error - language tag is always given by the sdk v2\n\t\t\tfor (const languageTag of settings.languageTags) {\n\t\t\t\tconst data = await nodeishFs.readFile(\n\t\t\t\t\tpathPattern.replace(\"{languageTag}\", languageTag)\n\t\t\t\t);\n\n\t\t\t\tfor (const [key, value] of Object.entries(\n\t\t\t\t\tJSON.parse(data.toString())\n\t\t\t\t)) {\n\t\t\t\t\tconst exisitngMessage = messages.find(\n\t\t\t\t\t\t(message) => message.id === key\n\t\t\t\t\t);\n\t\t\t\t\tconst variant = {\n\t\t\t\t\t\tlanguageTag: languageTag,\n\t\t\t\t\t\tmatch: [],\n\t\t\t\t\t\tpattern: [{ type: \"Text\", value: value }],\n\t\t\t\t\t} as VariantV1;\n\t\t\t\t\tif (exisitngMessage !== undefined) {\n\t\t\t\t\t\texisitngMessage.variants.push(variant);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tmessages.push({\n\t\t\t\t\t\t\talias: {},\n\t\t\t\t\t\t\tid: key,\n\t\t\t\t\t\t\tselectors: [],\n\t\t\t\t\t\t\tvariants: [variant],\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn messages;\n\t\t},\n\t\tsaveMessages: async ({ messages, nodeishFs, settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern as string;\n\t\t\tfor (const languageTag of settings.languageTags!) {\n\t\t\t\tconst messagesInLanguage = {} as Record<string, string>;\n\t\t\t\tfor (const message of messages) {\n\t\t\t\t\tconst variantsInLanguage = message.variants.filter(\n\t\t\t\t\t\t(variant) => variant.languageTag === languageTag\n\t\t\t\t\t);\n\t\t\t\t\tif (variantsInLanguage.length > 1) {\n\t\t\t\t\t\t// data will get lost during export => throw?\n\t\t\t\t\t} else if (variantsInLanguage.length === 1) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tvariantsInLanguage[0]!.pattern.length != 1 ||\n\t\t\t\t\t\t\tvariantsInLanguage[0]!.pattern[0]?.type !== \"Text\"\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// throw?\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmessagesInLanguage[message.id] = (\n\t\t\t\t\t\t\tvariantsInLanguage[0]!.pattern[0]! as any\n\t\t\t\t\t\t).value;\n\t\t\t\t\t}\n\t\t\t\t\t// else no-op\n\t\t\t\t}\n\t\t\t\tawait nodeishFs.writeFile(\n\t\t\t\t\tpathPattern.replace(\"{languageTag}\", languageTag),\n\t\t\t\t\tJSON.stringify(messagesInLanguage, null, 2)\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t};\n\tconst mockRepo = {\n\t\t\"./README.md\": \"# Hello World\",\n\t\t\"./src/index.js\": \"console.log('Hello World')\",\n\t\t\"./src/translations/en.json\": JSON.stringify({\n\t\t\tkey1: \"value1\",\n\t\t\tkey2: \"value2\",\n\t\t}),\n\t\t\"./src/translations/de.json\": JSON.stringify({\n\t\t\tkey1: \"wert1\",\n\t\t\tkey2: \"wert2\",\n\t\t}),\n\t\t\"./project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tmodules: [\"./mock-module.js\"],\n\t\t\t\"plugin.mock-plugin\": {\n\t\t\t\tpathPattern: \"./src/translations/{languageTag}.json\",\n\t\t\t},\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tlet project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"./project.inlang\",\n\t\tprovidePlugins: [mockLegacyPlugin],\n\t});\n\n\tawait insertBundleNested(project.db, {\n\t\tid: \"key-id\",\n\t\tmessages: [\n\t\t\t{\n\t\t\t\tid: \"mock-message\",\n\t\t\t\tbundleId: \"mock-bundle\",\n\t\t\t\tlocale: \"en\",\n\t\t\t\tselectors: [],\n\t\t\t\tvariants: [\n\t\t\t\t\t{\n\t\t\t\t\t\tmessageId: \"mock-message\",\n\t\t\t\t\t\tpattern: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\tvalue: \"JOJO\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t});\n\n\tawait saveProjectToDirectory({\n\t\tfs: fs.promises as any,\n\t\tpath: \"./project.inlang\",\n\t\tproject,\n\t});\n\n\tproject = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"./project.inlang\",\n\t\tprovidePlugins: [mockLegacyPlugin],\n\t});\n\n\tconst bundles = await selectBundleNested(project.db).execute();\n\n\tconst bundlesOrdered = bundles.sort((a, b) => a.id.localeCompare(b.id));\n\n\texpect(bundles.length).toBe(3);\n\texpect(bundlesOrdered[0]?.messages[0]?.locale).toBe(\"en\");\n\texpect(\n\t\t(bundlesOrdered[0]?.messages[0]?.variants[0]?.pattern[0] as Text)?.value\n\t).toBe(\"JOJO\");\n\n\t// TODO fix\n\t// expect(bundlesOrdered[0]?.messages[9]?.locale).toBe(\"en\");\n\t// expect(\n\t// \t(bundlesOrdered[0]?.messages[1]?.variants[0]?.pattern[0] as Text)?.value\n\t// ).toBe(\"wert1\");\n\n\t// expect(bundlesOrdered[1]?.messages[0]?.locale).toBe(\"en\");\n\t// expect(\n\t// \t(bundlesOrdered[1]?.messages[0]?.variants[0]?.pattern[0] as Text)?.value\n\t// ).toBe(\"value2\");\n\n\t// expect(bundlesOrdered[1]?.messages[1]?.locale).toBe(\"de\");\n\t// expect(\n\t// \t(bundlesOrdered[1]?.messages[1]?.variants[0]?.pattern[0] as Text)?.value\n\t// ).toBe(\"wert2\");\n});\n\nconst mockSettings = {\n\tbaseLocale: \"en\",\n\tlocales: [\"en\", \"de\"],\n\tmodules: [],\n} satisfies ProjectSettings;\n\nconst mockDirectory = {\n\t\"/project.inlang/cache/plugin/29j49j2\": \"cache value\",\n\t\"/project.inlang/.gitignore\": \"git value\",\n\t\"/project.inlang/prettierrc.json\": \"prettier value\",\n\t\"/project.inlang/README.md\": \"readme value\",\n\t\"/project.inlang/settings.json\": JSON.stringify(mockSettings),\n};\n\ndescribe(\"it should keep files between the inlang directory and lix in sync\", async () => {\n\ttest(\"files from directory should be available via lix after project has been loaded from directory\", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\tconst files = await project.lix.db.selectFrom(\"file\").selectAll().execute();\n\n\t\texpect(files.length).toBe(\n\t\t\t5 + 1 /* the db.sqlite file */ + 1 /* project_id */\n\t\t);\n\n\t\tconst filesByPath = files.reduce((acc, file) => {\n\t\t\tacc[file.path] = new TextDecoder().decode(file.data);\n\t\t\treturn acc;\n\t\t}, {} as any);\n\n\t\texpect(filesByPath[\"/cache/plugin/29j49j2\"]).toBe(\"cache value\");\n\t\texpect(filesByPath[\"/.gitignore\"]).toBe(\"git value\");\n\t\texpect(filesByPath[\"/prettierrc.json\"]).toBe(\"prettier value\");\n\t\texpect(filesByPath[\"/README.md\"]).toBe(\"readme value\");\n\t\texpect(filesByPath[\"/settings.json\"]).toBe(JSON.stringify(mockSettings));\n\t});\n\n\t// the test doesn't work on non-windows systems\n\t// mocking the node:path to use backlashes has no effect\n\ttest.skip(\"files from directory should be available via lix if the OS uses backlashes as folder separators\", async () => {\n\t\tconst mockWindowsDirectory = {\n\t\t\t\"\\\\project.inlang\\\\cache\\\\plugin\\\\29j49j2\": \"cache value\",\n\t\t\t\"\\\\project.inlang\\\\.gitignore\": \"git value\",\n\t\t\t\"\\\\project.inlang\\\\prettierrc.json\": \"prettier value\",\n\t\t\t\"\\\\project.inlang\\\\README.md\": \"readme value\",\n\t\t\t\"\\\\project.inlang\\\\settings.json\": JSON.stringify(mockSettings),\n\t\t};\n\n\t\t// Temporarily set the platform to win32\n\t\tObject.defineProperty(process, \"platform\", {\n\t\t\tvalue: \"win32\",\n\t\t});\n\n\t\tObject.defineProperty(nodePath, \"sep\", {\n\t\t\tvalue: \"\\\\\",\n\t\t});\n\n\t\tconst fs = Volume.fromJSON(mockWindowsDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"\\\\project.inlang\",\n\t\t});\n\n\t\tconst files = await project.lix.db.selectFrom(\"file\").selectAll().execute();\n\n\t\texpect(files.length).toBe(\n\t\t\t5 + 1 /* the db.sqlite file */ + 1 /* project_id */\n\t\t);\n\n\t\tconst filesByPath = files.reduce((acc, file) => {\n\t\t\tacc[file.path] = new TextDecoder().decode(file.data);\n\t\t\treturn acc;\n\t\t}, {} as any);\n\n\t\texpect(filesByPath[\"/cache/plugin/29j49j2\"]).toBe(\"cache value\");\n\t\texpect(filesByPath[\"/.gitignore\"]).toBe(\"git value\");\n\t\texpect(filesByPath[\"/prettierrc.json\"]).toBe(\"prettier value\");\n\t\texpect(filesByPath[\"/README.md\"]).toBe(\"readme value\");\n\t\texpect(filesByPath[\"/settings.json\"]).toBe(JSON.stringify(mockSettings));\n\t});\n\n\ttest(\"file created in fs should be avaialable in lix \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\tfs.writeFileSync(\n\t\t\t\"/project.inlang/file-created-on-fs.txt\",\n\t\t\t\"value written by fs\",\n\t\t\t{\n\t\t\t\tencoding: \"utf-8\",\n\t\t\t}\n\t\t);\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\n\t\tconst randomFileInLix = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/file-created-on-fs.txt\")\n\t\t\t.executeTakeFirstOrThrow();\n\n\t\texpect(new TextDecoder().decode(randomFileInLix.data)).toBe(\n\t\t\t\"value written by fs\"\n\t\t);\n\t});\n\n\ttest(\"file updated in fs should be avaialable in lix \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\t// \"changes to a file on disk should reflect in lix\n\t\tfs.writeFileSync(\n\t\t\t\"/project.inlang/settings.json\",\n\t\t\tJSON.stringify({\n\t\t\t\t...mockSettings,\n\t\t\t\tbaseLocale: \"brand-new-locale-written-to-fs-file\",\n\t\t\t})\n\t\t);\n\n\t\t// console.log(\"wrting fs settings\");\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\t\tconst fileInLix = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/settings.json\")\n\t\t\t.executeTakeFirstOrThrow();\n\n\t\tconst settingsAfterUpdateOnDisk = JSON.parse(\n\t\t\tnew TextDecoder().decode(fileInLix.data)\n\t\t);\n\n\t\texpect(settingsAfterUpdateOnDisk.baseLocale).toBe(\n\t\t\t\"brand-new-locale-written-to-fs-file\"\n\t\t);\n\t});\n\n\ttest(\"file deleted in fs should be droped from lix \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\tconst filesInLixBefore = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/README.md\")\n\t\t\t.execute();\n\n\t\texpect(filesInLixBefore.length).toBe(1);\n\n\t\t// \"changes to a file on disk should reflect in lix\n\t\tfs.unlinkSync(\"/project.inlang/README.md\");\n\n\t\t// console.log(\"wrting fs settings\");\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\t\tconst fileInLixAfter = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/README.md\")\n\t\t\t.execute();\n\n\t\texpect(fileInLixAfter.length).toBe(0);\n\t});\n\n\ttest(\"file created in lix should be avaialable in fs \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\tawait project.lix.db\n\t\t\t.insertInto(\"file\")\n\t\t\t.values({\n\t\t\t\tpath: \"/file-created-in.lix.txt\",\n\t\t\t\tdata: new TextEncoder().encode(\"random value lix\"),\n\t\t\t})\n\t\t\t.execute();\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\n\t\tconst randomFileOnDiskContent = fs\n\t\t\t.readFileSync(\"/project.inlang/file-created-in.lix.txt\")\n\t\t\t.toString();\n\t\texpect(randomFileOnDiskContent).toBe(\"random value lix\");\n\t});\n\n\ttest(\"file updated in lix should be avaialable in fs \", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\t// console.log(\"wrting lix settings\");\n\t\t// changes to a file in lix should reflect in the project directory\n\t\tawait project.lix.db\n\t\t\t.updateTable(\"file\")\n\t\t\t.where(\"path\", \"=\", \"/settings.json\")\n\t\t\t.set({\n\t\t\t\tdata: new TextEncoder().encode(\n\t\t\t\t\tJSON.stringify({ ...mockSettings, baseLocale: \"brand-new-locale2\" })\n\t\t\t\t),\n\t\t\t})\n\t\t\t.execute();\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\n\t\tconst fileOnDisk = fs.readFileSync(\"/project.inlang/settings.json\");\n\t\tconst settings = JSON.parse(fileOnDisk.toString());\n\n\t\texpect(settings.baseLocale).toBe(\"brand-new-locale2\");\n\t});\n\n\ttest(\"file deleted in lix should be gone in fs as awell\", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\t// console.log(\"wrting lix settings\");\n\t\t// changes to a file in lix should reflect in the project directory\n\t\tawait project.lix.db\n\t\t\t.deleteFrom(\"file\")\n\t\t\t.where(\"path\", \"=\", \"/.gitignore\")\n\t\t\t.execute();\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, syncInterval + 10));\n\n\t\tconst fileExistsOnDisk = fs.existsSync(\"/project.inlang/.gitignore\");\n\n\t\texpect(fileExistsOnDisk).toBe(false);\n\t});\n\n\ttest(\"file updated in fs and lix (conflicting) should result in the fs state\", async () => {\n\t\tconst syncInterval = 100;\n\t\tconst fs = Volume.fromJSON(mockDirectory);\n\n\t\tconst project = await loadProjectFromDirectory({\n\t\t\tfs: fs as any,\n\t\t\tpath: \"/project.inlang\",\n\t\t\tsyncInterval: syncInterval,\n\t\t});\n\n\t\t// console.log(\"wrting fs settings simultanous\");\n\t\t// changes to a file on disk and lix at the same time should lead to the fs version\n\t\tfs.writeFileSync(\n\t\t\t\"/project.inlang/settings.json\",\n\t\t\tJSON.stringify({ ...mockSettings, baseLocale: \"fs-version\" })\n\t\t);\n\n\t\t// console.log(\"wrting lix settings simultanous\");\n\t\tawait project.lix.db\n\t\t\t.updateTable(\"file\")\n\t\t\t.where(\"path\", \"=\", \"/settings.json\")\n\t\t\t.set({\n\t\t\t\tdata: new TextEncoder().encode(\n\t\t\t\t\tJSON.stringify({ ...mockSettings, baseLocale: \"lix-version\" })\n\t\t\t\t),\n\t\t\t})\n\t\t\t.execute();\n\n\t\t// lets wait a seconds to allow the sync process catch up\n\t\tawait new Promise((resolve) => setTimeout(resolve, 1010));\n\n\t\tconst fileOnDiskUpdated = fs.readFileSync(\"/project.inlang/settings.json\");\n\t\tconst settingsUpdated = JSON.parse(fileOnDiskUpdated.toString());\n\n\t\texpect(settingsUpdated.baseLocale).toBe(\"fs-version\");\n\n\t\tconst fileInLixUpdated = await project.lix.db\n\t\t\t.selectFrom(\"file\")\n\t\t\t.selectAll()\n\t\t\t.where(\"path\", \"=\", \"/settings.json\")\n\t\t\t.executeTakeFirstOrThrow();\n\n\t\tconst settingsAfterUpdateOnDiskAndLix = JSON.parse(\n\t\t\tnew TextDecoder().decode(fileInLixUpdated.data)\n\t\t);\n\n\t\texpect(settingsAfterUpdateOnDiskAndLix.baseLocale).toBe(\"fs-version\");\n\t});\n});\n\ntest(\"errors from importing translation files should be shown\", async () => {\n\tconst mock = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mock);\n\n\tconst proxiedFs = new Proxy(fs, {\n\t\tget: (target, prop) => {\n\t\t\tif (prop === \"promises\") {\n\t\t\t\t// Intercept the 'promises' object\n\t\t\t\treturn new Proxy(target.promises, {\n\t\t\t\t\tget: (promisesTarget, promisesProp) => {\n\t\t\t\t\t\tif (promisesProp === \"readFile\") {\n\t\t\t\t\t\t\t// @ts-expect-error - we are mocking the fs\n\t\t\t\t\t\t\treturn (path, ...args) => {\n\t\t\t\t\t\t\t\tif (path.endsWith(\"some-file.json\")) {\n\t\t\t\t\t\t\t\t\tthrow new Error(\"MOCK ERROR\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn promisesTarget.readFile(path, ...args);\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn Reflect.get(promisesTarget, promisesProp);\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn Reflect.get(target, prop);\n\t\t},\n\t});\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\timportFiles: async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t},\n\t\ttoBeImportedFiles: async () => {\n\t\t\treturn [{ path: \"./some-file.json\", locale: \"mock\" }];\n\t\t},\n\t};\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: proxiedFs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\tconst errors = await project.errors.get();\n\t// TODO deactivated for now - we need to proxy fs.promises or change the signature of loadProject\n\texpect(errors).toHaveLength(1);\n\texpect(errors[0]).toBeInstanceOf(ResourceFileImportError);\n});\n\n// it happens often that a resource file doesn't exist yet on import\ntest(\"errors from importing translation files that are ENOENT should not be shown\", async () => {\n\tconst mock = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mock);\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\timportFiles: async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t},\n\t\ttoBeImportedFiles: async () => {\n\t\t\treturn [{ path: \"./some-non-existing-file.json\", locale: \"mock\" }];\n\t\t},\n\t};\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\tconst errors = await project.errors.get();\n\texpect(errors).toHaveLength(0);\n});\n\n// it happens often that a resource file doesn't exist yet on import\ntest(\"it should pass toBeImportedMetadata on import\", async () => {\n\tconst mock = {\n\t\t\"/foo/en.json\": JSON.stringify({}),\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mock);\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\ttoBeImportedFiles: async () => {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: \"/foo/en.json\",\n\t\t\t\t\tlocale: \"mock\",\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tfoo: \"bar\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\t\t},\n\t\timportFiles: async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t},\n\t};\n\n\tconst toBeSpy = vi.spyOn(mockPlugin, \"toBeImportedFiles\");\n\tconst importSpy = vi.spyOn(mockPlugin, \"importFiles\");\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\texpect(toBeSpy).toHaveBeenCalled();\n\n\texpect(importSpy).toHaveBeenCalledWith(\n\t\texpect.objectContaining({\n\t\t\tfiles: [\n\t\t\t\texpect.objectContaining({\n\t\t\t\t\ttoBeImportedFilesMetadata: {\n\t\t\t\t\t\tfoo: \"bar\",\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t);\n});\n\ntest(\"it should provide plugins from disk for backwards compatibility but warn that those plugins are not portable\", async () => {\n\tconst mockRepo = {\n\t\t\"/local-plugins/mock-plugin.js\": \"export default { key: 'mock-plugin' }\",\n\t\t\"/local-plugins/mock-rule.js\":\n\t\t\t\"export default { id: 'messageLintRule.mock }\",\n\t\t\"/website/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\tmodules: [\n\t\t\t\t\"../local-plugins/mock-plugin.js\",\n\t\t\t\t\"../local-plugins/mock-rule.js\",\n\t\t\t],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/website/project.inlang\",\n\t});\n\n\tconst plugins = await project.plugins.get();\n\tconst errors = await project.errors.get();\n\tconst settings = await project.settings.get();\n\n\texpect(plugins.length).toBe(1);\n\texpect(plugins[0]?.key).toBe(\"mock-plugin\");\n\n\texpect(errors.length).toBe(1);\n\texpect(errors[0]).toBeInstanceOf(WarningDeprecatedLintRule);\n\n\t// it should not remove the module from the settings\n\t// else roundtrips would not work\n\texpect(settings.modules?.[0]).toBe(\"../local-plugins/mock-plugin.js\");\n});\n\n// https://github.com/opral/inlang-sdk/issues/174\ntest(\"plugin calls that use fs should be intercepted to use an absolute path\", async () => {\n\tprocess.cwd = () => \"/\";\n\n\tconst mockRepo = {\n\t\t\"/messages/en.json\": JSON.stringify({\n\t\t\tkey1: \"value1\",\n\t\t\tkey2: \"value2\",\n\t\t}),\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\", \"de\"],\n\t\t\t\"plugin.mock-plugin\": {\n\t\t\t\tpathPattern: \"./messages/{locale}.json\",\n\t\t\t},\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\tloadMessages: async ({ nodeishFs, settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern.replace(\n\t\t\t\t\"{locale}\",\n\t\t\t\t\"en\"\n\t\t\t) as string;\n\t\t\tconst file = await nodeishFs.readFile(pathPattern);\n\t\t\t// reading the file should be possible without an error\n\t\t\texpect(file.toString()).toBe(\n\t\t\t\tJSON.stringify({\n\t\t\t\t\tkey1: \"value1\",\n\t\t\t\t\tkey2: \"value2\",\n\t\t\t\t})\n\t\t\t);\n\t\t\treturn [];\n\t\t},\n\t\tsaveMessages: async ({ nodeishFs, settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern.replace(\n\t\t\t\t\"{locale}\",\n\t\t\t\t\"en\"\n\t\t\t) as string;\n\t\t\tconst file = new TextEncoder().encode(\n\t\t\t\tJSON.stringify({\n\t\t\t\t\tkey1: \"value1\",\n\t\t\t\t\tkey2: \"value2\",\n\t\t\t\t\tkey3: \"value3\",\n\t\t\t\t})\n\t\t\t);\n\t\t\tawait nodeishFs.writeFile(pathPattern, file.buffer as ArrayBuffer);\n\t\t},\n\t\ttoBeImportedFiles: async ({ settings }) => {\n\t\t\tconst pathPattern = settings[\"plugin.mock-plugin\"]?.pathPattern.replace(\n\t\t\t\t\"{locale}\",\n\t\t\t\t\"en\"\n\t\t\t) as string;\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tpath: pathPattern,\n\t\t\t\t\tlocale: \"en\",\n\t\t\t\t},\n\t\t\t];\n\t\t},\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst loadMessagesSpy = vi.spyOn(mockPlugin, \"loadMessages\");\n\tconst saveMessagesSpy = vi.spyOn(mockPlugin, \"saveMessages\");\n\tconst toBeImportedFilesSpy = vi.spyOn(mockPlugin, \"toBeImportedFiles\");\n\tconst fsReadFileSpy = vi.spyOn(fs.promises, \"readFile\");\n\tconst fsWriteFileSpy = vi.spyOn(fs.promises, \"writeFile\");\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\texpect(loadMessagesSpy).toHaveBeenCalled();\n\texpect(fsReadFileSpy).toHaveBeenCalledWith(\"/messages/en.json\", undefined);\n\n\t// todo test that saveMessages works too.\n\t// await project.db.insertInto(\"bundle\").defaultValues().execute();\n\n\t// const translationFile = await fs.readFile(\"/messages/en.json\", \"utf-8\");\n\n\t// expect(translationFile).toBe(\n\t// \tJSON.stringify({\n\t// \t\tkey1: \"value1\",\n\t// \t\tkey2: \"value2\",\n\t// \t\tkey3: \"value3\",\n\t// \t})\n\t// );\n\n\t// expect(fsWriteFileSpy).toHaveBeenCalledWith(\n\t// \t\"/messages/en.json\",\n\t// \tJSON.stringify({\n\t// \t\tkey1: \"value1\",\n\t// \t\tkey2: \"value2\",\n\t// \t\tkey3: \"value3\",\n\t// \t}),\n\t// \t\"utf-8\"\n\t// );\n\n\t// expect(saveMessagesSpy).toHaveBeenCalled();\n\t// expect(toBeImportedFilesSpy).toHaveBeenCalled();\n});\n\ntest(\"it can import plugins via http\", async () => {\n\tconst mockRepo = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\"],\n\t\t\tmodules: [\"https://example.com/plugin.js\"],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst mockPluginModule = `export default {\n\t\t\tkey: \"mock-plugin\"\t\n\t\t}`;\n\n\tglobal.fetch = vi.fn(() => Promise.resolve(new Response(mockPluginModule)));\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t});\n\n\tconst plugins = await project.plugins.get();\n\n\texpect(global.fetch).toHaveBeenCalledWith(\"https://example.com/plugin.js\");\n\texpect(plugins.length).toBe(1);\n\n\tconst pluginCache = await project.lix.db\n\t\t.selectFrom(\"file\")\n\t\t.selectAll()\n\t\t.where(\"path\", \"like\", \"/cache/plugins/%\")\n\t\t.execute();\n\n\texpect(\n\t\tpluginCache.some(\n\t\t\t(file) => new TextDecoder().decode(file.data) === mockPluginModule\n\t\t),\n\t\t\"expecting the plugin to be cached\"\n\t).toBe(true);\n});\n\ntest(\"plugins that provide both loadMessages and importFiles should be allowed and the importFiles should be called\", async () => {\n\tconst mockRepo = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst mockPlugin: InlangPlugin = {\n\t\tkey: \"mock-plugin\",\n\t\tloadMessages: vi.fn(async () => []),\n\t\timportFiles: vi.fn(async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t}),\n\t};\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin],\n\t});\n\n\texpect(mockPlugin.importFiles).toHaveBeenCalled();\n\texpect(mockPlugin.loadMessages).not.toHaveBeenCalled();\n});\n\ntest(\"providing multiple plugins that have legacy loadMessages and saveMessages function should be possible if they have import/export functions\", async () => {\n\tconst mockRepo = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst mockPlugin1: InlangPlugin = {\n\t\tkey: \"mock-plugin1\",\n\t\tloadMessages: vi.fn(async () => []),\n\t\timportFiles: vi.fn(async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t}),\n\t};\n\n\tconst mockPlugin2: InlangPlugin = {\n\t\tkey: \"mock-plugin2\",\n\t\tloadMessages: vi.fn(async () => []),\n\t\timportFiles: vi.fn(async () => {\n\t\t\treturn { bundles: [], messages: [], variants: [] };\n\t\t}),\n\t};\n\n\tconst project = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t\tprovidePlugins: [mockPlugin1, mockPlugin2],\n\t});\n\n\texpect(mockPlugin1.importFiles).toHaveBeenCalled();\n\texpect(mockPlugin1.loadMessages).not.toHaveBeenCalled();\n\n\texpect(mockPlugin2.importFiles).toHaveBeenCalled();\n\texpect(mockPlugin2.loadMessages).not.toHaveBeenCalled();\n});\n\n// https://github.com/opral/inlang-sdk/issues/228\ntest(\"the lix id should be stable between loadings of the same project\", async () => {\n\tconst mockRepo = {\n\t\t\"/project.inlang/settings.json\": JSON.stringify({\n\t\t\tbaseLocale: \"en\",\n\t\t\tlocales: [\"en\"],\n\t\t\tmodules: [],\n\t\t} satisfies ProjectSettings),\n\t};\n\n\tconst fs = Volume.fromJSON(mockRepo);\n\n\tconst project1 = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t});\n\n\tconst inlangId = await project1.id.get();\n\n\tconst { value: lixId } = await project1.lix.db\n\t\t.selectFrom(\"key_value\")\n\t\t.where(\"key\", \"=\", \"lix_id\")\n\t\t.selectAll()\n\t\t.executeTakeFirstOrThrow();\n\n\t// the project_id file does not exist on the first load\n\tawait saveProjectToDirectory({\n\t\tfs: fs.promises as any,\n\t\tpath: \"/project.inlang\",\n\t\tproject: project1,\n\t});\n\n\tconst project2 = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t});\n\n\tconst inlangId2 = await project2.id.get();\n\n\tconst { value: lixId2 } = await project2.lix.db\n\t\t.selectFrom(\"key_value\")\n\t\t.where(\"key\", \"=\", \"lix_id\")\n\t\t.selectAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst project3 = await loadProjectFromDirectory({\n\t\tfs: fs as any,\n\t\tpath: \"/project.inlang\",\n\t});\n\n\tconst inlangId3 = await project3.id.get();\n\tconst { value: lixId3 } = await project3.lix.db\n\t\t.selectFrom(\"key_value\")\n\t\t.where(\"key\", \"=\", \"lix_id\")\n\t\t.selectAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(inlangId).not.toBeUndefined();\n\texpect(inlangId).toBe(inlangId2);\n\texpect(inlangId).toBe(inlangId3);\n\n\texpect(lixId).not.toBeUndefined();\n\texpect(lixId).toBe(lixId2);\n\texpect(lixId).toBe(lixId3);\n});\n"]}
@@ -1,8 +1,10 @@
1
+ import { type NewKeyValue } from "@lix-js/sdk";
1
2
  import { loadProject } from "./loadProject.js";
2
3
  /**
3
4
  * Load a project from a blob in memory.
4
5
  */
5
6
  export declare function loadProjectInMemory(args: {
6
7
  blob: Blob;
8
+ lixKeyValues?: NewKeyValue[];
7
9
  } & Omit<Parameters<typeof loadProject>[0], "sqlite" | "lix">): Promise<import("./api.js").InlangProject>;
8
10
  //# sourceMappingURL=loadProjectInMemory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loadProjectInMemory.d.ts","sourceRoot":"/","sources":["project/loadProjectInMemory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;GAEG;AACH,wBAAsB,mBAAmB,CACxC,IAAI,EAAE;IACL,IAAI,EAAE,IAAI,CAAC;CACX,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,6CAyB7D"}
1
+ {"version":3,"file":"loadProjectInMemory.d.ts","sourceRoot":"/","sources":["project/loadProjectInMemory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;GAEG;AACH,wBAAsB,mBAAmB,CACxC,IAAI,EAAE;IACL,IAAI,EAAE,IAAI,CAAC;IACX,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,6CA0B7D"}
@@ -8,6 +8,7 @@ export async function loadProjectInMemory(args) {
8
8
  const lix = await openLixInMemory({
9
9
  blob: args.blob,
10
10
  account: args.account,
11
+ keyValues: args.lixKeyValues,
11
12
  providePlugins: [
12
13
  // inlangLixPluginV1
13
14
  ],
@@ -1 +1 @@
1
- {"version":3,"file":"loadProjectInMemory.js","sourceRoot":"/","sources":["project/loadProjectInMemory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,IAE6D;IAE7D,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC;QACjC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,cAAc,EAAE;QACf,oBAAoB;SACpB;KACD,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE;SACzB,UAAU,CAAC,MAAM,CAAC;SAClB,MAAM,CAAC,MAAM,CAAC;SACd,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,YAAY,CAAC;SAChC,uBAAuB,EAAE,CAAC;IAE5B,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAChD,cAAc,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAErE,OAAO,MAAM,WAAW,CAAC;QACxB,uCAAuC;QACvC,GAAG,IAAI;QACP,MAAM;QACN,GAAG;KACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { openLixInMemory } from \"@lix-js/sdk\";\nimport { createInMemoryDatabase, importDatabase } from \"sqlite-wasm-kysely\";\nimport { loadProject } from \"./loadProject.js\";\n\n/**\n * Load a project from a blob in memory.\n */\nexport async function loadProjectInMemory(\n\targs: {\n\t\tblob: Blob;\n\t} & Omit<Parameters<typeof loadProject>[0], \"sqlite\" | \"lix\">\n) {\n\tconst lix = await openLixInMemory({\n\t\tblob: args.blob,\n\t\taccount: args.account,\n\t\tprovidePlugins: [\n\t\t\t// inlangLixPluginV1\n\t\t],\n\t});\n\n\tconst dbFile = await lix.db\n\t\t.selectFrom(\"file\")\n\t\t.select(\"data\")\n\t\t.where(\"path\", \"=\", \"/db.sqlite\")\n\t\t.executeTakeFirstOrThrow();\n\n\tconst sqlite = await createInMemoryDatabase({});\n\timportDatabase({ db: sqlite, content: new Uint8Array(dbFile.data) });\n\n\treturn await loadProject({\n\t\t// pass common arguments to loadProject\n\t\t...args,\n\t\tsqlite,\n\t\tlix,\n\t});\n}\n"]}
1
+ {"version":3,"file":"loadProjectInMemory.js","sourceRoot":"/","sources":["project/loadProjectInMemory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAoB,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,IAG6D;IAE7D,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC;QACjC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,SAAS,EAAE,IAAI,CAAC,YAAY;QAC5B,cAAc,EAAE;QACf,oBAAoB;SACpB;KACD,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE;SACzB,UAAU,CAAC,MAAM,CAAC;SAClB,MAAM,CAAC,MAAM,CAAC;SACd,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,YAAY,CAAC;SAChC,uBAAuB,EAAE,CAAC;IAE5B,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAChD,cAAc,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAErE,OAAO,MAAM,WAAW,CAAC;QACxB,uCAAuC;QACvC,GAAG,IAAI;QACP,MAAM;QACN,GAAG;KACH,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import { openLixInMemory, type NewKeyValue } from \"@lix-js/sdk\";\nimport { createInMemoryDatabase, importDatabase } from \"sqlite-wasm-kysely\";\nimport { loadProject } from \"./loadProject.js\";\n\n/**\n * Load a project from a blob in memory.\n */\nexport async function loadProjectInMemory(\n\targs: {\n\t\tblob: Blob;\n\t\tlixKeyValues?: NewKeyValue[];\n\t} & Omit<Parameters<typeof loadProject>[0], \"sqlite\" | \"lix\">\n) {\n\tconst lix = await openLixInMemory({\n\t\tblob: args.blob,\n\t\taccount: args.account,\n\t\tkeyValues: args.lixKeyValues,\n\t\tprovidePlugins: [\n\t\t\t// inlangLixPluginV1\n\t\t],\n\t});\n\n\tconst dbFile = await lix.db\n\t\t.selectFrom(\"file\")\n\t\t.select(\"data\")\n\t\t.where(\"path\", \"=\", \"/db.sqlite\")\n\t\t.executeTakeFirstOrThrow();\n\n\tconst sqlite = await createInMemoryDatabase({});\n\timportDatabase({ db: sqlite, content: new Uint8Array(dbFile.data) });\n\n\treturn await loadProject({\n\t\t// pass common arguments to loadProject\n\t\t...args,\n\t\tsqlite,\n\t\tlix,\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"newProject.d.ts","sourceRoot":"/","sources":["project/newProject.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAOlE;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,CAAC,EAAE;IACvC,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CA8ChB;AAED,eAAO,MAAM,sBAAsB;;;;;CAcR,CAAC"}
1
+ {"version":3,"file":"newProject.d.ts","sourceRoot":"/","sources":["project/newProject.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAOlE;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,CAAC,EAAE;IACvC,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAoDhB;AAED,eAAO,MAAM,sBAAsB;;;;;CAcR,CAAC"}
@@ -1,5 +1,4 @@
1
1
  import { newLixFile, openLixInMemory, toBlob } from "@lix-js/sdk";
2
- import { v4 } from "uuid";
3
2
  import { contentFromDatabase, createInMemoryDatabase, } from "sqlite-wasm-kysely";
4
3
  import { initDb } from "../database/initDb.js";
5
4
  /**
@@ -16,6 +15,11 @@ export async function newProject(args) {
16
15
  try {
17
16
  const inlangDbContent = contentFromDatabase(sqlite);
18
17
  const lix = await openLixInMemory({ blob: await newLixFile() });
18
+ const { value: lixId } = await lix.db
19
+ .selectFrom("key_value")
20
+ .select("value")
21
+ .where("key", "=", "lix_id")
22
+ .executeTakeFirstOrThrow();
19
23
  // write files to lix
20
24
  await lix.db
21
25
  .insertInto("file")
@@ -30,7 +34,7 @@ export async function newProject(args) {
30
34
  },
31
35
  {
32
36
  path: "/project_id",
33
- data: new TextEncoder().encode(v4()),
37
+ data: new TextEncoder().encode(lixId),
34
38
  },
35
39
  ])
36
40
  .execute();
@@ -1 +1 @@
1
- {"version":3,"file":"newProject.js","sourceRoot":"/","sources":["project/newProject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAE1B,OAAO,EACN,mBAAmB,EACnB,sBAAsB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAEhC;IACA,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC;QAC3C,QAAQ,EAAE,KAAK;KACf,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAEnB,IAAI,CAAC;QACJ,MAAM,eAAe,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAEpD,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAEhE,qBAAqB;QACrB,MAAM,GAAG,CAAC,EAAE;aACV,UAAU,CAAC,MAAM,CAAC;aAClB,MAAM,CAAC;YACP;gBACC,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,eAAe;aACrB;YACD;gBACC,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAC7B,IAAI,CAAC,SAAS,CACb,IAAI,EAAE,QAAQ,IAAI,sBAAsB,EACxC,SAAS,EACT,CAAC,CACD,CACD;aACD;YACD;gBACC,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;aACpC;SACD,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7B,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,wCAAwC,CAAC,EAAE,EAAE;YACpE,KAAK,EAAE,CAAC;SACR,CAAC,CAAC;QACH,MAAM,KAAK,CAAC;IACb,CAAC;YAAS,CAAC;QACV,MAAM,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,OAAO,EAAE,4CAA4C;IACrD,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,CAAC,IAAI,CAAC;IACf,OAAO,EAAE;IACR,uDAAuD;IACvD,+FAA+F;IAC/F,qGAAqG;IACrG,gGAAgG;IAChG,wEAAwE;IACxE,qFAAqF;IACrF,wGAAwG;IACxG,yFAAyF;KACzF;CACyB,CAAC","sourcesContent":["import { newLixFile, openLixInMemory, toBlob } from \"@lix-js/sdk\";\nimport { v4 } from \"uuid\";\nimport type { ProjectSettings } from \"../json-schema/settings.js\";\nimport {\n\tcontentFromDatabase,\n\tcreateInMemoryDatabase,\n} from \"sqlite-wasm-kysely\";\nimport { initDb } from \"../database/initDb.js\";\n\n/**\n * Creates a new inlang project.\n *\n * The app is responsible for saving the project \"whereever\"\n * e.g. the user's computer, cloud storage, or OPFS in the browser.\n */\nexport async function newProject(args?: {\n\tsettings?: ProjectSettings;\n}): Promise<Blob> {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tinitDb({ sqlite });\n\n\ttry {\n\t\tconst inlangDbContent = contentFromDatabase(sqlite);\n\n\t\tconst lix = await openLixInMemory({ blob: await newLixFile() });\n\n\t\t// write files to lix\n\t\tawait lix.db\n\t\t\t.insertInto(\"file\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\t\tdata: inlangDbContent,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: \"/settings.json\",\n\t\t\t\t\tdata: new TextEncoder().encode(\n\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\targs?.settings ?? defaultProjectSettings,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t2\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: \"/project_id\",\n\t\t\t\t\tdata: new TextEncoder().encode(v4()),\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst blob = toBlob({ lix });\n\t\tlix.sqlite.close();\n\t\treturn blob;\n\t} catch (e) {\n\t\tconst error = new Error(`Failed to create new inlang project: ${e}`, {\n\t\t\tcause: e,\n\t\t});\n\t\tthrow error;\n\t} finally {\n\t\tsqlite.close();\n\t}\n}\n\nexport const defaultProjectSettings = {\n\t$schema: \"https://inlang.com/schema/project-settings\",\n\tbaseLocale: \"en\",\n\tlocales: [\"en\"],\n\tmodules: [\n\t\t// for instant gratification, we're adding common rules\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@latest/dist/index.js\",\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@latest/dist/index.js\",\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@latest/dist/index.js\",\n\t\t// default to the message format plugin because it supports all features\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@latest/dist/index.js\",\n\t\t// the m function matcher should be installed by default in case Sherlock (VS Code extension) is adopted\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@latest/dist/index.js\",\n\t],\n} satisfies ProjectSettings;\n"]}
1
+ {"version":3,"file":"newProject.js","sourceRoot":"/","sources":["project/newProject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,EACN,mBAAmB,EACnB,sBAAsB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAEhC;IACA,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC;QAC3C,QAAQ,EAAE,KAAK;KACf,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAEnB,IAAI,CAAC;QACJ,MAAM,eAAe,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAEpD,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAEhE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,EAAE;aACnC,UAAU,CAAC,WAAW,CAAC;aACvB,MAAM,CAAC,OAAO,CAAC;aACf,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC;aAC3B,uBAAuB,EAAE,CAAC;QAE5B,qBAAqB;QACrB,MAAM,GAAG,CAAC,EAAE;aACV,UAAU,CAAC,MAAM,CAAC;aAClB,MAAM,CAAC;YACP;gBACC,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,eAAe;aACrB;YACD;gBACC,IAAI,EAAE,gBAAgB;gBACtB,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAC7B,IAAI,CAAC,SAAS,CACb,IAAI,EAAE,QAAQ,IAAI,sBAAsB,EACxC,SAAS,EACT,CAAC,CACD,CACD;aACD;YACD;gBACC,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;aACrC;SACD,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7B,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,wCAAwC,CAAC,EAAE,EAAE;YACpE,KAAK,EAAE,CAAC;SACR,CAAC,CAAC;QACH,MAAM,KAAK,CAAC;IACb,CAAC;YAAS,CAAC;QACV,MAAM,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,OAAO,EAAE,4CAA4C;IACrD,UAAU,EAAE,IAAI;IAChB,OAAO,EAAE,CAAC,IAAI,CAAC;IACf,OAAO,EAAE;IACR,uDAAuD;IACvD,+FAA+F;IAC/F,qGAAqG;IACrG,gGAAgG;IAChG,wEAAwE;IACxE,qFAAqF;IACrF,wGAAwG;IACxG,yFAAyF;KACzF;CACyB,CAAC","sourcesContent":["import { newLixFile, openLixInMemory, toBlob } from \"@lix-js/sdk\";\nimport type { ProjectSettings } from \"../json-schema/settings.js\";\nimport {\n\tcontentFromDatabase,\n\tcreateInMemoryDatabase,\n} from \"sqlite-wasm-kysely\";\nimport { initDb } from \"../database/initDb.js\";\n\n/**\n * Creates a new inlang project.\n *\n * The app is responsible for saving the project \"whereever\"\n * e.g. the user's computer, cloud storage, or OPFS in the browser.\n */\nexport async function newProject(args?: {\n\tsettings?: ProjectSettings;\n}): Promise<Blob> {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tinitDb({ sqlite });\n\n\ttry {\n\t\tconst inlangDbContent = contentFromDatabase(sqlite);\n\n\t\tconst lix = await openLixInMemory({ blob: await newLixFile() });\n\n\t\tconst { value: lixId } = await lix.db\n\t\t\t.selectFrom(\"key_value\")\n\t\t\t.select(\"value\")\n\t\t\t.where(\"key\", \"=\", \"lix_id\")\n\t\t\t.executeTakeFirstOrThrow();\n\n\t\t// write files to lix\n\t\tawait lix.db\n\t\t\t.insertInto(\"file\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\t\tdata: inlangDbContent,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: \"/settings.json\",\n\t\t\t\t\tdata: new TextEncoder().encode(\n\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\targs?.settings ?? defaultProjectSettings,\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\t2\n\t\t\t\t\t\t)\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: \"/project_id\",\n\t\t\t\t\tdata: new TextEncoder().encode(lixId),\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst blob = toBlob({ lix });\n\t\tlix.sqlite.close();\n\t\treturn blob;\n\t} catch (e) {\n\t\tconst error = new Error(`Failed to create new inlang project: ${e}`, {\n\t\t\tcause: e,\n\t\t});\n\t\tthrow error;\n\t} finally {\n\t\tsqlite.close();\n\t}\n}\n\nexport const defaultProjectSettings = {\n\t$schema: \"https://inlang.com/schema/project-settings\",\n\tbaseLocale: \"en\",\n\tlocales: [\"en\"],\n\tmodules: [\n\t\t// for instant gratification, we're adding common rules\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-empty-pattern@latest/dist/index.js\",\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-missing-translation@latest/dist/index.js\",\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/message-lint-rule-without-source@latest/dist/index.js\",\n\t\t// default to the message format plugin because it supports all features\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@latest/dist/index.js\",\n\t\t// the m function matcher should be installed by default in case Sherlock (VS Code extension) is adopted\n\t\t// \"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@latest/dist/index.js\",\n\t],\n} satisfies ProjectSettings;\n"]}
@@ -1,7 +1,6 @@
1
1
  import { expect, test } from "vitest";
2
2
  import { defaultProjectSettings, newProject } from "./newProject.js";
3
3
  import { loadProjectInMemory } from "./loadProjectInMemory.js";
4
- import { validate } from "uuid";
5
4
  test("it should be possible to provide settings for testing or other purposes", async () => {
6
5
  const project = await loadProjectInMemory({
7
6
  blob: await newProject({
@@ -23,12 +22,20 @@ test("it should be possible to create a project with default settings", async ()
23
22
  delete settings.sourceLanguageTag;
24
23
  expect(settings).toStrictEqual(defaultProjectSettings);
25
24
  });
26
- test("it should have a uuid as project id", async () => {
25
+ // for historical reasons, inlang files introduced a project id
26
+ // before lix'es got their own id. having two ids for the same
27
+ // file is not needed anymore.
28
+ test("it should have the lix id as project id", async () => {
27
29
  const project = await loadProjectInMemory({
28
30
  blob: await newProject(),
29
31
  });
32
+ const { value: lixId } = await project.lix.db
33
+ .selectFrom("key_value")
34
+ .select("value")
35
+ .where("key", "=", "lix_id")
36
+ .executeTakeFirstOrThrow();
30
37
  const projectId = await project.id.get();
31
38
  expect(projectId).toBeDefined();
32
- expect(validate(projectId)).toBe(true);
39
+ expect(projectId).toBe(lixId);
33
40
  });
34
41
  //# sourceMappingURL=newProject.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"newProject.test.js","sourceRoot":"/","sources":["project/newProject.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEhC,IAAI,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;IAC1F,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACzC,IAAI,EAAE,MAAM,UAAU,CAAC;YACtB,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;SAC5D,CAAC;KACF,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAC9C,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;IAClF,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACzC,IAAI,EAAE,MAAM,UAAU,EAAE;KACxB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAC9C,2DAA2D;IAC3D,OAAO,QAAQ,CAAC,YAAY,CAAC;IAC7B,OAAO,QAAQ,CAAC,iBAAiB,CAAC;IAClC,MAAM,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;IACtD,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACzC,IAAI,EAAE,MAAM,UAAU,EAAE;KACxB,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC","sourcesContent":["import { expect, test } from \"vitest\";\nimport { defaultProjectSettings, newProject } from \"./newProject.js\";\nimport { loadProjectInMemory } from \"./loadProjectInMemory.js\";\nimport { validate } from \"uuid\";\n\ntest(\"it should be possible to provide settings for testing or other purposes\", async () => {\n\tconst project = await loadProjectInMemory({\n\t\tblob: await newProject({\n\t\t\tsettings: { baseLocale: \"fr\", locales: [\"fr\"], modules: [] },\n\t\t}),\n\t});\n\tconst settings = await project.settings.get();\n\texpect(settings.baseLocale).toBe(\"fr\");\n\texpect(settings.locales).toEqual([\"fr\"]);\n\texpect(settings.modules).toEqual([]);\n});\n\ntest(\"it should be possible to create a project with default settings\", async () => {\n\tconst project = await loadProjectInMemory({\n\t\tblob: await newProject(),\n\t});\n\tconst settings = await project.settings.get();\n\t// pruning old settings that might exist for legacy reasons\n\tdelete settings.languageTags;\n\tdelete settings.sourceLanguageTag;\n\texpect(settings).toStrictEqual(defaultProjectSettings);\n});\n\ntest(\"it should have a uuid as project id\", async () => {\n\tconst project = await loadProjectInMemory({\n\t\tblob: await newProject(),\n\t});\n\tconst projectId = await project.id.get();\n\texpect(projectId).toBeDefined();\n\texpect(validate(projectId)).toBe(true);\n});\n"]}
1
+ {"version":3,"file":"newProject.test.js","sourceRoot":"/","sources":["project/newProject.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,IAAI,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;IAC1F,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACzC,IAAI,EAAE,MAAM,UAAU,CAAC;YACtB,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE;SAC5D,CAAC;KACF,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAC9C,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;IAClF,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACzC,IAAI,EAAE,MAAM,UAAU,EAAE;KACxB,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAC9C,2DAA2D;IAC3D,OAAO,QAAQ,CAAC,YAAY,CAAC;IAC7B,OAAO,QAAQ,CAAC,iBAAiB,CAAC;IAClC,MAAM,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,sBAAsB,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AAEH,+DAA+D;AAC/D,8DAA8D;AAC9D,8BAA8B;AAC9B,IAAI,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;IAC1D,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC;QACzC,IAAI,EAAE,MAAM,UAAU,EAAE;KACxB,CAAC,CAAC;IACH,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE;SAC3C,UAAU,CAAC,WAAW,CAAC;SACvB,MAAM,CAAC,OAAO,CAAC;SACf,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC;SAC3B,uBAAuB,EAAE,CAAC;IAE5B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;IAChC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC","sourcesContent":["import { expect, test } from \"vitest\";\nimport { defaultProjectSettings, newProject } from \"./newProject.js\";\nimport { loadProjectInMemory } from \"./loadProjectInMemory.js\";\n\ntest(\"it should be possible to provide settings for testing or other purposes\", async () => {\n\tconst project = await loadProjectInMemory({\n\t\tblob: await newProject({\n\t\t\tsettings: { baseLocale: \"fr\", locales: [\"fr\"], modules: [] },\n\t\t}),\n\t});\n\tconst settings = await project.settings.get();\n\texpect(settings.baseLocale).toBe(\"fr\");\n\texpect(settings.locales).toEqual([\"fr\"]);\n\texpect(settings.modules).toEqual([]);\n});\n\ntest(\"it should be possible to create a project with default settings\", async () => {\n\tconst project = await loadProjectInMemory({\n\t\tblob: await newProject(),\n\t});\n\tconst settings = await project.settings.get();\n\t// pruning old settings that might exist for legacy reasons\n\tdelete settings.languageTags;\n\tdelete settings.sourceLanguageTag;\n\texpect(settings).toStrictEqual(defaultProjectSettings);\n});\n\n// for historical reasons, inlang files introduced a project id\n// before lix'es got their own id. having two ids for the same\n// file is not needed anymore.\ntest(\"it should have the lix id as project id\", async () => {\n\tconst project = await loadProjectInMemory({\n\t\tblob: await newProject(),\n\t});\n\tconst { value: lixId } = await project.lix.db\n\t\t.selectFrom(\"key_value\")\n\t\t.select(\"value\")\n\t\t.where(\"key\", \"=\", \"lix_id\")\n\t\t.executeTakeFirstOrThrow();\n\n\tconst projectId = await project.id.get();\n\texpect(projectId).toBeDefined();\n\texpect(projectId).toBe(lixId);\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"saveProjectToDirectory.d.ts","sourceRoot":"/","sources":["project/saveProjectToDirectory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAU9C,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IAClD,EAAE,EAAE,OAAO,EAAE,CAAC;IACd,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,IAAI,CAAC,CAgGhB"}
1
+ {"version":3,"file":"saveProjectToDirectory.d.ts","sourceRoot":"/","sources":["project/saveProjectToDirectory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAU9C,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IAClD,EAAE,EAAE,OAAO,EAAE,CAAC;IACd,OAAO,EAAE,aAAa,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,IAAI,CAAC,CAmGhB"}
@@ -53,7 +53,7 @@ export async function saveProjectToDirectory(args) {
53
53
  for (const file of files) {
54
54
  const pathPattern = settings[plugin.key]?.pathPattern;
55
55
  const p = pathPattern
56
- ? pathPattern.replace(/\{(languageTag|locale)\}/g, file.locale)
56
+ ? absolutePathFromProject(args.path, pathPattern.replace(/\{(languageTag|locale)\}/g, file.locale))
57
57
  : absolutePathFromProject(args.path, file.name);
58
58
  const dirname = path.dirname(p);
59
59
  if ((await args.fs.stat(dirname)).isDirectory() === false) {
@@ -1 +1 @@
1
- {"version":3,"file":"saveProjectToDirectory.js","sourceRoot":"/","sources":["project/saveProjectToDirectory.ts"],"names":[],"mappings":"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","sourcesContent":["import type fs from \"node:fs/promises\";\nimport type { InlangProject } from \"./api.js\";\nimport path from \"node:path\";\nimport { toMessageV1 } from \"../json-schema/old-v1-message/toMessageV1.js\";\nimport {\n\tabsolutePathFromProject,\n\twithAbsolutePaths,\n} from \"./loadProjectFromDirectory.js\";\nimport { detectJsonFormatting } from \"../utilities/detectJsonFormatting.js\";\nimport { selectBundleNested } from \"../query-utilities/selectBundleNested.js\";\n\nexport async function saveProjectToDirectory(args: {\n\tfs: typeof fs;\n\tproject: InlangProject;\n\tpath: string;\n}): Promise<void> {\n\tif (args.path.endsWith(\".inlang\") === false) {\n\t\tthrow new Error(\"The path must end with .inlang\");\n\t}\n\tconst files = await args.project.lix.db\n\t\t.selectFrom(\"file\")\n\t\t.selectAll()\n\t\t.execute();\n\n\tlet hasGitignore = false;\n\n\t// write all files to the directory\n\tfor (const file of files) {\n\t\tif (file.path.endsWith(\"db.sqlite\")) {\n\t\t\tcontinue;\n\t\t} else if (file.path.endsWith(\".gitignore\")) {\n\t\t\thasGitignore = true;\n\t\t}\n\t\tconst p = path.join(args.path, file.path);\n\t\tawait args.fs.mkdir(path.dirname(p), { recursive: true });\n\t\tawait args.fs.writeFile(p, new Uint8Array(file.data));\n\t}\n\n\tif (hasGitignore === false) {\n\t\tawait args.fs.writeFile(\n\t\t\tpath.join(args.path, \".gitignore\"),\n\t\t\tnew TextEncoder().encode(\"cache\")\n\t\t);\n\t}\n\n\t// run exporters\n\tconst plugins = await args.project.plugins.get();\n\tconst settings = await args.project.settings.get();\n\n\tfor (const plugin of plugins) {\n\t\tif (plugin.exportFiles) {\n\t\t\tconst bundles = await args.project.db\n\t\t\t\t.selectFrom(\"bundle\")\n\t\t\t\t.selectAll()\n\t\t\t\t.execute();\n\t\t\tconst messages = await args.project.db\n\t\t\t\t.selectFrom(\"message\")\n\t\t\t\t.selectAll()\n\t\t\t\t.execute();\n\t\t\tconst variants = await args.project.db\n\t\t\t\t.selectFrom(\"variant\")\n\t\t\t\t.selectAll()\n\t\t\t\t.execute();\n\t\t\tconst files = await plugin.exportFiles({\n\t\t\t\tbundles,\n\t\t\t\tmessages,\n\t\t\t\tvariants,\n\t\t\t\tsettings,\n\t\t\t});\n\t\t\tfor (const file of files) {\n\t\t\t\tconst pathPattern = settings[plugin.key]?.pathPattern;\n\t\t\t\tconst p = pathPattern\n\t\t\t\t\t? pathPattern.replace(/\\{(languageTag|locale)\\}/g, file.locale)\n\t\t\t\t\t: absolutePathFromProject(args.path, file.name);\n\t\t\t\tconst dirname = path.dirname(p);\n\t\t\t\tif ((await args.fs.stat(dirname)).isDirectory() === false) {\n\t\t\t\t\tawait args.fs.mkdir(dirname, { recursive: true });\n\t\t\t\t}\n\t\t\t\tif (p.endsWith(\".json\")) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst existing = await args.fs.readFile(p, \"utf-8\");\n\t\t\t\t\t\tconst stringify = detectJsonFormatting(existing);\n\t\t\t\t\t\tawait args.fs.writeFile(\n\t\t\t\t\t\t\tp,\n\t\t\t\t\t\t\tnew TextEncoder().encode(\n\t\t\t\t\t\t\t\tstringify(JSON.parse(new TextDecoder().decode(file.content)))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// write the file to disk (json doesn't exist yet)\n\t\t\t\t\t\t// yeah ugly duplication of write file but it works.\n\t\t\t\t\t\tawait args.fs.writeFile(p, new Uint8Array(file.content));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tawait args.fs.writeFile(p, new Uint8Array(file.content));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// old legacy remove with v3\n\t\telse if (plugin.saveMessages) {\n\t\t\t// in-efficient re-qeuery but it's a legacy function that will be removed.\n\t\t\t// the effort of adjusting the code to not re-query is not worth it.\n\t\t\tconst bundlesNested = await selectBundleNested(args.project.db).execute();\n\t\t\tawait plugin.saveMessages({\n\t\t\t\tmessages: bundlesNested.map((b) => toMessageV1(b)),\n\t\t\t\t// @ts-expect-error - legacy\n\t\t\t\tnodeishFs: withAbsolutePaths(args.fs, args.path),\n\t\t\t\tsettings,\n\t\t\t});\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"saveProjectToDirectory.js","sourceRoot":"/","sources":["project/saveProjectToDirectory.ts"],"names":[],"mappings":"AAEA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,8CAA8C,CAAC;AAC3E,OAAO,EACN,uBAAuB,EACvB,iBAAiB,GACjB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AAE9E,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAI5C;IACA,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,KAAK,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACnD,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;SACrC,UAAU,CAAC,MAAM,CAAC;SAClB,SAAS,EAAE;SACX,OAAO,EAAE,CAAC;IAEZ,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,mCAAmC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,SAAS;QACV,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7C,YAAY,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;QAC5B,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CACtB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,EAClC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CACjC,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAEnD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE;iBACnC,UAAU,CAAC,QAAQ,CAAC;iBACpB,SAAS,EAAE;iBACX,OAAO,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE;iBACpC,UAAU,CAAC,SAAS,CAAC;iBACrB,SAAS,EAAE;iBACX,OAAO,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE;iBACpC,UAAU,CAAC,SAAS,CAAC;iBACrB,SAAS,EAAE;iBACX,OAAO,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;gBACtC,OAAO;gBACP,QAAQ;gBACR,QAAQ;gBACR,QAAQ;aACR,CAAC,CAAC;YACH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBAC1B,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC;gBACtD,MAAM,CAAC,GAAG,WAAW;oBACpB,CAAC,CAAC,uBAAuB,CACvB,IAAI,CAAC,IAAI,EACT,WAAW,CAAC,OAAO,CAAC,2BAA2B,EAAE,IAAI,CAAC,MAAM,CAAC,CAC7D;oBACF,CAAC,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAChC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;oBAC3D,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnD,CAAC;gBACD,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBACzB,IAAI,CAAC;wBACJ,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;wBACpD,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;wBACjD,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CACtB,CAAC,EACD,IAAI,WAAW,EAAE,CAAC,MAAM,CACvB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAC7D,CACD,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACR,kDAAkD;wBAClD,oDAAoD;wBACpD,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC1D,CAAC;gBACF,CAAC;qBAAM,CAAC;oBACP,MAAM,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC1D,CAAC;YACF,CAAC;QACF,CAAC;QACD,4BAA4B;aACvB,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YAC9B,0EAA0E;YAC1E,oEAAoE;YACpE,MAAM,aAAa,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YAC1E,MAAM,MAAM,CAAC,YAAY,CAAC;gBACzB,QAAQ,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;gBAClD,4BAA4B;gBAC5B,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC;gBAChD,QAAQ;aACR,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["import type fs from \"node:fs/promises\";\nimport type { InlangProject } from \"./api.js\";\nimport path from \"node:path\";\nimport { toMessageV1 } from \"../json-schema/old-v1-message/toMessageV1.js\";\nimport {\n\tabsolutePathFromProject,\n\twithAbsolutePaths,\n} from \"./loadProjectFromDirectory.js\";\nimport { detectJsonFormatting } from \"../utilities/detectJsonFormatting.js\";\nimport { selectBundleNested } from \"../query-utilities/selectBundleNested.js\";\n\nexport async function saveProjectToDirectory(args: {\n\tfs: typeof fs;\n\tproject: InlangProject;\n\tpath: string;\n}): Promise<void> {\n\tif (args.path.endsWith(\".inlang\") === false) {\n\t\tthrow new Error(\"The path must end with .inlang\");\n\t}\n\tconst files = await args.project.lix.db\n\t\t.selectFrom(\"file\")\n\t\t.selectAll()\n\t\t.execute();\n\n\tlet hasGitignore = false;\n\n\t// write all files to the directory\n\tfor (const file of files) {\n\t\tif (file.path.endsWith(\"db.sqlite\")) {\n\t\t\tcontinue;\n\t\t} else if (file.path.endsWith(\".gitignore\")) {\n\t\t\thasGitignore = true;\n\t\t}\n\t\tconst p = path.join(args.path, file.path);\n\t\tawait args.fs.mkdir(path.dirname(p), { recursive: true });\n\t\tawait args.fs.writeFile(p, new Uint8Array(file.data));\n\t}\n\n\tif (hasGitignore === false) {\n\t\tawait args.fs.writeFile(\n\t\t\tpath.join(args.path, \".gitignore\"),\n\t\t\tnew TextEncoder().encode(\"cache\")\n\t\t);\n\t}\n\n\t// run exporters\n\tconst plugins = await args.project.plugins.get();\n\tconst settings = await args.project.settings.get();\n\n\tfor (const plugin of plugins) {\n\t\tif (plugin.exportFiles) {\n\t\t\tconst bundles = await args.project.db\n\t\t\t\t.selectFrom(\"bundle\")\n\t\t\t\t.selectAll()\n\t\t\t\t.execute();\n\t\t\tconst messages = await args.project.db\n\t\t\t\t.selectFrom(\"message\")\n\t\t\t\t.selectAll()\n\t\t\t\t.execute();\n\t\t\tconst variants = await args.project.db\n\t\t\t\t.selectFrom(\"variant\")\n\t\t\t\t.selectAll()\n\t\t\t\t.execute();\n\t\t\tconst files = await plugin.exportFiles({\n\t\t\t\tbundles,\n\t\t\t\tmessages,\n\t\t\t\tvariants,\n\t\t\t\tsettings,\n\t\t\t});\n\t\t\tfor (const file of files) {\n\t\t\t\tconst pathPattern = settings[plugin.key]?.pathPattern;\n\t\t\t\tconst p = pathPattern\n\t\t\t\t\t? absolutePathFromProject(\n\t\t\t\t\t\t\targs.path,\n\t\t\t\t\t\t\tpathPattern.replace(/\\{(languageTag|locale)\\}/g, file.locale)\n\t\t\t\t\t\t)\n\t\t\t\t\t: absolutePathFromProject(args.path, file.name);\n\t\t\t\tconst dirname = path.dirname(p);\n\t\t\t\tif ((await args.fs.stat(dirname)).isDirectory() === false) {\n\t\t\t\t\tawait args.fs.mkdir(dirname, { recursive: true });\n\t\t\t\t}\n\t\t\t\tif (p.endsWith(\".json\")) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst existing = await args.fs.readFile(p, \"utf-8\");\n\t\t\t\t\t\tconst stringify = detectJsonFormatting(existing);\n\t\t\t\t\t\tawait args.fs.writeFile(\n\t\t\t\t\t\t\tp,\n\t\t\t\t\t\t\tnew TextEncoder().encode(\n\t\t\t\t\t\t\t\tstringify(JSON.parse(new TextDecoder().decode(file.content)))\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// write the file to disk (json doesn't exist yet)\n\t\t\t\t\t\t// yeah ugly duplication of write file but it works.\n\t\t\t\t\t\tawait args.fs.writeFile(p, new Uint8Array(file.content));\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tawait args.fs.writeFile(p, new Uint8Array(file.content));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// old legacy remove with v3\n\t\telse if (plugin.saveMessages) {\n\t\t\t// in-efficient re-qeuery but it's a legacy function that will be removed.\n\t\t\t// the effort of adjusting the code to not re-query is not worth it.\n\t\t\tconst bundlesNested = await selectBundleNested(args.project.db).execute();\n\t\t\tawait plugin.saveMessages({\n\t\t\t\tmessages: bundlesNested.map((b) => toMessageV1(b)),\n\t\t\t\t// @ts-expect-error - legacy\n\t\t\t\tnodeishFs: withAbsolutePaths(args.fs, args.path),\n\t\t\t\tsettings,\n\t\t\t});\n\t\t}\n\t}\n}\n"]}