@convex-dev/static-hosting 0.1.2-beta.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 (98) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +333 -0
  3. package/dist/cli/deploy.d.ts +16 -0
  4. package/dist/cli/deploy.d.ts.map +1 -0
  5. package/dist/cli/deploy.js +324 -0
  6. package/dist/cli/deploy.js.map +1 -0
  7. package/dist/cli/index.d.ts +15 -0
  8. package/dist/cli/index.d.ts.map +1 -0
  9. package/dist/cli/index.js +95 -0
  10. package/dist/cli/index.js.map +1 -0
  11. package/dist/cli/init.d.ts +9 -0
  12. package/dist/cli/init.d.ts.map +1 -0
  13. package/dist/cli/init.js +181 -0
  14. package/dist/cli/init.js.map +1 -0
  15. package/dist/cli/next-build.d.ts +24 -0
  16. package/dist/cli/next-build.d.ts.map +1 -0
  17. package/dist/cli/next-build.js +569 -0
  18. package/dist/cli/next-build.js.map +1 -0
  19. package/dist/cli/setup.d.ts +9 -0
  20. package/dist/cli/setup.d.ts.map +1 -0
  21. package/dist/cli/setup.js +157 -0
  22. package/dist/cli/setup.js.map +1 -0
  23. package/dist/cli/upload.d.ts +15 -0
  24. package/dist/cli/upload.d.ts.map +1 -0
  25. package/dist/cli/upload.js +436 -0
  26. package/dist/cli/upload.js.map +1 -0
  27. package/dist/client/_generated/_ignore.d.ts +1 -0
  28. package/dist/client/_generated/_ignore.d.ts.map +1 -0
  29. package/dist/client/_generated/_ignore.js +3 -0
  30. package/dist/client/_generated/_ignore.js.map +1 -0
  31. package/dist/client/index.d.ts +142 -0
  32. package/dist/client/index.d.ts.map +1 -0
  33. package/dist/client/index.js +475 -0
  34. package/dist/client/index.js.map +1 -0
  35. package/dist/client/next.d.ts +38 -0
  36. package/dist/client/next.d.ts.map +1 -0
  37. package/dist/client/next.js +175 -0
  38. package/dist/client/next.js.map +1 -0
  39. package/dist/client/nextAdapter.d.ts +4 -0
  40. package/dist/client/nextAdapter.d.ts.map +1 -0
  41. package/dist/client/nextAdapter.js +9 -0
  42. package/dist/client/nextAdapter.js.map +1 -0
  43. package/dist/component/_generated/api.d.ts +34 -0
  44. package/dist/component/_generated/api.d.ts.map +1 -0
  45. package/dist/component/_generated/api.js +31 -0
  46. package/dist/component/_generated/api.js.map +1 -0
  47. package/dist/component/_generated/component.d.ts +73 -0
  48. package/dist/component/_generated/component.d.ts.map +1 -0
  49. package/dist/component/_generated/component.js +11 -0
  50. package/dist/component/_generated/component.js.map +1 -0
  51. package/dist/component/_generated/dataModel.d.ts +46 -0
  52. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  53. package/dist/component/_generated/dataModel.js +11 -0
  54. package/dist/component/_generated/dataModel.js.map +1 -0
  55. package/dist/component/_generated/server.d.ts +121 -0
  56. package/dist/component/_generated/server.d.ts.map +1 -0
  57. package/dist/component/_generated/server.js +78 -0
  58. package/dist/component/_generated/server.js.map +1 -0
  59. package/dist/component/convex.config.d.ts +3 -0
  60. package/dist/component/convex.config.d.ts.map +1 -0
  61. package/dist/component/convex.config.js +3 -0
  62. package/dist/component/convex.config.js.map +1 -0
  63. package/dist/component/lib.d.ts +88 -0
  64. package/dist/component/lib.d.ts.map +1 -0
  65. package/dist/component/lib.js +210 -0
  66. package/dist/component/lib.js.map +1 -0
  67. package/dist/component/schema.d.ts +27 -0
  68. package/dist/component/schema.d.ts.map +1 -0
  69. package/dist/component/schema.js +20 -0
  70. package/dist/component/schema.js.map +1 -0
  71. package/dist/react/index.d.ts +80 -0
  72. package/dist/react/index.d.ts.map +1 -0
  73. package/dist/react/index.js +138 -0
  74. package/dist/react/index.js.map +1 -0
  75. package/package.json +120 -0
  76. package/src/cli/deploy.ts +375 -0
  77. package/src/cli/index.ts +104 -0
  78. package/src/cli/init.ts +181 -0
  79. package/src/cli/next-build.ts +707 -0
  80. package/src/cli/setup.ts +190 -0
  81. package/src/cli/upload.ts +521 -0
  82. package/src/client/_generated/_ignore.ts +1 -0
  83. package/src/client/index.test.ts +67 -0
  84. package/src/client/index.ts +553 -0
  85. package/src/client/next.ts +223 -0
  86. package/src/client/nextAdapter.ts +17 -0
  87. package/src/client/setup.test.ts +26 -0
  88. package/src/component/_generated/api.ts +50 -0
  89. package/src/component/_generated/component.ts +104 -0
  90. package/src/component/_generated/dataModel.ts +60 -0
  91. package/src/component/_generated/server.ts +161 -0
  92. package/src/component/convex.config.ts +3 -0
  93. package/src/component/lib.test.ts +110 -0
  94. package/src/component/lib.ts +228 -0
  95. package/src/component/schema.ts +21 -0
  96. package/src/component/setup.test.ts +11 -0
  97. package/src/react/index.tsx +184 -0
  98. package/src/test.ts +18 -0
@@ -0,0 +1,324 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * One-shot deployment command that deploys both Convex backend and static files.
4
+ *
5
+ * Usage:
6
+ * npx @convex-dev/static-hosting deploy [options]
7
+ *
8
+ * This command:
9
+ * 1. Builds the frontend with the correct VITE_CONVEX_URL
10
+ * 2. Deploys the Convex backend (npx convex deploy)
11
+ * 3. Deploys static files to Convex storage
12
+ *
13
+ * The goal is to minimize the inconsistency window between backend and frontend.
14
+ */
15
+ import { existsSync, readFileSync } from "fs";
16
+ import { resolve } from "path";
17
+ import { execSync, spawnSync } from "child_process";
18
+ function parseArgs(args) {
19
+ const result = {
20
+ dist: "./dist",
21
+ component: "staticHosting",
22
+ help: false,
23
+ skipBuild: false,
24
+ skipConvex: false,
25
+ cdn: false,
26
+ dev: false,
27
+ };
28
+ for (let i = 0; i < args.length; i++) {
29
+ const arg = args[i];
30
+ if (arg === "--help" || arg === "-h") {
31
+ result.help = true;
32
+ }
33
+ else if (arg === "--dist" || arg === "-d") {
34
+ result.dist = args[++i] || result.dist;
35
+ }
36
+ else if (arg === "--component" || arg === "-c") {
37
+ result.component = args[++i] || result.component;
38
+ }
39
+ else if (arg === "--skip-build") {
40
+ result.skipBuild = true;
41
+ }
42
+ else if (arg === "--skip-convex") {
43
+ result.skipConvex = true;
44
+ }
45
+ else if (arg === "--cdn") {
46
+ result.cdn = true;
47
+ }
48
+ else if (arg === "--dev") {
49
+ result.dev = true;
50
+ }
51
+ }
52
+ return result;
53
+ }
54
+ function showHelp() {
55
+ console.log(`
56
+ Usage: npx @convex-dev/static-hosting deploy [options]
57
+
58
+ One-shot deployment: builds frontend, deploys Convex backend, then deploys static files.
59
+ Minimizes the inconsistency window between backend and frontend updates.
60
+
61
+ Options:
62
+ -d, --dist <path> Path to dist directory (default: ./dist)
63
+ -c, --component <name> Convex component name (default: staticHosting)
64
+ --skip-build Skip the build step (use existing dist)
65
+ --skip-convex Skip Convex backend deployment
66
+ --cdn Upload non-HTML assets to convex-fs CDN
67
+ --dev Deploy to dev environment (skip backend deploy, upload without --prod)
68
+ -h, --help Show this help message
69
+
70
+ Deployment Flow (production, default):
71
+ 1. Build frontend with production VITE_CONVEX_URL
72
+ 2. Deploy Convex backend (npx convex deploy)
73
+ 3. Deploy static files to Convex storage
74
+
75
+ Deployment Flow (--dev):
76
+ 1. Build frontend with dev VITE_CONVEX_URL (from .env.local)
77
+ 2. Skip Convex backend deployment (use running 'npx convex dev')
78
+ 3. Deploy static files to dev Convex storage
79
+
80
+ Examples:
81
+ # Full production deployment
82
+ npx @convex-dev/static-hosting deploy
83
+
84
+ # Deploy to dev environment
85
+ npx @convex-dev/static-hosting deploy --dev
86
+
87
+ # Skip build (if already built)
88
+ npx @convex-dev/static-hosting deploy --skip-build
89
+
90
+ # Only deploy static files (skip Convex backend)
91
+ npx @convex-dev/static-hosting deploy --skip-convex
92
+ `);
93
+ }
94
+ /**
95
+ * Get the production Convex URL
96
+ */
97
+ function getConvexProdUrl() {
98
+ try {
99
+ const result = execSync("npx convex env get CONVEX_CLOUD_URL --prod", {
100
+ stdio: "pipe",
101
+ encoding: "utf-8",
102
+ });
103
+ return result.trim() || null;
104
+ }
105
+ catch {
106
+ // Fall back to env files
107
+ }
108
+ // Try env files as fallback
109
+ const envFiles = [".env.production", ".env.production.local", ".env.local"];
110
+ for (const envFile of envFiles) {
111
+ if (existsSync(envFile)) {
112
+ const content = readFileSync(envFile, "utf-8");
113
+ const match = content.match(/(?:VITE_)?CONVEX_URL=(.+)/);
114
+ if (match) {
115
+ return match[1].trim();
116
+ }
117
+ }
118
+ }
119
+ return null;
120
+ }
121
+ /**
122
+ * Get the dev Convex URL (from running `npx convex dev`)
123
+ */
124
+ function getConvexDevUrl() {
125
+ try {
126
+ const result = execSync("npx convex env get CONVEX_CLOUD_URL", {
127
+ stdio: "pipe",
128
+ encoding: "utf-8",
129
+ });
130
+ return result.trim() || null;
131
+ }
132
+ catch {
133
+ // Fall back to env files
134
+ }
135
+ // Try .env.local (standard location for dev URL)
136
+ const envFiles = [".env.local", ".env.development.local", ".env.development"];
137
+ for (const envFile of envFiles) {
138
+ if (existsSync(envFile)) {
139
+ const content = readFileSync(envFile, "utf-8");
140
+ const match = content.match(/(?:VITE_)?CONVEX_URL=(.+)/);
141
+ if (match) {
142
+ return match[1].trim();
143
+ }
144
+ }
145
+ }
146
+ return null;
147
+ }
148
+ /**
149
+ * Run the Convex storage upload flow
150
+ */
151
+ async function uploadToConvexStorage(distDir, componentName, useCdn, prod) {
152
+ console.log("");
153
+ console.log(useCdn
154
+ ? "📦 Uploading static files (HTML to Convex, assets to CDN)..."
155
+ : "📦 Uploading static files to Convex storage...");
156
+ console.log("");
157
+ const uploadArgs = [
158
+ "@convex-dev/static-hosting",
159
+ "upload",
160
+ "--dist",
161
+ distDir,
162
+ "--component",
163
+ componentName,
164
+ ];
165
+ if (prod) {
166
+ uploadArgs.push("--prod");
167
+ }
168
+ if (useCdn) {
169
+ uploadArgs.push("--cdn");
170
+ }
171
+ const result = spawnSync("npx", uploadArgs, { stdio: "inherit" });
172
+ return result.status === 0;
173
+ }
174
+ async function main() {
175
+ const args = parseArgs(process.argv.slice(2));
176
+ if (args.help) {
177
+ showHelp();
178
+ process.exit(0);
179
+ }
180
+ const isDev = args.dev;
181
+ // --dev implies --skip-convex (backend is managed by `npx convex dev`)
182
+ if (isDev) {
183
+ args.skipConvex = true;
184
+ }
185
+ console.log("");
186
+ console.log(isDev
187
+ ? "🚀 Convex + Static Files Deployment (dev)"
188
+ : "🚀 Convex + Static Files Deployment");
189
+ console.log("═══════════════════════════════════════════════════════════");
190
+ const startTime = Date.now();
191
+ // Step 1: Get Convex URL (needed for build)
192
+ console.log("");
193
+ console.log(isDev
194
+ ? "Step 1: Getting dev Convex URL..."
195
+ : "Step 1: Getting production Convex URL...");
196
+ let convexUrl = isDev ? getConvexDevUrl() : getConvexProdUrl();
197
+ if (!convexUrl && !args.skipConvex) {
198
+ console.log(" No production deployment found. Will get URL after deploying backend.");
199
+ }
200
+ else if (!convexUrl && isDev) {
201
+ console.error("");
202
+ console.error("❌ Could not determine dev Convex URL");
203
+ console.error(" Make sure 'npx convex dev' is running and .env.local contains CONVEX_URL");
204
+ process.exit(1);
205
+ }
206
+ else if (convexUrl) {
207
+ console.log(` ✓ ${convexUrl}`);
208
+ }
209
+ // Step 2: Build frontend
210
+ if (!args.skipBuild) {
211
+ console.log("");
212
+ console.log("Step 2: Building frontend...");
213
+ // If we don't have a URL yet, we need to deploy Convex first to get it
214
+ if (!convexUrl && !args.skipConvex) {
215
+ console.log(" Deploying Convex backend first to get production URL...");
216
+ console.log("");
217
+ const convexResult = spawnSync("npx", ["convex", "deploy"], {
218
+ stdio: "inherit",
219
+ });
220
+ if (convexResult.status !== 0) {
221
+ console.error("");
222
+ console.error("❌ Convex deployment failed");
223
+ process.exit(1);
224
+ }
225
+ // Now get the URL
226
+ convexUrl = getConvexProdUrl();
227
+ if (!convexUrl) {
228
+ console.error("");
229
+ console.error("❌ Could not get production Convex URL after deployment");
230
+ process.exit(1);
231
+ }
232
+ console.log("");
233
+ console.log(` ✓ Production URL: ${convexUrl}`);
234
+ args.skipConvex = true; // Already deployed
235
+ }
236
+ if (!convexUrl) {
237
+ console.error("");
238
+ console.error("❌ Could not determine Convex URL for build");
239
+ console.error(" Run 'npx convex deploy' first or remove --skip-convex");
240
+ process.exit(1);
241
+ }
242
+ console.log(` Building with VITE_CONVEX_URL=${convexUrl}`);
243
+ console.log("");
244
+ const buildResult = spawnSync("npm", ["run", "build"], {
245
+ stdio: "inherit",
246
+ env: { ...process.env, VITE_CONVEX_URL: convexUrl },
247
+ });
248
+ if (buildResult.status !== 0) {
249
+ console.error("");
250
+ console.error("❌ Build failed");
251
+ process.exit(1);
252
+ }
253
+ console.log("");
254
+ console.log(" ✓ Build complete");
255
+ }
256
+ else {
257
+ console.log("");
258
+ console.log("Step 2: Skipping build (--skip-build)");
259
+ }
260
+ // Step 3: Deploy Convex backend
261
+ if (!args.skipConvex) {
262
+ console.log("");
263
+ console.log("Step 3: Deploying Convex backend...");
264
+ console.log("");
265
+ const convexResult = spawnSync("npx", ["convex", "deploy"], {
266
+ stdio: "inherit",
267
+ });
268
+ if (convexResult.status !== 0) {
269
+ console.error("");
270
+ console.error("❌ Convex deployment failed");
271
+ process.exit(1);
272
+ }
273
+ console.log("");
274
+ console.log(" ✓ Convex backend deployed");
275
+ }
276
+ else {
277
+ console.log("");
278
+ console.log("Step 3: Skipping Convex deployment (--skip-convex or already deployed)");
279
+ }
280
+ // Step 4: Deploy static files
281
+ console.log("");
282
+ console.log("Step 4: Deploying static files to Convex storage...");
283
+ const distDir = resolve(args.dist);
284
+ if (!existsSync(distDir)) {
285
+ console.error("");
286
+ console.error(`❌ Dist directory not found: ${distDir}`);
287
+ console.error(" Run build first or check --dist path");
288
+ process.exit(1);
289
+ }
290
+ const staticDeploySuccess = await uploadToConvexStorage(distDir, args.component, args.cdn, !isDev);
291
+ if (!staticDeploySuccess) {
292
+ console.error("");
293
+ console.error("❌ Static file upload failed");
294
+ process.exit(1);
295
+ }
296
+ // Done!
297
+ const duration = ((Date.now() - startTime) / 1000).toFixed(1);
298
+ console.log("");
299
+ console.log("═══════════════════════════════════════════════════════════");
300
+ console.log(`✨ Deployment complete! (${duration}s)`);
301
+ console.log("");
302
+ // Show Convex site URL
303
+ try {
304
+ const envFlag = isDev ? "" : "--prod";
305
+ const result = execSync(`npx convex env get CONVEX_CLOUD_URL ${envFlag}`, {
306
+ stdio: "pipe",
307
+ encoding: "utf-8",
308
+ });
309
+ const cloudUrl = result.trim();
310
+ if (cloudUrl && cloudUrl.includes(".convex.cloud")) {
311
+ const siteUrl = cloudUrl.replace(".convex.cloud", ".convex.site");
312
+ console.log(`Frontend: ${siteUrl}`);
313
+ }
314
+ }
315
+ catch {
316
+ // Ignore
317
+ }
318
+ console.log("");
319
+ }
320
+ main().catch((error) => {
321
+ console.error("Deployment failed:", error);
322
+ process.exit(1);
323
+ });
324
+ //# sourceMappingURL=deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/cli/deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI for Convex Static Hosting
4
+ *
5
+ * Commands:
6
+ * deploy One-shot deployment (Convex backend + static files)
7
+ * upload Upload static files to Convex storage
8
+ * next-build Build Next.js app and prepare for Convex deployment
9
+ * init Print setup instructions
10
+ */
11
+ declare const command: string;
12
+ declare function main(): Promise<void>;
13
+ declare function printHelp(): void;
14
+ declare function printInitInstructions(): void;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,QAAA,MAAM,OAAO,QAAkB,CAAC;AAEhC,iBAAe,IAAI,kBAwClB;AAED,iBAAS,SAAS,SA0BjB;AAED,iBAAS,qBAAqB,SAe7B"}
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * CLI for Convex Static Hosting
5
+ *
6
+ * Commands:
7
+ * deploy One-shot deployment (Convex backend + static files)
8
+ * upload Upload static files to Convex storage
9
+ * next-build Build Next.js app and prepare for Convex deployment
10
+ * init Print setup instructions
11
+ */
12
+ const command = process.argv[2];
13
+ async function main() {
14
+ switch (command) {
15
+ case "setup":
16
+ await import("./setup.js");
17
+ break;
18
+ case "deploy":
19
+ // Pass remaining args to deploy command
20
+ process.argv.splice(2, 1);
21
+ await import("./deploy.js");
22
+ break;
23
+ case "upload":
24
+ // Pass remaining args to upload command
25
+ process.argv.splice(2, 1);
26
+ await import("./upload.js");
27
+ break;
28
+ case "next-build":
29
+ // Pass remaining args to next-build command
30
+ process.argv.splice(2, 1);
31
+ await import("./next-build.js");
32
+ break;
33
+ case "init":
34
+ printInitInstructions();
35
+ break;
36
+ case "--help":
37
+ case "-h":
38
+ case undefined:
39
+ printHelp();
40
+ break;
41
+ default:
42
+ console.error(`Unknown command: ${command}`);
43
+ console.log("");
44
+ printHelp();
45
+ process.exit(1);
46
+ }
47
+ }
48
+ function printHelp() {
49
+ console.log(`
50
+ Convex Static Hosting CLI
51
+
52
+ Usage:
53
+ npx @convex-dev/static-hosting <command> [options]
54
+
55
+ Commands:
56
+ setup Interactive setup wizard (creates files, configures deployment)
57
+ deploy One-shot deployment (Convex backend + static files)
58
+ upload Upload static files to Convex storage
59
+ next-build Build Next.js app and prepare for Convex deployment
60
+ init Print setup instructions for integration
61
+
62
+ Examples:
63
+ # Interactive setup (recommended for first-time users)
64
+ npx @convex-dev/static-hosting setup
65
+
66
+ # One-shot deployment
67
+ npx @convex-dev/static-hosting deploy
68
+
69
+ # Upload only (no Convex backend deploy)
70
+ npx @convex-dev/static-hosting upload --build --prod
71
+
72
+ Run '<command> --help' for more information on a specific command.
73
+ `);
74
+ }
75
+ function printInitInstructions() {
76
+ console.log(`
77
+ 📦 Convex Static Hosting
78
+
79
+ Quick Start:
80
+ npx @convex-dev/static-hosting setup # Interactive setup wizard
81
+
82
+ For LLMs:
83
+ Read INTEGRATION.md in this package for complete integration instructions
84
+
85
+ Manual Setup:
86
+ See README.md at https://github.com/get-convex/static-hosting#readme
87
+
88
+ This component hosts your static files in Convex storage and serves them via HTTP actions.
89
+ `);
90
+ }
91
+ main().catch((err) => {
92
+ console.error("Error:", err);
93
+ process.exit(1);
94
+ });
95
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AACA;;;;;;;;GAQG;AAEH,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,KAAK,UAAU,IAAI;IACjB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO;YACV,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;YAC3B,MAAM;QAER,KAAK,QAAQ;YACX,wCAAwC;YACxC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YAC5B,MAAM;QAER,KAAK,QAAQ;YACX,wCAAwC;YACxC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YAC5B,MAAM;QAER,KAAK,YAAY;YACf,4CAA4C;YAC5C,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAChC,MAAM;QAER,KAAK,MAAM;YACT,qBAAqB,EAAE,CAAC;YACxB,MAAM;QAER,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI,CAAC;QACV,KAAK,SAAS;YACZ,SAAS,EAAE,CAAC;YACZ,MAAM;QAER;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAwBb,CAAC,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB;IAC5B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;CAab,CAAC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Output integration instructions for LLMs.
4
+ *
5
+ * Usage:
6
+ * npx @convex-dev/static-hosting init
7
+ */
8
+ declare const instructions = "\n# Convex Static Hosting - Integration Instructions\n\nYou are integrating the @convex-dev/static-hosting component into a Convex app.\nThis component enables hosting static files (React/Vite apps) directly on Convex.\n\n## What This Component Does\n\n- Stores static files in Convex storage\n- Serves files via HTTP actions with proper MIME types\n- Supports SPA routing (fallback to index.html)\n- Smart caching: hashed assets cached forever, HTML revalidates\n- ETag support for efficient cache revalidation\n- Live reload notifications when new deployments happen\n\n## Files to Create/Modify\n\n### 1. convex/convex.config.ts (create or modify)\n\n```typescript\nimport { defineApp } from \"convex/server\";\nimport staticHosting from \"@convex-dev/static-hosting/convex.config\";\n\nconst app = defineApp();\napp.use(staticHosting);\n\nexport default app;\n```\n\n### 2. convex/staticHosting.ts (create)\n\n```typescript\nimport { components } from \"./_generated/api\";\nimport {\n exposeUploadApi,\n exposeDeploymentQuery,\n} from \"@convex-dev/static-hosting\";\n\n// Internal functions for secure uploads (only callable via CLI)\nexport const { generateUploadUrl, recordAsset, gcOldAssets, listAssets } =\n exposeUploadApi(components.staticHosting);\n\n// Public query for live reload notifications\nexport const { getCurrentDeployment } =\n exposeDeploymentQuery(components.staticHosting);\n```\n\n### 3. convex/http.ts (create or modify)\n\n```typescript\nimport { httpRouter } from \"convex/server\";\nimport { registerStaticRoutes } from \"@convex-dev/static-hosting\";\nimport { components } from \"./_generated/api\";\n\nconst http = httpRouter();\n\n// Option A: Serve at root (if no other HTTP routes)\nregisterStaticRoutes(http, components.staticHosting);\n\n// Option B: Serve at /app/ prefix (recommended if you have API routes)\n// registerStaticRoutes(http, components.staticHosting, {\n// pathPrefix: \"/app\",\n// });\n\n// Add other HTTP routes here if needed\n// http.route({ path: \"/api/webhook\", method: \"POST\", handler: ... });\n\nexport default http;\n```\n\n### 4. package.json scripts (add)\n\n```json\n{\n \"scripts\": {\n \"build\": \"vite build\",\n \"deploy:static\": \"npx @convex-dev/static-hosting upload --build --prod\"\n }\n}\n```\n\nIMPORTANT: Use `--build` flag instead of running `npm run build` separately.\nThe `--build` flag ensures `VITE_CONVEX_URL` is set correctly for the target\nenvironment (production or dev). Running build separately uses .env.local which\nhas the dev URL.\n\n### 5. src/App.tsx (optional: add live reload banner)\n\n```typescript\nimport { UpdateBanner } from \"@convex-dev/static-hosting/react\";\nimport { api } from \"../convex/_generated/api\";\n\nfunction App() {\n return (\n <div>\n {/* Shows banner when new deployment is available */}\n <UpdateBanner\n getCurrentDeployment={api.staticHosting.getCurrentDeployment}\n message=\"New version available!\"\n buttonText=\"Refresh\"\n />\n \n {/* Rest of your app */}\n </div>\n );\n}\n```\n\nOr use the hook for custom UI:\n```typescript\nimport { useDeploymentUpdates } from \"@convex-dev/static-hosting/react\";\nimport { api } from \"../convex/_generated/api\";\n\nfunction App() {\n const { updateAvailable, reload, dismiss } = useDeploymentUpdates(\n api.staticHosting.getCurrentDeployment\n );\n \n // Custom update notification UI\n}\n```\n\n## Deployment\n\n```bash\n# Login to Convex (first time)\nnpx convex login\n\n# Deploy Convex backend to production FIRST\nnpx convex deploy\n\n# Deploy static files to production\nnpm run deploy:static\n\n# Your app is now live at:\n# https://your-deployment.convex.site\n# (or https://your-deployment.convex.site/app/ if using path prefix)\n```\n\nFor development/testing:\n```bash\n# Push to dev environment\nnpx convex dev --once\n\n# Deploy static files to dev (omit --prod)\nnpx @convex-dev/static-hosting upload --build\n```\n\n## CLI Reference\n\n```bash\nnpx @convex-dev/static-hosting upload [options]\n\nOptions:\n -d, --dist <path> Path to dist directory (default: ./dist)\n -c, --component <name> Convex component name (default: staticHosting)\n --prod Deploy to production Convex deployment\n --dev Deploy to dev deployment (default)\n -b, --build Run 'npm run build' with correct VITE_CONVEX_URL\n -h, --help Show help\n```\n\n## Important Notes\n\n1. The upload functions are INTERNAL - they can only be called via `npx convex run`, not from the public internet\n2. Static files are stored in the app's storage (not the component's) for proper isolation\n3. Hashed assets (e.g., main-abc123.js) get immutable caching; HTML files always revalidate\n4. The component supports SPA routing - routes without file extensions serve index.html\n5. Always use `--build` flag to ensure VITE_CONVEX_URL is set correctly for the target environment\n6. Deploy Convex backend (`npx convex deploy`) BEFORE deploying static files to production\n";
9
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,QAAA,MAAM,YAAY,+9JA0KjB,CAAC"}
@@ -0,0 +1,181 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Output integration instructions for LLMs.
5
+ *
6
+ * Usage:
7
+ * npx @convex-dev/static-hosting init
8
+ */
9
+ const instructions = `
10
+ # Convex Static Hosting - Integration Instructions
11
+
12
+ You are integrating the @convex-dev/static-hosting component into a Convex app.
13
+ This component enables hosting static files (React/Vite apps) directly on Convex.
14
+
15
+ ## What This Component Does
16
+
17
+ - Stores static files in Convex storage
18
+ - Serves files via HTTP actions with proper MIME types
19
+ - Supports SPA routing (fallback to index.html)
20
+ - Smart caching: hashed assets cached forever, HTML revalidates
21
+ - ETag support for efficient cache revalidation
22
+ - Live reload notifications when new deployments happen
23
+
24
+ ## Files to Create/Modify
25
+
26
+ ### 1. convex/convex.config.ts (create or modify)
27
+
28
+ \`\`\`typescript
29
+ import { defineApp } from "convex/server";
30
+ import staticHosting from "@convex-dev/static-hosting/convex.config";
31
+
32
+ const app = defineApp();
33
+ app.use(staticHosting);
34
+
35
+ export default app;
36
+ \`\`\`
37
+
38
+ ### 2. convex/staticHosting.ts (create)
39
+
40
+ \`\`\`typescript
41
+ import { components } from "./_generated/api";
42
+ import {
43
+ exposeUploadApi,
44
+ exposeDeploymentQuery,
45
+ } from "@convex-dev/static-hosting";
46
+
47
+ // Internal functions for secure uploads (only callable via CLI)
48
+ export const { generateUploadUrl, recordAsset, gcOldAssets, listAssets } =
49
+ exposeUploadApi(components.staticHosting);
50
+
51
+ // Public query for live reload notifications
52
+ export const { getCurrentDeployment } =
53
+ exposeDeploymentQuery(components.staticHosting);
54
+ \`\`\`
55
+
56
+ ### 3. convex/http.ts (create or modify)
57
+
58
+ \`\`\`typescript
59
+ import { httpRouter } from "convex/server";
60
+ import { registerStaticRoutes } from "@convex-dev/static-hosting";
61
+ import { components } from "./_generated/api";
62
+
63
+ const http = httpRouter();
64
+
65
+ // Option A: Serve at root (if no other HTTP routes)
66
+ registerStaticRoutes(http, components.staticHosting);
67
+
68
+ // Option B: Serve at /app/ prefix (recommended if you have API routes)
69
+ // registerStaticRoutes(http, components.staticHosting, {
70
+ // pathPrefix: "/app",
71
+ // });
72
+
73
+ // Add other HTTP routes here if needed
74
+ // http.route({ path: "/api/webhook", method: "POST", handler: ... });
75
+
76
+ export default http;
77
+ \`\`\`
78
+
79
+ ### 4. package.json scripts (add)
80
+
81
+ \`\`\`json
82
+ {
83
+ "scripts": {
84
+ "build": "vite build",
85
+ "deploy:static": "npx @convex-dev/static-hosting upload --build --prod"
86
+ }
87
+ }
88
+ \`\`\`
89
+
90
+ IMPORTANT: Use \`--build\` flag instead of running \`npm run build\` separately.
91
+ The \`--build\` flag ensures \`VITE_CONVEX_URL\` is set correctly for the target
92
+ environment (production or dev). Running build separately uses .env.local which
93
+ has the dev URL.
94
+
95
+ ### 5. src/App.tsx (optional: add live reload banner)
96
+
97
+ \`\`\`typescript
98
+ import { UpdateBanner } from "@convex-dev/static-hosting/react";
99
+ import { api } from "../convex/_generated/api";
100
+
101
+ function App() {
102
+ return (
103
+ <div>
104
+ {/* Shows banner when new deployment is available */}
105
+ <UpdateBanner
106
+ getCurrentDeployment={api.staticHosting.getCurrentDeployment}
107
+ message="New version available!"
108
+ buttonText="Refresh"
109
+ />
110
+
111
+ {/* Rest of your app */}
112
+ </div>
113
+ );
114
+ }
115
+ \`\`\`
116
+
117
+ Or use the hook for custom UI:
118
+ \`\`\`typescript
119
+ import { useDeploymentUpdates } from "@convex-dev/static-hosting/react";
120
+ import { api } from "../convex/_generated/api";
121
+
122
+ function App() {
123
+ const { updateAvailable, reload, dismiss } = useDeploymentUpdates(
124
+ api.staticHosting.getCurrentDeployment
125
+ );
126
+
127
+ // Custom update notification UI
128
+ }
129
+ \`\`\`
130
+
131
+ ## Deployment
132
+
133
+ \`\`\`bash
134
+ # Login to Convex (first time)
135
+ npx convex login
136
+
137
+ # Deploy Convex backend to production FIRST
138
+ npx convex deploy
139
+
140
+ # Deploy static files to production
141
+ npm run deploy:static
142
+
143
+ # Your app is now live at:
144
+ # https://your-deployment.convex.site
145
+ # (or https://your-deployment.convex.site/app/ if using path prefix)
146
+ \`\`\`
147
+
148
+ For development/testing:
149
+ \`\`\`bash
150
+ # Push to dev environment
151
+ npx convex dev --once
152
+
153
+ # Deploy static files to dev (omit --prod)
154
+ npx @convex-dev/static-hosting upload --build
155
+ \`\`\`
156
+
157
+ ## CLI Reference
158
+
159
+ \`\`\`bash
160
+ npx @convex-dev/static-hosting upload [options]
161
+
162
+ Options:
163
+ -d, --dist <path> Path to dist directory (default: ./dist)
164
+ -c, --component <name> Convex component name (default: staticHosting)
165
+ --prod Deploy to production Convex deployment
166
+ --dev Deploy to dev deployment (default)
167
+ -b, --build Run 'npm run build' with correct VITE_CONVEX_URL
168
+ -h, --help Show help
169
+ \`\`\`
170
+
171
+ ## Important Notes
172
+
173
+ 1. The upload functions are INTERNAL - they can only be called via \`npx convex run\`, not from the public internet
174
+ 2. Static files are stored in the app's storage (not the component's) for proper isolation
175
+ 3. Hashed assets (e.g., main-abc123.js) get immutable caching; HTML files always revalidate
176
+ 4. The component supports SPA routing - routes without file extensions serve index.html
177
+ 5. Always use \`--build\` flag to ensure VITE_CONVEX_URL is set correctly for the target environment
178
+ 6. Deploy Convex backend (\`npx convex deploy\`) BEFORE deploying static files to production
179
+ `;
180
+ console.log(instructions);
181
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":";;AACA;;;;;GAKG;AAEH,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0KpB,CAAC;AAEF,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC"}