acrylblends 0.6.1 → 0.6.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 +8 -6
- package/docs/framework/UPSTREAM.md +1 -1
- package/docs/framework/api/presets.md +0 -3
- package/docs/framework/cordis/acryl-in-a-cordis-app.md +3 -0
- package/docs/framework/getting-started/basic.md +4 -4
- package/docs/framework/guides/jsx.md +1 -1
- package/docs/framework/guides/middleware.md +1 -1
- package/docs/framework/helpers/cookie.md +1 -1
- package/docs/framework/helpers/dev.md +0 -3
- package/docs/framework/helpers/jwt.md +1 -1
- package/docs/framework/helpers/proxy.md +0 -3
- package/docs/framework/middleware/builtin/basic-auth.md +6 -6
- package/docs/framework/middleware/builtin/cache.md +0 -3
- package/docs/framework/middleware/builtin/combine.md +1 -1
- package/docs/framework/middleware/builtin/ip-restriction.md +1 -1
- package/docs/framework/middleware/builtin/logger.md +1 -1
- package/docs/framework/middleware/builtin/mount.md +0 -3
- package/docs/framework/upstream.json +2 -2
- package/lib/accepts.d.ts +1 -1
- package/lib/acryl-base.d.ts +1 -1
- package/lib/adapter.d.ts +1 -1
- package/lib/{app-CmAYW1Al.d.ts → app-BdrVHBlJ.d.ts} +1 -1
- package/lib/basic-auth.d.ts +1 -1
- package/lib/bearer-auth.d.ts +1 -1
- package/lib/body-limit.d.ts +1 -1
- package/lib/cache.d.ts +43 -0
- package/lib/cache.js +169 -0
- package/lib/client.d.ts +2 -2
- package/lib/combine.d.ts +1 -1
- package/lib/compress.d.ts +1 -1
- package/lib/conninfo.d.ts +2 -2
- package/lib/{context-Bm7rI-oK.d.ts → context-B5Y1lLha.d.ts} +1 -1
- package/lib/context-storage.d.ts +1 -1
- package/lib/{cookie-ClMaKDQf.d.ts → cookie-D9_nQbsM.d.ts} +1 -1
- package/lib/cookie.d.ts +3 -3
- package/lib/cors.d.ts +1 -1
- package/lib/csrf.d.ts +1 -1
- package/lib/dev.d.ts +19 -0
- package/lib/dev.js +50 -0
- package/lib/etag.d.ts +1 -1
- package/lib/factory.d.ts +2 -2
- package/lib/{index-B-3F4wt2.d.ts → index-DtEoak1i.d.ts} +2 -2
- package/lib/{index-UTBmM3GX.d.ts → index-Kqou8Fjh.d.ts} +2 -2
- package/lib/{index-oOClm_Xk.d.ts → index-m12zcmph.d.ts} +3 -3
- package/lib/index.d.ts +4 -4
- package/lib/ip-restriction.d.ts +2 -2
- package/lib/jwk.d.ts +4 -4
- package/lib/{jwt-Dg493Tai.d.ts → jwt-BA65QhnJ.d.ts} +1 -1
- package/lib/jwt.d.ts +4 -4
- package/lib/language.d.ts +1 -1
- package/lib/linear-router-C3FPib6h.js +96 -0
- package/lib/logger.d.ts +1 -1
- package/lib/loopback-only.d.ts +1 -1
- package/lib/method-not-allowed.d.ts +2 -2
- package/lib/method-override.d.ts +2 -2
- package/lib/mount.d.ts +44 -0
- package/lib/mount.js +67 -0
- package/lib/node-server/conninfo.d.ts +1 -1
- package/lib/node-server/serve-static.d.ts +1 -1
- package/lib/node-server.d.ts +1 -1
- package/lib/pattern-router-HZxjDGEQ.js +41 -0
- package/lib/powered-by.d.ts +1 -1
- package/lib/pretty-json.d.ts +1 -1
- package/lib/proxy.d.ts +72 -0
- package/lib/proxy.js +121 -0
- package/lib/quick.d.ts +8 -0
- package/lib/quick.js +17 -0
- package/lib/request-id.d.ts +1 -1
- package/lib/request.d.ts +1 -1
- package/lib/route.d.ts +1 -1
- package/lib/router/linear-router.js +1 -95
- package/lib/router/pattern-router.js +1 -40
- package/lib/schema-validator.d.ts +1 -1
- package/lib/secure-headers.d.ts +1 -1
- package/lib/serve-static.d.ts +1 -1
- package/lib/streaming.d.ts +1 -1
- package/lib/testing.d.ts +4 -4
- package/lib/timeout.d.ts +1 -1
- package/lib/timing.d.ts +1 -1
- package/lib/tiny.d.ts +8 -0
- package/lib/tiny.js +15 -0
- package/lib/trailing-slash.d.ts +1 -1
- package/lib/{types-CHesD1KG.d.ts → types-Bd29gh2o.d.ts} +3 -3
- package/lib/{types-CwrQjlaM.d.ts → types-D9DEXMjE.d.ts} +3 -1
- package/lib/{types-CDO6I3B0.d.ts → types-ZM9gIiKh.d.ts} +1 -1
- package/lib/types.d.ts +1 -1
- package/lib/utils/body.d.ts +1 -1
- package/lib/utils/cookie.d.ts +1 -1
- package/lib/utils/crypto.d.ts +1 -1
- package/lib/utils/ipaddr.d.ts +1 -1
- package/lib/utils/jwt.d.ts +1 -1
- package/lib/utils/types.d.ts +2 -2
- package/lib/validator.d.ts +2 -2
- package/lib/ws.d.ts +1 -1
- package/package.json +25 -1
- package/plugins/acryl-inspect/upstream.json +1 -1
- package/plugins/acryl-node-server/upstream.json +1 -1
- package/plugins/acryl-router/src/core/helper/dev/index.test.ts +181 -0
- package/plugins/acryl-router/src/core/helper/dev/index.ts +79 -0
- package/plugins/acryl-router/src/core/helper/proxy/index.test.ts +356 -0
- package/plugins/acryl-router/src/core/helper/proxy/index.ts +203 -0
- package/plugins/acryl-router/src/core/middleware/cache/index.test.ts +1211 -0
- package/plugins/acryl-router/src/core/middleware/cache/index.ts +323 -0
- package/plugins/acryl-router/src/core/middleware/mount/index.test.ts +334 -0
- package/plugins/acryl-router/src/core/middleware/mount/index.ts +108 -0
- package/plugins/acryl-router/src/core/preset/quick.test.ts +42 -0
- package/plugins/acryl-router/src/core/preset/quick.ts +24 -0
- package/plugins/acryl-router/src/core/preset/tiny.test.ts +42 -0
- package/plugins/acryl-router/src/core/preset/tiny.ts +20 -0
- package/plugins/acryl-router/src/core/utils/types.ts +3 -0
- package/plugins/acryl-router/src/helpers/index.ts +2 -0
- package/plugins/acryl-router/src/middleware/index.ts +2 -0
- package/plugins/acryl-router/src/service.ts +22 -5
- package/plugins/acryl-router/upstream.json +2 -2
- package/plugins/acryl-router-http/upstream.json +1 -1
- package/plugins/acryl-state/upstream.json +1 -1
- package/plugins/desktop/upstream.json +1 -1
- package/plugins/desktop-web/upstream.json +1 -1
- package/templates/todo/upstream.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ One <code>Request</code> in, one <code>Response</code> out: routing, middleware,
|
|
|
22
22
|
import { Acryl } from 'acrylblends'
|
|
23
23
|
|
|
24
24
|
const app = new Acryl()
|
|
25
|
-
app.get('/', (c) => c.text('
|
|
25
|
+
app.get('/', (c) => c.text('Acryl!'))
|
|
26
26
|
|
|
27
27
|
export default app
|
|
28
28
|
```
|
|
@@ -68,7 +68,7 @@ import { Acryl } from 'acrylblends'
|
|
|
68
68
|
|
|
69
69
|
const app = new Acryl()
|
|
70
70
|
|
|
71
|
-
app.get('/', (c) => c.text('
|
|
71
|
+
app.get('/', (c) => c.text('Acryl!'))
|
|
72
72
|
|
|
73
73
|
export default app
|
|
74
74
|
```
|
|
@@ -202,7 +202,7 @@ Export the app's type, and `acrylblends/client` calls its routes with typed path
|
|
|
202
202
|
// api.ts
|
|
203
203
|
import { Acryl } from 'acrylblends'
|
|
204
204
|
|
|
205
|
-
const app = new Acryl().get('/api/hello', (c) => c.json({ message: '
|
|
205
|
+
const app = new Acryl().get('/api/hello', (c) => c.json({ message: 'Acryl!' }))
|
|
206
206
|
export type AppType = typeof app
|
|
207
207
|
export default app
|
|
208
208
|
```
|
|
@@ -231,7 +231,7 @@ import app from './index.ts'
|
|
|
231
231
|
test('GET / says hello', async () => {
|
|
232
232
|
const response = await app.request('/')
|
|
233
233
|
assert.equal(response.status, 200)
|
|
234
|
-
assert.equal(await response.text(), '
|
|
234
|
+
assert.equal(await response.text(), 'Acryl!')
|
|
235
235
|
})
|
|
236
236
|
```
|
|
237
237
|
|
|
@@ -271,10 +271,12 @@ See [Node.js](https://github.com/acryldev/acryl/blob/main/docs/framework/getting
|
|
|
271
271
|
| `acrylblends/http-exception` | `HTTPException` |
|
|
272
272
|
| `acrylblends/router/*` | the routers: `reg-exp-router`, `smart-router`, `trie-router`, `pattern-router`, `linear-router` ([routers](https://github.com/acryldev/acryl/blob/main/docs/framework/concepts/routers.md)) |
|
|
273
273
|
| `acrylblends/utils/*` | the utilities the framework is built from |
|
|
274
|
+
| `acrylblends/tiny`, `acrylblends/quick` | the presets: `Acryl` with another router (`PatternRouter`; `LinearRouter` and `TrieRouter`) ([presets](https://github.com/acryldev/acryl/blob/main/docs/framework/api/presets.md)) |
|
|
275
|
+
| `acrylblends/cache`, `acrylblends/mount` | the cache middleware and mounting another framework's fetch handler |
|
|
276
|
+
| `acrylblends/proxy`, `acrylblends/dev` | the proxy helper and the dev helpers (`showRoutes`, `inspectRoutes`, `getRouterName`) |
|
|
274
277
|
| `acrylblends/node-server` | `serve`, `createAdaptorServer`, `getRequestListener`; with `node-server/serve-static` and `node-server/conninfo` |
|
|
275
278
|
|
|
276
|
-
Every subpath is listed in the package's `exports`. JSX, SSG
|
|
277
|
-
being ported. The docs mark them "not yet available" until they ship
|
|
279
|
+
Every subpath is listed in the package's `exports`. JSX, SSG and other runtimes' adapters are being ported. The docs mark them "not yet available" until they ship
|
|
278
280
|
([FAQ](https://github.com/acryldev/acryl/blob/main/docs/framework/guides/faq.md)).
|
|
279
281
|
|
|
280
282
|
To extend the context's typed variables, augment the root module:
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# Generated copy
|
|
2
2
|
|
|
3
|
-
This folder is a copy of `docs/framework` of acryldev/acryl at commit `
|
|
3
|
+
This folder is a copy of `docs/framework` of acryldev/acryl at commit `0174cb01625bfd32d0162ad56179c582f353321e`, made by `scripts/sync-framework.mjs`. Do not edit it here: change the text in ACRYL and sync again. `pnpm run verify:framework` fails when a page differs from the recorded digest.
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# Presets
|
|
2
2
|
|
|
3
|
-
> **Partly available.** The default router (`SmartRouter`), `RegExpRouter`, `TrieRouter`, `LinearRouter` and `PatternRouter` are available and are chosen with the `router` option of `new Acryl()` (see [Routers](../concepts/routers.md)). The presets `acrylblends/quick` and `acrylblends/tiny` are **not yet available**; their examples below are not checked by the docs tests.
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
Acryl has several routers, each designed for a specific purpose.
|
|
7
4
|
You can specify the router you want to use in the constructor of Acryl.
|
|
8
5
|
|
|
@@ -43,6 +43,9 @@ export function apply(ctx: Context): void {
|
|
|
43
43
|
| `GET /todo/todos/42` | `{ "id": "42" }` |
|
|
44
44
|
| `GET /todo/` | 404: `/todo` and `/todo/` are different paths (see below) |
|
|
45
45
|
|
|
46
|
+
The app can come from `acryl-router` or from the published `acrylblends` package: `route` takes any app by its routes
|
|
47
|
+
(`MountableApp`), so an `Acryl` imported from `acrylblends` mounts as it is, with its middleware and its own `onError`.
|
|
48
|
+
|
|
46
49
|
### `/todo/` is a 404 until you choose
|
|
47
50
|
|
|
48
51
|
`/todo/` is the first thing people type, and by default it is not found: the router treats `/todo` and `/todo/` as two paths. Choose
|
|
@@ -63,7 +63,7 @@ import { Acryl } from 'acrylblends'
|
|
|
63
63
|
const app = new Acryl()
|
|
64
64
|
|
|
65
65
|
app.get('/', (c) => {
|
|
66
|
-
return c.text('
|
|
66
|
+
return c.text('Acryl!')
|
|
67
67
|
})
|
|
68
68
|
|
|
69
69
|
export default app
|
|
@@ -83,7 +83,7 @@ const app = new Acryl()
|
|
|
83
83
|
app.get('/api/hello', (c) => {
|
|
84
84
|
return c.json({
|
|
85
85
|
ok: true,
|
|
86
|
-
message: '
|
|
86
|
+
message: 'Acryl!',
|
|
87
87
|
})
|
|
88
88
|
})
|
|
89
89
|
```
|
|
@@ -162,7 +162,7 @@ app.use(
|
|
|
162
162
|
'/admin/*',
|
|
163
163
|
basicAuth({
|
|
164
164
|
username: 'admin',
|
|
165
|
-
password:
|
|
165
|
+
password: process.env.ADMIN_PASSWORD!,
|
|
166
166
|
})
|
|
167
167
|
)
|
|
168
168
|
|
|
@@ -181,7 +181,7 @@ An app is a function from `Request` to `Response`, so a test needs no server:
|
|
|
181
181
|
import { Acryl } from 'acrylblends'
|
|
182
182
|
|
|
183
183
|
const app = new Acryl()
|
|
184
|
-
app.get('/', (c) => c.text('
|
|
184
|
+
app.get('/', (c) => c.text('Acryl!'))
|
|
185
185
|
|
|
186
186
|
const response = await app.request('/')
|
|
187
187
|
console.log(response.status, await response.text())
|
|
@@ -37,7 +37,7 @@ app.get('/cookie', (c) => {
|
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
app.get('/signed-cookie', (c) => {
|
|
40
|
-
const secret =
|
|
40
|
+
const secret = process.env.COOKIE_SECRET! // a long random string, kept out of the source
|
|
41
41
|
|
|
42
42
|
await setSignedCookie(c, 'cookie_name0', 'cookie_value', secret)
|
|
43
43
|
const fortuneCookie = await getSignedCookie(
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# Dev Helper
|
|
2
2
|
|
|
3
|
-
> **Not yet available.** The dev helper (`acrylblends/dev`) is documented here so the page structure matches the rest of the framework, and is not part of acrylblends yet. The code on this page is not checked by the docs tests.
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
Dev Helper provides useful methods you can use in development.
|
|
7
4
|
|
|
8
5
|
```ts
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# Proxy Helper
|
|
2
2
|
|
|
3
|
-
> **Not yet available.** The proxy helper (`acrylblends/proxy`) is documented here so the page structure matches the rest of the framework, and is not part of acrylblends yet. The code on this page is not checked by the docs tests.
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
Proxy Helper provides useful functions when using Acryl application as a (reverse) proxy.
|
|
7
4
|
|
|
8
5
|
## Import
|
|
@@ -21,7 +21,7 @@ app.use(
|
|
|
21
21
|
'/auth/*',
|
|
22
22
|
basicAuth({
|
|
23
23
|
username: 'acrylblends',
|
|
24
|
-
password:
|
|
24
|
+
password: process.env.BASIC_AUTH_PASSWORD!,
|
|
25
25
|
})
|
|
26
26
|
)
|
|
27
27
|
|
|
@@ -41,7 +41,7 @@ app.get('/auth/page', (c) => {
|
|
|
41
41
|
|
|
42
42
|
app.delete(
|
|
43
43
|
'/auth/page',
|
|
44
|
-
basicAuth({ username: 'acrylblends', password:
|
|
44
|
+
basicAuth({ username: 'acrylblends', password: process.env.BASIC_AUTH_PASSWORD! }),
|
|
45
45
|
(c) => {
|
|
46
46
|
return c.text('Page deleted')
|
|
47
47
|
}
|
|
@@ -100,7 +100,7 @@ app.use(
|
|
|
100
100
|
'/auth/*',
|
|
101
101
|
basicAuth({
|
|
102
102
|
username: 'acrylblends',
|
|
103
|
-
password:
|
|
103
|
+
password: process.env.BASIC_AUTH_PASSWORD!,
|
|
104
104
|
onAuthSuccess: (c, username) => {
|
|
105
105
|
c.set('username', username)
|
|
106
106
|
},
|
|
@@ -129,18 +129,18 @@ app.use(
|
|
|
129
129
|
basicAuth(
|
|
130
130
|
{
|
|
131
131
|
username: 'acrylblends',
|
|
132
|
-
password:
|
|
132
|
+
password: process.env.BASIC_AUTH_PASSWORD!,
|
|
133
133
|
// Define other params in the first object
|
|
134
134
|
realm: 'www.example.com',
|
|
135
135
|
},
|
|
136
136
|
{
|
|
137
137
|
username: 'acrylblends-admin',
|
|
138
|
-
password:
|
|
138
|
+
password: process.env.ADMIN_PASSWORD!,
|
|
139
139
|
// Cannot redefine other params here
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
142
|
username: 'acrylblends-user-1',
|
|
143
|
-
password:
|
|
143
|
+
password: process.env.USER_1_PASSWORD!,
|
|
144
144
|
// Or here
|
|
145
145
|
}
|
|
146
146
|
)
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# Cache Middleware
|
|
2
2
|
|
|
3
|
-
> **Not yet available.** The cache middleware (`acrylblends/cache`) is documented here so the page structure matches the rest of the framework, and is not part of acrylblends yet. The code on this page is not checked by the docs tests.
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
The Cache middleware uses the Web Standards' [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache).
|
|
7
4
|
|
|
8
5
|
The Cache middleware currently supports Cloudflare Workers projects using custom domains and Deno projects using [Deno 1.26+](https://github.com/denoland/deno/releases/tag/v1.26.0). Also available with Deno Deploy.
|
|
@@ -28,7 +28,7 @@ app.use(
|
|
|
28
28
|
})
|
|
29
29
|
)
|
|
30
30
|
|
|
31
|
-
app.get('/', (c) => c.text('
|
|
31
|
+
app.get('/', (c) => c.text('Acryl!'))
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
Pass the `getConninfo` from the [ConnInfo helper](../../helpers/conninfo.md) appropriate for your environment as the first argument of `ipRestriction`. For a runtime whose adapter is not yet available there is no `getConnInfo` to pass yet.
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# Mount Middleware
|
|
2
2
|
|
|
3
|
-
> **Not yet available.** The `acrylblends/mount` subpath (an app can still call `app.mount()`) is documented here so the page structure matches the rest of the framework, and is not part of acrylblends yet. The code on this page is not checked by the docs tests.
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
The Mount Middleware lets you mount an application built with another framework into your Acryl application.
|
|
7
4
|
|
|
8
5
|
## Import
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"source": {
|
|
3
3
|
"repo": "acryldev/acryl",
|
|
4
4
|
"path": "docs/framework",
|
|
5
|
-
"commit": "
|
|
5
|
+
"commit": "0174cb01625bfd32d0162ad56179c582f353321e"
|
|
6
6
|
},
|
|
7
7
|
"files": 87,
|
|
8
|
-
"digest": "sha256:
|
|
8
|
+
"digest": "sha256:be8b4bb2555dbc97ef94caa57f6b071f5c0f173f0711eecc2836a537a1a71681"
|
|
9
9
|
}
|
package/lib/accepts.d.ts
CHANGED
package/lib/acryl-base.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as Acryl, et as AcrylOptions } from "./context-
|
|
1
|
+
import { $ as Acryl, et as AcrylOptions } from "./context-B5Y1lLha.js";
|
|
2
2
|
export { Acryl as AcrylBase, AcrylOptions };
|
package/lib/adapter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Context } from "./context-
|
|
1
|
+
import { t as Context } from "./context-B5Y1lLha.js";
|
|
2
2
|
|
|
3
3
|
//#region ../../plugins/acryl-router/src/core/helper/adapter/index.d.ts
|
|
4
4
|
type Runtime = 'node' | 'deno' | 'bun' | 'workerd' | 'fastly' | 'edge-light' | 'other';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as Acryl$1, J as Schema, _ as Env, et as AcrylOptions, h as BlankSchema, p as BlankEnv } from "./context-
|
|
1
|
+
import { $ as Acryl$1, J as Schema, _ as Env, et as AcrylOptions, h as BlankSchema, p as BlankEnv } from "./context-B5Y1lLha.js";
|
|
2
2
|
|
|
3
3
|
//#region ../../plugins/acryl-router/src/core/app.d.ts
|
|
4
4
|
/**
|
package/lib/basic-auth.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as MiddlewareHandler, t as Context } from "./context-
|
|
1
|
+
import { I as MiddlewareHandler, t as Context } from "./context-B5Y1lLha.js";
|
|
2
2
|
|
|
3
3
|
//#region ../../plugins/acryl-router/src/core/middleware/basic-auth/index.d.ts
|
|
4
4
|
type MessageFunction = (c: Context) => string | object | Promise<string | object>;
|
package/lib/bearer-auth.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as MiddlewareHandler, _ as Env, t as Context } from "./context-
|
|
1
|
+
import { I as MiddlewareHandler, _ as Env, t as Context } from "./context-B5Y1lLha.js";
|
|
2
2
|
|
|
3
3
|
//#region ../../plugins/acryl-router/src/core/middleware/bearer-auth/index.d.ts
|
|
4
4
|
type MessageFunction = (c: Context) => string | object | Promise<string | object>;
|
package/lib/body-limit.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as MiddlewareHandler, t as Context } from "./context-
|
|
1
|
+
import { I as MiddlewareHandler, t as Context } from "./context-B5Y1lLha.js";
|
|
2
2
|
|
|
3
3
|
//#region ../../plugins/acryl-router/src/core/middleware/body-limit/index.d.ts
|
|
4
4
|
type OnError = (c: Context) => Response | Promise<Response>;
|
package/lib/cache.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { I as MiddlewareHandler, t as Context } from "./context-B5Y1lLha.js";
|
|
2
|
+
import { c as StatusCode } from "./http-status-DaAwGAFL.js";
|
|
3
|
+
|
|
4
|
+
//#region ../../plugins/acryl-router/src/core/middleware/cache/index.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Cache Middleware for Acryl.
|
|
7
|
+
*
|
|
8
|
+
*
|
|
9
|
+
* @param {Object} options - The options for the cache middleware.
|
|
10
|
+
* @param {string | Function} options.cacheName - The name of the cache. Can be used to store multiple caches with different identifiers.
|
|
11
|
+
* @param {boolean} [options.wait=false] - A boolean indicating if Acryl should wait for the Promise of the `cache.put` function to resolve before continuing with the request. Required to be true for the Deno environment.
|
|
12
|
+
* @param {string} [options.cacheControl] - A string of directives for the `Cache-Control` header.
|
|
13
|
+
* @param {string | string[]} [options.vary] - Adds the configured request headers to the cache key variants and sets the `Vary` header in the response. If the original response header already contains a `Vary` header, the values are merged, removing any duplicates.
|
|
14
|
+
* @param {Function} [options.keyGenerator] - Generates keys for every request in the `cacheName` store. This can be used to cache data based on request parameters or context parameters. QUERY keys additionally include a digest of the request content and its representation metadata.
|
|
15
|
+
* @param {number} [options.maxQueryBodySize=65536] - The maximum QUERY request body size in bytes that can be cached. Larger QUERY requests bypass the cache.
|
|
16
|
+
* @param {number[]} [options.cacheableStatusCodes=[200]] - An array of status codes that can be cached.
|
|
17
|
+
* @param {Function | false} [options.onCacheNotAvailable] - A callback invoked with the reason when `globalThis.caches` is not available or QUERY caching cannot use Web Crypto. By default, the reason is logged to the console. Set to `false` to suppress the log, or provide a custom function.
|
|
18
|
+
* @returns {MiddlewareHandler} The middleware handler function.
|
|
19
|
+
* @throws {Error} If the `vary` option includes "*".
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* app.use(
|
|
24
|
+
* '*',
|
|
25
|
+
* cache({
|
|
26
|
+
* cacheName: 'my-app',
|
|
27
|
+
* cacheControl: 'max-age=3600',
|
|
28
|
+
* })
|
|
29
|
+
* )
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
declare const cache: (options: {
|
|
33
|
+
cacheName: string | ((c: Context) => Promise<string> | string);
|
|
34
|
+
wait?: boolean;
|
|
35
|
+
cacheControl?: string;
|
|
36
|
+
vary?: string | string[];
|
|
37
|
+
keyGenerator?: (c: Context) => Promise<string> | string;
|
|
38
|
+
maxQueryBodySize?: number;
|
|
39
|
+
cacheableStatusCodes?: StatusCode[];
|
|
40
|
+
onCacheNotAvailable?: ((reason: string) => void) | false;
|
|
41
|
+
}) => MiddlewareHandler;
|
|
42
|
+
//#endregion
|
|
43
|
+
export { cache };
|
package/lib/cache.js
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { sha256 } from "./utils/crypto.js";
|
|
2
|
+
import { cloneRawRequest } from "./request.js";
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/middleware/cache/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* status codes that can be cached by default.
|
|
6
|
+
*/
|
|
7
|
+
const defaultCacheableStatusCodes = [200];
|
|
8
|
+
const defaultMaxQueryBodySize = 64 * 1024;
|
|
9
|
+
const cacheKeyPath = "/.acryl-router/cache";
|
|
10
|
+
const cacheKeyParameter = "__hono_cache_key";
|
|
11
|
+
const cacheMethodKeyParameter = "__hono_cache_method";
|
|
12
|
+
const queryDigestKeyParameter = "__hono_query_digest";
|
|
13
|
+
const cacheVaryKeyParameter = "__hono_cache_vary";
|
|
14
|
+
const queryRepresentationMetadataHeaders = [
|
|
15
|
+
"content-type",
|
|
16
|
+
"content-encoding",
|
|
17
|
+
"content-language",
|
|
18
|
+
"content-location"
|
|
19
|
+
];
|
|
20
|
+
const shouldSkipCacheControl = (cacheControl) => !!cacheControl && /(?:^|,\s*)(?:private|no-(?:store|cache))(?:\s*(?:=|,|$))/i.test(cacheControl);
|
|
21
|
+
const parseVaryDirectives = (vary) => {
|
|
22
|
+
if (vary == null) return [];
|
|
23
|
+
return (Array.isArray(vary) ? vary : vary.split(",")).map((directive) => directive.trim().toLowerCase()).filter(Boolean);
|
|
24
|
+
};
|
|
25
|
+
const createCacheKey = (key, requestUrl, request, varyHeaders) => {
|
|
26
|
+
const url = new URL(cacheKeyPath, requestUrl);
|
|
27
|
+
url.searchParams.append(cacheKeyParameter, key);
|
|
28
|
+
url.searchParams.append(cacheMethodKeyParameter, request.method);
|
|
29
|
+
if (request.method === "QUERY") url.searchParams.append(queryDigestKeyParameter, request.digest);
|
|
30
|
+
for (const header of varyHeaders) url.searchParams.append(cacheVaryKeyParameter, JSON.stringify(header));
|
|
31
|
+
return url.href;
|
|
32
|
+
};
|
|
33
|
+
const shouldSkipCache = (res, optionsVaryDirectives, responseVary) => responseVary.length && (!optionsVaryDirectives || responseVary.some((name) => !optionsVaryDirectives.has(name))) || shouldSkipCacheControl(res.headers.get("Cache-Control")) || res.headers.has("Set-Cookie");
|
|
34
|
+
const reportCacheNotAvailable = (onCacheNotAvailable, reason) => {
|
|
35
|
+
if (onCacheNotAvailable === false) {} else if (onCacheNotAvailable) onCacheNotAvailable(reason);
|
|
36
|
+
else console.log(reason);
|
|
37
|
+
};
|
|
38
|
+
const createQueryDigest = async (c, maxQueryBodySize) => {
|
|
39
|
+
if (!globalThis.crypto?.subtle) return;
|
|
40
|
+
if (c.req.raw.bodyUsed && Object.keys(c.req.bodyCache)[0] === "formData") return;
|
|
41
|
+
try {
|
|
42
|
+
const requestHeaders = c.req.raw.headers;
|
|
43
|
+
const metadata = new TextEncoder().encode(JSON.stringify(queryRepresentationMetadataHeaders.map((header) => [header, requestHeaders.get(header)])));
|
|
44
|
+
const body = (await cloneRawRequest(c.req)).body;
|
|
45
|
+
const chunks = [];
|
|
46
|
+
let bodySize = 0;
|
|
47
|
+
if (body) {
|
|
48
|
+
const reader = body.getReader();
|
|
49
|
+
for (;;) {
|
|
50
|
+
const { done, value } = await reader.read();
|
|
51
|
+
if (done) break;
|
|
52
|
+
bodySize += value.byteLength;
|
|
53
|
+
if (bodySize > maxQueryBodySize) {
|
|
54
|
+
reader.cancel().catch(() => {});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
chunks.push(value);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const data = new Uint8Array(metadata.byteLength + bodySize);
|
|
61
|
+
data.set(metadata);
|
|
62
|
+
let offset = metadata.byteLength;
|
|
63
|
+
for (const chunk of chunks) {
|
|
64
|
+
data.set(chunk, offset);
|
|
65
|
+
offset += chunk.byteLength;
|
|
66
|
+
}
|
|
67
|
+
return await sha256(data) ?? void 0;
|
|
68
|
+
} catch {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Cache Middleware for Acryl.
|
|
74
|
+
*
|
|
75
|
+
*
|
|
76
|
+
* @param {Object} options - The options for the cache middleware.
|
|
77
|
+
* @param {string | Function} options.cacheName - The name of the cache. Can be used to store multiple caches with different identifiers.
|
|
78
|
+
* @param {boolean} [options.wait=false] - A boolean indicating if Acryl should wait for the Promise of the `cache.put` function to resolve before continuing with the request. Required to be true for the Deno environment.
|
|
79
|
+
* @param {string} [options.cacheControl] - A string of directives for the `Cache-Control` header.
|
|
80
|
+
* @param {string | string[]} [options.vary] - Adds the configured request headers to the cache key variants and sets the `Vary` header in the response. If the original response header already contains a `Vary` header, the values are merged, removing any duplicates.
|
|
81
|
+
* @param {Function} [options.keyGenerator] - Generates keys for every request in the `cacheName` store. This can be used to cache data based on request parameters or context parameters. QUERY keys additionally include a digest of the request content and its representation metadata.
|
|
82
|
+
* @param {number} [options.maxQueryBodySize=65536] - The maximum QUERY request body size in bytes that can be cached. Larger QUERY requests bypass the cache.
|
|
83
|
+
* @param {number[]} [options.cacheableStatusCodes=[200]] - An array of status codes that can be cached.
|
|
84
|
+
* @param {Function | false} [options.onCacheNotAvailable] - A callback invoked with the reason when `globalThis.caches` is not available or QUERY caching cannot use Web Crypto. By default, the reason is logged to the console. Set to `false` to suppress the log, or provide a custom function.
|
|
85
|
+
* @returns {MiddlewareHandler} The middleware handler function.
|
|
86
|
+
* @throws {Error} If the `vary` option includes "*".
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* app.use(
|
|
91
|
+
* '*',
|
|
92
|
+
* cache({
|
|
93
|
+
* cacheName: 'my-app',
|
|
94
|
+
* cacheControl: 'max-age=3600',
|
|
95
|
+
* })
|
|
96
|
+
* )
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
const cache = (options) => {
|
|
100
|
+
if (!globalThis.caches) {
|
|
101
|
+
reportCacheNotAvailable(options.onCacheNotAvailable, "Cache Middleware is not enabled because caches is not defined.");
|
|
102
|
+
return async (_c, next) => await next();
|
|
103
|
+
}
|
|
104
|
+
if (!globalThis.crypto?.subtle) reportCacheNotAvailable(options.onCacheNotAvailable, "Cache Middleware cannot cache QUERY requests because Web Crypto is not available.");
|
|
105
|
+
if (options.wait === void 0) options.wait = false;
|
|
106
|
+
const cacheControlDirectives = options.cacheControl?.split(",").map((directive) => directive.toLowerCase());
|
|
107
|
+
const optionsVaryList = parseVaryDirectives(options.vary);
|
|
108
|
+
const varyDirectives = optionsVaryList.length ? new Set(optionsVaryList) : void 0;
|
|
109
|
+
if (varyDirectives?.has("*")) throw new Error("Middleware vary configuration cannot include \"*\", as it disallows effective caching.");
|
|
110
|
+
const cacheableStatusCodes = new Set(options.cacheableStatusCodes ?? defaultCacheableStatusCodes);
|
|
111
|
+
const maxQueryBodySize = options.maxQueryBodySize ?? defaultMaxQueryBodySize;
|
|
112
|
+
const addHeader = (c, responseVary) => {
|
|
113
|
+
if (cacheControlDirectives) {
|
|
114
|
+
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0].toLowerCase()) ?? [];
|
|
115
|
+
for (const directive of cacheControlDirectives) {
|
|
116
|
+
let [name, value] = directive.trim().split("=", 2);
|
|
117
|
+
name = name.toLowerCase();
|
|
118
|
+
if (!existingDirectives.includes(name)) c.header("Cache-Control", `${name}${value ? `=${value}` : ""}`, { append: true });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (varyDirectives) if (responseVary.length === 0) c.header("Vary", Array.from(varyDirectives).join(", "));
|
|
122
|
+
else {
|
|
123
|
+
const merged = new Set(varyDirectives);
|
|
124
|
+
for (const directive of responseVary) merged.add(directive);
|
|
125
|
+
if (merged.has("*")) c.header("Vary", "*");
|
|
126
|
+
else c.header("Vary", Array.from(merged).join(", "));
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
return async function cache(c, next) {
|
|
130
|
+
if (c.req.method !== "GET" && c.req.method !== "QUERY" || c.req.raw.headers.has("Authorization")) {
|
|
131
|
+
await next();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
let cacheKeyRequest = { method: "GET" };
|
|
135
|
+
if (c.req.method === "QUERY") {
|
|
136
|
+
const digest = await createQueryDigest(c, maxQueryBodySize);
|
|
137
|
+
if (digest === void 0) {
|
|
138
|
+
await next();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
cacheKeyRequest = {
|
|
142
|
+
method: "QUERY",
|
|
143
|
+
digest
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
let key = c.req.url;
|
|
147
|
+
if (options.keyGenerator) key = await options.keyGenerator(c);
|
|
148
|
+
const varyHeaders = [];
|
|
149
|
+
if (varyDirectives) for (const directive of varyDirectives) {
|
|
150
|
+
const value = c.req.raw.headers.get(directive) ?? "";
|
|
151
|
+
varyHeaders.push([directive, value]);
|
|
152
|
+
}
|
|
153
|
+
key = createCacheKey(key, c.req.url, cacheKeyRequest, varyHeaders);
|
|
154
|
+
const cacheName = typeof options.cacheName === "function" ? await options.cacheName(c) : options.cacheName;
|
|
155
|
+
const cache = await caches.open(cacheName);
|
|
156
|
+
const response = await cache.match(key);
|
|
157
|
+
if (response) return new Response(response.body, response);
|
|
158
|
+
await next();
|
|
159
|
+
if (!cacheableStatusCodes.has(c.res.status)) return;
|
|
160
|
+
const responseVary = parseVaryDirectives(c.res.headers.get("Vary"));
|
|
161
|
+
addHeader(c, responseVary);
|
|
162
|
+
if (shouldSkipCache(c.res, varyDirectives, responseVary)) return;
|
|
163
|
+
const res = c.res.clone();
|
|
164
|
+
if (options.wait) await cache.put(key, res);
|
|
165
|
+
else c.executionCtx.waitUntil(cache.put(key, res));
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
//#endregion
|
|
169
|
+
export { cache };
|
package/lib/client.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as ClientResponse, c as InferRequestType, i as ClientRequestOptions, l as InferResponseType, o as Fetch, r as ClientRequest, t as ApplyGlobalResponse, u as PickResponseByStatusCode } from "./types-
|
|
2
|
-
import { n as DetailedError, r as hc, t as parseResponse } from "./index-
|
|
1
|
+
import { a as ClientResponse, c as InferRequestType, i as ClientRequestOptions, l as InferResponseType, o as Fetch, r as ClientRequest, t as ApplyGlobalResponse, u as PickResponseByStatusCode } from "./types-Bd29gh2o.js";
|
|
2
|
+
import { n as DetailedError, r as hc, t as parseResponse } from "./index-m12zcmph.js";
|
|
3
3
|
export { type ApplyGlobalResponse, type ClientRequest, type ClientRequestOptions, type ClientResponse, DetailedError, type Fetch, type InferRequestType, type InferResponseType, type PickResponseByStatusCode, hc, parseResponse };
|
package/lib/combine.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as MiddlewareHandler, t as Context } from "./context-
|
|
1
|
+
import { I as MiddlewareHandler, t as Context } from "./context-B5Y1lLha.js";
|
|
2
2
|
|
|
3
3
|
//#region ../../plugins/acryl-router/src/core/middleware/combine/index.d.ts
|
|
4
4
|
type Condition = (c: Context) => boolean;
|
package/lib/compress.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as MiddlewareHandler } from "./context-
|
|
1
|
+
import { I as MiddlewareHandler } from "./context-B5Y1lLha.js";
|
|
2
2
|
import { COMPRESSIBLE_CONTENT_TYPE_REGEX } from "./utils/compress.js";
|
|
3
3
|
|
|
4
4
|
//#region ../../plugins/acryl-router/src/core/middleware/compress/index.d.ts
|
package/lib/conninfo.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as Context } from "./context-
|
|
2
|
-
import { i as NetAddrInfo, n as ConnInfo, r as GetConnInfo, t as AddressType } from "./types-
|
|
1
|
+
import { t as Context } from "./context-B5Y1lLha.js";
|
|
2
|
+
import { i as NetAddrInfo, n as ConnInfo, r as GetConnInfo, t as AddressType } from "./types-ZM9gIiKh.js";
|
|
3
3
|
|
|
4
4
|
//#region ../../plugins/acryl-router/src/connection.d.ts
|
|
5
5
|
/** An in-process caller (the terminal UI, a test) passes nothing, so a handler that needs a trusted peer must refuse an empty one. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as Result, l as Router } from "./router-CvUxUTOq.js";
|
|
2
2
|
import { i as ResponseHeader, n as CustomHeader, r as RequestHeader } from "./headers-tu2YYN8T.js";
|
|
3
3
|
import { c as StatusCode, n as ContentfulStatusCode, o as RedirectStatusCode } from "./http-status-DaAwGAFL.js";
|
|
4
|
-
import {
|
|
4
|
+
import { C as Simplify, E as UnionToIntersection, _ as JSONValue, d as InvalidJSONValue, f as IsAny, h as JSONParsed, l as IfAnyThenEmptyObject, x as RemoveBlankRecord } from "./types-D9DEXMjE.js";
|
|
5
5
|
import { t as BaseMime } from "./mime-BQOYHl-l.js";
|
|
6
6
|
|
|
7
7
|
//#region ../../plugins/acryl-router/src/core/request/constants.d.ts
|
package/lib/context-storage.d.ts
CHANGED
package/lib/cookie.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as Context } from "./context-
|
|
2
|
-
import { n as BufferSource } from "./types-
|
|
3
|
-
import { a as SignedCookie, i as CookiePrefixOptions, r as CookieOptions, t as Cookie } from "./cookie-
|
|
1
|
+
import { t as Context } from "./context-B5Y1lLha.js";
|
|
2
|
+
import { n as BufferSource } from "./types-D9DEXMjE.js";
|
|
3
|
+
import { a as SignedCookie, i as CookiePrefixOptions, r as CookieOptions, t as Cookie } from "./cookie-D9_nQbsM.js";
|
|
4
4
|
|
|
5
5
|
//#region ../../plugins/acryl-router/src/core/helper/cookie/index.d.ts
|
|
6
6
|
interface GetCookie {
|
package/lib/cors.d.ts
CHANGED
package/lib/csrf.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as MiddlewareHandler, t as Context } from "./context-
|
|
1
|
+
import { I as MiddlewareHandler, t as Context } from "./context-B5Y1lLha.js";
|
|
2
2
|
|
|
3
3
|
//#region ../../plugins/acryl-router/src/core/middleware/csrf/index.d.ts
|
|
4
4
|
type IsAllowedOriginHandler = (origin: string, context: Context) => boolean | Promise<boolean>;
|