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.
- package/cli.mjs +0 -10
- package/package.json +1 -1
- 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
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
|
-
}
|