|
1 | 1 | #!/usr/bin/env node |
2 | 2 | /** |
3 | | - * CLI entry point for @get-convex/self-static-hosting |
| 3 | + * CLI for Convex Self Static Hosting |
4 | 4 | * |
5 | 5 | * Commands: |
6 | | - * init - Output integration instructions (LLM-friendly) |
7 | | - * upload - Upload static files to Convex |
| 6 | + * upload Upload static files to Convex |
| 7 | + * setup-cloudflare Interactive Cloudflare CDN setup |
| 8 | + * init Print setup instructions |
8 | 9 | */ |
9 | 10 |
|
10 | | -import { spawn } from "child_process"; |
11 | | -import { fileURLToPath } from "url"; |
12 | | -import { dirname, join } from "path"; |
| 11 | +const command = process.argv[2]; |
13 | 12 |
|
14 | | -const __dirname = dirname(fileURLToPath(import.meta.url)); |
| 13 | +async function main() { |
| 14 | + switch (command) { |
| 15 | + case "upload": |
| 16 | + // Pass remaining args to upload command |
| 17 | + process.argv.splice(2, 1); |
| 18 | + await import("./upload.js"); |
| 19 | + break; |
15 | 20 |
|
16 | | -const command = process.argv[2]; |
17 | | -const args = process.argv.slice(3); |
18 | | - |
19 | | -if (command === "init") { |
20 | | - // Run init command |
21 | | - const initPath = join(__dirname, "init.js"); |
22 | | - await import(initPath); |
23 | | -} else if (command === "upload" || !command || command === "--help" || command === "-h") { |
24 | | - // Run upload command (default) |
25 | | - const uploadPath = join(__dirname, "upload.js"); |
26 | | - const uploadArgs = command === "upload" ? args : process.argv.slice(2); |
27 | | - |
28 | | - // Re-execute with upload script |
29 | | - const child = spawn(process.execPath, [uploadPath, ...uploadArgs], { |
30 | | - stdio: "inherit", |
31 | | - }); |
32 | | - |
33 | | - child.on("exit", (code) => { |
34 | | - process.exit(code ?? 0); |
35 | | - }); |
36 | | -} else { |
37 | | - console.error(`Unknown command: ${command}`); |
38 | | - console.error(""); |
39 | | - console.error("Available commands:"); |
40 | | - console.error(" init Output integration instructions for your LLM"); |
41 | | - console.error(" upload Upload static files to Convex storage"); |
42 | | - console.error(""); |
43 | | - console.error("Examples:"); |
44 | | - console.error(" npx @get-convex/self-static-hosting init"); |
45 | | - console.error(" npx @get-convex/self-static-hosting upload --dist ./dist"); |
46 | | - process.exit(1); |
| 21 | + case "setup-cloudflare": |
| 22 | + case "setup-cf": |
| 23 | + case "cloudflare": |
| 24 | + await import("./setup-cloudflare.js"); |
| 25 | + break; |
| 26 | + |
| 27 | + case "init": |
| 28 | + printInitInstructions(); |
| 29 | + break; |
| 30 | + |
| 31 | + case "--help": |
| 32 | + case "-h": |
| 33 | + case undefined: |
| 34 | + printHelp(); |
| 35 | + break; |
| 36 | + |
| 37 | + default: |
| 38 | + console.error(`Unknown command: ${command}`); |
| 39 | + console.log(""); |
| 40 | + printHelp(); |
| 41 | + process.exit(1); |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +function printHelp() { |
| 46 | + console.log(` |
| 47 | +Convex Self Static Hosting CLI |
| 48 | +
|
| 49 | +Usage: |
| 50 | + npx @get-convex/self-static-hosting <command> [options] |
| 51 | +
|
| 52 | +Commands: |
| 53 | + upload Upload static files to Convex storage |
| 54 | + setup-cloudflare Interactive Cloudflare CDN setup wizard |
| 55 | + init Print setup instructions for integration |
| 56 | +
|
| 57 | +Examples: |
| 58 | + npx @get-convex/self-static-hosting upload |
| 59 | + npx @get-convex/self-static-hosting upload --dist ./build |
| 60 | + npx @get-convex/self-static-hosting setup-cloudflare |
| 61 | + npx @get-convex/self-static-hosting init |
| 62 | +
|
| 63 | +Run '<command> --help' for more information on a specific command. |
| 64 | +`); |
| 65 | +} |
| 66 | + |
| 67 | +function printInitInstructions() { |
| 68 | + console.log(` |
| 69 | +# Convex Self Static Hosting - Setup Instructions |
| 70 | +
|
| 71 | +## 1. Install the component |
| 72 | +
|
| 73 | +\`\`\`bash |
| 74 | +npm install @get-convex/self-static-hosting |
| 75 | +\`\`\` |
| 76 | +
|
| 77 | +## 2. Add to convex.config.ts |
| 78 | +
|
| 79 | +\`\`\`typescript |
| 80 | +// convex/convex.config.ts |
| 81 | +import { defineApp } from "convex/server"; |
| 82 | +import selfStaticHosting from "@get-convex/self-static-hosting/convex.config.js"; |
| 83 | +
|
| 84 | +const app = defineApp(); |
| 85 | +app.use(selfStaticHosting); |
| 86 | +
|
| 87 | +export default app; |
| 88 | +\`\`\` |
| 89 | +
|
| 90 | +## 3. Create HTTP routes |
| 91 | +
|
| 92 | +\`\`\`typescript |
| 93 | +// convex/http.ts |
| 94 | +import { httpRouter } from "convex/server"; |
| 95 | +import { registerStaticRoutes } from "@get-convex/self-static-hosting"; |
| 96 | +import { components } from "./_generated/api"; |
| 97 | +
|
| 98 | +const http = httpRouter(); |
| 99 | +
|
| 100 | +// Serve static files (use pathPrefix for CDN setups) |
| 101 | +registerStaticRoutes(http, components.selfStaticHosting, { |
| 102 | + pathPrefix: "/", // or "/app" to keep API routes separate |
| 103 | + spaFallback: true, |
| 104 | +}); |
| 105 | +
|
| 106 | +export default http; |
| 107 | +\`\`\` |
| 108 | +
|
| 109 | +## 4. Expose upload API |
| 110 | +
|
| 111 | +\`\`\`typescript |
| 112 | +// convex/staticHosting.ts |
| 113 | +import { exposeUploadApi, exposeDeploymentQuery } from "@get-convex/self-static-hosting"; |
| 114 | +import { components } from "./_generated/api"; |
| 115 | +
|
| 116 | +// Internal functions for secure uploads |
| 117 | +export const { generateUploadUrl, recordAsset, gcOldAssets, listAssets } = |
| 118 | + exposeUploadApi(components.selfStaticHosting); |
| 119 | +
|
| 120 | +// Optional: Live reload notifications |
| 121 | +export const { getCurrentDeployment } = |
| 122 | + exposeDeploymentQuery(components.selfStaticHosting); |
| 123 | +\`\`\` |
| 124 | +
|
| 125 | +## 5. Add deploy script to package.json |
| 126 | +
|
| 127 | +\`\`\`json |
| 128 | +{ |
| 129 | + "scripts": { |
| 130 | + "build": "vite build", |
| 131 | + "deploy:static": "npm run build && npx @get-convex/self-static-hosting upload" |
| 132 | + } |
| 133 | +} |
| 134 | +\`\`\` |
| 135 | +
|
| 136 | +## 6. Deploy |
| 137 | +
|
| 138 | +\`\`\`bash |
| 139 | +npm run deploy:static |
| 140 | +\`\`\` |
| 141 | +
|
| 142 | +## Optional: Cloudflare CDN Setup |
| 143 | +
|
| 144 | +\`\`\`bash |
| 145 | +npx @get-convex/self-static-hosting setup-cloudflare |
| 146 | +\`\`\` |
| 147 | +
|
| 148 | +This interactive wizard will: |
| 149 | +- Login to Cloudflare |
| 150 | +- Help you select or add a domain |
| 151 | +- Configure DNS pointing to your Convex site |
| 152 | +- Create an API token for cache purging |
| 153 | +- Save credentials to .env.local |
| 154 | +
|
| 155 | +Then just deploy - cache is purged automatically! |
| 156 | +`); |
47 | 157 | } |
| 158 | + |
| 159 | +main().catch((err) => { |
| 160 | + console.error("Error:", err); |
| 161 | + process.exit(1); |
| 162 | +}); |
0 commit comments