@proveanything/smartlinks-utils-ui 0.6.4 → 0.6.6

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.
@@ -101,6 +101,32 @@ var upsertRecord = async (ctx, write) => {
101
101
  );
102
102
  return { record: res, isCreate: !!res?.created };
103
103
  };
104
+ var createRecord = async (ctx, write) => {
105
+ const payload = {
106
+ ...ctx.recordType ? { recordType: ctx.recordType } : {},
107
+ data: write.data,
108
+ status: write.status,
109
+ startsAt: write.startsAt,
110
+ expiresAt: write.expiresAt,
111
+ customId: write.customId,
112
+ sourceSystem: write.sourceSystem
113
+ };
114
+ if (write.ref) payload.ref = write.ref;
115
+ if (write.facetRule && write.facetRule.all && write.facetRule.all.length > 0) {
116
+ payload.facetRule = write.facetRule;
117
+ } else {
118
+ if (write.scope.productId) payload.productId = write.scope.productId;
119
+ if (write.scope.variantId) payload.variantId = write.scope.variantId;
120
+ if (write.scope.batchId) payload.batchId = write.scope.batchId;
121
+ if (write.scope.proofId) payload.proofId = write.scope.proofId;
122
+ }
123
+ return ctx.SL.app.records.create(
124
+ ctx.collectionId,
125
+ ctx.appId,
126
+ payload,
127
+ true
128
+ );
129
+ };
104
130
  var updateRecord = async (ctx, recordId, patch) => {
105
131
  const payload = {
106
132
  ...ctx.recordType ? { recordType: ctx.recordType } : {}
@@ -201,6 +227,6 @@ var bulkDelete = async (ctx, input) => {
201
227
  return { removed };
202
228
  };
203
229
 
204
- export { bulkDelete, bulkUpsert, getRecordById, listRecords, matchRecords, parsedRefToScope, parsedRefToTarget, removeRecord, restoreRecord, scopesEqual, updateRecord, upsertRecord, upsertRecordForScope };
205
- //# sourceMappingURL=chunk-24SJBCVB.js.map
206
- //# sourceMappingURL=chunk-24SJBCVB.js.map
230
+ export { bulkDelete, bulkUpsert, createRecord, getRecordById, listRecords, matchRecords, parsedRefToScope, parsedRefToTarget, removeRecord, restoreRecord, scopesEqual, updateRecord, upsertRecord, upsertRecordForScope };
231
+ //# sourceMappingURL=chunk-KFKVGUUP.js.map
232
+ //# sourceMappingURL=chunk-KFKVGUUP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/RecordsAdmin/data/scopeBridge.ts","../src/components/RecordsAdmin/data/records.ts"],"names":[],"mappings":"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","file":"chunk-KFKVGUUP.js","sourcesContent":["// =============================================================================\r\n// scopeBridge — Convert between our UI `ParsedRef` and the SDK record anchors.\r\n//\r\n// SDK 1.10.2 flattened `AppRecord`: anchor IDs (`productId`, `variantId`,\r\n// `batchId`, `proofId`) live at the top level and the nested `RecordScope`\r\n// type was removed. Facet selection moved to `facetRule` (rule records),\r\n// handled separately via the FacetRuleEditor.\r\n//\r\n// `parsedRefToScope` keeps its public name (it's re-exported from the\r\n// package entrypoint) but now returns the flat anchor object that Upsert /\r\n// Bulk inputs accept directly.\r\n// =============================================================================\r\nimport type { RecordTarget } from './sdkTypes';\r\nimport type { ParsedRef } from '../types';\r\n\r\n/** Flat anchor shape — matches `UpsertRecordInput` / `BulkUpsertItem`. */\r\nexport interface RecordAnchors {\r\n productId?: string | null;\r\n variantId?: string | null;\r\n batchId?: string | null;\r\n proofId?: string | null;\r\n}\r\n\r\n/**\r\n * Project a `ParsedRef` to the flat anchor IDs the SDK writes. Facet\r\n * components on the ref are intentionally ignored — facet targeting now\r\n * lives on `facetRule` (rule records), not as a record anchor.\r\n */\r\nexport const parsedRefToScope = (ref: ParsedRef): RecordAnchors => {\r\n const anchors: RecordAnchors = {};\r\n if (ref.productId) anchors.productId = ref.productId;\r\n if (ref.variantId) anchors.variantId = ref.variantId;\r\n if (ref.batchId) anchors.batchId = ref.batchId;\r\n if (ref.proofId) anchors.proofId = ref.proofId;\r\n return anchors;\r\n};\r\n\r\nexport const parsedRefToTarget = (ref: ParsedRef): RecordTarget => {\r\n const target: RecordTarget = {};\r\n if (ref.productId) target.productId = ref.productId;\r\n if (ref.variantId) target.variantId = ref.variantId;\r\n if (ref.batchId) target.batchId = ref.batchId;\r\n if (ref.proofId) target.proofId = ref.proofId;\r\n if (ref.facetId && ref.facetValue) {\r\n target.facets = { [ref.facetId]: [ref.facetValue] };\r\n }\r\n return target;\r\n};\r\n\r\n/**\r\n * True when two anchor sets refer to the same node. Used to decide\r\n * \"self\" vs \"inherited\" when consuming `match()` results: compare the\r\n * winning record's flat anchor IDs against the editing scope.\r\n */\r\nexport const scopesEqual = (a: RecordAnchors, b: RecordAnchors): boolean => {\r\n if ((a.productId ?? null) !== (b.productId ?? null)) return false;\r\n if ((a.variantId ?? null) !== (b.variantId ?? null)) return false;\r\n if ((a.batchId ?? null) !== (b.batchId ?? null)) return false;\r\n if ((a.proofId ?? null) !== (b.proofId ?? null)) return false;\r\n return true;\r\n};","// =============================================================================\r\n// Thin wrappers over SL.app.records.* — always admin: true here.\r\n//\r\n// As of `@proveanything/smartlinks` 1.9.0 the records surface ships a proper\r\n// `upsert()`, server-side `match()`, and atomic `bulkUpsert` / `bulkDelete`.\r\n// We delegate to those rather than rolling our own list+update sequences,\r\n// which were racy and ignored facet AND-of-OR semantics.\r\n//\r\n// Identity model (1.10.3+): every record has a stable UUID `id`. The shell\r\n// addresses existing records by id (`update`, `remove`); only genuinely new\r\n// records go via `upsert` (or `create`). We deliberately do NOT synthesise\r\n// a `ref` from anchor IDs anymore — anchors alone are sufficient for the\r\n// server to address the record, and a synthetic ref masks bugs by making\r\n// the editor \"find\" records that don't exist yet.\r\n// =============================================================================\r\nimport type {\r\n AppRecord, RecordTarget, BulkUpsertItem, BulkDeleteResult,\r\n MatchResult, FacetRule,\r\n} from './sdkTypes';\r\nimport type { ParsedRef, SmartLinksSDK } from '../types';\r\nimport { parsedRefToScope, type RecordAnchors } from './scopeBridge';\r\n\r\nexport interface RecordsCtx {\r\n SL: SmartLinksSDK;\r\n collectionId: string;\r\n appId: string;\r\n /** Optional — when omitted, records are stored against the app id alone\r\n * (no type qualifier). Set this only when an app uses multiple record types\r\n * and needs to query/scope by type. */\r\n recordType?: string;\r\n}\r\n\r\n/**\r\n * Shape of a single record write. SDK 1.10.2 takes flat anchor IDs\r\n * directly on the upsert payload (`productId`, `variantId`, `batchId`,\r\n * `proofId`); the legacy nested `scope` object is gone. Set `facetRule`\r\n * for rule records — mutually exclusive with anchor IDs.\r\n */\r\nexport interface RecordWrite<T = unknown> {\r\n /**\r\n * Optional caller-supplied external ref (e.g. a SKU or user-typed key).\r\n * When omitted the server addresses the record by anchors / facetRule\r\n * alone — we no longer synthesise one from anchor IDs client-side.\r\n */\r\n ref?: string;\r\n /** Flat anchor IDs. Drives specificity and `match()` server-side. */\r\n scope: RecordAnchors;\r\n data: T;\r\n visibility?: 'public' | 'owner' | 'admin';\r\n status?: string;\r\n startsAt?: string | null;\r\n expiresAt?: string | null;\r\n customId?: string;\r\n sourceSystem?: string;\r\n /**\r\n * Optional facet rule. When set, the record is targeted via this rule and\r\n * anchor IDs must be empty (SDK enforces mutual exclusion). Used by\r\n * the rule editor / Targeting section.\r\n */\r\n facetRule?: FacetRule | null;\r\n}\r\n\r\nexport const listRecords = async (\r\n ctx: RecordsCtx,\r\n params: { ref?: string; refPrefix?: string; q?: string; limit?: number; offset?: number; sort?: string } = {},\r\n): Promise<{ data: AppRecord[]; total: number; hasMore: boolean }> => {\r\n const { limit = 100, offset, ref, refPrefix, q, sort } = params;\r\n const res = await ctx.SL.app.records.list(\r\n ctx.collectionId,\r\n ctx.appId,\r\n {\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n limit, offset, ref, refPrefix, q, sort,\r\n },\r\n true,\r\n );\r\n return {\r\n data: res?.data ?? [],\r\n total: res?.pagination?.total ?? (res?.data?.length ?? 0),\r\n hasMore: res?.pagination?.hasMore ?? false,\r\n };\r\n};\r\n\r\n/**\r\n * Look up a single record by its UUID id. The id-primary read path used by\r\n * deep-link restore (`?recordId=`).\r\n */\r\nexport const getRecordById = async (\r\n ctx: RecordsCtx,\r\n recordId: string,\r\n): Promise<AppRecord | null> => {\r\n try {\r\n const record = await ctx.SL.app.records.get(ctx.collectionId, ctx.appId, recordId, true);\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdmin/getRecordById] direct get succeeded', { recordId, ref: record?.ref ?? null });\r\n return record;\r\n } catch (error) {\r\n // Some host environments appear to lag the id-primary `get()` path even\r\n // though the same record is visible in `list()`. Fall back to a bounded\r\n // scan so item selection still resolves instead of looking dead.\r\n // eslint-disable-next-line no-console\r\n console.warn('[RecordsAdmin/getRecordById] direct get failed, falling back to list scan', {\r\n recordId,\r\n error: error instanceof Error ? error.message : String(error),\r\n });\r\n let offset = 0;\r\n const limit = 100;\r\n for (let page = 0; page < 10; page += 1) {\r\n const res = await listRecords(ctx, { limit, offset }).catch(() => null);\r\n const hit = res?.data.find((rec) => rec.id === recordId) ?? null;\r\n if (hit) {\r\n // eslint-disable-next-line no-console\r\n console.info('[RecordsAdmin/getRecordById] recovered record via list scan', { recordId, ref: hit.ref ?? null, page });\r\n return hit;\r\n }\r\n if (!res?.hasMore) break;\r\n offset += res.data.length;\r\n }\r\n // eslint-disable-next-line no-console\r\n console.warn('[RecordsAdmin/getRecordById] record not found after fallback scan', { recordId });\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * Create-or-update by (anchors + recordType) — used when we don't yet know\r\n * the record's UUID id. The server addresses the row by anchors (or the\r\n * supplied `ref`/`facetRule`) and returns the row with its stable `id`.\r\n *\r\n * Prefer `updateRecord(ctx, id, …)` whenever an id is already in hand:\r\n * it's an unambiguous PATCH against a known row and never accidentally\r\n * resurrects a sibling at the same anchor.\r\n */\r\nexport const upsertRecord = async <T,>(\r\n ctx: RecordsCtx,\r\n write: RecordWrite<T>,\r\n): Promise<{ record: AppRecord; isCreate: boolean }> => {\r\n const payload: Record<string, unknown> = {\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n data: write.data as Record<string, unknown>,\r\n status: write.status,\r\n startsAt: write.startsAt,\r\n expiresAt: write.expiresAt,\r\n customId: write.customId,\r\n sourceSystem: write.sourceSystem,\r\n };\r\n // Only send `ref` when the caller supplied one explicitly (external key\r\n // such as a SKU). We no longer synthesise one from anchors.\r\n if (write.ref) payload.ref = write.ref;\r\n\r\n // SDK 1.10.3 enforces mutual exclusion between anchor IDs and `facetRule`.\r\n // Send exactly one. When a rule is supplied the server resolves matches\r\n // against it; otherwise the flat anchor IDs drive specificity.\r\n if (write.facetRule && write.facetRule.all && write.facetRule.all.length > 0) {\r\n payload.facetRule = write.facetRule;\r\n } else {\r\n if (write.scope.productId) payload.productId = write.scope.productId;\r\n if (write.scope.variantId) payload.variantId = write.scope.variantId;\r\n if (write.scope.batchId) payload.batchId = write.scope.batchId;\r\n if (write.scope.proofId) payload.proofId = write.scope.proofId;\r\n }\r\n const res = await ctx.SL.app.records.upsert(\r\n ctx.collectionId, ctx.appId, payload as Parameters<typeof ctx.SL.app.records.upsert>[2],\r\n );\r\n return { record: res, isCreate: !!res?.created };\r\n};\r\n\r\n/**\r\n * Create a brand-new record. Use this for collection-cardinality items\r\n * where each save must produce a distinct row (no upsert key collision).\r\n * Unlike `upsert`, the server allows omitting `ref` here — every call\r\n * inserts a new row and returns its UUID.\r\n */\r\nexport const createRecord = async <T,>(\r\n ctx: RecordsCtx,\r\n write: RecordWrite<T>,\r\n): Promise<AppRecord> => {\r\n const payload: Record<string, unknown> = {\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n data: write.data as Record<string, unknown>,\r\n status: write.status,\r\n startsAt: write.startsAt,\r\n expiresAt: write.expiresAt,\r\n customId: write.customId,\r\n sourceSystem: write.sourceSystem,\r\n };\r\n if (write.ref) payload.ref = write.ref;\r\n if (write.facetRule && write.facetRule.all && write.facetRule.all.length > 0) {\r\n payload.facetRule = write.facetRule;\r\n } else {\r\n if (write.scope.productId) payload.productId = write.scope.productId;\r\n if (write.scope.variantId) payload.variantId = write.scope.variantId;\r\n if (write.scope.batchId) payload.batchId = write.scope.batchId;\r\n if (write.scope.proofId) payload.proofId = write.scope.proofId;\r\n }\r\n return ctx.SL.app.records.create(\r\n ctx.collectionId, ctx.appId,\r\n payload as Parameters<typeof ctx.SL.app.records.create>[2],\r\n true,\r\n );\r\n};\r\n\r\n/**\r\n * PATCH an existing record by its UUID id. The id-primary save path —\r\n * preferred over `upsertRecord` whenever the resolver has handed us a\r\n * `recordId`. Anchors are passed through verbatim; pass `null` for an\r\n * anchor to clear it.\r\n */\r\nexport const updateRecord = async <T,>(\r\n ctx: RecordsCtx,\r\n recordId: string,\r\n patch: {\r\n data?: T;\r\n scope?: RecordAnchors;\r\n facetRule?: FacetRule | null;\r\n status?: string;\r\n startsAt?: string | null;\r\n expiresAt?: string | null;\r\n },\r\n): Promise<AppRecord> => {\r\n const payload: Record<string, unknown> = {\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n };\r\n if (patch.data !== undefined) payload.data = patch.data as Record<string, unknown>;\r\n if (patch.status !== undefined) payload.status = patch.status;\r\n if (patch.startsAt !== undefined) payload.startsAt = patch.startsAt;\r\n if (patch.expiresAt !== undefined) payload.expiresAt = patch.expiresAt;\r\n if (patch.scope) {\r\n if (patch.scope.productId !== undefined) payload.productId = patch.scope.productId;\r\n if (patch.scope.variantId !== undefined) payload.variantId = patch.scope.variantId;\r\n if (patch.scope.batchId !== undefined) payload.batchId = patch.scope.batchId;\r\n if (patch.scope.proofId !== undefined) payload.proofId = patch.scope.proofId;\r\n }\r\n if (patch.facetRule !== undefined) payload.facetRule = patch.facetRule;\r\n return ctx.SL.app.records.update(\r\n ctx.collectionId, ctx.appId, recordId,\r\n payload as Parameters<typeof ctx.SL.app.records.update>[3],\r\n true,\r\n );\r\n};\r\n\r\n/** Delete a record by its UUID id. The id-primary delete path. */\r\nexport const removeRecord = async (\r\n ctx: RecordsCtx,\r\n recordId: string,\r\n): Promise<void> => {\r\n await ctx.SL.app.records.remove(ctx.collectionId, ctx.appId, recordId, true);\r\n};\r\n\r\n/**\r\n * Convenience wrapper for callers that only have a `ParsedRef` and a payload —\r\n * matches the previous (`ref`, `data`) call shape used by the editor hook.\r\n */\r\nexport const upsertRecordForScope = async <T,>(\r\n ctx: RecordsCtx,\r\n scope: ParsedRef,\r\n data: T,\r\n extra: { visibility?: 'public' | 'owner' | 'admin' } = {},\r\n) => upsertRecord<T>(ctx, {\r\n ref: scope.raw || undefined,\r\n scope: parsedRefToScope(scope),\r\n data,\r\n visibility: extra.visibility,\r\n});\r\n\r\n/** Restore a soft-deleted record by ID (admin only). */\r\nexport const restoreRecord = async (\r\n ctx: RecordsCtx,\r\n recordId: string,\r\n): Promise<AppRecord> => ctx.SL.app.records.restore(ctx.collectionId, ctx.appId, recordId);\r\n\r\n/**\r\n * Server-side match — single round trip that returns every record whose\r\n * `scope` is satisfied by `target`, ordered by descending `specificity`.\r\n * Replaces the per-scope N+1 chain walk we used pre-1.9.\r\n */\r\nexport const matchRecords = async (\r\n ctx: RecordsCtx,\r\n target: RecordTarget,\r\n opts: {\r\n strategy?: 'all' | 'best';\r\n at?: string;\r\n includeScheduled?: boolean;\r\n includeExpired?: boolean;\r\n limit?: number;\r\n } = {},\r\n): Promise<MatchResult> => ctx.SL.app.records.match(\r\n ctx.collectionId,\r\n ctx.appId,\r\n {\r\n target,\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n strategy: opts.strategy ?? 'all',\r\n at: opts.at,\r\n includeScheduled: opts.includeScheduled,\r\n includeExpired: opts.includeExpired,\r\n limit: opts.limit,\r\n },\r\n true,\r\n);\r\n\r\n/**\r\n * Server-side bulk upsert. Up to 500 rows per call; any leftover is chunked.\r\n * Each row is error-isolated by the server.\r\n */\r\nexport const bulkUpsert = async <T,>(\r\n ctx: RecordsCtx,\r\n entries: Array<{ ref?: string; scope: RecordAnchors; data: T; status?: string }>,\r\n): Promise<{ saved: number; failed: number }> => {\r\n const CHUNK = 500;\r\n let saved = 0;\r\n let failed = 0;\r\n for (let i = 0; i < entries.length; i += CHUNK) {\r\n const slice = entries.slice(i, i + CHUNK);\r\n const items: BulkUpsertItem[] = slice.map((e) => {\r\n const item: BulkUpsertItem = {\r\n ...(ctx.recordType ? { recordType: ctx.recordType } : {}),\r\n productId: e.scope.productId ?? null,\r\n variantId: e.scope.variantId ?? null,\r\n batchId: e.scope.batchId ?? null,\r\n proofId: e.scope.proofId ?? null,\r\n data: e.data as Record<string, unknown>,\r\n status: e.status,\r\n } as BulkUpsertItem;\r\n // Caller-supplied external refs only — we no longer derive one from\r\n // anchors. Bulk imports without an external key rely on the server\r\n // matching on (recordType + anchors) for the upsert key.\r\n if (e.ref) (item as { ref?: string }).ref = e.ref;\r\n return item;\r\n });\r\n const res = await ctx.SL.app.records.bulkUpsert(ctx.collectionId, ctx.appId, items)\r\n .catch((): { saved: number; failed: number } => ({ saved: 0, failed: items.length }));\r\n saved += res.saved ?? 0;\r\n failed += res.failed ?? 0;\r\n }\r\n return { saved, failed };\r\n};\r\n\r\n/**\r\n * Server-side bulk delete. Accepts an explicit ref list (max 1000 per call,\r\n * chunked here) or a scope anchor (single call).\r\n */\r\nexport const bulkDelete = async (\r\n ctx: RecordsCtx,\r\n input: { refs: string[] } | { scope: RecordAnchors },\r\n): Promise<{ removed: number }> => {\r\n if ('scope' in input) {\r\n // SDK `BulkDeleteInput.scope` accepts the flat anchor object directly.\r\n const scope: Record<string, string> = {};\r\n if (input.scope.productId) scope.productId = input.scope.productId;\r\n if (input.scope.variantId) scope.variantId = input.scope.variantId;\r\n if (input.scope.batchId) scope.batchId = input.scope.batchId;\r\n if (input.scope.proofId) scope.proofId = input.scope.proofId;\r\n const res: BulkDeleteResult = await ctx.SL.app.records.bulkDelete(\r\n ctx.collectionId, ctx.appId,\r\n { scope, ...(ctx.recordType ? { recordType: ctx.recordType } : {}) },\r\n );\r\n return { removed: res.deleted ?? 0 };\r\n }\r\n\r\n const CHUNK = 1000;\r\n let removed = 0;\r\n for (let i = 0; i < input.refs.length; i += CHUNK) {\r\n const slice = input.refs.slice(i, i + CHUNK);\r\n const res: BulkDeleteResult = await ctx.SL.app.records.bulkDelete(\r\n ctx.collectionId, ctx.appId,\r\n { refs: slice, ...(ctx.recordType ? { recordType: ctx.recordType } : {}) },\r\n );\r\n removed += res.deleted ?? 0;\r\n }\r\n return { removed };\r\n};"]}
@@ -31,6 +31,8 @@ interface ParsedRef {
31
31
  * internally — every record is addressed by its UUID `id`.
32
32
  */
33
33
  raw: string;
34
+ /** Legacy collection-item identity for hosts that still key off `item:` refs. */
35
+ itemId?: string;
34
36
  collectionId?: string;
35
37
  productId?: string;
36
38
  facetId?: string;
@@ -116,6 +118,8 @@ interface EditorContext<TData = unknown> {
116
118
  value: TData;
117
119
  onChange: (next: TData) => void;
118
120
  source: RecordSource;
121
+ /** UUID of the concrete record currently open in the editor, when one exists. */
122
+ recordId?: string;
119
123
  parentValue?: TData | null;
120
124
  scope: ParsedRef;
121
125
  isDirty: boolean;
@@ -1388,6 +1392,13 @@ declare const upsertRecord: <T>(ctx: RecordsCtx, write: RecordWrite<T>) => Promi
1388
1392
  record: AppRecord;
1389
1393
  isCreate: boolean;
1390
1394
  }>;
1395
+ /**
1396
+ * Create a brand-new record. Use this for collection-cardinality items
1397
+ * where each save must produce a distinct row (no upsert key collision).
1398
+ * Unlike `upsert`, the server allows omitting `ref` here — every call
1399
+ * inserts a new row and returns its UUID.
1400
+ */
1401
+ declare const createRecord: <T>(ctx: RecordsCtx, write: RecordWrite<T>) => Promise<AppRecord>;
1391
1402
  /** Delete a record by its UUID id. The id-primary delete path. */
1392
1403
  declare const removeRecord: (ctx: RecordsCtx, recordId: string) => Promise<void>;
1393
1404
  /** Restore a soft-deleted record by ID (admin only). */
@@ -1495,6 +1506,15 @@ interface UseRecordEditorArgs<T> {
1495
1506
  * scopes unless the host explicitly opts a record into rule targeting.
1496
1507
  */
1497
1508
  initialFacetRule?: FacetRule | null;
1509
+ /**
1510
+ * When true, every save calls `records.create` (a fresh insert) instead
1511
+ * of `records.upsert`. Used by collection-cardinality hosts where
1512
+ * multiple items can share the same scope/recordType — each draft must
1513
+ * become its own row, not collide on an upsert key. The shell flips
1514
+ * this on for unsaved item drafts and clears it once the resolver hands
1515
+ * back a concrete `recordId`.
1516
+ */
1517
+ createMode?: boolean;
1498
1518
  }
1499
1519
  declare function useRecordEditor<T>(args: UseRecordEditorArgs<T>): EditorContext<T>;
1500
1520
 
@@ -2113,4 +2133,4 @@ declare const exportCsv: <T>(records: RecordSummary<T>[], schema: CsvSchema<T>)
2113
2133
  declare const importCsv: <T>(file: File, schema: CsvSchema<T>, ctx: RecordsCtx) => Promise<ImportReport>;
2114
2134
  declare const downloadBlob: (blob: Blob, filename: string) => void;
2115
2135
 
2116
- export { ALL_ITEM_VIEWS, ALL_PRESENTATIONS, BatchList, BulkActionsMenu, type ClipboardEntry, type CollectedRecord, type CollectedSort, type CollectionRailMode, type CsvSchema, type CsvSchemaColumn, DEFAULT_DEEP_LINK_PARAM_NAMES, DEFAULT_I18N, DEFAULT_ICONS, type DeepLinkAdapter, type DeepLinkChangeKind, type DeepLinkHistoryMode, type DeepLinkOptions, type DeepLinkParamNames, type DeepLinkState, DefaultItemCards, DefaultItemTable, DefaultRecordCard, DefaultRecordRow, DeleteButton, type DirtyStrategy, DrawerPreview, type EditorContext, EditorItemNav, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, type ItemColumn, ItemListView, type ItemSlotContext, type ItemView, type ItemViewContext, ItemViewSwitcher, LoadingState, type MergeStrategy, type MergedRecord, type NavConfirmI18n, type ParsedRef, type PasteCompatibility, type PasteCompatibilityResult, PresentationSwitcher, type PreviewMode, PreviewScopePicker, PreviewToggleButton, type ProductBrowseItem, type ProductChildItem, ProductDrillDown, ProductList, type RecordBadge, RecordBrowser, type RecordCardinality, RecordEditor, RecordList, type RecordPresentation, type RecordSlotContext, type RecordSource, type RecordStatus, type RecordSummary, type RecordsAdminI18n, type RecordsAdminIcons, RecordsAdminShell, type RecordsAdminShellProps, type ResolvedDeepLinkParamNames, ResolvedPreview, type ResolvedRecord, ScopeBreadcrumb, type ScopeKind, ScopeTabs, SiblingRail, SidePreview, type SmartLinksSDK, StatusDot, StatusFilterPills, StatusIcon, type StatusTone, TabbedPreview, type TelemetryEvent, type UseCollectionItemsArgs, type UseRecordClipboardArgs, type UseRecordClipboardReturn, type UseResolveAllRecordsArgs, type UseResolveAllResult, type UseRulePreviewArgs, type UseRulePreviewResult, UtilityRow, VariantList, buildRef, bulkDelete, bulkUpsert, checkPasteCompatibility, cloneValue, createDefaultDeepLinkAdapter, downloadBlob, exportCsv, getRecordById, importCsv, listRecords, matchRecords, mergeIcons, parseRef, parsedRefToScope, parsedRefToTarget, pickHeaderIcon, removeRecord, resolutionChain, resolveRecord, restoreRecord, scopesEqual, statusToneLabel, upsertRecord, useCollectedRecords, useCollectionItems, useDeepLinkState, useDirtyNavigation, useFacetBrowse, useIntroDismissed, useItemViewPref, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordClipboard, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeProbe, useUnsavedGuard };
2136
+ export { ALL_ITEM_VIEWS, ALL_PRESENTATIONS, BatchList, BulkActionsMenu, type ClipboardEntry, type CollectedRecord, type CollectedSort, type CollectionRailMode, type CsvSchema, type CsvSchemaColumn, DEFAULT_DEEP_LINK_PARAM_NAMES, DEFAULT_I18N, DEFAULT_ICONS, type DeepLinkAdapter, type DeepLinkChangeKind, type DeepLinkHistoryMode, type DeepLinkOptions, type DeepLinkParamNames, type DeepLinkState, DefaultItemCards, DefaultItemTable, DefaultRecordCard, DefaultRecordRow, DeleteButton, type DirtyStrategy, DrawerPreview, type EditorContext, EditorItemNav, EmptyState, ErrorState, FacetList, InheritanceMarker, InheritanceProvider, InlinePreview, IntroCard, type ItemColumn, ItemListView, type ItemSlotContext, type ItemView, type ItemViewContext, ItemViewSwitcher, LoadingState, type MergeStrategy, type MergedRecord, type NavConfirmI18n, type ParsedRef, type PasteCompatibility, type PasteCompatibilityResult, PresentationSwitcher, type PreviewMode, PreviewScopePicker, PreviewToggleButton, type ProductBrowseItem, type ProductChildItem, ProductDrillDown, ProductList, type RecordBadge, RecordBrowser, type RecordCardinality, RecordEditor, RecordList, type RecordPresentation, type RecordSlotContext, type RecordSource, type RecordStatus, type RecordSummary, type RecordsAdminI18n, type RecordsAdminIcons, RecordsAdminShell, type RecordsAdminShellProps, type ResolvedDeepLinkParamNames, ResolvedPreview, type ResolvedRecord, ScopeBreadcrumb, type ScopeKind, ScopeTabs, SiblingRail, SidePreview, type SmartLinksSDK, StatusDot, StatusFilterPills, StatusIcon, type StatusTone, TabbedPreview, type TelemetryEvent, type UseCollectionItemsArgs, type UseRecordClipboardArgs, type UseRecordClipboardReturn, type UseResolveAllRecordsArgs, type UseResolveAllResult, type UseRulePreviewArgs, type UseRulePreviewResult, UtilityRow, VariantList, buildRef, bulkDelete, bulkUpsert, checkPasteCompatibility, cloneValue, createDefaultDeepLinkAdapter, createRecord, downloadBlob, exportCsv, getRecordById, importCsv, listRecords, matchRecords, mergeIcons, parseRef, parsedRefToScope, parsedRefToTarget, pickHeaderIcon, removeRecord, resolutionChain, resolveRecord, restoreRecord, scopesEqual, statusToneLabel, upsertRecord, useCollectedRecords, useCollectionItems, useDeepLinkState, useDirtyNavigation, useFacetBrowse, useIntroDismissed, useItemViewPref, useMergedRecord, usePresentationPref, useProductBrowse, useProductChildren, useRecordClipboard, useRecordEditor, useRecordList, useResolveAllRecords, useResolvedRecord, useRulePreview, useScopeProbe, useUnsavedGuard };
@@ -2,8 +2,8 @@ import { styleInject } from '../../chunk-HXJLROC2.js';
2
2
  import { FacetRuleEditor } from '../../chunk-JMCV6FOW.js';
3
3
  import { useFacets } from '../../chunk-4LHF5JB7.js';
4
4
  import { cn } from '../../chunk-L7FQ52F5.js';
5
- import { listRecords, parsedRefToTarget, parsedRefToScope, matchRecords, scopesEqual, getRecordById, updateRecord, upsertRecord, removeRecord } from '../../chunk-24SJBCVB.js';
6
- export { bulkDelete, bulkUpsert, getRecordById, listRecords, matchRecords, parsedRefToScope, parsedRefToTarget, removeRecord, restoreRecord, scopesEqual, upsertRecord } from '../../chunk-24SJBCVB.js';
5
+ import { listRecords, parsedRefToTarget, parsedRefToScope, matchRecords, scopesEqual, getRecordById, updateRecord, createRecord, upsertRecord, removeRecord } from '../../chunk-KFKVGUUP.js';
6
+ export { bulkDelete, bulkUpsert, createRecord, getRecordById, listRecords, matchRecords, parsedRefToScope, parsedRefToTarget, removeRecord, restoreRecord, scopesEqual, upsertRecord } from '../../chunk-KFKVGUUP.js';
7
7
  import { createContext, useMemo, useState, useEffect, useCallback, useRef, useContext, createElement } from 'react';
8
8
  import { ChevronDown, Database, Lightbulb, SearchX, Inbox, LayoutGrid, Eye, MoreHorizontal, Download, Upload, Trash2, Copy, Pencil, Plus, CircleDashed, ArrowDownLeft, CheckCircle2, SlidersHorizontal, Globe, Tag, Boxes, Layers, Package, Rows3, List, ChevronRight, Eraser, ClipboardPaste, Box, X, Image, Table, ArrowLeft, ChevronLeft, AlertTriangle, Info, HelpCircle, Search, CornerDownLeft, Circle, AlertCircle, Undo2, Save, Target, Settings2 } from 'lucide-react';
9
9
  import { useQueryClient, useInfiniteQuery, useQuery } from '@tanstack/react-query';
@@ -584,7 +584,8 @@ function useRecordEditor(args) {
584
584
  onDeleted,
585
585
  onSaveError,
586
586
  reseed = "always",
587
- initialFacetRule = null
587
+ initialFacetRule = null,
588
+ createMode = false
588
589
  } = args;
589
590
  const queryClient = useQueryClient();
590
591
  const seed = cloneSeed(resolved, defaultData);
@@ -617,7 +618,10 @@ function useRecordEditor(args) {
617
618
  const anchors = parsedRefToScope(scope);
618
619
  const hasAnchors = !!(anchors.productId || anchors.variantId || anchors.batchId || anchors.proofId);
619
620
  const hasRule = !!(facetRule && facetRule.all && facetRule.all.length > 0);
620
- if (!hasAnchors && !hasRule && !scope.raw) return;
621
+ if (!hasAnchors && !hasRule && !scope.raw && !createMode && !resolved.recordId) {
622
+ console.warn("[useRecordEditor] save() bailed \u2014 no scope, no rule, no recordId, not in createMode");
623
+ return;
624
+ }
621
625
  const previousSnapshot = savedSnapshot;
622
626
  const previousRuleSnapshot = savedFacetRule;
623
627
  resolved.source;
@@ -653,6 +657,13 @@ function useRecordEditor(args) {
653
657
  data: value,
654
658
  facetRule
655
659
  });
660
+ } else if (createMode) {
661
+ await createRecord(ctx, {
662
+ ref: scope.kind === "rule" && scope.raw ? scope.raw : void 0,
663
+ scope: anchors,
664
+ data: value,
665
+ facetRule
666
+ });
656
667
  } else {
657
668
  await upsertRecord(ctx, {
658
669
  // External ref only when the underlying scope already carries
@@ -680,7 +691,7 @@ function useRecordEditor(args) {
680
691
  } finally {
681
692
  setIsSaving(false);
682
693
  }
683
- }, [scope.raw, value, savedSnapshot, facetRule, savedFacetRule, resolved.source, resolved.parentValue, resolved.recordId]);
694
+ }, [scope.raw, value, savedSnapshot, facetRule, savedFacetRule, resolved.source, resolved.parentValue, resolved.recordId, createMode]);
684
695
  const reset = useCallback(() => {
685
696
  setValue(savedSnapshot);
686
697
  setFacetRule(savedFacetRule);
@@ -700,6 +711,7 @@ function useRecordEditor(args) {
700
711
  value,
701
712
  onChange: setValue,
702
713
  source: effectiveSource,
714
+ recordId: resolved.recordId,
703
715
  parentValue: resolved.parentValue,
704
716
  scope,
705
717
  isDirty,
@@ -4172,7 +4184,16 @@ function RecordsAdminShell(props) {
4172
4184
  return parseRef(buildRef({ productId: selectedProductId }));
4173
4185
  }, [activeScope, cardinality, selectedRecordId, recordList.items, selectedProductId, drillTab, selectedVariantId, selectedBatchId]);
4174
4186
  const isCollection = cardinality === "collection";
4175
- const editingTargetScope = editingScope;
4187
+ const editingItemRecordId = isCollection ? selectedItemId : null;
4188
+ const editingTargetScope = useMemo(() => {
4189
+ if (!editingScope) return null;
4190
+ if (!isCollection || !editingItemRecordId) return editingScope;
4191
+ return {
4192
+ ...editingScope,
4193
+ itemId: editingItemRecordId,
4194
+ raw: editingScope.raw ? `${editingScope.raw}/item:${editingItemRecordId}` : `item:${editingItemRecordId}`
4195
+ };
4196
+ }, [editingScope, isCollection, editingItemRecordId]);
4176
4197
  const skipNextItemResetRef = useRef(false);
4177
4198
  useEffect(() => {
4178
4199
  if (skipNextItemResetRef.current) {
@@ -4266,9 +4287,22 @@ function RecordsAdminShell(props) {
4266
4287
  const editorCtx = useRecordEditor({
4267
4288
  ctx,
4268
4289
  scope: editingTargetScope ?? parseRef(""),
4269
- resolved: { data: resolved.data, source: resolved.source, sourceRef: resolved.sourceRef, parentValue: resolved.parentValue, facetRule: resolved.facetRule },
4290
+ resolved: {
4291
+ data: resolved.data,
4292
+ source: resolved.source,
4293
+ sourceRef: resolved.sourceRef,
4294
+ recordId: resolved.recordId,
4295
+ parentValue: resolved.parentValue,
4296
+ facetRule: resolved.facetRule
4297
+ },
4270
4298
  defaultData,
4271
4299
  reseed: dirtyStrategy === "keep" ? "preserve-dirty" : "always",
4300
+ // Collection-cardinality item drafts must `create` (insert a new row)
4301
+ // instead of `upsert` — multiple items can share the same scope +
4302
+ // recordType, so an upsert would collide on the server's dedupe key.
4303
+ // Flip on whenever the right pane shows an item that hasn't been
4304
+ // saved yet (no resolved.recordId).
4305
+ createMode: isCollection && !!selectedItemId && !resolved.recordId,
4272
4306
  // Seed an empty rule for freshly-minted `rule:{id}` refs so the Targeting
4273
4307
  // section can render its empty-state picker. For existing rule records
4274
4308
  // pull the saved rule off the resolved record. Pinned scopes get `null`
@@ -4486,14 +4520,14 @@ function RecordsAdminShell(props) {
4486
4520
  useEffect(() => {
4487
4521
  if (!pendingPasteTarget) return;
4488
4522
  if (!editingScope) return;
4489
- const matched = pendingPasteTarget.kind === "record" ? selectedRecordId === pendingPasteTarget.recordId : editingScope.raw === pendingPasteTarget.ref;
4523
+ const matched = pendingPasteTarget.kind === "record" ? (isCollection ? selectedItemId : selectedRecordId) === pendingPasteTarget.recordId : editingScope.raw === pendingPasteTarget.ref;
4490
4524
  if (!matched) return;
4491
4525
  const t = window.setTimeout(() => {
4492
4526
  setPendingPasteTarget(null);
4493
4527
  void pasteCurrent();
4494
4528
  }, 0);
4495
4529
  return () => window.clearTimeout(t);
4496
- }, [pendingPasteTarget, editingScope, selectedRecordId, pasteCurrent]);
4530
+ }, [pendingPasteTarget, editingScope, isCollection, selectedItemId, selectedRecordId, pasteCurrent]);
4497
4531
  const rowClipboard = enableClipboard ? (record) => {
4498
4532
  const summaryHasData = record.data != null;
4499
4533
  const sourceParsed = record.scope;
@@ -4562,7 +4596,7 @@ function RecordsAdminShell(props) {
4562
4596
  if (!ok) return;
4563
4597
  }
4564
4598
  try {
4565
- const { removeRecord: removeRecord2 } = await import('../../records-BXK5PXLN.js');
4599
+ const { removeRecord: removeRecord2 } = await import('../../records-AYYQSP7E.js');
4566
4600
  await removeRecord2(ctx, itemId);
4567
4601
  onTelemetry?.({ type: "item.delete", recordType, scopeRef: baseScopeRef, itemId });
4568
4602
  if (selectedItemId === itemId) setSelectedItemId(null);