@stone-js/edge-adapter 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/buildFetchHandler.d.ts +12 -0
- package/dist/declarations.d.ts +13 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +112 -0
- package/dist/serve.d.ts +52 -0
- package/package.json +92 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright © 2026 Stone Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Stone.js · Edge adapter
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@stone-js/edge-adapter)
|
|
4
|
+
[](https://github.com/stone-foundation/stone-js-framework/actions/workflows/ci.yml)
|
|
5
|
+
[](https://sonarcloud.io/summary/new_code?id=stone-foundation_stone-js-framework)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
[](https://conventionalcommits.org)
|
|
8
|
+
|
|
9
|
+
> Deploy a Stone.js app to any WinterCG/edge or JS runtime — Cloudflare Workers, Vercel Edge, Netlify Edge, Deno and Bun — with one-line serve helpers on top of @stone-js/fetch-adapter. Build once, deploy anywhere.
|
|
10
|
+
|
|
11
|
+
Part of **[Stone.js](https://stonejs.dev)**, the reference implementation of the
|
|
12
|
+
[Continuum Architecture](https://evens-stone.github.io/continuum-manifesto/manifesto): write your
|
|
13
|
+
domain once, and the context (runtime, protocol, caller) applies to it at run time.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm i @stone-js/edge-adapter
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// One Stone.js domain, every WinterCG/edge runtime. Thin helpers over @stone-js/fetch-adapter.
|
|
25
|
+
import { serveCloudflare } from '@stone-js/edge-adapter'
|
|
26
|
+
import { Application } from './Application'
|
|
27
|
+
|
|
28
|
+
// Cloudflare Workers entry point:
|
|
29
|
+
export default serveCloudflare(Application)
|
|
30
|
+
|
|
31
|
+
// Also: serveVercel, serveNetlify, serveFetch (generic WinterCG fetch handler).
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Documentation
|
|
35
|
+
|
|
36
|
+
Full documentation: **[stonejs.dev/docs/adapters/fetch](https://stonejs.dev/docs/adapters/fetch)**.
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
[MIT](https://opensource.org/licenses/MIT) © Evens Pierre ("Mr. Stone") and the Stone.js contributors.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { EdgeAppOptions, FetchHandler } from './declarations';
|
|
2
|
+
/**
|
|
3
|
+
* Boots a Stone.js app and returns its Web-standard fetch handler.
|
|
4
|
+
*
|
|
5
|
+
* This is the foundation the platform `serve*` helpers build on: it runs the real bootstrap via
|
|
6
|
+
* `StoneFactory` with the Fetch adapter forced current, yielding `(request, executionContext?)
|
|
7
|
+
* => Promise<Response>`.
|
|
8
|
+
*
|
|
9
|
+
* @param options - The modules/blueprint to boot.
|
|
10
|
+
* @returns The fetch handler.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildFetchHandler(options?: EdgeAppOptions): Promise<FetchHandler>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StoneBlueprint } from '@stone-js/core';
|
|
2
|
+
/** A Web-standard fetch handler `(request, executionContext?) => Promise<Response>`. */
|
|
3
|
+
export type FetchHandler = (request: Request, executionContext?: Record<string, unknown>) => Promise<Response>;
|
|
4
|
+
/**
|
|
5
|
+
* What to boot: the app's modules (decorated classes and/or blueprints). The Fetch adapter is
|
|
6
|
+
* forced as the current adapter, so the same app deploys to any edge/runtime target.
|
|
7
|
+
*/
|
|
8
|
+
export interface EdgeAppOptions {
|
|
9
|
+
/** App modules to boot. */
|
|
10
|
+
modules?: unknown[];
|
|
11
|
+
/** A base blueprint to merge (shorthand for one blueprint module). */
|
|
12
|
+
blueprint?: Partial<StoneBlueprint>;
|
|
13
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { StoneFactory } from '@stone-js/core';
|
|
2
|
+
import { fetchAdapterBlueprint } from '@stone-js/fetch-adapter';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A blueprint fragment that forces the Fetch adapter to be the current adapter (`current: true`
|
|
6
|
+
* wins over any real platform adapter the app declares), and sets it directly so a minimal app
|
|
7
|
+
* still resolves an adapter.
|
|
8
|
+
*
|
|
9
|
+
* @returns The forced-fetch blueprint fragment.
|
|
10
|
+
*/
|
|
11
|
+
function forcedFetchBlueprint() {
|
|
12
|
+
/* v8 ignore next -- `?? {}` is defensive: the fetch adapter always declares its adapter entry. */
|
|
13
|
+
const base = fetchAdapterBlueprint.stone.adapters?.[0] ?? {};
|
|
14
|
+
const current = { ...base, current: true, default: true };
|
|
15
|
+
return { stone: { ...fetchAdapterBlueprint.stone, adapter: current, adapters: [current] } };
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Boots a Stone.js app and returns its Web-standard fetch handler.
|
|
19
|
+
*
|
|
20
|
+
* This is the foundation the platform `serve*` helpers build on: it runs the real bootstrap via
|
|
21
|
+
* `StoneFactory` with the Fetch adapter forced current, yielding `(request, executionContext?)
|
|
22
|
+
* => Promise<Response>`.
|
|
23
|
+
*
|
|
24
|
+
* @param options - The modules/blueprint to boot.
|
|
25
|
+
* @returns The fetch handler.
|
|
26
|
+
*/
|
|
27
|
+
async function buildFetchHandler(options = {}) {
|
|
28
|
+
const modules = [
|
|
29
|
+
forcedFetchBlueprint(),
|
|
30
|
+
...(options.blueprint !== undefined ? [options.blueprint] : []),
|
|
31
|
+
...(options.modules ?? [])
|
|
32
|
+
];
|
|
33
|
+
return await StoneFactory.create({ modules }).run();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Returns a Web-standard fetch handler that boots the app lazily on the first request (so it works
|
|
38
|
+
* as a module export). This is the generic target — Vercel Edge and any WinterCG host use it as-is.
|
|
39
|
+
*
|
|
40
|
+
* @param options - The app to boot.
|
|
41
|
+
* @returns A fetch handler.
|
|
42
|
+
*/
|
|
43
|
+
function serveFetch(options = {}) {
|
|
44
|
+
let handler;
|
|
45
|
+
return async (request, executionContext) => {
|
|
46
|
+
handler = handler ?? buildFetchHandler(options);
|
|
47
|
+
return await (await handler)(request, executionContext);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Cloudflare Workers entry: `export default serveCloudflare({ modules: [App] })`.
|
|
52
|
+
* The Worker's `env`/`ctx` are forwarded to the handler's execution context.
|
|
53
|
+
*
|
|
54
|
+
* @param options - The app to boot.
|
|
55
|
+
* @returns A Cloudflare module worker with a `fetch` method.
|
|
56
|
+
*/
|
|
57
|
+
function serveCloudflare(options = {}) {
|
|
58
|
+
const handler = serveFetch(options);
|
|
59
|
+
return {
|
|
60
|
+
fetch: async (request, env, ctx) => await handler(request, { env, ctx })
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Vercel Edge Function entry: `export default serveVercel({ modules: [App] })`
|
|
65
|
+
* (add `export const config = { runtime: 'edge' }`).
|
|
66
|
+
*
|
|
67
|
+
* @param options - The app to boot.
|
|
68
|
+
* @returns A fetch handler.
|
|
69
|
+
*/
|
|
70
|
+
function serveVercel(options = {}) {
|
|
71
|
+
return serveFetch(options);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Netlify Edge Function entry: `export default serveNetlify({ modules: [App] })`.
|
|
75
|
+
* Netlify's context is forwarded to the handler's execution context.
|
|
76
|
+
*
|
|
77
|
+
* @param options - The app to boot.
|
|
78
|
+
* @returns A Netlify edge handler.
|
|
79
|
+
*/
|
|
80
|
+
function serveNetlify(options = {}) {
|
|
81
|
+
const handler = serveFetch(options);
|
|
82
|
+
return async (request, context) => await handler(request, { context });
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Bun entry: `export default serveBun({ modules: [App] })` — a `Bun.serve` compatible object.
|
|
86
|
+
*
|
|
87
|
+
* @param options - The app to boot.
|
|
88
|
+
* @param serveOptions - Extra `Bun.serve` options (e.g. `port`).
|
|
89
|
+
* @returns A Bun server object with a `fetch` method.
|
|
90
|
+
*/
|
|
91
|
+
function serveBun(options = {}, serveOptions = {}) {
|
|
92
|
+
const handler = serveFetch(options);
|
|
93
|
+
return { ...serveOptions, fetch: async (request) => await handler(request) };
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Deno entry: `serveDeno({ modules: [App] })` — starts `Deno.serve` immediately.
|
|
97
|
+
*
|
|
98
|
+
* @param options - The app to boot.
|
|
99
|
+
* @param serveOptions - Extra `Deno.serve` options (e.g. `{ port }`).
|
|
100
|
+
* @returns Whatever `Deno.serve` returns (the server).
|
|
101
|
+
* @throws {Error} When not running on Deno.
|
|
102
|
+
*/
|
|
103
|
+
function serveDeno(options = {}, serveOptions = {}) {
|
|
104
|
+
const deno = globalThis.Deno;
|
|
105
|
+
if (deno?.serve === undefined) {
|
|
106
|
+
throw new Error('serveDeno must run on the Deno runtime (`Deno.serve` was not found).');
|
|
107
|
+
}
|
|
108
|
+
const handler = serveFetch(options);
|
|
109
|
+
return deno.serve(serveOptions, async (request) => await handler(request));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { buildFetchHandler, serveBun, serveCloudflare, serveDeno, serveFetch, serveNetlify, serveVercel };
|
package/dist/serve.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { EdgeAppOptions, FetchHandler } from './declarations';
|
|
2
|
+
/**
|
|
3
|
+
* Returns a Web-standard fetch handler that boots the app lazily on the first request (so it works
|
|
4
|
+
* as a module export). This is the generic target — Vercel Edge and any WinterCG host use it as-is.
|
|
5
|
+
*
|
|
6
|
+
* @param options - The app to boot.
|
|
7
|
+
* @returns A fetch handler.
|
|
8
|
+
*/
|
|
9
|
+
export declare function serveFetch(options?: EdgeAppOptions): FetchHandler;
|
|
10
|
+
/**
|
|
11
|
+
* Cloudflare Workers entry: `export default serveCloudflare({ modules: [App] })`.
|
|
12
|
+
* The Worker's `env`/`ctx` are forwarded to the handler's execution context.
|
|
13
|
+
*
|
|
14
|
+
* @param options - The app to boot.
|
|
15
|
+
* @returns A Cloudflare module worker with a `fetch` method.
|
|
16
|
+
*/
|
|
17
|
+
export declare function serveCloudflare(options?: EdgeAppOptions): {
|
|
18
|
+
fetch: (request: Request, env?: unknown, ctx?: unknown) => Promise<Response>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Vercel Edge Function entry: `export default serveVercel({ modules: [App] })`
|
|
22
|
+
* (add `export const config = { runtime: 'edge' }`).
|
|
23
|
+
*
|
|
24
|
+
* @param options - The app to boot.
|
|
25
|
+
* @returns A fetch handler.
|
|
26
|
+
*/
|
|
27
|
+
export declare function serveVercel(options?: EdgeAppOptions): FetchHandler;
|
|
28
|
+
/**
|
|
29
|
+
* Netlify Edge Function entry: `export default serveNetlify({ modules: [App] })`.
|
|
30
|
+
* Netlify's context is forwarded to the handler's execution context.
|
|
31
|
+
*
|
|
32
|
+
* @param options - The app to boot.
|
|
33
|
+
* @returns A Netlify edge handler.
|
|
34
|
+
*/
|
|
35
|
+
export declare function serveNetlify(options?: EdgeAppOptions): (request: Request, context?: unknown) => Promise<Response>;
|
|
36
|
+
/**
|
|
37
|
+
* Bun entry: `export default serveBun({ modules: [App] })` — a `Bun.serve` compatible object.
|
|
38
|
+
*
|
|
39
|
+
* @param options - The app to boot.
|
|
40
|
+
* @param serveOptions - Extra `Bun.serve` options (e.g. `port`).
|
|
41
|
+
* @returns A Bun server object with a `fetch` method.
|
|
42
|
+
*/
|
|
43
|
+
export declare function serveBun(options?: EdgeAppOptions, serveOptions?: Record<string, unknown>): Record<string, unknown>;
|
|
44
|
+
/**
|
|
45
|
+
* Deno entry: `serveDeno({ modules: [App] })` — starts `Deno.serve` immediately.
|
|
46
|
+
*
|
|
47
|
+
* @param options - The app to boot.
|
|
48
|
+
* @param serveOptions - Extra `Deno.serve` options (e.g. `{ port }`).
|
|
49
|
+
* @returns Whatever `Deno.serve` returns (the server).
|
|
50
|
+
* @throws {Error} When not running on Deno.
|
|
51
|
+
*/
|
|
52
|
+
export declare function serveDeno(options?: EdgeAppOptions, serveOptions?: Record<string, unknown>): unknown;
|
package/package.json
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stone-js/edge-adapter",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Deploy a Stone.js app to any WinterCG/edge or JS runtime — Cloudflare Workers, Vercel Edge, Netlify Edge, Deno and Bun — with one-line serve helpers on top of @stone-js/fetch-adapter. Build once, deploy anywhere.",
|
|
5
|
+
"author": "Mr. Stone <evensstone@gmail.com>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/stone-foundation/stone-js-framework.git",
|
|
10
|
+
"directory": "stone-js-edge-adapter"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://stonejs.dev",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/stone-foundation/stone-js-framework/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"StoneJS",
|
|
18
|
+
"adapter",
|
|
19
|
+
"edge",
|
|
20
|
+
"cloudflare",
|
|
21
|
+
"vercel",
|
|
22
|
+
"netlify",
|
|
23
|
+
"deno",
|
|
24
|
+
"bun",
|
|
25
|
+
"wintercg"
|
|
26
|
+
],
|
|
27
|
+
"files": [
|
|
28
|
+
"/dist"
|
|
29
|
+
],
|
|
30
|
+
"type": "module",
|
|
31
|
+
"sideEffects": false,
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18.17.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@stone-js/core": "0.8.0",
|
|
44
|
+
"@stone-js/fetch-adapter": "0.8.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@commitlint/cli": "^19.8.1",
|
|
48
|
+
"@commitlint/config-conventional": "^19.8.1",
|
|
49
|
+
"@rollup/plugin-commonjs": "^28.0.6",
|
|
50
|
+
"@rollup/plugin-multi-entry": "^6.0.1",
|
|
51
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
52
|
+
"@rollup/plugin-typescript": "^12.1.4",
|
|
53
|
+
"@types/node": "^24.0.7",
|
|
54
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
55
|
+
"husky": "^9.1.7",
|
|
56
|
+
"rimraf": "^6.0.1",
|
|
57
|
+
"rollup": "^4.44.1",
|
|
58
|
+
"rollup-plugin-node-externals": "^8.0.1",
|
|
59
|
+
"ts-standard": "^12.0.2",
|
|
60
|
+
"tslib": "^2.8.1",
|
|
61
|
+
"typedoc": "^0.28.6",
|
|
62
|
+
"typedoc-plugin-markdown": "^4.7.0",
|
|
63
|
+
"typescript": "^5.6.3",
|
|
64
|
+
"vitest": "^3.2.4",
|
|
65
|
+
"@stone-js/core": "0.8.0",
|
|
66
|
+
"@stone-js/fetch-adapter": "0.8.0",
|
|
67
|
+
"@stone-js/http-core": "0.8.0"
|
|
68
|
+
},
|
|
69
|
+
"ts-standard": {
|
|
70
|
+
"globals": [
|
|
71
|
+
"it",
|
|
72
|
+
"test",
|
|
73
|
+
"vi",
|
|
74
|
+
"expect",
|
|
75
|
+
"describe",
|
|
76
|
+
"beforeEach"
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"lint": "ts-standard src",
|
|
81
|
+
"lint:fix": "ts-standard --fix src tests",
|
|
82
|
+
"predoc": "rimraf docs",
|
|
83
|
+
"doc": "typedoc",
|
|
84
|
+
"clean": "rimraf dist",
|
|
85
|
+
"build": "rollup -c",
|
|
86
|
+
"test": "vitest run",
|
|
87
|
+
"test:cvg": "npm run test -- --coverage",
|
|
88
|
+
"test:text": "npm run test:cvg -- --coverage.reporter=text",
|
|
89
|
+
"test:html": "npm run test:cvg -- --coverage.reporter=html",
|
|
90
|
+
"test:clover": "npm run test:cvg -- --coverage.reporter=clover"
|
|
91
|
+
}
|
|
92
|
+
}
|