@open-mercato/shared 0.5.1-develop.2756.cce1739df3 → 0.5.1-develop.2762.90c271efe2

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.
@@ -1,3 +1,4 @@
1
+ import { runWithCacheTenant } from "@open-mercato/cache";
1
2
  import { parseBooleanToken } from "../boolean.js";
2
3
  let crudCacheEnabledFlag = null;
3
4
  function isCrudCacheEnabled() {
@@ -147,7 +148,7 @@ async function invalidateCrudCache(container, resource, identifiers, fallbackTen
147
148
  tags: tagList,
148
149
  action: "clearing"
149
150
  });
150
- const deleted = await cache.deleteByTags(tagList);
151
+ const deleted = await runWithCacheTenant(tenantId, () => cache.deleteByTags(tagList));
151
152
  debugCrudCache("invalidate", {
152
153
  resource,
153
154
  reason,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/crud/cache.ts"],
4
- "sourcesContent": ["import type { AwilixContainer } from 'awilix'\nimport type { CacheStrategy } from '@open-mercato/cache'\nimport { parseBooleanToken } from '../boolean'\n\nexport type CrudCacheIdentifiers = {\n id?: string | null\n organizationId?: string | null\n tenantId?: string | null\n}\n\nlet crudCacheEnabledFlag: boolean | null = null\nexport function isCrudCacheEnabled(): boolean {\n if (crudCacheEnabledFlag !== null) return crudCacheEnabledFlag\n crudCacheEnabledFlag = parseBooleanToken(process.env.ENABLE_CRUD_API_CACHE ?? '') === true\n return crudCacheEnabledFlag\n}\n\nlet crudCacheDebugFlag: boolean | null = null\nexport function isCrudCacheDebugEnabled(): boolean {\n if (crudCacheDebugFlag !== null) return crudCacheDebugFlag\n crudCacheDebugFlag = parseBooleanToken(process.env.QUERY_ENGINE_DEBUG_SQL ?? '') === true\n return crudCacheDebugFlag\n}\n\nexport function debugCrudCache(event: string, context: Record<string, unknown>) {\n if (!isCrudCacheDebugEnabled()) return\n try {\n console.debug('[crud][cache]', event, context)\n } catch {}\n}\n\nexport function resolveCrudCache(container: AwilixContainer): CacheStrategy | null {\n try {\n const cache = (container.resolve('cache') as CacheStrategy)\n if (cache && typeof cache.get === 'function' && typeof cache.set === 'function') {\n return cache\n }\n } catch {}\n return null\n}\n\nexport function normalizeTagSegment(value: string | null | undefined): string {\n if (value === null || value === undefined || value === '') return 'null'\n return value.toString().trim().replace(/[^a-zA-Z0-9._-]/g, '-')\n}\n\nexport function canonicalizeResourceTag(value: string | null | undefined): string | null {\n if (value === null || value === undefined) return null\n const trimmed = String(value).trim()\n if (!trimmed.length) return null\n const withSeparators = trimmed\n .replace(/::/g, '.')\n .replace(/[/\\\\]+/g, '.')\n .replace(/[\\s]+/g, '.')\n .replace(/_/g, '.')\n .replace(/-+/g, '.')\n const withCamelBreaks = withSeparators.replace(/([a-z0-9])([A-Z])/g, '$1.$2')\n const collapsed = withCamelBreaks.replace(/\\.{2,}/g, '.').replace(/(?:^\\.+|\\.+$)/g, '')\n const lowered = collapsed.toLowerCase()\n return lowered.length ? lowered : null\n}\n\nexport function buildRecordTag(resource: string, tenantId: string | null, recordId: string): string {\n return [\n 'crud',\n normalizeTagSegment(resource),\n 'tenant',\n normalizeTagSegment(tenantId),\n 'record',\n normalizeTagSegment(recordId),\n ].join(':')\n}\n\nexport function buildCollectionTags(\n resource: string,\n tenantId: string | null,\n organizationIds: Array<string | null>\n): string[] {\n const normalizedResource = normalizeTagSegment(resource)\n const normalizedTenant = normalizeTagSegment(tenantId)\n const tags = new Set<string>()\n if (!organizationIds.length) {\n tags.add(['crud', normalizedResource, 'tenant', normalizedTenant, 'org', 'null', 'collection'].join(':'))\n return Array.from(tags)\n }\n for (const orgId of organizationIds) {\n tags.add(['crud', normalizedResource, 'tenant', normalizedTenant, 'org', normalizeTagSegment(orgId), 'collection'].join(':'))\n }\n return Array.from(tags)\n}\n\nexport function normalizeIdentifierValue(value: unknown): string | null {\n if (value === null || value === undefined) return null\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'bigint') return String(value)\n if (typeof value === 'object') {\n if (value instanceof Date) return value.toISOString()\n if (value && typeof (value as { id?: unknown }).id !== 'undefined') {\n return normalizeIdentifierValue((value as { id?: unknown }).id)\n }\n }\n return String(value)\n}\n\nexport function pickFirstIdentifier(...values: Array<unknown>): string | null {\n for (const value of values) {\n const normalized = normalizeIdentifierValue(value)\n if (normalized) return normalized\n }\n return null\n}\n\nfunction singularizeSegment(segment: string): string {\n const lower = segment.toLowerCase()\n if (lower.endsWith('ies') && lower.length > 3) return lower.slice(0, -3) + 'y'\n if (lower.endsWith('ses') && lower.length > 3) return lower.slice(0, -2)\n if (\n (lower.endsWith('xes') ||\n lower.endsWith('zes') ||\n lower.endsWith('ches') ||\n lower.endsWith('shes')) &&\n lower.length > 3\n ) {\n return lower.slice(0, -2)\n }\n if (lower.endsWith('s') && !lower.endsWith('ss') && lower.length > 1) return lower.slice(0, -1)\n return lower\n}\n\nfunction singularizeResourceSegment(segment: string): string {\n return segment\n .split('-')\n .map((part) => singularizeSegment(part))\n .join('-')\n}\n\nexport function deriveResourceFromCommandId(commandId: string | undefined | null): string | null {\n if (!commandId || typeof commandId !== 'string') return null\n const parts = commandId.split('.')\n if (parts.length < 2) return null\n const modulePart = parts[0]\n const entityPart = singularizeResourceSegment(parts[1])\n if (!modulePart || !entityPart) return null\n return `${modulePart}.${entityPart}`\n}\n\nexport function expandResourceAliases(resource: string, aliases?: string[]): string[] {\n const set = new Set<string>()\n const inputs = [resource, ...(aliases ?? [])]\n for (const candidate of inputs) {\n const canonical = canonicalizeResourceTag(candidate)\n if (canonical) set.add(canonical)\n }\n if (!set.size) return []\n return Array.from(set)\n}\n\nexport async function invalidateCrudCache(\n container: AwilixContainer,\n resource: string,\n identifiers: CrudCacheIdentifiers,\n fallbackTenant: string | null,\n reason: string,\n aliases?: string[]\n): Promise<void> {\n if (!isCrudCacheEnabled()) return\n const cache = resolveCrudCache(container)\n if (!cache || typeof cache.deleteByTags !== 'function') return\n const resources = expandResourceAliases(resource, aliases)\n const tenantId = identifiers.tenantId ?? fallbackTenant ?? null\n const recordId = normalizeIdentifierValue(identifiers.id)\n const tags = new Set<string>()\n for (const key of resources) {\n if (recordId) {\n tags.add(buildRecordTag(key, tenantId, recordId))\n }\n const organizationIds: Array<string | null> = []\n if (identifiers.organizationId !== undefined) {\n organizationIds.push(identifiers.organizationId ?? null)\n }\n if (!organizationIds.length) organizationIds.push(null)\n for (const tag of buildCollectionTags(key, tenantId, organizationIds)) {\n tags.add(tag)\n }\n }\n if (!tags.size) return\n const tagList = Array.from(tags)\n debugCrudCache('invalidate', {\n resource,\n aliases: resources,\n reason,\n tenantId: tenantId ?? 'null',\n tags: tagList,\n action: 'clearing',\n })\n const deleted = await cache.deleteByTags(tagList)\n debugCrudCache('invalidate', {\n resource,\n reason,\n tenantId: tenantId ?? 'null',\n tags: tagList,\n action: 'cleared',\n deleted,\n })\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { AwilixContainer } from 'awilix'\nimport { runWithCacheTenant, type CacheStrategy } from '@open-mercato/cache'\nimport { parseBooleanToken } from '../boolean'\n\nexport type CrudCacheIdentifiers = {\n id?: string | null\n organizationId?: string | null\n tenantId?: string | null\n}\n\nlet crudCacheEnabledFlag: boolean | null = null\nexport function isCrudCacheEnabled(): boolean {\n if (crudCacheEnabledFlag !== null) return crudCacheEnabledFlag\n crudCacheEnabledFlag = parseBooleanToken(process.env.ENABLE_CRUD_API_CACHE ?? '') === true\n return crudCacheEnabledFlag\n}\n\nlet crudCacheDebugFlag: boolean | null = null\nexport function isCrudCacheDebugEnabled(): boolean {\n if (crudCacheDebugFlag !== null) return crudCacheDebugFlag\n crudCacheDebugFlag = parseBooleanToken(process.env.QUERY_ENGINE_DEBUG_SQL ?? '') === true\n return crudCacheDebugFlag\n}\n\nexport function debugCrudCache(event: string, context: Record<string, unknown>) {\n if (!isCrudCacheDebugEnabled()) return\n try {\n console.debug('[crud][cache]', event, context)\n } catch {}\n}\n\nexport function resolveCrudCache(container: AwilixContainer): CacheStrategy | null {\n try {\n const cache = (container.resolve('cache') as CacheStrategy)\n if (cache && typeof cache.get === 'function' && typeof cache.set === 'function') {\n return cache\n }\n } catch {}\n return null\n}\n\nexport function normalizeTagSegment(value: string | null | undefined): string {\n if (value === null || value === undefined || value === '') return 'null'\n return value.toString().trim().replace(/[^a-zA-Z0-9._-]/g, '-')\n}\n\nexport function canonicalizeResourceTag(value: string | null | undefined): string | null {\n if (value === null || value === undefined) return null\n const trimmed = String(value).trim()\n if (!trimmed.length) return null\n const withSeparators = trimmed\n .replace(/::/g, '.')\n .replace(/[/\\\\]+/g, '.')\n .replace(/[\\s]+/g, '.')\n .replace(/_/g, '.')\n .replace(/-+/g, '.')\n const withCamelBreaks = withSeparators.replace(/([a-z0-9])([A-Z])/g, '$1.$2')\n const collapsed = withCamelBreaks.replace(/\\.{2,}/g, '.').replace(/(?:^\\.+|\\.+$)/g, '')\n const lowered = collapsed.toLowerCase()\n return lowered.length ? lowered : null\n}\n\nexport function buildRecordTag(resource: string, tenantId: string | null, recordId: string): string {\n return [\n 'crud',\n normalizeTagSegment(resource),\n 'tenant',\n normalizeTagSegment(tenantId),\n 'record',\n normalizeTagSegment(recordId),\n ].join(':')\n}\n\nexport function buildCollectionTags(\n resource: string,\n tenantId: string | null,\n organizationIds: Array<string | null>\n): string[] {\n const normalizedResource = normalizeTagSegment(resource)\n const normalizedTenant = normalizeTagSegment(tenantId)\n const tags = new Set<string>()\n if (!organizationIds.length) {\n tags.add(['crud', normalizedResource, 'tenant', normalizedTenant, 'org', 'null', 'collection'].join(':'))\n return Array.from(tags)\n }\n for (const orgId of organizationIds) {\n tags.add(['crud', normalizedResource, 'tenant', normalizedTenant, 'org', normalizeTagSegment(orgId), 'collection'].join(':'))\n }\n return Array.from(tags)\n}\n\nexport function normalizeIdentifierValue(value: unknown): string | null {\n if (value === null || value === undefined) return null\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'bigint') return String(value)\n if (typeof value === 'object') {\n if (value instanceof Date) return value.toISOString()\n if (value && typeof (value as { id?: unknown }).id !== 'undefined') {\n return normalizeIdentifierValue((value as { id?: unknown }).id)\n }\n }\n return String(value)\n}\n\nexport function pickFirstIdentifier(...values: Array<unknown>): string | null {\n for (const value of values) {\n const normalized = normalizeIdentifierValue(value)\n if (normalized) return normalized\n }\n return null\n}\n\nfunction singularizeSegment(segment: string): string {\n const lower = segment.toLowerCase()\n if (lower.endsWith('ies') && lower.length > 3) return lower.slice(0, -3) + 'y'\n if (lower.endsWith('ses') && lower.length > 3) return lower.slice(0, -2)\n if (\n (lower.endsWith('xes') ||\n lower.endsWith('zes') ||\n lower.endsWith('ches') ||\n lower.endsWith('shes')) &&\n lower.length > 3\n ) {\n return lower.slice(0, -2)\n }\n if (lower.endsWith('s') && !lower.endsWith('ss') && lower.length > 1) return lower.slice(0, -1)\n return lower\n}\n\nfunction singularizeResourceSegment(segment: string): string {\n return segment\n .split('-')\n .map((part) => singularizeSegment(part))\n .join('-')\n}\n\nexport function deriveResourceFromCommandId(commandId: string | undefined | null): string | null {\n if (!commandId || typeof commandId !== 'string') return null\n const parts = commandId.split('.')\n if (parts.length < 2) return null\n const modulePart = parts[0]\n const entityPart = singularizeResourceSegment(parts[1])\n if (!modulePart || !entityPart) return null\n return `${modulePart}.${entityPart}`\n}\n\nexport function expandResourceAliases(resource: string, aliases?: string[]): string[] {\n const set = new Set<string>()\n const inputs = [resource, ...(aliases ?? [])]\n for (const candidate of inputs) {\n const canonical = canonicalizeResourceTag(candidate)\n if (canonical) set.add(canonical)\n }\n if (!set.size) return []\n return Array.from(set)\n}\n\nexport async function invalidateCrudCache(\n container: AwilixContainer,\n resource: string,\n identifiers: CrudCacheIdentifiers,\n fallbackTenant: string | null,\n reason: string,\n aliases?: string[]\n): Promise<void> {\n if (!isCrudCacheEnabled()) return\n const cache = resolveCrudCache(container)\n if (!cache || typeof cache.deleteByTags !== 'function') return\n const resources = expandResourceAliases(resource, aliases)\n const tenantId = identifiers.tenantId ?? fallbackTenant ?? null\n const recordId = normalizeIdentifierValue(identifiers.id)\n const tags = new Set<string>()\n for (const key of resources) {\n if (recordId) {\n tags.add(buildRecordTag(key, tenantId, recordId))\n }\n const organizationIds: Array<string | null> = []\n if (identifiers.organizationId !== undefined) {\n organizationIds.push(identifiers.organizationId ?? null)\n }\n if (!organizationIds.length) organizationIds.push(null)\n for (const tag of buildCollectionTags(key, tenantId, organizationIds)) {\n tags.add(tag)\n }\n }\n if (!tags.size) return\n const tagList = Array.from(tags)\n debugCrudCache('invalidate', {\n resource,\n aliases: resources,\n reason,\n tenantId: tenantId ?? 'null',\n tags: tagList,\n action: 'clearing',\n })\n const deleted = await runWithCacheTenant(tenantId, () => cache.deleteByTags(tagList))\n debugCrudCache('invalidate', {\n resource,\n reason,\n tenantId: tenantId ?? 'null',\n tags: tagList,\n action: 'cleared',\n deleted,\n })\n}\n"],
5
+ "mappings": "AACA,SAAS,0BAA8C;AACvD,SAAS,yBAAyB;AAQlC,IAAI,uBAAuC;AACpC,SAAS,qBAA8B;AAC5C,MAAI,yBAAyB,KAAM,QAAO;AAC1C,yBAAuB,kBAAkB,QAAQ,IAAI,yBAAyB,EAAE,MAAM;AACtF,SAAO;AACT;AAEA,IAAI,qBAAqC;AAClC,SAAS,0BAAmC;AACjD,MAAI,uBAAuB,KAAM,QAAO;AACxC,uBAAqB,kBAAkB,QAAQ,IAAI,0BAA0B,EAAE,MAAM;AACrF,SAAO;AACT;AAEO,SAAS,eAAe,OAAe,SAAkC;AAC9E,MAAI,CAAC,wBAAwB,EAAG;AAChC,MAAI;AACF,YAAQ,MAAM,iBAAiB,OAAO,OAAO;AAAA,EAC/C,QAAQ;AAAA,EAAC;AACX;AAEO,SAAS,iBAAiB,WAAkD;AACjF,MAAI;AACF,UAAM,QAAS,UAAU,QAAQ,OAAO;AACxC,QAAI,SAAS,OAAO,MAAM,QAAQ,cAAc,OAAO,MAAM,QAAQ,YAAY;AAC/E,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAAC;AACT,SAAO;AACT;AAEO,SAAS,oBAAoB,OAA0C;AAC5E,MAAI,UAAU,QAAQ,UAAU,UAAa,UAAU,GAAI,QAAO;AAClE,SAAO,MAAM,SAAS,EAAE,KAAK,EAAE,QAAQ,oBAAoB,GAAG;AAChE;AAEO,SAAS,wBAAwB,OAAiD;AACvF,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,QAAM,UAAU,OAAO,KAAK,EAAE,KAAK;AACnC,MAAI,CAAC,QAAQ,OAAQ,QAAO;AAC5B,QAAM,iBAAiB,QACpB,QAAQ,OAAO,GAAG,EAClB,QAAQ,WAAW,GAAG,EACtB,QAAQ,UAAU,GAAG,EACrB,QAAQ,MAAM,GAAG,EACjB,QAAQ,OAAO,GAAG;AACrB,QAAM,kBAAkB,eAAe,QAAQ,sBAAsB,OAAO;AAC5E,QAAM,YAAY,gBAAgB,QAAQ,WAAW,GAAG,EAAE,QAAQ,kBAAkB,EAAE;AACtF,QAAM,UAAU,UAAU,YAAY;AACtC,SAAO,QAAQ,SAAS,UAAU;AACpC;AAEO,SAAS,eAAe,UAAkB,UAAyB,UAA0B;AAClG,SAAO;AAAA,IACL;AAAA,IACA,oBAAoB,QAAQ;AAAA,IAC5B;AAAA,IACA,oBAAoB,QAAQ;AAAA,IAC5B;AAAA,IACA,oBAAoB,QAAQ;AAAA,EAC9B,EAAE,KAAK,GAAG;AACZ;AAEO,SAAS,oBACd,UACA,UACA,iBACU;AACV,QAAM,qBAAqB,oBAAoB,QAAQ;AACvD,QAAM,mBAAmB,oBAAoB,QAAQ;AACrD,QAAM,OAAO,oBAAI,IAAY;AAC7B,MAAI,CAAC,gBAAgB,QAAQ;AAC3B,SAAK,IAAI,CAAC,QAAQ,oBAAoB,UAAU,kBAAkB,OAAO,QAAQ,YAAY,EAAE,KAAK,GAAG,CAAC;AACxG,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AACA,aAAW,SAAS,iBAAiB;AACnC,SAAK,IAAI,CAAC,QAAQ,oBAAoB,UAAU,kBAAkB,OAAO,oBAAoB,KAAK,GAAG,YAAY,EAAE,KAAK,GAAG,CAAC;AAAA,EAC9H;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,yBAAyB,OAA+B;AACtE,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAC/E,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI,iBAAiB,KAAM,QAAO,MAAM,YAAY;AACpD,QAAI,SAAS,OAAQ,MAA2B,OAAO,aAAa;AAClE,aAAO,yBAA0B,MAA2B,EAAE;AAAA,IAChE;AAAA,EACF;AACA,SAAO,OAAO,KAAK;AACrB;AAEO,SAAS,uBAAuB,QAAuC;AAC5E,aAAW,SAAS,QAAQ;AAC1B,UAAM,aAAa,yBAAyB,KAAK;AACjD,QAAI,WAAY,QAAO;AAAA,EACzB;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,SAAyB;AACnD,QAAM,QAAQ,QAAQ,YAAY;AAClC,MAAI,MAAM,SAAS,KAAK,KAAK,MAAM,SAAS,EAAG,QAAO,MAAM,MAAM,GAAG,EAAE,IAAI;AAC3E,MAAI,MAAM,SAAS,KAAK,KAAK,MAAM,SAAS,EAAG,QAAO,MAAM,MAAM,GAAG,EAAE;AACvE,OACG,MAAM,SAAS,KAAK,KACnB,MAAM,SAAS,KAAK,KACpB,MAAM,SAAS,MAAM,KACrB,MAAM,SAAS,MAAM,MACvB,MAAM,SAAS,GACf;AACA,WAAO,MAAM,MAAM,GAAG,EAAE;AAAA,EAC1B;AACA,MAAI,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,SAAS,IAAI,KAAK,MAAM,SAAS,EAAG,QAAO,MAAM,MAAM,GAAG,EAAE;AAC9F,SAAO;AACT;AAEA,SAAS,2BAA2B,SAAyB;AAC3D,SAAO,QACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,mBAAmB,IAAI,CAAC,EACtC,KAAK,GAAG;AACb;AAEO,SAAS,4BAA4B,WAAqD;AAC/F,MAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO;AACxD,QAAM,QAAQ,UAAU,MAAM,GAAG;AACjC,MAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAM,aAAa,MAAM,CAAC;AAC1B,QAAM,aAAa,2BAA2B,MAAM,CAAC,CAAC;AACtD,MAAI,CAAC,cAAc,CAAC,WAAY,QAAO;AACvC,SAAO,GAAG,UAAU,IAAI,UAAU;AACpC;AAEO,SAAS,sBAAsB,UAAkB,SAA8B;AACpF,QAAM,MAAM,oBAAI,IAAY;AAC5B,QAAM,SAAS,CAAC,UAAU,GAAI,WAAW,CAAC,CAAE;AAC5C,aAAW,aAAa,QAAQ;AAC9B,UAAM,YAAY,wBAAwB,SAAS;AACnD,QAAI,UAAW,KAAI,IAAI,SAAS;AAAA,EAClC;AACA,MAAI,CAAC,IAAI,KAAM,QAAO,CAAC;AACvB,SAAO,MAAM,KAAK,GAAG;AACvB;AAEA,eAAsB,oBACpB,WACA,UACA,aACA,gBACA,QACA,SACe;AACf,MAAI,CAAC,mBAAmB,EAAG;AAC3B,QAAM,QAAQ,iBAAiB,SAAS;AACxC,MAAI,CAAC,SAAS,OAAO,MAAM,iBAAiB,WAAY;AACxD,QAAM,YAAY,sBAAsB,UAAU,OAAO;AACzD,QAAM,WAAW,YAAY,YAAY,kBAAkB;AAC3D,QAAM,WAAW,yBAAyB,YAAY,EAAE;AACxD,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,OAAO,WAAW;AAC3B,QAAI,UAAU;AACZ,WAAK,IAAI,eAAe,KAAK,UAAU,QAAQ,CAAC;AAAA,IAClD;AACA,UAAM,kBAAwC,CAAC;AAC/C,QAAI,YAAY,mBAAmB,QAAW;AAC5C,sBAAgB,KAAK,YAAY,kBAAkB,IAAI;AAAA,IACzD;AACA,QAAI,CAAC,gBAAgB,OAAQ,iBAAgB,KAAK,IAAI;AACtD,eAAW,OAAO,oBAAoB,KAAK,UAAU,eAAe,GAAG;AACrE,WAAK,IAAI,GAAG;AAAA,IACd;AAAA,EACF;AACA,MAAI,CAAC,KAAK,KAAM;AAChB,QAAM,UAAU,MAAM,KAAK,IAAI;AAC/B,iBAAe,cAAc;AAAA,IAC3B;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,UAAU,YAAY;AAAA,IACtB,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,UAAU,MAAM,mBAAmB,UAAU,MAAM,MAAM,aAAa,OAAO,CAAC;AACpF,iBAAe,cAAc;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,UAAU,YAAY;AAAA,IACtB,MAAM;AAAA,IACN,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,4 @@
1
- const APP_VERSION = "0.5.1-develop.2756.cce1739df3";
1
+ const APP_VERSION = "0.5.1-develop.2762.90c271efe2";
2
2
  const appVersion = APP_VERSION;
3
3
  export {
4
4
  APP_VERSION,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/version.ts"],
4
- "sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.5.1-develop.2756.cce1739df3'\nexport const appVersion = APP_VERSION\n"],
4
+ "sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.5.1-develop.2762.90c271efe2'\nexport const appVersion = APP_VERSION\n"],
5
5
  "mappings": "AACO,MAAM,cAAc;AACpB,MAAM,aAAa;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/shared",
3
- "version": "0.5.1-develop.2756.cce1739df3",
3
+ "version": "0.5.1-develop.2762.90c271efe2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -92,6 +92,7 @@
92
92
  "@mikro-orm/core": "^7.0.10",
93
93
  "@mikro-orm/decorators": "^7.0.10",
94
94
  "@mikro-orm/postgresql": "^7.0.10",
95
+ "@open-mercato/cache": "0.5.1-develop.2762.90c271efe2",
95
96
  "dotenv": "^17.4.2",
96
97
  "rate-limiter-flexible": "^11.0.1",
97
98
  "reflect-metadata": "^0.2.2",
@@ -1,5 +1,5 @@
1
1
  import type { AwilixContainer } from 'awilix'
2
- import type { CacheStrategy } from '@open-mercato/cache'
2
+ import { runWithCacheTenant, type CacheStrategy } from '@open-mercato/cache'
3
3
  import { parseBooleanToken } from '../boolean'
4
4
 
5
5
  export type CrudCacheIdentifiers = {
@@ -193,7 +193,7 @@ export async function invalidateCrudCache(
193
193
  tags: tagList,
194
194
  action: 'clearing',
195
195
  })
196
- const deleted = await cache.deleteByTags(tagList)
196
+ const deleted = await runWithCacheTenant(tenantId, () => cache.deleteByTags(tagList))
197
197
  debugCrudCache('invalidate', {
198
198
  resource,
199
199
  reason,