xpine 0.0.58 → 0.0.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/.claude/settings.local.json +2 -1
  2. package/.claude/worktrees/happy-lalande-c6c39c/.claude/settings.local.json +33 -0
  3. package/.claude/worktrees/happy-lalande-c6c39c/.d.ts +1 -0
  4. package/.claude/worktrees/happy-lalande-c6c39c/.gitattributes +2 -0
  5. package/.claude/worktrees/happy-lalande-c6c39c/README.md +571 -0
  6. package/.claude/worktrees/happy-lalande-c6c39c/TODO +2 -0
  7. package/.claude/worktrees/happy-lalande-c6c39c/eslint.config.mjs +27 -0
  8. package/.claude/worktrees/happy-lalande-c6c39c/jsx-runtime.d.ts +1 -0
  9. package/.claude/worktrees/happy-lalande-c6c39c/package-lock.json +5862 -0
  10. package/.claude/worktrees/happy-lalande-c6c39c/package.json +62 -0
  11. package/.claude/worktrees/happy-lalande-c6c39c/tsconfig.json +43 -0
  12. package/.claude/worktrees/happy-lalande-c6c39c/types.ts +55 -0
  13. package/.claude/worktrees/happy-lalande-c6c39c/xpine.config.mjs +1 -0
  14. package/.claude/worktrees/jolly-hofstadter-2764be/.claude/settings.local.json +33 -0
  15. package/.claude/worktrees/jolly-hofstadter-2764be/.d.ts +1 -0
  16. package/.claude/worktrees/jolly-hofstadter-2764be/.gitattributes +2 -0
  17. package/.claude/worktrees/jolly-hofstadter-2764be/README.md +571 -0
  18. package/.claude/worktrees/jolly-hofstadter-2764be/TODO +2 -0
  19. package/.claude/worktrees/jolly-hofstadter-2764be/eslint.config.mjs +27 -0
  20. package/.claude/worktrees/jolly-hofstadter-2764be/jsx-runtime.d.ts +1 -0
  21. package/.claude/worktrees/jolly-hofstadter-2764be/package-lock.json +5862 -0
  22. package/.claude/worktrees/jolly-hofstadter-2764be/package.json +62 -0
  23. package/.claude/worktrees/jolly-hofstadter-2764be/tsconfig.json +43 -0
  24. package/.claude/worktrees/jolly-hofstadter-2764be/types.ts +55 -0
  25. package/.claude/worktrees/jolly-hofstadter-2764be/xpine.config.mjs +1 -0
  26. package/README.md +104 -0
  27. package/create-xpine-app/README.md +20 -0
  28. package/create-xpine-app/index.js +80 -0
  29. package/create-xpine-app/package.json +30 -0
  30. package/create-xpine-app/template/README.md +50 -0
  31. package/create-xpine-app/template/eslint.config.mjs +27 -0
  32. package/create-xpine-app/template/gitignore +5 -0
  33. package/create-xpine-app/template/package.json +32 -0
  34. package/create-xpine-app/template/tsconfig.json +36 -0
  35. package/create-xpine-app/template/xpine.config.mjs +1 -0
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +269 -106
  39. package/dist/src/auth.d.ts.map +1 -1
  40. package/dist/src/express.d.ts +5 -0
  41. package/dist/src/express.d.ts.map +1 -1
  42. package/dist/src/scripts/build.d.ts.map +1 -1
  43. package/dist/src/scripts/xpine-build.js +6 -2
  44. package/dist/src/scripts/xpine-dev.js +15 -21
  45. package/dist/src/util/html.d.ts +9 -1
  46. package/dist/src/util/html.d.ts.map +1 -1
  47. package/dist/src/util/regex.d.ts +2 -0
  48. package/dist/src/util/regex.d.ts.map +1 -1
  49. package/dist/types.d.ts +4 -1
  50. package/dist/types.d.ts.map +1 -1
  51. package/eslint.config.mjs +1 -1
  52. package/package.json +1 -1
  53. package/types.ts +5 -1
@@ -328,6 +328,9 @@ var regex_default = {
328
328
  configFile: /\+config\.[tj]sx?/g,
329
329
  dynamicRoutes: /(\[)(.*?)(\])/g,
330
330
  isDynamicRoute: /\[(.*)\]/g,
331
+ // Multi-segment (slash-containing) dynamic route, e.g. [...slug]
332
+ spreadRoute: /\[\.\.\.(.*?)\]/g,
333
+ isSpreadRoute: /\[\.\.\..*?\]/,
331
334
  endsWithTSX: /\.tsx$/,
332
335
  endsWithJSX: /\.jsx$/,
333
336
  endsWithJs: /\.js$/,
@@ -898,7 +901,7 @@ async function buildStaticFiles(config2, component, componentImport, builtCompon
898
901
  function determineOutputPathForStaticPath(builtComponentPath, componentDynamicPaths) {
899
902
  if (componentDynamicPaths?.length) {
900
903
  return componentDynamicPaths.reduce((total, current) => {
901
- return total.replace(`/[${current}]`, "");
904
+ return total.replace(`/[...${current}]`, "").replace(`/[${current}]`, "");
902
905
  }, path5.dirname(builtComponentPath));
903
906
  } else {
904
907
  if (builtComponentPath?.match(regex_default.endsWithIndex)) {
@@ -914,7 +917,8 @@ function getComponentDynamicPaths(componentPath) {
914
917
  if (!matches?.length) return null;
915
918
  const output = [];
916
919
  for (const match of matches) {
917
- output.push(match[2]);
920
+ if (!match[2]) continue;
921
+ output.push(match[2].replace(/^\.\.\./, ""));
918
922
  }
919
923
  return output;
920
924
  }
@@ -1096,9 +1100,9 @@ async function runDevServer() {
1096
1100
  });
1097
1101
  }
1098
1102
  function asyncServerClose(server) {
1099
- return new Promise((resolve, reject) => {
1100
- server.close();
1101
- resolve(true);
1103
+ return new Promise((resolve) => {
1104
+ server.close(() => resolve(true));
1105
+ server.closeAllConnections?.();
1102
1106
  });
1103
1107
  }
1104
1108
  function createRebuildEmitter(delay = 500) {
@@ -1106,24 +1110,14 @@ function createRebuildEmitter(delay = 500) {
1106
1110
  }
1107
1111
  ;
1108
1112
  const rebuildEmitter = new RebuildEmitter();
1109
- let start = 0;
1110
- let hasEmitted = false;
1113
+ let timeout = null;
1111
1114
  rebuildEmitter.on("rebuild-server", () => {
1112
- hasEmitted = false;
1113
- trigger();
1115
+ if (timeout) clearTimeout(timeout);
1116
+ timeout = setTimeout(() => {
1117
+ timeout = null;
1118
+ rebuildEmitter.emit("done");
1119
+ }, delay);
1114
1120
  });
1115
- function trigger() {
1116
- start = Date.now();
1117
- const interval = setInterval(() => {
1118
- if (hasEmitted) return;
1119
- const now = Date.now();
1120
- if (now - start >= delay) {
1121
- rebuildEmitter.emit("done");
1122
- clearInterval(interval);
1123
- hasEmitted = true;
1124
- }
1125
- }, 100);
1126
- }
1127
1121
  return rebuildEmitter;
1128
1122
  }
1129
1123
 
@@ -1,6 +1,14 @@
1
+ export declare class RawHtml {
2
+ value: string;
3
+ constructor(value: string);
4
+ toString(): string;
5
+ }
6
+ export declare function escapeHtml(value: unknown): string;
7
+ export declare function raw(value: string): RawHtml;
1
8
  export declare class html {
9
+ static raw: typeof raw;
2
10
  static attributeObjectToString(props: any): string;
3
- static fragment(props: any): Promise<string>;
11
+ static fragment(props: any): Promise<RawHtml>;
4
12
  static createElement(type: any, props: any, ...children: any[]): Promise<any>;
5
13
  }
6
14
  export declare function JSXRuntime(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/util/html.ts"],"names":[],"mappings":"AAAA,qBAAa,IAAI;IAEf,MAAM,CAAC,uBAAuB,CAAC,KAAK,KAAA;WAWvB,QAAQ,CAAC,KAAK,KAAA;WAKd,aAAa,CAAC,IAAI,KAAA,EAAE,KAAK,KAAA,EAAE,GAAG,QAAQ,OAAA;CASpD;AAED,wBAAgB,UAAU,YAEzB"}
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../../src/util/html.ts"],"names":[],"mappings":"AAGA,qBAAa,OAAO;IACC,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;IAChC,QAAQ;CACT;AAKD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOjD;AAID,wBAAgB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE1C;AAUD,qBAAa,IAAI;IACf,MAAM,CAAC,GAAG,aAAO;IAEjB,MAAM,CAAC,uBAAuB,CAAC,KAAK,KAAA;WAYvB,QAAQ,CAAC,KAAK,KAAA;WAKd,aAAa,CAAC,IAAI,KAAA,EAAE,KAAK,KAAA,EAAE,GAAG,QAAQ,OAAA;CAWpD;AAED,wBAAgB,UAAU,YAEzB"}
@@ -4,6 +4,8 @@ declare const _default: {
4
4
  configFile: RegExp;
5
5
  dynamicRoutes: RegExp;
6
6
  isDynamicRoute: RegExp;
7
+ spreadRoute: RegExp;
8
+ isSpreadRoute: RegExp;
7
9
  endsWithTSX: RegExp;
8
10
  endsWithJSX: RegExp;
9
11
  endsWithJs: RegExp;
@@ -1 +1 @@
1
- {"version":3,"file":"regex.d.ts","sourceRoot":"","sources":["../../../src/util/regex.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,wBAiBE"}
1
+ {"version":3,"file":"regex.d.ts","sourceRoot":"","sources":["../../../src/util/regex.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,wBAoBE"}
package/dist/types.d.ts CHANGED
@@ -21,10 +21,13 @@ export type WrapperProps = {
21
21
  export type ConfigFile = {
22
22
  staticPaths?: boolean | (() => Promise<{
23
23
  [key: string]: string;
24
- }[]>);
24
+ }[]> | {
25
+ [key: string]: string;
26
+ }[]);
25
27
  wrapper?: (props: WrapperProps) => Promise<any>;
26
28
  data?: (req: ServerRequest) => Promise<any>;
27
29
  routeMiddleware?: (req: ServerRequest, res: Response, next: NextFunction) => void;
30
+ isValid?: (slug: string, req: ServerRequest) => boolean | Promise<boolean>;
28
31
  };
29
32
  export type PageProps = {
30
33
  req: ServerRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5C,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CACnF,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,aAAa,CAAC;IACnB,GAAG,EAAE,QAAQ,CAAC;IACd,IAAI,EAAE,GAAG,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC;CACvB,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,EAAE,CAAC,GAAG;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IACnG,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5C,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAIlF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5E,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,aAAa,CAAC;IACnB,GAAG,EAAE,QAAQ,CAAC;IACd,IAAI,EAAE,GAAG,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC;CACvB,CAAA"}
package/eslint.config.mjs CHANGED
@@ -22,6 +22,6 @@ export default tseslint.config(
22
22
  files: ["src/**/*.{js,mjs,ts,tsx,jsx}"],
23
23
  },
24
24
  {
25
- ignores: ["dist/", "cdk.out/", "tests/dist/", "tests/playwright-report/"]
25
+ ignores: ["dist/", "cdk.out/", "tests/dist/", "tests/playwright-report/", "create-xpine-app/"]
26
26
  }
27
27
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xpine",
3
- "version": "0.0.58",
3
+ "version": "0.0.60",
4
4
  "main": "dist/index.js",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-secrets-manager": "^3.758.0",
package/types.ts CHANGED
@@ -24,10 +24,14 @@ export type WrapperProps = {
24
24
  }
25
25
 
26
26
  export type ConfigFile = {
27
- staticPaths?: boolean | (() => Promise<{ [key: string]: string }[]>);
27
+ staticPaths?: boolean | (() => Promise<{ [key: string]: string }[]> | { [key: string]: string }[]);
28
28
  wrapper?: (props: WrapperProps) => Promise<any>;
29
29
  data?: (req: ServerRequest) => Promise<any>;
30
30
  routeMiddleware?: (req: ServerRequest, res: Response, next: NextFunction) => void;
31
+ // For multi-segment dynamic routes ([...slug]): validate a slug that was not
32
+ // generated at build time so it can be resolved safely at request time.
33
+ // Return false (the default for unknown slugs) to fall through to the 404 handler.
34
+ isValid?: (slug: string, req: ServerRequest) => boolean | Promise<boolean>;
31
35
  }
32
36
 
33
37
  export type PageProps = {