@flight-framework/cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js ADDED
@@ -0,0 +1,3565 @@
1
+ #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
+ }) : x)(function(x) {
7
+ if (typeof require !== "undefined") return require.apply(this, arguments);
8
+ throw Error('Dynamic require of "' + x + '" is not supported');
9
+ });
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
+
2097
+ // src/index.ts
2098
+ import { cac } from "cac";
2099
+ import pc5 from "picocolors";
2100
+
2101
+ // src/version.ts
2102
+ var VERSION = "0.0.1";
2103
+
2104
+ // src/commands/create.ts
2105
+ import { existsSync, mkdirSync, writeFileSync, readdirSync } from "fs";
2106
+ import { join, resolve } from "path";
2107
+ import { execSync } from "child_process";
2108
+ import pc from "picocolors";
2109
+ import prompts from "prompts";
2110
+ async function createCommand(name, options) {
2111
+ printLogo();
2112
+ console.log(pc.cyan("\n[*] Creating a new Flight project...\n"));
2113
+ let projectName = name;
2114
+ let uiFramework = options.ui;
2115
+ if (!projectName) {
2116
+ const response = await prompts({
2117
+ type: "text",
2118
+ name: "name",
2119
+ message: "Project name:",
2120
+ initial: "my-flight-app",
2121
+ validate: (value) => {
2122
+ if (!value) return "Project name is required";
2123
+ if (!/^[a-z0-9-_]+$/i.test(value)) return "Invalid project name";
2124
+ return true;
2125
+ }
2126
+ });
2127
+ projectName = response.name;
2128
+ }
2129
+ if (!projectName) {
2130
+ console.log(pc.red("Project creation cancelled."));
2131
+ return;
2132
+ }
2133
+ if (!uiFramework) {
2134
+ const response = await prompts({
2135
+ type: "select",
2136
+ name: "ui",
2137
+ 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
+ ],
2149
+ initial: 0
2150
+ });
2151
+ uiFramework = response.ui;
2152
+ }
2153
+ if (!uiFramework) {
2154
+ console.log(pc.red("Project creation cancelled."));
2155
+ return;
2156
+ }
2157
+ const projectPath = resolve(process.cwd(), projectName);
2158
+ if (existsSync(projectPath)) {
2159
+ const files = readdirSync(projectPath);
2160
+ if (files.length > 0) {
2161
+ const response = await prompts({
2162
+ type: "confirm",
2163
+ name: "overwrite",
2164
+ message: `Directory ${projectName} is not empty. Continue anyway?`,
2165
+ initial: false
2166
+ });
2167
+ if (!response.overwrite) {
2168
+ console.log(pc.red("Project creation cancelled."));
2169
+ return;
2170
+ }
2171
+ }
2172
+ }
2173
+ console.log(pc.dim(`
2174
+ Creating project in ${projectPath}...
2175
+ `));
2176
+ try {
2177
+ createProjectStructure(projectPath, {
2178
+ name: projectName,
2179
+ ui: uiFramework,
2180
+ typescript: options.ts
2181
+ });
2182
+ console.log(pc.green("\u2713") + " Project structure created");
2183
+ if (options.git) {
2184
+ try {
2185
+ execSync("git init", { cwd: projectPath, stdio: "ignore" });
2186
+ console.log(pc.green("\u2713") + " Git repository initialized");
2187
+ } catch {
2188
+ console.log(pc.yellow("[!]") + " Could not initialize git repository");
2189
+ }
2190
+ }
2191
+ if (options.install) {
2192
+ console.log(pc.dim("\nInstalling dependencies...\n"));
2193
+ try {
2194
+ const pm = detectPackageManager();
2195
+ execSync(`${pm} install`, { cwd: projectPath, stdio: "inherit" });
2196
+ console.log(pc.green("\n\u2713") + " Dependencies installed");
2197
+ } catch {
2198
+ console.log(pc.yellow("\n[!]") + " Could not install dependencies. Run `npm install` manually.");
2199
+ }
2200
+ }
2201
+ console.log(`
2202
+ ${pc.green("[OK] Project created successfully!")}
2203
+
2204
+ ${pc.cyan("Next steps:")}
2205
+
2206
+ ${pc.dim("$")} cd ${projectName}
2207
+ ${pc.dim("$")} ${options.install ? "" : "npm install && "}npm run dev
2208
+
2209
+ ${pc.dim("Your project is 100% yours:")}
2210
+ ${pc.dim("\u2022")} No telemetry
2211
+ ${pc.dim("\u2022")} No lock-in
2212
+ ${pc.dim("\u2022")} Deploy anywhere
2213
+
2214
+ ${pc.cyan("Happy flying!")}
2215
+ `);
2216
+ } catch (error2) {
2217
+ console.error(pc.red("Failed to create project:"), error2);
2218
+ process.exit(1);
2219
+ }
2220
+ }
2221
+ function detectPackageManager() {
2222
+ if (process.env.npm_config_user_agent?.includes("pnpm")) return "pnpm";
2223
+ if (process.env.npm_config_user_agent?.includes("yarn")) return "yarn";
2224
+ if (process.env.npm_config_user_agent?.includes("bun")) return "bun";
2225
+ return "npm";
2226
+ }
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
+ }
2262
+ };
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";
2270
+ }
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
+ }
2905
+ }
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
+
3164
+ // src/commands/dev.ts
3165
+ import { resolve as resolve2, join as join3 } from "path";
3166
+ import { readFileSync, existsSync as existsSync2 } from "fs";
3167
+ import pc2 from "picocolors";
3168
+
3169
+ // ../core/dist/config/index.js
3170
+ init_chunk_WAGCTWGY();
3171
+
3172
+ // src/commands/dev.ts
3173
+ async function devCommand(options) {
3174
+ const startTime = Date.now();
3175
+ printLogo();
3176
+ console.log(pc2.cyan("\n\u2708\uFE0F Starting Flight development server...\n"));
3177
+ try {
3178
+ const root = resolve2(process.cwd());
3179
+ const config = await loadConfig(root);
3180
+ const port = options.port ? parseInt(options.port, 10) : config.dev.port;
3181
+ const host = options.host ?? config.dev.host;
3182
+ const open = options.open ?? config.dev.open;
3183
+ const ssrEnabled = options.ssr ?? config.rendering?.default === "ssr";
3184
+ const entryServerPath = join3(root, "src", "entry-server.tsx");
3185
+ const hasSSREntry = existsSync2(entryServerPath);
3186
+ const { createServer: createViteServer } = await import("vite");
3187
+ let flightHttpAvailable = false;
3188
+ let flightRouterAvailable = false;
3189
+ try {
3190
+ await Promise.resolve().then(() => (init_dist2(), dist_exports));
3191
+ flightHttpAvailable = true;
3192
+ } catch {
3193
+ }
3194
+ try {
3195
+ await Promise.resolve().then(() => (init_file_router(), file_router_exports));
3196
+ flightRouterAvailable = true;
3197
+ } catch {
3198
+ }
3199
+ const vite = await createViteServer({
3200
+ root,
3201
+ mode: "development",
3202
+ server: {
3203
+ middlewareMode: ssrEnabled && hasSSREntry,
3204
+ port: ssrEnabled && hasSSREntry ? void 0 : port,
3205
+ host: host === true ? "0.0.0.0" : host,
3206
+ open: ssrEnabled && hasSSREntry ? false : open,
3207
+ https: options.https ? {} : void 0
3208
+ },
3209
+ appType: ssrEnabled && hasSSREntry ? "custom" : "spa",
3210
+ plugins: [
3211
+ // Add Flight plugin when @flight/http is available
3212
+ flightHttpAvailable ? flightDevPlugin(root) : null
3213
+ ].filter(Boolean)
3214
+ });
3215
+ if (ssrEnabled && hasSSREntry) {
3216
+ await startSSRServer(vite, root, port, host);
3217
+ } else {
3218
+ await vite.listen();
3219
+ }
3220
+ const elapsed = Date.now() - startTime;
3221
+ const isSSR = ssrEnabled && hasSSREntry;
3222
+ console.log(`
3223
+ ${pc2.green("\u2713")} Flight dev server ready in ${pc2.bold(elapsed + "ms")}
3224
+
3225
+ ${pc2.cyan("\u279C")} Local: ${pc2.cyan(`http://localhost:${port}/`)}
3226
+ ${host === true || host === "0.0.0.0" ? ` ${pc2.cyan("\u279C")} Network: ${pc2.cyan(`http://${getNetworkAddress()}:${port}/`)}` : ""}
3227
+
3228
+ ${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"}
3230
+ ${flightRouterAvailable ? pc2.green("\u2713") : pc2.yellow("\u25CB")} File-based routing ${flightRouterAvailable ? "enabled" : "not available"}
3231
+
3232
+ ${pc2.dim("press")} ${pc2.bold("h")} ${pc2.dim("to show help")}
3233
+ `);
3234
+ if (!isSSR) {
3235
+ vite.bindCLIShortcuts({ print: true });
3236
+ }
3237
+ } catch (error2) {
3238
+ console.error(pc2.red("\nFailed to start dev server:"), error2);
3239
+ process.exit(1);
3240
+ }
3241
+ }
3242
+ async function startSSRServer(vite, root, port, host) {
3243
+ const { createServer: createHttpServer } = await import("http");
3244
+ let pageRouter = null;
3245
+ 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"),
3249
+ extensions: [".tsx", ".ts", ".jsx", ".js"]
3250
+ });
3251
+ console.log(pc2.green(` \u2713 Page router loaded: ${pageRouter.routes.filter((r) => r.type === "page").length} pages`));
3252
+ } catch {
3253
+ }
3254
+ const server = createHttpServer(async (req, res) => {
3255
+ const url = req.url || "/";
3256
+ const pathname = url.split("?")[0];
3257
+ if (url.startsWith("/@") || url.startsWith("/node_modules") || url.startsWith("/src") && !url.includes("entry-server")) {
3258
+ vite.middlewares(req, res);
3259
+ return;
3260
+ }
3261
+ try {
3262
+ let template = readFileSync(
3263
+ join3(root, "index.html"),
3264
+ "utf-8"
3265
+ );
3266
+ template = await vite.transformIndexHtml(url, template);
3267
+ let appHtml = "";
3268
+ if (pageRouter) {
3269
+ const pageRoute = pageRouter.routes.find(
3270
+ (r) => r.type === "page" && matchRoute(r.path, pathname)
3271
+ );
3272
+ if (pageRoute && pageRoute.component) {
3273
+ const mod = await vite.ssrLoadModule(pageRoute.filePath.replace(root, ""));
3274
+ const Component = mod.default;
3275
+ const { render } = await vite.ssrLoadModule("/src/entry-server.tsx");
3276
+ if (typeof render === "function" && Component) {
3277
+ appHtml = await render(url, { Component });
3278
+ }
3279
+ }
3280
+ }
3281
+ if (!appHtml) {
3282
+ const { render } = await vite.ssrLoadModule("/src/entry-server.tsx");
3283
+ if (typeof render === "function") {
3284
+ appHtml = await render(url);
3285
+ }
3286
+ }
3287
+ if (appHtml) {
3288
+ const html = template.replace("<!--ssr-outlet-->", appHtml);
3289
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
3290
+ res.end(html);
3291
+ } else {
3292
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
3293
+ res.end(template);
3294
+ }
3295
+ } catch (e) {
3296
+ vite.ssrFixStacktrace(e);
3297
+ console.error(pc2.red("[SSR Error]"), e.stack);
3298
+ if (!res.headersSent) {
3299
+ res.writeHead(500, { "Content-Type": "text/plain" });
3300
+ res.end(`SSR Error: ${e.message}
3301
+
3302
+ ${e.stack}`);
3303
+ }
3304
+ }
3305
+ });
3306
+ const listenHost = host === true ? "0.0.0.0" : host || "localhost";
3307
+ server.listen(port, listenHost, () => {
3308
+ console.log(pc2.green(` \u2713 SSR server listening`));
3309
+ });
3310
+ }
3311
+ function flightDevPlugin(root) {
3312
+ return {
3313
+ name: "flight:dev",
3314
+ configureServer(server) {
3315
+ server.middlewares.use(async (req, res, next) => {
3316
+ const url = req.url || "/";
3317
+ if (url.startsWith("/__flight_action/")) {
3318
+ try {
3319
+ const { handleActionRequest: handleActionRequest2 } = await Promise.resolve().then(() => (init_dist3(), dist_exports2));
3320
+ const webRequest = await nodeToWebRequest(req);
3321
+ const response = await handleActionRequest2(webRequest);
3322
+ res.statusCode = response.status;
3323
+ response.headers.forEach((value, key) => {
3324
+ res.setHeader(key, value);
3325
+ });
3326
+ const body = await response.text();
3327
+ res.end(body);
3328
+ } catch (error2) {
3329
+ console.error("[Flight] Action error:", error2);
3330
+ res.statusCode = 500;
3331
+ res.end(JSON.stringify({ error: "Internal server error" }));
3332
+ }
3333
+ return;
3334
+ }
3335
+ if (url.startsWith("/api/")) {
3336
+ 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 });
3340
+ const route = router.routes.find((r) => {
3341
+ return matchPath(r.path, url);
3342
+ });
3343
+ if (route && route.handler) {
3344
+ const webRequest = await nodeToWebRequest(req);
3345
+ const response = await route.handler({ req: webRequest, params: {} });
3346
+ res.statusCode = response.status;
3347
+ response.headers.forEach((value, key) => {
3348
+ res.setHeader(key, value);
3349
+ });
3350
+ const body = await response.text();
3351
+ res.end(body);
3352
+ return;
3353
+ }
3354
+ } catch (error2) {
3355
+ }
3356
+ }
3357
+ next();
3358
+ });
3359
+ }
3360
+ };
3361
+ }
3362
+ async function nodeToWebRequest(req) {
3363
+ const host = req.headers.host || "localhost";
3364
+ const protocol = "http";
3365
+ const url = new URL(req.url || "/", `${protocol}://${host}`);
3366
+ let body = null;
3367
+ if (req.method !== "GET" && req.method !== "HEAD") {
3368
+ const chunks = [];
3369
+ for await (const chunk of req) {
3370
+ chunks.push(chunk);
3371
+ }
3372
+ body = Buffer.concat(chunks);
3373
+ }
3374
+ const headers = new Headers();
3375
+ for (const [key, value] of Object.entries(req.headers)) {
3376
+ if (value) {
3377
+ if (Array.isArray(value)) {
3378
+ for (const v of value) {
3379
+ headers.append(key, v);
3380
+ }
3381
+ } else {
3382
+ headers.set(key, value);
3383
+ }
3384
+ }
3385
+ }
3386
+ return new Request(url.toString(), {
3387
+ method: req.method || "GET",
3388
+ headers,
3389
+ body
3390
+ });
3391
+ }
3392
+ function matchPath(pattern, path) {
3393
+ const cleanPath = path.split("?")[0];
3394
+ const regexPattern = pattern.replace(/:\w+/g, "[^/]+").replace(/\*/g, ".*");
3395
+ const regex = new RegExp(`^${regexPattern}$`);
3396
+ return regex.test(cleanPath || "/");
3397
+ }
3398
+ function getNetworkAddress() {
3399
+ try {
3400
+ const { networkInterfaces } = __require("os");
3401
+ const nets = networkInterfaces();
3402
+ for (const name of Object.keys(nets)) {
3403
+ for (const net of nets[name]) {
3404
+ if (net.family === "IPv4" && !net.internal) {
3405
+ return net.address;
3406
+ }
3407
+ }
3408
+ }
3409
+ } catch {
3410
+ }
3411
+ return "0.0.0.0";
3412
+ }
3413
+
3414
+ // src/commands/build.ts
3415
+ import { resolve as resolve3 } from "path";
3416
+ import pc3 from "picocolors";
3417
+ async function buildCommand(options) {
3418
+ const startTime = Date.now();
3419
+ printLogo();
3420
+ console.log(pc3.cyan("\n[*] Building Flight project for production...\n"));
3421
+ try {
3422
+ const root = resolve3(process.cwd());
3423
+ const config = await loadConfig(root);
3424
+ const outDir = options.outDir ?? config.build.outDir;
3425
+ const sourcemap = options.sourcemap ?? config.build.sourcemap;
3426
+ const minify = options.minify ?? config.build.minify;
3427
+ const { build } = await import("vite");
3428
+ console.log(pc3.dim(`Output directory: ${outDir}`));
3429
+ console.log(pc3.dim(`Sourcemaps: ${sourcemap ? "enabled" : "disabled"}`));
3430
+ console.log(pc3.dim(`Minification: ${minify ? "enabled" : "disabled"}
3431
+ `));
3432
+ console.log(pc3.cyan("Building client..."));
3433
+ await build({
3434
+ root,
3435
+ mode: "production",
3436
+ build: {
3437
+ outDir: `${outDir}/client`,
3438
+ sourcemap,
3439
+ minify: minify ? "esbuild" : false,
3440
+ rollupOptions: {
3441
+ input: resolve3(root, "index.html")
3442
+ }
3443
+ }
3444
+ });
3445
+ console.log(pc3.green("\u2713") + " Client build complete");
3446
+ if (config.rendering.default !== "csr") {
3447
+ console.log(pc3.cyan("\nBuilding server..."));
3448
+ await build({
3449
+ root,
3450
+ mode: "production",
3451
+ build: {
3452
+ outDir: `${outDir}/server`,
3453
+ sourcemap,
3454
+ minify: minify ? "esbuild" : false,
3455
+ ssr: true,
3456
+ rollupOptions: {
3457
+ input: resolve3(root, config.build.srcDir, "entry-server.ts")
3458
+ }
3459
+ }
3460
+ });
3461
+ console.log(pc3.green("\u2713") + " Server build complete");
3462
+ }
3463
+ if (config.adapter) {
3464
+ console.log(pc3.cyan(`
3465
+ Running ${config.adapter.name} adapter...`));
3466
+ console.log(pc3.green("\u2713") + ` ${config.adapter.name} adapter complete`);
3467
+ }
3468
+ const elapsed = Date.now() - startTime;
3469
+ const elapsedSeconds = (elapsed / 1e3).toFixed(2);
3470
+ console.log(`
3471
+ ${pc3.green("[OK] Build complete!")} ${pc3.dim(`(${elapsedSeconds}s)`)}
3472
+
3473
+ ${pc3.cyan("Output:")} ${resolve3(root, outDir)}
3474
+
3475
+ ${pc3.dim("To preview the build:")}
3476
+ ${pc3.dim("$")} flight preview
3477
+
3478
+ ${pc3.dim("To deploy:")}
3479
+ ${pc3.dim("\u2022")} Upload ${outDir}/ to your server
3480
+ ${pc3.dim("\u2022")} Or use your configured adapter
3481
+ `);
3482
+ } catch (error2) {
3483
+ console.error(pc3.red("\nBuild failed:"), error2);
3484
+ process.exit(1);
3485
+ }
3486
+ }
3487
+
3488
+ // src/commands/preview.ts
3489
+ import { resolve as resolve4 } from "path";
3490
+ import pc4 from "picocolors";
3491
+ async function previewCommand(options) {
3492
+ printLogo();
3493
+ console.log(pc4.cyan("\n\u2708\uFE0F Starting Flight preview server...\n"));
3494
+ try {
3495
+ const root = resolve4(process.cwd());
3496
+ const config = await loadConfig(root);
3497
+ const port = options.port ? parseInt(options.port, 10) : config.dev.port + 1;
3498
+ const host = options.host ?? config.dev.host;
3499
+ const open = options.open ?? false;
3500
+ const { preview } = await import("vite");
3501
+ const server = await preview({
3502
+ root,
3503
+ preview: {
3504
+ port,
3505
+ host: host === true ? "0.0.0.0" : host,
3506
+ open
3507
+ },
3508
+ build: {
3509
+ outDir: config.build.outDir
3510
+ }
3511
+ });
3512
+ console.log(`
3513
+ ${pc4.green("\u2713")} Flight preview server ready
3514
+
3515
+ ${pc4.cyan("\u279C")} Local: ${pc4.cyan(`http://localhost:${port}/`)}
3516
+ ${host === true || host === "0.0.0.0" ? ` ${pc4.cyan("\u279C")} Network: ${pc4.cyan(`http://0.0.0.0:${port}/`)}` : ""}
3517
+
3518
+ ${pc4.dim("This is a preview of your production build.")}
3519
+ ${pc4.dim("For development, use")} ${pc4.bold("flight dev")}
3520
+ `);
3521
+ server.printUrls();
3522
+ } catch (error2) {
3523
+ console.error(pc4.red("\nFailed to start preview server:"), error2);
3524
+ process.exit(1);
3525
+ }
3526
+ }
3527
+
3528
+ // src/index.ts
3529
+ var cli = cac("flight");
3530
+ var LOGO = `
3531
+ ${pc5.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
3532
+ ${pc5.cyan(" \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D")}
3533
+ ${pc5.cyan(" \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
3534
+ ${pc5.cyan(" \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 ")}
3535
+ ${pc5.cyan(" \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 ")}
3536
+ ${pc5.cyan(" \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D ")}
3537
+
3538
+ ${pc5.dim("The Agnostic Full-Stack Framework")}
3539
+ ${pc5.dim("Maximum Flexibility. Zero Lock-in.")}
3540
+ `;
3541
+ function printLogo() {
3542
+ console.log(LOGO);
3543
+ }
3544
+ cli.version(VERSION);
3545
+ cli.help();
3546
+ cli.command("create [name]", "Create a new Flight project").option("-t, --template <template>", "Project template to use", { default: "basic" }).option("--ui <framework>", "UI framework (react, vue, svelte, solid, vanilla)").option("--ts", "Use TypeScript", { default: true }).option("--git", "Initialize git repository", { default: true }).option("--install", "Install dependencies", { default: true }).action(createCommand);
3547
+ cli.command("dev", "Start development server").option("-p, --port <port>", "Port to listen on").option("-h, --host <host>", "Host to bind to").option("--open", "Open browser on start").option("--https", "Enable HTTPS").option("--ssr", "Enable Server-Side Rendering").action(devCommand);
3548
+ cli.command("build", "Build for production").option("--outDir <dir>", "Output directory").option("--sourcemap", "Generate source maps").option("--minify", "Minify output", { default: true }).action(buildCommand);
3549
+ cli.command("preview", "Preview production build").option("-p, --port <port>", "Port to listen on").option("-h, --host <host>", "Host to bind to").option("--open", "Open browser on start").action(previewCommand);
3550
+ function run() {
3551
+ try {
3552
+ cli.parse(process.argv, { run: false });
3553
+ if (cli.options.help || process.argv.length <= 2) {
3554
+ printLogo();
3555
+ }
3556
+ cli.runMatchedCommand();
3557
+ } catch (error2) {
3558
+ console.error(pc5.red("Error:"), error2 instanceof Error ? error2.message : error2);
3559
+ process.exit(1);
3560
+ }
3561
+ }
3562
+
3563
+ // src/bin.ts
3564
+ run();
3565
+ //# sourceMappingURL=bin.js.map