@salesforce/b2c-tooling-sdk 1.21.2 → 1.22.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.
Files changed (124) hide show
  1. package/data/guides/enrichment.json +294 -0
  2. package/data/guides/index.json +376 -16
  3. package/data/help/index.json +6 -1
  4. package/data/job-steps/index.json +1 -1
  5. package/data/job-steps/job-steps.json +1 -1
  6. package/data/script-api/index.json +49 -5
  7. package/data/tooling/index.json +2 -2
  8. package/data/xsd/commercefeaturestate.xsd +1 -0
  9. package/data/xsd/index.json +2 -1
  10. package/data/xsd/redirecturl.xsd +2 -0
  11. package/dist/esm/auth/index.d.ts +6 -3
  12. package/dist/esm/auth/index.js +4 -2
  13. package/dist/esm/auth/index.js.map +1 -1
  14. package/dist/esm/auth/oauth-implicit.d.ts +19 -0
  15. package/dist/esm/auth/oauth-implicit.js +103 -10
  16. package/dist/esm/auth/oauth-implicit.js.map +1 -1
  17. package/dist/esm/auth/oauth-pkce-fallback.d.ts +68 -0
  18. package/dist/esm/auth/oauth-pkce-fallback.js +128 -0
  19. package/dist/esm/auth/oauth-pkce-fallback.js.map +1 -0
  20. package/dist/esm/auth/oauth-pkce.d.ts +94 -0
  21. package/dist/esm/auth/oauth-pkce.js +579 -0
  22. package/dist/esm/auth/oauth-pkce.js.map +1 -0
  23. package/dist/esm/auth/resolve.d.ts +4 -3
  24. package/dist/esm/auth/resolve.js +17 -2
  25. package/dist/esm/auth/resolve.js.map +1 -1
  26. package/dist/esm/auth/session-store.d.ts +99 -0
  27. package/dist/esm/auth/session-store.js +242 -0
  28. package/dist/esm/auth/session-store.js.map +1 -0
  29. package/dist/esm/auth/stateful-oauth-strategy.d.ts +20 -24
  30. package/dist/esm/auth/stateful-oauth-strategy.js +16 -114
  31. package/dist/esm/auth/stateful-oauth-strategy.js.map +1 -1
  32. package/dist/esm/auth/types.d.ts +20 -4
  33. package/dist/esm/auth/types.js +1 -1
  34. package/dist/esm/auth/types.js.map +1 -1
  35. package/dist/esm/cli/am-command.d.ts +2 -2
  36. package/dist/esm/cli/am-command.js +13 -4
  37. package/dist/esm/cli/am-command.js.map +1 -1
  38. package/dist/esm/cli/base-command.js +3 -3
  39. package/dist/esm/cli/base-command.js.map +1 -1
  40. package/dist/esm/cli/config.js +3 -1
  41. package/dist/esm/cli/config.js.map +1 -1
  42. package/dist/esm/cli/lifecycle.d.ts +1 -1
  43. package/dist/esm/cli/lifecycle.js.map +1 -1
  44. package/dist/esm/cli/oauth-command.d.ts +12 -11
  45. package/dist/esm/cli/oauth-command.js +73 -41
  46. package/dist/esm/cli/oauth-command.js.map +1 -1
  47. package/dist/esm/cli/ods-command.d.ts +1 -1
  48. package/dist/esm/cli/ods-command.js +5 -3
  49. package/dist/esm/cli/ods-command.js.map +1 -1
  50. package/dist/esm/clients/ods.generated.d.ts +16 -0
  51. package/dist/esm/config/dw-json.d.ts +10 -0
  52. package/dist/esm/config/dw-json.js.map +1 -1
  53. package/dist/esm/config/index.d.ts +1 -0
  54. package/dist/esm/config/index.js +2 -0
  55. package/dist/esm/config/index.js.map +1 -1
  56. package/dist/esm/config/mapping.d.ts +13 -0
  57. package/dist/esm/config/mapping.js +66 -3
  58. package/dist/esm/config/mapping.js.map +1 -1
  59. package/dist/esm/config/redaction.d.ts +39 -0
  60. package/dist/esm/config/redaction.js +51 -0
  61. package/dist/esm/config/redaction.js.map +1 -0
  62. package/dist/esm/config/resolver.js +1 -0
  63. package/dist/esm/config/resolver.js.map +1 -1
  64. package/dist/esm/config/sources/env-source.js +2 -0
  65. package/dist/esm/config/sources/env-source.js.map +1 -1
  66. package/dist/esm/config/sources/package-json-source.js +1 -0
  67. package/dist/esm/config/sources/package-json-source.js.map +1 -1
  68. package/dist/esm/config/types.d.ts +14 -4
  69. package/dist/esm/defaults.d.ts +23 -4
  70. package/dist/esm/defaults.js +36 -4
  71. package/dist/esm/defaults.js.map +1 -1
  72. package/dist/esm/docs/content-cache.d.ts +1 -1
  73. package/dist/esm/docs/content-cache.js +1 -1
  74. package/dist/esm/docs/index.d.ts +1 -1
  75. package/dist/esm/docs/index.js.map +1 -1
  76. package/dist/esm/docs/types.d.ts +29 -0
  77. package/dist/esm/index.d.ts +6 -4
  78. package/dist/esm/index.js +3 -3
  79. package/dist/esm/index.js.map +1 -1
  80. package/dist/esm/instance/index.js +3 -3
  81. package/dist/esm/instance/index.js.map +1 -1
  82. package/dist/esm/operations/cap/index.d.ts +2 -2
  83. package/dist/esm/operations/cap/index.js +1 -1
  84. package/dist/esm/operations/cap/index.js.map +1 -1
  85. package/dist/esm/operations/cap/install.d.ts +17 -0
  86. package/dist/esm/operations/cap/install.js +29 -0
  87. package/dist/esm/operations/cap/install.js.map +1 -1
  88. package/dist/esm/operations/cap/package.js +36 -0
  89. package/dist/esm/operations/cap/package.js.map +1 -1
  90. package/dist/esm/operations/cap/validate.d.ts +9 -0
  91. package/dist/esm/operations/cap/validate.js +29 -0
  92. package/dist/esm/operations/cap/validate.js.map +1 -1
  93. package/dist/esm/operations/content/export.js +7 -3
  94. package/dist/esm/operations/content/export.js.map +1 -1
  95. package/dist/esm/operations/content/library.d.ts +26 -0
  96. package/dist/esm/operations/content/library.js +83 -2
  97. package/dist/esm/operations/content/library.js.map +1 -1
  98. package/dist/esm/operations/content/types.d.ts +10 -1
  99. package/dist/esm/operations/jobs/import-set.d.ts +170 -0
  100. package/dist/esm/operations/jobs/import-set.js +538 -0
  101. package/dist/esm/operations/jobs/import-set.js.map +1 -0
  102. package/dist/esm/operations/jobs/index.d.ts +3 -0
  103. package/dist/esm/operations/jobs/index.js +3 -0
  104. package/dist/esm/operations/jobs/index.js.map +1 -1
  105. package/dist/esm/operations/jobs/run.js +0 -11
  106. package/dist/esm/operations/jobs/run.js.map +1 -1
  107. package/dist/esm/operations/jobs/site-archive.js +13 -75
  108. package/dist/esm/operations/jobs/site-archive.js.map +1 -1
  109. package/dist/esm/operations/ods/index.d.ts +4 -0
  110. package/dist/esm/operations/ods/index.js +2 -0
  111. package/dist/esm/operations/ods/index.js.map +1 -1
  112. package/dist/esm/operations/ods/sandbox-settings.d.ts +51 -0
  113. package/dist/esm/operations/ods/sandbox-settings.js +63 -0
  114. package/dist/esm/operations/ods/sandbox-settings.js.map +1 -0
  115. package/dist/esm/operations/ods/wait-for-clones.d.ts +97 -0
  116. package/dist/esm/operations/ods/wait-for-clones.js +145 -0
  117. package/dist/esm/operations/ods/wait-for-clones.js.map +1 -0
  118. package/dist/esm/skills/parser.js +2 -2
  119. package/dist/esm/skills/parser.js.map +1 -1
  120. package/package.json +1 -1
  121. package/specs/ods-api-v1.json +43 -0
  122. package/dist/esm/auth/stateful-store.d.ts +0 -49
  123. package/dist/esm/auth/stateful-store.js +0 -166
  124. package/dist/esm/auth/stateful-store.js.map +0 -1
@@ -0,0 +1,538 @@
1
+ /*
2
+ * Copyright (c) 2025, Salesforce, Inc.
3
+ * SPDX-License-Identifier: Apache-2
4
+ * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
5
+ */
6
+ import { createHash, randomUUID } from 'node:crypto';
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import { HTTPError } from '../../errors/http-error.js';
10
+ import { findCartridges } from '../code/cartridges.js';
11
+ import { siteArchiveImport } from './site-archive.js';
12
+ const DEFAULT_STATE_ROOT = 'Impex/b2c-cli/import-sets';
13
+ const DEFAULT_SET_ID = 'migrations';
14
+ const DEFAULT_STALE_LOCK_SECONDS = 30 * 60;
15
+ const DEFAULT_LOCK_POLL_INTERVAL_SECONDS = 3;
16
+ const DEFAULT_HEARTBEAT_INTERVAL_SECONDS = 30;
17
+ const SITE_ARCHIVE_DIRECTORY_NAMES = new Set([
18
+ 'ab-tests',
19
+ 'cache-settings',
20
+ 'catalogs',
21
+ 'coupons',
22
+ 'csrf-allowlists',
23
+ 'csrf-whitelists',
24
+ 'customer-lists',
25
+ 'custom-objects',
26
+ 'dcext',
27
+ 'geolocations',
28
+ 'global-data',
29
+ 'inventory',
30
+ 'inventory-lists',
31
+ 'jobs',
32
+ 'libraries',
33
+ 'locales',
34
+ 'meta',
35
+ 'oauth-providers',
36
+ 'ocapi-settings',
37
+ 'payment-methods',
38
+ 'payment-processors',
39
+ 'preferences',
40
+ 'price-books',
41
+ 'pricebooks',
42
+ 'promotions',
43
+ 'redirect-urls',
44
+ 'search',
45
+ 'services',
46
+ 'shipping',
47
+ 'sites',
48
+ 'slots',
49
+ 'sorting-rules',
50
+ 'source-codes',
51
+ 'sourcecodes',
52
+ 'static',
53
+ 'static-resources',
54
+ 'stores',
55
+ 'system-type-definitions',
56
+ 'tax',
57
+ 'users',
58
+ ]);
59
+ /** Thrown when WebDAV lock or receipt state cannot be safely read or written. */
60
+ export class ImportSetStateError extends Error {
61
+ constructor(message) {
62
+ super(message);
63
+ this.name = 'ImportSetStateError';
64
+ }
65
+ }
66
+ /**
67
+ * Discovers import items from cartridge `metadata/` directories followed by
68
+ * the explicit import-set directory. A cartridge metadata directory that
69
+ * resembles a site archive is one item; otherwise its immediate child
70
+ * directories and zip archives are items. Cartridge sources are ordered by
71
+ * cartridge name, and child items within each source are sorted by name.
72
+ */
73
+ export async function discoverImportSet(directory, options = {}) {
74
+ const resolvedDirectory = path.resolve(directory);
75
+ const excludedDirectories = resolveExcludedDirectories(options);
76
+ const cartridgeItems = options.includeCartridgeMetadata === false ? [] : await discoverCartridgeMetadata(options, excludedDirectories);
77
+ const directoryItems = await discoverImportDirectory(resolvedDirectory, '', excludedDirectories);
78
+ const items = [...cartridgeItems, ...directoryItems];
79
+ if (items.length === 0) {
80
+ const importDirectoryExists = await isDirectory(resolvedDirectory);
81
+ if (!importDirectoryExists && options.includeCartridgeMetadata === false) {
82
+ throw new Error(`Import-set directory does not exist: ${resolvedDirectory}`);
83
+ }
84
+ throw new Error(options.includeCartridgeMetadata === false
85
+ ? `No import directories or zip archives found in ${resolvedDirectory}`
86
+ : `No import directories or zip archives found in ${resolvedDirectory} or discovered cartridge metadata`);
87
+ }
88
+ const itemIds = new Set();
89
+ for (const item of items) {
90
+ if (itemIds.has(item.id))
91
+ throw new Error(`Duplicate import-set item ID: ${item.id}`);
92
+ itemIds.add(item.id);
93
+ }
94
+ return items;
95
+ }
96
+ async function discoverCartridgeMetadata(options, excludedDirectories) {
97
+ const cartridges = findCartridges(options.cartridgeRoot)
98
+ .filter((cartridge) => !isExcludedPath(cartridge.src, excludedDirectories))
99
+ .sort((a, b) => a.name.localeCompare(b.name, 'en', { numeric: false }));
100
+ const items = [];
101
+ for (const cartridge of cartridges) {
102
+ const metadataDirectory = path.join(cartridge.src, 'metadata');
103
+ // eslint-disable-next-line no-await-in-loop
104
+ const metadataEntries = await readDirectory(metadataDirectory);
105
+ if (!metadataEntries)
106
+ continue;
107
+ if (looksLikeSiteArchive(metadataEntries)) {
108
+ items.push({
109
+ id: `cartridge-metadata/${cartridge.name}`,
110
+ target: metadataDirectory,
111
+ kind: 'directory',
112
+ // eslint-disable-next-line no-await-in-loop
113
+ note: await readItemNote(metadataDirectory),
114
+ });
115
+ continue;
116
+ }
117
+ // Keep source discovery sequential so ordering is explicit and stable.
118
+ // eslint-disable-next-line no-await-in-loop
119
+ const cartridgeItems = await discoverImportDirectory(metadataDirectory, `cartridge-metadata/${cartridge.name}/`, excludedDirectories);
120
+ items.push(...cartridgeItems);
121
+ }
122
+ return items;
123
+ }
124
+ function looksLikeSiteArchive(entries) {
125
+ return entries.some((entry) => {
126
+ if (entry.name.startsWith('.'))
127
+ return false;
128
+ if (entry.isFile())
129
+ return path.extname(entry.name).toLowerCase() === '.xml';
130
+ if (!entry.isDirectory())
131
+ return false;
132
+ return SITE_ARCHIVE_DIRECTORY_NAMES.has(entry.name.toLowerCase().replaceAll('_', '-'));
133
+ });
134
+ }
135
+ async function readDirectory(directory) {
136
+ const stat = await fs.promises.stat(directory).catch(() => undefined);
137
+ if (!stat)
138
+ return undefined;
139
+ if (!stat.isDirectory())
140
+ throw new Error(`Import-set source is not a directory: ${directory}`);
141
+ return fs.promises.readdir(directory, { withFileTypes: true });
142
+ }
143
+ async function discoverImportDirectory(directory, idPrefix = '', excludedDirectories = []) {
144
+ const entries = await readDirectory(directory);
145
+ if (!entries)
146
+ return [];
147
+ const candidates = entries
148
+ .filter((entry) => !entry.name.startsWith('.'))
149
+ .filter((entry) => entry.isDirectory() || (entry.isFile() && path.extname(entry.name).toLowerCase() === '.zip'))
150
+ .filter((entry) => !isExcludedPath(path.join(directory, entry.name), excludedDirectories))
151
+ .sort((a, b) => a.name.localeCompare(b.name, 'en', { numeric: false }));
152
+ return Promise.all(candidates.map(async (entry) => {
153
+ const target = path.join(directory, entry.name);
154
+ const kind = entry.isDirectory() ? 'directory' : 'zip';
155
+ return {
156
+ id: `${idPrefix}${entry.name}`,
157
+ target,
158
+ kind,
159
+ note: kind === 'directory' ? await readItemNote(target) : undefined,
160
+ };
161
+ }));
162
+ }
163
+ function resolveExcludedDirectories(options) {
164
+ const root = path.resolve(options.cartridgeRoot ?? process.cwd());
165
+ const configuredDirectories = options.excludeDirectories ?? [];
166
+ return [
167
+ ...new Set(configuredDirectories
168
+ .filter((directory) => typeof directory === 'string' && directory.trim().length > 0)
169
+ .map((directory) => path.resolve(root, directory.trim()))),
170
+ ];
171
+ }
172
+ /** README filenames checked, in priority order, at the top of a directory item. */
173
+ const README_FILENAMES = ['README.md', 'README'];
174
+ /**
175
+ * Reads the first README file at the top of a directory item, if present.
176
+ * Returns the trimmed contents, or undefined when no README exists or it is empty.
177
+ */
178
+ async function readItemNote(directory) {
179
+ for (const filename of README_FILENAMES) {
180
+ // eslint-disable-next-line no-await-in-loop
181
+ const contents = await fs.promises.readFile(path.join(directory, filename), 'utf8').catch(() => undefined);
182
+ if (contents === undefined)
183
+ continue;
184
+ const trimmed = contents.trim();
185
+ return trimmed.length > 0 ? trimmed : undefined;
186
+ }
187
+ return undefined;
188
+ }
189
+ function isExcludedPath(candidate, excludedDirectories) {
190
+ return excludedDirectories.some((excludedDirectory) => {
191
+ const relativePath = path.relative(excludedDirectory, candidate);
192
+ return relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath));
193
+ });
194
+ }
195
+ async function isDirectory(directory) {
196
+ const stat = await fs.promises.stat(directory).catch(() => undefined);
197
+ return stat?.isDirectory() === true;
198
+ }
199
+ /**
200
+ * Applies an ordered set of site archives exactly until a verified receipt
201
+ * directory is created for each item name. A missing or invalid receipt always
202
+ * leaves the item pending, even if a previous process may have completed the
203
+ * platform import.
204
+ *
205
+ * The operation uses an exclusive WebDAV directory (`MKCOL`) as a best-effort
206
+ * set-wide lock. B2C Commerce does not provide conditional WebDAV deletes, so
207
+ * stale lock takeover is intentionally observable through progress events.
208
+ * The operation never logs or writes output; callers can consume structured
209
+ * progress through {@link SiteArchiveImportSetOptions.onEvent}.
210
+ */
211
+ export async function siteArchiveImportSet(instance, directory, options = {}) {
212
+ const resolvedDirectory = path.resolve(directory);
213
+ const setId = options.setId ?? DEFAULT_SET_ID;
214
+ validateSetId(setId);
215
+ validateStateRoot(options.stateRoot ?? DEFAULT_STATE_ROOT);
216
+ const runId = randomUUID();
217
+ const items = await discoverImportSet(resolvedDirectory, {
218
+ includeCartridgeMetadata: options.includeCartridgeMetadata,
219
+ cartridgeRoot: options.cartridgeRoot,
220
+ excludeDirectories: options.excludeDirectories,
221
+ });
222
+ const stateRoot = (options.stateRoot ?? DEFAULT_STATE_ROOT).replace(/\/+$/, '');
223
+ const setRoot = `${stateRoot}/${setId}`;
224
+ const receiptsRoot = `${setRoot}/receipts`;
225
+ const lockPath = `${setRoot}/lock`;
226
+ const sleep = options.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
227
+ const importArchive = options.importArchive ?? siteArchiveImport;
228
+ let itemResults = await evaluateReceipts(instance, setId, receiptsRoot, items, options.onEvent);
229
+ emitPlan(options, setId, itemResults);
230
+ if (options.dryRun || itemResults.every((item) => item.status === 'skipped')) {
231
+ return buildResult(setId, resolvedDirectory, Boolean(options.dryRun), runId, itemResults);
232
+ }
233
+ await ensureCollection(instance, stateRoot, sleep);
234
+ await ensureCollection(instance, setRoot, sleep);
235
+ await ensureCollection(instance, receiptsRoot, sleep);
236
+ const lockOwner = await acquireLock(instance, lockPath, setId, runId, options, sleep);
237
+ let heartbeatError;
238
+ let heartbeatChain = Promise.resolve();
239
+ const heartbeatInterval = Math.max(1, options.heartbeatIntervalSeconds ?? DEFAULT_HEARTBEAT_INTERVAL_SECONDS);
240
+ const heartbeatTimer = setInterval(() => {
241
+ heartbeatChain = heartbeatChain
242
+ .then(() => heartbeatLock(instance, lockPath, lockOwner))
243
+ .catch((error) => {
244
+ heartbeatError = error instanceof Error ? error : new Error(String(error));
245
+ });
246
+ }, heartbeatInterval * 1000);
247
+ heartbeatTimer.unref();
248
+ let operationError;
249
+ try {
250
+ // Another runner may have completed work while this process waited.
251
+ itemResults = await evaluateReceipts(instance, setId, receiptsRoot, items, options.onEvent);
252
+ const total = itemResults.length;
253
+ for (const [index, itemResult] of itemResults.entries()) {
254
+ if (itemResult.status === 'skipped') {
255
+ options.onEvent?.({
256
+ type: 'item-skipped',
257
+ item: itemResult,
258
+ receipt: itemResult.receipt,
259
+ index: index + 1,
260
+ total,
261
+ });
262
+ continue;
263
+ }
264
+ if (heartbeatError)
265
+ throw heartbeatError;
266
+ await heartbeatLock(instance, lockPath, lockOwner);
267
+ options.onEvent?.({ type: 'item-importing', item: itemResult, index: index + 1, total });
268
+ const importResult = await importArchive(instance, itemResult.target, {
269
+ keepArchive: options.keepArchive,
270
+ wait: true,
271
+ waitOptions: options.waitOptions,
272
+ });
273
+ if (heartbeatError)
274
+ throw heartbeatError;
275
+ const receipt = createReceipt(setId, receiptsRoot, itemResult.id);
276
+ await writeAndVerifyReceipt(instance, receipt.receiptPath);
277
+ itemResult.status = 'imported';
278
+ itemResult.receipt = receipt;
279
+ itemResult.importResult = importResult;
280
+ options.onEvent?.({ type: 'item-imported', item: itemResult, receipt, index: index + 1, total });
281
+ }
282
+ return buildResult(setId, resolvedDirectory, false, runId, itemResults);
283
+ }
284
+ catch (error) {
285
+ operationError = error;
286
+ throw error;
287
+ }
288
+ finally {
289
+ clearInterval(heartbeatTimer);
290
+ await heartbeatChain;
291
+ try {
292
+ await releaseLock(instance, lockPath, runId);
293
+ }
294
+ catch (error) {
295
+ // Preserve an import or receipt error so callers can report the real
296
+ // failure. An unreleased lock will become eligible for stale takeover.
297
+ if (operationError === undefined)
298
+ throw error;
299
+ }
300
+ }
301
+ }
302
+ async function evaluateReceipts(instance, setId, receiptsRoot, items, onEvent) {
303
+ const results = [];
304
+ for (const item of items) {
305
+ const remotePath = receiptPath(receiptsRoot, item.id);
306
+ // Receipt reads are intentionally sequential to avoid bursting WebDAV on large sets.
307
+ // eslint-disable-next-line no-await-in-loop
308
+ const read = await readReceiptDirectory(instance, remotePath);
309
+ if (!read.found) {
310
+ results.push({ ...item, status: 'pending' });
311
+ continue;
312
+ }
313
+ if (!read.valid) {
314
+ onEvent?.({ type: 'receipt-invalid', item, receiptPath: remotePath });
315
+ results.push({ ...item, status: 'pending' });
316
+ continue;
317
+ }
318
+ results.push({ ...item, status: 'skipped', receipt: createReceipt(setId, receiptsRoot, item.id) });
319
+ }
320
+ return results;
321
+ }
322
+ async function acquireLock(instance, lockPath, setId, runId, options, sleep) {
323
+ const staleSeconds = Math.max(1, options.staleLockSeconds ?? DEFAULT_STALE_LOCK_SECONDS);
324
+ const pollMilliseconds = Math.max(1, options.lockPollIntervalSeconds ?? DEFAULT_LOCK_POLL_INTERVAL_SECONDS) * 1000;
325
+ let forceBreak = Boolean(options.breakLock);
326
+ let waitNotified = false;
327
+ while (true) {
328
+ // MKCOL is the only conditional creation primitive B2C WebDAV enforces.
329
+ // eslint-disable-next-line no-await-in-loop
330
+ const response = await instance.webdav.request(lockPath, { method: 'MKCOL' });
331
+ if (response.status === 201) {
332
+ const now = new Date().toISOString();
333
+ const owner = {
334
+ version: 1,
335
+ setId,
336
+ runId,
337
+ createdAt: now,
338
+ heartbeatAt: now,
339
+ owner: options.owner,
340
+ };
341
+ try {
342
+ // eslint-disable-next-line no-await-in-loop
343
+ await putJson(instance, `${lockPath}/owner.json`, owner);
344
+ }
345
+ catch (error) {
346
+ await deletePath(instance, lockPath);
347
+ throw error;
348
+ }
349
+ options.onEvent?.({ type: 'lock-acquired', setId, runId });
350
+ return owner;
351
+ }
352
+ if (response.status !== 405 && response.status !== 409) {
353
+ throw new ImportSetStateError(`Unable to acquire import-set lock ${lockPath}: ${response.status} ${response.statusText}`);
354
+ }
355
+ // eslint-disable-next-line no-await-in-loop
356
+ const info = await readLockInfo(instance, lockPath);
357
+ const stale = info.ageSeconds !== undefined && info.ageSeconds >= staleSeconds;
358
+ if (forceBreak || stale) {
359
+ options.onEvent?.({
360
+ type: 'lock-takeover',
361
+ setId,
362
+ owner: info.owner,
363
+ ageSeconds: info.ageSeconds,
364
+ forced: forceBreak,
365
+ });
366
+ // B2C WebDAV ignores conditional DELETE, so stale takeover is best effort.
367
+ // eslint-disable-next-line no-await-in-loop
368
+ await deletePath(instance, lockPath);
369
+ forceBreak = false;
370
+ waitNotified = false;
371
+ continue;
372
+ }
373
+ if (!waitNotified) {
374
+ options.onEvent?.({ type: 'lock-wait', setId, owner: info.owner, ageSeconds: info.ageSeconds });
375
+ waitNotified = true;
376
+ }
377
+ // eslint-disable-next-line no-await-in-loop
378
+ await sleep(pollMilliseconds);
379
+ }
380
+ }
381
+ async function heartbeatLock(instance, lockPath, owner) {
382
+ const ownerPath = `${lockPath}/owner.json`;
383
+ const current = await readJson(instance, ownerPath);
384
+ if (!current.found || !current.valid || current.value?.runId !== owner.runId) {
385
+ throw new ImportSetStateError(`Import-set lock ${lockPath} is no longer owned by run ${owner.runId}`);
386
+ }
387
+ owner.heartbeatAt = new Date().toISOString();
388
+ await putJson(instance, ownerPath, owner);
389
+ }
390
+ async function releaseLock(instance, lockPath, runId) {
391
+ const current = await readJson(instance, `${lockPath}/owner.json`);
392
+ if (current.found && current.valid && current.value?.runId === runId) {
393
+ await deletePath(instance, lockPath);
394
+ }
395
+ }
396
+ async function readLockInfo(instance, lockPath) {
397
+ const ownerRead = await readJson(instance, `${lockPath}/owner.json`);
398
+ const owner = ownerRead.valid ? ownerRead.value : undefined;
399
+ const timestamp = owner?.heartbeatAt ?? owner?.createdAt;
400
+ if (timestamp) {
401
+ const milliseconds = Date.parse(timestamp);
402
+ if (Number.isFinite(milliseconds)) {
403
+ return { owner, ageSeconds: Math.max(0, (Date.now() - milliseconds) / 1000) };
404
+ }
405
+ }
406
+ try {
407
+ const entries = await instance.webdav.propfind(lockPath, '0');
408
+ const modified = entries[0]?.lastModified;
409
+ return {
410
+ owner,
411
+ ageSeconds: modified ? Math.max(0, (Date.now() - modified.getTime()) / 1000) : undefined,
412
+ };
413
+ }
414
+ catch {
415
+ return { owner };
416
+ }
417
+ }
418
+ async function ensureCollection(instance, remotePath, sleep) {
419
+ const segments = remotePath.split('/').filter(Boolean);
420
+ if (segments.length < 2)
421
+ throw new ImportSetStateError(`Invalid WebDAV state path: ${remotePath}`);
422
+ let current = segments[0];
423
+ for (const segment of segments.slice(1)) {
424
+ current = `${current}/${segment}`;
425
+ // eslint-disable-next-line no-await-in-loop
426
+ const response = await instance.webdav.request(current, { method: 'MKCOL' });
427
+ if (response.status === 201 || response.status === 405)
428
+ continue;
429
+ if (response.status === 409) {
430
+ // Concurrent creators can receive 409 while the winning collection becomes visible.
431
+ // eslint-disable-next-line no-await-in-loop
432
+ await sleep(25);
433
+ // eslint-disable-next-line no-await-in-loop
434
+ const head = await instance.webdav.request(current, { method: 'HEAD' });
435
+ if (head.ok)
436
+ continue;
437
+ }
438
+ throw new ImportSetStateError(`Unable to create WebDAV collection ${current}: ${response.status} ${response.statusText}`);
439
+ }
440
+ }
441
+ async function readJson(instance, remotePath) {
442
+ const response = await instance.webdav.request(remotePath, { method: 'GET' });
443
+ if (response.status === 404)
444
+ return { found: false, valid: false };
445
+ if (!response.ok) {
446
+ throw new ImportSetStateError(`Unable to read WebDAV state ${remotePath}: ${response.status} ${response.statusText}`);
447
+ }
448
+ try {
449
+ return { found: true, valid: true, value: JSON.parse(await response.text()) };
450
+ }
451
+ catch {
452
+ return { found: true, valid: false };
453
+ }
454
+ }
455
+ async function putJson(instance, remotePath, value) {
456
+ const response = await instance.webdav.request(remotePath, {
457
+ method: 'PUT',
458
+ headers: { 'Content-Type': 'application/json' },
459
+ body: `${JSON.stringify(value, null, 2)}\n`,
460
+ });
461
+ if (!response.ok) {
462
+ throw new ImportSetStateError(`Unable to write WebDAV state ${remotePath}: ${response.status} ${response.statusText}`);
463
+ }
464
+ }
465
+ async function readReceiptDirectory(instance, remotePath) {
466
+ try {
467
+ const entries = await instance.webdav.propfind(remotePath, '0');
468
+ return { found: true, valid: entries[0]?.isCollection === true };
469
+ }
470
+ catch (error) {
471
+ if (error instanceof HTTPError && error.response.status === 404)
472
+ return { found: false, valid: false };
473
+ throw new ImportSetStateError(`Unable to read WebDAV receipt directory ${remotePath}: ${error instanceof Error ? error.message : String(error)}`);
474
+ }
475
+ }
476
+ async function writeAndVerifyReceipt(instance, remotePath) {
477
+ let response = await instance.webdav.request(remotePath, { method: 'MKCOL' });
478
+ if (response.status === 405) {
479
+ const existing = await readReceiptDirectory(instance, remotePath);
480
+ if (!existing.valid) {
481
+ await deletePath(instance, remotePath);
482
+ response = await instance.webdav.request(remotePath, { method: 'MKCOL' });
483
+ }
484
+ }
485
+ if (response.status !== 201 && response.status !== 405) {
486
+ throw new ImportSetStateError(`Unable to create WebDAV receipt directory ${remotePath}: ${response.status} ${response.statusText}`);
487
+ }
488
+ const verification = await readReceiptDirectory(instance, remotePath);
489
+ if (!verification.found || !verification.valid) {
490
+ throw new ImportSetStateError(`Receipt directory verification failed for ${remotePath}; the import will be retried.`);
491
+ }
492
+ }
493
+ async function deletePath(instance, remotePath) {
494
+ const response = await instance.webdav.request(remotePath, { method: 'DELETE' });
495
+ if (!response.ok && response.status !== 404) {
496
+ throw new ImportSetStateError(`Unable to delete WebDAV state ${remotePath}: ${response.status} ${response.statusText}`);
497
+ }
498
+ }
499
+ function createReceipt(setId, receiptsRoot, itemId) {
500
+ return { version: 1, setId, itemId, receiptPath: receiptPath(receiptsRoot, itemId) };
501
+ }
502
+ function receiptPath(receiptsRoot, itemId) {
503
+ return `${receiptsRoot}/${createHash('sha256').update(itemId).digest('hex')}`;
504
+ }
505
+ function emitPlan(options, setId, items) {
506
+ options.onEvent?.({
507
+ type: 'plan',
508
+ setId,
509
+ total: items.length,
510
+ pending: items.filter((item) => item.status === 'pending').length,
511
+ skipped: items.filter((item) => item.status === 'skipped').length,
512
+ dryRun: Boolean(options.dryRun),
513
+ });
514
+ }
515
+ function buildResult(setId, directory, dryRun, runId, items) {
516
+ return {
517
+ setId,
518
+ directory,
519
+ dryRun,
520
+ runId,
521
+ items,
522
+ imported: items.filter((item) => item.status === 'imported').length,
523
+ skipped: items.filter((item) => item.status === 'skipped').length,
524
+ pending: items.filter((item) => item.status === 'pending').length,
525
+ };
526
+ }
527
+ function validateSetId(setId) {
528
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(setId)) {
529
+ throw new Error(`Invalid import-set ID "${setId}". Use 1-128 letters, numbers, dots, underscores, or hyphens.`);
530
+ }
531
+ }
532
+ function validateStateRoot(stateRoot) {
533
+ const segments = stateRoot.split('/').filter(Boolean);
534
+ if (segments[0]?.toLowerCase() !== 'impex' || segments.some((segment) => segment === '.' || segment === '..')) {
535
+ throw new Error(`Import-set state root must be a path under Impex: ${stateRoot}`);
536
+ }
537
+ }
538
+ //# sourceMappingURL=import-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-set.js","sourceRoot":"","sources":["../../../../src/operations/jobs/import-set.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAC,UAAU,EAAE,UAAU,EAAC,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAC,SAAS,EAAC,MAAM,4BAA4B,CAAC;AAErD,OAAO,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAC,iBAAiB,EAA8D,MAAM,mBAAmB,CAAC;AAGjH,MAAM,kBAAkB,GAAG,2BAA2B,CAAC;AACvD,MAAM,cAAc,GAAG,YAAY,CAAC;AACpC,MAAM,0BAA0B,GAAG,EAAE,GAAG,EAAE,CAAC;AAC3C,MAAM,kCAAkC,GAAG,CAAC,CAAC;AAC7C,MAAM,kCAAkC,GAAG,EAAE,CAAC;AAC9C,MAAM,4BAA4B,GAAG,IAAI,GAAG,CAAC;IAC3C,UAAU;IACV,gBAAgB;IAChB,UAAU;IACV,SAAS;IACT,iBAAiB;IACjB,iBAAiB;IACjB,gBAAgB;IAChB,gBAAgB;IAChB,OAAO;IACP,cAAc;IACd,aAAa;IACb,WAAW;IACX,iBAAiB;IACjB,MAAM;IACN,WAAW;IACX,SAAS;IACT,MAAM;IACN,iBAAiB;IACjB,gBAAgB;IAChB,iBAAiB;IACjB,oBAAoB;IACpB,aAAa;IACb,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,eAAe;IACf,QAAQ;IACR,UAAU;IACV,UAAU;IACV,OAAO;IACP,OAAO;IACP,eAAe;IACf,cAAc;IACd,aAAa;IACb,QAAQ;IACR,kBAAkB;IAClB,QAAQ;IACR,yBAAyB;IACzB,KAAK;IACL,OAAO;CACR,CAAC,CAAC;AAyHH,iFAAiF;AACjF,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAkBD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,SAAiB,EACjB,UAAoC,EAAE;IAEtC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,mBAAmB,GAAG,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAChE,MAAM,cAAc,GAClB,OAAO,CAAC,wBAAwB,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,yBAAyB,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IAClH,MAAM,cAAc,GAAG,MAAM,uBAAuB,CAAC,iBAAiB,EAAE,EAAE,EAAE,mBAAmB,CAAC,CAAC;IACjG,MAAM,KAAK,GAAG,CAAC,GAAG,cAAc,EAAE,GAAG,cAAc,CAAC,CAAC;IAErD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,qBAAqB,GAAG,MAAM,WAAW,CAAC,iBAAiB,CAAC,CAAC;QACnE,IAAI,CAAC,qBAAqB,IAAI,OAAO,CAAC,wBAAwB,KAAK,KAAK,EAAE,CAAC;YACzE,MAAM,IAAI,KAAK,CAAC,wCAAwC,iBAAiB,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,MAAM,IAAI,KAAK,CACb,OAAO,CAAC,wBAAwB,KAAK,KAAK;YACxC,CAAC,CAAC,kDAAkD,iBAAiB,EAAE;YACvE,CAAC,CAAC,kDAAkD,iBAAiB,mCAAmC,CAC3G,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACtF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,OAAiC,EACjC,mBAA6B;IAE7B,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,aAAa,CAAC;SACrD,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC;SAC1E,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC,CAAC;IACxE,MAAM,KAAK,GAAoB,EAAE,CAAC;IAElC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC/D,4CAA4C;QAC5C,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC,iBAAiB,CAAC,CAAC;QAC/D,IAAI,CAAC,eAAe;YAAE,SAAS;QAE/B,IAAI,oBAAoB,CAAC,eAAe,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,sBAAsB,SAAS,CAAC,IAAI,EAAE;gBAC1C,MAAM,EAAE,iBAAiB;gBACzB,IAAI,EAAE,WAAW;gBACjB,4CAA4C;gBAC5C,IAAI,EAAE,MAAM,YAAY,CAAC,iBAAiB,CAAC;aAC5C,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QAED,uEAAuE;QACvE,4CAA4C;QAC5C,MAAM,cAAc,GAAG,MAAM,uBAAuB,CAClD,iBAAiB,EACjB,sBAAsB,SAAS,CAAC,IAAI,GAAG,EACvC,mBAAmB,CACpB,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAoB;IAChD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAC5B,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7C,IAAI,KAAK,CAAC,MAAM,EAAE;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC;QAC7E,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE;YAAE,OAAO,KAAK,CAAC;QACvC,OAAO,4BAA4B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,SAAiB;IAC5C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACtE,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,SAAS,EAAE,CAAC,CAAC;IAC/F,OAAO,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,EAAC,aAAa,EAAE,IAAI,EAAC,CAAC,CAAC;AAC/D,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,SAAiB,EACjB,QAAQ,GAAG,EAAE,EACb,sBAAgC,EAAE;IAElC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,UAAU,GAAG,OAAO;SACvB,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAC9C,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;SAC/G,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,CAAC;SACzF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC,CAAC;IAExE,OAAO,OAAO,CAAC,GAAG,CAChB,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAE,WAAqB,CAAC,CAAC,CAAE,KAAe,CAAC;QAC7E,OAAO;YACL,EAAE,EAAE,GAAG,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE;YAC9B,MAAM;YACN,IAAI;YACJ,IAAI,EAAE,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;SACpE,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CAAC,OAAiC;IACnE,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAClE,MAAM,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,IAAI,EAAE,CAAC;IAC/D,OAAO;QACL,GAAG,IAAI,GAAG,CACR,qBAAqB;aAClB,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;aACnF,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAC5D;KACF,CAAC;AACJ,CAAC;AAED,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAEjD;;;GAGG;AACH,KAAK,UAAU,YAAY,CAAC,SAAiB;IAC3C,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;QACxC,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC3G,IAAI,QAAQ,KAAK,SAAS;YAAE,SAAS;QACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAClD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,SAAiB,EAAE,mBAA6B;IACtE,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,iBAAiB,EAAE,EAAE;QACpD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;QACjE,OAAO,YAAY,KAAK,EAAE,IAAI,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC;IACnG,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,SAAiB;IAC1C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACtE,OAAO,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAqB,EACrB,SAAiB,EACjB,UAAuC,EAAE;IAEzC,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,cAAc,CAAC;IAC9C,aAAa,CAAC,KAAK,CAAC,CAAC;IACrB,iBAAiB,CAAC,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC;IAE3D,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,iBAAiB,EAAE;QACvD,wBAAwB,EAAE,OAAO,CAAC,wBAAwB;QAC1D,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;KAC/C,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChF,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,KAAK,EAAE,CAAC;IACxC,MAAM,YAAY,GAAG,GAAG,OAAO,WAAW,CAAC;IAC3C,MAAM,QAAQ,GAAG,GAAG,OAAO,OAAO,CAAC;IACnC,MAAM,KAAK,GACT,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,YAAoB,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IAC3G,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,iBAAiB,CAAC;IAEjE,IAAI,WAAW,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAChG,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAEtC,IAAI,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,EAAE,CAAC;QAC7E,OAAO,WAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,gBAAgB,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IACnD,MAAM,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACjD,MAAM,gBAAgB,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;IAEtD,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACtF,IAAI,cAAiC,CAAC;IACtC,IAAI,cAAc,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IACvC,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,wBAAwB,IAAI,kCAAkC,CAAC,CAAC;IAC9G,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,cAAc,GAAG,cAAc;aAC5B,IAAI,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;aACxD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;YACxB,cAAc,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC7B,cAAc,CAAC,KAAK,EAAE,CAAC;IACvB,IAAI,cAAuB,CAAC;IAE5B,IAAI,CAAC;QACH,oEAAoE;QACpE,WAAW,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5F,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,CAAC;QAEjC,KAAK,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACxD,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBACpC,OAAO,CAAC,OAAO,EAAE,CAAC;oBAChB,IAAI,EAAE,cAAc;oBACpB,IAAI,EAAE,UAAU;oBAChB,OAAO,EAAE,UAAU,CAAC,OAAQ;oBAC5B,KAAK,EAAE,KAAK,GAAG,CAAC;oBAChB,KAAK;iBACN,CAAC,CAAC;gBACH,SAAS;YACX,CAAC;YAED,IAAI,cAAc;gBAAE,MAAM,cAAc,CAAC;YACzC,MAAM,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YACnD,OAAO,CAAC,OAAO,EAAE,CAAC,EAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAC,CAAC,CAAC;YAEvF,MAAM,YAAY,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE;gBACpE,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,IAAI,EAAE,IAAI;gBACV,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,CAAC,CAAC;YAEH,IAAI,cAAc;gBAAE,MAAM,cAAc,CAAC;YACzC,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;YAClE,MAAM,qBAAqB,CAAC,QAAQ,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;YAE3D,UAAU,CAAC,MAAM,GAAG,UAAU,CAAC;YAC/B,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;YAC7B,UAAU,CAAC,YAAY,GAAG,YAAY,CAAC;YACvC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAC,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAC,CAAC,CAAC;QACjG,CAAC;QAED,OAAO,WAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IAC1E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,cAAc,GAAG,KAAK,CAAC;QACvB,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,aAAa,CAAC,cAAc,CAAC,CAAC;QAC9B,MAAM,cAAc,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qEAAqE;YACrE,uEAAuE;YACvE,IAAI,cAAc,KAAK,SAAS;gBAAE,MAAM,KAAK,CAAC;QAChD,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,QAAqB,EACrB,KAAa,EACb,YAAoB,EACpB,KAAsB,EACtB,OAAyC;IAEzC,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACtD,qFAAqF;QACrF,4CAA4C;QAC5C,MAAM,IAAI,GAAG,MAAM,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC9D,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,IAAI,EAAE,MAAM,EAAE,SAAS,EAAC,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,EAAE,CAAC,EAAC,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAC,CAAC,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,IAAI,EAAE,MAAM,EAAE,SAAS,EAAC,CAAC,CAAC;YAC3C,SAAS;QACX,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,EAAC,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,QAAqB,EACrB,QAAgB,EAChB,KAAa,EACb,KAAa,EACb,OAAoC,EACpC,KAA8C;IAE9C,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,gBAAgB,IAAI,0BAA0B,CAAC,CAAC;IACzF,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,uBAAuB,IAAI,kCAAkC,CAAC,GAAG,IAAI,CAAC;IACnH,IAAI,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,OAAO,IAAI,EAAE,CAAC;QACZ,wEAAwE;QACxE,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC,CAAC;QAC5E,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,KAAK,GAAuB;gBAChC,OAAO,EAAE,CAAC;gBACV,KAAK;gBACL,KAAK;gBACL,SAAS,EAAE,GAAG;gBACd,WAAW,EAAE,GAAG;gBAChB,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB,CAAC;YACF,IAAI,CAAC;gBACH,4CAA4C;gBAC5C,MAAM,OAAO,CAAC,QAAQ,EAAE,GAAG,QAAQ,aAAa,EAAE,KAAK,CAAC,CAAC;YAC3D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACrC,MAAM,KAAK,CAAC;YACd,CAAC;YACD,OAAO,CAAC,OAAO,EAAE,CAAC,EAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,EAAC,CAAC,CAAC;YACzD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvD,MAAM,IAAI,mBAAmB,CAC3B,qCAAqC,QAAQ,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAC3F,CAAC;QACJ,CAAC;QAED,4CAA4C;QAC5C,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,IAAI,YAAY,CAAC;QAC/E,IAAI,UAAU,IAAI,KAAK,EAAE,CAAC;YACxB,OAAO,CAAC,OAAO,EAAE,CAAC;gBAChB,IAAI,EAAE,eAAe;gBACrB,KAAK;gBACL,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,MAAM,EAAE,UAAU;aACnB,CAAC,CAAC;YACH,2EAA2E;YAC3E,4CAA4C;YAC5C,MAAM,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACrC,UAAU,GAAG,KAAK,CAAC;YACnB,YAAY,GAAG,KAAK,CAAC;YACrB,SAAS;QACX,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,CAAC,OAAO,EAAE,CAAC,EAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAC,CAAC,CAAC;YAC9F,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;QACD,4CAA4C;QAC5C,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,QAAqB,EAAE,QAAgB,EAAE,KAAyB;IAC7F,MAAM,SAAS,GAAG,GAAG,QAAQ,aAAa,CAAC;IAC3C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAqB,QAAQ,EAAE,SAAS,CAAC,CAAC;IACxE,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7E,MAAM,IAAI,mBAAmB,CAAC,mBAAmB,QAAQ,8BAA8B,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IACxG,CAAC;IACD,KAAK,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC7C,MAAM,OAAO,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,QAAqB,EAAE,QAAgB,EAAE,KAAa;IAC/E,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAqB,QAAQ,EAAE,GAAG,QAAQ,aAAa,CAAC,CAAC;IACvF,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,KAAK,KAAK,KAAK,EAAE,CAAC;QACrE,MAAM,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,QAAqB,EAAE,QAAgB;IACjE,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAqB,QAAQ,EAAE,GAAG,QAAQ,aAAa,CAAC,CAAC;IACzF,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,MAAM,SAAS,GAAG,KAAK,EAAE,WAAW,IAAI,KAAK,EAAE,SAAS,CAAC;IACzD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAClC,OAAO,EAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC,GAAG,IAAI,CAAC,EAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC;QAC1C,OAAO;YACL,KAAK;YACL,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SACzF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAC,KAAK,EAAC,CAAC;IACjB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAC7B,QAAqB,EACrB,UAAkB,EAClB,KAA8C;IAE9C,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,mBAAmB,CAAC,8BAA8B,UAAU,EAAE,CAAC,CAAC;IAEnG,IAAI,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC1B,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,OAAO,GAAG,GAAG,OAAO,IAAI,OAAO,EAAE,CAAC;QAClC,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC,CAAC;QAC3E,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,SAAS;QACjE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,oFAAoF;YACpF,4CAA4C;YAC5C,MAAM,KAAK,CAAC,EAAE,CAAC,CAAC;YAChB,4CAA4C;YAC5C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAC,MAAM,EAAE,MAAM,EAAC,CAAC,CAAC;YACtE,IAAI,IAAI,CAAC,EAAE;gBAAE,SAAS;QACxB,CAAC;QACD,MAAM,IAAI,mBAAmB,CAC3B,sCAAsC,OAAO,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAC3F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAI,QAAqB,EAAE,UAAkB;IAClE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAC,MAAM,EAAE,KAAK,EAAC,CAAC,CAAC;IAC5E,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAC,CAAC;IACjE,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,mBAAmB,CAC3B,+BAA+B,UAAU,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACvF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,EAAC,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAC,CAAC;IACrC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,QAAqB,EAAE,UAAkB,EAAE,KAAc;IAC9E,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE;QACzD,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC;QAC7C,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;KAC5C,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,mBAAmB,CAC3B,gCAAgC,UAAU,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACxF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,oBAAoB,CAAC,QAAqB,EAAE,UAAkB;IAC3E,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAChE,OAAO,EAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,EAAC,CAAC;IACjE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAC,CAAC;QACrG,MAAM,IAAI,mBAAmB,CAC3B,2CAA2C,UAAU,KAAK,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACnH,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,QAAqB,EAAE,UAAkB;IAC5E,IAAI,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC,CAAC;IAC5E,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAClE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACvC,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAC,MAAM,EAAE,OAAO,EAAC,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvD,MAAM,IAAI,mBAAmB,CAC3B,6CAA6C,UAAU,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACrG,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACtE,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC/C,MAAM,IAAI,mBAAmB,CAC3B,6CAA6C,UAAU,+BAA+B,CACvF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAqB,EAAE,UAAkB;IACjE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,EAAC,MAAM,EAAE,QAAQ,EAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5C,MAAM,IAAI,mBAAmB,CAC3B,iCAAiC,UAAU,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACzF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,YAAoB,EAAE,MAAc;IACxE,OAAO,EAAC,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,YAAY,EAAE,MAAM,CAAC,EAAC,CAAC;AACrF,CAAC;AAED,SAAS,WAAW,CAAC,YAAoB,EAAE,MAAc;IACvD,OAAO,GAAG,YAAY,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAChF,CAAC;AAED,SAAS,QAAQ,CAAC,OAAoC,EAAE,KAAa,EAAE,KAA4B;IACjG,OAAO,CAAC,OAAO,EAAE,CAAC;QAChB,IAAI,EAAE,MAAM;QACZ,KAAK;QACL,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;QACjE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;QACjE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;KAChC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAClB,KAAa,EACb,SAAiB,EACjB,MAAe,EACf,KAAa,EACb,KAA4B;IAE5B,OAAO;QACL,KAAK;QACL,SAAS;QACT,MAAM;QACN,KAAK;QACL,KAAK;QACL,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,MAAM;QACnE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;QACjE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM;KAClE,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,0BAA0B,KAAK,+DAA+D,CAAC,CAAC;IAClH,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,SAAiB;IAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI,CAAC,EAAE,CAAC;QAC9G,MAAM,IAAI,KAAK,CAAC,qDAAqD,SAAS,EAAE,CAAC,CAAC;IACpF,CAAC;AACH,CAAC"}
@@ -16,6 +16,7 @@
16
16
  * ## System Jobs
17
17
  *
18
18
  * - {@link siteArchiveImport} - Import a site archive
19
+ * - {@link siteArchiveImportSet} - Apply an ordered, receipted set of site archives
19
20
  * - {@link siteArchiveImportSplit} - Import a large site archive in multiple parts
20
21
  * - {@link siteArchiveExport} - Export a site archive
21
22
  * - {@link siteArchiveExportToPath} - Export and save to local path
@@ -64,6 +65,8 @@
64
65
  export { executeJob, getJobExecution, waitForJob, searchJobExecutions, findRunningJobExecution, getJobLog, getJobErrorMessage, JobExecutionError, } from './run.js';
65
66
  export type { JobExecution, JobStepExecution, JobExecutionStatus, JobExecutionParameter, ExecuteJobOptions, WaitForJobOptions, WaitForJobPollInfo, SearchJobExecutionsOptions, JobExecutionSearchResult, } from './run.js';
66
67
  export { siteArchiveImport, siteArchiveImportSplit, siteArchiveExport, siteArchiveExportToBuffer, siteArchiveExportToPath, } from './site-archive.js';
68
+ export { discoverImportSet, siteArchiveImportSet, ImportSetStateError } from './import-set.js';
69
+ export type { DiscoverImportSetOptions, ImportSetItem, ImportSetReceipt, ImportSetItemResult, ImportSetResult, ImportSetEvent, ImportSetLockOwner, SiteArchiveImportSetOptions, } from './import-set.js';
67
70
  export type { SiteArchiveImportOptions, SiteArchiveImportResult, SiteArchiveImportSplitOptions, SplitImportPlanInfo, SplitImportPartInfo, SiteArchiveExportOptions, SiteArchiveExportResult, ExportDataUnitsConfiguration, ExportSitesConfiguration, ExportGlobalDataConfiguration, } from './site-archive.js';
68
71
  export { discoverExportableUnits } from './discover.js';
69
72
  export type { ExportableUnits } from './discover.js';
@@ -21,6 +21,7 @@
21
21
  * ## System Jobs
22
22
  *
23
23
  * - {@link siteArchiveImport} - Import a site archive
24
+ * - {@link siteArchiveImportSet} - Apply an ordered, receipted set of site archives
24
25
  * - {@link siteArchiveImportSplit} - Import a large site archive in multiple parts
25
26
  * - {@link siteArchiveExport} - Export a site archive
26
27
  * - {@link siteArchiveExportToPath} - Export and save to local path
@@ -70,6 +71,8 @@
70
71
  export { executeJob, getJobExecution, waitForJob, searchJobExecutions, findRunningJobExecution, getJobLog, getJobErrorMessage, JobExecutionError, } from './run.js';
71
72
  // Site archive import/export
72
73
  export { siteArchiveImport, siteArchiveImportSplit, siteArchiveExport, siteArchiveExportToBuffer, siteArchiveExportToPath, } from './site-archive.js';
74
+ // Ordered, idempotent import sets
75
+ export { discoverImportSet, siteArchiveImportSet, ImportSetStateError } from './import-set.js';
73
76
  // Exportable data unit discovery
74
77
  export { discoverExportableUnits } from './discover.js';
75
78
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/operations/jobs/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH,qBAAqB;AACrB,OAAO,EACL,UAAU,EACV,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,uBAAuB,EACvB,SAAS,EACT,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAclB,6BAA6B;AAC7B,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAe3B,iCAAiC;AACjC,OAAO,EAAC,uBAAuB,EAAC,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/operations/jobs/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAEH,qBAAqB;AACrB,OAAO,EACL,UAAU,EACV,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,uBAAuB,EACvB,SAAS,EACT,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAclB,6BAA6B;AAC7B,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,kCAAkC;AAClC,OAAO,EAAC,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AA0B7F,iCAAiC;AACjC,OAAO,EAAC,uBAAuB,EAAC,MAAM,eAAe,CAAC"}
@@ -137,13 +137,11 @@ export async function getJobExecution(instance, jobId, executionId) {
137
137
  * ```
138
138
  */
139
139
  export async function waitForJob(instance, jobId, executionId, options = {}) {
140
- const logger = getLogger();
141
140
  const { pollIntervalSeconds = 3, timeoutSeconds = 0, onPoll } = options;
142
141
  const sleepFn = options.sleep ?? defaultSleep;
143
142
  const startTime = Date.now();
144
143
  const pollIntervalMs = pollIntervalSeconds * 1000;
145
144
  const timeoutMs = timeoutSeconds * 1000;
146
- let ticks = 0;
147
145
  await sleepFn(pollIntervalMs);
148
146
  while (true) {
149
147
  const elapsedSeconds = Math.round((Date.now() - startTime) / 1000);
@@ -152,23 +150,14 @@ export async function waitForJob(instance, jobId, executionId, options = {}) {
152
150
  }
153
151
  const execution = await getJobExecution(instance, jobId, executionId);
154
152
  const currentStatus = execution.execution_status ?? 'unknown';
155
- logger.trace({ jobId, executionId, elapsedSeconds, status: currentStatus }, '[Jobs] Job poll');
156
153
  onPoll?.({ jobId, executionId, elapsedSeconds, status: currentStatus });
157
154
  // Check for terminal states
158
155
  if (execution.execution_status === 'aborted' || execution.exit_status?.code === 'ERROR') {
159
- logger.debug({ jobId, executionId, execution }, `Job ${jobId} failed`);
160
156
  throw new JobExecutionError(`Job ${jobId} failed`, execution);
161
157
  }
162
158
  if (execution.execution_status === 'finished') {
163
- const durationSec = (execution.duration ?? 0) / 1000;
164
- logger.debug({ jobId, executionId, status: execution.exit_status?.code, duration: durationSec }, `Job ${jobId} finished. Status: ${execution.exit_status?.code} (duration: ${durationSec}s)`);
165
159
  return execution;
166
160
  }
167
- // Log periodic updates
168
- if (ticks % 5 === 0) {
169
- logger.debug({ jobId, executionId, status: currentStatus, elapsed: elapsedSeconds }, `Waiting for job ${jobId} to finish (${elapsedSeconds}s elapsed)...`);
170
- }
171
- ticks++;
172
161
  await sleepFn(pollIntervalMs);
173
162
  }
174
163
  }