@aglyn/plugins-commerce 1.0.0-beta.221 → 1.0.0-beta.222

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 (125) hide show
  1. package/README.md +4 -2
  2. package/package.json +14 -13
  3. package/src/lib/components/console/catalog-organization-card.component.js +9 -0
  4. package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
  5. package/src/lib/components/console/discounts-card.component.js +8 -0
  6. package/src/lib/components/console/discounts-card.component.js.map +1 -1
  7. package/src/lib/components/console/gift-cards-card.component.js +8 -0
  8. package/src/lib/components/console/gift-cards-card.component.js.map +1 -1
  9. package/src/lib/components/console/host-coupons-card.component.js +8 -0
  10. package/src/lib/components/console/host-coupons-card.component.js.map +1 -1
  11. package/src/lib/components/console/host-orders-card.component.js +34 -70
  12. package/src/lib/components/console/host-orders-card.component.js.map +1 -1
  13. package/src/lib/components/console/product-zones.d.ts +7 -6
  14. package/src/lib/components/console/product-zones.js +5 -4
  15. package/src/lib/components/console/product-zones.js.map +1 -1
  16. package/src/lib/components/console/products-hub-card.component.js +86 -284
  17. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  18. package/src/lib/declarations.console-server.d.ts +38 -0
  19. package/src/lib/declarations.console-server.js +67 -0
  20. package/src/lib/declarations.console-server.js.map +1 -0
  21. package/src/lib/model/commerce-gift-cards.d.ts +26 -0
  22. package/src/lib/model/commerce-gift-cards.js +42 -0
  23. package/src/lib/model/commerce-gift-cards.js.map +1 -1
  24. package/src/lib/model/commerce-orders.d.ts +0 -57
  25. package/src/lib/model/commerce-orders.js +0 -80
  26. package/src/lib/model/commerce-orders.js.map +1 -1
  27. package/src/lib/model/index.d.ts +0 -1
  28. package/src/lib/model/index.js +0 -1
  29. package/src/lib/model/index.js.map +1 -1
  30. package/src/lib/plugin.js +5 -0
  31. package/src/lib/plugin.js.map +1 -1
  32. package/src/lib/server/api-v1/openapi.d.ts +27 -0
  33. package/src/lib/server/api-v1/openapi.js +219 -0
  34. package/src/lib/server/api-v1/openapi.js.map +1 -0
  35. package/src/lib/server/api-v1/orders-and-products.d.ts +19 -0
  36. package/src/lib/server/api-v1/orders-and-products.js +419 -0
  37. package/src/lib/server/api-v1/orders-and-products.js.map +1 -0
  38. package/src/lib/server/billing-webhook.js +10 -13
  39. package/src/lib/server/billing-webhook.js.map +1 -1
  40. package/src/lib/server/download.js +4 -1
  41. package/src/lib/server/download.js.map +1 -1
  42. package/src/lib/server/fulfill-order.d.ts +52 -11
  43. package/src/lib/server/fulfill-order.js +6 -9
  44. package/src/lib/server/fulfill-order.js.map +1 -1
  45. package/src/lib/server/gift-card-issue.d.ts +57 -0
  46. package/src/lib/server/gift-card-issue.js +155 -0
  47. package/src/lib/server/gift-card-issue.js.map +1 -0
  48. package/src/lib/server/gift-cards.js +25 -84
  49. package/src/lib/server/gift-cards.js.map +1 -1
  50. package/src/lib/server/membership-register.js +9 -8
  51. package/src/lib/server/membership-register.js.map +1 -1
  52. package/src/lib/server/newsletter.js +7 -5
  53. package/src/lib/server/newsletter.js.map +1 -1
  54. package/src/lib/server/paid-media-delivery.d.ts +21 -0
  55. package/src/lib/server/paid-media-delivery.js +23 -5
  56. package/src/lib/server/paid-media-delivery.js.map +1 -1
  57. package/src/lib/server/paid-media-serve-count.d.ts +28 -0
  58. package/src/lib/server/paid-media-serve-count.js +46 -0
  59. package/src/lib/server/paid-media-serve-count.js.map +1 -0
  60. package/src/lib/server/person-eraser.d.ts +45 -0
  61. package/src/lib/server/person-eraser.js +57 -0
  62. package/src/lib/server/person-eraser.js.map +1 -0
  63. package/src/lib/server/refund.js +15 -15
  64. package/src/lib/server/refund.js.map +1 -1
  65. package/src/lib/server/restock-flag.d.ts +2 -2
  66. package/src/lib/server/restock-flag.js +1 -1
  67. package/src/lib/server/restock-flag.js.map +1 -1
  68. package/src/lib/server/stream.js +4 -1
  69. package/src/lib/server/stream.js.map +1 -1
  70. package/src/lib/server.js +5 -21
  71. package/src/lib/server.js.map +1 -1
  72. package/src/lib/testing/stand-in-person-records.d.ts +43 -0
  73. package/src/lib/testing/stand-in-person-records.js +63 -0
  74. package/src/lib/testing/stand-in-person-records.js.map +1 -0
  75. package/src/lib/transfer/gift-card-confirm-step.component.d.ts +22 -0
  76. package/src/lib/transfer/gift-card-confirm-step.component.js +259 -0
  77. package/src/lib/transfer/gift-card-confirm-step.component.js.map +1 -0
  78. package/src/lib/transfer/gift-cards-plan.d.ts +29 -0
  79. package/src/lib/transfer/gift-cards-plan.js +40 -0
  80. package/src/lib/transfer/gift-cards-plan.js.map +1 -0
  81. package/src/lib/transfer/gift-cards.server.d.ts +34 -0
  82. package/src/lib/transfer/gift-cards.server.js +296 -0
  83. package/src/lib/transfer/gift-cards.server.js.map +1 -0
  84. package/src/lib/transfer/list-filter.d.ts +29 -0
  85. package/src/lib/transfer/list-filter.js +112 -0
  86. package/src/lib/transfer/list-filter.js.map +1 -0
  87. package/src/lib/transfer/product-import-results.d.ts +29 -0
  88. package/src/lib/transfer/product-import-results.js +49 -0
  89. package/src/lib/transfer/product-import-results.js.map +1 -0
  90. package/src/lib/transfer/product-import-step.component.d.ts +30 -0
  91. package/src/lib/transfer/product-import-step.component.js +99 -0
  92. package/src/lib/transfer/product-import-step.component.js.map +1 -0
  93. package/src/lib/transfer/product-transfer.d.ts +211 -0
  94. package/src/lib/transfer/product-transfer.js +1594 -0
  95. package/src/lib/transfer/product-transfer.js.map +1 -0
  96. package/src/lib/transfer/products.server.d.ts +44 -0
  97. package/src/lib/transfer/products.server.js +550 -0
  98. package/src/lib/transfer/products.server.js.map +1 -0
  99. package/src/lib/transfer/records-transfer.d.ts +182 -0
  100. package/src/lib/transfer/records-transfer.js +1153 -0
  101. package/src/lib/transfer/records-transfer.js.map +1 -0
  102. package/src/lib/transfer/records.server.d.ts +68 -0
  103. package/src/lib/transfer/records.server.js +455 -0
  104. package/src/lib/transfer/records.server.js.map +1 -0
  105. package/src/lib/transfer/register-transfer-resources.d.ts +17 -0
  106. package/src/lib/transfer/register-transfer-resources.js +171 -0
  107. package/src/lib/transfer/register-transfer-resources.js.map +1 -0
  108. package/src/lib/transfer/register-transfer-ui.d.ts +23 -0
  109. package/src/lib/transfer/register-transfer-ui.js +78 -0
  110. package/src/lib/transfer/register-transfer-ui.js.map +1 -0
  111. package/src/lib/transfer/server-common.d.ts +76 -0
  112. package/src/lib/transfer/server-common.js +165 -0
  113. package/src/lib/transfer/server-common.js.map +1 -0
  114. package/src/lib/transfer/transfer-header-actions.component.d.ts +39 -0
  115. package/src/lib/transfer/transfer-header-actions.component.js +79 -0
  116. package/src/lib/transfer/transfer-header-actions.component.js.map +1 -0
  117. package/src/lib/transfer/transfer-keys.d.ts +31 -0
  118. package/src/lib/transfer/transfer-keys.js +56 -0
  119. package/src/lib/transfer/transfer-keys.js.map +1 -0
  120. package/src/lib/model/commerce-io.d.ts +0 -36
  121. package/src/lib/model/commerce-io.js +0 -245
  122. package/src/lib/model/commerce-io.js.map +0 -1
  123. package/src/lib/server/contact-refund.d.ts +0 -117
  124. package/src/lib/server/contact-refund.js +0 -196
  125. package/src/lib/server/contact-refund.js.map +0 -1
@@ -0,0 +1,455 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import * as Aglyn from "@aglyn/aglyn/server";
18
+ import { buildMatchLookup } from "@aglyn/aglyn/data-transfer";
19
+ import { firebaseAdmin } from "@aglyn/tenant-data-admin";
20
+ import { ORDER_LIST_QUERY } from "../constants/orders-list-query.js";
21
+ import { CATEGORY_MATCH_KEYS, COUPON_MATCH_KEYS, DISCOUNT_KIND_PICKLIST, DISCOUNT_KIND_SPEC, DISCOUNT_MATCH_KEYS, categoryRecord, categoryWrite, couponRecord, couponWrite, discountRecord, discountWrite, orderRecord, planWithCreateRequired, promotionCode, rowChanges } from "./records-transfer.js";
22
+ import { NOTHING, ROW_BUDGET_MS, countSource, firestoreOf, hostRefOf, readSourcePage, readerSeesHost, revertEntries, withoutUndefined } from "./server-common.js";
23
+ const IN_MAX = 30;
24
+ const noExtra = async ()=>({});
25
+ function sourceFor(spec, firestore, ctx) {
26
+ var _ref;
27
+ var _spec_source, _spec_source1;
28
+ return _extends({
29
+ collection: spec.collection(firestore, ctx),
30
+ declaration: (_ref = (_spec_source = spec.source) == null ? void 0 : _spec_source.declaration) != null ? _ref : {
31
+ fields: [],
32
+ sorts: []
33
+ }
34
+ }, ((_spec_source1 = spec.source) == null ? void 0 : _spec_source1.order) ? {
35
+ order: spec.source.order
36
+ } : {});
37
+ }
38
+ function refuseFilterWithout(spec, options) {
39
+ if ((options == null ? void 0 : options.filter) && !spec.source) throw new Error('This list exports everything, or the records you select.');
40
+ }
41
+ async function readPage(spec, ctx, cursor, fieldIds, options, firestore) {
42
+ var _ref, _spec_extra;
43
+ if (!readerSeesHost(ctx, options)) return NOTHING;
44
+ refuseFilterWithout(spec, options);
45
+ const pageSize = Math.max(1, Math.min(500, (_ref = options == null ? void 0 : options.pageSize) != null ? _ref : 500));
46
+ const page = await readSourcePage(firestore, sourceFor(spec, firestore, ctx), cursor, options, pageSize);
47
+ const extra = await ((_spec_extra = spec.extra) != null ? _spec_extra : noExtra)(firestore, ctx, page.docs);
48
+ const rows = page.docs.map((doc)=>{
49
+ var _doc_data;
50
+ const record = spec.record(doc.id, (_doc_data = doc.data()) != null ? _doc_data : {}, extra);
51
+ return Object.fromEntries(fieldIds.map((fieldId)=>{
52
+ var _record_fieldId;
53
+ return [
54
+ fieldId,
55
+ (_record_fieldId = record[fieldId]) != null ? _record_fieldId : null
56
+ ];
57
+ }));
58
+ });
59
+ return {
60
+ rows,
61
+ next: page.next
62
+ };
63
+ }
64
+ async function count(spec, ctx, options, firestore) {
65
+ if (!readerSeesHost(ctx, options)) return 0;
66
+ refuseFilterWithout(spec, options);
67
+ return countSource(firestore, sourceFor(spec, firestore, ctx), options);
68
+ }
69
+ async function lookup(spec, ctx, requests, firestore) {
70
+ var _spec_extra, _doc_data;
71
+ const collection = spec.collection(firestore, ctx);
72
+ const found = new Map();
73
+ const keys = [];
74
+ for (const request of requests){
75
+ keys.push({
76
+ fieldId: request.fieldId,
77
+ normalizer: request.normalizer
78
+ });
79
+ for(let at = 0; at < request.values.length; at += IN_MAX){
80
+ var _spec_find;
81
+ const slice = request.values.slice(at, at + IN_MAX);
82
+ if (request.fieldId === 'id') {
83
+ for (const doc of (await firestore.getAll(...slice.map((id)=>collection.doc(id))))){
84
+ if (doc.exists) found.set(doc.id, doc);
85
+ }
86
+ continue;
87
+ }
88
+ const query = (_spec_find = spec.find) == null ? void 0 : _spec_find[request.fieldId];
89
+ if (!query) continue;
90
+ for (const doc of (await query(collection, slice).get()).docs)found.set(doc.id, doc);
91
+ }
92
+ }
93
+ const docs = [
94
+ ...found.values()
95
+ ];
96
+ const extra = docs.length ? await ((_spec_extra = spec.extra) != null ? _spec_extra : noExtra)(firestore, ctx, docs) : {};
97
+ const records = new Map();
98
+ for (const doc of docs)records.set(doc.id, spec.record(doc.id, (_doc_data = doc.data()) != null ? _doc_data : {}, extra));
99
+ const lookupMap = buildMatchLookup(docs.map((doc)=>{
100
+ var _doc_data;
101
+ return {
102
+ id: doc.id,
103
+ values: spec.matchValues(doc.id, (_doc_data = doc.data()) != null ? _doc_data : {})
104
+ };
105
+ }), keys);
106
+ return {
107
+ lookup: lookupMap,
108
+ records
109
+ };
110
+ }
111
+ /** The reading hooks every records resource shares: count, a page of an export, and the lookup. */ export function readableRecords(spec) {
112
+ return {
113
+ count: (ctx, options)=>count(spec, ctx, options, firestoreOf()),
114
+ readPage: (ctx, cursor, fieldIds, options)=>readPage(spec, ctx, cursor, fieldIds, options, firestoreOf()),
115
+ lookup: (ctx, requests)=>lookup(spec, ctx, requests, firestoreOf())
116
+ };
117
+ }
118
+ /** The hooks an export-only resource answers with: read, find by id, and refuse every write. */ function exportOnly(spec, noun, why) {
119
+ return _extends({
120
+ matchKeys: [
121
+ {
122
+ fieldId: 'id',
123
+ normalizer: 'aglynId'
124
+ }
125
+ ]
126
+ }, readableRecords(spec), {
127
+ invariants: [
128
+ {
129
+ id: `${noun}-export-only`,
130
+ label: why,
131
+ check: ()=>why
132
+ }
133
+ ],
134
+ async apply (_ctx, chunk) {
135
+ const results = chunk.rows.map((row)=>({
136
+ row: row.index,
137
+ outcome: 'failed',
138
+ reason: 'refusedValue',
139
+ message: why
140
+ }));
141
+ return {
142
+ results,
143
+ undo: []
144
+ };
145
+ },
146
+ async revert () {
147
+ return {
148
+ done: [],
149
+ conflicts: []
150
+ };
151
+ }
152
+ });
153
+ }
154
+ /*==========================================
155
+ * ORDERS — exported only
156
+ *=========================================*/ const ORDERS = {
157
+ collection: (firestore, ctx)=>hostRefOf(firestore, ctx).collection('orders'),
158
+ source: {
159
+ declaration: ORDER_LIST_QUERY,
160
+ order: {
161
+ path: 'createdAtMs',
162
+ direction: 'desc'
163
+ }
164
+ },
165
+ record: (id, data, extra)=>orderRecord(id, data, extra.productNames),
166
+ matchValues: (id)=>({
167
+ id
168
+ }),
169
+ /** A legacy flat row is named by its product, read for that page alone. */ async extra (firestore, ctx, docs) {
170
+ const ids = [
171
+ ...new Set(docs.filter((doc)=>{
172
+ var _doc_get;
173
+ return !((_doc_get = doc.get('lineItems')) == null ? void 0 : _doc_get.length) && doc.get('productId');
174
+ }).map((doc)=>String(doc.get('productId'))))
175
+ ];
176
+ const productNames = {};
177
+ const products = hostRefOf(firestore, ctx).collection('products');
178
+ for(let at = 0; at < ids.length; at += 100){
179
+ for (const doc of (await firestore.getAll(...ids.slice(at, at + 100).map((id)=>products.doc(id))))){
180
+ if (doc.exists && doc.get('name')) productNames[doc.id] = String(doc.get('name'));
181
+ }
182
+ }
183
+ return {
184
+ productNames
185
+ };
186
+ }
187
+ };
188
+ export const ordersTransfer = exportOnly(ORDERS, 'orders', 'Orders are exported, never imported: an order is the record of a sale, written by checkout, the register or a paid draft.');
189
+ /*==========================================
190
+ * IMPORTABLE RECORDS
191
+ *=========================================*/ /** A row the apply refuses, with the sentence the results show. */ let RowRefusal = class RowRefusal extends Error {
192
+ };
193
+ function writable(spec, matchKeys) {
194
+ return {
195
+ matchKeys,
196
+ count: (ctx, options)=>count(spec, ctx, options, firestoreOf()),
197
+ readPage: (ctx, cursor, fieldIds, options)=>readPage(spec, ctx, cursor, fieldIds, options, firestoreOf()),
198
+ lookup: (ctx, requests)=>lookup(spec, ctx, requests, firestoreOf()),
199
+ plan (_ctx, input) {
200
+ const rows = spec.normalize ? input.rows.map((row)=>{
201
+ var _ref;
202
+ return _extends({}, row, {
203
+ values: (_ref = spec.normalize == null ? void 0 : spec.normalize.call(spec, _extends({}, row.values))) != null ? _ref : row.values
204
+ });
205
+ }) : input.rows;
206
+ return planWithCreateRequired(_extends({}, input, {
207
+ rows
208
+ }), spec.requiredToCreate);
209
+ },
210
+ apply: (ctx, chunk, writer)=>applyRecords(spec, ctx, chunk, writer, firestoreOf()),
211
+ revert: (ctx, snapshot, decisions)=>revertRecords(spec, ctx, snapshot, decisions, firestoreOf())
212
+ };
213
+ }
214
+ /** Writes one chunk of planned rows: each a create or an update of one document. */ export async function applyRecords(spec, ctx, chunk, writer, firestore) {
215
+ var _spec_extra;
216
+ const collection = spec.collection(firestore, ctx);
217
+ const results = [];
218
+ const undo = [];
219
+ const extra = await ((_spec_extra = spec.extra) != null ? _spec_extra : noExtra)(firestore, ctx, []);
220
+ for (const row of chunk.rows){
221
+ const earlier = await writer.alreadyApplied(row.index);
222
+ if (earlier) {
223
+ results.push(earlier);
224
+ continue;
225
+ }
226
+ if (writer.timeLeftMs() < ROW_BUDGET_MS) break;
227
+ const changes = rowChanges(row);
228
+ const creating = row.verdict === 'create';
229
+ const id = creating ? spec.newId(row, changes) : row.recordId;
230
+ const ref = collection.doc(id);
231
+ try {
232
+ const outcome = await firestore.runTransaction(async (tx)=>{
233
+ var _snapshot_data, _ref;
234
+ const snapshot = await tx.get(ref);
235
+ if (creating && snapshot.exists) throw new RowRefusal(`"${id}" already exists; match it to update it instead.`);
236
+ if (!creating && !snapshot.exists) throw new RowRefusal('The record was deleted after the dry run.');
237
+ const current = snapshot.exists ? (_snapshot_data = snapshot.data()) != null ? _snapshot_data : {} : null;
238
+ const made = spec.write(id, current, changes, extra);
239
+ if ('problem' in made) throw new RowRefusal(made.problem);
240
+ const doc = withoutUndefined(_extends({}, made.doc, creating ? (_ref = spec.createStamps == null ? void 0 : spec.createStamps.call(spec)) != null ? _ref : {} : {}));
241
+ if (creating) tx.create(ref, doc);
242
+ else tx.set(ref, doc);
243
+ return {
244
+ current,
245
+ doc
246
+ };
247
+ });
248
+ spec.afterWrite == null ? void 0 : spec.afterWrite.call(spec, id, outcome.doc, extra);
249
+ const after = spec.record(id, outcome.doc, extra);
250
+ const before = outcome.current ? spec.record(id, outcome.current, extra) : null;
251
+ const touched = Object.keys(changes);
252
+ const result = {
253
+ row: row.index,
254
+ outcome: creating ? 'created' : 'updated',
255
+ recordId: id
256
+ };
257
+ const entry = creating ? {
258
+ row: row.index,
259
+ recordId: id,
260
+ action: 'created',
261
+ written: pickKeys(after, touched)
262
+ } : {
263
+ row: row.index,
264
+ recordId: id,
265
+ action: 'updated',
266
+ previous: pickKeys(before != null ? before : {}, touched),
267
+ written: pickKeys(after, touched)
268
+ };
269
+ results.push(result);
270
+ undo.push(entry);
271
+ await writer.markApplied(result, entry);
272
+ } catch (error) {
273
+ if (!(error instanceof RowRefusal)) throw error;
274
+ const result = {
275
+ row: row.index,
276
+ outcome: 'failed',
277
+ reason: 'refusedValue',
278
+ message: error.message
279
+ };
280
+ results.push(result);
281
+ await writer.markApplied(result);
282
+ }
283
+ }
284
+ return {
285
+ results,
286
+ undo
287
+ };
288
+ }
289
+ const pickKeys = (record, keys)=>Object.fromEntries(keys.map((key)=>{
290
+ var _record_key;
291
+ return [
292
+ key,
293
+ (_record_key = record[key]) != null ? _record_key : null
294
+ ];
295
+ }));
296
+ /** Reverses one chunk: a created record deleted, an updated one's fields put back. */ export async function revertRecords(spec, ctx, snapshot, decisions, firestore) {
297
+ var _spec_extra;
298
+ const collection = spec.collection(firestore, ctx);
299
+ const extra = await ((_spec_extra = spec.extra) != null ? _spec_extra : noExtra)(firestore, ctx, []);
300
+ return revertEntries(snapshot, decisions, {
301
+ async current (entry) {
302
+ var _doc_data;
303
+ const doc = await collection.doc(entry.recordId).get();
304
+ return doc.exists ? spec.record(doc.id, (_doc_data = doc.data()) != null ? _doc_data : {}, extra) : null;
305
+ },
306
+ async remove (entry) {
307
+ await collection.doc(entry.recordId).delete();
308
+ },
309
+ async restore (entry, values) {
310
+ var _doc_data;
311
+ const ref = collection.doc(entry.recordId);
312
+ const doc = await ref.get();
313
+ if (!doc.exists) return;
314
+ const made = spec.write(entry.recordId, (_doc_data = doc.data()) != null ? _doc_data : {}, values, extra);
315
+ // A value the record held before the import is put back as it was, even one a file could not set.
316
+ if ('problem' in made) throw new Error(`Undo could not restore ${entry.recordId}: ${made.problem}`);
317
+ await ref.set(withoutUndefined(made.doc));
318
+ }
319
+ });
320
+ }
321
+ /*------------------------------------------
322
+ * Discounts
323
+ *-----------------------------------------*/ const DISCOUNTS = {
324
+ collection: (firestore, ctx)=>hostRefOf(firestore, ctx).collection('discounts'),
325
+ record: (id, data)=>discountRecord(id, data),
326
+ matchValues: (id, data)=>{
327
+ var _data_code, _data_name;
328
+ return {
329
+ id,
330
+ code: (_data_code = data['code']) != null ? _data_code : null,
331
+ name: (_data_name = data['name']) != null ? _data_name : null
332
+ };
333
+ },
334
+ find: {
335
+ code: (collection, values)=>collection.where('code', 'in', values.map((value)=>promotionCode(value))),
336
+ name: (collection, values)=>collection.where('name', 'in', values)
337
+ },
338
+ requiredToCreate: [
339
+ 'kind'
340
+ ],
341
+ newId: ()=>Aglyn.createResourceUid(),
342
+ write: (_id, current, changes)=>discountWrite(current, changes),
343
+ normalize (values) {
344
+ if ('code' in values) values['code'] = promotionCode(values['code']) || null;
345
+ return values;
346
+ }
347
+ };
348
+ export const discountsTransfer = _extends({}, writable(DISCOUNTS, DISCOUNT_MATCH_KEYS), {
349
+ async picklists (_ctx, picklistIds) {
350
+ return picklistIds.includes(DISCOUNT_KIND_PICKLIST) ? {
351
+ [DISCOUNT_KIND_PICKLIST]: {
352
+ spec: DISCOUNT_KIND_SPEC,
353
+ set: {
354
+ values: DISCOUNT_KIND_SPEC.standardValues.map((value)=>({
355
+ id: value.id,
356
+ label: value.label,
357
+ active: true
358
+ })),
359
+ defaultValueId: 'percent'
360
+ }
361
+ }
362
+ } : {};
363
+ }
364
+ });
365
+ /*------------------------------------------
366
+ * Coupons
367
+ *-----------------------------------------*/ const COUPONS = {
368
+ collection: (firestore, ctx)=>hostRefOf(firestore, ctx).collection('coupons'),
369
+ record: (id, data)=>couponRecord(id, data),
370
+ matchValues: (id)=>({
371
+ id,
372
+ code: id
373
+ }),
374
+ // A coupon's code is its document id: a code is looked up by id.
375
+ find: {
376
+ code: (collection, values)=>collection.where(firebaseAdmin.firestore.FieldPath.documentId(), 'in', values.map((value)=>promotionCode(value)).filter(Boolean))
377
+ },
378
+ requiredToCreate: [
379
+ 'code',
380
+ 'percentOff'
381
+ ],
382
+ newId: (_row, changes)=>{
383
+ const code = promotionCode(changes['code']);
384
+ if (!code) throw new RowRefusal('A coupon needs a code.');
385
+ return code;
386
+ },
387
+ write: (_id, current, changes)=>couponWrite(current, changes),
388
+ createStamps: ()=>({
389
+ createdAt: firebaseAdmin.firestore.Timestamp.now()
390
+ }),
391
+ normalize (values) {
392
+ if ('code' in values) values['code'] = promotionCode(values['code']) || null;
393
+ return values;
394
+ }
395
+ };
396
+ export const couponsTransfer = writable(COUPONS, COUPON_MATCH_KEYS);
397
+ /*------------------------------------------
398
+ * Categories
399
+ *-----------------------------------------*/ /** Every category of the site, for parents and for naming them. */ async function readCategories(firestore, ctx) {
400
+ const snapshot = await hostRefOf(firestore, ctx).collection('productCategories').limit(2000).get();
401
+ return new Map(snapshot.docs.map((doc)=>{
402
+ var _doc_data;
403
+ return [
404
+ doc.id,
405
+ (_doc_data = doc.data()) != null ? _doc_data : {}
406
+ ];
407
+ }));
408
+ }
409
+ const CATEGORIES = {
410
+ collection: (firestore, ctx)=>hostRefOf(firestore, ctx).collection('productCategories'),
411
+ record (id, data, extra) {
412
+ var _extra_categories;
413
+ const slugs = new Map([
414
+ ...(_extra_categories = extra.categories) != null ? _extra_categories : new Map()
415
+ ].map(([key, category])=>{
416
+ var _category_slug;
417
+ return [
418
+ key,
419
+ String((_category_slug = category.slug) != null ? _category_slug : key)
420
+ ];
421
+ }));
422
+ return categoryRecord(id, data, slugs);
423
+ },
424
+ matchValues: (id, data)=>{
425
+ var _data_slug, _data_name;
426
+ return {
427
+ id,
428
+ slug: (_data_slug = data['slug']) != null ? _data_slug : null,
429
+ name: (_data_name = data['name']) != null ? _data_name : null
430
+ };
431
+ },
432
+ find: {
433
+ slug: (collection, values)=>collection.where('slug', 'in', values),
434
+ name: (collection, values)=>collection.where('name', 'in', values)
435
+ },
436
+ extra: async (firestore, ctx)=>({
437
+ categories: await readCategories(firestore, ctx)
438
+ }),
439
+ requiredToCreate: [
440
+ 'name'
441
+ ],
442
+ newId: ()=>Aglyn.createResourceUid(),
443
+ write: (id, current, changes, extra)=>{
444
+ var _extra_categories;
445
+ return categoryWrite(id, current, changes, (_extra_categories = extra.categories) != null ? _extra_categories : new Map());
446
+ },
447
+ // A category written earlier in the file is a parent a later row can name.
448
+ afterWrite (id, doc, extra) {
449
+ var _extra_categories;
450
+ (_extra_categories = extra.categories) == null ? void 0 : _extra_categories.set(id, doc);
451
+ }
452
+ };
453
+ export const categoriesTransfer = writable(CATEGORIES, CATEGORY_MATCH_KEYS);
454
+
455
+ //# sourceMappingURL=records.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/transfer/records.server.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as Aglyn from '@aglyn/aglyn/server'\nimport {\n buildMatchLookup,\n type BuildTransferPlanInput,\n type MatchKeySpec,\n type MatchLookupRequest,\n type PlannedTransferRow,\n type TransferChunk,\n type TransferPlan,\n type TransferRowResult,\n type TransferUndoEntry,\n type TransferUndoSnapshot,\n} from '@aglyn/aglyn/data-transfer'\nimport type {\n PluginTransferResource,\n TransferApplyResult,\n TransferApplyWriter,\n TransferLookupResult,\n TransferReadOptions,\n TransferReadPage,\n TransferResourceContext,\n TransferRevertDecisions,\n TransferRevertResult,\n} from '@aglyn/aglyn/plugin-manager/plugin-transfer-resources'\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport { ORDER_LIST_QUERY } from '../constants/orders-list-query'\nimport {\n CATEGORY_MATCH_KEYS,\n COUPON_MATCH_KEYS,\n DISCOUNT_KIND_PICKLIST,\n DISCOUNT_KIND_SPEC,\n DISCOUNT_MATCH_KEYS,\n categoryRecord,\n categoryWrite,\n couponRecord,\n couponWrite,\n discountRecord,\n discountWrite,\n orderRecord,\n planWithCreateRequired,\n promotionCode,\n rowChanges,\n type CategoryIndex,\n type StoredCategory,\n type StoredCoupon,\n type StoredOrder,\n} from './records-transfer'\nimport {\n NOTHING,\n ROW_BUDGET_MS,\n countSource,\n firestoreOf,\n hostRefOf,\n readSourcePage,\n readerSeesHost,\n revertEntries,\n withoutUndefined,\n type CommerceListSource,\n type Firestore,\n} from './server-common'\n\n/*\n * THE SERVER HALVES OF ORDERS, DISCOUNTS, COUPONS AND CATEGORIES\n * (AGL-3531), and the reads gift cards share (`gift-cards.server.ts`,\n * AGL-3551). Their records are plain documents under the site,\n * so one shape serves each: an export reads the list's query (orders) or the\n * whole collection page by page; a lookup finds documents by the resource's\n * keys; an import writes the same document the console's card writes, and\n * undo puts back what it held or deletes what the import made.\n *\n * Orders declare `records` too — the kind a file of rows is — but refuse\n * every row they are handed: their fields are all read-only\n * and the invariant below fails a row that would write, so a dry run says\n * why rather than an apply discovering it.\n */\n\nexport type Doc = Record<string, unknown>\ntype Collection = FirebaseFirestore.CollectionReference\n\nconst IN_MAX = 30\n\nexport interface RecordsSpec {\n collection(firestore: Firestore, ctx: TransferResourceContext): Collection\n /** The list's query an export may carry a filter of. */\n source?: Omit<CommerceListSource, 'collection'>\n /** A document as a file names it. */\n record(id: string, data: Doc, extra: RecordsExtra): Record<string, unknown>\n /** The values a document is found by, per match key. */\n matchValues(id: string, data: Doc): Record<string, unknown>\n /** What a lookup or export reads once per call, besides the documents. */\n extra?(firestore: Firestore, ctx: TransferResourceContext, docs: readonly FirebaseFirestore.DocumentSnapshot[]): Promise<RecordsExtra>\n /** Finds documents by a key's values (at most 30); the id key is read directly. */\n find?: Record<string, (collection: Collection, values: string[]) => FirebaseFirestore.Query>\n}\n\nexport type RecordsExtra = {\n productNames?: Record<string, string>\n categories?: CategoryIndex\n}\n\nconst noExtra = async (): Promise<RecordsExtra> => ({})\n\nfunction sourceFor(spec: RecordsSpec, firestore: Firestore, ctx: TransferResourceContext): CommerceListSource {\n return {\n collection: spec.collection(firestore, ctx),\n declaration: spec.source?.declaration ?? { fields: [], sorts: [] },\n ...(spec.source?.order ? { order: spec.source.order } : {}),\n }\n}\n\nfunction refuseFilterWithout(spec: RecordsSpec, options?: TransferReadOptions): void {\n if (options?.filter && !spec.source) throw new Error('This list exports everything, or the records you select.')\n}\n\nasync function readPage(\n spec: RecordsSpec,\n ctx: TransferResourceContext,\n cursor: string | null,\n fieldIds: readonly string[],\n options: TransferReadOptions | undefined,\n firestore: Firestore,\n): Promise<TransferReadPage> {\n if (!readerSeesHost(ctx, options)) return NOTHING\n refuseFilterWithout(spec, options)\n const pageSize = Math.max(1, Math.min(500, options?.pageSize ?? 500))\n const page = await readSourcePage(firestore, sourceFor(spec, firestore, ctx), cursor, options, pageSize)\n const extra = await (spec.extra ?? noExtra)(firestore, ctx, page.docs)\n const rows = page.docs.map((doc) => {\n const record = spec.record(doc.id, (doc.data() ?? {}) as Doc, extra)\n return Object.fromEntries(fieldIds.map((fieldId) => [fieldId, record[fieldId] ?? null]))\n })\n return { rows, next: page.next }\n}\n\nasync function count(\n spec: RecordsSpec,\n ctx: TransferResourceContext,\n options: TransferReadOptions,\n firestore: Firestore,\n): Promise<number> {\n if (!readerSeesHost(ctx, options)) return 0\n refuseFilterWithout(spec, options)\n return countSource(firestore, sourceFor(spec, firestore, ctx), options)\n}\n\nasync function lookup(\n spec: RecordsSpec,\n ctx: TransferResourceContext,\n requests: readonly MatchLookupRequest[],\n firestore: Firestore,\n): Promise<TransferLookupResult> {\n const collection = spec.collection(firestore, ctx)\n const found = new Map<string, FirebaseFirestore.DocumentSnapshot>()\n const keys: MatchKeySpec[] = []\n for (const request of requests) {\n keys.push({ fieldId: request.fieldId, normalizer: request.normalizer })\n for (let at = 0; at < request.values.length; at += IN_MAX) {\n const slice = request.values.slice(at, at + IN_MAX)\n if (request.fieldId === 'id') {\n for (const doc of await firestore.getAll(...slice.map((id) => collection.doc(id)))) {\n if (doc.exists) found.set(doc.id, doc)\n }\n continue\n }\n const query = spec.find?.[request.fieldId]\n if (!query) continue\n for (const doc of (await query(collection, slice).get()).docs) found.set(doc.id, doc)\n }\n }\n const docs = [...found.values()]\n const extra = docs.length ? await (spec.extra ?? noExtra)(firestore, ctx, docs) : {}\n const records = new Map<string, Readonly<Record<string, unknown>>>()\n for (const doc of docs) records.set(doc.id, spec.record(doc.id, (doc.data() ?? {}) as Doc, extra))\n const lookupMap = buildMatchLookup(\n docs.map((doc) => ({ id: doc.id, values: spec.matchValues(doc.id, (doc.data() ?? {}) as Doc) })),\n keys,\n )\n return { lookup: lookupMap, records }\n}\n\n/** The reading hooks every records resource shares: count, a page of an export, and the lookup. */\nexport function readableRecords(spec: RecordsSpec): Pick<PluginTransferResource, 'count' | 'readPage' | 'lookup'> {\n return {\n count: (ctx, options) => count(spec, ctx, options, firestoreOf()),\n readPage: (ctx, cursor, fieldIds, options) => readPage(spec, ctx, cursor, fieldIds, options, firestoreOf()),\n lookup: (ctx, requests) => lookup(spec, ctx, requests, firestoreOf()),\n }\n}\n\n/** The hooks an export-only resource answers with: read, find by id, and refuse every write. */\nfunction exportOnly(spec: RecordsSpec, noun: string, why: string): PluginTransferResource {\n return {\n matchKeys: [{ fieldId: 'id', normalizer: 'aglynId' }],\n ...readableRecords(spec),\n invariants: [{ id: `${noun}-export-only`, label: why, check: () => why }],\n async apply(_ctx, chunk) {\n const results: TransferRowResult[] = chunk.rows.map((row) => ({\n row: row.index,\n outcome: 'failed',\n reason: 'refusedValue',\n message: why,\n }))\n return { results, undo: [] }\n },\n async revert() {\n return { done: [], conflicts: [] }\n },\n }\n}\n\n/*==========================================\n * ORDERS — exported only\n *=========================================*/\n\nconst ORDERS: RecordsSpec = {\n collection: (firestore, ctx) => hostRefOf(firestore, ctx).collection('orders'),\n source: { declaration: ORDER_LIST_QUERY, order: { path: 'createdAtMs', direction: 'desc' } },\n record: (id, data, extra) => orderRecord(id, data as StoredOrder, extra.productNames),\n matchValues: (id) => ({ id }),\n /** A legacy flat row is named by its product, read for that page alone. */\n async extra(firestore, ctx, docs) {\n const ids = [\n ...new Set(\n docs\n .filter((doc) => !(doc.get('lineItems') as unknown[] | undefined)?.length && doc.get('productId'))\n .map((doc) => String(doc.get('productId'))),\n ),\n ]\n const productNames: Record<string, string> = {}\n const products = hostRefOf(firestore, ctx).collection('products')\n for (let at = 0; at < ids.length; at += 100) {\n for (const doc of await firestore.getAll(...ids.slice(at, at + 100).map((id) => products.doc(id)))) {\n if (doc.exists && doc.get('name')) productNames[doc.id] = String(doc.get('name'))\n }\n }\n return { productNames }\n },\n}\n\nexport const ordersTransfer: PluginTransferResource = exportOnly(\n ORDERS,\n 'orders',\n 'Orders are exported, never imported: an order is the record of a sale, written by checkout, the register or a paid draft.',\n)\n\n\n/*==========================================\n * IMPORTABLE RECORDS\n *=========================================*/\n\n/** A row the apply refuses, with the sentence the results show. */\nclass RowRefusal extends Error {}\n\ninterface WritableSpec extends RecordsSpec {\n /** The fields a new record cannot be made without. */\n requiredToCreate: readonly string[]\n /** A new record's id: a fresh one, or what the row names (a coupon's code). */\n newId(row: PlannedTransferRow, changes: Readonly<Record<string, unknown>>): string\n /** The document a row's changes make, or the refusal. */\n write(\n id: string,\n current: Doc | null,\n changes: Readonly<Record<string, unknown>>,\n extra: RecordsExtra,\n ): { doc: Record<string, unknown> } | { problem: string }\n /** Stamps a create carries beyond its fields. */\n createStamps?(): Record<string, unknown>\n /** Values normalized before matching and planning (a code's case). */\n normalize?(values: Record<string, unknown>): Record<string, unknown>\n /** Called after a record is written, with what the next rows resolve against. */\n afterWrite?(id: string, doc: Doc, extra: RecordsExtra): void\n}\n\nfunction writable(spec: WritableSpec, matchKeys: readonly MatchKeySpec[]): PluginTransferResource {\n return {\n matchKeys,\n count: (ctx, options) => count(spec, ctx, options, firestoreOf()),\n readPage: (ctx, cursor, fieldIds, options) => readPage(spec, ctx, cursor, fieldIds, options, firestoreOf()),\n lookup: (ctx, requests) => lookup(spec, ctx, requests, firestoreOf()),\n plan(_ctx, input: BuildTransferPlanInput): TransferPlan {\n const rows = spec.normalize\n ? input.rows.map((row) => ({ ...row, values: spec.normalize?.({ ...row.values }) ?? row.values }))\n : input.rows\n return planWithCreateRequired({ ...input, rows }, spec.requiredToCreate)\n },\n apply: (ctx, chunk, writer) => applyRecords(spec, ctx, chunk, writer, firestoreOf()),\n revert: (ctx, snapshot, decisions) => revertRecords(spec, ctx, snapshot, decisions, firestoreOf()),\n }\n}\n\n/** Writes one chunk of planned rows: each a create or an update of one document. */\nexport async function applyRecords(\n spec: WritableSpec,\n ctx: TransferResourceContext,\n chunk: TransferChunk<PlannedTransferRow>,\n writer: TransferApplyWriter,\n firestore: Firestore,\n): Promise<TransferApplyResult> {\n const collection = spec.collection(firestore, ctx)\n const results: TransferRowResult[] = []\n const undo: TransferUndoEntry[] = []\n const extra = await (spec.extra ?? noExtra)(firestore, ctx, [])\n for (const row of chunk.rows) {\n const earlier = await writer.alreadyApplied(row.index)\n if (earlier) {\n results.push(earlier)\n continue\n }\n if (writer.timeLeftMs() < ROW_BUDGET_MS) break\n const changes = rowChanges(row)\n const creating = row.verdict === 'create'\n const id = creating ? spec.newId(row, changes) : (row.recordId as string)\n const ref = collection.doc(id)\n try {\n const outcome = await firestore.runTransaction(async (tx) => {\n const snapshot = await tx.get(ref)\n if (creating && snapshot.exists) throw new RowRefusal(`\"${id}\" already exists; match it to update it instead.`)\n if (!creating && !snapshot.exists) throw new RowRefusal('The record was deleted after the dry run.')\n const current = snapshot.exists ? ((snapshot.data() ?? {}) as Doc) : null\n const made = spec.write(id, current, changes, extra)\n if ('problem' in made) throw new RowRefusal(made.problem)\n const doc = withoutUndefined({ ...made.doc, ...(creating ? (spec.createStamps?.() ?? {}) : {}) })\n if (creating) tx.create(ref, doc)\n else tx.set(ref, doc)\n return { current, doc }\n })\n spec.afterWrite?.(id, outcome.doc, extra)\n const after = spec.record(id, outcome.doc, extra)\n const before = outcome.current ? spec.record(id, outcome.current, extra) : null\n const touched = Object.keys(changes)\n const result: TransferRowResult = { row: row.index, outcome: creating ? 'created' : 'updated', recordId: id }\n const entry: TransferUndoEntry = creating\n ? { row: row.index, recordId: id, action: 'created', written: pickKeys(after, touched) }\n : {\n row: row.index,\n recordId: id,\n action: 'updated',\n previous: pickKeys(before ?? {}, touched),\n written: pickKeys(after, touched),\n }\n results.push(result)\n undo.push(entry)\n await writer.markApplied(result, entry)\n } catch (error) {\n if (!(error instanceof RowRefusal)) throw error\n const result: TransferRowResult = { row: row.index, outcome: 'failed', reason: 'refusedValue', message: error.message }\n results.push(result)\n await writer.markApplied(result)\n }\n }\n return { results, undo }\n}\n\nconst pickKeys = (record: Readonly<Record<string, unknown>>, keys: readonly string[]) =>\n Object.fromEntries(keys.map((key) => [key, record[key] ?? null]))\n\n/** Reverses one chunk: a created record deleted, an updated one's fields put back. */\nexport async function revertRecords(\n spec: WritableSpec,\n ctx: TransferResourceContext,\n snapshot: TransferUndoSnapshot,\n decisions: TransferRevertDecisions | undefined,\n firestore: Firestore,\n): Promise<TransferRevertResult> {\n const collection = spec.collection(firestore, ctx)\n const extra = await (spec.extra ?? noExtra)(firestore, ctx, [])\n return revertEntries(snapshot, decisions, {\n async current(entry) {\n const doc = await collection.doc(entry.recordId).get()\n return doc.exists ? spec.record(doc.id, (doc.data() ?? {}) as Doc, extra) : null\n },\n async remove(entry) {\n await collection.doc(entry.recordId).delete()\n },\n async restore(entry, values) {\n const ref = collection.doc(entry.recordId)\n const doc = await ref.get()\n if (!doc.exists) return\n const made = spec.write(entry.recordId, (doc.data() ?? {}) as Doc, values, extra)\n // A value the record held before the import is put back as it was, even one a file could not set.\n if ('problem' in made) throw new Error(`Undo could not restore ${entry.recordId}: ${made.problem}`)\n await ref.set(withoutUndefined(made.doc))\n },\n })\n}\n\n/*------------------------------------------\n * Discounts\n *-----------------------------------------*/\n\nconst DISCOUNTS: WritableSpec = {\n collection: (firestore, ctx) => hostRefOf(firestore, ctx).collection('discounts'),\n record: (id, data) => discountRecord(id, data),\n matchValues: (id, data) => ({ id, code: data['code'] ?? null, name: data['name'] ?? null }),\n find: {\n code: (collection, values) => collection.where('code', 'in', values.map((value) => promotionCode(value))),\n name: (collection, values) => collection.where('name', 'in', values),\n },\n requiredToCreate: ['kind'],\n newId: () => Aglyn.createResourceUid(),\n write: (_id, current, changes) => discountWrite(current, changes),\n normalize(values) {\n if ('code' in values) values['code'] = promotionCode(values['code']) || null\n return values\n },\n}\n\nexport const discountsTransfer: PluginTransferResource = {\n ...writable(DISCOUNTS, DISCOUNT_MATCH_KEYS),\n async picklists(_ctx, picklistIds) {\n return picklistIds.includes(DISCOUNT_KIND_PICKLIST)\n ? {\n [DISCOUNT_KIND_PICKLIST]: {\n spec: DISCOUNT_KIND_SPEC,\n set: {\n values: DISCOUNT_KIND_SPEC.standardValues.map((value) => ({ id: value.id, label: value.label, active: true })),\n defaultValueId: 'percent',\n },\n },\n }\n : {}\n },\n}\n\n/*------------------------------------------\n * Coupons\n *-----------------------------------------*/\n\nconst COUPONS: WritableSpec = {\n collection: (firestore, ctx) => hostRefOf(firestore, ctx).collection('coupons'),\n record: (id, data) => couponRecord(id, data as StoredCoupon),\n matchValues: (id) => ({ id, code: id }),\n // A coupon's code is its document id: a code is looked up by id.\n find: {\n code: (collection, values) =>\n collection.where(\n firebaseAdmin.firestore.FieldPath.documentId(),\n 'in',\n values.map((value) => promotionCode(value)).filter(Boolean),\n ),\n },\n requiredToCreate: ['code', 'percentOff'],\n newId: (_row, changes) => {\n const code = promotionCode(changes['code'])\n if (!code) throw new RowRefusal('A coupon needs a code.')\n return code\n },\n write: (_id, current, changes) => couponWrite(current as StoredCoupon | null, changes),\n createStamps: () => ({ createdAt: firebaseAdmin.firestore.Timestamp.now() }),\n normalize(values) {\n if ('code' in values) values['code'] = promotionCode(values['code']) || null\n return values\n },\n}\n\nexport const couponsTransfer: PluginTransferResource = writable(COUPONS, COUPON_MATCH_KEYS)\n\n/*------------------------------------------\n * Categories\n *-----------------------------------------*/\n\n/** Every category of the site, for parents and for naming them. */\nasync function readCategories(firestore: Firestore, ctx: TransferResourceContext): Promise<CategoryIndex> {\n const snapshot = await hostRefOf(firestore, ctx).collection('productCategories').limit(2000).get()\n return new Map(snapshot.docs.map((doc) => [doc.id, (doc.data() ?? {}) as StoredCategory]))\n}\n\nconst CATEGORIES: WritableSpec = {\n collection: (firestore, ctx) => hostRefOf(firestore, ctx).collection('productCategories'),\n record(id, data, extra) {\n const slugs = new Map([...(extra.categories ?? new Map())].map(([key, category]) => [key, String(category.slug ?? key)]))\n return categoryRecord(id, data as StoredCategory, slugs)\n },\n matchValues: (id, data) => ({ id, slug: data['slug'] ?? null, name: data['name'] ?? null }),\n find: {\n slug: (collection, values) => collection.where('slug', 'in', values),\n name: (collection, values) => collection.where('name', 'in', values),\n },\n extra: async (firestore, ctx) => ({ categories: await readCategories(firestore, ctx) }),\n requiredToCreate: ['name'],\n newId: () => Aglyn.createResourceUid(),\n write: (id, current, changes, extra) =>\n categoryWrite(id, current as StoredCategory | null, changes, extra.categories ?? new Map()),\n // A category written earlier in the file is a parent a later row can name.\n afterWrite(id, doc, extra) {\n extra.categories?.set(id, doc as StoredCategory)\n },\n}\n\nexport const categoriesTransfer: PluginTransferResource = writable(CATEGORIES, CATEGORY_MATCH_KEYS)\n"],"names":["Aglyn","buildMatchLookup","firebaseAdmin","ORDER_LIST_QUERY","CATEGORY_MATCH_KEYS","COUPON_MATCH_KEYS","DISCOUNT_KIND_PICKLIST","DISCOUNT_KIND_SPEC","DISCOUNT_MATCH_KEYS","categoryRecord","categoryWrite","couponRecord","couponWrite","discountRecord","discountWrite","orderRecord","planWithCreateRequired","promotionCode","rowChanges","NOTHING","ROW_BUDGET_MS","countSource","firestoreOf","hostRefOf","readSourcePage","readerSeesHost","revertEntries","withoutUndefined","IN_MAX","noExtra","sourceFor","spec","firestore","ctx","collection","declaration","source","fields","sorts","order","refuseFilterWithout","options","filter","Error","readPage","cursor","fieldIds","pageSize","Math","max","min","page","extra","docs","rows","map","doc","record","id","data","Object","fromEntries","fieldId","next","count","lookup","requests","found","Map","keys","request","push","normalizer","at","values","length","slice","getAll","exists","set","query","find","get","records","lookupMap","matchValues","readableRecords","exportOnly","noun","why","matchKeys","invariants","label","check","apply","_ctx","chunk","results","row","index","outcome","reason","message","undo","revert","done","conflicts","ORDERS","path","direction","productNames","ids","Set","String","products","ordersTransfer","RowRefusal","writable","plan","input","normalize","requiredToCreate","writer","applyRecords","snapshot","decisions","revertRecords","earlier","alreadyApplied","timeLeftMs","changes","creating","verdict","newId","recordId","ref","runTransaction","tx","current","made","write","problem","createStamps","create","afterWrite","after","before","touched","result","entry","action","written","pickKeys","previous","markApplied","error","key","remove","delete","restore","DISCOUNTS","code","name","where","value","createResourceUid","_id","discountsTransfer","picklists","picklistIds","includes","standardValues","active","defaultValueId","COUPONS","FieldPath","documentId","Boolean","_row","createdAt","Timestamp","now","couponsTransfer","readCategories","limit","CATEGORIES","slugs","categories","category","slug","categoriesTransfer"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export declare function registerCommerceTransferResources(): void;