@open-mercato/core 0.6.4-develop.4000.1.450e315cec → 0.6.4-develop.4011.1.4f3ed9ae3e

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 (47) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/backend/users/[id]/edit/page.js +70 -57
  3. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  4. package/dist/modules/catalog/acl.js +30 -5
  5. package/dist/modules/catalog/acl.js.map +2 -2
  6. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +17 -5
  7. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  8. package/dist/modules/catalog/commands/offers.js +26 -7
  9. package/dist/modules/catalog/commands/offers.js.map +2 -2
  10. package/dist/modules/catalog/commands/prices.js +41 -26
  11. package/dist/modules/catalog/commands/prices.js.map +2 -2
  12. package/dist/modules/catalog/commands/productUnitConversions.js +7 -1
  13. package/dist/modules/catalog/commands/productUnitConversions.js.map +2 -2
  14. package/dist/modules/catalog/commands/products.js +2 -0
  15. package/dist/modules/catalog/commands/products.js.map +2 -2
  16. package/dist/modules/catalog/commands/shared.js +58 -11
  17. package/dist/modules/catalog/commands/shared.js.map +2 -2
  18. package/dist/modules/catalog/commands/variants.js +18 -5
  19. package/dist/modules/catalog/commands/variants.js.map +2 -2
  20. package/dist/modules/resources/backend/resources/resources/[id]/page.js +17 -2
  21. package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
  22. package/dist/modules/sales/backend/sales/documents/[id]/page.js +20 -1
  23. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  24. package/package.json +7 -7
  25. package/src/modules/auth/backend/users/[id]/edit/page.tsx +28 -6
  26. package/src/modules/auth/i18n/de.json +1 -0
  27. package/src/modules/auth/i18n/en.json +1 -0
  28. package/src/modules/auth/i18n/es.json +1 -0
  29. package/src/modules/auth/i18n/pl.json +1 -0
  30. package/src/modules/catalog/acl.ts +30 -5
  31. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +21 -5
  32. package/src/modules/catalog/commands/offers.ts +26 -7
  33. package/src/modules/catalog/commands/prices.ts +41 -26
  34. package/src/modules/catalog/commands/productUnitConversions.ts +7 -1
  35. package/src/modules/catalog/commands/products.ts +2 -0
  36. package/src/modules/catalog/commands/shared.ts +70 -6
  37. package/src/modules/catalog/commands/variants.ts +18 -5
  38. package/src/modules/catalog/i18n/de.json +1 -0
  39. package/src/modules/catalog/i18n/en.json +1 -0
  40. package/src/modules/catalog/i18n/es.json +1 -0
  41. package/src/modules/catalog/i18n/pl.json +1 -0
  42. package/src/modules/resources/backend/resources/resources/[id]/page.tsx +21 -2
  43. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +28 -1
  44. package/src/modules/sales/i18n/de.json +3 -0
  45. package/src/modules/sales/i18n/en.json +3 -0
  46. package/src/modules/sales/i18n/es.json +3 -0
  47. package/src/modules/sales/i18n/pl.json +3 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/catalog/commands/shared.ts"],
4
- "sourcesContent": ["import {\n CatalogProduct,\n CatalogOffer,\n CatalogProductVariant,\n CatalogOptionSchemaTemplate,\n CatalogPriceKind,\n} from '../data/entities'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nexport { ensureOrganizationScope, ensureSameScope, ensureTenantScope } from '@open-mercato/shared/lib/commands/scope'\nexport { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'\n\ntype QueryIndexCrudAction = 'created' | 'updated' | 'deleted'\n\nexport function ensureSameTenant(entity: Pick<{ tenantId: string }, 'tenantId'>, tenantId: string): void {\n if (entity.tenantId !== tenantId) {\n throw new CrudHttpError(403, { error: 'Cross-tenant relation forbidden' })\n }\n}\n\nexport { assertFound } from '@open-mercato/shared/lib/crud/errors'\n\nexport function cloneJson<T>(value: T): T {\n if (value === null || value === undefined) return value\n return JSON.parse(JSON.stringify(value)) as T\n}\n\nconst OPTION_SCHEMA_CODE_MAX_LENGTH = 150\n\nexport function randomSuffix(length = 6): string {\n return Math.random().toString(36).slice(2, 2 + length)\n}\n\nexport function normalizeOptionSchemaCode(value?: string | null): string {\n if (!value || typeof value !== 'string') return ''\n const ascii = value.normalize('NFKD').replace(/[\\u0300-\\u036f]/g, '')\n const slug = ascii\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9\\-_]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/(?:^-+|-+$)/g, '')\n return slug.slice(0, OPTION_SCHEMA_CODE_MAX_LENGTH)\n}\n\nexport function resolveOptionSchemaCode(opts: {\n code?: string | null\n name?: string | null\n fallback?: string | null\n uniqueHint?: string | null\n}): string {\n const baseCandidate =\n normalizeOptionSchemaCode(opts.code) ||\n normalizeOptionSchemaCode(opts.name) ||\n normalizeOptionSchemaCode(opts.fallback)\n let resolved = baseCandidate || ''\n if (!resolved) {\n resolved = `schema-${randomSuffix()}`\n }\n if (opts.uniqueHint) {\n const hinted = normalizeOptionSchemaCode(`${resolved}-${opts.uniqueHint}`)\n if (hinted) {\n resolved = hinted\n }\n }\n return resolved || `schema-${randomSuffix()}`\n}\n\nexport function toNumericString(value: number | null | undefined): string | null {\n if (value === undefined || value === null) return null\n return value.toString()\n}\n\nexport async function requireProduct(\n em: EntityManager,\n id: string,\n message = 'Catalog product not found'\n): Promise<CatalogProduct> {\n const product = await findOneWithDecryption(em, CatalogProduct, { id, deletedAt: null })\n if (!product) throw new CrudHttpError(404, { error: message })\n return product\n}\n\nexport async function requireVariant(\n em: EntityManager,\n id: string,\n message = 'Catalog variant not found'\n): Promise<CatalogProductVariant> {\n const variant = await findOneWithDecryption(\n em,\n CatalogProductVariant,\n { id, deletedAt: null },\n { populate: ['product'] },\n )\n if (!variant) throw new CrudHttpError(404, { error: message })\n return variant\n}\n\nexport async function requireOffer(\n em: EntityManager,\n id: string,\n message = 'Catalog offer not found'\n): Promise<CatalogOffer> {\n const offer = await findOneWithDecryption(em, CatalogOffer, { id })\n if (!offer) throw new CrudHttpError(404, { error: message })\n return offer\n}\n\nexport async function requirePriceKind(\n em: EntityManager,\n id: string,\n message = 'Catalog price kind not found'\n): Promise<CatalogPriceKind> {\n const priceKind = await findOneWithDecryption(em, CatalogPriceKind, { id, deletedAt: null })\n if (!priceKind) throw new CrudHttpError(404, { error: message })\n return priceKind\n}\n\nexport async function requireOptionSchemaTemplate(\n em: EntityManager,\n id: string,\n message = 'Option schema not found'\n): Promise<CatalogOptionSchemaTemplate> {\n const schema = await findOneWithDecryption(em, CatalogOptionSchemaTemplate, { id, deletedAt: null })\n if (!schema) throw new CrudHttpError(404, { error: message })\n return schema\n}\n\nexport function getErrorConstraint(error: unknown): string | null {\n const errObj = error as { constraint?: unknown; message?: unknown }\n if (typeof errObj.constraint === 'string') return errObj.constraint\n if (typeof errObj.message === 'string') {\n return null\n }\n return null\n}\n\nexport function getErrorMessage(error: unknown): string {\n const errObj = error as { message?: unknown }\n return typeof errObj.message === 'string' ? errObj.message : ''\n}\n\nexport async function emitCatalogQueryIndexEvent(\n ctx: CommandRuntimeContext,\n params: {\n entityType: string\n recordId: string\n organizationId?: string | null\n tenantId?: string | null\n action: QueryIndexCrudAction\n coverageBaseDelta?: number\n },\n): Promise<void> {\n const entityType = String(params.entityType || '')\n const recordId = String(params.recordId || '')\n if (!entityType || !recordId) return\n\n let bus: { emitEvent: (event: string, payload: Record<string, unknown>, options?: Record<string, unknown>) => Promise<void> } | null = null\n try {\n bus = ctx.container.resolve('eventBus')\n } catch {\n bus = null\n }\n if (!bus?.emitEvent) return\n\n const payload: Record<string, unknown> = {\n entityType,\n recordId,\n organizationId: params.organizationId ?? null,\n tenantId: params.tenantId ?? null,\n crudAction: params.action,\n }\n if (params.coverageBaseDelta !== undefined) {\n payload.coverageBaseDelta = params.coverageBaseDelta\n } else if (params.action === 'created') {\n payload.coverageBaseDelta = 1\n } else if (params.action === 'deleted') {\n payload.coverageBaseDelta = -1\n }\n\n const eventName = params.action === 'deleted' ? 'query_index.delete_one' : 'query_index.upsert_one'\n await bus.emitEvent(eventName, payload, {\n tenantId: params.tenantId ?? null,\n organizationId: params.organizationId ?? null,\n }).catch(() => undefined)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n CatalogProduct,\n CatalogOffer,\n CatalogProductVariant,\n CatalogOptionSchemaTemplate,\n CatalogPriceKind,\n} from '../data/entities'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nexport { ensureOrganizationScope, ensureSameScope, ensureTenantScope } from '@open-mercato/shared/lib/commands/scope'\nexport { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'\n\ntype QueryIndexCrudAction = 'created' | 'updated' | 'deleted'\n\nexport function ensureSameTenant(entity: Pick<{ tenantId: string }, 'tenantId'>, tenantId: string): void {\n if (entity.tenantId !== tenantId) {\n throw new CrudHttpError(403, { error: 'Cross-tenant relation forbidden' })\n }\n}\n\nexport { assertFound } from '@open-mercato/shared/lib/crud/errors'\n\nexport function cloneJson<T>(value: T): T {\n if (value === null || value === undefined) return value\n return JSON.parse(JSON.stringify(value)) as T\n}\n\nconst OPTION_SCHEMA_CODE_MAX_LENGTH = 150\n\nexport function randomSuffix(length = 6): string {\n return Math.random().toString(36).slice(2, 2 + length)\n}\n\nexport function normalizeOptionSchemaCode(value?: string | null): string {\n if (!value || typeof value !== 'string') return ''\n const ascii = value.normalize('NFKD').replace(/[\\u0300-\\u036f]/g, '')\n const slug = ascii\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9\\-_]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/(?:^-+|-+$)/g, '')\n return slug.slice(0, OPTION_SCHEMA_CODE_MAX_LENGTH)\n}\n\nexport function resolveOptionSchemaCode(opts: {\n code?: string | null\n name?: string | null\n fallback?: string | null\n uniqueHint?: string | null\n}): string {\n const baseCandidate =\n normalizeOptionSchemaCode(opts.code) ||\n normalizeOptionSchemaCode(opts.name) ||\n normalizeOptionSchemaCode(opts.fallback)\n let resolved = baseCandidate || ''\n if (!resolved) {\n resolved = `schema-${randomSuffix()}`\n }\n if (opts.uniqueHint) {\n const hinted = normalizeOptionSchemaCode(`${resolved}-${opts.uniqueHint}`)\n if (hinted) {\n resolved = hinted\n }\n }\n return resolved || `schema-${randomSuffix()}`\n}\n\nexport function toNumericString(value: number | null | undefined): string | null {\n if (value === undefined || value === null) return null\n return value.toString()\n}\n\nexport type RequireScope = {\n tenantId: string | null\n organizationId: string | null\n}\n\n// Derives the actor's effective tenant/org scope for entry-point lookups, mirroring\n// the bypass semantics of ensureTenantScope/ensureOrganizationScope: tenant is always\n// strict, organization is left unrestricted for super-admins and global-org actors.\nexport function commandActorScope(ctx: CommandRuntimeContext): RequireScope {\n const orgUnrestricted = ctx.auth?.isSuperAdmin === true || ctx.organizationScope?.allowedIds === null\n return {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: orgUnrestricted ? null : (ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null),\n }\n}\n\nfunction applyScopeToWhere(where: Record<string, unknown>, scope: RequireScope): void {\n if (scope.tenantId != null) where.tenantId = scope.tenantId\n if (scope.organizationId != null) where.organizationId = scope.organizationId\n}\n\nexport async function requireProduct(\n em: EntityManager,\n id: string,\n scope: RequireScope,\n message = 'Catalog product not found'\n): Promise<CatalogProduct> {\n const where: Record<string, unknown> = { id, deletedAt: null }\n applyScopeToWhere(where, scope)\n const product = await findOneWithDecryption(\n em,\n CatalogProduct,\n where as FilterQuery<CatalogProduct>,\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n if (!product) throw new CrudHttpError(404, { error: message })\n return product\n}\n\nexport async function requireVariant(\n em: EntityManager,\n id: string,\n scope: RequireScope,\n message = 'Catalog variant not found'\n): Promise<CatalogProductVariant> {\n const where: Record<string, unknown> = { id, deletedAt: null }\n applyScopeToWhere(where, scope)\n const variant = await findOneWithDecryption(\n em,\n CatalogProductVariant,\n where as FilterQuery<CatalogProductVariant>,\n { populate: ['product'] },\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n if (!variant) throw new CrudHttpError(404, { error: message })\n return variant\n}\n\nexport async function requireOffer(\n em: EntityManager,\n id: string,\n scope: RequireScope,\n message = 'Catalog offer not found'\n): Promise<CatalogOffer> {\n const where: Record<string, unknown> = { id }\n applyScopeToWhere(where, scope)\n const offer = await findOneWithDecryption(\n em,\n CatalogOffer,\n where as FilterQuery<CatalogOffer>,\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n if (!offer) throw new CrudHttpError(404, { error: message })\n return offer\n}\n\nexport async function requirePriceKind(\n em: EntityManager,\n id: string,\n scope: RequireScope,\n message = 'Catalog price kind not found'\n): Promise<CatalogPriceKind> {\n // Price kinds are tenant-global: organization_id is always null and the unique key is\n // (tenant_id, code). Scope by tenant only \u2014 applying a concrete org would never match the\n // null row. Tenant scoping still closes the cross-tenant read hole this helper guards.\n const where: Record<string, unknown> = { id, deletedAt: null }\n applyScopeToWhere(where, { tenantId: scope.tenantId, organizationId: null })\n const priceKind = await findOneWithDecryption(\n em,\n CatalogPriceKind,\n where as FilterQuery<CatalogPriceKind>,\n undefined,\n { tenantId: scope.tenantId, organizationId: null },\n )\n if (!priceKind) throw new CrudHttpError(404, { error: message })\n return priceKind\n}\n\nexport async function requireOptionSchemaTemplate(\n em: EntityManager,\n id: string,\n scope: RequireScope,\n message = 'Option schema not found'\n): Promise<CatalogOptionSchemaTemplate> {\n const where: Record<string, unknown> = { id, deletedAt: null }\n applyScopeToWhere(where, scope)\n const schema = await findOneWithDecryption(\n em,\n CatalogOptionSchemaTemplate,\n where as FilterQuery<CatalogOptionSchemaTemplate>,\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n if (!schema) throw new CrudHttpError(404, { error: message })\n return schema\n}\n\nexport function getErrorConstraint(error: unknown): string | null {\n const errObj = error as { constraint?: unknown; message?: unknown }\n if (typeof errObj.constraint === 'string') return errObj.constraint\n if (typeof errObj.message === 'string') {\n return null\n }\n return null\n}\n\nexport function getErrorMessage(error: unknown): string {\n const errObj = error as { message?: unknown }\n return typeof errObj.message === 'string' ? errObj.message : ''\n}\n\nexport async function emitCatalogQueryIndexEvent(\n ctx: CommandRuntimeContext,\n params: {\n entityType: string\n recordId: string\n organizationId?: string | null\n tenantId?: string | null\n action: QueryIndexCrudAction\n coverageBaseDelta?: number\n },\n): Promise<void> {\n const entityType = String(params.entityType || '')\n const recordId = String(params.recordId || '')\n if (!entityType || !recordId) return\n\n let bus: { emitEvent: (event: string, payload: Record<string, unknown>, options?: Record<string, unknown>) => Promise<void> } | null = null\n try {\n bus = ctx.container.resolve('eventBus')\n } catch {\n bus = null\n }\n if (!bus?.emitEvent) return\n\n const payload: Record<string, unknown> = {\n entityType,\n recordId,\n organizationId: params.organizationId ?? null,\n tenantId: params.tenantId ?? null,\n crudAction: params.action,\n }\n if (params.coverageBaseDelta !== undefined) {\n payload.coverageBaseDelta = params.coverageBaseDelta\n } else if (params.action === 'created') {\n payload.coverageBaseDelta = 1\n } else if (params.action === 'deleted') {\n payload.coverageBaseDelta = -1\n }\n\n const eventName = params.action === 'deleted' ? 'query_index.delete_one' : 'query_index.upsert_one'\n await bus.emitEvent(eventName, payload, {\n tenantId: params.tenantId ?? null,\n organizationId: params.organizationId ?? null,\n }).catch(() => undefined)\n}\n"],
5
+ "mappings": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,qBAAqB;AAE9B,SAAS,6BAA6B;AACtC,SAAS,yBAAyB,iBAAiB,yBAAyB;AAC5E,SAAS,0BAA0B;AAI5B,SAAS,iBAAiB,QAAgD,UAAwB;AACvG,MAAI,OAAO,aAAa,UAAU;AAChC,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,kCAAkC,CAAC;AAAA,EAC3E;AACF;AAEA,SAAS,mBAAmB;AAErB,SAAS,UAAa,OAAa;AACxC,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,SAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AACzC;AAEA,MAAM,gCAAgC;AAE/B,SAAS,aAAa,SAAS,GAAW;AAC/C,SAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,IAAI,MAAM;AACvD;AAEO,SAAS,0BAA0B,OAA+B;AACvE,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,QAAQ,MAAM,UAAU,MAAM,EAAE,QAAQ,oBAAoB,EAAE;AACpE,QAAM,OAAO,MACV,YAAY,EACZ,KAAK,EACL,QAAQ,kBAAkB,GAAG,EAC7B,QAAQ,OAAO,GAAG,EAClB,QAAQ,gBAAgB,EAAE;AAC7B,SAAO,KAAK,MAAM,GAAG,6BAA6B;AACpD;AAEO,SAAS,wBAAwB,MAK7B;AACT,QAAM,gBACJ,0BAA0B,KAAK,IAAI,KACnC,0BAA0B,KAAK,IAAI,KACnC,0BAA0B,KAAK,QAAQ;AACzC,MAAI,WAAW,iBAAiB;AAChC,MAAI,CAAC,UAAU;AACb,eAAW,UAAU,aAAa,CAAC;AAAA,EACrC;AACA,MAAI,KAAK,YAAY;AACnB,UAAM,SAAS,0BAA0B,GAAG,QAAQ,IAAI,KAAK,UAAU,EAAE;AACzE,QAAI,QAAQ;AACV,iBAAW;AAAA,IACb;AAAA,EACF;AACA,SAAO,YAAY,UAAU,aAAa,CAAC;AAC7C;AAEO,SAAS,gBAAgB,OAAiD;AAC/E,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,SAAO,MAAM,SAAS;AACxB;AAUO,SAAS,kBAAkB,KAA0C;AAC1E,QAAM,kBAAkB,IAAI,MAAM,iBAAiB,QAAQ,IAAI,mBAAmB,eAAe;AACjG,SAAO;AAAA,IACL,UAAU,IAAI,MAAM,YAAY;AAAA,IAChC,gBAAgB,kBAAkB,OAAQ,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,EAC7F;AACF;AAEA,SAAS,kBAAkB,OAAgC,OAA2B;AACpF,MAAI,MAAM,YAAY,KAAM,OAAM,WAAW,MAAM;AACnD,MAAI,MAAM,kBAAkB,KAAM,OAAM,iBAAiB,MAAM;AACjE;AAEA,eAAsB,eACpB,IACA,IACA,OACA,UAAU,6BACe;AACzB,QAAM,QAAiC,EAAE,IAAI,WAAW,KAAK;AAC7D,oBAAkB,OAAO,KAAK;AAC9B,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,EACnE;AACA,MAAI,CAAC,QAAS,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC7D,SAAO;AACT;AAEA,eAAsB,eACpB,IACA,IACA,OACA,UAAU,6BACsB;AAChC,QAAM,QAAiC,EAAE,IAAI,WAAW,KAAK;AAC7D,oBAAkB,OAAO,KAAK;AAC9B,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,IACxB,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,EACnE;AACA,MAAI,CAAC,QAAS,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC7D,SAAO;AACT;AAEA,eAAsB,aACpB,IACA,IACA,OACA,UAAU,2BACa;AACvB,QAAM,QAAiC,EAAE,GAAG;AAC5C,oBAAkB,OAAO,KAAK;AAC9B,QAAM,QAAQ,MAAM;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,EACnE;AACA,MAAI,CAAC,MAAO,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC3D,SAAO;AACT;AAEA,eAAsB,iBACpB,IACA,IACA,OACA,UAAU,gCACiB;AAI3B,QAAM,QAAiC,EAAE,IAAI,WAAW,KAAK;AAC7D,oBAAkB,OAAO,EAAE,UAAU,MAAM,UAAU,gBAAgB,KAAK,CAAC;AAC3E,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,KAAK;AAAA,EACnD;AACA,MAAI,CAAC,UAAW,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC/D,SAAO;AACT;AAEA,eAAsB,4BACpB,IACA,IACA,OACA,UAAU,2BAC4B;AACtC,QAAM,QAAiC,EAAE,IAAI,WAAW,KAAK;AAC7D,oBAAkB,OAAO,KAAK;AAC9B,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,EACnE;AACA,MAAI,CAAC,OAAQ,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC5D,SAAO;AACT;AAEO,SAAS,mBAAmB,OAA+B;AAChE,QAAM,SAAS;AACf,MAAI,OAAO,OAAO,eAAe,SAAU,QAAO,OAAO;AACzD,MAAI,OAAO,OAAO,YAAY,UAAU;AACtC,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,gBAAgB,OAAwB;AACtD,QAAM,SAAS;AACf,SAAO,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU;AAC/D;AAEA,eAAsB,2BACpB,KACA,QAQe;AACf,QAAM,aAAa,OAAO,OAAO,cAAc,EAAE;AACjD,QAAM,WAAW,OAAO,OAAO,YAAY,EAAE;AAC7C,MAAI,CAAC,cAAc,CAAC,SAAU;AAE9B,MAAI,MAAmI;AACvI,MAAI;AACF,UAAM,IAAI,UAAU,QAAQ,UAAU;AAAA,EACxC,QAAQ;AACN,UAAM;AAAA,EACR;AACA,MAAI,CAAC,KAAK,UAAW;AAErB,QAAM,UAAmC;AAAA,IACvC;AAAA,IACA;AAAA,IACA,gBAAgB,OAAO,kBAAkB;AAAA,IACzC,UAAU,OAAO,YAAY;AAAA,IAC7B,YAAY,OAAO;AAAA,EACrB;AACA,MAAI,OAAO,sBAAsB,QAAW;AAC1C,YAAQ,oBAAoB,OAAO;AAAA,EACrC,WAAW,OAAO,WAAW,WAAW;AACtC,YAAQ,oBAAoB;AAAA,EAC9B,WAAW,OAAO,WAAW,WAAW;AACtC,YAAQ,oBAAoB;AAAA,EAC9B;AAEA,QAAM,YAAY,OAAO,WAAW,YAAY,2BAA2B;AAC3E,QAAM,IAAI,UAAU,WAAW,SAAS;AAAA,IACtC,UAAU,OAAO,YAAY;AAAA,IAC7B,gBAAgB,OAAO,kBAAkB;AAAA,EAC3C,CAAC,EAAE,MAAM,MAAM,MAAS;AAC1B;",
6
6
  "names": []
7
7
  }
@@ -20,6 +20,7 @@ import {
20
20
  } from "../data/validators.js";
21
21
  import {
22
22
  cloneJson,
23
+ commandActorScope,
23
24
  ensureOrganizationScope,
24
25
  ensureTenantScope,
25
26
  emitCatalogQueryIndexEvent,
@@ -199,7 +200,10 @@ async function loadVariantPriceSnapshots(em, variantId, scope) {
199
200
  }
200
201
  async function restoreVariantPricesFromSnapshots(em, variant, snapshots, dataEngine) {
201
202
  if (!snapshots.length) return;
202
- const productRef = typeof variant.product === "string" ? await requireProduct(em, variant.product) : variant.product;
203
+ const productRef = typeof variant.product === "string" ? await requireProduct(em, variant.product, {
204
+ tenantId: variant.tenantId,
205
+ organizationId: variant.organizationId
206
+ }) : variant.product;
203
207
  for (const snapshot of snapshots) {
204
208
  const product = snapshot.productId && snapshot.productId !== productRef.id ? em.getReference(CatalogProduct, snapshot.productId) : productRef;
205
209
  const offer = snapshot.offerId ? em.getReference(CatalogOffer, snapshot.offerId) : null;
@@ -399,7 +403,7 @@ const createVariantCommand = {
399
403
  async execute(rawInput, ctx) {
400
404
  const { parsed, custom } = parseWithCustomFields(variantCreateSchema, rawInput);
401
405
  const em = ctx.container.resolve("em").fork();
402
- const product = await requireProduct(em, parsed.productId);
406
+ const product = await requireProduct(em, parsed.productId, commandActorScope(ctx));
403
407
  ensureTenantScope(ctx, product.tenantId);
404
408
  ensureOrganizationScope(ctx, product.organizationId);
405
409
  const { taxRateId, taxRate } = await resolveVariantTaxRate(
@@ -553,7 +557,10 @@ const updateVariantCommand = {
553
557
  if (!record) throw new CrudHttpError(404, { error: "Catalog variant not found" });
554
558
  ensureTenantScope(ctx, record.tenantId);
555
559
  ensureOrganizationScope(ctx, record.organizationId);
556
- const product = await requireProduct(em, record.product.id);
560
+ const product = await requireProduct(em, record.product.id, {
561
+ tenantId: record.tenantId,
562
+ organizationId: record.organizationId
563
+ });
557
564
  if (!product) throw new CrudHttpError(400, { error: "Variant product missing" });
558
565
  const taxRateProvided = parsed.taxRateId !== void 0 || parsed.taxRate !== void 0;
559
566
  const resolvedTaxRate = taxRateProvided ? await resolveVariantTaxRate(em, product, parsed.taxRateId ?? null, parsed.taxRate) : null;
@@ -668,7 +675,10 @@ const updateVariantCommand = {
668
675
  const em = ctx.container.resolve("em").fork();
669
676
  let record = await em.findOne(CatalogProductVariant, { id: before.id });
670
677
  if (!record) {
671
- const product = await requireProduct(em, before.productId);
678
+ const product = await requireProduct(em, before.productId, {
679
+ tenantId: before.tenantId,
680
+ organizationId: before.organizationId
681
+ });
672
682
  record = em.create(CatalogProductVariant, {
673
683
  id: before.id,
674
684
  product,
@@ -826,7 +836,10 @@ const deleteVariantCommand = {
826
836
  const em = ctx.container.resolve("em").fork();
827
837
  let record = await em.findOne(CatalogProductVariant, { id: before.id });
828
838
  if (!record) {
829
- const product = await requireProduct(em, before.productId);
839
+ const product = await requireProduct(em, before.productId, {
840
+ tenantId: before.tenantId,
841
+ organizationId: before.organizationId
842
+ });
830
843
  record = em.create(CatalogProductVariant, {
831
844
  id: before.id,
832
845
  product,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/catalog/commands/variants.ts"],
4
- "sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { buildChanges, requireId, parseWithCustomFields, setCustomFieldsIfAny, emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { UniqueConstraintViolationException } from '@mikro-orm/core'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { loadCustomFieldSnapshot, buildCustomFieldResetMap } from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { E } from '#generated/entities.ids.generated'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n CatalogProductVariant,\n CatalogProductPrice,\n CatalogProduct,\n CatalogOffer,\n CatalogPriceKind,\n} from '../data/entities'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { Attachment } from '@open-mercato/core/modules/attachments/data/entities'\nimport {\n variantCreateSchema,\n variantUpdateSchema,\n type VariantCreateInput,\n type VariantUpdateInput,\n} from '../data/validators'\nimport {\n cloneJson,\n ensureOrganizationScope,\n ensureTenantScope,\n emitCatalogQueryIndexEvent,\n extractUndoPayload,\n requireProduct,\n toNumericString,\n getErrorConstraint,\n getErrorMessage,\n} from './shared'\nimport { SalesTaxRate } from '@open-mercato/core/modules/sales/data/entities'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\n\nconst variantCrudEvents: CrudEventsConfig = {\n module: 'catalog',\n entity: 'variant',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\ntype VariantSnapshot = {\n id: string\n productId: string\n organizationId: string\n tenantId: string\n name: string | null\n sku: string | null\n barcode: string | null\n statusEntryId: string | null\n isDefault: boolean\n isActive: boolean\n weightValue: string | null\n weightUnit: string | null\n taxRateId: string | null\n taxRate: string | null\n dimensions: Record<string, unknown> | null\n metadata: Record<string, unknown> | null\n optionValues: Record<string, string> | null\n customFieldsetCode: string | null\n createdAt: string\n updatedAt: string\n custom: Record<string, unknown> | null\n prices?: VariantPriceSnapshot[] | null\n}\n\ntype VariantUndoPayload = {\n before?: VariantSnapshot | null\n after?: VariantSnapshot | null\n previousDefaultVariantId?: string | null\n}\n\nconst VARIANT_CHANGE_KEYS = [\n 'name',\n 'sku',\n 'barcode',\n 'statusEntryId',\n 'isDefault',\n 'isActive',\n 'weightValue',\n 'weightUnit',\n 'taxRateId',\n 'taxRate',\n 'dimensions',\n 'optionValues',\n 'customFieldsetCode',\n 'metadata',\n] as const satisfies readonly string[]\n\nasync function loadVariantSnapshot(\n em: EntityManager,\n id: string,\n options: { includePrices?: boolean } = {}\n): Promise<VariantSnapshot | null> {\n const record = await em.findOne(CatalogProductVariant, { id, deletedAt: null })\n if (!record) return null\n const prices = options.includePrices\n ? await loadVariantPriceSnapshots(em, record.id, {\n tenantId: record.tenantId,\n organizationId: record.organizationId,\n })\n : null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.catalog.catalog_product_variant,\n recordId: record.id,\n tenantId: record.tenantId,\n organizationId: record.organizationId,\n })\n const productId = typeof record.product === 'string' ? record.product : record.product.id\n return {\n id: record.id,\n productId,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n name: record.name ?? null,\n sku: record.sku ?? null,\n barcode: record.barcode ?? null,\n statusEntryId: record.statusEntryId ?? null,\n isDefault: record.isDefault,\n isActive: record.isActive,\n weightValue: record.weightValue ?? null,\n weightUnit: record.weightUnit ?? null,\n taxRateId: record.taxRateId ?? null,\n taxRate: record.taxRate ?? null,\n dimensions: record.dimensions ? cloneJson(record.dimensions) : null,\n metadata: record.metadata ? cloneJson(record.metadata) : null,\n optionValues: record.optionValues ? cloneJson(record.optionValues) : null,\n customFieldsetCode: record.customFieldsetCode ?? null,\n createdAt: record.createdAt.toISOString(),\n updatedAt: record.updatedAt.toISOString(),\n custom: Object.keys(custom).length ? custom : null,\n prices: prices && prices.length ? prices : null,\n }\n}\n\nfunction applyVariantSnapshot(record: CatalogProductVariant, snapshot: VariantSnapshot): void {\n record.organizationId = snapshot.organizationId\n record.tenantId = snapshot.tenantId\n record.name = snapshot.name ?? null\n record.sku = snapshot.sku ?? null\n record.barcode = snapshot.barcode ?? null\n record.statusEntryId = snapshot.statusEntryId ?? null\n record.isDefault = snapshot.isDefault\n record.isActive = snapshot.isActive\n record.weightValue = snapshot.weightValue ?? null\n record.weightUnit = snapshot.weightUnit ?? null\n record.taxRateId = snapshot.taxRateId ?? null\n record.taxRate = snapshot.taxRate ?? null\n record.dimensions = snapshot.dimensions ? cloneJson(snapshot.dimensions) : null\n record.metadata = snapshot.metadata ? cloneJson(snapshot.metadata) : null\n record.optionValues = snapshot.optionValues ? cloneJson(snapshot.optionValues) : null\n record.customFieldsetCode = snapshot.customFieldsetCode ?? null\n record.createdAt = new Date(snapshot.createdAt)\n record.updatedAt = new Date(snapshot.updatedAt)\n}\n\nasync function resolveVariantTaxRate(\n em: EntityManager,\n product: CatalogProduct,\n taxRateIdInput: string | null | undefined,\n taxRateInput: number | string | null | undefined\n): Promise<{ taxRateId: string | null; taxRate: string | null }> {\n const organizationId = product.organizationId\n const tenantId = product.tenantId\n const normalizedRate =\n taxRateInput === null || taxRateInput === undefined\n ? null\n : (() => {\n const numeric = typeof taxRateInput === 'string' ? Number(taxRateInput) : taxRateInput\n return Number.isFinite(numeric) ? toNumericString(numeric) : null\n })()\n if (taxRateIdInput === null) {\n return { taxRateId: product.taxRateId ?? null, taxRate: product.taxRate ?? null }\n }\n if (!taxRateIdInput) {\n return { taxRateId: product.taxRateId ?? null, taxRate: product.taxRate ?? normalizedRate }\n }\n const record = await em.findOne(SalesTaxRate, {\n id: taxRateIdInput,\n organizationId,\n tenantId,\n deletedAt: null,\n })\n if (!record) {\n throw new CrudHttpError(400, { error: 'Tax class not found' })\n }\n return { taxRateId: taxRateIdInput, taxRate: record.rate ?? normalizedRate }\n}\n\ntype VariantPriceSnapshot = {\n id: string\n variantId: string | null\n productId: string | null\n offerId: string | null\n organizationId: string\n tenantId: string\n priceKindId: string\n priceKindCode: string\n currencyCode: string\n kind: string\n minQuantity: number\n maxQuantity: number | null\n unitPriceNet: string | null\n unitPriceGross: string | null\n taxRate: string | null\n taxAmount: string | null\n channelId: string | null\n userId: string | null\n userGroupId: string | null\n customerId: string | null\n customerGroupId: string | null\n metadata: Record<string, unknown> | null\n startsAt: string | null\n endsAt: string | null\n createdAt: string\n updatedAt: string\n custom: Record<string, unknown> | null\n}\n\nasync function loadVariantPriceSnapshots(\n em: EntityManager,\n variantId: string,\n scope: { tenantId: string; organizationId: string }\n): Promise<VariantPriceSnapshot[]> {\n const prices = await findWithDecryption(\n em,\n CatalogProductPrice,\n { variant: variantId, tenantId: scope.tenantId, organizationId: scope.organizationId },\n { populate: ['priceKind', 'product', 'offer'] },\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n const snapshots: VariantPriceSnapshot[] = []\n for (const price of prices) {\n const variantRef = price.variant\n const variantIdValue =\n typeof variantRef === 'string'\n ? variantRef\n : variantRef\n ? variantRef.id\n : null\n const productRef = price.product\n ? price.product\n : typeof price.variant === 'object' && price.variant\n ? price.variant.product\n : null\n const productId =\n typeof productRef === 'string'\n ? productRef\n : productRef\n ? productRef.id\n : null\n const priceKindRef = price.priceKind\n const priceKindId =\n typeof priceKindRef === 'string'\n ? priceKindRef\n : priceKindRef\n ? priceKindRef.id\n : null\n if (!priceKindId) {\n throw new CrudHttpError(400, { error: 'Price is missing price kind metadata.' })\n }\n const priceKindCode =\n typeof priceKindRef === 'object' && priceKindRef ? priceKindRef.code : price.kind\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.catalog.catalog_product_price,\n recordId: price.id,\n tenantId: price.tenantId,\n organizationId: price.organizationId,\n })\n snapshots.push({\n id: price.id,\n variantId: variantIdValue,\n productId,\n offerId: typeof price.offer === 'string' ? price.offer : price.offer ? price.offer.id : null,\n organizationId: price.organizationId,\n tenantId: price.tenantId,\n priceKindId,\n priceKindCode,\n currencyCode: price.currencyCode,\n kind: price.kind,\n minQuantity: price.minQuantity,\n maxQuantity: price.maxQuantity ?? null,\n unitPriceNet: price.unitPriceNet ?? null,\n unitPriceGross: price.unitPriceGross ?? null,\n taxRate: price.taxRate ?? null,\n taxAmount: price.taxAmount ?? null,\n channelId: price.channelId ?? null,\n userId: price.userId ?? null,\n userGroupId: price.userGroupId ?? null,\n customerId: price.customerId ?? null,\n customerGroupId: price.customerGroupId ?? null,\n metadata: price.metadata ? cloneJson(price.metadata) : null,\n startsAt: price.startsAt ? price.startsAt.toISOString() : null,\n endsAt: price.endsAt ? price.endsAt.toISOString() : null,\n createdAt: price.createdAt.toISOString(),\n updatedAt: price.updatedAt.toISOString(),\n custom: Object.keys(custom).length ? custom : null,\n })\n }\n return snapshots\n}\n\nasync function restoreVariantPricesFromSnapshots(\n em: EntityManager,\n variant: CatalogProductVariant,\n snapshots: VariantPriceSnapshot[],\n dataEngine: DataEngine\n): Promise<void> {\n if (!snapshots.length) return\n const productRef =\n typeof variant.product === 'string'\n ? await requireProduct(em, variant.product)\n : variant.product\n for (const snapshot of snapshots) {\n const product =\n snapshot.productId && snapshot.productId !== productRef.id\n ? em.getReference(CatalogProduct, snapshot.productId)\n : productRef\n const offer = snapshot.offerId ? em.getReference(CatalogOffer, snapshot.offerId) : null\n const priceKind = em.getReference(CatalogPriceKind, snapshot.priceKindId)\n let record = await em.findOne(CatalogProductPrice, { id: snapshot.id })\n if (!record) {\n record = em.create(CatalogProductPrice, {\n id: snapshot.id,\n variant,\n product,\n offer,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n currencyCode: snapshot.currencyCode,\n priceKind,\n kind: snapshot.priceKindCode || snapshot.kind,\n minQuantity: snapshot.minQuantity,\n maxQuantity: snapshot.maxQuantity ?? null,\n unitPriceNet: snapshot.unitPriceNet ?? null,\n unitPriceGross: snapshot.unitPriceGross ?? null,\n taxRate: snapshot.taxRate ?? null,\n taxAmount: snapshot.taxAmount ?? null,\n channelId: snapshot.channelId ?? null,\n userId: snapshot.userId ?? null,\n userGroupId: snapshot.userGroupId ?? null,\n customerId: snapshot.customerId ?? null,\n customerGroupId: snapshot.customerGroupId ?? null,\n metadata: snapshot.metadata ? cloneJson(snapshot.metadata) : null,\n startsAt: snapshot.startsAt ? new Date(snapshot.startsAt) : null,\n endsAt: snapshot.endsAt ? new Date(snapshot.endsAt) : null,\n createdAt: new Date(snapshot.createdAt),\n updatedAt: new Date(snapshot.updatedAt),\n })\n em.persist(record)\n } else {\n record.variant = variant\n record.product = product\n record.offer = offer\n record.priceKind = priceKind\n record.organizationId = snapshot.organizationId\n record.tenantId = snapshot.tenantId\n record.currencyCode = snapshot.currencyCode\n record.kind = snapshot.priceKindCode || snapshot.kind\n record.minQuantity = snapshot.minQuantity\n record.maxQuantity = snapshot.maxQuantity ?? null\n record.unitPriceNet = snapshot.unitPriceNet ?? null\n record.unitPriceGross = snapshot.unitPriceGross ?? null\n record.taxRate = snapshot.taxRate ?? null\n record.taxAmount = snapshot.taxAmount ?? null\n record.channelId = snapshot.channelId ?? null\n record.userId = snapshot.userId ?? null\n record.userGroupId = snapshot.userGroupId ?? null\n record.customerId = snapshot.customerId ?? null\n record.customerGroupId = snapshot.customerGroupId ?? null\n record.metadata = snapshot.metadata ? cloneJson(snapshot.metadata) : null\n record.startsAt = snapshot.startsAt ? new Date(snapshot.startsAt) : null\n record.endsAt = snapshot.endsAt ? new Date(snapshot.endsAt) : null\n record.createdAt = new Date(snapshot.createdAt)\n record.updatedAt = new Date(snapshot.updatedAt)\n }\n }\n await em.flush()\n for (const snapshot of snapshots) {\n if (!snapshot.custom || !Object.keys(snapshot.custom).length) continue\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: E.catalog.catalog_product_price,\n recordId: snapshot.id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n values: snapshot.custom,\n })\n }\n}\n\ntype MetadataSplitResult = {\n metadata: Record<string, unknown> | null\n optionValues: Record<string, string> | null\n hadOptionValues: boolean\n}\n\nfunction splitOptionValuesFromMetadata(\n metadata?: Record<string, unknown> | null\n): MetadataSplitResult {\n if (!metadata || typeof metadata !== 'object' || Array.isArray(metadata)) {\n return {\n metadata: metadata ? cloneJson(metadata) : null,\n optionValues: null,\n hadOptionValues: false,\n }\n }\n const { optionValues, ...rest } = metadata as Record<string, unknown> & {\n optionValues?: unknown\n }\n const normalizedMetadata = Object.keys(rest).length ? cloneJson(rest) : null\n return {\n metadata: normalizedMetadata,\n optionValues: normalizeOptionValues(optionValues),\n hadOptionValues: optionValues !== undefined,\n }\n}\n\nfunction normalizeOptionValues(input: unknown): Record<string, string> | null {\n if (!input || typeof input !== 'object' || Array.isArray(input)) return null\n const normalized: Record<string, string> = {}\n for (const [rawKey, rawValue] of Object.entries(input)) {\n if (typeof rawValue !== 'string') continue\n const key = rawKey.trim()\n const value = rawValue.trim()\n if (!key || !value) continue\n normalized[key] = value\n }\n return Object.keys(normalized).length ? normalized : null\n}\n\nfunction resolveProductId(record: CatalogProductVariant): string {\n return typeof record.product === 'string' ? record.product : record.product.id\n}\n\nasync function enforceSingleDefaultVariant(\n em: EntityManager,\n variant: CatalogProductVariant\n): Promise<string | null> {\n if (!variant.isDefault) return null\n const productId = resolveProductId(variant)\n const existingDefault = await em.findOne(\n CatalogProductVariant,\n { product: productId, isDefault: true, deletedAt: null, id: { $ne: variant.id } },\n { fields: ['id', 'isDefault'] }\n )\n if (existingDefault) {\n existingDefault.isDefault = false\n return existingDefault.id\n }\n return null\n}\n\nasync function aggregateVariantMediaToProduct(\n em: EntityManager,\n variant: CatalogProductVariant\n): Promise<void> {\n const productId = resolveProductId(variant)\n const buildKey = (\n attachment: Pick<Attachment, 'fileName' | 'fileSize' | 'storageDriver' | 'partitionCode' | 'storagePath'>\n ) =>\n [\n attachment.fileName?.trim() ?? '',\n attachment.fileSize ?? '',\n attachment.storageDriver ?? '',\n attachment.partitionCode ?? '',\n ].join('|')\n const attachments = await em.find(\n Attachment,\n {\n entityId: E.catalog.catalog_product_variant,\n recordId: variant.id,\n organizationId: variant.organizationId ?? undefined,\n tenantId: variant.tenantId ?? undefined,\n },\n {\n fields: [\n 'id',\n 'partitionCode',\n 'fileName',\n 'mimeType',\n 'fileSize',\n 'storageDriver',\n 'storagePath',\n 'storageMetadata',\n 'url',\n 'organizationId',\n 'tenantId',\n 'fileSize',\n 'storageDriver',\n 'partitionCode',\n ],\n }\n )\n if (!attachments.length) return\n const existing = await em.find(\n Attachment,\n {\n entityId: E.catalog.catalog_product,\n recordId: productId,\n organizationId: variant.organizationId ?? undefined,\n tenantId: variant.tenantId ?? undefined,\n },\n {\n fields: ['storagePath', 'fileName', 'fileSize', 'storageDriver', 'partitionCode'],\n }\n )\n const existingKeys = new Set(existing.map((item) => buildKey(item)))\n let created = 0\n for (const source of attachments) {\n const key = buildKey(source)\n if (existingKeys.has(key)) continue\n const clone = em.create(Attachment, {\n entityId: E.catalog.catalog_product,\n recordId: productId,\n organizationId: source.organizationId ?? variant.organizationId ?? null,\n tenantId: source.tenantId ?? variant.tenantId ?? null,\n partitionCode: source.partitionCode,\n fileName: source.fileName,\n mimeType: source.mimeType,\n fileSize: source.fileSize,\n storageDriver: source.storageDriver,\n storagePath: source.storagePath,\n storageMetadata: source.storageMetadata ? cloneJson(source.storageMetadata) : null,\n url: source.url,\n })\n em.persist(clone)\n existingKeys.add(key)\n created += 1\n }\n if (created > 0) {\n await em.flush()\n }\n}\n\nconst createVariantCommand: CommandHandler<VariantCreateInput, { variantId: string; previousDefaultVariantId?: string | null }> = {\n id: 'catalog.variants.create',\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(variantCreateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const product = await requireProduct(em, parsed.productId)\n ensureTenantScope(ctx, product.tenantId)\n ensureOrganizationScope(ctx, product.organizationId)\n const { taxRateId, taxRate } = await resolveVariantTaxRate(\n em,\n product,\n parsed.taxRateId ?? null,\n parsed.taxRate\n )\n\n const metadataSplit = splitOptionValuesFromMetadata(parsed.metadata)\n const resolvedOptionValues =\n parsed.optionValues ?? (metadataSplit.hadOptionValues ? metadataSplit.optionValues : null)\n\n const now = new Date()\n const record = em.create(CatalogProductVariant, {\n organizationId: product.organizationId,\n tenantId: product.tenantId,\n product,\n name: parsed.name ?? null,\n sku: parsed.sku ?? null,\n barcode: parsed.barcode ?? null,\n statusEntryId: parsed.statusEntryId ?? null,\n isDefault: parsed.isDefault ?? false,\n isActive: parsed.isActive ?? true,\n weightValue: toNumericString(parsed.weightValue),\n weightUnit: parsed.weightUnit ?? null,\n taxRateId,\n taxRate,\n dimensions: parsed.dimensions ? cloneJson(parsed.dimensions) : null,\n metadata: metadataSplit.metadata,\n optionValues: resolvedOptionValues ? cloneJson(resolvedOptionValues) : null,\n customFieldsetCode: parsed.customFieldsetCode ?? null,\n createdAt: now,\n updatedAt: now,\n })\n em.persist(record)\n try {\n await em.flush()\n } catch (error) {\n await rethrowVariantUniqueConstraint(error)\n }\n let previousDefaultVariantId: string | null = null\n if (record.isDefault) {\n previousDefaultVariantId = await enforceSingleDefaultVariant(em, record)\n try {\n await em.flush()\n } catch (error) {\n await rethrowVariantUniqueConstraint(error)\n }\n }\n await aggregateVariantMediaToProduct(em, record)\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n values: custom,\n })\n await emitCatalogQueryIndexEvent(ctx, {\n entityType: E.catalog.catalog_product_variant,\n recordId: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n action: 'created',\n })\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n action: 'created',\n entity: record,\n identifiers: {\n id: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n },\n events: variantCrudEvents,\n })\n return { variantId: record.id, previousDefaultVariantId }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadVariantSnapshot(em, result.variantId)\n },\n buildLog: async ({ result, snapshots }) => {\n const after = snapshots.after as VariantSnapshot | undefined\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('catalog.audit.variants.create', 'Create product variant'),\n resourceKind: 'catalog.variant',\n resourceId: result.variantId,\n parentResourceKind: 'catalog.product',\n parentResourceId: after.productId ?? null,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n snapshotAfter: after,\n payload: {\n undo: {\n after,\n previousDefaultVariantId: (result as { previousDefaultVariantId?: string | null })?.previousDefaultVariantId ?? null,\n } satisfies VariantUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<VariantUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(CatalogProductVariant, { id: after.id })\n if (!record) return\n ensureTenantScope(ctx, record.tenantId)\n ensureOrganizationScope(ctx, record.organizationId)\n em.remove(record)\n await em.flush()\n if (payload?.previousDefaultVariantId) {\n const previousDefault = await em.findOne(CatalogProductVariant, { id: payload.previousDefaultVariantId })\n if (previousDefault) {\n ensureTenantScope(ctx, previousDefault.tenantId)\n ensureOrganizationScope(ctx, previousDefault.organizationId)\n previousDefault.isDefault = true\n await em.flush()\n }\n }\n const resetValues = buildCustomFieldResetMap(undefined, after.custom ?? undefined)\n if (Object.keys(resetValues).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: after.id,\n organizationId: after.organizationId,\n tenantId: after.tenantId,\n values: resetValues,\n })\n }\n },\n}\n\nconst updateVariantCommand: CommandHandler<VariantUpdateInput, { variantId: string; previousDefaultVariantId?: string | null }> = {\n id: 'catalog.variants.update',\n async prepare(input, ctx) {\n const id = requireId(input, 'Variant id is required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadVariantSnapshot(em, id)\n if (snapshot) {\n ensureTenantScope(ctx, snapshot.tenantId)\n ensureOrganizationScope(ctx, snapshot.organizationId)\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(variantUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(CatalogProductVariant, { id: parsed.id, deletedAt: null })\n if (!record) throw new CrudHttpError(404, { error: 'Catalog variant not found' })\n ensureTenantScope(ctx, record.tenantId)\n ensureOrganizationScope(ctx, record.organizationId)\n const product = await requireProduct(em, record.product.id)\n\n if (!product) throw new CrudHttpError(400, { error: 'Variant product missing' })\n\n const taxRateProvided = parsed.taxRateId !== undefined || parsed.taxRate !== undefined\n const resolvedTaxRate = taxRateProvided\n ? await resolveVariantTaxRate(em, product, parsed.taxRateId ?? null, parsed.taxRate)\n : null\n\n if (parsed.name !== undefined) record.name = parsed.name ?? null\n if (parsed.sku !== undefined) record.sku = parsed.sku ?? null\n if (parsed.barcode !== undefined) record.barcode = parsed.barcode ?? null\n if (parsed.statusEntryId !== undefined) record.statusEntryId = parsed.statusEntryId ?? null\n if (parsed.isDefault !== undefined) record.isDefault = parsed.isDefault\n if (parsed.isActive !== undefined) record.isActive = parsed.isActive\n if (Object.prototype.hasOwnProperty.call(parsed, 'weightValue')) {\n record.weightValue = toNumericString(parsed.weightValue)\n }\n if (parsed.weightUnit !== undefined) record.weightUnit = parsed.weightUnit ?? null\n if (parsed.dimensions !== undefined) {\n record.dimensions = parsed.dimensions ? cloneJson(parsed.dimensions) : null\n }\n let metadataSplit: MetadataSplitResult | null = null\n if (parsed.metadata !== undefined) {\n metadataSplit = splitOptionValuesFromMetadata(parsed.metadata)\n record.metadata = metadataSplit.metadata\n }\n if (parsed.optionValues !== undefined) {\n record.optionValues = parsed.optionValues ? cloneJson(parsed.optionValues) : null\n } else if (metadataSplit?.hadOptionValues) {\n record.optionValues = metadataSplit.optionValues ? cloneJson(metadataSplit.optionValues) : null\n }\n if (taxRateProvided) {\n record.taxRateId = resolvedTaxRate?.taxRateId ?? null\n record.taxRate = resolvedTaxRate?.taxRate ?? null\n }\n if (parsed.customFieldsetCode !== undefined) {\n record.customFieldsetCode = parsed.customFieldsetCode ?? null\n }\n\n let previousDefaultVariantId: string | null = null\n if (parsed.isDefault === true) {\n previousDefaultVariantId = await enforceSingleDefaultVariant(em, record)\n }\n try {\n await em.flush()\n } catch (error) {\n await rethrowVariantUniqueConstraint(error)\n }\n await aggregateVariantMediaToProduct(em, record)\n if (custom && Object.keys(custom).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n values: custom,\n })\n }\n await emitCatalogQueryIndexEvent(ctx, {\n entityType: E.catalog.catalog_product_variant,\n recordId: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n action: 'updated',\n })\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n action: 'updated',\n entity: record,\n identifiers: {\n id: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n },\n events: variantCrudEvents,\n })\n return { variantId: record.id, previousDefaultVariantId }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadVariantSnapshot(em, result.variantId)\n },\n buildLog: async ({ result, snapshots }) => {\n const before = snapshots.before as VariantSnapshot | undefined\n const after = snapshots.after as VariantSnapshot | undefined\n if (!before || !after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('catalog.audit.variants.update', 'Update product variant'),\n resourceKind: 'catalog.variant',\n resourceId: before.id,\n parentResourceKind: 'catalog.product',\n parentResourceId: before.productId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: after,\n changes: buildChanges(\n before as Record<string, unknown>,\n after as Record<string, unknown>,\n VARIANT_CHANGE_KEYS\n ),\n payload: {\n undo: {\n before,\n after,\n previousDefaultVariantId:\n (result as { previousDefaultVariantId?: string | null })?.previousDefaultVariantId ?? null,\n } satisfies VariantUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<VariantUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const after = payload?.after\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let record = await em.findOne(CatalogProductVariant, { id: before.id })\n if (!record) {\n const product = await requireProduct(em, before.productId)\n record = em.create(CatalogProductVariant, {\n id: before.id,\n product,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n name: before.name ?? null,\n sku: before.sku ?? null,\n barcode: before.barcode ?? null,\n statusEntryId: before.statusEntryId ?? null,\n isDefault: before.isDefault,\n isActive: before.isActive,\n weightValue: before.weightValue ?? null,\n weightUnit: before.weightUnit ?? null,\n dimensions: before.dimensions ? cloneJson(before.dimensions) : null,\n metadata: before.metadata ? cloneJson(before.metadata) : null,\n optionValues: before.optionValues ? cloneJson(before.optionValues) : null,\n customFieldsetCode: before.customFieldsetCode ?? null,\n createdAt: new Date(before.createdAt),\n updatedAt: new Date(before.updatedAt),\n })\n em.persist(record)\n }\n ensureTenantScope(ctx, before.tenantId)\n ensureOrganizationScope(ctx, before.organizationId)\n applyVariantSnapshot(record, before)\n await em.flush()\n const previousDefaultId = payload?.previousDefaultVariantId\n if (previousDefaultId) {\n const previousDefault = await em.findOne(CatalogProductVariant, { id: previousDefaultId })\n if (previousDefault) {\n ensureTenantScope(ctx, previousDefault.tenantId)\n ensureOrganizationScope(ctx, previousDefault.organizationId)\n previousDefault.isDefault = true\n await em.flush()\n }\n }\n const resetValues = buildCustomFieldResetMap(\n before.custom ?? undefined,\n after?.custom ?? undefined\n )\n if (Object.keys(resetValues).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n values: resetValues,\n })\n }\n },\n}\n\nconst deleteVariantCommand: CommandHandler<\n { body?: Record<string, unknown>; query?: Record<string, unknown> },\n { variantId: string }\n> = {\n id: 'catalog.variants.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Variant id is required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadVariantSnapshot(em, id, { includePrices: true })\n if (snapshot) {\n ensureTenantScope(ctx, snapshot.tenantId)\n ensureOrganizationScope(ctx, snapshot.organizationId)\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Variant id is required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(CatalogProductVariant, { id })\n if (!record) throw new CrudHttpError(404, { error: 'Catalog variant not found' })\n ensureTenantScope(ctx, record.tenantId)\n ensureOrganizationScope(ctx, record.organizationId)\n\n const baseEm = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadVariantSnapshot(baseEm, id, { includePrices: true })\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const priceSnapshots =\n snapshot?.prices && snapshot.prices.length\n ? snapshot.prices\n : await loadVariantPriceSnapshots(baseEm, id, {\n tenantId: record.tenantId,\n organizationId: record.organizationId,\n })\n\n if (priceSnapshots.length) {\n await em.nativeDelete(CatalogProductPrice, { id: { $in: priceSnapshots.map((price) => price.id) } })\n } else {\n await em.nativeDelete(CatalogProductPrice, { variant: record })\n }\n em.remove(record)\n await em.flush()\n for (const priceSnapshot of priceSnapshots) {\n const resetValues = buildCustomFieldResetMap(priceSnapshot.custom ?? undefined, undefined)\n if (!Object.keys(resetValues).length) continue\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: E.catalog.catalog_product_price,\n recordId: priceSnapshot.id,\n organizationId: priceSnapshot.organizationId,\n tenantId: priceSnapshot.tenantId,\n values: resetValues,\n })\n }\n if (snapshot?.custom && Object.keys(snapshot.custom).length) {\n const resetValues = buildCustomFieldResetMap(snapshot.custom, undefined)\n if (Object.keys(resetValues).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: E.catalog.catalog_product_variant,\n recordId: id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n values: resetValues,\n })\n }\n }\n await emitCatalogQueryIndexEvent(ctx, {\n entityType: E.catalog.catalog_product_variant,\n recordId: id,\n organizationId: snapshot?.organizationId ?? record.organizationId,\n tenantId: snapshot?.tenantId ?? record.tenantId,\n action: 'deleted',\n })\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n action: 'deleted',\n entity: record,\n identifiers: {\n id,\n organizationId: snapshot?.organizationId ?? record.organizationId,\n tenantId: snapshot?.tenantId ?? record.tenantId,\n },\n events: variantCrudEvents,\n })\n return { variantId: id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as VariantSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('catalog.audit.variants.delete', 'Delete product variant'),\n resourceKind: 'catalog.variant',\n resourceId: before.id,\n parentResourceKind: 'catalog.product',\n parentResourceId: before.productId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n } satisfies VariantUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<VariantUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let record = await em.findOne(CatalogProductVariant, { id: before.id })\n if (!record) {\n const product = await requireProduct(em, before.productId)\n record = em.create(CatalogProductVariant, {\n id: before.id,\n product,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n name: before.name ?? null,\n sku: before.sku ?? null,\n barcode: before.barcode ?? null,\n statusEntryId: before.statusEntryId ?? null,\n isDefault: before.isDefault,\n isActive: before.isActive,\n weightValue: before.weightValue ?? null,\n weightUnit: before.weightUnit ?? null,\n dimensions: before.dimensions ? cloneJson(before.dimensions) : null,\n metadata: before.metadata ? cloneJson(before.metadata) : null,\n customFieldsetCode: before.customFieldsetCode ?? null,\n createdAt: new Date(before.createdAt),\n updatedAt: new Date(before.updatedAt),\n })\n em.persist(record)\n }\n ensureTenantScope(ctx, before.tenantId)\n ensureOrganizationScope(ctx, before.organizationId)\n applyVariantSnapshot(record, before)\n if (before.prices?.length) {\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await restoreVariantPricesFromSnapshots(em, record, before.prices, dataEngine)\n }\n await em.flush()\n if (before.custom && Object.keys(before.custom).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n values: before.custom,\n })\n }\n },\n}\n\nasync function throwDuplicateVariantSkuError(): Promise<never> {\n const { translate } = await resolveTranslations()\n const message = translate('catalog.variants.errors.skuExists', 'SKU already in use.')\n throw new CrudHttpError(400, {\n error: message,\n fieldErrors: { sku: message },\n details: [{ path: ['sku'], message, code: 'duplicate', origin: 'validation' }],\n })\n}\n\nasync function rethrowVariantUniqueConstraint(error: unknown): Promise<never> {\n if (error instanceof UniqueConstraintViolationException) {\n const constraint = getErrorConstraint(error)\n const message = getErrorMessage(error).toLowerCase()\n if (\n constraint === 'catalog_product_variants_sku_unique' ||\n message.includes('catalog_product_variants_sku_unique')\n ) {\n await throwDuplicateVariantSkuError()\n }\n }\n throw error\n}\n\nregisterCommand(createVariantCommand)\nregisterCommand(updateVariantCommand)\nregisterCommand(deleteVariantCommand)\n"],
5
- "mappings": "AAAA,SAAS,uBAAuB;AAEhC,SAAS,cAAc,WAAW,uBAAuB,sBAAsB,2BAA2B;AAE1G,SAAS,0CAA0C;AACnD,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,yBAAyB,gCAAgC;AAClE,SAAS,SAAS;AAClB,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,kBAAkB;AAC3B;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,oBAAoB;AAG7B,MAAM,oBAAsC;AAAA,EAC1C,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,EAC5B;AACF;AAiCA,MAAM,sBAAsB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAe,oBACb,IACA,IACA,UAAuC,CAAC,GACP;AACjC,QAAM,SAAS,MAAM,GAAG,QAAQ,uBAAuB,EAAE,IAAI,WAAW,KAAK,CAAC;AAC9E,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,SAAS,QAAQ,gBACnB,MAAM,0BAA0B,IAAI,OAAO,IAAI;AAAA,IAC7C,UAAU,OAAO;AAAA,IACjB,gBAAgB,OAAO;AAAA,EACzB,CAAC,IACD;AACJ,QAAM,SAAS,MAAM,wBAAwB,IAAI;AAAA,IAC/C,UAAU,EAAE,QAAQ;AAAA,IACpB,UAAU,OAAO;AAAA,IACjB,UAAU,OAAO;AAAA,IACjB,gBAAgB,OAAO;AAAA,EACzB,CAAC;AACD,QAAM,YAAY,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU,OAAO,QAAQ;AACvF,SAAO;AAAA,IACL,IAAI,OAAO;AAAA,IACX;AAAA,IACA,gBAAgB,OAAO;AAAA,IACvB,UAAU,OAAO;AAAA,IACjB,MAAM,OAAO,QAAQ;AAAA,IACrB,KAAK,OAAO,OAAO;AAAA,IACnB,SAAS,OAAO,WAAW;AAAA,IAC3B,eAAe,OAAO,iBAAiB;AAAA,IACvC,WAAW,OAAO;AAAA,IAClB,UAAU,OAAO;AAAA,IACjB,aAAa,OAAO,eAAe;AAAA,IACnC,YAAY,OAAO,cAAc;AAAA,IACjC,WAAW,OAAO,aAAa;AAAA,IAC/B,SAAS,OAAO,WAAW;AAAA,IAC3B,YAAY,OAAO,aAAa,UAAU,OAAO,UAAU,IAAI;AAAA,IAC/D,UAAU,OAAO,WAAW,UAAU,OAAO,QAAQ,IAAI;AAAA,IACzD,cAAc,OAAO,eAAe,UAAU,OAAO,YAAY,IAAI;AAAA,IACrE,oBAAoB,OAAO,sBAAsB;AAAA,IACjD,WAAW,OAAO,UAAU,YAAY;AAAA,IACxC,WAAW,OAAO,UAAU,YAAY;AAAA,IACxC,QAAQ,OAAO,KAAK,MAAM,EAAE,SAAS,SAAS;AAAA,IAC9C,QAAQ,UAAU,OAAO,SAAS,SAAS;AAAA,EAC7C;AACF;AAEA,SAAS,qBAAqB,QAA+B,UAAiC;AAC5F,SAAO,iBAAiB,SAAS;AACjC,SAAO,WAAW,SAAS;AAC3B,SAAO,OAAO,SAAS,QAAQ;AAC/B,SAAO,MAAM,SAAS,OAAO;AAC7B,SAAO,UAAU,SAAS,WAAW;AACrC,SAAO,gBAAgB,SAAS,iBAAiB;AACjD,SAAO,YAAY,SAAS;AAC5B,SAAO,WAAW,SAAS;AAC3B,SAAO,cAAc,SAAS,eAAe;AAC7C,SAAO,aAAa,SAAS,cAAc;AAC3C,SAAO,YAAY,SAAS,aAAa;AACzC,SAAO,UAAU,SAAS,WAAW;AACrC,SAAO,aAAa,SAAS,aAAa,UAAU,SAAS,UAAU,IAAI;AAC3E,SAAO,WAAW,SAAS,WAAW,UAAU,SAAS,QAAQ,IAAI;AACrE,SAAO,eAAe,SAAS,eAAe,UAAU,SAAS,YAAY,IAAI;AACjF,SAAO,qBAAqB,SAAS,sBAAsB;AAC3D,SAAO,YAAY,IAAI,KAAK,SAAS,SAAS;AAC9C,SAAO,YAAY,IAAI,KAAK,SAAS,SAAS;AAChD;AAEA,eAAe,sBACb,IACA,SACA,gBACA,cAC+D;AAC/D,QAAM,iBAAiB,QAAQ;AAC/B,QAAM,WAAW,QAAQ;AACzB,QAAM,iBACJ,iBAAiB,QAAQ,iBAAiB,SACtC,QACC,MAAM;AACL,UAAM,UAAU,OAAO,iBAAiB,WAAW,OAAO,YAAY,IAAI;AAC1E,WAAO,OAAO,SAAS,OAAO,IAAI,gBAAgB,OAAO,IAAI;AAAA,EAC/D,GAAG;AACT,MAAI,mBAAmB,MAAM;AAC3B,WAAO,EAAE,WAAW,QAAQ,aAAa,MAAM,SAAS,QAAQ,WAAW,KAAK;AAAA,EAClF;AACA,MAAI,CAAC,gBAAgB;AACnB,WAAO,EAAE,WAAW,QAAQ,aAAa,MAAM,SAAS,QAAQ,WAAW,eAAe;AAAA,EAC5F;AACA,QAAM,SAAS,MAAM,GAAG,QAAQ,cAAc;AAAA,IAC5C,IAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EACb,CAAC;AACD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,sBAAsB,CAAC;AAAA,EAC/D;AACA,SAAO,EAAE,WAAW,gBAAgB,SAAS,OAAO,QAAQ,eAAe;AAC7E;AAgCA,eAAe,0BACb,IACA,WACA,OACiC;AACjC,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA,EAAE,SAAS,WAAW,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,IACrF,EAAE,UAAU,CAAC,aAAa,WAAW,OAAO,EAAE;AAAA,IAC9C,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,EACnE;AACA,QAAM,YAAoC,CAAC;AAC3C,aAAW,SAAS,QAAQ;AAC1B,UAAM,aAAa,MAAM;AACzB,UAAM,iBACJ,OAAO,eAAe,WAClB,aACA,aACE,WAAW,KACX;AACR,UAAM,aAAa,MAAM,UACrB,MAAM,UACN,OAAO,MAAM,YAAY,YAAY,MAAM,UACzC,MAAM,QAAQ,UACd;AACN,UAAM,YACJ,OAAO,eAAe,WAClB,aACA,aACE,WAAW,KACX;AACR,UAAM,eAAe,MAAM;AAC3B,UAAM,cACJ,OAAO,iBAAiB,WACpB,eACA,eACE,aAAa,KACb;AACR,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,wCAAwC,CAAC;AAAA,IACjF;AACA,UAAM,gBACJ,OAAO,iBAAiB,YAAY,eAAe,aAAa,OAAO,MAAM;AAC/E,UAAM,SAAS,MAAM,wBAAwB,IAAI;AAAA,MAC/C,UAAU,EAAE,QAAQ;AAAA,MACpB,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,IACxB,CAAC;AACD,cAAU,KAAK;AAAA,MACb,IAAI,MAAM;AAAA,MACV,WAAW;AAAA,MACX;AAAA,MACA,SAAS,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ,MAAM,QAAQ,MAAM,MAAM,KAAK;AAAA,MACxF,gBAAgB,MAAM;AAAA,MACtB,UAAU,MAAM;AAAA,MAChB;AAAA,MACA;AAAA,MACA,cAAc,MAAM;AAAA,MACpB,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB,aAAa,MAAM,eAAe;AAAA,MAClC,cAAc,MAAM,gBAAgB;AAAA,MACpC,gBAAgB,MAAM,kBAAkB;AAAA,MACxC,SAAS,MAAM,WAAW;AAAA,MAC1B,WAAW,MAAM,aAAa;AAAA,MAC9B,WAAW,MAAM,aAAa;AAAA,MAC9B,QAAQ,MAAM,UAAU;AAAA,MACxB,aAAa,MAAM,eAAe;AAAA,MAClC,YAAY,MAAM,cAAc;AAAA,MAChC,iBAAiB,MAAM,mBAAmB;AAAA,MAC1C,UAAU,MAAM,WAAW,UAAU,MAAM,QAAQ,IAAI;AAAA,MACvD,UAAU,MAAM,WAAW,MAAM,SAAS,YAAY,IAAI;AAAA,MAC1D,QAAQ,MAAM,SAAS,MAAM,OAAO,YAAY,IAAI;AAAA,MACpD,WAAW,MAAM,UAAU,YAAY;AAAA,MACvC,WAAW,MAAM,UAAU,YAAY;AAAA,MACvC,QAAQ,OAAO,KAAK,MAAM,EAAE,SAAS,SAAS;AAAA,IAChD,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,eAAe,kCACb,IACA,SACA,WACA,YACe;AACf,MAAI,CAAC,UAAU,OAAQ;AACvB,QAAM,aACJ,OAAO,QAAQ,YAAY,WACvB,MAAM,eAAe,IAAI,QAAQ,OAAO,IACxC,QAAQ;AACd,aAAW,YAAY,WAAW;AAChC,UAAM,UACJ,SAAS,aAAa,SAAS,cAAc,WAAW,KACpD,GAAG,aAAa,gBAAgB,SAAS,SAAS,IAClD;AACN,UAAM,QAAQ,SAAS,UAAU,GAAG,aAAa,cAAc,SAAS,OAAO,IAAI;AACnF,UAAM,YAAY,GAAG,aAAa,kBAAkB,SAAS,WAAW;AACxE,QAAI,SAAS,MAAM,GAAG,QAAQ,qBAAqB,EAAE,IAAI,SAAS,GAAG,CAAC;AACtE,QAAI,CAAC,QAAQ;AACX,eAAS,GAAG,OAAO,qBAAqB;AAAA,QACtC,IAAI,SAAS;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA,gBAAgB,SAAS;AAAA,QACzB,UAAU,SAAS;AAAA,QACnB,cAAc,SAAS;AAAA,QACvB;AAAA,QACA,MAAM,SAAS,iBAAiB,SAAS;AAAA,QACzC,aAAa,SAAS;AAAA,QACtB,aAAa,SAAS,eAAe;AAAA,QACrC,cAAc,SAAS,gBAAgB;AAAA,QACvC,gBAAgB,SAAS,kBAAkB;AAAA,QAC3C,SAAS,SAAS,WAAW;AAAA,QAC7B,WAAW,SAAS,aAAa;AAAA,QACjC,WAAW,SAAS,aAAa;AAAA,QACjC,QAAQ,SAAS,UAAU;AAAA,QAC3B,aAAa,SAAS,eAAe;AAAA,QACrC,YAAY,SAAS,cAAc;AAAA,QACnC,iBAAiB,SAAS,mBAAmB;AAAA,QAC7C,UAAU,SAAS,WAAW,UAAU,SAAS,QAAQ,IAAI;AAAA,QAC7D,UAAU,SAAS,WAAW,IAAI,KAAK,SAAS,QAAQ,IAAI;AAAA,QAC5D,QAAQ,SAAS,SAAS,IAAI,KAAK,SAAS,MAAM,IAAI;AAAA,QACtD,WAAW,IAAI,KAAK,SAAS,SAAS;AAAA,QACtC,WAAW,IAAI,KAAK,SAAS,SAAS;AAAA,MACxC,CAAC;AACD,SAAG,QAAQ,MAAM;AAAA,IACnB,OAAO;AACL,aAAO,UAAU;AACjB,aAAO,UAAU;AACjB,aAAO,QAAQ;AACf,aAAO,YAAY;AACnB,aAAO,iBAAiB,SAAS;AACjC,aAAO,WAAW,SAAS;AAC3B,aAAO,eAAe,SAAS;AAC/B,aAAO,OAAO,SAAS,iBAAiB,SAAS;AACjD,aAAO,cAAc,SAAS;AAC9B,aAAO,cAAc,SAAS,eAAe;AAC7C,aAAO,eAAe,SAAS,gBAAgB;AAC/C,aAAO,iBAAiB,SAAS,kBAAkB;AACnD,aAAO,UAAU,SAAS,WAAW;AACrC,aAAO,YAAY,SAAS,aAAa;AACzC,aAAO,YAAY,SAAS,aAAa;AACzC,aAAO,SAAS,SAAS,UAAU;AACnC,aAAO,cAAc,SAAS,eAAe;AAC7C,aAAO,aAAa,SAAS,cAAc;AAC3C,aAAO,kBAAkB,SAAS,mBAAmB;AACrD,aAAO,WAAW,SAAS,WAAW,UAAU,SAAS,QAAQ,IAAI;AACrE,aAAO,WAAW,SAAS,WAAW,IAAI,KAAK,SAAS,QAAQ,IAAI;AACpE,aAAO,SAAS,SAAS,SAAS,IAAI,KAAK,SAAS,MAAM,IAAI;AAC9D,aAAO,YAAY,IAAI,KAAK,SAAS,SAAS;AAC9C,aAAO,YAAY,IAAI,KAAK,SAAS,SAAS;AAAA,IAChD;AAAA,EACF;AACA,QAAM,GAAG,MAAM;AACf,aAAW,YAAY,WAAW;AAChC,QAAI,CAAC,SAAS,UAAU,CAAC,OAAO,KAAK,SAAS,MAAM,EAAE,OAAQ;AAC9D,UAAM,qBAAqB;AAAA,MACzB;AAAA,MACA,UAAU,EAAE,QAAQ;AAAA,MACpB,UAAU,SAAS;AAAA,MACnB,gBAAgB,SAAS;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,EACH;AACF;AAQA,SAAS,8BACP,UACqB;AACrB,MAAI,CAAC,YAAY,OAAO,aAAa,YAAY,MAAM,QAAQ,QAAQ,GAAG;AACxE,WAAO;AAAA,MACL,UAAU,WAAW,UAAU,QAAQ,IAAI;AAAA,MAC3C,cAAc;AAAA,MACd,iBAAiB;AAAA,IACnB;AAAA,EACF;AACA,QAAM,EAAE,cAAc,GAAG,KAAK,IAAI;AAGlC,QAAM,qBAAqB,OAAO,KAAK,IAAI,EAAE,SAAS,UAAU,IAAI,IAAI;AACxE,SAAO;AAAA,IACL,UAAU;AAAA,IACV,cAAc,sBAAsB,YAAY;AAAA,IAChD,iBAAiB,iBAAiB;AAAA,EACpC;AACF;AAEA,SAAS,sBAAsB,OAA+C;AAC5E,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO;AACxE,QAAM,aAAqC,CAAC;AAC5C,aAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,QAAQ,KAAK,GAAG;AACtD,QAAI,OAAO,aAAa,SAAU;AAClC,UAAM,MAAM,OAAO,KAAK;AACxB,UAAM,QAAQ,SAAS,KAAK;AAC5B,QAAI,CAAC,OAAO,CAAC,MAAO;AACpB,eAAW,GAAG,IAAI;AAAA,EACpB;AACA,SAAO,OAAO,KAAK,UAAU,EAAE,SAAS,aAAa;AACvD;AAEA,SAAS,iBAAiB,QAAuC;AAC/D,SAAO,OAAO,OAAO,YAAY,WAAW,OAAO,UAAU,OAAO,QAAQ;AAC9E;AAEA,eAAe,4BACb,IACA,SACwB;AACxB,MAAI,CAAC,QAAQ,UAAW,QAAO;AAC/B,QAAM,YAAY,iBAAiB,OAAO;AAC1C,QAAM,kBAAkB,MAAM,GAAG;AAAA,IAC/B;AAAA,IACA,EAAE,SAAS,WAAW,WAAW,MAAM,WAAW,MAAM,IAAI,EAAE,KAAK,QAAQ,GAAG,EAAE;AAAA,IAChF,EAAE,QAAQ,CAAC,MAAM,WAAW,EAAE;AAAA,EAChC;AACA,MAAI,iBAAiB;AACnB,oBAAgB,YAAY;AAC5B,WAAO,gBAAgB;AAAA,EACzB;AACA,SAAO;AACT;AAEA,eAAe,+BACb,IACA,SACe;AACf,QAAM,YAAY,iBAAiB,OAAO;AAC1C,QAAM,WAAW,CACf,eAEA;AAAA,IACE,WAAW,UAAU,KAAK,KAAK;AAAA,IAC/B,WAAW,YAAY;AAAA,IACvB,WAAW,iBAAiB;AAAA,IAC5B,WAAW,iBAAiB;AAAA,EAC9B,EAAE,KAAK,GAAG;AACZ,QAAM,cAAc,MAAM,GAAG;AAAA,IAC3B;AAAA,IACA;AAAA,MACE,UAAU,EAAE,QAAQ;AAAA,MACpB,UAAU,QAAQ;AAAA,MAClB,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,UAAU,QAAQ,YAAY;AAAA,IAChC;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,YAAY,OAAQ;AACzB,QAAM,WAAW,MAAM,GAAG;AAAA,IACxB;AAAA,IACA;AAAA,MACE,UAAU,EAAE,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,UAAU,QAAQ,YAAY;AAAA,IAChC;AAAA,IACA;AAAA,MACE,QAAQ,CAAC,eAAe,YAAY,YAAY,iBAAiB,eAAe;AAAA,IAClF;AAAA,EACF;AACA,QAAM,eAAe,IAAI,IAAI,SAAS,IAAI,CAAC,SAAS,SAAS,IAAI,CAAC,CAAC;AACnE,MAAI,UAAU;AACd,aAAW,UAAU,aAAa;AAChC,UAAM,MAAM,SAAS,MAAM;AAC3B,QAAI,aAAa,IAAI,GAAG,EAAG;AAC3B,UAAM,QAAQ,GAAG,OAAO,YAAY;AAAA,MAClC,UAAU,EAAE,QAAQ;AAAA,MACpB,UAAU;AAAA,MACV,gBAAgB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,MACnE,UAAU,OAAO,YAAY,QAAQ,YAAY;AAAA,MACjD,eAAe,OAAO;AAAA,MACtB,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,eAAe,OAAO;AAAA,MACtB,aAAa,OAAO;AAAA,MACpB,iBAAiB,OAAO,kBAAkB,UAAU,OAAO,eAAe,IAAI;AAAA,MAC9E,KAAK,OAAO;AAAA,IACd,CAAC;AACD,OAAG,QAAQ,KAAK;AAChB,iBAAa,IAAI,GAAG;AACpB,eAAW;AAAA,EACb;AACA,MAAI,UAAU,GAAG;AACf,UAAM,GAAG,MAAM;AAAA,EACjB;AACF;AAEA,MAAM,uBAA4H;AAAA,EAChI,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,EAAE,QAAQ,OAAO,IAAI,sBAAsB,qBAAqB,QAAQ;AAC9E,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,UAAU,MAAM,eAAe,IAAI,OAAO,SAAS;AACzD,sBAAkB,KAAK,QAAQ,QAAQ;AACvC,4BAAwB,KAAK,QAAQ,cAAc;AACnD,UAAM,EAAE,WAAW,QAAQ,IAAI,MAAM;AAAA,MACnC;AAAA,MACA;AAAA,MACA,OAAO,aAAa;AAAA,MACpB,OAAO;AAAA,IACT;AAEA,UAAM,gBAAgB,8BAA8B,OAAO,QAAQ;AACnE,UAAM,uBACJ,OAAO,iBAAiB,cAAc,kBAAkB,cAAc,eAAe;AAEvF,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,SAAS,GAAG,OAAO,uBAAuB;AAAA,MAC9C,gBAAgB,QAAQ;AAAA,MACxB,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA,MAAM,OAAO,QAAQ;AAAA,MACrB,KAAK,OAAO,OAAO;AAAA,MACnB,SAAS,OAAO,WAAW;AAAA,MAC3B,eAAe,OAAO,iBAAiB;AAAA,MACvC,WAAW,OAAO,aAAa;AAAA,MAC/B,UAAU,OAAO,YAAY;AAAA,MAC7B,aAAa,gBAAgB,OAAO,WAAW;AAAA,MAC/C,YAAY,OAAO,cAAc;AAAA,MACjC;AAAA,MACA;AAAA,MACA,YAAY,OAAO,aAAa,UAAU,OAAO,UAAU,IAAI;AAAA,MAC/D,UAAU,cAAc;AAAA,MACxB,cAAc,uBAAuB,UAAU,oBAAoB,IAAI;AAAA,MACvE,oBAAoB,OAAO,sBAAsB;AAAA,MACjD,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AACD,OAAG,QAAQ,MAAM;AACjB,QAAI;AACF,YAAM,GAAG,MAAM;AAAA,IACjB,SAAS,OAAO;AACd,YAAM,+BAA+B,KAAK;AAAA,IAC5C;AACA,QAAI,2BAA0C;AAC9C,QAAI,OAAO,WAAW;AACpB,iCAA2B,MAAM,4BAA4B,IAAI,MAAM;AACvE,UAAI;AACF,cAAM,GAAG,MAAM;AAAA,MACjB,SAAS,OAAO;AACd,cAAM,+BAA+B,KAAK;AAAA,MAC5C;AAAA,IACF;AACA,UAAM,+BAA+B,IAAI,MAAM;AAC/C,UAAM,qBAAqB;AAAA,MACzB,YAAY,IAAI,UAAU,QAAQ,YAAY;AAAA,MAC9C,UAAU,EAAE,QAAQ;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,UAAU,OAAO;AAAA,MACjB,QAAQ;AAAA,IACV,CAAC;AACD,UAAM,2BAA2B,KAAK;AAAA,MACpC,YAAY,EAAE,QAAQ;AAAA,MACtB,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,UAAU,OAAO;AAAA,MACjB,QAAQ;AAAA,IACV,CAAC;AACD,UAAM,oBAAoB;AAAA,MACxB,YAAY,IAAI,UAAU,QAAQ,YAAY;AAAA,MAC9C,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,OAAO;AAAA,QACX,gBAAgB,OAAO;AAAA,QACvB,UAAU,OAAO;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,EAAE,WAAW,OAAO,IAAI,yBAAyB;AAAA,EAC1D;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,oBAAoB,IAAI,OAAO,SAAS;AAAA,EACjD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,QAAQ,UAAU;AACxB,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,WAAO;AAAA,MACL,aAAa,UAAU,iCAAiC,wBAAwB;AAAA,MAChF,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,MAAM,aAAa;AAAA,MACrC,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,eAAe;AAAA,MACf,SAAS;AAAA,QACP,MAAM;AAAA,UACJ;AAAA,UACA,0BAA2B,QAAyD,4BAA4B;AAAA,QAClH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,MAAO;AACZ,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,SAAS,MAAM,GAAG,QAAQ,uBAAuB,EAAE,IAAI,MAAM,GAAG,CAAC;AACvE,QAAI,CAAC,OAAQ;AACb,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAClD,OAAG,OAAO,MAAM;AAChB,UAAM,GAAG,MAAM;AACf,QAAI,SAAS,0BAA0B;AACrC,YAAM,kBAAkB,MAAM,GAAG,QAAQ,uBAAuB,EAAE,IAAI,QAAQ,yBAAyB,CAAC;AACxG,UAAI,iBAAiB;AACnB,0BAAkB,KAAK,gBAAgB,QAAQ;AAC/C,gCAAwB,KAAK,gBAAgB,cAAc;AAC3D,wBAAgB,YAAY;AAC5B,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM,cAAc,yBAAyB,QAAW,MAAM,UAAU,MAAS;AACjF,QAAI,OAAO,KAAK,WAAW,EAAE,QAAQ;AACnC,YAAM,qBAAqB;AAAA,QACzB,YAAY,IAAI,UAAU,QAAQ,YAAY;AAAA,QAC9C,UAAU,EAAE,QAAQ;AAAA,QACpB,UAAU,MAAM;AAAA,QAChB,gBAAgB,MAAM;AAAA,QACtB,UAAU,MAAM;AAAA,QAChB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,MAAM,uBAA4H;AAAA,EAChI,IAAI;AAAA,EACJ,MAAM,QAAQ,OAAO,KAAK;AACxB,UAAM,KAAK,UAAU,OAAO,wBAAwB;AACpD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,WAAW,MAAM,oBAAoB,IAAI,EAAE;AACjD,QAAI,UAAU;AACZ,wBAAkB,KAAK,SAAS,QAAQ;AACxC,8BAAwB,KAAK,SAAS,cAAc;AAAA,IACtD;AACA,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,EAAE,QAAQ,OAAO,IAAI,sBAAsB,qBAAqB,QAAQ;AAC9E,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,SAAS,MAAM,GAAG,QAAQ,uBAAuB,EAAE,IAAI,OAAO,IAAI,WAAW,KAAK,CAAC;AACzF,QAAI,CAAC,OAAQ,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,4BAA4B,CAAC;AAChF,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAClD,UAAM,UAAU,MAAM,eAAe,IAAI,OAAO,QAAQ,EAAE;AAE1D,QAAI,CAAC,QAAS,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,0BAA0B,CAAC;AAE/E,UAAM,kBAAkB,OAAO,cAAc,UAAa,OAAO,YAAY;AAC7E,UAAM,kBAAkB,kBACpB,MAAM,sBAAsB,IAAI,SAAS,OAAO,aAAa,MAAM,OAAO,OAAO,IACjF;AAEJ,QAAI,OAAO,SAAS,OAAW,QAAO,OAAO,OAAO,QAAQ;AAC5D,QAAI,OAAO,QAAQ,OAAW,QAAO,MAAM,OAAO,OAAO;AACzD,QAAI,OAAO,YAAY,OAAW,QAAO,UAAU,OAAO,WAAW;AACrE,QAAI,OAAO,kBAAkB,OAAW,QAAO,gBAAgB,OAAO,iBAAiB;AACvF,QAAI,OAAO,cAAc,OAAW,QAAO,YAAY,OAAO;AAC9D,QAAI,OAAO,aAAa,OAAW,QAAO,WAAW,OAAO;AAC5D,QAAI,OAAO,UAAU,eAAe,KAAK,QAAQ,aAAa,GAAG;AAC/D,aAAO,cAAc,gBAAgB,OAAO,WAAW;AAAA,IACzD;AACA,QAAI,OAAO,eAAe,OAAW,QAAO,aAAa,OAAO,cAAc;AAC9E,QAAI,OAAO,eAAe,QAAW;AACnC,aAAO,aAAa,OAAO,aAAa,UAAU,OAAO,UAAU,IAAI;AAAA,IACzE;AACA,QAAI,gBAA4C;AAChD,QAAI,OAAO,aAAa,QAAW;AACjC,sBAAgB,8BAA8B,OAAO,QAAQ;AAC7D,aAAO,WAAW,cAAc;AAAA,IAClC;AACA,QAAI,OAAO,iBAAiB,QAAW;AACrC,aAAO,eAAe,OAAO,eAAe,UAAU,OAAO,YAAY,IAAI;AAAA,IAC/E,WAAW,eAAe,iBAAiB;AACzC,aAAO,eAAe,cAAc,eAAe,UAAU,cAAc,YAAY,IAAI;AAAA,IAC7F;AACA,QAAI,iBAAiB;AACnB,aAAO,YAAY,iBAAiB,aAAa;AACjD,aAAO,UAAU,iBAAiB,WAAW;AAAA,IAC/C;AACA,QAAI,OAAO,uBAAuB,QAAW;AAC3C,aAAO,qBAAqB,OAAO,sBAAsB;AAAA,IAC3D;AAEA,QAAI,2BAA0C;AAC9C,QAAI,OAAO,cAAc,MAAM;AAC7B,iCAA2B,MAAM,4BAA4B,IAAI,MAAM;AAAA,IACzE;AACA,QAAI;AACF,YAAM,GAAG,MAAM;AAAA,IACjB,SAAS,OAAO;AACd,YAAM,+BAA+B,KAAK;AAAA,IAC5C;AACA,UAAM,+BAA+B,IAAI,MAAM;AAC/C,QAAI,UAAU,OAAO,KAAK,MAAM,EAAE,QAAQ;AACxC,YAAM,qBAAqB;AAAA,QACzB,YAAY,IAAI,UAAU,QAAQ,YAAY;AAAA,QAC9C,UAAU,EAAE,QAAQ;AAAA,QACpB,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,UAAU,OAAO;AAAA,QACjB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AACA,UAAM,2BAA2B,KAAK;AAAA,MACpC,YAAY,EAAE,QAAQ;AAAA,MACtB,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,UAAU,OAAO;AAAA,MACjB,QAAQ;AAAA,IACV,CAAC;AACD,UAAM,oBAAoB;AAAA,MACxB,YAAY,IAAI,UAAU,QAAQ,YAAY;AAAA,MAC9C,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,OAAO;AAAA,QACX,gBAAgB,OAAO;AAAA,QACvB,UAAU,OAAO;AAAA,MACnB;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,EAAE,WAAW,OAAO,IAAI,yBAAyB;AAAA,EAC1D;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,WAAO,oBAAoB,IAAI,OAAO,SAAS;AAAA,EACjD;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,SAAS,UAAU;AACzB,UAAM,QAAQ,UAAU;AACxB,QAAI,CAAC,UAAU,CAAC,MAAO,QAAO;AAC9B,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,WAAO;AAAA,MACL,aAAa,UAAU,iCAAiC,wBAAwB;AAAA,MAChF,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,aAAa;AAAA,MACtC,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,gBAAgB;AAAA,MAChB,eAAe;AAAA,MACf,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAS;AAAA,QACP,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA,0BACG,QAAyD,4BAA4B;AAAA,QAC1F;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,QAAQ,SAAS;AACvB,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,QAAI,SAAS,MAAM,GAAG,QAAQ,uBAAuB,EAAE,IAAI,OAAO,GAAG,CAAC;AACtE,QAAI,CAAC,QAAQ;AACX,YAAM,UAAU,MAAM,eAAe,IAAI,OAAO,SAAS;AACzD,eAAS,GAAG,OAAO,uBAAuB;AAAA,QACxC,IAAI,OAAO;AAAA,QACX;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,UAAU,OAAO;AAAA,QACjB,MAAM,OAAO,QAAQ;AAAA,QACrB,KAAK,OAAO,OAAO;AAAA,QACnB,SAAS,OAAO,WAAW;AAAA,QAC3B,eAAe,OAAO,iBAAiB;AAAA,QACvC,WAAW,OAAO;AAAA,QAClB,UAAU,OAAO;AAAA,QACjB,aAAa,OAAO,eAAe;AAAA,QACnC,YAAY,OAAO,cAAc;AAAA,QACjC,YAAY,OAAO,aAAa,UAAU,OAAO,UAAU,IAAI;AAAA,QAC/D,UAAU,OAAO,WAAW,UAAU,OAAO,QAAQ,IAAI;AAAA,QACzD,cAAc,OAAO,eAAe,UAAU,OAAO,YAAY,IAAI;AAAA,QACrE,oBAAoB,OAAO,sBAAsB;AAAA,QACjD,WAAW,IAAI,KAAK,OAAO,SAAS;AAAA,QACpC,WAAW,IAAI,KAAK,OAAO,SAAS;AAAA,MACtC,CAAC;AACD,SAAG,QAAQ,MAAM;AAAA,IACnB;AACA,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAClD,yBAAqB,QAAQ,MAAM;AACnC,UAAM,GAAG,MAAM;AACf,UAAM,oBAAoB,SAAS;AACnC,QAAI,mBAAmB;AACrB,YAAM,kBAAkB,MAAM,GAAG,QAAQ,uBAAuB,EAAE,IAAI,kBAAkB,CAAC;AACzF,UAAI,iBAAiB;AACnB,0BAAkB,KAAK,gBAAgB,QAAQ;AAC/C,gCAAwB,KAAK,gBAAgB,cAAc;AAC3D,wBAAgB,YAAY;AAC5B,cAAM,GAAG,MAAM;AAAA,MACjB;AAAA,IACF;AACA,UAAM,cAAc;AAAA,MAClB,OAAO,UAAU;AAAA,MACjB,OAAO,UAAU;AAAA,IACnB;AACA,QAAI,OAAO,KAAK,WAAW,EAAE,QAAQ;AACnC,YAAM,qBAAqB;AAAA,QACzB,YAAY,IAAI,UAAU,QAAQ,YAAY;AAAA,QAC9C,UAAU,EAAE,QAAQ;AAAA,QACpB,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,UAAU,OAAO;AAAA,QACjB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,MAAM,uBAGF;AAAA,EACF,IAAI;AAAA,EACJ,MAAM,QAAQ,OAAO,KAAK;AACxB,UAAM,KAAK,UAAU,OAAO,wBAAwB;AACpD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,WAAW,MAAM,oBAAoB,IAAI,IAAI,EAAE,eAAe,KAAK,CAAC;AAC1E,QAAI,UAAU;AACZ,wBAAkB,KAAK,SAAS,QAAQ;AACxC,8BAAwB,KAAK,SAAS,cAAc;AAAA,IACtD;AACA,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,OAAO,KAAK;AACxB,UAAM,KAAK,UAAU,OAAO,wBAAwB;AACpD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,SAAS,MAAM,GAAG,QAAQ,uBAAuB,EAAE,GAAG,CAAC;AAC7D,QAAI,CAAC,OAAQ,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,4BAA4B,CAAC;AAChF,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAElD,UAAM,SAAU,IAAI,UAAU,QAAQ,IAAI;AAC1C,UAAM,WAAW,MAAM,oBAAoB,QAAQ,IAAI,EAAE,eAAe,KAAK,CAAC;AAC9E,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,iBACJ,UAAU,UAAU,SAAS,OAAO,SAChC,SAAS,SACT,MAAM,0BAA0B,QAAQ,IAAI;AAAA,MAC1C,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,IACzB,CAAC;AAEP,QAAI,eAAe,QAAQ;AACzB,YAAM,GAAG,aAAa,qBAAqB,EAAE,IAAI,EAAE,KAAK,eAAe,IAAI,CAAC,UAAU,MAAM,EAAE,EAAE,EAAE,CAAC;AAAA,IACrG,OAAO;AACL,YAAM,GAAG,aAAa,qBAAqB,EAAE,SAAS,OAAO,CAAC;AAAA,IAChE;AACA,OAAG,OAAO,MAAM;AAChB,UAAM,GAAG,MAAM;AACf,eAAW,iBAAiB,gBAAgB;AAC1C,YAAM,cAAc,yBAAyB,cAAc,UAAU,QAAW,MAAS;AACzF,UAAI,CAAC,OAAO,KAAK,WAAW,EAAE,OAAQ;AACtC,YAAM,qBAAqB;AAAA,QACzB;AAAA,QACA,UAAU,EAAE,QAAQ;AAAA,QACpB,UAAU,cAAc;AAAA,QACxB,gBAAgB,cAAc;AAAA,QAC9B,UAAU,cAAc;AAAA,QACxB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AACA,QAAI,UAAU,UAAU,OAAO,KAAK,SAAS,MAAM,EAAE,QAAQ;AAC3D,YAAM,cAAc,yBAAyB,SAAS,QAAQ,MAAS;AACvE,UAAI,OAAO,KAAK,WAAW,EAAE,QAAQ;AACnC,cAAM,qBAAqB;AAAA,UACzB;AAAA,UACA,UAAU,EAAE,QAAQ;AAAA,UACpB,UAAU;AAAA,UACV,gBAAgB,SAAS;AAAA,UACzB,UAAU,SAAS;AAAA,UACnB,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AACA,UAAM,2BAA2B,KAAK;AAAA,MACpC,YAAY,EAAE,QAAQ;AAAA,MACtB,UAAU;AAAA,MACV,gBAAgB,UAAU,kBAAkB,OAAO;AAAA,MACnD,UAAU,UAAU,YAAY,OAAO;AAAA,MACvC,QAAQ;AAAA,IACV,CAAC;AACD,UAAM,oBAAoB;AAAA,MACxB,YAAY,IAAI,UAAU,QAAQ,YAAY;AAAA,MAC9C,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX;AAAA,QACA,gBAAgB,UAAU,kBAAkB,OAAO;AAAA,QACnD,UAAU,UAAU,YAAY,OAAO;AAAA,MACzC;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AACD,WAAO,EAAE,WAAW,GAAG;AAAA,EACzB;AAAA,EACA,UAAU,OAAO,EAAE,UAAU,MAAM;AACjC,UAAM,SAAS,UAAU;AACzB,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,WAAO;AAAA,MACL,aAAa,UAAU,iCAAiC,wBAAwB;AAAA,MAChF,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,aAAa;AAAA,MACtC,UAAU,OAAO;AAAA,MACjB,gBAAgB,OAAO;AAAA,MACvB,gBAAgB;AAAA,MAChB,SAAS;AAAA,QACP,MAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAuC,QAAQ;AAC/D,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,QAAI,SAAS,MAAM,GAAG,QAAQ,uBAAuB,EAAE,IAAI,OAAO,GAAG,CAAC;AACtE,QAAI,CAAC,QAAQ;AACX,YAAM,UAAU,MAAM,eAAe,IAAI,OAAO,SAAS;AACzD,eAAS,GAAG,OAAO,uBAAuB;AAAA,QACxC,IAAI,OAAO;AAAA,QACX;AAAA,QACA,gBAAgB,OAAO;AAAA,QACvB,UAAU,OAAO;AAAA,QACjB,MAAM,OAAO,QAAQ;AAAA,QACrB,KAAK,OAAO,OAAO;AAAA,QACnB,SAAS,OAAO,WAAW;AAAA,QAC3B,eAAe,OAAO,iBAAiB;AAAA,QACvC,WAAW,OAAO;AAAA,QAClB,UAAU,OAAO;AAAA,QACjB,aAAa,OAAO,eAAe;AAAA,QACnC,YAAY,OAAO,cAAc;AAAA,QACjC,YAAY,OAAO,aAAa,UAAU,OAAO,UAAU,IAAI;AAAA,QAC/D,UAAU,OAAO,WAAW,UAAU,OAAO,QAAQ,IAAI;AAAA,QACzD,oBAAoB,OAAO,sBAAsB;AAAA,QACjD,WAAW,IAAI,KAAK,OAAO,SAAS;AAAA,QACpC,WAAW,IAAI,KAAK,OAAO,SAAS;AAAA,MACtC,CAAC;AACD,SAAG,QAAQ,MAAM;AAAA,IACnB;AACA,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAClD,yBAAqB,QAAQ,MAAM;AACnC,QAAI,OAAO,QAAQ,QAAQ;AACzB,YAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,YAAM,kCAAkC,IAAI,QAAQ,OAAO,QAAQ,UAAU;AAAA,IAC/E;AACA,UAAM,GAAG,MAAM;AACf,QAAI,OAAO,UAAU,OAAO,KAAK,OAAO,MAAM,EAAE,QAAQ;AACtD,YAAM,qBAAqB;AAAA,QACzB,YAAY,IAAI,UAAU,QAAQ,YAAY;AAAA,QAC9C,UAAU,EAAE,QAAQ;AAAA,QACpB,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,UAAU,OAAO;AAAA,QACjB,QAAQ,OAAO;AAAA,MACjB,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,eAAe,gCAAgD;AAC7D,QAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,QAAM,UAAU,UAAU,qCAAqC,qBAAqB;AACpF,QAAM,IAAI,cAAc,KAAK;AAAA,IAC3B,OAAO;AAAA,IACP,aAAa,EAAE,KAAK,QAAQ;AAAA,IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,SAAS,MAAM,aAAa,QAAQ,aAAa,CAAC;AAAA,EAC/E,CAAC;AACH;AAEA,eAAe,+BAA+B,OAAgC;AAC5E,MAAI,iBAAiB,oCAAoC;AACvD,UAAM,aAAa,mBAAmB,KAAK;AAC3C,UAAM,UAAU,gBAAgB,KAAK,EAAE,YAAY;AACnD,QACE,eAAe,yCACf,QAAQ,SAAS,qCAAqC,GACtD;AACA,YAAM,8BAA8B;AAAA,IACtC;AAAA,EACF;AACA,QAAM;AACR;AAEA,gBAAgB,oBAAoB;AACpC,gBAAgB,oBAAoB;AACpC,gBAAgB,oBAAoB;",
4
+ "sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { buildChanges, requireId, parseWithCustomFields, setCustomFieldsIfAny, emitCrudSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { UniqueConstraintViolationException } from '@mikro-orm/core'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { loadCustomFieldSnapshot, buildCustomFieldResetMap } from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { E } from '#generated/entities.ids.generated'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport {\n CatalogProductVariant,\n CatalogProductPrice,\n CatalogProduct,\n CatalogOffer,\n CatalogPriceKind,\n} from '../data/entities'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { Attachment } from '@open-mercato/core/modules/attachments/data/entities'\nimport {\n variantCreateSchema,\n variantUpdateSchema,\n type VariantCreateInput,\n type VariantUpdateInput,\n} from '../data/validators'\nimport {\n cloneJson,\n commandActorScope,\n ensureOrganizationScope,\n ensureTenantScope,\n emitCatalogQueryIndexEvent,\n extractUndoPayload,\n requireProduct,\n toNumericString,\n getErrorConstraint,\n getErrorMessage,\n} from './shared'\nimport { SalesTaxRate } from '@open-mercato/core/modules/sales/data/entities'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\n\nconst variantCrudEvents: CrudEventsConfig = {\n module: 'catalog',\n entity: 'variant',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\ntype VariantSnapshot = {\n id: string\n productId: string\n organizationId: string\n tenantId: string\n name: string | null\n sku: string | null\n barcode: string | null\n statusEntryId: string | null\n isDefault: boolean\n isActive: boolean\n weightValue: string | null\n weightUnit: string | null\n taxRateId: string | null\n taxRate: string | null\n dimensions: Record<string, unknown> | null\n metadata: Record<string, unknown> | null\n optionValues: Record<string, string> | null\n customFieldsetCode: string | null\n createdAt: string\n updatedAt: string\n custom: Record<string, unknown> | null\n prices?: VariantPriceSnapshot[] | null\n}\n\ntype VariantUndoPayload = {\n before?: VariantSnapshot | null\n after?: VariantSnapshot | null\n previousDefaultVariantId?: string | null\n}\n\nconst VARIANT_CHANGE_KEYS = [\n 'name',\n 'sku',\n 'barcode',\n 'statusEntryId',\n 'isDefault',\n 'isActive',\n 'weightValue',\n 'weightUnit',\n 'taxRateId',\n 'taxRate',\n 'dimensions',\n 'optionValues',\n 'customFieldsetCode',\n 'metadata',\n] as const satisfies readonly string[]\n\nasync function loadVariantSnapshot(\n em: EntityManager,\n id: string,\n options: { includePrices?: boolean } = {}\n): Promise<VariantSnapshot | null> {\n const record = await em.findOne(CatalogProductVariant, { id, deletedAt: null })\n if (!record) return null\n const prices = options.includePrices\n ? await loadVariantPriceSnapshots(em, record.id, {\n tenantId: record.tenantId,\n organizationId: record.organizationId,\n })\n : null\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.catalog.catalog_product_variant,\n recordId: record.id,\n tenantId: record.tenantId,\n organizationId: record.organizationId,\n })\n const productId = typeof record.product === 'string' ? record.product : record.product.id\n return {\n id: record.id,\n productId,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n name: record.name ?? null,\n sku: record.sku ?? null,\n barcode: record.barcode ?? null,\n statusEntryId: record.statusEntryId ?? null,\n isDefault: record.isDefault,\n isActive: record.isActive,\n weightValue: record.weightValue ?? null,\n weightUnit: record.weightUnit ?? null,\n taxRateId: record.taxRateId ?? null,\n taxRate: record.taxRate ?? null,\n dimensions: record.dimensions ? cloneJson(record.dimensions) : null,\n metadata: record.metadata ? cloneJson(record.metadata) : null,\n optionValues: record.optionValues ? cloneJson(record.optionValues) : null,\n customFieldsetCode: record.customFieldsetCode ?? null,\n createdAt: record.createdAt.toISOString(),\n updatedAt: record.updatedAt.toISOString(),\n custom: Object.keys(custom).length ? custom : null,\n prices: prices && prices.length ? prices : null,\n }\n}\n\nfunction applyVariantSnapshot(record: CatalogProductVariant, snapshot: VariantSnapshot): void {\n record.organizationId = snapshot.organizationId\n record.tenantId = snapshot.tenantId\n record.name = snapshot.name ?? null\n record.sku = snapshot.sku ?? null\n record.barcode = snapshot.barcode ?? null\n record.statusEntryId = snapshot.statusEntryId ?? null\n record.isDefault = snapshot.isDefault\n record.isActive = snapshot.isActive\n record.weightValue = snapshot.weightValue ?? null\n record.weightUnit = snapshot.weightUnit ?? null\n record.taxRateId = snapshot.taxRateId ?? null\n record.taxRate = snapshot.taxRate ?? null\n record.dimensions = snapshot.dimensions ? cloneJson(snapshot.dimensions) : null\n record.metadata = snapshot.metadata ? cloneJson(snapshot.metadata) : null\n record.optionValues = snapshot.optionValues ? cloneJson(snapshot.optionValues) : null\n record.customFieldsetCode = snapshot.customFieldsetCode ?? null\n record.createdAt = new Date(snapshot.createdAt)\n record.updatedAt = new Date(snapshot.updatedAt)\n}\n\nasync function resolveVariantTaxRate(\n em: EntityManager,\n product: CatalogProduct,\n taxRateIdInput: string | null | undefined,\n taxRateInput: number | string | null | undefined\n): Promise<{ taxRateId: string | null; taxRate: string | null }> {\n const organizationId = product.organizationId\n const tenantId = product.tenantId\n const normalizedRate =\n taxRateInput === null || taxRateInput === undefined\n ? null\n : (() => {\n const numeric = typeof taxRateInput === 'string' ? Number(taxRateInput) : taxRateInput\n return Number.isFinite(numeric) ? toNumericString(numeric) : null\n })()\n if (taxRateIdInput === null) {\n return { taxRateId: product.taxRateId ?? null, taxRate: product.taxRate ?? null }\n }\n if (!taxRateIdInput) {\n return { taxRateId: product.taxRateId ?? null, taxRate: product.taxRate ?? normalizedRate }\n }\n const record = await em.findOne(SalesTaxRate, {\n id: taxRateIdInput,\n organizationId,\n tenantId,\n deletedAt: null,\n })\n if (!record) {\n throw new CrudHttpError(400, { error: 'Tax class not found' })\n }\n return { taxRateId: taxRateIdInput, taxRate: record.rate ?? normalizedRate }\n}\n\ntype VariantPriceSnapshot = {\n id: string\n variantId: string | null\n productId: string | null\n offerId: string | null\n organizationId: string\n tenantId: string\n priceKindId: string\n priceKindCode: string\n currencyCode: string\n kind: string\n minQuantity: number\n maxQuantity: number | null\n unitPriceNet: string | null\n unitPriceGross: string | null\n taxRate: string | null\n taxAmount: string | null\n channelId: string | null\n userId: string | null\n userGroupId: string | null\n customerId: string | null\n customerGroupId: string | null\n metadata: Record<string, unknown> | null\n startsAt: string | null\n endsAt: string | null\n createdAt: string\n updatedAt: string\n custom: Record<string, unknown> | null\n}\n\nasync function loadVariantPriceSnapshots(\n em: EntityManager,\n variantId: string,\n scope: { tenantId: string; organizationId: string }\n): Promise<VariantPriceSnapshot[]> {\n const prices = await findWithDecryption(\n em,\n CatalogProductPrice,\n { variant: variantId, tenantId: scope.tenantId, organizationId: scope.organizationId },\n { populate: ['priceKind', 'product', 'offer'] },\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n const snapshots: VariantPriceSnapshot[] = []\n for (const price of prices) {\n const variantRef = price.variant\n const variantIdValue =\n typeof variantRef === 'string'\n ? variantRef\n : variantRef\n ? variantRef.id\n : null\n const productRef = price.product\n ? price.product\n : typeof price.variant === 'object' && price.variant\n ? price.variant.product\n : null\n const productId =\n typeof productRef === 'string'\n ? productRef\n : productRef\n ? productRef.id\n : null\n const priceKindRef = price.priceKind\n const priceKindId =\n typeof priceKindRef === 'string'\n ? priceKindRef\n : priceKindRef\n ? priceKindRef.id\n : null\n if (!priceKindId) {\n throw new CrudHttpError(400, { error: 'Price is missing price kind metadata.' })\n }\n const priceKindCode =\n typeof priceKindRef === 'object' && priceKindRef ? priceKindRef.code : price.kind\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.catalog.catalog_product_price,\n recordId: price.id,\n tenantId: price.tenantId,\n organizationId: price.organizationId,\n })\n snapshots.push({\n id: price.id,\n variantId: variantIdValue,\n productId,\n offerId: typeof price.offer === 'string' ? price.offer : price.offer ? price.offer.id : null,\n organizationId: price.organizationId,\n tenantId: price.tenantId,\n priceKindId,\n priceKindCode,\n currencyCode: price.currencyCode,\n kind: price.kind,\n minQuantity: price.minQuantity,\n maxQuantity: price.maxQuantity ?? null,\n unitPriceNet: price.unitPriceNet ?? null,\n unitPriceGross: price.unitPriceGross ?? null,\n taxRate: price.taxRate ?? null,\n taxAmount: price.taxAmount ?? null,\n channelId: price.channelId ?? null,\n userId: price.userId ?? null,\n userGroupId: price.userGroupId ?? null,\n customerId: price.customerId ?? null,\n customerGroupId: price.customerGroupId ?? null,\n metadata: price.metadata ? cloneJson(price.metadata) : null,\n startsAt: price.startsAt ? price.startsAt.toISOString() : null,\n endsAt: price.endsAt ? price.endsAt.toISOString() : null,\n createdAt: price.createdAt.toISOString(),\n updatedAt: price.updatedAt.toISOString(),\n custom: Object.keys(custom).length ? custom : null,\n })\n }\n return snapshots\n}\n\nasync function restoreVariantPricesFromSnapshots(\n em: EntityManager,\n variant: CatalogProductVariant,\n snapshots: VariantPriceSnapshot[],\n dataEngine: DataEngine\n): Promise<void> {\n if (!snapshots.length) return\n const productRef =\n typeof variant.product === 'string'\n ? await requireProduct(em, variant.product, {\n tenantId: variant.tenantId,\n organizationId: variant.organizationId,\n })\n : variant.product\n for (const snapshot of snapshots) {\n const product =\n snapshot.productId && snapshot.productId !== productRef.id\n ? em.getReference(CatalogProduct, snapshot.productId)\n : productRef\n const offer = snapshot.offerId ? em.getReference(CatalogOffer, snapshot.offerId) : null\n const priceKind = em.getReference(CatalogPriceKind, snapshot.priceKindId)\n let record = await em.findOne(CatalogProductPrice, { id: snapshot.id })\n if (!record) {\n record = em.create(CatalogProductPrice, {\n id: snapshot.id,\n variant,\n product,\n offer,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n currencyCode: snapshot.currencyCode,\n priceKind,\n kind: snapshot.priceKindCode || snapshot.kind,\n minQuantity: snapshot.minQuantity,\n maxQuantity: snapshot.maxQuantity ?? null,\n unitPriceNet: snapshot.unitPriceNet ?? null,\n unitPriceGross: snapshot.unitPriceGross ?? null,\n taxRate: snapshot.taxRate ?? null,\n taxAmount: snapshot.taxAmount ?? null,\n channelId: snapshot.channelId ?? null,\n userId: snapshot.userId ?? null,\n userGroupId: snapshot.userGroupId ?? null,\n customerId: snapshot.customerId ?? null,\n customerGroupId: snapshot.customerGroupId ?? null,\n metadata: snapshot.metadata ? cloneJson(snapshot.metadata) : null,\n startsAt: snapshot.startsAt ? new Date(snapshot.startsAt) : null,\n endsAt: snapshot.endsAt ? new Date(snapshot.endsAt) : null,\n createdAt: new Date(snapshot.createdAt),\n updatedAt: new Date(snapshot.updatedAt),\n })\n em.persist(record)\n } else {\n record.variant = variant\n record.product = product\n record.offer = offer\n record.priceKind = priceKind\n record.organizationId = snapshot.organizationId\n record.tenantId = snapshot.tenantId\n record.currencyCode = snapshot.currencyCode\n record.kind = snapshot.priceKindCode || snapshot.kind\n record.minQuantity = snapshot.minQuantity\n record.maxQuantity = snapshot.maxQuantity ?? null\n record.unitPriceNet = snapshot.unitPriceNet ?? null\n record.unitPriceGross = snapshot.unitPriceGross ?? null\n record.taxRate = snapshot.taxRate ?? null\n record.taxAmount = snapshot.taxAmount ?? null\n record.channelId = snapshot.channelId ?? null\n record.userId = snapshot.userId ?? null\n record.userGroupId = snapshot.userGroupId ?? null\n record.customerId = snapshot.customerId ?? null\n record.customerGroupId = snapshot.customerGroupId ?? null\n record.metadata = snapshot.metadata ? cloneJson(snapshot.metadata) : null\n record.startsAt = snapshot.startsAt ? new Date(snapshot.startsAt) : null\n record.endsAt = snapshot.endsAt ? new Date(snapshot.endsAt) : null\n record.createdAt = new Date(snapshot.createdAt)\n record.updatedAt = new Date(snapshot.updatedAt)\n }\n }\n await em.flush()\n for (const snapshot of snapshots) {\n if (!snapshot.custom || !Object.keys(snapshot.custom).length) continue\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: E.catalog.catalog_product_price,\n recordId: snapshot.id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n values: snapshot.custom,\n })\n }\n}\n\ntype MetadataSplitResult = {\n metadata: Record<string, unknown> | null\n optionValues: Record<string, string> | null\n hadOptionValues: boolean\n}\n\nfunction splitOptionValuesFromMetadata(\n metadata?: Record<string, unknown> | null\n): MetadataSplitResult {\n if (!metadata || typeof metadata !== 'object' || Array.isArray(metadata)) {\n return {\n metadata: metadata ? cloneJson(metadata) : null,\n optionValues: null,\n hadOptionValues: false,\n }\n }\n const { optionValues, ...rest } = metadata as Record<string, unknown> & {\n optionValues?: unknown\n }\n const normalizedMetadata = Object.keys(rest).length ? cloneJson(rest) : null\n return {\n metadata: normalizedMetadata,\n optionValues: normalizeOptionValues(optionValues),\n hadOptionValues: optionValues !== undefined,\n }\n}\n\nfunction normalizeOptionValues(input: unknown): Record<string, string> | null {\n if (!input || typeof input !== 'object' || Array.isArray(input)) return null\n const normalized: Record<string, string> = {}\n for (const [rawKey, rawValue] of Object.entries(input)) {\n if (typeof rawValue !== 'string') continue\n const key = rawKey.trim()\n const value = rawValue.trim()\n if (!key || !value) continue\n normalized[key] = value\n }\n return Object.keys(normalized).length ? normalized : null\n}\n\nfunction resolveProductId(record: CatalogProductVariant): string {\n return typeof record.product === 'string' ? record.product : record.product.id\n}\n\nasync function enforceSingleDefaultVariant(\n em: EntityManager,\n variant: CatalogProductVariant\n): Promise<string | null> {\n if (!variant.isDefault) return null\n const productId = resolveProductId(variant)\n const existingDefault = await em.findOne(\n CatalogProductVariant,\n { product: productId, isDefault: true, deletedAt: null, id: { $ne: variant.id } },\n { fields: ['id', 'isDefault'] }\n )\n if (existingDefault) {\n existingDefault.isDefault = false\n return existingDefault.id\n }\n return null\n}\n\nasync function aggregateVariantMediaToProduct(\n em: EntityManager,\n variant: CatalogProductVariant\n): Promise<void> {\n const productId = resolveProductId(variant)\n const buildKey = (\n attachment: Pick<Attachment, 'fileName' | 'fileSize' | 'storageDriver' | 'partitionCode' | 'storagePath'>\n ) =>\n [\n attachment.fileName?.trim() ?? '',\n attachment.fileSize ?? '',\n attachment.storageDriver ?? '',\n attachment.partitionCode ?? '',\n ].join('|')\n const attachments = await em.find(\n Attachment,\n {\n entityId: E.catalog.catalog_product_variant,\n recordId: variant.id,\n organizationId: variant.organizationId ?? undefined,\n tenantId: variant.tenantId ?? undefined,\n },\n {\n fields: [\n 'id',\n 'partitionCode',\n 'fileName',\n 'mimeType',\n 'fileSize',\n 'storageDriver',\n 'storagePath',\n 'storageMetadata',\n 'url',\n 'organizationId',\n 'tenantId',\n 'fileSize',\n 'storageDriver',\n 'partitionCode',\n ],\n }\n )\n if (!attachments.length) return\n const existing = await em.find(\n Attachment,\n {\n entityId: E.catalog.catalog_product,\n recordId: productId,\n organizationId: variant.organizationId ?? undefined,\n tenantId: variant.tenantId ?? undefined,\n },\n {\n fields: ['storagePath', 'fileName', 'fileSize', 'storageDriver', 'partitionCode'],\n }\n )\n const existingKeys = new Set(existing.map((item) => buildKey(item)))\n let created = 0\n for (const source of attachments) {\n const key = buildKey(source)\n if (existingKeys.has(key)) continue\n const clone = em.create(Attachment, {\n entityId: E.catalog.catalog_product,\n recordId: productId,\n organizationId: source.organizationId ?? variant.organizationId ?? null,\n tenantId: source.tenantId ?? variant.tenantId ?? null,\n partitionCode: source.partitionCode,\n fileName: source.fileName,\n mimeType: source.mimeType,\n fileSize: source.fileSize,\n storageDriver: source.storageDriver,\n storagePath: source.storagePath,\n storageMetadata: source.storageMetadata ? cloneJson(source.storageMetadata) : null,\n url: source.url,\n })\n em.persist(clone)\n existingKeys.add(key)\n created += 1\n }\n if (created > 0) {\n await em.flush()\n }\n}\n\nconst createVariantCommand: CommandHandler<VariantCreateInput, { variantId: string; previousDefaultVariantId?: string | null }> = {\n id: 'catalog.variants.create',\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(variantCreateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const product = await requireProduct(em, parsed.productId, commandActorScope(ctx))\n ensureTenantScope(ctx, product.tenantId)\n ensureOrganizationScope(ctx, product.organizationId)\n const { taxRateId, taxRate } = await resolveVariantTaxRate(\n em,\n product,\n parsed.taxRateId ?? null,\n parsed.taxRate\n )\n\n const metadataSplit = splitOptionValuesFromMetadata(parsed.metadata)\n const resolvedOptionValues =\n parsed.optionValues ?? (metadataSplit.hadOptionValues ? metadataSplit.optionValues : null)\n\n const now = new Date()\n const record = em.create(CatalogProductVariant, {\n organizationId: product.organizationId,\n tenantId: product.tenantId,\n product,\n name: parsed.name ?? null,\n sku: parsed.sku ?? null,\n barcode: parsed.barcode ?? null,\n statusEntryId: parsed.statusEntryId ?? null,\n isDefault: parsed.isDefault ?? false,\n isActive: parsed.isActive ?? true,\n weightValue: toNumericString(parsed.weightValue),\n weightUnit: parsed.weightUnit ?? null,\n taxRateId,\n taxRate,\n dimensions: parsed.dimensions ? cloneJson(parsed.dimensions) : null,\n metadata: metadataSplit.metadata,\n optionValues: resolvedOptionValues ? cloneJson(resolvedOptionValues) : null,\n customFieldsetCode: parsed.customFieldsetCode ?? null,\n createdAt: now,\n updatedAt: now,\n })\n em.persist(record)\n try {\n await em.flush()\n } catch (error) {\n await rethrowVariantUniqueConstraint(error)\n }\n let previousDefaultVariantId: string | null = null\n if (record.isDefault) {\n previousDefaultVariantId = await enforceSingleDefaultVariant(em, record)\n try {\n await em.flush()\n } catch (error) {\n await rethrowVariantUniqueConstraint(error)\n }\n }\n await aggregateVariantMediaToProduct(em, record)\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n values: custom,\n })\n await emitCatalogQueryIndexEvent(ctx, {\n entityType: E.catalog.catalog_product_variant,\n recordId: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n action: 'created',\n })\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n action: 'created',\n entity: record,\n identifiers: {\n id: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n },\n events: variantCrudEvents,\n })\n return { variantId: record.id, previousDefaultVariantId }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadVariantSnapshot(em, result.variantId)\n },\n buildLog: async ({ result, snapshots }) => {\n const after = snapshots.after as VariantSnapshot | undefined\n if (!after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('catalog.audit.variants.create', 'Create product variant'),\n resourceKind: 'catalog.variant',\n resourceId: result.variantId,\n parentResourceKind: 'catalog.product',\n parentResourceId: after.productId ?? null,\n tenantId: after.tenantId,\n organizationId: after.organizationId,\n snapshotAfter: after,\n payload: {\n undo: {\n after,\n previousDefaultVariantId: (result as { previousDefaultVariantId?: string | null })?.previousDefaultVariantId ?? null,\n } satisfies VariantUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<VariantUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(CatalogProductVariant, { id: after.id })\n if (!record) return\n ensureTenantScope(ctx, record.tenantId)\n ensureOrganizationScope(ctx, record.organizationId)\n em.remove(record)\n await em.flush()\n if (payload?.previousDefaultVariantId) {\n const previousDefault = await em.findOne(CatalogProductVariant, { id: payload.previousDefaultVariantId })\n if (previousDefault) {\n ensureTenantScope(ctx, previousDefault.tenantId)\n ensureOrganizationScope(ctx, previousDefault.organizationId)\n previousDefault.isDefault = true\n await em.flush()\n }\n }\n const resetValues = buildCustomFieldResetMap(undefined, after.custom ?? undefined)\n if (Object.keys(resetValues).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: after.id,\n organizationId: after.organizationId,\n tenantId: after.tenantId,\n values: resetValues,\n })\n }\n },\n}\n\nconst updateVariantCommand: CommandHandler<VariantUpdateInput, { variantId: string; previousDefaultVariantId?: string | null }> = {\n id: 'catalog.variants.update',\n async prepare(input, ctx) {\n const id = requireId(input, 'Variant id is required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadVariantSnapshot(em, id)\n if (snapshot) {\n ensureTenantScope(ctx, snapshot.tenantId)\n ensureOrganizationScope(ctx, snapshot.organizationId)\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(variantUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(CatalogProductVariant, { id: parsed.id, deletedAt: null })\n if (!record) throw new CrudHttpError(404, { error: 'Catalog variant not found' })\n ensureTenantScope(ctx, record.tenantId)\n ensureOrganizationScope(ctx, record.organizationId)\n const product = await requireProduct(em, record.product.id, {\n tenantId: record.tenantId,\n organizationId: record.organizationId,\n })\n\n if (!product) throw new CrudHttpError(400, { error: 'Variant product missing' })\n\n const taxRateProvided = parsed.taxRateId !== undefined || parsed.taxRate !== undefined\n const resolvedTaxRate = taxRateProvided\n ? await resolveVariantTaxRate(em, product, parsed.taxRateId ?? null, parsed.taxRate)\n : null\n\n if (parsed.name !== undefined) record.name = parsed.name ?? null\n if (parsed.sku !== undefined) record.sku = parsed.sku ?? null\n if (parsed.barcode !== undefined) record.barcode = parsed.barcode ?? null\n if (parsed.statusEntryId !== undefined) record.statusEntryId = parsed.statusEntryId ?? null\n if (parsed.isDefault !== undefined) record.isDefault = parsed.isDefault\n if (parsed.isActive !== undefined) record.isActive = parsed.isActive\n if (Object.prototype.hasOwnProperty.call(parsed, 'weightValue')) {\n record.weightValue = toNumericString(parsed.weightValue)\n }\n if (parsed.weightUnit !== undefined) record.weightUnit = parsed.weightUnit ?? null\n if (parsed.dimensions !== undefined) {\n record.dimensions = parsed.dimensions ? cloneJson(parsed.dimensions) : null\n }\n let metadataSplit: MetadataSplitResult | null = null\n if (parsed.metadata !== undefined) {\n metadataSplit = splitOptionValuesFromMetadata(parsed.metadata)\n record.metadata = metadataSplit.metadata\n }\n if (parsed.optionValues !== undefined) {\n record.optionValues = parsed.optionValues ? cloneJson(parsed.optionValues) : null\n } else if (metadataSplit?.hadOptionValues) {\n record.optionValues = metadataSplit.optionValues ? cloneJson(metadataSplit.optionValues) : null\n }\n if (taxRateProvided) {\n record.taxRateId = resolvedTaxRate?.taxRateId ?? null\n record.taxRate = resolvedTaxRate?.taxRate ?? null\n }\n if (parsed.customFieldsetCode !== undefined) {\n record.customFieldsetCode = parsed.customFieldsetCode ?? null\n }\n\n let previousDefaultVariantId: string | null = null\n if (parsed.isDefault === true) {\n previousDefaultVariantId = await enforceSingleDefaultVariant(em, record)\n }\n try {\n await em.flush()\n } catch (error) {\n await rethrowVariantUniqueConstraint(error)\n }\n await aggregateVariantMediaToProduct(em, record)\n if (custom && Object.keys(custom).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n values: custom,\n })\n }\n await emitCatalogQueryIndexEvent(ctx, {\n entityType: E.catalog.catalog_product_variant,\n recordId: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n action: 'updated',\n })\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n action: 'updated',\n entity: record,\n identifiers: {\n id: record.id,\n organizationId: record.organizationId,\n tenantId: record.tenantId,\n },\n events: variantCrudEvents,\n })\n return { variantId: record.id, previousDefaultVariantId }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return loadVariantSnapshot(em, result.variantId)\n },\n buildLog: async ({ result, snapshots }) => {\n const before = snapshots.before as VariantSnapshot | undefined\n const after = snapshots.after as VariantSnapshot | undefined\n if (!before || !after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('catalog.audit.variants.update', 'Update product variant'),\n resourceKind: 'catalog.variant',\n resourceId: before.id,\n parentResourceKind: 'catalog.product',\n parentResourceId: before.productId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: after,\n changes: buildChanges(\n before as Record<string, unknown>,\n after as Record<string, unknown>,\n VARIANT_CHANGE_KEYS\n ),\n payload: {\n undo: {\n before,\n after,\n previousDefaultVariantId:\n (result as { previousDefaultVariantId?: string | null })?.previousDefaultVariantId ?? null,\n } satisfies VariantUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<VariantUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const after = payload?.after\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let record = await em.findOne(CatalogProductVariant, { id: before.id })\n if (!record) {\n const product = await requireProduct(em, before.productId, {\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n })\n record = em.create(CatalogProductVariant, {\n id: before.id,\n product,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n name: before.name ?? null,\n sku: before.sku ?? null,\n barcode: before.barcode ?? null,\n statusEntryId: before.statusEntryId ?? null,\n isDefault: before.isDefault,\n isActive: before.isActive,\n weightValue: before.weightValue ?? null,\n weightUnit: before.weightUnit ?? null,\n dimensions: before.dimensions ? cloneJson(before.dimensions) : null,\n metadata: before.metadata ? cloneJson(before.metadata) : null,\n optionValues: before.optionValues ? cloneJson(before.optionValues) : null,\n customFieldsetCode: before.customFieldsetCode ?? null,\n createdAt: new Date(before.createdAt),\n updatedAt: new Date(before.updatedAt),\n })\n em.persist(record)\n }\n ensureTenantScope(ctx, before.tenantId)\n ensureOrganizationScope(ctx, before.organizationId)\n applyVariantSnapshot(record, before)\n await em.flush()\n const previousDefaultId = payload?.previousDefaultVariantId\n if (previousDefaultId) {\n const previousDefault = await em.findOne(CatalogProductVariant, { id: previousDefaultId })\n if (previousDefault) {\n ensureTenantScope(ctx, previousDefault.tenantId)\n ensureOrganizationScope(ctx, previousDefault.organizationId)\n previousDefault.isDefault = true\n await em.flush()\n }\n }\n const resetValues = buildCustomFieldResetMap(\n before.custom ?? undefined,\n after?.custom ?? undefined\n )\n if (Object.keys(resetValues).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n values: resetValues,\n })\n }\n },\n}\n\nconst deleteVariantCommand: CommandHandler<\n { body?: Record<string, unknown>; query?: Record<string, unknown> },\n { variantId: string }\n> = {\n id: 'catalog.variants.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Variant id is required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadVariantSnapshot(em, id, { includePrices: true })\n if (snapshot) {\n ensureTenantScope(ctx, snapshot.tenantId)\n ensureOrganizationScope(ctx, snapshot.organizationId)\n }\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Variant id is required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const record = await em.findOne(CatalogProductVariant, { id })\n if (!record) throw new CrudHttpError(404, { error: 'Catalog variant not found' })\n ensureTenantScope(ctx, record.tenantId)\n ensureOrganizationScope(ctx, record.organizationId)\n\n const baseEm = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadVariantSnapshot(baseEm, id, { includePrices: true })\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n const priceSnapshots =\n snapshot?.prices && snapshot.prices.length\n ? snapshot.prices\n : await loadVariantPriceSnapshots(baseEm, id, {\n tenantId: record.tenantId,\n organizationId: record.organizationId,\n })\n\n if (priceSnapshots.length) {\n await em.nativeDelete(CatalogProductPrice, { id: { $in: priceSnapshots.map((price) => price.id) } })\n } else {\n await em.nativeDelete(CatalogProductPrice, { variant: record })\n }\n em.remove(record)\n await em.flush()\n for (const priceSnapshot of priceSnapshots) {\n const resetValues = buildCustomFieldResetMap(priceSnapshot.custom ?? undefined, undefined)\n if (!Object.keys(resetValues).length) continue\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: E.catalog.catalog_product_price,\n recordId: priceSnapshot.id,\n organizationId: priceSnapshot.organizationId,\n tenantId: priceSnapshot.tenantId,\n values: resetValues,\n })\n }\n if (snapshot?.custom && Object.keys(snapshot.custom).length) {\n const resetValues = buildCustomFieldResetMap(snapshot.custom, undefined)\n if (Object.keys(resetValues).length) {\n await setCustomFieldsIfAny({\n dataEngine,\n entityId: E.catalog.catalog_product_variant,\n recordId: id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n values: resetValues,\n })\n }\n }\n await emitCatalogQueryIndexEvent(ctx, {\n entityType: E.catalog.catalog_product_variant,\n recordId: id,\n organizationId: snapshot?.organizationId ?? record.organizationId,\n tenantId: snapshot?.tenantId ?? record.tenantId,\n action: 'deleted',\n })\n await emitCrudSideEffects({\n dataEngine: ctx.container.resolve('dataEngine') as DataEngine,\n action: 'deleted',\n entity: record,\n identifiers: {\n id,\n organizationId: snapshot?.organizationId ?? record.organizationId,\n tenantId: snapshot?.tenantId ?? record.tenantId,\n },\n events: variantCrudEvents,\n })\n return { variantId: id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as VariantSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('catalog.audit.variants.delete', 'Delete product variant'),\n resourceKind: 'catalog.variant',\n resourceId: before.id,\n parentResourceKind: 'catalog.product',\n parentResourceId: before.productId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n } satisfies VariantUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<VariantUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let record = await em.findOne(CatalogProductVariant, { id: before.id })\n if (!record) {\n const product = await requireProduct(em, before.productId, {\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n })\n record = em.create(CatalogProductVariant, {\n id: before.id,\n product,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n name: before.name ?? null,\n sku: before.sku ?? null,\n barcode: before.barcode ?? null,\n statusEntryId: before.statusEntryId ?? null,\n isDefault: before.isDefault,\n isActive: before.isActive,\n weightValue: before.weightValue ?? null,\n weightUnit: before.weightUnit ?? null,\n dimensions: before.dimensions ? cloneJson(before.dimensions) : null,\n metadata: before.metadata ? cloneJson(before.metadata) : null,\n customFieldsetCode: before.customFieldsetCode ?? null,\n createdAt: new Date(before.createdAt),\n updatedAt: new Date(before.updatedAt),\n })\n em.persist(record)\n }\n ensureTenantScope(ctx, before.tenantId)\n ensureOrganizationScope(ctx, before.organizationId)\n applyVariantSnapshot(record, before)\n if (before.prices?.length) {\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await restoreVariantPricesFromSnapshots(em, record, before.prices, dataEngine)\n }\n await em.flush()\n if (before.custom && Object.keys(before.custom).length) {\n await setCustomFieldsIfAny({\n dataEngine: ctx.container.resolve('dataEngine'),\n entityId: E.catalog.catalog_product_variant,\n recordId: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n values: before.custom,\n })\n }\n },\n}\n\nasync function throwDuplicateVariantSkuError(): Promise<never> {\n const { translate } = await resolveTranslations()\n const message = translate('catalog.variants.errors.skuExists', 'SKU already in use.')\n throw new CrudHttpError(400, {\n error: message,\n fieldErrors: { sku: message },\n details: [{ path: ['sku'], message, code: 'duplicate', origin: 'validation' }],\n })\n}\n\nasync function rethrowVariantUniqueConstraint(error: unknown): Promise<never> {\n if (error instanceof UniqueConstraintViolationException) {\n const constraint = getErrorConstraint(error)\n const message = getErrorMessage(error).toLowerCase()\n if (\n constraint === 'catalog_product_variants_sku_unique' ||\n message.includes('catalog_product_variants_sku_unique')\n ) {\n await throwDuplicateVariantSkuError()\n }\n }\n throw error\n}\n\nregisterCommand(createVariantCommand)\nregisterCommand(updateVariantCommand)\nregisterCommand(deleteVariantCommand)\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -10,7 +10,7 @@ import { collectCustomFieldValues } from "@open-mercato/ui/backend/utils/customF
10
10
  import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
11
11
  import { updateCrud, deleteCrud } from "@open-mercato/ui/backend/utils/crud";
12
12
  import { flash } from "@open-mercato/ui/backend/FlashMessages";
13
- import { ActivitiesSection, NotesSection } from "@open-mercato/ui/backend/detail";
13
+ import { ActivitiesSection, NotesSection, RecordNotFoundState } from "@open-mercato/ui/backend/detail";
14
14
  import { VersionHistoryAction } from "@open-mercato/ui/backend/version-history";
15
15
  import { SendObjectMessageDialog } from "@open-mercato/ui/backend/messages";
16
16
  import { useT } from "@open-mercato/shared/lib/i18n/context";
@@ -48,6 +48,7 @@ function ResourcesResourceDetailPage({ params }) {
48
48
  const router = useRouter();
49
49
  const searchParams = useSearchParams();
50
50
  const [initialValues, setInitialValues] = React.useState(null);
51
+ const [isNotFound, setIsNotFound] = React.useState(false);
51
52
  const [tags, setTags] = React.useState([]);
52
53
  const [activeTab, setActiveTab] = React.useState("details");
53
54
  const [activeDetailTab, setActiveDetailTab] = React.useState("notes");
@@ -325,6 +326,7 @@ function ResourcesResourceDetailPage({ params }) {
325
326
  const { resourceTypesLoaded, resolveFieldsetCode } = formConfig;
326
327
  React.useEffect(() => {
327
328
  if (!resourceId || !resourceTypesLoaded) return;
329
+ setIsNotFound(false);
328
330
  let cancelled = false;
329
331
  async function loadResource() {
330
332
  try {
@@ -335,7 +337,10 @@ function ResourcesResourceDetailPage({ params }) {
335
337
  const record = await readApiResultOrThrow(`/api/resources/resources?${params2.toString()}`);
336
338
  const resourceRaw = Array.isArray(record?.items) ? record.items[0] : null;
337
339
  const resource = resourceRaw ? normalizeResourceRecord(resourceRaw) : null;
338
- if (!resource) throw new Error(t("resources.resources.form.errors.notFound", "Resource not found."));
340
+ if (!resource) {
341
+ if (!cancelled) setIsNotFound(true);
342
+ return;
343
+ }
339
344
  if (!cancelled) {
340
345
  const customValues = extractCustomFieldEntries(resource);
341
346
  setTags(Array.isArray(resource.tags) ? resource.tags : []);
@@ -382,6 +387,16 @@ function ResourcesResourceDetailPage({ params }) {
382
387
  flash(t("resources.resources.availability.ruleset.updateSuccess", "Schedule updated."), "success");
383
388
  }, [resourceId, t]);
384
389
  const resourceTitle = typeof initialValues?.name === "string" && initialValues.name.trim().length > 0 ? initialValues.name.trim() : t("resources.resources.detail.untitled", "Unnamed resource");
390
+ if (isNotFound) {
391
+ return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsx(
392
+ RecordNotFoundState,
393
+ {
394
+ label: t("resources.resources.form.errors.notFound", "Resource not found."),
395
+ backHref: "/backend/resources/resources",
396
+ backLabel: t("resources.resources.detail.back", "Back to resources")
397
+ }
398
+ ) }) });
399
+ }
385
400
  return /* @__PURE__ */ jsx(Page, { children: /* @__PURE__ */ jsx(PageBody, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
386
401
  /* @__PURE__ */ jsx(
387
402
  FormHeader,