@meshy-ai/cli 0.2.0 → 0.3.1

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 (289) hide show
  1. package/.env.example +8 -2
  2. package/README.md +343 -108
  3. package/dist/client/endpoints/animation-catalog.d.ts +37 -0
  4. package/dist/client/endpoints/animation-catalog.d.ts.map +1 -0
  5. package/dist/client/endpoints/animation-catalog.js +55 -0
  6. package/dist/client/endpoints/animation-catalog.js.map +1 -0
  7. package/dist/client/endpoints/balance.d.ts +5 -0
  8. package/dist/client/endpoints/balance.d.ts.map +1 -1
  9. package/dist/client/endpoints/balance.js +5 -1
  10. package/dist/client/endpoints/balance.js.map +1 -1
  11. package/dist/client/endpoints/base.d.ts +41 -7
  12. package/dist/client/endpoints/base.d.ts.map +1 -1
  13. package/dist/client/endpoints/base.js +61 -40
  14. package/dist/client/endpoints/base.js.map +1 -1
  15. package/dist/client/endpoints/showcases.d.ts +31 -0
  16. package/dist/client/endpoints/showcases.d.ts.map +1 -0
  17. package/dist/client/endpoints/showcases.js +49 -0
  18. package/dist/client/endpoints/showcases.js.map +1 -0
  19. package/dist/client/errors.d.ts +1 -0
  20. package/dist/client/errors.d.ts.map +1 -1
  21. package/dist/client/errors.js +1 -1
  22. package/dist/client/errors.js.map +1 -1
  23. package/dist/client/index.d.ts +47 -38
  24. package/dist/client/index.d.ts.map +1 -1
  25. package/dist/client/index.js +89 -120
  26. package/dist/client/index.js.map +1 -1
  27. package/dist/client/resource-registry.d.ts +97 -0
  28. package/dist/client/resource-registry.d.ts.map +1 -0
  29. package/dist/client/resource-registry.js +157 -0
  30. package/dist/client/resource-registry.js.map +1 -0
  31. package/dist/client/transport.d.ts +99 -0
  32. package/dist/client/transport.d.ts.map +1 -0
  33. package/dist/client/transport.js +320 -0
  34. package/dist/client/transport.js.map +1 -0
  35. package/dist/client/types.d.ts +17 -6
  36. package/dist/client/types.d.ts.map +1 -1
  37. package/dist/client/types.js +28 -6
  38. package/dist/client/types.js.map +1 -1
  39. package/dist/cmd/animation-catalog.d.ts +26 -0
  40. package/dist/cmd/animation-catalog.d.ts.map +1 -0
  41. package/dist/cmd/animation-catalog.js +80 -0
  42. package/dist/cmd/animation-catalog.js.map +1 -0
  43. package/dist/cmd/api.d.ts +3 -2
  44. package/dist/cmd/api.d.ts.map +1 -1
  45. package/dist/cmd/api.js +22 -8
  46. package/dist/cmd/api.js.map +1 -1
  47. package/dist/cmd/auth.d.ts.map +1 -1
  48. package/dist/cmd/auth.js +5 -0
  49. package/dist/cmd/auth.js.map +1 -1
  50. package/dist/cmd/balance.d.ts.map +1 -1
  51. package/dist/cmd/balance.js +10 -6
  52. package/dist/cmd/balance.js.map +1 -1
  53. package/dist/cmd/creative-lab.d.ts +26 -0
  54. package/dist/cmd/creative-lab.d.ts.map +1 -0
  55. package/dist/cmd/creative-lab.js +256 -0
  56. package/dist/cmd/creative-lab.js.map +1 -0
  57. package/dist/cmd/delete.d.ts.map +1 -1
  58. package/dist/cmd/delete.js +6 -7
  59. package/dist/cmd/delete.js.map +1 -1
  60. package/dist/cmd/doctor.d.ts +23 -0
  61. package/dist/cmd/doctor.d.ts.map +1 -0
  62. package/dist/cmd/doctor.js +61 -0
  63. package/dist/cmd/doctor.js.map +1 -0
  64. package/dist/cmd/download.d.ts +17 -0
  65. package/dist/cmd/download.d.ts.map +1 -0
  66. package/dist/cmd/download.js +436 -0
  67. package/dist/cmd/download.js.map +1 -0
  68. package/dist/cmd/inspect.d.ts +63 -0
  69. package/dist/cmd/inspect.d.ts.map +1 -0
  70. package/dist/cmd/inspect.js +179 -0
  71. package/dist/cmd/inspect.js.map +1 -0
  72. package/dist/cmd/make.d.ts +13 -3
  73. package/dist/cmd/make.d.ts.map +1 -1
  74. package/dist/cmd/make.js +240 -36
  75. package/dist/cmd/make.js.map +1 -1
  76. package/dist/cmd/mesh.d.ts +13 -0
  77. package/dist/cmd/mesh.d.ts.map +1 -0
  78. package/dist/cmd/mesh.js +67 -0
  79. package/dist/cmd/mesh.js.map +1 -0
  80. package/dist/cmd/project.d.ts +16 -0
  81. package/dist/cmd/project.d.ts.map +1 -0
  82. package/dist/cmd/project.js +136 -0
  83. package/dist/cmd/project.js.map +1 -0
  84. package/dist/cmd/resources.d.ts +5 -0
  85. package/dist/cmd/resources.d.ts.map +1 -1
  86. package/dist/cmd/resources.js +38 -10
  87. package/dist/cmd/resources.js.map +1 -1
  88. package/dist/cmd/showcases.d.ts +10 -0
  89. package/dist/cmd/showcases.d.ts.map +1 -0
  90. package/dist/cmd/showcases.js +63 -0
  91. package/dist/cmd/showcases.js.map +1 -0
  92. package/dist/cmd/slicer.d.ts +12 -0
  93. package/dist/cmd/slicer.d.ts.map +1 -0
  94. package/dist/cmd/slicer.js +46 -0
  95. package/dist/cmd/slicer.js.map +1 -0
  96. package/dist/cmd/uv-unwrap.d.ts +16 -0
  97. package/dist/cmd/uv-unwrap.d.ts.map +1 -0
  98. package/dist/cmd/uv-unwrap.js +52 -0
  99. package/dist/cmd/uv-unwrap.js.map +1 -0
  100. package/dist/index.d.ts +13 -1
  101. package/dist/index.d.ts.map +1 -1
  102. package/dist/index.js +141 -8
  103. package/dist/index.js.map +1 -1
  104. package/dist/internal/artifacts.d.ts +97 -0
  105. package/dist/internal/artifacts.d.ts.map +1 -0
  106. package/dist/internal/artifacts.js +280 -0
  107. package/dist/internal/artifacts.js.map +1 -0
  108. package/dist/internal/atomic-file.d.ts +39 -0
  109. package/dist/internal/atomic-file.d.ts.map +1 -0
  110. package/dist/internal/atomic-file.js +160 -0
  111. package/dist/internal/atomic-file.js.map +1 -0
  112. package/dist/internal/command-helpers.d.ts +46 -0
  113. package/dist/internal/command-helpers.d.ts.map +1 -0
  114. package/dist/internal/command-helpers.js +61 -0
  115. package/dist/internal/command-helpers.js.map +1 -0
  116. package/dist/internal/config.d.ts +48 -5
  117. package/dist/internal/config.d.ts.map +1 -1
  118. package/dist/internal/config.js +95 -6
  119. package/dist/internal/config.js.map +1 -1
  120. package/dist/internal/context.d.ts +25 -0
  121. package/dist/internal/context.d.ts.map +1 -0
  122. package/dist/internal/context.js +37 -0
  123. package/dist/internal/context.js.map +1 -0
  124. package/dist/internal/credentials.d.ts +11 -0
  125. package/dist/internal/credentials.d.ts.map +1 -1
  126. package/dist/internal/credentials.js +2 -0
  127. package/dist/internal/credentials.js.map +1 -1
  128. package/dist/internal/doctor.d.ts +94 -0
  129. package/dist/internal/doctor.d.ts.map +1 -0
  130. package/dist/internal/doctor.js +280 -0
  131. package/dist/internal/doctor.js.map +1 -0
  132. package/dist/internal/download.d.ts +147 -13
  133. package/dist/internal/download.d.ts.map +1 -1
  134. package/dist/internal/download.js +735 -142
  135. package/dist/internal/download.js.map +1 -1
  136. package/dist/internal/env-file.d.ts +29 -0
  137. package/dist/internal/env-file.d.ts.map +1 -0
  138. package/dist/internal/env-file.js +95 -0
  139. package/dist/internal/env-file.js.map +1 -0
  140. package/dist/internal/errors.d.ts +74 -1
  141. package/dist/internal/errors.d.ts.map +1 -1
  142. package/dist/internal/errors.js +173 -1
  143. package/dist/internal/errors.js.map +1 -1
  144. package/dist/internal/file-input.d.ts +52 -12
  145. package/dist/internal/file-input.d.ts.map +1 -1
  146. package/dist/internal/file-input.js +162 -33
  147. package/dist/internal/file-input.js.map +1 -1
  148. package/dist/internal/global-options.d.ts +6 -4
  149. package/dist/internal/global-options.d.ts.map +1 -1
  150. package/dist/internal/global-options.js +19 -4
  151. package/dist/internal/global-options.js.map +1 -1
  152. package/dist/internal/image-models.d.ts +9 -2
  153. package/dist/internal/image-models.d.ts.map +1 -1
  154. package/dist/internal/image-models.js +24 -12
  155. package/dist/internal/image-models.js.map +1 -1
  156. package/dist/internal/inspect.d.ts +67 -0
  157. package/dist/internal/inspect.d.ts.map +1 -0
  158. package/dist/internal/inspect.js +111 -0
  159. package/dist/internal/inspect.js.map +1 -0
  160. package/dist/internal/lock.d.ts +19 -0
  161. package/dist/internal/lock.d.ts.map +1 -0
  162. package/dist/internal/lock.js +66 -0
  163. package/dist/internal/lock.js.map +1 -0
  164. package/dist/internal/material-links.d.ts +115 -0
  165. package/dist/internal/material-links.d.ts.map +1 -0
  166. package/dist/internal/material-links.js +577 -0
  167. package/dist/internal/material-links.js.map +1 -0
  168. package/dist/internal/obj-transform.d.ts +115 -0
  169. package/dist/internal/obj-transform.d.ts.map +1 -0
  170. package/dist/internal/obj-transform.js +649 -0
  171. package/dist/internal/obj-transform.js.map +1 -0
  172. package/dist/internal/operation-store.d.ts +123 -0
  173. package/dist/internal/operation-store.d.ts.map +1 -0
  174. package/dist/internal/operation-store.js +229 -0
  175. package/dist/internal/operation-store.js.map +1 -0
  176. package/dist/internal/output.d.ts +20 -2
  177. package/dist/internal/output.d.ts.map +1 -1
  178. package/dist/internal/output.js +32 -4
  179. package/dist/internal/output.js.map +1 -1
  180. package/dist/internal/paths.d.ts +89 -0
  181. package/dist/internal/paths.d.ts.map +1 -0
  182. package/dist/internal/paths.js +168 -0
  183. package/dist/internal/paths.js.map +1 -0
  184. package/dist/internal/payload.d.ts +15 -0
  185. package/dist/internal/payload.d.ts.map +1 -1
  186. package/dist/internal/payload.js +50 -3
  187. package/dist/internal/payload.js.map +1 -1
  188. package/dist/internal/poll.d.ts +30 -4
  189. package/dist/internal/poll.d.ts.map +1 -1
  190. package/dist/internal/poll.js +99 -16
  191. package/dist/internal/poll.js.map +1 -1
  192. package/dist/internal/project-store.d.ts +197 -0
  193. package/dist/internal/project-store.d.ts.map +1 -0
  194. package/dist/internal/project-store.js +467 -0
  195. package/dist/internal/project-store.js.map +1 -0
  196. package/dist/internal/result.d.ts +50 -0
  197. package/dist/internal/result.d.ts.map +1 -0
  198. package/dist/internal/result.js +41 -0
  199. package/dist/internal/result.js.map +1 -0
  200. package/dist/internal/runtime.d.ts +35 -5
  201. package/dist/internal/runtime.d.ts.map +1 -1
  202. package/dist/internal/runtime.js +68 -18
  203. package/dist/internal/runtime.js.map +1 -1
  204. package/dist/internal/slicers.d.ts +117 -0
  205. package/dist/internal/slicers.d.ts.map +1 -0
  206. package/dist/internal/slicers.js +314 -0
  207. package/dist/internal/slicers.js.map +1 -0
  208. package/dist/internal/stream.d.ts +58 -0
  209. package/dist/internal/stream.d.ts.map +1 -0
  210. package/dist/internal/stream.js +280 -0
  211. package/dist/internal/stream.js.map +1 -0
  212. package/dist/internal/task-command.d.ts +128 -11
  213. package/dist/internal/task-command.d.ts.map +1 -1
  214. package/dist/internal/task-command.js +991 -111
  215. package/dist/internal/task-command.js.map +1 -1
  216. package/dist/internal/task-view.d.ts +56 -0
  217. package/dist/internal/task-view.d.ts.map +1 -0
  218. package/dist/internal/task-view.js +95 -0
  219. package/dist/internal/task-view.js.map +1 -0
  220. package/dist/internal/update-notifier.d.ts +5 -1
  221. package/dist/internal/update-notifier.d.ts.map +1 -1
  222. package/dist/internal/update-notifier.js +7 -3
  223. package/dist/internal/update-notifier.js.map +1 -1
  224. package/dist/root.d.ts +10 -0
  225. package/dist/root.d.ts.map +1 -1
  226. package/dist/root.js +75 -10
  227. package/dist/root.js.map +1 -1
  228. package/package.json +3 -2
  229. package/skills/meshy-cli/SKILL.md +140 -59
  230. package/dist/client/endpoints/analyze-printability.d.ts +0 -5
  231. package/dist/client/endpoints/analyze-printability.d.ts.map +0 -1
  232. package/dist/client/endpoints/analyze-printability.js +0 -7
  233. package/dist/client/endpoints/analyze-printability.js.map +0 -1
  234. package/dist/client/endpoints/animate.d.ts +0 -6
  235. package/dist/client/endpoints/animate.d.ts.map +0 -1
  236. package/dist/client/endpoints/animate.js +0 -8
  237. package/dist/client/endpoints/animate.js.map +0 -1
  238. package/dist/client/endpoints/convert.d.ts +0 -5
  239. package/dist/client/endpoints/convert.d.ts.map +0 -1
  240. package/dist/client/endpoints/convert.js +0 -7
  241. package/dist/client/endpoints/convert.js.map +0 -1
  242. package/dist/client/endpoints/image-to-3d.d.ts +0 -5
  243. package/dist/client/endpoints/image-to-3d.d.ts.map +0 -1
  244. package/dist/client/endpoints/image-to-3d.js +0 -7
  245. package/dist/client/endpoints/image-to-3d.js.map +0 -1
  246. package/dist/client/endpoints/image-to-image.d.ts +0 -5
  247. package/dist/client/endpoints/image-to-image.d.ts.map +0 -1
  248. package/dist/client/endpoints/image-to-image.js +0 -7
  249. package/dist/client/endpoints/image-to-image.js.map +0 -1
  250. package/dist/client/endpoints/multi-color-print.d.ts +0 -5
  251. package/dist/client/endpoints/multi-color-print.d.ts.map +0 -1
  252. package/dist/client/endpoints/multi-color-print.js +0 -7
  253. package/dist/client/endpoints/multi-color-print.js.map +0 -1
  254. package/dist/client/endpoints/multi-image-to-3d.d.ts +0 -5
  255. package/dist/client/endpoints/multi-image-to-3d.d.ts.map +0 -1
  256. package/dist/client/endpoints/multi-image-to-3d.js +0 -7
  257. package/dist/client/endpoints/multi-image-to-3d.js.map +0 -1
  258. package/dist/client/endpoints/remesh.d.ts +0 -5
  259. package/dist/client/endpoints/remesh.d.ts.map +0 -1
  260. package/dist/client/endpoints/remesh.js +0 -7
  261. package/dist/client/endpoints/remesh.js.map +0 -1
  262. package/dist/client/endpoints/repair-printability.d.ts +0 -5
  263. package/dist/client/endpoints/repair-printability.d.ts.map +0 -1
  264. package/dist/client/endpoints/repair-printability.js +0 -7
  265. package/dist/client/endpoints/repair-printability.js.map +0 -1
  266. package/dist/client/endpoints/resize.d.ts +0 -5
  267. package/dist/client/endpoints/resize.d.ts.map +0 -1
  268. package/dist/client/endpoints/resize.js +0 -7
  269. package/dist/client/endpoints/resize.js.map +0 -1
  270. package/dist/client/endpoints/retexture.d.ts +0 -5
  271. package/dist/client/endpoints/retexture.d.ts.map +0 -1
  272. package/dist/client/endpoints/retexture.js +0 -7
  273. package/dist/client/endpoints/retexture.js.map +0 -1
  274. package/dist/client/endpoints/rigging.d.ts +0 -6
  275. package/dist/client/endpoints/rigging.d.ts.map +0 -1
  276. package/dist/client/endpoints/rigging.js +0 -8
  277. package/dist/client/endpoints/rigging.js.map +0 -1
  278. package/dist/client/endpoints/text-to-3d.d.ts +0 -6
  279. package/dist/client/endpoints/text-to-3d.d.ts.map +0 -1
  280. package/dist/client/endpoints/text-to-3d.js +0 -8
  281. package/dist/client/endpoints/text-to-3d.js.map +0 -1
  282. package/dist/client/endpoints/text-to-image.d.ts +0 -5
  283. package/dist/client/endpoints/text-to-image.d.ts.map +0 -1
  284. package/dist/client/endpoints/text-to-image.js +0 -7
  285. package/dist/client/endpoints/text-to-image.js.map +0 -1
  286. package/dist/client/endpoints/text-to-motion.d.ts +0 -6
  287. package/dist/client/endpoints/text-to-motion.d.ts.map +0 -1
  288. package/dist/client/endpoints/text-to-motion.js +0 -8
  289. package/dist/client/endpoints/text-to-motion.js.map +0 -1
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Path containment and safe naming.
3
+ *
4
+ * Every file the CLI writes is checked against an authorised root: the
5
+ * explicit --workspace when given, otherwise the root the command itself
6
+ * authorised (a project directory, or the parent of an explicit output path).
7
+ * Containment is decided on real paths — the deepest existing ancestor is
8
+ * resolved with realpath so a symlinked directory cannot redirect a write —
9
+ * never with a string prefix test.
10
+ *
11
+ * The root itself is *frozen* when the command starts (`freezeRoot`): its real
12
+ * path and the identity (device, inode) of the physical directory behind it are
13
+ * captured before the first request or write, and every later check
14
+ * (`resolveWithinRoot` with an `AuthorisedRoot`) first proves that this very
15
+ * directory is still there — not a symlink that appeared at its path, not a
16
+ * different directory — and then proves the target's real path inside it. A
17
+ * root that is re-resolved at check time would move with whatever now sits at
18
+ * its path; a frozen root cannot. Stable aliases (macOS `/var` → `/private/var`,
19
+ * a symlinked parent, a workspace given through a symlink that keeps pointing
20
+ * at the same directory) resolve to the same physical directory and pass.
21
+ */
22
+ import { lstatSync, realpathSync, statSync } from "node:fs";
23
+ import { dirname, isAbsolute, relative, resolve as resolvePath, sep, basename } from "node:path";
24
+ import { CliError } from "./errors.js";
25
+ function errno(err) {
26
+ return err?.code;
27
+ }
28
+ /** Resolve the real path of the deepest existing ancestor and re-append the missing tail. */
29
+ export function realpathLenient(path) {
30
+ const abs = resolvePath(path);
31
+ const missing = [];
32
+ let cursor = abs;
33
+ for (;;) {
34
+ try {
35
+ const real = realpathSync.native(cursor);
36
+ return missing.length ? resolvePath(real, ...missing.reverse()) : real;
37
+ }
38
+ catch (err) {
39
+ if (errno(err) !== "ENOENT" && errno(err) !== "ENOTDIR")
40
+ throw err;
41
+ const parent = dirname(cursor);
42
+ if (parent === cursor)
43
+ return abs;
44
+ missing.push(basename(cursor));
45
+ cursor = parent;
46
+ }
47
+ }
48
+ }
49
+ export function isInside(root, candidate) {
50
+ const rel = relative(root, candidate);
51
+ return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
52
+ }
53
+ function errnoOf(err) {
54
+ return err?.code;
55
+ }
56
+ /** Freeze a write boundary: resolve it once and remember which directory it is. */
57
+ export function freezeRoot(path, opts = {}) {
58
+ const given = resolvePath(opts.cwd ?? process.cwd(), path);
59
+ const real = realpathLenient(given);
60
+ let anchor = real;
61
+ for (;;) {
62
+ try {
63
+ const st = statSync(anchor);
64
+ return { given, real, anchor, dev: st.dev, ino: st.ino, directory: st.isDirectory(), label: opts.label ?? "root" };
65
+ }
66
+ catch (err) {
67
+ if (errnoOf(err) !== "ENOENT" && errnoOf(err) !== "ENOTDIR")
68
+ throw err;
69
+ const parent = dirname(anchor);
70
+ if (parent === anchor)
71
+ throw err;
72
+ anchor = parent;
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * The directory a root was frozen on must still be the one at its path: a
78
+ * directory (never a symlink), with the same device and inode. Anything else
79
+ * means the authorised boundary was moved or replaced since the command started.
80
+ */
81
+ export function assertRootIntact(root) {
82
+ if (!root.directory) {
83
+ throw new CliError({ code: "local_io", message: `${root.label} ${root.given} is not a directory; refusing to write` });
84
+ }
85
+ let st;
86
+ try {
87
+ st = lstatSync(root.anchor);
88
+ }
89
+ catch (err) {
90
+ throw new CliError({
91
+ code: "local_io",
92
+ message: `${root.label} ${root.given} changed since the command started: ${root.anchor} is gone (${errnoOf(err) ?? "stat failed"}); refusing to write outside the authorised boundary`,
93
+ cause: err,
94
+ });
95
+ }
96
+ if (st.isSymbolicLink() || !st.isDirectory() || st.dev !== root.dev || st.ino !== root.ino) {
97
+ throw new CliError({
98
+ code: "local_io",
99
+ message: `${root.label} ${root.given} changed since the command started: ${root.anchor} is now ${st.isSymbolicLink() ? "a symbolic link" : st.isDirectory() ? "a different directory" : "not a directory"}; refusing to write outside the authorised boundary`,
100
+ });
101
+ }
102
+ }
103
+ /**
104
+ * Resolve `target` (file or directory) against cwd and prove it lies inside
105
+ * `root`. A symlink at the leaf is rejected for write targets: replacing or
106
+ * following it could land the bytes outside the root.
107
+ *
108
+ * With an `AuthorisedRoot` the root is not resolved again: its frozen real path
109
+ * is the boundary and its identity is re-proven first. A plain string root is
110
+ * resolved here (for one-shot local checks with no request in between).
111
+ */
112
+ export function resolveWithinRoot(target, root, opts = {}) {
113
+ const cwd = opts.cwd ?? process.cwd();
114
+ const label = opts.label ?? "path";
115
+ let rootReal;
116
+ if (typeof root === "string") {
117
+ rootReal = realpathLenient(resolvePath(cwd, root));
118
+ }
119
+ else {
120
+ assertRootIntact(root);
121
+ rootReal = root.real;
122
+ }
123
+ const absTarget = resolvePath(cwd, target);
124
+ let leaf = null;
125
+ try {
126
+ leaf = lstatSync(absTarget);
127
+ }
128
+ catch (err) {
129
+ if (errno(err) !== "ENOENT" && errno(err) !== "ENOTDIR")
130
+ throw err;
131
+ }
132
+ if (leaf?.isSymbolicLink() && !opts.allowSymlinkLeaf) {
133
+ throw new CliError({
134
+ code: "local_io",
135
+ message: `${label} ${target} is a symbolic link; refusing to write through it`,
136
+ });
137
+ }
138
+ const real = realpathLenient(absTarget);
139
+ if (!isInside(rootReal, real)) {
140
+ throw new CliError({
141
+ code: "local_io",
142
+ message: `${label} ${target} resolves outside the authorised root ${rootReal}`,
143
+ });
144
+ }
145
+ return { path: real, root: rootReal, relative: relative(rootReal, real).split(sep).join("/") };
146
+ }
147
+ const WINDOWS_RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i;
148
+ /**
149
+ * Turn an arbitrary string (asset key, task id, project name) into a single
150
+ * safe path segment: lowercase-insensitive ASCII letters, digits, `.`, `_`,
151
+ * `-`; everything else becomes `_`; no leading dots, no reserved names, no
152
+ * empty result.
153
+ */
154
+ export function safeSegment(input, fallback = "item") {
155
+ let s = input.replace(/[^A-Za-z0-9._-]+/g, "_").replace(/^\.+/, "").replace(/\.+$/, "");
156
+ s = s.replace(/_{2,}/g, "_");
157
+ if (!s)
158
+ s = fallback;
159
+ if (WINDOWS_RESERVED.test(s))
160
+ s = `_${s}`;
161
+ return s.slice(0, 120);
162
+ }
163
+ /** Lowercase file extension without the dot, or "" when the name has none or it is not a plain token. */
164
+ export function safeExtension(ext) {
165
+ const e = ext.replace(/^\./, "").toLowerCase();
166
+ return /^[a-z0-9]{1,8}$/.test(e) ? e : "";
167
+ }
168
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/internal/paths.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,23 @@
2
2
  * Build a request payload from structured CLI flags and optional raw JSON.
3
3
  * Merge order (later wins): CLI defaults < --data < flag-supplied fields —
4
4
  * pinned defaults must never clobber an explicit --data payload.
5
+ *
6
+ * Merging is shallow on purpose: arrays and plain fields replace wholesale so a
7
+ * `--data` array is exactly what is sent. The one exception is the small set of
8
+ * nested option objects a resource declares (`nestedObjectKeys`, e.g. Creative
9
+ * Lab `options`/`output`): those are merged field by field across the same
10
+ * layers, so `--data '{"options":{...}}'` and `--options '{...}'` compose
11
+ * instead of the later one silently deleting the earlier one's settings.
5
12
  */
6
13
  export declare function parseJsonFlag(raw: string | undefined, flag: string): Record<string, unknown>;
7
14
  export declare function dropNullish(input: Record<string, unknown>): Record<string, unknown>;
8
15
  export declare function mergePayload(...layers: Record<string, unknown>[]): Record<string, unknown>;
16
+ /**
17
+ * Field-level merge for the declared nested object keys, applied on top of a
18
+ * shallow `mergePayload` result. Layers are ordered weakest → strongest; within
19
+ * a key, a later layer's fields win, unspecified fields survive, and explicit
20
+ * `false`/`0`/`""` are kept. If the strongest layer that names the key is not
21
+ * an object (a deliberate replacement), the shallow result stands.
22
+ */
23
+ export declare function mergeNestedObjects(merged: Record<string, unknown>, layers: readonly Record<string, unknown>[], keys: readonly string[]): Record<string, unknown>;
9
24
  //# sourceMappingURL=payload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../src/internal/payload.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAe5F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOnF;AAED,wBAAgB,YAAY,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO1F"}
1
+ {"version":3,"file":"payload.d.ts","sourceRoot":"","sources":["../../src/internal/payload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwB5F;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOnF;AAED,wBAAgB,YAAY,CAAC,GAAG,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO1F;AAMD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC1C,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAczB"}
@@ -2,23 +2,42 @@
2
2
  * Build a request payload from structured CLI flags and optional raw JSON.
3
3
  * Merge order (later wins): CLI defaults < --data < flag-supplied fields —
4
4
  * pinned defaults must never clobber an explicit --data payload.
5
+ *
6
+ * Merging is shallow on purpose: arrays and plain fields replace wholesale so a
7
+ * `--data` array is exactly what is sent. The one exception is the small set of
8
+ * nested option objects a resource declares (`nestedObjectKeys`, e.g. Creative
9
+ * Lab `options`/`output`): those are merged field by field across the same
10
+ * layers, so `--data '{"options":{...}}'` and `--options '{...}'` compose
11
+ * instead of the later one silently deleting the earlier one's settings.
5
12
  */
6
13
  import { readFileSync } from "node:fs";
14
+ import { UsageError } from "./errors.js";
7
15
  export function parseJsonFlag(raw, flag) {
8
16
  if (!raw)
9
17
  return {};
10
18
  const trimmed = raw.trim();
11
- const text = trimmed.startsWith("@") ? readFileSync(trimmed.slice(1), "utf8") : trimmed;
19
+ let text;
20
+ if (trimmed.startsWith("@")) {
21
+ try {
22
+ text = readFileSync(trimmed.slice(1), "utf8");
23
+ }
24
+ catch (err) {
25
+ throw new UsageError(`${flag}: cannot read ${trimmed.slice(1)}: ${err instanceof Error ? err.message : String(err)}`);
26
+ }
27
+ }
28
+ else {
29
+ text = trimmed;
30
+ }
12
31
  let parsed;
13
32
  try {
14
33
  parsed = JSON.parse(text);
15
34
  }
16
35
  catch (err) {
17
36
  const msg = err instanceof Error ? err.message : String(err);
18
- throw new Error(`invalid JSON passed to ${flag}: ${msg}`);
37
+ throw new UsageError(`invalid JSON passed to ${flag}: ${msg}`);
19
38
  }
20
39
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
21
- throw new Error(`${flag} must be a JSON object (got ${Array.isArray(parsed) ? "array" : typeof parsed})`);
40
+ throw new UsageError(`${flag} must be a JSON object (got ${Array.isArray(parsed) ? "array" : typeof parsed})`);
22
41
  }
23
42
  return parsed;
24
43
  }
@@ -39,4 +58,32 @@ export function mergePayload(...layers) {
39
58
  }
40
59
  return merged;
41
60
  }
61
+ function isPlainObject(v) {
62
+ return Boolean(v) && typeof v === "object" && !Array.isArray(v);
63
+ }
64
+ /**
65
+ * Field-level merge for the declared nested object keys, applied on top of a
66
+ * shallow `mergePayload` result. Layers are ordered weakest → strongest; within
67
+ * a key, a later layer's fields win, unspecified fields survive, and explicit
68
+ * `false`/`0`/`""` are kept. If the strongest layer that names the key is not
69
+ * an object (a deliberate replacement), the shallow result stands.
70
+ */
71
+ export function mergeNestedObjects(merged, layers, keys) {
72
+ const out = { ...merged };
73
+ for (const key of keys) {
74
+ const present = layers.filter((l) => l[key] !== undefined && l[key] !== null);
75
+ if (present.length === 0)
76
+ continue;
77
+ const strongest = present[present.length - 1];
78
+ if (!isPlainObject(strongest[key]))
79
+ continue;
80
+ const combined = {};
81
+ for (const layer of present) {
82
+ if (isPlainObject(layer[key]))
83
+ Object.assign(combined, dropNullish(layer[key]));
84
+ }
85
+ out[key] = combined;
86
+ }
87
+ return out;
88
+ }
42
89
  //# sourceMappingURL=payload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../src/internal/payload.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,UAAU,aAAa,CAAC,GAAuB,EAAE,IAAY;IACjE,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACxF,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,+BAA+B,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,MAAM,GAAG,CAAC,CAAC;IAC5G,CAAC;IACD,OAAO,MAAiC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAA8B;IACxD,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI;YAAE,SAAS;QAC5C,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAG,MAAiC;IAC/D,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,2EAA2E;QAC3E,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"payload.js","sourceRoot":"","sources":["../../src/internal/payload.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,43 @@
1
1
  /**
2
- * Poll a task endpoint until it reaches a terminal status or the deadline hits.
3
- * Backoff grows 1.5× per iteration up to a 20s cap.
2
+ * Poll a task endpoint until it reaches a terminal status or the deadline
3
+ * hits. Backoff grows 1.5× per iteration up to a 20s cap.
4
+ *
5
+ * The deadline is monotonic and binds everything: every GET is issued with a
6
+ * request timeout no larger than the remaining budget (headers *and* body),
7
+ * the cancellable sleep never overshoots it, and no request is started once it
8
+ * has passed. A response that arrives after the budget therefore cannot be
9
+ * reported as an in-time success, and the loop never spends "one more GET"
10
+ * after the caller's deadline. `--timeout 0` is the one exception by design:
11
+ * exactly one query, bounded by the transport's own read timeout, returning
12
+ * whatever status it saw.
4
13
  */
5
14
  import type { TaskEndpoint } from "../client/endpoints/base.js";
6
15
  import { type Task } from "../client/types.js";
7
16
  export interface PollOptions {
8
17
  timeoutSeconds: number;
9
18
  intervalMs: number;
10
- onTick?: (task: Task) => void;
19
+ /** Transport read timeout; each request is capped at min(remaining budget, this). */
20
+ requestTimeoutMs?: number;
21
+ onTick?: (task: Task, raw: unknown) => void;
22
+ signal?: AbortSignal;
23
+ /** Test hook: injectable clock and sleep. */
24
+ now?: () => number;
25
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
11
26
  }
12
27
  export interface PollResult {
13
- task: Task;
28
+ /**
29
+ * The last task seen. `null` only when the deadline or the abort signal hit
30
+ * before the first response arrived — the caller still knows the task id.
31
+ */
32
+ task: Task | null;
33
+ raw: unknown;
14
34
  timedOut: boolean;
35
+ polls: number;
36
+ /** True when the external signal fired before a terminal status. */
37
+ aborted: boolean;
15
38
  }
39
+ /** Accept only finite, non-negative seconds. NaN/Infinity/negative are usage errors, never "wait forever". */
40
+ export declare function parseTimeoutSeconds(raw: unknown, flag?: string): number;
41
+ export declare function sleepWithSignal(ms: number, signal?: AbortSignal): Promise<void>;
16
42
  export declare function pollUntilTerminal(endpoint: TaskEndpoint, taskId: string, opts: PollOptions): Promise<PollResult>;
17
43
  //# sourceMappingURL=poll.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../src/internal/poll.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAqB,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAElE,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,UAAU,CAAC,CAiBrB"}
1
+ {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../src/internal/poll.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,EAAoB,KAAK,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAGjE,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,6CAA6C;IAC7C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,GAAG,EAAE,OAAO,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,8GAA8G;AAC9G,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,SAAc,GAAG,MAAM,CAO5E;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAa/E;AAED,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,UAAU,CAAC,CA6DrB"}
@@ -1,27 +1,110 @@
1
1
  /**
2
- * Poll a task endpoint until it reaches a terminal status or the deadline hits.
3
- * Backoff grows 1.5× per iteration up to a 20s cap.
2
+ * Poll a task endpoint until it reaches a terminal status or the deadline
3
+ * hits. Backoff grows 1.5× per iteration up to a 20s cap.
4
+ *
5
+ * The deadline is monotonic and binds everything: every GET is issued with a
6
+ * request timeout no larger than the remaining budget (headers *and* body),
7
+ * the cancellable sleep never overshoots it, and no request is started once it
8
+ * has passed. A response that arrives after the budget therefore cannot be
9
+ * reported as an in-time success, and the loop never spends "one more GET"
10
+ * after the caller's deadline. `--timeout 0` is the one exception by design:
11
+ * exactly one query, bounded by the transport's own read timeout, returning
12
+ * whatever status it saw.
4
13
  */
5
- import { TERMINAL_STATUSES } from "../client/types.js";
14
+ import { TransportError } from "../client/transport.js";
15
+ import { isTerminalStatus } from "../client/types.js";
16
+ import { UsageError } from "./errors.js";
17
+ /** Accept only finite, non-negative seconds. NaN/Infinity/negative are usage errors, never "wait forever". */
18
+ export function parseTimeoutSeconds(raw, flag = "--timeout") {
19
+ const text = String(raw ?? "").trim();
20
+ const n = typeof raw === "number" ? raw : Number(text);
21
+ if (text === "" || !Number.isFinite(n) || n < 0) {
22
+ throw new UsageError(`${flag} must be a finite number of seconds >= 0 (got '${String(raw)}')`);
23
+ }
24
+ return n;
25
+ }
26
+ export function sleepWithSignal(ms, signal) {
27
+ return new Promise((resolve) => {
28
+ if (signal?.aborted)
29
+ return resolve();
30
+ const timer = setTimeout(() => {
31
+ signal?.removeEventListener("abort", onAbort);
32
+ resolve();
33
+ }, ms);
34
+ function onAbort() {
35
+ clearTimeout(timer);
36
+ resolve();
37
+ }
38
+ signal?.addEventListener("abort", onAbort, { once: true });
39
+ });
40
+ }
6
41
  export async function pollUntilTerminal(endpoint, taskId, opts) {
7
- const deadline = Date.now() + Math.max(0, opts.timeoutSeconds) * 1000;
42
+ const now = opts.now ?? (() => performance.now());
43
+ const sleep = opts.sleep ?? sleepWithSignal;
44
+ const single = opts.timeoutSeconds === 0;
45
+ const deadline = now() + Math.max(0, opts.timeoutSeconds) * 1000;
8
46
  const baseInterval = Math.max(250, opts.intervalMs);
9
47
  let interval = baseInterval;
10
48
  const cap = Math.max(baseInterval, 20_000);
11
- while (true) {
12
- const task = await endpoint.retrieve(taskId);
13
- opts.onTick?.(task);
14
- if (TERMINAL_STATUSES.has(task.status)) {
15
- return { task, timedOut: false };
49
+ let polls = 0;
50
+ let last = null;
51
+ const done = (timedOut, aborted) => ({
52
+ task: last?.task ?? null,
53
+ raw: last?.raw ?? null,
54
+ timedOut,
55
+ polls,
56
+ aborted,
57
+ });
58
+ for (;;) {
59
+ const remaining = deadline - now();
60
+ if (!single && polls > 0 && remaining <= 0)
61
+ return done(true, false);
62
+ if (opts.signal?.aborted)
63
+ return done(false, true);
64
+ // Bound this request by what is left of the budget (and the transport's own
65
+ // read timeout, whichever is smaller). A deadline-bound request that times
66
+ // out *is* the deadline; a read-timeout-bound one is a network failure.
67
+ const requestCap = opts.requestTimeoutMs;
68
+ let timeoutMs;
69
+ let deadlineBound = false;
70
+ if (single) {
71
+ timeoutMs = requestCap;
72
+ }
73
+ else if (requestCap === undefined || remaining <= requestCap) {
74
+ timeoutMs = Math.max(1, Math.ceil(remaining));
75
+ deadlineBound = true;
16
76
  }
17
- const remaining = deadline - Date.now();
18
- if (remaining <= 0)
19
- return { task, timedOut: true };
20
- await sleep(Math.min(interval, Math.max(remaining, 100)));
77
+ else {
78
+ timeoutMs = requestCap;
79
+ }
80
+ let res;
81
+ try {
82
+ res = await endpoint.retrieveDetailed(taskId, { signal: opts.signal, timeoutMs });
83
+ }
84
+ catch (err) {
85
+ if (opts.signal?.aborted)
86
+ return done(false, true);
87
+ if (deadlineBound && err instanceof TransportError && (err.phase === "timeout" || err.phase === "aborted")) {
88
+ return done(true, false);
89
+ }
90
+ throw err;
91
+ }
92
+ polls += 1;
93
+ last = res;
94
+ opts.onTick?.(res.task, res.raw);
95
+ if (isTerminalStatus(res.task.status))
96
+ return done(false, false);
97
+ if (opts.signal?.aborted)
98
+ return done(false, true);
99
+ if (single)
100
+ return done(true, false);
101
+ const left = deadline - now();
102
+ if (left <= 0)
103
+ return done(true, false);
104
+ await sleep(Math.max(1, Math.min(interval, left)), opts.signal);
105
+ if (opts.signal?.aborted)
106
+ return done(false, true);
21
107
  interval = Math.min(cap, Math.floor(interval * 1.5));
22
108
  }
23
109
  }
24
- function sleep(ms) {
25
- return new Promise((resolve) => setTimeout(resolve, ms));
26
- }
27
110
  //# sourceMappingURL=poll.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/internal/poll.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAa,MAAM,oBAAoB,CAAC;AAalE,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAsB,EACtB,MAAc,EACd,IAAiB;IAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACtE,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACpD,IAAI,QAAQ,GAAG,YAAY,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAE3C,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QACpB,IAAI,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QACnC,CAAC;QACD,MAAM,SAAS,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACxC,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QACpD,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1D,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
1
+ {"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/internal/poll.ts"],"names":[],"mappings":"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"}