@solidjs/start 1.2.1 → 2.0.0-alpha.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 (191) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +2 -2
  3. package/dist/client/StartClient.d.ts +0 -1
  4. package/dist/client/StartClient.jsx +2 -4
  5. package/dist/client/index.d.ts +2 -3
  6. package/dist/client/index.jsx +2 -4
  7. package/dist/client/mount.d.ts +1 -7
  8. package/dist/client/mount.js +1 -91
  9. package/dist/client/spa/index.d.ts +1 -2
  10. package/dist/client/spa/index.jsx +1 -2
  11. package/dist/config/constants.d.ts +16 -0
  12. package/dist/config/constants.js +16 -0
  13. package/dist/config/dev-server.d.ts +2 -0
  14. package/dist/config/dev-server.js +108 -0
  15. package/dist/config/fs-router.d.ts +37 -0
  16. package/dist/config/fs-router.js +141 -0
  17. package/dist/config/fs-routes/fs-watcher.d.ts +3 -0
  18. package/dist/config/fs-routes/fs-watcher.js +49 -0
  19. package/dist/config/fs-routes/index.d.ts +7 -0
  20. package/dist/config/fs-routes/index.js +107 -0
  21. package/dist/config/fs-routes/router.d.ts +37 -0
  22. package/dist/config/fs-routes/router.js +136 -0
  23. package/dist/config/fs-routes/tree-shake.d.ts +2 -0
  24. package/dist/config/fs-routes/tree-shake.js +348 -0
  25. package/dist/config/index.d.ts +10 -0
  26. package/dist/config/index.js +214 -0
  27. package/dist/config/lazy.d.ts +3 -0
  28. package/dist/config/lazy.js +82 -0
  29. package/dist/config/manifest.d.ts +3 -0
  30. package/dist/config/manifest.js +74 -0
  31. package/dist/config/utils.d.ts +4 -0
  32. package/dist/config/utils.js +6 -0
  33. package/dist/config/vite-utils.d.ts +16 -0
  34. package/dist/config/vite-utils.js +81 -0
  35. package/dist/http/index.d.ts +81 -0
  36. package/dist/http/index.js +129 -0
  37. package/dist/index.d.ts +5 -5
  38. package/dist/index.jsx +5 -5
  39. package/dist/middleware/index.d.ts +6 -6
  40. package/dist/middleware/index.js +39 -0
  41. package/dist/{router/FileRoutes.js → router.jsx} +7 -8
  42. package/dist/server/StartServer.d.ts +3 -3
  43. package/dist/server/StartServer.jsx +9 -63
  44. package/dist/server/assets/index.d.ts +2 -0
  45. package/dist/server/assets/index.js +52 -0
  46. package/dist/server/assets/render.d.ts +19 -0
  47. package/dist/server/{renderAsset.jsx → assets/render.jsx} +1 -1
  48. package/dist/server/collect-styles.d.ts +3 -0
  49. package/dist/server/collect-styles.js +69 -0
  50. package/dist/server/fetchEvent.d.ts +4 -3
  51. package/dist/server/fetchEvent.js +12 -74
  52. package/dist/server/fetchEvent.spec.js +18 -197
  53. package/dist/server/handler.d.ts +6 -12
  54. package/dist/server/handler.js +193 -96
  55. package/dist/server/index.d.ts +9 -6
  56. package/dist/server/index.jsx +14 -6
  57. package/dist/server/manifest/client-manifest.d.ts +9 -0
  58. package/dist/server/manifest/client-manifest.js +6 -0
  59. package/dist/server/manifest/dev-client-manifest.d.ts +4 -0
  60. package/dist/server/manifest/dev-client-manifest.js +24 -0
  61. package/dist/server/manifest/dev-ssr-manifest.d.ts +5 -0
  62. package/dist/server/manifest/dev-ssr-manifest.js +23 -0
  63. package/dist/server/manifest/prod-client-manifest.d.ts +5 -0
  64. package/dist/server/manifest/prod-client-manifest.js +26 -0
  65. package/dist/server/manifest/prod-ssr-manifest.d.ts +6 -0
  66. package/dist/server/manifest/prod-ssr-manifest.js +85 -0
  67. package/dist/server/manifest/ssr-manifest.d.ts +4 -0
  68. package/dist/server/manifest/ssr-manifest.js +6 -0
  69. package/dist/{router → server}/routes.d.ts +5 -10
  70. package/dist/{router → server}/routes.js +32 -33
  71. package/dist/{runtime → server}/server-fns-runtime.d.ts +1 -1
  72. package/dist/{runtime → server}/server-fns-runtime.js +8 -7
  73. package/dist/server/server-functions-handler.d.ts +2 -0
  74. package/dist/{runtime/server-handler.js → server/server-functions-handler.js} +57 -97
  75. package/dist/server/server-runtime.d.ts +3 -0
  76. package/dist/{runtime → server}/server-runtime.js +17 -24
  77. package/dist/server/spa/StartServer.d.ts +1 -1
  78. package/dist/server/spa/StartServer.jsx +7 -9
  79. package/dist/server/spa/handler.d.ts +3 -3
  80. package/dist/server/spa/handler.js +9 -11
  81. package/dist/server/spa/index.d.ts +4 -3
  82. package/dist/server/spa/index.jsx +4 -3
  83. package/dist/server/types.d.ts +7 -9
  84. package/dist/server/util.d.ts +2 -0
  85. package/dist/server/util.js +8 -0
  86. package/dist/shared/ErrorBoundary.jsx +2 -2
  87. package/dist/shared/HttpHeader.jsx +4 -2
  88. package/dist/shared/{HttpStatusCode.jsx → HttpStatusCode.js} +3 -1
  89. package/dist/shared/dev-overlay/CodeView.d.ts +1 -1
  90. package/dist/shared/dev-overlay/CodeView.jsx +23 -34
  91. package/dist/shared/dev-overlay/DevOverlayDialog.d.ts +2 -2
  92. package/dist/shared/dev-overlay/DevOverlayDialog.jsx +73 -64
  93. package/dist/shared/dev-overlay/createStackFrame.js +3 -3
  94. package/dist/shared/dev-overlay/get-source-map.d.ts +1 -1
  95. package/dist/shared/dev-overlay/get-source-map.js +5 -5
  96. package/dist/shared/dev-overlay/icons.d.ts +10 -10
  97. package/dist/shared/dev-overlay/icons.jsx +91 -91
  98. package/dist/shared/dev-overlay/index.jsx +6 -9
  99. package/dist/shared/lazy.d.ts +3 -0
  100. package/dist/shared/lazy.js +42 -0
  101. package/dist/shared/serverFunction.d.ts +1 -1
  102. package/env.d.ts +2 -19
  103. package/package.json +44 -65
  104. package/scripts/build.js +15 -0
  105. package/scripts/validate-imports.js +316 -0
  106. package/src/client/StartClient.tsx +34 -0
  107. package/src/client/index.tsx +2 -0
  108. package/src/client/mount.ts +1 -0
  109. package/src/client/spa/index.tsx +9 -0
  110. package/src/config/constants.ts +19 -0
  111. package/src/config/dev-server.ts +145 -0
  112. package/{config/fs-router.js → src/config/fs-router.ts} +49 -29
  113. package/src/config/fs-routes/fs-watcher.ts +77 -0
  114. package/src/config/fs-routes/index.ts +136 -0
  115. package/src/config/fs-routes/router.ts +169 -0
  116. package/src/config/fs-routes/tree-shake.ts +371 -0
  117. package/src/config/index.ts +233 -0
  118. package/src/config/lazy.ts +100 -0
  119. package/src/config/manifest.ts +84 -0
  120. package/src/config/utils.ts +5 -0
  121. package/src/config/vite-utils.ts +109 -0
  122. package/src/env.d.ts +17 -0
  123. package/src/http/index.ts +216 -0
  124. package/src/index.tsx +7 -0
  125. package/src/internal.d.ts +14 -0
  126. package/src/middleware/index.ts +72 -0
  127. package/src/router.tsx +37 -0
  128. package/src/server/StartServer.tsx +56 -0
  129. package/src/server/assets/index.ts +70 -0
  130. package/src/server/assets/render.tsx +46 -0
  131. package/src/server/collect-styles.ts +87 -0
  132. package/src/server/fetchEvent.spec.ts +85 -0
  133. package/src/server/fetchEvent.ts +36 -0
  134. package/src/server/handler.ts +257 -0
  135. package/src/server/index.tsx +29 -0
  136. package/src/server/manifest/client-manifest.ts +8 -0
  137. package/src/server/manifest/dev-client-manifest.ts +21 -0
  138. package/src/server/manifest/dev-ssr-manifest.ts +23 -0
  139. package/src/server/manifest/prod-client-manifest.ts +21 -0
  140. package/src/server/manifest/prod-ssr-manifest.ts +109 -0
  141. package/src/server/manifest/ssr-manifest.ts +10 -0
  142. package/src/server/routes.ts +126 -0
  143. package/src/server/server-fns-runtime.ts +31 -0
  144. package/src/server/server-functions-handler.ts +339 -0
  145. package/src/server/server-runtime.ts +240 -0
  146. package/src/server/spa/StartServer.tsx +40 -0
  147. package/src/server/spa/handler.ts +29 -0
  148. package/src/server/spa/index.tsx +5 -0
  149. package/src/server/types.ts +82 -0
  150. package/src/server/util.ts +12 -0
  151. package/src/shared/ErrorBoundary.tsx +52 -0
  152. package/src/shared/GET.ts +8 -0
  153. package/src/shared/HttpHeader.tsx +42 -0
  154. package/src/shared/HttpStatusCode.ts +27 -0
  155. package/src/shared/clientOnly.ts +44 -0
  156. package/src/shared/dev-overlay/CodeView.tsx +92 -0
  157. package/src/shared/dev-overlay/DevOverlayDialog.tsx +316 -0
  158. package/src/shared/dev-overlay/createStackFrame.ts +74 -0
  159. package/src/shared/dev-overlay/download.ts +6 -0
  160. package/src/shared/dev-overlay/env.d.ts +4 -0
  161. package/src/shared/dev-overlay/get-source-map.ts +33 -0
  162. package/src/shared/dev-overlay/icons.tsx +456 -0
  163. package/src/shared/dev-overlay/index.tsx +63 -0
  164. package/src/shared/dev-overlay/styles.css +292 -0
  165. package/src/shared/lazy.ts +52 -0
  166. package/src/shared/serverFunction.ts +10 -0
  167. package/src/virtual.d.ts +27 -0
  168. package/tsconfig.json +23 -0
  169. package/vitest.config.ts +9 -0
  170. package/config/index.d.ts +0 -40
  171. package/config/index.js +0 -304
  172. package/config/server-components.js +0 -106
  173. package/dist/client/islands.d.ts +0 -7
  174. package/dist/client/islands.jsx +0 -10
  175. package/dist/middleware/index.jsx +0 -35
  176. package/dist/router/index.d.ts +0 -1
  177. package/dist/router/index.jsx +0 -2
  178. package/dist/router/lazyRoute.d.ts +0 -6
  179. package/dist/router/lazyRoute.js +0 -53
  180. package/dist/runtime/server-handler.d.ts +0 -2
  181. package/dist/runtime/server-runtime.d.ts +0 -3
  182. package/dist/server/islands/index.d.ts +0 -19
  183. package/dist/server/islands/index.jsx +0 -62
  184. package/dist/server/islands/utils.d.ts +0 -1
  185. package/dist/server/islands/utils.jsx +0 -85
  186. package/dist/server/pageEvent.d.ts +0 -2
  187. package/dist/server/pageEvent.js +0 -56
  188. package/dist/server/renderAsset.d.ts +0 -2
  189. /package/dist/{router/FileRoutes.d.ts → router.d.ts} +0 -0
  190. /package/dist/shared/{clientOnly.jsx → clientOnly.js} +0 -0
  191. /package/dist/shared/{serverFunction.jsx → serverFunction.js} +0 -0
@@ -0,0 +1,84 @@
1
+ import { type PluginOption, type ViteDevServer } from "vite";
2
+
3
+ import { findStylesInModuleGraph } from "../server/collect-styles.ts";
4
+ import { VIRTUAL_MODULES } from "./constants.ts";
5
+ import { type SolidStartOptions } from "./index.ts";
6
+
7
+ export function manifest(start: SolidStartOptions): PluginOption {
8
+ let devServer: ViteDevServer = undefined!;
9
+ return {
10
+ name: "solid-start:manifest-plugin",
11
+ enforce: "pre",
12
+ configureServer(server) {
13
+ devServer = server;
14
+ },
15
+ async resolveId(id) {
16
+ if (id === VIRTUAL_MODULES.clientViteManifest)
17
+ return `\0${VIRTUAL_MODULES.clientViteManifest}`;
18
+ if (id === VIRTUAL_MODULES.getClientManifest)
19
+ return this.resolve(
20
+ new URL("../server/manifest/client-manifest", import.meta.url).pathname,
21
+ );
22
+ if (id === VIRTUAL_MODULES.getManifest) {
23
+ return this.environment.config.consumer === "client"
24
+ ? this.resolve(new URL("../server/manifest/client-manifest", import.meta.url).pathname)
25
+ : this.resolve(new URL("../server/manifest/ssr-manifest", import.meta.url).pathname);
26
+ }
27
+ if (id === VIRTUAL_MODULES.middleware) {
28
+ if (start.middleware) return await this.resolve(start.middleware);
29
+ return `\0${VIRTUAL_MODULES.middleware}`;
30
+ }
31
+ },
32
+ async load(id) {
33
+ if (id === `\0${VIRTUAL_MODULES.clientViteManifest}`) {
34
+ let clientViteManifest: Record<string, Record<string, any>>;
35
+ if (this.environment.config.command === "serve") {
36
+ clientViteManifest = {};
37
+ } else {
38
+ const entry = Object.values(globalThis.START_CLIENT_BUNDLE).find(
39
+ v => "isEntry" in v && v.isEntry,
40
+ );
41
+ if (!entry) throw new Error("No client entry found");
42
+ clientViteManifest = JSON.parse(
43
+ (globalThis.START_CLIENT_BUNDLE[".vite/manifest.json"] as any).source,
44
+ );
45
+ }
46
+ return `export const clientViteManifest = ${JSON.stringify(clientViteManifest)};`;
47
+ } else if (id === `\0${VIRTUAL_MODULES.middleware}`) return "export default {};";
48
+ else if (id.startsWith("/@manifest")) {
49
+ if (this.environment.mode !== "dev")
50
+ throw new Error("@manifest queries are only allowed in dev");
51
+
52
+ const [path, query] = id.split("?");
53
+ const target = id.split("/")[2]!;
54
+ const params = new URLSearchParams(query);
55
+ if (!path || !query) return;
56
+ if (path.endsWith("assets")) {
57
+ const id = params.get("id");
58
+ if (!id) {
59
+ throw new Error("Missing id to get assets.");
60
+ }
61
+
62
+ // Client env does not have css dependencies in mod.transformResult
63
+ // Aalways use ssr env instead, to prevent hydration mismatches
64
+ const env = devServer.environments["ssr"];
65
+ const styles = await findStylesInModuleGraph(env, id);
66
+
67
+ const cssAssets = Object.entries(styles).map(
68
+ ([key, value]) => `{
69
+ tag: "style",
70
+ attrs: {
71
+ type: "text/css",
72
+ "data-vite-dev-id": "${key}",
73
+ "data-vite-ref": "0",
74
+ },
75
+ children: () => import("${value}?inline").then(mod => mod.default),
76
+ }`,
77
+ );
78
+
79
+ return `export default [${cssAssets.join(",")}]`;
80
+ }
81
+ }
82
+ },
83
+ };
84
+ }
@@ -0,0 +1,5 @@
1
+ export function parseIdQuery(id: string) {
2
+ if (!id.includes("?")) return { filename: id, query: new URLSearchParams() };
3
+ const [filename, rawQuery] = id.split(`?`, 2) as [string, string];
4
+ return { filename, query: new URLSearchParams(rawQuery) };
5
+ }
@@ -0,0 +1,109 @@
1
+ import { DevEnvironment, Rollup } from "vite";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+
5
+ const postfixRE = /[?#].*$/;
6
+ export function cleanUrl(url: string): string {
7
+ return url.replace(postfixRE, "");
8
+ }
9
+
10
+ export const FS_PREFIX = `/@fs/`;
11
+
12
+ export const VALID_ID_PREFIX = `/@id/`;
13
+
14
+ export const NULL_BYTE_PLACEHOLDER = `__x00__`;
15
+
16
+ export function normalizeResolvedIdToUrl(
17
+ environment: DevEnvironment,
18
+ url: string,
19
+ resolved: Rollup.PartialResolvedId,
20
+ ): string {
21
+ const root = environment.config.root;
22
+ const depsOptimizer = environment.depsOptimizer;
23
+
24
+ // normalize all imports into resolved URLs
25
+ // e.g. `import 'foo'` -> `import '/@fs/.../node_modules/foo/index.js'`
26
+ if (resolved.id.startsWith(withTrailingSlash(root))) {
27
+ // in root: infer short absolute path from root
28
+ url = resolved.id.slice(root.length);
29
+ } else if (
30
+ depsOptimizer?.isOptimizedDepFile(resolved.id) ||
31
+ // vite-plugin-react isn't following the leading \0 virtual module convention.
32
+ // This is a temporary hack to avoid expensive fs checks for React apps.
33
+ // We'll remove this as soon we're able to fix the react plugins.
34
+ (resolved.id !== "/@react-refresh" &&
35
+ path.isAbsolute(resolved.id) &&
36
+ fs.existsSync(cleanUrl(resolved.id)))
37
+ ) {
38
+ // an optimized deps may not yet exists in the filesystem, or
39
+ // a regular file exists but is out of root: rewrite to absolute /@fs/ paths
40
+ url = path.posix.join(FS_PREFIX, resolved.id);
41
+ } else {
42
+ url = resolved.id;
43
+ }
44
+
45
+ // if the resolved id is not a valid browser import specifier,
46
+ // prefix it to make it valid. We will strip this before feeding it
47
+ // back into the transform pipeline
48
+ if (url[0] !== "." && url[0] !== "/") {
49
+ url = wrapId(resolved.id);
50
+ }
51
+
52
+ return url;
53
+ }
54
+
55
+ export function wrapId(id: string): string {
56
+ return id.startsWith(VALID_ID_PREFIX)
57
+ ? id
58
+ : VALID_ID_PREFIX + id.replace("\0", NULL_BYTE_PLACEHOLDER);
59
+ }
60
+
61
+ export function unwrapId(id: string): string {
62
+ return id.startsWith(VALID_ID_PREFIX)
63
+ ? id.slice(VALID_ID_PREFIX.length).replace(NULL_BYTE_PLACEHOLDER, "\0")
64
+ : id;
65
+ }
66
+
67
+ export function normalizeViteImportAnalysisUrl(environment: DevEnvironment, id: string): string {
68
+ let url = normalizeResolvedIdToUrl(environment, id, { id });
69
+
70
+ // https://github.com/vitejs/vite/blob/c18ce868c4d70873406e9f7d1b2d0a03264d2168/packages/vite/src/node/plugins/importAnalysis.ts#L416
71
+ if (environment.config.consumer === "client") {
72
+ const mod = environment.moduleGraph.getModuleById(id);
73
+ if (mod && mod.lastHMRTimestamp > 0) {
74
+ url = injectQuery(url, `t=${mod.lastHMRTimestamp}`);
75
+ }
76
+ }
77
+
78
+ return url;
79
+ }
80
+
81
+ export function withTrailingSlash(path: string): string {
82
+ if (path[path.length - 1] !== "/") {
83
+ return `${path}/`;
84
+ }
85
+ return path;
86
+ }
87
+
88
+ export function splitFileAndPostfix(path: string): {
89
+ file: string;
90
+ postfix: string;
91
+ } {
92
+ const file = cleanUrl(path);
93
+ return { file, postfix: path.slice(file.length) };
94
+ }
95
+
96
+ const windowsSlashRE = /\\/g;
97
+ export function slash(p: string): string {
98
+ return p.replace(windowsSlashRE, "/");
99
+ }
100
+
101
+ const isWindows = typeof process !== "undefined" && process.platform === "win32";
102
+
103
+ export function injectQuery(url: string, queryToInject: string): string {
104
+ const { file, postfix } = splitFileAndPostfix(url);
105
+ const normalizedFile = isWindows ? slash(file) : file;
106
+ return `${normalizedFile}?${queryToInject}${
107
+ postfix[0] === "?" ? `&${postfix.slice(1)}` : /* hash only */ postfix
108
+ }`;
109
+ }
package/src/env.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ // This file contains global type definitions that are internal to SolidStart and are not exported
2
+
3
+ declare module "solidstart:server-fn-manifest" {
4
+ type ServerFn = (...args: Array<any>) => Promise<any>;
5
+ export function getServerFnById(id: string): Promise<ServerFn>;
6
+ }
7
+
8
+ interface ImportMetaEnv extends SolidStartMetaEnv {}
9
+
10
+ interface SolidStartMetaEnv {
11
+ START_SSR: boolean;
12
+ START_APP_ENTRY: string;
13
+ START_CLIENT_ENTRY: string;
14
+ START_ISLANDS: boolean;
15
+ // START_DEV_OVERLAY: boolean;
16
+ // SERVER_BASE_URL: string;
17
+ }
@@ -0,0 +1,216 @@
1
+ import type { H3Event, HTTPEvent, InferEventInput } from "h3";
2
+ import * as h3 from "h3";
3
+ import { getRequestEvent } from "solid-js/web";
4
+
5
+ function _setContext(event: H3Event, key: string, value: any) {
6
+ event.context[key] = value;
7
+ }
8
+
9
+ function _getContext(event: H3Event, key: string) {
10
+ return event.context[key];
11
+ }
12
+
13
+ function getEvent() {
14
+ return getRequestEvent()!.nativeEvent;
15
+ }
16
+
17
+ export function getWebRequest(): Request {
18
+ return getEvent().req;
19
+ }
20
+
21
+ export const HTTPEventSymbol = Symbol("$HTTPEvent");
22
+
23
+ export function isEvent(obj: any): obj is h3.H3Event | { [HTTPEventSymbol]: h3.H3Event } {
24
+ return (
25
+ typeof obj === "object" &&
26
+ (obj instanceof h3.H3Event ||
27
+ obj?.[HTTPEventSymbol] instanceof h3.H3Event ||
28
+ obj?.__is_event__ === true)
29
+ );
30
+ // Implement logic to check if obj is an H3Event
31
+ }
32
+
33
+ type Tail<T> = T extends [any, ...infer U] ? U : never;
34
+
35
+ type PrependOverload<
36
+ TOriginal extends (...args: Array<any>) => any,
37
+ TOverload extends (...args: Array<any>) => any,
38
+ > = TOverload & TOriginal;
39
+
40
+ // add an overload to the function without the event argument
41
+ type WrapFunction<TFn extends (...args: Array<any>) => any> = PrependOverload<
42
+ TFn,
43
+ (
44
+ ...args: Parameters<TFn> extends [h3.HTTPEvent<any> | h3.H3Event<any>, ...infer TArgs]
45
+ ? TArgs
46
+ : Parameters<TFn>
47
+ ) => ReturnType<TFn>
48
+ >;
49
+
50
+ function createWrapperFunction<TFn extends (...args: Array<any>) => any>(
51
+ h3Function: TFn,
52
+ ): WrapFunction<TFn> {
53
+ return ((...args: Array<any>) => {
54
+ const event = args[0];
55
+ if (!isEvent(event)) {
56
+ args.unshift(getEvent());
57
+ } else {
58
+ args[0] =
59
+ event instanceof h3.H3Event || (event as any).__is_event__ ? event : event[HTTPEventSymbol];
60
+ }
61
+
62
+ return (h3Function as any)(...args);
63
+ }) as any;
64
+ }
65
+
66
+ // Creating wrappers for each utility and exporting them with their original names
67
+ // readRawBody => getWebRequest().text()/.arrayBuffer()
68
+ type WrappedReadBody = <T, TEventInput = InferEventInput<"body", H3Event, T>>(
69
+ ...args: Tail<Parameters<typeof h3.readBody<T, H3Event, TEventInput>>>
70
+ ) => ReturnType<typeof h3.readBody<T, h3.H3Event, TEventInput>>;
71
+ export const readBody = createWrapperFunction(h3.readBody) as PrependOverload<
72
+ typeof h3.readBody,
73
+ WrappedReadBody
74
+ >;
75
+ type WrappedGetQuery = <T, TEventInput = Exclude<InferEventInput<"query", H3Event, T>, undefined>>(
76
+ ...args: Tail<Parameters<typeof h3.getQuery<T, H3Event, TEventInput>>>
77
+ ) => ReturnType<typeof h3.getQuery<T, H3Event, TEventInput>>;
78
+ export const getQuery = createWrapperFunction(h3.getQuery) as PrependOverload<
79
+ typeof h3.getQuery,
80
+ WrappedGetQuery
81
+ >;
82
+ export const isMethod = createWrapperFunction(h3.isMethod);
83
+ export const isPreflightRequest = createWrapperFunction(h3.isPreflightRequest);
84
+ type WrappedGetValidatedQuery = <
85
+ T extends HTTPEvent,
86
+ TEventInput = InferEventInput<"query", H3Event, T>,
87
+ >(
88
+ ...args: Tail<Parameters<typeof h3.getValidatedQuery<T, H3Event, TEventInput>>>
89
+ ) => ReturnType<typeof h3.getValidatedQuery<T, H3Event, TEventInput>>;
90
+ export const getValidatedQuery = createWrapperFunction(h3.getValidatedQuery) as PrependOverload<
91
+ typeof h3.getValidatedQuery,
92
+ WrappedGetValidatedQuery
93
+ >;
94
+ export const getRouterParams = createWrapperFunction(h3.getRouterParams);
95
+ export const getRouterParam = createWrapperFunction(h3.getRouterParam);
96
+ type WrappedGetValidatedRouterParams = <
97
+ T extends HTTPEvent,
98
+ TEventInput = InferEventInput<"routerParams", H3Event, T>,
99
+ >(
100
+ ...args: Tail<Parameters<typeof h3.getValidatedRouterParams<T, H3Event, TEventInput>>>
101
+ ) => ReturnType<typeof h3.getValidatedRouterParams<T, H3Event, TEventInput>>;
102
+ export const getValidatedRouterParams = createWrapperFunction(
103
+ h3.getValidatedRouterParams,
104
+ ) as PrependOverload<typeof h3.getValidatedRouterParams, WrappedGetValidatedRouterParams>;
105
+ export const assertMethod = createWrapperFunction(h3.assertMethod);
106
+ export const getRequestHeaders = createWrapperFunction(h3.getRequestHeaders);
107
+ export const getRequestHeader = createWrapperFunction(h3.getRequestHeader);
108
+ export const getRequestURL = createWrapperFunction(h3.getRequestURL);
109
+ export const getRequestHost = createWrapperFunction(h3.getRequestHost);
110
+ export const getRequestProtocol = createWrapperFunction(h3.getRequestProtocol);
111
+ export const getRequestIP = createWrapperFunction(h3.getRequestIP);
112
+ export const setResponseStatus = (code?: number, text?: string) => {
113
+ const e = getEvent();
114
+
115
+ if (e.res.status !== undefined) e.res.status = code;
116
+ if (e.res.statusText !== undefined) e.res.statusText = text;
117
+ };
118
+ export const getResponseStatus = () => getEvent().res.status;
119
+ export const getResponseStatusText = () => getEvent().res.statusText;
120
+ export const getResponseHeaders = () => Object.fromEntries(getEvent().res.headers.entries());
121
+ export const getResponseHeader = (name: string) => getEvent().res.headers.get(name);
122
+ export const setResponseHeaders = (values: Record<string, string>) => {
123
+ const headers = getEvent().res.headers;
124
+ for (const [name, value] of Object.entries(values)) {
125
+ headers.set(name, value);
126
+ }
127
+ };
128
+ export const setResponseHeader = (name: string, value: string | string[]) => {
129
+ const headers = getEvent().res.headers;
130
+
131
+ (Array.isArray(value) ? value : [value]).forEach(value => {
132
+ headers.set(name, value);
133
+ });
134
+ };
135
+ export const appendResponseHeaders = (values: Record<string, string>) => {
136
+ const headers = getEvent().res.headers;
137
+ for (const [name, value] of Object.entries(values)) {
138
+ headers.append(name, value);
139
+ }
140
+ };
141
+ export const appendResponseHeader = (name: string, value: string | string[]) => {
142
+ const headers = getEvent().res.headers;
143
+
144
+ (Array.isArray(value) ? value : [value]).forEach(value => {
145
+ headers.append(name, value);
146
+ });
147
+ };
148
+ export const defaultContentType = (type: string) =>
149
+ getEvent().res.headers.set("content-type", type);
150
+ export const proxyRequest = createWrapperFunction(h3.proxyRequest);
151
+ export const fetchWithEvent = createWrapperFunction(h3.fetchWithEvent);
152
+ export const getProxyRequestHeaders = createWrapperFunction(h3.getProxyRequestHeaders);
153
+
154
+ export const parseCookies = createWrapperFunction(h3.parseCookies);
155
+ export const getCookie = createWrapperFunction(h3.getCookie);
156
+ export const setCookie = createWrapperFunction(h3.setCookie);
157
+ export const deleteCookie = createWrapperFunction(h3.deleteCookie);
158
+ // not exported :(
159
+ type SessionDataT = Record<string, any>;
160
+ type WrappedUseSession = <T extends SessionDataT>(
161
+ ...args: Tail<Parameters<typeof h3.useSession<T>>>
162
+ ) => ReturnType<typeof h3.useSession<T>>;
163
+ export const useSession: WrappedUseSession = createWrapperFunction(h3.useSession);
164
+ type WrappedGetSession = <T extends SessionDataT>(
165
+ ...args: Tail<Parameters<typeof h3.getSession<T>>>
166
+ ) => ReturnType<typeof h3.getSession<T>>;
167
+ export const getSession: WrappedGetSession = createWrapperFunction(h3.getSession);
168
+ type WrappedUpdateSession = <T extends SessionDataT>(
169
+ ...args: Tail<Parameters<typeof h3.updateSession<T>>>
170
+ ) => ReturnType<typeof h3.updateSession<T>>;
171
+ export const updateSession: WrappedUpdateSession = createWrapperFunction(h3.updateSession);
172
+ type WrappedSealSession = <T extends SessionDataT>(
173
+ ...args: Tail<Parameters<typeof h3.sealSession<T>>>
174
+ ) => ReturnType<typeof h3.sealSession<T>>;
175
+ export const sealSession: WrappedSealSession = createWrapperFunction(h3.sealSession);
176
+ export const unsealSession = createWrapperFunction(h3.unsealSession);
177
+ export const clearSession = createWrapperFunction(h3.clearSession);
178
+ export const handleCacheHeaders = createWrapperFunction(h3.handleCacheHeaders);
179
+ export const handleCors = createWrapperFunction(h3.handleCors);
180
+ export const appendCorsHeaders = createWrapperFunction(h3.appendCorsHeaders);
181
+ export const appendCorsPreflightHeaders = createWrapperFunction(h3.appendCorsPreflightHeaders);
182
+ export const appendHeader = appendResponseHeader;
183
+ export const appendHeaders = appendResponseHeaders;
184
+ export const setHeader = setResponseHeader;
185
+ export const setHeaders = setResponseHeaders;
186
+ export const getHeader = getRequestHeader;
187
+ export const getHeaders = getRequestHeaders;
188
+ export const getRequestFingerprint = createWrapperFunction(h3.getRequestFingerprint);
189
+ export const getRequestWebStream = () => getEvent().req.body;
190
+ export const readFormData = () => getEvent().req.formData();
191
+ type WrappedReadValidatedBody = <
192
+ T extends HTTPEvent,
193
+ TEventInput = InferEventInput<"body", H3Event, T>,
194
+ >(
195
+ ...args: Tail<Parameters<typeof h3.readValidatedBody<T, H3Event, TEventInput>>>
196
+ ) => ReturnType<typeof h3.readValidatedBody<T, H3Event, TEventInput>>;
197
+ export const readValidatedBody = createWrapperFunction(h3.readValidatedBody) as PrependOverload<
198
+ typeof h3.readValidatedBody,
199
+ WrappedReadValidatedBody
200
+ >;
201
+ export const getContext = createWrapperFunction(_getContext);
202
+ export const setContext = createWrapperFunction(_setContext);
203
+ export const removeResponseHeader = (name: string) => getEvent().res.headers.delete(name);
204
+ export const clearResponseHeaders = (headerNames?: string[]) => {
205
+ const headers = getEvent().res.headers;
206
+
207
+ if (headerNames && headerNames.length > 0) {
208
+ for (const name of headerNames) {
209
+ headers.delete(name);
210
+ }
211
+ } else {
212
+ for (const name of headers.keys()) {
213
+ headers.delete(name);
214
+ }
215
+ }
216
+ };
package/src/index.tsx ADDED
@@ -0,0 +1,7 @@
1
+ // @refresh skip
2
+
3
+ export { default as clientOnly } from "./shared/clientOnly.ts";
4
+ export { GET } from "./shared/GET.ts";
5
+ export { HttpHeader } from "./shared/HttpHeader.tsx";
6
+ export { HttpStatusCode } from "./shared/HttpStatusCode.ts";
7
+ export { getServerFunctionMeta } from "./shared/serverFunction.ts";
@@ -0,0 +1,14 @@
1
+ import "h3";
2
+ declare module "h3" {
3
+ import { ViteDevServer } from "vite";
4
+
5
+ export interface H3EventContext {
6
+ viteDevServer?: ViteDevServer;
7
+ }
8
+ }
9
+
10
+ import type { Rollup } from "vite";
11
+ declare global {
12
+ var START_CLIENT_BUNDLE: Rollup.OutputBundle;
13
+ var USING_SOLID_START_DEV_SERVER: boolean | undefined;
14
+ }
@@ -0,0 +1,72 @@
1
+ // @refresh skip
2
+
3
+ import type { H3Event, Middleware } from "h3";
4
+ import { getFetchEvent } from "../server/fetchEvent.ts";
5
+ import type { FetchEvent } from "../server/types.ts";
6
+
7
+ /** Function responsible for receiving an observable [operation]{@link Operation} and returning a [result]{@link OperationResult}. */
8
+
9
+ export type MiddlewareFn = (event: FetchEvent) => Promise<unknown> | unknown;
10
+ /** This composes an array of Exchanges into a single ExchangeIO function */
11
+
12
+ export type RequestMiddleware = (
13
+ event: FetchEvent,
14
+ ) => Response | Promise<Response> | void | Promise<void> | Promise<void | Response>;
15
+
16
+ // copy-pasted from h3/dist/index.d.ts
17
+ type EventHandlerResponse<T = any> = T | Promise<T>;
18
+ type ResponseMiddlewareResponseParam = { body?: Awaited<EventHandlerResponse> };
19
+
20
+ export type ResponseMiddleware = (
21
+ event: FetchEvent,
22
+ response: ResponseMiddlewareResponseParam,
23
+ ) => Response | Promise<Response> | void | Promise<void>;
24
+
25
+ function wrapRequestMiddleware(onRequest: RequestMiddleware) {
26
+ return async (h3Event: H3Event) => {
27
+ const fetchEvent = getFetchEvent(h3Event);
28
+ const response = await onRequest(fetchEvent);
29
+ if (response) return response;
30
+ };
31
+ }
32
+
33
+ function wrapResponseMiddleware(onBeforeResponse: ResponseMiddleware): Middleware {
34
+ return async (h3Event, next) => {
35
+ const resp = await next();
36
+
37
+ const fetchEvent = getFetchEvent(h3Event);
38
+ const mwResponse = await onBeforeResponse(fetchEvent, {
39
+ body: (resp as any)?.body,
40
+ });
41
+ if (mwResponse) return mwResponse;
42
+ };
43
+ }
44
+
45
+ export function createMiddleware(
46
+ args:
47
+ | {
48
+ /** @deprecated Use H3 `Middleware` */
49
+ onRequest?: RequestMiddleware | RequestMiddleware[] | undefined;
50
+ /** @deprecated Use H3 `Middleware` */
51
+ onBeforeResponse?: ResponseMiddleware | ResponseMiddleware[] | undefined;
52
+ }
53
+ | Middleware[],
54
+ ): Middleware[] {
55
+ if (Array.isArray(args)) return args;
56
+
57
+ const mw: Middleware[] = [];
58
+
59
+ if (typeof args.onRequest === "function") {
60
+ mw.push(wrapRequestMiddleware(args.onRequest));
61
+ } else if (Array.isArray(args.onRequest)) {
62
+ mw.push(...args.onRequest.map(wrapRequestMiddleware));
63
+ }
64
+
65
+ if (typeof args.onBeforeResponse === "function") {
66
+ mw.push(wrapResponseMiddleware(args.onBeforeResponse));
67
+ } else if (Array.isArray(args.onBeforeResponse)) {
68
+ mw.push(...args.onBeforeResponse.map(wrapResponseMiddleware));
69
+ }
70
+
71
+ return mw;
72
+ }
package/src/router.tsx ADDED
@@ -0,0 +1,37 @@
1
+ import { lazy, type Component } from "solid-js";
2
+ import { getRequestEvent, isServer } from "solid-js/web";
3
+
4
+ import { pageRoutes as routeConfigs } from "./server/routes.ts";
5
+ import type { PageEvent } from "./server/types.ts";
6
+
7
+ const components: Record<string, Component> = {};
8
+
9
+ export function createRoutes() {
10
+ function createRoute(route: any) {
11
+ const component =
12
+ route.$component && (components[route.$component.src] ??= lazy(route.$component.import));
13
+
14
+ return {
15
+ ...route,
16
+ ...(route.$$route ? route.$$route.require().route : undefined),
17
+ info: {
18
+ ...(route.$$route ? route.$$route.require().route.info : {}),
19
+ filesystem: true,
20
+ },
21
+ component,
22
+ children: route.children ? route.children.map(createRoute) : undefined,
23
+ };
24
+ }
25
+ const routes = routeConfigs.map(createRoute);
26
+ return routes;
27
+ }
28
+
29
+ let routes: any[];
30
+
31
+ /**
32
+ *
33
+ * Read more: https://docs.solidjs.com/solid-start/reference/routing/file-routes
34
+ */
35
+ export const FileRoutes = isServer
36
+ ? () => (getRequestEvent() as PageEvent).routes
37
+ : () => routes || (routes = createRoutes());
@@ -0,0 +1,56 @@
1
+ // @refresh skip
2
+ import type { Component } from "solid-js";
3
+ import { Hydration, HydrationScript, NoHydration, getRequestEvent, ssr } from "solid-js/web";
4
+ import App from "solid-start:app";
5
+
6
+ import { ErrorBoundary, TopErrorBoundary } from "../shared/ErrorBoundary.tsx";
7
+ import { useAssets } from "./assets/index.ts";
8
+ import { getSsrManifest } from "./manifest/ssr-manifest.ts";
9
+ import type { DocumentComponentProps, PageEvent } from "./types.ts";
10
+
11
+ const docType = ssr("<!DOCTYPE html>");
12
+
13
+ /**
14
+ *
15
+ * Read more: https://docs.solidjs.com/solid-start/reference/server/start-server
16
+ */
17
+ export function StartServer(props: { document: Component<DocumentComponentProps> }) {
18
+ const context = getRequestEvent() as PageEvent;
19
+
20
+ // @ts-ignore
21
+ const nonce = context.nonce;
22
+ useAssets(context.assets, nonce);
23
+
24
+ return (
25
+ <NoHydration>
26
+ {docType as unknown as any}
27
+ <TopErrorBoundary>
28
+ <props.document
29
+ assets={<HydrationScript />}
30
+ scripts={
31
+ <>
32
+ <script
33
+ type="module"
34
+ nonce={nonce}
35
+ async
36
+ src={getSsrManifest("client").path(import.meta.env.START_CLIENT_ENTRY)}
37
+ />
38
+ </>
39
+ }
40
+ >
41
+ {!import.meta.env.START_ISLANDS ? (
42
+ <Hydration>
43
+ <ErrorBoundary>
44
+ <App />
45
+ </ErrorBoundary>
46
+ </Hydration>
47
+ ) : (
48
+ <ErrorBoundary>
49
+ <App />
50
+ </ErrorBoundary>
51
+ )}
52
+ </props.document>
53
+ </TopErrorBoundary>
54
+ </NoHydration>
55
+ );
56
+ }