gruber 0.6.1 → 0.7.0

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 (44) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +52 -2
  3. package/core/authorization.d.ts.map +1 -1
  4. package/core/authorization.js +6 -1
  5. package/core/authorization.test.js +32 -2
  6. package/core/authorization.ts +5 -1
  7. package/core/fetch-router.d.ts +7 -0
  8. package/core/fetch-router.d.ts.map +1 -1
  9. package/core/fetch-router.js +11 -1
  10. package/core/fetch-router.ts +18 -1
  11. package/core/http.d.ts.map +1 -1
  12. package/core/http.js +3 -1
  13. package/core/http.ts +7 -1
  14. package/core/mod.d.ts +1 -0
  15. package/core/mod.d.ts.map +1 -1
  16. package/core/mod.js +1 -0
  17. package/core/mod.ts +1 -0
  18. package/core/server-sent-events.d.ts +50 -0
  19. package/core/server-sent-events.d.ts.map +1 -0
  20. package/core/server-sent-events.js +75 -0
  21. package/core/server-sent-events.ts +112 -0
  22. package/core/store.d.ts +6 -7
  23. package/core/store.d.ts.map +1 -1
  24. package/core/store.ts +9 -11
  25. package/core/types.d.ts +7 -0
  26. package/core/types.d.ts.map +1 -1
  27. package/core/types.js +0 -1
  28. package/core/types.ts +6 -4
  29. package/package.json +1 -1
  30. package/source/express-router.d.ts +2 -0
  31. package/source/express-router.d.ts.map +1 -1
  32. package/source/express-router.js +6 -0
  33. package/source/express-router.ts +7 -0
  34. package/source/koa-router.d.ts +2 -0
  35. package/source/koa-router.d.ts.map +1 -1
  36. package/source/koa-router.js +6 -0
  37. package/source/koa-router.ts +7 -0
  38. package/source/node-router.d.ts.map +1 -1
  39. package/source/node-router.js +4 -2
  40. package/source/node-router.ts +4 -2
  41. package/source/postgres.d.ts +1 -1
  42. package/source/postgres.d.ts.map +1 -1
  43. package/source/postgres.js +4 -3
  44. package/source/postgres.ts +5 -4
package/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  This file documents notable changes to the project
4
4
 
5
+ ## 0.7.0
6
+
7
+ **new**
8
+
9
+ - Add Server-sent events utilities
10
+ - Add experimental `log` option to `FetchRouter`
11
+ - Add experimental `expressMiddleware` and `koaMiddleware`
12
+
13
+ **fixes**
14
+
15
+ - Fix malformed node HTTP headers when they contain a comma
16
+ - Ignore invalid cookies rather than throw an error
17
+ - `getRequestBody` also checks for `multipart/form-data`
18
+ - node: `request.signal` is now triggered if the request is cancelled
19
+
20
+ ## 0.6.2
21
+
22
+ **fixes**
23
+
24
+ - Use `unknown` type when expecting a dependency, its now on the consumer to make sure they pass the correct thing. TypeScript-ing this is too hard.
25
+ - Experimental stores use dependency types too
26
+
5
27
  ## 0.6.1
6
28
 
7
29
  **new**
package/README.md CHANGED
@@ -726,7 +726,7 @@ TODO: I'm not happy with this, will need to come back to it.
726
726
 
727
727
  ## Core library
728
728
 
729
- ### http
729
+ ### HTTP
730
730
 
731
731
  #### defineRoute
732
732
 
@@ -1144,7 +1144,7 @@ The idea is you might check for `user:books:write` inside a request handler agai
1144
1144
 
1145
1145
  ### Authentication
1146
1146
 
1147
- > UNSTABLE
1147
+ > VERY UNSTABLE
1148
1148
 
1149
1149
  Authentication provides a service to help users get authorization to use the application.
1150
1150
 
@@ -1183,6 +1183,56 @@ const { token, headers, redirect } = await authn.finish(login);
1183
1183
  These would obviously be spread accross multiple endpoints and you transfer
1184
1184
  the token / code combination to the user in a way that proves they are who they claim to be.
1185
1185
 
1186
+ ### Server Sent Events
1187
+
1188
+ Gruber includes utilities for sending [Server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) from regular route definitions.
1189
+
1190
+ ```ts
1191
+ import { defineRoute, ServerSentEventStream, sseHeaders } from "gruber";
1192
+
1193
+ const stream = defineRoute({
1194
+ method: "GET",
1195
+ pathname: "/stream",
1196
+ async handler({ request }) {
1197
+ let counter = 0;
1198
+ let timerId = null;
1199
+
1200
+ // Create a stream to pipe data to the response,
1201
+ // it sends an incrementing counter every second
1202
+ const stream = new ReadableStream({
1203
+ start(controller) {
1204
+ timerId = setInterval(() => {
1205
+ counter++;
1206
+ controller.enqueue({ data: JSON.stringify({ counter }) });
1207
+ }, 1_000);
1208
+ },
1209
+ cancel() {
1210
+ if (timerId) clearInterval(timerId);
1211
+ },
1212
+ });
1213
+
1214
+ // Create a response that transforms the stream into an SSE body
1215
+ return new Response(stream.pipeThrough(new ServerSentEventStream()), {
1216
+ headers: {
1217
+ "content-type": "text/event-stream",
1218
+ "cache-control": "no-cache",
1219
+ connection: "keep-alive",
1220
+ },
1221
+ });
1222
+ },
1223
+ });
1224
+ ```
1225
+
1226
+ > You might want to use [ReadableStream.from](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream/from_static) to create the stream
1227
+
1228
+ #### ServerSentEventMessage
1229
+
1230
+ `ServerSentEventMessage` is an interface for the payload to be delivered to the client.
1231
+
1232
+ #### ServerSentEventStream
1233
+
1234
+ `ServerSentEventStream` is a [TransformStream]() that converts `ServerSentEventMessage` into the raw bytes to send to a client.
1235
+
1186
1236
  ### Utilities
1187
1237
 
1188
1238
  #### loader
@@ -1 +1 @@
1
- {"version":3,"file":"authorization.d.ts","sourceRoot":"","sources":["authorization.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,WAAW,CAC1B,OAAO,EAAE,OAAO,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAapC;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,iBAIjD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAErE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,YAQ1C;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAM7D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAE7D;AAED,MAAM,WAAW,iBAAiB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,4BAA4B;IAC5C,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IAClD,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9C,UAAU,CACT,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC3C,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,gBAAgB;AAChB,qBAAa,oBAAqB,YAAW,4BAA4B;IAEhE,OAAO,EAAE,2BAA2B;IACpC,MAAM,EAAE,YAAY;gBADpB,OAAO,EAAE,2BAA2B,EACpC,MAAM,EAAE,YAAY;IAG5B,gBAAgB,CAAC,OAAO,EAAE,OAAO;IAO3B,MAAM,CAAC,OAAO,EAAE,OAAO;IAUvB,UAAU,CACf,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,gBAAgB,CAAC;CAY5B"}
1
+ {"version":3,"file":"authorization.d.ts","sourceRoot":"","sources":["authorization.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,WAAW,CAC1B,OAAO,EAAE,OAAO,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAapC;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,iBAIjD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAMrE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,YAQ1C;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAM7D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAE7D;AAED,MAAM,WAAW,iBAAiB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,4BAA4B;IAC5C,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;IAClD,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9C,UAAU,CACT,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,iBAAiB,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,2BAA2B;IAC3C,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,gBAAgB;AAChB,qBAAa,oBAAqB,YAAW,4BAA4B;IAEhE,OAAO,EAAE,2BAA2B;IACpC,MAAM,EAAE,YAAY;gBADpB,OAAO,EAAE,2BAA2B,EACpC,MAAM,EAAE,YAAY;IAG5B,gBAAgB,CAAC,OAAO,EAAE,OAAO;IAO3B,MAAM,CAAC,OAAO,EAAE,OAAO;IAUvB,UAAU,CACf,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,iBAAsB,GAC7B,OAAO,CAAC,gBAAgB,CAAC;CAY5B"}
@@ -24,7 +24,12 @@ export function _getRequestBearer(request) {
24
24
  return /^bearer (.+)$/i.exec(authz)?.[1] ?? null;
25
25
  }
26
26
  export function _getRequestCookie(request, cookieName) {
27
- return _getCookies(request.headers)[cookieName] ?? null;
27
+ try {
28
+ return _getCookies(request.headers)[cookieName] ?? null;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
28
33
  }
29
34
  /**
30
35
  * a:b:c -> [a, a:b, a:b:c]
@@ -72,6 +72,17 @@ describe("_getRequestCookie", () => {
72
72
  "abcdef",
73
73
  );
74
74
  });
75
+ it("does not throw", () => {
76
+ assertEquals(
77
+ _getRequestCookie(
78
+ new Request("https://example.com", {
79
+ headers: { Cookie: "not_;a-cookie" },
80
+ }),
81
+ "my_cookie",
82
+ ),
83
+ null,
84
+ );
85
+ });
75
86
  });
76
87
 
77
88
  describe("_expandScopes", () => {
@@ -124,13 +135,32 @@ describe("AuthorizationService", () => {
124
135
  }
125
136
 
126
137
  describe("getAuthorization", () => {
138
+ it("parses bearer", () => {
139
+ const { authz } = setup();
140
+
141
+ const request = new Request("https://example.com", {
142
+ headers: { Authorization: "Bearer test_bearer_token" },
143
+ });
144
+ assertEquals(authz.getAuthorization(request), "test_bearer_token");
145
+ });
146
+ it("parses cookies", () => {
147
+ const { authz } = setup();
148
+
149
+ const request = new Request("https://example.com", {
150
+ headers: { Cookie: "testing_session=test_cookie_value" },
151
+ });
152
+ assertEquals(authz.getAuthorization(request), "test_cookie_value");
153
+ });
154
+ });
155
+
156
+ describe("assert", () => {
127
157
  it("parses bearer", async () => {
128
158
  const { authz } = setup();
129
159
 
130
160
  const request = new Request("https://example.com", {
131
161
  headers: { Authorization: 'Bearer {"scope":"user","userId":1}' },
132
162
  });
133
- assertEquals(await authz.getAuthorization(request), {
163
+ assertEquals(await authz.assert(request), {
134
164
  scope: "user",
135
165
  userId: 1,
136
166
  });
@@ -141,7 +171,7 @@ describe("AuthorizationService", () => {
141
171
  const request = new Request("https://example.com", {
142
172
  headers: { Cookie: 'testing_session={"scope":"user","userId":1}' },
143
173
  });
144
- assertEquals(await authz.getAuthorization(request), {
174
+ assertEquals(await authz.assert(request), {
145
175
  scope: "user",
146
176
  userId: 1,
147
177
  });
@@ -29,7 +29,11 @@ export function _getRequestBearer(request: Request) {
29
29
  }
30
30
 
31
31
  export function _getRequestCookie(request: Request, cookieName: string) {
32
- return _getCookies(request.headers)[cookieName] ?? null;
32
+ try {
33
+ return _getCookies(request.headers)[cookieName] ?? null;
34
+ } catch {
35
+ return null;
36
+ }
33
37
  }
34
38
 
35
39
  /**
@@ -8,11 +8,18 @@ export interface MatchedRoute {
8
8
  export interface FetchRouterOptions {
9
9
  routes?: RouteDefinition[];
10
10
  errorHandler?: RouteErrorHandler;
11
+ /** @unstable */
12
+ log?: boolean | _RouteMiddleware;
13
+ }
14
+ /** @unstable */
15
+ export interface _RouteMiddleware {
16
+ (request: Request, response: Response): void;
11
17
  }
12
18
  /** A rudimentary HTTP router using fetch Request & Responses with RouteDefinitions based on URLPattern */
13
19
  export declare class FetchRouter {
14
20
  routes: RouteDefinition[];
15
21
  errorHandler: RouteErrorHandler | undefined;
22
+ _middleware: _RouteMiddleware[];
16
23
  constructor(options?: FetchRouterOptions);
17
24
  /**
18
25
  * Finds routes that match the request method and URLPattern
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-router.d.ts","sourceRoot":"","sources":["fetch-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,eAAe,EAAE,MAAM,WAAW,CAAC;AAEvD,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,eAAe,CAAC;IACvB,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,gBAAgB,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,iBAAiB,CAAC;CACjC;AAED,0GAA0G;AAC1G,qBAAa,WAAW;IACvB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,YAAY,EAAE,iBAAiB,GAAG,SAAS,CAAC;gBAEhC,OAAO,GAAE,kBAAuB;IAK5C;;;OAGG;IACF,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC;IAa7D;;OAEG;IACG,cAAc,CACnB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC7B,OAAO,CAAC,QAAQ,CAAC;IAepB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ;IAUjD,WAAW,CAAC,OAAO,EAAE,OAAO;CAUlC"}
1
+ {"version":3,"file":"fetch-router.d.ts","sourceRoot":"","sources":["fetch-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,eAAe,EAAE,MAAM,WAAW,CAAC;AAEvD,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,eAAe,CAAC;IACvB,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,gBAAgB,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAClC,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAEjC,gBAAgB;IAChB,GAAG,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;CACjC;AAED,gBAAgB;AAChB,MAAM,WAAW,gBAAgB;IAChC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC7C;AAMD,0GAA0G;AAC1G,qBAAa,WAAW;IACvB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,YAAY,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAC5C,WAAW,EAAE,gBAAgB,EAAE,CAAM;gBAEzB,OAAO,GAAE,kBAAuB;IAO5C;;;OAGG;IACF,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC;IAa7D;;OAEG;IACG,cAAc,CACnB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,GAC7B,OAAO,CAAC,QAAQ,CAAC;IAepB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,QAAQ;IAUjD,WAAW,CAAC,OAAO,EAAE,OAAO;CAYlC"}
@@ -1,11 +1,19 @@
1
1
  import { HTTPError } from "./http.js";
2
+ function _defaultLogger(request, response) {
3
+ console.debug(response.status, request.method.padEnd(5), request.url);
4
+ }
2
5
  /** A rudimentary HTTP router using fetch Request & Responses with RouteDefinitions based on URLPattern */
3
6
  export class FetchRouter {
4
7
  routes;
5
8
  errorHandler;
9
+ _middleware = [];
6
10
  constructor(options = {}) {
7
11
  this.routes = options.routes ?? [];
8
12
  this.errorHandler = options.errorHandler ?? undefined;
13
+ if (options.log === true)
14
+ this._middleware.push(_defaultLogger);
15
+ if (typeof options.log === "function")
16
+ this._middleware.push(options.log);
9
17
  }
10
18
  /**
11
19
  * Finds routes that match the request method and URLPattern
@@ -49,7 +57,9 @@ export class FetchRouter {
49
57
  }
50
58
  async getResponse(request) {
51
59
  try {
52
- return await this.processMatches(request, this.findMatchingRoutes(request));
60
+ const response = await this.processMatches(request, this.findMatchingRoutes(request));
61
+ this._middleware.forEach((fn) => fn(request, response));
62
+ return response;
53
63
  }
54
64
  catch (error) {
55
65
  return this.handleError(request, error);
@@ -11,16 +11,31 @@ export interface MatchedRoute {
11
11
  export interface FetchRouterOptions {
12
12
  routes?: RouteDefinition[];
13
13
  errorHandler?: RouteErrorHandler;
14
+
15
+ /** @unstable */
16
+ log?: boolean | _RouteMiddleware;
17
+ }
18
+
19
+ /** @unstable */
20
+ export interface _RouteMiddleware {
21
+ (request: Request, response: Response): void;
22
+ }
23
+
24
+ function _defaultLogger(request: Request, response: Response) {
25
+ console.debug(response.status, request.method.padEnd(5), request.url);
14
26
  }
15
27
 
16
28
  /** A rudimentary HTTP router using fetch Request & Responses with RouteDefinitions based on URLPattern */
17
29
  export class FetchRouter {
18
30
  routes: RouteDefinition[];
19
31
  errorHandler: RouteErrorHandler | undefined;
32
+ _middleware: _RouteMiddleware[] = [];
20
33
 
21
34
  constructor(options: FetchRouterOptions = {}) {
22
35
  this.routes = options.routes ?? [];
23
36
  this.errorHandler = options.errorHandler ?? undefined;
37
+ if (options.log === true) this._middleware.push(_defaultLogger);
38
+ if (typeof options.log === "function") this._middleware.push(options.log);
24
39
  }
25
40
 
26
41
  /**
@@ -73,10 +88,12 @@ export class FetchRouter {
73
88
 
74
89
  async getResponse(request: Request) {
75
90
  try {
76
- return await this.processMatches(
91
+ const response = await this.processMatches(
77
92
  request,
78
93
  this.findMatchingRoutes(request),
79
94
  );
95
+ this._middleware.forEach((fn) => fn(request, response));
96
+ return response;
80
97
  } catch (error) {
81
98
  return this.handleError(request, error);
82
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,MAAM,UAAU,GACnB,KAAK,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,OAAO,GACP,QAAQ,GACR,SAAS,GACT,SAAS,CAAC;AAEb,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/E,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAC9C,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE,GAC/C,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAChC,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,EAAE,GACnC,KAAK,GACL,KAAK,CAAC;AAEX,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,CACjD,kBAAkB,CAAC,CAAC,CAAC,EACrB,MAAM,CACN,CAAC;AAEF,MAAM,WAAW,YAAY,CAAC,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,CAAC;IACV,GAAG,EAAE,GAAG,CAAC;CACT;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC9B,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;CACxC;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM;IAC7C,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,CAAC,CAAC;IACZ,OAAO,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,GAAG;IACvC,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACzB;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC3C,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAMjC;AAGD,qBAAa,SAAU,SAAQ,KAAK;IACnC;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAIxD;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAI1D;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAItD;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAIjE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAI5D,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;gBAG5B,MAAM,GAAE,MAAY,EACpB,UAAU,GAAE,MAAa,EACzB,IAAI,GAAE,QAAQ,GAAG,SAAqB,EACtC,OAAO,GAAE,WAAW,GAAG,SAAqB;IAW7C,UAAU;CAOV;AAED,gBAAgB;AAChB,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,gBAI9C;AAED,gBAAgB;AAChB,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,CAU5E"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,MAAM,UAAU,GACnB,KAAK,GACL,MAAM,GACN,MAAM,GACN,KAAK,GACL,OAAO,GACP,QAAQ,GACR,SAAS,GACT,SAAS,CAAC;AAEb,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/E,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,MAAM,IAC9C,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI,EAAE,GAC/C,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,GAChC,CAAC,SAAS,GAAG,MAAM,IAAI,MAAM,KAAK,EAAE,GACnC,KAAK,GACL,KAAK,CAAC;AAEX,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,MAAM,IAAI,MAAM,CACjD,kBAAkB,CAAC,CAAC,CAAC,EACrB,MAAM,CACN,CAAC;AAEF,MAAM,WAAW,YAAY,CAAC,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,CAAC;IACV,GAAG,EAAE,GAAG,CAAC;CACT;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC9B,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;CACxC;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM;IAC7C,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,CAAC,CAAC;IACZ,OAAO,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,GAAG;IACvC,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CACzB;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC3C,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAMjC;AAGD,qBAAa,SAAU,SAAQ,KAAK;IACnC;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAIxD;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAI1D;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAItD;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAIjE;;OAEG;IACH,MAAM,CAAC,cAAc,CAAC,IAAI,GAAE,QAAQ,GAAG,SAAqB;IAI5D,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;gBAG5B,MAAM,GAAE,MAAY,EACpB,UAAU,GAAE,MAAa,EACzB,IAAI,GAAE,QAAQ,GAAG,SAAqB,EACtC,OAAO,GAAE,WAAW,GAAG,SAAqB;IAW7C,UAAU;CAOV;AAED,gBAAgB;AAChB,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,gBAU9C;AAED,gBAAgB;AAChB,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,CAU5E"}
package/core/http.js CHANGED
@@ -62,8 +62,10 @@ export class HTTPError extends Error {
62
62
  /** @unstable */
63
63
  export function getRequestBody(request) {
64
64
  const ct = request.headers.get("Content-Type");
65
- if (ct === "application/x-www-form-urlencoded")
65
+ if (ct?.startsWith("application/x-www-form-urlencoded") ||
66
+ ct?.startsWith("multipart/form-data")) {
66
67
  return request.formData();
68
+ }
67
69
  return request.json();
68
70
  }
69
71
  /** @unstable */
package/core/http.ts CHANGED
@@ -125,7 +125,13 @@ export class HTTPError extends Error {
125
125
  /** @unstable */
126
126
  export function getRequestBody(request: Request) {
127
127
  const ct = request.headers.get("Content-Type");
128
- if (ct === "application/x-www-form-urlencoded") return request.formData();
128
+ if (
129
+ ct?.startsWith("application/x-www-form-urlencoded") ||
130
+ ct?.startsWith("multipart/form-data")
131
+ ) {
132
+ return request.formData();
133
+ }
134
+
129
135
  return request.json();
130
136
  }
131
137
 
package/core/mod.d.ts CHANGED
@@ -7,6 +7,7 @@ export * from "./tokens.ts";
7
7
  export * from "./migrator.ts";
8
8
  export * from "./postgres.ts";
9
9
  export * from "./random.ts";
10
+ export * from "./server-sent-events.ts";
10
11
  export * from "./store.ts";
11
12
  export * from "./structures.ts";
12
13
  export * from "./terminator.ts";
package/core/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["mod.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["mod.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,yBAAyB,CAAC;AACxC,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
package/core/mod.js CHANGED
@@ -7,6 +7,7 @@ export * from "./tokens.js";
7
7
  export * from "./migrator.js";
8
8
  export * from "./postgres.js";
9
9
  export * from "./random.js";
10
+ export * from "./server-sent-events.js";
10
11
  export * from "./store.js";
11
12
  export * from "./structures.js";
12
13
  export * from "./terminator.js";
package/core/mod.ts CHANGED
@@ -7,6 +7,7 @@ export * from "./tokens.ts";
7
7
  export * from "./migrator.ts";
8
8
  export * from "./postgres.ts";
9
9
  export * from "./random.ts";
10
+ export * from "./server-sent-events.ts";
10
11
  export * from "./store.ts";
11
12
  export * from "./structures.ts";
12
13
  export * from "./terminator.ts";
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Represents a message in the Server-Sent Event (SSE) protocol.
3
+ *
4
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#fields}
5
+ */
6
+ export interface ServerSentEventMessage {
7
+ /** Ignored by the client. */
8
+ comment?: string;
9
+ /** A string identifying the type of event described. */
10
+ event?: string;
11
+ /** The data field for the message. Split by new lines. */
12
+ data?: string;
13
+ /** The event ID to set the {@linkcode EventSource} object's last event ID value. */
14
+ id?: string | number;
15
+ /** The reconnection time. */
16
+ retry?: number;
17
+ }
18
+ /**
19
+ * Transforms server-sent message objects into strings for the client.
20
+ *
21
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events}
22
+ *
23
+ * @example Usage
24
+ * ```ts no-assert
25
+ * import {
26
+ * type ServerSentEventMessage,
27
+ * ServerSentEventStream,
28
+ * } from "@std/http/server-sent-event-stream";
29
+ *
30
+ * const stream = ReadableStream.from<ServerSentEventMessage>([
31
+ * { data: "hello there" }
32
+ * ]).pipeThrough(new ServerSentEventStream());
33
+ * new Response(stream, {
34
+ * headers: {
35
+ * "content-type": "text/event-stream",
36
+ * "cache-control": "no-cache",
37
+ * },
38
+ * });
39
+ * ```
40
+ */
41
+ export declare class ServerSentEventStream extends TransformStream<ServerSentEventMessage, Uint8Array> {
42
+ constructor();
43
+ }
44
+ /** @unstable */
45
+ export declare const sseHeaders: {
46
+ "content-type": string;
47
+ "cache-control": string;
48
+ connection: string;
49
+ };
50
+ //# sourceMappingURL=server-sent-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-sent-events.d.ts","sourceRoot":"","sources":["server-sent-events.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oFAAoF;IACpF,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAgDD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,qBAAsB,SAAQ,eAAe,CACzD,sBAAsB,EACtB,UAAU,CACV;;CAQA;AAED,gBAAgB;AAChB,eAAO,MAAM,UAAU;;;;CAItB,CAAC"}
@@ -0,0 +1,75 @@
1
+ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2
+ // This module is browser compatible.
3
+ const NEWLINE_REGEXP = /\r\n|\r|\n/;
4
+ const encoder = new TextEncoder();
5
+ function assertHasNoNewline(value, varName, errPrefix) {
6
+ if (value.match(NEWLINE_REGEXP) !== null) {
7
+ throw new SyntaxError(`${errPrefix}: ${varName} cannot contain a newline`);
8
+ }
9
+ }
10
+ /**
11
+ * Converts a server-sent message object into a string for the client.
12
+ *
13
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format}
14
+ */
15
+ function stringify(message) {
16
+ const lines = [];
17
+ if (message.comment) {
18
+ assertHasNoNewline(message.comment, "`message.comment`", "Cannot serialize message");
19
+ lines.push(`:${message.comment}`);
20
+ }
21
+ if (message.event) {
22
+ assertHasNoNewline(message.event, "`message.event`", "Cannot serialize message");
23
+ lines.push(`event:${message.event}`);
24
+ }
25
+ if (message.data) {
26
+ message.data
27
+ .split(NEWLINE_REGEXP)
28
+ .forEach((line) => lines.push(`data:${line}`));
29
+ }
30
+ if (message.id) {
31
+ assertHasNoNewline(message.id.toString(), "`message.id`", "Cannot serialize message");
32
+ lines.push(`id:${message.id}`);
33
+ }
34
+ if (message.retry)
35
+ lines.push(`retry:${message.retry}`);
36
+ return encoder.encode(lines.join("\n") + "\n\n");
37
+ }
38
+ /**
39
+ * Transforms server-sent message objects into strings for the client.
40
+ *
41
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events}
42
+ *
43
+ * @example Usage
44
+ * ```ts no-assert
45
+ * import {
46
+ * type ServerSentEventMessage,
47
+ * ServerSentEventStream,
48
+ * } from "@std/http/server-sent-event-stream";
49
+ *
50
+ * const stream = ReadableStream.from<ServerSentEventMessage>([
51
+ * { data: "hello there" }
52
+ * ]).pipeThrough(new ServerSentEventStream());
53
+ * new Response(stream, {
54
+ * headers: {
55
+ * "content-type": "text/event-stream",
56
+ * "cache-control": "no-cache",
57
+ * },
58
+ * });
59
+ * ```
60
+ */
61
+ export class ServerSentEventStream extends TransformStream {
62
+ constructor() {
63
+ super({
64
+ transform: (message, controller) => {
65
+ controller.enqueue(stringify(message));
66
+ },
67
+ });
68
+ }
69
+ }
70
+ /** @unstable */
71
+ export const sseHeaders = {
72
+ "content-type": "text/event-stream",
73
+ "cache-control": "no-cache",
74
+ connection: "keep-alive",
75
+ };
@@ -0,0 +1,112 @@
1
+ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2
+ // This module is browser compatible.
3
+
4
+ const NEWLINE_REGEXP = /\r\n|\r|\n/;
5
+ const encoder = new TextEncoder();
6
+
7
+ /**
8
+ * Represents a message in the Server-Sent Event (SSE) protocol.
9
+ *
10
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#fields}
11
+ */
12
+ export interface ServerSentEventMessage {
13
+ /** Ignored by the client. */
14
+ comment?: string;
15
+ /** A string identifying the type of event described. */
16
+ event?: string;
17
+ /** The data field for the message. Split by new lines. */
18
+ data?: string;
19
+ /** The event ID to set the {@linkcode EventSource} object's last event ID value. */
20
+ id?: string | number;
21
+ /** The reconnection time. */
22
+ retry?: number;
23
+ }
24
+
25
+ function assertHasNoNewline(value: string, varName: string, errPrefix: string) {
26
+ if (value.match(NEWLINE_REGEXP) !== null) {
27
+ throw new SyntaxError(`${errPrefix}: ${varName} cannot contain a newline`);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Converts a server-sent message object into a string for the client.
33
+ *
34
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#event_stream_format}
35
+ */
36
+ function stringify(message: ServerSentEventMessage): Uint8Array {
37
+ const lines = [];
38
+ if (message.comment) {
39
+ assertHasNoNewline(
40
+ message.comment,
41
+ "`message.comment`",
42
+ "Cannot serialize message",
43
+ );
44
+ lines.push(`:${message.comment}`);
45
+ }
46
+ if (message.event) {
47
+ assertHasNoNewline(
48
+ message.event,
49
+ "`message.event`",
50
+ "Cannot serialize message",
51
+ );
52
+ lines.push(`event:${message.event}`);
53
+ }
54
+ if (message.data) {
55
+ message.data
56
+ .split(NEWLINE_REGEXP)
57
+ .forEach((line) => lines.push(`data:${line}`));
58
+ }
59
+ if (message.id) {
60
+ assertHasNoNewline(
61
+ message.id.toString(),
62
+ "`message.id`",
63
+ "Cannot serialize message",
64
+ );
65
+ lines.push(`id:${message.id}`);
66
+ }
67
+ if (message.retry) lines.push(`retry:${message.retry}`);
68
+ return encoder.encode(lines.join("\n") + "\n\n");
69
+ }
70
+
71
+ /**
72
+ * Transforms server-sent message objects into strings for the client.
73
+ *
74
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events}
75
+ *
76
+ * @example Usage
77
+ * ```ts no-assert
78
+ * import {
79
+ * type ServerSentEventMessage,
80
+ * ServerSentEventStream,
81
+ * } from "@std/http/server-sent-event-stream";
82
+ *
83
+ * const stream = ReadableStream.from<ServerSentEventMessage>([
84
+ * { data: "hello there" }
85
+ * ]).pipeThrough(new ServerSentEventStream());
86
+ * new Response(stream, {
87
+ * headers: {
88
+ * "content-type": "text/event-stream",
89
+ * "cache-control": "no-cache",
90
+ * },
91
+ * });
92
+ * ```
93
+ */
94
+ export class ServerSentEventStream extends TransformStream<
95
+ ServerSentEventMessage,
96
+ Uint8Array
97
+ > {
98
+ constructor() {
99
+ super({
100
+ transform: (message, controller) => {
101
+ controller.enqueue(stringify(message));
102
+ },
103
+ });
104
+ }
105
+ }
106
+
107
+ /** @unstable */
108
+ export const sseHeaders = {
109
+ "content-type": "text/event-stream",
110
+ "cache-control": "no-cache",
111
+ connection: "keep-alive",
112
+ };
package/core/store.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- import type { Sql } from "postgres";
2
- import type { RedisClientType } from "redis";
3
1
  import { MigrationDefinition } from "./migrator.ts";
4
2
  import { TimerService } from "./timers.ts";
3
+ import { RedisDependency, SqlDependency } from "./types.ts";
5
4
  /** @unstable */
6
5
  export interface StoreSetOptions {
7
6
  /** milliseconds */
@@ -38,10 +37,10 @@ export interface PostgresStoreOptions {
38
37
  /** @unstable */
39
38
  export declare class PostgresStore implements Store {
40
39
  get tableName(): string;
41
- static getMigration(tableName: string): MigrationDefinition<Sql>;
42
- sql: Sql;
40
+ static getMigration(tableName: string): MigrationDefinition<any>;
41
+ sql: SqlDependency;
43
42
  options: Required<PostgresStoreOptions>;
44
- constructor(sql: Sql, options?: PostgresStoreOptions);
43
+ constructor(sql: unknown, options?: PostgresStoreOptions);
45
44
  get<T>(key: string): Promise<T | undefined>;
46
45
  set<T>(key: string, value: T, options?: StoreSetOptions): Promise<void>;
47
46
  delete(key: string): Promise<void>;
@@ -53,9 +52,9 @@ export interface RedisStoreOptions {
53
52
  }
54
53
  /** @unstable */
55
54
  export declare class RedisStore implements Store {
56
- redis: RedisClientType;
55
+ redis: RedisDependency;
57
56
  prefix: string;
58
- constructor(redis: RedisClientType, options?: RedisStoreOptions);
57
+ constructor(redis: unknown, options?: RedisStoreOptions);
59
58
  get<T>(key: string): Promise<T | undefined>;
60
59
  set<T>(key: string, value: T, options?: StoreSetOptions): Promise<void>;
61
60
  delete<T>(key: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["store.ts"],"names":[],"mappings":"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"}
package/core/store.ts CHANGED
@@ -1,8 +1,6 @@
1
- import type { Sql } from "postgres";
2
- import type { RedisClientType, SetOptions } from "redis";
3
-
4
1
  import { MigrationDefinition } from "./migrator.ts";
5
2
  import { TimerService } from "./timers.ts";
3
+ import { RedisDependency, SqlDependency } from "./types.ts";
6
4
 
7
5
  /** @unstable */
8
6
  export interface StoreSetOptions {
@@ -79,7 +77,7 @@ export class PostgresStore implements Store {
79
77
  return this.options.tableName;
80
78
  }
81
79
 
82
- static getMigration(tableName: string): MigrationDefinition<Sql> {
80
+ static getMigration(tableName: string): MigrationDefinition<any> {
83
81
  return {
84
82
  name: "00-postgres-store",
85
83
  up: async (sql) => {
@@ -99,10 +97,10 @@ export class PostgresStore implements Store {
99
97
  };
100
98
  }
101
99
 
102
- sql: Sql;
100
+ sql: SqlDependency;
103
101
  options: Required<PostgresStoreOptions>;
104
- constructor(sql: Sql, options: PostgresStoreOptions = {}) {
105
- this.sql = sql;
102
+ constructor(sql: unknown, options: PostgresStoreOptions = {}) {
103
+ this.sql = sql as SqlDependency;
106
104
  this.options = {
107
105
  tableName: options.tableName ?? "cache",
108
106
  };
@@ -154,10 +152,10 @@ export interface RedisStoreOptions {
154
152
 
155
153
  /** @unstable */
156
154
  export class RedisStore implements Store {
157
- redis: RedisClientType;
155
+ redis: RedisDependency;
158
156
  prefix: string;
159
- constructor(redis: RedisClientType, options: RedisStoreOptions = {}) {
160
- this.redis = redis;
157
+ constructor(redis: unknown, options: RedisStoreOptions = {}) {
158
+ this.redis = redis as RedisDependency;
161
159
  this.prefix = options.prefix ?? "";
162
160
  }
163
161
 
@@ -171,7 +169,7 @@ export class RedisStore implements Store {
171
169
  value: T,
172
170
  options: StoreSetOptions = {},
173
171
  ): Promise<void> {
174
- const opts: SetOptions = {};
172
+ const opts: Record<string, any> = {};
175
173
  if (options.maxAge) opts.PX = options.maxAge;
176
174
  await this.redis.set(this.prefix + key, JSON.stringify(value), opts);
177
175
  }
package/core/types.d.ts CHANGED
@@ -31,4 +31,11 @@ export interface JoseDependency {
31
31
  }>;
32
32
  SignJWT: _SignJWT;
33
33
  }
34
+ export interface RedisDependency {
35
+ get(key: string): Promise<string | undefined>;
36
+ set(key: string, value: string, options?: {
37
+ PX?: number;
38
+ }): Promise<unknown>;
39
+ del(key: string): Promise<unknown>;
40
+ }
34
41
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7C,MAAM,MAAM,cAAc,CAAC,CAAC,IAC3B,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC7B,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvE,0EAA0E;IAC1E,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE7E,6CAA6C;IAC7C,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC;IAEtB,+BAA+B;IAC/B,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACxB,KAAK,OAAO,EAAE,GAAG,GAAG,QAAQ,CAAC;IAE7B,kBAAkB,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,QAAQ,CAAC;IACnE,WAAW,IAAI,QAAQ,CAAC;IACxB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;IACtC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;IAEvD,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC9B,SAAS,CACR,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,UAAU,EACf,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9C,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAE7B,OAAO,EAAE,QAAQ,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7C,MAAM,MAAM,cAAc,CAAC,CAAC,IAC3B,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC7B,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvE,0EAA0E;IAC1E,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE7E,6CAA6C;IAC7C,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC;IAEtB,+BAA+B;IAC/B,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACxB,KAAK,OAAO,EAAE,GAAG,GAAG,QAAQ,CAAC;IAE7B,kBAAkB,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,QAAQ,CAAC;IACnE,WAAW,IAAI,QAAQ,CAAC;IACxB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;IACtC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;IAEvD,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC9B,SAAS,CACR,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,UAAU,EACf,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9C,OAAO,CAAC;QAAE,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAE7B,OAAO,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC9C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACnC"}
package/core/types.js CHANGED
@@ -1,2 +1 @@
1
- /// <reference types="urlpattern-polyfill" />
2
1
  export {};
package/core/types.ts CHANGED
@@ -1,7 +1,3 @@
1
- /// <reference types="urlpattern-polyfill" />
2
-
3
- // import { SignJWT } from "jose";
4
-
5
1
  export type MaybePromise<T> = T | Promise<T>;
6
2
 
7
3
  export type ResolvePromise<T> =
@@ -42,3 +38,9 @@ export interface JoseDependency {
42
38
 
43
39
  SignJWT: _SignJWT;
44
40
  }
41
+
42
+ export interface RedisDependency {
43
+ get(key: string): Promise<string | undefined>;
44
+ set(key: string, value: string, options?: { PX?: number }): Promise<unknown>;
45
+ del(key: string): Promise<unknown>;
46
+ }
package/package.json CHANGED
@@ -23,5 +23,5 @@
23
23
  "import": "./source/*.js"
24
24
  }
25
25
  },
26
- "version": "0.6.1"
26
+ "version": "0.7.0"
27
27
  }
@@ -21,4 +21,6 @@ export declare class ExpressRouter {
21
21
  onRouteError(error: unknown, request: Request): void;
22
22
  respond(res: ExpressResponse, response: Response): void;
23
23
  }
24
+ /** @unstable */
25
+ export declare function expressMiddleware(router: FetchRouter): ExpressRequestHandler;
24
26
  //# sourceMappingURL=express-router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"express-router.d.ts","sourceRoot":"","sources":["express-router.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,IAAI,qBAAqB,EACvC,QAAQ,IAAI,eAAe,EAC3B,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAGN,iBAAiB,EACjB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;EAWE;AACF,qBAAa,aAAa;IACzB,MAAM,EAAE,WAAW,CAAC;gBACR,OAAO,GAAE,iBAAsB;IAO3C,UAAU,IAAI,qBAAqB;IASnC,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIhD,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpD,OAAO,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAGvD"}
1
+ {"version":3,"file":"express-router.d.ts","sourceRoot":"","sources":["express-router.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,cAAc,IAAI,qBAAqB,EACvC,QAAQ,IAAI,eAAe,EAC3B,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAGN,iBAAiB,EACjB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;EAWE;AACF,qBAAa,aAAa;IACzB,MAAM,EAAE,WAAW,CAAC;gBACR,OAAO,GAAE,iBAAsB;IAO3C,UAAU,IAAI,qBAAqB;IASnC,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIhD,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpD,OAAO,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAGvD;AAED,gBAAgB;AAChB,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,qBAAqB,CAI5E"}
@@ -38,3 +38,9 @@ export class ExpressRouter {
38
38
  applyResponse(response, res);
39
39
  }
40
40
  }
41
+ /** @unstable */
42
+ export function expressMiddleware(router) {
43
+ const express = new ExpressRouter();
44
+ express.router = router;
45
+ return express.middleware();
46
+ }
@@ -52,3 +52,10 @@ export class ExpressRouter {
52
52
  applyResponse(response, res);
53
53
  }
54
54
  }
55
+
56
+ /** @unstable */
57
+ export function expressMiddleware(router: FetchRouter): ExpressRequestHandler {
58
+ const express = new ExpressRouter();
59
+ express.router = router;
60
+ return express.middleware();
61
+ }
@@ -22,4 +22,6 @@ export declare class KoaRouter {
22
22
  onRouteError(error: unknown, request: Request): void;
23
23
  respond(ctx: Context, response: Response): void;
24
24
  }
25
+ /** @unstable */
26
+ export declare function koaMiddleware(router: FetchRouter): Middleware;
25
27
  //# sourceMappingURL=koa-router.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"koa-router.d.ts","sourceRoot":"","sources":["koa-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAGN,iBAAiB,EACjB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;EAYE;AACF,qBAAa,SAAS;IACrB,MAAM,EAAE,WAAW,CAAC;gBACR,OAAO,GAAE,iBAAsB;IAO3C,UAAU,IAAI,UAAU;IASxB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIhD,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpD,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAa/C"}
1
+ {"version":3,"file":"koa-router.d.ts","sourceRoot":"","sources":["koa-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAGN,iBAAiB,EACjB,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;EAYE;AACF,qBAAa,SAAS;IACrB,MAAM,EAAE,WAAW,CAAC;gBACR,OAAO,GAAE,iBAAsB;IAO3C,UAAU,IAAI,UAAU;IASxB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIhD,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpD,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAa/C;AAED,gBAAgB;AAChB,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAI7D"}
@@ -47,3 +47,9 @@ export class KoaRouter {
47
47
  }
48
48
  }
49
49
  }
50
+ /** @unstable */
51
+ export function koaMiddleware(router) {
52
+ const koa = new KoaRouter();
53
+ koa.router = router;
54
+ return koa.middleware();
55
+ }
@@ -60,3 +60,10 @@ export class KoaRouter {
60
60
  }
61
61
  }
62
62
  }
63
+
64
+ /** @unstable */
65
+ export function koaMiddleware(router: FetchRouter): Middleware {
66
+ const koa = new KoaRouter();
67
+ koa.router = router;
68
+ return koa.middleware();
69
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"node-router.d.ts","sourceRoot":"","sources":["node-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAEN,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IACjC,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;EAUE;AACF,qBAAa,UAAU;IACtB,MAAM,EAAE,WAAW,CAAC;gBACR,OAAO,GAAE,iBAAsB;IAO3C,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIhD,aAAa,IAAI,eAAe;IAQhC,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpD,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAGtD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CAU3E;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,WASnD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,mBAAmB,WAOzD;AAID,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,eAAe,GAClB,QAAQ,GAAG,SAAS,CAItB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,YAGrD;AAED,gBAAgB;AAChB,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,gBAAgB;AAChB,MAAM,WAAW,gBAAgB;IAChC,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;CAC3C;AAED,gFAAgF;AAChF,wBAAgB,SAAS,CACxB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,gBAAgB,wEAuBzB"}
1
+ {"version":3,"file":"node-router.d.ts","sourceRoot":"","sources":["node-router.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAEN,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,cAAc,EACd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,WAAW,iBAAiB;IACjC,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;EAUE;AACF,qBAAa,UAAU;IACtB,MAAM,EAAE,WAAW,CAAC;gBACR,OAAO,GAAE,iBAAsB;IAO3C,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIhD,aAAa,IAAI,eAAe;IAQhC,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpD,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAGtD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,CAS3E;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,WAYnD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,mBAAmB,WAOzD;AAID,wBAAgB,sBAAsB,CACrC,GAAG,EAAE,eAAe,GAClB,QAAQ,GAAG,SAAS,CAItB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,YAGrD;AAED,gBAAgB;AAChB,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,gBAAgB;AAChB,MAAM,WAAW,gBAAgB;IAChC,CAAC,OAAO,EAAE,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;CAC3C;AAED,gFAAgF;AAChF,wBAAgB,SAAS,CACxB,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,gBAAgB,wEAuBzB"}
@@ -39,8 +39,7 @@ export class NodeRouter {
39
39
  }
40
40
  export function applyResponse(response, res) {
41
41
  for (const [key, value] of response.headers) {
42
- const values = value.split(",");
43
- res.setHeader(key, values.length === 1 ? value : values);
42
+ res.appendHeader(key, value);
44
43
  }
45
44
  res.writeHead(response.status, response.statusText);
46
45
  if (response.body)
@@ -50,12 +49,15 @@ export function applyResponse(response, res) {
50
49
  }
51
50
  export function getFetchRequest(req) {
52
51
  const url = "http://" + (req.headers.host ?? "localhost") + req.url;
52
+ const ac = new AbortController();
53
+ req.once("error", (e) => ac.abort(e));
53
54
  return new Request(url, {
54
55
  method: req.method,
55
56
  headers: getFetchHeaders(req.headers),
56
57
  body: getIncomingMessageBody(req),
57
58
  // @ts-ignore
58
59
  duplex: "half",
60
+ signal: ac.signal,
59
61
  });
60
62
  }
61
63
  export function getFetchHeaders(input) {
@@ -58,8 +58,7 @@ export class NodeRouter {
58
58
 
59
59
  export function applyResponse(response: Response, res: ServerResponse): void {
60
60
  for (const [key, value] of response.headers) {
61
- const values = value.split(",");
62
- res.setHeader(key, values.length === 1 ? value : values);
61
+ res.appendHeader(key, value);
63
62
  }
64
63
 
65
64
  res.writeHead(response.status, response.statusText);
@@ -70,12 +69,15 @@ export function applyResponse(response: Response, res: ServerResponse): void {
70
69
 
71
70
  export function getFetchRequest(req: IncomingMessage) {
72
71
  const url = "http://" + (req.headers.host ?? "localhost") + req.url;
72
+ const ac = new AbortController();
73
+ req.once("error", (e) => ac.abort(e));
73
74
  return new Request(url, {
74
75
  method: req.method,
75
76
  headers: getFetchHeaders(req.headers),
76
77
  body: getIncomingMessageBody(req),
77
78
  // @ts-ignore
78
79
  duplex: "half",
80
+ signal: ac.signal,
79
81
  });
80
82
  }
81
83
 
@@ -1,7 +1,7 @@
1
1
  import type { SqlDependency } from "../core/types.ts";
2
2
  import { Migrator, MigratorOptions } from "../core/migrator.ts";
3
3
  export interface PostgresMigratorOptions {
4
- sql: SqlDependency;
4
+ sql: unknown;
5
5
  directory: URL;
6
6
  }
7
7
  export declare function getPostgresMigratorOptions(options: PostgresMigratorOptions): MigratorOptions<SqlDependency>;
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["postgres.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAiB,MAAM,qBAAqB,CAAC;AAS/E,MAAM,WAAW,uBAAuB;IACvC,GAAG,EAAE,aAAa,CAAC;IACnB,SAAS,EAAE,GAAG,CAAC;CACf;AAED,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,uBAAuB,GAC9B,eAAe,CAAC,aAAa,CAAC,CA6BhC;AAED,mDAAmD;AACnD,eAAO,MAAM,8BAA8B,mCAA6B,CAAC;AAEzE;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,2BAKnE;AAED,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,4BAAsB,CAAC"}
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["postgres.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAiB,QAAQ,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAS/E,MAAM,WAAW,uBAAuB;IACvC,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,EAAE,GAAG,CAAC;CACf;AAED,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,uBAAuB,GAC9B,eAAe,CAAC,aAAa,CAAC,CA8BhC;AAED,mDAAmD;AACnD,eAAO,MAAM,8BAA8B,mCAA6B,CAAC;AAEzE;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,2BAKnE;AAED,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,4BAAsB,CAAC"}
@@ -1,15 +1,16 @@
1
1
  import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
- import { Migrator, loadMigration } from "../core/migrator.js";
3
+ import { loadMigration, Migrator } from "../core/migrator.js";
4
4
  import { executePostgresMigration, getPostgresMigrations, postgresBootstrapMigration, } from "../core/postgres.js";
5
5
  const migrationExtensions = new Set([".ts", ".js"]);
6
6
  export function getPostgresMigratorOptions(options) {
7
+ const sql = options.sql;
7
8
  return {
8
9
  getRecords() {
9
- return getPostgresMigrations(options.sql);
10
+ return getPostgresMigrations(sql);
10
11
  },
11
12
  execute(def, direction) {
12
- return executePostgresMigration(def, direction, options.sql);
13
+ return executePostgresMigration(def, direction, sql);
13
14
  },
14
15
  async getDefinitions() {
15
16
  const migrations = [
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import type { SqlDependency } from "../core/types.ts";
4
4
 
5
- import { Migrator, MigratorOptions, loadMigration } from "../core/migrator.ts";
5
+ import { loadMigration, Migrator, MigratorOptions } from "../core/migrator.ts";
6
6
  import {
7
7
  executePostgresMigration,
8
8
  getPostgresMigrations,
@@ -12,20 +12,21 @@ import {
12
12
  const migrationExtensions = new Set([".ts", ".js"]);
13
13
 
14
14
  export interface PostgresMigratorOptions {
15
- sql: SqlDependency;
15
+ sql: unknown;
16
16
  directory: URL;
17
17
  }
18
18
 
19
19
  export function getPostgresMigratorOptions(
20
20
  options: PostgresMigratorOptions,
21
21
  ): MigratorOptions<SqlDependency> {
22
+ const sql = options.sql as SqlDependency;
22
23
  return {
23
24
  getRecords() {
24
- return getPostgresMigrations(options.sql);
25
+ return getPostgresMigrations(sql);
25
26
  },
26
27
 
27
28
  execute(def, direction) {
28
- return executePostgresMigration(def, direction, options.sql);
29
+ return executePostgresMigration(def, direction, sql);
29
30
  },
30
31
 
31
32
  async getDefinitions() {