dynara 0.0.1 → 0.0.2
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 +11 -11
- package/dist/index.d.ts +15 -15
- package/dist/index.js +10 -10
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Dynara
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/dynara)
|
|
4
4
|
|
|
5
5
|
An extremely simple HTTP framework for Bun — practically a typed wrapper around `Bun.serve`, with Fastify-style routing and fast schema validation. Made for people switching over from Fastify.
|
|
6
6
|
|
|
@@ -11,15 +11,15 @@ An extremely simple HTTP framework for Bun — practically a typed wrapper aroun
|
|
|
11
11
|
## Install
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
bun add
|
|
14
|
+
bun add dynara
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Quick start
|
|
18
18
|
|
|
19
19
|
```ts
|
|
20
|
-
import {
|
|
20
|
+
import { Router } from 'dynara'
|
|
21
21
|
|
|
22
|
-
const app = new
|
|
22
|
+
const app = new Router()
|
|
23
23
|
|
|
24
24
|
app.get('/', () => {
|
|
25
25
|
return { hello: 'world' }
|
|
@@ -80,22 +80,22 @@ app.addHook('onListen', (server) => {
|
|
|
80
80
|
```ts
|
|
81
81
|
type Ctx = { user: { id: number } }
|
|
82
82
|
|
|
83
|
-
app.register((users:
|
|
83
|
+
app.register((users: Router<Ctx>) => {
|
|
84
84
|
users.addHook('onRequest', (req) => { req.user = { id: 1 } })
|
|
85
85
|
users.get('/me', (req) => req.user)
|
|
86
86
|
}, { prefix: '/users' })
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
For composable, reusable plugins there is the `
|
|
89
|
+
For composable, reusable plugins there is the `dynara()` builder. `use` adds plugins, `routes` adds handlers, and the result can be passed to `register`:
|
|
90
90
|
|
|
91
91
|
```ts
|
|
92
|
-
import {
|
|
92
|
+
import { dynara, Router } from 'dynara'
|
|
93
93
|
|
|
94
|
-
const useAuth = (app:
|
|
94
|
+
const useAuth = (app: Router<Ctx>) => {
|
|
95
95
|
app.addHook('onRequest', (req) => { req.user = { id: 1 } })
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
const users =
|
|
98
|
+
const users = dynara<Ctx>()
|
|
99
99
|
.use(useAuth)
|
|
100
100
|
.routes((app) => {
|
|
101
101
|
app.get('/me', (req) => req.user)
|
|
@@ -109,7 +109,7 @@ app.register(users, { prefix: '/users' })
|
|
|
109
109
|
Throw `HTTPError` to send an explicit status code; validation failures are turned into `400` responses automatically.
|
|
110
110
|
|
|
111
111
|
```ts
|
|
112
|
-
import { HTTPError } from '
|
|
112
|
+
import { HTTPError } from 'dynara'
|
|
113
113
|
|
|
114
114
|
app.get('/secret', () => {
|
|
115
115
|
throw new HTTPError('Forbidden', 403) // text body
|
package/dist/index.d.ts
CHANGED
|
@@ -15,21 +15,21 @@ type GetRouteOptions = {
|
|
|
15
15
|
params?: SchemaItem
|
|
16
16
|
query?: SchemaItem
|
|
17
17
|
};
|
|
18
|
-
interface
|
|
19
|
-
type
|
|
18
|
+
interface DynaraContext {}
|
|
19
|
+
type DynaraRequest<
|
|
20
20
|
R extends object = {},
|
|
21
21
|
T extends RouteOptions = {}
|
|
22
|
-
> =
|
|
22
|
+
> = DynaraContext & R & {
|
|
23
23
|
params: T["params"] extends object ? SchemaType<T["params"]> : unknown
|
|
24
24
|
query: T["query"] extends object ? SchemaType<T["query"]> : unknown
|
|
25
25
|
body: T["body"] extends object ? SchemaType<T["body"]> : unknown
|
|
26
26
|
raw: BunRequest
|
|
27
27
|
server: Server
|
|
28
28
|
};
|
|
29
|
-
type
|
|
29
|
+
type GetDynaraRequest<
|
|
30
30
|
R extends object = {},
|
|
31
31
|
T extends GetRouteOptions = {}
|
|
32
|
-
> =
|
|
32
|
+
> = DynaraContext & R & {
|
|
33
33
|
params: T["params"] extends object ? SchemaType<T["params"]> : unknown
|
|
34
34
|
query: T["query"] extends object ? SchemaType<T["query"]> : unknown
|
|
35
35
|
raw: BunRequest
|
|
@@ -38,11 +38,11 @@ type GetMarciRequest<
|
|
|
38
38
|
type RouteAction<
|
|
39
39
|
T extends RouteOptions,
|
|
40
40
|
R extends object = {}
|
|
41
|
-
> = (req:
|
|
41
|
+
> = (req: DynaraRequest<R, T>) => (any | Promise<any>);
|
|
42
42
|
type GetRouteAction<
|
|
43
43
|
T extends GetRouteOptions,
|
|
44
44
|
R extends object = {}
|
|
45
|
-
> = (req:
|
|
45
|
+
> = (req: GetDynaraRequest<R, T>) => (any | Promise<any>);
|
|
46
46
|
type RegisterPluginOptions = {
|
|
47
47
|
prefix?: string
|
|
48
48
|
};
|
|
@@ -67,7 +67,7 @@ type PostOptionsFromSchemaList<T extends readonly SchemaItem2[]> = T extends [Sc
|
|
|
67
67
|
params: T[0]
|
|
68
68
|
body: T[1]
|
|
69
69
|
} : {};
|
|
70
|
-
declare class
|
|
70
|
+
declare class Router<R extends object = {}> {
|
|
71
71
|
private routes;
|
|
72
72
|
private promises;
|
|
73
73
|
private prefix;
|
|
@@ -77,7 +77,7 @@ declare class MarciApp<R extends object = {}> {
|
|
|
77
77
|
private onRequestHooks;
|
|
78
78
|
private add;
|
|
79
79
|
addHook(where: "onListen", callback: (server: Bun.Server2) => void): void;
|
|
80
|
-
addHook(where: "onRequest", callback: (ctx:
|
|
80
|
+
addHook(where: "onRequest", callback: (ctx: DynaraRequest<R>) => void): void;
|
|
81
81
|
get(path: string, callback: GetRouteAction<{}, R>): void;
|
|
82
82
|
get<T extends GetRouteOptions>(path: string, options: T, callback: GetRouteAction<T, R>): void;
|
|
83
83
|
get<T extends readonly SchemaItem3[]>(path: string, schemas: [...T], callback: GetRouteAction<GetOptionsFromSchemaList<T>, R>): void;
|
|
@@ -93,7 +93,7 @@ declare class MarciApp<R extends object = {}> {
|
|
|
93
93
|
delete(path: string, callback: RouteAction<{}, R>): void;
|
|
94
94
|
delete<T extends RouteOptions>(path: string, options: T, callback: RouteAction<T, R>): void;
|
|
95
95
|
delete<T extends readonly SchemaItem3[]>(path: string, schemas: [...T], callback: RouteAction<PostOptionsFromSchemaList<T>, R>): void;
|
|
96
|
-
register(plugin: (app:
|
|
96
|
+
register(plugin: (app: Router<any>) => void | Promise<void>, options?: RegisterPluginOptions): void;
|
|
97
97
|
private websocket?;
|
|
98
98
|
private websocketPath?;
|
|
99
99
|
private websocketFetch?;
|
|
@@ -108,12 +108,12 @@ declare class MarciApp<R extends object = {}> {
|
|
|
108
108
|
/**\\n\\t\\n\\t* Dispatches a request through the app's routes in-process — no server, no\\n\\t\\n\\t* socket. Matches the route the same way Bun would, then runs the onRequest\\n\\t\\n\\t* hooks, validation, handler, and error mapping, returning the Response.\\n\\t\\n\\t* Intended for integration testing.\\n\\t\\n\\t*\\n\\t\\n\\t* @example\\n\\t\\n\\t* const res = await app.inject("/users/1")\\n\\t\\n\\t* const res = await app.inject({ method: "POST", url: "/users", body: { name: "Alice" } })\\n\\t\\n\\t* expect(res.status).toBe(200)\\n\\t\\n\\t* expect(await res.json()).toEqual({ ... })\\n\\t\\n\\t*/
|
|
109
109
|
inject(options: string | InjectOptions): Promise<Response>;
|
|
110
110
|
}
|
|
111
|
-
type
|
|
111
|
+
type Plugin<R extends object = {}> = ((app: Router<any>) => Promise<void>) & {
|
|
112
112
|
use<
|
|
113
113
|
S extends object = {},
|
|
114
114
|
A extends any[] = []
|
|
115
|
-
>(plugin: (app:
|
|
116
|
-
routes(app: (app:
|
|
115
|
+
>(plugin: (app: Router<R & S>, ...args: A) => Promise<void> | void, ...args: A): Plugin<R & S>
|
|
116
|
+
routes(app: (app: Router<R>) => Promise<void> | void): Plugin<R>
|
|
117
117
|
};
|
|
118
|
-
declare const
|
|
119
|
-
export {
|
|
118
|
+
declare const dynara: <R extends object = {}>() => Plugin<R>;
|
|
119
|
+
export { dynara, Router, Plugin, InjectOptions, HTTPError, DynaraRequest };
|
package/dist/index.js
CHANGED
|
@@ -28,8 +28,8 @@ class ValidationError extends Error {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
// src/
|
|
32
|
-
var
|
|
31
|
+
// src/plugin.ts
|
|
32
|
+
var dynara = () => {
|
|
33
33
|
const plugins = [];
|
|
34
34
|
const handlers = [];
|
|
35
35
|
const app = Object.assign(async (app2) => {
|
|
@@ -51,7 +51,7 @@ var marci = () => {
|
|
|
51
51
|
});
|
|
52
52
|
return app;
|
|
53
53
|
};
|
|
54
|
-
// src/
|
|
54
|
+
// src/Router.ts
|
|
55
55
|
import { unfoldTypeBoxSchema } from "compact-json-schema";
|
|
56
56
|
import { TypeBoxError } from "@sinclair/typebox";
|
|
57
57
|
import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
@@ -59,7 +59,7 @@ import { TypeCompiler } from "@sinclair/typebox/compiler";
|
|
|
59
59
|
// src/request.ts
|
|
60
60
|
import { Value } from "@sinclair/typebox/value";
|
|
61
61
|
|
|
62
|
-
class
|
|
62
|
+
class DynaraRequestInternal {
|
|
63
63
|
server;
|
|
64
64
|
raw;
|
|
65
65
|
params;
|
|
@@ -220,8 +220,8 @@ var matchRoute = (routes, method, pathname) => {
|
|
|
220
220
|
return best;
|
|
221
221
|
};
|
|
222
222
|
|
|
223
|
-
// src/
|
|
224
|
-
class
|
|
223
|
+
// src/Router.ts
|
|
224
|
+
class Router {
|
|
225
225
|
routes = {};
|
|
226
226
|
promises = [];
|
|
227
227
|
prefix = "";
|
|
@@ -245,7 +245,7 @@ class MarciApp {
|
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
this.routes[fullPath][method] = async (req) => {
|
|
248
|
-
const request = new
|
|
248
|
+
const request = new DynaraRequestInternal(req, this.root?.server ?? this.server, paramsSchema, querySchema);
|
|
249
249
|
for (const callback2 of this.onRequestHooks) {
|
|
250
250
|
await callback2(request);
|
|
251
251
|
}
|
|
@@ -304,7 +304,7 @@ class MarciApp {
|
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
register(plugin, options = {}) {
|
|
307
|
-
const app = new
|
|
307
|
+
const app = new Router;
|
|
308
308
|
app.root = this.root ?? this;
|
|
309
309
|
app.routes = this.routes;
|
|
310
310
|
app.onListenHooks = this.onListenHooks;
|
|
@@ -420,7 +420,7 @@ class MarciApp {
|
|
|
420
420
|
}
|
|
421
421
|
}
|
|
422
422
|
export {
|
|
423
|
-
|
|
424
|
-
|
|
423
|
+
dynara,
|
|
424
|
+
Router,
|
|
425
425
|
HTTPError
|
|
426
426
|
};
|
package/package.json
CHANGED
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
|
-
"version": "0.0.
|
|
14
|
+
"version": "0.0.2",
|
|
15
15
|
"description": "Simple HTTP framework powered by Bun",
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "https://github.com/den59k/
|
|
19
|
-
"directory": "packages/
|
|
18
|
+
"url": "https://github.com/den59k/dynara.git",
|
|
19
|
+
"directory": "packages/dynara"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "bunx bunup src/index.ts --format esm",
|