@flight-framework/cli 0.0.1 → 0.0.3

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 (67) hide show
  1. package/dist/bin.js +97 -3076
  2. package/dist/bin.js.map +1 -1
  3. package/dist/index.js +97 -3076
  4. package/dist/index.js.map +1 -1
  5. package/package.json +53 -50
  6. package/templates/base/README.md.template +26 -0
  7. package/templates/base/_gitignore +25 -0
  8. package/templates/base/flight.config.ts.template +10 -0
  9. package/templates/base/styles/global.css +58 -0
  10. package/templates/htmx/index.html +19 -0
  11. package/templates/htmx/package.json.template +14 -0
  12. package/templates/htmx/vite.config.ts +6 -0
  13. package/templates/lit/index.html +15 -0
  14. package/templates/lit/package.json.template +19 -0
  15. package/templates/lit/src/app-root.ts +18 -0
  16. package/templates/lit/src/entry-client.ts +5 -0
  17. package/templates/lit/src/entry-server.ts +9 -0
  18. package/templates/lit/tsconfig.json +19 -0
  19. package/templates/lit/vite.config.ts +6 -0
  20. package/templates/preact/index.html +15 -0
  21. package/templates/preact/package.json.template +20 -0
  22. package/templates/preact/src/App.tsx +8 -0
  23. package/templates/preact/src/entry-client.tsx +11 -0
  24. package/templates/preact/src/entry-server.tsx +6 -0
  25. package/templates/preact/tsconfig.json +19 -0
  26. package/templates/preact/vite.config.ts +8 -0
  27. package/templates/qwik/index.html +15 -0
  28. package/templates/qwik/package.json.template +18 -0
  29. package/templates/qwik/src/App.tsx +10 -0
  30. package/templates/qwik/src/entry-client.tsx +4 -0
  31. package/templates/qwik/src/entry-server.tsx +9 -0
  32. package/templates/qwik/tsconfig.json +19 -0
  33. package/templates/qwik/vite.config.ts +8 -0
  34. package/templates/react/index.html +13 -0
  35. package/templates/react/package.json.template +22 -0
  36. package/templates/react/src/App.tsx +8 -0
  37. package/templates/react/src/entry-client.tsx +11 -0
  38. package/templates/react/src/entry-server.tsx +6 -0
  39. package/templates/react/tsconfig.json +20 -0
  40. package/templates/react/vite.config.ts +12 -0
  41. package/templates/solid/index.html +15 -0
  42. package/templates/solid/package.json.template +19 -0
  43. package/templates/solid/src/App.tsx +8 -0
  44. package/templates/solid/src/entry-client.tsx +11 -0
  45. package/templates/solid/src/entry-server.tsx +6 -0
  46. package/templates/solid/tsconfig.json +19 -0
  47. package/templates/solid/vite.config.ts +8 -0
  48. package/templates/svelte/index.html +15 -0
  49. package/templates/svelte/package.json.template +19 -0
  50. package/templates/svelte/src/App.svelte +4 -0
  51. package/templates/svelte/src/entry-client.ts +7 -0
  52. package/templates/svelte/src/entry-server.ts +7 -0
  53. package/templates/svelte/tsconfig.json +18 -0
  54. package/templates/svelte/vite.config.ts +8 -0
  55. package/templates/vanilla/index.html +15 -0
  56. package/templates/vanilla/package.json.template +15 -0
  57. package/templates/vanilla/src/main.ts +10 -0
  58. package/templates/vanilla/tsconfig.json +17 -0
  59. package/templates/vanilla/vite.config.ts +6 -0
  60. package/templates/vue/index.html +15 -0
  61. package/templates/vue/package.json.template +19 -0
  62. package/templates/vue/src/App.vue +6 -0
  63. package/templates/vue/src/entry-client.ts +12 -0
  64. package/templates/vue/src/entry-server.ts +8 -0
  65. package/templates/vue/tsconfig.json +18 -0
  66. package/templates/vue/vite.config.ts +8 -0
  67. package/LICENSE +0 -21
package/dist/index.js CHANGED
@@ -1,2098 +1,10 @@
1
1
  #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
2
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
3
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
4
  }) : x)(function(x) {
7
5
  if (typeof require !== "undefined") return require.apply(this, arguments);
8
6
  throw Error('Dynamic require of "' + x + '" is not supported');
9
7
  });
10
- var __esm = (fn, res) => function __init() {
11
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
- };
13
- var __export = (target, all) => {
14
- for (var name in all)
15
- __defProp(target, name, { get: all[name], enumerable: true });
16
- };
17
-
18
- // ../core/dist/chunk-WAGCTWGY.js
19
- function defineConfig(config) {
20
- return config;
21
- }
22
- function resolveConfig(userConfig = {}) {
23
- return {
24
- root: userConfig.root ?? process.cwd(),
25
- adapter: userConfig.adapter ?? DEFAULT_CONFIG.adapter,
26
- ui: {
27
- ...DEFAULT_CONFIG.ui,
28
- ...userConfig.ui
29
- },
30
- rendering: {
31
- ...DEFAULT_CONFIG.rendering,
32
- ...userConfig.rendering
33
- },
34
- dev: {
35
- ...DEFAULT_CONFIG.dev,
36
- ...userConfig.dev
37
- },
38
- build: {
39
- ...DEFAULT_CONFIG.build,
40
- ...userConfig.build
41
- },
42
- vite: userConfig.vite,
43
- plugins: userConfig.plugins ?? []
44
- };
45
- }
46
- async function findConfigFile(root) {
47
- const { existsSync: existsSync3 } = await import("fs");
48
- const { join: join4 } = await import("path");
49
- for (const file of CONFIG_FILES) {
50
- const path = join4(root, file);
51
- if (existsSync3(path)) {
52
- return path;
53
- }
54
- }
55
- return null;
56
- }
57
- async function loadConfig(root = process.cwd()) {
58
- const configFile = await findConfigFile(root);
59
- if (!configFile) {
60
- return resolveConfig({ root });
61
- }
62
- try {
63
- const { pathToFileURL } = await import("url");
64
- const configUrl = pathToFileURL(configFile).href;
65
- const module = await import(configUrl);
66
- const userConfig = module.default;
67
- return resolveConfig({
68
- ...userConfig,
69
- root
70
- });
71
- } catch (error2) {
72
- console.error(`Failed to load config from ${configFile}:`, error2);
73
- return resolveConfig({ root });
74
- }
75
- }
76
- var DEFAULT_CONFIG, CONFIG_FILES;
77
- var init_chunk_WAGCTWGY = __esm({
78
- "../core/dist/chunk-WAGCTWGY.js"() {
79
- "use strict";
80
- DEFAULT_CONFIG = {
81
- adapter: null,
82
- ui: {
83
- framework: "vanilla"
84
- },
85
- rendering: {
86
- default: "ssr",
87
- routes: {}
88
- },
89
- dev: {
90
- port: 5173,
91
- host: "localhost",
92
- open: false,
93
- https: false,
94
- proxy: {}
95
- },
96
- build: {
97
- outDir: "dist",
98
- srcDir: "src",
99
- publicDir: "public",
100
- routesDir: "src/routes",
101
- sourcemap: false,
102
- minify: true,
103
- target: "es2022"
104
- }
105
- };
106
- CONFIG_FILES = [
107
- "flight.config.ts",
108
- "flight.config.js",
109
- "flight.config.mjs",
110
- "flight.config.mts"
111
- ];
112
- }
113
- });
114
-
115
- // ../../node_modules/.pnpm/radix3@1.1.2/node_modules/radix3/dist/index.mjs
116
- function createRouter(options = {}) {
117
- const ctx = {
118
- options,
119
- rootNode: createRadixNode(),
120
- staticRoutesMap: {}
121
- };
122
- const normalizeTrailingSlash = (p) => options.strictTrailingSlash ? p : p.replace(/\/$/, "") || "/";
123
- if (options.routes) {
124
- for (const path in options.routes) {
125
- insert(ctx, normalizeTrailingSlash(path), options.routes[path]);
126
- }
127
- }
128
- return {
129
- ctx,
130
- lookup: (path) => lookup(ctx, normalizeTrailingSlash(path)),
131
- insert: (path, data) => insert(ctx, normalizeTrailingSlash(path), data),
132
- remove: (path) => remove(ctx, normalizeTrailingSlash(path))
133
- };
134
- }
135
- function lookup(ctx, path) {
136
- const staticPathNode = ctx.staticRoutesMap[path];
137
- if (staticPathNode) {
138
- return staticPathNode.data;
139
- }
140
- const sections = path.split("/");
141
- const params = {};
142
- let paramsFound = false;
143
- let wildcardNode = null;
144
- let node = ctx.rootNode;
145
- let wildCardParam = null;
146
- for (let i = 0; i < sections.length; i++) {
147
- const section = sections[i];
148
- if (node.wildcardChildNode !== null) {
149
- wildcardNode = node.wildcardChildNode;
150
- wildCardParam = sections.slice(i).join("/");
151
- }
152
- const nextNode = node.children.get(section);
153
- if (nextNode === void 0) {
154
- if (node && node.placeholderChildren.length > 1) {
155
- const remaining = sections.length - i;
156
- node = node.placeholderChildren.find((c) => c.maxDepth === remaining) || null;
157
- } else {
158
- node = node.placeholderChildren[0] || null;
159
- }
160
- if (!node) {
161
- break;
162
- }
163
- if (node.paramName) {
164
- params[node.paramName] = section;
165
- }
166
- paramsFound = true;
167
- } else {
168
- node = nextNode;
169
- }
170
- }
171
- if ((node === null || node.data === null) && wildcardNode !== null) {
172
- node = wildcardNode;
173
- params[node.paramName || "_"] = wildCardParam;
174
- paramsFound = true;
175
- }
176
- if (!node) {
177
- return null;
178
- }
179
- if (paramsFound) {
180
- return {
181
- ...node.data,
182
- params: paramsFound ? params : void 0
183
- };
184
- }
185
- return node.data;
186
- }
187
- function insert(ctx, path, data) {
188
- let isStaticRoute = true;
189
- const sections = path.split("/");
190
- let node = ctx.rootNode;
191
- let _unnamedPlaceholderCtr = 0;
192
- const matchedNodes = [node];
193
- for (const section of sections) {
194
- let childNode;
195
- if (childNode = node.children.get(section)) {
196
- node = childNode;
197
- } else {
198
- const type = getNodeType(section);
199
- childNode = createRadixNode({ type, parent: node });
200
- node.children.set(section, childNode);
201
- if (type === NODE_TYPES.PLACEHOLDER) {
202
- childNode.paramName = section === "*" ? `_${_unnamedPlaceholderCtr++}` : section.slice(1);
203
- node.placeholderChildren.push(childNode);
204
- isStaticRoute = false;
205
- } else if (type === NODE_TYPES.WILDCARD) {
206
- node.wildcardChildNode = childNode;
207
- childNode.paramName = section.slice(
208
- 3
209
- /* "**:" */
210
- ) || "_";
211
- isStaticRoute = false;
212
- }
213
- matchedNodes.push(childNode);
214
- node = childNode;
215
- }
216
- }
217
- for (const [depth, node2] of matchedNodes.entries()) {
218
- node2.maxDepth = Math.max(matchedNodes.length - depth, node2.maxDepth || 0);
219
- }
220
- node.data = data;
221
- if (isStaticRoute === true) {
222
- ctx.staticRoutesMap[path] = node;
223
- }
224
- return node;
225
- }
226
- function remove(ctx, path) {
227
- let success = false;
228
- const sections = path.split("/");
229
- let node = ctx.rootNode;
230
- for (const section of sections) {
231
- node = node.children.get(section);
232
- if (!node) {
233
- return success;
234
- }
235
- }
236
- if (node.data) {
237
- const lastSection = sections.at(-1) || "";
238
- node.data = null;
239
- if (Object.keys(node.children).length === 0 && node.parent) {
240
- node.parent.children.delete(lastSection);
241
- node.parent.wildcardChildNode = null;
242
- node.parent.placeholderChildren = [];
243
- }
244
- success = true;
245
- }
246
- return success;
247
- }
248
- function createRadixNode(options = {}) {
249
- return {
250
- type: options.type || NODE_TYPES.NORMAL,
251
- maxDepth: 0,
252
- parent: options.parent || null,
253
- children: /* @__PURE__ */ new Map(),
254
- data: options.data || null,
255
- paramName: options.paramName || null,
256
- wildcardChildNode: null,
257
- placeholderChildren: []
258
- };
259
- }
260
- function getNodeType(str) {
261
- if (str.startsWith("**")) {
262
- return NODE_TYPES.WILDCARD;
263
- }
264
- if (str[0] === ":" || str === "*") {
265
- return NODE_TYPES.PLACEHOLDER;
266
- }
267
- return NODE_TYPES.NORMAL;
268
- }
269
- var NODE_TYPES;
270
- var init_dist = __esm({
271
- "../../node_modules/.pnpm/radix3@1.1.2/node_modules/radix3/dist/index.mjs"() {
272
- "use strict";
273
- NODE_TYPES = {
274
- NORMAL: 0,
275
- WILDCARD: 1,
276
- PLACEHOLDER: 2
277
- };
278
- }
279
- });
280
-
281
- // ../http/dist/index.js
282
- var dist_exports = {};
283
- __export(dist_exports, {
284
- FlightHttp: () => FlightHttp,
285
- Router: () => Router,
286
- createContext: () => createContext,
287
- createServer: () => createServer
288
- });
289
- function createContext(request, params = {}, env = {}) {
290
- const variables = {};
291
- return {
292
- req: request,
293
- env,
294
- params,
295
- variables,
296
- // Response helpers
297
- json(data, status = 200) {
298
- return new Response(JSON.stringify(data), {
299
- status,
300
- headers: { "Content-Type": "application/json; charset=utf-8" }
301
- });
302
- },
303
- text(text, status = 200) {
304
- return new Response(text, {
305
- status,
306
- headers: { "Content-Type": "text/plain; charset=utf-8" }
307
- });
308
- },
309
- html(html, status = 200) {
310
- return new Response(html, {
311
- status,
312
- headers: { "Content-Type": "text/html; charset=utf-8" }
313
- });
314
- },
315
- redirect(url, status = 302) {
316
- return new Response(null, {
317
- status,
318
- headers: { Location: url }
319
- });
320
- },
321
- // Variable getter/setter
322
- get(key) {
323
- return variables[key];
324
- },
325
- set(key, value) {
326
- variables[key] = value;
327
- },
328
- // Request helpers
329
- header(name) {
330
- return request.headers.get(name);
331
- },
332
- cookie(name) {
333
- const cookieHeader = request.headers.get("cookie");
334
- if (!cookieHeader) return void 0;
335
- const cookies2 = parseCookies(cookieHeader);
336
- return cookies2[name];
337
- }
338
- };
339
- }
340
- function parseCookies(cookieHeader) {
341
- const cookies2 = {};
342
- for (const cookie of cookieHeader.split(";")) {
343
- const [name, ...rest] = cookie.trim().split("=");
344
- if (name) {
345
- cookies2[name] = rest.join("=");
346
- }
347
- }
348
- return cookies2;
349
- }
350
- function createServer(options = {}) {
351
- return new FlightHttp(options);
352
- }
353
- var Router, FlightHttp;
354
- var init_dist2 = __esm({
355
- "../http/dist/index.js"() {
356
- "use strict";
357
- init_dist();
358
- Router = class {
359
- radix;
360
- routes = [];
361
- constructor() {
362
- this.radix = createRouter();
363
- }
364
- /**
365
- * Add a route
366
- */
367
- add(method, path, handler) {
368
- const normalizedPath = this.normalizePath(path);
369
- let node = this.radix.lookup(normalizedPath);
370
- if (!node) {
371
- node = { handlers: /* @__PURE__ */ new Map() };
372
- this.radix.insert(normalizedPath, node);
373
- }
374
- node.handlers.set(method, handler);
375
- this.routes.push({
376
- method,
377
- path: normalizedPath,
378
- handler,
379
- middleware: []
380
- });
381
- }
382
- /**
383
- * Match a request to a route
384
- */
385
- match(method, path) {
386
- const normalizedPath = this.normalizePath(path);
387
- const result = this.radix.lookup(normalizedPath);
388
- if (!result) {
389
- return null;
390
- }
391
- let handler = result.handlers.get(method);
392
- if (!handler) {
393
- handler = result.handlers.get("*");
394
- }
395
- if (!handler) {
396
- return null;
397
- }
398
- const params = result.params || {};
399
- return { handler, params };
400
- }
401
- /**
402
- * Get all registered routes
403
- */
404
- getRoutes() {
405
- return [...this.routes];
406
- }
407
- /**
408
- * Normalize path
409
- */
410
- normalizePath(path) {
411
- if (!path.startsWith("/")) {
412
- path = "/" + path;
413
- }
414
- if (path !== "/" && path.endsWith("/")) {
415
- path = path.slice(0, -1);
416
- }
417
- path = path.replace(/\[([^\]]+)\]/g, ":$1");
418
- path = path.replace(/\[\.\.\.([\w]+)\]/g, "**");
419
- return path;
420
- }
421
- /**
422
- * Extract params from matched path
423
- * @deprecated radix3 handles param extraction internally
424
- */
425
- _extractParams(pattern, actualPath) {
426
- const params = {};
427
- const patternParts = pattern.split("/");
428
- const actualParts = actualPath.split("/");
429
- for (let i = 0; i < patternParts.length; i++) {
430
- const patternPart = patternParts[i];
431
- if (!patternPart) continue;
432
- if (patternPart.startsWith(":")) {
433
- const paramName = patternPart.slice(1);
434
- params[paramName] = actualParts[i] || "";
435
- } else if (patternPart === "**") {
436
- const paramName = "slug";
437
- params[paramName] = actualParts.slice(i).join("/");
438
- break;
439
- }
440
- }
441
- return params;
442
- }
443
- };
444
- FlightHttp = class _FlightHttp {
445
- router;
446
- globalMiddleware = [];
447
- notFoundHandler;
448
- errorHandler;
449
- basePath;
450
- constructor(options = {}) {
451
- this.router = new Router();
452
- this.basePath = options.basePath || "";
453
- this.notFoundHandler = (c) => c.json(
454
- { error: "Not Found", path: new URL(c.req.url).pathname },
455
- 404
456
- );
457
- this.errorHandler = (error2, c) => c.json(
458
- { error: error2.message || "Internal Server Error" },
459
- 500
460
- );
461
- }
462
- // ========================================================================
463
- // Route Registration
464
- // ========================================================================
465
- get(path, ...handlers) {
466
- return this.addRoute("GET", path, handlers);
467
- }
468
- post(path, ...handlers) {
469
- return this.addRoute("POST", path, handlers);
470
- }
471
- put(path, ...handlers) {
472
- return this.addRoute("PUT", path, handlers);
473
- }
474
- delete(path, ...handlers) {
475
- return this.addRoute("DELETE", path, handlers);
476
- }
477
- patch(path, ...handlers) {
478
- return this.addRoute("PATCH", path, handlers);
479
- }
480
- options(path, ...handlers) {
481
- return this.addRoute("OPTIONS", path, handlers);
482
- }
483
- head(path, ...handlers) {
484
- return this.addRoute("HEAD", path, handlers);
485
- }
486
- all(path, ...handlers) {
487
- return this.addRoute("*", path, handlers);
488
- }
489
- // ========================================================================
490
- // Middleware
491
- // ========================================================================
492
- use(...handlers) {
493
- this.globalMiddleware.push(...handlers);
494
- return this;
495
- }
496
- // ========================================================================
497
- // Sub-routing
498
- // ========================================================================
499
- route(path, router) {
500
- if (router instanceof _FlightHttp) {
501
- const routes = router.router.getRoutes();
502
- for (const route of routes) {
503
- const fullPath = this.basePath + path + route.path;
504
- this.router.add(route.method, fullPath, route.handler);
505
- }
506
- }
507
- return this;
508
- }
509
- // ========================================================================
510
- // Error Handling
511
- // ========================================================================
512
- notFound(handler) {
513
- this.notFoundHandler = handler;
514
- return this;
515
- }
516
- onError(handler) {
517
- this.errorHandler = handler;
518
- return this;
519
- }
520
- // ========================================================================
521
- // Core Fetch Handler
522
- // ========================================================================
523
- async fetch(request, options = {}) {
524
- const url = new URL(request.url);
525
- const path = url.pathname;
526
- const method = request.method.toUpperCase();
527
- const match = this.router.match(method, path);
528
- const context = createContext(
529
- request,
530
- match?.params || {},
531
- options.env || {}
532
- );
533
- try {
534
- const middlewares = [...this.globalMiddleware];
535
- if (match) {
536
- const composed = this.composeMiddleware(
537
- middlewares,
538
- match.handler
539
- );
540
- return await composed(context);
541
- } else {
542
- if (middlewares.length > 0) {
543
- const composed = this.composeMiddleware(
544
- middlewares,
545
- this.notFoundHandler
546
- );
547
- return await composed(context);
548
- }
549
- return await this.notFoundHandler(context);
550
- }
551
- } catch (error2) {
552
- console.error("[Flight HTTP] Error:", error2);
553
- return await this.errorHandler(
554
- error2 instanceof Error ? error2 : new Error(String(error2)),
555
- context
556
- );
557
- }
558
- }
559
- // ========================================================================
560
- // Listen (Node.js adapter will override this)
561
- // ========================================================================
562
- listen(options) {
563
- const port = typeof options === "number" ? options : options?.port || 3e3;
564
- console.log(`[Flight HTTP] Call adapter-specific listen() to start server on port ${port}`);
565
- console.log('[Flight HTTP] Import from "@flight/http/node" or "@flight/http/bun"');
566
- }
567
- // ========================================================================
568
- // Private Methods
569
- // ========================================================================
570
- addRoute(method, path, handlers) {
571
- const mainHandler = handlers[handlers.length - 1];
572
- const routeMiddleware = handlers.slice(0, -1);
573
- const fullPath = this.basePath + path;
574
- if (routeMiddleware.length > 0) {
575
- const composedHandler = this.composeMiddleware(routeMiddleware, mainHandler);
576
- this.router.add(method, fullPath, composedHandler);
577
- } else {
578
- this.router.add(method, fullPath, mainHandler);
579
- }
580
- return this;
581
- }
582
- /**
583
- * Compose middleware chain with final handler
584
- */
585
- composeMiddleware(middlewares, handler) {
586
- return async (c) => {
587
- let index = 0;
588
- const dispatch = async () => {
589
- if (index < middlewares.length) {
590
- const middleware = middlewares[index++];
591
- if (middleware) {
592
- return await middleware(c, dispatch);
593
- }
594
- }
595
- return await handler(c);
596
- };
597
- return await dispatch();
598
- };
599
- }
600
- };
601
- }
602
- });
603
-
604
- // ../core/dist/chunk-I5RHYGX6.js
605
- import { readdir } from "fs/promises";
606
- import { join as join2, extname, basename } from "path";
607
- async function scanRoutes(options) {
608
- const {
609
- directory,
610
- extensions = [".ts", ".js"]
611
- } = options;
612
- const routes = [];
613
- const errors = [];
614
- async function scanDir(dir, basePath = "") {
615
- try {
616
- const entries = await readdir(dir, { withFileTypes: true });
617
- for (const entry of entries) {
618
- const fullPath = join2(dir, entry.name);
619
- if (entry.isDirectory()) {
620
- if (entry.name.startsWith(".") || entry.name === "node_modules") {
621
- continue;
622
- }
623
- await scanDir(fullPath, `${basePath}/${entry.name}`);
624
- } else if (entry.isFile()) {
625
- const ext = extname(entry.name);
626
- if (!extensions.includes(ext)) {
627
- continue;
628
- }
629
- const routeInfo = parseRouteFile(entry.name, basePath);
630
- if (routeInfo && routeInfo.method && routeInfo.path) {
631
- routes.push({
632
- method: routeInfo.method,
633
- path: routeInfo.path,
634
- filePath: fullPath,
635
- type: routeInfo.type
636
- });
637
- }
638
- }
639
- }
640
- } catch (error2) {
641
- errors.push(`Failed to scan ${dir}: ${error2}`);
642
- }
643
- }
644
- await scanDir(directory);
645
- return { routes, errors };
646
- }
647
- function parseRouteFile(filename, basePath) {
648
- const ext = extname(filename);
649
- const nameWithoutExt = basename(filename, ext);
650
- if (nameWithoutExt.startsWith("_")) {
651
- return null;
652
- }
653
- let type = "api";
654
- let routeName = nameWithoutExt;
655
- let method = "ALL";
656
- const pageMatch = nameWithoutExt.match(/^(.+)?\.page$/i);
657
- if (pageMatch) {
658
- type = "page";
659
- method = "GET";
660
- routeName = pageMatch[1] || "index";
661
- } else {
662
- const methodMatch = nameWithoutExt.match(/^(.+)\.(get|post|put|delete|patch|head|options)$/i);
663
- if (methodMatch) {
664
- routeName = methodMatch[1] || nameWithoutExt;
665
- method = (methodMatch[2] || "ALL").toUpperCase();
666
- }
667
- }
668
- if (basePath.startsWith("/api") || basePath.includes("/api/")) {
669
- type = "api";
670
- }
671
- let path = basePath;
672
- if (routeName !== "index") {
673
- path = `${basePath}/${convertToRoutePath(routeName)}`;
674
- }
675
- if (!path.startsWith("/")) {
676
- path = "/" + path;
677
- }
678
- if (path !== "/" && path.endsWith("/")) {
679
- path = path.slice(0, -1);
680
- }
681
- return { method, path, type };
682
- }
683
- function convertToRoutePath(name) {
684
- if (name.startsWith("[[...") && name.endsWith("]]")) {
685
- const paramName = name.slice(5, -2);
686
- return `:${paramName}*`;
687
- }
688
- if (name.startsWith("[...") && name.endsWith("]")) {
689
- const paramName = name.slice(4, -1);
690
- return `:${paramName}+`;
691
- }
692
- if (name.startsWith("[") && name.endsWith("]")) {
693
- const paramName = name.slice(1, -1);
694
- return `:${paramName}`;
695
- }
696
- return name;
697
- }
698
- async function loadRoutes(scanResult) {
699
- const loadedRoutes = [];
700
- for (const route of scanResult.routes) {
701
- try {
702
- const module = await import(route.filePath);
703
- if (route.type === "page") {
704
- const component = module.default;
705
- const meta = module.meta || module.metadata || {};
706
- if (component) {
707
- loadedRoutes.push({
708
- ...route,
709
- component,
710
- meta
711
- });
712
- }
713
- continue;
714
- }
715
- if (route.method === "ALL") {
716
- const methods = ["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"];
717
- for (const method of methods) {
718
- if (typeof module[method] === "function") {
719
- loadedRoutes.push({
720
- ...route,
721
- method,
722
- handler: module[method]
723
- });
724
- }
725
- }
726
- if (typeof module.default === "function") {
727
- loadedRoutes.push({
728
- ...route,
729
- method: "ALL",
730
- handler: module.default
731
- });
732
- }
733
- } else {
734
- const handler = module[route.method] || module.default;
735
- if (typeof handler === "function") {
736
- loadedRoutes.push({
737
- ...route,
738
- handler
739
- });
740
- }
741
- }
742
- } catch (error2) {
743
- console.error(`[Flight] Failed to load route ${route.filePath}:`, error2);
744
- }
745
- }
746
- return loadedRoutes;
747
- }
748
- async function createFileRouter(options) {
749
- let routes = [];
750
- async function refresh() {
751
- const scanResult = await scanRoutes(options);
752
- if (scanResult.errors.length > 0) {
753
- console.warn("[Flight] Route scan errors:", scanResult.errors);
754
- }
755
- routes = await loadRoutes(scanResult);
756
- console.log(`[Flight] Loaded ${routes.length} routes from ${options.directory}`);
757
- }
758
- await refresh();
759
- return {
760
- get routes() {
761
- return routes;
762
- },
763
- refresh
764
- };
765
- }
766
- var init_chunk_I5RHYGX6 = __esm({
767
- "../core/dist/chunk-I5RHYGX6.js"() {
768
- "use strict";
769
- }
770
- });
771
-
772
- // ../core/dist/file-router/index.js
773
- var file_router_exports = {};
774
- __export(file_router_exports, {
775
- createFileRouter: () => createFileRouter,
776
- loadRoutes: () => loadRoutes,
777
- scanRoutes: () => scanRoutes
778
- });
779
- var init_file_router = __esm({
780
- "../core/dist/file-router/index.js"() {
781
- "use strict";
782
- init_chunk_I5RHYGX6();
783
- }
784
- });
785
-
786
- // ../core/dist/chunk-TKXN7KGE.js
787
- function registerAction(action) {
788
- actionRegistry.set(action.id, action);
789
- }
790
- function getAction(id) {
791
- return actionRegistry.get(id);
792
- }
793
- async function executeAction(actionId, args) {
794
- const action = getAction(actionId);
795
- if (!action) {
796
- return {
797
- success: false,
798
- error: `Action not found: ${actionId}`
799
- };
800
- }
801
- try {
802
- const result = await action.fn(...args);
803
- return {
804
- success: true,
805
- data: result
806
- };
807
- } catch (error2) {
808
- if (isRedirectError(error2)) {
809
- throw error2;
810
- }
811
- console.error(`[Flight] Action error (${actionId}):`, error2);
812
- return {
813
- success: false,
814
- error: error2 instanceof Error ? error2.message : "Unknown error"
815
- };
816
- }
817
- }
818
- async function executeFormAction(actionId, formData) {
819
- return executeAction(actionId, [formData]);
820
- }
821
- function cookies() {
822
- const cookieStore = globalThis.__flightCookies;
823
- if (!cookieStore) {
824
- console.warn("[Flight] Cookies not available outside of action context");
825
- return {
826
- get: () => void 0,
827
- set: () => {
828
- },
829
- delete: () => {
830
- }
831
- };
832
- }
833
- return cookieStore;
834
- }
835
- function redirect(url) {
836
- throw new RedirectError(url);
837
- }
838
- function isRedirectError(error2) {
839
- return error2 instanceof RedirectError;
840
- }
841
- function parseFormData(formData) {
842
- const result = {};
843
- formData.forEach((value, key) => {
844
- result[key] = String(value);
845
- });
846
- return result;
847
- }
848
- async function handleActionRequest(request) {
849
- const url = new URL(request.url);
850
- const actionPath = url.pathname;
851
- const match = actionPath.match(/^\/__flight_action\/(.+)$/);
852
- if (!match) {
853
- return new Response(JSON.stringify({ error: "Invalid action path" }), {
854
- status: 400,
855
- headers: { "Content-Type": "application/json" }
856
- });
857
- }
858
- const actionId = match[1];
859
- if (!actionId) {
860
- return new Response(JSON.stringify({ error: "Missing action ID" }), {
861
- status: 400,
862
- headers: { "Content-Type": "application/json" }
863
- });
864
- }
865
- try {
866
- let result;
867
- const contentType = request.headers.get("content-type") || "";
868
- if (contentType.includes("application/x-www-form-urlencoded") || contentType.includes("multipart/form-data")) {
869
- const formData = await request.formData();
870
- result = await executeFormAction(actionId, formData);
871
- } else {
872
- const args = await request.json();
873
- result = await executeAction(actionId, Array.isArray(args) ? args : [args]);
874
- }
875
- return new Response(JSON.stringify(result), {
876
- status: result.success ? 200 : 400,
877
- headers: { "Content-Type": "application/json" }
878
- });
879
- } catch (error2) {
880
- if (isRedirectError(error2)) {
881
- return new Response(null, {
882
- status: 303,
883
- headers: { Location: error2.url }
884
- });
885
- }
886
- return new Response(JSON.stringify({
887
- success: false,
888
- error: error2 instanceof Error ? error2.message : "Unknown error"
889
- }), {
890
- status: 500,
891
- headers: { "Content-Type": "application/json" }
892
- });
893
- }
894
- }
895
- var actionRegistry, RedirectError;
896
- var init_chunk_TKXN7KGE = __esm({
897
- "../core/dist/chunk-TKXN7KGE.js"() {
898
- "use strict";
899
- actionRegistry = /* @__PURE__ */ new Map();
900
- RedirectError = class extends Error {
901
- url;
902
- constructor(url) {
903
- super(`Redirect to ${url}`);
904
- this.name = "RedirectError";
905
- this.url = url;
906
- }
907
- };
908
- }
909
- });
910
-
911
- // ../core/dist/chunk-AJ3IBYXT.js
912
- function createRouteContext(request, params = {}) {
913
- const url = new URL(request.url);
914
- return {
915
- params,
916
- searchParams: url.searchParams
917
- };
918
- }
919
- function json(data, init) {
920
- const headers = new Headers(init?.headers);
921
- headers.set("Content-Type", "application/json; charset=utf-8");
922
- return new Response(JSON.stringify(data), {
923
- ...init,
924
- headers
925
- });
926
- }
927
- function redirect2(url, status = 302) {
928
- return new Response(null, {
929
- status,
930
- headers: { Location: url }
931
- });
932
- }
933
- function error(message, status = 500) {
934
- return new Response(JSON.stringify({ error: message }), {
935
- status,
936
- headers: { "Content-Type": "application/json" }
937
- });
938
- }
939
- async function parseBody(request) {
940
- const contentType = request.headers.get("content-type") || "";
941
- if (contentType.includes("application/json")) {
942
- return await request.json();
943
- }
944
- if (contentType.includes("application/x-www-form-urlencoded")) {
945
- const formData = await request.formData();
946
- const obj = {};
947
- formData.forEach((value, key) => {
948
- obj[key] = String(value);
949
- });
950
- return obj;
951
- }
952
- throw new Error(`Unsupported content type: ${contentType}`);
953
- }
954
- var init_chunk_AJ3IBYXT = __esm({
955
- "../core/dist/chunk-AJ3IBYXT.js"() {
956
- "use strict";
957
- }
958
- });
959
-
960
- // ../core/dist/chunk-QEFGUHYD.js
961
- async function createStreamingSSR(config) {
962
- const { shell, shellEnd, suspenseBoundaries = [], options = {} } = config;
963
- let shellResolved = false;
964
- let allResolved = false;
965
- let abortController = null;
966
- let resolveShell;
967
- const shellReady = new Promise((resolve5) => {
968
- resolveShell = resolve5;
969
- });
970
- let resolveAll;
971
- const allReady = new Promise((resolve5) => {
972
- resolveAll = resolve5;
973
- });
974
- const encoder = new TextEncoder();
975
- const stream = new ReadableStream({
976
- async start(controller) {
977
- try {
978
- const shellWithPlaceholders = buildShellWithPlaceholders(
979
- shell,
980
- suspenseBoundaries,
981
- shellEnd,
982
- options
983
- );
984
- controller.enqueue(encoder.encode(shellWithPlaceholders));
985
- shellResolved = true;
986
- options.onShellReady?.();
987
- resolveShell();
988
- if (suspenseBoundaries.length > 0) {
989
- await streamSuspenseContent(controller, encoder, suspenseBoundaries, options);
990
- }
991
- if (options.bootstrapScripts?.length || options.bootstrapModules?.length) {
992
- const hydrationScript = buildHydrationScript(options);
993
- controller.enqueue(encoder.encode(hydrationScript));
994
- }
995
- allResolved = true;
996
- options.onAllReady?.();
997
- resolveAll();
998
- controller.close();
999
- } catch (error2) {
1000
- if (!shellResolved) {
1001
- options.onShellError?.(error2);
1002
- }
1003
- options.onError?.(error2);
1004
- controller.error(error2);
1005
- }
1006
- },
1007
- cancel() {
1008
- abortController?.abort();
1009
- }
1010
- });
1011
- const abort = () => {
1012
- abortController?.abort();
1013
- };
1014
- if (options.timeoutMs) {
1015
- abortController = new AbortController();
1016
- setTimeout(() => {
1017
- if (!allResolved) {
1018
- abort();
1019
- }
1020
- }, options.timeoutMs);
1021
- }
1022
- return {
1023
- stream,
1024
- abort,
1025
- shellReady,
1026
- allReady
1027
- };
1028
- }
1029
- function buildShellWithPlaceholders(shell, boundaries, shellEnd, options) {
1030
- let html = shell;
1031
- if (options.bootstrapScriptContent) {
1032
- html += `<script>${options.bootstrapScriptContent}</script>`;
1033
- }
1034
- for (const boundary of boundaries) {
1035
- html += `
1036
- <!--$?--><template id="B:${boundary.id}"></template>
1037
- ${boundary.fallback}
1038
- <!--/$-->`;
1039
- }
1040
- html += shellEnd;
1041
- return html;
1042
- }
1043
- async function streamSuspenseContent(controller, encoder, boundaries, options) {
1044
- const pending = boundaries.map(async (boundary) => {
1045
- try {
1046
- const content = await boundary.contentPromise;
1047
- return { boundary, content, error: null };
1048
- } catch (error2) {
1049
- return { boundary, content: null, error: error2 };
1050
- }
1051
- });
1052
- const results = await Promise.allSettled(pending);
1053
- for (const result of results) {
1054
- if (result.status === "fulfilled") {
1055
- const { boundary, content, error: error2 } = result.value;
1056
- if (error2) {
1057
- const errorScript = buildErrorReplacement(boundary.id, error2.message);
1058
- controller.enqueue(encoder.encode(errorScript));
1059
- options.onError?.(error2);
1060
- } else if (content) {
1061
- const replacementScript = buildContentReplacement(boundary.id, content);
1062
- controller.enqueue(encoder.encode(replacementScript));
1063
- }
1064
- }
1065
- }
1066
- }
1067
- function buildContentReplacement(id, content) {
1068
- const escaped = content.replace(/\\/g, "\\\\").replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
1069
- return `
1070
- <script>
1071
- (function(){
1072
- var b=document.getElementById("B:${id}");
1073
- if(b){
1074
- var p=b.previousSibling;
1075
- while(p&&p.nodeType===8&&p.data==="$?")p=p.previousSibling;
1076
- var n=b.nextSibling;
1077
- var f=document.createDocumentFragment();
1078
- var t=document.createElement("template");
1079
- t.innerHTML="${escaped}";
1080
- while(t.content.firstChild)f.appendChild(t.content.firstChild);
1081
- if(n&&n.nodeType===8&&n.data==="/$"){
1082
- var s=n.nextSibling;
1083
- while(s&&s!==b){var x=s.nextSibling;s.parentNode.removeChild(s);s=x;}
1084
- }
1085
- b.parentNode.replaceChild(f,b);
1086
- }
1087
- })();
1088
- </script>`;
1089
- }
1090
- function buildErrorReplacement(id, message) {
1091
- const escaped = message.replace(/'/g, "\\'").replace(/"/g, '\\"');
1092
- return `
1093
- <script>
1094
- (function(){
1095
- var b=document.getElementById("B:${id}");
1096
- if(b){
1097
- var t=document.createElement("div");
1098
- t.className="streaming-error";
1099
- t.textContent="Error: ${escaped}";
1100
- b.parentNode.replaceChild(t,b);
1101
- }
1102
- })();
1103
- </script>`;
1104
- }
1105
- function buildHydrationScript(options) {
1106
- let scripts = "";
1107
- if (options.bootstrapScripts?.length) {
1108
- for (const src of options.bootstrapScripts) {
1109
- const nonceAttr = options.nonce ? ` nonce="${options.nonce}"` : "";
1110
- scripts += `<script src="${src}"${nonceAttr} async></script>`;
1111
- }
1112
- }
1113
- if (options.bootstrapModules?.length) {
1114
- for (const src of options.bootstrapModules) {
1115
- const nonceAttr = options.nonce ? ` nonce="${options.nonce}"` : "";
1116
- scripts += `<script type="module" src="${src}"${nonceAttr}></script>`;
1117
- }
1118
- }
1119
- return scripts;
1120
- }
1121
- function createStreamingResponse(stream, options = {}) {
1122
- return new Response(stream, {
1123
- status: options.status || 200,
1124
- headers: {
1125
- "Content-Type": "text/html; charset=utf-8",
1126
- "Transfer-Encoding": "chunked",
1127
- "X-Content-Type-Options": "nosniff",
1128
- ...options.headers
1129
- }
1130
- });
1131
- }
1132
- async function renderWithStreaming(config) {
1133
- const { layout, page, suspense = {}, bootstrapScripts, timeoutMs } = config;
1134
- const pageContent = await page();
1135
- const boundaries = Object.entries(suspense).map(
1136
- ([id, { fallback, content }]) => ({
1137
- id,
1138
- fallback,
1139
- contentPromise: content
1140
- })
1141
- );
1142
- const result = await createStreamingSSR({
1143
- shell: layout({ children: pageContent }),
1144
- shellEnd: "",
1145
- suspenseBoundaries: boundaries,
1146
- options: {
1147
- bootstrapScripts,
1148
- timeoutMs
1149
- }
1150
- });
1151
- return createStreamingResponse(result.stream);
1152
- }
1153
- function createLazyContent(fetcher, renderer, fallback) {
1154
- return {
1155
- fallback,
1156
- content: fetcher().then(renderer)
1157
- };
1158
- }
1159
- async function streamParallel(boundaries) {
1160
- return boundaries.map((b) => ({
1161
- id: b.id,
1162
- fallback: b.fallback,
1163
- contentPromise: b.content()
1164
- }));
1165
- }
1166
- async function streamSequential(boundaries) {
1167
- const result = [];
1168
- for (const b of boundaries) {
1169
- result.push({
1170
- id: b.id,
1171
- fallback: b.fallback,
1172
- contentPromise: b.content()
1173
- });
1174
- }
1175
- return result;
1176
- }
1177
- var init_chunk_QEFGUHYD = __esm({
1178
- "../core/dist/chunk-QEFGUHYD.js"() {
1179
- "use strict";
1180
- }
1181
- });
1182
-
1183
- // ../core/dist/chunk-AFSKXC6V.js
1184
- function hasUseClientDirective(source) {
1185
- const firstLine = source.trim().split("\n")[0] ?? "";
1186
- return /^['"]use client['"];?/.test(firstLine);
1187
- }
1188
- function hasUseServerDirective(source) {
1189
- const firstLine = source.trim().split("\n")[0] ?? "";
1190
- return /^['"]use server['"];?/.test(firstLine);
1191
- }
1192
- function detectComponentType(source) {
1193
- if (hasUseClientDirective(source)) return "client";
1194
- if (hasUseServerDirective(source)) return "server";
1195
- return "hybrid";
1196
- }
1197
- async function executeServerComponent(component, props, context) {
1198
- try {
1199
- const result = await component(props, context);
1200
- return result;
1201
- } catch (error2) {
1202
- console.error("[Flight] Server component error:", error2);
1203
- throw error2;
1204
- }
1205
- }
1206
- function createRenderContext(request, params = {}) {
1207
- const url = new URL(request.url);
1208
- const cookies2 = /* @__PURE__ */ new Map();
1209
- const cookieHeader = request.headers.get("cookie") || "";
1210
- cookieHeader.split(";").forEach((cookie) => {
1211
- const [key, value] = cookie.trim().split("=");
1212
- if (key && value) cookies2.set(key, value);
1213
- });
1214
- return {
1215
- request,
1216
- params,
1217
- searchParams: url.searchParams,
1218
- headers: request.headers,
1219
- cookies: cookies2
1220
- };
1221
- }
1222
- async function serverFetch(url, options = {}) {
1223
- const { revalidate = 60, tags = [], ...fetchOptions } = options;
1224
- const cacheKey = `${url}:${JSON.stringify(fetchOptions)}`;
1225
- const cached = fetchCache.get(cacheKey);
1226
- if (cached) {
1227
- const age = Date.now() - cached.timestamp;
1228
- if (revalidate === false || age < revalidate * 1e3) {
1229
- return cached.data;
1230
- }
1231
- }
1232
- const response = await fetch(url, fetchOptions);
1233
- if (!response.ok) {
1234
- throw new Error(`Fetch failed: ${response.status} ${response.statusText}`);
1235
- }
1236
- const data = await response.json();
1237
- if (revalidate !== false) {
1238
- fetchCache.set(cacheKey, {
1239
- data,
1240
- timestamp: Date.now()
1241
- });
1242
- }
1243
- return data;
1244
- }
1245
- function revalidateTag(tag) {
1246
- console.log(`[Flight] Revalidating tag: ${tag}`);
1247
- }
1248
- function revalidatePath(path) {
1249
- console.log(`[Flight] Revalidating path: ${path}`);
1250
- }
1251
- function serializeProps(props) {
1252
- function preProcess(value) {
1253
- if (value instanceof Date) {
1254
- return { __type: "Date", value: value.toISOString() };
1255
- }
1256
- if (value instanceof Map) {
1257
- return { __type: "Map", value: Array.from(value.entries()).map(([k, v]) => [preProcess(k), preProcess(v)]) };
1258
- }
1259
- if (value instanceof Set) {
1260
- return { __type: "Set", value: Array.from(value).map(preProcess) };
1261
- }
1262
- if (typeof value === "bigint") {
1263
- return { __type: "BigInt", value: value.toString() };
1264
- }
1265
- if (typeof value === "function") {
1266
- return void 0;
1267
- }
1268
- if (Array.isArray(value)) {
1269
- return value.map(preProcess);
1270
- }
1271
- if (value && typeof value === "object") {
1272
- const result = {};
1273
- for (const [k, v] of Object.entries(value)) {
1274
- result[k] = preProcess(v);
1275
- }
1276
- return result;
1277
- }
1278
- return value;
1279
- }
1280
- return JSON.stringify(preProcess(props));
1281
- }
1282
- function deserializeProps(serialized) {
1283
- return JSON.parse(serialized, (_key, value) => {
1284
- if (value && typeof value === "object" && "__type" in value) {
1285
- switch (value.__type) {
1286
- case "Date":
1287
- return new Date(value.value);
1288
- case "Map":
1289
- return new Map(value.value);
1290
- case "Set":
1291
- return new Set(value.value);
1292
- case "BigInt":
1293
- return BigInt(value.value);
1294
- }
1295
- }
1296
- return value;
1297
- });
1298
- }
1299
- function createClientBoundary(componentId, props, fallback) {
1300
- const serializedProps = serializeProps(props);
1301
- return `
1302
- <!--flight-client:${componentId}-->
1303
- <div data-flight-component="${componentId}" data-flight-props='${serializedProps.replace(/'/g, "&#39;")}'>
1304
- ${fallback || "<div>Loading...</div>"}
1305
- </div>
1306
- <!--/flight-client-->
1307
- <script type="module">
1308
- (async function() {
1309
- const component = await import('/_flight/components/${componentId}.js');
1310
- const props = JSON.parse('${serializedProps.replace(/'/g, "\\'")}');
1311
- const container = document.querySelector('[data-flight-component="${componentId}"]');
1312
- if (container && component.default) {
1313
- // Hydrate with the framework's hydration method
1314
- if (typeof component.hydrate === 'function') {
1315
- component.hydrate(container, props);
1316
- }
1317
- }
1318
- })();
1319
- </script>`;
1320
- }
1321
- function createAsyncComponent(fetcher, renderer) {
1322
- const component = async (props, context) => {
1323
- const data = await fetcher(props, context);
1324
- return renderer(data, props);
1325
- };
1326
- component.__flight_server = true;
1327
- return component;
1328
- }
1329
- function composeComponents(...components) {
1330
- return async () => {
1331
- const results = await Promise.all(
1332
- components.map(async (comp) => await comp())
1333
- );
1334
- return results.join("");
1335
- };
1336
- }
1337
- function withErrorBoundary(component, errorFallback) {
1338
- return async (props, context) => {
1339
- try {
1340
- return await component(props, context);
1341
- } catch (error2) {
1342
- console.error("[Flight] Server component error:", error2);
1343
- return errorFallback(error2);
1344
- }
1345
- };
1346
- }
1347
- function notFound() {
1348
- const error2 = new Error("Not Found");
1349
- error2.__flight_not_found = true;
1350
- throw error2;
1351
- }
1352
- function isNotFoundError(error2) {
1353
- return error2 instanceof Error && error2.__flight_not_found === true;
1354
- }
1355
- function redirect3(url, type = "replace") {
1356
- const error2 = new Error(`Redirect: ${url}`);
1357
- error2.__flight_redirect = { url, type };
1358
- throw error2;
1359
- }
1360
- function isRedirectError2(error2) {
1361
- if (error2 instanceof Error && error2.__flight_redirect) {
1362
- return error2.__flight_redirect;
1363
- }
1364
- return null;
1365
- }
1366
- var fetchCache;
1367
- var init_chunk_AFSKXC6V = __esm({
1368
- "../core/dist/chunk-AFSKXC6V.js"() {
1369
- "use strict";
1370
- fetchCache = /* @__PURE__ */ new Map();
1371
- }
1372
- });
1373
-
1374
- // ../core/dist/chunk-ZVC3ZWLM.js
1375
- var init_chunk_ZVC3ZWLM = __esm({
1376
- "../core/dist/chunk-ZVC3ZWLM.js"() {
1377
- "use strict";
1378
- }
1379
- });
1380
-
1381
- // ../core/dist/chunk-3AIQVGTM.js
1382
- function createCache(options = {}) {
1383
- const {
1384
- adapter = new MemoryCacheAdapter(),
1385
- defaultTTL,
1386
- prefix = ""
1387
- } = options;
1388
- const tagIndex = /* @__PURE__ */ new Map();
1389
- function prefixKey(key) {
1390
- return prefix ? `${prefix}:${key}` : key;
1391
- }
1392
- return {
1393
- async get(key) {
1394
- const entry = await adapter.get(prefixKey(key));
1395
- if (!entry) return void 0;
1396
- if (entry.staleAt && Date.now() > entry.staleAt) {
1397
- return entry.value;
1398
- }
1399
- return entry.value;
1400
- },
1401
- async set(key, value, opts) {
1402
- const ttl = opts?.ttl ?? defaultTTL;
1403
- const now = Date.now();
1404
- const entry = {
1405
- value,
1406
- createdAt: now,
1407
- tags: opts?.tags
1408
- };
1409
- if (ttl) {
1410
- entry.expiresAt = now + ttl * 1e3;
1411
- if (opts?.swr) {
1412
- entry.staleAt = now + (ttl - opts.swr) * 1e3;
1413
- }
1414
- }
1415
- const fullKey = prefixKey(key);
1416
- await adapter.set(fullKey, entry);
1417
- if (opts?.tags) {
1418
- for (const tag of opts.tags) {
1419
- if (!tagIndex.has(tag)) {
1420
- tagIndex.set(tag, /* @__PURE__ */ new Set());
1421
- }
1422
- tagIndex.get(tag).add(fullKey);
1423
- }
1424
- }
1425
- },
1426
- async delete(key) {
1427
- return adapter.delete(prefixKey(key));
1428
- },
1429
- async has(key) {
1430
- return adapter.has(prefixKey(key));
1431
- },
1432
- async clear() {
1433
- await adapter.clear();
1434
- tagIndex.clear();
1435
- },
1436
- async invalidateTag(tag) {
1437
- const keys = tagIndex.get(tag);
1438
- if (!keys) return;
1439
- for (const key of keys) {
1440
- await adapter.delete(key);
1441
- }
1442
- tagIndex.delete(tag);
1443
- },
1444
- async getOrSet(key, factory, opts) {
1445
- const cached2 = await this.get(key);
1446
- if (cached2 !== void 0) {
1447
- return cached2;
1448
- }
1449
- const value = await factory();
1450
- await this.set(key, value, opts);
1451
- return value;
1452
- }
1453
- };
1454
- }
1455
- var MemoryCacheAdapter;
1456
- var init_chunk_3AIQVGTM = __esm({
1457
- "../core/dist/chunk-3AIQVGTM.js"() {
1458
- "use strict";
1459
- MemoryCacheAdapter = class {
1460
- name = "memory";
1461
- store = /* @__PURE__ */ new Map();
1462
- async get(key) {
1463
- const entry = this.store.get(key);
1464
- if (!entry) return void 0;
1465
- if (entry.expiresAt && Date.now() > entry.expiresAt) {
1466
- this.store.delete(key);
1467
- return void 0;
1468
- }
1469
- return entry;
1470
- }
1471
- async set(key, entry) {
1472
- this.store.set(key, entry);
1473
- }
1474
- async delete(key) {
1475
- return this.store.delete(key);
1476
- }
1477
- async has(key) {
1478
- const entry = await this.get(key);
1479
- return entry !== void 0;
1480
- }
1481
- async clear() {
1482
- this.store.clear();
1483
- }
1484
- async keys(pattern) {
1485
- const allKeys = Array.from(this.store.keys());
1486
- if (!pattern) return allKeys;
1487
- const regex = new RegExp(pattern.replace(/\*/g, ".*"));
1488
- return allKeys.filter((key) => regex.test(key));
1489
- }
1490
- };
1491
- }
1492
- });
1493
-
1494
- // ../core/dist/chunk-Q4C5CCHK.js
1495
- var init_chunk_Q4C5CCHK = __esm({
1496
- "../core/dist/chunk-Q4C5CCHK.js"() {
1497
- "use strict";
1498
- }
1499
- });
1500
-
1501
- // ../core/dist/chunk-GCQZ4FHI.js
1502
- function createRouter2(options = {}) {
1503
- const ctx = {
1504
- options,
1505
- rootNode: createRadixNode2(),
1506
- staticRoutesMap: {}
1507
- };
1508
- const normalizeTrailingSlash = (p) => options.strictTrailingSlash ? p : p.replace(/\/$/, "") || "/";
1509
- if (options.routes) {
1510
- for (const path in options.routes) {
1511
- insert2(ctx, normalizeTrailingSlash(path), options.routes[path]);
1512
- }
1513
- }
1514
- return {
1515
- ctx,
1516
- lookup: (path) => lookup2(ctx, normalizeTrailingSlash(path)),
1517
- insert: (path, data) => insert2(ctx, normalizeTrailingSlash(path), data),
1518
- remove: (path) => remove2(ctx, normalizeTrailingSlash(path))
1519
- };
1520
- }
1521
- function lookup2(ctx, path) {
1522
- const staticPathNode = ctx.staticRoutesMap[path];
1523
- if (staticPathNode) {
1524
- return staticPathNode.data;
1525
- }
1526
- const sections = path.split("/");
1527
- const params = {};
1528
- let paramsFound = false;
1529
- let wildcardNode = null;
1530
- let node = ctx.rootNode;
1531
- let wildCardParam = null;
1532
- for (let i = 0; i < sections.length; i++) {
1533
- const section = sections[i];
1534
- if (node.wildcardChildNode !== null) {
1535
- wildcardNode = node.wildcardChildNode;
1536
- wildCardParam = sections.slice(i).join("/");
1537
- }
1538
- const nextNode = node.children.get(section);
1539
- if (nextNode === void 0) {
1540
- if (node && node.placeholderChildren.length > 1) {
1541
- const remaining = sections.length - i;
1542
- node = node.placeholderChildren.find((c) => c.maxDepth === remaining) || null;
1543
- } else {
1544
- node = node.placeholderChildren[0] || null;
1545
- }
1546
- if (!node) {
1547
- break;
1548
- }
1549
- if (node.paramName) {
1550
- params[node.paramName] = section;
1551
- }
1552
- paramsFound = true;
1553
- } else {
1554
- node = nextNode;
1555
- }
1556
- }
1557
- if ((node === null || node.data === null) && wildcardNode !== null) {
1558
- node = wildcardNode;
1559
- params[node.paramName || "_"] = wildCardParam;
1560
- paramsFound = true;
1561
- }
1562
- if (!node) {
1563
- return null;
1564
- }
1565
- if (paramsFound) {
1566
- return {
1567
- ...node.data,
1568
- params: paramsFound ? params : void 0
1569
- };
1570
- }
1571
- return node.data;
1572
- }
1573
- function insert2(ctx, path, data) {
1574
- let isStaticRoute = true;
1575
- const sections = path.split("/");
1576
- let node = ctx.rootNode;
1577
- let _unnamedPlaceholderCtr = 0;
1578
- const matchedNodes = [node];
1579
- for (const section of sections) {
1580
- let childNode;
1581
- if (childNode = node.children.get(section)) {
1582
- node = childNode;
1583
- } else {
1584
- const type = getNodeType2(section);
1585
- childNode = createRadixNode2({ type, parent: node });
1586
- node.children.set(section, childNode);
1587
- if (type === NODE_TYPES2.PLACEHOLDER) {
1588
- childNode.paramName = section === "*" ? `_${_unnamedPlaceholderCtr++}` : section.slice(1);
1589
- node.placeholderChildren.push(childNode);
1590
- isStaticRoute = false;
1591
- } else if (type === NODE_TYPES2.WILDCARD) {
1592
- node.wildcardChildNode = childNode;
1593
- childNode.paramName = section.slice(
1594
- 3
1595
- /* "**:" */
1596
- ) || "_";
1597
- isStaticRoute = false;
1598
- }
1599
- matchedNodes.push(childNode);
1600
- node = childNode;
1601
- }
1602
- }
1603
- for (const [depth, node2] of matchedNodes.entries()) {
1604
- node2.maxDepth = Math.max(matchedNodes.length - depth, node2.maxDepth || 0);
1605
- }
1606
- node.data = data;
1607
- if (isStaticRoute === true) {
1608
- ctx.staticRoutesMap[path] = node;
1609
- }
1610
- return node;
1611
- }
1612
- function remove2(ctx, path) {
1613
- let success = false;
1614
- const sections = path.split("/");
1615
- let node = ctx.rootNode;
1616
- for (const section of sections) {
1617
- node = node.children.get(section);
1618
- if (!node) {
1619
- return success;
1620
- }
1621
- }
1622
- if (node.data) {
1623
- const lastSection = sections.at(-1) || "";
1624
- node.data = null;
1625
- if (Object.keys(node.children).length === 0 && node.parent) {
1626
- node.parent.children.delete(lastSection);
1627
- node.parent.wildcardChildNode = null;
1628
- node.parent.placeholderChildren = [];
1629
- }
1630
- success = true;
1631
- }
1632
- return success;
1633
- }
1634
- function createRadixNode2(options = {}) {
1635
- return {
1636
- type: options.type || NODE_TYPES2.NORMAL,
1637
- maxDepth: 0,
1638
- parent: options.parent || null,
1639
- children: /* @__PURE__ */ new Map(),
1640
- data: options.data || null,
1641
- paramName: options.paramName || null,
1642
- wildcardChildNode: null,
1643
- placeholderChildren: []
1644
- };
1645
- }
1646
- function getNodeType2(str) {
1647
- if (str.startsWith("**")) {
1648
- return NODE_TYPES2.WILDCARD;
1649
- }
1650
- if (str[0] === ":" || str === "*") {
1651
- return NODE_TYPES2.PLACEHOLDER;
1652
- }
1653
- return NODE_TYPES2.NORMAL;
1654
- }
1655
- function convertPattern(pattern) {
1656
- return pattern.replace(/\[\.\.\.(\w+)\]/g, "**:$1").replace(/\[(\w+)\]/g, ":$1");
1657
- }
1658
- function createRouter22() {
1659
- const radix = createRouter2();
1660
- const routeMap = /* @__PURE__ */ new Map();
1661
- return {
1662
- add(route) {
1663
- const radixPath = convertPattern(route.path);
1664
- radix.insert(radixPath, route);
1665
- routeMap.set(route.path, route);
1666
- },
1667
- addAll(routes) {
1668
- for (const route of routes) {
1669
- this.add(route);
1670
- }
1671
- },
1672
- match(path) {
1673
- const result = radix.lookup(path);
1674
- if (!result) {
1675
- return null;
1676
- }
1677
- const params = {};
1678
- if (result.params) {
1679
- for (const [key, value] of Object.entries(result.params)) {
1680
- if (value !== void 0) {
1681
- params[key] = value;
1682
- }
1683
- }
1684
- }
1685
- return {
1686
- route: result,
1687
- params,
1688
- path
1689
- };
1690
- },
1691
- routes() {
1692
- return Array.from(routeMap.values());
1693
- },
1694
- remove(path) {
1695
- if (routeMap.has(path)) {
1696
- const radixPath = convertPattern(path);
1697
- radix.remove(radixPath);
1698
- routeMap.delete(path);
1699
- return true;
1700
- }
1701
- return false;
1702
- }
1703
- };
1704
- }
1705
- var NODE_TYPES2;
1706
- var init_chunk_GCQZ4FHI = __esm({
1707
- "../core/dist/chunk-GCQZ4FHI.js"() {
1708
- "use strict";
1709
- NODE_TYPES2 = {
1710
- NORMAL: 0,
1711
- WILDCARD: 1,
1712
- PLACEHOLDER: 2
1713
- };
1714
- }
1715
- });
1716
-
1717
- // ../core/dist/chunk-KWFX6WHG.js
1718
- function createMiddlewareChain() {
1719
- const stack = [];
1720
- function use(pathOrMiddleware, maybeMiddleware) {
1721
- if (typeof pathOrMiddleware === "function") {
1722
- stack.push({ handler: pathOrMiddleware });
1723
- } else if (typeof pathOrMiddleware === "string" && maybeMiddleware) {
1724
- stack.push({ path: pathOrMiddleware, handler: maybeMiddleware });
1725
- } else if (typeof pathOrMiddleware === "object") {
1726
- stack.push(pathOrMiddleware);
1727
- }
1728
- return chain;
1729
- }
1730
- async function execute(ctx) {
1731
- let index = -1;
1732
- async function dispatch(i) {
1733
- if (i <= index) {
1734
- throw new Error("next() called multiple times");
1735
- }
1736
- index = i;
1737
- if (i >= stack.length) {
1738
- return;
1739
- }
1740
- const definition = stack[i];
1741
- if (!definition) {
1742
- return dispatch(i + 1);
1743
- }
1744
- if (!shouldRun(definition, ctx)) {
1745
- return dispatch(i + 1);
1746
- }
1747
- await definition.handler(ctx, () => dispatch(i + 1));
1748
- }
1749
- await dispatch(0);
1750
- }
1751
- const chain = {
1752
- use,
1753
- execute,
1754
- middlewares: () => [...stack]
1755
- };
1756
- return chain;
1757
- }
1758
- function shouldRun(def, ctx) {
1759
- if (def.methods && !def.methods.includes(ctx.method.toUpperCase())) {
1760
- return false;
1761
- }
1762
- if (def.path) {
1763
- const path = ctx.url.pathname;
1764
- if (typeof def.path === "string") {
1765
- if (def.path.endsWith("*")) {
1766
- const prefix = def.path.slice(0, -1);
1767
- if (!path.startsWith(prefix)) {
1768
- return false;
1769
- }
1770
- } else if (def.path !== path) {
1771
- return false;
1772
- }
1773
- } else if (def.path instanceof RegExp) {
1774
- if (!def.path.test(path)) {
1775
- return false;
1776
- }
1777
- }
1778
- }
1779
- return true;
1780
- }
1781
- function createContextFromRequest(request, params = {}) {
1782
- const url = new URL(request.url);
1783
- return {
1784
- url,
1785
- method: request.method,
1786
- headers: request.headers,
1787
- params,
1788
- query: url.searchParams,
1789
- locals: {},
1790
- request,
1791
- status: 200,
1792
- responseHeaders: new Headers()
1793
- };
1794
- }
1795
- function createResponseFromContext(ctx) {
1796
- return new Response(ctx.responseBody, {
1797
- status: ctx.status,
1798
- headers: ctx.responseHeaders
1799
- });
1800
- }
1801
- var init_chunk_KWFX6WHG = __esm({
1802
- "../core/dist/chunk-KWFX6WHG.js"() {
1803
- "use strict";
1804
- }
1805
- });
1806
-
1807
- // ../core/dist/chunk-Y22KEW2F.js
1808
- function detectRuntime() {
1809
- if (typeof Bun !== "undefined") return "bun";
1810
- if (typeof Deno !== "undefined") return "deno";
1811
- if (typeof process !== "undefined" && process.versions?.node) return "node";
1812
- return "unknown";
1813
- }
1814
- function createServer2(options = {}) {
1815
- const config = resolveConfig(options.config ?? {});
1816
- const router = createRouter22();
1817
- const middlewareChain = createMiddlewareChain();
1818
- const deps = {
1819
- db: options.db,
1820
- auth: options.auth,
1821
- email: options.email
1822
- };
1823
- function addRoute(method, path, handler) {
1824
- const methods = Array.isArray(method) ? method : [method];
1825
- const methodSet = new Set(methods.map((m) => m.toUpperCase()));
1826
- const existingMatch = router.match(path);
1827
- if (existingMatch && existingMatch.route.path === path) {
1828
- for (const m of methodSet) {
1829
- existingMatch.route.handler.methods.add(m);
1830
- }
1831
- existingMatch.route.handler.handler = handler;
1832
- } else {
1833
- router.add({
1834
- path,
1835
- handler: { methods: methodSet, handler }
1836
- });
1837
- }
1838
- return server;
1839
- }
1840
- function useMiddleware(pathOrMiddleware, maybeMiddleware) {
1841
- if (typeof pathOrMiddleware === "string" && maybeMiddleware) {
1842
- middlewareChain.use(pathOrMiddleware, maybeMiddleware);
1843
- } else if (typeof pathOrMiddleware === "function") {
1844
- middlewareChain.use(pathOrMiddleware);
1845
- }
1846
- return server;
1847
- }
1848
- async function handle(request) {
1849
- const url = new URL(request.url);
1850
- const method = request.method.toUpperCase();
1851
- const ctx = createContextFromRequest(request);
1852
- await middlewareChain.execute(ctx);
1853
- if (ctx.responseBody !== void 0) {
1854
- return createResponseFromContext(ctx);
1855
- }
1856
- const match = router.match(url.pathname);
1857
- if (!match) {
1858
- return new Response("Not Found", { status: 404 });
1859
- }
1860
- if (!match.route.handler.methods.has(method) && !match.route.handler.methods.has("*")) {
1861
- return new Response("Method Not Allowed", { status: 405 });
1862
- }
1863
- const handlerContext = {
1864
- request,
1865
- params: match.params,
1866
- query: url.searchParams,
1867
- url,
1868
- locals: ctx.locals,
1869
- ...deps
1870
- };
1871
- try {
1872
- return await match.route.handler.handler(handlerContext);
1873
- } catch (error2) {
1874
- console.error("Route handler error:", error2);
1875
- return new Response("Internal Server Error", { status: 500 });
1876
- }
1877
- }
1878
- async function listen(portOrOptions) {
1879
- const opts = typeof portOrOptions === "number" ? { port: portOrOptions } : portOrOptions ?? {};
1880
- const port = opts.port ?? config.dev.port ?? 3e3;
1881
- const hostname = opts.hostname ?? "localhost";
1882
- const adapter = options.adapter ?? config.adapter;
1883
- if (adapter?.listen) {
1884
- await adapter.listen(server, port);
1885
- return;
1886
- }
1887
- const runtime = detectRuntime();
1888
- switch (runtime) {
1889
- case "bun":
1890
- await startBunServer(port, hostname, opts.onListen);
1891
- break;
1892
- case "deno":
1893
- await startDenoServer(port, hostname, opts.onListen);
1894
- break;
1895
- case "node":
1896
- default:
1897
- await startNodeServer(port, hostname, opts.onListen);
1898
- break;
1899
- }
1900
- }
1901
- async function startNodeServer(port, hostname, onListen) {
1902
- const { createServer: createHttpServer } = await import("http");
1903
- const httpServer = createHttpServer(async (req, res) => {
1904
- const url = new URL(req.url || "/", `http://${hostname}:${port}`);
1905
- const headers = new Headers();
1906
- for (const [key, value] of Object.entries(req.headers)) {
1907
- if (value) {
1908
- const headerValue = Array.isArray(value) ? value[0] : value;
1909
- if (headerValue) headers.set(key, headerValue);
1910
- }
1911
- }
1912
- let body;
1913
- if (["POST", "PUT", "PATCH"].includes(req.method || "")) {
1914
- body = await new Promise((resolve5) => {
1915
- let data = "";
1916
- req.on("data", (chunk) => data += chunk);
1917
- req.on("end", () => resolve5(data));
1918
- });
1919
- }
1920
- const request = new Request(url.toString(), {
1921
- method: req.method,
1922
- headers,
1923
- body: body || void 0
1924
- });
1925
- try {
1926
- const response = await handle(request);
1927
- res.statusCode = response.status;
1928
- response.headers.forEach((value, key) => {
1929
- res.setHeader(key, value);
1930
- });
1931
- const responseBody = await response.text();
1932
- res.end(responseBody);
1933
- } catch (error2) {
1934
- console.error("Server error:", error2);
1935
- res.statusCode = 500;
1936
- res.setHeader("Content-Type", "application/json");
1937
- res.end(JSON.stringify({ error: "Internal Server Error" }));
1938
- }
1939
- });
1940
- return new Promise((resolve5) => {
1941
- httpServer.listen(port, hostname, () => {
1942
- const info = { port, hostname };
1943
- if (onListen) {
1944
- onListen(info);
1945
- } else {
1946
- console.log(`
1947
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1948
- \u2551 Flight Server (Node.js) \u2551
1949
- \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
1950
- \u2551 Server: http://${hostname}:${port.toString().padEnd(37)}\u2551
1951
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1952
- `);
1953
- }
1954
- resolve5();
1955
- });
1956
- });
1957
- }
1958
- async function startBunServer(port, hostname, onListen) {
1959
- Bun.serve({
1960
- port,
1961
- hostname,
1962
- fetch: handle
1963
- });
1964
- const info = { port, hostname };
1965
- if (onListen) {
1966
- onListen(info);
1967
- } else {
1968
- console.log(`
1969
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1970
- \u2551 Flight Server (Bun) \u2551
1971
- \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
1972
- \u2551 Server: http://${hostname}:${port.toString().padEnd(37)}\u2551
1973
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1974
- `);
1975
- }
1976
- }
1977
- async function startDenoServer(port, hostname, onListen) {
1978
- Deno.serve({ port, hostname }, handle);
1979
- const info = { port, hostname };
1980
- if (onListen) {
1981
- onListen(info);
1982
- } else {
1983
- console.log(`
1984
- \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
1985
- \u2551 Flight Server (Deno) \u2551
1986
- \u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
1987
- \u2551 Server: http://${hostname}:${port.toString().padEnd(37)}\u2551
1988
- \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
1989
- `);
1990
- }
1991
- }
1992
- const server = {
1993
- route: addRoute,
1994
- get: (path, handler) => addRoute("GET", path, handler),
1995
- post: (path, handler) => addRoute("POST", path, handler),
1996
- put: (path, handler) => addRoute("PUT", path, handler),
1997
- delete: (path, handler) => addRoute("DELETE", path, handler),
1998
- patch: (path, handler) => addRoute("PATCH", path, handler),
1999
- use: useMiddleware,
2000
- handle,
2001
- listen,
2002
- fetch: handle,
2003
- // Alias for Bun/Deno compatibility
2004
- get config() {
2005
- return config;
2006
- },
2007
- get router() {
2008
- return router;
2009
- },
2010
- get middleware() {
2011
- return middlewareChain;
2012
- }
2013
- };
2014
- return server;
2015
- }
2016
- var init_chunk_Y22KEW2F = __esm({
2017
- "../core/dist/chunk-Y22KEW2F.js"() {
2018
- "use strict";
2019
- init_chunk_GCQZ4FHI();
2020
- init_chunk_KWFX6WHG();
2021
- init_chunk_WAGCTWGY();
2022
- }
2023
- });
2024
-
2025
- // ../core/dist/index.js
2026
- var dist_exports2 = {};
2027
- __export(dist_exports2, {
2028
- RedirectError: () => RedirectError,
2029
- VERSION: () => VERSION2,
2030
- actionRedirect: () => redirect,
2031
- composeComponents: () => composeComponents,
2032
- cookies: () => cookies,
2033
- createAsyncComponent: () => createAsyncComponent,
2034
- createCache: () => createCache,
2035
- createClientBoundary: () => createClientBoundary,
2036
- createFileRouter: () => createFileRouter,
2037
- createLazyContent: () => createLazyContent,
2038
- createMiddlewareChain: () => createMiddlewareChain,
2039
- createRenderContext: () => createRenderContext,
2040
- createRouteContext: () => createRouteContext,
2041
- createRouter: () => createRouter22,
2042
- createServer: () => createServer2,
2043
- createStreamingResponse: () => createStreamingResponse,
2044
- createStreamingSSR: () => createStreamingSSR,
2045
- defineConfig: () => defineConfig,
2046
- deserializeProps: () => deserializeProps,
2047
- detectComponentType: () => detectComponentType,
2048
- error: () => error,
2049
- executeAction: () => executeAction,
2050
- executeFormAction: () => executeFormAction,
2051
- executeServerComponent: () => executeServerComponent,
2052
- getAction: () => getAction,
2053
- handleActionRequest: () => handleActionRequest,
2054
- hasUseClientDirective: () => hasUseClientDirective,
2055
- hasUseServerDirective: () => hasUseServerDirective,
2056
- isNotFoundError: () => isNotFoundError,
2057
- isRedirectError: () => isRedirectError,
2058
- isRscRedirectError: () => isRedirectError2,
2059
- json: () => json,
2060
- loadRoutes: () => loadRoutes,
2061
- notFound: () => notFound,
2062
- parseBody: () => parseBody,
2063
- parseFormData: () => parseFormData,
2064
- redirect: () => redirect2,
2065
- registerAction: () => registerAction,
2066
- renderWithStreaming: () => renderWithStreaming,
2067
- revalidatePath: () => revalidatePath,
2068
- revalidateTag: () => revalidateTag,
2069
- rscRedirect: () => redirect3,
2070
- scanRoutes: () => scanRoutes,
2071
- serializeProps: () => serializeProps,
2072
- serverFetch: () => serverFetch,
2073
- streamParallel: () => streamParallel,
2074
- streamSequential: () => streamSequential,
2075
- withErrorBoundary: () => withErrorBoundary
2076
- });
2077
- var VERSION2;
2078
- var init_dist3 = __esm({
2079
- "../core/dist/index.js"() {
2080
- "use strict";
2081
- init_chunk_I5RHYGX6();
2082
- init_chunk_TKXN7KGE();
2083
- init_chunk_AJ3IBYXT();
2084
- init_chunk_QEFGUHYD();
2085
- init_chunk_AFSKXC6V();
2086
- init_chunk_ZVC3ZWLM();
2087
- init_chunk_3AIQVGTM();
2088
- init_chunk_Q4C5CCHK();
2089
- init_chunk_Y22KEW2F();
2090
- init_chunk_GCQZ4FHI();
2091
- init_chunk_KWFX6WHG();
2092
- init_chunk_WAGCTWGY();
2093
- VERSION2 = "0.0.1";
2094
- }
2095
- });
2096
8
 
2097
9
  // src/index.ts
2098
10
  import { cac } from "cac";
@@ -2102,11 +14,25 @@ import pc5 from "picocolors";
2102
14
  var VERSION = "0.0.1";
2103
15
 
2104
16
  // src/commands/create.ts
2105
- import { existsSync, mkdirSync, writeFileSync, readdirSync } from "fs";
2106
- import { join, resolve } from "path";
17
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, copyFileSync, unlinkSync } from "fs";
18
+ import { join, resolve, dirname } from "path";
2107
19
  import { execSync } from "child_process";
20
+ import { fileURLToPath } from "url";
2108
21
  import pc from "picocolors";
2109
22
  import prompts from "prompts";
23
+ var __dirname = dirname(fileURLToPath(import.meta.url));
24
+ var TEMPLATES_DIR = resolve(__dirname, "../../templates");
25
+ var UI_FRAMEWORKS = [
26
+ { title: "React", value: "react", description: "The library for web and native user interfaces" },
27
+ { title: "Vue", value: "vue", description: "The progressive JavaScript framework" },
28
+ { title: "Svelte", value: "svelte", description: "Cybernetically enhanced web apps" },
29
+ { title: "Solid", value: "solid", description: "Simple and performant reactivity" },
30
+ { title: "Preact", value: "preact", description: "Fast 3kB alternative to React" },
31
+ { title: "Qwik", value: "qwik", description: "Resumable framework with O(1) loading" },
32
+ { title: "Lit", value: "lit", description: "Fast, lightweight Web Components" },
33
+ { title: "Htmx", value: "htmx", description: "HTML over the wire, no JavaScript" },
34
+ { title: "Vanilla", value: "vanilla", description: "No framework, just TypeScript" }
35
+ ];
2110
36
  async function createCommand(name, options) {
2111
37
  printLogo();
2112
38
  console.log(pc.cyan("\n[*] Creating a new Flight project...\n"));
@@ -2135,17 +61,7 @@ async function createCommand(name, options) {
2135
61
  type: "select",
2136
62
  name: "ui",
2137
63
  message: "Choose your UI framework:",
2138
- choices: [
2139
- { title: "React", value: "react", description: "The library for web and native user interfaces" },
2140
- { title: "Vue", value: "vue", description: "The progressive JavaScript framework" },
2141
- { title: "Svelte", value: "svelte", description: "Cybernetically enhanced web apps" },
2142
- { title: "Solid", value: "solid", description: "Simple and performant reactivity" },
2143
- { title: "Preact", value: "preact", description: "Fast 3kB alternative to React" },
2144
- { title: "Qwik", value: "qwik", description: "Resumable framework with O(1) loading" },
2145
- { title: "Lit", value: "lit", description: "Fast, lightweight Web Components" },
2146
- { title: "Htmx", value: "htmx", description: "HTML over the wire, no JavaScript" },
2147
- { title: "Vanilla", value: "vanilla", description: "No framework, just JavaScript" }
2148
- ],
64
+ choices: UI_FRAMEWORKS,
2149
65
  initial: 0
2150
66
  });
2151
67
  uiFramework = response.ui;
@@ -2174,11 +90,7 @@ async function createCommand(name, options) {
2174
90
  Creating project in ${projectPath}...
2175
91
  `));
2176
92
  try {
2177
- createProjectStructure(projectPath, {
2178
- name: projectName,
2179
- ui: uiFramework,
2180
- typescript: options.ts
2181
- });
93
+ copyTemplate(projectPath, uiFramework, projectName);
2182
94
  console.log(pc.green("\u2713") + " Project structure created");
2183
95
  if (options.git) {
2184
96
  try {
@@ -2213,8 +125,8 @@ ${pc.dim("Your project is 100% yours:")}
2213
125
 
2214
126
  ${pc.cyan("Happy flying!")}
2215
127
  `);
2216
- } catch (error2) {
2217
- console.error(pc.red("Failed to create project:"), error2);
128
+ } catch (error) {
129
+ console.error(pc.red("Failed to create project:"), error);
2218
130
  process.exit(1);
2219
131
  }
2220
132
  }
@@ -2224,952 +136,59 @@ function detectPackageManager() {
2224
136
  if (process.env.npm_config_user_agent?.includes("bun")) return "bun";
2225
137
  return "npm";
2226
138
  }
2227
- function createProjectStructure(projectPath, options) {
2228
- const { name, ui, typescript } = options;
2229
- const ext = typescript ? "ts" : "js";
2230
- const extx = typescript ? "tsx" : "jsx";
2231
- const dirs = [
2232
- "",
2233
- "src",
2234
- "src/styles",
2235
- "public"
2236
- ];
2237
- for (const dir of dirs) {
2238
- mkdirSync(join(projectPath, dir), { recursive: true });
2239
- }
2240
- const vitePlugin = getVitePlugin(ui);
2241
- const vitePluginImport = getVitePluginImport(ui);
2242
- const packageJson = {
2243
- name,
2244
- version: "0.0.1",
2245
- private: true,
2246
- type: "module",
2247
- scripts: {
2248
- dev: "vite",
2249
- build: "vite build",
2250
- preview: "vite preview",
2251
- "flight:dev": "flight dev",
2252
- "flight:build": "flight build"
2253
- },
2254
- dependencies: {},
2255
- devDependencies: {
2256
- "vite": "^6.0.0",
2257
- ...typescript ? {
2258
- "typescript": "^5.7.0",
2259
- "@types/node": "^22.0.0"
2260
- } : {}
2261
- }
139
+ function copyTemplate(projectPath, ui, projectName) {
140
+ const baseDir = join(TEMPLATES_DIR, "base");
141
+ const uiDir = join(TEMPLATES_DIR, ui);
142
+ mkdirSync(projectPath, { recursive: true });
143
+ mkdirSync(join(projectPath, "src"), { recursive: true });
144
+ mkdirSync(join(projectPath, "src/styles"), { recursive: true });
145
+ mkdirSync(join(projectPath, "public"), { recursive: true });
146
+ const vars = {
147
+ "{{PROJECT_NAME}}": projectName,
148
+ "{{UI_FRAMEWORK}}": ui,
149
+ "{{LANGUAGE}}": "TypeScript"
2262
150
  };
2263
- if (ui === "react") {
2264
- packageJson.dependencies["react"] = "^19.0.0";
2265
- packageJson.dependencies["react-dom"] = "^19.0.0";
2266
- packageJson.devDependencies["@vitejs/plugin-react"] = "^4.3.0";
2267
- if (typescript) {
2268
- packageJson.devDependencies["@types/react"] = "^19.0.0";
2269
- packageJson.devDependencies["@types/react-dom"] = "^19.0.0";
151
+ copyDirWithTemplates(baseDir, projectPath, vars);
152
+ copyDirWithTemplates(uiDir, projectPath, vars);
153
+ const gitignoreSrc = join(projectPath, "_gitignore");
154
+ const gitignoreDest = join(projectPath, ".gitignore");
155
+ if (existsSync(gitignoreSrc)) {
156
+ copyFileSync(gitignoreSrc, gitignoreDest);
157
+ unlinkSync(gitignoreSrc);
158
+ }
159
+ }
160
+ function copyDirWithTemplates(srcDir, destDir, vars) {
161
+ if (!existsSync(srcDir)) return;
162
+ const entries = readdirSync(srcDir, { withFileTypes: true });
163
+ for (const entry of entries) {
164
+ const srcPath = join(srcDir, entry.name);
165
+ let destName = entry.name;
166
+ let isTemplate = false;
167
+ if (destName.endsWith(".template")) {
168
+ destName = destName.replace(".template", "");
169
+ isTemplate = true;
170
+ }
171
+ const destPath = join(destDir, destName);
172
+ if (entry.isDirectory()) {
173
+ mkdirSync(destPath, { recursive: true });
174
+ copyDirWithTemplates(srcPath, destPath, vars);
175
+ } else {
176
+ let content = readFileSync(srcPath, "utf-8");
177
+ if (isTemplate || destName.endsWith(".json") || destName.endsWith(".html") || destName.endsWith(".md")) {
178
+ for (const [key, value] of Object.entries(vars)) {
179
+ content = content.replaceAll(key, value);
180
+ }
181
+ }
182
+ writeFileSync(destPath, content);
2270
183
  }
2271
- } else if (ui === "vue") {
2272
- packageJson.dependencies["vue"] = "^3.5.0";
2273
- packageJson.devDependencies["@vitejs/plugin-vue"] = "^5.2.0";
2274
- } else if (ui === "svelte") {
2275
- packageJson.dependencies["svelte"] = "^5.0.0";
2276
- packageJson.devDependencies["@sveltejs/vite-plugin-svelte"] = "^4.0.0";
2277
- } else if (ui === "solid") {
2278
- packageJson.dependencies["solid-js"] = "^1.9.0";
2279
- packageJson.devDependencies["vite-plugin-solid"] = "^2.10.0";
2280
- } else if (ui === "preact") {
2281
- packageJson.dependencies["preact"] = "^10.25.0";
2282
- packageJson.devDependencies["@preact/preset-vite"] = "^2.9.0";
2283
- packageJson.devDependencies["preact-render-to-string"] = "^6.5.0";
2284
- } else if (ui === "qwik") {
2285
- packageJson.dependencies["@builder.io/qwik"] = "^2.0.0";
2286
- packageJson.devDependencies["@builder.io/qwik-city"] = "^2.0.0";
2287
- } else if (ui === "lit") {
2288
- packageJson.dependencies["lit"] = "^3.2.0";
2289
- packageJson.devDependencies["@lit-labs/ssr"] = "^3.3.0";
2290
- } else if (ui === "htmx") {
2291
- packageJson.dependencies["htmx.org"] = "^2.0.0";
2292
- }
2293
- writeFileSync(
2294
- join(projectPath, "package.json"),
2295
- JSON.stringify(packageJson, null, 2)
2296
- );
2297
- const viteConfig = `import { defineConfig } from 'vite';
2298
- ${vitePluginImport}
2299
-
2300
- // https://vite.dev/config/
2301
- export default defineConfig({
2302
- plugins: [${vitePlugin}],
2303
- server: {
2304
- port: 5173,
2305
- open: false,
2306
- },
2307
- build: {
2308
- target: 'es2022',
2309
- sourcemap: true,
2310
- },
2311
- });
2312
- `;
2313
- writeFileSync(join(projectPath, `vite.config.${ext}`), viteConfig);
2314
- const indexHtml = createIndexHtml(name, ui);
2315
- writeFileSync(join(projectPath, "index.html"), indexHtml);
2316
- const clientEntry = createClientEntry(ui, typescript);
2317
- writeFileSync(join(projectPath, `src/entry-client.${extx}`), clientEntry);
2318
- const serverEntry = createServerEntry(ui, typescript);
2319
- writeFileSync(join(projectPath, `src/entry-server.${extx}`), serverEntry);
2320
- const appComponent = createAppComponent(ui, typescript);
2321
- const appExt = ui === "svelte" ? "svelte" : ui === "vue" ? "vue" : extx;
2322
- writeFileSync(join(projectPath, `src/App.${appExt}`), appComponent);
2323
- const globalStyles = createGlobalStyles();
2324
- writeFileSync(join(projectPath, "src/styles/global.css"), globalStyles);
2325
- const flightConfig = `// Flight Framework Configuration
2326
- // SSR enabled by default
2327
-
2328
- export default {
2329
- ui: {
2330
- framework: '${ui}',
2331
- },
2332
- rendering: {
2333
- default: 'ssr', // Server-side rendering enabled
2334
- },
2335
- };
2336
- `;
2337
- writeFileSync(join(projectPath, `flight.config.${ext}`), flightConfig);
2338
- if (typescript) {
2339
- const tsconfig = {
2340
- compilerOptions: {
2341
- target: "ES2022",
2342
- module: "ESNext",
2343
- moduleResolution: "bundler",
2344
- lib: ["ES2022", "DOM", "DOM.Iterable"],
2345
- strict: true,
2346
- noEmit: true,
2347
- esModuleInterop: true,
2348
- skipLibCheck: true,
2349
- forceConsistentCasingInFileNames: true,
2350
- resolveJsonModule: true,
2351
- isolatedModules: true,
2352
- verbatimModuleSyntax: true,
2353
- jsx: ui === "react" || ui === "preact" ? "react-jsx" : ui === "solid" ? "preserve" : void 0,
2354
- jsxImportSource: ui === "preact" ? "preact" : ui === "solid" ? "solid-js" : void 0
2355
- },
2356
- include: ["src"],
2357
- exclude: ["node_modules"]
2358
- };
2359
- writeFileSync(
2360
- join(projectPath, "tsconfig.json"),
2361
- JSON.stringify(tsconfig, null, 2)
2362
- );
2363
- }
2364
- const gitignore = `# Dependencies
2365
- node_modules/
2366
-
2367
- # Build output
2368
- dist/
2369
- .output/
2370
-
2371
- # Environment
2372
- .env
2373
- .env.*
2374
- !.env.example
2375
-
2376
- # Logs
2377
- *.log
2378
- npm-debug.log*
2379
-
2380
- # Editor
2381
- .vscode/
2382
- .idea/
2383
- *.swp
2384
- *.swo
2385
-
2386
- # OS
2387
- .DS_Store
2388
- Thumbs.db
2389
- `;
2390
- writeFileSync(join(projectPath, ".gitignore"), gitignore);
2391
- const readme = `# ${name}
2392
-
2393
- A modern web application built with Flight Framework.
2394
-
2395
- ## Development
2396
-
2397
- \`\`\`bash
2398
- npm run dev
2399
- \`\`\`
2400
-
2401
- ## Production Build
2402
-
2403
- \`\`\`bash
2404
- npm run build
2405
- npm run preview
2406
- \`\`\`
2407
-
2408
- ## Tech Stack
2409
-
2410
- - **Framework**: ${ui.charAt(0).toUpperCase() + ui.slice(1)}
2411
- - **Build Tool**: Vite 6
2412
- - **Language**: ${typescript ? "TypeScript" : "JavaScript"}
2413
-
2414
- ## Flight Philosophy
2415
-
2416
- This project runs on Flight Framework:
2417
- - **No lock-in** - Deploy anywhere
2418
- - **No telemetry** - Your code, your privacy
2419
- - **You choose** - UI, database, auth, hosting
2420
- `;
2421
- writeFileSync(join(projectPath, "README.md"), readme);
2422
- }
2423
- function getVitePlugin(ui) {
2424
- switch (ui) {
2425
- case "react":
2426
- return "react()";
2427
- case "vue":
2428
- return "vue()";
2429
- case "svelte":
2430
- return "svelte()";
2431
- case "solid":
2432
- return "solid()";
2433
- case "preact":
2434
- return "preact()";
2435
- case "qwik":
2436
- return "qwikVite()";
2437
- case "lit":
2438
- return "";
2439
- // Lit doesn't need Vite plugin for SSR
2440
- case "htmx":
2441
- return "";
2442
- // HTMX is HTML-only, no plugin needed
2443
- default:
2444
- return "";
2445
- }
2446
- }
2447
- function getVitePluginImport(ui) {
2448
- switch (ui) {
2449
- case "react":
2450
- return "import react from '@vitejs/plugin-react';";
2451
- case "vue":
2452
- return "import vue from '@vitejs/plugin-vue';";
2453
- case "svelte":
2454
- return "import { svelte } from '@sveltejs/vite-plugin-svelte';";
2455
- case "solid":
2456
- return "import solid from 'vite-plugin-solid';";
2457
- case "preact":
2458
- return "import preact from '@preact/preset-vite';";
2459
- case "qwik":
2460
- return "import { qwikVite } from '@builder.io/qwik/optimizer';";
2461
- case "lit":
2462
- return "// Lit uses native Web Components, no Vite plugin required";
2463
- case "htmx":
2464
- return "// HTMX is HTML-only, no Vite plugin required";
2465
- default:
2466
- return "";
2467
- }
2468
- }
2469
- function createIndexHtml(name, ui) {
2470
- const moduleExt = ui === "svelte" ? "ts" : "tsx";
2471
- return `<!DOCTYPE html>
2472
- <html lang="en">
2473
- <head>
2474
- <meta charset="UTF-8" />
2475
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
2476
- <meta name="description" content="${name} - Built with Flight Framework" />
2477
- <title>${name}</title>
2478
- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
2479
- </head>
2480
- <body>
2481
- <div id="root"><!--ssr-outlet--></div>
2482
- <script type="module" src="/src/entry-client.${moduleExt}"></script>
2483
- </body>
2484
- </html>
2485
- `;
2486
- }
2487
- function createClientEntry(ui, _typescript) {
2488
- switch (ui) {
2489
- case "react":
2490
- return `import { hydrateRoot, createRoot } from 'react-dom/client';
2491
- import App from './App';
2492
- import './styles/global.css';
2493
-
2494
- const rootElement = document.getElementById('root');
2495
-
2496
- if (!rootElement) {
2497
- throw new Error('Root element not found');
2498
- }
2499
-
2500
- // Check if we have SSR content to hydrate
2501
- if (rootElement.innerHTML.trim()) {
2502
- hydrateRoot(rootElement, <App />);
2503
- } else {
2504
- // CSR fallback
2505
- createRoot(rootElement).render(<App />);
2506
- }
2507
- `;
2508
- case "vue":
2509
- return `import { createApp, createSSRApp } from 'vue';
2510
- import App from './App.vue';
2511
- import './styles/global.css';
2512
-
2513
- const rootElement = document.getElementById('root');
2514
- const hasSSRContent = rootElement?.innerHTML.trim();
2515
-
2516
- if (hasSSRContent) {
2517
- createSSRApp(App).mount('#root');
2518
- } else {
2519
- createApp(App).mount('#root');
2520
- }
2521
- `;
2522
- case "solid":
2523
- return `import { hydrate, render } from 'solid-js/web';
2524
- import App from './App';
2525
- import './styles/global.css';
2526
-
2527
- const root = document.getElementById('root');
2528
-
2529
- if (!root) {
2530
- throw new Error('Root element not found');
2531
- }
2532
-
2533
- // Check for SSR content
2534
- if (root.innerHTML.trim()) {
2535
- hydrate(() => <App />, root);
2536
- } else {
2537
- render(() => <App />, root);
2538
- }
2539
- `;
2540
- case "preact":
2541
- return `import { hydrate, render } from 'preact';
2542
- import App from './App';
2543
- import './styles/global.css';
2544
-
2545
- const root = document.getElementById('root');
2546
-
2547
- if (!root) {
2548
- throw new Error('Root element not found');
2549
- }
2550
-
2551
- // Check for SSR content
2552
- if (root.innerHTML.trim()) {
2553
- hydrate(<App />, root);
2554
- } else {
2555
- render(<App />, root);
2556
- }
2557
- `;
2558
- case "svelte":
2559
- return `import App from './App.svelte';
2560
- import './styles/global.css';
2561
-
2562
- const target = document.getElementById('root');
2563
-
2564
- if (!target) {
2565
- throw new Error('Root element not found');
2566
- }
2567
-
2568
- // Hydrate or mount
2569
- const app = new App({
2570
- target,
2571
- hydrate: target.innerHTML.trim() !== '',
2572
- });
2573
-
2574
- export default app;
2575
- `;
2576
- case "qwik":
2577
- return `import './styles/global.css';
2578
-
2579
- /**
2580
- * Qwik Client Entry
2581
- * Qwik uses resumability - no hydration needed!
2582
- * The framework automatically resumes where the server left off.
2583
- */
2584
- console.log('Qwik app resumed!');
2585
- `;
2586
- case "lit":
2587
- return `import './styles/global.css';
2588
- import './components/app-element.js';
2589
-
2590
- /**
2591
- * Lit Client Entry
2592
- * Web Components hydrate automatically via declarative shadow DOM
2593
- */
2594
- console.log('Lit Web Components ready!');
2595
- `;
2596
- case "htmx":
2597
- return `import './styles/global.css';
2598
- import 'htmx.org';
2599
-
2600
- /**
2601
- * HTMX Client Entry
2602
- * HTMX handles all interactivity via HTML attributes
2603
- * No JavaScript framework needed!
2604
- */
2605
- document.body.addEventListener('htmx:afterSwap', (event) => {
2606
- console.log('HTMX content swapped:', event.detail.target);
2607
- });
2608
-
2609
- console.log('HTMX ready!');
2610
- `;
2611
- default:
2612
- return `import './styles/global.css';
2613
-
2614
- // CSR only for vanilla
2615
- const root = document.getElementById('root');
2616
- if (root && !root.innerHTML.trim()) {
2617
- root.innerHTML = \`
2618
- <main class="container">
2619
- <h1>Welcome to Flight \u2708\uFE0F</h1>
2620
- <p>The agnostic full-stack framework.</p>
2621
- <p>Maximum flexibility. Zero lock-in.</p>
2622
- </main>
2623
- \`;
2624
- }
2625
- `;
2626
- }
2627
- }
2628
- function createServerEntry(ui, _typescript) {
2629
- switch (ui) {
2630
- case "react":
2631
- return `import { renderToString } from 'react-dom/server';
2632
- import App from './App';
2633
-
2634
- /**
2635
- * Server-side render function
2636
- * Called by Flight dev server for each request
2637
- */
2638
- export function render(url: string): string {
2639
- const html = renderToString(<App />);
2640
- return html;
2641
- }
2642
- `;
2643
- case "vue":
2644
- return `import { renderToString } from 'vue/server-renderer';
2645
- import { createSSRApp } from 'vue';
2646
- import App from './App.vue';
2647
-
2648
- /**
2649
- * Server-side render function
2650
- */
2651
- export async function render(url: string): Promise<string> {
2652
- const app = createSSRApp(App);
2653
- const html = await renderToString(app);
2654
- return html;
2655
- }
2656
- `;
2657
- case "solid":
2658
- return `import { renderToString } from 'solid-js/web';
2659
- import App from './App';
2660
-
2661
- /**
2662
- * Server-side render function
2663
- */
2664
- export function render(url: string): string {
2665
- const html = renderToString(() => <App />);
2666
- return html;
2667
- }
2668
- `;
2669
- case "preact":
2670
- return `import renderToString from 'preact-render-to-string';
2671
- import App from './App';
2672
-
2673
- /**
2674
- * Server-side render function
2675
- */
2676
- export function render(url: string): string {
2677
- const html = renderToString(<App />);
2678
- return html;
2679
- }
2680
- `;
2681
- case "svelte":
2682
- return `import { render } from 'svelte/server';
2683
- import App from './App.svelte';
2684
-
2685
- /**
2686
- * Server-side render function
2687
- * Uses Svelte 5 native SSR (no SvelteKit required)
2688
- */
2689
- export function render(url: string): string {
2690
- const { body, head } = render(App, {
2691
- props: { url }
2692
- });
2693
- return body;
2694
- }
2695
- `;
2696
- case "qwik":
2697
- return `import { renderToString } from '@builder.io/qwik/server';
2698
- import App from './App';
2699
-
2700
- /**
2701
- * Server-side render function
2702
- * Qwik: Resumable framework with O(1) loading
2703
- */
2704
- export async function render(url: string): Promise<string> {
2705
- const { html } = await renderToString(<App />, {
2706
- containerTagName: 'div',
2707
- });
2708
- return html;
2709
- }
2710
- `;
2711
- case "lit":
2712
- return `import { render } from '@lit-labs/ssr';
2713
- import { html } from 'lit';
2714
- import { collectResult } from '@lit-labs/ssr/lib/render-result.js';
2715
- import './components/app-element.js';
2716
-
2717
- /**
2718
- * Server-side render function
2719
- * Lit: Web Components SSR
2720
- */
2721
- export async function render(url: string): Promise<string> {
2722
- const result = render(html\`<app-element></app-element>\`);
2723
- return collectResult(result);
2724
- }
2725
- `;
2726
- case "htmx":
2727
- return `/**
2728
- * Server-side render function
2729
- * HTMX: HTML over the wire - no JavaScript needed
2730
- */
2731
- export function render(url: string): string {
2732
- return \`
2733
- <main class="container" hx-boost="true">
2734
- <div class="hero">
2735
- <h1>
2736
- <span class="flight-icon">*</span>
2737
- Welcome to <span class="gradient-text">Flight</span>
2738
- </h1>
2739
- <p class="tagline">The agnostic full-stack framework</p>
2740
- <p class="subtitle">Maximum flexibility. Zero lock-in.</p>
2741
-
2742
- <div class="features" hx-get="/api/features" hx-trigger="load" hx-swap="innerHTML">
2743
- <p>Loading features...</p>
2744
- </div>
2745
-
2746
- <div class="cta">
2747
- <a href="/docs" class="btn btn-primary" hx-boost="true">Get Started</a>
2748
- <a href="/api" class="btn btn-secondary" hx-boost="true">API Docs</a>
2749
- </div>
2750
- </div>
2751
- </main>
2752
- \`;
2753
- }
2754
- `;
2755
- default:
2756
- return `/**
2757
- * Server-side render function for vanilla JS
2758
- */
2759
- export function render(url: string): string {
2760
- return \`
2761
- <main class="container">
2762
- <h1>Welcome to Flight *</h1>
2763
- <p>The agnostic full-stack framework.</p>
2764
- <p>Maximum flexibility. Zero lock-in.</p>
2765
- </main>
2766
- \`;
2767
- }
2768
- `;
2769
- }
2770
- }
2771
- function createAppComponent(ui, _typescript) {
2772
- switch (ui) {
2773
- case "react":
2774
- case "solid":
2775
- case "preact":
2776
- return `export default function App() {
2777
- return (
2778
- <main className="container">
2779
- <div className="hero">
2780
- <h1>
2781
- <span className="flight-icon">*</span>
2782
- Welcome to <span className="gradient-text">Flight</span>
2783
- </h1>
2784
- <p className="tagline">The agnostic full-stack framework</p>
2785
- <p className="subtitle">Maximum flexibility. Zero lock-in.</p>
2786
-
2787
- <div className="features">
2788
- <div className="feature">
2789
- <span className="feature-icon">*</span>
2790
- <h3>Lightning Fast</h3>
2791
- <p>Powered by Vite for instant HMR</p>
2792
- </div>
2793
- <div className="feature">
2794
- <span className="feature-icon">*</span>
2795
- <h3>No Lock-in</h3>
2796
- <p>Deploy anywhere you want</p>
2797
- </div>
2798
- <div className="feature">
2799
- <span className="feature-icon">*</span>
2800
- <h3>Privacy First</h3>
2801
- <p>Zero telemetry, ever</p>
2802
- </div>
2803
- </div>
2804
-
2805
- <div className="cta">
2806
- <a href="https://github.com" className="btn btn-primary">Get Started</a>
2807
- <a href="https://github.com" className="btn btn-secondary">Documentation</a>
2808
- </div>
2809
- </div>
2810
- </main>
2811
- );
2812
- }
2813
- `;
2814
- case "vue":
2815
- return `<template>
2816
- <main class="container">
2817
- <div class="hero">
2818
- <h1>
2819
- <span class="flight-icon">*</span>
2820
- Welcome to <span class="gradient-text">Flight</span>
2821
- </h1>
2822
- <p class="tagline">The agnostic full-stack framework</p>
2823
- <p class="subtitle">Maximum flexibility. Zero lock-in.</p>
2824
-
2825
- <div class="features">
2826
- <div class="feature">
2827
- <span class="feature-icon">*</span>
2828
- <h3>Lightning Fast</h3>
2829
- <p>Powered by Vite for instant HMR</p>
2830
- </div>
2831
- <div class="feature">
2832
- <span class="feature-icon">*</span>
2833
- <h3>No Lock-in</h3>
2834
- <p>Deploy anywhere you want</p>
2835
- </div>
2836
- <div class="feature">
2837
- <span class="feature-icon">*</span>
2838
- <h3>Privacy First</h3>
2839
- <p>Zero telemetry, ever</p>
2840
- </div>
2841
- </div>
2842
-
2843
- <div class="cta">
2844
- <a href="https://github.com" class="btn btn-primary">Get Started</a>
2845
- <a href="https://github.com" class="btn btn-secondary">Documentation</a>
2846
- </div>
2847
- </div>
2848
- </main>
2849
- </template>
2850
-
2851
- <script setup>
2852
- // Vue component logic here
2853
- </script>
2854
- `;
2855
- case "svelte":
2856
- return `<script>
2857
- // Svelte component logic here
2858
- </script>
2859
-
2860
- <main class="container">
2861
- <div class="hero">
2862
- <h1>
2863
- <span class="flight-icon">*</span>
2864
- Welcome to <span class="gradient-text">Flight</span>
2865
- </h1>
2866
- <p class="tagline">The agnostic full-stack framework</p>
2867
- <p class="subtitle">Maximum flexibility. Zero lock-in.</p>
2868
-
2869
- <div class="features">
2870
- <div class="feature">
2871
- <span class="feature-icon">*</span>
2872
- <h3>Lightning Fast</h3>
2873
- <p>Powered by Vite for instant HMR</p>
2874
- </div>
2875
- <div class="feature">
2876
- <span class="feature-icon">*</span>
2877
- <h3>No Lock-in</h3>
2878
- <p>Deploy anywhere you want</p>
2879
- </div>
2880
- <div class="feature">
2881
- <span class="feature-icon">*</span>
2882
- <h3>Privacy First</h3>
2883
- <p>Zero telemetry, ever</p>
2884
- </div>
2885
- </div>
2886
-
2887
- <div class="cta">
2888
- <a href="https://github.com" class="btn btn-primary">Get Started</a>
2889
- <a href="https://github.com" class="btn btn-secondary">Documentation</a>
2890
- </div>
2891
- </div>
2892
- </main>
2893
- `;
2894
- default:
2895
- return `export function render() {
2896
- return \`
2897
- <main class="container">
2898
- <h1>Welcome to Flight *</h1>
2899
- <p>The agnostic full-stack framework.</p>
2900
- </main>
2901
- \`;
2902
- }
2903
- `;
2904
184
  }
2905
185
  }
2906
- function createGlobalStyles() {
2907
- return `/* Flight Framework - 2026 Modern CSS */
2908
-
2909
- :root {
2910
- /* Colors - Dark theme by default */
2911
- --color-bg: #0a0a0f;
2912
- --color-bg-secondary: #12121a;
2913
- --color-text: #f0f0f5;
2914
- --color-text-muted: #8888a0;
2915
- --color-primary: #6366f1;
2916
- --color-primary-light: #818cf8;
2917
- --color-secondary: #22d3ee;
2918
- --color-accent: #f472b6;
2919
- --color-border: #2a2a3a;
2920
-
2921
- /* Gradients */
2922
- --gradient-primary: linear-gradient(135deg, var(--color-primary) 0%, var(--color-secondary) 100%);
2923
- --gradient-text: linear-gradient(135deg, var(--color-primary-light) 0%, var(--color-secondary) 50%, var(--color-accent) 100%);
2924
-
2925
- /* Spacing */
2926
- --space-xs: 0.25rem;
2927
- --space-sm: 0.5rem;
2928
- --space-md: 1rem;
2929
- --space-lg: 2rem;
2930
- --space-xl: 4rem;
2931
-
2932
- /* Typography */
2933
- --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
2934
- --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
2935
-
2936
- /* Effects */
2937
- --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.3);
2938
- --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.4);
2939
- --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5);
2940
- --shadow-glow: 0 0 40px rgba(99, 102, 241, 0.3);
2941
-
2942
- /* Transitions */
2943
- --transition-fast: 150ms ease;
2944
- --transition-normal: 250ms ease;
2945
- --transition-slow: 400ms ease;
2946
-
2947
- /* Border radius */
2948
- --radius-sm: 0.375rem;
2949
- --radius-md: 0.75rem;
2950
- --radius-lg: 1rem;
2951
- --radius-full: 9999px;
2952
- }
2953
-
2954
- /* Reset */
2955
- *, *::before, *::after {
2956
- box-sizing: border-box;
2957
- margin: 0;
2958
- padding: 0;
2959
- }
2960
-
2961
- html {
2962
- font-size: 16px;
2963
- scroll-behavior: smooth;
2964
- -webkit-font-smoothing: antialiased;
2965
- -moz-osx-font-smoothing: grayscale;
2966
- }
2967
-
2968
- body {
2969
- font-family: var(--font-sans);
2970
- background: var(--color-bg);
2971
- color: var(--color-text);
2972
- line-height: 1.6;
2973
- min-height: 100vh;
2974
- }
2975
-
2976
- /* Typography */
2977
- h1, h2, h3, h4, h5, h6 {
2978
- line-height: 1.2;
2979
- font-weight: 700;
2980
- }
2981
-
2982
- h1 { font-size: clamp(2.5rem, 5vw, 4rem); }
2983
- h2 { font-size: clamp(1.75rem, 3vw, 2.5rem); }
2984
- h3 { font-size: clamp(1.25rem, 2vw, 1.5rem); }
2985
-
2986
- a {
2987
- color: var(--color-primary-light);
2988
- text-decoration: none;
2989
- transition: color var(--transition-fast);
2990
- }
2991
-
2992
- a:hover {
2993
- color: var(--color-secondary);
2994
- }
2995
-
2996
- /* Container */
2997
- .container {
2998
- width: 100%;
2999
- max-width: 1200px;
3000
- margin: 0 auto;
3001
- padding: var(--space-lg);
3002
- }
3003
-
3004
- /* Hero Section */
3005
- .hero {
3006
- display: flex;
3007
- flex-direction: column;
3008
- align-items: center;
3009
- justify-content: center;
3010
- min-height: 100vh;
3011
- text-align: center;
3012
- gap: var(--space-lg);
3013
- }
3014
-
3015
- .flight-icon {
3016
- display: inline-block;
3017
- font-size: 1.2em;
3018
- margin-right: var(--space-sm);
3019
- animation: float 3s ease-in-out infinite;
3020
- }
3021
-
3022
- @keyframes float {
3023
- 0%, 100% { transform: translateY(0) rotate(-5deg); }
3024
- 50% { transform: translateY(-10px) rotate(5deg); }
3025
- }
3026
-
3027
- .gradient-text {
3028
- background: var(--gradient-text);
3029
- -webkit-background-clip: text;
3030
- -webkit-text-fill-color: transparent;
3031
- background-clip: text;
3032
- }
3033
-
3034
- .tagline {
3035
- font-size: clamp(1.25rem, 2.5vw, 1.75rem);
3036
- color: var(--color-text);
3037
- font-weight: 500;
3038
- }
3039
-
3040
- .subtitle {
3041
- font-size: clamp(1rem, 2vw, 1.25rem);
3042
- color: var(--color-text-muted);
3043
- }
3044
-
3045
- /* Features Grid */
3046
- .features {
3047
- display: grid;
3048
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
3049
- gap: var(--space-lg);
3050
- width: 100%;
3051
- max-width: 900px;
3052
- margin-top: var(--space-xl);
3053
- }
3054
-
3055
- .feature {
3056
- background: var(--color-bg-secondary);
3057
- border: 1px solid var(--color-border);
3058
- border-radius: var(--radius-lg);
3059
- padding: var(--space-lg);
3060
- text-align: center;
3061
- transition: all var(--transition-normal);
3062
- }
3063
-
3064
- .feature:hover {
3065
- border-color: var(--color-primary);
3066
- box-shadow: var(--shadow-glow);
3067
- transform: translateY(-4px);
3068
- }
3069
-
3070
- .feature-icon {
3071
- font-size: 2.5rem;
3072
- display: block;
3073
- margin-bottom: var(--space-md);
3074
- }
3075
-
3076
- .feature h3 {
3077
- margin-bottom: var(--space-sm);
3078
- color: var(--color-text);
3079
- }
3080
-
3081
- .feature p {
3082
- color: var(--color-text-muted);
3083
- font-size: 0.95rem;
3084
- }
3085
-
3086
- /* Buttons */
3087
- .cta {
3088
- display: flex;
3089
- gap: var(--space-md);
3090
- margin-top: var(--space-xl);
3091
- flex-wrap: wrap;
3092
- justify-content: center;
3093
- }
3094
-
3095
- .btn {
3096
- display: inline-flex;
3097
- align-items: center;
3098
- justify-content: center;
3099
- padding: var(--space-md) var(--space-lg);
3100
- font-size: 1rem;
3101
- font-weight: 600;
3102
- border-radius: var(--radius-md);
3103
- border: none;
3104
- cursor: pointer;
3105
- transition: all var(--transition-fast);
3106
- text-decoration: none;
3107
- }
3108
-
3109
- .btn-primary {
3110
- background: var(--gradient-primary);
3111
- color: white;
3112
- box-shadow: var(--shadow-md);
3113
- }
3114
-
3115
- .btn-primary:hover {
3116
- transform: translateY(-2px);
3117
- box-shadow: var(--shadow-lg), var(--shadow-glow);
3118
- color: white;
3119
- }
3120
-
3121
- .btn-secondary {
3122
- background: transparent;
3123
- color: var(--color-text);
3124
- border: 1px solid var(--color-border);
3125
- }
3126
-
3127
- .btn-secondary:hover {
3128
- border-color: var(--color-primary);
3129
- color: var(--color-primary-light);
3130
- }
3131
-
3132
- /* Responsive */
3133
- @media (max-width: 768px) {
3134
- .container {
3135
- padding: var(--space-md);
3136
- }
3137
-
3138
- .hero {
3139
- padding: var(--space-lg) 0;
3140
- }
3141
-
3142
- .features {
3143
- grid-template-columns: 1fr;
3144
- }
3145
- }
3146
-
3147
- /* Dark mode is default, but support light mode */
3148
- @media (prefers-color-scheme: light) {
3149
- :root {
3150
- --color-bg: #fafafa;
3151
- --color-bg-secondary: #ffffff;
3152
- --color-text: #1a1a2e;
3153
- --color-text-muted: #64648a;
3154
- --color-border: #e0e0e8;
3155
- --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08);
3156
- --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.12);
3157
- --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.16);
3158
- --shadow-glow: 0 0 40px rgba(99, 102, 241, 0.15);
3159
- }
3160
- }
3161
- `;
3162
- }
3163
186
 
3164
187
  // src/commands/dev.ts
3165
- import { resolve as resolve2, join as join3 } from "path";
3166
- import { readFileSync, existsSync as existsSync2 } from "fs";
188
+ import { resolve as resolve2, join as join2 } from "path";
189
+ import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
3167
190
  import pc2 from "picocolors";
3168
-
3169
- // ../core/dist/config/index.js
3170
- init_chunk_WAGCTWGY();
3171
-
3172
- // src/commands/dev.ts
191
+ import { loadConfig } from "@flight-framework/core/config";
3173
192
  async function devCommand(options) {
3174
193
  const startTime = Date.now();
3175
194
  printLogo();
@@ -3181,18 +200,18 @@ async function devCommand(options) {
3181
200
  const host = options.host ?? config.dev.host;
3182
201
  const open = options.open ?? config.dev.open;
3183
202
  const ssrEnabled = options.ssr ?? config.rendering?.default === "ssr";
3184
- const entryServerPath = join3(root, "src", "entry-server.tsx");
203
+ const entryServerPath = join2(root, "src", "entry-server.tsx");
3185
204
  const hasSSREntry = existsSync2(entryServerPath);
3186
205
  const { createServer: createViteServer } = await import("vite");
3187
206
  let flightHttpAvailable = false;
3188
207
  let flightRouterAvailable = false;
3189
208
  try {
3190
- await Promise.resolve().then(() => (init_dist2(), dist_exports));
209
+ await import("@flight-framework/http");
3191
210
  flightHttpAvailable = true;
3192
211
  } catch {
3193
212
  }
3194
213
  try {
3195
- await Promise.resolve().then(() => (init_file_router(), file_router_exports));
214
+ await import("@flight-framework/core/file-router");
3196
215
  flightRouterAvailable = true;
3197
216
  } catch {
3198
217
  }
@@ -3208,7 +227,7 @@ async function devCommand(options) {
3208
227
  },
3209
228
  appType: ssrEnabled && hasSSREntry ? "custom" : "spa",
3210
229
  plugins: [
3211
- // Add Flight plugin when @flight/http is available
230
+ // Add Flight plugin when @flight-framework/http is available
3212
231
  flightHttpAvailable ? flightDevPlugin(root) : null
3213
232
  ].filter(Boolean)
3214
233
  });
@@ -3226,7 +245,7 @@ async function devCommand(options) {
3226
245
  ${host === true || host === "0.0.0.0" ? ` ${pc2.cyan("\u279C")} Network: ${pc2.cyan(`http://${getNetworkAddress()}:${port}/`)}` : ""}
3227
246
 
3228
247
  ${isSSR ? pc2.green("\u2713") : pc2.yellow("\u25CB")} SSR ${isSSR ? "enabled (streaming)" : "disabled (CSR mode)"}
3229
- ${flightHttpAvailable ? pc2.green("\u2713") : pc2.yellow("\u25CB")} @flight/http ${flightHttpAvailable ? "enabled" : "not installed"}
248
+ ${flightHttpAvailable ? pc2.green("\u2713") : pc2.yellow("\u25CB")} @flight-framework/http ${flightHttpAvailable ? "enabled" : "not installed"}
3230
249
  ${flightRouterAvailable ? pc2.green("\u2713") : pc2.yellow("\u25CB")} File-based routing ${flightRouterAvailable ? "enabled" : "not available"}
3231
250
 
3232
251
  ${pc2.dim("press")} ${pc2.bold("h")} ${pc2.dim("to show help")}
@@ -3234,8 +253,8 @@ async function devCommand(options) {
3234
253
  if (!isSSR) {
3235
254
  vite.bindCLIShortcuts({ print: true });
3236
255
  }
3237
- } catch (error2) {
3238
- console.error(pc2.red("\nFailed to start dev server:"), error2);
256
+ } catch (error) {
257
+ console.error(pc2.red("\nFailed to start dev server:"), error);
3239
258
  process.exit(1);
3240
259
  }
3241
260
  }
@@ -3243,9 +262,9 @@ async function startSSRServer(vite, root, port, host) {
3243
262
  const { createServer: createHttpServer } = await import("http");
3244
263
  let pageRouter = null;
3245
264
  try {
3246
- const { createFileRouter: createFileRouter2 } = await Promise.resolve().then(() => (init_file_router(), file_router_exports));
3247
- pageRouter = await createFileRouter2({
3248
- directory: join3(root, "src", "routes"),
265
+ const { createFileRouter } = await import("@flight-framework/core/file-router");
266
+ pageRouter = await createFileRouter({
267
+ directory: join2(root, "src", "routes"),
3249
268
  extensions: [".tsx", ".ts", ".jsx", ".js"]
3250
269
  });
3251
270
  console.log(pc2.green(` \u2713 Page router loaded: ${pageRouter.routes.filter((r) => r.type === "page").length} pages`));
@@ -3259,15 +278,15 @@ async function startSSRServer(vite, root, port, host) {
3259
278
  return;
3260
279
  }
3261
280
  try {
3262
- let template = readFileSync(
3263
- join3(root, "index.html"),
281
+ let template = readFileSync2(
282
+ join2(root, "index.html"),
3264
283
  "utf-8"
3265
284
  );
3266
285
  template = await vite.transformIndexHtml(url, template);
3267
286
  let appHtml = "";
3268
287
  if (pageRouter) {
3269
288
  const pageRoute = pageRouter.routes.find(
3270
- (r) => r.type === "page" && matchRoute(r.path, pathname)
289
+ (r) => r.type === "page" && matchPath(r.path, pathname)
3271
290
  );
3272
291
  if (pageRoute && pageRoute.component) {
3273
292
  const mod = await vite.ssrLoadModule(pageRoute.filePath.replace(root, ""));
@@ -3316,17 +335,17 @@ function flightDevPlugin(root) {
3316
335
  const url = req.url || "/";
3317
336
  if (url.startsWith("/__flight_action/")) {
3318
337
  try {
3319
- const { handleActionRequest: handleActionRequest2 } = await Promise.resolve().then(() => (init_dist3(), dist_exports2));
338
+ const { handleActionRequest } = await import("@flight-framework/core");
3320
339
  const webRequest = await nodeToWebRequest(req);
3321
- const response = await handleActionRequest2(webRequest);
340
+ const response = await handleActionRequest(webRequest);
3322
341
  res.statusCode = response.status;
3323
342
  response.headers.forEach((value, key) => {
3324
343
  res.setHeader(key, value);
3325
344
  });
3326
345
  const body = await response.text();
3327
346
  res.end(body);
3328
- } catch (error2) {
3329
- console.error("[Flight] Action error:", error2);
347
+ } catch (error) {
348
+ console.error("[Flight] Action error:", error);
3330
349
  res.statusCode = 500;
3331
350
  res.end(JSON.stringify({ error: "Internal server error" }));
3332
351
  }
@@ -3334,9 +353,9 @@ function flightDevPlugin(root) {
3334
353
  }
3335
354
  if (url.startsWith("/api/")) {
3336
355
  try {
3337
- const { createFileRouter: createFileRouter2 } = await Promise.resolve().then(() => (init_file_router(), file_router_exports));
3338
- const routesDir = join3(root, "src", "routes");
3339
- const router = await createFileRouter2({ directory: routesDir });
356
+ const { createFileRouter } = await import("@flight-framework/core/file-router");
357
+ const routesDir = join2(root, "src", "routes");
358
+ const router = await createFileRouter({ directory: routesDir });
3340
359
  const route = router.routes.find((r) => {
3341
360
  return matchPath(r.path, url);
3342
361
  });
@@ -3351,7 +370,7 @@ function flightDevPlugin(root) {
3351
370
  res.end(body);
3352
371
  return;
3353
372
  }
3354
- } catch (error2) {
373
+ } catch (error) {
3355
374
  }
3356
375
  }
3357
376
  next();
@@ -3414,13 +433,14 @@ function getNetworkAddress() {
3414
433
  // src/commands/build.ts
3415
434
  import { resolve as resolve3 } from "path";
3416
435
  import pc3 from "picocolors";
436
+ import { loadConfig as loadConfig2 } from "@flight-framework/core/config";
3417
437
  async function buildCommand(options) {
3418
438
  const startTime = Date.now();
3419
439
  printLogo();
3420
440
  console.log(pc3.cyan("\n[*] Building Flight project for production...\n"));
3421
441
  try {
3422
442
  const root = resolve3(process.cwd());
3423
- const config = await loadConfig(root);
443
+ const config = await loadConfig2(root);
3424
444
  const outDir = options.outDir ?? config.build.outDir;
3425
445
  const sourcemap = options.sourcemap ?? config.build.sourcemap;
3426
446
  const minify = options.minify ?? config.build.minify;
@@ -3479,8 +499,8 @@ ${pc3.dim("To deploy:")}
3479
499
  ${pc3.dim("\u2022")} Upload ${outDir}/ to your server
3480
500
  ${pc3.dim("\u2022")} Or use your configured adapter
3481
501
  `);
3482
- } catch (error2) {
3483
- console.error(pc3.red("\nBuild failed:"), error2);
502
+ } catch (error) {
503
+ console.error(pc3.red("\nBuild failed:"), error);
3484
504
  process.exit(1);
3485
505
  }
3486
506
  }
@@ -3488,12 +508,13 @@ ${pc3.dim("To deploy:")}
3488
508
  // src/commands/preview.ts
3489
509
  import { resolve as resolve4 } from "path";
3490
510
  import pc4 from "picocolors";
511
+ import { loadConfig as loadConfig3 } from "@flight-framework/core/config";
3491
512
  async function previewCommand(options) {
3492
513
  printLogo();
3493
514
  console.log(pc4.cyan("\n\u2708\uFE0F Starting Flight preview server...\n"));
3494
515
  try {
3495
516
  const root = resolve4(process.cwd());
3496
- const config = await loadConfig(root);
517
+ const config = await loadConfig3(root);
3497
518
  const port = options.port ? parseInt(options.port, 10) : config.dev.port + 1;
3498
519
  const host = options.host ?? config.dev.host;
3499
520
  const open = options.open ?? false;
@@ -3519,8 +540,8 @@ async function previewCommand(options) {
3519
540
  ${pc4.dim("For development, use")} ${pc4.bold("flight dev")}
3520
541
  `);
3521
542
  server.printUrls();
3522
- } catch (error2) {
3523
- console.error(pc4.red("\nFailed to start preview server:"), error2);
543
+ } catch (error) {
544
+ console.error(pc4.red("\nFailed to start preview server:"), error);
3524
545
  process.exit(1);
3525
546
  }
3526
547
  }
@@ -3554,8 +575,8 @@ function run() {
3554
575
  printLogo();
3555
576
  }
3556
577
  cli.runMatchedCommand();
3557
- } catch (error2) {
3558
- console.error(pc5.red("Error:"), error2 instanceof Error ? error2.message : error2);
578
+ } catch (error) {
579
+ console.error(pc5.red("Error:"), error instanceof Error ? error.message : error);
3559
580
  process.exit(1);
3560
581
  }
3561
582
  }