@fayz-ai/shop 0.9.0 → 0.11.0
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.
- package/README.md +18 -1
- package/dist/admin.d.ts +2 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/catalog.d.ts +1 -3
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +2 -2
- package/dist/{chunk-IYQHKMLB.js → chunk-2WACO2TG.js} +4 -4
- package/dist/chunk-2WACO2TG.js.map +1 -0
- package/dist/chunk-3GERSY5F.js +526 -0
- package/dist/chunk-3GERSY5F.js.map +1 -0
- package/dist/chunk-6BO2TMZ5.js +93 -0
- package/dist/chunk-6BO2TMZ5.js.map +1 -0
- package/dist/chunk-FQPGE3YN.js +3 -0
- package/dist/{chunk-JR25TISO.js.map → chunk-FQPGE3YN.js.map} +1 -1
- package/dist/{chunk-CTKZ6O2J.js → chunk-IKNGCRUM.js} +41 -15
- package/dist/chunk-IKNGCRUM.js.map +1 -0
- package/dist/chunk-KLDS7IPU.js +17 -0
- package/dist/chunk-KLDS7IPU.js.map +1 -0
- package/dist/chunk-NWW3WJ7Y.js +136 -0
- package/dist/chunk-NWW3WJ7Y.js.map +1 -0
- package/dist/chunk-STRNMFC4.js +1438 -0
- package/dist/chunk-STRNMFC4.js.map +1 -0
- package/dist/chunk-U6HV3LVP.js +1170 -0
- package/dist/chunk-U6HV3LVP.js.map +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/data/customer-search.d.ts +3 -0
- package/dist/data/customer-search.d.ts.map +1 -0
- package/dist/data/functions.d.ts +9 -0
- package/dist/data/functions.d.ts.map +1 -0
- package/dist/data/media.d.ts +37 -0
- package/dist/data/media.d.ts.map +1 -0
- package/dist/{mock-catalog.d.ts → data/mock-catalog.d.ts} +21 -1
- package/dist/data/mock-catalog.d.ts.map +1 -0
- package/dist/data/mock-provider.d.ts +165 -0
- package/dist/data/mock-provider.d.ts.map +1 -0
- package/dist/data/mock.d.ts +3 -0
- package/dist/data/mock.d.ts.map +1 -0
- package/dist/data/provider.d.ts +335 -0
- package/dist/data/provider.d.ts.map +1 -0
- package/dist/data/supabase-provider.d.ts +208 -0
- package/dist/data/supabase-provider.d.ts.map +1 -0
- package/dist/data/tables.d.ts +38 -0
- package/dist/data/tables.d.ts.map +1 -0
- package/dist/data/tenant.d.ts.map +1 -0
- package/dist/entities/entity-reconcile.d.ts +32 -0
- package/dist/entities/entity-reconcile.d.ts.map +1 -0
- package/dist/entities/entity-sql.d.ts +50 -0
- package/dist/entities/entity-sql.d.ts.map +1 -0
- package/dist/entities/entity-store.d.ts +58 -0
- package/dist/entities/entity-store.d.ts.map +1 -0
- package/dist/entities/index.d.ts +10 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/mock-entity-store.d.ts +17 -0
- package/dist/entities/mock-entity-store.d.ts.map +1 -0
- package/dist/entities/supabase-entity-store.d.ts +8 -0
- package/dist/entities/supabase-entity-store.d.ts.map +1 -0
- package/dist/entities.js +159 -0
- package/dist/entities.js.map +1 -0
- package/dist/index.d.ts +28 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1558 -40
- package/dist/index.js.map +1 -1
- package/dist/inventory/allocation.d.ts +98 -0
- package/dist/inventory/allocation.d.ts.map +1 -0
- package/dist/inventory/index.d.ts +13 -0
- package/dist/inventory/index.d.ts.map +1 -0
- package/dist/inventory/mock-stock-store.d.ts +89 -0
- package/dist/inventory/mock-stock-store.d.ts.map +1 -0
- package/dist/inventory/postgrest-double.d.ts +65 -0
- package/dist/inventory/postgrest-double.d.ts.map +1 -0
- package/dist/inventory/shopify-mapping.d.ts +67 -0
- package/dist/inventory/shopify-mapping.d.ts.map +1 -0
- package/dist/inventory/stock-contract.d.ts +46 -0
- package/dist/inventory/stock-contract.d.ts.map +1 -0
- package/dist/inventory/stock-store.d.ts +96 -0
- package/dist/inventory/stock-store.d.ts.map +1 -0
- package/dist/inventory/stock-types.d.ts +351 -0
- package/dist/inventory/stock-types.d.ts.map +1 -0
- package/dist/inventory/supabase-stock-store.d.ts +60 -0
- package/dist/inventory/supabase-stock-store.d.ts.map +1 -0
- package/dist/inventory/vocabulary.d.ts +86 -0
- package/dist/inventory/vocabulary.d.ts.map +1 -0
- package/dist/inventory.js +4 -0
- package/dist/inventory.js.map +1 -0
- package/dist/lib/catalog.d.ts +4 -0
- package/dist/lib/catalog.d.ts.map +1 -0
- package/dist/{commerce.d.ts → lib/commerce.d.ts} +2 -2
- package/dist/lib/commerce.d.ts.map +1 -0
- package/dist/lib/document.d.ts +13 -0
- package/dist/lib/document.d.ts.map +1 -0
- package/dist/lib/emails.d.ts +50 -0
- package/dist/lib/emails.d.ts.map +1 -0
- package/dist/lib/message-events.d.ts +4 -0
- package/dist/lib/message-events.d.ts.map +1 -0
- package/dist/lib/runtime.d.ts +5 -0
- package/dist/lib/runtime.d.ts.map +1 -0
- package/dist/lib/variant-matrix.d.ts +120 -0
- package/dist/lib/variant-matrix.d.ts.map +1 -0
- package/dist/mock.d.ts +1 -2
- package/dist/mock.d.ts.map +1 -1
- package/dist/mock.js +4 -2
- package/dist/provider.d.ts +1 -88
- package/dist/provider.d.ts.map +1 -1
- package/dist/providers/checkout.d.ts +129 -0
- package/dist/providers/checkout.d.ts.map +1 -0
- package/dist/providers/index.d.ts +5 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/shipping.d.ts +43 -0
- package/dist/providers/shipping.d.ts.map +1 -0
- package/dist/providers.js +70 -0
- package/dist/providers.js.map +1 -0
- package/dist/rules/adapter.d.ts +36 -0
- package/dist/rules/adapter.d.ts.map +1 -0
- package/dist/rules/attributes.d.ts +64 -0
- package/dist/rules/attributes.d.ts.map +1 -0
- package/dist/rules/context.d.ts +43 -0
- package/dist/rules/context.d.ts.map +1 -0
- package/dist/rules/evaluator.d.ts +37 -0
- package/dist/rules/evaluator.d.ts.map +1 -0
- package/dist/rules/index.d.ts +13 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/prices.d.ts +25 -0
- package/dist/rules/prices.d.ts.map +1 -0
- package/dist/rules/rule-types.d.ts +160 -0
- package/dist/rules/rule-types.d.ts.map +1 -0
- package/dist/rules.js +22 -0
- package/dist/rules.js.map +1 -0
- package/dist/runtime.d.ts +1 -4
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +5 -3
- package/dist/shipping/label-provider.d.ts +43 -0
- package/dist/shipping/label-provider.d.ts.map +1 -0
- package/dist/types.d.ts +688 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +30 -20
- package/dist/chunk-CTKZ6O2J.js.map +0 -1
- package/dist/chunk-IYQHKMLB.js.map +0 -1
- package/dist/chunk-JR25TISO.js +0 -3
- package/dist/chunk-SVTCJ6HP.js +0 -440
- package/dist/chunk-SVTCJ6HP.js.map +0 -1
- package/dist/commerce.d.ts.map +0 -1
- package/dist/mock-catalog.d.ts.map +0 -1
- package/dist/mock-provider.d.ts +0 -60
- package/dist/mock-provider.d.ts.map +0 -1
- package/dist/supabase-provider.d.ts +0 -56
- package/dist/supabase-provider.d.ts.map +0 -1
- package/dist/tables.d.ts +0 -12
- package/dist/tables.d.ts.map +0 -1
- package/dist/tenant.d.ts.map +0 -1
- package/src/catalog.ts +0 -3
- package/src/commerce.ts +0 -120
- package/src/index.ts +0 -40
- package/src/mock-catalog.ts +0 -266
- package/src/mock-provider.ts +0 -480
- package/src/mock.ts +0 -2
- package/src/provider.ts +0 -117
- package/src/runtime.ts +0 -20
- package/src/supabase-provider.ts +0 -754
- package/src/tables.ts +0 -17
- package/src/tenant.ts +0 -21
- package/src/types.ts +0 -623
- /package/dist/{tenant.d.ts → data/tenant.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/entities/entity-store.ts","../src/entities/mock-entity-store.ts"],"names":[],"mappings":"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","file":"chunk-NWW3WJ7Y.js","sourcesContent":["import type { EntityRecordIssue } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// EntityStore — the I5 storage indirection for declared entities.\n//\n// WooCommerce survived escaping wp_postmeta ONLY because WC_Data_Store let one\n// filter swap the storage implementation per entity type. This is that seam,\n// present from day one: every reader and writer of entity records goes through\n// an EntityStore resolved PER ENTITY KEY, so a hot entity can later be promoted\n// from the generic jsonb table to typed columns by registering a dedicated\n// store for its key — and no caller changes.\n//\n// Two implementations ship with M4: the generic Supabase store over\n// plg_entity_records (supabase-entity-store.ts) and the in-memory mock\n// (mock-entity-store.ts). Both run the SAME write gate: a record that does not\n// validate against the entity's declared schema is rejected with the issues.\n// ---------------------------------------------------------------------------\n\n/** One stored record. Structural columns + the declared `data` payload. */\nexport interface EntityRecord<TData extends Record<string, unknown> = Record<string, unknown>> {\n id: string\n tenantId: string\n /** The entity key this record belongs to (defineEntity key). */\n entity: string\n /** URL-stable identity within (tenant, entity); derived from the title field\n * when not provided. Null for entities that never surface on a URL. */\n slug: string | null\n data: TData\n createdAt: string\n updatedAt: string\n}\n\nexport interface ListEntityRecordsOptions {\n /** Equality filters over declared data fields ({ region: 'sudeste' }). */\n filter?: Record<string, unknown>\n /** Declared field to order by. Default: creation order. */\n orderBy?: string\n order?: 'asc' | 'desc'\n limit?: number\n offset?: number\n}\n\nexport interface EntityRecordInput<TData extends Record<string, unknown> = Record<string, unknown>> {\n slug?: string | null\n data: TData\n}\n\n/** The typed CRUD surface one entity's storage exposes. */\nexport interface EntityStore<TData extends Record<string, unknown> = Record<string, unknown>> {\n list(options?: ListEntityRecordsOptions): Promise<EntityRecord<TData>[]>\n get(id: string): Promise<EntityRecord<TData> | null>\n getBySlug(slug: string): Promise<EntityRecord<TData> | null>\n create(input: EntityRecordInput<TData>): Promise<EntityRecord<TData>>\n update(id: string, input: Partial<EntityRecordInput<TData>>): Promise<EntityRecord<TData>>\n delete(id: string): Promise<void>\n}\n\n/** Thrown by every EntityStore write whose data fails the declared schema. */\nexport class EntityValidationError extends Error {\n constructor(\n readonly entity: string,\n readonly issues: EntityRecordIssue[],\n ) {\n super(\n `Invalid ${entity} record:\\n${issues\n .map((i) => ` - ${i.path || '(record)'}: ${i.message}${i.valid ? ` (valid: ${i.valid.join(', ')})` : ''}`)\n .join('\\n')}`,\n )\n this.name = 'EntityValidationError'\n }\n}\n\n// --- Per-entity store resolution (the promotion seam) -------------------------\n\nconst storeOverrides = new Map<string, EntityStore>()\n\n/**\n * Promote an entity to a dedicated store implementation. From this call on,\n * every provider read/write for `entity` routes here instead of the generic\n * jsonb store — callers, loaders and blocks are untouched (I5).\n */\nexport function registerEntityStore(entity: string, store: EntityStore): void {\n storeOverrides.set(entity, store)\n}\n\n/** The registered dedicated store for an entity, when one exists. */\nexport function getRegisteredEntityStore(entity: string): EntityStore | undefined {\n return storeOverrides.get(entity)\n}\n\n/** Resolve an entity's store: the promoted implementation when registered,\n * otherwise the caller's generic fallback. The ONLY lookup providers use. */\nexport function resolveEntityStore(\n entity: string,\n generic: (entity: string) => EntityStore,\n): EntityStore {\n return storeOverrides.get(entity) ?? generic(entity)\n}\n\n/** Test seam. */\nexport function clearEntityStores(): void {\n storeOverrides.clear()\n}\n\n/** Shared slug derivation: mirrors the product path so entity URLs read the same. */\nexport function slugifyEntityTitle(value: string): string {\n return value\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n}\n","import { resolveEntityDeclaration, validateEntityRecordData } from '@fayz-ai/core'\nimport { EntityValidationError, slugifyEntityTitle } from './entity-store'\nimport type { EntityRecord, EntityRecordInput, EntityStore, ListEntityRecordsOptions } from './entity-store'\n\n// ---------------------------------------------------------------------------\n// The in-memory EntityStore — the mock half of the provider pair (I11).\n//\n// Semantics are the contract here, not persistence: the same write gate\n// (declared-schema validation), the same slug identity, the same list\n// vocabulary (equality filter / orderBy / limit / offset) as the Supabase\n// store, so a loader tested against the mock means what it means live.\n// ---------------------------------------------------------------------------\n\nfunction uid(): string {\n return Math.random().toString(36).slice(2)\n}\n\nexport interface MockEntityStoreOptions {\n tenantId?: string\n /** Seed records: `data` payloads (validated), with optional slug/id. */\n seed?: Array<{ id?: string; slug?: string | null; data: Record<string, unknown> }>\n}\n\n/**\n * An EntityStore for one declared entity, in memory. The entity must be\n * declared (defineEntity) before records move: validation IS the store's\n * contract, and there is nothing to validate against without the declaration.\n */\nexport function createMockEntityStore(entity: string, options: MockEntityStoreOptions = {}): EntityStore {\n const tenantId = options.tenantId ?? 'mock'\n const records: EntityRecord[] = []\n\n const declaration = () => resolveEntityDeclaration(entity)\n\n const gate = (data: Record<string, unknown>): void => {\n const issues = validateEntityRecordData(declaration(), data)\n if (issues.length > 0) throw new EntityValidationError(entity, issues)\n }\n\n const deriveSlug = (input: EntityRecordInput): string | null => {\n if (input.slug !== undefined) return input.slug\n const titleField = declaration().titleField\n const title = titleField ? input.data[titleField] : undefined\n return typeof title === 'string' && title ? slugifyEntityTitle(title) : null\n }\n\n const uniqueSlug = (slug: string | null, exceptId?: string): void => {\n if (slug === null) return\n if (records.some((r) => r.slug === slug && r.id !== exceptId)) {\n throw new Error(`Entity \"${entity}\" already has a record with slug \"${slug}\".`)\n }\n }\n\n const store: EntityStore = {\n async list(listOptions: ListEntityRecordsOptions = {}) {\n let out = [...records]\n for (const [field, value] of Object.entries(listOptions.filter ?? {})) {\n out = out.filter((r) => r.data[field] === value)\n }\n if (listOptions.orderBy) {\n const key = listOptions.orderBy\n const dir = listOptions.order === 'desc' ? -1 : 1\n out.sort((a, b) => {\n const av = a.data[key]\n const bv = b.data[key]\n if (av === bv) return 0\n if (av === undefined || av === null) return dir\n if (bv === undefined || bv === null) return -dir\n return (av < bv ? -1 : 1) * dir\n })\n }\n const offset = listOptions.offset ?? 0\n return out.slice(offset, listOptions.limit != null ? offset + listOptions.limit : undefined)\n },\n\n async get(id) {\n return records.find((r) => r.id === id) ?? null\n },\n\n async getBySlug(slug) {\n return records.find((r) => r.slug === slug) ?? null\n },\n\n async create(input) {\n gate(input.data)\n const slug = deriveSlug(input)\n uniqueSlug(slug)\n const now = new Date().toISOString()\n const record: EntityRecord = {\n id: uid(),\n tenantId,\n entity,\n slug,\n data: { ...input.data },\n createdAt: now,\n updatedAt: now,\n }\n records.push(record)\n return record\n },\n\n async update(id, input) {\n const record = records.find((r) => r.id === id)\n if (!record) throw new Error(`Entity \"${entity}\" has no record \"${id}\".`)\n const data = input.data !== undefined ? { ...input.data } : record.data\n gate(data)\n const slug = input.slug !== undefined ? input.slug : record.slug\n uniqueSlug(slug, id)\n record.data = data\n record.slug = slug\n record.updatedAt = new Date().toISOString()\n return record\n },\n\n async delete(id) {\n const index = records.findIndex((r) => r.id === id)\n if (index >= 0) records.splice(index, 1)\n },\n }\n\n for (const seed of options.seed ?? []) {\n const issues = validateEntityRecordData(declaration(), seed.data)\n if (issues.length > 0) throw new EntityValidationError(entity, issues)\n const slug = deriveSlug({ slug: seed.slug, data: seed.data })\n uniqueSlug(slug)\n const now = new Date().toISOString()\n records.push({\n id: seed.id ?? uid(),\n tenantId,\n entity,\n slug,\n data: { ...seed.data },\n createdAt: now,\n updatedAt: now,\n })\n }\n\n return store\n}\n"]}
|