acrylblends 0.7.3 → 0.7.5
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/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/docs/framework/README.md +6 -4
- package/docs/framework/UPSTREAM.md +1 -1
- package/docs/framework/getting-started/aws-lambda.md +115 -0
- package/docs/framework/getting-started/bun.md +1 -3
- package/docs/framework/getting-started/cloudflare-pages.md +53 -0
- package/docs/framework/getting-started/cloudflare-workers.md +67 -0
- package/docs/framework/getting-started/deploy.md +5 -5
- package/docs/framework/getting-started/lambda-edge.md +41 -0
- package/docs/framework/getting-started/netlify.md +25 -0
- package/docs/framework/getting-started/other-runtimes.md +20 -9
- package/docs/framework/getting-started/service-worker.md +33 -0
- package/docs/framework/getting-started/vercel.md +28 -0
- package/docs/framework/guides/create-acrylblends.md +40 -2
- package/docs/framework/guides/data.md +202 -0
- package/docs/framework/guides/faq.md +2 -2
- package/docs/framework/guides/forms-and-sessions.md +34 -30
- package/docs/framework/helpers/conninfo.md +1 -1
- package/docs/framework/helpers/ssg.md +1 -1
- package/docs/framework/helpers/streaming.md +3 -2
- package/docs/framework/helpers/websocket.md +2 -2
- package/docs/framework/middleware/builtin/ip-restriction.md +1 -1
- package/docs/framework/upstream.json +3 -3
- package/lib/aws-lambda.d.ts +324 -0
- package/lib/aws-lambda.js +357 -0
- package/lib/bun.d.ts +75 -0
- package/lib/bun.js +134 -0
- package/lib/cloudflare-pages.d.ts +58 -0
- package/lib/cloudflare-pages.js +78 -0
- package/lib/cloudflare-workers.d.ts +21 -0
- package/lib/cloudflare-workers.js +80 -0
- package/lib/db/sqlite.d.ts +27 -0
- package/lib/db/sqlite.js +197 -0
- package/lib/db.d.ts +2 -0
- package/lib/db.js +2 -0
- package/lib/index-CseujaYI.d.ts +31 -0
- package/lib/index-D4FAsBZu.d.ts +85 -0
- package/lib/index-DaJtL7ci.d.ts +156 -0
- package/lib/lambda-edge.d.ts +92 -0
- package/lib/lambda-edge.js +105 -0
- package/lib/netlify.d.ts +29 -0
- package/lib/netlify.js +30 -0
- package/lib/node-server/register.js +1 -1
- package/lib/node-server/serve-static.js +1 -1
- package/lib/node-server.js +3 -3
- package/lib/serve-static-Cp5adzGo.js +77 -0
- package/lib/serve-static.d.ts +1 -30
- package/lib/serve-static.js +1 -76
- package/lib/service-worker.d.ts +48 -0
- package/lib/service-worker.js +38 -0
- package/lib/src-MWcsMS8i.js +85 -0
- package/lib/ssg.d.ts +1 -155
- package/lib/vercel.d.ts +10 -0
- package/lib/vercel.js +9 -0
- package/package.json +41 -1
- package/plugins/acryl-db/LICENSE +47 -0
- package/plugins/acryl-db/plugin.json +12 -0
- package/plugins/acryl-db/src/cordis.ts +13 -0
- package/plugins/acryl-db/src/facade/database.ts +41 -0
- package/plugins/acryl-db/src/facade/migrations.ts +50 -0
- package/plugins/acryl-db/src/facade/schema.ts +9 -0
- package/plugins/acryl-db/src/index.ts +19 -0
- package/plugins/acryl-db/src/migration-files.ts +31 -0
- package/plugins/acryl-db/upstream.json +18 -0
- package/plugins/acryl-db-sqlite/LICENSE +47 -0
- package/plugins/acryl-db-sqlite/plugin.json +13 -0
- package/plugins/acryl-db-sqlite/src/facade/node.ts +199 -0
- package/plugins/acryl-db-sqlite/src/index.ts +88 -0
- package/plugins/acryl-db-sqlite/src/open.ts +61 -0
- package/plugins/acryl-db-sqlite/upstream.json +21 -0
- package/plugins/acryl-inspect/upstream.json +1 -1
- package/plugins/acryl-node-server/upstream.json +1 -1
- package/plugins/acryl-router/src/core/adapter/aws-lambda/conninfo.ts +73 -0
- package/plugins/acryl-router/src/core/adapter/aws-lambda/handler.ts +682 -0
- package/plugins/acryl-router/src/core/adapter/aws-lambda/index.ts +14 -0
- package/plugins/acryl-router/src/core/adapter/aws-lambda/types.ts +173 -0
- package/plugins/acryl-router/src/core/adapter/bun/conninfo.ts +43 -0
- package/plugins/acryl-router/src/core/adapter/bun/index.ts +11 -0
- package/plugins/acryl-router/src/core/adapter/bun/serve-static.ts +32 -0
- package/plugins/acryl-router/src/core/adapter/bun/server.ts +14 -0
- package/plugins/acryl-router/src/core/adapter/bun/ssg.ts +26 -0
- package/plugins/acryl-router/src/core/adapter/bun/websocket.ts +113 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-pages/conninfo.ts +26 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-pages/handler.ts +122 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-pages/index.ts +11 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-workers/conninfo.ts +7 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-workers/index.ts +8 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-workers/serve-static-module.ts +12 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-workers/serve-static.ts +41 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-workers/utils.ts +50 -0
- package/plugins/acryl-router/src/core/adapter/cloudflare-workers/websocket.ts +52 -0
- package/plugins/acryl-router/src/core/adapter/lambda-edge/conninfo.ts +15 -0
- package/plugins/acryl-router/src/core/adapter/lambda-edge/handler.ts +239 -0
- package/plugins/acryl-router/src/core/adapter/lambda-edge/index.ts +14 -0
- package/plugins/acryl-router/src/core/adapter/netlify/conninfo.ts +57 -0
- package/plugins/acryl-router/src/core/adapter/netlify/handler.ts +10 -0
- package/plugins/acryl-router/src/core/adapter/netlify/index.ts +6 -0
- package/plugins/acryl-router/src/core/adapter/netlify/mod.ts +2 -0
- package/plugins/acryl-router/src/core/adapter/service-worker/handler.ts +37 -0
- package/plugins/acryl-router/src/core/adapter/service-worker/index.ts +36 -0
- package/plugins/acryl-router/src/core/adapter/service-worker/types.ts +14 -0
- package/plugins/acryl-router/src/core/adapter/vercel/conninfo.ts +8 -0
- package/plugins/acryl-router/src/core/adapter/vercel/handler.ts +8 -0
- package/plugins/acryl-router/src/core/adapter/vercel/index.ts +7 -0
- 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/main.ts +13 -3
- package/plugins/desktop-web/upstream.json +1 -1
- package/plugins/tsconfig.json +1 -0
- package/templates/todo/upstream.json +1 -1
- package/lib/{serve-static-B14MF1Va.js → serve-static-B849HlX2.js} +1 -1
- package/lib/{transpile-CTnWof4z.js → transpile-QUK9b3eG.js} +1 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
export interface CognitoIdentity {
|
|
4
|
+
cognitoIdentityId: string
|
|
5
|
+
cognitoIdentityPoolId: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ClientContext {
|
|
9
|
+
client: ClientContextClient
|
|
10
|
+
|
|
11
|
+
Custom?: any
|
|
12
|
+
env: ClientContextEnv
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ClientContextClient {
|
|
16
|
+
installationId: string
|
|
17
|
+
appTitle: string
|
|
18
|
+
appVersionName: string
|
|
19
|
+
appVersionCode: string
|
|
20
|
+
appPackageName: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ClientContextEnv {
|
|
24
|
+
platformVersion: string
|
|
25
|
+
platform: string
|
|
26
|
+
make: string
|
|
27
|
+
model: string
|
|
28
|
+
locale: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* {@link Handler} context parameter.
|
|
33
|
+
* See {@link https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html AWS documentation}.
|
|
34
|
+
*/
|
|
35
|
+
export interface LambdaContext {
|
|
36
|
+
callbackWaitsForEmptyEventLoop: boolean
|
|
37
|
+
functionName: string
|
|
38
|
+
functionVersion: string
|
|
39
|
+
invokedFunctionArn: string
|
|
40
|
+
memoryLimitInMB: string
|
|
41
|
+
awsRequestId: string
|
|
42
|
+
logGroupName: string
|
|
43
|
+
logStreamName: string
|
|
44
|
+
identity?: CognitoIdentity | undefined
|
|
45
|
+
clientContext?: ClientContext | undefined
|
|
46
|
+
|
|
47
|
+
getRemainingTimeInMillis(): number
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type Callback<TResult = any> = (error?: Error | string | null, result?: TResult) => void
|
|
51
|
+
|
|
52
|
+
export type Handler<TEvent = any, TResult = any> = (
|
|
53
|
+
event: TEvent,
|
|
54
|
+
context: LambdaContext,
|
|
55
|
+
callback: Callback<TResult>
|
|
56
|
+
) => void | Promise<TResult>
|
|
57
|
+
|
|
58
|
+
interface ClientCert {
|
|
59
|
+
clientCertPem: string
|
|
60
|
+
subjectDN: string
|
|
61
|
+
issuerDN: string
|
|
62
|
+
serialNumber: string
|
|
63
|
+
validity: {
|
|
64
|
+
notBefore: string
|
|
65
|
+
notAfter: string
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface Identity {
|
|
70
|
+
accessKey?: string
|
|
71
|
+
accountId?: string
|
|
72
|
+
caller?: string
|
|
73
|
+
cognitoAuthenticationProvider?: string
|
|
74
|
+
cognitoAuthenticationType?: string
|
|
75
|
+
cognitoIdentityId?: string
|
|
76
|
+
cognitoIdentityPoolId?: string
|
|
77
|
+
principalOrgId?: string
|
|
78
|
+
sourceIp: string
|
|
79
|
+
user?: string
|
|
80
|
+
userAgent: string
|
|
81
|
+
userArn?: string
|
|
82
|
+
clientCert?: ClientCert
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface ApiGatewayRequestContext {
|
|
86
|
+
accountId: string
|
|
87
|
+
apiId: string
|
|
88
|
+
authorizer: {
|
|
89
|
+
claims?: unknown
|
|
90
|
+
scopes?: unknown
|
|
91
|
+
}
|
|
92
|
+
domainName: string
|
|
93
|
+
domainPrefix: string
|
|
94
|
+
extendedRequestId: string
|
|
95
|
+
httpMethod: string
|
|
96
|
+
identity: Identity
|
|
97
|
+
path: string
|
|
98
|
+
protocol: string
|
|
99
|
+
requestId: string
|
|
100
|
+
requestTime: string
|
|
101
|
+
requestTimeEpoch: number
|
|
102
|
+
resourceId?: string
|
|
103
|
+
resourcePath: string
|
|
104
|
+
stage: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface Authorizer {
|
|
108
|
+
iam?: {
|
|
109
|
+
accessKey: string
|
|
110
|
+
accountId: string
|
|
111
|
+
callerId: string
|
|
112
|
+
cognitoIdentity: null
|
|
113
|
+
principalOrgId: null
|
|
114
|
+
userArn: string
|
|
115
|
+
userId: string
|
|
116
|
+
}
|
|
117
|
+
jwt?: {
|
|
118
|
+
claims: Record<string, string | number | boolean | string[]>
|
|
119
|
+
scopes: string[] | null
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The `context` object returned by a Lambda (REQUEST) authorizer.
|
|
123
|
+
* It is `null` when the authorizer returns no context.
|
|
124
|
+
*/
|
|
125
|
+
lambda?: Record<string, unknown> | null
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface ApiGatewayRequestContextV2 {
|
|
129
|
+
accountId: string
|
|
130
|
+
apiId: string
|
|
131
|
+
authentication: null
|
|
132
|
+
authorizer: Authorizer
|
|
133
|
+
domainName: string
|
|
134
|
+
domainPrefix: string
|
|
135
|
+
http: {
|
|
136
|
+
method: string
|
|
137
|
+
path: string
|
|
138
|
+
protocol: string
|
|
139
|
+
sourceIp: string
|
|
140
|
+
userAgent: string
|
|
141
|
+
}
|
|
142
|
+
requestId: string
|
|
143
|
+
routeKey: string
|
|
144
|
+
stage: string
|
|
145
|
+
time: string
|
|
146
|
+
timeEpoch: number
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface ALBRequestContext {
|
|
150
|
+
elb: {
|
|
151
|
+
targetGroupArn: string
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface LatticeRequestContextV2 {
|
|
156
|
+
serviceNetworkArn: string
|
|
157
|
+
serviceArn: string
|
|
158
|
+
targetGroupArn: string
|
|
159
|
+
region: string
|
|
160
|
+
timeEpoch: string
|
|
161
|
+
identity: {
|
|
162
|
+
sourceVpcArn?: string
|
|
163
|
+
type?: string
|
|
164
|
+
principal?: string
|
|
165
|
+
principalOrgID?: string
|
|
166
|
+
sessionName?: string
|
|
167
|
+
x509IssuerOu?: string
|
|
168
|
+
x509SanDns?: string
|
|
169
|
+
x509SanNameCn?: string
|
|
170
|
+
x509SanUri?: string
|
|
171
|
+
x509SubjectCn?: string
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Context } from '../../index.ts'
|
|
2
|
+
import type { GetConnInfo } from '../../helper/conninfo/index.ts'
|
|
3
|
+
import { getBunServer } from './server.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get ConnInfo with Bun
|
|
7
|
+
* @param c Context
|
|
8
|
+
* @returns ConnInfo
|
|
9
|
+
*/
|
|
10
|
+
export const getConnInfo: GetConnInfo = (c: Context) => {
|
|
11
|
+
const server = getBunServer<{
|
|
12
|
+
requestIP?: (req: Request) => {
|
|
13
|
+
address: string
|
|
14
|
+
family: string
|
|
15
|
+
port: number
|
|
16
|
+
} | null
|
|
17
|
+
}>(c)
|
|
18
|
+
|
|
19
|
+
if (!server) {
|
|
20
|
+
throw new TypeError('env has to include the 2nd argument of fetch.')
|
|
21
|
+
}
|
|
22
|
+
if (typeof server.requestIP !== 'function') {
|
|
23
|
+
throw new TypeError('server.requestIP is not a function.')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// https://bun.sh/docs/runtime/http/server#server-requestip-request
|
|
27
|
+
// Returns null for closed requests or Unix domain sockets.
|
|
28
|
+
const info = server.requestIP(c.req.raw)
|
|
29
|
+
|
|
30
|
+
if (!info) {
|
|
31
|
+
return {
|
|
32
|
+
remote: {},
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
remote: {
|
|
38
|
+
address: info.address,
|
|
39
|
+
addressType: info.family === 'IPv6' || info.family === 'IPv4' ? info.family : undefined,
|
|
40
|
+
port: info.port,
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* Bun Adapter for Acryl.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { serveStatic } from './serve-static.ts'
|
|
7
|
+
export { bunFileSystemModule, toSSG } from './ssg.ts'
|
|
8
|
+
export { createBunWebSocket, upgradeWebSocket, websocket } from './websocket.ts'
|
|
9
|
+
export type { BunWebSocketData, BunWebSocketHandler } from './websocket.ts'
|
|
10
|
+
export { getConnInfo } from './conninfo.ts'
|
|
11
|
+
export { getBunServer } from './server.ts'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
|
+
import { stat } from 'node:fs/promises'
|
|
3
|
+
import { join } from 'node:path'
|
|
4
|
+
import { serveStatic as baseServeStatic } from '../../middleware/serve-static/index.ts'
|
|
5
|
+
import type { ServeStaticOptions } from '../../middleware/serve-static/index.ts'
|
|
6
|
+
import type { Env, MiddlewareHandler } from '../../types.ts'
|
|
7
|
+
|
|
8
|
+
export const serveStatic = <E extends Env = Env>(
|
|
9
|
+
options: ServeStaticOptions<E> = {}
|
|
10
|
+
): MiddlewareHandler => {
|
|
11
|
+
return async function serveStatic(c, next) {
|
|
12
|
+
const getContent = async (path: string) => {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
const file = Bun.file(path)
|
|
15
|
+
return (await file.exists()) ? file : null
|
|
16
|
+
}
|
|
17
|
+
const isDir = async (path: string) => {
|
|
18
|
+
let isDir
|
|
19
|
+
try {
|
|
20
|
+
const stats = await stat(path)
|
|
21
|
+
isDir = stats.isDirectory()
|
|
22
|
+
} catch {}
|
|
23
|
+
return isDir
|
|
24
|
+
}
|
|
25
|
+
return baseServeStatic({
|
|
26
|
+
...options,
|
|
27
|
+
getContent,
|
|
28
|
+
join,
|
|
29
|
+
isDir,
|
|
30
|
+
})(c, next)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Getting Bun Server Object for Bun adapters
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '../../context.ts'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get Bun Server Object from Context
|
|
9
|
+
* @template T - The type of Bun Server
|
|
10
|
+
* @param c Context
|
|
11
|
+
* @returns Bun Server
|
|
12
|
+
*/
|
|
13
|
+
export const getBunServer = <T>(c: Context): T | undefined =>
|
|
14
|
+
('server' in c.env ? c.env.server : c.env) as T | undefined
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
2
|
+
import { toSSG as baseToSSG } from '../../helper/ssg/index.ts'
|
|
3
|
+
import type { FileSystemModule, ToSSGAdaptorInterface } from '../../helper/ssg/index.ts'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @experimental
|
|
8
|
+
* `bunFileSystemModule` is an experimental feature.
|
|
9
|
+
* The API might be changed.
|
|
10
|
+
*/
|
|
11
|
+
export const bunFileSystemModule: FileSystemModule = {
|
|
12
|
+
writeFile: async (path, data) => {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
await Bun.write(path, data)
|
|
15
|
+
},
|
|
16
|
+
mkdir: async () => {},
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @experimental
|
|
21
|
+
* `toSSG` is an experimental feature.
|
|
22
|
+
* The API might be changed.
|
|
23
|
+
*/
|
|
24
|
+
export const toSSG: ToSSGAdaptorInterface = async (app, options) => {
|
|
25
|
+
return baseToSSG(app, bunFileSystemModule, options)
|
|
26
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { UpgradeWebSocket, WSEvents, WSMessageReceive } from '../../helper/websocket/index.ts'
|
|
2
|
+
import { createWSMessageEvent, defineWebSocketHelper, WSContext } from '../../helper/websocket/index.ts'
|
|
3
|
+
import { getBunServer } from './server.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export interface BunServerWebSocket<T> {
|
|
9
|
+
send(data: string | ArrayBuffer | Uint8Array, compress?: boolean): void
|
|
10
|
+
close(code?: number, reason?: string): void
|
|
11
|
+
data: T
|
|
12
|
+
readyState: 0 | 1 | 2 | 3
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface BunWebSocketHandler<T> {
|
|
16
|
+
open(ws: BunServerWebSocket<T>): void
|
|
17
|
+
close(ws: BunServerWebSocket<T>, code?: number, reason?: string): void
|
|
18
|
+
message(ws: BunServerWebSocket<T>, message: string | { buffer: ArrayBufferLike }): void
|
|
19
|
+
}
|
|
20
|
+
interface CreateWebSocket<T> {
|
|
21
|
+
upgradeWebSocket: UpgradeWebSocket<T>
|
|
22
|
+
websocket: BunWebSocketHandler<BunWebSocketData>
|
|
23
|
+
}
|
|
24
|
+
export interface BunWebSocketData {
|
|
25
|
+
events: WSEvents
|
|
26
|
+
url: URL
|
|
27
|
+
protocol: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export const createWSContext = (ws: BunServerWebSocket<BunWebSocketData>): WSContext => {
|
|
34
|
+
return new WSContext({
|
|
35
|
+
send: (source, options) => {
|
|
36
|
+
ws.send(source, options?.compress)
|
|
37
|
+
},
|
|
38
|
+
raw: ws,
|
|
39
|
+
readyState: ws.readyState,
|
|
40
|
+
url: ws.data.url,
|
|
41
|
+
protocol: ws.data.protocol,
|
|
42
|
+
close(code, reason) {
|
|
43
|
+
ws.close(code, reason)
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const upgradeWebSocket: UpgradeWebSocket<any> = defineWebSocketHelper((c, events) => {
|
|
49
|
+
const server = getBunServer<{
|
|
50
|
+
upgrade<T>(
|
|
51
|
+
req: Request,
|
|
52
|
+
options?: {
|
|
53
|
+
data: T
|
|
54
|
+
}
|
|
55
|
+
): boolean
|
|
56
|
+
}>(c)
|
|
57
|
+
|
|
58
|
+
if (!server) {
|
|
59
|
+
throw new TypeError('env has to include the 2nd argument of fetch.')
|
|
60
|
+
}
|
|
61
|
+
const upgradeResult = server.upgrade<BunWebSocketData>(c.req.raw, {
|
|
62
|
+
data: {
|
|
63
|
+
events,
|
|
64
|
+
url: new URL(c.req.url),
|
|
65
|
+
// The first requested subprotocol, exposed via WSContext.protocol to
|
|
66
|
+
// match the deno and cloudflare adapters.
|
|
67
|
+
protocol: c.req.header('sec-websocket-protocol')?.split(',')[0]?.trim() ?? '',
|
|
68
|
+
},
|
|
69
|
+
})
|
|
70
|
+
if (upgradeResult) {
|
|
71
|
+
return new Response(null)
|
|
72
|
+
}
|
|
73
|
+
return // failed
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
export const websocket: BunWebSocketHandler<BunWebSocketData> = {
|
|
77
|
+
open(ws) {
|
|
78
|
+
const websocketListeners = ws.data.events
|
|
79
|
+
if (websocketListeners.onOpen) {
|
|
80
|
+
websocketListeners.onOpen(new Event('open'), createWSContext(ws))
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
close(ws, code, reason) {
|
|
84
|
+
const websocketListeners = ws.data.events
|
|
85
|
+
if (websocketListeners.onClose) {
|
|
86
|
+
websocketListeners.onClose(
|
|
87
|
+
new CloseEvent('close', {
|
|
88
|
+
code,
|
|
89
|
+
reason,
|
|
90
|
+
}),
|
|
91
|
+
createWSContext(ws)
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
message(ws, message) {
|
|
96
|
+
const websocketListeners = ws.data.events
|
|
97
|
+
if (websocketListeners.onMessage) {
|
|
98
|
+
const normalizedReceiveData: WSMessageReceive =
|
|
99
|
+
typeof message === 'string' ? message : message.buffer
|
|
100
|
+
|
|
101
|
+
websocketListeners.onMessage(createWSMessageEvent(normalizedReceiveData), createWSContext(ws))
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @deprecated Import `upgradeWebSocket` and `websocket` directly from `acryl-router/bun` instead.
|
|
108
|
+
* @returns A function to create a Bun WebSocket handler.
|
|
109
|
+
*/
|
|
110
|
+
export const createBunWebSocket = <T>(): CreateWebSocket<T> => ({
|
|
111
|
+
upgradeWebSocket,
|
|
112
|
+
websocket,
|
|
113
|
+
})
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { GetConnInfo } from '../../helper/conninfo/index.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get connection information from Cloudflare Pages
|
|
5
|
+
* @param c - Context
|
|
6
|
+
* @returns Connection information including remote address
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { Acryl } from 'acrylblends'
|
|
10
|
+
* import { handle, getConnInfo } from 'acrylblends/cloudflare-pages'
|
|
11
|
+
*
|
|
12
|
+
* const app = new Acryl()
|
|
13
|
+
*
|
|
14
|
+
* app.get('/', (c) => {
|
|
15
|
+
* const info = getConnInfo(c)
|
|
16
|
+
* return c.text(`Your IP: ${info.remote.address}`)
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* export const onRequest = handle(app)
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export const getConnInfo: GetConnInfo = (c) => ({
|
|
23
|
+
remote: {
|
|
24
|
+
address: c.req.header('cf-connecting-ip'),
|
|
25
|
+
},
|
|
26
|
+
})
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Context } from '../../context.ts'
|
|
2
|
+
import type { Acryl } from '../../app.ts'
|
|
3
|
+
import { HTTPException } from '../../http-exception.ts'
|
|
4
|
+
import type { BlankSchema, Env, Input, MiddlewareHandler, Schema } from '../../types.ts'
|
|
5
|
+
|
|
6
|
+
// Ref: https://github.com/cloudflare/workerd/blob/main/types/defines/pages.d.ts
|
|
7
|
+
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
|
+
type Params<P extends string = any> = Record<P, string | string[]>
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
export type EventContext<Env = {}, P extends string = any, Data = Record<string, unknown>> = {
|
|
13
|
+
request: Request
|
|
14
|
+
functionPath: string
|
|
15
|
+
waitUntil: (promise: Promise<unknown>) => void
|
|
16
|
+
passThroughOnException: () => void
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
+
props: any
|
|
19
|
+
next: (input?: Request | string, init?: RequestInit) => Promise<Response>
|
|
20
|
+
env: Env & { ASSETS: { fetch: typeof fetch } }
|
|
21
|
+
params: Params<P>
|
|
22
|
+
data: Data
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare type PagesFunction<
|
|
26
|
+
Env = unknown,
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
Params extends string = any,
|
|
29
|
+
Data extends Record<string, unknown> = Record<string, unknown>,
|
|
30
|
+
> = (context: EventContext<Env, Params, Data>) => Response | Promise<Response>
|
|
31
|
+
|
|
32
|
+
export const handle =
|
|
33
|
+
<E extends Env = Env, S extends Schema = BlankSchema, BasePath extends string = '/'>(
|
|
34
|
+
app: Acryl<E, S, BasePath>
|
|
35
|
+
): PagesFunction<E['Bindings']> =>
|
|
36
|
+
(eventContext) => {
|
|
37
|
+
return app.fetch(
|
|
38
|
+
eventContext.request,
|
|
39
|
+
{ ...eventContext.env, eventContext },
|
|
40
|
+
{
|
|
41
|
+
waitUntil: eventContext.waitUntil,
|
|
42
|
+
passThroughOnException: eventContext.passThroughOnException,
|
|
43
|
+
props: {},
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
|
+
export function handleMiddleware<E extends Env = {}, P extends string = any, I extends Input = {}>(
|
|
50
|
+
middleware: MiddlewareHandler<
|
|
51
|
+
E & {
|
|
52
|
+
Bindings: {
|
|
53
|
+
eventContext: EventContext
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
P,
|
|
57
|
+
I
|
|
58
|
+
>
|
|
59
|
+
): PagesFunction<E['Bindings']> {
|
|
60
|
+
return async (executionCtx) => {
|
|
61
|
+
const context = new Context(executionCtx.request, {
|
|
62
|
+
env: { ...executionCtx.env, eventContext: executionCtx },
|
|
63
|
+
executionCtx,
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
let response: Response | void = undefined
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
response = await middleware(context, async () => {
|
|
70
|
+
try {
|
|
71
|
+
context.res = await executionCtx.next()
|
|
72
|
+
} catch (error) {
|
|
73
|
+
if (error instanceof Error) {
|
|
74
|
+
context.error = error
|
|
75
|
+
} else {
|
|
76
|
+
throw error
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error instanceof Error) {
|
|
82
|
+
context.error = error
|
|
83
|
+
} else {
|
|
84
|
+
throw error
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (response) {
|
|
89
|
+
return response
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (context.error instanceof HTTPException) {
|
|
93
|
+
return context.error.getResponse()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (context.error) {
|
|
97
|
+
throw context.error
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return context.res
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
declare abstract class FetcherLike {
|
|
105
|
+
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
*
|
|
110
|
+
* @description `serveStatic()` is for advanced mode:
|
|
111
|
+
* https://developers.cloudflare.com/pages/platform/functions/advanced-mode/#set-up-a-function
|
|
112
|
+
*/
|
|
113
|
+
export const serveStatic = (): MiddlewareHandler => {
|
|
114
|
+
return async (c) => {
|
|
115
|
+
const env = c.env as { ASSETS: FetcherLike }
|
|
116
|
+
const res = await env.ASSETS.fetch(c.req.raw)
|
|
117
|
+
if (res.status === 404) {
|
|
118
|
+
return c.notFound()
|
|
119
|
+
}
|
|
120
|
+
return res
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module
|
|
3
|
+
* Cloudflare Pages Adapter for Acryl.
|
|
4
|
+
*
|
|
5
|
+
* @deprecated
|
|
6
|
+
* Cloudflare recommends Workers with static assets; use `acryl` on Workers instead.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export { handle, handleMiddleware, serveStatic } from './handler.ts'
|
|
10
|
+
export { getConnInfo } from './conninfo.ts'
|
|
11
|
+
export type { EventContext } from './handler.ts'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// For ES module mode
|
|
2
|
+
import type { Env, MiddlewareHandler } from '../../types.ts'
|
|
3
|
+
import type { ServeStaticOptions } from './serve-static.ts'
|
|
4
|
+
import { serveStatic } from './serve-static.ts'
|
|
5
|
+
|
|
6
|
+
const module = <E extends Env = Env>(
|
|
7
|
+
options: Omit<ServeStaticOptions<E>, 'namespace'>
|
|
8
|
+
): MiddlewareHandler => {
|
|
9
|
+
return serveStatic<E>(options)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { module as serveStatic }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { serveStatic as baseServeStatic } from '../../middleware/serve-static/index.ts'
|
|
2
|
+
import type { ServeStaticOptions as BaseServeStaticOptions } from '../../middleware/serve-static/index.ts'
|
|
3
|
+
import type { Env, MiddlewareHandler } from '../../types.ts'
|
|
4
|
+
import { getContentFromKVAsset } from './utils.ts'
|
|
5
|
+
|
|
6
|
+
export type ServeStaticOptions<E extends Env = Env> = BaseServeStaticOptions<E> & {
|
|
7
|
+
// namespace is KVNamespace
|
|
8
|
+
namespace?: unknown
|
|
9
|
+
manifest?: object | string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated
|
|
14
|
+
* `serveStatic` in the Cloudflare Workers adapter is deprecated.
|
|
15
|
+
* You can serve static files directly using Cloudflare Static Assets.
|
|
16
|
+
* @see https://developers.cloudflare.com/workers/static-assets/
|
|
17
|
+
* Cloudflare Static Assets is currently in open beta. If this doesn't work for you,
|
|
18
|
+
* please consider using Cloudflare Pages.
|
|
19
|
+
*/
|
|
20
|
+
export const serveStatic = <E extends Env = Env>(
|
|
21
|
+
options: ServeStaticOptions<E> = {}
|
|
22
|
+
): MiddlewareHandler => {
|
|
23
|
+
return async function serveStatic(c, next) {
|
|
24
|
+
const getContent = async (path: string) => {
|
|
25
|
+
return getContentFromKVAsset(path, {
|
|
26
|
+
manifest: options.manifest,
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
namespace: options.namespace
|
|
30
|
+
? options.namespace
|
|
31
|
+
: c.env
|
|
32
|
+
? c.env.__STATIC_CONTENT
|
|
33
|
+
: undefined,
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
return baseServeStatic({
|
|
37
|
+
...options,
|
|
38
|
+
getContent,
|
|
39
|
+
})(c, next)
|
|
40
|
+
}
|
|
41
|
+
}
|