run402 1.54.0 → 1.54.2
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/lib/agent.mjs +4 -2
- package/lib/ai.mjs +24 -10
- package/lib/allowance.mjs +53 -15
- package/lib/apps.mjs +13 -11
- package/lib/argparse.mjs +147 -0
- package/lib/auth.mjs +24 -9
- package/lib/billing.mjs +33 -17
- package/lib/blob.mjs +58 -26
- package/lib/cdn.mjs +3 -4
- package/lib/config.mjs +32 -8
- package/lib/contracts.mjs +38 -21
- package/lib/deploy-v2.mjs +38 -23
- package/lib/deploy.mjs +43 -44
- package/lib/domains.mjs +24 -8
- package/lib/email.mjs +38 -29
- package/lib/functions.mjs +77 -34
- package/lib/image.mjs +8 -2
- package/lib/message.mjs +4 -2
- package/lib/projects.mjs +115 -40
- package/lib/sdk-errors.mjs +66 -10
- package/lib/secrets.mjs +14 -8
- package/lib/sender-domain.mjs +11 -5
- package/lib/sites.mjs +9 -7
- package/lib/status.mjs +5 -2
- package/lib/subdomains.mjs +26 -11
- package/lib/tier.mjs +8 -2
- package/lib/webhooks.mjs +27 -13
- package/package.json +1 -1
- package/sdk/dist/index.d.ts +1 -0
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +5 -0
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/namespaces/auth.d.ts +7 -0
- package/sdk/dist/namespaces/auth.d.ts.map +1 -1
- package/sdk/dist/namespaces/auth.js +24 -0
- package/sdk/dist/namespaces/auth.js.map +1 -1
- package/sdk/dist/namespaces/billing.d.ts +3 -0
- package/sdk/dist/namespaces/billing.d.ts.map +1 -1
- package/sdk/dist/namespaces/billing.js +6 -0
- package/sdk/dist/namespaces/billing.js.map +1 -1
- package/sdk/dist/namespaces/contracts.d.ts +3 -0
- package/sdk/dist/namespaces/contracts.d.ts.map +1 -1
- package/sdk/dist/namespaces/contracts.js +6 -0
- package/sdk/dist/namespaces/contracts.js.map +1 -1
- package/sdk/dist/namespaces/email.d.ts +4 -0
- package/sdk/dist/namespaces/email.d.ts.map +1 -1
- package/sdk/dist/namespaces/email.js +8 -0
- package/sdk/dist/namespaces/email.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +14 -0
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +72 -0
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/sender-domain.d.ts +2 -0
- package/sdk/dist/namespaces/sender-domain.d.ts.map +1 -1
- package/sdk/dist/namespaces/sender-domain.js +4 -0
- package/sdk/dist/namespaces/sender-domain.js.map +1 -1
- package/sdk/dist/scoped.d.ts +8 -1
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +21 -0
- package/sdk/dist/scoped.js.map +1 -1
- package/core-dist/wallet-auth.js +0 -62
- package/core-dist/wallet.js +0 -25
- package/sdk/core-dist/wallet-auth.js +0 -62
- package/sdk/core-dist/wallet.js +0 -25
package/lib/domains.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolveProjectId } from "./config.mjs";
|
|
2
2
|
import { getSdk } from "./sdk.mjs";
|
|
3
|
-
import { reportSdkError } from "./sdk-errors.mjs";
|
|
3
|
+
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
4
4
|
|
|
5
5
|
const HELP = `run402 domains — Manage custom domains
|
|
6
6
|
|
|
@@ -40,7 +40,13 @@ async function add(args) {
|
|
|
40
40
|
const { project, rest } = parseProjectFlag(args);
|
|
41
41
|
const domain = rest[0];
|
|
42
42
|
const subdomainName = rest[1];
|
|
43
|
-
if (!domain || !subdomainName) {
|
|
43
|
+
if (!domain || !subdomainName) {
|
|
44
|
+
fail({
|
|
45
|
+
code: "BAD_USAGE",
|
|
46
|
+
message: "Missing <domain> and/or <subdomain_name>.",
|
|
47
|
+
hint: "run402 domains add <domain> <subdomain_name> [--project <id>]",
|
|
48
|
+
});
|
|
49
|
+
}
|
|
44
50
|
const projectId = resolveProjectId(project);
|
|
45
51
|
try {
|
|
46
52
|
const data = await getSdk().domains.add(projectId, domain, subdomainName);
|
|
@@ -63,7 +69,13 @@ async function list(projectIdArg) {
|
|
|
63
69
|
async function status(args) {
|
|
64
70
|
const { project, rest } = parseProjectFlag(args);
|
|
65
71
|
const domain = rest[0];
|
|
66
|
-
if (!domain) {
|
|
72
|
+
if (!domain) {
|
|
73
|
+
fail({
|
|
74
|
+
code: "BAD_USAGE",
|
|
75
|
+
message: "Missing <domain>.",
|
|
76
|
+
hint: "run402 domains status <domain> [--project <id>]",
|
|
77
|
+
});
|
|
78
|
+
}
|
|
67
79
|
const projectId = resolveProjectId(project);
|
|
68
80
|
try {
|
|
69
81
|
const data = await getSdk().domains.status(projectId, domain);
|
|
@@ -76,15 +88,19 @@ async function status(args) {
|
|
|
76
88
|
async function deleteDomain(args) {
|
|
77
89
|
const { project, rest } = parseProjectFlag(args);
|
|
78
90
|
const domain = rest.find((a) => !a.startsWith("--"));
|
|
79
|
-
if (!domain) {
|
|
91
|
+
if (!domain) {
|
|
92
|
+
fail({
|
|
93
|
+
code: "BAD_USAGE",
|
|
94
|
+
message: "Missing <domain>.",
|
|
95
|
+
hint: "run402 domains delete <domain> --confirm [--project <id>]",
|
|
96
|
+
});
|
|
97
|
+
}
|
|
80
98
|
if (!Array.isArray(args) || !args.includes("--confirm")) {
|
|
81
|
-
|
|
82
|
-
status: "error",
|
|
99
|
+
fail({
|
|
83
100
|
code: "CONFIRMATION_REQUIRED",
|
|
84
101
|
message: `Destructive: releasing custom domain '${domain}' detaches it from this project and clears its DNS/SSL configuration. This is irreversible. Re-run with --confirm to proceed.`,
|
|
85
102
|
details: { domain },
|
|
86
|
-
})
|
|
87
|
-
process.exit(1);
|
|
103
|
+
});
|
|
88
104
|
}
|
|
89
105
|
const projectId = resolveProjectId(project);
|
|
90
106
|
try {
|
package/lib/email.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolveProjectId } from "./config.mjs";
|
|
2
2
|
import { getSdk } from "./sdk.mjs";
|
|
3
|
-
import { reportSdkError } from "./sdk-errors.mjs";
|
|
3
|
+
import { reportSdkError, fail, parseFlagJson } from "./sdk-errors.mjs";
|
|
4
4
|
|
|
5
5
|
const HELP = `run402 email — Send emails from your project
|
|
6
6
|
|
|
@@ -130,14 +130,12 @@ function parseVars(args) {
|
|
|
130
130
|
for (let i = 0; i < args.length; i++) {
|
|
131
131
|
if (args[i] === "--vars" && args[i + 1]) {
|
|
132
132
|
const raw = args[++i];
|
|
133
|
-
|
|
134
|
-
try { parsed = JSON.parse(raw); } catch {
|
|
135
|
-
console.error(JSON.stringify({ status: "error", message: "Invalid JSON for --vars. Expected a JSON object, e.g. '{\"key\":\"value\"}'" }));
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
133
|
+
const parsed = parseFlagJson("--vars", raw);
|
|
138
134
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
139
|
-
|
|
140
|
-
|
|
135
|
+
fail({
|
|
136
|
+
code: "BAD_USAGE",
|
|
137
|
+
message: "--vars must be a JSON object, e.g. '{\"key\":\"value\"}'",
|
|
138
|
+
});
|
|
141
139
|
}
|
|
142
140
|
for (const [k, v] of Object.entries(parsed)) vars[k] = typeof v === "string" ? v : String(v);
|
|
143
141
|
}
|
|
@@ -161,8 +159,11 @@ async function create(args) {
|
|
|
161
159
|
}
|
|
162
160
|
const projectId = resolveProjectId(projectOpt);
|
|
163
161
|
if (!slug) {
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
fail({
|
|
163
|
+
code: "BAD_USAGE",
|
|
164
|
+
message: "Missing slug.",
|
|
165
|
+
hint: "run402 email create <slug>",
|
|
166
|
+
});
|
|
166
167
|
}
|
|
167
168
|
|
|
168
169
|
try {
|
|
@@ -184,8 +185,7 @@ async function send(args) {
|
|
|
184
185
|
const variables = parseVars(args);
|
|
185
186
|
|
|
186
187
|
if (!to) {
|
|
187
|
-
|
|
188
|
-
process.exit(1);
|
|
188
|
+
fail({ code: "BAD_USAGE", message: "Missing --to <email>" });
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
try {
|
|
@@ -228,8 +228,11 @@ async function get(args) {
|
|
|
228
228
|
}
|
|
229
229
|
const projectId = resolveProjectId(projectOpt);
|
|
230
230
|
if (!messageId) {
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
fail({
|
|
232
|
+
code: "BAD_USAGE",
|
|
233
|
+
message: "Missing message_id.",
|
|
234
|
+
hint: "run402 email get <message_id>",
|
|
235
|
+
});
|
|
233
236
|
}
|
|
234
237
|
try {
|
|
235
238
|
const data = await getSdk().email.get(projectId, messageId);
|
|
@@ -250,8 +253,11 @@ async function getRaw(args) {
|
|
|
250
253
|
}
|
|
251
254
|
const projectId = resolveProjectId(projectOpt);
|
|
252
255
|
if (!messageId) {
|
|
253
|
-
|
|
254
|
-
|
|
256
|
+
fail({
|
|
257
|
+
code: "BAD_USAGE",
|
|
258
|
+
message: "Missing message_id.",
|
|
259
|
+
hint: "run402 email get-raw <message_id> [--output <file>]",
|
|
260
|
+
});
|
|
255
261
|
}
|
|
256
262
|
|
|
257
263
|
try {
|
|
@@ -286,12 +292,17 @@ async function reply(args) {
|
|
|
286
292
|
const projectId = resolveProjectId(projectOpt);
|
|
287
293
|
|
|
288
294
|
if (!messageId) {
|
|
289
|
-
|
|
290
|
-
|
|
295
|
+
fail({
|
|
296
|
+
code: "BAD_USAGE",
|
|
297
|
+
message: "Missing message_id.",
|
|
298
|
+
hint: 'run402 email reply <message_id> --html "..."',
|
|
299
|
+
});
|
|
291
300
|
}
|
|
292
301
|
if (!html && !text) {
|
|
293
|
-
|
|
294
|
-
|
|
302
|
+
fail({
|
|
303
|
+
code: "BAD_USAGE",
|
|
304
|
+
message: "Provide --html and/or --text for the reply body",
|
|
305
|
+
});
|
|
295
306
|
}
|
|
296
307
|
|
|
297
308
|
try {
|
|
@@ -299,12 +310,11 @@ async function reply(args) {
|
|
|
299
310
|
const original = await getSdk().email.get(projectId, messageId);
|
|
300
311
|
const replyTo = original.from || original.from_address || original.sender || null;
|
|
301
312
|
if (!replyTo) {
|
|
302
|
-
|
|
303
|
-
|
|
313
|
+
fail({
|
|
314
|
+
code: "BAD_USAGE",
|
|
304
315
|
message: "Original message has no from address to reply to",
|
|
305
|
-
original_keys: Object.keys(original),
|
|
306
|
-
})
|
|
307
|
-
process.exit(1);
|
|
316
|
+
details: { original_keys: Object.keys(original) },
|
|
317
|
+
});
|
|
308
318
|
}
|
|
309
319
|
const origSubject = typeof original.subject === "string" ? original.subject : "";
|
|
310
320
|
const defaultSubject = origSubject && origSubject.toLowerCase().startsWith("re:")
|
|
@@ -339,11 +349,10 @@ async function deleteMailbox(args) {
|
|
|
339
349
|
const confirmed = args.includes("--confirm");
|
|
340
350
|
|
|
341
351
|
if (!confirmed) {
|
|
342
|
-
|
|
343
|
-
|
|
352
|
+
fail({
|
|
353
|
+
code: "CONFIRMATION_REQUIRED",
|
|
344
354
|
message: "Destructive: deleting a mailbox is irreversible (drops all messages and webhook subscriptions). Re-run with --confirm to proceed.",
|
|
345
|
-
})
|
|
346
|
-
process.exit(1);
|
|
355
|
+
});
|
|
347
356
|
}
|
|
348
357
|
|
|
349
358
|
try {
|
package/lib/functions.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readFileSync } from "fs";
|
|
2
2
|
import { findProject, API } from "./config.mjs";
|
|
3
3
|
import { getSdk } from "./sdk.mjs";
|
|
4
|
-
import { reportSdkError } from "./sdk-errors.mjs";
|
|
4
|
+
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
5
|
+
import { assertKnownFlags, hasHelp, normalizeArgv, parseIntegerFlag } from "./argparse.mjs";
|
|
5
6
|
|
|
6
7
|
const HELP = `run402 functions — Manage serverless functions
|
|
7
8
|
|
|
@@ -21,18 +22,18 @@ Subcommands:
|
|
|
21
22
|
delete <id> <name> Delete a function
|
|
22
23
|
|
|
23
24
|
Examples:
|
|
24
|
-
run402 functions deploy
|
|
25
|
-
run402 functions deploy
|
|
26
|
-
run402 functions deploy
|
|
27
|
-
run402 functions invoke
|
|
28
|
-
run402 functions logs
|
|
29
|
-
run402 functions logs
|
|
30
|
-
run402 functions logs
|
|
31
|
-
run402 functions update
|
|
32
|
-
run402 functions update
|
|
33
|
-
run402 functions update
|
|
34
|
-
run402 functions list
|
|
35
|
-
run402 functions delete
|
|
25
|
+
run402 functions deploy prj_abc123 stripe-webhook --file handler.ts
|
|
26
|
+
run402 functions deploy prj_abc123 send-reminders --file remind.ts --schedule '*/15 * * * *'
|
|
27
|
+
run402 functions deploy prj_abc123 send-reminders --file remind.ts --schedule '' # remove schedule
|
|
28
|
+
run402 functions invoke prj_abc123 stripe-webhook --body '{"event":"test"}'
|
|
29
|
+
run402 functions logs prj_abc123 stripe-webhook --tail 100
|
|
30
|
+
run402 functions logs prj_abc123 stripe-webhook --since 2026-03-29T14:00:00Z
|
|
31
|
+
run402 functions logs prj_abc123 stripe-webhook --follow
|
|
32
|
+
run402 functions update prj_abc123 send-reminders --schedule '0 */4 * * *'
|
|
33
|
+
run402 functions update prj_abc123 send-reminders --schedule-remove
|
|
34
|
+
run402 functions update prj_abc123 my-func --timeout 15 --memory 256
|
|
35
|
+
run402 functions list prj_abc123
|
|
36
|
+
run402 functions delete prj_abc123 stripe-webhook
|
|
36
37
|
|
|
37
38
|
Notes:
|
|
38
39
|
- Code must export a default async function: export default async (req: Request) => Response
|
|
@@ -77,10 +78,10 @@ Notes:
|
|
|
77
78
|
notes such as bundle-size advisories
|
|
78
79
|
|
|
79
80
|
Examples:
|
|
80
|
-
run402 functions deploy
|
|
81
|
-
run402 functions deploy
|
|
81
|
+
run402 functions deploy prj_abc123 stripe-webhook --file handler.ts
|
|
82
|
+
run402 functions deploy prj_abc123 send-reminders --file remind.ts \\
|
|
82
83
|
--schedule '*/15 * * * *'
|
|
83
|
-
run402 functions deploy
|
|
84
|
+
run402 functions deploy prj_abc123 send-reminders --file remind.ts --schedule ''
|
|
84
85
|
`,
|
|
85
86
|
invoke: `run402 functions invoke — Invoke a deployed function
|
|
86
87
|
|
|
@@ -96,8 +97,8 @@ Options:
|
|
|
96
97
|
--body <json> Request body (ignored for GET/HEAD)
|
|
97
98
|
|
|
98
99
|
Examples:
|
|
99
|
-
run402 functions invoke
|
|
100
|
-
run402 functions invoke
|
|
100
|
+
run402 functions invoke prj_abc123 stripe-webhook --body '{"event":"test"}'
|
|
101
|
+
run402 functions invoke prj_abc123 ping --method GET
|
|
101
102
|
`,
|
|
102
103
|
logs: `run402 functions logs — Fetch or tail function logs
|
|
103
104
|
|
|
@@ -114,9 +115,9 @@ Options:
|
|
|
114
115
|
--follow Poll every 3s and stream new entries (Ctrl-C to stop)
|
|
115
116
|
|
|
116
117
|
Examples:
|
|
117
|
-
run402 functions logs
|
|
118
|
-
run402 functions logs
|
|
119
|
-
run402 functions logs
|
|
118
|
+
run402 functions logs prj_abc123 stripe-webhook --tail 100
|
|
119
|
+
run402 functions logs prj_abc123 stripe-webhook --since 2026-03-29T14:00:00Z
|
|
120
|
+
run402 functions logs prj_abc123 stripe-webhook --follow
|
|
120
121
|
`,
|
|
121
122
|
update: `run402 functions update — Update function config without re-deploying
|
|
122
123
|
|
|
@@ -137,22 +138,26 @@ Notes:
|
|
|
137
138
|
Must provide at least one of the options above.
|
|
138
139
|
|
|
139
140
|
Examples:
|
|
140
|
-
run402 functions update
|
|
141
|
-
run402 functions update
|
|
142
|
-
run402 functions update
|
|
141
|
+
run402 functions update prj_abc123 send-reminders --schedule '0 */4 * * *'
|
|
142
|
+
run402 functions update prj_abc123 send-reminders --schedule-remove
|
|
143
|
+
run402 functions update prj_abc123 my-func --timeout 15 --memory 256
|
|
143
144
|
`,
|
|
144
145
|
};
|
|
145
146
|
|
|
146
147
|
async function deploy(projectId, name, args) {
|
|
148
|
+
assertRequiredProjectAndName(projectId, name, "run402 functions deploy <project_id> <name> --file <file>");
|
|
149
|
+
assertKnownFlags(args, ["--file", "--timeout", "--memory", "--deps", "--schedule", "--help", "-h"], ["--file", "--timeout", "--memory", "--deps", "--schedule"]);
|
|
147
150
|
const opts = { file: null, timeout: undefined, memory: undefined, deps: undefined, schedule: undefined };
|
|
148
151
|
for (let i = 0; i < args.length; i++) {
|
|
149
152
|
if (args[i] === "--file" && args[i + 1]) opts.file = args[++i];
|
|
150
|
-
if (args[i] === "--timeout"
|
|
151
|
-
if (args[i] === "--memory"
|
|
153
|
+
if (args[i] === "--timeout") opts.timeout = parseIntegerFlag("--timeout", args[++i], { min: 1 });
|
|
154
|
+
if (args[i] === "--memory") opts.memory = parseIntegerFlag("--memory", args[++i], { min: 1 });
|
|
152
155
|
if (args[i] === "--deps" && args[i + 1]) opts.deps = args[++i].split(",");
|
|
153
156
|
if (args[i] === "--schedule" && i + 1 < args.length) opts.schedule = args[++i];
|
|
154
157
|
}
|
|
155
|
-
if (!opts.file) {
|
|
158
|
+
if (!opts.file) {
|
|
159
|
+
fail({ code: "BAD_USAGE", message: "Missing --file <file>" });
|
|
160
|
+
}
|
|
156
161
|
const code = readFileSync(opts.file, "utf-8");
|
|
157
162
|
|
|
158
163
|
const deployOpts = { name, code };
|
|
@@ -173,6 +178,8 @@ async function deploy(projectId, name, args) {
|
|
|
173
178
|
}
|
|
174
179
|
|
|
175
180
|
async function invoke(projectId, name, args) {
|
|
181
|
+
assertRequiredProjectAndName(projectId, name, "run402 functions invoke <project_id> <name> [--method <M>] [--body <json>]");
|
|
182
|
+
assertKnownFlags(args, ["--method", "--body", "--help", "-h"], ["--method", "--body"]);
|
|
176
183
|
const opts = { method: "POST", body: undefined };
|
|
177
184
|
for (let i = 0; i < args.length; i++) {
|
|
178
185
|
if (args[i] === "--method" && args[i + 1]) opts.method = args[++i];
|
|
@@ -196,11 +203,13 @@ async function invoke(projectId, name, args) {
|
|
|
196
203
|
}
|
|
197
204
|
|
|
198
205
|
async function logs(projectId, name, args) {
|
|
206
|
+
assertRequiredProjectAndName(projectId, name, "run402 functions logs <project_id> <name> [--tail <n>]");
|
|
207
|
+
assertKnownFlags(args, ["--tail", "--since", "--follow", "--help", "-h"], ["--tail", "--since"]);
|
|
199
208
|
let tail = 50;
|
|
200
209
|
let since = undefined;
|
|
201
210
|
let follow = false;
|
|
202
211
|
for (let i = 0; i < args.length; i++) {
|
|
203
|
-
if (args[i] === "--tail"
|
|
212
|
+
if (args[i] === "--tail") tail = parseIntegerFlag("--tail", args[++i], { min: 1 });
|
|
204
213
|
if (args[i] === "--since" && args[i + 1]) since = args[++i];
|
|
205
214
|
if (args[i] === "--follow") follow = true;
|
|
206
215
|
}
|
|
@@ -212,7 +221,13 @@ async function logs(projectId, name, args) {
|
|
|
212
221
|
if (since !== undefined) {
|
|
213
222
|
const parsed = Number(since);
|
|
214
223
|
const ms = Number.isNaN(parsed) ? new Date(since).getTime() : parsed;
|
|
215
|
-
if (Number.isNaN(ms)) {
|
|
224
|
+
if (Number.isNaN(ms)) {
|
|
225
|
+
fail({
|
|
226
|
+
code: "BAD_USAGE",
|
|
227
|
+
message: `Invalid --since value: ${since}`,
|
|
228
|
+
details: { flag: "--since", value: since },
|
|
229
|
+
});
|
|
230
|
+
}
|
|
216
231
|
sinceIso = new Date(ms).toISOString();
|
|
217
232
|
}
|
|
218
233
|
|
|
@@ -261,6 +276,8 @@ async function logs(projectId, name, args) {
|
|
|
261
276
|
}
|
|
262
277
|
|
|
263
278
|
async function update(projectId, name, args) {
|
|
279
|
+
assertRequiredProjectAndName(projectId, name, "run402 functions update <project_id> <name> [options]");
|
|
280
|
+
assertKnownFlags(args, ["--schedule", "--schedule-remove", "--timeout", "--memory", "--help", "-h"], ["--schedule", "--timeout", "--memory"]);
|
|
264
281
|
let schedule = undefined;
|
|
265
282
|
let scheduleRemove = false;
|
|
266
283
|
let timeout = undefined;
|
|
@@ -268,8 +285,8 @@ async function update(projectId, name, args) {
|
|
|
268
285
|
for (let i = 0; i < args.length; i++) {
|
|
269
286
|
if (args[i] === "--schedule" && i + 1 < args.length) schedule = args[++i];
|
|
270
287
|
if (args[i] === "--schedule-remove") scheduleRemove = true;
|
|
271
|
-
if (args[i] === "--timeout"
|
|
272
|
-
if (args[i] === "--memory"
|
|
288
|
+
if (args[i] === "--timeout") timeout = parseIntegerFlag("--timeout", args[++i], { min: 1 });
|
|
289
|
+
if (args[i] === "--memory") memory = parseIntegerFlag("--memory", args[++i], { min: 1 });
|
|
273
290
|
}
|
|
274
291
|
|
|
275
292
|
const updateOpts = {};
|
|
@@ -282,8 +299,10 @@ async function update(projectId, name, args) {
|
|
|
282
299
|
if (memory !== undefined) updateOpts.memory = memory;
|
|
283
300
|
|
|
284
301
|
if (Object.keys(updateOpts).length === 0) {
|
|
285
|
-
|
|
286
|
-
|
|
302
|
+
fail({
|
|
303
|
+
code: "BAD_USAGE",
|
|
304
|
+
message: "Provide at least one of: --schedule, --schedule-remove, --timeout, --memory",
|
|
305
|
+
});
|
|
287
306
|
}
|
|
288
307
|
|
|
289
308
|
try {
|
|
@@ -295,6 +314,7 @@ async function update(projectId, name, args) {
|
|
|
295
314
|
}
|
|
296
315
|
|
|
297
316
|
async function list(projectId) {
|
|
317
|
+
assertRequiredProject(projectId, "run402 functions list <project_id>");
|
|
298
318
|
try {
|
|
299
319
|
const data = await getSdk().functions.list(projectId);
|
|
300
320
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -304,6 +324,7 @@ async function list(projectId) {
|
|
|
304
324
|
}
|
|
305
325
|
|
|
306
326
|
async function deleteFunction(projectId, name) {
|
|
327
|
+
assertRequiredProjectAndName(projectId, name, "run402 functions delete <project_id> <name>");
|
|
307
328
|
try {
|
|
308
329
|
await getSdk().functions.delete(projectId, name);
|
|
309
330
|
console.log(JSON.stringify({ status: "ok", message: `Function '${name}' deleted.` }));
|
|
@@ -314,7 +335,8 @@ async function deleteFunction(projectId, name) {
|
|
|
314
335
|
|
|
315
336
|
export async function run(sub, args) {
|
|
316
337
|
if (!sub || sub === '--help' || sub === '-h') { console.log(HELP); process.exit(0); }
|
|
317
|
-
|
|
338
|
+
args = normalizeArgv(args);
|
|
339
|
+
if (Array.isArray(args) && hasHelp(args)) {
|
|
318
340
|
console.log(SUB_HELP[sub] || HELP);
|
|
319
341
|
process.exit(0);
|
|
320
342
|
}
|
|
@@ -331,3 +353,24 @@ export async function run(sub, args) {
|
|
|
331
353
|
process.exit(1);
|
|
332
354
|
}
|
|
333
355
|
}
|
|
356
|
+
|
|
357
|
+
function assertRequiredProject(projectId, usage) {
|
|
358
|
+
if (!projectId || String(projectId).startsWith("-")) {
|
|
359
|
+
fail({
|
|
360
|
+
code: "BAD_USAGE",
|
|
361
|
+
message: "Missing <project_id>.",
|
|
362
|
+
hint: usage,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function assertRequiredProjectAndName(projectId, name, usage) {
|
|
368
|
+
assertRequiredProject(projectId, usage);
|
|
369
|
+
if (!name || String(name).startsWith("-")) {
|
|
370
|
+
fail({
|
|
371
|
+
code: "BAD_USAGE",
|
|
372
|
+
message: "Missing <name>.",
|
|
373
|
+
hint: usage,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
}
|
package/lib/image.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { writeFileSync } from "fs";
|
|
2
2
|
import { getSdk } from "./sdk.mjs";
|
|
3
|
-
import { reportSdkError } from "./sdk-errors.mjs";
|
|
3
|
+
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
4
4
|
|
|
5
5
|
const HELP = `run402 image — Generate AI images via x402 micropayments
|
|
6
6
|
|
|
@@ -49,7 +49,13 @@ export async function run(sub, args) {
|
|
|
49
49
|
i++;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
if (!opts.prompt) {
|
|
52
|
+
if (!opts.prompt) {
|
|
53
|
+
fail({
|
|
54
|
+
code: "BAD_USAGE",
|
|
55
|
+
message: "Prompt required.",
|
|
56
|
+
hint: 'run402 image generate "your prompt"',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
53
59
|
|
|
54
60
|
try {
|
|
55
61
|
const data = await getSdk().ai.generateImage({ prompt: opts.prompt, aspect: opts.aspect });
|
package/lib/message.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { allowanceAuthHeaders } from "./config.mjs";
|
|
2
2
|
import { getSdk } from "./sdk.mjs";
|
|
3
|
-
import { reportSdkError } from "./sdk-errors.mjs";
|
|
3
|
+
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
4
4
|
|
|
5
5
|
const HELP = `run402 message — Send messages to Run402 developers
|
|
6
6
|
|
|
@@ -16,7 +16,9 @@ Examples:
|
|
|
16
16
|
`;
|
|
17
17
|
|
|
18
18
|
async function send(text) {
|
|
19
|
-
if (!text) {
|
|
19
|
+
if (!text) {
|
|
20
|
+
fail({ code: "BAD_USAGE", message: "Missing message text." });
|
|
21
|
+
}
|
|
20
22
|
// Preserve the aggressive early exit when no allowance is configured.
|
|
21
23
|
allowanceAuthHeaders("/message/v1");
|
|
22
24
|
|