gemi 0.2.1 → 0.3.2

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/app/App.d.ts CHANGED
@@ -15,8 +15,8 @@ interface RenderParams {
15
15
  serverManifest: Record<string, any>;
16
16
  }
17
17
  interface AppParams {
18
- viewRouter: new (app: App) => ViewRouter;
19
- apiRouter: new (app: App) => ApiRouter;
18
+ viewRouter: new () => ViewRouter;
19
+ apiRouter: new () => ApiRouter;
20
20
  plugins?: (new () => Plugin)[];
21
21
  middlewareAliases?: Record<string, new () => Middleware>;
22
22
  root: ComponentType;
@@ -44,16 +44,16 @@ export declare class App {
44
44
  kind: string;
45
45
  data?: undefined;
46
46
  headers?: undefined;
47
- status?: undefined;
48
47
  } | {
49
48
  kind: string;
50
- data: any;
51
- headers: any;
52
- status: any;
49
+ data: {};
50
+ headers: {
51
+ "Set-Cookie": string;
52
+ };
53
53
  } | {
54
54
  kind: string;
55
55
  data: {
56
- [x: string]: Record<string, any>;
56
+ [x: string]: any;
57
57
  pageData?: undefined;
58
58
  auth?: undefined;
59
59
  routeManifest?: undefined;
@@ -61,14 +61,14 @@ export declare class App {
61
61
  componentTree?: undefined;
62
62
  };
63
63
  meta: any[];
64
- headers: Record<string, any>;
64
+ headers: {};
65
65
  head?: undefined;
66
66
  status?: undefined;
67
67
  } | {
68
68
  kind: string;
69
69
  data: {
70
70
  pageData: {
71
- [x: string]: Record<string, any>;
71
+ [x: string]: any;
72
72
  };
73
73
  auth: {
74
74
  user: any;
@@ -80,11 +80,9 @@ export declare class App {
80
80
  currentPath: string;
81
81
  is404: boolean;
82
82
  };
83
- componentTree: (string[] | {
84
- [x: string]: ComponentTree;
85
- })[];
83
+ componentTree: ([string, [string, [string, [string, [string, [string, [string, [string, [string, [string, [string, any[]][]][]][]][]][]][]][]][]][]][]] | (string | any[])[])[];
86
84
  };
87
- head: Record<string, Record<string, any>[]>;
85
+ head: {};
88
86
  headers: {
89
87
  "Content-Type": string;
90
88
  "Cache-Control": string;
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../app/App.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EAGV,SAAS,EACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAsB,MAAM,oBAAoB,CAAC;AAKpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAM3C,OAAO,EAAE,aAAa,EAA2B,MAAM,OAAO,CAAC;AAE/D,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACrC;AAoCD,UAAU,SAAS;IACjB,UAAU,EAAE,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,CAAC;IACzC,SAAS,EAAE,KAAK,GAAG,EAAE,GAAG,KAAK,SAAS,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,EAAE,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU,CAAC,CAAC;IACzD,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,qBAAa,GAAG;IACd,OAAO,CAAC,cAAc,CAGf;IACP,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,aAAa,CAAgC;IAC9C,IAAI,SAAS;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,aAAa,CAAgB;IAC9B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU,CAAC,CAAM;IAC7D,UAAU,SAAK;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,IAAI,CAAgB;gBAEhB,MAAM,EAAE,SAAS;IAY7B,OAAO,CAAC,OAAO;IAqCR,SAAS;IAIT,gBAAgB;IAIvB,OAAO,CAAC,gBAAgB;YA6DV,eAAe;IAyDvB,aAAa,CAAC,GAAG,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuJ1B,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY;IAyGpD,OAAO,CAAC,sBAAsB,CAGtB;IACR,OAAO,CAAC,mBAAmB,CAEzB;IACF,OAAO,CAAC,oBAAoB,CAM1B;IAEF,SAAS;sBAdH,eAAe,WACV,MAAM,GAAG,MAAM;mBAES,eAAe;oBAI5C,eAAe,QACb,MAAM,UACJ,MAAM;MASd;CACH"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../app/App.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EAGV,SAAS,EACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAsB,MAAM,oBAAoB,CAAC;AAKpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAS3C,OAAO,EAAE,aAAa,EAA2B,MAAM,OAAO,CAAC;AAE/D,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACrC;AAED,UAAU,SAAS;IACjB,UAAU,EAAE,UAAU,UAAU,CAAC;IACjC,SAAS,EAAE,UAAU,SAAS,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,EAAE,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU,CAAC,CAAC;IACzD,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,qBAAa,GAAG;IACd,OAAO,CAAC,cAAc,CAGf;IACP,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,aAAa,CAAgC;IAC9C,IAAI,SAAS;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,aAAa,CAAgB;IAC9B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU,CAAC,CAAM;IAC7D,UAAU,SAAK;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,IAAI,CAAgB;gBAEhB,MAAM,EAAE,SAAS;IAU7B,OAAO,CAAC,OAAO;IAkCR,SAAS;IAIT,gBAAgB;IAIvB,OAAO,CAAC,gBAAgB;YA6DV,eAAe;IAsDvB,aAAa,CAAC,GAAG,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2J1B,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY;IA2GpD,OAAO,CAAC,sBAAsB,CAGtB;IACR,OAAO,CAAC,mBAAmB,CAEzB;IACF,OAAO,CAAC,oBAAoB,CAM1B;IAEF,SAAS;sBAdH,eAAe,WACV,MAAM,GAAG,MAAM;mBAES,eAAe;oBAI5C,eAAe,QACb,MAAM,UACJ,MAAM;MASd;CACH"}
@@ -0,0 +1,4 @@
1
+ import { ComponentTree } from "../client/types";
2
+ import { ViewChildren } from "../http/ViewRouter";
3
+ export declare function createComponentTree(routes: ViewChildren): ComponentTree;
4
+ //# sourceMappingURL=createComponentTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createComponentTree.d.ts","sourceRoot":"","sources":["../../app/createComponentTree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,CAoBvE"}
@@ -0,0 +1,6 @@
1
+ import { ViewChildren, ViewRouteExec } from "../http/ViewRouter";
2
+ export declare function createFlatViewRoutes(routes: ViewChildren): Record<string, {
3
+ exec: ViewRouteExec[];
4
+ middleware: (string | any)[];
5
+ }>;
6
+ //# sourceMappingURL=createFlatViewRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createFlatViewRoutes.d.ts","sourceRoot":"","sources":["../../app/createFlatViewRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEjE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY;UAG7C,aAAa,EAAE;gBAAc,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE;GA8CxD"}
@@ -0,0 +1,3 @@
1
+ import { ViewChildren } from "../http/ViewRouter";
2
+ export declare function createRouteManifest(routes: ViewChildren): Record<string, string[]>;
3
+ //# sourceMappingURL=createRouteManifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createRouteManifest.d.ts","sourceRoot":"","sources":["../../app/createRouteManifest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,4BAiCvD"}
package/dist/app/index.js CHANGED
@@ -1311,111 +1311,115 @@ class RequestBreakerError extends Error {
1311
1311
  import {AsyncLocalStorage} from "async_hooks";
1312
1312
  var requestContext = new AsyncLocalStorage;
1313
1313
 
1314
- // app/flattenViewRoutes.ts
1315
- function flattenViewRoutes(routes, app) {
1316
- const flatRoutes = {};
1317
- const routeManifest = {};
1314
+ // client/helpers/flattenComponentTree.ts
1315
+ function flattenComponentTree(componentTree) {
1316
+ let out = [];
1317
+ for (const [root, branches] of componentTree) {
1318
+ out.push(root, ...flattenComponentTree(branches).flat());
1319
+ }
1320
+ return Array.from(new Set(out));
1321
+ }
1322
+
1323
+ // app/createComponentTree.ts
1324
+ function createComponentTree(routes) {
1318
1325
  const componentTree = [];
1319
- for (const [rootPath, viewConfigOrViewRouter] of Object.entries(routes)) {
1320
- let children;
1321
- let rootHandler = async () => ({});
1322
- let rootMiddleware = [];
1323
- let layoutViewPath = null;
1324
- if ("prepare" in viewConfigOrViewRouter) {
1325
- const result2 = viewConfigOrViewRouter.prepare();
1326
- children = result2.children;
1327
- rootHandler = result2.exec;
1328
- flatRoutes[rootPath] = {
1329
- exec: [rootHandler],
1330
- middleware: result2.middlewares
1331
- };
1332
- if (Object.keys(children).length > 0) {
1333
- layoutViewPath = result2.viewPath;
1326
+ for (const [_2, routeHandler] of Object.entries(routes)) {
1327
+ if ("prepare" in routeHandler) {
1328
+ const { viewPath, children } = routeHandler.prepare();
1329
+ if (Object.entries(children).length > 0) {
1330
+ const branch = createComponentTree(children);
1331
+ componentTree.push([viewPath, branch]);
1334
1332
  } else {
1335
- routeManifest[rootPath] = [result2.viewPath];
1336
- componentTree.push([result2.viewPath]);
1333
+ componentTree.push([viewPath, []]);
1337
1334
  }
1338
1335
  } else {
1339
- const router = new viewConfigOrViewRouter(app);
1340
- const middlewares = router.middlewares.map((alias) => {
1341
- if (app.middlewareAliases?.[alias]) {
1342
- const middleware = new app.middlewareAliases[alias];
1343
- return middleware.run;
1344
- }
1345
- }).filter(Boolean);
1346
- rootMiddleware.push(router.middleware, ...middlewares);
1347
- children = router.routes;
1336
+ const router = new routeHandler;
1337
+ const branch = createComponentTree(router.routes);
1338
+ componentTree.push(...branch);
1348
1339
  }
1349
- const result = flattenViewRoutes(children, app);
1350
- if (layoutViewPath) {
1351
- componentTree.push({ [layoutViewPath]: result.componentTree });
1352
- } else {
1353
- componentTree.push(...result.componentTree);
1354
- }
1355
- for (const [path, handlers] of Object.entries(result.flatRoutes)) {
1356
- const subPath = path === "/" ? "" : path;
1357
- const _rootPath = rootPath === "/" ? "" : rootPath;
1358
- const finalPath = `${_rootPath}${subPath}` === "" ? "/" : `${_rootPath}${subPath}`;
1359
- flatRoutes[finalPath] = {
1360
- exec: [rootHandler, ...handlers.exec],
1361
- middleware: [...rootMiddleware, ...handlers.middleware]
1362
- };
1363
- if (layoutViewPath) {
1364
- routeManifest[finalPath] = [
1365
- layoutViewPath,
1366
- ...result.routeManifest[path] ?? []
1367
- ];
1340
+ }
1341
+ return componentTree;
1342
+ }
1343
+
1344
+ // app/createFlatViewRoutes.ts
1345
+ function createFlatViewRoutes(routes) {
1346
+ const flatRoutes = {};
1347
+ for (const [routePath, viewConfigOrViewRouter] of Object.entries(routes)) {
1348
+ if ("prepare" in viewConfigOrViewRouter) {
1349
+ const route = viewConfigOrViewRouter.prepare();
1350
+ if (Object.entries(route.children).length > 0) {
1351
+ const result = createFlatViewRoutes(route.children);
1352
+ if (route.kind === "view") {
1353
+ flatRoutes[routePath] = {
1354
+ exec: [route.exec],
1355
+ middleware: route.middlewares
1356
+ };
1357
+ }
1358
+ for (const [path, { exec, middleware }] of Object.entries(result)) {
1359
+ const key = routePath === "/" ? path : `${routePath}${path}`;
1360
+ const _key = path === "/" && routePath !== "/" ? routePath : key;
1361
+ flatRoutes[_key] = {
1362
+ exec,
1363
+ middleware: [...route.middlewares, ...middleware]
1364
+ };
1365
+ }
1368
1366
  } else {
1369
- routeManifest[finalPath] = [...result.routeManifest[path] ?? []];
1367
+ flatRoutes[routePath] = {
1368
+ exec: [route.exec],
1369
+ middleware: route.middlewares
1370
+ };
1371
+ }
1372
+ } else {
1373
+ const router = new viewConfigOrViewRouter;
1374
+ const result = createFlatViewRoutes(router.routes);
1375
+ for (const [path, { exec, middleware }] of Object.entries(result)) {
1376
+ const key = routePath === "/" ? path : `${routePath}${path}`;
1377
+ const _key = path === "/" && routePath !== "/" ? routePath : key;
1378
+ flatRoutes[_key] = {
1379
+ exec,
1380
+ middleware: [...router.middlewares, ...middleware]
1381
+ };
1370
1382
  }
1371
1383
  }
1372
1384
  }
1373
- return {
1374
- flatRoutes,
1375
- routeManifest,
1376
- componentTree
1377
- };
1385
+ return flatRoutes;
1378
1386
  }
1379
1387
 
1380
- // client/helpers/flattenComponentTree.ts
1381
- function flattenComponentTree(componentTree) {
1382
- const out = [];
1383
- for (const section of componentTree.flat()) {
1384
- if (typeof section === "string") {
1385
- out.push(section);
1388
+ // app/createRouteManifest.ts
1389
+ function createRouteManifest(routes) {
1390
+ const routeManifest = {};
1391
+ for (const [routePath, routeHandler] of Object.entries(routes)) {
1392
+ if ("prepare" in routeHandler) {
1393
+ const { viewPath, children, kind } = routeHandler.prepare();
1394
+ if (kind === "view") {
1395
+ routeManifest[routePath] = [viewPath];
1396
+ }
1397
+ if (Object.entries(children).length > 0) {
1398
+ const manifest = createRouteManifest(children);
1399
+ for (const [path, viewPaths] of Object.entries(manifest)) {
1400
+ const key = routePath === "/" ? path : `${routePath}${path}`;
1401
+ const _key = path === "/" && routePath !== "/" ? routePath : key;
1402
+ routeManifest[_key] = [viewPath, ...viewPaths];
1403
+ }
1404
+ } else {
1405
+ routeManifest[routePath] = [viewPath];
1406
+ }
1386
1407
  } else {
1387
- for (const [key, value] of Object.entries(section)) {
1388
- out.push(key);
1389
- out.push(...flattenComponentTree(value));
1408
+ const router = new routeHandler;
1409
+ const manifest = createRouteManifest(router.routes);
1410
+ for (const [path, viewPaths] of Object.entries(manifest)) {
1411
+ const key = routePath === "/" ? path : `${routePath}${path}`;
1412
+ const _key = path === "/" && routePath !== "/" ? routePath : key;
1413
+ routeManifest[_key] = viewPaths;
1390
1414
  }
1391
1415
  }
1392
1416
  }
1393
- return out;
1417
+ return routeManifest;
1394
1418
  }
1395
1419
 
1396
1420
  // app/App.ts
1397
1421
  import {renderToReadableStream} from "react-dom/server.browser";
1398
1422
  import {createElement, Fragment} from "react";
1399
- var prepareViewData = function(result) {
1400
- return result.reduce((acc, next) => {
1401
- return {
1402
- pageData: {
1403
- ...acc.pageData,
1404
- ...next.data
1405
- },
1406
- headers: {
1407
- ...acc.headers,
1408
- ...next.headers
1409
- },
1410
- head: {
1411
- ...acc.head,
1412
- title: next?.head?.title ?? acc.head?.title ?? "Gemi App",
1413
- meta: [...acc.head?.meta ?? [], ...next?.head?.meta ?? []],
1414
- link: [...acc.head?.link ?? [], ...next?.head?.link ?? []]
1415
- }
1416
- };
1417
- }, { pageData: {}, headers: {}, head: {} });
1418
- };
1419
1423
 
1420
1424
  class App {
1421
1425
  flatViewRoutes = {};
@@ -1431,13 +1435,11 @@ class App {
1431
1435
  viewRouter;
1432
1436
  Root;
1433
1437
  constructor(params) {
1434
- console.log("[App] initialized");
1435
1438
  this.params = params;
1436
1439
  this.apiRouter = params.apiRouter;
1437
1440
  this.viewRouter = params.viewRouter;
1438
1441
  this.Root = params.root;
1439
1442
  this.prepare();
1440
- console.log("[App] routes are prepared");
1441
1443
  this.appId = generateETag(Date.now());
1442
1444
  }
1443
1445
  prepare() {
@@ -1464,10 +1466,9 @@ class App {
1464
1466
  };
1465
1467
  }
1466
1468
  }
1467
- const { flatRoutes, routeManifest, componentTree } = flattenViewRoutes(viewRouters, this);
1468
- this.componentTree = componentTree;
1469
- this.routeManifest = routeManifest;
1470
- this.flatViewRoutes = flatRoutes;
1469
+ this.flatViewRoutes = createFlatViewRoutes(viewRouters);
1470
+ this.componentTree = createComponentTree(viewRouters);
1471
+ this.routeManifest = createRouteManifest(viewRouters);
1471
1472
  this.flatApiRoutes = this.flattenApiRoutes(apiRouters);
1472
1473
  }
1473
1474
  printName() {
@@ -1544,7 +1545,12 @@ class App {
1544
1545
  middlewares = handler.middleware;
1545
1546
  }
1546
1547
  }
1547
- const reqWithMiddlewares = middlewares.reduce((acc, middleware) => {
1548
+ const reqWithMiddlewares = middlewares.map((middleware) => {
1549
+ if (typeof middleware === "string") {
1550
+ return new this.middlewareAliases[middleware]().run;
1551
+ }
1552
+ return middleware;
1553
+ }).reduce((acc, middleware) => {
1548
1554
  return async (req2, ctx) => {
1549
1555
  return {
1550
1556
  ...await acc(req2, ctx),
@@ -1553,21 +1559,12 @@ class App {
1553
1559
  };
1554
1560
  }, (_req, _ctx) => Promise.resolve({}));
1555
1561
  const reqCtx = new Map;
1556
- const result = await requestContext.run(reqCtx, async () => {
1562
+ const data = await requestContext.run(reqCtx, async () => {
1557
1563
  await reqWithMiddlewares(req, reqCtx);
1558
1564
  return await Promise.all(handlers.map((fn) => fn(req, params, this)));
1559
1565
  });
1560
- let is404 = false;
1561
- for (const res of result) {
1562
- const [data] = Object.values(res.data ?? {});
1563
- if (data?.status === 404) {
1564
- is404 = true;
1565
- break;
1566
- }
1567
- }
1568
1566
  return {
1569
- is404,
1570
- result,
1567
+ data,
1571
1568
  currentPathName,
1572
1569
  params,
1573
1570
  user: reqCtx.get("user") ?? null
@@ -1602,11 +1599,12 @@ class App {
1602
1599
  ...err.payload.api
1603
1600
  };
1604
1601
  }
1602
+ throw err;
1605
1603
  }
1606
1604
  if (exec) {
1607
- let result = {};
1605
+ let data = {};
1608
1606
  try {
1609
- result = await exec(req, params, this);
1607
+ data = await exec(req, params, this);
1610
1608
  } catch (err) {
1611
1609
  if (err instanceof RequestBreakerError) {
1612
1610
  return {
@@ -1614,18 +1612,16 @@ class App {
1614
1612
  ...err.payload.api
1615
1613
  };
1616
1614
  }
1615
+ throw err;
1617
1616
  }
1618
- const { data, cookies = {}, headers, status } = result;
1619
1617
  return {
1620
1618
  kind: "api",
1621
1619
  data,
1622
1620
  headers: {
1623
- ...headers,
1624
- "Set-Cookie": Object.entries(cookies).map(([name, config]) => {
1621
+ "Set-Cookie": Object.entries({}).map(([name, config]) => {
1625
1622
  return `${name}=${config.value}; HttpOnly; SameSite=Strict; Path=/; Max-Age=${config.maxAge}`;
1626
1623
  }).join(", ")
1627
- },
1628
- status
1624
+ }
1629
1625
  };
1630
1626
  }
1631
1627
  });
@@ -1654,16 +1650,21 @@ class App {
1654
1650
  headers: {}
1655
1651
  };
1656
1652
  }
1657
- const { result, params, currentPathName, is404, user } = pageData;
1658
- const data = prepareViewData(result);
1653
+ const { data, params, currentPathName, user } = pageData;
1654
+ const viewData = data.reduce((acc, data2) => {
1655
+ return {
1656
+ ...acc,
1657
+ ...data2
1658
+ };
1659
+ }, {});
1659
1660
  if (url.searchParams.get("json")) {
1660
1661
  return {
1661
1662
  kind: "viewData",
1662
1663
  data: {
1663
- [url.pathname]: data.pageData
1664
+ [url.pathname]: viewData
1664
1665
  },
1665
1666
  meta: [],
1666
- headers: data.headers
1667
+ headers: {}
1667
1668
  };
1668
1669
  }
1669
1670
  let cookieHeaders = {};
@@ -1677,7 +1678,7 @@ class App {
1677
1678
  kind: "view",
1678
1679
  data: {
1679
1680
  pageData: {
1680
- [url.pathname]: data.pageData
1681
+ [url.pathname]: viewData
1681
1682
  },
1682
1683
  auth: { user },
1683
1684
  routeManifest: this.routeManifest,
@@ -1685,19 +1686,18 @@ class App {
1685
1686
  pathname: currentPathName,
1686
1687
  params,
1687
1688
  currentPath: url.pathname,
1688
- is404
1689
+ is404: false
1689
1690
  },
1690
- componentTree: [["404"], ...this.componentTree]
1691
+ componentTree: [["404", []], ...this.componentTree]
1691
1692
  },
1692
- head: data.head,
1693
+ head: {},
1693
1694
  headers: {
1694
- ...data.headers,
1695
1695
  "Content-Type": "text/html",
1696
1696
  "Cache-Control": user ? "private, no-cache, no-store, max-age=0, must-revalidate" : "public, max-age=864000, must-revalidate",
1697
1697
  ETag: this.appId,
1698
1698
  ...cookieHeaders
1699
1699
  },
1700
- status: is404 ? 404 : 200
1700
+ status: 200
1701
1701
  };
1702
1702
  }
1703
1703
  }
@@ -1737,7 +1737,10 @@ class App {
1737
1737
  let appDir = null;
1738
1738
  const template = (viewName, path) => `"${viewName}": () => import("${path}")`;
1739
1739
  const templates = [];
1740
- for (const fileName of flattenComponentTree(this.componentTree)) {
1740
+ for (const fileName of [
1741
+ "404",
1742
+ ...flattenComponentTree(this.componentTree)
1743
+ ]) {
1741
1744
  if (!manifest) {
1742
1745
  appDir = `${process.env.APP_DIR}`;
1743
1746
  const mod = await import(`${appDir}/views/${fileName}.tsx`);
@@ -1758,7 +1761,6 @@ class App {
1758
1761
  children: [
1759
1762
  styles,
1760
1763
  createElement(this.Root, {
1761
- head,
1762
1764
  data,
1763
1765
  viewImportMap
1764
1766
  })
@@ -1776,9 +1778,8 @@ class App {
1776
1778
  });
1777
1779
  }
1778
1780
  if (result.kind === "api") {
1779
- const { data, headers, status } = result;
1781
+ const { data, headers } = result;
1780
1782
  return new Response(JSON.stringify(data), {
1781
- status,
1782
1783
  headers: {
1783
1784
  "Content-Type": "application/json",
1784
1785
  ...headers
package/dist/bin/gemi CHANGED
Binary file
@@ -1,4 +1,6 @@
1
+ import { type ComponentType } from "react";
1
2
  export declare const ClientRouter: (props: {
2
3
  viewImportMap?: Record<string, any>;
4
+ RootLayout: ComponentType<any>;
3
5
  }) => import("react/jsx-runtime").JSX.Element;
4
6
  //# sourceMappingURL=ClientRouter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClientRouter.d.ts","sourceRoot":"","sources":["../../client/ClientRouter.tsx"],"names":[],"mappings":"AA2HA,eAAO,MAAM,YAAY,UAAW;IAClC,aAAa,CAAC,EAAE,OAAO,MAAM,EAAE,GAAG,CAAC,CAAC;CACrC,4CAwBA,CAAC"}
1
+ {"version":3,"file":"ClientRouter.d.ts","sourceRoot":"","sources":["../../client/ClientRouter.tsx"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAkFf,eAAO,MAAM,YAAY,UAAW;IAClC,aAAa,CAAC,EAAE,OAAO,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,UAAU,EAAE,cAAc,GAAG,CAAC,CAAC;CAChC,4CA2BA,CAAC"}
@@ -22,6 +22,7 @@ interface ClientRouterProviderProps {
22
22
  export declare const ClientRouterProvider: (props: PropsWithChildren<ClientRouterProviderProps>) => import("react/jsx-runtime").JSX.Element;
23
23
  export declare function useLocation(): Location;
24
24
  export declare function useParams(): Record<string, string>;
25
+ export declare function useViewData(): void;
25
26
  export declare function useRouter(): {
26
27
  push: (to: To, state?: any) => Promise<void>;
27
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ClientRouterContext.d.ts","sourceRoot":"","sources":["../../client/ClientRouterContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,EAAE,EACP,KAAK,QAAQ,EAEd,MAAM,SAAS,CAAC;AACjB,OAAO,EAOL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,UAAU,wBAAwB;IAChC,kBAAkB,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACxD,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,mBAAmB,mDAE/B,CAAC;AAEF,UAAU,yBAAyB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,oBAAoB,UACxB,kBAAkB,yBAAyB,CAAC,4CA2GpD,CAAC;AAUF,wBAAgB,WAAW,aAU1B;AAED,wBAAgB,SAAS,2BAGxB;AAED,wBAAgB,SAAS;eAGJ,EAAE,UAAU,GAAG;EAsBnC;AAED,eAAO,MAAM,IAAI,UACR,KAAK,eAAe,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,EAAE,CAAA;CAAE,4CA0BxD,CAAC"}
1
+ {"version":3,"file":"ClientRouterContext.d.ts","sourceRoot":"","sources":["../../client/ClientRouterContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,EAAE,EACP,KAAK,QAAQ,EAEd,MAAM,SAAS,CAAC;AACjB,OAAO,EAOL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,UAAU,wBAAwB;IAChC,kBAAkB,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACxD,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,mBAAmB,mDAE/B,CAAC;AAEF,UAAU,yBAAyB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,oBAAoB,UACxB,kBAAkB,yBAAyB,CAAC,4CA2GpD,CAAC;AAUF,wBAAgB,WAAW,aAU1B;AAED,wBAAgB,SAAS,2BAGxB;AAED,wBAAgB,WAAW,SAAK;AAEhC,wBAAgB,SAAS;eAGJ,EAAE,UAAU,GAAG;EAsBnC;AAED,eAAO,MAAM,IAAI,UACR,KAAK,eAAe,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,EAAE,CAAA;CAAE,4CA0BxD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"createRoot.d.ts","sourceRoot":"","sources":["../../client/createRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAK3C,wBAAgB,UAAU,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,WACxC,GAAG,6CAOnB"}
1
+ {"version":3,"file":"createRoot.d.ts","sourceRoot":"","sources":["../../client/createRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAK3C,wBAAgB,UAAU,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,WACxC,GAAG,6CAQnB"}
@@ -1,3 +1,3 @@
1
1
  import type { ComponentTree } from "../types";
2
- export declare function flattenComponentTree(componentTree: ComponentTree): any[];
2
+ export declare function flattenComponentTree(componentTree: ComponentTree): string[];
3
3
  //# sourceMappingURL=flattenComponentTree.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"flattenComponentTree.d.ts","sourceRoot":"","sources":["../../../client/helpers/flattenComponentTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,aAAa,SAahE"}
1
+ {"version":3,"file":"flattenComponentTree.d.ts","sourceRoot":"","sources":["../../../client/helpers/flattenComponentTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,aAAa,GAAG,MAAM,EAAE,CAM3E"}
@@ -573,7 +573,7 @@ const ClientRouterProvider = (props) => {
573
573
  params
574
574
  } = props;
575
575
  const [parameters, setParameters] = useState(params);
576
- const pageDataRef = useRef(pageData);
576
+ const pageDataRef = useRef(structuredClone(pageData));
577
577
  const scrollHistoryRef = useRef(/* @__PURE__ */ new Map());
578
578
  const initalViewEntries = is404 ? ["404"] : routeManifest[pathname] ?? ["404"];
579
579
  const viewEntriesSubject = useRef(new Subject(initalViewEntries));
@@ -29364,18 +29364,11 @@ if (process.env.NODE_ENV === "production") {
29364
29364
  }
29365
29365
  var clientExports = client.exports;
29366
29366
  function flattenComponentTree(componentTree) {
29367
- const out = [];
29368
- for (const section of componentTree.flat()) {
29369
- if (typeof section === "string") {
29370
- out.push(section);
29371
- } else {
29372
- for (const [key, value] of Object.entries(section)) {
29373
- out.push(key);
29374
- out.push(...flattenComponentTree(value));
29375
- }
29376
- }
29367
+ let out = [];
29368
+ for (const [root, branches] of componentTree) {
29369
+ out.push(root, ...flattenComponentTree(branches).flat());
29377
29370
  }
29378
- return out;
29371
+ return Array.from(new Set(out));
29379
29372
  }
29380
29373
  let viewImportMap = null;
29381
29374
  if (typeof window !== "undefined") {
@@ -29405,37 +29398,24 @@ const Route = (props) => {
29405
29398
  });
29406
29399
  }, []);
29407
29400
  if (!render) return null;
29408
- if (viewImportMap2) {
29409
- const Component = viewImportMap2[componentPath];
29401
+ const Component = viewImportMap2[componentPath];
29402
+ if (Component) {
29410
29403
  return /* @__PURE__ */ jsx(Component, { ...data, children: props.children });
29411
29404
  }
29412
29405
  return /* @__PURE__ */ jsx("div", { children: "Not found" });
29413
29406
  };
29414
29407
  const Routes = (props) => {
29415
29408
  const { componentTree } = props;
29416
- return /* @__PURE__ */ jsx(Suspense, { children: componentTree.map((node, i) => {
29417
- if (typeof node === "undefined") {
29418
- return null;
29419
- }
29420
- if (typeof node === "string") {
29421
- return /* @__PURE__ */ jsx(Route, { componentPath: node }, node);
29409
+ return /* @__PURE__ */ jsx(Suspense, { children: componentTree.map((node) => {
29410
+ const [path, subtree] = node;
29411
+ if (subtree.length > 0) {
29412
+ return /* @__PURE__ */ jsx(Route, { componentPath: path, children: /* @__PURE__ */ jsx(Routes, { componentTree: subtree }) }, path);
29422
29413
  }
29423
- if (Array.isArray(node)) {
29424
- const [path, subtree2] = node;
29425
- if (subtree2) {
29426
- return /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(Route, { componentPath: path, children: /* @__PURE__ */ jsx(Routes, { componentTree: subtree2 }) }, i) }, path);
29427
- } else {
29428
- return /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(Route, { componentPath: path }, i) }, path);
29429
- }
29430
- }
29431
- const [[first, subtree]] = Object.entries(node);
29432
- if (subtree) {
29433
- return /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(Route, { componentPath: String(first), children: /* @__PURE__ */ jsx(Routes, { componentTree: subtree }) }, i) }, first);
29434
- }
29435
- return /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(Route, { componentPath: String(first) }, i) }, first);
29414
+ return /* @__PURE__ */ jsx(Route, { componentPath: path }, path);
29436
29415
  }) });
29437
29416
  };
29438
29417
  const ClientRouter = (props) => {
29418
+ const { RootLayout } = props;
29439
29419
  const { routeManifest, router, componentTree, pageData, auth } = useContext(ServerDataContext);
29440
29420
  return /* @__PURE__ */ jsx(
29441
29421
  ClientRouterProvider,
@@ -29452,7 +29432,7 @@ const ClientRouter = (props) => {
29452
29432
  value: {
29453
29433
  viewImportMap: props.viewImportMap ?? viewImportMap
29454
29434
  },
29455
- children: /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(Routes, { componentTree }) })
29435
+ children: /* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(RootLayout, { children: /* @__PURE__ */ jsx(Routes, { componentTree }) }) })
29456
29436
  }
29457
29437
  )
29458
29438
  }
@@ -29460,12 +29440,18 @@ const ClientRouter = (props) => {
29460
29440
  };
29461
29441
  function init(RootLayout) {
29462
29442
  clientExports.hydrateRoot(
29463
- document,
29464
- /* @__PURE__ */ jsx(RootLayout, { children: /* @__PURE__ */ jsx(ServerDataProvider, { children: /* @__PURE__ */ jsx(ClientRouter, {}) }) })
29443
+ document.body,
29444
+ /* @__PURE__ */ jsx(ServerDataProvider, { children: /* @__PURE__ */ jsx(ClientRouter, { RootLayout }) })
29465
29445
  );
29466
29446
  }
29467
29447
  function createRoot(RootLayout) {
29468
- return (props) => /* @__PURE__ */ jsx(RootLayout, { children: /* @__PURE__ */ jsx(ServerDataProvider, { value: props.data, children: /* @__PURE__ */ jsx(ClientRouter, { viewImportMap: props.viewImportMap }) }) });
29448
+ return (props) => /* @__PURE__ */ jsx(ServerDataProvider, { value: props.data, children: /* @__PURE__ */ jsx(
29449
+ ClientRouter,
29450
+ {
29451
+ RootLayout,
29452
+ viewImportMap: props.viewImportMap
29453
+ }
29454
+ ) });
29469
29455
  }
29470
29456
  export {
29471
29457
  Form,
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../client/init.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAK3C,wBAAgB,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,QASlD"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../client/init.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAK3C,wBAAgB,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,QAOlD"}
@@ -1,4 +1,4 @@
1
- type ComponentTreeBranch = Record<string, ComponentTree>;
2
- export type ComponentTree = (string[] | ComponentTreeBranch)[];
1
+ type ComponentBranch = [string, ComponentBranch[]];
2
+ export type ComponentTree = ComponentBranch[];
3
3
  export {};
4
4
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../client/types.ts"],"names":[],"mappings":"AAAA,KAAK,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AACzD,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,GAAG,mBAAmB,CAAC,EAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../client/types.ts"],"names":[],"mappings":"AAAA,KAAK,eAAe,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;AACnD,MAAM,MAAM,aAAa,GAAG,eAAe,EAAE,CAAC"}
@@ -1,53 +1,41 @@
1
- import type { Controller } from "./Controller";
1
+ import { Controller } from "./Controller";
2
2
  import { type MiddlewareReturnType } from "./Router";
3
3
  import type { App } from "../app/App";
4
+ import { HttpRequest } from "./HttpRequest";
4
5
  type ControllerMethods<T extends new (app: App) => Controller> = {
5
6
  [K in keyof InstanceType<T>]: InstanceType<T>[K] extends Function ? K : never;
6
7
  }[keyof InstanceType<T>];
7
- type DataResponse = {
8
- data: any;
9
- status: number;
10
- headers: Record<string, string>;
11
- cookies: Record<string, string>;
12
- };
8
+ type DataResponse = any;
13
9
  type ErrorResponse = {
14
10
  error: any;
15
- status: number;
16
- headers: Record<string, string>;
17
- cookies: Record<string, string>;
11
+ };
12
+ type ApiHandler<T extends new (app: App) => Controller, U = {}> = {
13
+ method: string;
14
+ exec: (req: Request, params: Record<string, any>, app: App) => Promise<Partial<DataResponse> | ErrorResponse>;
18
15
  };
19
16
  export type ApiRouteExec = (req: Request, params: Record<string, string>) => Promise<DataResponse | ErrorResponse>;
20
17
  type ApiRouteConfig = {
21
18
  method: string;
22
19
  exec: ApiRouteExec;
23
20
  };
21
+ type CallbackHandler<T> = (req: HttpRequest) => Promise<T> | T;
24
22
  export type ApiRouteChildren = Record<string, ApiRouteConfig | ApiRouteConfig[] | (new (app: App) => ApiRouter)>;
25
23
  export declare class ApiRouter {
26
24
  routes: Record<string, any>;
27
25
  middlewares: string[];
28
26
  constructor();
29
- middleware(req: Request): MiddlewareReturnType;
27
+ middleware(_req: Request): MiddlewareReturnType;
30
28
  private handleRequest;
31
- protected get<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): {
32
- method: string;
33
- exec: (req: Request, params: Record<string, string>, app: App) => Promise<DataResponse | ErrorResponse>;
34
- };
35
- protected post<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): {
36
- method: string;
37
- exec: (req: Request, params: Record<string, string>, app: App) => Promise<DataResponse | ErrorResponse>;
38
- };
39
- protected patch<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): {
40
- method: string;
41
- exec: (req: Request, params: Record<string, string>, app: App) => Promise<DataResponse | ErrorResponse>;
42
- };
43
- protected put<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): {
44
- method: string;
45
- exec: (req: Request, params: Record<string, string>, app: App) => Promise<DataResponse | ErrorResponse>;
46
- };
47
- protected delete<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): {
48
- method: string;
49
- exec: (req: Request, params: Record<string, string>, app: App) => Promise<DataResponse | ErrorResponse>;
50
- };
29
+ protected get<T>(controller: CallbackHandler<T>): ApiHandler<any>;
30
+ protected get<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): ApiHandler<T>;
31
+ protected post<T>(controller: CallbackHandler<T>): ApiHandler<any>;
32
+ protected post<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): ApiHandler<T>;
33
+ protected put<T>(controller: CallbackHandler<T>): ApiHandler<any>;
34
+ protected put<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): ApiHandler<T>;
35
+ protected delete<T>(controller: CallbackHandler<T>): ApiHandler<any>;
36
+ protected delete<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): ApiHandler<T>;
37
+ protected patch<T>(controller: CallbackHandler<T>): ApiHandler<any>;
38
+ protected patch<T extends new (app: App) => Controller>(controller: T, methodName: ControllerMethods<T>): ApiHandler<T>;
51
39
  }
52
40
  export {};
53
41
  //# sourceMappingURL=ApiRouter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ApiRouter.d.ts","sourceRoot":"","sources":["../../http/ApiRouter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAGtC,KAAK,iBAAiB,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,IAAI;KAC9D,CAAC,IAAI,MAAM,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,GAAG,KAAK;CAC9E,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzB,KAAK,YAAY,GAAG;IAClB,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AACF,KAAK,aAAa,GAAG;IACnB,KAAK,EAAE,GAAG,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAYF,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,OAAO,CAAC,YAAY,GAAG,aAAa,CAAC,CAAC;AAE3C,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CACnC,MAAM,EACN,cAAc,GAAG,cAAc,EAAE,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,KAAK,SAAS,CAAC,CAClE,CAAC;AAEF,qBAAa,SAAS;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAM;IACjC,WAAW,EAAE,MAAM,EAAE,CAAM;;IAI3B,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB;IAErD,OAAO,CAAC,aAAa;IAkCrB,SAAS,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EAClD,UAAU,EAAE,CAAC,EACb,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;;;;IAMlC,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACnD,UAAU,EAAE,CAAC,EACb,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;;;;IAMlC,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACpD,UAAU,EAAE,CAAC,EACb,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;;;;IAMlC,SAAS,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EAClD,UAAU,EAAE,CAAC,EACb,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;;;;IAMlC,SAAS,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACrD,UAAU,EAAE,CAAC,EACb,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;;;;CAKnC"}
1
+ {"version":3,"file":"ApiRouter.d.ts","sourceRoot":"","sources":["../../http/ApiRouter.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  import { App } from "../app/App";
2
2
  import type { HttpRequest } from "./HttpRequest";
3
3
  export declare class Controller {
4
- app: App;
4
+ private app;
5
5
  requests: Record<string, typeof HttpRequest<any>>;
6
+ static kind: "controller";
6
7
  constructor(app: App);
7
8
  }
8
9
  //# sourceMappingURL=Controller.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Controller.d.ts","sourceRoot":"","sources":["../../http/Controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,qBAAa,UAAU;IAGF,GAAG,EAAE,GAAG;IAF3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAM;gBAEpC,GAAG,EAAE,GAAG;CAC5B"}
1
+ {"version":3,"file":"Controller.d.ts","sourceRoot":"","sources":["../../http/Controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,qBAAa,UAAU;IAKT,OAAO,CAAC,GAAG;IAJvB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAM;IAEvD,MAAM,CAAC,IAAI,eAAyB;gBAEhB,GAAG,EAAE,GAAG;CAC7B"}
@@ -4,30 +4,30 @@ import type { App } from "../app/App";
4
4
  type ControllerMethods<T extends new () => Controller> = {
5
5
  [K in keyof InstanceType<T>]: InstanceType<T>[K] extends Function ? K : never;
6
6
  }[keyof InstanceType<T>];
7
- type ViewHandler<T extends new () => Controller> = [
8
- controller: T,
9
- method: ControllerMethods<T>
10
- ];
7
+ type ViewHandler<T extends new () => Controller> = [controller: T, method: ControllerMethods<T>] | ((req: Request) => Promise<any> | any);
11
8
  type ViewPrepare = {
12
9
  exec: (req: Request, params: Record<string, string>) => any;
13
10
  viewPath: string;
14
11
  children: ViewChildren;
15
12
  middlewares: any[];
13
+ kind: "view" | "layout";
16
14
  };
17
15
  type ViewConfig = {
18
16
  prepare: (_middlewares?: any[]) => ViewPrepare;
19
- middlewares: (middlewares: any[]) => {
20
- prepare: () => ViewPrepare;
21
- };
17
+ middleware: (middlewares: any[]) => ViewConfig;
22
18
  };
23
- export type ViewChildren = Record<string, ViewConfig | (new (app: App) => ViewRouter)>;
19
+ export type ViewChildren = Record<string, ViewConfig | (new () => ViewRouter)>;
24
20
  export type ViewRouteExec = (req: Request, params: Record<string, string>, app: App) => any;
25
21
  export declare class ViewRouter {
26
22
  routes: ViewChildren;
27
23
  middlewares: string[];
28
- constructor();
29
24
  middleware(req: Request): MiddlewareReturnType;
30
- protected view<T extends new (app: App) => Controller>(viewPath: string, handler?: ViewHandler<T>, children?: ViewChildren): ViewConfig;
25
+ protected layout<T extends new (app: App) => Controller>(viewPath: string): ViewConfig;
26
+ protected layout<T extends new (app: App) => Controller>(viewPath: string, children?: ViewChildren): ViewConfig;
27
+ protected layout<T extends new (app: App) => Controller>(viewPath: string, handler: ViewHandler<T>): ViewConfig;
28
+ protected view<T extends new (app: App) => Controller>(viewPath: string): ViewConfig;
29
+ protected view<T extends new (app: App) => Controller>(viewPath: string, children?: ViewChildren): ViewConfig;
30
+ protected view<T extends new (app: App) => Controller>(viewPath: string, handler: ViewHandler<T>): ViewConfig;
31
31
  }
32
32
  export {};
33
33
  //# sourceMappingURL=ViewRouter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ViewRouter.d.ts","sourceRoot":"","sources":["../../http/ViewRouter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,KAAK,iBAAiB,CAAC,CAAC,SAAS,UAAU,UAAU,IAAI;KACtD,CAAC,IAAI,MAAM,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,GAAG,KAAK;CAC9E,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzB,KAAK,WAAW,CAAC,CAAC,SAAS,UAAU,UAAU,IAAI;IACjD,UAAU,EAAE,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC;CAC7B,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,GAAG,EAAE,CAAC;CACpB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,KAAK,WAAW,CAAC;IAC/C,WAAW,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK;QACnC,OAAO,EAAE,MAAM,WAAW,CAAC;KAC5B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,CAC/B,MAAM,EACN,UAAU,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,CAAC,CAC5C,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,GAAG,EAAE,GAAG,KACL,GAAG,CAAC;AAET,qBAAa,UAAU;IACd,MAAM,EAAE,YAAY,CAAM;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAM;;IAG3B,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB;IAErD,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACnD,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EACxB,QAAQ,GAAE,YAAiB,GAC1B,UAAU;CA8Bd"}
1
+ {"version":3,"file":"ViewRouter.d.ts","sourceRoot":"","sources":["../../http/ViewRouter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACrD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,KAAK,iBAAiB,CAAC,CAAC,SAAS,UAAU,UAAU,IAAI;KACtD,CAAC,IAAI,MAAM,YAAY,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC,GAAG,KAAK;CAC9E,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzB,KAAK,WAAW,CAAC,CAAC,SAAS,UAAU,UAAU,IAC3C,CAAC,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAC7C,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAE3C,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,GAAG,EAAE,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CACzB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,KAAK,WAAW,CAAC;IAC/C,UAAU,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,UAAU,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC;AAE/E,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,GAAG,EAAE,GAAG,KACL,GAAG,CAAC;AAET,qBAAa,UAAU;IACd,MAAM,EAAE,YAAY,CAAM;IAC1B,WAAW,EAAE,MAAM,EAAE,CAAM;IAE3B,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB;IAErD,SAAS,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACrD,QAAQ,EAAE,MAAM,GACf,UAAU;IACb,SAAS,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACrD,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,YAAiB,GAC1B,UAAU;IACb,SAAS,CAAC,MAAM,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACrD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GACtB,UAAU;IAmDb,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACnD,QAAQ,EAAE,MAAM,GACf,UAAU;IACb,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACnD,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,YAAiB,GAC1B,UAAU;IACb,SAAS,CAAC,IAAI,CAAC,CAAC,SAAS,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,EACnD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,GACtB,UAAU;CAkDd"}
@@ -22,6 +22,7 @@ var __require = createRequire(import.meta.url);
22
22
  class Controller {
23
23
  app;
24
24
  requests = {};
25
+ static kind = "controller";
25
26
  constructor(app) {
26
27
  this.app = app;
27
28
  }
@@ -225,34 +226,33 @@ class HttpRequest {
225
226
  }
226
227
 
227
228
  // http/ApiRouter.ts
229
+ var isController = function(controller) {
230
+ return "kind" in controller && controller.kind === "controller";
231
+ };
232
+
228
233
  class ApiRouter {
229
234
  routes = {};
230
235
  middlewares = [];
231
236
  constructor() {
232
237
  }
233
- middleware(req) {
238
+ middleware(_req) {
234
239
  }
235
240
  handleRequest(controller, methodName) {
236
241
  return (method) => {
237
242
  return {
238
243
  method,
239
244
  exec: async (req, params, app) => {
240
- const controllerInstance = new controller(app);
241
- const handler = controllerInstance[methodName].bind(controllerInstance);
242
- const Req = controllerInstance.requests[methodName] ?? HttpRequest;
243
- const httpRequest = new Req(req);
244
- const {
245
- data,
246
- status = method === "post" ? 201 : 200,
247
- headers = {},
248
- cookies = {}
249
- } = await handler(httpRequest, params);
250
- return {
251
- data,
252
- status,
253
- headers,
254
- cookies
255
- };
245
+ let handler = (_req, params2) => Promise.resolve({});
246
+ let httpRequest = new HttpRequest(req);
247
+ if (isController(controller)) {
248
+ const controllerInstance = new controller(app);
249
+ const Req = controllerInstance.requests[methodName] ?? HttpRequest;
250
+ httpRequest = new Req(req);
251
+ handler = controllerInstance[methodName].bind(controllerInstance);
252
+ } else if (typeof controller === "function") {
253
+ handler = (req2) => controller(new HttpRequest(req2));
254
+ }
255
+ return await handler(httpRequest, params);
256
256
  }
257
257
  };
258
258
  };
@@ -265,10 +265,6 @@ class ApiRouter {
265
265
  const handler = this.handleRequest(controller, methodName);
266
266
  return handler("post");
267
267
  }
268
- patch(controller, methodName) {
269
- const handler = this.handleRequest(controller, methodName);
270
- return handler("patch");
271
- }
272
268
  put(controller, methodName) {
273
269
  const handler = this.handleRequest(controller, methodName);
274
270
  return handler("put");
@@ -277,39 +273,89 @@ class ApiRouter {
277
273
  const handler = this.handleRequest(controller, methodName);
278
274
  return handler("delete");
279
275
  }
276
+ patch(controller, methodName) {
277
+ const handler = this.handleRequest(controller, methodName);
278
+ return handler("patch");
279
+ }
280
280
  }
281
281
  // http/ViewRouter.ts
282
282
  class ViewRouter {
283
283
  routes = {};
284
284
  middlewares = [];
285
- constructor() {
286
- }
287
285
  middleware(req) {
288
286
  }
289
- view(viewPath, handler, children = {}) {
287
+ layout(viewPath, handler, children = {}) {
290
288
  function prepare(middlewares = []) {
289
+ let _children = children;
290
+ if (handler && handler.constructor === Object) {
291
+ _children = handler;
292
+ }
291
293
  return {
292
294
  exec: async (req, params, app) => {
293
- if (!handler) {
294
- return { data: { [viewPath]: {} }, headers: {}, head: {} };
295
+ let _handler = () => Promise.resolve({
296
+ data: { [viewPath]: {} },
297
+ headers: {},
298
+ head: {}
299
+ });
300
+ if (typeof handler === "function") {
301
+ _handler = handler;
295
302
  }
296
- const [controller, methodName] = handler;
297
- const instance = new controller(app);
298
- const method = instance[methodName].bind(instance);
299
- const { data, headers = {}, head = {} } = await method(req, params);
300
- return { data: { [viewPath]: data }, headers, head };
303
+ if (Array.isArray(handler)) {
304
+ const [controller, methodName] = handler;
305
+ const instance = new controller(app);
306
+ _handler = instance[methodName].bind(instance);
307
+ }
308
+ const data = await _handler(req, params);
309
+ return { [viewPath]: data };
301
310
  },
302
- children,
311
+ children: _children,
303
312
  viewPath,
304
- middlewares
313
+ middlewares,
314
+ kind: "layout"
305
315
  };
306
316
  }
307
317
  return {
308
318
  prepare,
309
- middlewares: (middlewares) => {
310
- prepare:
311
- ;
319
+ middleware: (middlewares) => ({
320
+ prepare: () => prepare(middlewares)
321
+ })
322
+ };
323
+ }
324
+ view(viewPath, handler, children = {}) {
325
+ function prepare(middlewares = []) {
326
+ let _children = children;
327
+ if (handler && handler.constructor === Object) {
328
+ _children = handler;
312
329
  }
330
+ return {
331
+ exec: async (req, params, app) => {
332
+ let _handler = () => Promise.resolve({
333
+ data: { [viewPath]: {} },
334
+ headers: {},
335
+ head: {}
336
+ });
337
+ if (typeof handler === "function") {
338
+ _handler = handler;
339
+ }
340
+ if (Array.isArray(handler)) {
341
+ const [controller, methodName] = handler;
342
+ const instance = new controller(app);
343
+ _handler = instance[methodName].bind(instance);
344
+ }
345
+ const data = await _handler(req, params);
346
+ return { [viewPath]: data };
347
+ },
348
+ children: _children,
349
+ viewPath,
350
+ middlewares,
351
+ kind: "view"
352
+ };
353
+ }
354
+ return {
355
+ prepare,
356
+ middleware: (middlewares) => ({
357
+ prepare: () => prepare(middlewares)
358
+ })
313
359
  };
314
360
  }
315
361
  }
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "gemi",
3
- "version": "0.2.1",
3
+ "version": "0.3.2",
4
4
  "devDependencies": {
5
5
  "@repo/eslint-config": "*",
6
6
  "@repo/typescript-config": "*",
7
+ "@types/bun": "^1.1.4",
7
8
  "@types/eslint": "^8.56.5",
8
9
  "@types/node": "^20.11.24",
9
10
  "@types/react": "^18.2.61",
10
11
  "@types/react-dom": "^18.2.19",
11
12
  "eslint": "^8.57.0",
12
- "typescript": "^5.3.3"
13
+ "typescript": "^5.3.3",
14
+ "vitest": "^1.6.0"
13
15
  },
14
16
  "bin": {
15
17
  "gemi": "./dist/bin/gemi"
@@ -35,7 +37,8 @@
35
37
  "build:bin": "bun build --compile ./bin/gemi.ts --external vite --external react-dom --external react/jsx-runtime --outfile ./dist/bin/gemi",
36
38
  "build:client": "vite build",
37
39
  "build:types": "tsc",
38
- "build:client-types": "tsc -p tsconfig.browser.json"
40
+ "build:client-types": "tsc -p tsconfig.browser.json",
41
+ "test": "vitest"
39
42
  },
40
43
  "dependencies": {
41
44
  "@react-email/components": "^0.0.19",