run402 4.1.1 → 4.2.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/lib/billing.mjs +7 -7
- package/lib/org.mjs +77 -39
- package/lib/projects.mjs +51 -0
- package/package.json +1 -1
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +41 -2
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/namespaces/deploy.types.d.ts +11 -0
- package/sdk/dist/namespaces/deploy.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.types.js +4 -0
- package/sdk/dist/namespaces/deploy.types.js.map +1 -1
- package/sdk/dist/namespaces/org.d.ts +8 -1
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +16 -0
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/org.types.d.ts +37 -0
- package/sdk/dist/namespaces/org.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +8 -1
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +17 -0
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/projects.types.d.ts +58 -0
- package/sdk/dist/namespaces/projects.types.d.ts.map +1 -1
- package/sdk/dist/node/deploy-manifest.js +1 -1
- package/sdk/dist/node/deploy-manifest.js.map +1 -1
- package/sdk/dist/scoped.d.ts +2 -1
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +3 -0
- package/sdk/dist/scoped.js.map +1 -1
package/lib/billing.mjs
CHANGED
|
@@ -9,7 +9,7 @@ Usage:
|
|
|
9
9
|
|
|
10
10
|
Subcommands:
|
|
11
11
|
create-email <email> Create an email organization
|
|
12
|
-
link-wallet <org_id> <
|
|
12
|
+
link-wallet <org_id> <wallet_address> Link a wallet to an email organization
|
|
13
13
|
checkout <identifier> --product <p> Create an org checkout
|
|
14
14
|
auto-recharge <org_id> <on|off> [--threshold <n>]
|
|
15
15
|
balance <identifier> Balance by organization id (UUID), wallet (0x...), or email
|
|
@@ -114,11 +114,11 @@ Examples:
|
|
|
114
114
|
"link-wallet": `run402 billing link-wallet — Link a wallet to an email organization
|
|
115
115
|
|
|
116
116
|
Usage:
|
|
117
|
-
run402 billing link-wallet <org_id> <
|
|
117
|
+
run402 billing link-wallet <org_id> <wallet_address>
|
|
118
118
|
|
|
119
119
|
Arguments:
|
|
120
120
|
<org_id> Organization ID (e.g. org_abc123)
|
|
121
|
-
<
|
|
121
|
+
<wallet_address> Wallet address (0x...) to link
|
|
122
122
|
|
|
123
123
|
Notes:
|
|
124
124
|
- Tier and quotas are per-organization. Linking a wallet merges its
|
|
@@ -242,8 +242,8 @@ async function linkWallet(args) {
|
|
|
242
242
|
if (!organizationId || !wallet) {
|
|
243
243
|
fail({
|
|
244
244
|
code: "BAD_USAGE",
|
|
245
|
-
message: "Missing <org_id> and/or <
|
|
246
|
-
hint: "run402 billing link-wallet <org_id> <
|
|
245
|
+
message: "Missing <org_id> and/or <wallet_address>.",
|
|
246
|
+
hint: "run402 billing link-wallet <org_id> <wallet_address>",
|
|
247
247
|
});
|
|
248
248
|
}
|
|
249
249
|
try {
|
|
@@ -305,7 +305,7 @@ async function balance(args) {
|
|
|
305
305
|
fail({
|
|
306
306
|
code: "BAD_USAGE",
|
|
307
307
|
message: "Missing <identifier>.",
|
|
308
|
-
hint: "run402 billing balance <
|
|
308
|
+
hint: "run402 billing balance <org_id | wallet | email>",
|
|
309
309
|
});
|
|
310
310
|
}
|
|
311
311
|
try {
|
|
@@ -329,7 +329,7 @@ async function history(args) {
|
|
|
329
329
|
fail({
|
|
330
330
|
code: "BAD_USAGE",
|
|
331
331
|
message: "Missing <identifier>.",
|
|
332
|
-
hint: "run402 billing history <
|
|
332
|
+
hint: "run402 billing history <org_id | wallet | email> [--limit <n>] [--after <cursor>]",
|
|
333
333
|
});
|
|
334
334
|
}
|
|
335
335
|
const limit = parsedArgs.includes("--limit")
|
package/lib/org.mjs
CHANGED
|
@@ -15,23 +15,25 @@ const HELP = `run402 org — organizations: create, label, membership, invites
|
|
|
15
15
|
Usage:
|
|
16
16
|
run402 org create [--name <label>]
|
|
17
17
|
run402 org list
|
|
18
|
-
run402 org get <
|
|
19
|
-
run402 org rename <
|
|
18
|
+
run402 org get <org_id>
|
|
19
|
+
run402 org rename <org_id> <display_name> (or: --clear to remove the label)
|
|
20
|
+
run402 org payout-wallet <org_id> <wallet_address> (or: --clear to remove the explicit default)
|
|
20
21
|
run402 org whoami
|
|
21
|
-
run402 org audit <
|
|
22
|
-
run402 org member list <
|
|
23
|
-
run402 org member add <
|
|
24
|
-
run402 org member role <
|
|
25
|
-
run402 org member rm <
|
|
26
|
-
run402 org invite list <
|
|
27
|
-
run402 org invite create <
|
|
28
|
-
run402 org invite rm <
|
|
22
|
+
run402 org audit <org_id> [--limit N] [--after <cursor>] [--before <cursor>]
|
|
23
|
+
run402 org member list <org_id>
|
|
24
|
+
run402 org member add <org_id> <wallet_address> [--role <role>]
|
|
25
|
+
run402 org member role <org_id> <principal_id> <role>
|
|
26
|
+
run402 org member rm <org_id> <principal_id>
|
|
27
|
+
run402 org invite list <org_id>
|
|
28
|
+
run402 org invite create <org_id> <email> [--role <role>] [--ttl-hours N]
|
|
29
|
+
run402 org invite rm <org_id> <principal_id>
|
|
29
30
|
|
|
30
31
|
Subcommands:
|
|
31
32
|
create Create an empty org on the prototype tier (you become owner)
|
|
32
33
|
list Orgs you are a member of
|
|
33
34
|
get Read one org (label + tier/lease + your role)
|
|
34
35
|
rename Set or clear an org's display label (owner-only)
|
|
36
|
+
payout-wallet Set or clear the tenant route payout wallet (admin+)
|
|
35
37
|
whoami Resolved principal + org memberships (GET /agent/v1/whoami)
|
|
36
38
|
member Manage members (list, add, role, rm) — mutations require owner
|
|
37
39
|
invite Manage email invites (list, create, rm) — mutations require owner
|
|
@@ -40,7 +42,7 @@ Subcommands:
|
|
|
40
42
|
Notes:
|
|
41
43
|
- A wallet AUTHENTICATES; an org owns projects. Membership/role authorizes.
|
|
42
44
|
- Roles: ${ROLE_LIST}. Member/invite changes need an active owner.
|
|
43
|
-
- create/rename/member/invite are step-up gated for control-plane sessions.
|
|
45
|
+
- create/rename/payout-wallet/member/invite are step-up gated for control-plane sessions.
|
|
44
46
|
- Removing/demoting the org's only active owner fails with 409 LAST_OWNER.
|
|
45
47
|
- JSON in, JSON out.
|
|
46
48
|
|
|
@@ -50,6 +52,8 @@ Examples:
|
|
|
50
52
|
run402 org get org_abc
|
|
51
53
|
run402 org rename org_abc "New Name"
|
|
52
54
|
run402 org rename org_abc --clear
|
|
55
|
+
run402 org payout-wallet org_abc 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
|
|
56
|
+
run402 org payout-wallet org_abc --clear
|
|
53
57
|
run402 org member add org_abc 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --role admin
|
|
54
58
|
run402 org invite create org_abc dev@example.com --role developer
|
|
55
59
|
run402 org audit org_abc --limit 50
|
|
@@ -75,7 +79,7 @@ Usage:
|
|
|
75
79
|
get: `run402 org get — read one org (label + tier/lease + your role)
|
|
76
80
|
|
|
77
81
|
Usage:
|
|
78
|
-
run402 org get <
|
|
82
|
+
run402 org get <org_id>
|
|
79
83
|
|
|
80
84
|
Any active member may read. A non-member (including a guessed id) gets the same
|
|
81
85
|
non-revealing 403.
|
|
@@ -83,11 +87,25 @@ non-revealing 403.
|
|
|
83
87
|
rename: `run402 org rename — set or clear an org's display label (owner-only)
|
|
84
88
|
|
|
85
89
|
Usage:
|
|
86
|
-
run402 org rename <
|
|
87
|
-
run402 org rename <
|
|
90
|
+
run402 org rename <org_id> <display_name>
|
|
91
|
+
run402 org rename <org_id> --clear
|
|
88
92
|
|
|
89
93
|
Owner-only + step-up gated. Pass --clear (or an empty display_name) to remove
|
|
90
94
|
the label. Output includes the updated tier and lease timestamps.
|
|
95
|
+
`,
|
|
96
|
+
"payout-wallet": `run402 org payout-wallet — set or clear the tenant route payout wallet
|
|
97
|
+
|
|
98
|
+
Usage:
|
|
99
|
+
run402 org payout-wallet <org_id> <wallet_address>
|
|
100
|
+
run402 org payout-wallet <org_id> --clear
|
|
101
|
+
|
|
102
|
+
Admin/owner-only + step-up gated. The wallet must already be active and linked
|
|
103
|
+
to the same org. This wallet receives x402 settlement for function web routes
|
|
104
|
+
that declare pricing.pay_to = "org_default_payout". Pass --clear to remove the
|
|
105
|
+
explicit default; a single active org wallet may still resolve automatically.
|
|
106
|
+
|
|
107
|
+
The JSON response includes recovery.status, active_wallet_count, and
|
|
108
|
+
next_actions for PAYOUT_WALLET_REQUIRED / PAYOUT_WALLET_AMBIGUOUS setup.
|
|
91
109
|
`,
|
|
92
110
|
whoami: `run402 org whoami — resolved principal + org memberships
|
|
93
111
|
|
|
@@ -101,10 +119,10 @@ for local wallet/profile state use 'run402 status'.
|
|
|
101
119
|
member: `run402 org member — manage org members
|
|
102
120
|
|
|
103
121
|
Usage:
|
|
104
|
-
run402 org member list <
|
|
105
|
-
run402 org member add <
|
|
106
|
-
run402 org member role <
|
|
107
|
-
run402 org member rm <
|
|
122
|
+
run402 org member list <org_id>
|
|
123
|
+
run402 org member add <org_id> <wallet_address> [--role <role>]
|
|
124
|
+
run402 org member role <org_id> <principal_id> <role>
|
|
125
|
+
run402 org member rm <org_id> <principal_id>
|
|
108
126
|
|
|
109
127
|
Roles: ${ROLE_LIST} (add defaults to developer). Mutations require an active owner.
|
|
110
128
|
Demoting/removing the org's only active owner fails with 409 LAST_OWNER.
|
|
@@ -112,9 +130,9 @@ Demoting/removing the org's only active owner fails with 409 LAST_OWNER.
|
|
|
112
130
|
invite: `run402 org invite — manage email invites
|
|
113
131
|
|
|
114
132
|
Usage:
|
|
115
|
-
run402 org invite list <
|
|
116
|
-
run402 org invite create <
|
|
117
|
-
run402 org invite rm <
|
|
133
|
+
run402 org invite list <org_id>
|
|
134
|
+
run402 org invite create <org_id> <email> [--role <role>] [--ttl-hours N]
|
|
135
|
+
run402 org invite rm <org_id> <principal_id>
|
|
118
136
|
|
|
119
137
|
An invite is claimed at the recipient's first login. Mutations require an active owner
|
|
120
138
|
(plus step-up when driven by a control-plane session).
|
|
@@ -122,7 +140,7 @@ An invite is claimed at the recipient's first login. Mutations require an active
|
|
|
122
140
|
audit: `run402 org audit — control-plane audit trail
|
|
123
141
|
|
|
124
142
|
Usage:
|
|
125
|
-
run402 org audit <
|
|
143
|
+
run402 org audit <org_id> [--limit N] [--after <cursor>] [--before <cursor>]
|
|
126
144
|
|
|
127
145
|
Requires an admin+ membership on the org. Newest-first. Page forward with --after
|
|
128
146
|
(next_cursor from a prior page); --before is the legacy cursor. Returns
|
|
@@ -171,7 +189,7 @@ async function get(args) {
|
|
|
171
189
|
const a = normalizeArgv(args);
|
|
172
190
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
173
191
|
const [org] = requirePositionalCount(a, [], {
|
|
174
|
-
min: 1, max: 1, command: "run402 org get <
|
|
192
|
+
min: 1, max: 1, command: "run402 org get <org_id>", missing: "Missing <org_id>.",
|
|
175
193
|
});
|
|
176
194
|
try {
|
|
177
195
|
console.log(JSON.stringify(await getSdk().org(org).get(), null, 2));
|
|
@@ -187,8 +205,8 @@ async function rename(args) {
|
|
|
187
205
|
const positionals = requirePositionalCount(a, [], {
|
|
188
206
|
min: clear ? 1 : 2,
|
|
189
207
|
max: clear ? 1 : 2,
|
|
190
|
-
command: "run402 org rename <
|
|
191
|
-
missing: clear ? "Missing <
|
|
208
|
+
command: "run402 org rename <org_id> <display_name>",
|
|
209
|
+
missing: clear ? "Missing <org_id>." : "Missing <org_id> and/or <display_name> (or pass --clear).",
|
|
192
210
|
});
|
|
193
211
|
const org = positionals[0];
|
|
194
212
|
const displayName = clear ? null : positionals[1];
|
|
@@ -199,6 +217,25 @@ async function rename(args) {
|
|
|
199
217
|
}
|
|
200
218
|
}
|
|
201
219
|
|
|
220
|
+
async function payoutWallet(args) {
|
|
221
|
+
const a = normalizeArgv(args);
|
|
222
|
+
assertKnownFlags(a, ["--clear", "--help", "-h"]);
|
|
223
|
+
const clear = a.includes("--clear");
|
|
224
|
+
const positionals = requirePositionalCount(a, [], {
|
|
225
|
+
min: clear ? 1 : 2,
|
|
226
|
+
max: clear ? 1 : 2,
|
|
227
|
+
command: "run402 org payout-wallet <org_id> <wallet_address>",
|
|
228
|
+
missing: clear ? "Missing <org_id>." : "Missing <org_id> and/or <wallet_address> (or pass --clear).",
|
|
229
|
+
});
|
|
230
|
+
const org = positionals[0];
|
|
231
|
+
const walletAddress = clear ? null : positionals[1];
|
|
232
|
+
try {
|
|
233
|
+
console.log(JSON.stringify(await getSdk().org(org).setPayoutWallet({ walletAddress }), null, 2));
|
|
234
|
+
} catch (err) {
|
|
235
|
+
reportSdkError(err);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
202
239
|
async function audit(args) {
|
|
203
240
|
const a = normalizeArgv(args);
|
|
204
241
|
const valueFlags = ["--limit", "--after", "--before"];
|
|
@@ -206,8 +243,8 @@ async function audit(args) {
|
|
|
206
243
|
const [org] = requirePositionalCount(a, valueFlags, {
|
|
207
244
|
min: 1,
|
|
208
245
|
max: 1,
|
|
209
|
-
command: "run402 org audit <
|
|
210
|
-
missing: "Missing <
|
|
246
|
+
command: "run402 org audit <org_id>",
|
|
247
|
+
missing: "Missing <org_id>.",
|
|
211
248
|
});
|
|
212
249
|
const limitFlag = flagValue(a, "--limit");
|
|
213
250
|
const after = flagValue(a, "--after");
|
|
@@ -243,7 +280,7 @@ async function runMember(args) {
|
|
|
243
280
|
const a = normalizeArgv(rest);
|
|
244
281
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
245
282
|
const [org] = requirePositionalCount(a, [], {
|
|
246
|
-
min: 1, max: 1, command: "run402 org member list <
|
|
283
|
+
min: 1, max: 1, command: "run402 org member list <org_id>", missing: "Missing <org_id>.",
|
|
247
284
|
});
|
|
248
285
|
try {
|
|
249
286
|
console.log(JSON.stringify({ members: await getSdk().org(org).members.list() }, null, 2));
|
|
@@ -258,8 +295,8 @@ async function runMember(args) {
|
|
|
258
295
|
assertKnownFlags(a, ["--role", "--help", "-h"], ["--role"]);
|
|
259
296
|
const role = flagValue(a, "--role");
|
|
260
297
|
const [org, wallet] = requirePositionalCount(a, ["--role"], {
|
|
261
|
-
min: 2, max: 2, command: "run402 org member add <
|
|
262
|
-
missing: "Missing <
|
|
298
|
+
min: 2, max: 2, command: "run402 org member add <org_id> <wallet_address> [--role <role>]",
|
|
299
|
+
missing: "Missing <org_id> and/or <wallet_address>.",
|
|
263
300
|
});
|
|
264
301
|
try {
|
|
265
302
|
const res = await getSdk().org(org).members.add({ wallet, role: role || undefined });
|
|
@@ -274,8 +311,8 @@ async function runMember(args) {
|
|
|
274
311
|
const a = normalizeArgv(rest);
|
|
275
312
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
276
313
|
const [org, principalId, role] = requirePositionalCount(a, [], {
|
|
277
|
-
min: 3, max: 3, command: "run402 org member role <
|
|
278
|
-
missing: "Missing <
|
|
314
|
+
min: 3, max: 3, command: "run402 org member role <org_id> <principal_id> <role>",
|
|
315
|
+
missing: "Missing <org_id>, <principal_id>, and/or <role>.",
|
|
279
316
|
});
|
|
280
317
|
try {
|
|
281
318
|
console.log(JSON.stringify(await getSdk().org(org).members.setRole(principalId, { role }), null, 2));
|
|
@@ -289,8 +326,8 @@ async function runMember(args) {
|
|
|
289
326
|
const a = normalizeArgv(rest);
|
|
290
327
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
291
328
|
const [org, principalId] = requirePositionalCount(a, [], {
|
|
292
|
-
min: 2, max: 2, command: "run402 org member rm <
|
|
293
|
-
missing: "Missing <
|
|
329
|
+
min: 2, max: 2, command: "run402 org member rm <org_id> <principal_id>",
|
|
330
|
+
missing: "Missing <org_id> and/or <principal_id>.",
|
|
294
331
|
});
|
|
295
332
|
try {
|
|
296
333
|
console.log(JSON.stringify(await getSdk().org(org).members.revoke(principalId), null, 2));
|
|
@@ -321,7 +358,7 @@ async function runInvite(args) {
|
|
|
321
358
|
const a = normalizeArgv(rest);
|
|
322
359
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
323
360
|
const [org] = requirePositionalCount(a, [], {
|
|
324
|
-
min: 1, max: 1, command: "run402 org invite list <
|
|
361
|
+
min: 1, max: 1, command: "run402 org invite list <org_id>", missing: "Missing <org_id>.",
|
|
325
362
|
});
|
|
326
363
|
try {
|
|
327
364
|
console.log(JSON.stringify({ invites: await getSdk().org(org).invites.list() }, null, 2));
|
|
@@ -338,8 +375,8 @@ async function runInvite(args) {
|
|
|
338
375
|
const role = flagValue(a, "--role");
|
|
339
376
|
const ttlFlag = flagValue(a, "--ttl-hours");
|
|
340
377
|
const [org, email] = requirePositionalCount(a, valueFlags, {
|
|
341
|
-
min: 2, max: 2, command: "run402 org invite create <
|
|
342
|
-
missing: "Missing <
|
|
378
|
+
min: 2, max: 2, command: "run402 org invite create <org_id> <email> [--role <role>]",
|
|
379
|
+
missing: "Missing <org_id> and/or <email>.",
|
|
343
380
|
});
|
|
344
381
|
const inviteTtlHours = ttlFlag === null ? undefined : parseIntegerFlag("--ttl-hours", ttlFlag, { min: 1, max: 8760 });
|
|
345
382
|
try {
|
|
@@ -355,8 +392,8 @@ async function runInvite(args) {
|
|
|
355
392
|
const a = normalizeArgv(rest);
|
|
356
393
|
assertKnownFlags(a, ["--help", "-h"]);
|
|
357
394
|
const [org, principalId] = requirePositionalCount(a, [], {
|
|
358
|
-
min: 2, max: 2, command: "run402 org invite rm <
|
|
359
|
-
missing: "Missing <
|
|
395
|
+
min: 2, max: 2, command: "run402 org invite rm <org_id> <principal_id>",
|
|
396
|
+
missing: "Missing <org_id> and/or <principal_id>.",
|
|
360
397
|
});
|
|
361
398
|
try {
|
|
362
399
|
console.log(JSON.stringify(await getSdk().org(org).invites.revoke(principalId), null, 2));
|
|
@@ -393,6 +430,7 @@ export async function run(sub, args) {
|
|
|
393
430
|
case "list": await list(args); break;
|
|
394
431
|
case "get": await get(args); break;
|
|
395
432
|
case "rename": await rename(args); break;
|
|
433
|
+
case "payout-wallet": await payoutWallet(args); break;
|
|
396
434
|
case "whoami": await whoami(args); break;
|
|
397
435
|
case "audit": await audit(args); break;
|
|
398
436
|
default:
|
package/lib/projects.mjs
CHANGED
|
@@ -18,6 +18,7 @@ Subcommands:
|
|
|
18
18
|
use <id> Set the active project (used as default for other commands)
|
|
19
19
|
list [--org <id>] [--all] List your projects from the server (name, site_url, custom domains, org_id, active marker)
|
|
20
20
|
rename <id> --name <label> Rename a project (fix an auto-generated name)
|
|
21
|
+
tenant-payments [project_id] [--status <s>] List redacted tenant x402 payments for priced routes
|
|
21
22
|
get [id] Authoritative server read: status, org, tier, active deploy, mailbox, usage vs limits (live; no keys)
|
|
22
23
|
current Show the active project pointer and validation status
|
|
23
24
|
sql [id] "<query>" [--file <path>] [--params '<json>'] Run a SQL query (supports parameterized queries)
|
|
@@ -44,6 +45,7 @@ Examples:
|
|
|
44
45
|
run402 projects list --org 11111111-2222-3333-4444-555555555555
|
|
45
46
|
run402 projects list --all
|
|
46
47
|
run402 projects rename prj_abc123 --name "My Site"
|
|
48
|
+
run402 projects tenant-payments prj_abc123 --status settled
|
|
47
49
|
run402 projects get prj_abc123
|
|
48
50
|
run402 projects current
|
|
49
51
|
run402 projects sql prj_abc123 "SELECT * FROM users LIMIT 5"
|
|
@@ -150,6 +152,25 @@ Notes:
|
|
|
150
152
|
Examples:
|
|
151
153
|
run402 projects rename prj_abc123 --name "My Site"
|
|
152
154
|
`,
|
|
155
|
+
"tenant-payments": `run402 projects tenant-payments — List tenant x402 payments
|
|
156
|
+
|
|
157
|
+
Usage:
|
|
158
|
+
run402 projects tenant-payments [project_id] [--status <settling|settled|settle_failed|ambiguous>] [--limit N] [--after <cursor>]
|
|
159
|
+
|
|
160
|
+
Arguments:
|
|
161
|
+
[project_id] Project ID (defaults to the active project if omitted)
|
|
162
|
+
|
|
163
|
+
Options:
|
|
164
|
+
--status <s> Optional payment status filter
|
|
165
|
+
--limit N Page size (server default 50, max 200)
|
|
166
|
+
--after <cursor> Opaque cursor from a previous next_cursor
|
|
167
|
+
|
|
168
|
+
Notes:
|
|
169
|
+
- Requires project.tenant_payments.read: org developer+ or a read-scoped
|
|
170
|
+
project grant/delegate.
|
|
171
|
+
- Output is the gateway's redacted payment page. Raw X-PAYMENT headers,
|
|
172
|
+
authorization hashes, and internal metadata are never returned.
|
|
173
|
+
`,
|
|
153
174
|
current: `run402 projects current — Inspect active project selection
|
|
154
175
|
|
|
155
176
|
Usage:
|
|
@@ -544,6 +565,34 @@ async function rename(projectId, args = []) {
|
|
|
544
565
|
}
|
|
545
566
|
}
|
|
546
567
|
|
|
568
|
+
async function tenantPayments(projectId, args = []) {
|
|
569
|
+
const status = flagValue(args, "--status") ?? undefined;
|
|
570
|
+
const after = flagValue(args, "--after") ?? undefined;
|
|
571
|
+
const limitFlag = flagValue(args, "--limit");
|
|
572
|
+
const limit = limitFlag === null ? undefined : Number(limitFlag);
|
|
573
|
+
if (limitFlag !== null && (!Number.isInteger(limit) || limit <= 0 || limit > 200)) {
|
|
574
|
+
fail({
|
|
575
|
+
code: "BAD_FLAG",
|
|
576
|
+
message: `--limit must be an integer from 1 to 200; got ${limitFlag}.`,
|
|
577
|
+
details: { flag: "--limit", value: limitFlag },
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
const allowed = new Set(["settling", "settled", "settle_failed", "ambiguous"]);
|
|
581
|
+
if (status !== undefined && !allowed.has(status)) {
|
|
582
|
+
fail({
|
|
583
|
+
code: "BAD_FLAG",
|
|
584
|
+
message: `--status must be one of settling, settled, settle_failed, ambiguous; got ${status}.`,
|
|
585
|
+
details: { flag: "--status", value: status },
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
try {
|
|
589
|
+
const data = await getSdk().projects.listTenantPayments(projectId, { status, after, limit });
|
|
590
|
+
console.log(JSON.stringify(data, null, 2));
|
|
591
|
+
} catch (err) {
|
|
592
|
+
reportSdkError(err);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
547
596
|
async function get(projectId) {
|
|
548
597
|
try {
|
|
549
598
|
const data = await getSdk().projects.get(projectId);
|
|
@@ -793,6 +842,7 @@ const FLAGS_BY_SUB = {
|
|
|
793
842
|
},
|
|
794
843
|
list: { known: ["--org", "--all"], values: ["--org"] },
|
|
795
844
|
rename: { known: ["--name"], values: ["--name"] },
|
|
845
|
+
"tenant-payments": { known: ["--status", "--limit", "--after"], values: ["--status", "--limit", "--after"] },
|
|
796
846
|
sql: { known: ["--file", "--params"], values: ["--file", "--params"] },
|
|
797
847
|
costs: { known: ["--window"], values: ["--window"] },
|
|
798
848
|
"apply-expose": { known: ["--file"], values: ["--file"] },
|
|
@@ -839,6 +889,7 @@ export async function run(sub, args) {
|
|
|
839
889
|
case "list": await list(args); break;
|
|
840
890
|
case "current": await current(); break;
|
|
841
891
|
case "rename": { const { projectId, rest } = resolvePositionalProject(args, { rejectBareFirst: true, valueFlags: FLAGS_BY_SUB.rename.values }); await rename(projectId, rest); break; }
|
|
892
|
+
case "tenant-payments": { const { projectId, rest } = resolvePositionalProject(args, { rejectBareFirst: true, valueFlags: FLAGS_BY_SUB["tenant-payments"].values }); await tenantPayments(projectId, rest); break; }
|
|
842
893
|
case "get": { const { projectId } = resolvePositionalProject(args, { rejectBareFirst: true }); await get(projectId); break; }
|
|
843
894
|
case "info": commandMoved("info"); break;
|
|
844
895
|
case "keys": commandMoved("keys"); break;
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/namespaces/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/namespaces/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { isCiSessionCredentials } from "../ci-credentials.js";
|
|
22
22
|
import { assertCiDeployableSpec } from "./ci.js";
|
|
23
|
-
import { ROUTE_HTTP_METHODS, normalizeDeployResolveRequest, } from "./deploy.types.js";
|
|
23
|
+
import { ROUTE_PRICING_NETWORKS, ROUTE_HTTP_METHODS, normalizeDeployResolveRequest, } from "./deploy.types.js";
|
|
24
24
|
import { ApiError, LocalError, NetworkError, PaymentRequired, Run402DeployError, Unauthorized, isTransferFreezeError, } from "../errors.js";
|
|
25
25
|
import { assertAssetMetadata, assertExifPolicy, } from "./assets-validation.js";
|
|
26
26
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
@@ -2073,10 +2073,12 @@ const SITE_PUBLIC_PATHS_FIELDS = new Set(["mode", "replace"]);
|
|
|
2073
2073
|
const PUBLIC_STATIC_PATH_FIELDS = new Set(["asset", "cache_class"]);
|
|
2074
2074
|
const SUBDOMAINS_SPEC_FIELDS = new Set(["set", "add", "remove"]);
|
|
2075
2075
|
const ROUTES_SPEC_FIELDS = new Set(["replace"]);
|
|
2076
|
-
const ROUTE_ENTRY_FIELDS = new Set(["pattern", "methods", "target", "acknowledge_readonly"]);
|
|
2076
|
+
const ROUTE_ENTRY_FIELDS = new Set(["pattern", "methods", "target", "pricing", "acknowledge_readonly"]);
|
|
2077
2077
|
const FUNCTION_ROUTE_TARGET_FIELDS = new Set(["type", "name"]);
|
|
2078
2078
|
const STATIC_ROUTE_TARGET_FIELDS = new Set(["type", "file"]);
|
|
2079
2079
|
const ROUTE_METHOD_SET = new Set(ROUTE_HTTP_METHODS);
|
|
2080
|
+
const ROUTE_PRICING_FIELDS = new Set(["mode", "amount_usd_micros", "pay_to", "networks"]);
|
|
2081
|
+
const ROUTE_PRICING_NETWORK_SET = new Set(ROUTE_PRICING_NETWORKS);
|
|
2080
2082
|
const I18N_SPEC_FIELDS = new Set(["defaultLocale", "locales", "detect", "unknownLocalePolicy"]);
|
|
2081
2083
|
const I18N_LOCALE_TAG_REGEX = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
2082
2084
|
const I18N_COOKIE_NAME_REGEX = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
@@ -2493,11 +2495,48 @@ function validateRouteEntry(route, resource) {
|
|
|
2493
2495
|
}
|
|
2494
2496
|
}
|
|
2495
2497
|
const targetType = validateRouteTarget(entry.target, `${resource}.target`);
|
|
2498
|
+
validateRoutePricing(entry.pricing, resource, targetType);
|
|
2496
2499
|
validateRouteReadOnlyAcknowledgement(entry, targetType, resource);
|
|
2497
2500
|
if (targetType === "static") {
|
|
2498
2501
|
validateStaticRouteEntry(entry, resource);
|
|
2499
2502
|
}
|
|
2500
2503
|
}
|
|
2504
|
+
function validateRoutePricing(pricing, resource, targetType) {
|
|
2505
|
+
if (pricing === undefined)
|
|
2506
|
+
return;
|
|
2507
|
+
if (targetType !== "function") {
|
|
2508
|
+
throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing is only supported on function route targets`, `${resource}.pricing`);
|
|
2509
|
+
}
|
|
2510
|
+
const obj = requireObject(pricing, `${resource}.pricing`);
|
|
2511
|
+
validateKnownFields(obj, `${resource}.pricing`, ROUTE_PRICING_FIELDS);
|
|
2512
|
+
if (obj.mode !== "always") {
|
|
2513
|
+
throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing.mode must be "always"`, `${resource}.pricing.mode`);
|
|
2514
|
+
}
|
|
2515
|
+
if (typeof obj.amount_usd_micros !== "number" || !Number.isSafeInteger(obj.amount_usd_micros) || obj.amount_usd_micros <= 0) {
|
|
2516
|
+
throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing.amount_usd_micros must be a positive safe JSON integer`, `${resource}.pricing.amount_usd_micros`);
|
|
2517
|
+
}
|
|
2518
|
+
if (obj.pay_to !== "org_default_payout") {
|
|
2519
|
+
throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing.pay_to must be "org_default_payout"`, `${resource}.pricing.pay_to`);
|
|
2520
|
+
}
|
|
2521
|
+
if (obj.networks === undefined)
|
|
2522
|
+
return;
|
|
2523
|
+
if (!Array.isArray(obj.networks)) {
|
|
2524
|
+
throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing.networks must be an array`, `${resource}.pricing.networks`);
|
|
2525
|
+
}
|
|
2526
|
+
if (obj.networks.length === 0) {
|
|
2527
|
+
throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing.networks must not be empty; omit networks for production mainnet only`, `${resource}.pricing.networks`);
|
|
2528
|
+
}
|
|
2529
|
+
const seen = new Set();
|
|
2530
|
+
for (const network of obj.networks) {
|
|
2531
|
+
if (typeof network !== "string" || !ROUTE_PRICING_NETWORK_SET.has(network)) {
|
|
2532
|
+
throw invalidRouteSpec(`Unsupported route pricing network ${JSON.stringify(network)} at ReleaseSpec.${resource}.pricing.networks. Supported networks: ${ROUTE_PRICING_NETWORKS.join(", ")}`, `${resource}.pricing.networks`);
|
|
2533
|
+
}
|
|
2534
|
+
if (seen.has(network)) {
|
|
2535
|
+
throw invalidRouteSpec(`ReleaseSpec.${resource}.pricing.networks contains duplicate network ${JSON.stringify(network)}`, `${resource}.pricing.networks`);
|
|
2536
|
+
}
|
|
2537
|
+
seen.add(network);
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2501
2540
|
function validateRouteReadOnlyAcknowledgement(entry, targetType, resource) {
|
|
2502
2541
|
if (entry.acknowledge_readonly === undefined)
|
|
2503
2542
|
return;
|