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.
Files changed (115) hide show
  1. package/dist/index.js +5 -1
  2. package/dist/index.js.map +1 -1
  3. package/docs/framework/README.md +6 -4
  4. package/docs/framework/UPSTREAM.md +1 -1
  5. package/docs/framework/getting-started/aws-lambda.md +115 -0
  6. package/docs/framework/getting-started/bun.md +1 -3
  7. package/docs/framework/getting-started/cloudflare-pages.md +53 -0
  8. package/docs/framework/getting-started/cloudflare-workers.md +67 -0
  9. package/docs/framework/getting-started/deploy.md +5 -5
  10. package/docs/framework/getting-started/lambda-edge.md +41 -0
  11. package/docs/framework/getting-started/netlify.md +25 -0
  12. package/docs/framework/getting-started/other-runtimes.md +20 -9
  13. package/docs/framework/getting-started/service-worker.md +33 -0
  14. package/docs/framework/getting-started/vercel.md +28 -0
  15. package/docs/framework/guides/create-acrylblends.md +40 -2
  16. package/docs/framework/guides/data.md +202 -0
  17. package/docs/framework/guides/faq.md +2 -2
  18. package/docs/framework/guides/forms-and-sessions.md +34 -30
  19. package/docs/framework/helpers/conninfo.md +1 -1
  20. package/docs/framework/helpers/ssg.md +1 -1
  21. package/docs/framework/helpers/streaming.md +3 -2
  22. package/docs/framework/helpers/websocket.md +2 -2
  23. package/docs/framework/middleware/builtin/ip-restriction.md +1 -1
  24. package/docs/framework/upstream.json +3 -3
  25. package/lib/aws-lambda.d.ts +324 -0
  26. package/lib/aws-lambda.js +357 -0
  27. package/lib/bun.d.ts +75 -0
  28. package/lib/bun.js +134 -0
  29. package/lib/cloudflare-pages.d.ts +58 -0
  30. package/lib/cloudflare-pages.js +78 -0
  31. package/lib/cloudflare-workers.d.ts +21 -0
  32. package/lib/cloudflare-workers.js +80 -0
  33. package/lib/db/sqlite.d.ts +27 -0
  34. package/lib/db/sqlite.js +197 -0
  35. package/lib/db.d.ts +2 -0
  36. package/lib/db.js +2 -0
  37. package/lib/index-CseujaYI.d.ts +31 -0
  38. package/lib/index-D4FAsBZu.d.ts +85 -0
  39. package/lib/index-DaJtL7ci.d.ts +156 -0
  40. package/lib/lambda-edge.d.ts +92 -0
  41. package/lib/lambda-edge.js +105 -0
  42. package/lib/netlify.d.ts +29 -0
  43. package/lib/netlify.js +30 -0
  44. package/lib/node-server/register.js +1 -1
  45. package/lib/node-server/serve-static.js +1 -1
  46. package/lib/node-server.js +3 -3
  47. package/lib/serve-static-Cp5adzGo.js +77 -0
  48. package/lib/serve-static.d.ts +1 -30
  49. package/lib/serve-static.js +1 -76
  50. package/lib/service-worker.d.ts +48 -0
  51. package/lib/service-worker.js +38 -0
  52. package/lib/src-MWcsMS8i.js +85 -0
  53. package/lib/ssg.d.ts +1 -155
  54. package/lib/vercel.d.ts +10 -0
  55. package/lib/vercel.js +9 -0
  56. package/package.json +41 -1
  57. package/plugins/acryl-db/LICENSE +47 -0
  58. package/plugins/acryl-db/plugin.json +12 -0
  59. package/plugins/acryl-db/src/cordis.ts +13 -0
  60. package/plugins/acryl-db/src/facade/database.ts +41 -0
  61. package/plugins/acryl-db/src/facade/migrations.ts +50 -0
  62. package/plugins/acryl-db/src/facade/schema.ts +9 -0
  63. package/plugins/acryl-db/src/index.ts +19 -0
  64. package/plugins/acryl-db/src/migration-files.ts +31 -0
  65. package/plugins/acryl-db/upstream.json +18 -0
  66. package/plugins/acryl-db-sqlite/LICENSE +47 -0
  67. package/plugins/acryl-db-sqlite/plugin.json +13 -0
  68. package/plugins/acryl-db-sqlite/src/facade/node.ts +199 -0
  69. package/plugins/acryl-db-sqlite/src/index.ts +88 -0
  70. package/plugins/acryl-db-sqlite/src/open.ts +61 -0
  71. package/plugins/acryl-db-sqlite/upstream.json +21 -0
  72. package/plugins/acryl-inspect/upstream.json +1 -1
  73. package/plugins/acryl-node-server/upstream.json +1 -1
  74. package/plugins/acryl-router/src/core/adapter/aws-lambda/conninfo.ts +73 -0
  75. package/plugins/acryl-router/src/core/adapter/aws-lambda/handler.ts +682 -0
  76. package/plugins/acryl-router/src/core/adapter/aws-lambda/index.ts +14 -0
  77. package/plugins/acryl-router/src/core/adapter/aws-lambda/types.ts +173 -0
  78. package/plugins/acryl-router/src/core/adapter/bun/conninfo.ts +43 -0
  79. package/plugins/acryl-router/src/core/adapter/bun/index.ts +11 -0
  80. package/plugins/acryl-router/src/core/adapter/bun/serve-static.ts +32 -0
  81. package/plugins/acryl-router/src/core/adapter/bun/server.ts +14 -0
  82. package/plugins/acryl-router/src/core/adapter/bun/ssg.ts +26 -0
  83. package/plugins/acryl-router/src/core/adapter/bun/websocket.ts +113 -0
  84. package/plugins/acryl-router/src/core/adapter/cloudflare-pages/conninfo.ts +26 -0
  85. package/plugins/acryl-router/src/core/adapter/cloudflare-pages/handler.ts +122 -0
  86. package/plugins/acryl-router/src/core/adapter/cloudflare-pages/index.ts +11 -0
  87. package/plugins/acryl-router/src/core/adapter/cloudflare-workers/conninfo.ts +7 -0
  88. package/plugins/acryl-router/src/core/adapter/cloudflare-workers/index.ts +8 -0
  89. package/plugins/acryl-router/src/core/adapter/cloudflare-workers/serve-static-module.ts +12 -0
  90. package/plugins/acryl-router/src/core/adapter/cloudflare-workers/serve-static.ts +41 -0
  91. package/plugins/acryl-router/src/core/adapter/cloudflare-workers/utils.ts +50 -0
  92. package/plugins/acryl-router/src/core/adapter/cloudflare-workers/websocket.ts +52 -0
  93. package/plugins/acryl-router/src/core/adapter/lambda-edge/conninfo.ts +15 -0
  94. package/plugins/acryl-router/src/core/adapter/lambda-edge/handler.ts +239 -0
  95. package/plugins/acryl-router/src/core/adapter/lambda-edge/index.ts +14 -0
  96. package/plugins/acryl-router/src/core/adapter/netlify/conninfo.ts +57 -0
  97. package/plugins/acryl-router/src/core/adapter/netlify/handler.ts +10 -0
  98. package/plugins/acryl-router/src/core/adapter/netlify/index.ts +6 -0
  99. package/plugins/acryl-router/src/core/adapter/netlify/mod.ts +2 -0
  100. package/plugins/acryl-router/src/core/adapter/service-worker/handler.ts +37 -0
  101. package/plugins/acryl-router/src/core/adapter/service-worker/index.ts +36 -0
  102. package/plugins/acryl-router/src/core/adapter/service-worker/types.ts +14 -0
  103. package/plugins/acryl-router/src/core/adapter/vercel/conninfo.ts +8 -0
  104. package/plugins/acryl-router/src/core/adapter/vercel/handler.ts +8 -0
  105. package/plugins/acryl-router/src/core/adapter/vercel/index.ts +7 -0
  106. package/plugins/acryl-router/upstream.json +2 -2
  107. package/plugins/acryl-router-http/upstream.json +1 -1
  108. package/plugins/acryl-state/upstream.json +1 -1
  109. package/plugins/desktop/upstream.json +1 -1
  110. package/plugins/desktop-web/main.ts +13 -3
  111. package/plugins/desktop-web/upstream.json +1 -1
  112. package/plugins/tsconfig.json +1 -0
  113. package/templates/todo/upstream.json +1 -1
  114. package/lib/{serve-static-B14MF1Va.js → serve-static-B849HlX2.js} +1 -1
  115. package/lib/{transpile-CTnWof4z.js → transpile-QUK9b3eG.js} +1 -1
@@ -0,0 +1,31 @@
1
+ import { L as MiddlewareHandler, i as Data, t as Context, v as Env } from "./context-DS3fYyG-.js";
2
+
3
+ //#region ../../plugins/acryl-router/src/core/middleware/serve-static/index.d.ts
4
+ type ServeStaticOptions<E extends Env = Env> = {
5
+ root?: string;
6
+ path?: string;
7
+ precompressed?: boolean; /** Allow percent signs in the routed request path. Defaults to false. */
8
+ allowPercentInPath?: boolean;
9
+ mimes?: Record<string, string>;
10
+ rewriteRequestPath?: (path: string) => string;
11
+ onFound?: (path: string, c: Context<E>) => void | Promise<void>;
12
+ onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
13
+ };
14
+ /**
15
+ * This middleware is not directly used by the user. Create a wrapper specifying `getContent()` by the environment such as Deno or Bun.
16
+ */
17
+ declare const serveStatic: <E extends Env = Env>(options: ServeStaticOptions<E> & {
18
+ getContent: (path: string, c: Context<E>) => Promise<Data | Response | null>;
19
+ /**
20
+ *
21
+ * `join` option according to the runtime. Example `import { join } from 'node:path`. If not specified, it will fall back to the default join function.`
22
+ */
23
+ join?: (...paths: string[]) => string;
24
+ /**
25
+ * @deprecated Currently, `pathResolve` is no longer used.
26
+ */
27
+ pathResolve?: (path: string) => string;
28
+ isDir?: (path: string) => boolean | undefined | Promise<boolean | undefined>;
29
+ }) => MiddlewareHandler;
30
+ //#endregion
31
+ export { serveStatic as n, ServeStaticOptions as t };
@@ -0,0 +1,85 @@
1
+ //#region ../../plugins/acryl-db/src/facade/database.d.ts
2
+ /** Values supported by the portable SQL drivers. */
3
+ type SqlValue = null | number | bigint | string | Uint8Array;
4
+ /**
5
+ * Asynchronous SQL operations shared by a database and its transaction handles.
6
+ *
7
+ * `exec` runs SQL text without bindings and may contain several statements. `run`, `get`, and `all`
8
+ * execute one statement with positional bindings. Adapters may cache prepared statements by SQL text,
9
+ * so callers pass values as bindings instead of interpolating them. `run` resolves the number of rows
10
+ * the statement changed.
11
+ */
12
+ interface DbExecutor {
13
+ exec(sql: string): Promise<void>;
14
+ run(sql: string, ...params: SqlValue[]): Promise<{
15
+ readonly changes: number;
16
+ }>;
17
+ get<T extends object>(sql: string, ...params: SqlValue[]): Promise<T | undefined>;
18
+ all<T extends object>(sql: string, ...params: SqlValue[]): Promise<T[]>;
19
+ }
20
+ /**
21
+ * Minimal portable SQL database facade.
22
+ *
23
+ * All operations are asynchronous so adapters may execute outside the caller's runtime.
24
+ *
25
+ * `transaction` passes the callback a transaction handle. All work in the transaction
26
+ * must use that handle; the handle is invalid after the callback settles. Adapters must
27
+ * queue unrelated operations and other transactions until the transaction finishes. The
28
+ * returned promise settles after commit or rollback. Calling the database itself (including
29
+ * `transaction`) from inside a callback therefore waits for that transaction and
30
+ * never settles.
31
+ *
32
+ * When the callback rejects, the adapter must roll the transaction back before rejecting
33
+ * with that same error. If rollback fails, it must reject with a different error (for
34
+ * example an `AggregateError`) so callers cannot mistake the callback error for a
35
+ * guaranteed rollback.
36
+ *
37
+ * Closing is the adapter's: the plugin that opened a database closes it, so the facade an
38
+ * app receives has no `close`.
39
+ */
40
+ interface Db extends DbExecutor {
41
+ transaction<T>(callback: (transaction: DbExecutor) => Promise<T>): Promise<T>;
42
+ }
43
+ //#endregion
44
+ //#region ../../plugins/acryl-db/src/facade/migrations.d.ts
45
+ type Migration = {
46
+ readonly version: number;
47
+ readonly statements: readonly string[];
48
+ };
49
+ /**
50
+ * Apply all pending migrations atomically, tracking their version in the named metadata table.
51
+ *
52
+ * The bookkeeping SQL runs unchanged on SQLite and Postgres: no `STRICT` table, `ON CONFLICT DO NOTHING`
53
+ * instead of `INSERT OR IGNORE`, and the version written as a checked integer rather than a binding,
54
+ * since the two dialects spell placeholders differently.
55
+ */
56
+ declare function applyMigrations(database: Db, migrations: readonly Migration[], options: {
57
+ readonly table: string;
58
+ }): Promise<void>;
59
+ //#endregion
60
+ //#region ../../plugins/acryl-db/src/facade/schema.d.ts
61
+ /** Validate a prefix before using it as part of a SQL identifier. */
62
+ declare function validateSchemaPrefix(prefix: string): void;
63
+ //#endregion
64
+ //#region ../../plugins/acryl-db/src/migration-files.d.ts
65
+ /**
66
+ * Read every `NNN-name.sql` file of a folder, in number order.
67
+ * @throws when a `.sql` file is not named `NNN-name.sql`, or the numbers do not run 1, 2, 3, ... without gaps or repeats.
68
+ */
69
+ declare function readMigrationFiles(folder: string | URL): Promise<Migration[]>;
70
+ //#endregion
71
+ //#region ../../plugins/acryl-db/src/index.d.ts
72
+ /**
73
+ * The `db` port: what an app's code sees of its relational database, whichever provider (`acryl-db-sqlite`, `acryl-db-postgres`) serves
74
+ * it. Plain code (an acrylblends app) opens a database with a provider's `openDb`; a Cordis plugin declares `inject: ['db']`, imports
75
+ * `acryl-db/cordis` for the `ctx.db` type, and never imports a driver.
76
+ *
77
+ * Bindings are positional `?` placeholders on every provider; a provider whose database spells them differently translates them.
78
+ * This entry imports nothing from Cordis, at runtime or in its types.
79
+ */
80
+ /** The service name every `db` provider registers. */
81
+ declare const DB_SERVICE = "db";
82
+ /** The table that records an app's migration version. */
83
+ declare const MIGRATIONS_TABLE = "_migrations";
84
+ //#endregion
85
+ export { Migration as a, DbExecutor as c, validateSchemaPrefix as i, SqlValue as l, MIGRATIONS_TABLE as n, applyMigrations as o, readMigrationFiles as r, Db as s, DB_SERVICE as t };
@@ -0,0 +1,156 @@
1
+ import { L as MiddlewareHandler, Y as Schema, t as Context, v as Env } from "./context-DS3fYyG-.js";
2
+ import { t as Acryl } from "./app-D8riatvv.js";
3
+
4
+ //#region ../../plugins/acryl-router/src/core/helper/ssg/ssg.d.ts
5
+ declare const DEFAULT_OUTPUT_DIR = "./static";
6
+ /**
7
+ * @experimental
8
+ * `FileSystemModule` is an experimental feature.
9
+ * The API might be changed.
10
+ */
11
+ interface FileSystemModule {
12
+ writeFile(path: string, data: string | Uint8Array): Promise<void>;
13
+ mkdir(path: string, options: {
14
+ recursive: boolean;
15
+ }): Promise<void | string>;
16
+ }
17
+ /**
18
+ * @experimental
19
+ * `ToSSGResult` is an experimental feature.
20
+ * The API might be changed.
21
+ */
22
+ interface ToSSGResult {
23
+ success: boolean;
24
+ files: string[];
25
+ error?: Error;
26
+ }
27
+ declare const defaultExtensionMap: Record<string, string>;
28
+ type BeforeRequestHook = (req: Request) => Request | false | Promise<Request | false>;
29
+ type AfterResponseHook = (res: Response) => Response | false | Promise<Response | false>;
30
+ type AfterGenerateHook = (result: ToSSGResult, fsModule: FileSystemModule, options?: ToSSGOptions) => void | Promise<void>;
31
+ declare const combineBeforeRequestHooks: (hooks: BeforeRequestHook | BeforeRequestHook[]) => BeforeRequestHook;
32
+ declare const combineAfterResponseHooks: (hooks: AfterResponseHook | AfterResponseHook[]) => AfterResponseHook;
33
+ declare const combineAfterGenerateHooks: (hooks: AfterGenerateHook | AfterGenerateHook[], fsModule: FileSystemModule, options?: ToSSGOptions) => AfterGenerateHook;
34
+ interface SSGPlugin {
35
+ beforeRequestHook?: BeforeRequestHook | BeforeRequestHook[];
36
+ afterResponseHook?: AfterResponseHook | AfterResponseHook[];
37
+ afterGenerateHook?: AfterGenerateHook | AfterGenerateHook[];
38
+ }
39
+ interface ToSSGOptions {
40
+ dir?: string;
41
+ /**
42
+ * @deprecated Use plugins[].beforeRequestHook instead.
43
+ */
44
+ beforeRequestHook?: BeforeRequestHook | BeforeRequestHook[];
45
+ /**
46
+ * @deprecated Use plugins[].afterResponseHook instead.
47
+ */
48
+ afterResponseHook?: AfterResponseHook | AfterResponseHook[];
49
+ /**
50
+ * @deprecated Use plugins[].afterGenerateHook instead.
51
+ */
52
+ afterGenerateHook?: AfterGenerateHook | AfterGenerateHook[];
53
+ concurrency?: number;
54
+ extensionMap?: Record<string, string>;
55
+ plugins?: SSGPlugin[];
56
+ }
57
+ /**
58
+ * @experimental
59
+ * `fetchRoutesContent` is an experimental feature.
60
+ * The API might be changed.
61
+ */
62
+ declare const fetchRoutesContent: <E extends Env = Env, S extends Schema = {}, BasePath extends string = "/">(app: Acryl<E, S, BasePath>, beforeRequestHook?: BeforeRequestHook, afterResponseHook?: AfterResponseHook, concurrency?: number) => Generator<Promise<Generator<Promise<{
63
+ routePath: string;
64
+ mimeType: string;
65
+ content: string | ArrayBuffer;
66
+ } | undefined>> | undefined>>;
67
+ declare const saveContentToFile: (data: Promise<{
68
+ routePath: string;
69
+ content: string | ArrayBuffer;
70
+ mimeType: string;
71
+ } | undefined>, fsModule: FileSystemModule, outDir: string, extensionMap?: Record<string, string>) => Promise<string | undefined>;
72
+ /**
73
+ * @experimental
74
+ * `ToSSGInterface` is an experimental feature.
75
+ * The API might be changed.
76
+ */
77
+ interface ToSSGInterface {
78
+ (app: Acryl<any, any, any>, fsModule: FileSystemModule, options?: ToSSGOptions): Promise<ToSSGResult>;
79
+ }
80
+ /**
81
+ * @experimental
82
+ * `ToSSGAdaptorInterface` is an experimental feature.
83
+ * The API might be changed.
84
+ */
85
+ interface ToSSGAdaptorInterface<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'> {
86
+ (app: Acryl<E, S, BasePath>, options?: ToSSGOptions): Promise<ToSSGResult>;
87
+ }
88
+ /**
89
+ * @experimental
90
+ * `toSSG` is an experimental feature.
91
+ * The API might be changed.
92
+ */
93
+ declare const toSSG: ToSSGInterface;
94
+ //#endregion
95
+ //#region ../../plugins/acryl-router/src/core/helper/ssg/middleware.d.ts
96
+ declare const X_ACRYL_DISABLE_SSG_HEADER_KEY = "x-acryl-disable-ssg";
97
+ interface SSGParam {
98
+ [key: string]: string;
99
+ }
100
+ type SSGParams = SSGParam[];
101
+ interface SSGParamsMiddleware {
102
+ <E extends Env = Env>(generateParams: (c: Context<E>) => SSGParams | Promise<SSGParams>): MiddlewareHandler<E>;
103
+ <E extends Env = Env>(params: SSGParams): MiddlewareHandler<E>;
104
+ }
105
+ /**
106
+ * Define SSG Route
107
+ */
108
+ declare const ssgParams: SSGParamsMiddleware;
109
+ /**
110
+ * @experimental
111
+ * `isSSGContext` is an experimental feature.
112
+ * The API might be changed.
113
+ */
114
+ declare const isSSGContext: (c: Context) => boolean;
115
+ /**
116
+ * @experimental
117
+ * `disableSSG` is an experimental feature.
118
+ * The API might be changed.
119
+ */
120
+ declare const disableSSG: () => MiddlewareHandler;
121
+ /**
122
+ * @experimental
123
+ * `onlySSG` is an experimental feature.
124
+ * The API might be changed.
125
+ */
126
+ declare const onlySSG: () => MiddlewareHandler;
127
+ //#endregion
128
+ //#region ../../plugins/acryl-router/src/core/helper/ssg/plugins.d.ts
129
+ /**
130
+ * The default plugin that defines the recommended behavior.
131
+ *
132
+ * @experimental
133
+ * `defaultPlugin` is an experimental feature.
134
+ * The API might be changed.
135
+ */
136
+ declare const defaultPlugin: () => SSGPlugin;
137
+ /**
138
+ * The redirect plugin that generates HTML redirect pages for HTTP redirect responses for status codes 301, 302, 303, 307 and 308.
139
+ *
140
+ * When used with `defaultPlugin`, place `redirectPlugin` before it, because `defaultPlugin` skips non-200 responses.
141
+ *
142
+ * ```ts
143
+ * // ✅ Will work as expected
144
+ * toSSG(app, fs, { plugins: [redirectPlugin(), defaultPlugin()] })
145
+ *
146
+ * // ❌ Will not work as expected
147
+ * toSSG(app, fs, { plugins: [defaultPlugin(), redirectPlugin()] })
148
+ * ```
149
+ *
150
+ * @experimental
151
+ * `redirectPlugin` is an experimental feature.
152
+ * The API might be changed.
153
+ */
154
+ declare const redirectPlugin: () => SSGPlugin;
155
+ //#endregion
156
+ export { saveContentToFile as C, fetchRoutesContent as S, ToSSGResult as _, isSSGContext as a, combineBeforeRequestHooks as b, AfterGenerateHook as c, DEFAULT_OUTPUT_DIR as d, FileSystemModule as f, ToSSGOptions as g, ToSSGInterface as h, disableSSG as i, AfterResponseHook as l, ToSSGAdaptorInterface as m, redirectPlugin as n, onlySSG as o, SSGPlugin as p, X_ACRYL_DISABLE_SSG_HEADER_KEY as r, ssgParams as s, defaultPlugin as t, BeforeRequestHook as u, combineAfterGenerateHooks as v, toSSG as w, defaultExtensionMap as x, combineAfterResponseHooks as y };
@@ -0,0 +1,92 @@
1
+ import { r as GetConnInfo } from "./types-Dv_nV2cv.js";
2
+ import { t as Acryl } from "./app-D8riatvv.js";
3
+
4
+ //#region ../../plugins/acryl-router/src/core/adapter/lambda-edge/handler.d.ts
5
+ interface CloudFrontHeader {
6
+ key: string;
7
+ value: string;
8
+ }
9
+ interface CloudFrontHeaders {
10
+ [name: string]: CloudFrontHeader[];
11
+ }
12
+ interface CloudFrontCustomOrigin {
13
+ customHeaders: CloudFrontHeaders;
14
+ domainName: string;
15
+ keepaliveTimeout: number;
16
+ path: string;
17
+ port: number;
18
+ protocol: string;
19
+ readTimeout: number;
20
+ sslProtocols: string[];
21
+ }
22
+ interface CloudFrontS3Origin {
23
+ authMethod: 'origin-access-identity' | 'none';
24
+ customHeaders: CloudFrontHeaders;
25
+ domainName: string;
26
+ path: string;
27
+ region: string;
28
+ }
29
+ type CloudFrontOrigin = {
30
+ s3: CloudFrontS3Origin;
31
+ custom?: never;
32
+ } | {
33
+ custom: CloudFrontCustomOrigin;
34
+ s3?: never;
35
+ };
36
+ interface CloudFrontRequest {
37
+ clientIp: string;
38
+ headers: CloudFrontHeaders;
39
+ method: string;
40
+ querystring: string;
41
+ uri: string;
42
+ body?: {
43
+ inputTruncated: boolean;
44
+ action: string;
45
+ encoding: string;
46
+ data: string;
47
+ };
48
+ origin?: CloudFrontOrigin;
49
+ }
50
+ interface CloudFrontResponse {
51
+ headers: CloudFrontHeaders;
52
+ status: string;
53
+ statusDescription?: string;
54
+ }
55
+ interface CloudFrontConfig {
56
+ distributionDomainName: string;
57
+ distributionId: string;
58
+ eventType: string;
59
+ requestId: string;
60
+ }
61
+ interface CloudFrontEvent {
62
+ cf: {
63
+ config: CloudFrontConfig;
64
+ request: CloudFrontRequest;
65
+ response?: CloudFrontResponse;
66
+ };
67
+ }
68
+ interface CloudFrontEdgeEvent {
69
+ Records: CloudFrontEvent[];
70
+ }
71
+ type CloudFrontContext = {};
72
+ interface Callback {
73
+ (err: Error | null, result?: CloudFrontRequest | CloudFrontResult): void;
74
+ }
75
+ interface CloudFrontResult {
76
+ status: string;
77
+ statusDescription?: string;
78
+ headers?: {
79
+ [header: string]: {
80
+ key: string;
81
+ value: string;
82
+ }[];
83
+ };
84
+ body?: string;
85
+ bodyEncoding?: 'text' | 'base64';
86
+ }
87
+ declare const handle: (app: Acryl<any>) => ((event: CloudFrontEdgeEvent, context?: CloudFrontContext, callback?: Callback) => Promise<CloudFrontResult | CloudFrontRequest>);
88
+ //#endregion
89
+ //#region ../../plugins/acryl-router/src/core/adapter/lambda-edge/conninfo.d.ts
90
+ declare const getConnInfo: GetConnInfo;
91
+ //#endregion
92
+ export { type Callback, type CloudFrontConfig, type CloudFrontEdgeEvent, type CloudFrontRequest, type CloudFrontResponse, getConnInfo, handle };
@@ -0,0 +1,105 @@
1
+ import { decodeBase64, encodeBase64 } from "./utils/encode.js";
2
+ import crypto from "node:crypto";
3
+ //#region ../../plugins/acryl-router/src/core/adapter/lambda-edge/handler.ts
4
+ globalThis.crypto ??= crypto;
5
+ /**
6
+ * Accepts events from 'Lambda@Edge' event
7
+ * https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html
8
+ */
9
+ const convertHeaders = (headers) => {
10
+ const cfHeaders = {};
11
+ headers.forEach((value, key) => {
12
+ cfHeaders[key.toLowerCase()] = [...cfHeaders[key.toLowerCase()] || [], {
13
+ key: key.toLowerCase(),
14
+ value
15
+ }];
16
+ });
17
+ return cfHeaders;
18
+ };
19
+ const handle = (app) => {
20
+ return async (event, ...args) => {
21
+ const [context, callback] = args;
22
+ let callbackError = null;
23
+ let callbackResult;
24
+ const cf = getCloudFrontRecord(event);
25
+ const res = await app.fetch(createRequest(cf), {
26
+ event,
27
+ context,
28
+ callback: (err, result) => {
29
+ if (!callbackError && !callbackResult) {
30
+ callbackError = err;
31
+ callbackResult = result;
32
+ }
33
+ callback?.(err, result);
34
+ },
35
+ config: cf.config,
36
+ request: cf.request,
37
+ response: cf.response
38
+ });
39
+ if (callbackError) throw callbackError;
40
+ return callbackResult ?? createResult(res);
41
+ };
42
+ };
43
+ const createResult = async (res) => {
44
+ const contentEncoding = res.headers.get("content-encoding");
45
+ const isBase64Encoded = isContentTypeBinary(res.headers.get("content-type") || "") || !!contentEncoding && !/^identity$/i.test(contentEncoding);
46
+ const body = isBase64Encoded ? encodeBase64(await res.arrayBuffer()) : await res.text();
47
+ return {
48
+ status: res.status.toString(),
49
+ headers: convertHeaders(res.headers),
50
+ body,
51
+ ...isBase64Encoded && { bodyEncoding: "base64" }
52
+ };
53
+ };
54
+ /**
55
+ * Reads the CloudFront record out of a Lambda@Edge event.
56
+ *
57
+ * The event is supplied by the runtime, so a malformed one means the function
58
+ * was invoked with something other than a Lambda@Edge event. Fail with a
59
+ * message naming the adapter and the missing field, rather than letting an
60
+ * unattributable property access error escape.
61
+ */
62
+ const getCloudFrontRecord = (event) => {
63
+ const cf = event?.Records?.[0]?.cf;
64
+ if (!cf?.request) throw new TypeError("Unable to map the CloudFront event to a Request: expected `Records[0].cf.request` in the Lambda@Edge event.");
65
+ return cf;
66
+ };
67
+ const createRequest = (cf) => {
68
+ const request = cf.request;
69
+ const queryString = request.querystring;
70
+ const urlPath = `https://${request.headers?.host?.[0]?.value || cf.config?.distributionDomainName}${request.uri}`;
71
+ const url = queryString ? `${urlPath}?${queryString}` : urlPath;
72
+ const headers = new Headers();
73
+ Object.entries(request.headers ?? {}).forEach(([k, v]) => {
74
+ v.forEach((header) => headers.append(k, header.value));
75
+ });
76
+ const requestBody = request.body;
77
+ const method = request.method;
78
+ const rawBody = createBody(method, requestBody);
79
+ let body = rawBody;
80
+ if (rawBody !== void 0) {
81
+ const bytes = typeof rawBody === "string" ? new TextEncoder().encode(rawBody) : rawBody;
82
+ body = bytes;
83
+ headers.set("content-length", bytes.length.toString());
84
+ }
85
+ return new Request(url, {
86
+ headers,
87
+ method,
88
+ body
89
+ });
90
+ };
91
+ const createBody = (method, requestBody) => {
92
+ if (!requestBody || !requestBody.data) return;
93
+ if (method === "GET" || method === "HEAD") return;
94
+ if (requestBody.encoding === "base64") return decodeBase64(requestBody.data);
95
+ return requestBody.data;
96
+ };
97
+ const isContentTypeBinary = (contentType) => {
98
+ if (/^application\/vnd\.(?:apple\.installer|mozilla\.xul)\+xml\s*(?:;|$)/i.test(contentType)) return true;
99
+ return !/^text\/(?:plain|html|css|javascript|csv)|(?:\/|\+)(?:json|xml)\s*(?:;|$)/i.test(contentType);
100
+ };
101
+ //#endregion
102
+ //#region ../../plugins/acryl-router/src/core/adapter/lambda-edge/conninfo.ts
103
+ const getConnInfo = (c) => ({ remote: { address: c.env.event.Records[0].cf.request.clientIp } });
104
+ //#endregion
105
+ export { getConnInfo, handle };
@@ -0,0 +1,29 @@
1
+ import { r as GetConnInfo } from "./types-Dv_nV2cv.js";
2
+ import { t as Acryl } from "./app-D8riatvv.js";
3
+
4
+ //#region ../../plugins/acryl-router/src/core/adapter/netlify/handler.d.ts
5
+ declare const handle: (app: Acryl<any, any>) => ((req: Request, context: any) => Response | Promise<Response>);
6
+ //#endregion
7
+ //#region ../../plugins/acryl-router/src/core/adapter/netlify/conninfo.d.ts
8
+ /**
9
+ * Get connection information from Netlify
10
+ * @param c - Context
11
+ * @returns Connection information including remote address
12
+ * @example
13
+ * ```ts
14
+ * import { Acryl } from 'acrylblends'
15
+ * import { handle, getConnInfo } from 'acrylblends/netlify'
16
+ *
17
+ * const app = new Acryl()
18
+ *
19
+ * app.get('/', (c) => {
20
+ * const info = getConnInfo(c)
21
+ * return c.text(`Your IP: ${info.remote.address}`)
22
+ * })
23
+ *
24
+ * export default handle(app)
25
+ * ```
26
+ */
27
+ declare const getConnInfo: GetConnInfo;
28
+ //#endregion
29
+ export { getConnInfo, handle };
package/lib/netlify.js ADDED
@@ -0,0 +1,30 @@
1
+ //#region ../../plugins/acryl-router/src/core/adapter/netlify/handler.ts
2
+ const handle = (app) => {
3
+ return (req, context) => {
4
+ return app.fetch(req, { context });
5
+ };
6
+ };
7
+ //#endregion
8
+ //#region ../../plugins/acryl-router/src/core/adapter/netlify/conninfo.ts
9
+ /**
10
+ * Get connection information from Netlify
11
+ * @param c - Context
12
+ * @returns Connection information including remote address
13
+ * @example
14
+ * ```ts
15
+ * import { Acryl } from 'acrylblends'
16
+ * import { handle, getConnInfo } from 'acrylblends/netlify'
17
+ *
18
+ * const app = new Acryl()
19
+ *
20
+ * app.get('/', (c) => {
21
+ * const info = getConnInfo(c)
22
+ * return c.text(`Your IP: ${info.remote.address}`)
23
+ * })
24
+ *
25
+ * export default handle(app)
26
+ * ```
27
+ */
28
+ const getConnInfo = (c) => ({ remote: { address: c.env.context?.ip } });
29
+ //#endregion
30
+ export { getConnInfo, handle };
@@ -1,4 +1,4 @@
1
- import { n as compileModule } from "../transpile-CTnWof4z.js";
1
+ import { n as compileModule } from "../transpile-QUK9b3eG.js";
2
2
  import { registerHooks } from "node:module";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
@@ -1,2 +1,2 @@
1
- import { t as serveStatic } from "../serve-static-B14MF1Va.js";
1
+ import { t as serveStatic } from "../serve-static-B849HlX2.js";
2
2
  export { serveStatic };
@@ -1,14 +1,14 @@
1
1
  import { t as Acryl } from "./app-BM0rTCp7.js";
2
2
  import { basePath } from "./route.js";
3
3
  import { defineWebSocketHelper } from "./ws.js";
4
- import { t as serveStatic } from "./serve-static-B14MF1Va.js";
4
+ import { t as serveStatic } from "./serve-static-B849HlX2.js";
5
5
  import { getConnInfo } from "./node-server/conninfo.js";
6
- import { n as compileModule, t as MissingTypeScriptError } from "./transpile-CTnWof4z.js";
6
+ import { n as compileModule, t as MissingTypeScriptError } from "./transpile-QUK9b3eG.js";
7
+ import { dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
7
8
  import { STATUS_CODES, ServerResponse, createServer } from "node:http";
8
9
  import { Http2ServerRequest, constants } from "node:http2";
9
10
  import { Readable } from "node:stream";
10
11
  import { copyFileSync, mkdirSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "node:fs";
11
- import { dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
  //#region ../../plugins/acryl-node-server/src/adapter/error.ts
14
14
  var RequestError = class extends Error {
@@ -0,0 +1,77 @@
1
+ import { tryDecodeURI } from "./utils/url.js";
2
+ import { parseAccept } from "./utils/accept.js";
3
+ import { COMPRESSIBLE_CONTENT_TYPE_REGEX } from "./utils/compress.js";
4
+ import { getMimeType } from "./utils/mime.js";
5
+ //#region ../../plugins/acryl-router/src/core/middleware/serve-static/path.ts
6
+ /**
7
+ * `defaultJoin` does not support Windows paths and always uses `/` separators.
8
+ * If you need Windows path support, please use `join` exported from `node:path` etc. instead.
9
+ */
10
+ const defaultJoin = (...paths) => {
11
+ let result = paths.filter((p) => p !== "").join("/");
12
+ result = result.replace(/(?<=\/)\/+/g, "");
13
+ const segments = result.split("/");
14
+ const resolved = [];
15
+ for (const segment of segments) if (segment === ".." && resolved.length > 0 && resolved.at(-1) !== "..") resolved.pop();
16
+ else if (segment !== ".") resolved.push(segment);
17
+ return resolved.join("/") || ".";
18
+ };
19
+ //#endregion
20
+ //#region ../../plugins/acryl-router/src/core/middleware/serve-static/index.ts
21
+ const ENCODINGS = {
22
+ br: ".br",
23
+ zstd: ".zst",
24
+ gzip: ".gz"
25
+ };
26
+ const ENCODINGS_ORDERED_KEYS = Object.keys(ENCODINGS);
27
+ const DEFAULT_DOCUMENT = "index.html";
28
+ /**
29
+ * This middleware is not directly used by the user. Create a wrapper specifying `getContent()` by the environment such as Deno or Bun.
30
+ */
31
+ const serveStatic = (options) => {
32
+ const root = options.root ?? "./";
33
+ const optionPath = options.path;
34
+ const join = options.join ?? defaultJoin;
35
+ return async (c, next) => {
36
+ if (c.finalized) return next();
37
+ if (c.req.method !== "GET" && c.req.method !== "HEAD") return next();
38
+ let filename;
39
+ if (options.path) filename = options.path;
40
+ else try {
41
+ if (!options.allowPercentInPath && c.req.path.includes("%")) throw new Error();
42
+ filename = tryDecodeURI(c.req.path);
43
+ if (/(?:^|[\/\\])\.{1,2}(?:$|[\/\\])|[\/\\]{2,}|\\/.test(filename)) throw new Error();
44
+ } catch {
45
+ await options.onNotFound?.(c.req.path, c);
46
+ return next();
47
+ }
48
+ let path = join(root, !optionPath && options.rewriteRequestPath ? options.rewriteRequestPath(filename) : filename);
49
+ if (options.isDir && await options.isDir(path)) path = join(path, DEFAULT_DOCUMENT);
50
+ const getContent = options.getContent;
51
+ let content = await getContent(path, c);
52
+ if (content instanceof Response) return c.newResponse(content.body, content);
53
+ if (content != null) {
54
+ const mimeType = options.mimes && getMimeType(path, options.mimes) || getMimeType(path);
55
+ c.header("Content-Type", mimeType || "application/octet-stream");
56
+ if (options.precompressed && (!mimeType || COMPRESSIBLE_CONTENT_TYPE_REGEX.test(mimeType))) {
57
+ const acceptEncodingSet = new Set(parseAccept(c.req.header("Accept-Encoding") ?? "").filter((encoding) => encoding.q > 0).map((encoding) => encoding.type));
58
+ for (const encoding of ENCODINGS_ORDERED_KEYS) {
59
+ if (!acceptEncodingSet.has(encoding)) continue;
60
+ const compressedContent = await getContent(path + ENCODINGS[encoding], c);
61
+ if (compressedContent) {
62
+ content = compressedContent;
63
+ c.header("Content-Encoding", encoding);
64
+ c.header("Vary", "Accept-Encoding", { append: true });
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ await options.onFound?.(path, c);
70
+ return c.body(content);
71
+ }
72
+ await options.onNotFound?.(path, c);
73
+ await next();
74
+ };
75
+ };
76
+ //#endregion
77
+ export { serveStatic as t };
@@ -1,31 +1,2 @@
1
- import { L as MiddlewareHandler, i as Data, t as Context, v as Env } from "./context-DS3fYyG-.js";
2
-
3
- //#region ../../plugins/acryl-router/src/core/middleware/serve-static/index.d.ts
4
- type ServeStaticOptions<E extends Env = Env> = {
5
- root?: string;
6
- path?: string;
7
- precompressed?: boolean; /** Allow percent signs in the routed request path. Defaults to false. */
8
- allowPercentInPath?: boolean;
9
- mimes?: Record<string, string>;
10
- rewriteRequestPath?: (path: string) => string;
11
- onFound?: (path: string, c: Context<E>) => void | Promise<void>;
12
- onNotFound?: (path: string, c: Context<E>) => void | Promise<void>;
13
- };
14
- /**
15
- * This middleware is not directly used by the user. Create a wrapper specifying `getContent()` by the environment such as Deno or Bun.
16
- */
17
- declare const serveStatic: <E extends Env = Env>(options: ServeStaticOptions<E> & {
18
- getContent: (path: string, c: Context<E>) => Promise<Data | Response | null>;
19
- /**
20
- *
21
- * `join` option according to the runtime. Example `import { join } from 'node:path`. If not specified, it will fall back to the default join function.`
22
- */
23
- join?: (...paths: string[]) => string;
24
- /**
25
- * @deprecated Currently, `pathResolve` is no longer used.
26
- */
27
- pathResolve?: (path: string) => string;
28
- isDir?: (path: string) => boolean | undefined | Promise<boolean | undefined>;
29
- }) => MiddlewareHandler;
30
- //#endregion
1
+ import { n as serveStatic, t as ServeStaticOptions } from "./index-CseujaYI.js";
31
2
  export { ServeStaticOptions, serveStatic };