@open-mercato/core 0.6.3-develop.3586.1.d5a44c810f → 0.6.3-develop.3588.1.2f62d1bb0d

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.
@@ -7,13 +7,19 @@ async function customerPersonCompanyLinksSupportDeletedAt(em) {
7
7
  if (typeof em.getKysely !== "function") {
8
8
  return true;
9
9
  }
10
- if (!supportsDeletedAtColumnPromise) {
11
- const db = em.getKysely();
12
- const probe = db.selectFrom("information_schema.columns").select(["column_name"]).where(sql`table_schema = current_schema()`).where("table_name", "=", PERSON_COMPANY_LINKS_TABLE).where("column_name", "=", PERSON_COMPANY_LINKS_DELETED_AT_COLUMN).executeTakeFirst().then((row) => !!row).catch(() => false);
13
- supportsDeletedAtColumnPromise = probe;
14
- return probe;
15
- }
16
- return supportsDeletedAtColumnPromise;
10
+ if (supportsDeletedAtColumnPromise) return supportsDeletedAtColumnPromise;
11
+ const probe = (async () => {
12
+ try {
13
+ const db = em.getKysely();
14
+ const row = await db.selectFrom("information_schema.columns").select(["column_name"]).where(sql`table_schema = current_schema()`).where("table_name", "=", PERSON_COMPANY_LINKS_TABLE).where("column_name", "=", PERSON_COMPANY_LINKS_DELETED_AT_COLUMN).executeTakeFirst();
15
+ return !!row;
16
+ } catch {
17
+ supportsDeletedAtColumnPromise = null;
18
+ return true;
19
+ }
20
+ })();
21
+ supportsDeletedAtColumnPromise = probe;
22
+ return probe;
17
23
  }
18
24
  function warnMissingCustomerPersonCompanyLinksDeletedAt(source) {
19
25
  if (warnedAboutMissingDeletedAtColumn) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customers/lib/personCompanyLinkTable.ts"],
4
- "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { sql } from '@mikro-orm/postgresql'\n\nconst PERSON_COMPANY_LINKS_TABLE = 'customer_person_company_links'\nconst PERSON_COMPANY_LINKS_DELETED_AT_COLUMN = 'deleted_at'\n\nlet supportsDeletedAtColumnPromise: Promise<boolean> | null = null\nlet warnedAboutMissingDeletedAtColumn = false\n\nexport async function customerPersonCompanyLinksSupportDeletedAt(em: EntityManager): Promise<boolean> {\n if (typeof (em as { getKysely?: unknown }).getKysely !== 'function') {\n return true\n }\n if (!supportsDeletedAtColumnPromise) {\n const db = em.getKysely<any>() as any\n const probe: Promise<boolean> = db\n .selectFrom('information_schema.columns')\n .select(['column_name'])\n .where(sql<boolean>`table_schema = current_schema()`)\n .where('table_name', '=', PERSON_COMPANY_LINKS_TABLE)\n .where('column_name', '=', PERSON_COMPANY_LINKS_DELETED_AT_COLUMN)\n .executeTakeFirst()\n .then((row: unknown) => !!row)\n .catch(() => false)\n supportsDeletedAtColumnPromise = probe\n return probe\n }\n return supportsDeletedAtColumnPromise\n}\n\nexport function warnMissingCustomerPersonCompanyLinksDeletedAt(source: string): void {\n if (warnedAboutMissingDeletedAtColumn) {\n return\n }\n warnedAboutMissingDeletedAtColumn = true\n console.warn(\n `[${source}] missing ${PERSON_COMPANY_LINKS_TABLE}.${PERSON_COMPANY_LINKS_DELETED_AT_COLUMN}; ` +\n 'continuing without link soft-delete filtering. Run yarn db:migrate.',\n )\n}\n\nexport async function withActiveCustomerPersonCompanyLinkFilter<T extends Record<string, unknown>>(\n em: EntityManager,\n where: T,\n source: string,\n): Promise<T & { deletedAt?: null }> {\n const supportsDeletedAt = await customerPersonCompanyLinksSupportDeletedAt(em)\n if (!supportsDeletedAt) {\n warnMissingCustomerPersonCompanyLinksDeletedAt(source)\n return { ...where }\n }\n return { ...where, deletedAt: null }\n}\n\n/**\n * Drop soft-deleted link rows from a result set as a defense-in-depth fallback.\n * MikroORM has historically dropped `deletedAt: null` from the WHERE clause for\n * nullable date columns under certain configurations, so callers SHOULD apply this\n * after `findWithDecryption(...)` until the upstream query filter is verified to\n * fully cover all callers.\n */\nexport function filterActivePersonCompanyLinks<T extends { deletedAt?: Date | string | null | undefined }>(\n links: T[] | null | undefined,\n): T[] {\n if (!Array.isArray(links)) return []\n return links.filter((entry) => entry?.deletedAt == null)\n}\n"],
5
- "mappings": "AACA,SAAS,WAAW;AAEpB,MAAM,6BAA6B;AACnC,MAAM,yCAAyC;AAE/C,IAAI,iCAA0D;AAC9D,IAAI,oCAAoC;AAExC,eAAsB,2CAA2C,IAAqC;AACpG,MAAI,OAAQ,GAA+B,cAAc,YAAY;AACnE,WAAO;AAAA,EACT;AACA,MAAI,CAAC,gCAAgC;AACnC,UAAM,KAAK,GAAG,UAAe;AAC7B,UAAM,QAA0B,GAC7B,WAAW,4BAA4B,EACvC,OAAO,CAAC,aAAa,CAAC,EACtB,MAAM,oCAA6C,EACnD,MAAM,cAAc,KAAK,0BAA0B,EACnD,MAAM,eAAe,KAAK,sCAAsC,EAChE,iBAAiB,EACjB,KAAK,CAAC,QAAiB,CAAC,CAAC,GAAG,EAC5B,MAAM,MAAM,KAAK;AACpB,qCAAiC;AACjC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,+CAA+C,QAAsB;AACnF,MAAI,mCAAmC;AACrC;AAAA,EACF;AACA,sCAAoC;AACpC,UAAQ;AAAA,IACN,IAAI,MAAM,aAAa,0BAA0B,IAAI,sCAAsC;AAAA,EAE7F;AACF;AAEA,eAAsB,0CACpB,IACA,OACA,QACmC;AACnC,QAAM,oBAAoB,MAAM,2CAA2C,EAAE;AAC7E,MAAI,CAAC,mBAAmB;AACtB,mDAA+C,MAAM;AACrD,WAAO,EAAE,GAAG,MAAM;AAAA,EACpB;AACA,SAAO,EAAE,GAAG,OAAO,WAAW,KAAK;AACrC;AASO,SAAS,+BACd,OACK;AACL,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MAAM,OAAO,CAAC,UAAU,OAAO,aAAa,IAAI;AACzD;",
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { sql } from '@mikro-orm/postgresql'\n\nconst PERSON_COMPANY_LINKS_TABLE = 'customer_person_company_links'\nconst PERSON_COMPANY_LINKS_DELETED_AT_COLUMN = 'deleted_at'\n\nlet supportsDeletedAtColumnPromise: Promise<boolean> | null = null\nlet warnedAboutMissingDeletedAtColumn = false\n\nexport async function customerPersonCompanyLinksSupportDeletedAt(em: EntityManager): Promise<boolean> {\n if (typeof (em as { getKysely?: unknown }).getKysely !== 'function') {\n return true\n }\n if (supportsDeletedAtColumnPromise) return supportsDeletedAtColumnPromise\n const probe = (async (): Promise<boolean> => {\n try {\n const db = em.getKysely<any>() as any\n const row = await db\n .selectFrom('information_schema.columns')\n .select(['column_name'])\n .where(sql<boolean>`table_schema = current_schema()`)\n .where('table_name', '=', PERSON_COMPANY_LINKS_TABLE)\n .where('column_name', '=', PERSON_COMPANY_LINKS_DELETED_AT_COLUMN)\n .executeTakeFirst()\n return !!row\n } catch {\n // The probe can fail transiently (e.g. when invoked inside an already-aborted\n // postgres transaction \u2014 25P02). Clear the cache so the next caller re-probes\n // on a healthy connection, and assume the column is present: the migration is\n // committed, and if it really is missing the downstream em.find will surface\n // the authentic \"column does not exist\" error instead of a misleading warning.\n supportsDeletedAtColumnPromise = null\n return true\n }\n })()\n supportsDeletedAtColumnPromise = probe\n return probe\n}\n\nexport function warnMissingCustomerPersonCompanyLinksDeletedAt(source: string): void {\n if (warnedAboutMissingDeletedAtColumn) {\n return\n }\n warnedAboutMissingDeletedAtColumn = true\n console.warn(\n `[${source}] missing ${PERSON_COMPANY_LINKS_TABLE}.${PERSON_COMPANY_LINKS_DELETED_AT_COLUMN}; ` +\n 'continuing without link soft-delete filtering. Run yarn db:migrate.',\n )\n}\n\nexport async function withActiveCustomerPersonCompanyLinkFilter<T extends Record<string, unknown>>(\n em: EntityManager,\n where: T,\n source: string,\n): Promise<T & { deletedAt?: null }> {\n const supportsDeletedAt = await customerPersonCompanyLinksSupportDeletedAt(em)\n if (!supportsDeletedAt) {\n warnMissingCustomerPersonCompanyLinksDeletedAt(source)\n return { ...where }\n }\n return { ...where, deletedAt: null }\n}\n\n/**\n * Drop soft-deleted link rows from a result set as a defense-in-depth fallback.\n * MikroORM has historically dropped `deletedAt: null` from the WHERE clause for\n * nullable date columns under certain configurations, so callers SHOULD apply this\n * after `findWithDecryption(...)` until the upstream query filter is verified to\n * fully cover all callers.\n */\nexport function filterActivePersonCompanyLinks<T extends { deletedAt?: Date | string | null | undefined }>(\n links: T[] | null | undefined,\n): T[] {\n if (!Array.isArray(links)) return []\n return links.filter((entry) => entry?.deletedAt == null)\n}\n"],
5
+ "mappings": "AACA,SAAS,WAAW;AAEpB,MAAM,6BAA6B;AACnC,MAAM,yCAAyC;AAE/C,IAAI,iCAA0D;AAC9D,IAAI,oCAAoC;AAExC,eAAsB,2CAA2C,IAAqC;AACpG,MAAI,OAAQ,GAA+B,cAAc,YAAY;AACnE,WAAO;AAAA,EACT;AACA,MAAI,+BAAgC,QAAO;AAC3C,QAAM,SAAS,YAA8B;AAC3C,QAAI;AACF,YAAM,KAAK,GAAG,UAAe;AAC7B,YAAM,MAAM,MAAM,GACf,WAAW,4BAA4B,EACvC,OAAO,CAAC,aAAa,CAAC,EACtB,MAAM,oCAA6C,EACnD,MAAM,cAAc,KAAK,0BAA0B,EACnD,MAAM,eAAe,KAAK,sCAAsC,EAChE,iBAAiB;AACpB,aAAO,CAAC,CAAC;AAAA,IACX,QAAQ;AAMN,uCAAiC;AACjC,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,mCAAiC;AACjC,SAAO;AACT;AAEO,SAAS,+CAA+C,QAAsB;AACnF,MAAI,mCAAmC;AACrC;AAAA,EACF;AACA,sCAAoC;AACpC,UAAQ;AAAA,IACN,IAAI,MAAM,aAAa,0BAA0B,IAAI,sCAAsC;AAAA,EAE7F;AACF;AAEA,eAAsB,0CACpB,IACA,OACA,QACmC;AACnC,QAAM,oBAAoB,MAAM,2CAA2C,EAAE;AAC7E,MAAI,CAAC,mBAAmB;AACtB,mDAA+C,MAAM;AACrD,WAAO,EAAE,GAAG,MAAM;AAAA,EACpB;AACA,SAAO,EAAE,GAAG,OAAO,WAAW,KAAK;AACrC;AASO,SAAS,+BACd,OACK;AACL,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MAAM,OAAO,CAAC,UAAU,OAAO,aAAa,IAAI;AACzD;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.6.3-develop.3586.1.d5a44c810f",
3
+ "version": "0.6.3-develop.3588.1.2f62d1bb0d",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -242,16 +242,16 @@
242
242
  "zod": "^4.4.3"
243
243
  },
244
244
  "peerDependencies": {
245
- "@open-mercato/ai-assistant": "0.6.3-develop.3586.1.d5a44c810f",
246
- "@open-mercato/shared": "0.6.3-develop.3586.1.d5a44c810f",
247
- "@open-mercato/ui": "0.6.3-develop.3586.1.d5a44c810f",
245
+ "@open-mercato/ai-assistant": "0.6.3-develop.3588.1.2f62d1bb0d",
246
+ "@open-mercato/shared": "0.6.3-develop.3588.1.2f62d1bb0d",
247
+ "@open-mercato/ui": "0.6.3-develop.3588.1.2f62d1bb0d",
248
248
  "react": "^19.0.0",
249
249
  "react-dom": "^19.0.0"
250
250
  },
251
251
  "devDependencies": {
252
- "@open-mercato/ai-assistant": "0.6.3-develop.3586.1.d5a44c810f",
253
- "@open-mercato/shared": "0.6.3-develop.3586.1.d5a44c810f",
254
- "@open-mercato/ui": "0.6.3-develop.3586.1.d5a44c810f",
252
+ "@open-mercato/ai-assistant": "0.6.3-develop.3588.1.2f62d1bb0d",
253
+ "@open-mercato/shared": "0.6.3-develop.3588.1.2f62d1bb0d",
254
+ "@open-mercato/ui": "0.6.3-develop.3588.1.2f62d1bb0d",
255
255
  "@testing-library/dom": "^10.4.1",
256
256
  "@testing-library/jest-dom": "^6.9.1",
257
257
  "@testing-library/react": "^16.3.1",
@@ -11,21 +11,30 @@ export async function customerPersonCompanyLinksSupportDeletedAt(em: EntityManag
11
11
  if (typeof (em as { getKysely?: unknown }).getKysely !== 'function') {
12
12
  return true
13
13
  }
14
- if (!supportsDeletedAtColumnPromise) {
15
- const db = em.getKysely<any>() as any
16
- const probe: Promise<boolean> = db
17
- .selectFrom('information_schema.columns')
18
- .select(['column_name'])
19
- .where(sql<boolean>`table_schema = current_schema()`)
20
- .where('table_name', '=', PERSON_COMPANY_LINKS_TABLE)
21
- .where('column_name', '=', PERSON_COMPANY_LINKS_DELETED_AT_COLUMN)
22
- .executeTakeFirst()
23
- .then((row: unknown) => !!row)
24
- .catch(() => false)
25
- supportsDeletedAtColumnPromise = probe
26
- return probe
27
- }
28
- return supportsDeletedAtColumnPromise
14
+ if (supportsDeletedAtColumnPromise) return supportsDeletedAtColumnPromise
15
+ const probe = (async (): Promise<boolean> => {
16
+ try {
17
+ const db = em.getKysely<any>() as any
18
+ const row = await db
19
+ .selectFrom('information_schema.columns')
20
+ .select(['column_name'])
21
+ .where(sql<boolean>`table_schema = current_schema()`)
22
+ .where('table_name', '=', PERSON_COMPANY_LINKS_TABLE)
23
+ .where('column_name', '=', PERSON_COMPANY_LINKS_DELETED_AT_COLUMN)
24
+ .executeTakeFirst()
25
+ return !!row
26
+ } catch {
27
+ // The probe can fail transiently (e.g. when invoked inside an already-aborted
28
+ // postgres transaction — 25P02). Clear the cache so the next caller re-probes
29
+ // on a healthy connection, and assume the column is present: the migration is
30
+ // committed, and if it really is missing the downstream em.find will surface
31
+ // the authentic "column does not exist" error instead of a misleading warning.
32
+ supportsDeletedAtColumnPromise = null
33
+ return true
34
+ }
35
+ })()
36
+ supportsDeletedAtColumnPromise = probe
37
+ return probe
29
38
  }
30
39
 
31
40
  export function warnMissingCustomerPersonCompanyLinksDeletedAt(source: string): void {