run402 1.46.0 → 1.47.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 (3) hide show
  1. package/cli.mjs +0 -10
  2. package/package.json +1 -1
  3. package/lib/storage.mjs +0 -125
package/cli.mjs CHANGED
@@ -29,7 +29,6 @@ Commands:
29
29
  functions Manage serverless functions (deploy, invoke, logs, list, delete)
30
30
  secrets Manage project secrets (set, list, delete)
31
31
  blob Direct-to-S3 blob storage (put, get, ls, rm, sign, diagnose) — up to 5 TiB
32
- storage Legacy file storage (deprecated — sunset 2026-06-01, use 'blob')
33
32
  sites Deploy static sites
34
33
  cdn CloudFront CDN diagnostics (wait-fresh) for public blob URLs
35
34
  subdomains Manage custom subdomains (claim, list, delete)
@@ -116,15 +115,6 @@ switch (cmd) {
116
115
  await run(sub, rest);
117
116
  break;
118
117
  }
119
- case "storage": {
120
- process.stderr.write(
121
- "run402 storage is deprecated — sunset 2026-06-01. Use `run402 blob` instead.\n" +
122
- "See https://run402.com/docs/blob#migration\n\n",
123
- );
124
- const { run } = await import("./lib/storage.mjs");
125
- await run(sub, rest);
126
- break;
127
- }
128
118
  case "blob": {
129
119
  const { run } = await import("./lib/blob.mjs");
130
120
  await run(sub, rest);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "run402",
3
- "version": "1.46.0",
3
+ "version": "1.47.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": {
package/lib/storage.mjs DELETED
@@ -1,125 +0,0 @@
1
- import { readFileSync } from "fs";
2
- import { findProject, API } from "./config.mjs";
3
-
4
- const HELP = `run402 storage — Manage project file storage
5
-
6
- Usage:
7
- run402 storage <subcommand> [args...]
8
-
9
- Subcommands:
10
- upload <id> <bucket> <path> [--file <local>] [--content-type <mime>]
11
- Upload a file to storage
12
- download <id> <bucket> <path> Download a file from storage
13
- delete <id> <bucket> <path> Delete a file from storage
14
- list <id> <bucket> List files in a bucket
15
-
16
- Examples:
17
- run402 storage upload abc123 assets logo.png --file ./logo.png --content-type image/png
18
- echo "hello" | run402 storage upload abc123 data notes.txt
19
- run402 storage download abc123 assets logo.png
20
- run402 storage list abc123 assets
21
- run402 storage delete abc123 assets logo.png
22
-
23
- Notes:
24
- - <id> is the project_id from 'run402 projects list'
25
- - Upload reads from --file or stdin if no --file is given
26
- `;
27
-
28
- const SUB_HELP = {
29
- upload: `run402 storage upload — Upload a file to a project's storage bucket
30
-
31
- Usage:
32
- run402 storage upload <id> <bucket> <path> [--file <local>] [--content-type <mime>]
33
- echo "..." | run402 storage upload <id> <bucket> <path> [--content-type <mime>]
34
-
35
- Arguments:
36
- <id> Project ID (from 'run402 projects list')
37
- <bucket> Target bucket name
38
- <path> Destination path within the bucket
39
-
40
- Options:
41
- --file <local> Local file to upload; if omitted, content is read from stdin
42
- --content-type <mime> MIME type of the upload (default: text/plain)
43
-
44
- Examples:
45
- run402 storage upload abc123 assets logo.png --file ./logo.png \\
46
- --content-type image/png
47
- echo "hello" | run402 storage upload abc123 data notes.txt
48
- `,
49
- };
50
-
51
- async function readStdin() {
52
- const chunks = [];
53
- for await (const chunk of process.stdin) chunks.push(chunk);
54
- return Buffer.concat(chunks).toString("utf-8");
55
- }
56
-
57
- async function upload(projectId, bucket, path, args) {
58
- const p = findProject(projectId);
59
- const opts = { file: null, contentType: "text/plain" };
60
- for (let i = 0; i < args.length; i++) {
61
- if (args[i] === "--file" && args[i + 1]) opts.file = args[++i];
62
- if (args[i] === "--content-type" && args[i + 1]) opts.contentType = args[++i];
63
- }
64
- const content = opts.file ? readFileSync(opts.file, "utf-8") : await readStdin();
65
- const res = await fetch(`${API}/storage/v1/object/${bucket}/${path}`, {
66
- method: "POST",
67
- headers: { "Content-Type": opts.contentType, "apikey": p.anon_key, "Authorization": `Bearer ${p.anon_key}` },
68
- body: content,
69
- });
70
- const data = await res.json();
71
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
72
- console.log(JSON.stringify(data, null, 2));
73
- }
74
-
75
- async function download(projectId, bucket, path) {
76
- const p = findProject(projectId);
77
- const res = await fetch(`${API}/storage/v1/object/${bucket}/${path}`, {
78
- headers: { "apikey": p.anon_key, "Authorization": `Bearer ${p.anon_key}` },
79
- });
80
- if (!res.ok) {
81
- const data = await res.json().catch(() => ({}));
82
- console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1);
83
- }
84
- const text = await res.text();
85
- process.stdout.write(text);
86
- }
87
-
88
- async function deleteFile(projectId, bucket, path) {
89
- const p = findProject(projectId);
90
- const res = await fetch(`${API}/storage/v1/object/${bucket}/${path}`, {
91
- method: "DELETE",
92
- headers: { "apikey": p.anon_key, "Authorization": `Bearer ${p.anon_key}` },
93
- });
94
- if (res.status === 204 || res.ok) {
95
- console.log(JSON.stringify({ status: "ok", message: `File '${bucket}/${path}' deleted.` }));
96
- } else {
97
- const data = await res.json().catch(() => ({}));
98
- console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1);
99
- }
100
- }
101
-
102
- async function list(projectId, bucket) {
103
- const p = findProject(projectId);
104
- const res = await fetch(`${API}/storage/v1/object/list/${bucket}`, {
105
- headers: { "apikey": p.anon_key, "Authorization": `Bearer ${p.anon_key}` },
106
- });
107
- const data = await res.json();
108
- if (!res.ok) { console.error(JSON.stringify({ status: "error", http: res.status, ...data })); process.exit(1); }
109
- console.log(JSON.stringify(data, null, 2));
110
- }
111
-
112
- export async function run(sub, args) {
113
- if (!sub || sub === '--help' || sub === '-h') { console.log(HELP); process.exit(0); }
114
- if (Array.isArray(args) && (args.includes("--help") || args.includes("-h"))) { console.log(SUB_HELP[sub] || HELP); process.exit(0); }
115
- switch (sub) {
116
- case "upload": await upload(args[0], args[1], args[2], args.slice(3)); break;
117
- case "download": await download(args[0], args[1], args[2]); break;
118
- case "delete": await deleteFile(args[0], args[1], args[2]); break;
119
- case "list": await list(args[0], args[1]); break;
120
- default:
121
- console.error(`Unknown subcommand: ${sub}\n`);
122
- console.log(HELP);
123
- process.exit(1);
124
- }
125
- }