@jasonshimmy/vite-plugin-cer-app 0.8.0 → 0.10.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 (84) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/ROADMAP.md +23 -11
  3. package/commits.txt +1 -1
  4. package/dist/cli/adapters/netlify.d.ts +24 -0
  5. package/dist/cli/adapters/netlify.d.ts.map +1 -0
  6. package/dist/cli/adapters/netlify.js +266 -0
  7. package/dist/cli/adapters/netlify.js.map +1 -0
  8. package/dist/cli/adapters/vercel.d.ts +20 -0
  9. package/dist/cli/adapters/vercel.d.ts.map +1 -0
  10. package/dist/cli/adapters/vercel.js +217 -0
  11. package/dist/cli/adapters/vercel.js.map +1 -0
  12. package/dist/cli/commands/adapt.d.ts +3 -0
  13. package/dist/cli/commands/adapt.d.ts.map +1 -0
  14. package/dist/cli/commands/adapt.js +25 -0
  15. package/dist/cli/commands/adapt.js.map +1 -0
  16. package/dist/cli/commands/build.d.ts.map +1 -1
  17. package/dist/cli/commands/build.js +19 -0
  18. package/dist/cli/commands/build.js.map +1 -1
  19. package/dist/cli/commands/preview.d.ts.map +1 -1
  20. package/dist/cli/commands/preview.js +57 -4
  21. package/dist/cli/commands/preview.js.map +1 -1
  22. package/dist/cli/index.js +2 -0
  23. package/dist/cli/index.js.map +1 -1
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/plugin/dts-generator.js +1 -1
  27. package/dist/plugin/dts-generator.js.map +1 -1
  28. package/dist/plugin/transforms/auto-import.js +2 -2
  29. package/dist/plugin/transforms/auto-import.js.map +1 -1
  30. package/dist/runtime/composables/index.d.ts +4 -0
  31. package/dist/runtime/composables/index.d.ts.map +1 -1
  32. package/dist/runtime/composables/index.js +2 -0
  33. package/dist/runtime/composables/index.js.map +1 -1
  34. package/dist/runtime/composables/use-cookie.d.ts +38 -0
  35. package/dist/runtime/composables/use-cookie.d.ts.map +1 -0
  36. package/dist/runtime/composables/use-cookie.js +104 -0
  37. package/dist/runtime/composables/use-cookie.js.map +1 -0
  38. package/dist/runtime/composables/use-runtime-config.d.ts.map +1 -1
  39. package/dist/runtime/composables/use-runtime-config.js +12 -4
  40. package/dist/runtime/composables/use-runtime-config.js.map +1 -1
  41. package/dist/runtime/composables/use-seo-meta.d.ts +42 -0
  42. package/dist/runtime/composables/use-seo-meta.d.ts.map +1 -0
  43. package/dist/runtime/composables/use-seo-meta.js +58 -0
  44. package/dist/runtime/composables/use-seo-meta.js.map +1 -0
  45. package/dist/runtime/entry-server-template.d.ts +1 -1
  46. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  47. package/dist/runtime/entry-server-template.js +8 -0
  48. package/dist/runtime/entry-server-template.js.map +1 -1
  49. package/dist/types/config.d.ts +11 -0
  50. package/dist/types/config.d.ts.map +1 -1
  51. package/dist/types/config.js.map +1 -1
  52. package/docs/cli.md +56 -0
  53. package/docs/composables.md +133 -0
  54. package/e2e/cypress/e2e/cookie.cy.ts +68 -0
  55. package/e2e/cypress/e2e/preview-hardening.cy.ts +79 -0
  56. package/e2e/cypress/e2e/seo-meta.cy.ts +108 -0
  57. package/e2e/kitchen-sink/app/pages/cookie-test.ts +22 -0
  58. package/e2e/kitchen-sink/app/pages/seo-test.ts +23 -0
  59. package/e2e/scripts/clean.mjs +5 -1
  60. package/package.json +3 -1
  61. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +138 -0
  62. package/src/__tests__/cli/adapters/netlify.test.ts +225 -0
  63. package/src/__tests__/cli/adapters/vercel.test.ts +233 -0
  64. package/src/__tests__/cli/preview-hardening.test.ts +175 -0
  65. package/src/__tests__/plugin/entry-server-template.test.ts +21 -0
  66. package/src/__tests__/plugin/transforms/auto-import.test.ts +23 -0
  67. package/src/__tests__/runtime/use-cookie.test.ts +218 -0
  68. package/src/__tests__/runtime/use-runtime-config.test.ts +24 -1
  69. package/src/__tests__/runtime/use-seo-meta.test.ts +109 -0
  70. package/src/cli/adapters/netlify.ts +295 -0
  71. package/src/cli/adapters/vercel.ts +272 -0
  72. package/src/cli/commands/adapt.ts +27 -0
  73. package/src/cli/commands/build.ts +19 -0
  74. package/src/cli/commands/preview.ts +66 -5
  75. package/src/cli/index.ts +2 -0
  76. package/src/index.ts +2 -0
  77. package/src/plugin/dts-generator.ts +1 -1
  78. package/src/plugin/transforms/auto-import.ts +2 -2
  79. package/src/runtime/composables/index.ts +4 -0
  80. package/src/runtime/composables/use-cookie.ts +128 -0
  81. package/src/runtime/composables/use-runtime-config.ts +14 -4
  82. package/src/runtime/composables/use-seo-meta.ts +75 -0
  83. package/src/runtime/entry-server-template.ts +8 -0
  84. package/src/types/config.ts +11 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # Changelog
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
+ ## [v0.10.0] - 2026-03-22
5
+
6
+ - feat: add adapters for Vercel and Netlify deployment platforms (7112bf6)
7
+
8
+ ## [v0.9.0] - 2026-03-21
9
+
10
+ - feat: add useCookie and useSeoMeta composables with tests (6536902)
11
+
4
12
  ## [v0.8.0] - 2026-03-21
5
13
 
6
14
  - feat: add middleware support and enhance runtime configuration (78ef4d2)
package/ROADMAP.md CHANGED
@@ -78,7 +78,7 @@ export const loader = async () => {
78
78
 
79
79
  ---
80
80
 
81
- ### 8.3 Preview server hardening 📋
81
+ ### 8.3 Preview server hardening
82
82
 
83
83
  **Problem:** The preview server (`cer-app preview`) is used in CI and staging
84
84
  but lacks basic production safeguards.
@@ -185,7 +185,7 @@ export function defineMiddleware(fn: MiddlewareFn): MiddlewareFn { return fn }
185
185
 
186
186
  ---
187
187
 
188
- ### 9.2 `useCookie()` composable 📋
188
+ ### 9.2 `useCookie()` composable
189
189
 
190
190
  **Problem:** Session-based auth requires manual `document.cookie` parsing on
191
191
  the client and `req.headers.cookie` parsing in loaders. No isomorphic helper
@@ -222,7 +222,7 @@ changes.
222
222
 
223
223
  ---
224
224
 
225
- ### 10.2 Vercel adapter 🔜
225
+ ### 10.2 Vercel adapter
226
226
 
227
227
  **Problem:** Vercel expects functions in `.vercel/output/functions/` with a
228
228
  specific manifest format.
@@ -233,11 +233,23 @@ Static assets are moved to `.vercel/output/static/`.
233
233
 
234
234
  **Complexity:** Medium. Mostly file system manipulation.
235
235
 
236
+ **Files:**
237
+ - `src/cli/adapters/vercel.ts` — Vercel Build Output API v3 adapter
238
+ - `src/cli/commands/adapt.ts` — `cer-app adapt` command
239
+ - `src/types/config.ts` — `adapter` field on `CerAppConfig`
240
+ - `src/cli/commands/build.ts` — auto-runs adapter post-build
241
+
236
242
  ---
237
243
 
238
- ### 10.3 Netlify adapter 🔜
244
+ ### 10.3 Netlify adapter
239
245
 
240
- Similar to Vercel but targets Netlify Functions / Edge Functions format.
246
+ Similar to Vercel but targets Netlify Functions v2 format. Writes a bridge
247
+ function (`netlify/functions/ssr.mjs`) that converts between the Web
248
+ `Request`/`Response` API and the Node.js-style handler. Responses are
249
+ buffered (no streaming — Netlify Functions limitation).
250
+
251
+ **Files:**
252
+ - `src/cli/adapters/netlify.ts` — Netlify adapter
241
253
 
242
254
  ---
243
255
 
@@ -254,7 +266,7 @@ Convention: `app/i18n/en.json` + `app/i18n/fr.json`. Auto-injected
254
266
  `useI18n()` composable that reads the active locale from a cookie/query param.
255
267
  `cer-app i18n extract` CLI command for string extraction.
256
268
 
257
- ### 11.3 `useSeoMeta()` 📋
269
+ ### 11.3 `useSeoMeta()`
258
270
 
259
271
  Thin wrapper around `useHead()` covering OpenGraph, Twitter cards, and
260
272
  canonical URL. No new infrastructure needed — all forwarded to `<head>`.
@@ -267,12 +279,12 @@ canonical URL. No new infrastructure needed — all forwarded to `<head>`.
267
279
  |---|------|----------|--------|
268
280
  | 8.1 | Path traversal fix in preview server | 🔴 Critical | ✅ |
269
281
  | 8.2 | `runtimeConfig.private` (server-only secrets) | 🔴 Critical | ✅ |
270
- | 8.3 | Preview server hardening (headers, timeouts, graceful shutdown) | 🟡 High | 📋 |
282
+ | 8.3 | Preview server hardening (headers, timeouts, graceful shutdown) | 🟡 High | |
271
283
  | 9.1 | Client-side route middleware (navigation guards) | 🟡 High | ✅ |
272
- | 9.2 | `useCookie()` composable | 🟡 High | 📋 |
284
+ | 9.2 | `useCookie()` composable | 🟡 High | |
273
285
  | 10.1 | Cloudflare Workers adapter | 🟢 Medium | 🔜 |
274
- | 10.2 | Vercel adapter | 🟢 Medium | 🔜 |
275
- | 10.3 | Netlify adapter | 🟢 Medium | 🔜 |
286
+ | 10.2 | Vercel adapter | 🟢 Medium | |
287
+ | 10.3 | Netlify adapter | 🟢 Medium | |
276
288
  | 11.1 | DevTools overlay | 🟢 Medium | ❌ |
277
289
  | 11.2 | i18n | 🟢 Medium | 🔜 |
278
- | 11.3 | `useSeoMeta()` | 🟢 Medium | 📋 |
290
+ | 11.3 | `useSeoMeta()` | 🟢 Medium | |
package/commits.txt CHANGED
@@ -1 +1 @@
1
- - feat: add middleware support and enhance runtime configuration (78ef4d2)
1
+ - feat: add adapters for Vercel and Netlify deployment platforms (7112bf6)
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Netlify adapter.
3
+ *
4
+ * Transforms the cer-app `dist/` output into the files needed to deploy on
5
+ * Netlify.
6
+ *
7
+ * SSR mode:
8
+ * - Writes a `netlify/functions/ssr.mjs` bridge that converts Netlify
9
+ * Functions v2 Web API (Request/Response) to the Node.js-style handler
10
+ * used by the cer-app server bundle. Handles /api/* routing inline.
11
+ * - Creates `.netlify/publish/` with content-hashed assets only (no HTML),
12
+ * so Netlify's CDN serves static files and everything else falls through
13
+ * to the SSR function.
14
+ * - Writes `netlify.toml` with the publish directory and catch-all redirect.
15
+ *
16
+ * SPA/SSG mode:
17
+ * - Writes `netlify.toml` that points to the correct publish directory and
18
+ * adds a SPA fallback redirect (/* → /index.html).
19
+ *
20
+ * Netlify Functions v2 limitation: responses are buffered (no streaming).
21
+ * All other behaviour (cookies, headers, API routes, ISR) is fully supported.
22
+ */
23
+ export declare function runNetlifyAdapter(root: string): Promise<void>;
24
+ //# sourceMappingURL=netlify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"netlify.d.ts","sourceRoot":"","sources":["../../../src/cli/adapters/netlify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA8IH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0BnE"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Netlify adapter.
3
+ *
4
+ * Transforms the cer-app `dist/` output into the files needed to deploy on
5
+ * Netlify.
6
+ *
7
+ * SSR mode:
8
+ * - Writes a `netlify/functions/ssr.mjs` bridge that converts Netlify
9
+ * Functions v2 Web API (Request/Response) to the Node.js-style handler
10
+ * used by the cer-app server bundle. Handles /api/* routing inline.
11
+ * - Creates `.netlify/publish/` with content-hashed assets only (no HTML),
12
+ * so Netlify's CDN serves static files and everything else falls through
13
+ * to the SSR function.
14
+ * - Writes `netlify.toml` with the publish directory and catch-all redirect.
15
+ *
16
+ * SPA/SSG mode:
17
+ * - Writes `netlify.toml` that points to the correct publish directory and
18
+ * adds a SPA fallback redirect (/* → /index.html).
19
+ *
20
+ * Netlify Functions v2 limitation: responses are buffered (no streaming).
21
+ * All other behaviour (cookies, headers, API routes, ISR) is fully supported.
22
+ */
23
+ import { join } from 'pathe';
24
+ import { existsSync, mkdirSync, writeFileSync, copyFileSync, cpSync, readdirSync, statSync, rmSync, } from 'node:fs';
25
+ // ─── SSR function bridge template ────────────────────────────────────────────
26
+ /**
27
+ * Netlify Functions v2 bridge.
28
+ *
29
+ * The function:
30
+ * 1. Converts the incoming Web API Request to a mock Node.js IncomingMessage.
31
+ * 2. Creates a mock ServerResponse that collects chunks and resolves a Promise
32
+ * with a Web API Response once `end()` is called.
33
+ * 3. Routes /api/* to the API handlers, everything else to the SSR handler.
34
+ *
35
+ * The server bundle is imported using a path relative to the function file
36
+ * location: netlify/functions/ssr.mjs → ../../dist/server/server.js.
37
+ */
38
+ const NETLIFY_SSR_BRIDGE = `\
39
+ // Auto-generated by @jasonshimmy/vite-plugin-cer-app — do not edit.
40
+ import { Readable } from 'node:stream'
41
+ import { handler, apiRoutes } from '../../dist/server/server.js'
42
+
43
+ function matchApiPattern(pattern, urlPath) {
44
+ const pp = pattern.split('/')
45
+ const up = urlPath.split('/')
46
+ if (pp.length !== up.length) return null
47
+ const params = {}
48
+ for (let i = 0; i < pp.length; i++) {
49
+ if (pp[i].startsWith(':')) params[pp[i].slice(1)] = decodeURIComponent(up[i])
50
+ else if (pp[i] !== up[i]) return null
51
+ }
52
+ return params
53
+ }
54
+
55
+ async function toNodeRequest(webReq) {
56
+ const url = new URL(webReq.url)
57
+ const hasBody = webReq.body !== null
58
+ && webReq.method !== 'GET'
59
+ && webReq.method !== 'HEAD'
60
+ const body = hasBody ? Buffer.from(await webReq.arrayBuffer()) : null
61
+ const req = Object.assign(
62
+ body ? Readable.from([body]) : Readable.from([]),
63
+ {
64
+ url: url.pathname + url.search,
65
+ method: webReq.method,
66
+ headers: Object.fromEntries(webReq.headers.entries()),
67
+ },
68
+ )
69
+ return req
70
+ }
71
+
72
+ function createNodeResponse() {
73
+ const chunks = []
74
+ const headers = {}
75
+ let _resolve
76
+ let _ended = false
77
+ const promise = new Promise((res) => { _resolve = res })
78
+ const res = {
79
+ statusCode: 200,
80
+ setHeader(name, value) { headers[name.toLowerCase()] = String(value) },
81
+ getHeader(name) { return headers[name.toLowerCase()] },
82
+ removeHeader(name) { delete headers[name.toLowerCase()] },
83
+ write(chunk) {
84
+ if (_ended) return
85
+ chunks.push(typeof chunk === 'string' ? Buffer.from(chunk, 'utf-8') : Buffer.from(chunk))
86
+ },
87
+ end(chunk) {
88
+ if (_ended) return
89
+ _ended = true
90
+ if (chunk) {
91
+ chunks.push(typeof chunk === 'string' ? Buffer.from(chunk, 'utf-8') : Buffer.from(chunk))
92
+ }
93
+ _resolve(new Response(Buffer.concat(chunks), { status: res.statusCode, headers }))
94
+ },
95
+ // Helpers expected by API route handlers.
96
+ json(data) {
97
+ this.setHeader('Content-Type', 'application/json; charset=utf-8')
98
+ this.end(JSON.stringify(data))
99
+ },
100
+ status(code) { this.statusCode = code; return this },
101
+ get writableEnded() { return _ended },
102
+ }
103
+ return { res, promise }
104
+ }
105
+
106
+ export default async (webReq) => {
107
+ const url = new URL(webReq.url)
108
+ const urlPath = url.pathname
109
+ const method = webReq.method ?? 'GET'
110
+
111
+ // Route /api/* requests to the API handlers exported by the server bundle.
112
+ if (urlPath.startsWith('/api/')) {
113
+ for (const route of (apiRoutes ?? [])) {
114
+ const params = matchApiPattern(route.path, urlPath)
115
+ if (params !== null) {
116
+ const nodeReq = await toNodeRequest(webReq)
117
+ nodeReq.params = params
118
+ const { res, promise } = createNodeResponse()
119
+ const fn = route.handlers[method.toLowerCase()]
120
+ ?? route.handlers[method.toUpperCase()]
121
+ ?? route.handlers['default']
122
+ if (typeof fn === 'function') {
123
+ // Use Promise.resolve() so the catch works for both sync and async handlers.
124
+ Promise.resolve(fn(nodeReq, res)).catch(() => {
125
+ if (!res.writableEnded) {
126
+ res.statusCode = 500
127
+ res.end(JSON.stringify({ error: 'Internal Server Error' }))
128
+ }
129
+ })
130
+ return promise
131
+ }
132
+ }
133
+ }
134
+ return new Response('Not Found', { status: 404 })
135
+ }
136
+
137
+ // All other requests: SSR.
138
+ const nodeReq = await toNodeRequest(webReq)
139
+ const { res, promise } = createNodeResponse()
140
+ handler(nodeReq, res).catch(() => {
141
+ if (!res.writableEnded) {
142
+ res.statusCode = 500
143
+ res.end('Internal Server Error')
144
+ }
145
+ })
146
+ return promise
147
+ }
148
+ `;
149
+ // ─── Public API ───────────────────────────────────────────────────────────────
150
+ export async function runNetlifyAdapter(root) {
151
+ const distDir = join(root, 'dist');
152
+ if (!existsSync(distDir)) {
153
+ throw new Error(`[cer-app] No dist/ directory found at ${distDir}. Run 'cer-app build' first.`);
154
+ }
155
+ const serverBundle = join(distDir, 'server/server.js');
156
+ const ssgManifest = join(distDir, 'ssg-manifest.json');
157
+ const isSSR = existsSync(serverBundle) && !existsSync(ssgManifest);
158
+ if (isSSR) {
159
+ _buildSSR(root, distDir);
160
+ }
161
+ else {
162
+ _buildStatic(root, distDir);
163
+ }
164
+ console.log('[cer-app] Netlify adapter complete.');
165
+ if (isSSR) {
166
+ console.log(' Function: netlify/functions/ssr.mjs');
167
+ console.log(' Static: .netlify/publish/');
168
+ console.log(' Deploy with: netlify deploy');
169
+ }
170
+ else {
171
+ console.log(' Deploy with: netlify deploy');
172
+ }
173
+ }
174
+ // ─── SSR output ───────────────────────────────────────────────────────────────
175
+ function _buildSSR(root, distDir) {
176
+ // Write the SSR bridge function.
177
+ const functionsDir = join(root, 'netlify/functions');
178
+ mkdirSync(functionsDir, { recursive: true });
179
+ writeFileSync(join(functionsDir, 'ssr.mjs'), NETLIFY_SSR_BRIDGE);
180
+ // Build the static publish directory with assets only (no HTML).
181
+ // Netlify serves files in the publish directory as static responses first.
182
+ // By omitting index.html we ensure all HTML routes fall through to the
183
+ // SSR function instead of being served as stale static files.
184
+ const publishDir = join(root, '.netlify/publish');
185
+ if (existsSync(publishDir)) {
186
+ rmSync(publishDir, { recursive: true, force: true });
187
+ }
188
+ _copyClientAssets(join(distDir, 'client'), publishDir);
189
+ // netlify.toml: publish directory + cache headers + catch-all to SSR function.
190
+ writeFileSync(join(root, 'netlify.toml'), `# Auto-generated by @jasonshimmy/vite-plugin-cer-app — do not edit.
191
+ [build]
192
+ publish = ".netlify/publish"
193
+
194
+ [[headers]]
195
+ for = "/assets/*"
196
+ [headers.values]
197
+ Cache-Control = "public, max-age=31536000, immutable"
198
+
199
+ [[redirects]]
200
+ from = "/*"
201
+ to = "/.netlify/functions/ssr"
202
+ status = 200
203
+ `);
204
+ }
205
+ // ─── Static (SPA / SSG) output ────────────────────────────────────────────────
206
+ function _buildStatic(root, distDir) {
207
+ const clientDir = join(distDir, 'client');
208
+ let publishDir;
209
+ if (existsSync(clientDir)) {
210
+ // SSG: HTML in dist/, assets in dist/client/. Merge into .netlify/publish/.
211
+ publishDir = join(root, '.netlify/publish');
212
+ if (existsSync(publishDir)) {
213
+ rmSync(publishDir, { recursive: true, force: true });
214
+ }
215
+ // Copy pre-rendered HTML from dist/ (skip client/ sub-dir and manifest).
216
+ cpSync(distDir, publishDir, {
217
+ recursive: true,
218
+ filter: (src) => src !== clientDir && !src.endsWith('ssg-manifest.json'),
219
+ });
220
+ // Copy assets from dist/client/ into the publish root.
221
+ _copyClientAssets(clientDir, publishDir);
222
+ }
223
+ else {
224
+ // SPA: everything is in dist/ at correct URL paths already.
225
+ publishDir = 'dist';
226
+ }
227
+ // netlify.toml: SPA fallback redirect.
228
+ writeFileSync(join(root, 'netlify.toml'), `# Auto-generated by @jasonshimmy/vite-plugin-cer-app — do not edit.
229
+ [build]
230
+ publish = "${publishDir.startsWith(root) ? publishDir.slice(root.length + 1) : publishDir}"
231
+
232
+ [[headers]]
233
+ for = "/assets/*"
234
+ [headers.values]
235
+ Cache-Control = "public, max-age=31536000, immutable"
236
+
237
+ [[redirects]]
238
+ from = "/*"
239
+ to = "/index.html"
240
+ status = 200
241
+ `);
242
+ }
243
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
244
+ /**
245
+ * Copies content-hashed assets and other public files (favicon, robots.txt, …)
246
+ * from the client dist directory into `destDir`.
247
+ * Skips index.html so it is never served as a static file in SSR mode.
248
+ */
249
+ function _copyClientAssets(clientDir, destDir) {
250
+ if (!existsSync(clientDir))
251
+ return;
252
+ mkdirSync(destDir, { recursive: true });
253
+ for (const entry of readdirSync(clientDir)) {
254
+ if (entry === 'index.html')
255
+ continue;
256
+ const src = join(clientDir, entry);
257
+ const dest = join(destDir, entry);
258
+ if (statSync(src).isDirectory()) {
259
+ cpSync(src, dest, { recursive: true });
260
+ }
261
+ else {
262
+ copyFileSync(src, dest);
263
+ }
264
+ }
265
+ }
266
+ //# sourceMappingURL=netlify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"netlify.js","sourceRoot":"","sources":["../../../src/cli/adapters/netlify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Vercel Build Output API v3 adapter.
3
+ *
4
+ * Transforms the cer-app `dist/` output into a `.vercel/output/` directory
5
+ * that can be deployed with `vercel deploy --prebuilt`.
6
+ *
7
+ * SSR mode:
8
+ * - Copies dist/server/server.js into a Vercel Serverless Function
9
+ * - Copies dist/client/index.html alongside the server bundle so the
10
+ * `../client/index.html` relative path in the bundle resolves correctly
11
+ * - Copies content-hashed assets to .vercel/output/static/ for CDN delivery
12
+ * - Writes a launcher (index.js) that routes /api/* to the API handlers and
13
+ * forwards all other requests to the SSR handler
14
+ *
15
+ * SPA/SSG mode:
16
+ * - Copies all static files to .vercel/output/static/
17
+ * - Writes a config.json with SPA fallback (serve index.html for unknown paths)
18
+ */
19
+ export declare function runVercelAdapter(root: string): Promise<void>;
20
+ //# sourceMappingURL=vercel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel.d.ts","sourceRoot":"","sources":["../../../src/cli/adapters/vercel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAqFH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BlE"}
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Vercel Build Output API v3 adapter.
3
+ *
4
+ * Transforms the cer-app `dist/` output into a `.vercel/output/` directory
5
+ * that can be deployed with `vercel deploy --prebuilt`.
6
+ *
7
+ * SSR mode:
8
+ * - Copies dist/server/server.js into a Vercel Serverless Function
9
+ * - Copies dist/client/index.html alongside the server bundle so the
10
+ * `../client/index.html` relative path in the bundle resolves correctly
11
+ * - Copies content-hashed assets to .vercel/output/static/ for CDN delivery
12
+ * - Writes a launcher (index.js) that routes /api/* to the API handlers and
13
+ * forwards all other requests to the SSR handler
14
+ *
15
+ * SPA/SSG mode:
16
+ * - Copies all static files to .vercel/output/static/
17
+ * - Writes a config.json with SPA fallback (serve index.html for unknown paths)
18
+ */
19
+ import { join } from 'pathe';
20
+ import { existsSync, mkdirSync, writeFileSync, copyFileSync, cpSync, readdirSync, statSync, rmSync, } from 'node:fs';
21
+ // ─── Launcher template ────────────────────────────────────────────────────────
22
+ /**
23
+ * Vercel serverless function entry point.
24
+ * Handles /api/* routing and falls through to the SSR handler for all other
25
+ * requests. Imported by Vercel's Node.js launcher via the handler export.
26
+ *
27
+ * The server bundle lives at ./server/server.js so its own ../client/index.html
28
+ * reference resolves to ./client/index.html — both files are copied into the
29
+ * function directory by the adapter.
30
+ */
31
+ const VERCEL_LAUNCHER = `\
32
+ // Auto-generated by @jasonshimmy/vite-plugin-cer-app — do not edit.
33
+ import { handler, apiRoutes } from './server/server.js'
34
+
35
+ function matchApiPattern(pattern, urlPath) {
36
+ const pp = pattern.split('/')
37
+ const up = urlPath.split('/')
38
+ if (pp.length !== up.length) return null
39
+ const params = {}
40
+ for (let i = 0; i < pp.length; i++) {
41
+ if (pp[i].startsWith(':')) params[pp[i].slice(1)] = decodeURIComponent(up[i])
42
+ else if (pp[i] !== up[i]) return null
43
+ }
44
+ return params
45
+ }
46
+
47
+ export default async function cerAppHandler(req, res) {
48
+ const urlPath = (req.url ?? '/').split('?')[0]
49
+ const method = req.method ?? 'GET'
50
+
51
+ // Route /api/* to API handlers exported by the server bundle.
52
+ if (urlPath.startsWith('/api/')) {
53
+ for (const route of (apiRoutes ?? [])) {
54
+ const params = matchApiPattern(route.path, urlPath)
55
+ if (params !== null) {
56
+ req.params = params
57
+ res.json = function (data) {
58
+ this.setHeader('Content-Type', 'application/json; charset=utf-8')
59
+ this.end(JSON.stringify(data))
60
+ }
61
+ res.status = function (code) { this.statusCode = code; return this }
62
+ const fn = route.handlers[method.toLowerCase()]
63
+ ?? route.handlers[method.toUpperCase()]
64
+ ?? route.handlers['default']
65
+ if (typeof fn === 'function') {
66
+ try {
67
+ await fn(req, res)
68
+ } catch {
69
+ if (!res.writableEnded) {
70
+ res.statusCode = 500
71
+ res.setHeader('Content-Type', 'application/json')
72
+ res.end(JSON.stringify({ error: 'Internal Server Error' }))
73
+ }
74
+ }
75
+ return
76
+ }
77
+ }
78
+ }
79
+ res.statusCode = 404
80
+ res.end('Not Found')
81
+ return
82
+ }
83
+
84
+ // All other requests: SSR.
85
+ await handler(req, res)
86
+ }
87
+ `;
88
+ // ─── Public API ───────────────────────────────────────────────────────────────
89
+ export async function runVercelAdapter(root) {
90
+ const distDir = join(root, 'dist');
91
+ if (!existsSync(distDir)) {
92
+ throw new Error(`[cer-app] No dist/ directory found at ${distDir}. Run 'cer-app build' first.`);
93
+ }
94
+ const serverBundle = join(distDir, 'server/server.js');
95
+ const ssgManifest = join(distDir, 'ssg-manifest.json');
96
+ const isSSR = existsSync(serverBundle) && !existsSync(ssgManifest);
97
+ const outDir = join(root, '.vercel/output');
98
+ // Clean existing Vercel output to avoid stale files.
99
+ if (existsSync(outDir)) {
100
+ rmSync(outDir, { recursive: true, force: true });
101
+ }
102
+ mkdirSync(outDir, { recursive: true });
103
+ if (isSSR) {
104
+ _buildSSR(distDir, outDir);
105
+ }
106
+ else {
107
+ _buildStatic(distDir, outDir);
108
+ }
109
+ console.log('[cer-app] Vercel adapter complete — output written to .vercel/output/');
110
+ console.log(' Deploy with: vercel deploy --prebuilt');
111
+ }
112
+ // ─── SSR output ───────────────────────────────────────────────────────────────
113
+ function _buildSSR(distDir, outDir) {
114
+ const funcDir = join(outDir, 'functions/index.func');
115
+ // Maintain the server/ → ../client/ relative layout so the server bundle's
116
+ // built-in `../client/index.html` reference resolves correctly.
117
+ mkdirSync(join(funcDir, 'server'), { recursive: true });
118
+ mkdirSync(join(funcDir, 'client'), { recursive: true });
119
+ // Server bundle.
120
+ copyFileSync(join(distDir, 'server/server.js'), join(funcDir, 'server/server.js'));
121
+ // Client HTML template (referenced as ../client/index.html from server.js).
122
+ const clientHtml = join(distDir, 'client/index.html');
123
+ if (existsSync(clientHtml)) {
124
+ copyFileSync(clientHtml, join(funcDir, 'client/index.html'));
125
+ }
126
+ // Launcher: routes API requests + forwards the rest to the SSR handler.
127
+ writeFileSync(join(funcDir, 'index.js'), VERCEL_LAUNCHER);
128
+ // package.json: mark the function directory as ESM so Node.js treats .js
129
+ // files as ES modules (the server bundle uses import.meta.url, etc.).
130
+ writeFileSync(join(funcDir, 'package.json'), '{"type":"module"}\n');
131
+ // Vercel function config.
132
+ writeFileSync(join(funcDir, '.vc-config.json'), JSON.stringify({
133
+ runtime: 'nodejs20.x',
134
+ handler: 'index.js',
135
+ launcherType: 'Nodejs',
136
+ }, null, 2) + '\n');
137
+ // Static assets: content-hashed files served by the Vercel CDN.
138
+ const staticDir = join(outDir, 'static');
139
+ _copyClientAssets(join(distDir, 'client'), staticDir);
140
+ // Vercel output routes config.
141
+ writeFileSync(join(outDir, 'config.json'), JSON.stringify({
142
+ version: 3,
143
+ routes: [
144
+ // Apply immutable cache headers to content-hashed assets then continue
145
+ // (so the filesystem handler can still serve them as static files).
146
+ {
147
+ src: '/assets/(.*)',
148
+ headers: { 'cache-control': 'public, max-age=31536000, immutable' },
149
+ continue: true,
150
+ },
151
+ // Serve matched static files from .vercel/output/static/.
152
+ { handle: 'filesystem' },
153
+ // Fall through to the SSR function for all other paths.
154
+ { src: '/(.*)', dest: '/index' },
155
+ ],
156
+ }, null, 2) + '\n');
157
+ }
158
+ // ─── Static (SPA / SSG) output ────────────────────────────────────────────────
159
+ function _buildStatic(distDir, outDir) {
160
+ const staticDir = join(outDir, 'static');
161
+ mkdirSync(staticDir, { recursive: true });
162
+ const clientDir = join(distDir, 'client');
163
+ if (existsSync(clientDir)) {
164
+ // SSG: pre-rendered HTML lives in dist/, assets in dist/client/.
165
+ // Copy HTML (and any other root-level files) from dist/ — skip client/ dir
166
+ // and ssg-manifest.json which are build artifacts, not deployable content.
167
+ cpSync(distDir, staticDir, {
168
+ recursive: true,
169
+ filter: (src) => src !== clientDir && !src.endsWith('ssg-manifest.json'),
170
+ });
171
+ // Copy assets and other non-HTML files from dist/client/ into static root
172
+ // so URLs like /assets/main.abc123.js resolve correctly.
173
+ _copyClientAssets(clientDir, staticDir);
174
+ }
175
+ else {
176
+ // SPA: everything is in dist/ at the correct paths already.
177
+ cpSync(distDir, staticDir, { recursive: true });
178
+ }
179
+ // Vercel output config: serve static files, fall back to index.html (SPA).
180
+ writeFileSync(join(outDir, 'config.json'), JSON.stringify({
181
+ version: 3,
182
+ routes: [
183
+ {
184
+ src: '/assets/(.*)',
185
+ headers: { 'cache-control': 'public, max-age=31536000, immutable' },
186
+ continue: true,
187
+ },
188
+ { handle: 'filesystem' },
189
+ // SPA fallback: serve index.html for any unmatched path.
190
+ { src: '/(.*)', dest: '/index.html' },
191
+ ],
192
+ }, null, 2) + '\n');
193
+ }
194
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
195
+ /**
196
+ * Copies Vite-hashed assets and any other public files (favicon, robots.txt, …)
197
+ * from the client dist directory into `destDir`.
198
+ * Skips index.html — that is handled by the SSR function or SSG pre-rendering.
199
+ */
200
+ function _copyClientAssets(clientDir, destDir) {
201
+ if (!existsSync(clientDir))
202
+ return;
203
+ mkdirSync(destDir, { recursive: true });
204
+ for (const entry of readdirSync(clientDir)) {
205
+ if (entry === 'index.html')
206
+ continue; // served by function / SSG HTML
207
+ const src = join(clientDir, entry);
208
+ const dest = join(destDir, entry);
209
+ if (statSync(src).isDirectory()) {
210
+ cpSync(src, dest, { recursive: true });
211
+ }
212
+ else {
213
+ copyFileSync(src, dest);
214
+ }
215
+ }
216
+ }
217
+ //# sourceMappingURL=vercel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel.js","sourceRoot":"","sources":["../../../src/cli/adapters/vercel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function adaptCommand(): Command;
3
+ //# sourceMappingURL=adapt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapt.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/adapt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,wBAAgB,YAAY,IAAI,OAAO,CAqBtC"}