flingit 0.0.1
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 +84 -0
- package/dist/cli/commands/db.d.ts +9 -0
- package/dist/cli/commands/db.d.ts.map +1 -0
- package/dist/cli/commands/db.js +215 -0
- package/dist/cli/commands/db.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +6 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +145 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/feedback.d.ts +6 -0
- package/dist/cli/commands/feedback.d.ts.map +1 -0
- package/dist/cli/commands/feedback.js +116 -0
- package/dist/cli/commands/feedback.js.map +1 -0
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +161 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/launch.d.ts +12 -0
- package/dist/cli/commands/launch.d.ts.map +1 -0
- package/dist/cli/commands/launch.js +176 -0
- package/dist/cli/commands/launch.js.map +1 -0
- package/dist/cli/commands/login.d.ts +6 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +90 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/logout.d.ts +6 -0
- package/dist/cli/commands/logout.d.ts.map +1 -0
- package/dist/cli/commands/logout.js +32 -0
- package/dist/cli/commands/logout.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +12 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +261 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +22 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -0
- package/dist/cli/commands/onboard.js +244 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/project.d.ts +6 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +142 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/commands/push.d.ts +6 -0
- package/dist/cli/commands/push.d.ts.map +1 -0
- package/dist/cli/commands/push.js +351 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/register.d.ts +6 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +115 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/commands/secret.d.ts +11 -0
- package/dist/cli/commands/secret.d.ts.map +1 -0
- package/dist/cli/commands/secret.js +124 -0
- package/dist/cli/commands/secret.js.map +1 -0
- package/dist/cli/commands/whoami.d.ts +6 -0
- package/dist/cli/commands/whoami.d.ts.map +1 -0
- package/dist/cli/commands/whoami.js +54 -0
- package/dist/cli/commands/whoami.js.map +1 -0
- package/dist/cli/deploy/assets.d.ts +73 -0
- package/dist/cli/deploy/assets.d.ts.map +1 -0
- package/dist/cli/deploy/assets.js +167 -0
- package/dist/cli/deploy/assets.js.map +1 -0
- package/dist/cli/deploy/base64-stream.d.ts +16 -0
- package/dist/cli/deploy/base64-stream.d.ts.map +1 -0
- package/dist/cli/deploy/base64-stream.js +44 -0
- package/dist/cli/deploy/base64-stream.js.map +1 -0
- package/dist/cli/deploy/bucket-stream.d.ts +18 -0
- package/dist/cli/deploy/bucket-stream.d.ts.map +1 -0
- package/dist/cli/deploy/bucket-stream.js +63 -0
- package/dist/cli/deploy/bucket-stream.js.map +1 -0
- package/dist/cli/deploy/bundler.d.ts +22 -0
- package/dist/cli/deploy/bundler.d.ts.map +1 -0
- package/dist/cli/deploy/bundler.js +131 -0
- package/dist/cli/deploy/bundler.js.map +1 -0
- package/dist/cli/deploy/worker-entry.d.ts +14 -0
- package/dist/cli/deploy/worker-entry.d.ts.map +1 -0
- package/dist/cli/deploy/worker-entry.js +60 -0
- package/dist/cli/deploy/worker-entry.js.map +1 -0
- package/dist/cli/deploy/wrangler-config.d.ts +20 -0
- package/dist/cli/deploy/wrangler-config.d.ts.map +1 -0
- package/dist/cli/deploy/wrangler-config.js +54 -0
- package/dist/cli/deploy/wrangler-config.js.map +1 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +72 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/config.d.ts +39 -0
- package/dist/cli/utils/config.d.ts.map +1 -0
- package/dist/cli/utils/config.js +105 -0
- package/dist/cli/utils/config.js.map +1 -0
- package/dist/cli/utils/duration.d.ts +21 -0
- package/dist/cli/utils/duration.d.ts.map +1 -0
- package/dist/cli/utils/duration.js +44 -0
- package/dist/cli/utils/duration.js.map +1 -0
- package/dist/cli/utils/environment.d.ts +17 -0
- package/dist/cli/utils/environment.d.ts.map +1 -0
- package/dist/cli/utils/environment.js +27 -0
- package/dist/cli/utils/environment.js.map +1 -0
- package/dist/cli/utils/project.d.ts +24 -0
- package/dist/cli/utils/project.d.ts.map +1 -0
- package/dist/cli/utils/project.js +47 -0
- package/dist/cli/utils/project.js.map +1 -0
- package/dist/cli/utils/registry.d.ts +34 -0
- package/dist/cli/utils/registry.d.ts.map +1 -0
- package/dist/cli/utils/registry.js +94 -0
- package/dist/cli/utils/registry.js.map +1 -0
- package/dist/cli/utils/token.d.ts +12 -0
- package/dist/cli/utils/token.d.ts.map +1 -0
- package/dist/cli/utils/token.js +27 -0
- package/dist/cli/utils/token.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/cron.d.ts +50 -0
- package/dist/runtime/cron.d.ts.map +1 -0
- package/dist/runtime/cron.js +80 -0
- package/dist/runtime/cron.js.map +1 -0
- package/dist/runtime/db.d.ts +93 -0
- package/dist/runtime/db.d.ts.map +1 -0
- package/dist/runtime/db.js +137 -0
- package/dist/runtime/db.js.map +1 -0
- package/dist/runtime/http.d.ts +33 -0
- package/dist/runtime/http.d.ts.map +1 -0
- package/dist/runtime/http.js +36 -0
- package/dist/runtime/http.js.map +1 -0
- package/dist/runtime/log.d.ts +90 -0
- package/dist/runtime/log.d.ts.map +1 -0
- package/dist/runtime/log.js +211 -0
- package/dist/runtime/log.js.map +1 -0
- package/dist/runtime/migrate.d.ts +54 -0
- package/dist/runtime/migrate.d.ts.map +1 -0
- package/dist/runtime/migrate.js +130 -0
- package/dist/runtime/migrate.js.map +1 -0
- package/dist/runtime/secrets.d.ts +36 -0
- package/dist/runtime/secrets.d.ts.map +1 -0
- package/dist/runtime/secrets.js +75 -0
- package/dist/runtime/secrets.js.map +1 -0
- package/dist/worker-runtime/index.d.ts +79 -0
- package/dist/worker-runtime/index.d.ts.map +1 -0
- package/dist/worker-runtime/index.js +203 -0
- package/dist/worker-runtime/index.js.map +1 -0
- package/package.json +81 -0
- package/templates/default/.nvmrc +1 -0
- package/templates/default/CLAUDE.md +197 -0
- package/templates/default/index.html +13 -0
- package/templates/default/package.json +25 -0
- package/templates/default/public/vite.svg +1 -0
- package/templates/default/skills/fling/API.md +335 -0
- package/templates/default/skills/fling/EXAMPLES.md +204 -0
- package/templates/default/skills/fling/FEEDBACK.md +73 -0
- package/templates/default/skills/fling/SKILL.md +159 -0
- package/templates/default/src/react-app/App.css +34 -0
- package/templates/default/src/react-app/App.tsx +27 -0
- package/templates/default/src/react-app/index.css +15 -0
- package/templates/default/src/react-app/main.tsx +10 -0
- package/templates/default/src/react-app/vite-env.d.ts +1 -0
- package/templates/default/src/worker/index.ts +27 -0
- package/templates/default/tsconfig.app.json +22 -0
- package/templates/default/tsconfig.json +7 -0
- package/templates/default/tsconfig.worker.json +11 -0
- package/templates/default/vite.config.ts +21 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling project - Project management commands
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { createInterface } from "node:readline";
|
|
6
|
+
import { isLoggedIn, platformFetch } from "../utils/config.js";
|
|
7
|
+
/**
|
|
8
|
+
* Prompt for confirmation.
|
|
9
|
+
*/
|
|
10
|
+
async function confirm(question) {
|
|
11
|
+
const rl = createInterface({
|
|
12
|
+
input: process.stdin,
|
|
13
|
+
output: process.stdout,
|
|
14
|
+
});
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
rl.question(question, (answer) => {
|
|
17
|
+
rl.close();
|
|
18
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export const projectCommand = new Command("project")
|
|
23
|
+
.description("Project management commands")
|
|
24
|
+
.addHelpText("after", `
|
|
25
|
+
Commands:
|
|
26
|
+
fling project slug Show current project slug and URL
|
|
27
|
+
fling project slug:set <slug> Change project slug
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
fling project slug Show current slug
|
|
31
|
+
fling project slug:set my-app Change slug to 'my-app'
|
|
32
|
+
`);
|
|
33
|
+
/**
|
|
34
|
+
* fling project slug - Show current project slug and URL
|
|
35
|
+
*/
|
|
36
|
+
projectCommand
|
|
37
|
+
.command("slug")
|
|
38
|
+
.description("Show current project slug and URL")
|
|
39
|
+
.action(async () => {
|
|
40
|
+
if (!isLoggedIn()) {
|
|
41
|
+
console.error("Error: Not logged in. Run 'fling login' first.");
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const response = await platformFetch("/me");
|
|
46
|
+
const data = (await response.json());
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
console.error(`Error: ${data.error ?? "Failed to fetch user info"}`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const project = data.projects?.[0];
|
|
52
|
+
if (!project) {
|
|
53
|
+
console.error("Error: No project found");
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
console.log(`Slug: ${project.slug}`);
|
|
57
|
+
console.log(`URL: ${project.url}`);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error(`Error: ${error instanceof Error ? error.message : "Network error"}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* fling project slug:set <newSlug> - Change project slug
|
|
66
|
+
*/
|
|
67
|
+
projectCommand
|
|
68
|
+
.command("slug:set")
|
|
69
|
+
.argument("<newSlug>", "New slug (lowercase alphanumeric with hyphens, >4 chars)")
|
|
70
|
+
.description("Change project slug (affects public URL)")
|
|
71
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
72
|
+
.action(async (newSlug, options) => {
|
|
73
|
+
if (!isLoggedIn()) {
|
|
74
|
+
console.error("Error: Not logged in. Run 'fling login' first.");
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
// Validate slug format client-side for quick feedback
|
|
78
|
+
if (newSlug.length <= 4) {
|
|
79
|
+
console.error("Error: Slug must be more than 4 characters");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
if (newSlug.length > 63) {
|
|
83
|
+
console.error("Error: Slug must be at most 63 characters");
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/.test(newSlug)) {
|
|
87
|
+
console.error("Error: Slug must be lowercase alphanumeric with optional hyphens");
|
|
88
|
+
console.error(" Must start and end with alphanumeric character");
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
// First, get current project info
|
|
93
|
+
const meResponse = await platformFetch("/me");
|
|
94
|
+
const meData = (await meResponse.json());
|
|
95
|
+
if (!meResponse.ok) {
|
|
96
|
+
console.error(`Error: ${meData.error ?? "Failed to fetch user info"}`);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
const project = meData.projects?.[0];
|
|
100
|
+
if (!project) {
|
|
101
|
+
console.error("Error: No project found");
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
// Show what will change
|
|
105
|
+
const domain = project.url.split("//")[1]?.split("/")[0]?.split(".").slice(1).join(".");
|
|
106
|
+
const newUrl = `https://${newSlug}.${domain}`;
|
|
107
|
+
console.log(`Current slug: ${project.slug}`);
|
|
108
|
+
console.log(`Current URL: ${project.url}`);
|
|
109
|
+
console.log("");
|
|
110
|
+
console.log(`New slug: ${newSlug}`);
|
|
111
|
+
console.log(`New URL: ${newUrl}`);
|
|
112
|
+
console.log("");
|
|
113
|
+
// Confirm unless --yes flag is provided
|
|
114
|
+
if (!options.yes) {
|
|
115
|
+
const confirmed = await confirm("Are you sure you want to change your project slug? (y/N) ");
|
|
116
|
+
if (!confirmed) {
|
|
117
|
+
console.log("Cancelled.");
|
|
118
|
+
process.exit(0);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Update the slug
|
|
122
|
+
console.log("\nUpdating slug...");
|
|
123
|
+
const updateResponse = await platformFetch("/project/default", {
|
|
124
|
+
method: "PATCH",
|
|
125
|
+
headers: { "Content-Type": "application/json" },
|
|
126
|
+
body: JSON.stringify({ slug: newSlug }),
|
|
127
|
+
});
|
|
128
|
+
const updateData = (await updateResponse.json());
|
|
129
|
+
if (!updateResponse.ok) {
|
|
130
|
+
console.error(`Error: ${updateData.error ?? "Failed to update slug"}`);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
console.log("\nSlug updated successfully!");
|
|
134
|
+
console.log(`New slug: ${updateData.slug}`);
|
|
135
|
+
console.log(`New URL: ${updateData.url}`);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.error(`Error: ${error instanceof Error ? error.message : "Network error"}`);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/cli/commands/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/push.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyXpC,eAAO,MAAM,WAAW,SA6EpB,CAAC"}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling push - Deploy to Cloudflare Workers via Fling platform
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { join, dirname } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { Readable } from "node:stream";
|
|
9
|
+
import { spawn } from "node:child_process";
|
|
10
|
+
import { isLoggedIn, platformFetch } from "../utils/config.js";
|
|
11
|
+
import { hasWorkerEntry } from "../utils/project.js";
|
|
12
|
+
import { loadLocalSecrets } from "./secret.js";
|
|
13
|
+
import { bundleForPlatform } from "../deploy/bundler.js";
|
|
14
|
+
import { collectAssets, buildManifest, validateAssetSizes, } from "../deploy/assets.js";
|
|
15
|
+
import { createBucketUploadStream } from "../deploy/bucket-stream.js";
|
|
16
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
/**
|
|
18
|
+
* Sync local secrets to production.
|
|
19
|
+
* Reads from .fling/secrets and uploads to the platform API.
|
|
20
|
+
*/
|
|
21
|
+
async function syncSecrets(verbose) {
|
|
22
|
+
const secrets = loadLocalSecrets();
|
|
23
|
+
if (secrets.size === 0) {
|
|
24
|
+
if (verbose) {
|
|
25
|
+
console.log("[verbose] No secrets to sync");
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
console.log(`Syncing ${secrets.size} secret${secrets.size === 1 ? "" : "s"}...`);
|
|
30
|
+
for (const [key, value] of secrets) {
|
|
31
|
+
if (verbose) {
|
|
32
|
+
console.log(`[verbose] Setting secret: ${key}`);
|
|
33
|
+
}
|
|
34
|
+
const response = await platformFetch(`/project/default/secrets/${key}`, {
|
|
35
|
+
method: "PUT",
|
|
36
|
+
headers: { "Content-Type": "application/json" },
|
|
37
|
+
body: JSON.stringify({ value }),
|
|
38
|
+
});
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
const data = (await response.json());
|
|
41
|
+
throw new Error(`Failed to sync secret ${key}: ${data.error ?? `API error: ${response.status}`}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
console.log("Secrets synced.\n");
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run Vite build to generate frontend assets.
|
|
48
|
+
* If basePath is provided, sets VITE_BASE env var for path-based routing.
|
|
49
|
+
*/
|
|
50
|
+
async function runViteBuild(projectDir, verbose, basePath) {
|
|
51
|
+
console.log("Building frontend with Vite...\n");
|
|
52
|
+
const env = { ...process.env };
|
|
53
|
+
if (basePath) {
|
|
54
|
+
env["VITE_BASE"] = basePath;
|
|
55
|
+
if (verbose) {
|
|
56
|
+
console.log(`[verbose] Setting VITE_BASE=${basePath} for path-based routing`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
await new Promise((resolve, reject) => {
|
|
60
|
+
const build = spawn("npm", ["run", "build"], {
|
|
61
|
+
cwd: projectDir,
|
|
62
|
+
env,
|
|
63
|
+
stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
|
|
64
|
+
});
|
|
65
|
+
let stdout = "";
|
|
66
|
+
let stderr = "";
|
|
67
|
+
if (!verbose) {
|
|
68
|
+
build.stdout?.on("data", (data) => {
|
|
69
|
+
stdout += data.toString();
|
|
70
|
+
});
|
|
71
|
+
build.stderr?.on("data", (data) => {
|
|
72
|
+
stderr += data.toString();
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
build.on("error", (error) => {
|
|
76
|
+
if (error.code === "ENOENT") {
|
|
77
|
+
reject(new Error("Failed to run Vite build: npm not found.\n\n" +
|
|
78
|
+
"Ensure Node.js is properly installed and npm is in your PATH."));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
reject(new Error(`Failed to run Vite build: ${error.message}`));
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
build.on("close", (code) => {
|
|
85
|
+
if (code === 0) {
|
|
86
|
+
console.log("Frontend build complete.\n");
|
|
87
|
+
resolve();
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const output = stderr || stdout;
|
|
91
|
+
reject(new Error(`Vite build failed with exit code ${code}.\n\n` +
|
|
92
|
+
`Build output:\n${output}\n\n` +
|
|
93
|
+
"Check the error output above for details.\n" +
|
|
94
|
+
"Common fixes:\n" +
|
|
95
|
+
" - Run 'npm install' to ensure dependencies are installed\n" +
|
|
96
|
+
" - Check vite.config.ts for syntax errors\n" +
|
|
97
|
+
" - Check src/react-app/ for TypeScript errors"));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Upload static assets to the platform.
|
|
104
|
+
* Returns the completion JWT to include in code deployment.
|
|
105
|
+
*/
|
|
106
|
+
async function uploadAssets(assets, verbose) {
|
|
107
|
+
if (assets.length === 0) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
// Validate sizes
|
|
111
|
+
validateAssetSizes(assets);
|
|
112
|
+
const totalSize = assets.reduce((sum, a) => sum + a.size, 0);
|
|
113
|
+
const totalSizeKB = totalSize / 1024;
|
|
114
|
+
const totalSizeMB = totalSizeKB / 1024;
|
|
115
|
+
if (totalSizeMB >= 1) {
|
|
116
|
+
console.log(`Static assets: ${assets.length} files (${totalSizeMB.toFixed(2)} MB)`);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
console.log(`Static assets: ${assets.length} files (${totalSizeKB.toFixed(1)} KB)`);
|
|
120
|
+
}
|
|
121
|
+
if (verbose) {
|
|
122
|
+
for (const asset of assets) {
|
|
123
|
+
console.log(` ${asset.path} (${(asset.size / 1024).toFixed(1)} KB)`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Step 1: Create upload session
|
|
127
|
+
const manifest = buildManifest(assets);
|
|
128
|
+
const sessionRes = await platformFetch("/project/default/deploy/assets", {
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: { "Content-Type": "application/json" },
|
|
131
|
+
body: JSON.stringify({ manifest }),
|
|
132
|
+
});
|
|
133
|
+
if (!sessionRes.ok) {
|
|
134
|
+
const err = await sessionRes.text();
|
|
135
|
+
throw new Error(`Asset upload session failed: ${err}`);
|
|
136
|
+
}
|
|
137
|
+
const { sessionJwt, buckets } = (await sessionRes.json());
|
|
138
|
+
if (verbose) {
|
|
139
|
+
console.log(`[verbose] Upload session created, ${buckets.length} bucket(s) to upload`);
|
|
140
|
+
}
|
|
141
|
+
// If buckets is empty, all files already cached - sessionJwt serves as completion JWT
|
|
142
|
+
if (buckets.length === 0) {
|
|
143
|
+
console.log("All assets already cached");
|
|
144
|
+
return sessionJwt;
|
|
145
|
+
}
|
|
146
|
+
// Step 2: Upload each bucket
|
|
147
|
+
let assetsJwt;
|
|
148
|
+
for (const [i, bucket] of buckets.entries()) {
|
|
149
|
+
const bucketAssets = assets.filter((a) => bucket.includes(a.hash));
|
|
150
|
+
if (verbose) {
|
|
151
|
+
console.log(`[verbose] Uploading bucket ${i + 1}/${buckets.length} (${bucketAssets.length} files)`);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
console.log(`Uploading assets: ${i + 1}/${buckets.length}`);
|
|
155
|
+
}
|
|
156
|
+
// Create streaming multipart body
|
|
157
|
+
const { stream } = createBucketUploadStream(bucketAssets);
|
|
158
|
+
// Convert Node stream to Web stream for fetch
|
|
159
|
+
const webStream = Readable.toWeb(stream);
|
|
160
|
+
const uploadRes = await platformFetch("/project/default/deploy/assets/upload", {
|
|
161
|
+
method: "POST",
|
|
162
|
+
headers: {
|
|
163
|
+
"Content-Type": "application/octet-stream",
|
|
164
|
+
"X-Session-Jwt": sessionJwt,
|
|
165
|
+
},
|
|
166
|
+
body: webStream,
|
|
167
|
+
duplex: "half",
|
|
168
|
+
});
|
|
169
|
+
if (!uploadRes.ok) {
|
|
170
|
+
const err = await uploadRes.text();
|
|
171
|
+
throw new Error(`Asset upload failed: ${err}`);
|
|
172
|
+
}
|
|
173
|
+
const result = (await uploadRes.json());
|
|
174
|
+
if (!result.ok) {
|
|
175
|
+
throw new Error(`Asset upload error: ${result.error}`);
|
|
176
|
+
}
|
|
177
|
+
if (result.completionJwt) {
|
|
178
|
+
assetsJwt = result.completionJwt;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// After uploading all buckets, we MUST have a completion JWT
|
|
182
|
+
if (!assetsJwt) {
|
|
183
|
+
throw new Error("Asset upload completed but no completion JWT received");
|
|
184
|
+
}
|
|
185
|
+
return assetsJwt;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Deploy via the Fling platform (when logged in).
|
|
189
|
+
* Uses streaming upload for memory efficiency with large bundles.
|
|
190
|
+
*/
|
|
191
|
+
async function deployViaPlatform(projectDir, verbose = false) {
|
|
192
|
+
// Step 0: Fetch project info (needed for base path detection and asset hashing)
|
|
193
|
+
const meRes = await platformFetch("/me");
|
|
194
|
+
if (!meRes.ok) {
|
|
195
|
+
throw new Error("Failed to fetch user info");
|
|
196
|
+
}
|
|
197
|
+
const meData = (await meRes.json());
|
|
198
|
+
const userId = meData.user.id;
|
|
199
|
+
const projectId = meData.projects[0]?.id ?? "default";
|
|
200
|
+
const projectUrl = meData.projects[0]?.url;
|
|
201
|
+
const projectSlug = meData.projects[0]?.slug;
|
|
202
|
+
// Determine base path for Vite build (path-based routing needs a prefix)
|
|
203
|
+
let basePath;
|
|
204
|
+
if (projectUrl && projectSlug) {
|
|
205
|
+
try {
|
|
206
|
+
const parsed = new URL(projectUrl);
|
|
207
|
+
if (parsed.pathname !== "/" && parsed.pathname.startsWith(`/${projectSlug}`)) {
|
|
208
|
+
basePath = `/${projectSlug}/`;
|
|
209
|
+
if (verbose) {
|
|
210
|
+
console.log(`[verbose] Detected path-based routing, base: ${basePath}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// URL parsing failed, use default base
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Step 1: Run Vite build
|
|
219
|
+
await runViteBuild(projectDir, verbose, basePath);
|
|
220
|
+
// Step 2: Check for and upload static assets
|
|
221
|
+
const assetsDir = join(projectDir, "dist", "client");
|
|
222
|
+
let assetsJwt;
|
|
223
|
+
if (existsSync(assetsDir)) {
|
|
224
|
+
const assets = await collectAssets(projectDir, userId, projectId);
|
|
225
|
+
if (assets.length > 0) {
|
|
226
|
+
assetsJwt = await uploadAssets(assets, verbose);
|
|
227
|
+
console.log(""); // Blank line before bundling
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// Step 3: Bundle the code
|
|
231
|
+
console.log("Bundling for platform deployment...\n");
|
|
232
|
+
if (verbose) {
|
|
233
|
+
console.log("[verbose] projectDir:", projectDir);
|
|
234
|
+
console.log("[verbose] Calling bundleForPlatform...");
|
|
235
|
+
}
|
|
236
|
+
const code = await bundleForPlatform(projectDir, verbose);
|
|
237
|
+
const sizeKB = code.length / 1024;
|
|
238
|
+
const sizeMB = sizeKB / 1024;
|
|
239
|
+
if (sizeMB >= 1) {
|
|
240
|
+
console.log(`Bundle size: ${sizeMB.toFixed(2)} MB`);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
console.log(`Bundle size: ${sizeKB.toFixed(1)} KB`);
|
|
244
|
+
}
|
|
245
|
+
// Step 4: Deploy via API using streaming mode
|
|
246
|
+
console.log("Deploying to Fling platform...\n");
|
|
247
|
+
const headers = {
|
|
248
|
+
"Content-Type": "text/javascript",
|
|
249
|
+
"X-Code-Size": String(code.length),
|
|
250
|
+
};
|
|
251
|
+
// Include assets JWT if we uploaded assets
|
|
252
|
+
if (assetsJwt) {
|
|
253
|
+
headers["X-Assets-Jwt"] = assetsJwt;
|
|
254
|
+
}
|
|
255
|
+
const response = await platformFetch("/project/default/deploy", {
|
|
256
|
+
method: "POST",
|
|
257
|
+
headers,
|
|
258
|
+
body: code,
|
|
259
|
+
});
|
|
260
|
+
const data = (await response.json());
|
|
261
|
+
if (!response.ok) {
|
|
262
|
+
throw new Error(data.error ?? "Deployment failed");
|
|
263
|
+
}
|
|
264
|
+
console.log("Deployed successfully!");
|
|
265
|
+
console.log(`URL: ${data.url}`);
|
|
266
|
+
console.log(`Version: ${data.version}`);
|
|
267
|
+
console.log("");
|
|
268
|
+
// Show tip about customizing slug on first deploy or for auto-generated slugs
|
|
269
|
+
const urlSlug = data.url?.split("//")[1]?.split(".")[0];
|
|
270
|
+
const isAutoGeneratedSlug = urlSlug?.startsWith("proj-");
|
|
271
|
+
const isFirstDeploy = data.version === 1;
|
|
272
|
+
if (isFirstDeploy || isAutoGeneratedSlug) {
|
|
273
|
+
console.log("Tip: Want a custom URL? Run: fling project slug:set my-custom-slug");
|
|
274
|
+
console.log("");
|
|
275
|
+
}
|
|
276
|
+
// Step 5: Sync secrets to production
|
|
277
|
+
await syncSecrets(verbose);
|
|
278
|
+
}
|
|
279
|
+
export const pushCommand = new Command("push")
|
|
280
|
+
.description("Bundle and deploy your project to Cloudflare Workers")
|
|
281
|
+
.option("--verbose", "Show detailed bundling and deployment information")
|
|
282
|
+
.addHelpText("after", `
|
|
283
|
+
Prerequisites:
|
|
284
|
+
- Must be logged in (run 'fling login' first)
|
|
285
|
+
- Must have run 'fling init' first
|
|
286
|
+
- Requires src/worker/index.ts
|
|
287
|
+
|
|
288
|
+
What it does:
|
|
289
|
+
1. Builds frontend with Vite (outputs to dist/client/)
|
|
290
|
+
2. Uploads static assets from dist/client/
|
|
291
|
+
3. Bundles your backend code with esbuild
|
|
292
|
+
4. Deploys to Cloudflare Workers
|
|
293
|
+
5. Syncs secrets from .fling/secrets to production
|
|
294
|
+
|
|
295
|
+
Static assets:
|
|
296
|
+
Vite outputs to dist/client/ automatically.
|
|
297
|
+
Assets are served when no API route matches.
|
|
298
|
+
Limits: 25MB per file, 100MB total.
|
|
299
|
+
|
|
300
|
+
After deployment, your app will be available at:
|
|
301
|
+
https://<your-project>.fling.dev
|
|
302
|
+
|
|
303
|
+
Examples:
|
|
304
|
+
fling push Deploy to production
|
|
305
|
+
fling push --verbose Deploy with detailed output
|
|
306
|
+
`)
|
|
307
|
+
.action(async (options) => {
|
|
308
|
+
const verbose = options.verbose ?? false;
|
|
309
|
+
if (verbose) {
|
|
310
|
+
console.log("[verbose] Starting push command");
|
|
311
|
+
console.log("[verbose] __dirname:", __dirname);
|
|
312
|
+
console.log("[verbose] process.cwd():", process.cwd());
|
|
313
|
+
console.log("[verbose] isLoggedIn:", isLoggedIn());
|
|
314
|
+
}
|
|
315
|
+
const cwd = process.cwd();
|
|
316
|
+
// Check if project is initialized
|
|
317
|
+
if (!existsSync(join(cwd, ".fling"))) {
|
|
318
|
+
console.error("Error: Not a Fling project. Run 'fling init' first.");
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
// Check for worker entry point
|
|
322
|
+
if (!hasWorkerEntry(cwd)) {
|
|
323
|
+
console.error("Error: src/worker/index.ts not found.\n");
|
|
324
|
+
console.error("This file is your backend API entry point.");
|
|
325
|
+
console.error("Run 'fling init' to create a new project with the correct structure.");
|
|
326
|
+
process.exit(1);
|
|
327
|
+
}
|
|
328
|
+
// Must be logged in to deploy
|
|
329
|
+
if (!isLoggedIn()) {
|
|
330
|
+
console.error("Error: Not logged in.\n");
|
|
331
|
+
console.error("To deploy, you need to authenticate first.\n");
|
|
332
|
+
console.error("Options:");
|
|
333
|
+
console.error(" fling onboard Interactive setup (recommended)");
|
|
334
|
+
console.error(" fling login <token> If you have an API token");
|
|
335
|
+
console.error(" fling register <invite> If you have an invite link\n");
|
|
336
|
+
console.error("Don't have credentials? Contact Fling to get an invite.");
|
|
337
|
+
process.exit(1);
|
|
338
|
+
}
|
|
339
|
+
try {
|
|
340
|
+
if (verbose)
|
|
341
|
+
console.log("[verbose] Using platform deployment");
|
|
342
|
+
await deployViaPlatform(cwd, verbose);
|
|
343
|
+
}
|
|
344
|
+
catch (error) {
|
|
345
|
+
console.error("Deployment failed:", error.message);
|
|
346
|
+
if (verbose)
|
|
347
|
+
console.error("[verbose] Full error:", error);
|
|
348
|
+
process.exit(1);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../../src/cli/commands/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/register.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC,eAAO,MAAM,eAAe,SA+GxB,CAAC"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* fling register - Create a new account using an invite token
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { createInterface } from "node:readline";
|
|
6
|
+
import { setToken, isLoggedIn, getApiUrl, setApiUrl } from "../utils/config.js";
|
|
7
|
+
import { normalizeInviteToken } from "../utils/token.js";
|
|
8
|
+
/**
|
|
9
|
+
* Prompt for input.
|
|
10
|
+
*/
|
|
11
|
+
async function prompt(question) {
|
|
12
|
+
const rl = createInterface({
|
|
13
|
+
input: process.stdin,
|
|
14
|
+
output: process.stdout,
|
|
15
|
+
});
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
rl.question(question, (answer) => {
|
|
18
|
+
rl.close();
|
|
19
|
+
resolve(answer);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export const registerCommand = new Command("register")
|
|
24
|
+
.description("Create a new Fling account using an invite token")
|
|
25
|
+
.argument("[invite-token]", "Invite token (inv_ prefix optional, will prompt if not provided)")
|
|
26
|
+
.option("--api-url <url>", "Override API endpoint (internal/testing use only)")
|
|
27
|
+
.option("--email <email>", "Email address (for CI/scripts, skips prompt)")
|
|
28
|
+
.option("--name <name>", "Display name (for CI/scripts, skips prompt)")
|
|
29
|
+
.addHelpText("after", `
|
|
30
|
+
Getting an invite token:
|
|
31
|
+
Invite tokens are distributed by Fling administrators.
|
|
32
|
+
The 'inv_' prefix is optional - you can enter just the token value.
|
|
33
|
+
|
|
34
|
+
What it does:
|
|
35
|
+
- Creates a new Fling account with your email and name
|
|
36
|
+
- Creates your first project with an auto-generated slug (e.g. proj-abc123)
|
|
37
|
+
- Logs you in automatically (stores token in ~/.fling/token)
|
|
38
|
+
|
|
39
|
+
Non-interactive mode (for CI/scripts):
|
|
40
|
+
Provide --email and --name to skip all prompts.
|
|
41
|
+
|
|
42
|
+
Customizing your project URL:
|
|
43
|
+
Your project gets an auto-generated slug like proj-abc123.
|
|
44
|
+
To change it after registration: fling project slug:set my-custom-slug
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
fling register Interactive registration
|
|
48
|
+
fling register xyz789... Provide invite token (inv_ prefix optional)
|
|
49
|
+
fling register xyz789... --email me@example.com --name "My Name"
|
|
50
|
+
`)
|
|
51
|
+
.action(async (inviteTokenArg, options) => {
|
|
52
|
+
// Check if already logged in
|
|
53
|
+
if (isLoggedIn()) {
|
|
54
|
+
console.error("Already logged in. Use 'fling logout' first.");
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
// Set API URL if provided
|
|
58
|
+
if (options.apiUrl) {
|
|
59
|
+
setApiUrl(options.apiUrl);
|
|
60
|
+
}
|
|
61
|
+
// Get invite token
|
|
62
|
+
const inviteToken = inviteTokenArg ?? (await prompt("Invite token: "));
|
|
63
|
+
if (!inviteToken) {
|
|
64
|
+
console.error("Invite token is required.");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
// Normalize token format - auto-prepend inv_ if missing
|
|
68
|
+
const normalizedToken = normalizeInviteToken(inviteToken);
|
|
69
|
+
// Get user details (from options or interactive prompt)
|
|
70
|
+
const email = options.email ?? (await prompt("Email: "));
|
|
71
|
+
if (!email) {
|
|
72
|
+
console.error("Email is required.");
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
const name = options.name ?? (await prompt("Name: "));
|
|
76
|
+
if (!name) {
|
|
77
|
+
console.error("Name is required.");
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
// Register via API (slug is auto-generated by the server)
|
|
81
|
+
console.log("\nRegistering...");
|
|
82
|
+
try {
|
|
83
|
+
const response = await fetch(`${getApiUrl()}/me`, {
|
|
84
|
+
method: "POST",
|
|
85
|
+
headers: {
|
|
86
|
+
"Authorization": `Bearer ${normalizedToken}`,
|
|
87
|
+
"Content-Type": "application/json",
|
|
88
|
+
},
|
|
89
|
+
body: JSON.stringify({ email, name }),
|
|
90
|
+
});
|
|
91
|
+
const data = (await response.json());
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
console.error(`Registration failed: ${data.error ?? "Unknown error"}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
if (!data.token) {
|
|
97
|
+
console.error("Registration failed: No token returned");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
// Store the user token
|
|
101
|
+
setToken(data.token);
|
|
102
|
+
// Welcome message
|
|
103
|
+
console.log(`\nWelcome to Fling, ${data.name}!`);
|
|
104
|
+
console.log(`Email: ${data.email}`);
|
|
105
|
+
console.log(`Project: ${data.project?.slug}`);
|
|
106
|
+
console.log(`URL: ${data.project?.url}`);
|
|
107
|
+
console.log(`\nRun 'fling init' to create your first app.`);
|
|
108
|
+
console.log(`\nTip: To customize your URL, run: fling project slug:set my-custom-slug`);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
console.error(`Registration failed: ${error instanceof Error ? error.message : "Network error"}`);
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=register.js.map
|