@torpor/build 0.4.14 → 1.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.
Files changed (193) hide show
  1. package/README.md +20 -2
  2. package/dist/Jsonify-Dg6gChd3.d.mts +10 -0
  3. package/dist/Jsonify-Dg6gChd3.d.mts.map +1 -0
  4. package/dist/ParseRouteParams-DBmqlmLh.d.mts +42 -0
  5. package/dist/ParseRouteParams-DBmqlmLh.d.mts.map +1 -0
  6. package/dist/{RouteType-B6BMOyYw.mjs → Router-C4ADUfhv.mjs} +30 -42
  7. package/dist/Router-C4ADUfhv.mjs.map +1 -0
  8. package/dist/Server-BnjLJleZ.mjs +104 -0
  9. package/dist/Server-BnjLJleZ.mjs.map +1 -0
  10. package/dist/Server-Cler2w5O.d.mts +61 -0
  11. package/dist/Server-Cler2w5O.d.mts.map +1 -0
  12. package/dist/ServerEvent-CTx3Q-hk.d.mts +48 -0
  13. package/dist/ServerEvent-CTx3Q-hk.d.mts.map +1 -0
  14. package/dist/{ServerEvent-CxPwA4lH.mjs → ServerEvent-Dljn5i7A.mjs} +37 -11
  15. package/dist/ServerEvent-Dljn5i7A.mjs.map +1 -0
  16. package/dist/Site-CE0_o5Ci.d.mts +566 -0
  17. package/dist/Site-CE0_o5Ci.d.mts.map +1 -0
  18. package/dist/StandardSchema-D28L8_zZ.d.mts +100 -0
  19. package/dist/StandardSchema-D28L8_zZ.d.mts.map +1 -0
  20. package/dist/TypedResponse-6lznqN4U.d.mts +22 -0
  21. package/dist/TypedResponse-6lznqN4U.d.mts.map +1 -0
  22. package/dist/{_page-BQs4WvCO.mjs → _page-4cQKs_Dn.mjs} +3 -5
  23. package/dist/_page-4cQKs_Dn.mjs.map +1 -0
  24. package/dist/bin/index.d.mts +1 -1
  25. package/dist/bin/index.js +15 -11
  26. package/dist/bin/index.js.map +1 -1
  27. package/dist/clientEntry.d.mts +1 -0
  28. package/dist/clientEntry.mjs +59 -0
  29. package/dist/clientEntry.mjs.map +1 -0
  30. package/dist/clientEntryDev.d.mts +1 -0
  31. package/dist/clientEntryDev.mjs +7 -0
  32. package/dist/clientEntryDev.mjs.map +1 -0
  33. package/dist/dev.d.mts +3 -0
  34. package/dist/dev.mjs +3 -0
  35. package/dist/endpoint-EULRGCKA.mjs +108 -0
  36. package/dist/endpoint-EULRGCKA.mjs.map +1 -0
  37. package/dist/flattenHeaders-DM5qsSqO.mjs +13 -0
  38. package/dist/flattenHeaders-DM5qsSqO.mjs.map +1 -0
  39. package/dist/form.d.mts +35 -0
  40. package/dist/form.d.mts.map +1 -0
  41. package/dist/form.mjs +48 -0
  42. package/dist/form.mjs.map +1 -0
  43. package/dist/index.d.mts +72 -156
  44. package/dist/index.d.mts.map +1 -1
  45. package/dist/index.mjs +158 -26
  46. package/dist/index.mjs.map +1 -1
  47. package/dist/load-BntzvmwL.mjs +228 -0
  48. package/dist/load-BntzvmwL.mjs.map +1 -0
  49. package/dist/nav.d.mts +58 -5
  50. package/dist/nav.d.mts.map +1 -1
  51. package/dist/nav.mjs +63 -209
  52. package/dist/nav.mjs.map +1 -1
  53. package/dist/openapi.d.mts +144 -0
  54. package/dist/openapi.d.mts.map +1 -0
  55. package/dist/openapi.mjs +2 -0
  56. package/dist/pathTrie-D4Ax2Mu9.mjs +160 -0
  57. package/dist/pathTrie-D4Ax2Mu9.mjs.map +1 -0
  58. package/dist/plugin-D8Www11B.mjs +202 -0
  59. package/dist/plugin-D8Www11B.mjs.map +1 -0
  60. package/dist/{response-C5TtAsh1.mjs → response-Bg4w2S1q.mjs} +16 -39
  61. package/dist/response-Bg4w2S1q.mjs.map +1 -0
  62. package/dist/response.d.mts +309 -289
  63. package/dist/response.d.mts.map +1 -1
  64. package/dist/response.mjs +3 -4
  65. package/dist/run.d.mts +11 -4
  66. package/dist/run.d.mts.map +1 -1
  67. package/dist/run.mjs +2 -8
  68. package/dist/runOpenApi-DlOgF2Il.mjs +1419 -0
  69. package/dist/runOpenApi-DlOgF2Il.mjs.map +1 -0
  70. package/dist/schema.d.mts +32 -0
  71. package/dist/schema.d.mts.map +1 -0
  72. package/dist/schema.mjs +2 -0
  73. package/dist/server/Server.d.mts +2 -0
  74. package/dist/server/Server.mjs +2 -0
  75. package/dist/server.d.mts +11 -8
  76. package/dist/server.d.mts.map +1 -1
  77. package/dist/server.mjs +133 -4
  78. package/dist/server.mjs.map +1 -0
  79. package/dist/serverEntry-1qY3wZig.mjs +351 -0
  80. package/dist/serverEntry-1qY3wZig.mjs.map +1 -0
  81. package/dist/serverEntry-BAO8m03V.d.mts +6 -0
  82. package/dist/serverEntry-BAO8m03V.d.mts.map +1 -0
  83. package/dist/serverEntry.d.mts +2 -0
  84. package/dist/serverEntry.mjs +2 -0
  85. package/dist/state.d.mts.map +1 -1
  86. package/dist/state.mjs +2 -3
  87. package/dist/test.d.mts +8 -10
  88. package/dist/test.d.mts.map +1 -1
  89. package/dist/test.mjs +181 -79
  90. package/dist/test.mjs.map +1 -1
  91. package/dist/{seeOther-B4Yhu9iq.mjs → unprocessable-DAZbrDeR.mjs} +34 -13
  92. package/dist/unprocessable-DAZbrDeR.mjs.map +1 -0
  93. package/dist/validate-Ok4krlkX.mjs +40 -0
  94. package/dist/validate-Ok4krlkX.mjs.map +1 -0
  95. package/package.json +30 -18
  96. package/dist/RouteType-B6BMOyYw.mjs.map +0 -1
  97. package/dist/Server-CF5wDJp6.d.mts +0 -78
  98. package/dist/Server-CF5wDJp6.d.mts.map +0 -1
  99. package/dist/ServerEvent-CxPwA4lH.mjs.map +0 -1
  100. package/dist/Site-DgC6WWn1.d.mts +0 -78
  101. package/dist/Site-DgC6WWn1.d.mts.map +0 -1
  102. package/dist/_page-BQs4WvCO.mjs.map +0 -1
  103. package/dist/connectMiddleware-D7nehjj3.mjs +0 -252
  104. package/dist/connectMiddleware-D7nehjj3.mjs.map +0 -1
  105. package/dist/pathToRegex-TUAMc3zS.mjs +0 -11
  106. package/dist/pathToRegex-TUAMc3zS.mjs.map +0 -1
  107. package/dist/response-C5TtAsh1.mjs.map +0 -1
  108. package/dist/run-BPFtSYA3.mjs +0 -332
  109. package/dist/run-BPFtSYA3.mjs.map +0 -1
  110. package/dist/seeOther-B4Yhu9iq.mjs.map +0 -1
  111. package/src/bin/index.ts +0 -11
  112. package/src/index.ts +0 -30
  113. package/src/nav/formSubmit.ts +0 -56
  114. package/src/nav/load.ts +0 -9
  115. package/src/nav/loadData.ts +0 -134
  116. package/src/nav/navigate.ts +0 -164
  117. package/src/nav/reload.ts +0 -9
  118. package/src/nav.ts +0 -4
  119. package/src/response/badRequest.ts +0 -19
  120. package/src/response/created.ts +0 -20
  121. package/src/response/forbidden.ts +0 -21
  122. package/src/response/found.ts +0 -30
  123. package/src/response/methodNotAllowed.ts +0 -18
  124. package/src/response/movedPermanently.ts +0 -25
  125. package/src/response/notFound.ts +0 -24
  126. package/src/response/notModified.ts +0 -34
  127. package/src/response/ok.ts +0 -29
  128. package/src/response/permanentRedirect.ts +0 -30
  129. package/src/response/response.ts +0 -22
  130. package/src/response/seeOther.ts +0 -19
  131. package/src/response/serverError.ts +0 -24
  132. package/src/response/temporaryRedirect.ts +0 -31
  133. package/src/response/transfer.ts +0 -14
  134. package/src/response/unauthorized.ts +0 -21
  135. package/src/response/unprocessable.ts +0 -18
  136. package/src/response.ts +0 -37
  137. package/src/run/prepareTemplate.ts +0 -39
  138. package/src/run/run.ts +0 -62
  139. package/src/run/runBuild.ts +0 -77
  140. package/src/run/runDev.ts +0 -89
  141. package/src/run/runPreview.ts +0 -93
  142. package/src/run.ts +0 -6
  143. package/src/server/CookieHelper.ts +0 -36
  144. package/src/server/HeaderHelper.ts +0 -25
  145. package/src/server/Routerx.ts +0 -72
  146. package/src/server/Server.ts +0 -144
  147. package/src/server/ServerEvent.ts +0 -39
  148. package/src/server/connect/bufferToArrayBuffer.ts +0 -8
  149. package/src/server/connect/connectMiddleware.ts +0 -81
  150. package/src/server/connect/flattenHeaders.ts +0 -44
  151. package/src/server/connect/nodeMessageToNodeResponse.ts +0 -89
  152. package/src/server/connect/readableToBuffer.ts +0 -16
  153. package/src/server/connect/requestToNodeMessage.ts +0 -26
  154. package/src/server/contentType.ts +0 -85
  155. package/src/server/types/HttpMethod.ts +0 -12
  156. package/src/server/types/MiddlewareFunction.ts +0 -8
  157. package/src/server/types/ServerFunction.ts +0 -7
  158. package/src/server.ts +0 -7
  159. package/src/site/Router.ts +0 -164
  160. package/src/site/Site.ts +0 -214
  161. package/src/site/clientEntry.ts +0 -108
  162. package/src/site/clientEntryDev.ts +0 -3
  163. package/src/site/defaultAdapter.ts +0 -11
  164. package/src/site/manifest.ts +0 -54
  165. package/src/site/serverEntry.ts +0 -439
  166. package/src/state/$page.ts +0 -24
  167. package/src/state/client.ts +0 -15
  168. package/src/state.ts +0 -3
  169. package/src/test/runTest.ts +0 -350
  170. package/src/test.ts +0 -3
  171. package/src/types/Adapter.ts +0 -8
  172. package/src/types/ClientState.ts +0 -8
  173. package/src/types/InternalState.ts +0 -7
  174. package/src/types/LayoutHandler.ts +0 -5
  175. package/src/types/LayoutPath.ts +0 -10
  176. package/src/types/ManifestRoute.ts +0 -6
  177. package/src/types/PageEndPoint.ts +0 -39
  178. package/src/types/PageLoadEvent.ts +0 -14
  179. package/src/types/PageServerAction.ts +0 -7
  180. package/src/types/PageServerEndPoint.ts +0 -16
  181. package/src/types/PageServerLoad.ts +0 -7
  182. package/src/types/PageState.ts +0 -8
  183. package/src/types/Route.ts +0 -11
  184. package/src/types/RouteHandler.ts +0 -16
  185. package/src/types/RouteLayoutHandler.ts +0 -5
  186. package/src/types/RouteMatchResult.ts +0 -7
  187. package/src/types/RouteType.ts +0 -19
  188. package/src/types/ServerEndPoint.ts +0 -37
  189. package/src/types/ServerHook.ts +0 -11
  190. package/src/types/ServerLoadEvent.ts +0 -37
  191. package/src/types/ServerRequest.ts +0 -7
  192. package/src/utils/pathToRegex.ts +0 -15
  193. package/src/vite-env.d.ts +0 -2
package/dist/index.d.mts CHANGED
@@ -1,7 +1,8 @@
1
- import { a as CookieHelper, i as HeaderHelper } from "./Server-CF5wDJp6.mjs";
2
- import { n as Adapter, t as Site } from "./Site-DgC6WWn1.mjs";
3
- import { Component } from "@torpor/view";
4
-
1
+ import { a as RouteParamsOf, i as RouteArgsOf, n as ParseRouteParams, r as RouteArgs } from "./ParseRouteParams-DBmqlmLh.mjs";
2
+ import { C as ServerLoadEvent, S as QueryRecord, _ as PageLoadEvent, a as ServerEndPoint, b as ServerHook, c as ActionBody, d as PageServerActionSchemas, f as PageServerEndPoint, g as PageLoadReturn, h as PageEndPoint, i as SchemaQuery, l as LoadParams, m as PageServerAction, n as ParamsOf, o as ServerEndPointSchemas, p as PageServerLoad, r as SchemaBody, s as ServerRequest, t as Site, u as LoadQuery, v as SitePlugin, x as FormDataRecord, y as Adapter } from "./Site-CE0_o5Ci.mjs";
3
+ import { n as UntypedResponse, t as TypedResponse } from "./TypedResponse-6lznqN4U.mjs";
4
+ import { t as StandardSchemaV1 } from "./StandardSchema-D28L8_zZ.mjs";
5
+ import { t as Jsonify } from "./Jsonify-Dg6gChd3.mjs";
5
6
  //#region src/types/ManifestRoute.d.ts
6
7
  interface ManifestRoute {
7
8
  path: string;
@@ -19,8 +20,8 @@ interface RouteLayoutHandler {
19
20
  //#endregion
20
21
  //#region src/types/RouteHandler.d.ts
21
22
  /**
22
- * A handler for a route in the Router.
23
- */
23
+ * A handler for a route in the Router.
24
+ */
24
25
  interface RouteHandler {
25
26
  path: string;
26
27
  type: number;
@@ -29,13 +30,16 @@ interface RouteHandler {
29
30
  loaded?: boolean;
30
31
  layouts?: RouteLayoutHandler[];
31
32
  serverEndPoint?: () => Promise<any>;
32
- serverHook?: () => Promise<any>;
33
+ serverHooks?: (() => Promise<any>)[];
34
+ modulePromise?: Promise<any>;
35
+ resolvedModule?: any;
36
+ resolvedHooks?: Promise<ServerHook[]>;
33
37
  }
34
38
  //#endregion
35
39
  //#region src/site/Router.d.ts
36
40
  /**
37
- * A router that handles file routes with layouts, hooks, etc.
38
- */
41
+ * A router that handles file routes with layouts, hooks, etc.
42
+ */
39
43
  declare class Router {
40
44
  #private;
41
45
  routes: Route[];
@@ -46,7 +50,6 @@ declare class Router {
46
50
  }
47
51
  declare class Route {
48
52
  path: string;
49
- regex: RegExp;
50
53
  handler: RouteHandler;
51
54
  constructor(path: string, handler: RouteHandler);
52
55
  }
@@ -56,158 +59,71 @@ interface RouteMatch {
56
59
  query: URLSearchParams;
57
60
  }
58
61
  //#endregion
59
- //#region src/types/PageLoadEvent.d.ts
60
- interface PageLoadEvent {
61
- /**
62
- * The URL for the server function.
63
- */
64
- url: URL;
65
- /**
66
- * Route params from the URL and route path.
67
- */
68
- params: Record<string, string>;
69
- /**
70
- * Data that is (optionally) loaded from the load function and passed into the page as $props.data.
71
- */
72
- data: Record<string, any>;
73
- }
74
- //#endregion
75
- //#region src/types/PageEndPoint.d.ts
62
+ //#region src/types/PageData.d.ts
76
63
  /**
77
- * For +page.
78
- */
79
- interface PageEndPoint {
80
- /**
81
- * Builds the route path for the page in a type-safe manner.
82
- * TODO: Not sure this is actually the best way to do it...
83
- */
84
- route?: (...args: any[]) => string;
85
- /**
86
- * Loads data for the page.
87
- */
88
- load?: (event: PageLoadEvent) => Response | undefined | void | Promise<Response | undefined | void>;
89
- /**
90
- * The component that is displayed for the page.
91
- */
92
- component?: Component;
93
- /**
94
- * The head element data for the page, which may include a <title> and <meta> elements.
95
- */
96
- head?: HeadElement[] | ((event: PageLoadEvent) => HeadElement[]);
97
- }
98
- type HeadElement = TitleElement | MetaElement;
99
- interface TitleElement {
100
- title: string;
101
- }
102
- interface MetaElement {
103
- name: string;
104
- content: string;
105
- }
106
- //#endregion
107
- //#region src/types/ServerLoadEvent.d.ts
108
- interface ServerLoadEvent {
109
- /**
110
- * The URL for the server function.
111
- */
112
- url: URL;
113
- /**
114
- * Route params from the URL and route path.
115
- */
116
- params: Record<string, string>;
117
- /**
118
- * Data that is available to functions in +server hooks, layouts, endpoints
119
- * and pages. It flows down in that order.
120
- */
121
- appData: Record<string, any>;
122
- /**
123
- * The server request.
124
- */
125
- request: Request;
126
- /**
127
- * A helper for getting and setting cookie data.
128
- */
129
- cookies: CookieHelper;
130
- /**
131
- * A helper for getting and setting headers.
132
- */
133
- headers: HeaderHelper;
134
- /**
135
- * An optional adapter object, containing adapter-specific functionality.
136
- */
137
- adapter: Record<PropertyKey, any>;
138
- }
139
- //#endregion
140
- //#region src/types/PageServerAction.d.ts
141
- type PageServerAction = (event: ServerLoadEvent) => Response | undefined | void | Promise<Response | undefined | void>;
142
- //#endregion
143
- //#region src/types/PageServerLoad.d.ts
144
- type PageServerLoad = (event: ServerLoadEvent) => Response | undefined | void | Promise<Response | undefined | void>;
145
- //#endregion
146
- //#region src/types/PageServerEndPoint.d.ts
64
+ * The page data produced by an endpoint's `load` function, e.g.
65
+ *
66
+ * ```ts
67
+ * import type server from "./+page.server";
68
+ * type Data = PageData<typeof server>;
69
+ * ```
70
+ *
71
+ * Falls back to a loose record when the endpoint has no load or its load
72
+ * returns untyped responses.
73
+ */
74
+ type PageData<EndPoint> = EndPoint extends {
75
+ load?: (event: any) => infer Return;
76
+ } ? NonNullable<Awaited<Return>> extends TypedResponse<infer Body> ? Body : Record<string, any> : Record<string, any>;
147
77
  /**
148
- * For +page.server.
149
- */
150
- interface PageServerEndPoint {
151
- /**
152
- * Loads data from the server for a page.
153
- */
154
- load?: PageServerLoad;
155
- /**
156
- * A map of actions that can be performed on the server for a page, generally from a form submit.
157
- */
158
- actions?: Record<string, PageServerAction>;
159
- }
78
+ * The merged page data for a page that sits under one or more layouts: pass
79
+ * the layout endpoints first and the page endpoint last, e.g.
80
+ *
81
+ * ```ts
82
+ * import type layoutServer from "../_layout.server";
83
+ * import type server from "./+page.server";
84
+ * type Data = MergePageData<typeof layoutServer, typeof server>;
85
+ * ```
86
+ *
87
+ * Each endpoint's data is intersected in order; endpoints without a typed
88
+ * `load` contribute nothing but looseness.
89
+ */
90
+ type MergePageData<EndPoints extends any[]> = EndPoints extends [infer First, ...infer Rest] ? PageData<First> & MergePageData<Rest> : unknown;
160
91
  //#endregion
161
- //#region src/types/ServerRequest.d.ts
162
- type ServerRequest = (event: ServerLoadEvent) => Response | undefined | void | Promise<Response | undefined | void>;
163
- //#endregion
164
- //#region src/types/ServerEndPoint.d.ts
92
+ //#region src/types/PageForm.d.ts
93
+ /** The non-undefined return values of an endpoint's actions. */
94
+ type ActionReturns<Actions> = { [K in keyof Actions]: Actions[K] extends ((event: any) => infer Return) ? NonNullable<Awaited<Return>> : never; }[keyof Actions];
165
95
  /**
166
- * For +server.
167
- */
168
- type ServerEndPoint = {
169
- [key: string]: ServerRequest;
170
- } & {
171
- /**
172
- * Performs a GET.
173
- */
174
- get?: ServerRequest;
175
- /**
176
- * Performs a POST.
177
- */
178
- post?: ServerRequest;
179
- /**
180
- * Performs a PATCH.
181
- */
182
- patch?: ServerRequest;
183
- /**
184
- * Performs a PUT.
185
- */
186
- put?: ServerRequest;
187
- /**
188
- * Performs a DELETE.
189
- */
190
- del?: ServerRequest;
191
- /**
192
- * Performs an OPTIONS request.
193
- */
194
- options?: ServerRequest;
195
- /**
196
- * Performs a HEAD request.
197
- */
198
- head?: ServerRequest;
199
- };
96
+ * The form result an endpoint's actions produce, i.e. what becomes the page's
97
+ * `$props.form` after a submit, e.g.
98
+ *
99
+ * ```ts
100
+ * import type server from "./+page.server";
101
+ * type Form = PageForm<typeof server>;
102
+ * ```
103
+ *
104
+ * Actions returning typed responses (e.g. `ok({ ... })`, `badRequest({ ... })`)
105
+ * contribute their JSON bodies as a union. Falls back to a loose record when
106
+ * there are no actions or their responses are untyped.
107
+ */
108
+ type PageForm<EndPoint> = EndPoint extends {
109
+ actions?: infer Actions;
110
+ } ? [NonNullable<Actions>] extends [never] ? Record<string, any> : ActionReturns<NonNullable<Actions>> extends TypedResponse<infer Body> ? Body : Record<string, any> : Record<string, any>;
200
111
  //#endregion
201
- //#region src/types/ServerHook.d.ts
112
+ //#region src/types/PageProps.d.ts
202
113
  /**
203
- * For _hook.server.
204
- */
205
- interface ServerHook {
206
- /**
207
- * Called on each server request.
208
- */
209
- handle?: (event: ServerLoadEvent) => Promise<void> | void;
114
+ * The props passed to a page (or layout) component: the data accumulated from
115
+ * load functions, plus the result of the last form action if any.
116
+ */
117
+ interface PageProps<Data = Record<string, any>, Form = Record<string, any>> {
118
+ /**
119
+ * Data loaded by the page's (and its layouts') load functions.
120
+ */
121
+ data: Data;
122
+ /**
123
+ * The JSON result of the last form action, if a form was submitted.
124
+ */
125
+ form: Form | undefined;
210
126
  }
211
127
  //#endregion
212
- export { type Adapter, type PageEndPoint, type PageLoadEvent, type PageServerAction, type PageServerEndPoint, type PageServerLoad, Router, type ServerEndPoint, type ServerHook, type ServerLoadEvent, type ServerRequest, Site };
128
+ export { type ActionBody, type Adapter, type FormDataRecord, type Jsonify, type LoadParams, type LoadQuery, type MergePageData, type PageData, type PageEndPoint, type PageForm, type PageLoadEvent, type PageLoadReturn, type PageProps, type PageServerAction, type PageServerActionSchemas, type PageServerEndPoint, type PageServerLoad, type ParamsOf, type ParseRouteParams, type QueryRecord, type RouteArgs, type RouteArgsOf, type RouteParamsOf, Router, type SchemaBody, type SchemaQuery, type ServerEndPoint, type ServerEndPointSchemas, type ServerHook, type ServerLoadEvent, type ServerRequest, Site, type SitePlugin, type StandardSchemaV1, type TypedResponse, type UntypedResponse };
213
129
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/ManifestRoute.ts","../src/types/RouteLayoutHandler.ts","../src/types/RouteHandler.ts","../src/site/Router.ts","../src/types/PageLoadEvent.ts","../src/types/PageEndPoint.ts","../src/types/ServerLoadEvent.ts","../src/types/PageServerAction.ts","../src/types/PageServerLoad.ts","../src/types/PageServerEndPoint.ts","../src/types/ServerRequest.ts","../src/types/ServerEndPoint.ts","../src/types/ServerHook.ts"],"sourcesContent":[],"mappings":";;;;;UAAyB,aAAA;;;kBAGR;;;;;UCHQ,kBAAA;;kBAER;yBACO;;;;;;;UCEC,YAAA;MFLA,EAAA,MAAA;;kBEQR;;QDRQ,CAAA,EAAA,OAAA;YCYd;yBACa;qBACJ;AAdgB;;;;;;AFAX,cGQJ,MAAA,CHRI;;UGShB;;UFTgB,CAAA,MAAA,EEkBP,aFlBO,EAAA,CAAA,EAAA,IAER;sDEgCoC;6BAuBzB,kBAAkB;;ADzDV,cCmJ9B,KAAA,CD9ImB;EAGR,IAAA,EAAA,MAAA;EAIN,KAAA,ECyIH,MDzIG;EACa,OAAA,ECyId,YDzIc;EACJ,WAAA,CAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EC0IgB,YD1IhB;;UCiJV,UAAA;WACA;WACA;EA/JoB,KAMT,EA0Jb,eA1Ja;;;;UCRI,aAAA;;;;OAInB;;;;UAIG;;;;QAIF;AFZ6B;;;;;;AFAX,UKMA,YAAA,CLHR;;;;;;;;AEHmB;EAQnB,IAAA,CAAA,EAAA,CAAA,KAAA,EGQR,aHRQ,EAAA,GGSX,QHTW,GAAA,SAAA,GAAA,IAAA,GGSmB,OHTnB,CGS2B,QHT3B,GAAA,SAAA,GAAA,IAAA,CAAA;EAIN;;;EAES,SAAA,CAAA,EGOP,SHPO;;;;ECZU,IAMT,CAAA,EEkBb,WFlBa,EAAA,GAAA,CAAA,CAAA,KAAA,EEkBY,aFlBZ,EAAA,GEkB8B,WFlB9B,EAAA,CAAA;;AACZ,KEoBJ,WAAA,GAAc,YFpBV,GEoByB,WFpBzB;UEsBC,YAAA,CFbQ;EAgBmC,KAAA,EAAA,MAAA;;UEC3C,WAAA,CFsBoC;EAAA,IAAA,EAAA,MAAA;EAAA,OA0FxC,EAAA,MAAA;;;;UGhJmB,eAAA;;;;OAInB;;;;UAIG;;;AJX2B;;EAYzB,OAAA,EIMD,MJNC,CAAA,MAAA,EAAA,GAAA,CAAA;EACa;;;WISd;;;AHpBoB;EAOrB,OAAA,EGkBC,YHlBD;EASS;;;EAuC4B,OAAA,EG1BpC,YH0BoC;EAAA;AAAA;;EA6FpC,OAAA,EGnHA,MHmHA,CGnHO,WHmHP,EAAA,GAAA,CAAA;;;;KIpJL,gBAAA,WACG,oBACH,8BAA8B,QAAQ;;;KCFtC,cAAA,WACG,oBACH,8BAA8B,QAAQ;;;;;;ARJlB,USMA,kBAAA,CTHR;;;;MCHQ,CAAA,EQUjB,cRViB;;;;ECAW,OAKX,CAAA,EOSd,MPTc,CAAA,MAAA,EOSC,gBPTD,CAAA;;;;KQHpB,aAAA,WACG,oBACH,8BAA8B,QAAQ;;;;;;KCCtC,cAAA;MXLoB,EAAA,MAAA,CAAA,EWKc,aXLd;;;;;QWSlB;;;ATT6B;EAQnB,IAAA,CAAA,ESKT,aTLS;EAIN;;;EAES,KAAA,CAAA,ESGX,aTHW;;;;ECZU,GAMT,CAAA,EQad,aRbc;EACZ;;;EAgDmB,GAAA,CAAA,EQhCrB,aRgCqB;EAAkB;;AAAA;EA4FtC,OAAA,CAAA,EQxHG,aRwHH;EACE;;;EAE0B,IAO1B,CAAA,EQ9HF,aR8HE;CACA;;;;;;US3Je,UAAA;;;;mBAIP,oBAAoB"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/ManifestRoute.ts","../src/types/RouteLayoutHandler.ts","../src/types/RouteHandler.ts","../src/site/Router.ts","../src/types/PageData.ts","../src/types/PageForm.ts","../src/types/PageProps.ts"],"mappings":";;;;;;UAAyB;EACxB;EACA;EACA,gBAAgB;EAChB;;;;UCJwB;EACxB;EACA,gBAAgB;EAChB,uBAAuB;;;;;;;UCGC;EACxB;EACA;EACA,gBAAgB;EAChB;EAEA;EACA,UAAU;EACV,uBAAuB;EACvB,qBAAqB;EAIrB,gBAAgB;EAChB;EACA,gBAAgB,QAAQ;;;;;;;cCbJ;;EACpB,QAAQ;EAMR;EAOA,SAAS,QAAQ;EAQjB,QAAQ,cAAc,cAAc,gBAAgB,cAAc;EAuBlE,MAAM,cAAc,OAAO,kBAAkB;;cA2GxC;EACL;EACA,SAAS;EAET,YAAY,cAAc,SAAS;;UAM1B;EACT,SAAS;EACT,SAAS;EACT,OAAO;;;;;;;;;;;;;;;KChKI,SAAS,YAAY;EAAmB,QAAQ,qBAAqB;IAC9E,YAAY,QAAQ,iBAAiB,oBAAoB,QACxD,OACA,sBACD;;;;;;;;;;;;;;KAeS,cAAc,2BAA2B,yBAAyB,gBAAgB,QAC3F,SAAS,SAAS,cAAc;;;;KC9B9B,cAAc,cACjB,WAAW,UAAU,QAAQ,aAAY,qBAAqB,UAC5D,YAAY,QAAQ,0BAEhB;;;;;;;;;;;;;;KAeI,SAAS,YAAY;EAAmB,gBAAgB;KAChE,YAAY,4BACZ,sBACA,cAAc,YAAY,kBAAkB,oBAAoB,QAC/D,OACA,sBACF;;;;;;;UCxBsB,UAAU,OAAO,qBAAqB,OAAO;;;;EAIrE,MAAM;;;;EAIN,MAAM"}
package/dist/index.mjs CHANGED
@@ -1,15 +1,10 @@
1
- import "./pathToRegex-TUAMc3zS.mjs";
2
- import { a as LAYOUT_SERVER_ROUTE, c as SERVER_ROUTE, i as LAYOUT_ROUTE, l as Router, n as HOOK_ROUTE, o as PAGE_ROUTE, r as HOOK_SERVER_ROUTE, s as PAGE_SERVER_ROUTE, t as ERROR_ROUTE } from "./RouteType-B6BMOyYw.mjs";
1
+ import { t as Router } from "./Router-C4ADUfhv.mjs";
3
2
  import { promises } from "node:fs";
4
3
  import fpath from "node:path";
5
- import tsconfigPaths from "vite-tsconfig-paths";
6
-
7
4
  //#region src/site/defaultAdapter.ts
8
5
  const defaultAdapter = { serve: () => {
9
6
  console.log("An adapter needs to be set in site.config");
10
7
  } };
11
- var defaultAdapter_default = defaultAdapter;
12
-
13
8
  //#endregion
14
9
  //#region src/site/Site.ts
15
10
  /**
@@ -19,8 +14,18 @@ var defaultAdapter_default = defaultAdapter;
19
14
  var Site = class {
20
15
  root;
21
16
  routes = [];
22
- plugins = [tsconfigPaths({ loose: true })];
23
- adapter = defaultAdapter_default;
17
+ /**
18
+ * Torpor site plugins, run when the site config is loaded (for dev and
19
+ * build) and when the server starts up. Use these to register extra
20
+ * routes (e.g. `openApi()` from `@torpor/build/openapi`) or add other
21
+ * framework-level functionality
22
+ */
23
+ plugins = [];
24
+ /**
25
+ * Vite plugins to add to the client and server builds
26
+ */
27
+ vitePlugins = [];
28
+ adapter = defaultAdapter;
24
29
  /**
25
30
  * Extra inputs, as absolute file paths, that will be compiled with the
26
31
  * output. What you do with them after that is up to you. File paths ending
@@ -30,10 +35,36 @@ var Site = class {
30
35
  /**
31
36
  * Vite config options to merge with the standard Torpor build options.
32
37
  * `plugins` and `build.rollupOptions.input` will be overridden, so you
33
- * should set `Site.plugins` and `Site.inputs` instead. Other options may be
38
+ * should set `Site.vitePlugins` and `Site.inputs` instead. Other options may be
34
39
  * overridden or incompatible, so experimentation may be required
35
40
  */
36
41
  viteConfig;
42
+ /**
43
+ * The path to the site.config file. Set automatically by the CLI; used by
44
+ * the manifest plugin to import inline endpoints for server builds.
45
+ */
46
+ configFile;
47
+ /**
48
+ * A state map for plugins to store their configuration and state on the
49
+ * site, so that framework internals (e.g. the manifest plugin) and other
50
+ * plugins can read them back:
51
+ *
52
+ * ```ts
53
+ * const myKey = Symbol.for("my-plugin");
54
+ * site.pluginState.set(myKey, options);
55
+ * ```
56
+ *
57
+ * Prefer `Symbol.for("...")` keys (or plain strings) over `Symbol()`,
58
+ * because the user's config file and framework internals can be loaded as
59
+ * separate module instances -- registry symbols are shared across
60
+ * instances, `Symbol()` ones are not.
61
+ */
62
+ pluginState = /* @__PURE__ */ new Map();
63
+ /**
64
+ * Inline endpoints keyed by `"path:type"`. Populated by `addRoute` when
65
+ * the user passes an inline endpoint object instead of a file path.
66
+ */
67
+ inlineEndPoints = {};
37
68
  constructor() {
38
69
  this.root = process.cwd();
39
70
  }
@@ -88,26 +119,127 @@ var Site = class {
88
119
  }
89
120
  #routeType(file) {
90
121
  let routePath = file.replace(/^\//, "").replace(/(\.ts|\.js)$/, "");
91
- if (routePath.endsWith("+page")) return PAGE_ROUTE;
92
- else if (routePath.endsWith("+page.server")) return PAGE_SERVER_ROUTE;
93
- else if (routePath.endsWith("+server")) return SERVER_ROUTE;
94
- else if (routePath.endsWith("_layout")) return LAYOUT_ROUTE;
95
- else if (routePath.endsWith("_layout.server")) return LAYOUT_SERVER_ROUTE;
96
- else if (routePath.endsWith("_hook")) return HOOK_ROUTE;
97
- else if (routePath.endsWith("_hook.server")) return HOOK_SERVER_ROUTE;
98
- else if (routePath.endsWith("_error")) return ERROR_ROUTE;
122
+ if (routePath.endsWith("+page")) return 0;
123
+ else if (routePath.endsWith("+page.server")) return 1;
124
+ else if (routePath.endsWith("+server")) return 3;
125
+ else if (routePath.endsWith("_layout")) return 4;
126
+ else if (routePath.endsWith("_layout.server")) return 5;
127
+ else if (routePath.endsWith("_hook")) return 6;
128
+ else if (routePath.endsWith("_hook.server")) return 7;
129
+ else if (routePath.endsWith("_error")) return 8;
99
130
  return -1;
100
131
  }
101
132
  #routeTypeFromString(type) {
102
133
  switch (type) {
103
- case "+page": return PAGE_ROUTE;
104
- case "+page.server": return PAGE_SERVER_ROUTE;
105
- case "+server": return SERVER_ROUTE;
106
- case "_layout": return LAYOUT_ROUTE;
107
- case "_layout.server": return LAYOUT_SERVER_ROUTE;
108
- case "_hook": return HOOK_ROUTE;
109
- case "_hook.server": return HOOK_SERVER_ROUTE;
110
- case "_error": return ERROR_ROUTE;
134
+ case "+page": return 0;
135
+ case "+page.server": return 1;
136
+ case "+server": return 3;
137
+ case "_layout": return 4;
138
+ case "_layout.server": return 5;
139
+ case "_hook": return 6;
140
+ case "_hook.server": return 7;
141
+ case "_error": return 8;
142
+ }
143
+ }
144
+ /**
145
+ * Adds a route in code, without needing the standard file naming
146
+ * conventions (+page.ts, +page.server.ts, etc). This is useful for small
147
+ * sites with one or two pages.
148
+ *
149
+ * Any combination of options may be provided; each maps to the
150
+ * corresponding file-route type:
151
+ *
152
+ * - `page` — a `+page` (`.torp` component or `.ts`/`.js` `PageEndPoint`)
153
+ * - `pageServer` — a `+page.server` (`PageServerEndPoint`, file or inline)
154
+ * - `server` — a `+server` HTTP endpoint (`ServerEndPoint`, file or inline)
155
+ * - `layout` — a `_layout` (`.torp` component or `.ts`/`.js` `PageEndPoint`)
156
+ * - `layoutServer` — a `_layout.server` (`PageServerEndPoint`, file or inline)
157
+ * - `hookServer` — a `_hook.server` (`ServerHook`, file or inline)
158
+ * - `error` — an `_error` page (`.torp` component or `.ts`/`.js` `PageEndPoint`)
159
+ *
160
+ * Options that need a component (`page`, `layout`, `error`) must be file
161
+ * paths so the component is included in the client bundle. Server-only
162
+ * options (`pageServer`, `server`, `layoutServer`, `hookServer`) accept
163
+ * either a file path or an inline object; inline server code is kept out
164
+ * of the client bundle automatically.
165
+ *
166
+ * @example
167
+ * // A page with an inline server action
168
+ * site.addRoute("/", {
169
+ * page: "./src/Counter.torp",
170
+ * pageServer: { actions: { set: async ({ request }) => ok() } },
171
+ * });
172
+ * @example
173
+ * // A JSON API endpoint
174
+ * site.addRoute("/api/time", {
175
+ * server: { get: async () => ok({ time: Date.now() }) },
176
+ * });
177
+ * @example
178
+ * // A root layout, server hook, and error page
179
+ * site.addRoute("/", {
180
+ * layout: "./src/Layout.torp",
181
+ * hookServer: { enter: async (event) => {} },
182
+ * error: "./src/ErrorPage.torp",
183
+ * });
184
+ *
185
+ * @param path The route path, e.g. `/` or `/about`
186
+ * @param options File paths and/or inline endpoints for the route
187
+ * @param subFolder An optional subFolder for grouping routes
188
+ */
189
+ addRoute(path, options, subFolder) {
190
+ let normalizedSubFolder = subFolder;
191
+ if (normalizedSubFolder !== void 0 && !normalizedSubFolder.startsWith("/")) normalizedSubFolder = "/" + normalizedSubFolder;
192
+ let base = path.replace(/\/$/, "");
193
+ if (options.page !== void 0) this.#pushRoute(path, 0, options.page, normalizedSubFolder);
194
+ if (options.pageServer !== void 0) this.#pushRoute(`${base}/~server`, 1, options.pageServer, normalizedSubFolder);
195
+ if (options.server !== void 0) this.#pushRoute(path, 3, options.server, normalizedSubFolder);
196
+ if (options.layout !== void 0) this.#pushRoute(`${base}/_layout`, 4, options.layout, normalizedSubFolder);
197
+ if (options.layoutServer !== void 0) this.#pushRoute(`${base}/_layout/~server`, 5, options.layoutServer, normalizedSubFolder);
198
+ if (options.hookServer !== void 0) this.#pushRoute(`${base}/_hook/~server`, 7, options.hookServer, normalizedSubFolder);
199
+ if (options.error !== void 0) this.#pushRoute(`${base}/_error`, 8, options.error, normalizedSubFolder);
200
+ this.#sortRoutes();
201
+ }
202
+ /**
203
+ * Pushes a single route entry, handling both file-path and inline-endpoint
204
+ * targets. File paths are resolved relative to the site root; inline
205
+ * endpoints are also stored in `inlineEndPoints` keyed by `"path:type"`
206
+ * so the manifest plugin can resolve them at build time.
207
+ *
208
+ * If a route with the same path and type was already added, it is
209
+ * replaced, so that running a plugin twice (config load and server
210
+ * startup) doesn't add duplicate routes.
211
+ */
212
+ #pushRoute(routePath, type, target, subFolder) {
213
+ const index = this.routes.findIndex((r) => r.path === routePath && r.type === type);
214
+ if (typeof target === "string") {
215
+ let file = fpath.relative(this.root, fpath.resolve(this.root, target));
216
+ if (index >= 0) this.routes[index] = {
217
+ path: routePath,
218
+ file,
219
+ type,
220
+ subFolder
221
+ };
222
+ else this.routes.push({
223
+ path: routePath,
224
+ file,
225
+ type,
226
+ subFolder
227
+ });
228
+ } else {
229
+ let key = `${routePath}:${type}`;
230
+ this.inlineEndPoints[key] = target;
231
+ if (index >= 0) this.routes[index] = {
232
+ path: routePath,
233
+ endPoint: target,
234
+ type,
235
+ subFolder
236
+ };
237
+ else this.routes.push({
238
+ path: routePath,
239
+ endPoint: target,
240
+ type,
241
+ subFolder
242
+ });
111
243
  }
112
244
  }
113
245
  #sortRoutes() {
@@ -119,7 +251,7 @@ var Site = class {
119
251
  });
120
252
  }
121
253
  };
122
-
123
254
  //#endregion
124
255
  export { Router, Site };
256
+
125
257
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["defaultAdapter: Adapter","defaultAdapter","fs","#routePath","#routeType","#sortRoutes","#routeTypeFromString"],"sources":["../src/site/defaultAdapter.ts","../src/site/Site.ts"],"sourcesContent":["import type Adapter from \"../types/Adapter\";\n\n// TODO: This should be an adapter-auto package that conditionally loads other packages...\n\nconst defaultAdapter: Adapter = {\n\tserve: () => {\n\t\tconsole.log(\"An adapter needs to be set in site.config\");\n\t},\n};\n\nexport default defaultAdapter;\n","import { promises as fs } from \"node:fs\";\nimport fpath from \"node:path\";\nimport { type Plugin, type UserConfig } from \"vite\";\nimport tsconfigPaths from \"vite-tsconfig-paths\";\nimport type Adapter from \"../types/Adapter\";\nimport type Route from \"../types/Route\";\nimport {\n\tERROR_ROUTE,\n\tHOOK_ROUTE,\n\tHOOK_SERVER_ROUTE,\n\tLAYOUT_ROUTE,\n\tLAYOUT_SERVER_ROUTE,\n\tPAGE_ROUTE,\n\tPAGE_SERVER_ROUTE,\n\tRouteType,\n\tSERVER_ROUTE,\n} from \"../types/RouteType\";\nimport defaultAdapter from \"./defaultAdapter\";\n\n// 1. The user sets this up\n// 2. It is passed into serverEntry and clientEntry through a Vite plugin\n// (defined in manifest.ts)\n// 3. In those files, it is used to build a Router\n\n/**\n * The Site class contains the information necessary to setup a @torpor/build\n * site, including routes, plugins, and options.\n */\nexport default class Site {\n\troot: string;\n\troutes: Route[] = [];\n\t// Is default plugins a bad idea?\n\t// HACK: Set loose because otherwise it uses a list of allowed extensions\n\t// TODO: Should probably just do this ourselves and let the user pass in\n\t// tsconfigPaths themselves if they want to do something funky\n\tplugins: Plugin[] = [tsconfigPaths({ loose: true })];\n\t// Is default adapter a bad idea?\n\tadapter: Adapter = defaultAdapter;\n\t/**\n\t * Extra inputs, as absolute file paths, that will be compiled with the\n\t * output. What you do with them after that is up to you. File paths ending\n\t * with server.ts/js will only be compiled with the server output\n\t */\n\tinputs: string[] = [];\n\t/**\n\t * Vite config options to merge with the standard Torpor build options.\n\t * `plugins` and `build.rollupOptions.input` will be overridden, so you\n\t * should set `Site.plugins` and `Site.inputs` instead. Other options may be\n\t * overridden or incompatible, so experimentation may be required\n\t */\n\tviteConfig?: UserConfig;\n\n\tconstructor() {\n\t\tthis.root = process.cwd();\n\t}\n\n\t/**\n\t * Adds a folder of routes, based on the names of the files in the folder\n\t * @param folder The folder containing the routes\n\t * @param subFolder If a subFolder is set, all routes in the folder will be\n\t * placed under the subFolder, and only hooks, layouts etc will be used if\n\t * they have the same subFolder. This can be used to create e.g. an `api`\n\t * set of routes with their own hook for authorization from various clients\n\t */\n\tasync addRouteFolder(folder: string, subFolder?: string): Promise<void> {\n\t\tconst routeFolder = fpath.join(this.root, folder);\n\t\tconst routeFiles = await fs.readdir(routeFolder, { recursive: true });\n\t\tif (subFolder !== undefined && !subFolder.startsWith(\"/\")) {\n\t\t\tsubFolder = \"/\" + subFolder;\n\t\t}\n\t\tfor (let file of routeFiles) {\n\t\t\t// The file must start with `+` or `_` and end with `.js` or `.ts`\n\t\t\tif (/^(\\+|_).+(\\.js|\\.ts)$/.test(fpath.basename(file))) {\n\t\t\t\tlet routePath = this.#routePath(file);\n\t\t\t\tif (subFolder !== undefined) {\n\t\t\t\t\troutePath = subFolder + routePath;\n\t\t\t\t}\n\t\t\t\tlet type = this.#routeType(file);\n\t\t\t\tfile = fpath.relative(this.root, fpath.resolve(routeFolder, file));\n\t\t\t\tthis.routes.push({\n\t\t\t\t\tpath: routePath,\n\t\t\t\t\tfile,\n\t\t\t\t\ttype,\n\t\t\t\t\tsubFolder: subFolder,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis.#sortRoutes();\n\t}\n\n\t/**\n\t * Adds a file route, which can have a standard name (e.g. +page.ts) or any\n\t * name if you pass the type\n\t * @param path The route path\n\t * @param file The file\n\t * @param type The file type (if the file name is non-standard)\n\t */\n\taddRouteFile(\n\t\tpath: string,\n\t\tfile: string,\n\t\ttype?:\n\t\t\t| \"+page\"\n\t\t\t| \"+page.server\"\n\t\t\t| \"+server\"\n\t\t\t| \"_layout\"\n\t\t\t| \"_layout.server\"\n\t\t\t| \"_hook\"\n\t\t\t| \"_hook.server\"\n\t\t\t| \"_error\",\n\t\tsubFolder?: string,\n\t): void {\n\t\tlet routePath = this.#routePath(fpath.join(path, type ?? fpath.basename(file)));\n\t\tlet routeType = type ? this.#routeTypeFromString(type) : this.#routeType(file);\n\t\tif (subFolder !== undefined && !subFolder.startsWith(\"/\")) {\n\t\t\tsubFolder = \"/\" + subFolder;\n\t\t}\n\t\tthis.routes.push({\n\t\t\tpath: routePath,\n\t\t\tfile,\n\t\t\ttype: routeType,\n\t\t\tsubFolder: subFolder,\n\t\t});\n\t\tthis.#sortRoutes();\n\t}\n\n\t#routePath(file: string): string {\n\t\tlet routePath = file\n\t\t\t.replace(/^\\//, \"\")\n\t\t\t.replace(/(\\.ts|\\.js)$/, \"\")\n\t\t\t.replace(/_hook.server$/, \"_hook/~server\")\n\t\t\t.replace(/_layout.server$/, \"_layout/~server\")\n\t\t\t.replace(/\\+page.server$/, \"~server\")\n\t\t\t.replace(/\\+server$/, \"\")\n\t\t\t.replace(/\\+page$/, \"\")\n\t\t\t.replace(/\\/$/, \"\");\n\t\treturn routePath.length > 0 ? `/${routePath}` : \"/\";\n\t}\n\n\t#routeType(file: string): RouteType {\n\t\tlet routePath = file.replace(/^\\//, \"\").replace(/(\\.ts|\\.js)$/, \"\");\n\t\tif (routePath.endsWith(\"+page\")) {\n\t\t\treturn PAGE_ROUTE;\n\t\t} else if (routePath.endsWith(\"+page.server\")) {\n\t\t\treturn PAGE_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"+server\")) {\n\t\t\treturn SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout\")) {\n\t\t\treturn LAYOUT_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout.server\")) {\n\t\t\treturn LAYOUT_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook\")) {\n\t\t\treturn HOOK_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook.server\")) {\n\t\t\treturn HOOK_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_error\")) {\n\t\t\treturn ERROR_ROUTE;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t#routeTypeFromString(\n\t\ttype:\n\t\t\t| \"+page\"\n\t\t\t| \"+page.server\"\n\t\t\t| \"+server\"\n\t\t\t| \"_layout\"\n\t\t\t| \"_layout.server\"\n\t\t\t| \"_hook\"\n\t\t\t| \"_hook.server\"\n\t\t\t| \"_error\",\n\t) {\n\t\tswitch (type) {\n\t\t\tcase \"+page\":\n\t\t\t\treturn PAGE_ROUTE;\n\t\t\tcase \"+page.server\":\n\t\t\t\treturn PAGE_SERVER_ROUTE;\n\t\t\tcase \"+server\":\n\t\t\t\treturn SERVER_ROUTE;\n\t\t\tcase \"_layout\":\n\t\t\t\treturn LAYOUT_ROUTE;\n\t\t\tcase \"_layout.server\":\n\t\t\t\treturn LAYOUT_SERVER_ROUTE;\n\t\t\tcase \"_hook\":\n\t\t\t\treturn HOOK_ROUTE;\n\t\t\tcase \"_hook.server\":\n\t\t\t\treturn HOOK_SERVER_ROUTE;\n\t\t\tcase \"_error\":\n\t\t\t\treturn ERROR_ROUTE;\n\t\t}\n\t}\n\n\t// TODO: You could make your site in a single file, like e.g. Hono...\n\t//addPage(path: string, endPoint: PageEndPoint, serverEndPoint?: PageServerEndPoint) {}\n\t//addEndPoint(path: string, endPoint: ServerEndPoint) {}\n\n\t#sortRoutes() {\n\t\tthis.routes = this.routes.sort((a, b) => {\n\t\t\t// Sort [param]s after paths\n\t\t\t// There might be a quicker/easier way to do this\n\t\t\tfor (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {\n\t\t\t\tif (a.path[i] === \"[\" && b.path[i] !== \"[\") {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (b.path[i] === \"[\" && a.path[i] !== \"[\") {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (a.path[i] === b.path[i]) {\n\t\t\t\t\t// Keep going...\n\t\t\t\t} else {\n\t\t\t\t\treturn a.path[i].localeCompare(b.path[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn a.path.length - b.path.length;\n\t\t});\n\t}\n}\n"],"mappings":";;;;;;;AAIA,MAAMA,iBAA0B,EAC/B,aAAa;AACZ,SAAQ,IAAI,4CAA4C;GAEzD;AAED,6BAAe;;;;;;;;ACkBf,IAAqB,OAArB,MAA0B;CACzB;CACA,SAAkB,EAAE;CAKpB,UAAoB,CAAC,cAAc,EAAE,OAAO,MAAM,CAAC,CAAC;CAEpD,UAAmBC;;;;;;CAMnB,SAAmB,EAAE;;;;;;;CAOrB;CAEA,cAAc;AACb,OAAK,OAAO,QAAQ,KAAK;;;;;;;;;;CAW1B,MAAM,eAAe,QAAgB,WAAmC;EACvE,MAAM,cAAc,MAAM,KAAK,KAAK,MAAM,OAAO;EACjD,MAAM,aAAa,MAAMC,SAAG,QAAQ,aAAa,EAAE,WAAW,MAAM,CAAC;AACrE,MAAI,cAAc,UAAa,CAAC,UAAU,WAAW,IAAI,CACxD,aAAY,MAAM;AAEnB,OAAK,IAAI,QAAQ,WAEhB,KAAI,wBAAwB,KAAK,MAAM,SAAS,KAAK,CAAC,EAAE;GACvD,IAAI,YAAY,MAAKC,UAAW,KAAK;AACrC,OAAI,cAAc,OACjB,aAAY,YAAY;GAEzB,IAAI,OAAO,MAAKC,UAAW,KAAK;AAChC,UAAO,MAAM,SAAS,KAAK,MAAM,MAAM,QAAQ,aAAa,KAAK,CAAC;AAClE,QAAK,OAAO,KAAK;IAChB,MAAM;IACN;IACA;IACW;IACX,CAAC;;AAGJ,QAAKC,YAAa;;;;;;;;;CAUnB,aACC,MACA,MACA,MASA,WACO;EACP,IAAI,YAAY,MAAKF,UAAW,MAAM,KAAK,MAAM,QAAQ,MAAM,SAAS,KAAK,CAAC,CAAC;EAC/E,IAAI,YAAY,OAAO,MAAKG,oBAAqB,KAAK,GAAG,MAAKF,UAAW,KAAK;AAC9E,MAAI,cAAc,UAAa,CAAC,UAAU,WAAW,IAAI,CACxD,aAAY,MAAM;AAEnB,OAAK,OAAO,KAAK;GAChB,MAAM;GACN;GACA,MAAM;GACK;GACX,CAAC;AACF,QAAKC,YAAa;;CAGnB,WAAW,MAAsB;EAChC,IAAI,YAAY,KACd,QAAQ,OAAO,GAAG,CAClB,QAAQ,gBAAgB,GAAG,CAC3B,QAAQ,iBAAiB,gBAAgB,CACzC,QAAQ,mBAAmB,kBAAkB,CAC7C,QAAQ,kBAAkB,UAAU,CACpC,QAAQ,aAAa,GAAG,CACxB,QAAQ,WAAW,GAAG,CACtB,QAAQ,OAAO,GAAG;AACpB,SAAO,UAAU,SAAS,IAAI,IAAI,cAAc;;CAGjD,WAAW,MAAyB;EACnC,IAAI,YAAY,KAAK,QAAQ,OAAO,GAAG,CAAC,QAAQ,gBAAgB,GAAG;AACnE,MAAI,UAAU,SAAS,QAAQ,CAC9B,QAAO;WACG,UAAU,SAAS,eAAe,CAC5C,QAAO;WACG,UAAU,SAAS,UAAU,CACvC,QAAO;WACG,UAAU,SAAS,UAAU,CACvC,QAAO;WACG,UAAU,SAAS,iBAAiB,CAC9C,QAAO;WACG,UAAU,SAAS,QAAQ,CACrC,QAAO;WACG,UAAU,SAAS,eAAe,CAC5C,QAAO;WACG,UAAU,SAAS,SAAS,CACtC,QAAO;AAER,SAAO;;CAGR,qBACC,MASC;AACD,UAAQ,MAAR;GACC,KAAK,QACJ,QAAO;GACR,KAAK,eACJ,QAAO;GACR,KAAK,UACJ,QAAO;GACR,KAAK,UACJ,QAAO;GACR,KAAK,iBACJ,QAAO;GACR,KAAK,QACJ,QAAO;GACR,KAAK,eACJ,QAAO;GACR,KAAK,SACJ,QAAO;;;CAQV,cAAc;AACb,OAAK,SAAS,KAAK,OAAO,MAAM,GAAG,MAAM;AAGxC,QAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,OAAO,EAAE,IAC3D,KAAI,EAAE,KAAK,OAAO,OAAO,EAAE,KAAK,OAAO,IACtC,QAAO;YACG,EAAE,KAAK,OAAO,OAAO,EAAE,KAAK,OAAO,IAC7C,QAAO;YACG,EAAE,KAAK,OAAO,EAAE,KAAK,IAAI,OAGnC,QAAO,EAAE,KAAK,GAAG,cAAc,EAAE,KAAK,GAAG;AAG3C,UAAO,EAAE,KAAK,SAAS,EAAE,KAAK;IAC7B"}
1
+ {"version":3,"file":"index.mjs","names":["fs","#routePath","#routeType","#sortRoutes","#routeTypeFromString","#pushRoute"],"sources":["../src/site/defaultAdapter.ts","../src/site/Site.ts"],"sourcesContent":["import type Adapter from \"../types/Adapter\";\n\n// TODO: This should be an adapter-auto package that conditionally loads other packages...\n\nconst defaultAdapter: Adapter = {\n\tserve: () => {\n\t\tconsole.log(\"An adapter needs to be set in site.config\");\n\t},\n};\n\nexport default defaultAdapter;\n","import { promises as fs } from \"node:fs\";\nimport fpath from \"node:path\";\nimport { type Plugin, type UserConfig } from \"vite\";\nimport type Adapter from \"../types/Adapter\";\nimport type SitePlugin from \"../types/SitePlugin\";\nimport type { InlineEndPoint } from \"../types/Route\";\nimport type PageServerEndPoint from \"../types/PageServerEndPoint\";\nimport type Route from \"../types/Route\";\nimport type ServerEndPoint from \"../types/ServerEndPoint\";\nimport type ServerHook from \"../types/ServerHook\";\nimport {\n\tERROR_ROUTE,\n\tHOOK_ROUTE,\n\tHOOK_SERVER_ROUTE,\n\tLAYOUT_ROUTE,\n\tLAYOUT_SERVER_ROUTE,\n\tPAGE_ROUTE,\n\tPAGE_SERVER_ROUTE,\n\tRouteType,\n\tSERVER_ROUTE,\n} from \"../types/RouteType\";\nimport defaultAdapter from \"./defaultAdapter\";\n\n// 1. The user sets this up\n// 2. It is passed into serverEntry and clientEntry through a Vite plugin\n// (defined in manifest.ts)\n// 3. In those files, it is used to build a Router\n\n/**\n * The Site class contains the information necessary to setup a @torpor/build\n * site, including routes, plugins, and options.\n */\nexport default class Site {\n\troot: string;\n\troutes: Route[] = [];\n\t/**\n\t * Torpor site plugins, run when the site config is loaded (for dev and\n\t * build) and when the server starts up. Use these to register extra\n\t * routes (e.g. `openApi()` from `@torpor/build/openapi`) or add other\n\t * framework-level functionality\n\t */\n\tplugins: SitePlugin[] = [];\n\t/**\n\t * Vite plugins to add to the client and server builds\n\t */\n\tvitePlugins: Plugin[] = [];\n\t// Is default adapter a bad idea?\n\tadapter: Adapter = defaultAdapter;\n\t/**\n\t * Extra inputs, as absolute file paths, that will be compiled with the\n\t * output. What you do with them after that is up to you. File paths ending\n\t * with server.ts/js will only be compiled with the server output\n\t */\n\tinputs: string[] = [];\n\t/**\n\t * Vite config options to merge with the standard Torpor build options.\n\t * `plugins` and `build.rollupOptions.input` will be overridden, so you\n\t * should set `Site.vitePlugins` and `Site.inputs` instead. Other options may be\n\t * overridden or incompatible, so experimentation may be required\n\t */\n\tviteConfig?: UserConfig;\n\t/**\n\t * The path to the site.config file. Set automatically by the CLI; used by\n\t * the manifest plugin to import inline endpoints for server builds.\n\t */\n\tconfigFile?: string;\n\t/**\n\t * A state map for plugins to store their configuration and state on the\n\t * site, so that framework internals (e.g. the manifest plugin) and other\n\t * plugins can read them back:\n\t *\n\t * ```ts\n\t * const myKey = Symbol.for(\"my-plugin\");\n\t * site.pluginState.set(myKey, options);\n\t * ```\n\t *\n\t * Prefer `Symbol.for(\"...\")` keys (or plain strings) over `Symbol()`,\n\t * because the user's config file and framework internals can be loaded as\n\t * separate module instances -- registry symbols are shared across\n\t * instances, `Symbol()` ones are not.\n\t */\n\tpluginState: Map<PropertyKey, unknown> = new Map();\n\t/**\n\t * Inline endpoints keyed by `\"path:type\"`. Populated by `addRoute` when\n\t * the user passes an inline endpoint object instead of a file path.\n\t */\n\tinlineEndPoints: Record<string, InlineEndPoint> = {};\n\n\tconstructor() {\n\t\tthis.root = process.cwd();\n\t}\n\n\t/**\n\t * Adds a folder of routes, based on the names of the files in the folder\n\t * @param folder The folder containing the routes\n\t * @param subFolder If a subFolder is set, all routes in the folder will be\n\t * placed under the subFolder, and only hooks, layouts etc will be used if\n\t * they have the same subFolder. This can be used to create e.g. an `api`\n\t * set of routes with their own hook for authorization from various clients\n\t */\n\tasync addRouteFolder(folder: string, subFolder?: string): Promise<void> {\n\t\tconst routeFolder = fpath.join(this.root, folder);\n\t\tconst routeFiles = await fs.readdir(routeFolder, { recursive: true });\n\t\tif (subFolder !== undefined && !subFolder.startsWith(\"/\")) {\n\t\t\tsubFolder = \"/\" + subFolder;\n\t\t}\n\t\tfor (let file of routeFiles) {\n\t\t\t// The file must start with `+` or `_` and end with `.js` or `.ts`\n\t\t\tif (/^(\\+|_).+(\\.js|\\.ts)$/.test(fpath.basename(file))) {\n\t\t\t\tlet routePath = this.#routePath(file);\n\t\t\t\tif (subFolder !== undefined) {\n\t\t\t\t\troutePath = subFolder + routePath;\n\t\t\t\t}\n\t\t\t\tlet type = this.#routeType(file);\n\t\t\t\tfile = fpath.relative(this.root, fpath.resolve(routeFolder, file));\n\t\t\t\tthis.routes.push({\n\t\t\t\t\tpath: routePath,\n\t\t\t\t\tfile,\n\t\t\t\t\ttype,\n\t\t\t\t\tsubFolder: subFolder,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis.#sortRoutes();\n\t}\n\n\t/**\n\t * Adds a file route, which can have a standard name (e.g. +page.ts) or any\n\t * name if you pass the type\n\t * @param path The route path\n\t * @param file The file\n\t * @param type The file type (if the file name is non-standard)\n\t */\n\taddRouteFile(\n\t\tpath: string,\n\t\tfile: string,\n\t\ttype?:\n\t\t\t| \"+page\"\n\t\t\t| \"+page.server\"\n\t\t\t| \"+server\"\n\t\t\t| \"_layout\"\n\t\t\t| \"_layout.server\"\n\t\t\t| \"_hook\"\n\t\t\t| \"_hook.server\"\n\t\t\t| \"_error\",\n\t\tsubFolder?: string,\n\t): void {\n\t\tlet routePath = this.#routePath(fpath.join(path, type ?? fpath.basename(file)));\n\t\tlet routeType = type ? this.#routeTypeFromString(type) : this.#routeType(file);\n\t\tif (subFolder !== undefined && !subFolder.startsWith(\"/\")) {\n\t\t\tsubFolder = \"/\" + subFolder;\n\t\t}\n\t\tthis.routes.push({\n\t\t\tpath: routePath,\n\t\t\tfile,\n\t\t\ttype: routeType,\n\t\t\tsubFolder: subFolder,\n\t\t});\n\t\tthis.#sortRoutes();\n\t}\n\n\t#routePath(file: string): string {\n\t\tlet routePath = file\n\t\t\t.replace(/^\\//, \"\")\n\t\t\t.replace(/(\\.ts|\\.js)$/, \"\")\n\t\t\t.replace(/_hook.server$/, \"_hook/~server\")\n\t\t\t.replace(/_layout.server$/, \"_layout/~server\")\n\t\t\t.replace(/\\+page.server$/, \"~server\")\n\t\t\t.replace(/\\+server$/, \"\")\n\t\t\t.replace(/\\+page$/, \"\")\n\t\t\t.replace(/\\/$/, \"\");\n\t\treturn routePath.length > 0 ? `/${routePath}` : \"/\";\n\t}\n\n\t#routeType(file: string): RouteType {\n\t\tlet routePath = file.replace(/^\\//, \"\").replace(/(\\.ts|\\.js)$/, \"\");\n\t\tif (routePath.endsWith(\"+page\")) {\n\t\t\treturn PAGE_ROUTE;\n\t\t} else if (routePath.endsWith(\"+page.server\")) {\n\t\t\treturn PAGE_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"+server\")) {\n\t\t\treturn SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout\")) {\n\t\t\treturn LAYOUT_ROUTE;\n\t\t} else if (routePath.endsWith(\"_layout.server\")) {\n\t\t\treturn LAYOUT_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook\")) {\n\t\t\treturn HOOK_ROUTE;\n\t\t} else if (routePath.endsWith(\"_hook.server\")) {\n\t\t\treturn HOOK_SERVER_ROUTE;\n\t\t} else if (routePath.endsWith(\"_error\")) {\n\t\t\treturn ERROR_ROUTE;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t#routeTypeFromString(\n\t\ttype:\n\t\t\t| \"+page\"\n\t\t\t| \"+page.server\"\n\t\t\t| \"+server\"\n\t\t\t| \"_layout\"\n\t\t\t| \"_layout.server\"\n\t\t\t| \"_hook\"\n\t\t\t| \"_hook.server\"\n\t\t\t| \"_error\",\n\t) {\n\t\tswitch (type) {\n\t\t\tcase \"+page\":\n\t\t\t\treturn PAGE_ROUTE;\n\t\t\tcase \"+page.server\":\n\t\t\t\treturn PAGE_SERVER_ROUTE;\n\t\t\tcase \"+server\":\n\t\t\t\treturn SERVER_ROUTE;\n\t\t\tcase \"_layout\":\n\t\t\t\treturn LAYOUT_ROUTE;\n\t\t\tcase \"_layout.server\":\n\t\t\t\treturn LAYOUT_SERVER_ROUTE;\n\t\t\tcase \"_hook\":\n\t\t\t\treturn HOOK_ROUTE;\n\t\t\tcase \"_hook.server\":\n\t\t\t\treturn HOOK_SERVER_ROUTE;\n\t\t\tcase \"_error\":\n\t\t\t\treturn ERROR_ROUTE;\n\t\t}\n\t}\n\n\t/**\n\t * Adds a route in code, without needing the standard file naming\n\t * conventions (+page.ts, +page.server.ts, etc). This is useful for small\n\t * sites with one or two pages.\n\t *\n\t * Any combination of options may be provided; each maps to the\n\t * corresponding file-route type:\n\t *\n\t * - `page` — a `+page` (`.torp` component or `.ts`/`.js` `PageEndPoint`)\n\t * - `pageServer` — a `+page.server` (`PageServerEndPoint`, file or inline)\n\t * - `server` — a `+server` HTTP endpoint (`ServerEndPoint`, file or inline)\n\t * - `layout` — a `_layout` (`.torp` component or `.ts`/`.js` `PageEndPoint`)\n\t * - `layoutServer` — a `_layout.server` (`PageServerEndPoint`, file or inline)\n\t * - `hookServer` — a `_hook.server` (`ServerHook`, file or inline)\n\t * - `error` — an `_error` page (`.torp` component or `.ts`/`.js` `PageEndPoint`)\n\t *\n\t * Options that need a component (`page`, `layout`, `error`) must be file\n\t * paths so the component is included in the client bundle. Server-only\n\t * options (`pageServer`, `server`, `layoutServer`, `hookServer`) accept\n\t * either a file path or an inline object; inline server code is kept out\n\t * of the client bundle automatically.\n\t *\n\t * @example\n\t * // A page with an inline server action\n\t * site.addRoute(\"/\", {\n\t * page: \"./src/Counter.torp\",\n\t * pageServer: { actions: { set: async ({ request }) => ok() } },\n\t * });\n\t * @example\n\t * // A JSON API endpoint\n\t * site.addRoute(\"/api/time\", {\n\t * server: { get: async () => ok({ time: Date.now() }) },\n\t * });\n\t * @example\n\t * // A root layout, server hook, and error page\n\t * site.addRoute(\"/\", {\n\t * layout: \"./src/Layout.torp\",\n\t * hookServer: { enter: async (event) => {} },\n\t * error: \"./src/ErrorPage.torp\",\n\t * });\n\t *\n\t * @param path The route path, e.g. `/` or `/about`\n\t * @param options File paths and/or inline endpoints for the route\n\t * @param subFolder An optional subFolder for grouping routes\n\t */\n\taddRoute(\n\t\tpath: string,\n\t\toptions: {\n\t\t\tpage?: string;\n\t\t\tpageServer?: string | PageServerEndPoint;\n\t\t\tserver?: string | ServerEndPoint;\n\t\t\tlayout?: string;\n\t\t\tlayoutServer?: string | PageServerEndPoint;\n\t\t\thookServer?: string | ServerHook;\n\t\t\terror?: string;\n\t\t},\n\t\tsubFolder?: string,\n\t): void {\n\t\tlet normalizedSubFolder = subFolder;\n\t\tif (normalizedSubFolder !== undefined && !normalizedSubFolder.startsWith(\"/\")) {\n\t\t\tnormalizedSubFolder = \"/\" + normalizedSubFolder;\n\t\t}\n\n\t\t// The base path with any trailing slash stripped, so that we can\n\t\t// append \"/_layout\", \"/~server\" etc. For the root \"/\" this is \"\".\n\t\tlet base = path.replace(/\\/$/, \"\");\n\n\t\tif (options.page !== undefined) {\n\t\t\tthis.#pushRoute(path, PAGE_ROUTE, options.page, normalizedSubFolder);\n\t\t}\n\t\tif (options.pageServer !== undefined) {\n\t\t\tthis.#pushRoute(\n\t\t\t\t`${base}/~server`,\n\t\t\t\tPAGE_SERVER_ROUTE,\n\t\t\t\toptions.pageServer,\n\t\t\t\tnormalizedSubFolder,\n\t\t\t);\n\t\t}\n\t\tif (options.server !== undefined) {\n\t\t\tthis.#pushRoute(path, SERVER_ROUTE, options.server, normalizedSubFolder);\n\t\t}\n\t\tif (options.layout !== undefined) {\n\t\t\tthis.#pushRoute(`${base}/_layout`, LAYOUT_ROUTE, options.layout, normalizedSubFolder);\n\t\t}\n\t\tif (options.layoutServer !== undefined) {\n\t\t\tthis.#pushRoute(\n\t\t\t\t`${base}/_layout/~server`,\n\t\t\t\tLAYOUT_SERVER_ROUTE,\n\t\t\t\toptions.layoutServer,\n\t\t\t\tnormalizedSubFolder,\n\t\t\t);\n\t\t}\n\t\tif (options.hookServer !== undefined) {\n\t\t\tthis.#pushRoute(\n\t\t\t\t`${base}/_hook/~server`,\n\t\t\t\tHOOK_SERVER_ROUTE,\n\t\t\t\toptions.hookServer,\n\t\t\t\tnormalizedSubFolder,\n\t\t\t);\n\t\t}\n\t\tif (options.error !== undefined) {\n\t\t\tthis.#pushRoute(`${base}/_error`, ERROR_ROUTE, options.error, normalizedSubFolder);\n\t\t}\n\n\t\tthis.#sortRoutes();\n\t}\n\n\t/**\n\t * Pushes a single route entry, handling both file-path and inline-endpoint\n\t * targets. File paths are resolved relative to the site root; inline\n\t * endpoints are also stored in `inlineEndPoints` keyed by `\"path:type\"`\n\t * so the manifest plugin can resolve them at build time.\n\t *\n\t * If a route with the same path and type was already added, it is\n\t * replaced, so that running a plugin twice (config load and server\n\t * startup) doesn't add duplicate routes.\n\t */\n\t#pushRoute(\n\t\troutePath: string,\n\t\ttype: RouteType,\n\t\ttarget: string | InlineEndPoint,\n\t\tsubFolder?: string,\n\t): void {\n\t\tconst index = this.routes.findIndex((r) => r.path === routePath && r.type === type);\n\t\tif (typeof target === \"string\") {\n\t\t\tlet file = fpath.relative(this.root, fpath.resolve(this.root, target));\n\t\t\tif (index >= 0) {\n\t\t\t\tthis.routes[index] = { path: routePath, file, type, subFolder };\n\t\t\t} else {\n\t\t\t\tthis.routes.push({ path: routePath, file, type, subFolder });\n\t\t\t}\n\t\t} else {\n\t\t\tlet key = `${routePath}:${type}`;\n\t\t\tthis.inlineEndPoints[key] = target;\n\t\t\tif (index >= 0) {\n\t\t\t\tthis.routes[index] = { path: routePath, endPoint: target, type, subFolder };\n\t\t\t} else {\n\t\t\t\tthis.routes.push({ path: routePath, endPoint: target, type, subFolder });\n\t\t\t}\n\t\t}\n\t}\n\n\t#sortRoutes() {\n\t\tthis.routes = this.routes.sort((a, b) => {\n\t\t\t// Sort [param]s after paths\n\t\t\t// There might be a quicker/easier way to do this\n\t\t\tfor (let i = 0; i < Math.min(a.path.length, b.path.length); i++) {\n\t\t\t\tif (a.path[i] === \"[\" && b.path[i] !== \"[\") {\n\t\t\t\t\treturn 1;\n\t\t\t\t} else if (b.path[i] === \"[\" && a.path[i] !== \"[\") {\n\t\t\t\t\treturn -1;\n\t\t\t\t} else if (a.path[i] === b.path[i]) {\n\t\t\t\t\t// Keep going...\n\t\t\t\t} else {\n\t\t\t\t\treturn a.path[i].localeCompare(b.path[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn a.path.length - b.path.length;\n\t\t});\n\t}\n}\n"],"mappings":"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"}