flingit 0.0.12 → 0.0.14
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/README.md +8 -1
- package/dist/cli/commands/db.d.ts +11 -0
- package/dist/cli/commands/db.d.ts.map +1 -1
- package/dist/cli/commands/db.js +60 -48
- package/dist/cli/commands/db.js.map +1 -1
- package/dist/cli/commands/dev.d.ts +9 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +96 -100
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/feedback.d.ts +23 -0
- package/dist/cli/commands/feedback.d.ts.map +1 -1
- package/dist/cli/commands/feedback.js +60 -73
- package/dist/cli/commands/feedback.js.map +1 -1
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +96 -107
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/launch.d.ts +11 -1
- package/dist/cli/commands/launch.d.ts.map +1 -1
- package/dist/cli/commands/launch.js +32 -36
- package/dist/cli/commands/launch.js.map +1 -1
- package/dist/cli/commands/login.d.ts +30 -0
- package/dist/cli/commands/login.d.ts.map +1 -1
- package/dist/cli/commands/login.js +71 -58
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/cli/commands/logout.js +1 -1
- package/dist/cli/commands/logs.d.ts +39 -0
- package/dist/cli/commands/logs.d.ts.map +1 -1
- package/dist/cli/commands/logs.js +121 -90
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/commands/onboard.d.ts +1 -1
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/onboard.js +97 -42
- package/dist/cli/commands/onboard.js.map +1 -1
- package/dist/cli/commands/plugin.d.ts +43 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -1
- package/dist/cli/commands/plugin.js +229 -211
- package/dist/cli/commands/plugin.js.map +1 -1
- package/dist/cli/commands/project.d.ts +27 -0
- package/dist/cli/commands/project.d.ts.map +1 -1
- package/dist/cli/commands/project.js +101 -85
- package/dist/cli/commands/project.js.map +1 -1
- package/dist/cli/commands/push.d.ts +39 -0
- package/dist/cli/commands/push.d.ts.map +1 -1
- package/dist/cli/commands/push.js +152 -118
- package/dist/cli/commands/push.js.map +1 -1
- package/dist/cli/commands/register.js +1 -1
- package/dist/cli/commands/storage.d.ts +32 -0
- package/dist/cli/commands/storage.d.ts.map +1 -1
- package/dist/cli/commands/storage.js +180 -140
- package/dist/cli/commands/storage.js.map +1 -1
- package/dist/cli/commands/tunnel.d.ts +41 -0
- package/dist/cli/commands/tunnel.d.ts.map +1 -0
- package/dist/cli/commands/tunnel.js +210 -0
- package/dist/cli/commands/tunnel.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +15 -0
- package/dist/cli/commands/upgrade.d.ts.map +1 -0
- package/dist/cli/commands/upgrade.js +82 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/index.js +35 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/cli-io-impl.d.ts +64 -0
- package/dist/cli/utils/cli-io-impl.d.ts.map +1 -0
- package/dist/cli/utils/cli-io-impl.js +521 -0
- package/dist/cli/utils/cli-io-impl.js.map +1 -0
- package/dist/cli/utils/cli-io.d.ts +350 -0
- package/dist/cli/utils/cli-io.d.ts.map +1 -0
- package/dist/cli/utils/cli-io.js +13 -0
- package/dist/cli/utils/cli-io.js.map +1 -0
- package/dist/cli/utils/config.d.ts +60 -2
- package/dist/cli/utils/config.d.ts.map +1 -1
- package/dist/cli/utils/config.js +158 -37
- package/dist/cli/utils/config.js.map +1 -1
- package/dist/cli/utils/project.d.ts +60 -0
- package/dist/cli/utils/project.d.ts.map +1 -1
- package/dist/cli/utils/project.js +112 -2
- package/dist/cli/utils/project.js.map +1 -1
- package/dist/cli/utils/prompt-new-project.d.ts +1 -1
- package/dist/cli/utils/prompt-new-project.d.ts.map +1 -1
- package/dist/cli/utils/registry.d.ts +2 -2
- package/dist/cli/utils/registry.d.ts.map +1 -1
- package/dist/cli/utils/registry.js +13 -3
- package/dist/cli/utils/registry.js.map +1 -1
- package/dist/runtime/log.d.ts.map +1 -1
- package/dist/runtime/log.js +8 -4
- package/dist/runtime/log.js.map +1 -1
- package/dist/runtime/storage.js +1 -1
- package/dist/runtime/storage.js.map +1 -1
- package/package.json +3 -2
- package/templates/default/CLAUDE.md +1 -0
- package/templates/default/skills/fling/.hash +1 -0
- package/templates/default/skills/fling/SKILL.md +12 -4
- /package/templates/default/skills/{discord/SKILL.md → fling/DISCORD.md} +0 -0
|
@@ -6,5 +6,37 @@
|
|
|
6
6
|
* - Use --prod to operate on production R2 storage
|
|
7
7
|
*/
|
|
8
8
|
import { Command } from "commander";
|
|
9
|
+
import type { StorageIO } from "../utils/cli-io.js";
|
|
10
|
+
/**
|
|
11
|
+
* Check if project is initialized.
|
|
12
|
+
*/
|
|
13
|
+
export declare function checkProject(io: StorageIO): void;
|
|
9
14
|
export declare const storageCommand: Command;
|
|
15
|
+
/**
|
|
16
|
+
* List objects in storage.
|
|
17
|
+
*/
|
|
18
|
+
export declare function listStorage(prefix: string | undefined, options: {
|
|
19
|
+
json?: boolean;
|
|
20
|
+
limit: string;
|
|
21
|
+
}, env: "local" | "prod", io: StorageIO): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Upload a file to storage.
|
|
24
|
+
*/
|
|
25
|
+
export declare function putStorage(key: string, file: string, options: {
|
|
26
|
+
contentType?: string;
|
|
27
|
+
}, env: "local" | "prod", io: StorageIO): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Download an object from storage.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getStorage(key: string, output: string | undefined, env: "local" | "prod", io: StorageIO): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Delete an object from storage.
|
|
34
|
+
*/
|
|
35
|
+
export declare function deleteStorage(key: string, options: {
|
|
36
|
+
yes?: boolean;
|
|
37
|
+
}, env: "local" | "prod", io: StorageIO): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Show storage information and usage.
|
|
40
|
+
*/
|
|
41
|
+
export declare function infoStorage(env: "local" | "prod", io: StorageIO): Promise<void>;
|
|
10
42
|
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/storage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/storage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAuBpD;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,SAAS,GAAG,IAAI,CAKhD;AAuBD,eAAO,MAAM,cAAc,SAmBxB,CAAC;AAMJ;;GAEG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAC1C,GAAG,EAAE,OAAO,GAAG,MAAM,EACrB,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,IAAI,CAAC,CA+Gf;AAoBD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EACjC,GAAG,EAAE,OAAO,GAAG,MAAM,EACrB,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,IAAI,CAAC,CAwEf;AAmBD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,GAAG,EAAE,OAAO,GAAG,MAAM,EACrB,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,IAAI,CAAC,CAgEf;AAkBD;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,EAC1B,GAAG,EAAE,OAAO,GAAG,MAAM,EACrB,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,IAAI,CAAC,CAiDf;AAmBD;;GAEG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,OAAO,GAAG,MAAM,EACrB,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,IAAI,CAAC,CAiEf"}
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* - Use --prod to operate on production R2 storage
|
|
7
7
|
*/
|
|
8
8
|
import { Command } from "commander";
|
|
9
|
-
import { existsSync, readFileSync, writeFileSync, statSync, } from "node:fs";
|
|
10
9
|
import { join } from "node:path";
|
|
11
10
|
import { platformFetch } from "../utils/config.js";
|
|
12
11
|
import { getTargetEnv, requireProdAuth } from "../utils/environment.js";
|
|
13
12
|
import { storage } from "../../runtime/storage.js";
|
|
13
|
+
import { defaultStorageIO } from "../utils/cli-io-impl.js";
|
|
14
14
|
// ============================================================================
|
|
15
15
|
// Helpers
|
|
16
16
|
// ============================================================================
|
|
@@ -33,10 +33,10 @@ function formatDate(date) {
|
|
|
33
33
|
/**
|
|
34
34
|
* Check if project is initialized.
|
|
35
35
|
*/
|
|
36
|
-
function checkProject() {
|
|
37
|
-
if (!
|
|
38
|
-
console.error("Error: Not a Fling project. Run 'fling init' first.");
|
|
39
|
-
process.exit(1);
|
|
36
|
+
export function checkProject(io) {
|
|
37
|
+
if (!io.file.exists(join(io.process.cwd(), ".fling"))) {
|
|
38
|
+
io.console.error("Error: Not a Fling project. Run 'fling init' first.");
|
|
39
|
+
io.process.exit(1);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
@@ -74,17 +74,12 @@ Examples:
|
|
|
74
74
|
// ============================================================================
|
|
75
75
|
// storage list
|
|
76
76
|
// ============================================================================
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
.option("--limit <n>", "Maximum objects to return", "100")
|
|
82
|
-
.action(async (prefix, options, command) => {
|
|
83
|
-
checkProject();
|
|
84
|
-
const env = getTargetEnv(command);
|
|
77
|
+
/**
|
|
78
|
+
* List objects in storage.
|
|
79
|
+
*/
|
|
80
|
+
export async function listStorage(prefix, options, env, io) {
|
|
85
81
|
const limit = parseInt(options.limit, 10);
|
|
86
82
|
if (env === "prod") {
|
|
87
|
-
requireProdAuth(env);
|
|
88
83
|
try {
|
|
89
84
|
const projectName = await getProjectName();
|
|
90
85
|
const params = new URLSearchParams();
|
|
@@ -94,12 +89,12 @@ storageCommand
|
|
|
94
89
|
const response = await platformFetch(`/project/${encodeURIComponent(projectName)}/storage?${params.toString()}`);
|
|
95
90
|
if (!response.ok) {
|
|
96
91
|
const data = (await response.json());
|
|
97
|
-
console.error(`Error: ${data.error ?? `API error: ${response.status}`}`);
|
|
98
|
-
process.exit(1);
|
|
92
|
+
io.console.error(`Error: ${data.error ?? `API error: ${response.status}`}`);
|
|
93
|
+
io.process.exit(1);
|
|
99
94
|
}
|
|
100
95
|
const data = (await response.json());
|
|
101
96
|
if (options.json) {
|
|
102
|
-
console.log(JSON.stringify({
|
|
97
|
+
io.console.log(JSON.stringify({
|
|
103
98
|
objects: data.objects,
|
|
104
99
|
count: data.objects.length,
|
|
105
100
|
totalSize: data.objects.reduce((sum, o) => sum + o.size, 0),
|
|
@@ -108,27 +103,27 @@ storageCommand
|
|
|
108
103
|
}
|
|
109
104
|
else {
|
|
110
105
|
if (data.objects.length === 0) {
|
|
111
|
-
console.log("No objects in storage.");
|
|
106
|
+
io.console.log("No objects in storage.");
|
|
112
107
|
return;
|
|
113
108
|
}
|
|
114
|
-
console.log("Objects in production storage:\n");
|
|
109
|
+
io.console.log("Objects in production storage:\n");
|
|
115
110
|
let totalSize = 0;
|
|
116
111
|
for (const obj of data.objects) {
|
|
117
112
|
const size = formatBytes(obj.size).padStart(10);
|
|
118
113
|
const date = formatDate(new Date(obj.uploaded));
|
|
119
|
-
console.log(` ${obj.key.padEnd(40)} ${size} ${date}`);
|
|
114
|
+
io.console.log(` ${obj.key.padEnd(40)} ${size} ${date}`);
|
|
120
115
|
totalSize += obj.size;
|
|
121
116
|
}
|
|
122
|
-
console.log("");
|
|
123
|
-
console.log(`${data.objects.length} objects, ${formatBytes(totalSize)} total`);
|
|
117
|
+
io.console.log("");
|
|
118
|
+
io.console.log(`${data.objects.length} objects, ${formatBytes(totalSize)} total`);
|
|
124
119
|
if (data.truncated) {
|
|
125
|
-
console.log(`(more objects available, use --limit to increase)`);
|
|
120
|
+
io.console.log(`(more objects available, use --limit to increase)`);
|
|
126
121
|
}
|
|
127
122
|
}
|
|
128
123
|
}
|
|
129
124
|
catch (error) {
|
|
130
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
131
|
-
process.exit(1);
|
|
125
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
126
|
+
io.process.exit(1);
|
|
132
127
|
}
|
|
133
128
|
}
|
|
134
129
|
else {
|
|
@@ -139,7 +134,7 @@ storageCommand
|
|
|
139
134
|
listOptions.prefix = prefix;
|
|
140
135
|
const result = await storage.list(listOptions);
|
|
141
136
|
if (options.json) {
|
|
142
|
-
console.log(JSON.stringify({
|
|
137
|
+
io.console.log(JSON.stringify({
|
|
143
138
|
objects: result.objects.map((o) => ({
|
|
144
139
|
key: o.key,
|
|
145
140
|
size: o.size,
|
|
@@ -153,69 +148,78 @@ storageCommand
|
|
|
153
148
|
}
|
|
154
149
|
else {
|
|
155
150
|
if (result.objects.length === 0) {
|
|
156
|
-
console.log("No objects in storage.");
|
|
151
|
+
io.console.log("No objects in storage.");
|
|
157
152
|
return;
|
|
158
153
|
}
|
|
159
|
-
console.log("Objects in local storage:\n");
|
|
154
|
+
io.console.log("Objects in local storage:\n");
|
|
160
155
|
let totalSize = 0;
|
|
161
156
|
for (const obj of result.objects) {
|
|
162
157
|
const size = formatBytes(obj.size).padStart(10);
|
|
163
158
|
const date = formatDate(obj.uploaded);
|
|
164
|
-
console.log(` ${obj.key.padEnd(40)} ${size} ${date}`);
|
|
159
|
+
io.console.log(` ${obj.key.padEnd(40)} ${size} ${date}`);
|
|
165
160
|
totalSize += obj.size;
|
|
166
161
|
}
|
|
167
|
-
console.log("");
|
|
168
|
-
console.log(`${result.objects.length} objects, ${formatBytes(totalSize)} total`);
|
|
162
|
+
io.console.log("");
|
|
163
|
+
io.console.log(`${result.objects.length} objects, ${formatBytes(totalSize)} total`);
|
|
169
164
|
if (result.truncated) {
|
|
170
|
-
console.log(`(more objects available, use --limit to increase)`);
|
|
165
|
+
io.console.log(`(more objects available, use --limit to increase)`);
|
|
171
166
|
}
|
|
172
167
|
}
|
|
173
168
|
}
|
|
174
169
|
catch (error) {
|
|
175
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
176
|
-
process.exit(1);
|
|
170
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
171
|
+
io.process.exit(1);
|
|
177
172
|
}
|
|
178
173
|
}
|
|
174
|
+
}
|
|
175
|
+
storageCommand
|
|
176
|
+
.command("list [prefix]")
|
|
177
|
+
.description("List objects in storage")
|
|
178
|
+
.option("--json", "Output as JSON")
|
|
179
|
+
.option("--limit <n>", "Maximum objects to return", "100")
|
|
180
|
+
.action(async (prefix, options, command) => {
|
|
181
|
+
checkProject(defaultStorageIO);
|
|
182
|
+
const env = getTargetEnv(command);
|
|
183
|
+
if (env === "prod") {
|
|
184
|
+
requireProdAuth(env);
|
|
185
|
+
}
|
|
186
|
+
await listStorage(prefix, options, env, defaultStorageIO);
|
|
179
187
|
});
|
|
180
188
|
// ============================================================================
|
|
181
189
|
// storage put
|
|
182
190
|
// ============================================================================
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
.action(async (key, file, options, command) => {
|
|
188
|
-
checkProject();
|
|
189
|
-
const env = getTargetEnv(command);
|
|
191
|
+
/**
|
|
192
|
+
* Upload a file to storage.
|
|
193
|
+
*/
|
|
194
|
+
export async function putStorage(key, file, options, env, io) {
|
|
190
195
|
// Read from stdin if file is "-"
|
|
191
196
|
let content;
|
|
192
197
|
const contentType = options.contentType;
|
|
193
198
|
if (file === "-") {
|
|
194
199
|
// Read from stdin
|
|
195
200
|
const chunks = [];
|
|
196
|
-
for await (const chunk of process.stdin) {
|
|
201
|
+
for await (const chunk of io.process.stdin) {
|
|
197
202
|
chunks.push(chunk);
|
|
198
203
|
}
|
|
199
204
|
content = Buffer.concat(chunks);
|
|
200
205
|
}
|
|
201
206
|
else {
|
|
202
207
|
// Read from file
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
208
|
+
const fileContent = io.file.readFileBuffer(file);
|
|
209
|
+
if (fileContent === null) {
|
|
210
|
+
io.console.error(`Error: File not found: ${file}`);
|
|
211
|
+
io.process.exit(1);
|
|
206
212
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
process.exit(1);
|
|
213
|
+
if (fileContent.length > 100 * 1024 * 1024) {
|
|
214
|
+
io.console.error("Error: File too large (maximum 100 MB).");
|
|
215
|
+
io.process.exit(1);
|
|
211
216
|
}
|
|
212
|
-
content =
|
|
217
|
+
content = fileContent;
|
|
213
218
|
}
|
|
214
219
|
if (env === "prod") {
|
|
215
|
-
requireProdAuth(env);
|
|
216
220
|
try {
|
|
217
221
|
const projectName = await getProjectName();
|
|
218
|
-
console.log(`Uploading ${key}...`);
|
|
222
|
+
io.console.log(`Uploading ${key}...`);
|
|
219
223
|
const headers = {};
|
|
220
224
|
if (contentType) {
|
|
221
225
|
headers["Content-Type"] = contentType;
|
|
@@ -227,52 +231,61 @@ storageCommand
|
|
|
227
231
|
});
|
|
228
232
|
if (!response.ok) {
|
|
229
233
|
const data = (await response.json());
|
|
230
|
-
console.error(`Error: ${data.error ?? `API error: ${response.status}`}`);
|
|
231
|
-
process.exit(1);
|
|
234
|
+
io.console.error(`Error: ${data.error ?? `API error: ${response.status}`}`);
|
|
235
|
+
io.process.exit(1);
|
|
232
236
|
}
|
|
233
237
|
const data = (await response.json());
|
|
234
|
-
console.log(` ${formatBytes(data.size)} uploaded\n`);
|
|
235
|
-
console.log(`Object stored: ${data.key} (${data.size} bytes)`);
|
|
238
|
+
io.console.log(` ${formatBytes(data.size)} uploaded\n`);
|
|
239
|
+
io.console.log(`Object stored: ${data.key} (${data.size} bytes)`);
|
|
236
240
|
}
|
|
237
241
|
catch (error) {
|
|
238
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
239
|
-
process.exit(1);
|
|
242
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
243
|
+
io.process.exit(1);
|
|
240
244
|
}
|
|
241
245
|
}
|
|
242
246
|
else {
|
|
243
247
|
// Local storage
|
|
244
248
|
try {
|
|
245
|
-
console.log(`Uploading ${key}...`);
|
|
249
|
+
io.console.log(`Uploading ${key}...`);
|
|
246
250
|
const putOptions = {};
|
|
247
251
|
if (contentType)
|
|
248
252
|
putOptions.contentType = contentType;
|
|
249
253
|
const result = await storage.put(key, content, putOptions);
|
|
250
|
-
console.log(` ${formatBytes(result.size)} uploaded\n`);
|
|
251
|
-
console.log(`Object stored: ${result.key} (${result.size} bytes)`);
|
|
254
|
+
io.console.log(` ${formatBytes(result.size)} uploaded\n`);
|
|
255
|
+
io.console.log(`Object stored: ${result.key} (${result.size} bytes)`);
|
|
252
256
|
}
|
|
253
257
|
catch (error) {
|
|
254
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
255
|
-
process.exit(1);
|
|
258
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
259
|
+
io.process.exit(1);
|
|
256
260
|
}
|
|
257
261
|
}
|
|
262
|
+
}
|
|
263
|
+
storageCommand
|
|
264
|
+
.command("put <key> <file>")
|
|
265
|
+
.description("Upload a file to storage")
|
|
266
|
+
.option("--content-type <type>", "Override MIME type")
|
|
267
|
+
.action(async (key, file, options, command) => {
|
|
268
|
+
checkProject(defaultStorageIO);
|
|
269
|
+
const env = getTargetEnv(command);
|
|
270
|
+
if (env === "prod") {
|
|
271
|
+
requireProdAuth(env);
|
|
272
|
+
}
|
|
273
|
+
await putStorage(key, file, options, env, defaultStorageIO);
|
|
258
274
|
});
|
|
259
275
|
// ============================================================================
|
|
260
276
|
// storage get
|
|
261
277
|
// ============================================================================
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
checkProject();
|
|
267
|
-
const env = getTargetEnv(command);
|
|
278
|
+
/**
|
|
279
|
+
* Download an object from storage.
|
|
280
|
+
*/
|
|
281
|
+
export async function getStorage(key, output, env, io) {
|
|
268
282
|
if (env === "prod") {
|
|
269
|
-
requireProdAuth(env);
|
|
270
283
|
try {
|
|
271
284
|
const projectName = await getProjectName();
|
|
272
285
|
const response = await platformFetch(`/project/${encodeURIComponent(projectName)}/storage/${encodeURIComponent(key)}`);
|
|
273
286
|
if (response.status === 404) {
|
|
274
|
-
console.error(`Error: Object not found: ${key}`);
|
|
275
|
-
process.exit(1);
|
|
287
|
+
io.console.error(`Error: Object not found: ${key}`);
|
|
288
|
+
io.process.exit(1);
|
|
276
289
|
}
|
|
277
290
|
if (!response.ok) {
|
|
278
291
|
let errorMessage = `API error: ${response.status}`;
|
|
@@ -284,24 +297,24 @@ storageCommand
|
|
|
284
297
|
catch {
|
|
285
298
|
// Ignore JSON parse errors
|
|
286
299
|
}
|
|
287
|
-
console.error(`Error: ${errorMessage}`);
|
|
288
|
-
process.exit(1);
|
|
300
|
+
io.console.error(`Error: ${errorMessage}`);
|
|
301
|
+
io.process.exit(1);
|
|
289
302
|
}
|
|
290
303
|
const buffer = Buffer.from(await response.arrayBuffer());
|
|
291
304
|
if (output) {
|
|
292
|
-
console.error(`Downloading ${key}...`);
|
|
293
|
-
|
|
294
|
-
console.error(` ${formatBytes(buffer.length)} downloaded\n`);
|
|
295
|
-
console.error(`Saved to: ${output}`);
|
|
305
|
+
io.console.error(`Downloading ${key}...`);
|
|
306
|
+
io.file.writeFileBuffer(output, buffer);
|
|
307
|
+
io.console.error(` ${formatBytes(buffer.length)} downloaded\n`);
|
|
308
|
+
io.console.error(`Saved to: ${output}`);
|
|
296
309
|
}
|
|
297
310
|
else {
|
|
298
311
|
// Write to stdout
|
|
299
|
-
process.stdout.write(buffer);
|
|
312
|
+
io.process.stdout.write(buffer);
|
|
300
313
|
}
|
|
301
314
|
}
|
|
302
315
|
catch (error) {
|
|
303
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
304
|
-
process.exit(1);
|
|
316
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
317
|
+
io.process.exit(1);
|
|
305
318
|
}
|
|
306
319
|
}
|
|
307
320
|
else {
|
|
@@ -309,45 +322,52 @@ storageCommand
|
|
|
309
322
|
try {
|
|
310
323
|
const obj = await storage.get(key);
|
|
311
324
|
if (!obj) {
|
|
312
|
-
console.error(`Error: Object not found: ${key}`);
|
|
313
|
-
process.exit(1);
|
|
325
|
+
io.console.error(`Error: Object not found: ${key}`);
|
|
326
|
+
io.process.exit(1);
|
|
314
327
|
}
|
|
315
328
|
const buffer = Buffer.from(await obj.arrayBuffer());
|
|
316
329
|
if (output) {
|
|
317
|
-
console.error(`Downloading ${key}...`);
|
|
318
|
-
|
|
319
|
-
console.error(` ${formatBytes(buffer.length)} downloaded\n`);
|
|
320
|
-
console.error(`Saved to: ${output}`);
|
|
330
|
+
io.console.error(`Downloading ${key}...`);
|
|
331
|
+
io.file.writeFileBuffer(output, buffer);
|
|
332
|
+
io.console.error(` ${formatBytes(buffer.length)} downloaded\n`);
|
|
333
|
+
io.console.error(`Saved to: ${output}`);
|
|
321
334
|
}
|
|
322
335
|
else {
|
|
323
336
|
// Write to stdout
|
|
324
|
-
process.stdout.write(buffer);
|
|
337
|
+
io.process.stdout.write(buffer);
|
|
325
338
|
}
|
|
326
339
|
}
|
|
327
340
|
catch (error) {
|
|
328
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
329
|
-
process.exit(1);
|
|
341
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
342
|
+
io.process.exit(1);
|
|
330
343
|
}
|
|
331
344
|
}
|
|
345
|
+
}
|
|
346
|
+
storageCommand
|
|
347
|
+
.command("get <key> [output]")
|
|
348
|
+
.description("Download an object from storage")
|
|
349
|
+
.action(async (key, output, _options, command) => {
|
|
350
|
+
checkProject(defaultStorageIO);
|
|
351
|
+
const env = getTargetEnv(command);
|
|
352
|
+
if (env === "prod") {
|
|
353
|
+
requireProdAuth(env);
|
|
354
|
+
}
|
|
355
|
+
await getStorage(key, output, env, defaultStorageIO);
|
|
332
356
|
});
|
|
333
357
|
// ============================================================================
|
|
334
358
|
// storage delete
|
|
335
359
|
// ============================================================================
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
.action(async (key, options, command) => {
|
|
341
|
-
checkProject();
|
|
342
|
-
const env = getTargetEnv(command);
|
|
360
|
+
/**
|
|
361
|
+
* Delete an object from storage.
|
|
362
|
+
*/
|
|
363
|
+
export async function deleteStorage(key, options, env, io) {
|
|
343
364
|
if (env === "prod") {
|
|
344
|
-
requireProdAuth(env);
|
|
345
365
|
// Show warning for production deletion
|
|
346
366
|
if (!options.yes) {
|
|
347
|
-
console.log(`\n⚠️ You are about to delete from PRODUCTION storage:`);
|
|
348
|
-
console.log(` ${key}\n`);
|
|
349
|
-
console.log(`This cannot be undone. Use --yes to confirm.`);
|
|
350
|
-
process.exit(1);
|
|
367
|
+
io.console.log(`\n⚠️ You are about to delete from PRODUCTION storage:`);
|
|
368
|
+
io.console.log(` ${key}\n`);
|
|
369
|
+
io.console.log(`This cannot be undone. Use --yes to confirm.`);
|
|
370
|
+
io.process.exit(1);
|
|
351
371
|
}
|
|
352
372
|
try {
|
|
353
373
|
const projectName = await getProjectName();
|
|
@@ -355,19 +375,19 @@ storageCommand
|
|
|
355
375
|
method: "DELETE",
|
|
356
376
|
});
|
|
357
377
|
if (response.status === 404) {
|
|
358
|
-
console.error(`Error: Object not found: ${key}`);
|
|
359
|
-
process.exit(1);
|
|
378
|
+
io.console.error(`Error: Object not found: ${key}`);
|
|
379
|
+
io.process.exit(1);
|
|
360
380
|
}
|
|
361
381
|
if (!response.ok) {
|
|
362
382
|
const data = (await response.json());
|
|
363
|
-
console.error(`Error: ${data.error ?? `API error: ${response.status}`}`);
|
|
364
|
-
process.exit(1);
|
|
383
|
+
io.console.error(`Error: ${data.error ?? `API error: ${response.status}`}`);
|
|
384
|
+
io.process.exit(1);
|
|
365
385
|
}
|
|
366
|
-
console.log(`Deleted: ${key}`);
|
|
386
|
+
io.console.log(`Deleted: ${key}`);
|
|
367
387
|
}
|
|
368
388
|
catch (error) {
|
|
369
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
370
|
-
process.exit(1);
|
|
389
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
390
|
+
io.process.exit(1);
|
|
371
391
|
}
|
|
372
392
|
}
|
|
373
393
|
else {
|
|
@@ -376,50 +396,59 @@ storageCommand
|
|
|
376
396
|
// Check if object exists
|
|
377
397
|
const obj = await storage.head(key);
|
|
378
398
|
if (!obj) {
|
|
379
|
-
console.error(`Error: Object not found: ${key}`);
|
|
380
|
-
process.exit(1);
|
|
399
|
+
io.console.error(`Error: Object not found: ${key}`);
|
|
400
|
+
io.process.exit(1);
|
|
381
401
|
}
|
|
382
402
|
await storage.delete(key);
|
|
383
|
-
console.log(`Deleted: ${key}`);
|
|
403
|
+
io.console.log(`Deleted: ${key}`);
|
|
384
404
|
}
|
|
385
405
|
catch (error) {
|
|
386
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
387
|
-
process.exit(1);
|
|
406
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
407
|
+
io.process.exit(1);
|
|
388
408
|
}
|
|
389
409
|
}
|
|
410
|
+
}
|
|
411
|
+
storageCommand
|
|
412
|
+
.command("delete <key>")
|
|
413
|
+
.description("Delete an object from storage")
|
|
414
|
+
.option("--yes", "Skip confirmation prompt")
|
|
415
|
+
.action(async (key, options, command) => {
|
|
416
|
+
checkProject(defaultStorageIO);
|
|
417
|
+
const env = getTargetEnv(command);
|
|
418
|
+
if (env === "prod") {
|
|
419
|
+
requireProdAuth(env);
|
|
420
|
+
}
|
|
421
|
+
await deleteStorage(key, options, env, defaultStorageIO);
|
|
390
422
|
});
|
|
391
423
|
// ============================================================================
|
|
392
424
|
// storage info
|
|
393
425
|
// ============================================================================
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
checkProject();
|
|
399
|
-
const env = getTargetEnv(command);
|
|
426
|
+
/**
|
|
427
|
+
* Show storage information and usage.
|
|
428
|
+
*/
|
|
429
|
+
export async function infoStorage(env, io) {
|
|
400
430
|
if (env === "prod") {
|
|
401
|
-
requireProdAuth(env);
|
|
402
431
|
try {
|
|
403
432
|
const projectName = await getProjectName();
|
|
404
433
|
const response = await platformFetch(`/project/${encodeURIComponent(projectName)}/storage/info`);
|
|
405
434
|
if (!response.ok) {
|
|
406
435
|
const data = (await response.json());
|
|
407
|
-
console.error(`Error: ${data.error ?? `API error: ${response.status}`}`);
|
|
408
|
-
process.exit(1);
|
|
436
|
+
io.console.error(`Error: ${data.error ?? `API error: ${response.status}`}`);
|
|
437
|
+
io.process.exit(1);
|
|
409
438
|
}
|
|
410
439
|
const data = (await response.json());
|
|
411
|
-
console.log("Production Storage (R2)\n");
|
|
412
|
-
console.log(` Bucket: ${data.bucket}`);
|
|
413
|
-
console.log(` Objects: ${data.objectCount.toLocaleString()}`);
|
|
414
|
-
console.log(` Size: ${formatBytes(data.totalSizeBytes)}`);
|
|
415
|
-
console.log("");
|
|
416
|
-
console.log(" Pricing: $0.015/GB-month storage");
|
|
417
|
-
console.log(" $0.36/million Class A ops (write)");
|
|
418
|
-
console.log(" $0.036/million Class B ops (read)");
|
|
440
|
+
io.console.log("Production Storage (R2)\n");
|
|
441
|
+
io.console.log(` Bucket: ${data.bucket}`);
|
|
442
|
+
io.console.log(` Objects: ${data.objectCount.toLocaleString()}`);
|
|
443
|
+
io.console.log(` Size: ${formatBytes(data.totalSizeBytes)}`);
|
|
444
|
+
io.console.log("");
|
|
445
|
+
io.console.log(" Pricing: $0.015/GB-month storage");
|
|
446
|
+
io.console.log(" $0.36/million Class A ops (write)");
|
|
447
|
+
io.console.log(" $0.036/million Class B ops (read)");
|
|
419
448
|
}
|
|
420
449
|
catch (error) {
|
|
421
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
422
|
-
process.exit(1);
|
|
450
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
451
|
+
io.process.exit(1);
|
|
423
452
|
}
|
|
424
453
|
}
|
|
425
454
|
else {
|
|
@@ -444,16 +473,27 @@ storageCommand
|
|
|
444
473
|
if (!more.truncated)
|
|
445
474
|
break;
|
|
446
475
|
}
|
|
447
|
-
const storagePath = join(process.cwd(), ".fling", "data", "storage");
|
|
448
|
-
console.log("Local Storage\n");
|
|
449
|
-
console.log(` Location: ${storagePath}`);
|
|
450
|
-
console.log(` Objects: ${count.toLocaleString()}`);
|
|
451
|
-
console.log(` Size: ${formatBytes(totalSize)}`);
|
|
476
|
+
const storagePath = join(io.process.cwd(), ".fling", "data", "storage");
|
|
477
|
+
io.console.log("Local Storage\n");
|
|
478
|
+
io.console.log(` Location: ${storagePath}`);
|
|
479
|
+
io.console.log(` Objects: ${count.toLocaleString()}`);
|
|
480
|
+
io.console.log(` Size: ${formatBytes(totalSize)}`);
|
|
452
481
|
}
|
|
453
482
|
catch (error) {
|
|
454
|
-
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
455
|
-
process.exit(1);
|
|
483
|
+
io.console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
484
|
+
io.process.exit(1);
|
|
456
485
|
}
|
|
457
486
|
}
|
|
487
|
+
}
|
|
488
|
+
storageCommand
|
|
489
|
+
.command("info")
|
|
490
|
+
.description("Show storage information and usage")
|
|
491
|
+
.action(async (_options, command) => {
|
|
492
|
+
checkProject(defaultStorageIO);
|
|
493
|
+
const env = getTargetEnv(command);
|
|
494
|
+
if (env === "prod") {
|
|
495
|
+
requireProdAuth(env);
|
|
496
|
+
}
|
|
497
|
+
await infoStorage(env, defaultStorageIO);
|
|
458
498
|
});
|
|
459
499
|
//# sourceMappingURL=storage.js.map
|