@uipath/vertical-solutions-tool 1.204.0 → 1.205.0-preview.258

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 (60) hide show
  1. package/README.md +80 -0
  2. package/dist/THIRD-PARTY-NOTICES.md +1617 -369
  3. package/dist/createSdk-2f9x47em.js +12 -0
  4. package/dist/deploy-jobs-3k87fkwz.js +23 -0
  5. package/dist/deploy-service-qaykt7er.js +1779 -0
  6. package/dist/deployment-search-arbm2z06.js +2649 -0
  7. package/dist/embedded-file-reader-r66242ey.js +114 -0
  8. package/dist/first-party-service-srxaftkn.js +27 -0
  9. package/dist/index-7a3eqtxv.js +3174 -0
  10. package/dist/index-8s9dxpj4.js +18812 -0
  11. package/dist/index-fyc0k5dd.js +51405 -0
  12. package/dist/index-h43sj8at.js +23075 -0
  13. package/dist/index-kmp9fmhb.js +25 -0
  14. package/dist/index-ngs0a2he.js +15 -0
  15. package/dist/index.js +14 -3
  16. package/dist/index.umd.min-fqefd9kn.js +7814 -0
  17. package/dist/job-commands-azgbrbdb.js +23 -0
  18. package/dist/job-output-t43hzj1f.js +36 -0
  19. package/dist/prompts-dtgt183n.js +260 -0
  20. package/dist/resume-service-mqfnnzb5.js +344 -0
  21. package/dist/seed-service-2d1f7zaz.js +2014 -0
  22. package/dist/seed-templates-sqqqratr.js +14 -0
  23. package/dist/service-errors-jzbq3z7p.js +22 -0
  24. package/dist/solution-auth-zq6gyxsv.js +11 -0
  25. package/dist/solution-deployments-m44fyb88.js +33 -0
  26. package/dist/templates-85yrztpk.js +15 -0
  27. package/dist/tool-342sz3hm.js +439 -0
  28. package/dist/tool-38ad77wd.js +1472 -0
  29. package/dist/tool-4z1dy1rn.js +260 -0
  30. package/dist/tool-53w8skv5.js +262 -0
  31. package/dist/tool-67587985.js +554 -0
  32. package/dist/tool-87e2ps7f.js +13 -0
  33. package/dist/tool-cag2z2d6.js +30 -0
  34. package/dist/tool-e4qgwf9h.js +2281 -0
  35. package/dist/tool-gdtpsdn7.js +342 -0
  36. package/dist/tool-gvmshnq9.js +555 -0
  37. package/dist/tool-h4f967yd.js +73 -0
  38. package/dist/tool-hdxtgckw.js +249 -0
  39. package/dist/tool-jjxbj28g.js +17067 -0
  40. package/dist/tool-keqjsxdx.js +28 -0
  41. package/dist/tool-maw0g02p.js +24 -0
  42. package/dist/tool-mn1wkbhw.js +113 -0
  43. package/dist/tool-n35nrs32.js +4949 -0
  44. package/dist/tool-p589v2r5.js +114 -0
  45. package/dist/tool-pz9qm3dv.js +6723 -0
  46. package/dist/tool-r1ewa0tf.js +5645 -0
  47. package/dist/tool-r2epw08s.js +164 -0
  48. package/dist/tool-rr9fensp.js +12 -0
  49. package/dist/tool-s04z9t80.js +19 -0
  50. package/dist/tool-s9qbxa2g.js +638 -0
  51. package/dist/tool-tjhwq0ez.js +261 -0
  52. package/dist/tool-v15vxc4x.js +183 -0
  53. package/dist/tool-vf2mgth0.js +14286 -0
  54. package/dist/tool-vp7rjr2q.js +22083 -0
  55. package/dist/tool-xd2ejt3h.js +103 -0
  56. package/dist/tool-yx29vb63.js +672 -0
  57. package/dist/tool.js +12 -2
  58. package/dist/watch-job-wh6m7xzq.js +31 -0
  59. package/package.json +3 -3
  60. package/dist/tool-xymb3dsq.js +0 -45085
@@ -0,0 +1,638 @@
1
+ import {
2
+ jsonObject
3
+ } from "./tool-87e2ps7f.js";
4
+ import {
5
+ exports_external
6
+ } from "./tool-vf2mgth0.js";
7
+ import {
8
+ canPrompt,
9
+ catchError
10
+ } from "./tool-pz9qm3dv.js";
11
+ import {
12
+ getFileSystem
13
+ } from "./tool-hdxtgckw.js";
14
+
15
+ // src/services/seed/workspace.ts
16
+ import { randomUUID } from "node:crypto";
17
+ var SEED_ROOT_DIR = "seeding";
18
+ var SEED_CONTEXT_FILE = ".seed-context.json";
19
+ var SEED_JOURNAL_FILE = ".seed-ids.json";
20
+ function tempPathFor(target) {
21
+ return `${target}.${randomUUID()}.uip-tmp`;
22
+ }
23
+ async function writeFileByRename(target, contents) {
24
+ const fs = getFileSystem();
25
+ const temp = tempPathFor(target);
26
+ const [writeError] = await catchError(fs.writeFile(temp, contents));
27
+ const [renameError] = writeError ? [writeError] : await catchError(fs.rename(temp, target));
28
+ if (renameError) {
29
+ await catchError(fs.rm(temp));
30
+ throw renameError;
31
+ }
32
+ }
33
+ function isPreservedWorkspaceFile(name) {
34
+ const folded = name.replace(/[. ]+$/, "").toLowerCase();
35
+ return folded === SEED_CONTEXT_FILE || folded === SEED_JOURNAL_FILE || folded.startsWith(`${SEED_CONTEXT_FILE}.`) || folded.startsWith(`${SEED_JOURNAL_FILE}.`);
36
+ }
37
+ function seedRoot(fs = getFileSystem()) {
38
+ return fs.path.join(fs.env.cwd(), SEED_ROOT_DIR);
39
+ }
40
+ var PACKAGE_NAME_PATTERN = /^[A-Za-z0-9_](?:[A-Za-z0-9._-]{0,198}[A-Za-z0-9_-])?$/;
41
+ var WINDOWS_DEVICE_NAME = /^(?:CON|PRN|AUX|NUL|COM[1-9¹²³]|LPT[1-9¹²³])$/i;
42
+ function isWindowsDeviceName(segment) {
43
+ const base = segment.split(".")[0].replace(/ +$/, "");
44
+ return WINDOWS_DEVICE_NAME.test(base);
45
+ }
46
+ function reservedOnThisPlatform(segment, platform = process.platform) {
47
+ return platform === "win32" && isWindowsDeviceName(segment);
48
+ }
49
+ function packageNameProblem(packageName) {
50
+ if (packageName === "" || packageName === "." || packageName === "..") {
51
+ return `"${packageName}" is not a package name.`;
52
+ }
53
+ if (!PACKAGE_NAME_PATTERN.test(packageName)) {
54
+ return `"${packageName}" cannot name a seed workspace: use letters, digits, ` + "dots, hyphens and underscores only, with no path separators and " + "no dot at the end.";
55
+ }
56
+ if (reservedOnThisPlatform(packageName)) {
57
+ return `"${packageName}" cannot name a seed workspace: Windows reserves it as a device name.`;
58
+ }
59
+ return;
60
+ }
61
+ function entityNameProblem(entityName) {
62
+ if (entityName === "" || /^\.+$/.test(entityName)) {
63
+ return `"${entityName}" is not an entity name.`;
64
+ }
65
+ if (!PACKAGE_NAME_PATTERN.test(entityName)) {
66
+ return `"${entityName}" cannot name a seed file: use letters, digits, dots, ` + "hyphens and underscores only, with no path separators and no dot " + "at the end.";
67
+ }
68
+ if (reservedOnThisPlatform(entityName)) {
69
+ return `"${entityName}" cannot name a seed file: Windows reserves it as a device name.`;
70
+ }
71
+ return;
72
+ }
73
+ function packageDir(packageName) {
74
+ const problem = packageNameProblem(packageName);
75
+ if (problem)
76
+ throw new Error(problem);
77
+ return getFileSystem().path.join(seedRoot(), packageName);
78
+ }
79
+
80
+ // src/services/error-code.ts
81
+ var WithCode = exports_external.object({ code: exports_external.string() });
82
+ function errorCode(error) {
83
+ const parsed = WithCode.safeParse(error);
84
+ return parsed.success ? parsed.data.code : undefined;
85
+ }
86
+
87
+ // src/services/seed/workspace-containment.ts
88
+ async function workspaceRoot(dir, fs = getFileSystem()) {
89
+ const lexical = fs.path.resolve(dir);
90
+ return { lexical, real: await realpathThroughAncestors(lexical, fs) };
91
+ }
92
+ async function isCaseInsensitiveDisk(root, fs = getFileSystem()) {
93
+ const probe = await nearestProbe(root.real, fs);
94
+ if (probe === undefined)
95
+ return;
96
+ const flipped = flipCase(probe);
97
+ if (!await fs.exists(flipped))
98
+ return false;
99
+ const [listError, entries] = await catchError(fs.readdir(fs.path.dirname(flipped)));
100
+ if (listError || entries === undefined)
101
+ return;
102
+ const flippedName = fs.path.basename(flipped).normalize("NFC");
103
+ if (entries.some((entry) => entry.normalize("NFC") === flippedName)) {
104
+ return false;
105
+ }
106
+ const [resolveError, resolved] = await catchError(fs.realpath(flipped));
107
+ if (resolveError || resolved === undefined)
108
+ return;
109
+ return resolved.normalize("NFC") === probe.normalize("NFC");
110
+ }
111
+ function flipCase(path) {
112
+ return path.replace(/[A-Za-z]/g, (char) => char === char.toLowerCase() ? char.toUpperCase() : char.toLowerCase());
113
+ }
114
+ async function nearestProbe(path, fs) {
115
+ for (let current = path;; current = fs.path.dirname(current)) {
116
+ if (/[A-Za-z]/.test(fs.path.basename(current)) && await fs.exists(current)) {
117
+ return current;
118
+ }
119
+ if (fs.path.dirname(current) === current)
120
+ return;
121
+ }
122
+ }
123
+ async function pathHasExpectedTarget(root, path, fs) {
124
+ if (!await fs.exists(path)) {
125
+ const [listError, entries] = await catchError(fs.readdir(fs.path.dirname(path)));
126
+ if (listError) {
127
+ return isMissingOrNotADirectory(listError) ? true : undefined;
128
+ }
129
+ if (!entries)
130
+ return true;
131
+ const name = fs.path.basename(path).normalize("NFC");
132
+ const folded = name.toLowerCase();
133
+ const exact = entries.some((entry) => entry.normalize("NFC") === name);
134
+ if (exact)
135
+ return false;
136
+ if (await isCaseInsensitiveDisk(root) === false)
137
+ return true;
138
+ return !entries.some((entry) => {
139
+ const normalized = entry.normalize("NFC");
140
+ return normalized.toLowerCase() === folded;
141
+ });
142
+ }
143
+ const lexical = fs.path.resolve(path);
144
+ const relative = fs.path.relative(root.lexical, lexical);
145
+ const expected = fs.path.join(root.real, relative).normalize("NFC");
146
+ const actual = (await fs.realpath(path)).normalize("NFC");
147
+ if (expected === actual)
148
+ return true;
149
+ if (await isCaseInsensitiveDisk(root) !== true)
150
+ return false;
151
+ return expected.toLowerCase() === actual.toLowerCase();
152
+ }
153
+ function isUnder(fs, root, path) {
154
+ const relative = fs.path.relative(root, path);
155
+ return relative === "" || relative.split(/[\\/]/)[0] !== ".." && !fs.path.isAbsolute(relative);
156
+ }
157
+ async function namesSeedRoot(dir, fs = getFileSystem()) {
158
+ const root = fs.path.resolve(seedRoot(fs));
159
+ const target = fs.path.resolve(fs.env.cwd(), dir);
160
+ if (isUnder(fs, root, target))
161
+ return true;
162
+ const folds = await isCaseInsensitiveDisk(await workspaceRoot(root, fs));
163
+ if (folds === false)
164
+ return false;
165
+ return isUnder(fs, root.toLowerCase(), target.toLowerCase());
166
+ }
167
+ async function isInsideWorkspace(root, path, fs = getFileSystem()) {
168
+ const resolved = await realpathThroughAncestors(path, fs);
169
+ return isUnder(fs, root.real, resolved) || isUnder(fs, root.lexical, resolved);
170
+ }
171
+ function isMissingOrNotADirectory(error) {
172
+ const code = errorCode(error);
173
+ return code === "ENOENT" || code === "ENOTDIR";
174
+ }
175
+ var MAX_ANCESTOR_WALK = 64;
176
+ async function realpathThroughAncestors(path, fs, depth = 0) {
177
+ const absolute = fs.path.resolve(path);
178
+ const real = await fs.realpath(absolute);
179
+ if (real !== absolute)
180
+ return real;
181
+ if (typeof fs.exists === "function" && await fs.exists(absolute)) {
182
+ return absolute;
183
+ }
184
+ const parent = fs.path.dirname(absolute);
185
+ if (depth > 0 && typeof fs.readdir === "function" && parent !== absolute) {
186
+ const [listError, entries] = await catchError(fs.readdir(parent));
187
+ if (listError && !isMissingOrNotADirectory(listError)) {
188
+ throw new Error(`Could not check where ${path} leads: ${parent} could not be ` + `listed (${listError.message}).`);
189
+ }
190
+ const name = fs.path.basename(absolute).normalize("NFC");
191
+ const folded = name.toLowerCase();
192
+ const sameName = (entry) => entry.normalize("NFC") === name;
193
+ const foldsOnto = (entry) => entry.normalize("NFC").toLowerCase() === folded;
194
+ const dangling = entries?.some(sameName) === true || entries?.some(foldsOnto) === true && await isCaseInsensitiveDisk({
195
+ lexical: parent,
196
+ real: await fs.realpath(parent)
197
+ }) !== false;
198
+ if (dangling) {
199
+ throw new Error(`${path} is a link to a path that does not exist; refusing to ` + "use it. Replace the link with a real file or folder.");
200
+ }
201
+ }
202
+ if (parent === absolute)
203
+ return absolute;
204
+ if (depth >= MAX_ANCESTOR_WALK) {
205
+ throw new Error(`Could not work out where ${path} leads: it names more than ` + `${MAX_ANCESTOR_WALK} folders that do not exist yet.`);
206
+ }
207
+ const realParent = await realpathThroughAncestors(parent, fs, depth + 1);
208
+ return realParent === parent ? absolute : fs.path.join(realParent, fs.path.basename(absolute));
209
+ }
210
+ async function isDanglingLink(path, fs = getFileSystem()) {
211
+ if (await fs.exists(path))
212
+ return false;
213
+ const parent = fs.path.dirname(path);
214
+ const [listError, entries] = await catchError(fs.readdir(parent));
215
+ if (listError) {
216
+ if (isMissingOrNotADirectory(listError))
217
+ return false;
218
+ throw listError;
219
+ }
220
+ if (!entries)
221
+ return false;
222
+ const name = fs.path.basename(path);
223
+ const spelled = name.normalize("NFC");
224
+ if (entries.some((entry) => entry.normalize("NFC") === spelled)) {
225
+ return true;
226
+ }
227
+ const caseless = await isCaseInsensitiveDisk(await workspaceRoot(parent, fs), fs);
228
+ if (caseless === false)
229
+ return false;
230
+ const folded = name.normalize("NFC").toLowerCase();
231
+ return entries.some((entry) => entry.normalize("NFC").toLowerCase() === folded);
232
+ }
233
+
234
+ // src/services/seed/seed-dir.ts
235
+ async function metadataIsItsOwnFile(dir, name, fs) {
236
+ const [error, ok] = await catchError(async () => {
237
+ if (await namesSeedRoot(dir, fs)) {
238
+ const inside = await insideSeedRoot(dir, fs);
239
+ if (!inside.ok)
240
+ return false;
241
+ }
242
+ const root = await workspaceRoot(dir, fs);
243
+ const path = fs.path.join(dir, name);
244
+ return await isInsideWorkspace(root, path, fs) && await pathHasExpectedTarget(root, path, fs);
245
+ });
246
+ return !error && ok === true;
247
+ }
248
+ async function resolveSeedDir(options) {
249
+ const fs = getFileSystem();
250
+ if (options.dir !== undefined)
251
+ return resolveExplicitDir(options.dir);
252
+ const linkedRoot = await seedRootLinkProblem();
253
+ if (linkedRoot)
254
+ return linkedRoot;
255
+ if (options.packageName !== undefined) {
256
+ const problem = packageNameProblem(options.packageName);
257
+ if (problem) {
258
+ return {
259
+ ok: false,
260
+ message: `--package-name ${problem}`,
261
+ instructions: "Pass the package name as the manifest spells it, or point --dir at the seed folder."
262
+ };
263
+ }
264
+ return resolvePackageDir(options.packageName);
265
+ }
266
+ const root = seedRoot();
267
+ const rootProblem = await seedRootProblem(root);
268
+ if (rootProblem)
269
+ return rootProblem;
270
+ if (await holdsSeedFiles(root))
271
+ return insideSeedRoot(root);
272
+ const candidates = await listPackageDirs(root);
273
+ if (candidates.length === 0) {
274
+ return { ok: true, dir: root };
275
+ }
276
+ if (candidates.length === 1) {
277
+ return insideSeedRoot(fs.path.join(root, candidates[0]));
278
+ }
279
+ if (!canPrompt() || !options.pickOne) {
280
+ return {
281
+ ok: false,
282
+ message: `${candidates.length} seed workspaces exist: ${candidates.join(", ")}.`,
283
+ instructions: "Name the one to seed with --package-name <name>, or pass --dir <path>."
284
+ };
285
+ }
286
+ const picked = await options.pickOne("Seed workspace", candidates);
287
+ const chosen = await insideSeedRoot(fs.path.join(root, picked));
288
+ return chosen.ok ? { ...chosen, picked: true } : chosen;
289
+ }
290
+ async function seedRootLinkProblem() {
291
+ const fs = getFileSystem();
292
+ const root = await workspaceRoot(seedRoot(), fs);
293
+ const target = await seedRootIsLinked(root, fs);
294
+ if (!target)
295
+ return;
296
+ return {
297
+ ok: false,
298
+ message: `The seed root ${root.lexical} is a link to ${target}.`,
299
+ instructions: LINKED_OUT_INSTRUCTIONS
300
+ };
301
+ }
302
+ async function insideSeedRoot(dir, fs = getFileSystem()) {
303
+ const root = await workspaceRoot(seedRoot(fs), fs);
304
+ const linkedRoot = await seedRootIsLinked(root, fs);
305
+ if (linkedRoot) {
306
+ return {
307
+ ok: false,
308
+ message: `The seed root ${root.lexical} is a link to ${linkedRoot}.`,
309
+ instructions: LINKED_OUT_INSTRUCTIONS
310
+ };
311
+ }
312
+ if (await isDanglingLink(dir, fs)) {
313
+ return {
314
+ ok: false,
315
+ message: `The seed workspace ${dir} is a link to a path that does not exist.`,
316
+ instructions: LINKED_OUT_INSTRUCTIONS
317
+ };
318
+ }
319
+ const inside = await isInsideWorkspace(root, dir, fs);
320
+ const ownPath = inside ? await pathHasExpectedTarget(root, dir, fs) : false;
321
+ if (ownPath === true)
322
+ return { ok: true, dir };
323
+ if (inside && ownPath === undefined) {
324
+ return {
325
+ ok: false,
326
+ message: `The seed workspace ${dir} could not be checked for a link.`,
327
+ instructions: LINKED_OUT_INSTRUCTIONS
328
+ };
329
+ }
330
+ if (inside) {
331
+ return {
332
+ ok: false,
333
+ message: `The seed workspace ${dir} is a link to another seed workspace.`,
334
+ instructions: LINKED_OUT_INSTRUCTIONS
335
+ };
336
+ }
337
+ return {
338
+ ok: false,
339
+ message: `The seed workspace ${dir} links outside ${root.lexical}.`,
340
+ instructions: LINKED_OUT_INSTRUCTIONS
341
+ };
342
+ }
343
+ async function seedRootIsLinked(root, fs) {
344
+ if (!await fs.exists(root.lexical)) {
345
+ const [danglingError, dangling] = await catchError(isDanglingLink(root.lexical, fs));
346
+ if (danglingError)
347
+ return "a path that could not be checked";
348
+ return dangling ? "a path that does not exist" : undefined;
349
+ }
350
+ const parent = await workspaceRoot(fs.path.dirname(root.lexical), fs);
351
+ const [error, ownPath] = await catchError(pathHasExpectedTarget(parent, root.lexical, fs));
352
+ if (ownPath === true)
353
+ return;
354
+ const [, real] = await catchError(fs.realpath(root.lexical));
355
+ if (error || ownPath === undefined) {
356
+ return real === undefined || real === root.lexical ? "a path that could not be checked" : real;
357
+ }
358
+ return real ?? "somewhere else";
359
+ }
360
+ var LINKED_OUT_INSTRUCTIONS = "Replace the link with a real folder, or pass --dir <path> to seed from that folder on purpose.";
361
+ async function seedRootProblem(root) {
362
+ const [, stats] = await catchError(getFileSystem().stat(root));
363
+ if (!stats) {
364
+ return {
365
+ ok: false,
366
+ message: `No seed workspace found at ${root}.`,
367
+ instructions: "A successful deploy writes the seed templates. Run 'uip vss deploy' first, " + "or pass --dir <path>."
368
+ };
369
+ }
370
+ if (!stats.isDirectory()) {
371
+ return {
372
+ ok: false,
373
+ message: `The seed workspace root is not a directory: ${root}`,
374
+ instructions: "Move the file at that path out of the way, or point --dir at the folder holding the seed CSVs."
375
+ };
376
+ }
377
+ return;
378
+ }
379
+ async function resolvePackageDir(packageName) {
380
+ const dir = packageDir(packageName);
381
+ const [, stats] = await catchError(getFileSystem().stat(dir));
382
+ if (!stats && await isDanglingLink(dir))
383
+ return insideSeedRoot(dir);
384
+ if (!stats) {
385
+ return {
386
+ ok: false,
387
+ message: `No seed workspace for "${packageName}" at ${dir}.`,
388
+ instructions: "A deploy that runs to the end writes it. Pass --package-version <version> " + "to create it from that version's seed templates, or --dir <path> to use " + "another folder.",
389
+ missing: true
390
+ };
391
+ }
392
+ if (!stats.isDirectory()) {
393
+ return {
394
+ ok: false,
395
+ message: `The seed workspace for "${packageName}" is not a directory: ${dir}`,
396
+ instructions: "Remove or rename that file, or pass --dir <path> to use another folder."
397
+ };
398
+ }
399
+ return insideSeedRoot(dir);
400
+ }
401
+ async function resolveExplicitDir(dir) {
402
+ const fs = getFileSystem();
403
+ if (dir.trim() === "") {
404
+ return {
405
+ ok: false,
406
+ message: "--dir was given no path.",
407
+ instructions: "Pass the folder holding the seed workspace, or drop --dir to use " + "./seeding/<package-name>."
408
+ };
409
+ }
410
+ const absolute = fs.path.isAbsolute(dir) ? dir : fs.path.join(fs.env.cwd(), dir);
411
+ const [, stats] = await catchError(fs.stat(absolute));
412
+ if (!stats?.isDirectory()) {
413
+ return {
414
+ ok: false,
415
+ message: stats ? `--dir is not a directory: ${dir}` : `--dir not found: ${dir}`,
416
+ instructions: "Run a deploy first, or point --dir at the folder holding the seed CSVs."
417
+ };
418
+ }
419
+ if (await namesSeedRoot(absolute)) {
420
+ return insideSeedRoot(absolute);
421
+ }
422
+ return { ok: true, dir: absolute };
423
+ }
424
+ async function holdsSeedFiles(dir) {
425
+ const fs = getFileSystem();
426
+ const [listError, entries] = await catchError(fs.readdir(dir));
427
+ if (listError && !isMissingOrNotADirectory(listError))
428
+ throw listError;
429
+ if (listError || !entries)
430
+ return false;
431
+ return entries.some((entry) => !entry.startsWith(".") && entry.toLowerCase().endsWith(".csv"));
432
+ }
433
+ async function listPackageDirs(root) {
434
+ const fs = getFileSystem();
435
+ const [listError, entries] = await catchError(fs.readdir(root));
436
+ if (listError && !isMissingOrNotADirectory(listError))
437
+ throw listError;
438
+ if (listError || !entries)
439
+ return [];
440
+ const dirs = [];
441
+ for (const entry of entries) {
442
+ if (entry.startsWith("."))
443
+ continue;
444
+ const path = fs.path.join(root, entry);
445
+ const [, stats] = await catchError(fs.stat(path));
446
+ if (stats?.isDirectory()) {
447
+ dirs.push(entry);
448
+ continue;
449
+ }
450
+ if (!stats && await isDanglingLink(path))
451
+ dirs.push(entry);
452
+ }
453
+ return dirs.sort((a, b) => a.localeCompare(b));
454
+ }
455
+
456
+ // src/services/seed/journal.ts
457
+ async function acquireSeedWorkspaceLock(dir, fs = getFileSystem()) {
458
+ const root = await workspaceRoot(dir, fs);
459
+ const journal = fs.path.join(dir, SEED_JOURNAL_FILE);
460
+ if (typeof fs.acquireLock !== "function")
461
+ return async () => {
462
+ return;
463
+ };
464
+ if (typeof fs.exists !== "function")
465
+ return fs.acquireLock(journal);
466
+ if (!await isInsideWorkspace(root, journal, fs) || await pathHasExpectedTarget(root, journal, fs) === false) {
467
+ throw new Error(`The seed journal ${journal} is a link; refusing to lock it. Replace the link with a real file.`);
468
+ }
469
+ return fs.acquireLock(journal);
470
+ }
471
+ var JOURNAL_VERSION = 1;
472
+ function journalScopeKeys(scope) {
473
+ const raw = (value) => (value ?? "").trim();
474
+ if (raw(scope.organizationId) && raw(scope.tenantId)) {
475
+ return [
476
+ ...new Set([
477
+ `${raw(scope.organizationId)}/${raw(scope.tenantId)}/` + `${raw(scope.folderKey) || "tenant"}`,
478
+ journalScopeKey({
479
+ organizationId: scope.organizationId,
480
+ tenantId: scope.tenantId,
481
+ folderKey: scope.folderKey
482
+ })
483
+ ])
484
+ ];
485
+ }
486
+ return [journalScopeKey(scope)];
487
+ }
488
+ function journalReadKeys(scope) {
489
+ return journalScopeKeys(scope);
490
+ }
491
+ function journalScopeKey(scope) {
492
+ const part = (value) => encodeURIComponent((value ?? "").trim().toLowerCase());
493
+ const org = part(scope.organizationName) || part(scope.organizationId);
494
+ const tenant = part(scope.tenantName) || part(scope.tenantId);
495
+ if (org === "" || tenant === "") {
496
+ throw new Error("Cannot record seeded rows: this run does not know which " + "organization and tenant it is seeding. Run `uip login` and " + "try again.");
497
+ }
498
+ return `${org}/${tenant}/${part(scope.folderKey) || "tenant"}`;
499
+ }
500
+ function emptyJournalFile() {
501
+ return { version: JOURNAL_VERSION, scopes: Object.create(null) };
502
+ }
503
+ async function readJournalFile(dir) {
504
+ const fs = getFileSystem();
505
+ const path = fs.path.join(dir, SEED_JOURNAL_FILE);
506
+ if (!await metadataIsItsOwnFile(dir, SEED_JOURNAL_FILE, fs)) {
507
+ return {
508
+ file: emptyJournalFile(),
509
+ unreadable: true,
510
+ warning: `Seed journal ${path} is not the workspace's own file — it, or the ` + `workspace holding it, is a link. Refusing to read it. ${JOURNAL_LOST_HINT}`
511
+ };
512
+ }
513
+ const [readError, contents] = await catchError(fs.readFile(path, "utf-8"));
514
+ if (readError) {
515
+ return {
516
+ file: emptyJournalFile(),
517
+ unreadable: true,
518
+ warning: `Seed journal ${path} could not be read (${readError.message}) — starting fresh. ` + JOURNAL_LOST_HINT
519
+ };
520
+ }
521
+ if (contents === null)
522
+ return { file: emptyJournalFile() };
523
+ const [parseError, parsed] = catchError(() => JSON.parse(contents));
524
+ const current = CurrentJournalSchema.safeParse(parsed);
525
+ if (!parseError && current.success) {
526
+ return { file: normalizeJournalFile(current.data.scopes) };
527
+ }
528
+ const foreign = ForeignJournalSchema.safeParse(parsed);
529
+ if (!parseError && foreign.success) {
530
+ return {
531
+ file: emptyJournalFile(),
532
+ unreadable: true,
533
+ warning: `Seed journal ${path} is version ${String(foreign.data.version)}, which this CLI ` + "does not know — leaving it alone and seeding without it. " + JOURNAL_LOST_HINT
534
+ };
535
+ }
536
+ return {
537
+ file: emptyJournalFile(),
538
+ warning: `Seed journal ${path} is unreadable or in an old format — starting fresh. ` + JOURNAL_LOST_HINT
539
+ };
540
+ }
541
+ var CurrentJournalSchema = exports_external.object({
542
+ version: exports_external.literal(JOURNAL_VERSION),
543
+ scopes: jsonObject
544
+ });
545
+ var ForeignJournalSchema = exports_external.object({
546
+ version: exports_external.custom((version) => typeof version === "number" || typeof version === "string").refine((version) => version !== JOURNAL_VERSION),
547
+ scopes: jsonObject
548
+ });
549
+ var JournalMapSchema = exports_external.union([jsonObject, exports_external.array(exports_external.unknown())]);
550
+ var JournalEntrySchema = exports_external.object({
551
+ recordId: exports_external.string().min(1),
552
+ pendingFiles: exports_external.array(exports_external.unknown()).optional().catch(undefined)
553
+ }).transform((entry) => ({
554
+ recordId: entry.recordId,
555
+ ...entry.pendingFiles !== undefined && entry.pendingFiles.length > 0 ? { pendingFiles: entry.pendingFiles.map(String) } : {}
556
+ }));
557
+ var JOURNAL_LOST_HINT = "Retry protection for previously seeded rows is lost; rows already in Data Fabric " + "may be inserted again.";
558
+ function normalizeJournalFile(rawScopes) {
559
+ const scopes = Object.create(null);
560
+ for (const [scopeKey, raw] of Object.entries(rawScopes)) {
561
+ const scope = JournalMapSchema.safeParse(raw);
562
+ if (scope.success)
563
+ scopes[scopeKey] = normalizeScope(scope.data);
564
+ }
565
+ return { version: JOURNAL_VERSION, scopes };
566
+ }
567
+ function normalizeScope(scope) {
568
+ const entities = Object.create(null);
569
+ for (const [entity, raw] of Object.entries(scope)) {
570
+ const rows = JournalMapSchema.safeParse(raw);
571
+ if (rows.success)
572
+ entities[entity] = normalizeRows(rows.data);
573
+ }
574
+ return entities;
575
+ }
576
+ function normalizeRows(rows) {
577
+ const kept = Object.create(null);
578
+ for (const [key, raw] of Object.entries(rows)) {
579
+ const entry = JournalEntrySchema.safeParse(raw);
580
+ if (entry.success)
581
+ kept[key] = entry.data;
582
+ }
583
+ return kept;
584
+ }
585
+ async function readJournal(dir, scope) {
586
+ const { file, warning } = await readJournalFile(dir);
587
+ const journal = Object.create(null);
588
+ for (const key of journalReadKeys(scope)) {
589
+ const scoped = file.scopes[key];
590
+ if (!scoped)
591
+ continue;
592
+ for (const [entity, rows] of Object.entries(scoped)) {
593
+ if (!Object.hasOwn(journal, entity)) {
594
+ const empty = Object.create(null);
595
+ journal[entity] = empty;
596
+ }
597
+ const target = journal[entity];
598
+ for (const [rowKey, entry] of Object.entries(rows)) {
599
+ if (!Object.hasOwn(target, rowKey))
600
+ target[rowKey] = entry;
601
+ }
602
+ }
603
+ }
604
+ return { journal, warning };
605
+ }
606
+ async function writeJournal(dir, scope, journal, lockHeld = false) {
607
+ const fs = getFileSystem();
608
+ if (lockHeld) {
609
+ const { file, unreadable, warning } = await readJournalFile(dir);
610
+ if (unreadable)
611
+ throw new Error(warning);
612
+ writeScope(file, scope, journal);
613
+ await writeJournalFile(dir, file);
614
+ return;
615
+ }
616
+ const release = await acquireSeedWorkspaceLock(dir, fs);
617
+ try {
618
+ const { file, unreadable, warning } = await readJournalFile(dir);
619
+ if (unreadable)
620
+ throw new Error(warning);
621
+ writeScope(file, scope, journal);
622
+ await writeJournalFile(dir, file);
623
+ } finally {
624
+ await catchError(release());
625
+ }
626
+ }
627
+ function writeScope(file, scope, journal) {
628
+ for (const key of journalScopeKeys(scope))
629
+ file.scopes[key] = journal;
630
+ }
631
+ async function writeJournalFile(dir, file) {
632
+ const fs = getFileSystem();
633
+ await writeFileByRename(fs.path.join(dir, SEED_JOURNAL_FILE), JSON.stringify(file, null, 2));
634
+ }
635
+
636
+ export { SEED_ROOT_DIR, SEED_CONTEXT_FILE, tempPathFor, writeFileByRename, isPreservedWorkspaceFile, seedRoot, reservedOnThisPlatform, packageNameProblem, entityNameProblem, packageDir, errorCode, workspaceRoot, isCaseInsensitiveDisk, pathHasExpectedTarget, namesSeedRoot, isInsideWorkspace, isMissingOrNotADirectory, isDanglingLink, metadataIsItsOwnFile, resolveSeedDir, insideSeedRoot, acquireSeedWorkspaceLock, readJournal, writeJournal };
637
+
638
+ //# debugId=E9C29EF019AD78A464756E2164756E21