@webtypen/webframez-react 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/router.js CHANGED
@@ -114,6 +114,10 @@ function readSearchParams(urlSearchParams) {
114
114
  function escapeHtml(value) {
115
115
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;").replace(/'/g, "&#39;");
116
116
  }
117
+ var MANAGED_HEAD_ATTR = "data-webframez-head";
118
+ function createManagedAttributes() {
119
+ return `${MANAGED_HEAD_ATTR}="true"`;
120
+ }
117
121
  function toRouteEntry(pagesDir, filePath) {
118
122
  const normalized = filePath.replace(/\\/g, "/");
119
123
  if (!normalized.endsWith("/index.js")) {
@@ -182,19 +186,21 @@ function renderHeadToString(head) {
182
186
  const tags = [];
183
187
  if (head.description) {
184
188
  tags.push(
185
- `<meta name="description" content="${escapeHtml(head.description)}" />`
189
+ `<meta ${createManagedAttributes()} name="description" content="${escapeHtml(head.description)}" />`
186
190
  );
187
191
  }
188
192
  if (head.favicon) {
189
- tags.push(`<link rel="icon" href="${escapeHtml(head.favicon)}" />`);
193
+ tags.push(
194
+ `<link ${createManagedAttributes()} rel="icon" href="${escapeHtml(head.favicon)}" />`
195
+ );
190
196
  }
191
197
  for (const meta of head.meta ?? []) {
192
198
  const attrs = Object.entries(meta).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
193
- tags.push(`<meta ${attrs} />`);
199
+ tags.push(`<meta ${createManagedAttributes()} ${attrs} />`);
194
200
  }
195
201
  for (const link of head.links ?? []) {
196
202
  const attrs = Object.entries(link).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
197
- tags.push(`<link ${attrs} />`);
203
+ tags.push(`<link ${createManagedAttributes()} ${attrs} />`);
198
204
  }
199
205
  return tags.join("\n");
200
206
  }
@@ -208,6 +214,12 @@ async function resolveHead(candidate, context) {
208
214
  }
209
215
  return candidate.Head(context);
210
216
  }
217
+ async function resolvePageData(candidate, context) {
218
+ if (!candidate.Data) {
219
+ return void 0;
220
+ }
221
+ return candidate.Data(context);
222
+ }
211
223
  function findBestMatch(entries, pathname) {
212
224
  const matches = [];
213
225
  for (const entry of entries) {
@@ -287,10 +299,11 @@ function createFileRouter(options) {
287
299
  };
288
300
  }
289
301
  const errorModule = resolveModule(errorPath);
290
- const errorNode = errorModule.default(errorProps);
302
+ const errorNode = await errorModule.default(errorProps);
291
303
  const layoutHead = layoutModule ? await resolveHead(layoutModule, context) : void 0;
292
304
  const errorHead = await resolveHead(errorModule, errorProps);
293
- const model = layoutModule ? injectRouteChildren(layoutModule.default(context), errorNode) : errorNode;
305
+ const layoutNode = layoutModule ? await layoutModule.default(context) : null;
306
+ const model = layoutNode ? injectRouteChildren(layoutNode, errorNode) : errorNode;
294
307
  return {
295
308
  statusCode,
296
309
  model,
@@ -322,10 +335,17 @@ function createFileRouter(options) {
322
335
  activeContext = context;
323
336
  const pageModule = resolveModule(match.entry.filePath);
324
337
  const layoutModule = fs.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
325
- const pageNode = pageModule.default(context);
326
- const layoutHead = layoutModule ? await resolveHead(layoutModule, context) : void 0;
327
- const pageHead = await resolveHead(pageModule, context);
328
- const model = layoutModule ? injectRouteChildren(layoutModule.default(context), pageNode) : pageNode;
338
+ const pageData = await resolvePageData(pageModule, context);
339
+ const pageContext = {
340
+ ...context,
341
+ data: pageData
342
+ };
343
+ activeContext = pageContext;
344
+ const pageNode = await pageModule.default(pageContext);
345
+ const layoutHead = layoutModule ? await resolveHead(layoutModule, pageContext) : void 0;
346
+ const pageHead = await resolveHead(pageModule, pageContext);
347
+ const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
348
+ const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
329
349
  return {
330
350
  statusCode: 200,
331
351
  model,
package/dist/types.d.ts CHANGED
@@ -9,17 +9,24 @@ export type AbortRouteOptions = {
9
9
  payload?: unknown;
10
10
  };
11
11
 
12
- export type RouteContext = {
12
+ export type RouteContext<TData = unknown> = {
13
13
  pathname: string;
14
14
  params: RouteParams;
15
15
  searchParams: RouteSearchParams;
16
16
  cookies: Record<string, string>;
17
+ data?: TData;
17
18
  abort: (options?: AbortRouteOptions) => never;
18
19
  };
19
20
 
20
- export type PageProps = RouteContext;
21
+ export type InferPageData<TDataResolver> =
22
+ TDataResolver extends (...args: any[]) => any
23
+ ? Awaited<ReturnType<TDataResolver>>
24
+ : TDataResolver;
25
+ export type PageProps<TData = unknown> = RouteContext<InferPageData<TData>>;
26
+ export type PagePropsFromData<TDataResolver extends (...args: any[]) => any> =
27
+ PageProps<InferPageData<TDataResolver>>;
21
28
 
22
- export type ErrorPageProps = RouteContext & {
29
+ export type ErrorPageProps<TData = unknown> = RouteContext<TData> & {
23
30
  statusCode: number;
24
31
  message: string;
25
32
  payload?: unknown;
@@ -49,22 +56,32 @@ export type HeadConfig = {
49
56
  links?: HeadLinkTag[];
50
57
  };
51
58
 
59
+ export type ClientNavigationPayload = {
60
+ model: ReactNode;
61
+ head: HeadConfig;
62
+ };
63
+
52
64
  export type HeadResolver<TContext = RouteContext> = (
53
65
  context: TContext
54
66
  ) => HeadConfig | Promise<HeadConfig>;
55
67
 
56
- export type PageModule = {
57
- default: (props: PageProps) => ReactNode;
58
- Head?: HeadResolver<RouteContext>;
68
+ export type PageDataResolver<TData = unknown> = (
69
+ context: RouteContext
70
+ ) => TData | Promise<TData>;
71
+
72
+ export type PageModule<TData = unknown> = {
73
+ default: (props: PageProps<TData>) => ReactNode | Promise<ReactNode>;
74
+ Head?: HeadResolver<PageProps<TData>>;
75
+ Data?: PageDataResolver<TData>;
59
76
  };
60
77
 
61
78
  export type LayoutModule = {
62
- default: (props: RouteContext) => ReactNode;
79
+ default: (props: RouteContext) => ReactNode | Promise<ReactNode>;
63
80
  Head?: HeadResolver<RouteContext>;
64
81
  };
65
82
 
66
83
  export type ErrorModule = {
67
- default: (props: ErrorPageProps) => ReactNode;
84
+ default: (props: ErrorPageProps) => ReactNode | Promise<ReactNode>;
68
85
  Head?: HeadResolver<ErrorPageProps>;
69
86
  };
70
87
 
@@ -226,6 +226,10 @@ function readSearchParams(urlSearchParams) {
226
226
  function escapeHtml(value) {
227
227
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;").replace(/'/g, "&#39;");
228
228
  }
229
+ var MANAGED_HEAD_ATTR = "data-webframez-head";
230
+ function createManagedAttributes() {
231
+ return `${MANAGED_HEAD_ATTR}="true"`;
232
+ }
229
233
  function toRouteEntry(pagesDir, filePath) {
230
234
  const normalized = filePath.replace(/\\/g, "/");
231
235
  if (!normalized.endsWith("/index.js")) {
@@ -294,19 +298,21 @@ function renderHeadToString(head) {
294
298
  const tags = [];
295
299
  if (head.description) {
296
300
  tags.push(
297
- `<meta name="description" content="${escapeHtml(head.description)}" />`
301
+ `<meta ${createManagedAttributes()} name="description" content="${escapeHtml(head.description)}" />`
298
302
  );
299
303
  }
300
304
  if (head.favicon) {
301
- tags.push(`<link rel="icon" href="${escapeHtml(head.favicon)}" />`);
305
+ tags.push(
306
+ `<link ${createManagedAttributes()} rel="icon" href="${escapeHtml(head.favicon)}" />`
307
+ );
302
308
  }
303
309
  for (const meta of head.meta ?? []) {
304
310
  const attrs = Object.entries(meta).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
305
- tags.push(`<meta ${attrs} />`);
311
+ tags.push(`<meta ${createManagedAttributes()} ${attrs} />`);
306
312
  }
307
313
  for (const link of head.links ?? []) {
308
314
  const attrs = Object.entries(link).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
309
- tags.push(`<link ${attrs} />`);
315
+ tags.push(`<link ${createManagedAttributes()} ${attrs} />`);
310
316
  }
311
317
  return tags.join("\n");
312
318
  }
@@ -320,6 +326,12 @@ async function resolveHead(candidate, context) {
320
326
  }
321
327
  return candidate.Head(context);
322
328
  }
329
+ async function resolvePageData(candidate, context) {
330
+ if (!candidate.Data) {
331
+ return void 0;
332
+ }
333
+ return candidate.Data(context);
334
+ }
323
335
  function findBestMatch(entries, pathname) {
324
336
  const matches = [];
325
337
  for (const entry of entries) {
@@ -399,10 +411,11 @@ function createFileRouter(options) {
399
411
  };
400
412
  }
401
413
  const errorModule = resolveModule(errorPath);
402
- const errorNode = errorModule.default(errorProps);
414
+ const errorNode = await errorModule.default(errorProps);
403
415
  const layoutHead = layoutModule ? await resolveHead(layoutModule, context) : void 0;
404
416
  const errorHead = await resolveHead(errorModule, errorProps);
405
- const model = layoutModule ? injectRouteChildren(layoutModule.default(context), errorNode) : errorNode;
417
+ const layoutNode = layoutModule ? await layoutModule.default(context) : null;
418
+ const model = layoutNode ? injectRouteChildren(layoutNode, errorNode) : errorNode;
406
419
  return {
407
420
  statusCode,
408
421
  model,
@@ -434,10 +447,17 @@ function createFileRouter(options) {
434
447
  activeContext = context;
435
448
  const pageModule = resolveModule(match.entry.filePath);
436
449
  const layoutModule = import_node_fs.default.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
437
- const pageNode = pageModule.default(context);
438
- const layoutHead = layoutModule ? await resolveHead(layoutModule, context) : void 0;
439
- const pageHead = await resolveHead(pageModule, context);
440
- const model = layoutModule ? injectRouteChildren(layoutModule.default(context), pageNode) : pageNode;
450
+ const pageData = await resolvePageData(pageModule, context);
451
+ const pageContext = {
452
+ ...context,
453
+ data: pageData
454
+ };
455
+ activeContext = pageContext;
456
+ const pageNode = await pageModule.default(pageContext);
457
+ const layoutHead = layoutModule ? await resolveHead(layoutModule, pageContext) : void 0;
458
+ const pageHead = await resolveHead(pageModule, pageContext);
459
+ const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
460
+ const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
441
461
  return {
442
462
  statusCode: 200,
443
463
  model,
@@ -496,8 +516,23 @@ async function renderInitialHtmlInWorker(options) {
496
516
  const payload = Buffer.from(JSON.stringify(options), "utf8").toString("base64url");
497
517
  const script = `
498
518
  const path = require("node:path");
519
+ const Module = require("node:module");
499
520
  const input = JSON.parse(Buffer.from(process.argv[1], "base64url").toString("utf8"));
500
521
  globalThis.__RSC_BASENAME = input.basename || "";
522
+ const appRequire = Module.createRequire(path.join(input.pagesDir, "__webframez_react_worker__.js"));
523
+ const originalResolveFilename = Module._resolveFilename;
524
+ const forcedResolutions = new Map([
525
+ ["react", appRequire.resolve("react")],
526
+ ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
527
+ ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
528
+ ["react-dom/client", appRequire.resolve("react-dom/client")]
529
+ ]);
530
+ Module._resolveFilename = function(request, parent, isMain, options) {
531
+ if (forcedResolutions.has(request)) {
532
+ return forcedResolutions.get(request);
533
+ }
534
+ return originalResolveFilename.call(this, request, parent, isMain, options);
535
+ };
501
536
  const { createFileRouter } = require("webframez-react/router");
502
537
  const reactDomPkg = require.resolve("react-dom/package.json", {
503
538
  paths: [process.cwd(), input.pagesDir]
@@ -637,7 +672,11 @@ function createNodeRequestHandler(options) {
637
672
  cookies: requestCookies
638
673
  })
639
674
  );
640
- sendRSC(res, resolved2.model, {
675
+ const payload = {
676
+ model: resolved2.model,
677
+ head: resolved2.head
678
+ };
679
+ sendRSC(res, payload, {
641
680
  moduleMap,
642
681
  statusCode: resolved2.statusCode
643
682
  });
@@ -2,18 +2,42 @@ import type { RouteFacade } from "@webtypen/webframez-core";
2
2
  import type { CreateNodeHandlerOptions } from "./http";
3
3
 
4
4
  export type WebframezCoreRouteMethod = "GET" | "POST" | "PUT" | "DELETE";
5
+ export type WebframezCoreRouteMiddleware = string | string[];
5
6
 
6
- export type WebframezCoreReactRenderRouteOptions = CreateNodeHandlerOptions & {
7
+ export interface WebframezCoreRouteRegistrationOptions {
8
+ middleware?: WebframezCoreRouteMiddleware;
9
+ domains?: string | string[];
10
+ [key: string]: unknown;
11
+ }
12
+
13
+ export interface WebframezCoreReactRenderRouteOptions
14
+ extends CreateNodeHandlerOptions {
7
15
  method?: WebframezCoreRouteMethod | WebframezCoreRouteMethod[];
8
- routeOptions?: Record<string, any>;
9
- };
16
+ routeOptions?: WebframezCoreRouteRegistrationOptions;
17
+ }
18
+
19
+ export interface WebframezCoreRouteFacadeExtensions {
20
+ renderReact(path: string, options: WebframezCoreReactRenderRouteOptions): void;
21
+ reactRender(path: string, options: WebframezCoreReactRenderRouteOptions): void;
22
+ }
10
23
 
11
24
  declare module "@webtypen/webframez-core" {
12
- interface RouteFacade {
13
- renderReact(path: string, options: WebframezCoreReactRenderRouteOptions): void;
14
- reactRender(path: string, options: WebframezCoreReactRenderRouteOptions): void;
15
- }
25
+ interface RouteFacade extends WebframezCoreRouteFacadeExtensions {}
26
+ }
27
+
28
+ declare module "webframez-core" {
29
+ interface RouteFacade extends WebframezCoreRouteFacadeExtensions {}
30
+ }
31
+
32
+ declare module "@webtypen/webframez-core/dist/Router/Route" {
33
+ interface RouteFacade extends WebframezCoreRouteFacadeExtensions {}
34
+ }
35
+
36
+ declare module "webframez-core/dist/Router/Route" {
37
+ interface RouteFacade extends WebframezCoreRouteFacadeExtensions {}
16
38
  }
17
39
 
18
- export function initWebframezReact(route: RouteFacade): RouteFacade;
40
+ export function initWebframezReact<T extends RouteFacade>(
41
+ route: T,
42
+ ): T & WebframezCoreRouteFacadeExtensions;
19
43
  export const setupWebframezCoreReactRoute: typeof initWebframezReact;
@@ -198,6 +198,10 @@ function readSearchParams(urlSearchParams) {
198
198
  function escapeHtml(value) {
199
199
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\"/g, "&quot;").replace(/'/g, "&#39;");
200
200
  }
201
+ var MANAGED_HEAD_ATTR = "data-webframez-head";
202
+ function createManagedAttributes() {
203
+ return `${MANAGED_HEAD_ATTR}="true"`;
204
+ }
201
205
  function toRouteEntry(pagesDir, filePath) {
202
206
  const normalized = filePath.replace(/\\/g, "/");
203
207
  if (!normalized.endsWith("/index.js")) {
@@ -266,19 +270,21 @@ function renderHeadToString(head) {
266
270
  const tags = [];
267
271
  if (head.description) {
268
272
  tags.push(
269
- `<meta name="description" content="${escapeHtml(head.description)}" />`
273
+ `<meta ${createManagedAttributes()} name="description" content="${escapeHtml(head.description)}" />`
270
274
  );
271
275
  }
272
276
  if (head.favicon) {
273
- tags.push(`<link rel="icon" href="${escapeHtml(head.favicon)}" />`);
277
+ tags.push(
278
+ `<link ${createManagedAttributes()} rel="icon" href="${escapeHtml(head.favicon)}" />`
279
+ );
274
280
  }
275
281
  for (const meta of head.meta ?? []) {
276
282
  const attrs = Object.entries(meta).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
277
- tags.push(`<meta ${attrs} />`);
283
+ tags.push(`<meta ${createManagedAttributes()} ${attrs} />`);
278
284
  }
279
285
  for (const link of head.links ?? []) {
280
286
  const attrs = Object.entries(link).filter(([, value]) => Boolean(value)).map(([key, value]) => `${key}="${escapeHtml(String(value))}"`).join(" ");
281
- tags.push(`<link ${attrs} />`);
287
+ tags.push(`<link ${createManagedAttributes()} ${attrs} />`);
282
288
  }
283
289
  return tags.join("\n");
284
290
  }
@@ -292,6 +298,12 @@ async function resolveHead(candidate, context) {
292
298
  }
293
299
  return candidate.Head(context);
294
300
  }
301
+ async function resolvePageData(candidate, context) {
302
+ if (!candidate.Data) {
303
+ return void 0;
304
+ }
305
+ return candidate.Data(context);
306
+ }
295
307
  function findBestMatch(entries, pathname) {
296
308
  const matches = [];
297
309
  for (const entry of entries) {
@@ -371,10 +383,11 @@ function createFileRouter(options) {
371
383
  };
372
384
  }
373
385
  const errorModule = resolveModule(errorPath);
374
- const errorNode = errorModule.default(errorProps);
386
+ const errorNode = await errorModule.default(errorProps);
375
387
  const layoutHead = layoutModule ? await resolveHead(layoutModule, context) : void 0;
376
388
  const errorHead = await resolveHead(errorModule, errorProps);
377
- const model = layoutModule ? injectRouteChildren(layoutModule.default(context), errorNode) : errorNode;
389
+ const layoutNode = layoutModule ? await layoutModule.default(context) : null;
390
+ const model = layoutNode ? injectRouteChildren(layoutNode, errorNode) : errorNode;
378
391
  return {
379
392
  statusCode,
380
393
  model,
@@ -406,10 +419,17 @@ function createFileRouter(options) {
406
419
  activeContext = context;
407
420
  const pageModule = resolveModule(match.entry.filePath);
408
421
  const layoutModule = fs.existsSync(layoutPath) ? resolveModule(layoutPath) : null;
409
- const pageNode = pageModule.default(context);
410
- const layoutHead = layoutModule ? await resolveHead(layoutModule, context) : void 0;
411
- const pageHead = await resolveHead(pageModule, context);
412
- const model = layoutModule ? injectRouteChildren(layoutModule.default(context), pageNode) : pageNode;
422
+ const pageData = await resolvePageData(pageModule, context);
423
+ const pageContext = {
424
+ ...context,
425
+ data: pageData
426
+ };
427
+ activeContext = pageContext;
428
+ const pageNode = await pageModule.default(pageContext);
429
+ const layoutHead = layoutModule ? await resolveHead(layoutModule, pageContext) : void 0;
430
+ const pageHead = await resolveHead(pageModule, pageContext);
431
+ const layoutNode = layoutModule ? await layoutModule.default(pageContext) : null;
432
+ const model = layoutNode ? injectRouteChildren(layoutNode, pageNode) : pageNode;
413
433
  return {
414
434
  statusCode: 200,
415
435
  model,
@@ -468,8 +488,23 @@ async function renderInitialHtmlInWorker(options) {
468
488
  const payload = Buffer.from(JSON.stringify(options), "utf8").toString("base64url");
469
489
  const script = `
470
490
  const path = require("node:path");
491
+ const Module = require("node:module");
471
492
  const input = JSON.parse(Buffer.from(process.argv[1], "base64url").toString("utf8"));
472
493
  globalThis.__RSC_BASENAME = input.basename || "";
494
+ const appRequire = Module.createRequire(path.join(input.pagesDir, "__webframez_react_worker__.js"));
495
+ const originalResolveFilename = Module._resolveFilename;
496
+ const forcedResolutions = new Map([
497
+ ["react", appRequire.resolve("react")],
498
+ ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
499
+ ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
500
+ ["react-dom/client", appRequire.resolve("react-dom/client")]
501
+ ]);
502
+ Module._resolveFilename = function(request, parent, isMain, options) {
503
+ if (forcedResolutions.has(request)) {
504
+ return forcedResolutions.get(request);
505
+ }
506
+ return originalResolveFilename.call(this, request, parent, isMain, options);
507
+ };
473
508
  const { createFileRouter } = require("webframez-react/router");
474
509
  const reactDomPkg = require.resolve("react-dom/package.json", {
475
510
  paths: [process.cwd(), input.pagesDir]
@@ -609,7 +644,11 @@ function createNodeRequestHandler(options) {
609
644
  cookies: requestCookies
610
645
  })
611
646
  );
612
- sendRSC(res, resolved2.model, {
647
+ const payload = {
648
+ model: resolved2.model,
649
+ head: resolved2.head
650
+ };
651
+ sendRSC(res, payload, {
613
652
  moduleMap,
614
653
  statusCode: resolved2.statusCode
615
654
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {
@@ -19,6 +19,9 @@
19
19
  "main": "./dist/index.cjs",
20
20
  "module": "./dist/index.js",
21
21
  "types": "./dist/index.d.ts",
22
+ "bin": {
23
+ "webframez-react": "./bin/webframez-react.mjs"
24
+ },
22
25
  "exports": {
23
26
  ".": {
24
27
  "types": "./dist/index.d.ts",
@@ -54,10 +57,17 @@
54
57
  "types": "./dist/webframez-core.d.ts",
55
58
  "import": "./dist/webframez-core.js",
56
59
  "require": "./dist/webframez-core.cjs"
57
- }
60
+ },
61
+ "./defaults/webpack.client": "./defaults/webpack.client.cjs",
62
+ "./defaults/webpack.server": "./defaults/webpack.server.cjs",
63
+ "./defaults/tsconfig.server": "./defaults/tsconfig.server.json",
64
+ "./defaults/tsconfig.server.example": "./defaults/tsconfig.server.example.json",
65
+ "./cli": "./bin/webframez-react.mjs"
58
66
  },
59
67
  "files": [
60
- "dist"
68
+ "dist",
69
+ "defaults",
70
+ "bin"
61
71
  ],
62
72
  "scripts": {
63
73
  "clean": "rm -rf dist",