@server/next 0.27.1 → 0.27.4
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/index.d.ts +392 -0
- package/index.js +172 -146
- package/package.json +5 -3
- package/src/jsx/jsx-dev-runtime.js +1 -91
- package/src/jsx/jsx-runtime.js +91 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
type Method = "get" | "post" | "put" | "patch" | "delete" | "head" | "options" | "socket";
|
|
2
|
+
type ServerConfig = {
|
|
3
|
+
User?: Record<string, string | number | boolean | Date | null | undefined>;
|
|
4
|
+
};
|
|
5
|
+
type RouteOptions = {
|
|
6
|
+
tags?: string | string[];
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
};
|
|
10
|
+
type Cookie = {
|
|
11
|
+
value?: string;
|
|
12
|
+
path?: string;
|
|
13
|
+
expires?: number | string | Date;
|
|
14
|
+
};
|
|
15
|
+
type RouterMethod = "*" | Method;
|
|
16
|
+
type Bucket = {
|
|
17
|
+
read: (path: string) => Promise<ReadableStream | null>;
|
|
18
|
+
write: (path: string, data: string | Buffer) => Promise<void | string>;
|
|
19
|
+
delete: (path: string) => Promise<boolean>;
|
|
20
|
+
};
|
|
21
|
+
type CorsSettings = {
|
|
22
|
+
origin: string | boolean;
|
|
23
|
+
methods: string;
|
|
24
|
+
headers: string;
|
|
25
|
+
};
|
|
26
|
+
type CorsOptions = boolean | string | string[] | {
|
|
27
|
+
origin?: string | string[];
|
|
28
|
+
methods?: string | Method[];
|
|
29
|
+
headers?: string | string[];
|
|
30
|
+
};
|
|
31
|
+
type BasicValue = string | number | boolean | null;
|
|
32
|
+
type SerializableValue = BasicValue | {
|
|
33
|
+
[key: string]: SerializableValue;
|
|
34
|
+
} | Array<SerializableValue>;
|
|
35
|
+
type KVStore = {
|
|
36
|
+
name?: string;
|
|
37
|
+
prefix: (key: string) => KVStore;
|
|
38
|
+
get: <T = SerializableValue>(key: string) => Promise<T>;
|
|
39
|
+
set: <T = SerializableValue>(key: string, value: T, options?: {
|
|
40
|
+
expires: string | number;
|
|
41
|
+
}) => Promise<void | string>;
|
|
42
|
+
has: (key: string) => Promise<boolean>;
|
|
43
|
+
del: (key: string) => Promise<void | string>;
|
|
44
|
+
keys: () => Promise<string[]>;
|
|
45
|
+
};
|
|
46
|
+
type Provider = "email" | "github";
|
|
47
|
+
type Strategy = "cookie" | "jwt" | "token";
|
|
48
|
+
type AuthSession = {
|
|
49
|
+
id: string;
|
|
50
|
+
provider: Provider;
|
|
51
|
+
strategy: Strategy;
|
|
52
|
+
user: string;
|
|
53
|
+
};
|
|
54
|
+
type AuthUser<T = object> = T & {
|
|
55
|
+
id: string | number;
|
|
56
|
+
provider: Provider;
|
|
57
|
+
strategy: Strategy;
|
|
58
|
+
email: string;
|
|
59
|
+
};
|
|
60
|
+
type ProviderString = Provider | `${Provider}|${Provider}`;
|
|
61
|
+
type AuthOption = `${Strategy}:${Provider | ProviderString}` | {
|
|
62
|
+
provider: Provider | ProviderString | Provider[];
|
|
63
|
+
strategy: Strategy;
|
|
64
|
+
session?: KVStore;
|
|
65
|
+
store?: KVStore;
|
|
66
|
+
redirect?: string;
|
|
67
|
+
cleanUser?: <T = AuthUser>(user: T) => T | Promise<T>;
|
|
68
|
+
};
|
|
69
|
+
type AuthSettings = {
|
|
70
|
+
provider: Provider[];
|
|
71
|
+
strategy: Strategy;
|
|
72
|
+
store: KVStore;
|
|
73
|
+
session: KVStore;
|
|
74
|
+
cleanUser: <T = AuthUser>(user: T) => T | Promise<T>;
|
|
75
|
+
redirect: string;
|
|
76
|
+
};
|
|
77
|
+
type Options = {
|
|
78
|
+
port?: number;
|
|
79
|
+
secret?: string;
|
|
80
|
+
views?: string | Bucket;
|
|
81
|
+
public?: string | Bucket;
|
|
82
|
+
uploads?: string | Bucket;
|
|
83
|
+
store?: KVStore;
|
|
84
|
+
cookies?: KVStore;
|
|
85
|
+
session?: KVStore | {
|
|
86
|
+
store: KVStore;
|
|
87
|
+
};
|
|
88
|
+
cors?: CorsOptions;
|
|
89
|
+
auth?: AuthOption;
|
|
90
|
+
openapi?: any;
|
|
91
|
+
};
|
|
92
|
+
type Settings = {
|
|
93
|
+
port: number;
|
|
94
|
+
secret: string;
|
|
95
|
+
views?: Bucket;
|
|
96
|
+
public?: Bucket;
|
|
97
|
+
uploads?: Bucket;
|
|
98
|
+
store?: KVStore;
|
|
99
|
+
cookies?: KVStore;
|
|
100
|
+
session?: {
|
|
101
|
+
store: KVStore;
|
|
102
|
+
};
|
|
103
|
+
cors?: CorsSettings;
|
|
104
|
+
auth?: AuthSettings;
|
|
105
|
+
openapi?: any;
|
|
106
|
+
};
|
|
107
|
+
type Time = {
|
|
108
|
+
(name: string): void;
|
|
109
|
+
times: [string, number][];
|
|
110
|
+
headers: () => string;
|
|
111
|
+
};
|
|
112
|
+
type Platform = {
|
|
113
|
+
provider: string | null;
|
|
114
|
+
runtime: string | null;
|
|
115
|
+
production: boolean;
|
|
116
|
+
};
|
|
117
|
+
type ExtractPathParams<Path extends string> = Path extends `${string}:${infer Param}(${infer Type})?/${infer Rest}` ? `${Param}:${Type}?` | ExtractPathParams<`/${Rest}`> : Path extends `${string}:${infer Param}(${infer Type})?` ? `${Param}:${Type}?` : Path extends `${string}:${infer Param}(${infer Type})/${infer Rest}` ? `${Param}:${Type}` | ExtractPathParams<`/${Rest}`> : Path extends `${string}:${infer Param}(${infer Type})` ? `${Param}:${Type}` : Path extends `${string}:${infer Param}?/${infer Rest}` ? `${Param}?` | ExtractPathParams<`/${Rest}`> : Path extends `${string}:${infer Param}?` ? `${Param}?` : Path extends `${string}:${infer Param}/${infer Rest}` ? Param | ExtractPathParams<`/${Rest}`> : Path extends `${string}:${infer Param}` ? Param : never;
|
|
118
|
+
type ParamTypeMap = {
|
|
119
|
+
string: string;
|
|
120
|
+
number: number;
|
|
121
|
+
date: Date;
|
|
122
|
+
};
|
|
123
|
+
type InferParamType<T extends string> = T extends keyof ParamTypeMap ? ParamTypeMap[T] : string;
|
|
124
|
+
type ParamsToObject<Params extends string> = {
|
|
125
|
+
[K in Params as K extends `${infer Key}:${infer _Type}?` ? Key : K extends `${infer Key}:${infer _Type}` ? Key : K extends `${infer Key}?` ? Key : K]: K extends `${infer _Key}:${infer Type}?` ? InferParamType<Type> | undefined : K extends `${infer _Key}:${infer Type}` ? InferParamType<Type> : K extends `${infer _Key}?` ? string | undefined : string;
|
|
126
|
+
};
|
|
127
|
+
type PathToParams<Path extends string> = ParamsToObject<ExtractPathParams<Path>>;
|
|
128
|
+
type BunEnv = Record<string, string> & {
|
|
129
|
+
upgrade?: (req: Request) => boolean;
|
|
130
|
+
};
|
|
131
|
+
type EventCallback = (data: Context & SerializableValue) => void;
|
|
132
|
+
type Events = Record<string, EventCallback[]> & {
|
|
133
|
+
on?: (key: string, cb: (value?: Context & SerializableValue) => void) => void;
|
|
134
|
+
trigger?: (key: string, value?: Partial<Context & SerializableValue>) => void;
|
|
135
|
+
};
|
|
136
|
+
type Context<Params extends Record<string, string> = Record<string, string>, O extends ServerConfig = object> = {
|
|
137
|
+
method: Method;
|
|
138
|
+
headers: Record<string, string | string[]>;
|
|
139
|
+
cookies: Record<string, string>;
|
|
140
|
+
body?: SerializableValue;
|
|
141
|
+
url: URL & {
|
|
142
|
+
params: Params;
|
|
143
|
+
query: Record<string, string>;
|
|
144
|
+
};
|
|
145
|
+
options: Settings;
|
|
146
|
+
platform: Platform;
|
|
147
|
+
time?: Time;
|
|
148
|
+
socket?: WebSocket;
|
|
149
|
+
sockets?: WebSocket[];
|
|
150
|
+
session?: Record<string, BasicValue>;
|
|
151
|
+
user?: O extends {
|
|
152
|
+
User: infer U;
|
|
153
|
+
} ? U & AuthUser : AuthUser;
|
|
154
|
+
init: number;
|
|
155
|
+
events: Events;
|
|
156
|
+
req?: Request;
|
|
157
|
+
res?: Response & {
|
|
158
|
+
cookies?: Record<string, string>;
|
|
159
|
+
};
|
|
160
|
+
app: Server;
|
|
161
|
+
};
|
|
162
|
+
type InlineReply = Response | {
|
|
163
|
+
body: string;
|
|
164
|
+
headers?: Headers;
|
|
165
|
+
} | SerializableValue;
|
|
166
|
+
type Body = InlineReply;
|
|
167
|
+
type Middleware<O extends ServerConfig = object, Params extends Record<string, string> = Record<string, string>> = (ctx: Context<Params, O>) => InlineReply | Promise<InlineReply> | void | Promise<void>;
|
|
168
|
+
|
|
169
|
+
type Variables = Record<string, string | string[]>;
|
|
170
|
+
type ExtendError = string | {
|
|
171
|
+
message: string;
|
|
172
|
+
status: number;
|
|
173
|
+
};
|
|
174
|
+
interface ServerErrorConstructor {
|
|
175
|
+
extend(errors: Record<string, ExtendError>): Record<string, ExtendError>;
|
|
176
|
+
[key: string]: ((vars?: Variables) => ServerError) | any;
|
|
177
|
+
}
|
|
178
|
+
declare class ServerError extends Error {
|
|
179
|
+
code: string;
|
|
180
|
+
status: number;
|
|
181
|
+
constructor(code: string, status: number, message: string | ((vars: Variables) => string), vars?: Variables);
|
|
182
|
+
static extend(errors: Record<string, ExtendError>): Record<string, ExtendError>;
|
|
183
|
+
}
|
|
184
|
+
declare const TypedServerError: typeof ServerError & ServerErrorConstructor;
|
|
185
|
+
|
|
186
|
+
declare global {
|
|
187
|
+
var env: Record<string, any>;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
type Mids<O, Path extends string> = Middleware<O, PathToParams<Path>>[];
|
|
191
|
+
type PathOrMiddle<O extends ServerConfig = object> = string | Middleware<O>;
|
|
192
|
+
type FullRoute = [RouterMethod, string, ...Middleware[]][];
|
|
193
|
+
declare class Router<O extends ServerConfig = object> {
|
|
194
|
+
handlers: Record<Method, FullRoute>;
|
|
195
|
+
self(): this;
|
|
196
|
+
handle(method: RouterMethod, path: PathOrMiddle<O>, ...middleware: Middleware<O>[]): this;
|
|
197
|
+
socket<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
198
|
+
socket<Path extends string>(path: Path, options: RouteOptions, ...middleware: Mids<O, Path>): this;
|
|
199
|
+
socket(...middleware: Middleware<O>[]): this;
|
|
200
|
+
socket(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
201
|
+
get<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
202
|
+
get<Path extends string>(path: Path, options: RouteOptions, ...middleware: Mids<O, Path>): this;
|
|
203
|
+
get(...middleware: Middleware<O>[]): this;
|
|
204
|
+
get(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
205
|
+
head<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
206
|
+
head<Path extends string>(path: Path, options: RouteOptions, ...middleware: Mids<O, Path>): this;
|
|
207
|
+
head(...middleware: Middleware<O>[]): this;
|
|
208
|
+
head(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
209
|
+
post<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
210
|
+
post<Path extends string>(path: Path, options: RouteOptions, ...middleware: Mids<O, Path>): this;
|
|
211
|
+
post(...middleware: Middleware<O>[]): this;
|
|
212
|
+
post(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
213
|
+
put<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
214
|
+
put<Path extends string>(path: Path, options: RouteOptions, ...middleware: Mids<O, Path>): this;
|
|
215
|
+
put(...middleware: Middleware<O>[]): this;
|
|
216
|
+
put(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
217
|
+
patch<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
218
|
+
patch<Path extends string>(path: Path, options: RouteOptions, ...middleware: Mids<O, Path>): this;
|
|
219
|
+
patch(...middleware: Middleware<O>[]): this;
|
|
220
|
+
patch(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
221
|
+
del<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
222
|
+
del<Path extends string>(path: Path, options: RouteOptions, ...middleware: Mids<O, Path>): this;
|
|
223
|
+
del(...middleware: Middleware<O>[]): this;
|
|
224
|
+
del(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
225
|
+
options<Path extends string>(path: Path, ...middleware: Mids<O, Path>): this;
|
|
226
|
+
options<Path extends string>(path: Path, options: RouteOptions, ...mid: Mids<O, Path>): this;
|
|
227
|
+
options(...middleware: Middleware<O>[]): this;
|
|
228
|
+
options(options: RouteOptions, ...middleware: Middleware<O>[]): this;
|
|
229
|
+
use(...middleware: Middleware[]): this;
|
|
230
|
+
use(path: string, ...middleware: Middleware[]): this;
|
|
231
|
+
use(router: Router): this;
|
|
232
|
+
use(path: string, router: Router): this;
|
|
233
|
+
}
|
|
234
|
+
declare function router(): Router;
|
|
235
|
+
|
|
236
|
+
type CookieOptions = string | string[] | Cookie | Cookie[] | null;
|
|
237
|
+
interface ResponseData {
|
|
238
|
+
headers: Headers;
|
|
239
|
+
status?: number;
|
|
240
|
+
}
|
|
241
|
+
declare class Reply {
|
|
242
|
+
res: ResponseData;
|
|
243
|
+
constructor();
|
|
244
|
+
status(status: number): this;
|
|
245
|
+
type(type?: string): this;
|
|
246
|
+
download(name?: string): this;
|
|
247
|
+
headers(key: string | Record<string, string>, value?: string): this;
|
|
248
|
+
cookies(key: string | Record<string, CookieOptions>, value?: CookieOptions): this;
|
|
249
|
+
json(body: unknown): Response;
|
|
250
|
+
redirect(path: string): Response;
|
|
251
|
+
file(path: string): Promise<Response>;
|
|
252
|
+
send(body?: string | Buffer | ReadableStream | any): Response;
|
|
253
|
+
}
|
|
254
|
+
type Params<K extends keyof Reply> = Reply[K] extends (...args: infer A) => any ? A : never;
|
|
255
|
+
declare const status: (...args: Params<"status">) => Reply;
|
|
256
|
+
declare const headers: (...args: Params<"headers">) => Reply;
|
|
257
|
+
declare const type: (...args: Params<"type">) => Reply;
|
|
258
|
+
declare const download: (...args: Params<"download">) => Reply;
|
|
259
|
+
declare const cookies: (...args: Params<"cookies">) => Reply;
|
|
260
|
+
declare const send: (...args: Params<"send">) => Response;
|
|
261
|
+
declare const json: (...args: Params<"json">) => Response;
|
|
262
|
+
declare const file: (...args: Params<"file">) => Promise<Response>;
|
|
263
|
+
declare const redirect: (...args: Params<"redirect">) => Response;
|
|
264
|
+
|
|
265
|
+
declare class Server<O extends ServerConfig = object> extends Router<O> {
|
|
266
|
+
settings: Settings;
|
|
267
|
+
platform: Platform;
|
|
268
|
+
sockets: any[];
|
|
269
|
+
websocket: any;
|
|
270
|
+
port?: number;
|
|
271
|
+
constructor(options?: Options);
|
|
272
|
+
self(): this & ((request: any, context?: any) => any);
|
|
273
|
+
node(): Promise<void>;
|
|
274
|
+
fetch(request: Request, env?: BunEnv): Promise<Response>;
|
|
275
|
+
callback(request: Request, context: unknown): Promise<Response>;
|
|
276
|
+
test(): {
|
|
277
|
+
get: (path: string, options?: {
|
|
278
|
+
cache?: RequestCache;
|
|
279
|
+
credentials?: RequestCredentials;
|
|
280
|
+
headers?: HeadersInit;
|
|
281
|
+
integrity?: string;
|
|
282
|
+
keepalive?: boolean;
|
|
283
|
+
method?: string;
|
|
284
|
+
mode?: RequestMode;
|
|
285
|
+
priority?: RequestPriority;
|
|
286
|
+
redirect?: RequestRedirect;
|
|
287
|
+
referrer?: string;
|
|
288
|
+
referrerPolicy?: ReferrerPolicy;
|
|
289
|
+
signal?: AbortSignal | null;
|
|
290
|
+
window?: null;
|
|
291
|
+
}) => Promise<Response>;
|
|
292
|
+
head: (path: string, options?: {
|
|
293
|
+
cache?: RequestCache;
|
|
294
|
+
credentials?: RequestCredentials;
|
|
295
|
+
headers?: HeadersInit;
|
|
296
|
+
integrity?: string;
|
|
297
|
+
keepalive?: boolean;
|
|
298
|
+
method?: string;
|
|
299
|
+
mode?: RequestMode;
|
|
300
|
+
priority?: RequestPriority;
|
|
301
|
+
redirect?: RequestRedirect;
|
|
302
|
+
referrer?: string;
|
|
303
|
+
referrerPolicy?: ReferrerPolicy;
|
|
304
|
+
signal?: AbortSignal | null;
|
|
305
|
+
window?: null;
|
|
306
|
+
}) => Promise<Response>;
|
|
307
|
+
post: (path: string, body?: string | number | boolean | ArrayBuffer | {
|
|
308
|
+
[key: string]: SerializableValue;
|
|
309
|
+
} | SerializableValue[] | ReadableStream<any> | Blob | ArrayBufferView<ArrayBuffer> | FormData | URLSearchParams, options?: {
|
|
310
|
+
cache?: RequestCache;
|
|
311
|
+
credentials?: RequestCredentials;
|
|
312
|
+
headers?: HeadersInit;
|
|
313
|
+
integrity?: string;
|
|
314
|
+
keepalive?: boolean;
|
|
315
|
+
method?: string;
|
|
316
|
+
mode?: RequestMode;
|
|
317
|
+
priority?: RequestPriority;
|
|
318
|
+
redirect?: RequestRedirect;
|
|
319
|
+
referrer?: string;
|
|
320
|
+
referrerPolicy?: ReferrerPolicy;
|
|
321
|
+
signal?: AbortSignal | null;
|
|
322
|
+
window?: null;
|
|
323
|
+
}) => Promise<Response>;
|
|
324
|
+
put: (path: string, body?: string | number | boolean | ArrayBuffer | {
|
|
325
|
+
[key: string]: SerializableValue;
|
|
326
|
+
} | SerializableValue[] | ReadableStream<any> | Blob | ArrayBufferView<ArrayBuffer> | FormData | URLSearchParams, options?: {
|
|
327
|
+
cache?: RequestCache;
|
|
328
|
+
credentials?: RequestCredentials;
|
|
329
|
+
headers?: HeadersInit;
|
|
330
|
+
integrity?: string;
|
|
331
|
+
keepalive?: boolean;
|
|
332
|
+
method?: string;
|
|
333
|
+
mode?: RequestMode;
|
|
334
|
+
priority?: RequestPriority;
|
|
335
|
+
redirect?: RequestRedirect;
|
|
336
|
+
referrer?: string;
|
|
337
|
+
referrerPolicy?: ReferrerPolicy;
|
|
338
|
+
signal?: AbortSignal | null;
|
|
339
|
+
window?: null;
|
|
340
|
+
}) => Promise<Response>;
|
|
341
|
+
patch: (path: string, body?: string | number | boolean | ArrayBuffer | {
|
|
342
|
+
[key: string]: SerializableValue;
|
|
343
|
+
} | SerializableValue[] | ReadableStream<any> | Blob | ArrayBufferView<ArrayBuffer> | FormData | URLSearchParams, options?: {
|
|
344
|
+
cache?: RequestCache;
|
|
345
|
+
credentials?: RequestCredentials;
|
|
346
|
+
headers?: HeadersInit;
|
|
347
|
+
integrity?: string;
|
|
348
|
+
keepalive?: boolean;
|
|
349
|
+
method?: string;
|
|
350
|
+
mode?: RequestMode;
|
|
351
|
+
priority?: RequestPriority;
|
|
352
|
+
redirect?: RequestRedirect;
|
|
353
|
+
referrer?: string;
|
|
354
|
+
referrerPolicy?: ReferrerPolicy;
|
|
355
|
+
signal?: AbortSignal | null;
|
|
356
|
+
window?: null;
|
|
357
|
+
}) => Promise<Response>;
|
|
358
|
+
delete: (path: string, options?: {
|
|
359
|
+
cache?: RequestCache;
|
|
360
|
+
credentials?: RequestCredentials;
|
|
361
|
+
headers?: HeadersInit;
|
|
362
|
+
integrity?: string;
|
|
363
|
+
keepalive?: boolean;
|
|
364
|
+
method?: string;
|
|
365
|
+
mode?: RequestMode;
|
|
366
|
+
priority?: RequestPriority;
|
|
367
|
+
redirect?: RequestRedirect;
|
|
368
|
+
referrer?: string;
|
|
369
|
+
referrerPolicy?: ReferrerPolicy;
|
|
370
|
+
signal?: AbortSignal | null;
|
|
371
|
+
window?: null;
|
|
372
|
+
}) => Promise<Response>;
|
|
373
|
+
options: (path: string, options?: {
|
|
374
|
+
cache?: RequestCache;
|
|
375
|
+
credentials?: RequestCredentials;
|
|
376
|
+
headers?: HeadersInit;
|
|
377
|
+
integrity?: string;
|
|
378
|
+
keepalive?: boolean;
|
|
379
|
+
method?: string;
|
|
380
|
+
mode?: RequestMode;
|
|
381
|
+
priority?: RequestPriority;
|
|
382
|
+
redirect?: RequestRedirect;
|
|
383
|
+
referrer?: string;
|
|
384
|
+
referrerPolicy?: ReferrerPolicy;
|
|
385
|
+
signal?: AbortSignal | null;
|
|
386
|
+
window?: null;
|
|
387
|
+
}) => Promise<Response>;
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
declare function server<Options>(options?: {}): Server<Options> & ((request: any, context?: any) => any);
|
|
391
|
+
|
|
392
|
+
export { type AuthOption, type AuthSession, type AuthSettings, type AuthUser, type BasicValue, type Body, type Bucket, type BunEnv, type Context, type Cookie, type CorsSettings, type EventCallback, type ExtractPathParams, type InferParamType, type InlineReply, type KVStore, type Method, type Middleware, type Options, type ParamTypeMap, type ParamsToObject, type PathToParams, type Platform, type Provider, type RouteOptions, type RouterMethod, type SerializableValue, Server, type ServerConfig, TypedServerError as ServerError, type Settings, type Strategy, type Time, cookies, server as default, download, file, headers, json, redirect, router, send, status, type };
|
package/index.js
CHANGED
|
@@ -172,21 +172,14 @@ var email_default = {
|
|
|
172
172
|
};
|
|
173
173
|
|
|
174
174
|
// src/reply.ts
|
|
175
|
+
var EXPIRED = (/* @__PURE__ */ new Date(0)).toUTCString();
|
|
175
176
|
var Reply = class {
|
|
176
177
|
res;
|
|
177
178
|
constructor() {
|
|
178
179
|
this.res = {
|
|
179
|
-
headers:
|
|
180
|
-
cookies: {}
|
|
180
|
+
headers: new Headers()
|
|
181
181
|
};
|
|
182
182
|
}
|
|
183
|
-
generateHeaders() {
|
|
184
|
-
const headers2 = new Headers(this.res.headers);
|
|
185
|
-
for (const cookie of createCookies(this.res.cookies)) {
|
|
186
|
-
headers2.append("set-cookie", cookie);
|
|
187
|
-
}
|
|
188
|
-
return headers2;
|
|
189
|
-
}
|
|
190
183
|
status(status2) {
|
|
191
184
|
this.res.status = status2;
|
|
192
185
|
return this;
|
|
@@ -194,46 +187,55 @@ var Reply = class {
|
|
|
194
187
|
type(type2) {
|
|
195
188
|
if (!type2) return this;
|
|
196
189
|
type2 = types_default[type2.replace(/^\./, "")] || type2;
|
|
197
|
-
|
|
190
|
+
this.res.headers.set("content-type", type2);
|
|
191
|
+
return this;
|
|
198
192
|
}
|
|
199
|
-
download(name
|
|
200
|
-
|
|
201
|
-
if (
|
|
202
|
-
const filename = name ? `; filename="${name}"` : "";
|
|
203
|
-
return this.headers(
|
|
193
|
+
download(name) {
|
|
194
|
+
const ext = name?.split(".").pop();
|
|
195
|
+
if (type && ext && !this.res.headers.get("content-type")) this.type(ext);
|
|
196
|
+
const filename = name ? `; filename="${encodeURIComponent(name)}"` : "";
|
|
197
|
+
return this.headers("content-disposition", `attachment${filename}`);
|
|
204
198
|
}
|
|
205
|
-
headers(
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
this
|
|
199
|
+
headers(key, value) {
|
|
200
|
+
if (typeof key !== "string") {
|
|
201
|
+
Object.entries(key).map(([key2, value2]) => this.headers(key2, value2));
|
|
202
|
+
return this;
|
|
209
203
|
}
|
|
204
|
+
if (Array.isArray(value)) {
|
|
205
|
+
Object.values(value).map((val) => this.headers(key, val));
|
|
206
|
+
return this;
|
|
207
|
+
}
|
|
208
|
+
this.res.headers.append(key, value);
|
|
210
209
|
return this;
|
|
211
210
|
}
|
|
212
|
-
cookies(
|
|
213
|
-
if (
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
this.res.cookies[key] = { value: cookies2[key] };
|
|
217
|
-
} else {
|
|
218
|
-
this.res.cookies[key] = cookies2[key];
|
|
219
|
-
}
|
|
211
|
+
cookies(key, value) {
|
|
212
|
+
if (typeof key === "object") {
|
|
213
|
+
Object.entries(key).map(([key2, value2]) => this.cookies(key2, value2));
|
|
214
|
+
return this;
|
|
220
215
|
}
|
|
221
|
-
|
|
216
|
+
if (Array.isArray(value)) {
|
|
217
|
+
Object.values(value).map((val) => this.cookies(key, val));
|
|
218
|
+
return this;
|
|
219
|
+
}
|
|
220
|
+
console.log(key, value);
|
|
221
|
+
if (value === null) return this.cookies(key, { expires: EXPIRED });
|
|
222
|
+
if (typeof value !== "object") return this.cookies(key, { value });
|
|
223
|
+
return this.headers("set-cookie", createCookies(key, value));
|
|
222
224
|
}
|
|
223
225
|
json(body) {
|
|
224
|
-
return this.headers(
|
|
225
|
-
|
|
226
|
-
|
|
226
|
+
return this.headers("content-type", "application/json").send(
|
|
227
|
+
JSON.stringify(body)
|
|
228
|
+
);
|
|
227
229
|
}
|
|
228
|
-
redirect(
|
|
229
|
-
return this.headers(
|
|
230
|
+
redirect(path2) {
|
|
231
|
+
return this.headers("location", path2).status(302).send();
|
|
230
232
|
}
|
|
231
|
-
async file(path2
|
|
233
|
+
async file(path2) {
|
|
232
234
|
try {
|
|
233
|
-
const fs2 = await import("fs
|
|
234
|
-
const data = await fs2.readFile(path2);
|
|
235
|
+
const fs2 = await import("fs");
|
|
235
236
|
const ext = path2.split(".").pop();
|
|
236
|
-
|
|
237
|
+
const stream = fs2.createReadStream(path2);
|
|
238
|
+
return this.type(ext).send(stream);
|
|
237
239
|
} catch (error) {
|
|
238
240
|
if (error.code === "ENOENT") {
|
|
239
241
|
return this.status(404).send();
|
|
@@ -241,50 +243,39 @@ var Reply = class {
|
|
|
241
243
|
throw error;
|
|
242
244
|
}
|
|
243
245
|
}
|
|
244
|
-
async view(path2, renderer = async (data) => data, ctx) {
|
|
245
|
-
if (!ctx?.options.views) {
|
|
246
|
-
throw new Error("Views not enabled");
|
|
247
|
-
}
|
|
248
|
-
const data = await ctx.options.views.read(path2);
|
|
249
|
-
if (!data) return this.status(404).send();
|
|
250
|
-
return this.type(path2.split(".").pop()).send(await renderer(data));
|
|
251
|
-
}
|
|
252
246
|
send(body = "") {
|
|
253
|
-
const { status: status2 = 200 } = this.res;
|
|
247
|
+
const { status: status2 = 200, headers: headers2 } = this.res;
|
|
254
248
|
if (typeof body === "string") {
|
|
255
|
-
if (!
|
|
256
|
-
const isHtml = body.startsWith("<");
|
|
257
|
-
|
|
249
|
+
if (!headers2.get("content-type")) {
|
|
250
|
+
const isHtml = body.trim().startsWith("<");
|
|
251
|
+
headers2.set("content-type", isHtml ? "text/html" : "text/plain");
|
|
258
252
|
}
|
|
259
|
-
const headers2 = this.generateHeaders();
|
|
260
253
|
return new Response(body, { status: status2, headers: headers2 });
|
|
261
254
|
}
|
|
262
255
|
const name = body?.constructor?.name;
|
|
263
256
|
if (name === "Buffer") {
|
|
264
|
-
const headers2 = this.generateHeaders();
|
|
265
257
|
return new Response(body, { status: status2, headers: headers2 });
|
|
266
258
|
}
|
|
267
|
-
if (
|
|
268
|
-
const headers2 = this.generateHeaders();
|
|
259
|
+
if (typeof body?.getReader === "function") {
|
|
269
260
|
return new Response(body, { status: status2, headers: headers2 });
|
|
270
261
|
}
|
|
271
262
|
if (name === "PassThrough" || name === "Readable") {
|
|
272
|
-
const headers2 = this.generateHeaders();
|
|
273
263
|
return new Response(toWeb(body), { status: status2, headers: headers2 });
|
|
274
264
|
}
|
|
275
|
-
|
|
265
|
+
headers2.set("content-type", "application/json");
|
|
266
|
+
return new Response(JSON.stringify(body), { status: status2, headers: headers2 });
|
|
276
267
|
}
|
|
277
268
|
};
|
|
278
|
-
var
|
|
279
|
-
var
|
|
280
|
-
var
|
|
281
|
-
var
|
|
282
|
-
var
|
|
283
|
-
var
|
|
284
|
-
var
|
|
285
|
-
var
|
|
286
|
-
var
|
|
287
|
-
var
|
|
269
|
+
var r = () => new Reply();
|
|
270
|
+
var status = (...args) => r().status(...args);
|
|
271
|
+
var headers = (...args) => r().headers(...args);
|
|
272
|
+
var type = (...args) => r().type(...args);
|
|
273
|
+
var download = (...args) => r().download(...args);
|
|
274
|
+
var cookies = (...args) => r().cookies(...args);
|
|
275
|
+
var send = (...args) => r().send(...args);
|
|
276
|
+
var json = (...args) => r().json(...args);
|
|
277
|
+
var file = (...args) => r().file(...args);
|
|
278
|
+
var redirect = (...args) => r().redirect(...args);
|
|
288
279
|
|
|
289
280
|
// src/auth/providers/github.ts
|
|
290
281
|
var oauth = async (code) => {
|
|
@@ -364,14 +355,30 @@ var github_default = { login, callback };
|
|
|
364
355
|
var providers_default = { email: email_default, github: github_default };
|
|
365
356
|
|
|
366
357
|
// src/auth/parseAuthOptions.ts
|
|
358
|
+
var defaultRedirect = "/user";
|
|
359
|
+
function defaultCleanUser(fullUser) {
|
|
360
|
+
const { password: _password, ...user } = fullUser;
|
|
361
|
+
return user;
|
|
362
|
+
}
|
|
363
|
+
var providersKeys = Object.keys(providers_default);
|
|
364
|
+
function getProviders(provider) {
|
|
365
|
+
if (typeof provider === "string") {
|
|
366
|
+
provider = provider.split("|");
|
|
367
|
+
}
|
|
368
|
+
const invalidProvider = provider.find((p) => !providersKeys.includes(p));
|
|
369
|
+
if (invalidProvider) {
|
|
370
|
+
throw new Error(
|
|
371
|
+
`Provider "${invalidProvider}" not found, available ones are "${providersKeys.join('", "')}"`
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
return provider;
|
|
375
|
+
}
|
|
367
376
|
function parseAuthOptions(auth2, all) {
|
|
368
377
|
if (!auth2) return null;
|
|
369
378
|
if (typeof auth2 === "string") {
|
|
370
|
-
const [
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
if (typeof auth2.provider === "string") {
|
|
374
|
-
auth2.provider = auth2.provider.split("|").filter(Boolean);
|
|
379
|
+
const [strategy2, providerRaw] = auth2.split(":");
|
|
380
|
+
const provider2 = providerRaw && providerRaw.split("|");
|
|
381
|
+
auth2 = { strategy: strategy2, provider: provider2 };
|
|
375
382
|
}
|
|
376
383
|
if (!auth2.strategy) {
|
|
377
384
|
throw new Error("Auth options needs a strategy");
|
|
@@ -379,31 +386,32 @@ function parseAuthOptions(auth2, all) {
|
|
|
379
386
|
if (!auth2.strategy.length) {
|
|
380
387
|
throw new Error("Auth options needs a strategy");
|
|
381
388
|
}
|
|
389
|
+
const strategy = auth2.strategy;
|
|
382
390
|
if (!auth2.provider || !auth2.provider.length) {
|
|
383
391
|
throw new Error("Auth options needs a provider");
|
|
384
392
|
}
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
);
|
|
393
|
+
const provider = getProviders(auth2.provider);
|
|
394
|
+
const redirect2 = auth2.redirect || defaultRedirect;
|
|
395
|
+
const cleanUser = auth2.cleanUser || defaultCleanUser;
|
|
396
|
+
if (!auth2.store && !all.store) {
|
|
397
|
+
throw new Error("Need a userStore store for Auth");
|
|
390
398
|
}
|
|
391
|
-
if (!auth2.session && all.store) {
|
|
392
|
-
|
|
399
|
+
if (!auth2.session && !all.store) {
|
|
400
|
+
throw new Error("Need a sessionStore store for Auth");
|
|
393
401
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
402
|
+
const store = auth2.store || all.store.prefix("user:");
|
|
403
|
+
const session2 = auth2.session || all.store.prefix("auth:");
|
|
404
|
+
return {
|
|
405
|
+
// Base main configuration
|
|
406
|
+
strategy,
|
|
407
|
+
provider,
|
|
408
|
+
// Extra configuration
|
|
409
|
+
redirect: redirect2,
|
|
410
|
+
cleanUser,
|
|
411
|
+
// Stores for the auth session and users
|
|
412
|
+
store,
|
|
413
|
+
session: session2
|
|
414
|
+
};
|
|
407
415
|
}
|
|
408
416
|
|
|
409
417
|
// src/helpers/bucket.ts
|
|
@@ -660,20 +668,52 @@ function cors(config2, origin = "") {
|
|
|
660
668
|
}
|
|
661
669
|
|
|
662
670
|
// src/helpers/createCookies.ts
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
671
|
+
var EXPIRED2 = (/* @__PURE__ */ new Date(0)).toUTCString();
|
|
672
|
+
var times = /(-?(?:\d+\.?\d*|\d*\.?\d+)(?:e[-+]?\d+)?)\s*([\p{L}]*)/iu;
|
|
673
|
+
parse.millisecond = parse.ms = 1e-3;
|
|
674
|
+
parse.second = parse.sec = parse.s = parse[""] = 1;
|
|
675
|
+
parse.minute = parse.min = parse.m = parse.s * 60;
|
|
676
|
+
parse.hour = parse.hr = parse.h = parse.m * 60;
|
|
677
|
+
parse.day = parse.d = parse.h * 24;
|
|
678
|
+
parse.week = parse.wk = parse.w = parse.d * 7;
|
|
679
|
+
parse.year = parse.yr = parse.y = parse.d * 365.25;
|
|
680
|
+
parse.month = parse.b = parse.y / 12;
|
|
681
|
+
function parse(str) {
|
|
682
|
+
if (str === null || str === void 0) return null;
|
|
683
|
+
if (typeof str === "number") return str;
|
|
684
|
+
str = str.toLowerCase().replace(/[,_]/g, "");
|
|
685
|
+
const [_, value, units] = times.exec(str) || [];
|
|
686
|
+
if (!units) return null;
|
|
687
|
+
const unitValue = parse[units] || parse[units.replace(/s$/, "")];
|
|
688
|
+
if (!unitValue) return null;
|
|
689
|
+
const result = unitValue * parseFloat(value);
|
|
690
|
+
return Math.abs(Math.round(result * 1e3));
|
|
691
|
+
}
|
|
692
|
+
function normalizeExpires(expires) {
|
|
693
|
+
if (expires === null || expires === void 0) return void 0;
|
|
694
|
+
if (expires === 0) return EXPIRED2;
|
|
695
|
+
if (typeof expires === "string") {
|
|
696
|
+
if (/^[\d._]+\w+$/.test(expires)) {
|
|
697
|
+
return new Date(Date.now() + parse(expires)).toUTCString();
|
|
698
|
+
} else {
|
|
699
|
+
return expires;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
if (typeof expires === "number") {
|
|
703
|
+
return new Date(Date.now() + expires).toUTCString();
|
|
704
|
+
}
|
|
705
|
+
if (expires instanceof Date) {
|
|
706
|
+
return expires.toUTCString();
|
|
707
|
+
}
|
|
708
|
+
return void 0;
|
|
709
|
+
}
|
|
710
|
+
function createCookies(key, val) {
|
|
711
|
+
if (val.value === null) val.expires = EXPIRED2;
|
|
712
|
+
const { value, path: path2, expires } = val;
|
|
713
|
+
const pathPart = `;Path=${path2 || "/"}`;
|
|
714
|
+
const expiresStr = normalizeExpires(expires);
|
|
715
|
+
const expiresPart = typeof expires !== "undefined" ? `;Expires=${expiresStr}` : "";
|
|
716
|
+
return `${key}=${value || ""}${pathPart}${expiresPart}`;
|
|
677
717
|
}
|
|
678
718
|
|
|
679
719
|
// src/helpers/createWebsocket.ts
|
|
@@ -789,7 +829,7 @@ async function parseResponse(out, ctx) {
|
|
|
789
829
|
}
|
|
790
830
|
if (Object.keys(ctx.session || {}).length) {
|
|
791
831
|
if (!ctx.options.session?.store) {
|
|
792
|
-
throw ServerError_default.NO_STORE(
|
|
832
|
+
throw ServerError_default.NO_STORE();
|
|
793
833
|
}
|
|
794
834
|
if (!ctx.cookies.session) {
|
|
795
835
|
ctx.res.cookies.session = createId();
|
|
@@ -1378,7 +1418,7 @@ var encode = (str = "") => {
|
|
|
1378
1418
|
};
|
|
1379
1419
|
var getConfig = (routes) => {
|
|
1380
1420
|
const config2 = routes.find(
|
|
1381
|
-
(
|
|
1421
|
+
(r2) => typeof r2 !== "string" && typeof r2 !== "function" && typeof r2 === "object"
|
|
1382
1422
|
);
|
|
1383
1423
|
if (!config2) return {};
|
|
1384
1424
|
if (config2.tags) {
|
|
@@ -1527,13 +1567,13 @@ var openapi_default = async (ctx) => {
|
|
|
1527
1567
|
|
|
1528
1568
|
// src/middle/timer.ts
|
|
1529
1569
|
var createTime = () => {
|
|
1530
|
-
const
|
|
1531
|
-
const time = (name) =>
|
|
1532
|
-
time.times =
|
|
1570
|
+
const times2 = [["init", performance.now()]];
|
|
1571
|
+
const time = (name) => times2.push([name, performance.now()]);
|
|
1572
|
+
time.times = times2;
|
|
1533
1573
|
time.headers = () => {
|
|
1534
|
-
const
|
|
1535
|
-
const
|
|
1536
|
-
const timing =
|
|
1574
|
+
const r2 = (t) => Math.round(t);
|
|
1575
|
+
const times3 = time.times;
|
|
1576
|
+
const timing = times3.slice(1).map(([name, time2], i) => `${name};dur=${r2(time2 - times3[i][1])}`).join(", ");
|
|
1537
1577
|
return timing;
|
|
1538
1578
|
};
|
|
1539
1579
|
return time;
|
|
@@ -1833,39 +1873,27 @@ function isSerializable(body) {
|
|
|
1833
1873
|
}
|
|
1834
1874
|
function ServerTest(app) {
|
|
1835
1875
|
const port = app.settings.port;
|
|
1836
|
-
const fetch2 = async (
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
);
|
|
1849
|
-
const headers2 = parseHeaders_default(res.headers);
|
|
1850
|
-
let body;
|
|
1851
|
-
if (headers2["content-type"]?.includes("application/json")) {
|
|
1852
|
-
body = await res.json();
|
|
1853
|
-
} else {
|
|
1854
|
-
body = await res.text();
|
|
1855
|
-
}
|
|
1856
|
-
return { status: res.status, headers: headers2, body };
|
|
1857
|
-
} catch (error) {
|
|
1858
|
-
return { status: 500, headers: {}, body: error.message };
|
|
1859
|
-
}
|
|
1876
|
+
const fetch2 = async (method, path2, options = {}) => {
|
|
1877
|
+
if (!options.headers) options.headers = {};
|
|
1878
|
+
if (isSerializable(options.body)) {
|
|
1879
|
+
options.headers["content-type"] = "application/json";
|
|
1880
|
+
options.body = JSON.stringify(options.body);
|
|
1881
|
+
}
|
|
1882
|
+
return await app.fetch(
|
|
1883
|
+
new Request(`http://localhost:${port}${path2}`, {
|
|
1884
|
+
method,
|
|
1885
|
+
...options
|
|
1886
|
+
})
|
|
1887
|
+
);
|
|
1860
1888
|
};
|
|
1861
1889
|
return {
|
|
1862
|
-
get: (path2, options) => fetch2(
|
|
1863
|
-
head: (path2, options) => fetch2(
|
|
1864
|
-
post: (path2, body, options) => fetch2(
|
|
1865
|
-
put: (path2, body, options) => fetch2(
|
|
1866
|
-
patch: (path2, body, options) => fetch2(
|
|
1867
|
-
delete: (path2, options) => fetch2(
|
|
1868
|
-
options: (path2, options) => fetch2(
|
|
1890
|
+
get: (path2, options) => fetch2("get", path2, options),
|
|
1891
|
+
head: (path2, options) => fetch2("head", path2, options),
|
|
1892
|
+
post: (path2, body, options) => fetch2("post", path2, { body, ...options }),
|
|
1893
|
+
put: (path2, body, options) => fetch2("put", path2, { body, ...options }),
|
|
1894
|
+
patch: (path2, body, options) => fetch2("patch", path2, { body, ...options }),
|
|
1895
|
+
delete: (path2, options) => fetch2("delete", path2, options),
|
|
1896
|
+
options: (path2, options) => fetch2("options", path2, options)
|
|
1869
1897
|
};
|
|
1870
1898
|
}
|
|
1871
1899
|
|
|
@@ -1934,7 +1962,6 @@ function server(options = {}) {
|
|
|
1934
1962
|
return new Server(options).self();
|
|
1935
1963
|
}
|
|
1936
1964
|
export {
|
|
1937
|
-
Reply,
|
|
1938
1965
|
Server,
|
|
1939
1966
|
ServerError_default as ServerError,
|
|
1940
1967
|
cookies,
|
|
@@ -1947,6 +1974,5 @@ export {
|
|
|
1947
1974
|
router,
|
|
1948
1975
|
send,
|
|
1949
1976
|
status,
|
|
1950
|
-
type
|
|
1951
|
-
view
|
|
1977
|
+
type
|
|
1952
1978
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@server/next",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.4",
|
|
4
4
|
"description": "A fully-fledged web server with routing, file uploads, sessions, static files, schema validation, websockets, testing, etc.",
|
|
5
5
|
"homepage": "https://server-js.com/",
|
|
6
6
|
"repository": "https://github.com/franciscop/server-next.git",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"build": "bunx tsup src/index.ts --format esm --dts --out-dir . --target node24",
|
|
21
21
|
"start": "bun test --watch",
|
|
22
22
|
"lint": "npx @biomejs/biome lint ./src --skip=lint/suspicious/noExplicitAny --skip=lint/style/noParameterAssign --skip=lint/suspicious/noConfusingVoidType",
|
|
23
|
-
"types": "npx tsc --noEmit
|
|
23
|
+
"types": "npx tsc --noEmit",
|
|
24
24
|
"test": "npm run test:bun && tsc --noEmit",
|
|
25
25
|
"test:bun": "bun test",
|
|
26
26
|
"test:jest": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
|
|
@@ -34,11 +34,13 @@
|
|
|
34
34
|
"main": "index.js",
|
|
35
35
|
"types": "index.d.ts",
|
|
36
36
|
"files": [
|
|
37
|
+
"index.d.ts",
|
|
37
38
|
"src/jsx/"
|
|
38
39
|
],
|
|
39
40
|
"exports": {
|
|
40
41
|
".": "./index.js",
|
|
41
|
-
"./
|
|
42
|
+
"./index.d.ts": "./index.d.ts",
|
|
43
|
+
"./jsx-runtime": "./src/jsx/jsx-runtime.js",
|
|
42
44
|
"./jsx-dev-runtime": "./src/jsx/jsx-dev-runtime.js"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
|
@@ -1,91 +1 @@
|
|
|
1
|
-
|
|
2
|
-
"&": "&",
|
|
3
|
-
"<": "<",
|
|
4
|
-
">": ">",
|
|
5
|
-
'"': """,
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const encode = (str = "") => {
|
|
9
|
-
if (typeof str === "number") str = String(str);
|
|
10
|
-
if (typeof str !== "string") return "";
|
|
11
|
-
return str.replace(/[&<>"]/g, (tag) => entities[tag]);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
const SELFCLOSE = new Set(
|
|
15
|
-
"area,base,br,col,embed,hr,img,input,link,meta,source,track,wbr".split(","),
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const altAttrs = {
|
|
19
|
-
classname: "class",
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
// "" and 0 are valid children, false and null and undefined are not
|
|
23
|
-
const isValidChild = (child) => child || child === "" || child === 0;
|
|
24
|
-
|
|
25
|
-
const escapeCSS = (value) => String(value).replace(/[<>&"'`]/g, "\\$&");
|
|
26
|
-
|
|
27
|
-
const minifyCss = (str) =>
|
|
28
|
-
str
|
|
29
|
-
.replace(/\s+/g, " ")
|
|
30
|
-
.replace(/(?!<")\/\*[^*]+\*\/(?!")/g, "")
|
|
31
|
-
.replace(/(\w|\*) (\{)/g, "$1$2")
|
|
32
|
-
.replace(/(\}) (\w|\*)/g, "$1$2")
|
|
33
|
-
.replace(/(\{) (\w)/g, "$1$2")
|
|
34
|
-
.replace(/(\w)(:) /g, "$1$2")
|
|
35
|
-
.replace(/(;) (\})/g, "$1$2")
|
|
36
|
-
.replace(/(;) (\w)/g, "$1$2")
|
|
37
|
-
.replace(/;(\})/g, "$1")
|
|
38
|
-
.replace(/(\w), (\w)/g, "$1,$2")
|
|
39
|
-
.replace(/(\w), (\w)/g, "$1,$2")
|
|
40
|
-
.replace(/(\{) (\w)/g, "$1$2")
|
|
41
|
-
.trim();
|
|
42
|
-
|
|
43
|
-
const jsx = (tag, { children, ...props }) => {
|
|
44
|
-
if (typeof tag === "function") return tag({ children, ...props });
|
|
45
|
-
|
|
46
|
-
if (tag === "script" && children) {
|
|
47
|
-
const src = children;
|
|
48
|
-
children = () => src;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (tag === "style" && children && typeof children === "string") {
|
|
52
|
-
const src = minifyCss(escapeCSS(children));
|
|
53
|
-
children = () => src;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (props?.dangerouslySetInnerHTML) {
|
|
57
|
-
children = () => props.dangerouslySetInnerHTML.__html;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (!isValidChild(children)) children = [];
|
|
61
|
-
if (typeof children === "string") children = [children];
|
|
62
|
-
|
|
63
|
-
children = (Array.isArray(children) ? children : [children])
|
|
64
|
-
.flat()
|
|
65
|
-
.map((c) => (typeof c === "function" ? c() : encode(c)))
|
|
66
|
-
.join("");
|
|
67
|
-
|
|
68
|
-
if (!tag) return () => children;
|
|
69
|
-
|
|
70
|
-
let attrStr = Object.entries(props || {})
|
|
71
|
-
.filter(([k]) => k !== "dangerouslySetInnerHTML")
|
|
72
|
-
.filter(([k, v]) => !/on[A-Z]/.test(k) && typeof v !== "function")
|
|
73
|
-
.filter(([, v]) => v !== false)
|
|
74
|
-
.map(([k, v]) =>
|
|
75
|
-
v === true
|
|
76
|
-
? altAttrs[k.toLowerCase()] || encode(k)
|
|
77
|
-
: `${altAttrs[k.toLowerCase()] || encode(k)}="${encode(String(v))}"`,
|
|
78
|
-
)
|
|
79
|
-
.join(" ");
|
|
80
|
-
|
|
81
|
-
if (attrStr) attrStr = ` ${attrStr}`;
|
|
82
|
-
|
|
83
|
-
if (SELFCLOSE.has(tag)) return () => `<${tag}${attrStr} />`;
|
|
84
|
-
|
|
85
|
-
const doctype = tag === "html" ? "<!DOCTYPE html>" : "";
|
|
86
|
-
return () => `${doctype}<${tag}${attrStr}>${children}</${tag}>`;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const Fragment = "";
|
|
90
|
-
|
|
91
|
-
export { jsx, jsx as jsxs, jsx as jsxDEV, Fragment };
|
|
1
|
+
export * from "./jsx-runtime.js";
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const entities = {
|
|
2
|
+
"&": "&",
|
|
3
|
+
"<": "<",
|
|
4
|
+
">": ">",
|
|
5
|
+
'"': """,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const encode = (str = "") => {
|
|
9
|
+
if (typeof str === "number") str = String(str);
|
|
10
|
+
if (typeof str !== "string") return "";
|
|
11
|
+
return str.replace(/[&<>"]/g, (tag) => entities[tag]);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const SELFCLOSE = new Set(
|
|
15
|
+
"area,base,br,col,embed,hr,img,input,link,meta,source,track,wbr".split(","),
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const altAttrs = {
|
|
19
|
+
classname: "class",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// "" and 0 are valid children, false and null and undefined are not
|
|
23
|
+
const isValidChild = (child) => child || child === "" || child === 0;
|
|
24
|
+
|
|
25
|
+
const escapeCSS = (value) => String(value).replace(/[<>&"'`]/g, "\\$&");
|
|
26
|
+
|
|
27
|
+
const minifyCss = (str) =>
|
|
28
|
+
str
|
|
29
|
+
.replace(/\s+/g, " ")
|
|
30
|
+
.replace(/(?!<")\/\*[^*]+\*\/(?!")/g, "")
|
|
31
|
+
.replace(/(\w|\*) (\{)/g, "$1$2")
|
|
32
|
+
.replace(/(\}) (\w|\*)/g, "$1$2")
|
|
33
|
+
.replace(/(\{) (\w)/g, "$1$2")
|
|
34
|
+
.replace(/(\w)(:) /g, "$1$2")
|
|
35
|
+
.replace(/(;) (\})/g, "$1$2")
|
|
36
|
+
.replace(/(;) (\w)/g, "$1$2")
|
|
37
|
+
.replace(/;(\})/g, "$1")
|
|
38
|
+
.replace(/(\w), (\w)/g, "$1,$2")
|
|
39
|
+
.replace(/(\w), (\w)/g, "$1,$2")
|
|
40
|
+
.replace(/(\{) (\w)/g, "$1$2")
|
|
41
|
+
.trim();
|
|
42
|
+
|
|
43
|
+
const jsx = (tag, { children, ...props }) => {
|
|
44
|
+
if (typeof tag === "function") return tag({ children, ...props });
|
|
45
|
+
|
|
46
|
+
if (tag === "script" && children) {
|
|
47
|
+
const src = children;
|
|
48
|
+
children = () => src;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (tag === "style" && children && typeof children === "string") {
|
|
52
|
+
const src = minifyCss(escapeCSS(children));
|
|
53
|
+
children = () => src;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (props?.dangerouslySetInnerHTML) {
|
|
57
|
+
children = () => props.dangerouslySetInnerHTML.__html;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!isValidChild(children)) children = [];
|
|
61
|
+
if (typeof children === "string") children = [children];
|
|
62
|
+
|
|
63
|
+
children = (Array.isArray(children) ? children : [children])
|
|
64
|
+
.flat()
|
|
65
|
+
.map((c) => (typeof c === "function" ? c() : encode(c)))
|
|
66
|
+
.join("");
|
|
67
|
+
|
|
68
|
+
if (!tag) return () => children;
|
|
69
|
+
|
|
70
|
+
let attrStr = Object.entries(props || {})
|
|
71
|
+
.filter(([k]) => k !== "dangerouslySetInnerHTML")
|
|
72
|
+
.filter(([k, v]) => !/on[A-Z]/.test(k) && typeof v !== "function")
|
|
73
|
+
.filter(([, v]) => v !== false)
|
|
74
|
+
.map(([k, v]) =>
|
|
75
|
+
v === true
|
|
76
|
+
? altAttrs[k.toLowerCase()] || encode(k)
|
|
77
|
+
: `${altAttrs[k.toLowerCase()] || encode(k)}="${encode(String(v))}"`,
|
|
78
|
+
)
|
|
79
|
+
.join(" ");
|
|
80
|
+
|
|
81
|
+
if (attrStr) attrStr = ` ${attrStr}`;
|
|
82
|
+
|
|
83
|
+
if (SELFCLOSE.has(tag)) return () => `<${tag}${attrStr} />`;
|
|
84
|
+
|
|
85
|
+
const doctype = tag === "html" ? "<!DOCTYPE html>" : "";
|
|
86
|
+
return () => `${doctype}<${tag}${attrStr}>${children}</${tag}>`;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const Fragment = "";
|
|
90
|
+
|
|
91
|
+
export { jsx, jsx as jsxs, jsx as jsxDEV, Fragment };
|