run402 1.22.0 → 1.23.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.
Files changed (2) hide show
  1. package/lib/projects.mjs +31 -1
  2. package/package.json +1 -1
package/lib/projects.mjs CHANGED
@@ -20,6 +20,8 @@ Subcommands:
20
20
  rls <id> <template> <tables_json> Apply Row-Level Security policies
21
21
  delete <id> Delete a project and remove it from local state
22
22
  pin <id> Pin a project (prevents expiry/GC)
23
+ promote-user <id> <email> Promote a user to project_admin role
24
+ demote-user <id> <email> Demote a user from project_admin role
23
25
 
24
26
  Examples:
25
27
  run402 projects quote
@@ -190,6 +192,32 @@ async function pin(projectId) {
190
192
  console.log(JSON.stringify(data, null, 2));
191
193
  }
192
194
 
195
+ async function promoteUser(projectId, email) {
196
+ if (!email) { console.error(JSON.stringify({ status: "error", message: "Usage: run402 projects promote-user <project_id> <email>" })); process.exit(1); }
197
+ const p = findProject(projectId);
198
+ const res = await fetch(`${API}/projects/v1/admin/${projectId}/promote-user`, {
199
+ method: "POST",
200
+ headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "application/json" },
201
+ body: JSON.stringify({ email }),
202
+ });
203
+ const data = await res.json();
204
+ if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
205
+ console.log(JSON.stringify(data, null, 2));
206
+ }
207
+
208
+ async function demoteUser(projectId, email) {
209
+ if (!email) { console.error(JSON.stringify({ status: "error", message: "Usage: run402 projects demote-user <project_id> <email>" })); process.exit(1); }
210
+ const p = findProject(projectId);
211
+ const res = await fetch(`${API}/projects/v1/admin/${projectId}/demote-user`, {
212
+ method: "POST",
213
+ headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "application/json" },
214
+ body: JSON.stringify({ email }),
215
+ });
216
+ const data = await res.json();
217
+ if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
218
+ console.log(JSON.stringify(data, null, 2));
219
+ }
220
+
193
221
  async function deleteProject(projectId) {
194
222
  const p = findProject(projectId);
195
223
  const res = await fetch(`${API}/projects/v1/${projectId}`, { method: "DELETE", headers: { "Authorization": `Bearer ${p.service_key}` } });
@@ -220,7 +248,9 @@ export async function run(sub, args) {
220
248
  case "schema": await schema(args[0]); break;
221
249
  case "rls": await rls(args[0], args[1], args[2]); break;
222
250
  case "delete": await deleteProject(args[0]); break;
223
- case "pin": await pin(args[0]); break;
251
+ case "pin": await pin(args[0]); break;
252
+ case "promote-user": await promoteUser(args[0], args[1]); break;
253
+ case "demote-user": await demoteUser(args[0], args[1]); break;
224
254
  default:
225
255
  console.error(`Unknown subcommand: ${sub}\n`);
226
256
  console.log(HELP);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "1.22.0",
3
+ "version": "1.23.0",
4
4
  "description": "CLI for Run402 — provision Postgres databases, deploy static sites, generate images, and manage wallets via x402 and MPP micropayments.",
5
5
  "type": "module",
6
6
  "bin": {