tempo.ts 0.7.1 → 0.7.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/CHANGELOG.md +32 -0
- package/dist/server/Handler.d.ts +12 -2
- package/dist/server/Handler.d.ts.map +1 -1
- package/dist/server/Handler.js +21 -3
- package/dist/server/Handler.js.map +1 -1
- package/package.json +1 -1
- package/src/server/Handler.test.ts +223 -0
- package/src/server/Handler.ts +41 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# tempo.ts
|
|
2
2
|
|
|
3
|
+
## 0.7.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#90](https://github.com/tempoxyz/tempo-ts/pull/90) [`625c8e4`](https://github.com/tempoxyz/tempo-ts/commit/625c8e4a4b0c4fac3d6c278c9a964fc5d6b7a78f) Thanks [@jxom](https://github.com/jxom)! - Added `Handler.compose` to compose multiple handlers into a single handler.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { Handler, Kv } from 'tempo.ts/server'
|
|
11
|
+
|
|
12
|
+
const handler = Handler.compose([
|
|
13
|
+
Handler.feePayer({
|
|
14
|
+
account,
|
|
15
|
+
client,
|
|
16
|
+
path: '/fee-payer'
|
|
17
|
+
}),
|
|
18
|
+
Handler.keyManager({
|
|
19
|
+
kv: Kv.memory()
|
|
20
|
+
path: '/key'
|
|
21
|
+
}),
|
|
22
|
+
], { path: '/api' })
|
|
23
|
+
|
|
24
|
+
Bun.serve(handler) // Bun
|
|
25
|
+
Deno.serve(handler) // Deno
|
|
26
|
+
createServer(handler.listener) // Node.js
|
|
27
|
+
app.use(c => handler.fetch(c.req.raw)) // Hono
|
|
28
|
+
app.use(handler.listener) // Express
|
|
29
|
+
|
|
30
|
+
// Exposed endpoints:
|
|
31
|
+
// - '/api/fee-payer'
|
|
32
|
+
// - '/api/key/*'
|
|
33
|
+
```
|
|
34
|
+
|
|
3
35
|
## 0.7.1
|
|
4
36
|
|
|
5
37
|
### Patch Changes
|
package/dist/server/Handler.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Router } from '@remix-run/fetch-router';
|
|
1
|
+
import { type Router, type RouterOptions } from '@remix-run/fetch-router';
|
|
2
2
|
import { RpcRequest } from 'ox';
|
|
3
3
|
import * as Hex from 'ox/Hex';
|
|
4
4
|
import type * as WebAuthnP256 from 'ox/WebAuthnP256';
|
|
@@ -9,13 +9,23 @@ import type * as Kv from './Kv.js';
|
|
|
9
9
|
export type Handler = Router & {
|
|
10
10
|
listener: (req: any, res: any) => void;
|
|
11
11
|
};
|
|
12
|
+
export declare function compose(handlers: Handler[], options?: compose.Options): Handler;
|
|
13
|
+
export declare namespace compose {
|
|
14
|
+
type Options = {
|
|
15
|
+
/** The path to use for the handler. */
|
|
16
|
+
path?: string | undefined;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
12
19
|
/**
|
|
13
20
|
* Instantiates a new request handler.
|
|
14
21
|
*
|
|
15
22
|
* @param options - constructor options
|
|
16
23
|
* @returns Handler instance
|
|
17
24
|
*/
|
|
18
|
-
export declare function from(): Handler;
|
|
25
|
+
export declare function from(options?: from.Options): Handler;
|
|
26
|
+
export declare namespace from {
|
|
27
|
+
type Options = RouterOptions;
|
|
28
|
+
}
|
|
19
29
|
/**
|
|
20
30
|
* Defines a Key Manager request handler.
|
|
21
31
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Handler.d.ts","sourceRoot":"","sources":["../../src/server/Handler.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Handler.d.ts","sourceRoot":"","sources":["../../src/server/Handler.ts"],"names":[],"mappings":"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"}
|
package/dist/server/Handler.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createRouter } from '@remix-run/fetch-router';
|
|
1
|
+
import { createRouter, } from '@remix-run/fetch-router';
|
|
2
2
|
import { RpcRequest, RpcResponse } from 'ox';
|
|
3
3
|
import * as Base64 from 'ox/Base64';
|
|
4
4
|
import * as Hex from 'ox/Hex';
|
|
@@ -7,14 +7,32 @@ import { signTransaction } from 'viem/actions';
|
|
|
7
7
|
import { formatTransaction } from '../viem/Formatters.js';
|
|
8
8
|
import * as Transaction from '../viem/Transaction.js';
|
|
9
9
|
import * as RequestListener from './internal/requestListener.js';
|
|
10
|
+
export function compose(handlers, options = {}) {
|
|
11
|
+
const path = options.path ?? '/';
|
|
12
|
+
return from({
|
|
13
|
+
async defaultHandler(context) {
|
|
14
|
+
const url = new URL(context.request.url);
|
|
15
|
+
if (!url.pathname.startsWith(path))
|
|
16
|
+
return new Response('Not Found', { status: 404 });
|
|
17
|
+
url.pathname = url.pathname.replace(path, '');
|
|
18
|
+
for (const handler of handlers) {
|
|
19
|
+
const request = new Request(url, context.request.clone());
|
|
20
|
+
const response = await handler.fetch(request);
|
|
21
|
+
if (response.status !== 404)
|
|
22
|
+
return response;
|
|
23
|
+
}
|
|
24
|
+
return new Response('Not Found', { status: 404 });
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
10
28
|
/**
|
|
11
29
|
* Instantiates a new request handler.
|
|
12
30
|
*
|
|
13
31
|
* @param options - constructor options
|
|
14
32
|
* @returns Handler instance
|
|
15
33
|
*/
|
|
16
|
-
export function from() {
|
|
17
|
-
const router = createRouter();
|
|
34
|
+
export function from(options = {}) {
|
|
35
|
+
const router = createRouter(options);
|
|
18
36
|
return {
|
|
19
37
|
...router,
|
|
20
38
|
listener: RequestListener.fromFetchHandler((request) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Handler.js","sourceRoot":"","sources":["../../src/server/Handler.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"Handler.js","sourceRoot":"","sources":["../../src/server/Handler.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,GAGb,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,IAAI,CAAA;AAC5C,OAAO,KAAK,MAAM,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,QAAQ,CAAA;AAE7B,OAAO,EAA2B,YAAY,EAAkB,MAAM,MAAM,CAAA;AAE5E,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACzD,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAA;AACrD,OAAO,KAAK,eAAe,MAAM,+BAA+B,CAAA;AAOhE,MAAM,UAAU,OAAO,CACrB,QAAmB,EACnB,UAA2B,EAAE;IAE7B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,GAAG,CAAA;IAEhC,OAAO,IAAI,CAAC;QACV,KAAK,CAAC,cAAc,CAAC,OAAO;YAC1B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YACxC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;gBAChC,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;YAEnD,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;YAC7C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;gBACzD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;gBAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;oBAAE,OAAO,QAAQ,CAAA;YAC9C,CAAC;YACD,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QACnD,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AASD;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAAC,UAAwB,EAAE;IAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IACpC,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,EAAE,eAAe,CAAC,gBAAgB,CAAC,CAAC,OAAO,EAAE,EAAE;YACrD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAC9B,CAAC,CAAC;KACH,CAAA;AACH,CAAC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AACH,MAAM,UAAU,UAAU,CAAC,OAA2B;IACpD,MAAM,EAAE,EAAE,EAAE,GAAG,OAAO,CAAA;IAEtB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAA;IAE/B,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE;QACf,IAAI,OAAO,OAAO,CAAC,EAAE,KAAK,QAAQ;YAChC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,CAAA;QAC7C,IAAI,OAAO,CAAC,EAAE;YACZ,OAAO;gBACL,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE;gBACjB,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE;aACvC,CAAA;QACH,OAAO,SAAS,CAAA;IAClB,CAAC,CAAC,EAAE,CAAA;IAEJ,MAAM,MAAM,GAAG,IAAI,EAAE,CAAA;IAErB,iDAAiD;IACjD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,YAAY,EAAE,KAAK,IAAI,EAAE;QACzC,8BAA8B;QAC9B,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QAEhC,iDAAiD;QACjD,MAAM,EAAE,CAAC,GAAG,CAAC,aAAa,SAAS,EAAE,EAAE,GAAG,CAAC,CAAA;QAE3C,OAAO,QAAQ,CAAC,IAAI,CAAC;YACnB,SAAS;YACT,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACiB,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,kCAAkC;IAClC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC7C,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,CAAA;QAErB,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,GAAG,CAAU,cAAc,EAAE,EAAE,CAAC,CAAA;QAE3D,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,QAAQ,CAAC,sBAAsB,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAE5E,OAAO,QAAQ,CAAC,IAAI,CAAC;YACnB,SAAS;SACV,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,kCAAkC;IAClC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;QACvD,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,CAAA;QACrB,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAQ,CAAA;QAE/D,IAAI,CAAC,UAAU;YACb,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAC1E,IAAI,CAAC,SAAS;YACZ,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAEzE,mCAAmC;QACnC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAC/B,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,cAAmC,CAAC,CACzE,CAAA;QAED,mBAAmB;QACnB,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;QAExD,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAS,aAAa,SAAS,EAAE,CAAC,CAAC;YACnD,OAAO,QAAQ,CAAC,IAAI,CAClB,EAAE,KAAK,EAAE,gCAAgC,EAAE,EAC3C,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;QAEH,cAAc;QACd,IAAI,cAAc,CAAC,IAAI,KAAK,iBAAiB;YAC3C,OAAO,QAAQ,CAAC,IAAI,CAClB,EAAE,KAAK,EAAE,+BAA+B,EAAE,EAC1C,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;QAEH,gBAAgB;QAChB,IACE,EAAE,EAAE,EAAE;YACN,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;YAC5B,cAAc,CAAC,MAAM,KAAK,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM;YAE5D,OAAO,QAAQ,CAAC,IAAI,CAClB,EAAE,KAAK,EAAE,iCAAiC,EAAE,EAC5C,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;QAEH,0BAA0B;QAC1B,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CACrC,UAAU,CAAC,QAAgB,CAAC,iBAAiB,CAC/C,CAAA;QAED,wBAAwB;QACxB,MAAM,KAAK,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAA;QACnC,IAAI,CAAC,KAAK;YACR,OAAO,QAAQ,CAAC,IAAI,CAClB,EAAE,KAAK,EAAE,6BAA6B,EAAE,EACxC,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;QAEH,uCAAuC;QACvC,MAAM,WAAW,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAA;QACxC,IAAI,CAAC,WAAW;YACd,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QAEtE,0DAA0D;QAC1D,MAAM,EAAE,CAAC,MAAM,CAAC,aAAa,SAAS,EAAE,CAAC,CAAA;QAEzC,uBAAuB;QACvB,MAAM,EAAE,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,CAAC,CAAA;QAE3C,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AAsCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4KG;AACH,MAAM,UAAU,QAAQ,CAAC,OAAyB;IAChD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,GAAG,GAAG,EAAE,GAAG,OAAO,CAAA;IAElD,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE;QACnB,IAAI,QAAQ,IAAI,OAAO;YAAE,OAAO,OAAO,CAAC,MAAO,CAAA;QAC/C,IAAI,OAAO,IAAI,OAAO,IAAI,WAAW,IAAI,OAAO;YAC9C,OAAO,YAAY,CAAC;gBAClB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC,CAAA;QACJ,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAChD,CAAC,CAAC,EAAE,CAAA;IAEJ,MAAM,MAAM,GAAG,IAAI,EAAE,CAAA;IAErB,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE;QAC3C,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC,CAAA;QAE1D,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC,CAAA;QAE1B,IAAI,OAAO,CAAC,MAAM,KAAK,qBAAqB,EAAE,CAAC;YAC7C,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAU,CAAC,CAAA;YAE1E,MAAM,qBAAqB,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE;gBAC1D,GAAG,kBAAkB;gBACrB,OAAO;gBACP,mBAAmB;gBACnB,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAA;YAEF,OAAO,QAAQ,CAAC,IAAI,CAClB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CACjE,CAAA;QACH,CAAC;QAED,IAAK,OAAe,CAAC,MAAM,KAAK,wBAAwB,EAAE,CAAC;YACzD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAoB,CAAA;YACzD,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAA;YAEvD,MAAM,qBAAqB,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE;gBAC1D,GAAG,WAAW;gBACd,OAAO;gBACP,mBAAmB;gBACnB,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAA;YAEF,OAAO,QAAQ,CAAC,IAAI,CAClB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,qBAAqB,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CACjE,CAAA;QACH,CAAC;QAED,IACE,OAAO,CAAC,MAAM,KAAK,wBAAwB;YAC3C,OAAO,CAAC,MAAM,KAAK,4BAA4B,EAC/C,CAAC;YACD,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAoB,CAAA;YACzD,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC,UAAU,CAAC,CAAA;YAEvD,MAAM,qBAAqB,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE;gBAC1D,GAAG,WAAW;gBACd,OAAO;gBACP,mBAAmB;gBACnB,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAA;YAEF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;gBAClC,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,MAAM,EAAE,CAAC,qBAAqB,CAAC;aAChC,CAAC,CAAA;YAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAA;QACjE,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAClB,WAAW,CAAC,IAAI,CACd;YACE,KAAK,EAAE,IAAI,WAAW,CAAC,uBAAuB,CAAC;gBAC7C,OAAO,EAAE,yBAAyB,OAAO,CAAC,MAAM,EAAE;aACnD,CAAC;SACH,EACD,EAAE,OAAO,EAAE,CACZ,EACD,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Elysia } from 'elysia'
|
|
1
2
|
import express from 'express'
|
|
2
3
|
import { Hono } from 'hono'
|
|
3
4
|
import type { RpcRequest } from 'ox'
|
|
@@ -20,6 +21,210 @@ import { withFeePayer } from '../viem/Transport.js'
|
|
|
20
21
|
import * as Handler from './Handler.js'
|
|
21
22
|
import * as Kv from './Kv.js'
|
|
22
23
|
|
|
24
|
+
describe('compose', () => {
|
|
25
|
+
test('default', async () => {
|
|
26
|
+
const handler1 = Handler.from()
|
|
27
|
+
handler1.get('/test', () => new Response('test'))
|
|
28
|
+
const handler2 = Handler.from()
|
|
29
|
+
handler2.get('/test2', () => new Response('test2'))
|
|
30
|
+
|
|
31
|
+
const handler = Handler.compose([handler1, handler2])
|
|
32
|
+
expect(handler).toBeDefined()
|
|
33
|
+
|
|
34
|
+
{
|
|
35
|
+
const response = await handler.fetch(new Request('http://localhost/test'))
|
|
36
|
+
expect(response.status).toBe(200)
|
|
37
|
+
expect(await response.text()).toBe('test')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
const response = await handler.fetch(
|
|
42
|
+
new Request('http://localhost/test2'),
|
|
43
|
+
)
|
|
44
|
+
expect(response.status).toBe(200)
|
|
45
|
+
expect(await response.text()).toBe('test2')
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('behavior: path', async () => {
|
|
50
|
+
const handler1 = Handler.from()
|
|
51
|
+
handler1.get('/test', () => new Response('test'))
|
|
52
|
+
const handler2 = Handler.from()
|
|
53
|
+
handler2.get('/test2', () => new Response('test2'))
|
|
54
|
+
|
|
55
|
+
const handler = Handler.compose([handler1, handler2], {
|
|
56
|
+
path: '/api',
|
|
57
|
+
})
|
|
58
|
+
expect(handler).toBeDefined()
|
|
59
|
+
|
|
60
|
+
{
|
|
61
|
+
const response = await handler.fetch(
|
|
62
|
+
new Request('http://localhost/api/test'),
|
|
63
|
+
)
|
|
64
|
+
expect(response.status).toBe(200)
|
|
65
|
+
expect(await response.text()).toBe('test')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
{
|
|
69
|
+
const response = await handler.fetch(
|
|
70
|
+
new Request('http://localhost/api/test2'),
|
|
71
|
+
)
|
|
72
|
+
expect(response.status).toBe(200)
|
|
73
|
+
expect(await response.text()).toBe('test2')
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('integration', () => {
|
|
78
|
+
const handler1 = Handler.from()
|
|
79
|
+
handler1.get('/foo', () => new Response('foo'))
|
|
80
|
+
handler1.post('/bar', () => new Response('bar'))
|
|
81
|
+
|
|
82
|
+
const handler2 = Handler.from()
|
|
83
|
+
handler2.get('/baz', () => new Response('baz'))
|
|
84
|
+
handler2.post('/qux', () => new Response('qux'))
|
|
85
|
+
|
|
86
|
+
const handler = Handler.compose([handler1, handler2], {
|
|
87
|
+
path: '/api',
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
test('hono', async () => {
|
|
91
|
+
const app = new Hono()
|
|
92
|
+
app.use((c) => handler.fetch(c.req.raw))
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
const response = await app.request('/api/foo')
|
|
96
|
+
expect(await response.text()).toBe('foo')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
const response = await app.request('/api/bar', {
|
|
101
|
+
method: 'POST',
|
|
102
|
+
})
|
|
103
|
+
expect(await response.text()).toBe('bar')
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
{
|
|
107
|
+
const response = await app.request('/api/baz', {
|
|
108
|
+
method: 'GET',
|
|
109
|
+
})
|
|
110
|
+
expect(await response.text()).toBe('baz')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
const response = await app.request('/api/qux', {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
})
|
|
117
|
+
expect(await response.text()).toBe('qux')
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('elysia', async () => {
|
|
122
|
+
const app = new Elysia().all('*', ({ request }) => handler.fetch(request))
|
|
123
|
+
|
|
124
|
+
{
|
|
125
|
+
const response = await app.handle(
|
|
126
|
+
new Request('http://localhost/api/foo'),
|
|
127
|
+
)
|
|
128
|
+
expect(await response.text()).toBe('foo')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
{
|
|
132
|
+
const response = await app.handle(
|
|
133
|
+
new Request('http://localhost/api/bar', {
|
|
134
|
+
method: 'POST',
|
|
135
|
+
}),
|
|
136
|
+
)
|
|
137
|
+
expect(await response.text()).toBe('bar')
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
{
|
|
141
|
+
const response = await app.handle(
|
|
142
|
+
new Request('http://localhost/api/baz', {
|
|
143
|
+
method: 'GET',
|
|
144
|
+
}),
|
|
145
|
+
)
|
|
146
|
+
expect(await response.text()).toBe('baz')
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
{
|
|
150
|
+
const response = await app.handle(
|
|
151
|
+
new Request('http://localhost/api/qux', {
|
|
152
|
+
method: 'POST',
|
|
153
|
+
}),
|
|
154
|
+
)
|
|
155
|
+
expect(await response.text()).toBe('qux')
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
test('node.js', async () => {
|
|
160
|
+
const server = await createServer(handler.listener)
|
|
161
|
+
|
|
162
|
+
{
|
|
163
|
+
const response = await fetch(`${server.url}/api/foo`)
|
|
164
|
+
expect(await response.text()).toBe('foo')
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
{
|
|
168
|
+
const response = await fetch(`${server.url}/api/bar`, {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
})
|
|
171
|
+
expect(await response.text()).toBe('bar')
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
const response = await fetch(`${server.url}/api/baz`, {
|
|
176
|
+
method: 'GET',
|
|
177
|
+
})
|
|
178
|
+
expect(await response.text()).toBe('baz')
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
{
|
|
182
|
+
const response = await fetch(`${server.url}/api/qux`, {
|
|
183
|
+
method: 'POST',
|
|
184
|
+
})
|
|
185
|
+
expect(await response.text()).toBe('qux')
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
await server.closeAsync()
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
test('express', async () => {
|
|
192
|
+
const app = express()
|
|
193
|
+
app.use(handler.listener)
|
|
194
|
+
|
|
195
|
+
const server = await createServer(app)
|
|
196
|
+
|
|
197
|
+
{
|
|
198
|
+
const response = await fetch(`${server.url}/api/foo`)
|
|
199
|
+
expect(await response.text()).toBe('foo')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
{
|
|
203
|
+
const response = await fetch(`${server.url}/api/bar`, {
|
|
204
|
+
method: 'POST',
|
|
205
|
+
})
|
|
206
|
+
expect(await response.text()).toBe('bar')
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
{
|
|
210
|
+
const response = await fetch(`${server.url}/api/baz`, {
|
|
211
|
+
method: 'GET',
|
|
212
|
+
})
|
|
213
|
+
expect(await response.text()).toBe('baz')
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
{
|
|
217
|
+
const response = await fetch(`${server.url}/api/qux`, {
|
|
218
|
+
method: 'POST',
|
|
219
|
+
})
|
|
220
|
+
expect(await response.text()).toBe('qux')
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
await server.closeAsync()
|
|
224
|
+
})
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
|
|
23
228
|
describe('from', () => {
|
|
24
229
|
test('default', () => {
|
|
25
230
|
const handler = Handler.from()
|
|
@@ -73,6 +278,24 @@ describe('from', () => {
|
|
|
73
278
|
}
|
|
74
279
|
})
|
|
75
280
|
|
|
281
|
+
test('elysia', async () => {
|
|
282
|
+
const app = new Elysia().all('*', ({ request }) => handler.fetch(request))
|
|
283
|
+
|
|
284
|
+
{
|
|
285
|
+
const response = await app.handle(new Request('http://localhost/foo'))
|
|
286
|
+
expect(await response.text()).toBe('foo')
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
{
|
|
290
|
+
const response = await app.handle(
|
|
291
|
+
new Request('http://localhost/bar', {
|
|
292
|
+
method: 'POST',
|
|
293
|
+
}),
|
|
294
|
+
)
|
|
295
|
+
expect(await response.text()).toBe('bar')
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
|
|
76
299
|
test('node.js', async () => {
|
|
77
300
|
const server = await createServer(handler.listener)
|
|
78
301
|
|
package/src/server/Handler.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createRouter,
|
|
3
|
+
type Router,
|
|
4
|
+
type RouterOptions,
|
|
5
|
+
} from '@remix-run/fetch-router'
|
|
2
6
|
import { RpcRequest, RpcResponse } from 'ox'
|
|
3
7
|
import * as Base64 from 'ox/Base64'
|
|
4
8
|
import * as Hex from 'ox/Hex'
|
|
@@ -16,14 +20,44 @@ export type Handler = Router & {
|
|
|
16
20
|
listener: (req: any, res: any) => void
|
|
17
21
|
}
|
|
18
22
|
|
|
23
|
+
export function compose(
|
|
24
|
+
handlers: Handler[],
|
|
25
|
+
options: compose.Options = {},
|
|
26
|
+
): Handler {
|
|
27
|
+
const path = options.path ?? '/'
|
|
28
|
+
|
|
29
|
+
return from({
|
|
30
|
+
async defaultHandler(context) {
|
|
31
|
+
const url = new URL(context.request.url)
|
|
32
|
+
if (!url.pathname.startsWith(path))
|
|
33
|
+
return new Response('Not Found', { status: 404 })
|
|
34
|
+
|
|
35
|
+
url.pathname = url.pathname.replace(path, '')
|
|
36
|
+
for (const handler of handlers) {
|
|
37
|
+
const request = new Request(url, context.request.clone())
|
|
38
|
+
const response = await handler.fetch(request)
|
|
39
|
+
if (response.status !== 404) return response
|
|
40
|
+
}
|
|
41
|
+
return new Response('Not Found', { status: 404 })
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export declare namespace compose {
|
|
47
|
+
export type Options = {
|
|
48
|
+
/** The path to use for the handler. */
|
|
49
|
+
path?: string | undefined
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
19
53
|
/**
|
|
20
54
|
* Instantiates a new request handler.
|
|
21
55
|
*
|
|
22
56
|
* @param options - constructor options
|
|
23
57
|
* @returns Handler instance
|
|
24
58
|
*/
|
|
25
|
-
export function from(): Handler {
|
|
26
|
-
const router = createRouter()
|
|
59
|
+
export function from(options: from.Options = {}): Handler {
|
|
60
|
+
const router = createRouter(options)
|
|
27
61
|
return {
|
|
28
62
|
...router,
|
|
29
63
|
listener: RequestListener.fromFetchHandler((request) => {
|
|
@@ -32,6 +66,10 @@ export function from(): Handler {
|
|
|
32
66
|
}
|
|
33
67
|
}
|
|
34
68
|
|
|
69
|
+
export declare namespace from {
|
|
70
|
+
export type Options = RouterOptions
|
|
71
|
+
}
|
|
72
|
+
|
|
35
73
|
/**
|
|
36
74
|
* Defines a Key Manager request handler.
|
|
37
75
|
*
|