@webiny/api-headless-cms-pg-os 6.6.0-alpha.7 → 6.6.0-alpha.9

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.
@@ -5,8 +5,8 @@ class RemoveEntryImpl {
5
5
  this.syncRowQuery = syncRowQuery;
6
6
  }
7
7
  async execute(params) {
8
- const { entryId } = params;
9
- await this.syncRowQuery.create().whereIn("id", [
8
+ const { model, entryId } = params;
9
+ await this.syncRowQuery.create().where("tenant", model.tenant).whereIn("id", [
10
10
  `${entryId}:L`,
11
11
  `${entryId}:P`
12
12
  ]).delete();
@@ -1 +1 @@
1
- {"version":3,"file":"features/SyncWriter/RemoveEntry.js","sources":["../../../src/features/SyncWriter/RemoveEntry.ts"],"sourcesContent":["import { RemoveEntry as Abstraction } from \"./abstractions/RemoveEntry.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass RemoveEntryImpl implements Abstraction.Interface {\n public constructor(private readonly syncRowQuery: SyncRowQuery.Interface) {}\n\n public async execute(params: Abstraction.Params) {\n const { entryId } = params;\n await this.syncRowQuery\n .create()\n .whereIn(\"id\", [`${entryId}:L`, `${entryId}:P`])\n .delete();\n }\n}\n\nexport const RemoveEntry = Abstraction.createImplementation({\n implementation: RemoveEntryImpl,\n dependencies: [SyncRowQuery]\n});\n"],"names":["RemoveEntryImpl","syncRowQuery","params","entryId","RemoveEntry","Abstraction","SyncRowQuery"],"mappings":";;AAGA,MAAMA;IACF,YAAoCC,YAAoC,CAAE;aAAtCA,YAAY,GAAZA;IAAuC;IAE3E,MAAa,QAAQC,MAA0B,EAAE;QAC7C,MAAM,EAAEC,OAAO,EAAE,GAAGD;QACpB,MAAM,IAAI,CAAC,YAAY,CAClB,MAAM,GACN,OAAO,CAAC,MAAM;YAAC,GAAGC,QAAQ,EAAE,CAAC;YAAE,GAAGA,QAAQ,EAAE,CAAC;SAAC,EAC9C,MAAM;IACf;AACJ;AAEO,MAAMC,0BAAcC,YAAAA,oBAAgC,CAAC;IACxD,gBAAgBL;IAChB,cAAc;QAACM;KAAa;AAChC"}
1
+ {"version":3,"file":"features/SyncWriter/RemoveEntry.js","sources":["../../../src/features/SyncWriter/RemoveEntry.ts"],"sourcesContent":["import { RemoveEntry as Abstraction } from \"./abstractions/RemoveEntry.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass RemoveEntryImpl implements Abstraction.Interface {\n public constructor(private readonly syncRowQuery: SyncRowQuery.Interface) {}\n\n public async execute(params: Abstraction.Params) {\n const { model, entryId } = params;\n await this.syncRowQuery\n .create()\n .where(\"tenant\", model.tenant)\n .whereIn(\"id\", [`${entryId}:L`, `${entryId}:P`])\n .delete();\n }\n}\n\nexport const RemoveEntry = Abstraction.createImplementation({\n implementation: RemoveEntryImpl,\n dependencies: [SyncRowQuery]\n});\n"],"names":["RemoveEntryImpl","syncRowQuery","params","model","entryId","RemoveEntry","Abstraction","SyncRowQuery"],"mappings":";;AAGA,MAAMA;IACF,YAAoCC,YAAoC,CAAE;aAAtCA,YAAY,GAAZA;IAAuC;IAE3E,MAAa,QAAQC,MAA0B,EAAE;QAC7C,MAAM,EAAEC,KAAK,EAAEC,OAAO,EAAE,GAAGF;QAC3B,MAAM,IAAI,CAAC,YAAY,CAClB,MAAM,GACN,KAAK,CAAC,UAAUC,MAAM,MAAM,EAC5B,OAAO,CAAC,MAAM;YAAC,GAAGC,QAAQ,EAAE,CAAC;YAAE,GAAGA,QAAQ,EAAE,CAAC;SAAC,EAC9C,MAAM;IACf;AACJ;AAEO,MAAMC,0BAAcC,YAAAA,oBAAgC,CAAC;IACxD,gBAAgBN;IAChB,cAAc;QAACO;KAAa;AAChC"}
@@ -5,7 +5,7 @@ class RemoveLatestImpl {
5
5
  this.syncRowQuery = syncRowQuery;
6
6
  }
7
7
  async execute(params) {
8
- await this.syncRowQuery.create().where("id", `${params.entryId}:L`).delete();
8
+ await this.syncRowQuery.create().where("tenant", params.model.tenant).andWhere("id", `${params.entryId}:L`).delete();
9
9
  }
10
10
  }
11
11
  const RemoveLatest_RemoveLatest = RemoveLatest.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/SyncWriter/RemoveLatest.js","sources":["../../../src/features/SyncWriter/RemoveLatest.ts"],"sourcesContent":["import { RemoveLatest as Abstraction } from \"./abstractions/RemoveLatest.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass RemoveLatestImpl implements Abstraction.Interface {\n public constructor(private readonly syncRowQuery: SyncRowQuery.Interface) {}\n\n public async execute(params: Abstraction.Params) {\n await this.syncRowQuery.create().where(\"id\", `${params.entryId}:L`).delete();\n }\n}\n\nexport const RemoveLatest = Abstraction.createImplementation({\n implementation: RemoveLatestImpl,\n dependencies: [SyncRowQuery]\n});\n"],"names":["RemoveLatestImpl","syncRowQuery","params","RemoveLatest","Abstraction","SyncRowQuery"],"mappings":";;AAGA,MAAMA;IACF,YAAoCC,YAAoC,CAAE;aAAtCA,YAAY,GAAZA;IAAuC;IAE3E,MAAa,QAAQC,MAA0B,EAAE;QAC7C,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAGA,OAAO,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM;IAC9E;AACJ;AAEO,MAAMC,4BAAeC,aAAAA,oBAAgC,CAAC;IACzD,gBAAgBJ;IAChB,cAAc;QAACK;KAAa;AAChC"}
1
+ {"version":3,"file":"features/SyncWriter/RemoveLatest.js","sources":["../../../src/features/SyncWriter/RemoveLatest.ts"],"sourcesContent":["import { RemoveLatest as Abstraction } from \"./abstractions/RemoveLatest.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass RemoveLatestImpl implements Abstraction.Interface {\n public constructor(private readonly syncRowQuery: SyncRowQuery.Interface) {}\n\n public async execute(params: Abstraction.Params) {\n await this.syncRowQuery\n .create()\n .where(\"tenant\", params.model.tenant)\n .andWhere(\"id\", `${params.entryId}:L`)\n .delete();\n }\n}\n\nexport const RemoveLatest = Abstraction.createImplementation({\n implementation: RemoveLatestImpl,\n dependencies: [SyncRowQuery]\n});\n"],"names":["RemoveLatestImpl","syncRowQuery","params","RemoveLatest","Abstraction","SyncRowQuery"],"mappings":";;AAGA,MAAMA;IACF,YAAoCC,YAAoC,CAAE;aAAtCA,YAAY,GAAZA;IAAuC;IAE3E,MAAa,QAAQC,MAA0B,EAAE;QAC7C,MAAM,IAAI,CAAC,YAAY,CAClB,MAAM,GACN,KAAK,CAAC,UAAUA,OAAO,KAAK,CAAC,MAAM,EACnC,QAAQ,CAAC,MAAM,GAAGA,OAAO,OAAO,CAAC,EAAE,CAAC,EACpC,MAAM;IACf;AACJ;AAEO,MAAMC,4BAAeC,aAAAA,oBAAgC,CAAC;IACzD,gBAAgBJ;IAChB,cAAc;QAACK;KAAa;AAChC"}
@@ -5,7 +5,7 @@ class RemovePublishedImpl {
5
5
  this.syncRowQuery = syncRowQuery;
6
6
  }
7
7
  async execute(params) {
8
- await this.syncRowQuery.create().where("id", `${params.entryId}:P`).delete();
8
+ await this.syncRowQuery.create().where("tenant", params.model.tenant).andWhere("id", `${params.entryId}:P`).delete();
9
9
  }
10
10
  }
11
11
  const RemovePublished_RemovePublished = RemovePublished.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/SyncWriter/RemovePublished.js","sources":["../../../src/features/SyncWriter/RemovePublished.ts"],"sourcesContent":["import { RemovePublished as Abstraction } from \"./abstractions/RemovePublished.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass RemovePublishedImpl implements Abstraction.Interface {\n public constructor(private readonly syncRowQuery: SyncRowQuery.Interface) {}\n\n public async execute(params: Abstraction.Params) {\n await this.syncRowQuery.create().where(\"id\", `${params.entryId}:P`).delete();\n }\n}\n\nexport const RemovePublished = Abstraction.createImplementation({\n implementation: RemovePublishedImpl,\n dependencies: [SyncRowQuery]\n});\n"],"names":["RemovePublishedImpl","syncRowQuery","params","RemovePublished","Abstraction","SyncRowQuery"],"mappings":";;AAGA,MAAMA;IACF,YAAoCC,YAAoC,CAAE;aAAtCA,YAAY,GAAZA;IAAuC;IAE3E,MAAa,QAAQC,MAA0B,EAAE;QAC7C,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,GAAGA,OAAO,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM;IAC9E;AACJ;AAEO,MAAMC,kCAAkBC,gBAAAA,oBAAgC,CAAC;IAC5D,gBAAgBJ;IAChB,cAAc;QAACK;KAAa;AAChC"}
1
+ {"version":3,"file":"features/SyncWriter/RemovePublished.js","sources":["../../../src/features/SyncWriter/RemovePublished.ts"],"sourcesContent":["import { RemovePublished as Abstraction } from \"./abstractions/RemovePublished.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass RemovePublishedImpl implements Abstraction.Interface {\n public constructor(private readonly syncRowQuery: SyncRowQuery.Interface) {}\n\n public async execute(params: Abstraction.Params) {\n await this.syncRowQuery\n .create()\n .where(\"tenant\", params.model.tenant)\n .andWhere(\"id\", `${params.entryId}:P`)\n .delete();\n }\n}\n\nexport const RemovePublished = Abstraction.createImplementation({\n implementation: RemovePublishedImpl,\n dependencies: [SyncRowQuery]\n});\n"],"names":["RemovePublishedImpl","syncRowQuery","params","RemovePublished","Abstraction","SyncRowQuery"],"mappings":";;AAGA,MAAMA;IACF,YAAoCC,YAAoC,CAAE;aAAtCA,YAAY,GAAZA;IAAuC;IAE3E,MAAa,QAAQC,MAA0B,EAAE;QAC7C,MAAM,IAAI,CAAC,YAAY,CAClB,MAAM,GACN,KAAK,CAAC,UAAUA,OAAO,KAAK,CAAC,MAAM,EACnC,QAAQ,CAAC,MAAM,GAAGA,OAAO,OAAO,CAAC,EAAE,CAAC,EACpC,MAAM;IACf;AACJ;AAEO,MAAMC,kCAAkBC,gBAAAA,oBAAgC,CAAC;IAC5D,gBAAgBJ;IAChB,cAAc;QAACK;KAAa;AAChC"}
@@ -17,7 +17,10 @@ class WriteEntryImpl {
17
17
  ...params,
18
18
  kind: "published"
19
19
  }));
20
- await this.syncRowQuery.create().insert(rows).onConflict("id").merge();
20
+ await this.syncRowQuery.create().insert(rows).onConflict([
21
+ "tenant",
22
+ "id"
23
+ ]).merge();
21
24
  }
22
25
  }
23
26
  const WriteEntry_WriteEntry = WriteEntry.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/SyncWriter/WriteEntry.js","sources":["../../../src/features/SyncWriter/WriteEntry.ts"],"sourcesContent":["import type { CmsEntryValues } from \"@webiny/api-headless-cms/types/index.js\";\nimport { WriteEntry as Abstraction } from \"./abstractions/WriteEntry.js\";\nimport { BuildSyncRecord } from \"./abstractions/BuildSyncRecord.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\nimport type { ISyncRow } from \"~/types.js\";\n\nclass WriteEntryImpl implements Abstraction.Interface {\n public constructor(\n private readonly buildSyncRecord: BuildSyncRecord.Interface,\n private readonly syncRowQuery: SyncRowQuery.Interface\n ) {}\n\n public async execute<T extends CmsEntryValues = CmsEntryValues>(params: Abstraction.Params<T>) {\n const rows: ISyncRow[] = [\n await this.buildSyncRecord.execute({ ...params, kind: \"latest\" })\n ];\n\n if (params.entry.status === \"published\") {\n rows.push(await this.buildSyncRecord.execute({ ...params, kind: \"published\" }));\n }\n\n await this.syncRowQuery.create().insert(rows).onConflict(\"id\").merge();\n }\n}\n\nexport const WriteEntry = Abstraction.createImplementation({\n implementation: WriteEntryImpl,\n dependencies: [BuildSyncRecord, SyncRowQuery]\n});\n"],"names":["WriteEntryImpl","buildSyncRecord","syncRowQuery","params","rows","WriteEntry","Abstraction","BuildSyncRecord","SyncRowQuery"],"mappings":";;;AAMA,MAAMA;IACF,YACqBC,eAA0C,EAC1CC,YAAoC,CACvD;aAFmBD,eAAe,GAAfA;aACAC,YAAY,GAAZA;IAClB;IAEH,MAAa,QAAmDC,MAA6B,EAAE;QAC3F,MAAMC,OAAmB;YACrB,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;gBAAE,GAAGD,MAAM;gBAAE,MAAM;YAAS;SAClE;QAED,IAAIA,AAAwB,gBAAxBA,OAAO,KAAK,CAAC,MAAM,EACnBC,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YAAE,GAAGD,MAAM;YAAE,MAAM;QAAY;QAGhF,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,MAAM,CAACC,MAAM,UAAU,CAAC,MAAM,KAAK;IACxE;AACJ;AAEO,MAAMC,wBAAaC,WAAAA,oBAAgC,CAAC;IACvD,gBAAgBN;IAChB,cAAc;QAACO;QAAiBC;KAAa;AACjD"}
1
+ {"version":3,"file":"features/SyncWriter/WriteEntry.js","sources":["../../../src/features/SyncWriter/WriteEntry.ts"],"sourcesContent":["import type { CmsEntryValues } from \"@webiny/api-headless-cms/types/index.js\";\nimport { WriteEntry as Abstraction } from \"./abstractions/WriteEntry.js\";\nimport { BuildSyncRecord } from \"./abstractions/BuildSyncRecord.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\nimport type { ISyncRow } from \"~/types.js\";\n\nclass WriteEntryImpl implements Abstraction.Interface {\n public constructor(\n private readonly buildSyncRecord: BuildSyncRecord.Interface,\n private readonly syncRowQuery: SyncRowQuery.Interface\n ) {}\n\n public async execute<T extends CmsEntryValues = CmsEntryValues>(params: Abstraction.Params<T>) {\n const rows: ISyncRow[] = [\n await this.buildSyncRecord.execute({ ...params, kind: \"latest\" })\n ];\n\n if (params.entry.status === \"published\") {\n rows.push(await this.buildSyncRecord.execute({ ...params, kind: \"published\" }));\n }\n\n await this.syncRowQuery.create().insert(rows).onConflict([\"tenant\", \"id\"]).merge();\n }\n}\n\nexport const WriteEntry = Abstraction.createImplementation({\n implementation: WriteEntryImpl,\n dependencies: [BuildSyncRecord, SyncRowQuery]\n});\n"],"names":["WriteEntryImpl","buildSyncRecord","syncRowQuery","params","rows","WriteEntry","Abstraction","BuildSyncRecord","SyncRowQuery"],"mappings":";;;AAMA,MAAMA;IACF,YACqBC,eAA0C,EAC1CC,YAAoC,CACvD;aAFmBD,eAAe,GAAfA;aACAC,YAAY,GAAZA;IAClB;IAEH,MAAa,QAAmDC,MAA6B,EAAE;QAC3F,MAAMC,OAAmB;YACrB,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;gBAAE,GAAGD,MAAM;gBAAE,MAAM;YAAS;SAClE;QAED,IAAIA,AAAwB,gBAAxBA,OAAO,KAAK,CAAC,MAAM,EACnBC,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YAAE,GAAGD,MAAM;YAAE,MAAM;QAAY;QAGhF,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,MAAM,CAACC,MAAM,UAAU,CAAC;YAAC;YAAU;SAAK,EAAE,KAAK;IACpF;AACJ;AAEO,MAAMC,wBAAaC,WAAAA,oBAAgC,CAAC;IACvD,gBAAgBN;IAChB,cAAc;QAACO;QAAiBC;KAAa;AACjD"}
@@ -11,7 +11,10 @@ class WriteLatestImpl {
11
11
  ...params,
12
12
  kind: "latest"
13
13
  });
14
- await this.syncRowQuery.create().insert(row).onConflict("id").merge();
14
+ await this.syncRowQuery.create().insert(row).onConflict([
15
+ "tenant",
16
+ "id"
17
+ ]).merge();
15
18
  }
16
19
  }
17
20
  const WriteLatest_WriteLatest = WriteLatest.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/SyncWriter/WriteLatest.js","sources":["../../../src/features/SyncWriter/WriteLatest.ts"],"sourcesContent":["import type { CmsEntryValues } from \"@webiny/api-headless-cms/types/index.js\";\nimport { WriteLatest as Abstraction } from \"./abstractions/WriteLatest.js\";\nimport { BuildSyncRecord } from \"./abstractions/BuildSyncRecord.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass WriteLatestImpl implements Abstraction.Interface {\n public constructor(\n private readonly buildSyncRecord: BuildSyncRecord.Interface,\n private readonly syncRowQuery: SyncRowQuery.Interface\n ) {}\n\n public async execute<T extends CmsEntryValues = CmsEntryValues>(params: Abstraction.Params<T>) {\n const row = await this.buildSyncRecord.execute({ ...params, kind: \"latest\" });\n await this.syncRowQuery.create().insert(row).onConflict(\"id\").merge();\n }\n}\n\nexport const WriteLatest = Abstraction.createImplementation({\n implementation: WriteLatestImpl,\n dependencies: [BuildSyncRecord, SyncRowQuery]\n});\n"],"names":["WriteLatestImpl","buildSyncRecord","syncRowQuery","params","row","WriteLatest","Abstraction","BuildSyncRecord","SyncRowQuery"],"mappings":";;;AAKA,MAAMA;IACF,YACqBC,eAA0C,EAC1CC,YAAoC,CACvD;aAFmBD,eAAe,GAAfA;aACAC,YAAY,GAAZA;IAClB;IAEH,MAAa,QAAmDC,MAA6B,EAAE;QAC3F,MAAMC,MAAM,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YAAE,GAAGD,MAAM;YAAE,MAAM;QAAS;QAC3E,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,MAAM,CAACC,KAAK,UAAU,CAAC,MAAM,KAAK;IACvE;AACJ;AAEO,MAAMC,0BAAcC,YAAAA,oBAAgC,CAAC;IACxD,gBAAgBN;IAChB,cAAc;QAACO;QAAiBC;KAAa;AACjD"}
1
+ {"version":3,"file":"features/SyncWriter/WriteLatest.js","sources":["../../../src/features/SyncWriter/WriteLatest.ts"],"sourcesContent":["import type { CmsEntryValues } from \"@webiny/api-headless-cms/types/index.js\";\nimport { WriteLatest as Abstraction } from \"./abstractions/WriteLatest.js\";\nimport { BuildSyncRecord } from \"./abstractions/BuildSyncRecord.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass WriteLatestImpl implements Abstraction.Interface {\n public constructor(\n private readonly buildSyncRecord: BuildSyncRecord.Interface,\n private readonly syncRowQuery: SyncRowQuery.Interface\n ) {}\n\n public async execute<T extends CmsEntryValues = CmsEntryValues>(params: Abstraction.Params<T>) {\n const row = await this.buildSyncRecord.execute({ ...params, kind: \"latest\" });\n await this.syncRowQuery.create().insert(row).onConflict([\"tenant\", \"id\"]).merge();\n }\n}\n\nexport const WriteLatest = Abstraction.createImplementation({\n implementation: WriteLatestImpl,\n dependencies: [BuildSyncRecord, SyncRowQuery]\n});\n"],"names":["WriteLatestImpl","buildSyncRecord","syncRowQuery","params","row","WriteLatest","Abstraction","BuildSyncRecord","SyncRowQuery"],"mappings":";;;AAKA,MAAMA;IACF,YACqBC,eAA0C,EAC1CC,YAAoC,CACvD;aAFmBD,eAAe,GAAfA;aACAC,YAAY,GAAZA;IAClB;IAEH,MAAa,QAAmDC,MAA6B,EAAE;QAC3F,MAAMC,MAAM,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YAAE,GAAGD,MAAM;YAAE,MAAM;QAAS;QAC3E,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,MAAM,CAACC,KAAK,UAAU,CAAC;YAAC;YAAU;SAAK,EAAE,KAAK;IACnF;AACJ;AAEO,MAAMC,0BAAcC,YAAAA,oBAAgC,CAAC;IACxD,gBAAgBN;IAChB,cAAc;QAACO;QAAiBC;KAAa;AACjD"}
@@ -11,7 +11,10 @@ class WritePublishedImpl {
11
11
  ...params,
12
12
  kind: "published"
13
13
  });
14
- await this.syncRowQuery.create().insert(row).onConflict("id").merge();
14
+ await this.syncRowQuery.create().insert(row).onConflict([
15
+ "tenant",
16
+ "id"
17
+ ]).merge();
15
18
  }
16
19
  }
17
20
  const WritePublished_WritePublished = WritePublished.createImplementation({
@@ -1 +1 @@
1
- {"version":3,"file":"features/SyncWriter/WritePublished.js","sources":["../../../src/features/SyncWriter/WritePublished.ts"],"sourcesContent":["import type { CmsEntryValues } from \"@webiny/api-headless-cms/types/index.js\";\nimport { WritePublished as Abstraction } from \"./abstractions/WritePublished.js\";\nimport { BuildSyncRecord } from \"./abstractions/BuildSyncRecord.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass WritePublishedImpl implements Abstraction.Interface {\n public constructor(\n private readonly buildSyncRecord: BuildSyncRecord.Interface,\n private readonly syncRowQuery: SyncRowQuery.Interface\n ) {}\n\n public async execute<T extends CmsEntryValues = CmsEntryValues>(params: Abstraction.Params<T>) {\n const row = await this.buildSyncRecord.execute({ ...params, kind: \"published\" });\n await this.syncRowQuery.create().insert(row).onConflict(\"id\").merge();\n }\n}\n\nexport const WritePublished = Abstraction.createImplementation({\n implementation: WritePublishedImpl,\n dependencies: [BuildSyncRecord, SyncRowQuery]\n});\n"],"names":["WritePublishedImpl","buildSyncRecord","syncRowQuery","params","row","WritePublished","Abstraction","BuildSyncRecord","SyncRowQuery"],"mappings":";;;AAKA,MAAMA;IACF,YACqBC,eAA0C,EAC1CC,YAAoC,CACvD;aAFmBD,eAAe,GAAfA;aACAC,YAAY,GAAZA;IAClB;IAEH,MAAa,QAAmDC,MAA6B,EAAE;QAC3F,MAAMC,MAAM,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YAAE,GAAGD,MAAM;YAAE,MAAM;QAAY;QAC9E,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,MAAM,CAACC,KAAK,UAAU,CAAC,MAAM,KAAK;IACvE;AACJ;AAEO,MAAMC,gCAAiBC,eAAAA,oBAAgC,CAAC;IAC3D,gBAAgBN;IAChB,cAAc;QAACO;QAAiBC;KAAa;AACjD"}
1
+ {"version":3,"file":"features/SyncWriter/WritePublished.js","sources":["../../../src/features/SyncWriter/WritePublished.ts"],"sourcesContent":["import type { CmsEntryValues } from \"@webiny/api-headless-cms/types/index.js\";\nimport { WritePublished as Abstraction } from \"./abstractions/WritePublished.js\";\nimport { BuildSyncRecord } from \"./abstractions/BuildSyncRecord.js\";\nimport { SyncRowQuery } from \"./abstractions/SyncRowQuery.js\";\n\nclass WritePublishedImpl implements Abstraction.Interface {\n public constructor(\n private readonly buildSyncRecord: BuildSyncRecord.Interface,\n private readonly syncRowQuery: SyncRowQuery.Interface\n ) {}\n\n public async execute<T extends CmsEntryValues = CmsEntryValues>(params: Abstraction.Params<T>) {\n const row = await this.buildSyncRecord.execute({ ...params, kind: \"published\" });\n await this.syncRowQuery.create().insert(row).onConflict([\"tenant\", \"id\"]).merge();\n }\n}\n\nexport const WritePublished = Abstraction.createImplementation({\n implementation: WritePublishedImpl,\n dependencies: [BuildSyncRecord, SyncRowQuery]\n});\n"],"names":["WritePublishedImpl","buildSyncRecord","syncRowQuery","params","row","WritePublished","Abstraction","BuildSyncRecord","SyncRowQuery"],"mappings":";;;AAKA,MAAMA;IACF,YACqBC,eAA0C,EAC1CC,YAAoC,CACvD;aAFmBD,eAAe,GAAfA;aACAC,YAAY,GAAZA;IAClB;IAEH,MAAa,QAAmDC,MAA6B,EAAE;QAC3F,MAAMC,MAAM,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YAAE,GAAGD,MAAM;YAAE,MAAM;QAAY;QAC9E,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,MAAM,CAACC,KAAK,UAAU,CAAC;YAAC;YAAU;SAAK,EAAE,KAAK;IACnF;AACJ;AAEO,MAAMC,gCAAiBC,eAAAA,oBAAgC,CAAC;IAC3D,gBAAgBN;IAChB,cAAc;QAACO;QAAiBC;KAAa;AACjD"}
@@ -33,14 +33,15 @@ class SyncTableManagerImpl {
33
33
  async createTable() {
34
34
  try {
35
35
  await this.knex.client.schema.createTable(this.tableName, (table)=>{
36
- table.text("id").primary();
36
+ table.text("id").notNullable();
37
37
  table.text("entryId").notNullable();
38
38
  table.text("index").notNullable();
39
39
  table.text("operation").notNullable();
40
40
  table.text("data").notNullable();
41
41
  table.text("tenant").notNullable();
42
- table.index([
43
- "tenant"
42
+ table.primary([
43
+ "tenant",
44
+ "id"
44
45
  ]);
45
46
  });
46
47
  } catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"features/syncTableManager/SyncTableManager.js","sources":["../../../src/features/syncTableManager/SyncTableManager.ts"],"sourcesContent":["import { KnexClient } from \"@webiny/api-core-sql\";\nimport { SyncTableManager as SyncTableManagerAbstraction } from \"./abstractions.js\";\nimport { TableNameResolver } from \"@webiny/api-headless-cms-sql/features/tableNameResolver/abstractions.js\";\n\nclass SyncTableManagerImpl implements SyncTableManagerAbstraction.Interface {\n private readonly knex;\n private readonly tableName;\n private initialized = false;\n private initPromise?: Promise<void>;\n\n constructor(knex: KnexClient.Interface, tableNameResolver: TableNameResolver.Interface) {\n this.knex = knex;\n this.tableName = tableNameResolver.resolve(\"os_sync\");\n\n const g = globalThis as Record<string, unknown>;\n const managers = (g.__sqlTableManagers ??= []) as SyncTableManagerAbstraction.Interface[];\n managers.push(this);\n }\n\n public reset(): void {\n this.initialized = false;\n this.initPromise = undefined;\n }\n\n public async ensureTable(): Promise<void> {\n if (this.initialized) {\n return;\n }\n if (!this.initPromise) {\n this.initPromise = this.doEnsureTable().catch(err => {\n this.initPromise = undefined;\n throw err;\n });\n }\n return this.initPromise;\n }\n\n public getTableName(): string {\n return this.tableName;\n }\n\n private async doEnsureTable(): Promise<void> {\n const exists = await this.knex.client.schema.hasTable(this.tableName);\n\n if (!exists) {\n await this.createTable();\n }\n\n this.initialized = true;\n }\n\n private async createTable(): Promise<void> {\n try {\n await this.knex.client.schema.createTable(this.tableName, table => {\n table.text(\"id\").primary();\n table.text(\"entryId\").notNullable();\n table.text(\"index\").notNullable();\n table.text(\"operation\").notNullable();\n table.text(\"data\").notNullable();\n table.text(\"tenant\").notNullable();\n\n table.index([\"tenant\"]);\n });\n } catch (err) {\n if (await this.knex.client.schema.hasTable(this.tableName)) {\n return;\n }\n throw err;\n }\n }\n}\n\nexport const SyncTableManager = SyncTableManagerAbstraction.createImplementation({\n implementation: SyncTableManagerImpl,\n dependencies: [KnexClient, TableNameResolver]\n});\n"],"names":["SyncTableManagerImpl","knex","tableNameResolver","g","globalThis","managers","undefined","err","exists","table","SyncTableManager","SyncTableManagerAbstraction","KnexClient","TableNameResolver"],"mappings":";;;AAIA,MAAMA;IAMF,YAAYC,IAA0B,EAAEC,iBAA8C,CAAE;aAHhF,WAAW,GAAG;QAIlB,IAAI,CAAC,IAAI,GAAGD;QACZ,IAAI,CAAC,SAAS,GAAGC,kBAAkB,OAAO,CAAC;QAE3C,MAAMC,IAAIC;QACV,MAAMC,WAAYF,EAAE,kBAAkB,KAAK,EAAE;QAC7CE,SAAS,IAAI,CAAC,IAAI;IACtB;IAEO,QAAc;QACjB,IAAI,CAAC,WAAW,GAAG;QACnB,IAAI,CAAC,WAAW,GAAGC;IACvB;IAEA,MAAa,cAA6B;QACtC,IAAI,IAAI,CAAC,WAAW,EAChB;QAEJ,IAAI,CAAC,IAAI,CAAC,WAAW,EACjB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,GAAG,KAAK,CAACC,CAAAA;YAC1C,IAAI,CAAC,WAAW,GAAGD;YACnB,MAAMC;QACV;QAEJ,OAAO,IAAI,CAAC,WAAW;IAC3B;IAEO,eAAuB;QAC1B,OAAO,IAAI,CAAC,SAAS;IACzB;IAEA,MAAc,gBAA+B;QACzC,MAAMC,SAAS,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS;QAEpE,IAAI,CAACA,QACD,MAAM,IAAI,CAAC,WAAW;QAG1B,IAAI,CAAC,WAAW,GAAG;IACvB;IAEA,MAAc,cAA6B;QACvC,IAAI;YACA,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAEC,CAAAA;gBACtDA,MAAM,IAAI,CAAC,MAAM,OAAO;gBACxBA,MAAM,IAAI,CAAC,WAAW,WAAW;gBACjCA,MAAM,IAAI,CAAC,SAAS,WAAW;gBAC/BA,MAAM,IAAI,CAAC,aAAa,WAAW;gBACnCA,MAAM,IAAI,CAAC,QAAQ,WAAW;gBAC9BA,MAAM,IAAI,CAAC,UAAU,WAAW;gBAEhCA,MAAM,KAAK,CAAC;oBAAC;iBAAS;YAC1B;QACJ,EAAE,OAAOF,KAAK;YACV,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,GACrD;YAEJ,MAAMA;QACV;IACJ;AACJ;AAEO,MAAMG,oCAAmBC,iBAAAA,oBAAgD,CAAC;IAC7E,gBAAgBX;IAChB,cAAc;QAACY;QAAYC;KAAkB;AACjD"}
1
+ {"version":3,"file":"features/syncTableManager/SyncTableManager.js","sources":["../../../src/features/syncTableManager/SyncTableManager.ts"],"sourcesContent":["import { KnexClient } from \"@webiny/api-core-sql\";\nimport { SyncTableManager as SyncTableManagerAbstraction } from \"./abstractions.js\";\nimport { TableNameResolver } from \"@webiny/api-headless-cms-sql/features/tableNameResolver/abstractions.js\";\n\nclass SyncTableManagerImpl implements SyncTableManagerAbstraction.Interface {\n private readonly knex;\n private readonly tableName;\n private initialized = false;\n private initPromise?: Promise<void>;\n\n constructor(knex: KnexClient.Interface, tableNameResolver: TableNameResolver.Interface) {\n this.knex = knex;\n this.tableName = tableNameResolver.resolve(\"os_sync\");\n\n const g = globalThis as Record<string, unknown>;\n const managers = (g.__sqlTableManagers ??= []) as SyncTableManagerAbstraction.Interface[];\n managers.push(this);\n }\n\n public reset(): void {\n this.initialized = false;\n this.initPromise = undefined;\n }\n\n public async ensureTable(): Promise<void> {\n if (this.initialized) {\n return;\n }\n if (!this.initPromise) {\n this.initPromise = this.doEnsureTable().catch(err => {\n this.initPromise = undefined;\n throw err;\n });\n }\n return this.initPromise;\n }\n\n public getTableName(): string {\n return this.tableName;\n }\n\n private async doEnsureTable(): Promise<void> {\n const exists = await this.knex.client.schema.hasTable(this.tableName);\n\n if (!exists) {\n await this.createTable();\n }\n\n this.initialized = true;\n }\n\n private async createTable(): Promise<void> {\n try {\n await this.knex.client.schema.createTable(this.tableName, table => {\n table.text(\"id\").notNullable();\n table.text(\"entryId\").notNullable();\n table.text(\"index\").notNullable();\n table.text(\"operation\").notNullable();\n table.text(\"data\").notNullable();\n table.text(\"tenant\").notNullable();\n\n table.primary([\"tenant\", \"id\"]);\n });\n } catch (err) {\n if (await this.knex.client.schema.hasTable(this.tableName)) {\n return;\n }\n throw err;\n }\n }\n}\n\nexport const SyncTableManager = SyncTableManagerAbstraction.createImplementation({\n implementation: SyncTableManagerImpl,\n dependencies: [KnexClient, TableNameResolver]\n});\n"],"names":["SyncTableManagerImpl","knex","tableNameResolver","g","globalThis","managers","undefined","err","exists","table","SyncTableManager","SyncTableManagerAbstraction","KnexClient","TableNameResolver"],"mappings":";;;AAIA,MAAMA;IAMF,YAAYC,IAA0B,EAAEC,iBAA8C,CAAE;aAHhF,WAAW,GAAG;QAIlB,IAAI,CAAC,IAAI,GAAGD;QACZ,IAAI,CAAC,SAAS,GAAGC,kBAAkB,OAAO,CAAC;QAE3C,MAAMC,IAAIC;QACV,MAAMC,WAAYF,EAAE,kBAAkB,KAAK,EAAE;QAC7CE,SAAS,IAAI,CAAC,IAAI;IACtB;IAEO,QAAc;QACjB,IAAI,CAAC,WAAW,GAAG;QACnB,IAAI,CAAC,WAAW,GAAGC;IACvB;IAEA,MAAa,cAA6B;QACtC,IAAI,IAAI,CAAC,WAAW,EAChB;QAEJ,IAAI,CAAC,IAAI,CAAC,WAAW,EACjB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,GAAG,KAAK,CAACC,CAAAA;YAC1C,IAAI,CAAC,WAAW,GAAGD;YACnB,MAAMC;QACV;QAEJ,OAAO,IAAI,CAAC,WAAW;IAC3B;IAEO,eAAuB;QAC1B,OAAO,IAAI,CAAC,SAAS;IACzB;IAEA,MAAc,gBAA+B;QACzC,MAAMC,SAAS,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS;QAEpE,IAAI,CAACA,QACD,MAAM,IAAI,CAAC,WAAW;QAG1B,IAAI,CAAC,WAAW,GAAG;IACvB;IAEA,MAAc,cAA6B;QACvC,IAAI;YACA,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,EAAEC,CAAAA;gBACtDA,MAAM,IAAI,CAAC,MAAM,WAAW;gBAC5BA,MAAM,IAAI,CAAC,WAAW,WAAW;gBACjCA,MAAM,IAAI,CAAC,SAAS,WAAW;gBAC/BA,MAAM,IAAI,CAAC,aAAa,WAAW;gBACnCA,MAAM,IAAI,CAAC,QAAQ,WAAW;gBAC9BA,MAAM,IAAI,CAAC,UAAU,WAAW;gBAEhCA,MAAM,OAAO,CAAC;oBAAC;oBAAU;iBAAK;YAClC;QACJ,EAAE,OAAOF,KAAK;YACV,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,GACrD;YAEJ,MAAMA;QACV;IACJ;AACJ;AAEO,MAAMG,oCAAmBC,iBAAAA,oBAAgD,CAAC;IAC7E,gBAAgBX;IAChB,cAAc;QAACY;QAAYC;KAAkB;AACjD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webiny/api-headless-cms-pg-os",
3
- "version": "6.6.0-alpha.7",
3
+ "version": "6.6.0-alpha.9",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./index.js",
@@ -23,28 +23,28 @@
23
23
  "license": "MIT",
24
24
  "author": "Webiny Ltd.",
25
25
  "dependencies": {
26
- "@webiny/api": "6.6.0-alpha.7",
27
- "@webiny/api-core-sql": "6.6.0-alpha.7",
28
- "@webiny/api-headless-cms": "6.6.0-alpha.7",
29
- "@webiny/api-headless-cms-sql": "6.6.0-alpha.7",
30
- "@webiny/api-headless-cms-storage": "6.6.0-alpha.7",
31
- "@webiny/api-headless-cms-utils-os": "6.6.0-alpha.7",
32
- "@webiny/api-opensearch": "6.6.0-alpha.7",
33
- "@webiny/api-sync-to-opensearch": "6.6.0-alpha.7",
34
- "@webiny/db-utils": "6.6.0-alpha.7",
35
- "@webiny/error": "6.6.0-alpha.7",
36
- "@webiny/feature": "6.6.0-alpha.7",
37
- "@webiny/handler": "6.6.0-alpha.7",
38
- "@webiny/plugins": "6.6.0-alpha.7",
39
- "@webiny/utils": "6.6.0-alpha.7",
26
+ "@webiny/api": "6.6.0-alpha.9",
27
+ "@webiny/api-core-sql": "6.6.0-alpha.9",
28
+ "@webiny/api-headless-cms": "6.6.0-alpha.9",
29
+ "@webiny/api-headless-cms-sql": "6.6.0-alpha.9",
30
+ "@webiny/api-headless-cms-storage": "6.6.0-alpha.9",
31
+ "@webiny/api-headless-cms-utils-os": "6.6.0-alpha.9",
32
+ "@webiny/api-opensearch": "6.6.0-alpha.9",
33
+ "@webiny/api-sync-to-opensearch": "6.6.0-alpha.9",
34
+ "@webiny/db-utils": "6.6.0-alpha.9",
35
+ "@webiny/error": "6.6.0-alpha.9",
36
+ "@webiny/feature": "6.6.0-alpha.9",
37
+ "@webiny/handler": "6.6.0-alpha.9",
38
+ "@webiny/plugins": "6.6.0-alpha.9",
39
+ "@webiny/utils": "6.6.0-alpha.9",
40
40
  "knex": "3.3.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@electric-sql/pglite": "0.5.5",
44
44
  "@electric-sql/pglite-socket": "0.2.8",
45
- "@webiny/api-core": "6.6.0-alpha.7",
46
- "@webiny/api-sync-pg-to-opensearch": "6.6.0-alpha.7",
47
- "@webiny/build-tools": "6.6.0-alpha.7",
45
+ "@webiny/api-core": "6.6.0-alpha.9",
46
+ "@webiny/api-sync-pg-to-opensearch": "6.6.0-alpha.9",
47
+ "@webiny/build-tools": "6.6.0-alpha.9",
48
48
  "@webiny/di": "1.1.0",
49
49
  "@webiny/stdlib": "0.0.17",
50
50
  "typescript": "7.0.2",
@@ -8,6 +8,7 @@ const toSyncEvent = (row, type)=>({
8
8
  data: row.data
9
9
  } : {}
10
10
  });
11
+ const createRowKey = (row)=>`${row.tenant}:${row.id}`;
11
12
  const simulatePgStream = (params)=>{
12
13
  const { knex, tableName, handler } = params;
13
14
  const query = ()=>knex(tableName);
@@ -23,24 +24,24 @@ const simulatePgStream = (params)=>{
23
24
  if (!isInsert && !isDelete) return originalQuery(connection, obj);
24
25
  const rowsBefore = await query().select("*");
25
26
  const beforeMap = new Map(rowsBefore.map((row)=>[
26
- row.id,
27
+ createRowKey(row),
27
28
  row
28
29
  ]));
29
30
  const result = await originalQuery(connection, obj);
30
31
  const rowsAfter = await query().select("*");
31
32
  const afterMap = new Map(rowsAfter.map((row)=>[
32
- row.id,
33
+ createRowKey(row),
33
34
  row
34
35
  ]));
35
36
  const events = [];
36
- if (isInsert) for (const [id, row] of afterMap){
37
- const before = beforeMap.get(id);
37
+ if (isInsert) for (const [key, row] of afterMap){
38
+ const before = beforeMap.get(key);
38
39
  if (before) {
39
40
  if (before.data !== row.data) events.push(toSyncEvent(row, "MODIFY"));
40
41
  } else events.push(toSyncEvent(row, "INSERT"));
41
42
  }
42
43
  if (isDelete) {
43
- for (const [id, row] of beforeMap)if (!afterMap.has(id)) events.push(toSyncEvent(row, "REMOVE"));
44
+ for (const [key, row] of beforeMap)if (!afterMap.has(key)) events.push(toSyncEvent(row, "REMOVE"));
44
45
  }
45
46
  if (events.length > 0) await handler(events);
46
47
  return result;
@@ -1 +1 @@
1
- {"version":3,"file":"testing/simulatePgStream.js","sources":["../../src/testing/simulatePgStream.ts"],"sourcesContent":["import type { Knex } from \"knex\";\nimport type { SyncEvent, ISyncRow, SyncEventType } from \"~/types.js\";\n\nexport interface SimulatePgStreamParams {\n knex: Knex;\n tableName: string;\n handler: (events: SyncEvent[]) => Promise<void>;\n}\n\nconst toSyncEvent = (row: ISyncRow, type: SyncEventType): SyncEvent => ({\n type,\n id: row.id,\n entryId: row.entryId,\n tenant: row.tenant,\n index: row.index,\n ...(type !== \"REMOVE\" ? { data: row.data } : {})\n});\n\n/**\n * Simulates a PostgreSQL -> OpenSearch sync stream (the PG equivalent of the\n * DynamoDB Streams simulation in `@webiny/project-utils/testing/dynamodb`) by\n * monkey-patching knex's internal `client.query` method.\n *\n * Uses a snapshot-diff approach: capture all rows in the target table before\n * the operation, execute the operation, capture all rows after, then diff the\n * two snapshots to determine which `SyncEvent`s occurred. This is robust\n * against SQL structure changes, since it never has to parse bindings or SQL\n * text to reconstruct row data.\n */\nexport const simulatePgStream = (params: SimulatePgStreamParams): void => {\n const { knex, tableName, handler } = params;\n const query = () => knex<ISyncRow>(tableName);\n\n const originalClient = knex.client;\n const originalQuery = originalClient.query.bind(originalClient);\n\n originalClient.query = async (connection: unknown, obj: unknown) => {\n const sql: string = typeof obj === \"string\" ? obj : ((obj as { sql?: string })?.sql ?? \"\");\n const isTargetTable = sql.includes(tableName);\n\n if (!isTargetTable) {\n return originalQuery(connection, obj);\n }\n\n const upperSql = sql.toUpperCase();\n const isInsert = upperSql.includes(\"INSERT\");\n const isDelete = upperSql.includes(\"DELETE\");\n\n if (!isInsert && !isDelete) {\n return originalQuery(connection, obj);\n }\n\n const rowsBefore = await query().select(\"*\");\n const beforeMap = new Map(rowsBefore.map(row => [row.id, row]));\n\n const result = await originalQuery(connection, obj);\n\n const rowsAfter = await query().select(\"*\");\n const afterMap = new Map(rowsAfter.map(row => [row.id, row]));\n\n const events: SyncEvent[] = [];\n\n if (isInsert) {\n for (const [id, row] of afterMap) {\n const before = beforeMap.get(id);\n if (!before) {\n events.push(toSyncEvent(row, \"INSERT\"));\n } else if (before.data !== row.data) {\n events.push(toSyncEvent(row, \"MODIFY\"));\n }\n }\n }\n\n if (isDelete) {\n for (const [id, row] of beforeMap) {\n if (!afterMap.has(id)) {\n events.push(toSyncEvent(row, \"REMOVE\"));\n }\n }\n }\n\n if (events.length > 0) {\n await handler(events);\n }\n\n return result;\n };\n};\n"],"names":["toSyncEvent","row","type","simulatePgStream","params","knex","tableName","handler","query","originalClient","originalQuery","connection","obj","sql","isTargetTable","upperSql","isInsert","isDelete","rowsBefore","beforeMap","Map","result","rowsAfter","afterMap","events","id","before"],"mappings":"AASA,MAAMA,cAAc,CAACC,KAAeC,OAAoC;QACpEA;QACA,IAAID,IAAI,EAAE;QACV,SAASA,IAAI,OAAO;QACpB,QAAQA,IAAI,MAAM;QAClB,OAAOA,IAAI,KAAK;QAChB,GAAIC,AAAS,aAATA,OAAoB;YAAE,MAAMD,IAAI,IAAI;QAAC,IAAI,CAAC,CAAC;IACnD;AAaO,MAAME,mBAAmB,CAACC;IAC7B,MAAM,EAAEC,IAAI,EAAEC,SAAS,EAAEC,OAAO,EAAE,GAAGH;IACrC,MAAMI,QAAQ,IAAMH,KAAeC;IAEnC,MAAMG,iBAAiBJ,KAAK,MAAM;IAClC,MAAMK,gBAAgBD,eAAe,KAAK,CAAC,IAAI,CAACA;IAEhDA,eAAe,KAAK,GAAG,OAAOE,YAAqBC;QAC/C,MAAMC,MAAc,AAAe,YAAf,OAAOD,MAAmBA,MAAQA,KAA0B,OAAO;QACvF,MAAME,gBAAgBD,IAAI,QAAQ,CAACP;QAEnC,IAAI,CAACQ,eACD,OAAOJ,cAAcC,YAAYC;QAGrC,MAAMG,WAAWF,IAAI,WAAW;QAChC,MAAMG,WAAWD,SAAS,QAAQ,CAAC;QACnC,MAAME,WAAWF,SAAS,QAAQ,CAAC;QAEnC,IAAI,CAACC,YAAY,CAACC,UACd,OAAOP,cAAcC,YAAYC;QAGrC,MAAMM,aAAa,MAAMV,QAAQ,MAAM,CAAC;QACxC,MAAMW,YAAY,IAAIC,IAAIF,WAAW,GAAG,CAACjB,CAAAA,MAAO;gBAACA,IAAI,EAAE;gBAAEA;aAAI;QAE7D,MAAMoB,SAAS,MAAMX,cAAcC,YAAYC;QAE/C,MAAMU,YAAY,MAAMd,QAAQ,MAAM,CAAC;QACvC,MAAMe,WAAW,IAAIH,IAAIE,UAAU,GAAG,CAACrB,CAAAA,MAAO;gBAACA,IAAI,EAAE;gBAAEA;aAAI;QAE3D,MAAMuB,SAAsB,EAAE;QAE9B,IAAIR,UACA,KAAK,MAAM,CAACS,IAAIxB,IAAI,IAAIsB,SAAU;YAC9B,MAAMG,SAASP,UAAU,GAAG,CAACM;YAC7B,IAAKC,QAEE;gBAAA,IAAIA,OAAO,IAAI,KAAKzB,IAAI,IAAI,EAC/BuB,OAAO,IAAI,CAACxB,YAAYC,KAAK;YACjC,OAHIuB,OAAO,IAAI,CAACxB,YAAYC,KAAK;QAIrC;QAGJ,IAAIgB,UACA;YAAA,KAAK,MAAM,CAACQ,IAAIxB,IAAI,IAAIkB,UACpB,IAAI,CAACI,SAAS,GAAG,CAACE,KACdD,OAAO,IAAI,CAACxB,YAAYC,KAAK;QAErC;QAGJ,IAAIuB,OAAO,MAAM,GAAG,GAChB,MAAMjB,QAAQiB;QAGlB,OAAOH;IACX;AACJ"}
1
+ {"version":3,"file":"testing/simulatePgStream.js","sources":["../../src/testing/simulatePgStream.ts"],"sourcesContent":["import type { Knex } from \"knex\";\nimport type { SyncEvent, ISyncRow, SyncEventType } from \"~/types.js\";\n\nexport interface SimulatePgStreamParams {\n knex: Knex;\n tableName: string;\n handler: (events: SyncEvent[]) => Promise<void>;\n}\n\nconst toSyncEvent = (row: ISyncRow, type: SyncEventType): SyncEvent => ({\n type,\n id: row.id,\n entryId: row.entryId,\n tenant: row.tenant,\n index: row.index,\n ...(type !== \"REMOVE\" ? { data: row.data } : {})\n});\n\nconst createRowKey = (row: ISyncRow): string => {\n return `${row.tenant}:${row.id}`;\n};\n\n/**\n * Simulates a PostgreSQL -> OpenSearch sync stream (the PG equivalent of the\n * DynamoDB Streams simulation in `@webiny/project-utils/testing/dynamodb`) by\n * monkey-patching knex's internal `client.query` method.\n *\n * Uses a snapshot-diff approach: capture all rows in the target table before\n * the operation, execute the operation, capture all rows after, then diff the\n * two snapshots to determine which `SyncEvent`s occurred. This is robust\n * against SQL structure changes, since it never has to parse bindings or SQL\n * text to reconstruct row data.\n */\nexport const simulatePgStream = (params: SimulatePgStreamParams): void => {\n const { knex, tableName, handler } = params;\n const query = () => knex<ISyncRow>(tableName);\n\n const originalClient = knex.client;\n const originalQuery = originalClient.query.bind(originalClient);\n\n originalClient.query = async (connection: unknown, obj: unknown) => {\n const sql: string = typeof obj === \"string\" ? obj : ((obj as { sql?: string })?.sql ?? \"\");\n const isTargetTable = sql.includes(tableName);\n\n if (!isTargetTable) {\n return originalQuery(connection, obj);\n }\n\n const upperSql = sql.toUpperCase();\n const isInsert = upperSql.includes(\"INSERT\");\n const isDelete = upperSql.includes(\"DELETE\");\n\n if (!isInsert && !isDelete) {\n return originalQuery(connection, obj);\n }\n\n const rowsBefore = await query().select(\"*\");\n const beforeMap = new Map(rowsBefore.map(row => [createRowKey(row), row]));\n\n const result = await originalQuery(connection, obj);\n\n const rowsAfter = await query().select(\"*\");\n const afterMap = new Map(rowsAfter.map(row => [createRowKey(row), row]));\n\n const events: SyncEvent[] = [];\n\n if (isInsert) {\n for (const [key, row] of afterMap) {\n const before = beforeMap.get(key);\n if (!before) {\n events.push(toSyncEvent(row, \"INSERT\"));\n } else if (before.data !== row.data) {\n events.push(toSyncEvent(row, \"MODIFY\"));\n }\n }\n }\n\n if (isDelete) {\n for (const [key, row] of beforeMap) {\n if (!afterMap.has(key)) {\n events.push(toSyncEvent(row, \"REMOVE\"));\n }\n }\n }\n\n if (events.length > 0) {\n await handler(events);\n }\n\n return result;\n };\n};\n"],"names":["toSyncEvent","row","type","createRowKey","simulatePgStream","params","knex","tableName","handler","query","originalClient","originalQuery","connection","obj","sql","isTargetTable","upperSql","isInsert","isDelete","rowsBefore","beforeMap","Map","result","rowsAfter","afterMap","events","key","before"],"mappings":"AASA,MAAMA,cAAc,CAACC,KAAeC,OAAoC;QACpEA;QACA,IAAID,IAAI,EAAE;QACV,SAASA,IAAI,OAAO;QACpB,QAAQA,IAAI,MAAM;QAClB,OAAOA,IAAI,KAAK;QAChB,GAAIC,AAAS,aAATA,OAAoB;YAAE,MAAMD,IAAI,IAAI;QAAC,IAAI,CAAC,CAAC;IACnD;AAEA,MAAME,eAAe,CAACF,MACX,GAAGA,IAAI,MAAM,CAAC,CAAC,EAAEA,IAAI,EAAE,EAAE;AAc7B,MAAMG,mBAAmB,CAACC;IAC7B,MAAM,EAAEC,IAAI,EAAEC,SAAS,EAAEC,OAAO,EAAE,GAAGH;IACrC,MAAMI,QAAQ,IAAMH,KAAeC;IAEnC,MAAMG,iBAAiBJ,KAAK,MAAM;IAClC,MAAMK,gBAAgBD,eAAe,KAAK,CAAC,IAAI,CAACA;IAEhDA,eAAe,KAAK,GAAG,OAAOE,YAAqBC;QAC/C,MAAMC,MAAc,AAAe,YAAf,OAAOD,MAAmBA,MAAQA,KAA0B,OAAO;QACvF,MAAME,gBAAgBD,IAAI,QAAQ,CAACP;QAEnC,IAAI,CAACQ,eACD,OAAOJ,cAAcC,YAAYC;QAGrC,MAAMG,WAAWF,IAAI,WAAW;QAChC,MAAMG,WAAWD,SAAS,QAAQ,CAAC;QACnC,MAAME,WAAWF,SAAS,QAAQ,CAAC;QAEnC,IAAI,CAACC,YAAY,CAACC,UACd,OAAOP,cAAcC,YAAYC;QAGrC,MAAMM,aAAa,MAAMV,QAAQ,MAAM,CAAC;QACxC,MAAMW,YAAY,IAAIC,IAAIF,WAAW,GAAG,CAAClB,CAAAA,MAAO;gBAACE,aAAaF;gBAAMA;aAAI;QAExE,MAAMqB,SAAS,MAAMX,cAAcC,YAAYC;QAE/C,MAAMU,YAAY,MAAMd,QAAQ,MAAM,CAAC;QACvC,MAAMe,WAAW,IAAIH,IAAIE,UAAU,GAAG,CAACtB,CAAAA,MAAO;gBAACE,aAAaF;gBAAMA;aAAI;QAEtE,MAAMwB,SAAsB,EAAE;QAE9B,IAAIR,UACA,KAAK,MAAM,CAACS,KAAKzB,IAAI,IAAIuB,SAAU;YAC/B,MAAMG,SAASP,UAAU,GAAG,CAACM;YAC7B,IAAKC,QAEE;gBAAA,IAAIA,OAAO,IAAI,KAAK1B,IAAI,IAAI,EAC/BwB,OAAO,IAAI,CAACzB,YAAYC,KAAK;YACjC,OAHIwB,OAAO,IAAI,CAACzB,YAAYC,KAAK;QAIrC;QAGJ,IAAIiB,UACA;YAAA,KAAK,MAAM,CAACQ,KAAKzB,IAAI,IAAImB,UACrB,IAAI,CAACI,SAAS,GAAG,CAACE,MACdD,OAAO,IAAI,CAACzB,YAAYC,KAAK;QAErC;QAGJ,IAAIwB,OAAO,MAAM,GAAG,GAChB,MAAMjB,QAAQiB;QAGlB,OAAOH;IACX;AACJ"}