@proveanything/smartlinks-utils-ui 0.4.2 → 0.6.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.
@@ -1,17 +1,11 @@
1
1
  // src/components/RecordsAdmin/data/scopeBridge.ts
2
2
  var parsedRefToScope = (ref) => {
3
- const scope = {};
4
- if (ref.productId) scope.productId = ref.productId;
5
- if (ref.variantId) scope.variantId = ref.variantId;
6
- if (ref.batchId) scope.batchId = ref.batchId;
7
- if (ref.proofId) scope.proofId = ref.proofId;
8
- if (ref.facetId) {
9
- scope.facets = [{
10
- key: ref.facetId,
11
- valueKeys: ref.facetValue ? [ref.facetValue] : []
12
- }];
13
- }
14
- return scope;
3
+ const anchors = {};
4
+ if (ref.productId) anchors.productId = ref.productId;
5
+ if (ref.variantId) anchors.variantId = ref.variantId;
6
+ if (ref.batchId) anchors.batchId = ref.batchId;
7
+ if (ref.proofId) anchors.proofId = ref.proofId;
8
+ return anchors;
15
9
  };
16
10
  var parsedRefToTarget = (ref) => {
17
11
  const target = {};
@@ -29,11 +23,7 @@ var scopesEqual = (a, b) => {
29
23
  if ((a.variantId ?? null) !== (b.variantId ?? null)) return false;
30
24
  if ((a.batchId ?? null) !== (b.batchId ?? null)) return false;
31
25
  if ((a.proofId ?? null) !== (b.proofId ?? null)) return false;
32
- const af = a.facets ?? [];
33
- const bf = b.facets ?? [];
34
- if (af.length !== bf.length) return false;
35
- const norm = (xs) => xs.map((f) => `${f.key}:${[...f.valueKeys].sort().join(",")}`).sort().join("|");
36
- return norm(af) === norm(bf);
26
+ return true;
37
27
  };
38
28
 
39
29
  // src/components/RecordsAdmin/data/records.ts
@@ -59,19 +49,15 @@ var listRecords = async (ctx, params = {}) => {
59
49
  hasMore: res?.pagination?.hasMore ?? false
60
50
  };
61
51
  };
62
- var getRecordByRef = async (ctx, ref) => {
63
- const res = await ctx.SL.app.records.list(
64
- ctx.collectionId,
65
- ctx.appId,
66
- { ...ctx.recordType ? { recordType: ctx.recordType } : {}, ref, limit: 1 },
67
- true
68
- );
69
- return res?.data?.[0] ?? null;
52
+ var getRecordById = async (ctx, recordId) => {
53
+ try {
54
+ return await ctx.SL.app.records.get(ctx.collectionId, ctx.appId, recordId, true);
55
+ } catch {
56
+ return null;
57
+ }
70
58
  };
71
59
  var upsertRecord = async (ctx, write) => {
72
- const ref = write.ref ?? deriveRefFromScope(write.scope);
73
60
  const payload = {
74
- ref,
75
61
  ...ctx.recordType ? { recordType: ctx.recordType } : {},
76
62
  data: write.data,
77
63
  status: write.status,
@@ -80,10 +66,14 @@ var upsertRecord = async (ctx, write) => {
80
66
  customId: write.customId,
81
67
  sourceSystem: write.sourceSystem
82
68
  };
69
+ if (write.ref) payload.ref = write.ref;
83
70
  if (write.facetRule && write.facetRule.all && write.facetRule.all.length > 0) {
84
71
  payload.facetRule = write.facetRule;
85
72
  } else {
86
- payload.scope = write.scope;
73
+ if (write.scope.productId) payload.productId = write.scope.productId;
74
+ if (write.scope.variantId) payload.variantId = write.scope.variantId;
75
+ if (write.scope.batchId) payload.batchId = write.scope.batchId;
76
+ if (write.scope.proofId) payload.proofId = write.scope.proofId;
87
77
  }
88
78
  const res = await ctx.SL.app.records.upsert(
89
79
  ctx.collectionId,
@@ -92,18 +82,38 @@ var upsertRecord = async (ctx, write) => {
92
82
  );
93
83
  return { record: res, isCreate: !!res?.created };
94
84
  };
85
+ var updateRecord = async (ctx, recordId, patch) => {
86
+ const payload = {
87
+ ...ctx.recordType ? { recordType: ctx.recordType } : {}
88
+ };
89
+ if (patch.data !== void 0) payload.data = patch.data;
90
+ if (patch.status !== void 0) payload.status = patch.status;
91
+ if (patch.startsAt !== void 0) payload.startsAt = patch.startsAt;
92
+ if (patch.expiresAt !== void 0) payload.expiresAt = patch.expiresAt;
93
+ if (patch.scope) {
94
+ if (patch.scope.productId !== void 0) payload.productId = patch.scope.productId;
95
+ if (patch.scope.variantId !== void 0) payload.variantId = patch.scope.variantId;
96
+ if (patch.scope.batchId !== void 0) payload.batchId = patch.scope.batchId;
97
+ if (patch.scope.proofId !== void 0) payload.proofId = patch.scope.proofId;
98
+ }
99
+ if (patch.facetRule !== void 0) payload.facetRule = patch.facetRule;
100
+ return ctx.SL.app.records.update(
101
+ ctx.collectionId,
102
+ ctx.appId,
103
+ recordId,
104
+ payload,
105
+ true
106
+ );
107
+ };
108
+ var removeRecord = async (ctx, recordId) => {
109
+ await ctx.SL.app.records.remove(ctx.collectionId, ctx.appId, recordId, true);
110
+ };
95
111
  var upsertRecordForScope = async (ctx, scope, data, extra = {}) => upsertRecord(ctx, {
96
112
  ref: scope.raw || void 0,
97
113
  scope: parsedRefToScope(scope),
98
114
  data,
99
115
  visibility: extra.visibility
100
116
  });
101
- var deleteRecord = async (ctx, ref) => {
102
- const existing = await getRecordByRef(ctx, ref).catch(() => null);
103
- if (!existing) return false;
104
- await ctx.SL.app.records.remove(ctx.collectionId, ctx.appId, existing.id, true);
105
- return true;
106
- };
107
117
  var restoreRecord = async (ctx, recordId) => ctx.SL.app.records.restore(ctx.collectionId, ctx.appId, recordId);
108
118
  var matchRecords = async (ctx, target, opts = {}) => ctx.SL.app.records.match(
109
119
  ctx.collectionId,
@@ -125,13 +135,19 @@ var bulkUpsert = async (ctx, entries) => {
125
135
  let failed = 0;
126
136
  for (let i = 0; i < entries.length; i += CHUNK) {
127
137
  const slice = entries.slice(i, i + CHUNK);
128
- const items = slice.map((e) => ({
129
- ref: e.ref ?? deriveRefFromScope(e.scope),
130
- ...ctx.recordType ? { recordType: ctx.recordType } : {},
131
- scope: e.scope,
132
- data: e.data,
133
- status: e.status
134
- }));
138
+ const items = slice.map((e) => {
139
+ const item = {
140
+ ...ctx.recordType ? { recordType: ctx.recordType } : {},
141
+ productId: e.scope.productId ?? null,
142
+ variantId: e.scope.variantId ?? null,
143
+ batchId: e.scope.batchId ?? null,
144
+ proofId: e.scope.proofId ?? null,
145
+ data: e.data,
146
+ status: e.status
147
+ };
148
+ if (e.ref) item.ref = e.ref;
149
+ return item;
150
+ });
135
151
  const res = await ctx.SL.app.records.bulkUpsert(ctx.collectionId, ctx.appId, items).catch(() => ({ saved: 0, failed: items.length }));
136
152
  saved += res.saved ?? 0;
137
153
  failed += res.failed ?? 0;
@@ -140,10 +156,15 @@ var bulkUpsert = async (ctx, entries) => {
140
156
  };
141
157
  var bulkDelete = async (ctx, input) => {
142
158
  if ("scope" in input) {
159
+ const scope = {};
160
+ if (input.scope.productId) scope.productId = input.scope.productId;
161
+ if (input.scope.variantId) scope.variantId = input.scope.variantId;
162
+ if (input.scope.batchId) scope.batchId = input.scope.batchId;
163
+ if (input.scope.proofId) scope.proofId = input.scope.proofId;
143
164
  const res = await ctx.SL.app.records.bulkDelete(
144
165
  ctx.collectionId,
145
166
  ctx.appId,
146
- { scope: input.scope, ...ctx.recordType ? { recordType: ctx.recordType } : {} }
167
+ { scope, ...ctx.recordType ? { recordType: ctx.recordType } : {} }
147
168
  );
148
169
  return { removed: res.deleted ?? 0 };
149
170
  }
@@ -160,22 +181,7 @@ var bulkDelete = async (ctx, input) => {
160
181
  }
161
182
  return { removed };
162
183
  };
163
- var deriveRefFromScope = (scope) => {
164
- const parts = [];
165
- if (scope.facets && scope.facets.length > 0) {
166
- const sorted = [...scope.facets].sort((a, b) => a.key.localeCompare(b.key));
167
- for (const f of sorted) {
168
- const vals = [...f.valueKeys].sort().join(",");
169
- parts.push(vals ? `facet:${f.key}=${vals}` : `facet:${f.key}`);
170
- }
171
- }
172
- if (scope.productId) parts.push(`product:${scope.productId}`);
173
- if (scope.variantId) parts.push(`variant:${scope.variantId}`);
174
- if (scope.batchId) parts.push(`batch:${scope.batchId}`);
175
- if (scope.proofId) parts.push(`proof:${scope.proofId}`);
176
- return parts.join("/");
177
- };
178
184
 
179
- export { bulkDelete, bulkUpsert, deleteRecord, getRecordByRef, listRecords, matchRecords, parsedRefToScope, parsedRefToTarget, restoreRecord, scopesEqual, upsertRecord, upsertRecordForScope };
180
- //# sourceMappingURL=chunk-76Y4UTYQ.js.map
181
- //# sourceMappingURL=chunk-76Y4UTYQ.js.map
185
+ export { bulkDelete, bulkUpsert, getRecordById, listRecords, matchRecords, parsedRefToScope, parsedRefToTarget, removeRecord, restoreRecord, scopesEqual, updateRecord, upsertRecord, upsertRecordForScope };
186
+ //# sourceMappingURL=chunk-WB775Z2I.js.map
187
+ //# sourceMappingURL=chunk-WB775Z2I.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-WB775Z2I.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 return await ctx.SL.app.records.get(ctx.collectionId, ctx.appId, recordId, true);\r\n } catch {\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 * 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};"]}