run402 1.69.3 → 1.69.5
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/ai.mjs +16 -15
- package/lib/allowance.mjs +23 -7
- package/lib/argparse.mjs +7 -0
- package/lib/auth.mjs +62 -1
- package/lib/billing.mjs +24 -7
- package/lib/contracts.mjs +11 -0
- package/lib/deploy-v2.mjs +99 -15
- package/lib/email.mjs +68 -61
- package/lib/webhooks.mjs +46 -33
- package/package.json +1 -1
- package/sdk/dist/errors.d.ts +4 -1
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +16 -2
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/namespaces/billing.d.ts.map +1 -1
- package/sdk/dist/namespaces/billing.js +25 -18
- package/sdk/dist/namespaces/billing.js.map +1 -1
- package/sdk/dist/namespaces/blobs.d.ts.map +1 -1
- package/sdk/dist/namespaces/blobs.js +6 -1
- package/sdk/dist/namespaces/blobs.js.map +1 -1
- package/sdk/dist/namespaces/contracts.d.ts.map +1 -1
- package/sdk/dist/namespaces/contracts.js +5 -1
- package/sdk/dist/namespaces/contracts.js.map +1 -1
- package/sdk/dist/namespaces/deploy.d.ts +4 -7
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +41 -9
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +5 -0
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/email.d.ts.map +1 -1
- package/sdk/dist/namespaces/email.js +4 -0
- package/sdk/dist/namespaces/email.js.map +1 -1
- package/sdk/dist/namespaces/functions.d.ts.map +1 -1
- package/sdk/dist/namespaces/functions.js +20 -0
- package/sdk/dist/namespaces/functions.js.map +1 -1
- package/sdk/dist/retry.d.ts +2 -1
- package/sdk/dist/retry.d.ts.map +1 -1
- package/sdk/dist/retry.js +2 -1
- package/sdk/dist/retry.js.map +1 -1
- package/sdk/dist/validation.d.ts +3 -0
- package/sdk/dist/validation.d.ts.map +1 -0
- package/sdk/dist/validation.js +12 -0
- package/sdk/dist/validation.js.map +1 -0
package/lib/ai.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveProjectId } from "./config.mjs";
|
|
2
2
|
import { getSdk } from "./sdk.mjs";
|
|
3
3
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
4
|
-
import { resolvePositionalProject } from "./argparse.mjs";
|
|
4
|
+
import { assertKnownFlags, flagValue, normalizeArgv, resolvePositionalProject } from "./argparse.mjs";
|
|
5
5
|
|
|
6
6
|
const HELP = `run402 ai — AI translation and moderation tools
|
|
7
7
|
|
|
@@ -103,20 +103,19 @@ Examples:
|
|
|
103
103
|
`,
|
|
104
104
|
};
|
|
105
105
|
|
|
106
|
-
function parseFlag(args, flag) {
|
|
107
|
-
for (let i = 0; i < args.length; i++) {
|
|
108
|
-
if (args[i] === flag && args[i + 1]) return args[i + 1];
|
|
109
|
-
}
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
106
|
// translate has value-bearing flags (--to, --from, --context, --project) that
|
|
114
107
|
// must not be mistaken for positional bare args when prefix-matching.
|
|
115
108
|
const TRANSLATE_VALUE_FLAGS = ["--to", "--from", "--context", "--project"];
|
|
116
109
|
|
|
117
110
|
async function translate(args) {
|
|
111
|
+
args = normalizeArgv(args);
|
|
112
|
+
assertKnownFlags(args, TRANSLATE_VALUE_FLAGS, TRANSLATE_VALUE_FLAGS);
|
|
113
|
+
|
|
118
114
|
// --project <id> wins over positional, mirroring previous behavior.
|
|
119
|
-
const projectOpt =
|
|
115
|
+
const projectOpt = flagValue(args, "--project");
|
|
116
|
+
const to = flagValue(args, "--to");
|
|
117
|
+
const from = flagValue(args, "--from");
|
|
118
|
+
const context = flagValue(args, "--context");
|
|
120
119
|
let projectId;
|
|
121
120
|
let rest;
|
|
122
121
|
if (projectOpt) {
|
|
@@ -139,10 +138,6 @@ async function translate(args) {
|
|
|
139
138
|
break;
|
|
140
139
|
}
|
|
141
140
|
|
|
142
|
-
const to = parseFlag(args, "--to");
|
|
143
|
-
const from = parseFlag(args, "--from");
|
|
144
|
-
const context = parseFlag(args, "--context");
|
|
145
|
-
|
|
146
141
|
if (!text) {
|
|
147
142
|
fail({
|
|
148
143
|
code: "BAD_USAGE",
|
|
@@ -165,7 +160,10 @@ async function translate(args) {
|
|
|
165
160
|
const MODERATE_VALUE_FLAGS = ["--project"];
|
|
166
161
|
|
|
167
162
|
async function moderate(args) {
|
|
168
|
-
|
|
163
|
+
args = normalizeArgv(args);
|
|
164
|
+
assertKnownFlags(args, MODERATE_VALUE_FLAGS, MODERATE_VALUE_FLAGS);
|
|
165
|
+
|
|
166
|
+
const projectOpt = flagValue(args, "--project");
|
|
169
167
|
let projectId;
|
|
170
168
|
let rest;
|
|
171
169
|
if (projectOpt) {
|
|
@@ -203,7 +201,10 @@ async function moderate(args) {
|
|
|
203
201
|
}
|
|
204
202
|
|
|
205
203
|
async function usage(args) {
|
|
206
|
-
|
|
204
|
+
args = normalizeArgv(args);
|
|
205
|
+
assertKnownFlags(args, MODERATE_VALUE_FLAGS, MODERATE_VALUE_FLAGS);
|
|
206
|
+
|
|
207
|
+
const projectOpt = flagValue(args, "--project");
|
|
207
208
|
let projectId;
|
|
208
209
|
if (projectOpt) {
|
|
209
210
|
projectId = resolveProjectId(projectOpt);
|
package/lib/allowance.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readAllowance, saveAllowance, ALLOWANCE_FILE } from "./config.mjs";
|
|
2
2
|
import { getSdk } from "./sdk.mjs";
|
|
3
3
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
4
|
+
import { assertKnownFlags, flagValue, normalizeArgv, parseIntegerFlag, positionalArgs } from "./argparse.mjs";
|
|
4
5
|
|
|
5
6
|
const HELP = `run402 allowance — Manage your agent allowance
|
|
6
7
|
|
|
@@ -258,17 +259,25 @@ async function checkout(args) {
|
|
|
258
259
|
hint: "Run: run402 allowance create",
|
|
259
260
|
});
|
|
260
261
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
const parsedArgs = normalizeArgv(args);
|
|
263
|
+
assertKnownFlags(parsedArgs, ["--amount", "--help", "-h"], ["--amount"]);
|
|
264
|
+
const bare = positionalArgs(parsedArgs, ["--amount"]);
|
|
265
|
+
if (bare.length > 0) {
|
|
266
|
+
fail({
|
|
267
|
+
code: "BAD_USAGE",
|
|
268
|
+
message: `Unexpected argument for allowance checkout: ${bare[0]}`,
|
|
269
|
+
details: { argument: bare[0] },
|
|
270
|
+
});
|
|
264
271
|
}
|
|
265
|
-
|
|
272
|
+
const amountRaw = flagValue(parsedArgs, "--amount");
|
|
273
|
+
if (amountRaw === null) {
|
|
266
274
|
fail({
|
|
267
275
|
code: "BAD_USAGE",
|
|
268
276
|
message: "Missing --amount <usd_micros>",
|
|
269
277
|
hint: "e.g. --amount 5000000 for $5",
|
|
270
278
|
});
|
|
271
279
|
}
|
|
280
|
+
const amount = parseIntegerFlag("--amount", amountRaw, { min: 1 });
|
|
272
281
|
try {
|
|
273
282
|
const data = await getSdk().billing.createCheckout(w.address, amount);
|
|
274
283
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -286,10 +295,17 @@ async function history(args) {
|
|
|
286
295
|
hint: "Run: run402 allowance create",
|
|
287
296
|
});
|
|
288
297
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
298
|
+
const parsedArgs = normalizeArgv(args);
|
|
299
|
+
assertKnownFlags(parsedArgs, ["--limit", "--help", "-h"], ["--limit"]);
|
|
300
|
+
const bare = positionalArgs(parsedArgs, ["--limit"]);
|
|
301
|
+
if (bare.length > 0) {
|
|
302
|
+
fail({
|
|
303
|
+
code: "BAD_USAGE",
|
|
304
|
+
message: `Unexpected argument for allowance history: ${bare[0]}`,
|
|
305
|
+
details: { argument: bare[0] },
|
|
306
|
+
});
|
|
292
307
|
}
|
|
308
|
+
const limit = parseIntegerFlag("--limit", flagValue(parsedArgs, "--limit"), { min: 1, def: 20 });
|
|
293
309
|
try {
|
|
294
310
|
const data = await getSdk().billing.history(w.address, limit);
|
|
295
311
|
console.log(JSON.stringify(data, null, 2));
|
package/lib/argparse.mjs
CHANGED
|
@@ -75,6 +75,13 @@ export function parseIntegerFlag(name, value, { min = 1, max = Number.POSITIVE_I
|
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
77
|
const n = Number.parseInt(raw, 10);
|
|
78
|
+
if (!Number.isSafeInteger(n)) {
|
|
79
|
+
fail({
|
|
80
|
+
code: "BAD_FLAG",
|
|
81
|
+
message: `${name} must be a safe integer, got: ${raw}`,
|
|
82
|
+
details: { flag: name, value: raw },
|
|
83
|
+
});
|
|
84
|
+
}
|
|
78
85
|
if (n < min) {
|
|
79
86
|
fail({
|
|
80
87
|
code: "BAD_FLAG",
|
package/lib/auth.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolveProjectId } from "./config.mjs";
|
|
2
2
|
import { getSdk } from "./sdk.mjs";
|
|
3
3
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
4
|
+
import { assertKnownFlags, hasHelp, normalizeArgv } from "./argparse.mjs";
|
|
4
5
|
|
|
5
6
|
const HELP = `run402 auth — Manage project user authentication
|
|
6
7
|
|
|
@@ -230,6 +231,61 @@ Examples:
|
|
|
230
231
|
`,
|
|
231
232
|
};
|
|
232
233
|
|
|
234
|
+
const AUTH_FLAGS = {
|
|
235
|
+
"magic-link": {
|
|
236
|
+
known: ["--email", "--redirect", "--intent", "--state", "--project", "--help", "-h"],
|
|
237
|
+
values: ["--email", "--redirect", "--intent", "--state", "--project"],
|
|
238
|
+
},
|
|
239
|
+
"create-user": {
|
|
240
|
+
known: ["--email", "--admin", "--invite", "--redirect", "--state", "--project", "--help", "-h"],
|
|
241
|
+
values: ["--email", "--admin", "--redirect", "--state", "--project"],
|
|
242
|
+
},
|
|
243
|
+
"invite-user": {
|
|
244
|
+
known: ["--email", "--redirect", "--admin", "--state", "--project", "--help", "-h"],
|
|
245
|
+
values: ["--email", "--redirect", "--admin", "--state", "--project"],
|
|
246
|
+
},
|
|
247
|
+
verify: {
|
|
248
|
+
known: ["--token", "--project", "--help", "-h"],
|
|
249
|
+
values: ["--token", "--project"],
|
|
250
|
+
},
|
|
251
|
+
"set-password": {
|
|
252
|
+
known: ["--token", "--new", "--current", "--project", "--help", "-h"],
|
|
253
|
+
values: ["--token", "--new", "--current", "--project"],
|
|
254
|
+
},
|
|
255
|
+
settings: {
|
|
256
|
+
known: ["--allow-password-set", "--preferred", "--public-signup", "--require-admin-passkey", "--project", "--help", "-h"],
|
|
257
|
+
values: ["--allow-password-set", "--preferred", "--public-signup", "--require-admin-passkey", "--project"],
|
|
258
|
+
},
|
|
259
|
+
"passkey-register-options": {
|
|
260
|
+
known: ["--token", "--app-origin", "--project", "--help", "-h"],
|
|
261
|
+
values: ["--token", "--app-origin", "--project"],
|
|
262
|
+
},
|
|
263
|
+
"passkey-register-verify": {
|
|
264
|
+
known: ["--token", "--challenge", "--response", "--label", "--project", "--help", "-h"],
|
|
265
|
+
values: ["--token", "--challenge", "--response", "--label", "--project"],
|
|
266
|
+
},
|
|
267
|
+
"passkey-login-options": {
|
|
268
|
+
known: ["--app-origin", "--email", "--project", "--help", "-h"],
|
|
269
|
+
values: ["--app-origin", "--email", "--project"],
|
|
270
|
+
},
|
|
271
|
+
"passkey-login-verify": {
|
|
272
|
+
known: ["--challenge", "--response", "--project", "--help", "-h"],
|
|
273
|
+
values: ["--challenge", "--response", "--project"],
|
|
274
|
+
},
|
|
275
|
+
passkeys: {
|
|
276
|
+
known: ["--token", "--project", "--help", "-h"],
|
|
277
|
+
values: ["--token", "--project"],
|
|
278
|
+
},
|
|
279
|
+
"delete-passkey": {
|
|
280
|
+
known: ["--token", "--id", "--project", "--help", "-h"],
|
|
281
|
+
values: ["--token", "--id", "--project"],
|
|
282
|
+
},
|
|
283
|
+
providers: {
|
|
284
|
+
known: ["--project", "--help", "-h"],
|
|
285
|
+
values: ["--project"],
|
|
286
|
+
},
|
|
287
|
+
};
|
|
288
|
+
|
|
233
289
|
function parseFlag(args, flag) {
|
|
234
290
|
for (let i = 0; i < args.length; i++) {
|
|
235
291
|
if (args[i] === flag && args[i + 1]) return args[i + 1];
|
|
@@ -557,10 +613,15 @@ async function providers(args) {
|
|
|
557
613
|
|
|
558
614
|
export async function run(sub, args) {
|
|
559
615
|
if (!sub || sub === "--help" || sub === "-h") { console.log(HELP); process.exit(0); }
|
|
560
|
-
|
|
616
|
+
args = normalizeArgv(args);
|
|
617
|
+
if (Array.isArray(args) && hasHelp(args)) {
|
|
561
618
|
console.log(SUB_HELP[sub] || HELP);
|
|
562
619
|
process.exit(0);
|
|
563
620
|
}
|
|
621
|
+
const flagSpec = AUTH_FLAGS[sub];
|
|
622
|
+
if (flagSpec) {
|
|
623
|
+
assertKnownFlags(args, flagSpec.known, flagSpec.values);
|
|
624
|
+
}
|
|
564
625
|
switch (sub) {
|
|
565
626
|
case "magic-link": await magicLink(args); break;
|
|
566
627
|
case "verify": await verify(args); break;
|
package/lib/billing.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getSdk } from "./sdk.mjs";
|
|
2
2
|
import { reportSdkError, fail } from "./sdk-errors.mjs";
|
|
3
|
+
import { parseIntegerFlag } from "./argparse.mjs";
|
|
3
4
|
|
|
4
5
|
const HELP = `run402 billing — Email billing accounts, Stripe tier checkout, email packs
|
|
5
6
|
|
|
@@ -128,6 +129,23 @@ function parseFlag(args, flag) {
|
|
|
128
129
|
return null;
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
function requireSingleBillingIdentifier(email, wallet) {
|
|
133
|
+
if (email && wallet) {
|
|
134
|
+
fail({
|
|
135
|
+
code: "BAD_USAGE",
|
|
136
|
+
message: "Provide either --email or --wallet, not both.",
|
|
137
|
+
hint: "[--email <e> | --wallet <w>]",
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if (!email && !wallet) {
|
|
141
|
+
fail({
|
|
142
|
+
code: "BAD_USAGE",
|
|
143
|
+
message: "Must provide --email or --wallet",
|
|
144
|
+
hint: "[--email <e> | --wallet <w>]",
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
131
149
|
async function createEmail(args) {
|
|
132
150
|
const email = args[0];
|
|
133
151
|
if (!email) {
|
|
@@ -174,9 +192,7 @@ async function tierCheckout(args) {
|
|
|
174
192
|
}
|
|
175
193
|
const email = parseFlag(args, "--email");
|
|
176
194
|
const wallet = parseFlag(args, "--wallet");
|
|
177
|
-
|
|
178
|
-
fail({ code: "BAD_USAGE", message: "Must provide --email or --wallet" });
|
|
179
|
-
}
|
|
195
|
+
requireSingleBillingIdentifier(email, wallet);
|
|
180
196
|
try {
|
|
181
197
|
const data = await getSdk().billing.tierCheckout(tier, { email: email ?? undefined, wallet: wallet ?? undefined });
|
|
182
198
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -188,9 +204,7 @@ async function tierCheckout(args) {
|
|
|
188
204
|
async function buyPack(args) {
|
|
189
205
|
const email = parseFlag(args, "--email");
|
|
190
206
|
const wallet = parseFlag(args, "--wallet");
|
|
191
|
-
|
|
192
|
-
fail({ code: "BAD_USAGE", message: "Must provide --email or --wallet" });
|
|
193
|
-
}
|
|
207
|
+
requireSingleBillingIdentifier(email, wallet);
|
|
194
208
|
try {
|
|
195
209
|
const data = await getSdk().billing.buyEmailPack({ email: email ?? undefined, wallet: wallet ?? undefined });
|
|
196
210
|
console.log(JSON.stringify(data, null, 2));
|
|
@@ -210,11 +224,14 @@ async function autoRecharge(args) {
|
|
|
210
224
|
});
|
|
211
225
|
}
|
|
212
226
|
const thresholdStr = parseFlag(args, "--threshold");
|
|
227
|
+
const threshold = args.includes("--threshold")
|
|
228
|
+
? parseIntegerFlag("--threshold", thresholdStr, { min: 0 })
|
|
229
|
+
: undefined;
|
|
213
230
|
try {
|
|
214
231
|
await getSdk().billing.setAutoRecharge({
|
|
215
232
|
billingAccountId: accountId,
|
|
216
233
|
enabled: state === "on",
|
|
217
|
-
threshold
|
|
234
|
+
threshold,
|
|
218
235
|
});
|
|
219
236
|
console.log(JSON.stringify({ status: "ok", billing_account_id: accountId, enabled: state === "on" }));
|
|
220
237
|
} catch (err) {
|
package/lib/contracts.mjs
CHANGED
|
@@ -135,6 +135,15 @@ function parseFlag(args, flag) {
|
|
|
135
135
|
function hasFlag(args, flag) {
|
|
136
136
|
return args.includes(flag);
|
|
137
137
|
}
|
|
138
|
+
function validateWeiFlag(flag, value) {
|
|
139
|
+
if (!/^\d+$/.test(String(value))) {
|
|
140
|
+
fail({
|
|
141
|
+
code: "BAD_FLAG",
|
|
142
|
+
message: `${flag} must be a decimal non-negative integer string in wei`,
|
|
143
|
+
details: { flag, value: String(value) },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
138
147
|
|
|
139
148
|
async function provisionWallet(projectId, args) {
|
|
140
149
|
const chain = parseFlag(args, "--chain");
|
|
@@ -210,6 +219,7 @@ async function setAlert(projectId, walletId, args) {
|
|
|
210
219
|
if (!threshold) {
|
|
211
220
|
fail({ code: "BAD_USAGE", message: "Missing --threshold-wei <n>" });
|
|
212
221
|
}
|
|
222
|
+
validateWeiFlag("--threshold-wei", threshold);
|
|
213
223
|
try {
|
|
214
224
|
await getSdk().contracts.setLowBalanceAlert(projectId, walletId, threshold);
|
|
215
225
|
console.log(JSON.stringify({ status: "ok", wallet_id: walletId, threshold_wei: threshold }));
|
|
@@ -233,6 +243,7 @@ async function call(projectId, walletId, args) {
|
|
|
233
243
|
hint: "Cost: chain gas + $0.000005 KMS sign fee.",
|
|
234
244
|
});
|
|
235
245
|
}
|
|
246
|
+
if (value !== null) validateWeiFlag("--value-wei", value);
|
|
236
247
|
const abiFragment = parseFlagJson("--abi", abi);
|
|
237
248
|
const callArgs = parseFlagJson("--args", argsJson);
|
|
238
249
|
try {
|
package/lib/deploy-v2.mjs
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* UTF-8 is the default; binary files pass `"encoding": "base64"`.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
-
import { readFileSync } from "node:fs";
|
|
24
|
+
import { fstatSync, readFileSync } from "node:fs";
|
|
25
25
|
import { resolve, dirname, isAbsolute } from "node:path";
|
|
26
26
|
import {
|
|
27
27
|
buildDeployResolveSummary,
|
|
@@ -266,6 +266,15 @@ async function readStdin() {
|
|
|
266
266
|
return Buffer.concat(chunks).toString("utf-8");
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
function hasStdinSource() {
|
|
270
|
+
try {
|
|
271
|
+
const stats = fstatSync(0);
|
|
272
|
+
return stats.isFIFO() || stats.isFile();
|
|
273
|
+
} catch {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
269
278
|
function makeStderrEventWriter(quiet) {
|
|
270
279
|
if (quiet) return undefined;
|
|
271
280
|
return (event) => {
|
|
@@ -273,22 +282,97 @@ function makeStderrEventWriter(quiet) {
|
|
|
273
282
|
};
|
|
274
283
|
}
|
|
275
284
|
|
|
276
|
-
|
|
285
|
+
function parseApplyArgs(args) {
|
|
277
286
|
const opts = { manifest: null, spec: null, project: null, quiet: false, allowWarnings: false };
|
|
287
|
+
const allowedFlags = ["--manifest", "--spec", "--project", "--quiet", "--allow-warnings", "--help", "-h"];
|
|
288
|
+
|
|
278
289
|
for (let i = 0; i < args.length; i++) {
|
|
279
|
-
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (
|
|
290
|
+
const arg = args[i];
|
|
291
|
+
if (arg === "--help" || arg === "-h") {
|
|
292
|
+
console.log(APPLY_HELP);
|
|
293
|
+
process.exit(0);
|
|
294
|
+
}
|
|
295
|
+
if (arg === "--manifest" || arg === "--spec" || arg === "--project") {
|
|
296
|
+
const value = args[i + 1];
|
|
297
|
+
if (value === undefined || (typeof value === "string" && value.startsWith("--"))) {
|
|
298
|
+
fail({
|
|
299
|
+
code: "BAD_USAGE",
|
|
300
|
+
message: `${arg} requires a value`,
|
|
301
|
+
details: { flag: arg },
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
if (arg === "--manifest") {
|
|
305
|
+
if (opts.manifest !== null) {
|
|
306
|
+
fail({
|
|
307
|
+
code: "BAD_USAGE",
|
|
308
|
+
message: "--manifest may only be provided once",
|
|
309
|
+
details: { flag: "--manifest" },
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
opts.manifest = value;
|
|
313
|
+
} else if (arg === "--spec") {
|
|
314
|
+
if (opts.spec !== null) {
|
|
315
|
+
fail({
|
|
316
|
+
code: "BAD_USAGE",
|
|
317
|
+
message: "--spec may only be provided once",
|
|
318
|
+
details: { flag: "--spec" },
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
opts.spec = value;
|
|
322
|
+
} else {
|
|
323
|
+
opts.project = value;
|
|
324
|
+
}
|
|
325
|
+
i += 1;
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (arg === "--quiet") { opts.quiet = true; continue; }
|
|
329
|
+
if (arg === "--allow-warnings") { opts.allowWarnings = true; continue; }
|
|
330
|
+
if (typeof arg === "string" && arg.startsWith("-")) {
|
|
331
|
+
fail({
|
|
332
|
+
code: "BAD_USAGE",
|
|
333
|
+
message: `Unknown flag for deploy apply: ${arg}`,
|
|
334
|
+
details: { flag: arg, allowed_flags: allowedFlags },
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
fail({
|
|
338
|
+
code: "BAD_USAGE",
|
|
339
|
+
message: `Unexpected argument for deploy apply: ${arg}`,
|
|
340
|
+
details: { argument: arg },
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return opts;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function applySourceField(opts) {
|
|
348
|
+
if (opts.manifest !== null) return "manifest";
|
|
349
|
+
if (opts.spec !== null) return "spec";
|
|
350
|
+
return "stdin";
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function validateApplySources(opts) {
|
|
354
|
+
const sources = [];
|
|
355
|
+
if (opts.manifest !== null) sources.push("--manifest");
|
|
356
|
+
if (opts.spec !== null) sources.push("--spec");
|
|
357
|
+
if (hasStdinSource()) sources.push("stdin");
|
|
358
|
+
if (sources.length > 1) {
|
|
359
|
+
fail({
|
|
360
|
+
code: "BAD_USAGE",
|
|
361
|
+
message: "Only one deploy manifest source may be provided: --spec, --manifest, or stdin.",
|
|
362
|
+
details: { sources },
|
|
363
|
+
});
|
|
285
364
|
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async function applyCmd(args) {
|
|
368
|
+
const opts = parseApplyArgs(args);
|
|
369
|
+
validateApplySources(opts);
|
|
286
370
|
|
|
287
371
|
let raw;
|
|
288
372
|
let manifestPath = null;
|
|
289
|
-
if (opts.spec) {
|
|
373
|
+
if (opts.spec !== null) {
|
|
290
374
|
raw = opts.spec;
|
|
291
|
-
} else if (opts.manifest) {
|
|
375
|
+
} else if (opts.manifest !== null) {
|
|
292
376
|
try {
|
|
293
377
|
manifestPath = isAbsolute(opts.manifest) ? opts.manifest : resolve(process.cwd(), opts.manifest);
|
|
294
378
|
raw = readFileSync(manifestPath, "utf-8");
|
|
@@ -310,11 +394,11 @@ async function applyCmd(args) {
|
|
|
310
394
|
fail({
|
|
311
395
|
code: "BAD_USAGE",
|
|
312
396
|
message: `Manifest is not valid JSON: ${err.message}`,
|
|
313
|
-
details: { source: opts
|
|
397
|
+
details: { source: applySourceField(opts), parse_error: err.message },
|
|
314
398
|
});
|
|
315
399
|
}
|
|
316
400
|
rejectLegacySecretManifest(spec, {
|
|
317
|
-
source: opts
|
|
401
|
+
source: applySourceField(opts),
|
|
318
402
|
...(manifestPath ? { path: manifestPath } : {}),
|
|
319
403
|
});
|
|
320
404
|
|
|
@@ -355,7 +439,7 @@ async function applyCmd(args) {
|
|
|
355
439
|
message: `Manifest contains no deployable sections. Expected at least one of: ${meaningful.join(", ")}`,
|
|
356
440
|
hint: "Did you mean to write a 'site.replace' or 'database.migrations' block? See https://run402.com/schemas/manifest.v1.json",
|
|
357
441
|
details: {
|
|
358
|
-
field: opts
|
|
442
|
+
field: applySourceField(opts),
|
|
359
443
|
...(manifestPath ? { path: manifestPath } : {}),
|
|
360
444
|
meaningful_keys: meaningful,
|
|
361
445
|
},
|
|
@@ -725,7 +809,7 @@ async function listCmd(args) {
|
|
|
725
809
|
for (let i = 0; i < args.length; i++) {
|
|
726
810
|
if (args[i] === "--help" || args[i] === "-h") { console.log(LIST_HELP); process.exit(0); }
|
|
727
811
|
if (args[i] === "--project" && args[i + 1]) { opts.project = args[++i]; continue; }
|
|
728
|
-
if (args[i] === "--limit"
|
|
812
|
+
if (args[i] === "--limit") { opts.limit = parsePositiveInt(args[++i], "--limit"); continue; }
|
|
729
813
|
}
|
|
730
814
|
|
|
731
815
|
const project = resolveProjectId(opts.project);
|
|
@@ -733,7 +817,7 @@ async function listCmd(args) {
|
|
|
733
817
|
|
|
734
818
|
try {
|
|
735
819
|
const sdkOpts = { project };
|
|
736
|
-
if (opts.limit !== null
|
|
820
|
+
if (opts.limit !== null) sdkOpts.limit = opts.limit;
|
|
737
821
|
const result = await getSdk().deploy.list(sdkOpts);
|
|
738
822
|
console.log(JSON.stringify({ status: "ok", ...result }, null, 2));
|
|
739
823
|
} catch (err) {
|