@hyperspan/framework 0.0.3 → 0.1.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.
- package/README.md +3 -81
- package/build.ts +24 -26
- package/dist/assets.d.ts +34 -0
- package/dist/assets.js +394 -0
- package/dist/index.d.ts +101 -30
- package/dist/index.js +2421 -408
- package/dist/server.d.ts +85 -73
- package/dist/server.js +2142 -1603
- package/package.json +42 -29
- package/src/assets.ts +141 -0
- package/src/clientjs/hyperspan-client.ts +7 -175
- package/src/clientjs/idiomorph.esm.js +1278 -0
- package/src/clientjs/preact.ts +1 -0
- package/src/index.ts +1 -14
- package/src/server.ts +232 -151
- package/.prettierrc +0 -7
- package/bun.lockb +0 -0
- package/src/app.ts +0 -186
- package/src/clientjs/idomorph.esm.js +0 -854
- package/src/document.ts +0 -10
- package/src/forms.ts +0 -110
- package/src/html.test.ts +0 -69
- package/src/html.ts +0 -345
package/src/app.ts
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
|
-
import Router from 'trek-router';
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import Middleware from 'trek-middleware';
|
|
5
|
-
import deepmerge from '@fastify/deepmerge';
|
|
6
|
-
import Headers from '@mjackson/headers';
|
|
7
|
-
|
|
8
|
-
const mergeAll = deepmerge({ all: true });
|
|
9
|
-
|
|
10
|
-
type THTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Request context
|
|
14
|
-
*/
|
|
15
|
-
export class HSRequestContext {
|
|
16
|
-
public req: Request;
|
|
17
|
-
public locals: Record<string, any>;
|
|
18
|
-
public headers: Headers;
|
|
19
|
-
public route: {
|
|
20
|
-
params: Record<string, string>;
|
|
21
|
-
query: URLSearchParams;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
constructor(req: Request, params: Record<string, string> = {}) {
|
|
25
|
-
this.req = req;
|
|
26
|
-
this.locals = {};
|
|
27
|
-
this.route = {
|
|
28
|
-
params,
|
|
29
|
-
query: new URL(req.url).searchParams,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// This could probably be re-visited...
|
|
33
|
-
const allowHeaders = ['cookie'];
|
|
34
|
-
const reqHeaders: Record<string, string> = {};
|
|
35
|
-
|
|
36
|
-
for (let [name, value] of req.headers) {
|
|
37
|
-
if (allowHeaders.includes(name)) {
|
|
38
|
-
reqHeaders[name] = value;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
this.headers = new Headers(reqHeaders);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Response helper
|
|
47
|
-
* Merges a Response object while preserving all headers added in context/middleware
|
|
48
|
-
*/
|
|
49
|
-
resMerge(res: Response) {
|
|
50
|
-
const cHeaders: Record<string, string> = {};
|
|
51
|
-
for (let [name, value] of this.headers) {
|
|
52
|
-
cHeaders[name] = value;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const newRes = new Response(
|
|
56
|
-
res.body,
|
|
57
|
-
mergeAll(
|
|
58
|
-
{ headers: cHeaders },
|
|
59
|
-
{ headers: res.headers.toJSON() },
|
|
60
|
-
{ status: res.status, statusText: res.statusText }
|
|
61
|
-
)
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
return newRes;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* HTML response helper
|
|
69
|
-
* Preserves all headers added in context/middleware
|
|
70
|
-
*/
|
|
71
|
-
html(content: string, options?: ResponseInit): Response {
|
|
72
|
-
return new Response(content, mergeAll({ headers: { 'Content-Type': 'text/html' } }, options));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* JSON response helper
|
|
77
|
-
* Preserves all headers added in context/middleware
|
|
78
|
-
*/
|
|
79
|
-
json(content: any, options?: ResponseInit): Response {
|
|
80
|
-
return new Response(
|
|
81
|
-
JSON.stringify(content),
|
|
82
|
-
mergeAll({ headers: { 'Content-Type': 'application/json' } }, options)
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
notFound(msg: string = 'Not found!') {
|
|
87
|
-
return this.html(msg, { status: 404 });
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
type THSRouteHandler = (
|
|
92
|
-
context: HSRequestContext
|
|
93
|
-
) => (Response | null | void) | Promise<Response | null | void>;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* App
|
|
97
|
-
*/
|
|
98
|
-
export class HSApp {
|
|
99
|
-
private _router: typeof Router;
|
|
100
|
-
private _mw: typeof Middleware;
|
|
101
|
-
public _defaultRoute: THSRouteHandler;
|
|
102
|
-
|
|
103
|
-
constructor() {
|
|
104
|
-
this._router = new Router();
|
|
105
|
-
this._mw = new Middleware();
|
|
106
|
-
this._defaultRoute = (c: HSRequestContext) => {
|
|
107
|
-
return c.notFound('Not found');
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// @TODO: Middleware !!!!
|
|
112
|
-
|
|
113
|
-
public get(path: string, handler: THSRouteHandler) {
|
|
114
|
-
return this._route('GET', path, handler);
|
|
115
|
-
}
|
|
116
|
-
public post(path: string, handler: THSRouteHandler) {
|
|
117
|
-
return this._route('POST', path, handler);
|
|
118
|
-
}
|
|
119
|
-
public put(path: string, handler: THSRouteHandler) {
|
|
120
|
-
return this._route('PUT', path, handler);
|
|
121
|
-
}
|
|
122
|
-
public delete(path: string, handler: THSRouteHandler) {
|
|
123
|
-
return this._route('DELETE', path, handler);
|
|
124
|
-
}
|
|
125
|
-
public all(path: string, handler: THSRouteHandler) {
|
|
126
|
-
return this.addRoute(['GET', 'POST', 'PUT', 'PATCH', 'DELETE'], path, handler);
|
|
127
|
-
}
|
|
128
|
-
public addRoute(methods: THTTPMethod[], path: string, handler: THSRouteHandler) {
|
|
129
|
-
methods.forEach((method) => {
|
|
130
|
-
this._route(method, path, handler);
|
|
131
|
-
});
|
|
132
|
-
return this;
|
|
133
|
-
}
|
|
134
|
-
public defaultRoute(handler: THSRouteHandler) {
|
|
135
|
-
this._defaultRoute = handler;
|
|
136
|
-
}
|
|
137
|
-
private _route(method: string | string[], path: string, handler: any) {
|
|
138
|
-
this._router.add(method, path, handler);
|
|
139
|
-
return this;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async run(req: Request): Promise<Response> {
|
|
143
|
-
let response: Response;
|
|
144
|
-
let url = new URL(req.url);
|
|
145
|
-
let urlPath = normalizePath(url.pathname);
|
|
146
|
-
|
|
147
|
-
// Redirect to normalized path (lowercase & without trailing slash)
|
|
148
|
-
if (urlPath !== url.pathname) {
|
|
149
|
-
url.pathname = urlPath;
|
|
150
|
-
return Response.redirect(url);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
let result = this._router.find(req.method.toUpperCase(), urlPath);
|
|
154
|
-
let params: Record<string, any> = {};
|
|
155
|
-
|
|
156
|
-
if (result && result[0]) {
|
|
157
|
-
// Build params
|
|
158
|
-
result[1].forEach((param: any) => (params[param.name] = param.value));
|
|
159
|
-
|
|
160
|
-
// Run route with context
|
|
161
|
-
const context = new HSRequestContext(req, params);
|
|
162
|
-
response = result[0](context);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// @ts-ignore
|
|
166
|
-
if (response) {
|
|
167
|
-
return response;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const context = new HSRequestContext(req);
|
|
171
|
-
|
|
172
|
-
// @ts-ignore
|
|
173
|
-
return this._defaultRoute(context);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Normalize URL path
|
|
179
|
-
* Removes trailing slash and lowercases path
|
|
180
|
-
*/
|
|
181
|
-
export function normalizePath(urlPath: string): string {
|
|
182
|
-
return (
|
|
183
|
-
(urlPath.endsWith('/') ? urlPath.substring(0, urlPath.length - 1) : urlPath).toLowerCase() ||
|
|
184
|
-
'/'
|
|
185
|
-
);
|
|
186
|
-
}
|