@meshy-ai/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +14 -0
- package/LICENSE +21 -0
- package/README.md +376 -0
- package/dist/client/endpoints/analyze-printability.d.ts +5 -0
- package/dist/client/endpoints/analyze-printability.d.ts.map +1 -0
- package/dist/client/endpoints/analyze-printability.js +7 -0
- package/dist/client/endpoints/analyze-printability.js.map +1 -0
- package/dist/client/endpoints/animate.d.ts +6 -0
- package/dist/client/endpoints/animate.d.ts.map +1 -0
- package/dist/client/endpoints/animate.js +8 -0
- package/dist/client/endpoints/animate.js.map +1 -0
- package/dist/client/endpoints/balance.d.ts +9 -0
- package/dist/client/endpoints/balance.d.ts.map +1 -0
- package/dist/client/endpoints/balance.js +27 -0
- package/dist/client/endpoints/balance.js.map +1 -0
- package/dist/client/endpoints/base.d.ts +24 -0
- package/dist/client/endpoints/base.d.ts.map +1 -0
- package/dist/client/endpoints/base.js +87 -0
- package/dist/client/endpoints/base.js.map +1 -0
- package/dist/client/endpoints/convert.d.ts +5 -0
- package/dist/client/endpoints/convert.d.ts.map +1 -0
- package/dist/client/endpoints/convert.js +7 -0
- package/dist/client/endpoints/convert.js.map +1 -0
- package/dist/client/endpoints/image-to-3d.d.ts +5 -0
- package/dist/client/endpoints/image-to-3d.d.ts.map +1 -0
- package/dist/client/endpoints/image-to-3d.js +7 -0
- package/dist/client/endpoints/image-to-3d.js.map +1 -0
- package/dist/client/endpoints/image-to-image.d.ts +5 -0
- package/dist/client/endpoints/image-to-image.d.ts.map +1 -0
- package/dist/client/endpoints/image-to-image.js +7 -0
- package/dist/client/endpoints/image-to-image.js.map +1 -0
- package/dist/client/endpoints/multi-color-print.d.ts +5 -0
- package/dist/client/endpoints/multi-color-print.d.ts.map +1 -0
- package/dist/client/endpoints/multi-color-print.js +7 -0
- package/dist/client/endpoints/multi-color-print.js.map +1 -0
- package/dist/client/endpoints/multi-image-to-3d.d.ts +5 -0
- package/dist/client/endpoints/multi-image-to-3d.d.ts.map +1 -0
- package/dist/client/endpoints/multi-image-to-3d.js +7 -0
- package/dist/client/endpoints/multi-image-to-3d.js.map +1 -0
- package/dist/client/endpoints/remesh.d.ts +5 -0
- package/dist/client/endpoints/remesh.d.ts.map +1 -0
- package/dist/client/endpoints/remesh.js +7 -0
- package/dist/client/endpoints/remesh.js.map +1 -0
- package/dist/client/endpoints/repair-printability.d.ts +5 -0
- package/dist/client/endpoints/repair-printability.d.ts.map +1 -0
- package/dist/client/endpoints/repair-printability.js +7 -0
- package/dist/client/endpoints/repair-printability.js.map +1 -0
- package/dist/client/endpoints/resize.d.ts +5 -0
- package/dist/client/endpoints/resize.d.ts.map +1 -0
- package/dist/client/endpoints/resize.js +7 -0
- package/dist/client/endpoints/resize.js.map +1 -0
- package/dist/client/endpoints/retexture.d.ts +5 -0
- package/dist/client/endpoints/retexture.d.ts.map +1 -0
- package/dist/client/endpoints/retexture.js +7 -0
- package/dist/client/endpoints/retexture.js.map +1 -0
- package/dist/client/endpoints/rigging.d.ts +6 -0
- package/dist/client/endpoints/rigging.d.ts.map +1 -0
- package/dist/client/endpoints/rigging.js +8 -0
- package/dist/client/endpoints/rigging.js.map +1 -0
- package/dist/client/endpoints/text-to-3d.d.ts +6 -0
- package/dist/client/endpoints/text-to-3d.d.ts.map +1 -0
- package/dist/client/endpoints/text-to-3d.js +8 -0
- package/dist/client/endpoints/text-to-3d.js.map +1 -0
- package/dist/client/endpoints/text-to-image.d.ts +5 -0
- package/dist/client/endpoints/text-to-image.d.ts.map +1 -0
- package/dist/client/endpoints/text-to-image.js +7 -0
- package/dist/client/endpoints/text-to-image.js.map +1 -0
- package/dist/client/errors.d.ts +23 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +82 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/index.d.ts +48 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +147 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/types.d.ts +298 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +97 -0
- package/dist/client/types.js.map +1 -0
- package/dist/cmd/analyze-printability.d.ts +8 -0
- package/dist/cmd/analyze-printability.d.ts.map +1 -0
- package/dist/cmd/analyze-printability.js +34 -0
- package/dist/cmd/analyze-printability.js.map +1 -0
- package/dist/cmd/animate.d.ts +9 -0
- package/dist/cmd/animate.d.ts.map +1 -0
- package/dist/cmd/animate.js +51 -0
- package/dist/cmd/animate.js.map +1 -0
- package/dist/cmd/api.d.ts +9 -0
- package/dist/cmd/api.d.ts.map +1 -0
- package/dist/cmd/api.js +50 -0
- package/dist/cmd/api.js.map +1 -0
- package/dist/cmd/auth.d.ts +19 -0
- package/dist/cmd/auth.d.ts.map +1 -0
- package/dist/cmd/auth.js +583 -0
- package/dist/cmd/auth.js.map +1 -0
- package/dist/cmd/balance.d.ts +6 -0
- package/dist/cmd/balance.d.ts.map +1 -0
- package/dist/cmd/balance.js +14 -0
- package/dist/cmd/balance.js.map +1 -0
- package/dist/cmd/convert.d.ts +8 -0
- package/dist/cmd/convert.d.ts.map +1 -0
- package/dist/cmd/convert.js +40 -0
- package/dist/cmd/convert.js.map +1 -0
- package/dist/cmd/delete.d.ts +7 -0
- package/dist/cmd/delete.d.ts.map +1 -0
- package/dist/cmd/delete.js +19 -0
- package/dist/cmd/delete.js.map +1 -0
- package/dist/cmd/image-to-3d.d.ts +12 -0
- package/dist/cmd/image-to-3d.d.ts.map +1 -0
- package/dist/cmd/image-to-3d.js +97 -0
- package/dist/cmd/image-to-3d.js.map +1 -0
- package/dist/cmd/image-to-image.d.ts +5 -0
- package/dist/cmd/image-to-image.d.ts.map +1 -0
- package/dist/cmd/image-to-image.js +56 -0
- package/dist/cmd/image-to-image.js.map +1 -0
- package/dist/cmd/make.d.ts +31 -0
- package/dist/cmd/make.d.ts.map +1 -0
- package/dist/cmd/make.js +195 -0
- package/dist/cmd/make.js.map +1 -0
- package/dist/cmd/multi-color-print.d.ts +6 -0
- package/dist/cmd/multi-color-print.d.ts.map +1 -0
- package/dist/cmd/multi-color-print.js +44 -0
- package/dist/cmd/multi-color-print.js.map +1 -0
- package/dist/cmd/multi-image-to-3d.d.ts +5 -0
- package/dist/cmd/multi-image-to-3d.d.ts.map +1 -0
- package/dist/cmd/multi-image-to-3d.js +72 -0
- package/dist/cmd/multi-image-to-3d.js.map +1 -0
- package/dist/cmd/remesh.d.ts +8 -0
- package/dist/cmd/remesh.d.ts.map +1 -0
- package/dist/cmd/remesh.js +49 -0
- package/dist/cmd/remesh.js.map +1 -0
- package/dist/cmd/repair-printability.d.ts +7 -0
- package/dist/cmd/repair-printability.d.ts.map +1 -0
- package/dist/cmd/repair-printability.js +32 -0
- package/dist/cmd/repair-printability.js.map +1 -0
- package/dist/cmd/resize.d.ts +8 -0
- package/dist/cmd/resize.d.ts.map +1 -0
- package/dist/cmd/resize.js +51 -0
- package/dist/cmd/resize.js.map +1 -0
- package/dist/cmd/resources.d.ts +18 -0
- package/dist/cmd/resources.d.ts.map +1 -0
- package/dist/cmd/resources.js +59 -0
- package/dist/cmd/resources.js.map +1 -0
- package/dist/cmd/retexture.d.ts +5 -0
- package/dist/cmd/retexture.d.ts.map +1 -0
- package/dist/cmd/retexture.js +64 -0
- package/dist/cmd/retexture.js.map +1 -0
- package/dist/cmd/rigging.d.ts +6 -0
- package/dist/cmd/rigging.d.ts.map +1 -0
- package/dist/cmd/rigging.js +40 -0
- package/dist/cmd/rigging.js.map +1 -0
- package/dist/cmd/text-to-3d.d.ts +14 -0
- package/dist/cmd/text-to-3d.d.ts.map +1 -0
- package/dist/cmd/text-to-3d.js +76 -0
- package/dist/cmd/text-to-3d.js.map +1 -0
- package/dist/cmd/text-to-image.d.ts +5 -0
- package/dist/cmd/text-to-image.d.ts.map +1 -0
- package/dist/cmd/text-to-image.js +53 -0
- package/dist/cmd/text-to-image.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/config.d.ts +46 -0
- package/dist/internal/config.d.ts.map +1 -0
- package/dist/internal/config.js +94 -0
- package/dist/internal/config.js.map +1 -0
- package/dist/internal/credentials.d.ts +106 -0
- package/dist/internal/credentials.d.ts.map +1 -0
- package/dist/internal/credentials.js +297 -0
- package/dist/internal/credentials.js.map +1 -0
- package/dist/internal/device-state.d.ts +45 -0
- package/dist/internal/device-state.d.ts.map +1 -0
- package/dist/internal/device-state.js +180 -0
- package/dist/internal/device-state.js.map +1 -0
- package/dist/internal/device.d.ts +79 -0
- package/dist/internal/device.d.ts.map +1 -0
- package/dist/internal/device.js +374 -0
- package/dist/internal/device.js.map +1 -0
- package/dist/internal/download.d.ts +34 -0
- package/dist/internal/download.d.ts.map +1 -0
- package/dist/internal/download.js +283 -0
- package/dist/internal/download.js.map +1 -0
- package/dist/internal/errors.d.ts +66 -0
- package/dist/internal/errors.d.ts.map +1 -0
- package/dist/internal/errors.js +169 -0
- package/dist/internal/errors.js.map +1 -0
- package/dist/internal/file-input.d.ts +24 -0
- package/dist/internal/file-input.d.ts.map +1 -0
- package/dist/internal/file-input.js +164 -0
- package/dist/internal/file-input.js.map +1 -0
- package/dist/internal/flags.d.ts +9 -0
- package/dist/internal/flags.d.ts.map +1 -0
- package/dist/internal/flags.js +31 -0
- package/dist/internal/flags.js.map +1 -0
- package/dist/internal/global-options.d.ts +16 -0
- package/dist/internal/global-options.d.ts.map +1 -0
- package/dist/internal/global-options.js +57 -0
- package/dist/internal/global-options.js.map +1 -0
- package/dist/internal/headless.d.ts +69 -0
- package/dist/internal/headless.d.ts.map +1 -0
- package/dist/internal/headless.js +101 -0
- package/dist/internal/headless.js.map +1 -0
- package/dist/internal/image-models.d.ts +20 -0
- package/dist/internal/image-models.d.ts.map +1 -0
- package/dist/internal/image-models.js +40 -0
- package/dist/internal/image-models.js.map +1 -0
- package/dist/internal/logger.d.ts +14 -0
- package/dist/internal/logger.d.ts.map +1 -0
- package/dist/internal/logger.js +42 -0
- package/dist/internal/logger.js.map +1 -0
- package/dist/internal/make-plan.d.ts +41 -0
- package/dist/internal/make-plan.d.ts.map +1 -0
- package/dist/internal/make-plan.js +67 -0
- package/dist/internal/make-plan.js.map +1 -0
- package/dist/internal/oauth.d.ts +95 -0
- package/dist/internal/oauth.d.ts.map +1 -0
- package/dist/internal/oauth.js +365 -0
- package/dist/internal/oauth.js.map +1 -0
- package/dist/internal/output.d.ts +15 -0
- package/dist/internal/output.d.ts.map +1 -0
- package/dist/internal/output.js +66 -0
- package/dist/internal/output.js.map +1 -0
- package/dist/internal/payload.d.ts +9 -0
- package/dist/internal/payload.d.ts.map +1 -0
- package/dist/internal/payload.js +42 -0
- package/dist/internal/payload.js.map +1 -0
- package/dist/internal/poll.d.ts +17 -0
- package/dist/internal/poll.d.ts.map +1 -0
- package/dist/internal/poll.js +27 -0
- package/dist/internal/poll.js.map +1 -0
- package/dist/internal/pricing.d.ts +23 -0
- package/dist/internal/pricing.d.ts.map +1 -0
- package/dist/internal/pricing.js +24 -0
- package/dist/internal/pricing.js.map +1 -0
- package/dist/internal/report.d.ts +40 -0
- package/dist/internal/report.d.ts.map +1 -0
- package/dist/internal/report.js +48 -0
- package/dist/internal/report.js.map +1 -0
- package/dist/internal/runtime.d.ts +66 -0
- package/dist/internal/runtime.d.ts.map +1 -0
- package/dist/internal/runtime.js +160 -0
- package/dist/internal/runtime.js.map +1 -0
- package/dist/internal/task-command.d.ts +39 -0
- package/dist/internal/task-command.d.ts.map +1 -0
- package/dist/internal/task-command.js +189 -0
- package/dist/internal/task-command.js.map +1 -0
- package/dist/internal/update-notifier.d.ts +160 -0
- package/dist/internal/update-notifier.d.ts.map +1 -0
- package/dist/internal/update-notifier.js +445 -0
- package/dist/internal/update-notifier.js.map +1 -0
- package/dist/internal/user-agent.d.ts +6 -0
- package/dist/internal/user-agent.d.ts.map +1 -0
- package/dist/internal/user-agent.js +7 -0
- package/dist/internal/user-agent.js.map +1 -0
- package/dist/internal/version.d.ts +2 -0
- package/dist/internal/version.d.ts.map +1 -0
- package/dist/internal/version.js +11 -0
- package/dist/internal/version.js.map +1 -0
- package/dist/root.d.ts +13 -0
- package/dist/root.d.ts.map +1 -0
- package/dist/root.js +148 -0
- package/dist/root.js.map +1 -0
- package/package.json +65 -0
- package/skills/meshy-cli/SKILL.md +99 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 Device Authorization Grant (RFC 8628) helpers.
|
|
3
|
+
*
|
|
4
|
+
* Implements:
|
|
5
|
+
* - deviceAuthorization(): POST /oauth/device_authorization
|
|
6
|
+
* - pollDeviceToken(): polling loop for /oauth/token with device_code grant
|
|
7
|
+
* - ensureRequestedScopesGranted(): scope verification
|
|
8
|
+
*/
|
|
9
|
+
import { HintedError } from "./errors.js";
|
|
10
|
+
import { USER_AGENT } from "./user-agent.js";
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Error classes
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/**
|
|
15
|
+
* Thrown when the /oauth/device_authorization endpoint returns 404.
|
|
16
|
+
* Indicates the meshyd deployment does not support device flow yet.
|
|
17
|
+
*/
|
|
18
|
+
export class DeviceFlowNotSupportedError extends HintedError {
|
|
19
|
+
constructor() {
|
|
20
|
+
super({
|
|
21
|
+
// Do NOT suggest --manual here: a meshyd old enough to lack
|
|
22
|
+
// device_authorization also lacks the OOB display branch that --manual
|
|
23
|
+
// depends on, so that flag would fail too. Only safe options are to
|
|
24
|
+
// wait for the backend deployment or use an API key.
|
|
25
|
+
message: "This Meshy API host does not support device login yet — retry after backend deployment or use an API key (meshy auth login --with-key).",
|
|
26
|
+
code: "device_flow_not_supported",
|
|
27
|
+
hint: "Run: meshy auth login --with-key msy_...",
|
|
28
|
+
});
|
|
29
|
+
this.name = "DeviceFlowNotSupportedError";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* An error from the device token polling endpoint that carries the machine
|
|
34
|
+
* error code from the OAuth response body.
|
|
35
|
+
*/
|
|
36
|
+
export class DeviceFlowError extends HintedError {
|
|
37
|
+
oauthErrorCode;
|
|
38
|
+
constructor(params) {
|
|
39
|
+
super({ message: params.message, code: params.code, hint: params.hint });
|
|
40
|
+
this.name = "DeviceFlowError";
|
|
41
|
+
this.oauthErrorCode = params.oauthErrorCode;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Device authorization request
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
48
|
+
/**
|
|
49
|
+
* POST /oauth/device_authorization to start a device flow.
|
|
50
|
+
*
|
|
51
|
+
* @throws DeviceFlowNotSupportedError on 404
|
|
52
|
+
* @throws HintedError on other non-200 responses
|
|
53
|
+
*/
|
|
54
|
+
export async function deviceAuthorization(baseUrlV1, scope) {
|
|
55
|
+
const url = `${baseUrlV1}/oauth/device_authorization`;
|
|
56
|
+
let res;
|
|
57
|
+
try {
|
|
58
|
+
res = await fetch(url, {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: {
|
|
61
|
+
"Content-Type": "application/json",
|
|
62
|
+
Accept: "application/json",
|
|
63
|
+
"User-Agent": USER_AGENT,
|
|
64
|
+
},
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
client_id: "meshy-cli",
|
|
67
|
+
...(scope ? { scope } : {}),
|
|
68
|
+
}),
|
|
69
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
throw new HintedError({
|
|
74
|
+
message: `Network error contacting device authorization endpoint: ${err instanceof Error ? err.message : String(err)}`,
|
|
75
|
+
code: "oauth_network",
|
|
76
|
+
hint: "Run: meshy auth login --with-key msy_...",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (res.status === 404) {
|
|
80
|
+
throw new DeviceFlowNotSupportedError();
|
|
81
|
+
}
|
|
82
|
+
let parsed;
|
|
83
|
+
try {
|
|
84
|
+
parsed = await res.json();
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
throw new HintedError({
|
|
88
|
+
message: `Device authorization endpoint returned non-JSON (status ${res.status})`,
|
|
89
|
+
code: "oauth_bad_response",
|
|
90
|
+
hint: "Run: meshy auth login",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (!res.ok) {
|
|
94
|
+
const obj = parsed;
|
|
95
|
+
const msg = (typeof obj["error_description"] === "string" ? obj["error_description"] : undefined) ??
|
|
96
|
+
(typeof obj["message"] === "string" ? obj["message"] : undefined) ??
|
|
97
|
+
(typeof obj["error"] === "string" ? obj["error"] : undefined) ??
|
|
98
|
+
`Device authorization endpoint error (status ${res.status})`;
|
|
99
|
+
throw new HintedError({
|
|
100
|
+
message: msg,
|
|
101
|
+
code: "oauth_device_error",
|
|
102
|
+
hint: "Run: meshy auth login",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const obj = parsed;
|
|
106
|
+
// Validate required fields.
|
|
107
|
+
if (typeof obj["device_code"] !== "string" || !obj["device_code"]) {
|
|
108
|
+
throw new HintedError({
|
|
109
|
+
message: "Device authorization response missing device_code",
|
|
110
|
+
code: "oauth_bad_response",
|
|
111
|
+
hint: "Run: meshy auth login",
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (typeof obj["user_code"] !== "string" || !obj["user_code"]) {
|
|
115
|
+
throw new HintedError({
|
|
116
|
+
message: "Device authorization response missing user_code",
|
|
117
|
+
code: "oauth_bad_response",
|
|
118
|
+
hint: "Run: meshy auth login",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (typeof obj["verification_uri"] !== "string" || !obj["verification_uri"]) {
|
|
122
|
+
throw new HintedError({
|
|
123
|
+
message: "Device authorization response missing verification_uri",
|
|
124
|
+
code: "oauth_bad_response",
|
|
125
|
+
hint: "Run: meshy auth login",
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const rawInterval = typeof obj["interval"] === "number" ? obj["interval"] : 5;
|
|
129
|
+
const interval = rawInterval < 1 ? 5 : rawInterval;
|
|
130
|
+
const expiresIn = typeof obj["expires_in"] === "number" && obj["expires_in"] > 0 ? obj["expires_in"] : 600;
|
|
131
|
+
return {
|
|
132
|
+
device_code: obj["device_code"],
|
|
133
|
+
user_code: obj["user_code"],
|
|
134
|
+
verification_uri: obj["verification_uri"],
|
|
135
|
+
verification_uri_complete: typeof obj["verification_uri_complete"] === "string"
|
|
136
|
+
? obj["verification_uri_complete"]
|
|
137
|
+
: obj["verification_uri"],
|
|
138
|
+
expires_in: expiresIn,
|
|
139
|
+
interval,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Device token polling
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
/** Sleep for `ms` milliseconds. */
|
|
146
|
+
function sleep(ms) {
|
|
147
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* POST /oauth/token with grant_type=device_code once and return the result.
|
|
151
|
+
* Returns the parsed body (success or error) and the HTTP status.
|
|
152
|
+
*/
|
|
153
|
+
async function deviceTokenOnce(baseUrlV1, deviceCode) {
|
|
154
|
+
const url = `${baseUrlV1}/oauth/token`;
|
|
155
|
+
let res;
|
|
156
|
+
try {
|
|
157
|
+
res = await fetch(url, {
|
|
158
|
+
method: "POST",
|
|
159
|
+
headers: {
|
|
160
|
+
"Content-Type": "application/json",
|
|
161
|
+
Accept: "application/json",
|
|
162
|
+
"User-Agent": USER_AGENT,
|
|
163
|
+
},
|
|
164
|
+
body: JSON.stringify({
|
|
165
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
166
|
+
device_code: deviceCode,
|
|
167
|
+
client_id: "meshy-cli",
|
|
168
|
+
}),
|
|
169
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
throw new HintedError({
|
|
174
|
+
message: `Network error polling device token: ${err instanceof Error ? err.message : String(err)}`,
|
|
175
|
+
code: "oauth_network",
|
|
176
|
+
hint: "Run: meshy auth login",
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
let body;
|
|
180
|
+
try {
|
|
181
|
+
body = (await res.json());
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
throw new HintedError({
|
|
185
|
+
message: `Device token endpoint returned non-JSON (status ${res.status})`,
|
|
186
|
+
code: "oauth_bad_response",
|
|
187
|
+
hint: "Run: meshy auth login",
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return { status: res.status, body };
|
|
191
|
+
}
|
|
192
|
+
/** Validate and extract a TokenResponse from a successful device token body. */
|
|
193
|
+
function extractTokenResponse(body) {
|
|
194
|
+
if (typeof body["access_token"] !== "string" || !body["access_token"]) {
|
|
195
|
+
throw new HintedError({
|
|
196
|
+
message: "Device token response missing access_token",
|
|
197
|
+
code: "oauth_bad_response",
|
|
198
|
+
hint: "Run: meshy auth login",
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
if (typeof body["token_type"] !== "string" ||
|
|
202
|
+
body["token_type"].toLowerCase() !== "bearer") {
|
|
203
|
+
throw new HintedError({
|
|
204
|
+
message: `Device token response has unexpected token_type: ${JSON.stringify(body["token_type"])}`,
|
|
205
|
+
code: "oauth_bad_response",
|
|
206
|
+
hint: "Run: meshy auth login",
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
const expiresIn = body["expires_in"];
|
|
210
|
+
if (typeof expiresIn !== "number" || !Number.isFinite(expiresIn) || expiresIn <= 0) {
|
|
211
|
+
throw new HintedError({
|
|
212
|
+
message: `Device token response has invalid expires_in: ${JSON.stringify(expiresIn)}`,
|
|
213
|
+
code: "oauth_bad_response",
|
|
214
|
+
hint: "Run: meshy auth login",
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
if (typeof body["refresh_token"] !== "string" || !body["refresh_token"]) {
|
|
218
|
+
throw new HintedError({
|
|
219
|
+
message: "Device token response missing refresh_token",
|
|
220
|
+
code: "oauth_bad_response",
|
|
221
|
+
hint: "Run: meshy auth login",
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
access_token: body["access_token"],
|
|
226
|
+
token_type: body["token_type"],
|
|
227
|
+
expires_in: expiresIn,
|
|
228
|
+
refresh_token: body["refresh_token"],
|
|
229
|
+
scope: typeof body["scope"] === "string" ? body["scope"] : undefined,
|
|
230
|
+
user_id: typeof body["user_id"] === "string" ? body["user_id"] : undefined,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
const MAX_INTERVAL_S = 60;
|
|
234
|
+
/**
|
|
235
|
+
* Poll the device token endpoint until the user approves, denies, or the
|
|
236
|
+
* token expires.
|
|
237
|
+
*
|
|
238
|
+
* Implements RFC 8628 §3.5 polling semantics:
|
|
239
|
+
* - authorization_pending → wait current interval
|
|
240
|
+
* - slow_down or HTTP 429 → interval += 5s (capped at 60s), wait
|
|
241
|
+
* - expired_token or deadline exceeded → throw oauth_timeout
|
|
242
|
+
* - access_denied → throw AUTH error
|
|
243
|
+
* - invalid_grant → throw AUTH error (already consumed)
|
|
244
|
+
* - 5xx / network → retry up to 3 consecutive, then throw
|
|
245
|
+
*/
|
|
246
|
+
export async function pollDeviceToken(baseUrlV1, deviceCode, opts) {
|
|
247
|
+
const deadline = opts.deadline ?? Date.now() + opts.expiresIn * 1000;
|
|
248
|
+
let intervalMs = (opts.interval < 1 ? 5 : opts.interval) * 1000;
|
|
249
|
+
/** Consecutive network-level errors (thrown by deviceTokenOnce). */
|
|
250
|
+
let consecutiveNetworkErrors = 0;
|
|
251
|
+
/** Consecutive 5xx HTTP errors. */
|
|
252
|
+
let consecutive5xxErrors = 0;
|
|
253
|
+
for (;;) {
|
|
254
|
+
if (Date.now() >= deadline) {
|
|
255
|
+
throw new HintedError({
|
|
256
|
+
message: "Device flow timed out waiting for authorization. Run: meshy auth login",
|
|
257
|
+
code: "oauth_timeout",
|
|
258
|
+
hint: "Run: meshy auth login",
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
let result;
|
|
262
|
+
try {
|
|
263
|
+
result = await deviceTokenOnce(baseUrlV1, deviceCode);
|
|
264
|
+
consecutiveNetworkErrors = 0;
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
consecutiveNetworkErrors++;
|
|
268
|
+
if (consecutiveNetworkErrors >= 3) {
|
|
269
|
+
throw err;
|
|
270
|
+
}
|
|
271
|
+
await sleep(intervalMs);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
const { status, body } = result;
|
|
275
|
+
// Success.
|
|
276
|
+
if (status === 200) {
|
|
277
|
+
consecutive5xxErrors = 0;
|
|
278
|
+
return extractTokenResponse(body);
|
|
279
|
+
}
|
|
280
|
+
// Parse the OAuth error code from the body.
|
|
281
|
+
const oauthError = typeof body["error"] === "string" ? body["error"] : undefined;
|
|
282
|
+
const humanMsg = (typeof body["error_description"] === "string" ? body["error_description"] : undefined) ??
|
|
283
|
+
(typeof body["message"] === "string" ? body["message"] : undefined) ??
|
|
284
|
+
oauthError ??
|
|
285
|
+
`Device token error (status ${status})`;
|
|
286
|
+
// Handle specific OAuth error codes.
|
|
287
|
+
if (oauthError === "authorization_pending") {
|
|
288
|
+
consecutive5xxErrors = 0;
|
|
289
|
+
opts.onPending?.();
|
|
290
|
+
await sleep(intervalMs);
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (oauthError === "slow_down" || status === 429) {
|
|
294
|
+
consecutive5xxErrors = 0;
|
|
295
|
+
intervalMs = Math.min(intervalMs + 5000, MAX_INTERVAL_S * 1000);
|
|
296
|
+
await sleep(intervalMs);
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (oauthError === "expired_token") {
|
|
300
|
+
// Use DeviceFlowError so oauthErrorCode:"expired_token" survives to
|
|
301
|
+
// --json output, letting machine consumers distinguish this from
|
|
302
|
+
// access_denied / invalid_grant. Exit code stays TIMED_OUT (the
|
|
303
|
+
// "oauth_timeout" code maps there in exitCodeFor).
|
|
304
|
+
throw new DeviceFlowError({
|
|
305
|
+
message: "Device flow authorization code expired. Run: meshy auth login",
|
|
306
|
+
code: "oauth_timeout",
|
|
307
|
+
oauthErrorCode: "expired_token",
|
|
308
|
+
hint: "Run: meshy auth login",
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
if (oauthError === "access_denied") {
|
|
312
|
+
throw new DeviceFlowError({
|
|
313
|
+
message: "Device login was denied by the user.",
|
|
314
|
+
code: "oauth_access_denied",
|
|
315
|
+
oauthErrorCode: "access_denied",
|
|
316
|
+
hint: "Run: meshy auth login",
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
if (oauthError === "invalid_grant") {
|
|
320
|
+
throw new DeviceFlowError({
|
|
321
|
+
message: "Device flow already consumed or invalid; restart login.",
|
|
322
|
+
code: "oauth_invalid_grant",
|
|
323
|
+
oauthErrorCode: "invalid_grant",
|
|
324
|
+
hint: "Run: meshy auth login",
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
// 5xx errors: retry up to 3 consecutive, then surface.
|
|
328
|
+
if (status >= 500) {
|
|
329
|
+
consecutive5xxErrors++;
|
|
330
|
+
if (consecutive5xxErrors >= 3) {
|
|
331
|
+
throw new HintedError({
|
|
332
|
+
message: `Device token server error (status ${status}): ${humanMsg}`,
|
|
333
|
+
code: "oauth_server_error",
|
|
334
|
+
hint: "Run: meshy auth login",
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
await sleep(intervalMs);
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
// Other 400-level errors.
|
|
341
|
+
throw new HintedError({
|
|
342
|
+
message: humanMsg,
|
|
343
|
+
code: "oauth_device_error",
|
|
344
|
+
hint: "Run: meshy auth login",
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// ---------------------------------------------------------------------------
|
|
349
|
+
// Scope verification
|
|
350
|
+
// ---------------------------------------------------------------------------
|
|
351
|
+
/**
|
|
352
|
+
* Verify that all requested scopes were granted.
|
|
353
|
+
*
|
|
354
|
+
* Both `requested` and `granted` are space-separated scope strings.
|
|
355
|
+
* Today both are "" — this trivially passes. Implemented generically for
|
|
356
|
+
* future use.
|
|
357
|
+
*
|
|
358
|
+
* @throws HintedError listing missing scopes if any requested scope is absent.
|
|
359
|
+
*/
|
|
360
|
+
export function ensureRequestedScopesGranted(requested, granted) {
|
|
361
|
+
const requestedScopes = requested.split(/\s+/).filter(Boolean);
|
|
362
|
+
if (requestedScopes.length === 0)
|
|
363
|
+
return;
|
|
364
|
+
const grantedScopes = new Set((granted ?? "").split(/\s+/).filter(Boolean));
|
|
365
|
+
const missing = requestedScopes.filter((s) => !grantedScopes.has(s));
|
|
366
|
+
if (missing.length > 0) {
|
|
367
|
+
throw new HintedError({
|
|
368
|
+
message: `The following requested scopes were not granted: ${missing.join(", ")}`,
|
|
369
|
+
code: "oauth_scope_denied",
|
|
370
|
+
hint: "Run: meshy auth login",
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/internal/device.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Download a completed task's artifacts to the local filesystem.
|
|
3
|
+
*
|
|
4
|
+
* Two target shapes:
|
|
5
|
+
* 1. File path (e.g. `character/front.jpeg`) — used when the task has a
|
|
6
|
+
* single downloadable artifact (most 2D image tasks). The Content-Type
|
|
7
|
+
* of the HTTP response is authoritative; if the user-supplied extension
|
|
8
|
+
* disagrees, the file is saved with the correct extension instead.
|
|
9
|
+
* 2. Directory path (anything without a recognized file extension) — used
|
|
10
|
+
* when the task emits multiple artifacts (3D models, thumbnails,
|
|
11
|
+
* textures, animation outputs). Each artifact is named after its role
|
|
12
|
+
* (model.glb, thumbnail.png, texture_0_base_color.png, ...).
|
|
13
|
+
*
|
|
14
|
+
* A `meta.json` alongside the artifacts records the full task response plus
|
|
15
|
+
* the saved paths for later reference.
|
|
16
|
+
*/
|
|
17
|
+
import type { Task } from "../client/types.js";
|
|
18
|
+
export interface Artifact {
|
|
19
|
+
/** Stable slot name ("model_glb", "image_0", "texture_0_base_color", ...) */
|
|
20
|
+
key: string;
|
|
21
|
+
/** Source URL (presigned). */
|
|
22
|
+
url: string;
|
|
23
|
+
/** Expected extension inferred from the slot name (no dot, may be empty). */
|
|
24
|
+
preferredExt: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function enumerateArtifacts(task: Task): Artifact[];
|
|
27
|
+
/** Heuristic: does this look like a file path (has an extension) or a dir? */
|
|
28
|
+
export declare function looksLikeFile(path: string): boolean;
|
|
29
|
+
export interface DownloadResult {
|
|
30
|
+
savedFiles: string[];
|
|
31
|
+
metadataPath: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function downloadArtifacts(task: Task, outputPath: string, resource: string): Promise<DownloadResult>;
|
|
34
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/internal/download.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAO/C,MAAM,WAAW,QAAQ;IACvB,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,EAAE,CA4CzD;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,CAAC,CA6DzB"}
|