@inlang/sdk 2.6.0 → 2.6.2

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 (32) hide show
  1. package/README.md +4 -4
  2. package/dist/database/initDbAndSchema.test.js +1 -1
  3. package/dist/database/initDbAndSchema.test.js.map +1 -1
  4. package/dist/database/jsonbPlugin.js +1 -1
  5. package/dist/database/jsonbPlugin.js.map +1 -1
  6. package/dist/database/schema.d.ts +1 -1
  7. package/dist/database/schema.js.map +1 -1
  8. package/dist/lix-plugin/applyChanges.js +1 -1
  9. package/dist/lix-plugin/applyChanges.js.map +1 -1
  10. package/dist/lix-plugin/inlangLixPluginV1.test.js +1 -1
  11. package/dist/lix-plugin/inlangLixPluginV1.test.js.map +1 -1
  12. package/dist/plugin/schema.d.ts +2 -2
  13. package/dist/plugin/schema.js.map +1 -1
  14. package/dist/project/api.d.ts +1 -1
  15. package/dist/project/api.js.map +1 -1
  16. package/dist/project/loadProjectFromDirectory.d.ts.map +1 -1
  17. package/dist/project/loadProjectFromDirectory.js +4 -5
  18. package/dist/project/loadProjectFromDirectory.js.map +1 -1
  19. package/dist/project/loadProjectFromDirectory.test.js +2 -2
  20. package/dist/project/loadProjectFromDirectory.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 +1 -1
  24. package/src/database/initDbAndSchema.test.ts +1 -1
  25. package/src/database/jsonbPlugin.ts +1 -1
  26. package/src/database/schema.ts +1 -1
  27. package/src/lix-plugin/applyChanges.ts +1 -1
  28. package/src/lix-plugin/inlangLixPluginV1.test.ts +1 -1
  29. package/src/plugin/schema.ts +2 -2
  30. package/src/project/api.ts +1 -1
  31. package/src/project/loadProjectFromDirectory.test.ts +2 -2
  32. package/src/project/loadProjectFromDirectory.ts +3 -5
package/README.md CHANGED
@@ -27,7 +27,7 @@ The inlang SDK is the official specification and parser for `.inlang` files.
27
27
  - 🖊️ **CRUD API**: Query messages with SQL.
28
28
  - 🧩 **Plugin System**: Extend the capabilities with plugins.
29
29
  - 📦 **Import/Export**: Import and export messages in different file formats.
30
- - [<img src="https://raw.githubusercontent.com/opral/inlang/refs/heads/main/lix/assets/lix-icon.svg" width="20" height="12" alt="Lix Icon">**Change control**](https://lix.opral.com/): Collaboration, change proposals, reviews, and automation.
30
+ - [<img src="https://raw.githubusercontent.com/opral/inlang/refs/heads/main/lix/assets/lix-icon.svg" width="20" height="12" alt="Lix Icon">**Change control**](https://lix.dev/): Collaboration, change proposals, reviews, and automation.
31
31
 
32
32
 
33
33
 
@@ -153,9 +153,9 @@ console.log(messages);
153
153
  ### Querying changes
154
154
 
155
155
  > [!NOTE]
156
- > The inlang plugin for lix is work in progress. If you stumble on issues, please open an issue on the [GitHub](https://github.com/opral/inlang-sdk).
156
+ > The inlang plugin for lix is work in progress. If you stumble on issues, please open an issue on the [GitHub](https://github.com/opral/inlang).
157
157
 
158
- The inlang file format uses lix for change control. The lix APIs are exposed via `project.lix.*`. Visit the [lix documentation](https://lix.opral.com/) for more information on how to query changes.
158
+ The inlang file format uses lix for change control. The lix APIs are exposed via `project.lix.*`. Visit the [lix documentation](https://lix.dev/) for more information on how to query changes.
159
159
 
160
160
  ```typescript
161
161
  const changes = await project.lix.db
@@ -214,7 +214,7 @@ await project.settings.set(settings)
214
214
  >
215
215
  > Git can't handle binary files. **If you don't intend to store the inlang file in git, do not use unpacked inlang files.**
216
216
  >
217
- > Unpacked inlang files are not portable. They depent on plugins that and do not persist [lix change control](https://lix.opral.com/) data.
217
+ > Unpacked inlang files are not portable. They depent on plugins that and do not persist [lix change control](https://lix.dev/) data.
218
218
 
219
219
  ```typescript
220
220
  import {
@@ -132,7 +132,7 @@ test("it should preserve json-like text in variant patterns", async () => {
132
132
  },
133
133
  ]);
134
134
  });
135
- // https://github.com/opral/inlang-sdk/issues/209
135
+ // https://github.com/opral/inlang/issues/209
136
136
  test.todo("it should enable foreign key constraints", async () => {
137
137
  const sqlite = await createInMemoryDatabase({
138
138
  readOnly: false,
@@ -1 +1 @@
1
- {"version":3,"file":"initDbAndSchema.test.js","sourceRoot":"/","sources":["database/initDbAndSchema.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInMemoryDatabase } from \"sqlite-wasm-kysely\";\nimport { test, expect } from \"vitest\";\nimport { initDb } from \"./initDb.js\";\nimport { isHumanId } from \"../human-id/human-id.js\";\nimport { validate as isUuid } from \"uuid\";\n\ntest(\"bundle default values\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.defaultValues()\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(isHumanId(bundle.id)).toBe(true);\n\texpect(bundle.declarations).toStrictEqual([]);\n});\n\ntest(\"message default values\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.defaultValues()\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst message = await db\n\t\t.insertInto(\"message\")\n\t\t.values({\n\t\t\tbundleId: bundle.id,\n\t\t\tlocale: \"en\",\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(isUuid(message.id)).toBe(true);\n\texpect(message.selectors).toStrictEqual([]);\n});\n\ntest(\"variant default values\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.defaultValues()\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst message = await db\n\t\t.insertInto(\"message\")\n\t\t.values({\n\t\t\tbundleId: bundle.id,\n\t\t\tlocale: \"en\",\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst variant = await db\n\t\t.insertInto(\"variant\")\n\t\t.values({\n\t\t\tmessageId: message.id,\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(isUuid(variant.id)).toBe(true);\n\texpect(variant.matches).toStrictEqual([]);\n\texpect(variant.pattern).toStrictEqual([]);\n});\n\ntest(\"it should handle json serialization and parsing for bundles\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.values({\n\t\t\tdeclarations: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"input-variable\",\n\t\t\t\t\tname: \"mock\",\n\t\t\t\t},\n\t\t\t],\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(bundle.declarations).toStrictEqual([\n\t\t{\n\t\t\ttype: \"input-variable\",\n\t\t\tname: \"mock\",\n\t\t},\n\t]);\n});\n\n// https://github.com/opral/paraglide-js/issues/571\ntest(\"it should preserve json-like text in variant patterns\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.values({ id: \"json_array\" })\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst message = await db\n\t\t.insertInto(\"message\")\n\t\t.values({\n\t\t\tbundleId: bundle.id,\n\t\t\tlocale: \"en\",\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tawait db\n\t\t.insertInto(\"variant\")\n\t\t.values({\n\t\t\tmessageId: message.id,\n\t\t\tpattern: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\tvalue: '[\"a\", \"b\", \"c\"]',\n\t\t\t\t},\n\t\t\t],\n\t\t})\n\t\t.execute();\n\n\tconst variant = await db\n\t\t.selectFrom(\"variant\")\n\t\t.selectAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(variant.pattern).toStrictEqual([\n\t\t{\n\t\t\ttype: \"text\",\n\t\t\tvalue: '[\"a\", \"b\", \"c\"]',\n\t\t},\n\t]);\n});\n\n// https://github.com/opral/inlang-sdk/issues/209\ntest.todo(\"it should enable foreign key constraints\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\texpect(() =>\n\t\tdb\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({\n\t\t\t\tbundleId: \"non-existent\",\n\t\t\t\tlocale: \"en\",\n\t\t\t})\n\t\t\t.execute()\n\t).rejects.toThrow();\n});\n"]}
1
+ {"version":3,"file":"initDbAndSchema.test.js","sourceRoot":"/","sources":["database/initDbAndSchema.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { createInMemoryDatabase } from \"sqlite-wasm-kysely\";\nimport { test, expect } from \"vitest\";\nimport { initDb } from \"./initDb.js\";\nimport { isHumanId } from \"../human-id/human-id.js\";\nimport { validate as isUuid } from \"uuid\";\n\ntest(\"bundle default values\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.defaultValues()\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(isHumanId(bundle.id)).toBe(true);\n\texpect(bundle.declarations).toStrictEqual([]);\n});\n\ntest(\"message default values\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.defaultValues()\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst message = await db\n\t\t.insertInto(\"message\")\n\t\t.values({\n\t\t\tbundleId: bundle.id,\n\t\t\tlocale: \"en\",\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(isUuid(message.id)).toBe(true);\n\texpect(message.selectors).toStrictEqual([]);\n});\n\ntest(\"variant default values\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.defaultValues()\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst message = await db\n\t\t.insertInto(\"message\")\n\t\t.values({\n\t\t\tbundleId: bundle.id,\n\t\t\tlocale: \"en\",\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst variant = await db\n\t\t.insertInto(\"variant\")\n\t\t.values({\n\t\t\tmessageId: message.id,\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(isUuid(variant.id)).toBe(true);\n\texpect(variant.matches).toStrictEqual([]);\n\texpect(variant.pattern).toStrictEqual([]);\n});\n\ntest(\"it should handle json serialization and parsing for bundles\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.values({\n\t\t\tdeclarations: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"input-variable\",\n\t\t\t\t\tname: \"mock\",\n\t\t\t\t},\n\t\t\t],\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(bundle.declarations).toStrictEqual([\n\t\t{\n\t\t\ttype: \"input-variable\",\n\t\t\tname: \"mock\",\n\t\t},\n\t]);\n});\n\n// https://github.com/opral/paraglide-js/issues/571\ntest(\"it should preserve json-like text in variant patterns\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\tconst bundle = await db\n\t\t.insertInto(\"bundle\")\n\t\t.values({ id: \"json_array\" })\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tconst message = await db\n\t\t.insertInto(\"message\")\n\t\t.values({\n\t\t\tbundleId: bundle.id,\n\t\t\tlocale: \"en\",\n\t\t})\n\t\t.returningAll()\n\t\t.executeTakeFirstOrThrow();\n\n\tawait db\n\t\t.insertInto(\"variant\")\n\t\t.values({\n\t\t\tmessageId: message.id,\n\t\t\tpattern: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\tvalue: '[\"a\", \"b\", \"c\"]',\n\t\t\t\t},\n\t\t\t],\n\t\t})\n\t\t.execute();\n\n\tconst variant = await db\n\t\t.selectFrom(\"variant\")\n\t\t.selectAll()\n\t\t.executeTakeFirstOrThrow();\n\n\texpect(variant.pattern).toStrictEqual([\n\t\t{\n\t\t\ttype: \"text\",\n\t\t\tvalue: '[\"a\", \"b\", \"c\"]',\n\t\t},\n\t]);\n});\n\n// https://github.com/opral/inlang/issues/209\ntest.todo(\"it should enable foreign key constraints\", async () => {\n\tconst sqlite = await createInMemoryDatabase({\n\t\treadOnly: false,\n\t});\n\tconst db = initDb({ sqlite });\n\n\texpect(() =>\n\t\tdb\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({\n\t\t\t\tbundleId: \"non-existent\",\n\t\t\t\tlocale: \"en\",\n\t\t\t})\n\t\t\t.execute()\n\t).rejects.toThrow();\n});\n"]}
@@ -194,7 +194,7 @@ function maybeSerializeJson(value) {
194
194
  }
195
195
  return value;
196
196
  }
197
- // The code here didn't work https://github.com/opral/inlang-sdk/issues/132#issuecomment-2339321910
197
+ // The code here didn't work https://github.com/opral/inlang/issues/132#issuecomment-2339321910
198
198
  // but would be the "right" solution to avoid heuristics which column might or might not be a json column
199
199
  // // modifies the query in place for readability and performance
200
200
  // function mapQuery(
@@ -1 +1 @@
1
- {"version":3,"file":"jsonbPlugin.js","sourceRoot":"/","sources":["database/jsonbPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tOperationNodeTransformer,\n\tsql,\n\tValueListNode,\n\tValueNode,\n\tValuesNode,\n\ttype KyselyPlugin,\n\ttype PluginTransformQueryArgs,\n\ttype PluginTransformResultArgs,\n\ttype QueryResult,\n\ttype RootOperationNode,\n\ttype UnknownRow,\n\tOnConflictNode,\n} from \"kysely\";\nimport type { SqliteWasmDatabase } from \"sqlite-wasm-kysely\";\n\nexport class JsonbPlugin implements KyselyPlugin {\n\t#serializeJsonTransformer = new SerializeJsonbTransformer();\n\t#database: SqliteWasmDatabase;\n\n\tconstructor(args: { database: SqliteWasmDatabase }) {\n\t\tthis.#database = args.database;\n\t}\n\n\t/**\n\t * For an outgoing query like insert or update, the JSON\n\t * values are transformed into `jsonb` function calls when\n\t * executed against the database.\n\t */\n\ttransformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n\t\tif (\n\t\t\targs.node.kind === \"InsertQueryNode\" ||\n\t\t\targs.node.kind === \"UpdateQueryNode\"\n\t\t) {\n\t\t\tconst result = this.#serializeJsonTransformer.transformNode(args.node);\n\t\t\treturn result;\n\t\t}\n\t\treturn args.node;\n\t}\n\n\t/**\n\t * For incoming query results, the JSON binaries are parsed\n\t * into JSON objects.\n\t */\n\tasync transformResult(\n\t\targs: PluginTransformResultArgs\n\t): Promise<QueryResult<UnknownRow>> {\n\t\tfor (const row of args.result.rows) {\n\t\t\tfor (const key in row) {\n\t\t\t\tconst value = row[key];\n\t\t\t\t// Always try to decode JSONB binary payloads.\n\t\t\t\tif (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst res = this.#database.exec(`SELECT json(?)`, {\n\t\t\t\t\t\t\treturnValue: \"resultRows\",\n\t\t\t\t\t\t\tbind: [value as any],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\trow[key] = JSON.parse(res[0] as any);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// it's not a json binary\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Only parse JSON text for known JSON columns to avoid\n\t\t\t\t// coercing nested string values that look like JSON.\n\t\t\t\tif (JSON_COLUMNS.has(key) && typeof value === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\trow[key] = JSON.parse(value);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// leave as-is if parsing fails\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (key === \"messages\" && Array.isArray(row[key])) {\n\t\t\t\t\trow[key] = normalizeMessages(row[key]);\n\t\t\t\t} else if (key === \"variants\" && Array.isArray(row[key])) {\n\t\t\t\t\trow[key] = normalizeVariants(row[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn args.result;\n\t}\n}\n\nconst JSON_COLUMNS = new Set([\n\t\"declarations\",\n\t\"selectors\",\n\t\"matches\",\n\t\"pattern\",\n\t// jsonArrayFrom results in nested bundle queries\n\t\"messages\",\n\t\"variants\",\n]);\n\nfunction parseJsonIfString<T>(value: T): T | unknown {\n\tif (typeof value !== \"string\") {\n\t\treturn value;\n\t}\n\ttry {\n\t\treturn JSON.parse(value);\n\t} catch {\n\t\treturn value;\n\t}\n}\n\nfunction normalizeVariants(variants: any[]) {\n\treturn variants.map((variant) => {\n\t\tif (variant && typeof variant === \"object\") {\n\t\t\treturn {\n\t\t\t\t...variant,\n\t\t\t\tmatches: parseJsonIfString(variant.matches),\n\t\t\t\tpattern: parseJsonIfString(variant.pattern),\n\t\t\t};\n\t\t}\n\t\treturn variant;\n\t});\n}\n\nfunction normalizeMessages(messages: any[]) {\n\treturn messages.map((message) => {\n\t\tif (message && typeof message === \"object\") {\n\t\t\tconst rawVariants = Array.isArray(message.variants)\n\t\t\t\t? message.variants\n\t\t\t\t: parseJsonIfString(message.variants);\n\t\t\tconst normalizedVariants = Array.isArray(rawVariants)\n\t\t\t\t? normalizeVariants(rawVariants)\n\t\t\t\t: rawVariants;\n\t\t\treturn {\n\t\t\t\t...message,\n\t\t\t\tselectors: parseJsonIfString(message.selectors),\n\t\t\t\tvariants: normalizedVariants,\n\t\t\t};\n\t\t}\n\t\treturn message;\n\t});\n}\n\nclass SerializeJsonbTransformer extends OperationNodeTransformer {\n\tprotected override transformOnConflict(node: OnConflictNode): OnConflictNode {\n\t\treturn super.transformOnConflict({\n\t\t\t...node,\n\t\t\tupdates: node.updates?.map((updateItem) => {\n\t\t\t\tif (updateItem.kind !== \"ColumnUpdateNode\") {\n\t\t\t\t\treturn updateItem;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"ColumnUpdateNode\",\n\t\t\t\t\tcolumn: updateItem.column,\n\t\t\t\t\t// @ts-expect-error - we know that the value is a ValueNode\n\t\t\t\t\tvalue: this.transformValue(updateItem.value),\n\t\t\t\t};\n\t\t\t}),\n\t\t});\n\t}\n\n\tprotected override transformValue(node: ValueNode): ValueNode {\n\t\tconst { value } = node;\n\t\tconst serializedValue = maybeSerializeJson(value);\n\t\tif (value === serializedValue) {\n\t\t\treturn node;\n\t\t}\n\t\t// @ts-expect-error - we know that the node is a ValueNode\n\t\treturn sql`jsonb(${serializedValue})`.toOperationNode();\n\t}\n\t/**\n\t * Transforms the value list node by replacing all JSON objects with `jsonb` function calls.\n\t */\n\tprotected override transformValueList(node: ValueListNode): ValueListNode {\n\t\treturn super.transformValueList({\n\t\t\t...node,\n\t\t\tvalues: node.values.map((listNodeItem) => {\n\t\t\t\tif (listNodeItem.kind !== \"ValueNode\") {\n\t\t\t\t\treturn listNodeItem;\n\t\t\t\t}\n\t\t\t\t// @ts-expect-error - we know that the node is a ValueNode\n\t\t\t\tconst { value } = listNodeItem;\n\t\t\t\tconst serializedValue = maybeSerializeJson(value);\n\n\t\t\t\tif (value === serializedValue) {\n\t\t\t\t\treturn listNodeItem;\n\t\t\t\t}\n\t\t\t\treturn sql`jsonb(${serializedValue})`.toOperationNode();\n\t\t\t}),\n\t\t});\n\t}\n\n\t/**\n\t * Why this function is needed or why this works remains a mystery.\n\t */\n\toverride transformValues(node: ValuesNode): ValuesNode {\n\t\treturn super.transformValues({\n\t\t\t...node,\n\t\t\tvalues: node.values.map((valueItemNode) => {\n\t\t\t\tif (valueItemNode.kind !== \"PrimitiveValueListNode\") {\n\t\t\t\t\treturn valueItemNode;\n\t\t\t\t}\n\n\t\t\t\t// change valueItem to ValueListNode\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"ValueListNode\",\n\t\t\t\t\tvalues: valueItemNode.values.map(\n\t\t\t\t\t\t(value) =>\n\t\t\t\t\t\t\t({\n\t\t\t\t\t\t\t\tkind: \"ValueNode\",\n\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t}) as ValueNode\n\t\t\t\t\t),\n\t\t\t\t} as ValueListNode;\n\t\t\t}),\n\t\t});\n\t}\n}\n\nfunction maybeSerializeJson(value: any): any {\n\tif (\n\t\t// binary data\n\t\tvalue instanceof ArrayBuffer ||\n\t\t// uint8array, etc\n\t\tArrayBuffer.isView(value) ||\n\t\tvalue === null ||\n\t\tvalue === undefined\n\t) {\n\t\treturn value;\n\t} else if (typeof value === \"object\" || Array.isArray(value)) {\n\t\treturn JSON.stringify(value);\n\t}\n\treturn value;\n}\n\n// The code here didn't work https://github.com/opral/inlang-sdk/issues/132#issuecomment-2339321910\n// but would be the \"right\" solution to avoid heuristics which column might or might not be a json column\n// // modifies the query in place for readability and performance\n// function mapQuery(\n// \tnode: InsertQueryNode,\n// \tjsonColumns: TableSchema\n// ): InsertQueryNode {\n// \t// if the query is not an insert query, we don't need to do anything\n// \tif (node.into === undefined) {\n// \t\treturn node;\n// \t}\n// \t// if the table is not in the schema that has json columns, we don't need to do anything\n// \tconst columnsWithJson = jsonColumns[node.into.table.identifier.name];\n// \tif (columnsWithJson === undefined) {\n// \t\treturn node;\n// \t}\n// \t// find the indexes of the values that need to be transformed\n// \t// SQL query: INSERT INTO table (col1, col2) VALUES (val1, val2)\n// \tconst indexesThatNeedToBeTransformed: [number, string][] = [];\n// \tfor (const [i, col] of node.columns?.entries() ?? []) {\n// \t\tconst jsonType = columnsWithJson[col.column.name];\n// \t\tif (jsonType !== undefined) {\n// \t\t\tindexesThatNeedToBeTransformed.push([i, jsonType]);\n// \t\t}\n// \t}\n// \tconst values = structuredClone(node.values);\n// \tfor (const [i, jsonType] of indexesThatNeedToBeTransformed) {\n// \t\tif (\n// \t\t\t// top level values node that should contain a list of values\n// \t\t\tnode.values?.kind !== \"ValuesNode\" &&\n// \t\t\t// the node we are interested in must be a value node\n// \t\t\t// @ts-expect-error - we know that the node is a ValuesNode with values\n// \t\t\t(node.values as ValuesNode).values?.[i].kind !== \"ValueNode\"\n// \t\t) {\n// \t\t\tthrow new Error(\"Unexpected node structure\");\n// \t\t}\n// \t\tconst serializedJson = JSON.stringify(node.values.values[0].values[i]);\n// \t\t// @ts-expect-error - we know that the node is a ValuesNode with values\n// \t\tvalues.values[0].values[i] =\n// \t\t\tjsonType === \"jsonb\"\n// \t\t\t\t? sql`jsonb(${serializedJson})`.toOperationNode()\n// \t\t\t\t: sql`json(${serializedJson})`.toOperationNode();\n// \t}\n\n// \treturn {\n// \t\t...node,\n// \t\tvalues,\n// \t};\n// }\n"]}
1
+ {"version":3,"file":"jsonbPlugin.js","sourceRoot":"/","sources":["database/jsonbPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tOperationNodeTransformer,\n\tsql,\n\tValueListNode,\n\tValueNode,\n\tValuesNode,\n\ttype KyselyPlugin,\n\ttype PluginTransformQueryArgs,\n\ttype PluginTransformResultArgs,\n\ttype QueryResult,\n\ttype RootOperationNode,\n\ttype UnknownRow,\n\tOnConflictNode,\n} from \"kysely\";\nimport type { SqliteWasmDatabase } from \"sqlite-wasm-kysely\";\n\nexport class JsonbPlugin implements KyselyPlugin {\n\t#serializeJsonTransformer = new SerializeJsonbTransformer();\n\t#database: SqliteWasmDatabase;\n\n\tconstructor(args: { database: SqliteWasmDatabase }) {\n\t\tthis.#database = args.database;\n\t}\n\n\t/**\n\t * For an outgoing query like insert or update, the JSON\n\t * values are transformed into `jsonb` function calls when\n\t * executed against the database.\n\t */\n\ttransformQuery(args: PluginTransformQueryArgs): RootOperationNode {\n\t\tif (\n\t\t\targs.node.kind === \"InsertQueryNode\" ||\n\t\t\targs.node.kind === \"UpdateQueryNode\"\n\t\t) {\n\t\t\tconst result = this.#serializeJsonTransformer.transformNode(args.node);\n\t\t\treturn result;\n\t\t}\n\t\treturn args.node;\n\t}\n\n\t/**\n\t * For incoming query results, the JSON binaries are parsed\n\t * into JSON objects.\n\t */\n\tasync transformResult(\n\t\targs: PluginTransformResultArgs\n\t): Promise<QueryResult<UnknownRow>> {\n\t\tfor (const row of args.result.rows) {\n\t\t\tfor (const key in row) {\n\t\t\t\tconst value = row[key];\n\t\t\t\t// Always try to decode JSONB binary payloads.\n\t\t\t\tif (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst res = this.#database.exec(`SELECT json(?)`, {\n\t\t\t\t\t\t\treturnValue: \"resultRows\",\n\t\t\t\t\t\t\tbind: [value as any],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\trow[key] = JSON.parse(res[0] as any);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// it's not a json binary\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Only parse JSON text for known JSON columns to avoid\n\t\t\t\t// coercing nested string values that look like JSON.\n\t\t\t\tif (JSON_COLUMNS.has(key) && typeof value === \"string\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\trow[key] = JSON.parse(value);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// leave as-is if parsing fails\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (key === \"messages\" && Array.isArray(row[key])) {\n\t\t\t\t\trow[key] = normalizeMessages(row[key]);\n\t\t\t\t} else if (key === \"variants\" && Array.isArray(row[key])) {\n\t\t\t\t\trow[key] = normalizeVariants(row[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn args.result;\n\t}\n}\n\nconst JSON_COLUMNS = new Set([\n\t\"declarations\",\n\t\"selectors\",\n\t\"matches\",\n\t\"pattern\",\n\t// jsonArrayFrom results in nested bundle queries\n\t\"messages\",\n\t\"variants\",\n]);\n\nfunction parseJsonIfString<T>(value: T): T | unknown {\n\tif (typeof value !== \"string\") {\n\t\treturn value;\n\t}\n\ttry {\n\t\treturn JSON.parse(value);\n\t} catch {\n\t\treturn value;\n\t}\n}\n\nfunction normalizeVariants(variants: any[]) {\n\treturn variants.map((variant) => {\n\t\tif (variant && typeof variant === \"object\") {\n\t\t\treturn {\n\t\t\t\t...variant,\n\t\t\t\tmatches: parseJsonIfString(variant.matches),\n\t\t\t\tpattern: parseJsonIfString(variant.pattern),\n\t\t\t};\n\t\t}\n\t\treturn variant;\n\t});\n}\n\nfunction normalizeMessages(messages: any[]) {\n\treturn messages.map((message) => {\n\t\tif (message && typeof message === \"object\") {\n\t\t\tconst rawVariants = Array.isArray(message.variants)\n\t\t\t\t? message.variants\n\t\t\t\t: parseJsonIfString(message.variants);\n\t\t\tconst normalizedVariants = Array.isArray(rawVariants)\n\t\t\t\t? normalizeVariants(rawVariants)\n\t\t\t\t: rawVariants;\n\t\t\treturn {\n\t\t\t\t...message,\n\t\t\t\tselectors: parseJsonIfString(message.selectors),\n\t\t\t\tvariants: normalizedVariants,\n\t\t\t};\n\t\t}\n\t\treturn message;\n\t});\n}\n\nclass SerializeJsonbTransformer extends OperationNodeTransformer {\n\tprotected override transformOnConflict(node: OnConflictNode): OnConflictNode {\n\t\treturn super.transformOnConflict({\n\t\t\t...node,\n\t\t\tupdates: node.updates?.map((updateItem) => {\n\t\t\t\tif (updateItem.kind !== \"ColumnUpdateNode\") {\n\t\t\t\t\treturn updateItem;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"ColumnUpdateNode\",\n\t\t\t\t\tcolumn: updateItem.column,\n\t\t\t\t\t// @ts-expect-error - we know that the value is a ValueNode\n\t\t\t\t\tvalue: this.transformValue(updateItem.value),\n\t\t\t\t};\n\t\t\t}),\n\t\t});\n\t}\n\n\tprotected override transformValue(node: ValueNode): ValueNode {\n\t\tconst { value } = node;\n\t\tconst serializedValue = maybeSerializeJson(value);\n\t\tif (value === serializedValue) {\n\t\t\treturn node;\n\t\t}\n\t\t// @ts-expect-error - we know that the node is a ValueNode\n\t\treturn sql`jsonb(${serializedValue})`.toOperationNode();\n\t}\n\t/**\n\t * Transforms the value list node by replacing all JSON objects with `jsonb` function calls.\n\t */\n\tprotected override transformValueList(node: ValueListNode): ValueListNode {\n\t\treturn super.transformValueList({\n\t\t\t...node,\n\t\t\tvalues: node.values.map((listNodeItem) => {\n\t\t\t\tif (listNodeItem.kind !== \"ValueNode\") {\n\t\t\t\t\treturn listNodeItem;\n\t\t\t\t}\n\t\t\t\t// @ts-expect-error - we know that the node is a ValueNode\n\t\t\t\tconst { value } = listNodeItem;\n\t\t\t\tconst serializedValue = maybeSerializeJson(value);\n\n\t\t\t\tif (value === serializedValue) {\n\t\t\t\t\treturn listNodeItem;\n\t\t\t\t}\n\t\t\t\treturn sql`jsonb(${serializedValue})`.toOperationNode();\n\t\t\t}),\n\t\t});\n\t}\n\n\t/**\n\t * Why this function is needed or why this works remains a mystery.\n\t */\n\toverride transformValues(node: ValuesNode): ValuesNode {\n\t\treturn super.transformValues({\n\t\t\t...node,\n\t\t\tvalues: node.values.map((valueItemNode) => {\n\t\t\t\tif (valueItemNode.kind !== \"PrimitiveValueListNode\") {\n\t\t\t\t\treturn valueItemNode;\n\t\t\t\t}\n\n\t\t\t\t// change valueItem to ValueListNode\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"ValueListNode\",\n\t\t\t\t\tvalues: valueItemNode.values.map(\n\t\t\t\t\t\t(value) =>\n\t\t\t\t\t\t\t({\n\t\t\t\t\t\t\t\tkind: \"ValueNode\",\n\t\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t\t}) as ValueNode\n\t\t\t\t\t),\n\t\t\t\t} as ValueListNode;\n\t\t\t}),\n\t\t});\n\t}\n}\n\nfunction maybeSerializeJson(value: any): any {\n\tif (\n\t\t// binary data\n\t\tvalue instanceof ArrayBuffer ||\n\t\t// uint8array, etc\n\t\tArrayBuffer.isView(value) ||\n\t\tvalue === null ||\n\t\tvalue === undefined\n\t) {\n\t\treturn value;\n\t} else if (typeof value === \"object\" || Array.isArray(value)) {\n\t\treturn JSON.stringify(value);\n\t}\n\treturn value;\n}\n\n// The code here didn't work https://github.com/opral/inlang/issues/132#issuecomment-2339321910\n// but would be the \"right\" solution to avoid heuristics which column might or might not be a json column\n// // modifies the query in place for readability and performance\n// function mapQuery(\n// \tnode: InsertQueryNode,\n// \tjsonColumns: TableSchema\n// ): InsertQueryNode {\n// \t// if the query is not an insert query, we don't need to do anything\n// \tif (node.into === undefined) {\n// \t\treturn node;\n// \t}\n// \t// if the table is not in the schema that has json columns, we don't need to do anything\n// \tconst columnsWithJson = jsonColumns[node.into.table.identifier.name];\n// \tif (columnsWithJson === undefined) {\n// \t\treturn node;\n// \t}\n// \t// find the indexes of the values that need to be transformed\n// \t// SQL query: INSERT INTO table (col1, col2) VALUES (val1, val2)\n// \tconst indexesThatNeedToBeTransformed: [number, string][] = [];\n// \tfor (const [i, col] of node.columns?.entries() ?? []) {\n// \t\tconst jsonType = columnsWithJson[col.column.name];\n// \t\tif (jsonType !== undefined) {\n// \t\t\tindexesThatNeedToBeTransformed.push([i, jsonType]);\n// \t\t}\n// \t}\n// \tconst values = structuredClone(node.values);\n// \tfor (const [i, jsonType] of indexesThatNeedToBeTransformed) {\n// \t\tif (\n// \t\t\t// top level values node that should contain a list of values\n// \t\t\tnode.values?.kind !== \"ValuesNode\" &&\n// \t\t\t// the node we are interested in must be a value node\n// \t\t\t// @ts-expect-error - we know that the node is a ValuesNode with values\n// \t\t\t(node.values as ValuesNode).values?.[i].kind !== \"ValueNode\"\n// \t\t) {\n// \t\t\tthrow new Error(\"Unexpected node structure\");\n// \t\t}\n// \t\tconst serializedJson = JSON.stringify(node.values.values[0].values[i]);\n// \t\t// @ts-expect-error - we know that the node is a ValuesNode with values\n// \t\tvalues.values[0].values[i] =\n// \t\t\tjsonType === \"jsonb\"\n// \t\t\t\t? sql`jsonb(${serializedJson})`.toOperationNode()\n// \t\t\t\t: sql`json(${serializedJson})`.toOperationNode();\n// \t}\n\n// \treturn {\n// \t\t...node,\n// \t\tvalues,\n// \t};\n// }\n"]}
@@ -28,7 +28,7 @@ type VariantTable = {
28
28
  /**
29
29
  * A match is a variable reference that is either a literal or a catch-all.
30
30
  *
31
- * https://github.com/opral/inlang-sdk/issues/205
31
+ * https://github.com/opral/inlang/issues/205
32
32
  *
33
33
  * @example
34
34
  * match = { type: "match", name: "gender", value: { type: "literal", value: "male" }}
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"/","sources":["database/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,WAAW,EACX,OAAO,EACP,iBAAiB,GACjB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,UAAU,WAAW,CAAC,IAAoC;IAC/D,MAAM,mBAAmB,GAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE;QACxE,WAAW,EAAE,YAAY;KACzB,CAAC,CAAC;IACH;IACC,6BAA6B;IAC7B,gCAAgC;IAChC,gDAAgD;IAChD,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAC9B,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE;YAC5C,WAAW,EAAE,YAAY;SACzB,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBf,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { Generated, Insertable, Selectable, Updateable } from \"kysely\";\nimport type { SqliteWasmDatabase } from \"sqlite-wasm-kysely\";\nimport {\n\tDeclaration,\n\tPattern,\n\tVariableReference,\n} from \"../json-schema/pattern.js\";\n\nexport function applySchema(args: { sqlite: SqliteWasmDatabase }) {\n\tconst foreignKeyActivated: any = args.sqlite.exec(\"PRAGMA foreign_keys\", {\n\t\treturnValue: \"resultRows\",\n\t});\n\tif (\n\t\t// first row that is returned\n\t\t// first column of the first row\n\t\t// is equal to 0, then foreign keys are disabled\n\t\tforeignKeyActivated[0][0] === 0\n\t) {\n\t\targs.sqlite.exec(\"PRAGMA foreign_keys = ON\", {\n\t\t\treturnValue: \"resultRows\",\n\t\t});\n\t}\n\n\targs.sqlite.exec(`\nCREATE TABLE IF NOT EXISTS bundle (\n id TEXT PRIMARY KEY DEFAULT (human_id()),\n\tdeclarations BLOB NOT NULL DEFAULT (jsonb('[]'))\n) strict;\n\nCREATE TABLE IF NOT EXISTS message (\n id TEXT PRIMARY KEY DEFAULT (uuid_v7()), \n bundle_id TEXT NOT NULL,\n locale TEXT NOT NULL,\n selectors BLOB NOT NULL DEFAULT (jsonb('[]')),\n FOREIGN KEY (bundle_id) REFERENCES bundle(id) ON DELETE CASCADE\n) strict;\n\n\nCREATE TABLE IF NOT EXISTS variant (\n id TEXT PRIMARY KEY DEFAULT (uuid_v7()), \n message_id TEXT NOT NULL,\n matches BLOB NOT NULL DEFAULT (jsonb('[]')),\n pattern BLOB NOT NULL DEFAULT (jsonb('[]')),\n FOREIGN KEY (message_id) REFERENCES message(id) ON DELETE CASCADE\n) strict;\n \nCREATE INDEX IF NOT EXISTS idx_message_bundle_id ON message (bundle_id);\nCREATE INDEX IF NOT EXISTS idx_variant_message_id ON variant (message_id);\n\t\t`);\n}\n\nexport type InlangDatabaseSchema = {\n\tbundle: BundleTable;\n\tmessage: MessageTable;\n\tvariant: VariantTable;\n};\n\ntype BundleTable = {\n\tid: Generated<string>;\n\tdeclarations: Generated<Array<Declaration>>;\n};\n\ntype MessageTable = {\n\tid: Generated<string>;\n\tbundleId: string;\n\tlocale: string;\n\tselectors: Generated<Array<VariableReference>>;\n};\n\ntype VariantTable = {\n\tid: Generated<string>;\n\tmessageId: string;\n\tmatches: Generated<Array<Match>>;\n\tpattern: Generated<Pattern>;\n};\n\n/**\n * A match is a variable reference that is either a literal or a catch-all.\n *\n * https://github.com/opral/inlang-sdk/issues/205\n *\n * @example\n * match = { type: \"match\", name: \"gender\", value: { type: \"literal\", value: \"male\" }}\n */\nexport type Match = LiteralMatch | CatchAllMatch;\n\nexport type LiteralMatch = {\n\ttype: \"literal-match\";\n\tkey: VariableReference[\"name\"];\n\tvalue: string;\n};\nexport type CatchAllMatch = {\n\ttype: \"catchall-match\";\n\tkey: VariableReference[\"name\"];\n};\n\nexport type Bundle = Selectable<BundleTable>;\nexport type NewBundle = Insertable<BundleTable>;\nexport type BundleUpdate = Updateable<BundleTable>;\n\nexport type Message = Selectable<MessageTable>;\nexport type NewMessage = Insertable<MessageTable>;\nexport type MessageUpdate = Updateable<MessageTable>;\n\nexport type Variant = Selectable<VariantTable>;\nexport type NewVariant = Insertable<VariantTable>;\nexport type VariantUpdate = Updateable<VariantTable>;\n\nexport type MessageNested = Message & {\n\tvariants: Variant[];\n};\nexport type NewMessageNested = NewMessage & {\n\tvariants: NewVariant[];\n};\nexport type MessageNestedUpdate = Updateable<MessageTable> & {\n\tvariants: VariantUpdate[];\n};\n\nexport type BundleNested = Bundle & {\n\tmessages: MessageNested[];\n};\nexport type NewBundleNested = NewBundle & {\n\tmessages: NewMessageNested[];\n};\nexport type BundleNestedUpdate = BundleUpdate & {\n\tmessages: MessageNestedUpdate[];\n};\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"/","sources":["database/schema.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,WAAW,EACX,OAAO,EACP,iBAAiB,GACjB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,UAAU,WAAW,CAAC,IAAoC;IAC/D,MAAM,mBAAmB,GAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE;QACxE,WAAW,EAAE,YAAY;KACzB,CAAC,CAAC;IACH;IACC,6BAA6B;IAC7B,gCAAgC;IAChC,gDAAgD;IAChD,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAC9B,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,EAAE;YAC5C,WAAW,EAAE,YAAY;SACzB,CAAC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBf,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { Generated, Insertable, Selectable, Updateable } from \"kysely\";\nimport type { SqliteWasmDatabase } from \"sqlite-wasm-kysely\";\nimport {\n\tDeclaration,\n\tPattern,\n\tVariableReference,\n} from \"../json-schema/pattern.js\";\n\nexport function applySchema(args: { sqlite: SqliteWasmDatabase }) {\n\tconst foreignKeyActivated: any = args.sqlite.exec(\"PRAGMA foreign_keys\", {\n\t\treturnValue: \"resultRows\",\n\t});\n\tif (\n\t\t// first row that is returned\n\t\t// first column of the first row\n\t\t// is equal to 0, then foreign keys are disabled\n\t\tforeignKeyActivated[0][0] === 0\n\t) {\n\t\targs.sqlite.exec(\"PRAGMA foreign_keys = ON\", {\n\t\t\treturnValue: \"resultRows\",\n\t\t});\n\t}\n\n\targs.sqlite.exec(`\nCREATE TABLE IF NOT EXISTS bundle (\n id TEXT PRIMARY KEY DEFAULT (human_id()),\n\tdeclarations BLOB NOT NULL DEFAULT (jsonb('[]'))\n) strict;\n\nCREATE TABLE IF NOT EXISTS message (\n id TEXT PRIMARY KEY DEFAULT (uuid_v7()), \n bundle_id TEXT NOT NULL,\n locale TEXT NOT NULL,\n selectors BLOB NOT NULL DEFAULT (jsonb('[]')),\n FOREIGN KEY (bundle_id) REFERENCES bundle(id) ON DELETE CASCADE\n) strict;\n\n\nCREATE TABLE IF NOT EXISTS variant (\n id TEXT PRIMARY KEY DEFAULT (uuid_v7()), \n message_id TEXT NOT NULL,\n matches BLOB NOT NULL DEFAULT (jsonb('[]')),\n pattern BLOB NOT NULL DEFAULT (jsonb('[]')),\n FOREIGN KEY (message_id) REFERENCES message(id) ON DELETE CASCADE\n) strict;\n \nCREATE INDEX IF NOT EXISTS idx_message_bundle_id ON message (bundle_id);\nCREATE INDEX IF NOT EXISTS idx_variant_message_id ON variant (message_id);\n\t\t`);\n}\n\nexport type InlangDatabaseSchema = {\n\tbundle: BundleTable;\n\tmessage: MessageTable;\n\tvariant: VariantTable;\n};\n\ntype BundleTable = {\n\tid: Generated<string>;\n\tdeclarations: Generated<Array<Declaration>>;\n};\n\ntype MessageTable = {\n\tid: Generated<string>;\n\tbundleId: string;\n\tlocale: string;\n\tselectors: Generated<Array<VariableReference>>;\n};\n\ntype VariantTable = {\n\tid: Generated<string>;\n\tmessageId: string;\n\tmatches: Generated<Array<Match>>;\n\tpattern: Generated<Pattern>;\n};\n\n/**\n * A match is a variable reference that is either a literal or a catch-all.\n *\n * https://github.com/opral/inlang/issues/205\n *\n * @example\n * match = { type: \"match\", name: \"gender\", value: { type: \"literal\", value: \"male\" }}\n */\nexport type Match = LiteralMatch | CatchAllMatch;\n\nexport type LiteralMatch = {\n\ttype: \"literal-match\";\n\tkey: VariableReference[\"name\"];\n\tvalue: string;\n};\nexport type CatchAllMatch = {\n\ttype: \"catchall-match\";\n\tkey: VariableReference[\"name\"];\n};\n\nexport type Bundle = Selectable<BundleTable>;\nexport type NewBundle = Insertable<BundleTable>;\nexport type BundleUpdate = Updateable<BundleTable>;\n\nexport type Message = Selectable<MessageTable>;\nexport type NewMessage = Insertable<MessageTable>;\nexport type MessageUpdate = Updateable<MessageTable>;\n\nexport type Variant = Selectable<VariantTable>;\nexport type NewVariant = Insertable<VariantTable>;\nexport type VariantUpdate = Updateable<VariantTable>;\n\nexport type MessageNested = Message & {\n\tvariants: Variant[];\n};\nexport type NewMessageNested = NewMessage & {\n\tvariants: NewVariant[];\n};\nexport type MessageNestedUpdate = Updateable<MessageTable> & {\n\tvariants: VariantUpdate[];\n};\n\nexport type BundleNested = Bundle & {\n\tmessages: MessageNested[];\n};\nexport type NewBundleNested = NewBundle & {\n\tmessages: NewMessageNested[];\n};\nexport type BundleNestedUpdate = BundleUpdate & {\n\tmessages: MessageNestedUpdate[];\n};\n"]}
@@ -85,7 +85,7 @@ async function handleForeignKeyViolation(args) {
85
85
  // TODO shouldn't throw. The API needs to be able to
86
86
  // report issues back to the app without throwing and potentially failing
87
87
  // to apply 1000 changes because 1 change is invalid
88
- // same requirement as in inlang, see https://github.com/opral/inlang-sdk/issues/213
88
+ // same requirement as in inlang, see https://github.com/opral/inlang/issues/213
89
89
  .executeTakeFirstOrThrow();
90
90
  if (args.change.type === "message") {
91
91
  const lastKnownBundle = await lastKnown("bundle", args.change.value?.bundleId);
@@ -1 +1 @@
1
- {"version":3,"file":"applyChanges.js","sourceRoot":"/","sources":["lix-plugin/applyChanges.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\n\nimport {\n\tgetLeafChange,\n\ttype Change,\n\ttype LixPlugin,\n\ttype LixReadonly,\n} from \"@lix-js/sdk\";\nimport { contentFromDatabase, loadDatabaseInMemory } from \"sqlite-wasm-kysely\";\nimport { initDb } from \"../database/initDb.js\";\nimport type { Kysely } from \"kysely\";\nimport type { InlangDatabaseSchema } from \"../database/schema.js\";\n\nexport const applyChanges: NonNullable<LixPlugin[\"applyChanges\"]> = async ({\n\tlix,\n\tfile,\n\tchanges,\n}) => {\n\tif (file.path?.endsWith(\"db.sqlite\") === false) {\n\t\tthrow new Error(\n\t\t\t\"Unimplemented. Only the db.sqlite file can be handled for now.\"\n\t\t);\n\t}\n\n\t// todo make transactional\n\n\tconst sqlite = await loadDatabaseInMemory(file.data);\n\tconst db = initDb({ sqlite });\n\n\t// the award for the most inefficient deduplication goes to...\n\tconst leafChanges = [\n\t\t...new Set(\n\t\t\tawait Promise.all(\n\t\t\t\tchanges.map(async (change) => {\n\t\t\t\t\tconst leafChange = await getLeafChange({ change, lix });\n\t\t\t\t\t// enable string comparison to avoid duplicates\n\t\t\t\t\treturn JSON.stringify(leafChange);\n\t\t\t\t})\n\t\t\t)\n\t\t),\n\t].map((v) => JSON.parse(v));\n\n\t// changes need to be applied in order of foreign keys to avoid constraint violations\n\t// 1. bundles\n\t// 2. messages\n\t// 3. variants\n\tconst applyOrder: Record<string, number> = {\n\t\tbundle: 1,\n\t\tmessage: 2,\n\t\tvariant: 3,\n\t};\n\n\t// future optimization potential here but sorting in one go\n\tconst orderedLeafChanges = [...leafChanges].sort((a, b) => {\n\t\tconst orderA = applyOrder[a.type];\n\t\tconst orderB = applyOrder[b.type];\n\n\t\tif (orderA === undefined || orderB === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`Received an unknown entity type: ${a.type} && ${\n\t\t\t\t\tb.type\n\t\t\t\t}. Expected one of: ${Object.keys(applyOrder)}`\n\t\t\t);\n\t\t}\n\n\t\treturn orderA - orderB;\n\t});\n\tfor (const leafChange of orderedLeafChanges) {\n\t\t// deletion\n\t\tif (leafChange.value === undefined) {\n\t\t\tawait db\n\t\t\t\t.deleteFrom(leafChange.type as \"bundle\" | \"message\" | \"variant\")\n\t\t\t\t.where(\"id\", \"=\", leafChange.meta?.id)\n\t\t\t\t.execute();\n\t\t\tcontinue;\n\t\t}\n\n\t\t// upsert the value\n\t\tconst value = leafChange.value as any;\n\n\t\ttry {\n\t\t\tawait db\n\t\t\t\t.insertInto(leafChange.type as \"bundle\" | \"message\" | \"variant\")\n\t\t\t\t.values(value)\n\t\t\t\t.onConflict((c) => c.column(\"id\").doUpdateSet(value))\n\t\t\t\t.execute();\n\t\t} catch (e) {\n\t\t\t// 787 = SQLITE_CONSTRAINT_FOREIGNKEY\n\t\t\tif (e instanceof Error && (e as any)?.resultCode === 787) {\n\t\t\t\tawait handleForeignKeyViolation({ change: leafChange, lix, db });\n\t\t\t} else {\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t}\n\treturn { fileData: contentFromDatabase(sqlite) };\n};\n\n/**\n * Handles foreign key violations e.g. a change\n * doesn't exist in the target database but is referenced\n * by an entity.\n */\nasync function handleForeignKeyViolation(args: {\n\tchange: Change;\n\tlix: LixReadonly;\n\tdb: Kysely<InlangDatabaseSchema>;\n}) {\n\tconst lastKnown = async (\n\t\ttype: \"bundle\" | \"message\" | \"variant\",\n\t\tid: string\n\t) =>\n\t\tawait args.lix.db\n\t\t\t.selectFrom(\"change\")\n\t\t\t.selectAll()\n\t\t\t// heuristic that getting the last bundle value is fine\n\t\t\t// and using created_at is fine too. if the change is undesired\n\t\t\t// , a user can revert it with lix change control\n\t\t\t.orderBy(\"created_at desc\")\n\t\t\t.where(\"type\", \"=\", type)\n\t\t\t.where((eb) => eb.ref(\"value\", \"->>\").key(\"id\"), \"=\", id)\n\t\t\t.where(\"operation\", \"in\", [\"create\", \"update\"])\n\t\t\t// TODO shouldn't throw. The API needs to be able to\n\t\t\t// report issues back to the app without throwing and potentially failing\n\t\t\t// to apply 1000 changes because 1 change is invalid\n\t\t\t// same requirement as in inlang, see https://github.com/opral/inlang-sdk/issues/213\n\t\t\t.executeTakeFirstOrThrow();\n\n\tif (args.change.type === \"message\") {\n\t\tconst lastKnownBundle = await lastKnown(\n\t\t\t\"bundle\",\n\t\t\targs.change.value?.bundleId\n\t\t);\n\t\tawait args.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values(lastKnownBundle.value as any)\n\t\t\t.execute();\n\t} else if (args.change.type === \"variant\") {\n\t\tconst lastKnownMessage = await lastKnown(\n\t\t\t\"message\",\n\t\t\targs.change.value?.messageId\n\t\t);\n\t\t// getting the bundle too out of precaution\n\t\tconst lastKnownBundle = await lastKnown(\n\t\t\t\"bundle\",\n\t\t\tlastKnownMessage.value?.bundleId\n\t\t);\n\t\tawait args.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values(lastKnownBundle.value as any)\n\t\t\t// the bundle exists, so we can ignore the conflict\n\t\t\t.onConflict((c) => c.doNothing())\n\t\t\t.execute();\n\t\tawait args.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values(lastKnownMessage.value as any)\n\t\t\t.execute();\n\t\tawait args.db\n\t\t\t.insertInto(args.change.type as \"bundle\" | \"message\" | \"variant\")\n\t\t\t.values(args.change.value as any)\n\t\t\t.onConflict((c) => c.column(\"id\").doUpdateSet(args.change.value as any))\n\t\t\t.execute();\n\t}\n\t// re-execute applying the change\n\tawait args.db\n\t\t.insertInto(args.change.type as \"bundle\" | \"message\" | \"variant\")\n\t\t.values(args.change.value as any)\n\t\t.onConflict((c) => c.column(\"id\").doUpdateSet(args.change.value as any))\n\t\t.execute();\n}\n"]}
1
+ {"version":3,"file":"applyChanges.js","sourceRoot":"/","sources":["lix-plugin/applyChanges.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\n\nimport {\n\tgetLeafChange,\n\ttype Change,\n\ttype LixPlugin,\n\ttype LixReadonly,\n} from \"@lix-js/sdk\";\nimport { contentFromDatabase, loadDatabaseInMemory } from \"sqlite-wasm-kysely\";\nimport { initDb } from \"../database/initDb.js\";\nimport type { Kysely } from \"kysely\";\nimport type { InlangDatabaseSchema } from \"../database/schema.js\";\n\nexport const applyChanges: NonNullable<LixPlugin[\"applyChanges\"]> = async ({\n\tlix,\n\tfile,\n\tchanges,\n}) => {\n\tif (file.path?.endsWith(\"db.sqlite\") === false) {\n\t\tthrow new Error(\n\t\t\t\"Unimplemented. Only the db.sqlite file can be handled for now.\"\n\t\t);\n\t}\n\n\t// todo make transactional\n\n\tconst sqlite = await loadDatabaseInMemory(file.data);\n\tconst db = initDb({ sqlite });\n\n\t// the award for the most inefficient deduplication goes to...\n\tconst leafChanges = [\n\t\t...new Set(\n\t\t\tawait Promise.all(\n\t\t\t\tchanges.map(async (change) => {\n\t\t\t\t\tconst leafChange = await getLeafChange({ change, lix });\n\t\t\t\t\t// enable string comparison to avoid duplicates\n\t\t\t\t\treturn JSON.stringify(leafChange);\n\t\t\t\t})\n\t\t\t)\n\t\t),\n\t].map((v) => JSON.parse(v));\n\n\t// changes need to be applied in order of foreign keys to avoid constraint violations\n\t// 1. bundles\n\t// 2. messages\n\t// 3. variants\n\tconst applyOrder: Record<string, number> = {\n\t\tbundle: 1,\n\t\tmessage: 2,\n\t\tvariant: 3,\n\t};\n\n\t// future optimization potential here but sorting in one go\n\tconst orderedLeafChanges = [...leafChanges].sort((a, b) => {\n\t\tconst orderA = applyOrder[a.type];\n\t\tconst orderB = applyOrder[b.type];\n\n\t\tif (orderA === undefined || orderB === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`Received an unknown entity type: ${a.type} && ${\n\t\t\t\t\tb.type\n\t\t\t\t}. Expected one of: ${Object.keys(applyOrder)}`\n\t\t\t);\n\t\t}\n\n\t\treturn orderA - orderB;\n\t});\n\tfor (const leafChange of orderedLeafChanges) {\n\t\t// deletion\n\t\tif (leafChange.value === undefined) {\n\t\t\tawait db\n\t\t\t\t.deleteFrom(leafChange.type as \"bundle\" | \"message\" | \"variant\")\n\t\t\t\t.where(\"id\", \"=\", leafChange.meta?.id)\n\t\t\t\t.execute();\n\t\t\tcontinue;\n\t\t}\n\n\t\t// upsert the value\n\t\tconst value = leafChange.value as any;\n\n\t\ttry {\n\t\t\tawait db\n\t\t\t\t.insertInto(leafChange.type as \"bundle\" | \"message\" | \"variant\")\n\t\t\t\t.values(value)\n\t\t\t\t.onConflict((c) => c.column(\"id\").doUpdateSet(value))\n\t\t\t\t.execute();\n\t\t} catch (e) {\n\t\t\t// 787 = SQLITE_CONSTRAINT_FOREIGNKEY\n\t\t\tif (e instanceof Error && (e as any)?.resultCode === 787) {\n\t\t\t\tawait handleForeignKeyViolation({ change: leafChange, lix, db });\n\t\t\t} else {\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t}\n\t}\n\treturn { fileData: contentFromDatabase(sqlite) };\n};\n\n/**\n * Handles foreign key violations e.g. a change\n * doesn't exist in the target database but is referenced\n * by an entity.\n */\nasync function handleForeignKeyViolation(args: {\n\tchange: Change;\n\tlix: LixReadonly;\n\tdb: Kysely<InlangDatabaseSchema>;\n}) {\n\tconst lastKnown = async (\n\t\ttype: \"bundle\" | \"message\" | \"variant\",\n\t\tid: string\n\t) =>\n\t\tawait args.lix.db\n\t\t\t.selectFrom(\"change\")\n\t\t\t.selectAll()\n\t\t\t// heuristic that getting the last bundle value is fine\n\t\t\t// and using created_at is fine too. if the change is undesired\n\t\t\t// , a user can revert it with lix change control\n\t\t\t.orderBy(\"created_at desc\")\n\t\t\t.where(\"type\", \"=\", type)\n\t\t\t.where((eb) => eb.ref(\"value\", \"->>\").key(\"id\"), \"=\", id)\n\t\t\t.where(\"operation\", \"in\", [\"create\", \"update\"])\n\t\t\t// TODO shouldn't throw. The API needs to be able to\n\t\t\t// report issues back to the app without throwing and potentially failing\n\t\t\t// to apply 1000 changes because 1 change is invalid\n\t\t\t// same requirement as in inlang, see https://github.com/opral/inlang/issues/213\n\t\t\t.executeTakeFirstOrThrow();\n\n\tif (args.change.type === \"message\") {\n\t\tconst lastKnownBundle = await lastKnown(\n\t\t\t\"bundle\",\n\t\t\targs.change.value?.bundleId\n\t\t);\n\t\tawait args.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values(lastKnownBundle.value as any)\n\t\t\t.execute();\n\t} else if (args.change.type === \"variant\") {\n\t\tconst lastKnownMessage = await lastKnown(\n\t\t\t\"message\",\n\t\t\targs.change.value?.messageId\n\t\t);\n\t\t// getting the bundle too out of precaution\n\t\tconst lastKnownBundle = await lastKnown(\n\t\t\t\"bundle\",\n\t\t\tlastKnownMessage.value?.bundleId\n\t\t);\n\t\tawait args.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values(lastKnownBundle.value as any)\n\t\t\t// the bundle exists, so we can ignore the conflict\n\t\t\t.onConflict((c) => c.doNothing())\n\t\t\t.execute();\n\t\tawait args.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values(lastKnownMessage.value as any)\n\t\t\t.execute();\n\t\tawait args.db\n\t\t\t.insertInto(args.change.type as \"bundle\" | \"message\" | \"variant\")\n\t\t\t.values(args.change.value as any)\n\t\t\t.onConflict((c) => c.column(\"id\").doUpdateSet(args.change.value as any))\n\t\t\t.execute();\n\t}\n\t// re-execute applying the change\n\tawait args.db\n\t\t.insertInto(args.change.type as \"bundle\" | \"message\" | \"variant\")\n\t\t.values(args.change.value as any)\n\t\t.onConflict((c) => c.column(\"id\").doUpdateSet(args.change.value as any))\n\t\t.execute();\n}\n"]}
@@ -331,7 +331,7 @@ describe.skip("plugin.diff.file", () => {
331
331
  },
332
332
  ]);
333
333
  });
334
- // https://github.com/opral/lix-sdk/issues/33
334
+ // https://github.com/opral/lix/issues/33
335
335
  test("it should generate changes after the first change", async () => {
336
336
  const project = await loadProjectInMemory({ blob: await newProject() });
337
337
  const initialChanges = await project.lix.db
@@ -1 +1 @@
1
- {"version":3,"file":"inlangLixPluginV1.test.js","sourceRoot":"/","sources":["lix-plugin/inlangLixPluginV1.test.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,cAAc;AAEd,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAmB,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE;IACtC,IAAI,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC;YACP,EAAE,EAAE,GAAG;SACP,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,YAAY,CAAC;QAC1B,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAK,CAAC;YACtD,GAAG,EAAE,SAAS;YACd,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI;gBACJ,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;SACD,CAAC,CAAC;QACH,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC;YAC3B;gBACC,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,QAAQ;gBACnB,GAAG,EAAE,SAAS;gBACd,GAAG,EAAE,MAAM,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;aACpB;SACtB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,4BAA4B;IAC5B,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC;YACP;gBACC,EAAE,EAAE,GAAG;aACP;YACD;gBACC,EAAE,EAAE,GAAG;aACP;SACD,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC;YACP;gBACC,EAAE,EAAE,GAAG;aACP;YACD;gBACC,EAAE,EAAE,GAAG;aACP;SACD,CAAC;aACD,OAAO,EAAE,CAAC;QAEZ,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAK,CAAC;YACtD,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;YACD,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;SACD,CAAC,CAAC;QAEH,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC;YAC3B;gBACC,IAAI,EAAE;oBACL,EAAE,EAAE,GAAG;iBACP;gBACD,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,QAAQ;gBACnB,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE;gBAChB,GAAG,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE;aACK;SACtB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;aACzB,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC;YACP,EAAE,EAAE,GAAG;YACP,QAAQ,EAAE,SAAS;YACnB,MAAM,EAAE,IAAI;SACZ,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAK,CAAC;YACtD,GAAG,EAAE,SAAS;YACd,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;SACD,CAAC,CAAC;QACH,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAC1B,MAAM,CAAC,eAAe,CAAC;YACtB;gBACC,IAAI,EAAE,SAAS;gBACf,SAAS,EAAE,QAAQ;gBACnB,GAAG,EAAE,SAAS;gBACd,GAAG,EAAE;oBACJ,EAAE,EAAE,GAAG;oBACP,QAAQ,EAAE,SAAS;oBACnB,SAAS,EAAE,EAAE;oBACb,MAAM,EAAE,IAAI;iBACZ;aACoB;SACtB,CAAC,CACF,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;aACzB,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC;YACP;gBACC,EAAE,EAAE,GAAG;gBACP,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,IAAI;aACZ;YACD;gBACC,EAAE,EAAE,GAAG;gBACP,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,IAAI;aACZ;SACD,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;aACzB,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC;YACP;gBACC,EAAE,EAAE,GAAG;gBACP,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,IAAI;aACZ;YACD;gBACC,EAAE,EAAE,GAAG;gBACP,QAAQ,EAAE,SAAS;gBACnB,MAAM,EAAE,IAAI;aACZ;SACD,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAK,CAAC;YACtD,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;YACD,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;SACD,CAAC,CAAC;QACH,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAC1B,MAAM,CAAC,eAAe,CAAC;YACtB;gBACC,IAAI,EAAE;oBACL,EAAE,EAAE,GAAG;iBACP;gBACD,IAAI,EAAE,SAAS;gBACf,SAAS,EAAE,QAAQ;gBACnB,GAAG,EAAE;oBACJ,EAAE,EAAE,GAAG;oBACP,QAAQ,EAAE,SAAS;oBACnB,SAAS,EAAE,EAAE;oBACb,MAAM,EAAE,IAAI;iBACZ;gBACD,GAAG,EAAE;oBACJ,EAAE,EAAE,GAAG;oBACP,QAAQ,EAAE,SAAS;oBACnB,SAAS,EAAE,EAAE;oBACb,MAAM,EAAE,IAAI;iBACZ;aACoB;SACtB,CAAC,CACF,CAAC;IACH,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;aACzB,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aACtD,OAAO,EAAE,CAAC;QAEZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC;YACP,EAAE,EAAE,GAAG;YACP,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;YACjD,OAAO,EAAE,EAAE;SACX,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAK,CAAC;YACtD,GAAG,EAAE,SAAS;YACd,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;SACD,CAAC,CAAC;QACH,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAC1B,MAAM,CAAC,eAAe,CAAC;YACtB;gBACC,IAAI,EAAE,SAAS;gBACf,SAAS,EAAE,QAAQ;gBACnB,GAAG,EAAE,SAAS;gBACd,GAAG,EAAE;oBACJ,EAAE,EAAE,GAAG;oBACP,SAAS,EAAE,GAAG;oBACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;oBACjD,OAAO,EAAE,EAAE;iBACX;aACoB;SACtB,CAAC,CACF,CAAC;IACH,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;aACzB,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aACtD,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC;YACP;gBACC,EAAE,EAAE,GAAG;gBACP,SAAS,EAAE,GAAG;gBACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;gBACjD,OAAO,EAAE,EAAE;aACX;YACD;gBACC,EAAE,EAAE,GAAG;gBACP,SAAS,EAAE,GAAG;gBACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;gBACjD,OAAO,EAAE,EAAE;aACX;SACD,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAC3E,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;aACzB,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;aACtD,OAAO,EAAE,CAAC;QACZ,MAAM,UAAU,CAAC,EAAE;aACjB,UAAU,CAAC,SAAS,CAAC;aACrB,MAAM,CAAC;YACP;gBACC,EAAE,EAAE,GAAG;gBACP,SAAS,EAAE,GAAG;gBACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;gBAC7D,OAAO,EAAE,EAAE;aACX;YACD;gBACC,EAAE,EAAE,GAAG;gBACP,SAAS,EAAE,GAAG;gBACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;gBACjD,OAAO,EAAE,EAAE;aACX;SACD,CAAC;aACD,OAAO,EAAE,CAAC;QACZ,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAK,CAAC;YACtD,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;YACD,GAAG,EAAE;gBACJ,EAAE,EAAE,MAAM;gBACV,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC7C,QAAQ,EAAE,EAAE;aACZ;SACD,CAAC,CAAC;QACH,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC;YAC3B;gBACC,IAAI,EAAE;oBACL,EAAE,EAAE,GAAG;iBACP;gBACD,SAAS,EAAE,QAAQ;gBACnB,IAAI,EAAE,SAAS;gBACf,GAAG,EAAE;oBACJ,EAAE,EAAE,GAAG;oBACP,SAAS,EAAE,GAAG;oBACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;oBACjD,OAAO,EAAE,EAAE;iBACX;gBACD,GAAG,EAAE;oBACJ,EAAE,EAAE,GAAG;oBACP,SAAS,EAAE,GAAG;oBACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;oBAC7D,OAAO,EAAE,EAAE;iBACX;aACoB;SACtB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,6CAA6C;IAC7C,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,MAAM,UAAU,EAAE,EAAE,CAAC,CAAC;QAExE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE;aACzC,UAAU,CAAC,QAAQ,CAAC;aACpB,SAAS,EAAE;aACX,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAEzC,MAAM,OAAO,CAAC,EAAE;aACd,UAAU,CAAC,QAAQ,CAAC;aACpB,MAAM,CAAC;YACP,EAAE,EAAE,GAAG;SACP,CAAC;aACD,OAAO,EAAE,CAAC;QAEZ,kEAAkE;QAClE,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAEzD,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAE5B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE;aAClC,UAAU,CAAC,QAAQ,CAAC;aACpB,SAAS,EAAE;aACX,OAAO,EAAE,CAAC;QAEZ,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACzC,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,GAAG,GAAY;YACpB,EAAE,EAAE,GAAG;YACP,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;SACjD,CAAC;QACF,MAAM,GAAG,GAAY;YACpB,EAAE,EAAE,GAAG;YACP,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;SACjD,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,GAAG,GAAY;YACpB,EAAE,EAAE,GAAG;YACP,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;SACjD,CAAC;QACF,MAAM,GAAG,GAAY;YACpB,EAAE,EAAE,GAAG;YACP,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;SAC7D,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACpB;gBACC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE;gBACjB,SAAS,EAAE,QAAQ;gBACnB,IAAI,EAAE,SAAS;gBACf,GAAG;gBACH,GAAG;aACkB;SACtB,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QACpG,MAAM,GAAG,GAAG,SAAS,CAAC;QACtB,MAAM,GAAG,GAAY;YACpB,EAAE,EAAE,GAAG;YACP,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,GAAG;YACd,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;SACjD,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACpB,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,EAAuB;SACvE,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\n\nimport { test, expect, describe } from \"vitest\";\nimport { inlangLixPluginV1 } from \"./inlangLixPluginV1.js\";\nimport { type DiffReport } from \"@lix-js/sdk\";\nimport { newProject } from \"../project/newProject.js\";\nimport { loadProjectInMemory } from \"../project/loadProjectInMemory.js\";\nimport { contentFromDatabase } from \"sqlite-wasm-kysely\";\nimport type { Variant } from \"../database/schema.js\";\n\ndescribe.skip(\"plugin.diff.file\", () => {\n\ttest(\"insert of bundle\", async () => {\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({\n\t\t\t\tid: \"1\",\n\t\t\t})\n\t\t\t.execute();\n\t\tconst path = \"/db.sqlite\";\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: undefined,\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath,\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual([\n\t\t\t{\n\t\t\t\ttype: \"bundle\",\n\t\t\t\toperation: \"create\",\n\t\t\t\told: undefined,\n\t\t\t\tneu: expect.objectContaining({ id: \"1\" }),\n\t\t\t} satisfies DiffReport,\n\t\t]);\n\t});\n\n\t// reanble with declarations\n\ttest.todo(\"update of bundle\", async () => {\n\t\tconst oldProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(oldProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\n\t\texpect(diffReports).toEqual([\n\t\t\t{\n\t\t\t\tmeta: {\n\t\t\t\t\tid: \"1\",\n\t\t\t\t},\n\t\t\t\ttype: \"bundle\",\n\t\t\t\toperation: \"update\",\n\t\t\t\told: { id: \"1\" },\n\t\t\t\tneu: { id: \"1\" },\n\t\t\t} satisfies DiffReport,\n\t\t]);\n\t});\n\n\ttest(\"insert of message\", async () => {\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"unknown\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({\n\t\t\t\tid: \"1\",\n\t\t\t\tbundleId: \"unknown\",\n\t\t\t\tlocale: \"en\",\n\t\t\t})\n\t\t\t.execute();\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: undefined,\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual(\n\t\t\texpect.arrayContaining([\n\t\t\t\t{\n\t\t\t\t\ttype: \"message\",\n\t\t\t\t\toperation: \"create\",\n\t\t\t\t\told: undefined,\n\t\t\t\t\tneu: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\t\tselectors: [],\n\t\t\t\t\t\tlocale: \"en\",\n\t\t\t\t\t},\n\t\t\t\t} satisfies DiffReport,\n\t\t\t])\n\t\t);\n\t});\n\n\ttest(\"update of message\", async () => {\n\t\tconst oldProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"unknown\" })\n\t\t\t.execute();\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\tlocale: \"en\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\tlocale: \"en\",\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"unknown\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\tlocale: \"de\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\tlocale: \"en\",\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(oldProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual(\n\t\t\texpect.arrayContaining([\n\t\t\t\t{\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t},\n\t\t\t\t\ttype: \"message\",\n\t\t\t\t\toperation: \"update\",\n\t\t\t\t\told: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\t\tselectors: [],\n\t\t\t\t\t\tlocale: \"en\",\n\t\t\t\t\t},\n\t\t\t\t\tneu: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\t\tselectors: [],\n\t\t\t\t\t\tlocale: \"de\",\n\t\t\t\t\t},\n\t\t\t\t} satisfies DiffReport,\n\t\t\t])\n\t\t);\n\t});\n\ttest(\"insert of variant\", async () => {\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"bundle1\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({ id: \"1\", bundleId: \"bundle1\", locale: \"en\" })\n\t\t\t.execute();\n\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"variant\")\n\t\t\t.values({\n\t\t\t\tid: \"1\",\n\t\t\t\tmessageId: \"1\",\n\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\tmatches: [],\n\t\t\t})\n\t\t\t.execute();\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: undefined,\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual(\n\t\t\texpect.arrayContaining([\n\t\t\t\t{\n\t\t\t\t\ttype: \"variant\",\n\t\t\t\t\toperation: \"create\",\n\t\t\t\t\told: undefined,\n\t\t\t\t\tneu: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\t\tmatches: [],\n\t\t\t\t\t},\n\t\t\t\t} satisfies DiffReport,\n\t\t\t])\n\t\t);\n\t});\n\ttest(\"update of variant\", async () => {\n\t\tconst oldProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"bundle1\" })\n\t\t\t.execute();\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({ id: \"1\", bundleId: \"bundle1\", locale: \"en\" })\n\t\t\t.execute();\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"variant\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"bundle1\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({ id: \"1\", bundleId: \"bundle1\", locale: \"en\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"variant\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world from Berlin\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(oldProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual([\n\t\t\t{\n\t\t\t\tmeta: {\n\t\t\t\t\tid: \"1\",\n\t\t\t\t},\n\t\t\t\toperation: \"update\",\n\t\t\t\ttype: \"variant\",\n\t\t\t\told: {\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t\tneu: {\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world from Berlin\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t} satisfies DiffReport,\n\t\t]);\n\t});\n\n\t// https://github.com/opral/lix-sdk/issues/33\n\ttest(\"it should generate changes after the first change\", async () => {\n\t\tconst project = await loadProjectInMemory({ blob: await newProject() });\n\n\t\tconst initialChanges = await project.lix.db\n\t\t\t.selectFrom(\"change\")\n\t\t\t.selectAll()\n\t\t\t.execute();\n\t\texpect(initialChanges.length).toEqual(0);\n\n\t\tawait project.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({\n\t\t\t\tid: \"1\",\n\t\t\t})\n\t\t\t.execute();\n\n\t\t// FIXME: how to await inlang sdk persisting the inlang db to lix?\n\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\n\t\tawait project.lix.settled();\n\n\t\tconst changes = await project.lix.db\n\t\t\t.selectFrom(\"change\")\n\t\t\t.selectAll()\n\t\t\t.execute();\n\n\t\texpect(changes.length).toBe(1);\n\t\texpect(changes[0]?.value?.id).toBe(\"1\");\n\t\texpect(changes[0]?.operation).toBe(\"create\");\n\t});\n});\n\ndescribe.skip(\"plugin.diff.variant\", () => {\n\ttest(\"old and neu are the same should not report a diff\", async () => {\n\t\tconst old: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t};\n\t\tconst neu: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t};\n\t\tconst diff = await inlangLixPluginV1.diff.variant({ old, neu });\n\t\texpect(diff).toEqual([]);\n\t});\n\n\ttest(\"old and neu are different should yield a diff report\", async () => {\n\t\tconst old: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t};\n\t\tconst neu: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world from Berlin\" }],\n\t\t};\n\t\tconst diff = await inlangLixPluginV1.diff.variant({ old, neu });\n\t\texpect(diff).toEqual([\n\t\t\t{\n\t\t\t\tmeta: { id: \"1\" },\n\t\t\t\toperation: \"update\",\n\t\t\t\ttype: \"variant\",\n\t\t\t\tneu,\n\t\t\t\told,\n\t\t\t} satisfies DiffReport,\n\t\t]);\n\t});\n\n\ttest(\"old is undefined and neu is defined should return a diff report for the new value\", async () => {\n\t\tconst old = undefined;\n\t\tconst neu: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t};\n\t\tconst diff = await inlangLixPluginV1.diff.variant({ old, neu });\n\t\texpect(diff).toEqual([\n\t\t\t{ operation: \"create\", type: \"variant\", neu, old } satisfies DiffReport,\n\t\t]);\n\t});\n});\n"]}
1
+ {"version":3,"file":"inlangLixPluginV1.test.js","sourceRoot":"/","sources":["lix-plugin/inlangLixPluginV1.test.ts"],"names":[],"mappings":"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","sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\n\nimport { test, expect, describe } from \"vitest\";\nimport { inlangLixPluginV1 } from \"./inlangLixPluginV1.js\";\nimport { type DiffReport } from \"@lix-js/sdk\";\nimport { newProject } from \"../project/newProject.js\";\nimport { loadProjectInMemory } from \"../project/loadProjectInMemory.js\";\nimport { contentFromDatabase } from \"sqlite-wasm-kysely\";\nimport type { Variant } from \"../database/schema.js\";\n\ndescribe.skip(\"plugin.diff.file\", () => {\n\ttest(\"insert of bundle\", async () => {\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({\n\t\t\t\tid: \"1\",\n\t\t\t})\n\t\t\t.execute();\n\t\tconst path = \"/db.sqlite\";\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: undefined,\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath,\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual([\n\t\t\t{\n\t\t\t\ttype: \"bundle\",\n\t\t\t\toperation: \"create\",\n\t\t\t\told: undefined,\n\t\t\t\tneu: expect.objectContaining({ id: \"1\" }),\n\t\t\t} satisfies DiffReport,\n\t\t]);\n\t});\n\n\t// reanble with declarations\n\ttest.todo(\"update of bundle\", async () => {\n\t\tconst oldProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(oldProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\n\t\texpect(diffReports).toEqual([\n\t\t\t{\n\t\t\t\tmeta: {\n\t\t\t\t\tid: \"1\",\n\t\t\t\t},\n\t\t\t\ttype: \"bundle\",\n\t\t\t\toperation: \"update\",\n\t\t\t\told: { id: \"1\" },\n\t\t\t\tneu: { id: \"1\" },\n\t\t\t} satisfies DiffReport,\n\t\t]);\n\t});\n\n\ttest(\"insert of message\", async () => {\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"unknown\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({\n\t\t\t\tid: \"1\",\n\t\t\t\tbundleId: \"unknown\",\n\t\t\t\tlocale: \"en\",\n\t\t\t})\n\t\t\t.execute();\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: undefined,\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual(\n\t\t\texpect.arrayContaining([\n\t\t\t\t{\n\t\t\t\t\ttype: \"message\",\n\t\t\t\t\toperation: \"create\",\n\t\t\t\t\told: undefined,\n\t\t\t\t\tneu: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\t\tselectors: [],\n\t\t\t\t\t\tlocale: \"en\",\n\t\t\t\t\t},\n\t\t\t\t} satisfies DiffReport,\n\t\t\t])\n\t\t);\n\t});\n\n\ttest(\"update of message\", async () => {\n\t\tconst oldProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"unknown\" })\n\t\t\t.execute();\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\tlocale: \"en\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\tlocale: \"en\",\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"unknown\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\tlocale: \"de\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\tlocale: \"en\",\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(oldProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual(\n\t\t\texpect.arrayContaining([\n\t\t\t\t{\n\t\t\t\t\tmeta: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t},\n\t\t\t\t\ttype: \"message\",\n\t\t\t\t\toperation: \"update\",\n\t\t\t\t\told: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\t\tselectors: [],\n\t\t\t\t\t\tlocale: \"en\",\n\t\t\t\t\t},\n\t\t\t\t\tneu: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t\tbundleId: \"unknown\",\n\t\t\t\t\t\tselectors: [],\n\t\t\t\t\t\tlocale: \"de\",\n\t\t\t\t\t},\n\t\t\t\t} satisfies DiffReport,\n\t\t\t])\n\t\t);\n\t});\n\ttest(\"insert of variant\", async () => {\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"bundle1\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({ id: \"1\", bundleId: \"bundle1\", locale: \"en\" })\n\t\t\t.execute();\n\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"variant\")\n\t\t\t.values({\n\t\t\t\tid: \"1\",\n\t\t\t\tmessageId: \"1\",\n\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\tmatches: [],\n\t\t\t})\n\t\t\t.execute();\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: undefined,\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual(\n\t\t\texpect.arrayContaining([\n\t\t\t\t{\n\t\t\t\t\ttype: \"variant\",\n\t\t\t\t\toperation: \"create\",\n\t\t\t\t\told: undefined,\n\t\t\t\t\tneu: {\n\t\t\t\t\t\tid: \"1\",\n\t\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\t\tmatches: [],\n\t\t\t\t\t},\n\t\t\t\t} satisfies DiffReport,\n\t\t\t])\n\t\t);\n\t});\n\ttest(\"update of variant\", async () => {\n\t\tconst oldProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"bundle1\" })\n\t\t\t.execute();\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({ id: \"1\", bundleId: \"bundle1\", locale: \"en\" })\n\t\t\t.execute();\n\t\tawait oldProject.db\n\t\t\t.insertInto(\"variant\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst neuProject = await loadProjectInMemory({ blob: await newProject() });\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({ id: \"bundle1\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"message\")\n\t\t\t.values({ id: \"1\", bundleId: \"bundle1\", locale: \"en\" })\n\t\t\t.execute();\n\t\tawait neuProject.db\n\t\t\t.insertInto(\"variant\")\n\t\t\t.values([\n\t\t\t\t{\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world from Berlin\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tid: \"2\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t])\n\t\t\t.execute();\n\t\tconst diffReports = await inlangLixPluginV1.diff.file!({\n\t\t\told: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(oldProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t\tneu: {\n\t\t\t\tid: \"uuid\",\n\t\t\t\tpath: \"/db.sqlite\",\n\t\t\t\tdata: contentFromDatabase(neuProject._sqlite),\n\t\t\t\tmetadata: {},\n\t\t\t},\n\t\t});\n\t\texpect(diffReports).toEqual([\n\t\t\t{\n\t\t\t\tmeta: {\n\t\t\t\t\tid: \"1\",\n\t\t\t\t},\n\t\t\t\toperation: \"update\",\n\t\t\t\ttype: \"variant\",\n\t\t\t\told: {\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t\tneu: {\n\t\t\t\t\tid: \"1\",\n\t\t\t\t\tmessageId: \"1\",\n\t\t\t\t\tpattern: [{ type: \"text\", value: \"hello world from Berlin\" }],\n\t\t\t\t\tmatches: [],\n\t\t\t\t},\n\t\t\t} satisfies DiffReport,\n\t\t]);\n\t});\n\n\t// https://github.com/opral/lix/issues/33\n\ttest(\"it should generate changes after the first change\", async () => {\n\t\tconst project = await loadProjectInMemory({ blob: await newProject() });\n\n\t\tconst initialChanges = await project.lix.db\n\t\t\t.selectFrom(\"change\")\n\t\t\t.selectAll()\n\t\t\t.execute();\n\t\texpect(initialChanges.length).toEqual(0);\n\n\t\tawait project.db\n\t\t\t.insertInto(\"bundle\")\n\t\t\t.values({\n\t\t\t\tid: \"1\",\n\t\t\t})\n\t\t\t.execute();\n\n\t\t// FIXME: how to await inlang sdk persisting the inlang db to lix?\n\t\tawait new Promise((resolve) => setTimeout(resolve, 500));\n\n\t\tawait project.lix.settled();\n\n\t\tconst changes = await project.lix.db\n\t\t\t.selectFrom(\"change\")\n\t\t\t.selectAll()\n\t\t\t.execute();\n\n\t\texpect(changes.length).toBe(1);\n\t\texpect(changes[0]?.value?.id).toBe(\"1\");\n\t\texpect(changes[0]?.operation).toBe(\"create\");\n\t});\n});\n\ndescribe.skip(\"plugin.diff.variant\", () => {\n\ttest(\"old and neu are the same should not report a diff\", async () => {\n\t\tconst old: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t};\n\t\tconst neu: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t};\n\t\tconst diff = await inlangLixPluginV1.diff.variant({ old, neu });\n\t\texpect(diff).toEqual([]);\n\t});\n\n\ttest(\"old and neu are different should yield a diff report\", async () => {\n\t\tconst old: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t};\n\t\tconst neu: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world from Berlin\" }],\n\t\t};\n\t\tconst diff = await inlangLixPluginV1.diff.variant({ old, neu });\n\t\texpect(diff).toEqual([\n\t\t\t{\n\t\t\t\tmeta: { id: \"1\" },\n\t\t\t\toperation: \"update\",\n\t\t\t\ttype: \"variant\",\n\t\t\t\tneu,\n\t\t\t\told,\n\t\t\t} satisfies DiffReport,\n\t\t]);\n\t});\n\n\ttest(\"old is undefined and neu is defined should return a diff report for the new value\", async () => {\n\t\tconst old = undefined;\n\t\tconst neu: Variant = {\n\t\t\tid: \"1\",\n\t\t\tmatches: [],\n\t\t\tmessageId: \"5\",\n\t\t\tpattern: [{ type: \"text\", value: \"hello world\" }],\n\t\t};\n\t\tconst diff = await inlangLixPluginV1.diff.variant({ old, neu });\n\t\texpect(diff).toEqual([\n\t\t\t{ operation: \"create\", type: \"variant\", neu, old } satisfies DiffReport,\n\t\t]);\n\t});\n});\n"]}
@@ -33,7 +33,7 @@ export type InlangPlugin<ExternalSettings extends Record<string, any> | unknown
33
33
  *
34
34
  * - `metadata` is optional and can be used to store additional information
35
35
  * that is accessible in `importFiles` via `toBeImportedMetadata`. See
36
- * https://github.com/opral/inlang-sdk/issues/218 for more info.
36
+ * https://github.com/opral/inlang/issues/218 for more info.
37
37
  *
38
38
  */
39
39
  toBeImportedFiles?: (args: {
@@ -78,7 +78,7 @@ export type InlangPlugin<ExternalSettings extends Record<string, any> | unknown
78
78
  /**
79
79
  * Exposing only a subset to ease mapping of fs functions.
80
80
  *
81
- * https://github.com/opral/inlang-sdk/issues/136
81
+ * https://github.com/opral/inlang/issues/136
82
82
  */
83
83
  export type NodeFsPromisesSubsetLegacy = {
84
84
  readFile: ((path: string) => Promise<ArrayBuffer>) | ((path: string, options?: {
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"/","sources":["plugin/schema.ts"],"names":[],"mappings":"","sourcesContent":["import type { TObject } from \"@sinclair/typebox\";\nimport type { MessageV1 } from \"../json-schema/old-v1-message/schemaV1.js\";\nimport type { ProjectSettings } from \"../json-schema/settings.js\";\nimport type {\n\tBundle,\n\tMessage,\n\tNewBundle,\n\tNewMessage,\n\tNewVariant,\n\tVariant,\n} from \"../database/schema.js\";\nimport type { ExportFile, ImportFile } from \"../project/api.js\";\n\nexport type InlangPlugin<\n\tExternalSettings extends Record<string, any> | unknown = unknown,\n> = {\n\t/**\n\t * @deprecated Use `key` instead.\n\t */\n\tid?: string;\n\t/**\n\t * The key of the plugin.\n\t */\n\tkey: string;\n\tsettingsSchema?: TObject;\n\t/**\n\t * @deprecated Use `importFiles` instead.\n\t */\n\tloadMessages?: (args: {\n\t\tsettings: ProjectSettings;\n\t\tnodeishFs: NodeFsPromisesSubsetLegacy;\n\t}) => Promise<MessageV1[]> | MessageV1[];\n\t/**\n\t * @deprecated Use `exportFiles` instead.\n\t */\n\tsaveMessages?: (args: {\n\t\tmessages: MessageV1[];\n\t\tsettings: ProjectSettings;\n\t\tnodeishFs: NodeFsPromisesSubsetLegacy;\n\t}) => Promise<void> | void;\n\t/**\n\t * Files that should be imported by the inlang SDK.\n\t *\n\t * - `metadata` is optional and can be used to store additional information\n\t * that is accessible in `importFiles` via `toBeImportedMetadata`. See\n\t * https://github.com/opral/inlang-sdk/issues/218 for more info.\n\t *\n\t */\n\ttoBeImportedFiles?: (args: {\n\t\tsettings: ProjectSettings & ExternalSettings;\n\t}) => MaybePromise<\n\t\tArray<{ path: string; locale: string; metadata?: Record<string, any> }>\n\t>;\n\timportFiles?: (args: {\n\t\tfiles: ImportFile[];\n\t\tsettings: ProjectSettings & ExternalSettings; // we expose the settings in case the importFunction needs to access the plugin config\n\t}) => MaybePromise<{\n\t\tbundles: BundleImport[];\n\t\tmessages: MessageImport[];\n\t\tvariants: VariantImport[];\n\t}>;\n\texportFiles?: (args: {\n\t\tbundles: Bundle[];\n\t\tmessages: Message[];\n\t\tvariants: Variant[];\n\t\tsettings: ProjectSettings & ExternalSettings;\n\t}) => MaybePromise<Array<ExportFile>>;\n\t/**\n\t * @deprecated Use the `meta` field instead.\n\t */\n\taddCustomApi?: (args: {\n\t\tsettings: ProjectSettings & ExternalSettings;\n\t}) => Record<string, unknown>;\n\t/**\n\t * Define app-specific APIs under a `meta` field.\n\t *\n\t * @example\n\t * meta: {\n\t * \"app.inlang.ide-extension\": {\n\t * documentPaths: [\"*.json\"]\n\t * }\n\t * }\n\t */\n\tmeta?: Record<string, Record<string, unknown>>;\n};\n\n/**\n * Exposing only a subset to ease mapping of fs functions.\n *\n * https://github.com/opral/inlang-sdk/issues/136\n */\nexport type NodeFsPromisesSubsetLegacy = {\n\treadFile:\n\t\t| ((path: string) => Promise<ArrayBuffer>)\n\t\t| ((path: string, options?: { encoding: \"utf-8\" }) => Promise<string>);\n\treaddir: (path: string) => Promise<string[]>;\n\twriteFile: (path: string, data: ArrayBuffer | string) => Promise<void>;\n\tmkdir: (path: string) => Promise<void>;\n};\n\n/**\n * A to be imported bundle.\n */\nexport type BundleImport = NewBundle;\n\n/**\n * A to be imported message.\n *\n * The `id` property is omitted because it is generated by the SDK.\n */\nexport type MessageImport = Omit<NewMessage, \"id\"> & {\n\t/**\n\t * If the id is not provided, the SDK will generate one.\n\t */\n\tid?: string;\n};\n\n/**\n * A to be imported variant.\n *\n * - The `id` and `messageId` properties are omitted because they are generated by the SDK.\n * - The `bundleId` and `locale` properties are added to the import variant to match the variant\n * with a message.\n */\nexport type VariantImport =\n\t| (NewVariant & {\n\t\t\t/**\n\t\t\t * If the id is not provided, the SDK will generate one.\n\t\t\t */\n\t\t\tid: string;\n\t\t\t/**\n\t\t\t * If the messageId is not provided, the SDK will match the variant\n\t\t\t * with a message based on the `messageBundleId` and `messageLocale` properties.\n\t\t\t */\n\t\t\tmessageId: string;\n\t\t\t/**\n\t\t\t * Required to match the variant with a message in case the `id` and `messageId` are undefined.\n\t\t\t */\n\t\t\tmessageBundleId?: undefined;\n\t\t\t/**\n\t\t\t * Required to match the variant with a message in case the `id` and `messageId` are undefined.\n\t\t\t */\n\t\t\tmessageLocale?: undefined;\n\t })\n\t| (Omit<NewVariant, \"id\" | \"messageId\"> & {\n\t\t\t/**\n\t\t\t * If the id is not provided, the SDK will generate one.\n\t\t\t */\n\t\t\tid?: undefined;\n\t\t\t/**\n\t\t\t * If the messageId is not provided, the SDK will match the variant\n\t\t\t * with a message based on the `messageBundleId` and `messageLocale` properties.\n\t\t\t */\n\t\t\tmessageId?: undefined;\n\t\t\t/**\n\t\t\t * Required to match the variant with a message in case the `id` and `messageId` are undefined.\n\t\t\t */\n\t\t\tmessageBundleId: string;\n\t\t\t/**\n\t\t\t * Required to match the variant with a message in case the `id` and `messageId` are undefined.\n\t\t\t */\n\t\t\tmessageLocale: string;\n\t });\n\ntype MaybePromise<T> = T | Promise<T>;\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"/","sources":["plugin/schema.ts"],"names":[],"mappings":"","sourcesContent":["import type { TObject } from \"@sinclair/typebox\";\nimport type { MessageV1 } from \"../json-schema/old-v1-message/schemaV1.js\";\nimport type { ProjectSettings } from \"../json-schema/settings.js\";\nimport type {\n\tBundle,\n\tMessage,\n\tNewBundle,\n\tNewMessage,\n\tNewVariant,\n\tVariant,\n} from \"../database/schema.js\";\nimport type { ExportFile, ImportFile } from \"../project/api.js\";\n\nexport type InlangPlugin<\n\tExternalSettings extends Record<string, any> | unknown = unknown,\n> = {\n\t/**\n\t * @deprecated Use `key` instead.\n\t */\n\tid?: string;\n\t/**\n\t * The key of the plugin.\n\t */\n\tkey: string;\n\tsettingsSchema?: TObject;\n\t/**\n\t * @deprecated Use `importFiles` instead.\n\t */\n\tloadMessages?: (args: {\n\t\tsettings: ProjectSettings;\n\t\tnodeishFs: NodeFsPromisesSubsetLegacy;\n\t}) => Promise<MessageV1[]> | MessageV1[];\n\t/**\n\t * @deprecated Use `exportFiles` instead.\n\t */\n\tsaveMessages?: (args: {\n\t\tmessages: MessageV1[];\n\t\tsettings: ProjectSettings;\n\t\tnodeishFs: NodeFsPromisesSubsetLegacy;\n\t}) => Promise<void> | void;\n\t/**\n\t * Files that should be imported by the inlang SDK.\n\t *\n\t * - `metadata` is optional and can be used to store additional information\n\t * that is accessible in `importFiles` via `toBeImportedMetadata`. See\n\t * https://github.com/opral/inlang/issues/218 for more info.\n\t *\n\t */\n\ttoBeImportedFiles?: (args: {\n\t\tsettings: ProjectSettings & ExternalSettings;\n\t}) => MaybePromise<\n\t\tArray<{ path: string; locale: string; metadata?: Record<string, any> }>\n\t>;\n\timportFiles?: (args: {\n\t\tfiles: ImportFile[];\n\t\tsettings: ProjectSettings & ExternalSettings; // we expose the settings in case the importFunction needs to access the plugin config\n\t}) => MaybePromise<{\n\t\tbundles: BundleImport[];\n\t\tmessages: MessageImport[];\n\t\tvariants: VariantImport[];\n\t}>;\n\texportFiles?: (args: {\n\t\tbundles: Bundle[];\n\t\tmessages: Message[];\n\t\tvariants: Variant[];\n\t\tsettings: ProjectSettings & ExternalSettings;\n\t}) => MaybePromise<Array<ExportFile>>;\n\t/**\n\t * @deprecated Use the `meta` field instead.\n\t */\n\taddCustomApi?: (args: {\n\t\tsettings: ProjectSettings & ExternalSettings;\n\t}) => Record<string, unknown>;\n\t/**\n\t * Define app-specific APIs under a `meta` field.\n\t *\n\t * @example\n\t * meta: {\n\t * \"app.inlang.ide-extension\": {\n\t * documentPaths: [\"*.json\"]\n\t * }\n\t * }\n\t */\n\tmeta?: Record<string, Record<string, unknown>>;\n};\n\n/**\n * Exposing only a subset to ease mapping of fs functions.\n *\n * https://github.com/opral/inlang/issues/136\n */\nexport type NodeFsPromisesSubsetLegacy = {\n\treadFile:\n\t\t| ((path: string) => Promise<ArrayBuffer>)\n\t\t| ((path: string, options?: { encoding: \"utf-8\" }) => Promise<string>);\n\treaddir: (path: string) => Promise<string[]>;\n\twriteFile: (path: string, data: ArrayBuffer | string) => Promise<void>;\n\tmkdir: (path: string) => Promise<void>;\n};\n\n/**\n * A to be imported bundle.\n */\nexport type BundleImport = NewBundle;\n\n/**\n * A to be imported message.\n *\n * The `id` property is omitted because it is generated by the SDK.\n */\nexport type MessageImport = Omit<NewMessage, \"id\"> & {\n\t/**\n\t * If the id is not provided, the SDK will generate one.\n\t */\n\tid?: string;\n};\n\n/**\n * A to be imported variant.\n *\n * - The `id` and `messageId` properties are omitted because they are generated by the SDK.\n * - The `bundleId` and `locale` properties are added to the import variant to match the variant\n * with a message.\n */\nexport type VariantImport =\n\t| (NewVariant & {\n\t\t\t/**\n\t\t\t * If the id is not provided, the SDK will generate one.\n\t\t\t */\n\t\t\tid: string;\n\t\t\t/**\n\t\t\t * If the messageId is not provided, the SDK will match the variant\n\t\t\t * with a message based on the `messageBundleId` and `messageLocale` properties.\n\t\t\t */\n\t\t\tmessageId: string;\n\t\t\t/**\n\t\t\t * Required to match the variant with a message in case the `id` and `messageId` are undefined.\n\t\t\t */\n\t\t\tmessageBundleId?: undefined;\n\t\t\t/**\n\t\t\t * Required to match the variant with a message in case the `id` and `messageId` are undefined.\n\t\t\t */\n\t\t\tmessageLocale?: undefined;\n\t })\n\t| (Omit<NewVariant, \"id\" | \"messageId\"> & {\n\t\t\t/**\n\t\t\t * If the id is not provided, the SDK will generate one.\n\t\t\t */\n\t\t\tid?: undefined;\n\t\t\t/**\n\t\t\t * If the messageId is not provided, the SDK will match the variant\n\t\t\t * with a message based on the `messageBundleId` and `messageLocale` properties.\n\t\t\t */\n\t\t\tmessageId?: undefined;\n\t\t\t/**\n\t\t\t * Required to match the variant with a message in case the `id` and `messageId` are undefined.\n\t\t\t */\n\t\t\tmessageBundleId: string;\n\t\t\t/**\n\t\t\t * Required to match the variant with a message in case the `id` and `messageId` are undefined.\n\t\t\t */\n\t\t\tmessageLocale: string;\n\t });\n\ntype MaybePromise<T> = T | Promise<T>;\n"]}
@@ -50,7 +50,7 @@ export type ImportFile = {
50
50
  * The metadata of the file to be imported.
51
51
  *
52
52
  * Used to store additional information that is accessible in `importFiles` via `toBeImportedFilesMetadata`.
53
- * https://github.com/opral/inlang-sdk/issues/218
53
+ * https://github.com/opral/inlang/issues/218
54
54
  */
55
55
  toBeImportedFilesMetadata?: Record<string, any>;
56
56
  };
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"/","sources":["project/api.ts"],"names":[],"mappings":"","sourcesContent":["import type { Kysely } from \"kysely\";\nimport type { InlangDatabaseSchema } from \"../database/schema.js\";\nimport type { InlangPlugin } from \"../plugin/schema.js\";\nimport type { ProjectSettings } from \"../json-schema/settings.js\";\nimport type { Lix } from \"@lix-js/sdk\";\nimport type { SqliteWasmDatabase } from \"sqlite-wasm-kysely\";\n\nexport type InlangProject = {\n\tdb: Kysely<InlangDatabaseSchema>;\n\t/**\n\t * @deprecated Don't use this. Only an internal hack to unblock\n\t * fink v2.\n\t *\n\t * TODO remove this\n\t */\n\t_sqlite: SqliteWasmDatabase;\n\tid: {\n\t\t/**\n\t\t * Stable for packed `.inlang` files. For unpacked projects loaded from a\n\t\t * directory, the id is unstable because `project_id` is not persisted.\n\t\t */\n\t\tget: () => Promise<string>;\n\t};\n\tplugins: {\n\t\tget: () => Promise<readonly InlangPlugin[]>;\n\t};\n\terrors: {\n\t\tget: () => Promise<readonly Error[]>;\n\t};\n\tsettings: {\n\t\tget: () => Promise<ProjectSettings>;\n\t\tset: (settings: ProjectSettings) => Promise<void>;\n\t};\n\tlix: Lix;\n\timportFiles: (args: {\n\t\tpluginKey: InlangPlugin[\"key\"];\n\t\tfiles: ImportFile[];\n\t}) => Promise<void>;\n\texportFiles: (args: {\n\t\tpluginKey: InlangPlugin[\"key\"];\n\t}) => Promise<ExportFile[]>;\n\tclose: () => Promise<void>;\n\ttoBlob: () => Promise<Blob>;\n};\n\nexport type ImportFile = {\n\t/** The locale of the resource file */\n\tlocale: string;\n\t/** The binary content of the resource */\n\tcontent: Uint8Array;\n\t/**\n\t * The metadata of the file to be imported.\n\t *\n\t * Used to store additional information that is accessible in `importFiles` via `toBeImportedFilesMetadata`.\n\t * https://github.com/opral/inlang-sdk/issues/218\n\t */\n\ttoBeImportedFilesMetadata?: Record<string, any>;\n};\n\nexport type ExportFile = {\n\t/** The locale of the resource file */\n\tlocale: string;\n\t/**\n\t * The name of the file.\n\t *\n\t * @example\n\t * \"en.json\"\n\t * \"common-de.json\"\n\t *\n\t */\n\tname: string;\n\t/** The binary content of the resource */\n\tcontent: Uint8Array;\n};\n\n/**\n * Minimal RxJS compatible (generic) subscription type.\n */\nexport type Subscription<T> = (callback: (value: T) => void) => {\n\tunsubscribe: () => void;\n};\n"]}
1
+ {"version":3,"file":"api.js","sourceRoot":"/","sources":["project/api.ts"],"names":[],"mappings":"","sourcesContent":["import type { Kysely } from \"kysely\";\nimport type { InlangDatabaseSchema } from \"../database/schema.js\";\nimport type { InlangPlugin } from \"../plugin/schema.js\";\nimport type { ProjectSettings } from \"../json-schema/settings.js\";\nimport type { Lix } from \"@lix-js/sdk\";\nimport type { SqliteWasmDatabase } from \"sqlite-wasm-kysely\";\n\nexport type InlangProject = {\n\tdb: Kysely<InlangDatabaseSchema>;\n\t/**\n\t * @deprecated Don't use this. Only an internal hack to unblock\n\t * fink v2.\n\t *\n\t * TODO remove this\n\t */\n\t_sqlite: SqliteWasmDatabase;\n\tid: {\n\t\t/**\n\t\t * Stable for packed `.inlang` files. For unpacked projects loaded from a\n\t\t * directory, the id is unstable because `project_id` is not persisted.\n\t\t */\n\t\tget: () => Promise<string>;\n\t};\n\tplugins: {\n\t\tget: () => Promise<readonly InlangPlugin[]>;\n\t};\n\terrors: {\n\t\tget: () => Promise<readonly Error[]>;\n\t};\n\tsettings: {\n\t\tget: () => Promise<ProjectSettings>;\n\t\tset: (settings: ProjectSettings) => Promise<void>;\n\t};\n\tlix: Lix;\n\timportFiles: (args: {\n\t\tpluginKey: InlangPlugin[\"key\"];\n\t\tfiles: ImportFile[];\n\t}) => Promise<void>;\n\texportFiles: (args: {\n\t\tpluginKey: InlangPlugin[\"key\"];\n\t}) => Promise<ExportFile[]>;\n\tclose: () => Promise<void>;\n\ttoBlob: () => Promise<Blob>;\n};\n\nexport type ImportFile = {\n\t/** The locale of the resource file */\n\tlocale: string;\n\t/** The binary content of the resource */\n\tcontent: Uint8Array;\n\t/**\n\t * The metadata of the file to be imported.\n\t *\n\t * Used to store additional information that is accessible in `importFiles` via `toBeImportedFilesMetadata`.\n\t * https://github.com/opral/inlang/issues/218\n\t */\n\ttoBeImportedFilesMetadata?: Record<string, any>;\n};\n\nexport type ExportFile = {\n\t/** The locale of the resource file */\n\tlocale: string;\n\t/**\n\t * The name of the file.\n\t *\n\t * @example\n\t * \"en.json\"\n\t * \"common-de.json\"\n\t *\n\t */\n\tname: string;\n\t/** The binary content of the resource */\n\tcontent: Uint8Array;\n};\n\n/**\n * Minimal RxJS compatible (generic) subscription type.\n */\nexport type Subscription<T> = (callback: (value: T) => void) => {\n\tunsubscribe: () => void;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"loadProjectFromDirectory.d.ts","sourceRoot":"/","sources":["project/loadProjectFromDirectory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAKN,KAAK,GAAG,EACR,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAIlE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAM3C;;;;;;;;;;;GAWG;AACH,wBAAsB,wBAAwB,CAC7C,IAAI,EAAE;IACL;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,EAAE,EAAE,OAAO,EAAE,CAAC;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;GAkL3D;AAggBD,qBAAa,yBAA0B,SAAQ,KAAK;gBACvC,MAAM,EAAE,MAAM;CAM1B;AAuCD,qBAAa,uBAAwB,SAAQ,KAAK;IACjD,IAAI,EAAE,MAAM,CAAC;gBAED,IAAI,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;CAMhD"}
1
+ {"version":3,"file":"loadProjectFromDirectory.d.ts","sourceRoot":"/","sources":["project/loadProjectFromDirectory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAIN,KAAK,GAAG,EACR,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,SAAS,CAAC;AAEzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAIlE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAM3C;;;;;;;;;;;GAWG;AACH,wBAAsB,wBAAwB,CAC7C,IAAI,EAAE;IACL;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,EAAE,EAAE,OAAO,EAAE,CAAC;IACd;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;GAiL3D;AAggBD,qBAAa,yBAA0B,SAAQ,KAAK;gBACvC,MAAM,EAAE,MAAM;CAM1B;AAuCD,qBAAa,uBAAwB,SAAQ,KAAK;IACjD,IAAI,EAAE,MAAM,CAAC;gBAED,IAAI,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;CAMhD"}
@@ -1,6 +1,6 @@
1
1
  import { newProject } from "./newProject.js";
2
2
  import { loadProjectInMemory } from "./loadProjectInMemory.js";
3
- import { closeLix, fileQueueSettled, openLixInMemory, toBlob, } from "@lix-js/sdk";
3
+ import { closeLix, openLixInMemory, toBlob, } from "@lix-js/sdk";
4
4
  import fs from "node:fs";
5
5
  import nodePath from "node:path";
6
6
  import { fromMessageV1 } from "../json-schema/old-v1-message/fromMessageV1.js";
@@ -59,7 +59,6 @@ export async function loadProjectFromDirectory(args) {
59
59
  lix: tempLix,
60
60
  syncInterval: undefined,
61
61
  });
62
- await fileQueueSettled({ lix: tempLix });
63
62
  // TODO call tempProject.lix.settled() to wait for the new settings file, and remove reload of the proejct as soon as reactive settings has landed
64
63
  // NOTE: we need to ensure two things:
65
64
  // 1. settled needs to include the changes from the copyFiles call
@@ -113,7 +112,7 @@ export async function loadProjectFromDirectory(args) {
113
112
  });
114
113
  }
115
114
  catch (e) {
116
- // https://github.com/opral/inlang-sdk/issues/202
115
+ // https://github.com/opral/inlang/issues/202
117
116
  if (e?.code === "ENOENT") {
118
117
  continue;
119
118
  }
@@ -515,7 +514,7 @@ async function syncLixFsFiles(args) {
515
514
  }
516
515
  async function upsertFileInLix(args, path, data) {
517
516
  // force posix path when upserting into lix
518
- // https://github.com/opral/inlang-sdk/issues/229
517
+ // https://github.com/opral/inlang/issues/229
519
518
  let posixPath = path.split(nodePath.win32.sep).join(nodePath.posix.sep);
520
519
  if (posixPath.startsWith("/") === false) {
521
520
  posixPath = "/" + posixPath;
@@ -552,7 +551,7 @@ function categorizePlugins(plugins) {
552
551
  /**
553
552
  * Imports local plugins for backwards compatibility.
554
553
  *
555
- * https://github.com/opral/inlang-sdk/issues/171
554
+ * https://github.com/opral/inlang/issues/171
556
555
  */
557
556
  async function importLocalPlugins(args) {
558
557
  const errors = [];