run402 1.17.0 → 1.18.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/cli.mjs CHANGED
@@ -44,7 +44,7 @@ Examples:
44
44
  run402 deploy --manifest app.json
45
45
  run402 projects list
46
46
  run402 projects sql <project_id> "SELECT * FROM users LIMIT 5"
47
- run402 functions deploy <project_id> my-fn --code handler.ts
47
+ run402 functions deploy <project_id> my-fn --file handler.ts
48
48
  run402 secrets set <project_id> API_KEY sk-1234
49
49
  run402 image generate "a startup mascot, pixel art" --output logo.png
50
50
 
package/lib/functions.mjs CHANGED
@@ -7,7 +7,7 @@ Usage:
7
7
  run402 functions <subcommand> [args...]
8
8
 
9
9
  Subcommands:
10
- deploy <id> <name> --code <file> [--timeout <s>] [--memory <mb>] [--deps <pkg,...>]
10
+ deploy <id> <name> --file <file> [--timeout <s>] [--memory <mb>] [--deps <pkg,...>]
11
11
  Deploy a function to a project
12
12
  invoke <id> <name> [--method <M>] [--body <json>]
13
13
  Invoke a deployed function
@@ -16,7 +16,7 @@ Subcommands:
16
16
  delete <id> <name> Delete a function
17
17
 
18
18
  Examples:
19
- run402 functions deploy abc123 stripe-webhook --code handler.ts
19
+ run402 functions deploy abc123 stripe-webhook --file handler.ts
20
20
  run402 functions invoke abc123 stripe-webhook --body '{"event":"test"}'
21
21
  run402 functions logs abc123 stripe-webhook --tail 100
22
22
  run402 functions list abc123
@@ -49,15 +49,15 @@ async function setupPaidFetch() {
49
49
 
50
50
  async function deploy(projectId, name, args) {
51
51
  const p = findProject(projectId);
52
- const opts = { code: null, timeout: undefined, memory: undefined, deps: undefined };
52
+ const opts = { file: null, timeout: undefined, memory: undefined, deps: undefined };
53
53
  for (let i = 0; i < args.length; i++) {
54
- if (args[i] === "--code" && args[i + 1]) opts.code = args[++i];
54
+ if (args[i] === "--file" && args[i + 1]) opts.file = args[++i];
55
55
  if (args[i] === "--timeout" && args[i + 1]) opts.timeout = parseInt(args[++i]);
56
56
  if (args[i] === "--memory" && args[i + 1]) opts.memory = parseInt(args[++i]);
57
57
  if (args[i] === "--deps" && args[i + 1]) opts.deps = args[++i].split(",");
58
58
  }
59
- if (!opts.code) { console.error(JSON.stringify({ status: "error", message: "Missing --code <file>" })); process.exit(1); }
60
- const code = readFileSync(opts.code, "utf-8");
59
+ if (!opts.file) { console.error(JSON.stringify({ status: "error", message: "Missing --file <file>" })); process.exit(1); }
60
+ const code = readFileSync(opts.file, "utf-8");
61
61
  const body = { name, code };
62
62
  if (opts.timeout || opts.memory) body.config = {};
63
63
  if (opts.timeout) body.config.timeout = opts.timeout;
package/lib/projects.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { readFileSync } from "fs";
1
2
  import { findProject, loadKeyStore, saveProject, removeProject, API, allowanceAuthHeaders, setActiveProjectId, getActiveProjectId } from "./config.mjs";
2
3
 
3
4
  const HELP = `run402 projects — Manage your deployed Run402 projects
@@ -12,7 +13,7 @@ Subcommands:
12
13
  list List all your projects (IDs, URLs, active marker)
13
14
  info <id> Show project details: REST URL, keys
14
15
  keys <id> Print anon_key and service_key as JSON
15
- sql <id> "<query>" Run a SQL query against a project's Postgres DB
16
+ sql <id> "<query>" [--file <path>] Run a SQL query against a project's Postgres DB
16
17
  rest <id> <table> [params] Query a table via the REST API (PostgREST)
17
18
  usage <id> Show compute/storage usage for a project
18
19
  schema <id> Inspect the database schema
@@ -28,6 +29,7 @@ Examples:
28
29
  run402 projects list
29
30
  run402 projects info abc123
30
31
  run402 projects sql abc123 "SELECT * FROM users LIMIT 5"
32
+ run402 projects sql abc123 --file setup.sql
31
33
  run402 projects rest abc123 users "limit=10&select=id,name"
32
34
  run402 projects usage abc123
33
35
  run402 projects schema abc123
@@ -115,9 +117,17 @@ async function keys(projectId) {
115
117
  console.log(JSON.stringify({ project_id: projectId, anon_key: p.anon_key, service_key: p.service_key }, null, 2));
116
118
  }
117
119
 
118
- async function sqlCmd(projectId, query) {
120
+ async function sqlCmd(projectId, args = []) {
119
121
  const p = findProject(projectId);
120
- const res = await fetch(`${API}/projects/v1/admin/${projectId}/sql`, { method: "POST", headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "text/plain" }, body: query });
122
+ let file = null;
123
+ let query = null;
124
+ for (let i = 0; i < args.length; i++) {
125
+ if (args[i] === "--file" && args[i + 1]) { file = args[++i]; }
126
+ else if (!query && !args[i].startsWith("--")) { query = args[i]; }
127
+ }
128
+ const sql = file ? readFileSync(file, "utf-8") : query;
129
+ if (!sql) { console.error(JSON.stringify({ status: "error", message: "Missing SQL query. Provide inline or use --file <path>" })); process.exit(1); }
130
+ const res = await fetch(`${API}/projects/v1/admin/${projectId}/sql`, { method: "POST", headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "text/plain" }, body: sql });
121
131
  console.log(JSON.stringify(await res.json(), null, 2));
122
132
  }
123
133
 
@@ -193,7 +203,7 @@ export async function run(sub, args) {
193
203
  case "list": await list(); break;
194
204
  case "info": await info(args[0]); break;
195
205
  case "keys": await keys(args[0]); break;
196
- case "sql": await sqlCmd(args[0], args[1]); break;
206
+ case "sql": await sqlCmd(args[0], args.slice(1)); break;
197
207
  case "rest": await rest(args[0], args[1], args[2]); break;
198
208
  case "usage": await usage(args[0]); break;
199
209
  case "schema": await schema(args[0]); break;
package/lib/secrets.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { readFileSync } from "fs";
1
2
  import { findProject, API } from "./config.mjs";
2
3
 
3
4
  const HELP = `run402 secrets — Manage project secrets
@@ -6,12 +7,13 @@ Usage:
6
7
  run402 secrets <subcommand> [args...]
7
8
 
8
9
  Subcommands:
9
- set <id> <key> <value> Set a secret on a project
10
+ set <id> <key> <value> [--file <path>] Set a secret on a project
10
11
  list <id> List all secrets for a project
11
12
  delete <id> <key> Delete a secret from a project
12
13
 
13
14
  Examples:
14
15
  run402 secrets set abc123 STRIPE_KEY sk-1234
16
+ run402 secrets set abc123 TLS_CERT --file cert.pem
15
17
  run402 secrets list abc123
16
18
  run402 secrets delete abc123 STRIPE_KEY
17
19
 
@@ -20,12 +22,20 @@ Notes:
20
22
  - Values are never shown after being set
21
23
  `;
22
24
 
23
- async function set(projectId, key, value) {
25
+ async function set(projectId, key, args = []) {
24
26
  const p = findProject(projectId);
27
+ let file = null;
28
+ let value = null;
29
+ for (let i = 0; i < args.length; i++) {
30
+ if (args[i] === "--file" && args[i + 1]) { file = args[++i]; }
31
+ else if (!value && !args[i].startsWith("--")) { value = args[i]; }
32
+ }
33
+ const val = file ? readFileSync(file, "utf-8") : value;
34
+ if (!val) { console.error(JSON.stringify({ status: "error", message: "Missing secret value. Provide inline or use --file <path>" })); process.exit(1); }
25
35
  const res = await fetch(`${API}/projects/v1/admin/${projectId}/secrets`, {
26
36
  method: "POST",
27
37
  headers: { "Authorization": `Bearer ${p.service_key}`, "Content-Type": "application/json" },
28
- body: JSON.stringify({ key, value }),
38
+ body: JSON.stringify({ key, value: val }),
29
39
  });
30
40
  const data = await res.json();
31
41
  if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
@@ -59,7 +69,7 @@ async function deleteSecret(projectId, key) {
59
69
  export async function run(sub, args) {
60
70
  if (!sub || sub === '--help' || sub === '-h') { console.log(HELP); process.exit(0); }
61
71
  switch (sub) {
62
- case "set": await set(args[0], args[1], args[2]); break;
72
+ case "set": await set(args[0], args[1], args.slice(2)); break;
63
73
  case "list": await list(args[0]); break;
64
74
  case "delete": await deleteSecret(args[0], args[1]); break;
65
75
  default:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "1.17.0",
3
+ "version": "1.18.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": {