@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.
- package/.env.example +8 -2
- package/README.md +343 -108
- package/dist/client/endpoints/animation-catalog.d.ts +37 -0
- package/dist/client/endpoints/animation-catalog.d.ts.map +1 -0
- package/dist/client/endpoints/animation-catalog.js +55 -0
- package/dist/client/endpoints/animation-catalog.js.map +1 -0
- package/dist/client/endpoints/balance.d.ts +5 -0
- package/dist/client/endpoints/balance.d.ts.map +1 -1
- package/dist/client/endpoints/balance.js +5 -1
- package/dist/client/endpoints/balance.js.map +1 -1
- package/dist/client/endpoints/base.d.ts +41 -7
- package/dist/client/endpoints/base.d.ts.map +1 -1
- package/dist/client/endpoints/base.js +61 -40
- package/dist/client/endpoints/base.js.map +1 -1
- package/dist/client/endpoints/showcases.d.ts +31 -0
- package/dist/client/endpoints/showcases.d.ts.map +1 -0
- package/dist/client/endpoints/showcases.js +49 -0
- package/dist/client/endpoints/showcases.js.map +1 -0
- package/dist/client/errors.d.ts +1 -0
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +1 -1
- package/dist/client/errors.js.map +1 -1
- package/dist/client/index.d.ts +47 -38
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +89 -120
- package/dist/client/index.js.map +1 -1
- package/dist/client/resource-registry.d.ts +97 -0
- package/dist/client/resource-registry.d.ts.map +1 -0
- package/dist/client/resource-registry.js +157 -0
- package/dist/client/resource-registry.js.map +1 -0
- package/dist/client/transport.d.ts +99 -0
- package/dist/client/transport.d.ts.map +1 -0
- package/dist/client/transport.js +320 -0
- package/dist/client/transport.js.map +1 -0
- package/dist/client/types.d.ts +17 -6
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/types.js +28 -6
- package/dist/client/types.js.map +1 -1
- package/dist/cmd/animation-catalog.d.ts +26 -0
- package/dist/cmd/animation-catalog.d.ts.map +1 -0
- package/dist/cmd/animation-catalog.js +80 -0
- package/dist/cmd/animation-catalog.js.map +1 -0
- package/dist/cmd/api.d.ts +3 -2
- package/dist/cmd/api.d.ts.map +1 -1
- package/dist/cmd/api.js +22 -8
- package/dist/cmd/api.js.map +1 -1
- package/dist/cmd/auth.d.ts.map +1 -1
- package/dist/cmd/auth.js +5 -0
- package/dist/cmd/auth.js.map +1 -1
- package/dist/cmd/balance.d.ts.map +1 -1
- package/dist/cmd/balance.js +10 -6
- package/dist/cmd/balance.js.map +1 -1
- package/dist/cmd/creative-lab.d.ts +26 -0
- package/dist/cmd/creative-lab.d.ts.map +1 -0
- package/dist/cmd/creative-lab.js +256 -0
- package/dist/cmd/creative-lab.js.map +1 -0
- package/dist/cmd/delete.d.ts.map +1 -1
- package/dist/cmd/delete.js +6 -7
- package/dist/cmd/delete.js.map +1 -1
- package/dist/cmd/doctor.d.ts +23 -0
- package/dist/cmd/doctor.d.ts.map +1 -0
- package/dist/cmd/doctor.js +61 -0
- package/dist/cmd/doctor.js.map +1 -0
- package/dist/cmd/download.d.ts +17 -0
- package/dist/cmd/download.d.ts.map +1 -0
- package/dist/cmd/download.js +436 -0
- package/dist/cmd/download.js.map +1 -0
- package/dist/cmd/inspect.d.ts +63 -0
- package/dist/cmd/inspect.d.ts.map +1 -0
- package/dist/cmd/inspect.js +179 -0
- package/dist/cmd/inspect.js.map +1 -0
- package/dist/cmd/make.d.ts +13 -3
- package/dist/cmd/make.d.ts.map +1 -1
- package/dist/cmd/make.js +240 -36
- package/dist/cmd/make.js.map +1 -1
- package/dist/cmd/mesh.d.ts +13 -0
- package/dist/cmd/mesh.d.ts.map +1 -0
- package/dist/cmd/mesh.js +67 -0
- package/dist/cmd/mesh.js.map +1 -0
- package/dist/cmd/project.d.ts +16 -0
- package/dist/cmd/project.d.ts.map +1 -0
- package/dist/cmd/project.js +136 -0
- package/dist/cmd/project.js.map +1 -0
- package/dist/cmd/resources.d.ts +5 -0
- package/dist/cmd/resources.d.ts.map +1 -1
- package/dist/cmd/resources.js +38 -10
- package/dist/cmd/resources.js.map +1 -1
- package/dist/cmd/showcases.d.ts +10 -0
- package/dist/cmd/showcases.d.ts.map +1 -0
- package/dist/cmd/showcases.js +63 -0
- package/dist/cmd/showcases.js.map +1 -0
- package/dist/cmd/slicer.d.ts +12 -0
- package/dist/cmd/slicer.d.ts.map +1 -0
- package/dist/cmd/slicer.js +46 -0
- package/dist/cmd/slicer.js.map +1 -0
- package/dist/cmd/uv-unwrap.d.ts +16 -0
- package/dist/cmd/uv-unwrap.d.ts.map +1 -0
- package/dist/cmd/uv-unwrap.js +52 -0
- package/dist/cmd/uv-unwrap.js.map +1 -0
- package/dist/index.d.ts +13 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +141 -8
- package/dist/index.js.map +1 -1
- package/dist/internal/artifacts.d.ts +97 -0
- package/dist/internal/artifacts.d.ts.map +1 -0
- package/dist/internal/artifacts.js +280 -0
- package/dist/internal/artifacts.js.map +1 -0
- package/dist/internal/atomic-file.d.ts +39 -0
- package/dist/internal/atomic-file.d.ts.map +1 -0
- package/dist/internal/atomic-file.js +160 -0
- package/dist/internal/atomic-file.js.map +1 -0
- package/dist/internal/command-helpers.d.ts +46 -0
- package/dist/internal/command-helpers.d.ts.map +1 -0
- package/dist/internal/command-helpers.js +61 -0
- package/dist/internal/command-helpers.js.map +1 -0
- package/dist/internal/config.d.ts +48 -5
- package/dist/internal/config.d.ts.map +1 -1
- package/dist/internal/config.js +95 -6
- package/dist/internal/config.js.map +1 -1
- package/dist/internal/context.d.ts +25 -0
- package/dist/internal/context.d.ts.map +1 -0
- package/dist/internal/context.js +37 -0
- package/dist/internal/context.js.map +1 -0
- package/dist/internal/credentials.d.ts +11 -0
- package/dist/internal/credentials.d.ts.map +1 -1
- package/dist/internal/credentials.js +2 -0
- package/dist/internal/credentials.js.map +1 -1
- package/dist/internal/doctor.d.ts +94 -0
- package/dist/internal/doctor.d.ts.map +1 -0
- package/dist/internal/doctor.js +280 -0
- package/dist/internal/doctor.js.map +1 -0
- package/dist/internal/download.d.ts +147 -13
- package/dist/internal/download.d.ts.map +1 -1
- package/dist/internal/download.js +735 -142
- package/dist/internal/download.js.map +1 -1
- package/dist/internal/env-file.d.ts +29 -0
- package/dist/internal/env-file.d.ts.map +1 -0
- package/dist/internal/env-file.js +95 -0
- package/dist/internal/env-file.js.map +1 -0
- package/dist/internal/errors.d.ts +74 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +173 -1
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/file-input.d.ts +52 -12
- package/dist/internal/file-input.d.ts.map +1 -1
- package/dist/internal/file-input.js +162 -33
- package/dist/internal/file-input.js.map +1 -1
- package/dist/internal/global-options.d.ts +6 -4
- package/dist/internal/global-options.d.ts.map +1 -1
- package/dist/internal/global-options.js +19 -4
- package/dist/internal/global-options.js.map +1 -1
- package/dist/internal/image-models.d.ts +9 -2
- package/dist/internal/image-models.d.ts.map +1 -1
- package/dist/internal/image-models.js +24 -12
- package/dist/internal/image-models.js.map +1 -1
- package/dist/internal/inspect.d.ts +67 -0
- package/dist/internal/inspect.d.ts.map +1 -0
- package/dist/internal/inspect.js +111 -0
- package/dist/internal/inspect.js.map +1 -0
- package/dist/internal/lock.d.ts +19 -0
- package/dist/internal/lock.d.ts.map +1 -0
- package/dist/internal/lock.js +66 -0
- package/dist/internal/lock.js.map +1 -0
- package/dist/internal/material-links.d.ts +115 -0
- package/dist/internal/material-links.d.ts.map +1 -0
- package/dist/internal/material-links.js +577 -0
- package/dist/internal/material-links.js.map +1 -0
- package/dist/internal/obj-transform.d.ts +115 -0
- package/dist/internal/obj-transform.d.ts.map +1 -0
- package/dist/internal/obj-transform.js +649 -0
- package/dist/internal/obj-transform.js.map +1 -0
- package/dist/internal/operation-store.d.ts +123 -0
- package/dist/internal/operation-store.d.ts.map +1 -0
- package/dist/internal/operation-store.js +229 -0
- package/dist/internal/operation-store.js.map +1 -0
- package/dist/internal/output.d.ts +20 -2
- package/dist/internal/output.d.ts.map +1 -1
- package/dist/internal/output.js +32 -4
- package/dist/internal/output.js.map +1 -1
- package/dist/internal/paths.d.ts +89 -0
- package/dist/internal/paths.d.ts.map +1 -0
- package/dist/internal/paths.js +168 -0
- package/dist/internal/paths.js.map +1 -0
- package/dist/internal/payload.d.ts +15 -0
- package/dist/internal/payload.d.ts.map +1 -1
- package/dist/internal/payload.js +50 -3
- package/dist/internal/payload.js.map +1 -1
- package/dist/internal/poll.d.ts +30 -4
- package/dist/internal/poll.d.ts.map +1 -1
- package/dist/internal/poll.js +99 -16
- package/dist/internal/poll.js.map +1 -1
- package/dist/internal/project-store.d.ts +197 -0
- package/dist/internal/project-store.d.ts.map +1 -0
- package/dist/internal/project-store.js +467 -0
- package/dist/internal/project-store.js.map +1 -0
- package/dist/internal/result.d.ts +50 -0
- package/dist/internal/result.d.ts.map +1 -0
- package/dist/internal/result.js +41 -0
- package/dist/internal/result.js.map +1 -0
- package/dist/internal/runtime.d.ts +35 -5
- package/dist/internal/runtime.d.ts.map +1 -1
- package/dist/internal/runtime.js +68 -18
- package/dist/internal/runtime.js.map +1 -1
- package/dist/internal/slicers.d.ts +117 -0
- package/dist/internal/slicers.d.ts.map +1 -0
- package/dist/internal/slicers.js +314 -0
- package/dist/internal/slicers.js.map +1 -0
- package/dist/internal/stream.d.ts +58 -0
- package/dist/internal/stream.d.ts.map +1 -0
- package/dist/internal/stream.js +280 -0
- package/dist/internal/stream.js.map +1 -0
- package/dist/internal/task-command.d.ts +128 -11
- package/dist/internal/task-command.d.ts.map +1 -1
- package/dist/internal/task-command.js +991 -111
- package/dist/internal/task-command.js.map +1 -1
- package/dist/internal/task-view.d.ts +56 -0
- package/dist/internal/task-view.d.ts.map +1 -0
- package/dist/internal/task-view.js +95 -0
- package/dist/internal/task-view.js.map +1 -0
- package/dist/internal/update-notifier.d.ts +5 -1
- package/dist/internal/update-notifier.d.ts.map +1 -1
- package/dist/internal/update-notifier.js +7 -3
- package/dist/internal/update-notifier.js.map +1 -1
- package/dist/root.d.ts +10 -0
- package/dist/root.d.ts.map +1 -1
- package/dist/root.js +75 -10
- package/dist/root.js.map +1 -1
- package/package.json +3 -2
- package/skills/meshy-cli/SKILL.md +140 -59
- package/dist/client/endpoints/analyze-printability.d.ts +0 -5
- package/dist/client/endpoints/analyze-printability.d.ts.map +0 -1
- package/dist/client/endpoints/analyze-printability.js +0 -7
- package/dist/client/endpoints/analyze-printability.js.map +0 -1
- package/dist/client/endpoints/animate.d.ts +0 -6
- package/dist/client/endpoints/animate.d.ts.map +0 -1
- package/dist/client/endpoints/animate.js +0 -8
- package/dist/client/endpoints/animate.js.map +0 -1
- package/dist/client/endpoints/convert.d.ts +0 -5
- package/dist/client/endpoints/convert.d.ts.map +0 -1
- package/dist/client/endpoints/convert.js +0 -7
- package/dist/client/endpoints/convert.js.map +0 -1
- package/dist/client/endpoints/image-to-3d.d.ts +0 -5
- package/dist/client/endpoints/image-to-3d.d.ts.map +0 -1
- package/dist/client/endpoints/image-to-3d.js +0 -7
- package/dist/client/endpoints/image-to-3d.js.map +0 -1
- package/dist/client/endpoints/image-to-image.d.ts +0 -5
- package/dist/client/endpoints/image-to-image.d.ts.map +0 -1
- package/dist/client/endpoints/image-to-image.js +0 -7
- package/dist/client/endpoints/image-to-image.js.map +0 -1
- package/dist/client/endpoints/multi-color-print.d.ts +0 -5
- package/dist/client/endpoints/multi-color-print.d.ts.map +0 -1
- package/dist/client/endpoints/multi-color-print.js +0 -7
- package/dist/client/endpoints/multi-color-print.js.map +0 -1
- package/dist/client/endpoints/multi-image-to-3d.d.ts +0 -5
- package/dist/client/endpoints/multi-image-to-3d.d.ts.map +0 -1
- package/dist/client/endpoints/multi-image-to-3d.js +0 -7
- package/dist/client/endpoints/multi-image-to-3d.js.map +0 -1
- package/dist/client/endpoints/remesh.d.ts +0 -5
- package/dist/client/endpoints/remesh.d.ts.map +0 -1
- package/dist/client/endpoints/remesh.js +0 -7
- package/dist/client/endpoints/remesh.js.map +0 -1
- package/dist/client/endpoints/repair-printability.d.ts +0 -5
- package/dist/client/endpoints/repair-printability.d.ts.map +0 -1
- package/dist/client/endpoints/repair-printability.js +0 -7
- package/dist/client/endpoints/repair-printability.js.map +0 -1
- package/dist/client/endpoints/resize.d.ts +0 -5
- package/dist/client/endpoints/resize.d.ts.map +0 -1
- package/dist/client/endpoints/resize.js +0 -7
- package/dist/client/endpoints/resize.js.map +0 -1
- package/dist/client/endpoints/retexture.d.ts +0 -5
- package/dist/client/endpoints/retexture.d.ts.map +0 -1
- package/dist/client/endpoints/retexture.js +0 -7
- package/dist/client/endpoints/retexture.js.map +0 -1
- package/dist/client/endpoints/rigging.d.ts +0 -6
- package/dist/client/endpoints/rigging.d.ts.map +0 -1
- package/dist/client/endpoints/rigging.js +0 -8
- package/dist/client/endpoints/rigging.js.map +0 -1
- package/dist/client/endpoints/text-to-3d.d.ts +0 -6
- package/dist/client/endpoints/text-to-3d.d.ts.map +0 -1
- package/dist/client/endpoints/text-to-3d.js +0 -8
- package/dist/client/endpoints/text-to-3d.js.map +0 -1
- package/dist/client/endpoints/text-to-image.d.ts +0 -5
- package/dist/client/endpoints/text-to-image.d.ts.map +0 -1
- package/dist/client/endpoints/text-to-image.js +0 -7
- package/dist/client/endpoints/text-to-image.js.map +0 -1
- package/dist/client/endpoints/text-to-motion.d.ts +0 -6
- package/dist/client/endpoints/text-to-motion.d.ts.map +0 -1
- package/dist/client/endpoints/text-to-motion.js +0 -8
- package/dist/client/endpoints/text-to-motion.js.map +0 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset enumeration — which files a task exposes, under stable keys.
|
|
3
|
+
*
|
|
4
|
+
* Only known response fields are walked; an unknown string URL anywhere in
|
|
5
|
+
* `result` is reported under `unknown_urls` and never downloaded. Keys are
|
|
6
|
+
* the stable selectors of `meshy download --asset` and of the v1 download
|
|
7
|
+
* manifest; the file name is derived separately and never from the key or
|
|
8
|
+
* the URL alone.
|
|
9
|
+
*
|
|
10
|
+
* Product knowledge that changes the delivery format lives here too:
|
|
11
|
+
* - lamp build: `lamp_stl` / `base_stl` are STL files, `bundle_zip` is a ZIP;
|
|
12
|
+
* - keychain / fridge-magnet build: `model_urls.obj` is a ZIP bundle
|
|
13
|
+
* (model.obj + model.mtl + texture.png), delivered as `.zip`, unextracted;
|
|
14
|
+
* - motion clips carry their format in `result.motion_format`.
|
|
15
|
+
*/
|
|
16
|
+
import { safeExtension, safeSegment } from "./paths.js";
|
|
17
|
+
const IMAGE_EXTS = new Set(["png", "jpg", "jpeg", "webp", "gif"]);
|
|
18
|
+
function isUrl(v) {
|
|
19
|
+
return typeof v === "string" && /^https?:\/\//i.test(v);
|
|
20
|
+
}
|
|
21
|
+
/** Creative Lab product from a task type such as `creative-lab-keychain-build`. */
|
|
22
|
+
export function productFromTaskType(type) {
|
|
23
|
+
if (typeof type !== "string")
|
|
24
|
+
return null;
|
|
25
|
+
const m = /^creative-lab-([a-z-]+?)-(prototype|build)$/.exec(type);
|
|
26
|
+
return m ? { product: m[1], stage: m[2] } : null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The asset a `model_urls` entry stands for. Shared with the legacy `-o`
|
|
30
|
+
* downloader so both paths name Creative Lab parts the same way (`lamp.stl`,
|
|
31
|
+
* `base.stl`, `bundle.zip`, the keychain/fridge-magnet OBJ bundle as
|
|
32
|
+
* `model.obj.zip`) instead of turning the key into an extension.
|
|
33
|
+
*/
|
|
34
|
+
export function modelAsset(fmtKey, url, product) {
|
|
35
|
+
const key = `model.${fmtKey}`;
|
|
36
|
+
const sourcePath = `model_urls.${fmtKey}`;
|
|
37
|
+
switch (fmtKey) {
|
|
38
|
+
case "lamp_stl":
|
|
39
|
+
return { key, kind: "model", url, format: "stl", containerFormat: null, modelFormat: "stl", sourcePath, filename: "lamp.stl", dependencies: [], notes: { part: "lampshade" } };
|
|
40
|
+
case "base_stl":
|
|
41
|
+
return { key, kind: "model", url, format: "stl", containerFormat: null, modelFormat: "stl", sourcePath, filename: "base.stl", dependencies: [], notes: { part: "fixture_base" } };
|
|
42
|
+
case "bundle_zip":
|
|
43
|
+
return { key, kind: "model", url, format: "zip", containerFormat: "zip", modelFormat: null, sourcePath, filename: "bundle.zip", dependencies: [], notes: { extracted: false } };
|
|
44
|
+
case "pre_remeshed_glb":
|
|
45
|
+
return { key, kind: "model", url, format: "glb", containerFormat: null, modelFormat: "glb", sourcePath, filename: "model.pre_remeshed.glb", dependencies: [] };
|
|
46
|
+
default: {
|
|
47
|
+
const ext = safeExtension(fmtKey) || null;
|
|
48
|
+
if (ext === "obj" && (product === "keychain" || product === "fridge-magnet")) {
|
|
49
|
+
return { key, kind: "model", url, format: "zip", containerFormat: "zip", modelFormat: "obj", sourcePath, filename: "model.obj.zip", dependencies: [], notes: { extracted: false, bundle_contents: ["model.obj", "model.mtl", "texture.png"] } };
|
|
50
|
+
}
|
|
51
|
+
const deps = ext === "obj" ? ["model.mtl"] : [];
|
|
52
|
+
return { key, kind: "model", url, format: ext, containerFormat: null, modelFormat: ext, sourcePath, filename: ext ? `model.${ext}` : `model.${safeSegment(fmtKey)}`, dependencies: deps };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Enumerate every downloadable asset of a task object (raw API shape).
|
|
58
|
+
* `descriptor` (when known) supplies the product for Creative Lab builds.
|
|
59
|
+
*/
|
|
60
|
+
export function enumerateAssets(task, descriptor) {
|
|
61
|
+
const assets = [];
|
|
62
|
+
const unknown = [];
|
|
63
|
+
const product = descriptor?.creativeLab?.product ?? productFromTaskType(task["type"])?.product ?? null;
|
|
64
|
+
const modelUrls = task["model_urls"];
|
|
65
|
+
if (modelUrls && typeof modelUrls === "object" && !Array.isArray(modelUrls)) {
|
|
66
|
+
for (const [fmt, url] of Object.entries(modelUrls)) {
|
|
67
|
+
if (isUrl(url))
|
|
68
|
+
assets.push(modelAsset(fmt, url, product));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// OBJ depends on MTL only when the MTL exists in this task.
|
|
72
|
+
const hasMtl = assets.some((a) => a.key === "model.mtl");
|
|
73
|
+
for (const a of assets) {
|
|
74
|
+
if (a.key === "model.obj" && a.containerFormat === null) {
|
|
75
|
+
a.dependencies = hasMtl ? ["model.mtl", ...textureKeys(task)] : [];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (isUrl(task["thumbnail_url"])) {
|
|
79
|
+
assets.push({ key: "thumbnail.primary", kind: "thumbnail", url: task["thumbnail_url"], format: "png", containerFormat: null, modelFormat: null, sourcePath: "thumbnail_url", filename: "thumbnail.png", dependencies: [] });
|
|
80
|
+
}
|
|
81
|
+
const thumbs = task["thumbnail_urls"];
|
|
82
|
+
if (thumbs && typeof thumbs === "object") {
|
|
83
|
+
if (Array.isArray(thumbs)) {
|
|
84
|
+
thumbs.forEach((url, i) => {
|
|
85
|
+
if (isUrl(url))
|
|
86
|
+
assets.push({ key: `thumbnail.${i}`, kind: "thumbnail", url, format: "png", containerFormat: null, modelFormat: null, sourcePath: `thumbnail_urls[${i}]`, filename: `thumbnail_${i}.png`, dependencies: [] });
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
for (const [view, url] of Object.entries(thumbs)) {
|
|
91
|
+
if (isUrl(url))
|
|
92
|
+
assets.push({ key: `thumbnail.${safeSegment(view)}`, kind: "thumbnail", url, format: "png", containerFormat: null, modelFormat: null, sourcePath: `thumbnail_urls.${view}`, filename: `thumbnail_${safeSegment(view)}.png`, dependencies: [], notes: { view } });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (isUrl(task["alpha_thumbnail_url"])) {
|
|
97
|
+
assets.push({ key: "thumbnail.alpha", kind: "thumbnail", url: task["alpha_thumbnail_url"], format: "png", containerFormat: null, modelFormat: null, sourcePath: "alpha_thumbnail_url", filename: "thumbnail_alpha.png", dependencies: [] });
|
|
98
|
+
}
|
|
99
|
+
const textures = task["texture_urls"];
|
|
100
|
+
if (Array.isArray(textures)) {
|
|
101
|
+
textures.forEach((set, i) => {
|
|
102
|
+
if (!set || typeof set !== "object")
|
|
103
|
+
return;
|
|
104
|
+
for (const [channel, url] of Object.entries(set)) {
|
|
105
|
+
if (isUrl(url)) {
|
|
106
|
+
assets.push({ key: `texture.${i}.${safeSegment(channel)}`, kind: "texture", url, format: "png", containerFormat: null, modelFormat: null, sourcePath: `texture_urls[${i}].${channel}`, filename: `texture_${i}_${safeSegment(channel)}.png`, dependencies: [] });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const images = task["image_urls"];
|
|
112
|
+
if (Array.isArray(images)) {
|
|
113
|
+
images.forEach((url, i) => {
|
|
114
|
+
if (isUrl(url))
|
|
115
|
+
assets.push({ key: `image.${i}`, kind: "image", url, format: null, containerFormat: null, modelFormat: null, sourcePath: `image_urls[${i}]`, filename: `image_${i}`, dependencies: [] });
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
const result = task["result"];
|
|
119
|
+
if (result && typeof result === "object" && !Array.isArray(result)) {
|
|
120
|
+
const r = result;
|
|
121
|
+
const motionFormat = typeof r["motion_format"] === "string" ? safeExtension(r["motion_format"]) : "";
|
|
122
|
+
for (const [field, value] of Object.entries(r)) {
|
|
123
|
+
if (field === "basic_animations" && value && typeof value === "object" && !Array.isArray(value)) {
|
|
124
|
+
for (const [sub, url] of Object.entries(value)) {
|
|
125
|
+
if (!isUrl(url))
|
|
126
|
+
continue;
|
|
127
|
+
const ext = extFromFieldName(sub);
|
|
128
|
+
assets.push({ key: `result.basic_animations.${safeSegment(sub)}`, kind: "animation", url, format: ext, containerFormat: null, modelFormat: ext, sourcePath: `result.basic_animations.${sub}`, filename: `${safeSegment(sub.replace(/_url$/, ""))}${ext ? `.${ext}` : ""}`, dependencies: [] });
|
|
129
|
+
}
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (!isUrl(value)) {
|
|
133
|
+
if (value && typeof value === "object")
|
|
134
|
+
collectUnknownUrls(value, `result.${field}`, unknown);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
if (field === "motion_url") {
|
|
138
|
+
const ext = motionFormat === "fbx" || motionFormat === "bvh" ? motionFormat : null;
|
|
139
|
+
assets.push({ key: "result.motion_url", kind: "motion", url: value, format: ext, containerFormat: null, modelFormat: ext, sourcePath: "result.motion_url", filename: ext ? `motion.${ext}` : "motion", dependencies: [] });
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (/^rigged_character_(glb|fbx)_url$/.test(field)) {
|
|
143
|
+
const ext = extFromFieldName(field);
|
|
144
|
+
assets.push({ key: `result.${field}`, kind: "rig", url: value, format: ext, containerFormat: null, modelFormat: ext, sourcePath: `result.${field}`, filename: `rigged_character.${ext}`, dependencies: [] });
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (/^(animation_(glb|fbx)_url|processed_[a-z0-9_]+_url)$/.test(field)) {
|
|
148
|
+
const ext = extFromFieldName(field);
|
|
149
|
+
assets.push({ key: `result.${field}`, kind: "animation", url: value, format: ext, containerFormat: null, modelFormat: ext, sourcePath: `result.${field}`, filename: `${safeSegment(field.replace(/_url$/, ""))}${ext ? `.${ext}` : ""}`, dependencies: [] });
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
unknown.push({ path: `result.${field}`, url: value });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
const printability = task["printability"];
|
|
156
|
+
if (printability && typeof printability === "object") {
|
|
157
|
+
assets.push({ key: "report.printability", kind: "report", url: null, format: "json", containerFormat: null, modelFormat: null, sourcePath: "printability", filename: "printability.json", dependencies: [], report: printability });
|
|
158
|
+
}
|
|
159
|
+
return { assets, unknown_urls: unknown, product };
|
|
160
|
+
}
|
|
161
|
+
function textureKeys(task) {
|
|
162
|
+
const keys = [];
|
|
163
|
+
const textures = task["texture_urls"];
|
|
164
|
+
if (Array.isArray(textures)) {
|
|
165
|
+
textures.forEach((set, i) => {
|
|
166
|
+
if (!set || typeof set !== "object")
|
|
167
|
+
return;
|
|
168
|
+
for (const [channel, url] of Object.entries(set)) {
|
|
169
|
+
if (isUrl(url))
|
|
170
|
+
keys.push(`texture.${i}.${safeSegment(channel)}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return keys;
|
|
175
|
+
}
|
|
176
|
+
function extFromFieldName(field) {
|
|
177
|
+
const m = /_(glb|fbx|usdz|obj|bvh|png|jpg|jpeg|webp|gltf|stl|3mf)_url$/i.exec(field);
|
|
178
|
+
if (m)
|
|
179
|
+
return m[1].toLowerCase();
|
|
180
|
+
// processed_usdz_url → usdz ; processed_armature_fbx_url → fbx handled above ; processed_animation_fps_fbx_url → fbx
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
function collectUnknownUrls(value, path, out) {
|
|
184
|
+
if (isUrl(value)) {
|
|
185
|
+
out.push({ path, url: value });
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (Array.isArray(value)) {
|
|
189
|
+
value.forEach((v, i) => collectUnknownUrls(v, `${path}[${i}]`, out));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (value && typeof value === "object") {
|
|
193
|
+
for (const [k, v] of Object.entries(value))
|
|
194
|
+
collectUnknownUrls(v, `${path}.${k}`, out);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/** 0.2.0 artifact keys → stable keys, so old scripts and internal tests keep resolving. */
|
|
198
|
+
export const LEGACY_KEY_ALIASES = {
|
|
199
|
+
thumbnail: "thumbnail.primary",
|
|
200
|
+
motion_url: "result.motion_url",
|
|
201
|
+
};
|
|
202
|
+
export function resolveAssetKey(requested, assets) {
|
|
203
|
+
const direct = assets.find((a) => a.key === requested);
|
|
204
|
+
if (direct)
|
|
205
|
+
return direct;
|
|
206
|
+
const alias = LEGACY_KEY_ALIASES[requested];
|
|
207
|
+
if (alias)
|
|
208
|
+
return assets.find((a) => a.key === alias);
|
|
209
|
+
let m = /^model_([a-z0-9_]+)$/i.exec(requested);
|
|
210
|
+
if (m)
|
|
211
|
+
return assets.find((a) => a.key === `model.${m[1]}`);
|
|
212
|
+
m = /^image_(\d+)$/.exec(requested);
|
|
213
|
+
if (m)
|
|
214
|
+
return assets.find((a) => a.key === `image.${m[1]}`);
|
|
215
|
+
m = /^texture_(\d+)_([a-z0-9_]+)$/i.exec(requested);
|
|
216
|
+
if (m)
|
|
217
|
+
return assets.find((a) => a.key === `texture.${m[1]}.${m[2]}`);
|
|
218
|
+
m = /^([a-z0-9_]+_url)$/i.exec(requested);
|
|
219
|
+
if (m)
|
|
220
|
+
return assets.find((a) => a.key === `result.${m[1]}` || a.key === `result.basic_animations.${m[1]}`);
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Apply a selector to the enumeration. Exactly one selector kind must be
|
|
225
|
+
* given; contradictory combinations are rejected by the caller (usage).
|
|
226
|
+
* With `withDependencies`, an OBJ selection pulls its MTL and textures.
|
|
227
|
+
*/
|
|
228
|
+
export function selectAssets(enumeration, sel, opts) {
|
|
229
|
+
const { assets } = enumeration;
|
|
230
|
+
let selected;
|
|
231
|
+
if (sel.all)
|
|
232
|
+
selected = assets.filter((a) => a.url !== null || a.kind === "report");
|
|
233
|
+
else if (sel.keys && sel.keys.length > 0) {
|
|
234
|
+
selected = [];
|
|
235
|
+
for (const k of sel.keys) {
|
|
236
|
+
const a = resolveAssetKey(k, assets);
|
|
237
|
+
if (!a)
|
|
238
|
+
throw new SelectionError(`no asset with key '${k}'`, assets);
|
|
239
|
+
if (!selected.includes(a))
|
|
240
|
+
selected.push(a);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
else if (sel.modelFormat) {
|
|
244
|
+
const fmt = sel.modelFormat.toLowerCase();
|
|
245
|
+
selected = assets.filter((a) => a.kind === "model" && (a.key === `model.${fmt}` || a.modelFormat === fmt || a.format === fmt));
|
|
246
|
+
if (selected.length === 0)
|
|
247
|
+
throw new SelectionError(`no model asset in format '${sel.modelFormat}'`, assets);
|
|
248
|
+
}
|
|
249
|
+
else if (sel.kind) {
|
|
250
|
+
selected = assets.filter((a) => a.kind === sel.kind);
|
|
251
|
+
if (selected.length === 0)
|
|
252
|
+
throw new SelectionError(`no asset of kind '${sel.kind}'`, assets);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
throw new SelectionError("no selector given", assets);
|
|
256
|
+
}
|
|
257
|
+
const dependencies = [];
|
|
258
|
+
const missing = [];
|
|
259
|
+
if (opts.withDependencies) {
|
|
260
|
+
for (const a of selected) {
|
|
261
|
+
for (const dep of a.dependencies) {
|
|
262
|
+
const d = assets.find((x) => x.key === dep);
|
|
263
|
+
if (!d)
|
|
264
|
+
missing.push(dep);
|
|
265
|
+
else if (!selected.includes(d) && !dependencies.includes(d))
|
|
266
|
+
dependencies.push(d);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return { selected, dependencies, missingDependencies: missing };
|
|
271
|
+
}
|
|
272
|
+
export class SelectionError extends Error {
|
|
273
|
+
candidates;
|
|
274
|
+
constructor(message, assets) {
|
|
275
|
+
super(message);
|
|
276
|
+
this.name = "SelectionError";
|
|
277
|
+
this.candidates = assets.map((a) => ({ key: a.key, kind: a.kind, format: a.format }));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/internal/artifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exclusive and atomic file publication.
|
|
3
|
+
*
|
|
4
|
+
* Two contracts:
|
|
5
|
+
* - no-overwrite (default): the target must not exist when the file lands.
|
|
6
|
+
* `exists → rename` is a race (POSIX rename replaces a concurrent
|
|
7
|
+
* winner), so the temp file is published with `link()`, which fails
|
|
8
|
+
* atomically with EEXIST. Where hard links are unsupported the fallback
|
|
9
|
+
* opens the target with O_EXCL and copies — still exclusive, no longer
|
|
10
|
+
* atomic, and reported as such.
|
|
11
|
+
* - overwrite: `rename()` over a target that is a regular file (or absent).
|
|
12
|
+
* Directories and symlinks are never replaced.
|
|
13
|
+
*
|
|
14
|
+
* Temp files always live in the target directory (same filesystem) and are
|
|
15
|
+
* removed on every failure path.
|
|
16
|
+
*/
|
|
17
|
+
import { CliError } from "./errors.js";
|
|
18
|
+
export type PublishMethod = "link" | "rename" | "copy-exclusive";
|
|
19
|
+
export interface PublishOptions {
|
|
20
|
+
overwrite?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface PublishResult {
|
|
23
|
+
path: string;
|
|
24
|
+
method: PublishMethod;
|
|
25
|
+
}
|
|
26
|
+
export declare function tempPathFor(target: string): string;
|
|
27
|
+
export declare function refuseOverwriteError(target: string): CliError;
|
|
28
|
+
/**
|
|
29
|
+
* Move a fully written temp file onto `target`.
|
|
30
|
+
* The temp file is consumed (removed) whether or not publication succeeds.
|
|
31
|
+
*/
|
|
32
|
+
export declare function publishTempFile(tmp: string, target: string, opts?: PublishOptions): PublishResult;
|
|
33
|
+
/** Serialise `value` as pretty JSON and publish it exclusively (or atomically replace with overwrite). */
|
|
34
|
+
export declare function writeJsonFile(target: string, value: unknown, opts?: PublishOptions & {
|
|
35
|
+
mode?: number;
|
|
36
|
+
}): PublishResult;
|
|
37
|
+
/** Copy an existing file to `target` under the same publish rules. */
|
|
38
|
+
export declare function copyFilePublished(source: string, target: string, opts?: PublishOptions): PublishResult;
|
|
39
|
+
//# sourceMappingURL=atomic-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-file.d.ts","sourceRoot":"","sources":["../../src/internal/atomic-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAkBH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,gBAAgB,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD;AA2BD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAM7D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,aAAa,CAyDrG;AAED,0GAA0G;AAC1G,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,cAAc,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,aAAa,CAcf;AAED,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,aAAa,CAc1G"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exclusive and atomic file publication.
|
|
3
|
+
*
|
|
4
|
+
* Two contracts:
|
|
5
|
+
* - no-overwrite (default): the target must not exist when the file lands.
|
|
6
|
+
* `exists → rename` is a race (POSIX rename replaces a concurrent
|
|
7
|
+
* winner), so the temp file is published with `link()`, which fails
|
|
8
|
+
* atomically with EEXIST. Where hard links are unsupported the fallback
|
|
9
|
+
* opens the target with O_EXCL and copies — still exclusive, no longer
|
|
10
|
+
* atomic, and reported as such.
|
|
11
|
+
* - overwrite: `rename()` over a target that is a regular file (or absent).
|
|
12
|
+
* Directories and symlinks are never replaced.
|
|
13
|
+
*
|
|
14
|
+
* Temp files always live in the target directory (same filesystem) and are
|
|
15
|
+
* removed on every failure path.
|
|
16
|
+
*/
|
|
17
|
+
import { closeSync, copyFileSync, constants as fsConstants, linkSync, lstatSync, mkdirSync, openSync, renameSync, unlinkSync, writeFileSync, writeSync, readFileSync, } from "node:fs";
|
|
18
|
+
import { randomBytes } from "node:crypto";
|
|
19
|
+
import { basename, dirname, join } from "node:path";
|
|
20
|
+
import { CliError } from "./errors.js";
|
|
21
|
+
export function tempPathFor(target) {
|
|
22
|
+
return join(dirname(target), `.${basename(target)}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`);
|
|
23
|
+
}
|
|
24
|
+
function errno(err) {
|
|
25
|
+
return err?.code;
|
|
26
|
+
}
|
|
27
|
+
function removeQuietly(path) {
|
|
28
|
+
try {
|
|
29
|
+
unlinkSync(path);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
/* already gone */
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Create the target's directory; a parent that is a file (or unwritable) is a local_io error, not an internal one. */
|
|
36
|
+
function ensureParentDir(target) {
|
|
37
|
+
try {
|
|
38
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
throw new CliError({
|
|
42
|
+
code: "local_io",
|
|
43
|
+
message: `cannot create directory ${dirname(target)}: ${err instanceof Error ? err.message : String(err)}`,
|
|
44
|
+
cause: err,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function refuseOverwriteError(target) {
|
|
49
|
+
return new CliError({
|
|
50
|
+
code: "local_io",
|
|
51
|
+
message: `refusing to overwrite existing file: ${target} (pass --overwrite, or choose another path)`,
|
|
52
|
+
recovery: { action: "choose_path", automatic: false },
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Move a fully written temp file onto `target`.
|
|
57
|
+
* The temp file is consumed (removed) whether or not publication succeeds.
|
|
58
|
+
*/
|
|
59
|
+
export function publishTempFile(tmp, target, opts = {}) {
|
|
60
|
+
try {
|
|
61
|
+
if (opts.overwrite) {
|
|
62
|
+
let existing = null;
|
|
63
|
+
try {
|
|
64
|
+
existing = lstatSync(target);
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (errno(err) !== "ENOENT")
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
if (existing && !existing.isFile()) {
|
|
71
|
+
throw new CliError({
|
|
72
|
+
code: "local_io",
|
|
73
|
+
message: `refusing to replace ${target}: it is not a regular file`,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
renameSync(tmp, target);
|
|
77
|
+
return { path: target, method: "rename" };
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
linkSync(tmp, target);
|
|
81
|
+
unlinkSync(tmp);
|
|
82
|
+
return { path: target, method: "link" };
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
const code = errno(err);
|
|
86
|
+
if (code === "EEXIST")
|
|
87
|
+
throw refuseOverwriteError(target);
|
|
88
|
+
if (code !== "EPERM" && code !== "ENOTSUP" && code !== "EXDEV" && code !== "EOPNOTSUPP" && code !== "EACCES" && code !== "EMLINK") {
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
// Hard links unavailable on this filesystem: exclusive create + copy.
|
|
92
|
+
let fd;
|
|
93
|
+
try {
|
|
94
|
+
fd = openSync(target, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL, 0o600);
|
|
95
|
+
}
|
|
96
|
+
catch (openErr) {
|
|
97
|
+
if (errno(openErr) === "EEXIST")
|
|
98
|
+
throw refuseOverwriteError(target);
|
|
99
|
+
throw openErr;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const data = readFileSync(tmp);
|
|
103
|
+
let offset = 0;
|
|
104
|
+
while (offset < data.length) {
|
|
105
|
+
offset += writeSync(fd, data, offset, data.length - offset);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
closeSync(fd);
|
|
110
|
+
}
|
|
111
|
+
unlinkSync(tmp);
|
|
112
|
+
return { path: target, method: "copy-exclusive" };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
removeQuietly(tmp);
|
|
117
|
+
if (err instanceof CliError)
|
|
118
|
+
throw err;
|
|
119
|
+
throw new CliError({
|
|
120
|
+
code: "local_io",
|
|
121
|
+
message: `failed to write ${target}: ${err instanceof Error ? err.message : String(err)}`,
|
|
122
|
+
cause: err,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Serialise `value` as pretty JSON and publish it exclusively (or atomically replace with overwrite). */
|
|
127
|
+
export function writeJsonFile(target, value, opts = {}) {
|
|
128
|
+
ensureParentDir(target);
|
|
129
|
+
const tmp = tempPathFor(target);
|
|
130
|
+
try {
|
|
131
|
+
writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, { encoding: "utf8", mode: opts.mode ?? 0o600 });
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
removeQuietly(tmp);
|
|
135
|
+
throw new CliError({
|
|
136
|
+
code: "local_io",
|
|
137
|
+
message: `failed to write ${target}: ${err instanceof Error ? err.message : String(err)}`,
|
|
138
|
+
cause: err,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return publishTempFile(tmp, target, opts);
|
|
142
|
+
}
|
|
143
|
+
/** Copy an existing file to `target` under the same publish rules. */
|
|
144
|
+
export function copyFilePublished(source, target, opts = {}) {
|
|
145
|
+
ensureParentDir(target);
|
|
146
|
+
const tmp = tempPathFor(target);
|
|
147
|
+
try {
|
|
148
|
+
copyFileSync(source, tmp);
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
removeQuietly(tmp);
|
|
152
|
+
throw new CliError({
|
|
153
|
+
code: "local_io",
|
|
154
|
+
message: `failed to copy ${source} → ${target}: ${err instanceof Error ? err.message : String(err)}`,
|
|
155
|
+
cause: err,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
return publishTempFile(tmp, target, opts);
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=atomic-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-file.js","sourceRoot":"","sources":["../../src/internal/atomic-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small shared pieces every command action uses:
|
|
3
|
+
* - open the command context (name, schema, format) so the error exit can
|
|
4
|
+
* render in the right shape;
|
|
5
|
+
* - render a result in either schema;
|
|
6
|
+
* - save the raw API JSON (--save-json) with exclusive publication.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from "commander";
|
|
9
|
+
import { type CommandContext } from "./context.js";
|
|
10
|
+
import { type Warning } from "./errors.js";
|
|
11
|
+
import { type OutputFormat } from "./output.js";
|
|
12
|
+
import { type OutputSchema } from "./result.js";
|
|
13
|
+
import { type GlobalFlags } from "./runtime.js";
|
|
14
|
+
import { type AuthorisedRoot } from "./paths.js";
|
|
15
|
+
export interface OpenedCommand extends CommandContext {
|
|
16
|
+
flags: GlobalFlags;
|
|
17
|
+
}
|
|
18
|
+
/** Read global flags, decide the schema and register the command context. */
|
|
19
|
+
export declare function openCommand(thisCmd: Command, command: string, defaultSchema: OutputSchema): OpenedCommand;
|
|
20
|
+
/**
|
|
21
|
+
* Print a command result. Legacy keeps the bare payload (and the historical
|
|
22
|
+
* `-o <file>` meaning "write the JSON there" for non-task commands); v1 prints
|
|
23
|
+
* the envelope and treats `-o` on a non-task command as a usage error that
|
|
24
|
+
* points at --save-json.
|
|
25
|
+
*/
|
|
26
|
+
export declare function emitResult(opened: OpenedCommand, legacyValue: unknown, v1Result: unknown, opts?: {
|
|
27
|
+
warnings?: Warning[];
|
|
28
|
+
legacyFile?: string | undefined;
|
|
29
|
+
format?: OutputFormat;
|
|
30
|
+
}): Promise<void>;
|
|
31
|
+
/** v1: `-o` is reserved for assets; JSON goes through --save-json. */
|
|
32
|
+
export declare function rejectOutputFlagForV1(opened: OpenedCommand, saveJson: string | undefined): void;
|
|
33
|
+
export interface SavedJson {
|
|
34
|
+
path: string;
|
|
35
|
+
bytes: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Save the raw JSON the API returned (never the CLI envelope). The file is
|
|
39
|
+
* published exclusively; an existing file is an error unless `overwrite`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function saveRawJson(target: string, raw: unknown, opts?: {
|
|
42
|
+
workspace?: string | AuthorisedRoot | undefined;
|
|
43
|
+
overwrite?: boolean;
|
|
44
|
+
cwd?: string;
|
|
45
|
+
}): SavedJson;
|
|
46
|
+
//# sourceMappingURL=command-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-helpers.d.ts","sourceRoot":"","sources":["../../src/internal/command-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAkC,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhF,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,GAAG,aAAa,CAKzG;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,OAAO,EACpB,QAAQ,EAAE,OAAO,EACjB,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAO,GAC1F,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,sEAAsE;AACtE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAQ/F;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAChG,SAAS,CAQX"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small shared pieces every command action uses:
|
|
3
|
+
* - open the command context (name, schema, format) so the error exit can
|
|
4
|
+
* render in the right shape;
|
|
5
|
+
* - render a result in either schema;
|
|
6
|
+
* - save the raw API JSON (--save-json) with exclusive publication.
|
|
7
|
+
*/
|
|
8
|
+
import { dirname, resolve as resolvePath } from "node:path";
|
|
9
|
+
import { beginCommand } from "./context.js";
|
|
10
|
+
import { UsageError } from "./errors.js";
|
|
11
|
+
import { emit, emitEnvelope } from "./output.js";
|
|
12
|
+
import { okEnvelope } from "./result.js";
|
|
13
|
+
import { readGlobalFlags, resolveSchema } from "./runtime.js";
|
|
14
|
+
import { writeJsonFile } from "./atomic-file.js";
|
|
15
|
+
import { resolveWithinRoot } from "./paths.js";
|
|
16
|
+
/** Read global flags, decide the schema and register the command context. */
|
|
17
|
+
export function openCommand(thisCmd, command, defaultSchema) {
|
|
18
|
+
const flags = readGlobalFlags(thisCmd);
|
|
19
|
+
const schema = resolveSchema(flags, defaultSchema);
|
|
20
|
+
const ctx = beginCommand({ command, schema, format: flags.format });
|
|
21
|
+
return { ...ctx, flags };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Print a command result. Legacy keeps the bare payload (and the historical
|
|
25
|
+
* `-o <file>` meaning "write the JSON there" for non-task commands); v1 prints
|
|
26
|
+
* the envelope and treats `-o` on a non-task command as a usage error that
|
|
27
|
+
* points at --save-json.
|
|
28
|
+
*/
|
|
29
|
+
export async function emitResult(opened, legacyValue, v1Result, opts = {}) {
|
|
30
|
+
const format = opts.format ?? opened.format;
|
|
31
|
+
if (opened.schema === "v1") {
|
|
32
|
+
await emitEnvelope(okEnvelope(opened.command, v1Result, opts.warnings ?? []), format);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
emit(legacyValue, { format, file: opts.legacyFile });
|
|
36
|
+
}
|
|
37
|
+
/** v1: `-o` is reserved for assets; JSON goes through --save-json. */
|
|
38
|
+
export function rejectOutputFlagForV1(opened, saveJson) {
|
|
39
|
+
if (opened.schema !== "v1")
|
|
40
|
+
return;
|
|
41
|
+
if (opened.flags.output && saveJson) {
|
|
42
|
+
throw new UsageError("--output/-o and --save-json cannot be combined on this command; -o is for assets, --save-json for the raw JSON");
|
|
43
|
+
}
|
|
44
|
+
if (opened.flags.output) {
|
|
45
|
+
throw new UsageError("this command produces JSON, not assets: use --save-json <file> instead of --output/-o under --output-schema v1");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Save the raw JSON the API returned (never the CLI envelope). The file is
|
|
50
|
+
* published exclusively; an existing file is an error unless `overwrite`.
|
|
51
|
+
*/
|
|
52
|
+
export function saveRawJson(target, raw, opts = {}) {
|
|
53
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
54
|
+
const abs = resolvePath(cwd, target);
|
|
55
|
+
const root = opts.workspace ?? dirname(abs);
|
|
56
|
+
const resolved = resolveWithinRoot(abs, root, { cwd, label: "--save-json target" });
|
|
57
|
+
const text = `${JSON.stringify(raw, null, 2)}\n`;
|
|
58
|
+
writeJsonFile(resolved.path, raw, { overwrite: opts.overwrite ?? false });
|
|
59
|
+
return { path: resolved.path, bytes: Buffer.byteLength(text, "utf8") };
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=command-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-helpers.js","sourceRoot":"","sources":["../../src/internal/command-helpers.ts"],"names":[],"mappings":"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"}
|