@vesk/adapter 0.0.1
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 +21 -0
- package/dist/api-function.d.ts +7 -0
- package/dist/api-function.d.ts.map +1 -0
- package/dist/api-function.js +187 -0
- package/dist/client-bundle.d.ts +19 -0
- package/dist/client-bundle.d.ts.map +1 -0
- package/dist/client-bundle.js +491 -0
- package/dist/dev-server.d.ts +4 -0
- package/dist/dev-server.d.ts.map +1 -0
- package/dist/dev-server.js +358 -0
- package/dist/esbuild-fallback.d.ts +3 -0
- package/dist/esbuild-fallback.d.ts.map +1 -0
- package/dist/esbuild-fallback.js +64 -0
- package/dist/hmr.d.ts +7 -0
- package/dist/hmr.d.ts.map +1 -0
- package/dist/hmr.js +411 -0
- package/dist/image-pipeline.d.ts +3 -0
- package/dist/image-pipeline.d.ts.map +1 -0
- package/dist/image-pipeline.js +120 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +291 -0
- package/dist/manifest.d.ts +3 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +47 -0
- package/dist/middleware.d.ts +4 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +96 -0
- package/dist/package.json +15 -0
- package/dist/platform-deploy.d.ts +18 -0
- package/dist/platform-deploy.d.ts.map +1 -0
- package/dist/platform-deploy.js +354 -0
- package/dist/platform-handler.d.ts +32 -0
- package/dist/platform-handler.d.ts.map +1 -0
- package/dist/platform-handler.js +211 -0
- package/dist/platform-output.d.ts +30 -0
- package/dist/platform-output.d.ts.map +1 -0
- package/dist/platform-output.js +119 -0
- package/dist/platform.d.ts +17 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +35 -0
- package/dist/prod-server.d.ts +5 -0
- package/dist/prod-server.d.ts.map +1 -0
- package/dist/prod-server.js +429 -0
- package/dist/runtime-bundle.d.ts +2 -0
- package/dist/runtime-bundle.d.ts.map +1 -0
- package/dist/runtime-bundle.js +140 -0
- package/dist/seo-audit.d.ts +3 -0
- package/dist/seo-audit.d.ts.map +1 -0
- package/dist/seo-audit.js +169 -0
- package/dist/ssr-function.d.ts +8 -0
- package/dist/ssr-function.d.ts.map +1 -0
- package/dist/ssr-function.js +415 -0
- package/dist/static.d.ts +8 -0
- package/dist/static.d.ts.map +1 -0
- package/dist/static.js +130 -0
- package/dist/types.d.ts +182 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @vesk/adapter
|
|
2
|
+
|
|
3
|
+
Vesk adapter — builds deployable output for Deno and Node serverless platforms. Handles SSR functions, API routes, client bundling, static assets, and HMR dev server.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @vesk/adapter
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import { build, startDevServer } from '@vesk/adapter';
|
|
15
|
+
|
|
16
|
+
await build(appDir, { platform: 'node', target: 'node' });
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
MIT
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ApiRouteNode, ApiFunctionOptions } from '@vesk/adapter/src/types';
|
|
2
|
+
export declare function generateApiFunction(apiNode: ApiRouteNode, _apiDir: string, outDir: string, options?: ApiFunctionOptions): {
|
|
3
|
+
funcPath: string;
|
|
4
|
+
funcCode: string;
|
|
5
|
+
name: string;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=api-function.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-function.d.ts","sourceRoot":"","sources":["../src/api-function.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAOhF,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAuLtD"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { transformSync } from './esbuild-fallback.js';
|
|
4
|
+
function apiRouteName(fullPath) {
|
|
5
|
+
const parts = fullPath.split('/').filter(Boolean);
|
|
6
|
+
return parts.map(s => s.startsWith(':') ? s.slice(1) || 'param' : s).join('_') || 'index';
|
|
7
|
+
}
|
|
8
|
+
export function generateApiFunction(apiNode, _apiDir, outDir, options) {
|
|
9
|
+
const middlewareCode = options?.middlewareCode || null;
|
|
10
|
+
const name = apiRouteName(apiNode.fullPath);
|
|
11
|
+
const funcPath = resolve(outDir, 'server', 'api', `${name}.js`);
|
|
12
|
+
const routeFilePath = apiNode.filePath;
|
|
13
|
+
let routeSrc = readFileSync(routeFilePath, 'utf-8');
|
|
14
|
+
routeSrc = routeSrc
|
|
15
|
+
.replace(/from\s+['"]@vesk\/runtime['"]\s*;?/g, "from '../runtime.js';")
|
|
16
|
+
.replace(/from\s+['"]@vesk\/runtime\/(\w+)['"]\s*;?/g, () => {
|
|
17
|
+
return "from '../runtime.js';";
|
|
18
|
+
});
|
|
19
|
+
if (routeFilePath.endsWith('.ts')) {
|
|
20
|
+
try {
|
|
21
|
+
const result = transformSync(routeSrc, { loader: 'ts' });
|
|
22
|
+
routeSrc = result.code;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// fall back to original source if stripping fails
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const urlParts = apiNode.fullPath.split('/').filter(Boolean);
|
|
29
|
+
const extracts = [];
|
|
30
|
+
let partIdx = 0;
|
|
31
|
+
for (const p of urlParts) {
|
|
32
|
+
if (p.startsWith(':') && p.includes('...')) {
|
|
33
|
+
extracts.push(`${JSON.stringify(p.slice(1))}: urlParts.slice(${partIdx}).join('/')`);
|
|
34
|
+
}
|
|
35
|
+
else if (p.startsWith(':')) {
|
|
36
|
+
extracts.push(`${JSON.stringify(p.slice(1))}: urlParts[${partIdx}]`);
|
|
37
|
+
partIdx++;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
partIdx++;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const paramsCode = extracts.length > 0
|
|
44
|
+
? ` const params = { ${extracts.join(', ')} };\n`
|
|
45
|
+
: ' const params = {};\n';
|
|
46
|
+
const handlerMethods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']
|
|
47
|
+
.filter(m => routeSrc.includes(`async function ${m}(`) || routeSrc.includes(`async function ${m} (`) || routeSrc.includes(`export async function ${m}`))
|
|
48
|
+
.map(m => `${m}`).join(', ');
|
|
49
|
+
let handleBody;
|
|
50
|
+
if (middlewareCode) {
|
|
51
|
+
handleBody = [
|
|
52
|
+
" const url = new URL(request.url);",
|
|
53
|
+
" const urlParts = url.pathname.replace(/^\\/api\\/?/, '/').split('/').filter(Boolean);",
|
|
54
|
+
" const method = request.method || 'GET';",
|
|
55
|
+
`${paramsCode}`,
|
|
56
|
+
" Object.defineProperty(request, 'query', {",
|
|
57
|
+
' get: () => Object.fromEntries(url.searchParams.entries()),',
|
|
58
|
+
' enumerable: true,',
|
|
59
|
+
' });',
|
|
60
|
+
' // ── Middleware context ──',
|
|
61
|
+
' const __ctx = {',
|
|
62
|
+
' request,',
|
|
63
|
+
' params,',
|
|
64
|
+
' url,',
|
|
65
|
+
' locals: {},',
|
|
66
|
+
" cookies: parseCookies(request.headers.get('cookie') || ''),",
|
|
67
|
+
' set(key, value) { this.locals[key] = value; },',
|
|
68
|
+
' get(key) { return this.locals[key]; },',
|
|
69
|
+
' };',
|
|
70
|
+
' const __mwResult = await __executeMw(__ctx);',
|
|
71
|
+
' if (__mwResult.response) return __mwResult.response;',
|
|
72
|
+
" if (__mwResult.rewriteUrl) url.pathname = __mwResult.rewriteUrl;",
|
|
73
|
+
' const ctx = {',
|
|
74
|
+
" headers: Object.fromEntries(request.headers.entries()),",
|
|
75
|
+
' url: request.url,',
|
|
76
|
+
' method,',
|
|
77
|
+
' cookies: __ctx.cookies,',
|
|
78
|
+
' locals: __ctx.locals,',
|
|
79
|
+
' };',
|
|
80
|
+
" Object.defineProperty(request, 'locals', {",
|
|
81
|
+
' get: () => ctx.locals,',
|
|
82
|
+
' enumerable: true,',
|
|
83
|
+
' });',
|
|
84
|
+
' const prev = globalThis.__vesk_request;',
|
|
85
|
+
' globalThis.__vesk_request = ctx;',
|
|
86
|
+
' try {',
|
|
87
|
+
` const handler = { ${handlerMethods} }[method];`,
|
|
88
|
+
' if (!handler) {',
|
|
89
|
+
" return new Response(JSON.stringify({ error: 'Method not allowed' }), {",
|
|
90
|
+
' status: 405,',
|
|
91
|
+
" headers: { 'Content-Type': 'application/json' },",
|
|
92
|
+
' });',
|
|
93
|
+
' }',
|
|
94
|
+
' const response = await handler(request, { params: Promise.resolve(params) });',
|
|
95
|
+
' if (response instanceof Response) {',
|
|
96
|
+
" if (typeof response.build === 'function') response.build();",
|
|
97
|
+
' return response;',
|
|
98
|
+
' }',
|
|
99
|
+
' return new Response(JSON.stringify(response), {',
|
|
100
|
+
' status: 200,',
|
|
101
|
+
" headers: { 'Content-Type': 'application/json' },",
|
|
102
|
+
' });',
|
|
103
|
+
' } catch (e) {',
|
|
104
|
+
' const err = /** @type {Error & Record<string, unknown>} */(e);',
|
|
105
|
+
" if (err.name === 'Redirect') {",
|
|
106
|
+
' return new Response(null, { status: Number(err.status) || 302, headers: { Location: String(err.url || "") } });',
|
|
107
|
+
' }',
|
|
108
|
+
" if (err.name === 'NotFoundError') {",
|
|
109
|
+
" return new Response(JSON.stringify({ error: 'Not Found' }), { status: 404, headers: { 'Content-Type': 'application/json' } });",
|
|
110
|
+
' }',
|
|
111
|
+
' return new Response(JSON.stringify({ error: err.message }), { status: 500, headers: { \'Content-Type\': \'application/json\' } });',
|
|
112
|
+
' } finally {',
|
|
113
|
+
' globalThis.__vesk_request = prev;',
|
|
114
|
+
' }',
|
|
115
|
+
].join('\n');
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
handleBody = [
|
|
119
|
+
" const url = new URL(request.url);",
|
|
120
|
+
" const urlParts = url.pathname.replace(/^\\/api\\/?/, '/').split('/').filter(Boolean);",
|
|
121
|
+
" const method = request.method || 'GET';",
|
|
122
|
+
`${paramsCode}`,
|
|
123
|
+
" Object.defineProperty(request, 'query', {",
|
|
124
|
+
' get: () => Object.fromEntries(url.searchParams.entries()),',
|
|
125
|
+
' enumerable: true,',
|
|
126
|
+
' });',
|
|
127
|
+
' const ctx = {',
|
|
128
|
+
" headers: Object.fromEntries(request.headers.entries()),",
|
|
129
|
+
' url: request.url,',
|
|
130
|
+
' method,',
|
|
131
|
+
" cookies: parseCookies(request.headers.get('cookie') || ''),",
|
|
132
|
+
' locals: {},',
|
|
133
|
+
' };',
|
|
134
|
+
" Object.defineProperty(request, 'locals', {",
|
|
135
|
+
' get: () => ctx.locals,',
|
|
136
|
+
' enumerable: true,',
|
|
137
|
+
' });',
|
|
138
|
+
' const prev = globalThis.__vesk_request;',
|
|
139
|
+
' globalThis.__vesk_request = ctx;',
|
|
140
|
+
' try {',
|
|
141
|
+
` const handler = { ${handlerMethods} }[method];`,
|
|
142
|
+
' if (!handler) {',
|
|
143
|
+
" return new Response(JSON.stringify({ error: 'Method not allowed' }), {",
|
|
144
|
+
' status: 405,',
|
|
145
|
+
" headers: { 'Content-Type': 'application/json' },",
|
|
146
|
+
' });',
|
|
147
|
+
' }',
|
|
148
|
+
' const response = await handler(request, { params: Promise.resolve(params) });',
|
|
149
|
+
' if (response instanceof Response) {',
|
|
150
|
+
" if (typeof response.build === 'function') response.build();",
|
|
151
|
+
' return response;',
|
|
152
|
+
' }',
|
|
153
|
+
' return new Response(JSON.stringify(response), {',
|
|
154
|
+
' status: 200,',
|
|
155
|
+
" headers: { 'Content-Type': 'application/json' },",
|
|
156
|
+
' });',
|
|
157
|
+
' } catch (e) {',
|
|
158
|
+
' const err = /** @type {Error & Record<string, unknown>} */(e);',
|
|
159
|
+
" if (err.name === 'Redirect') {",
|
|
160
|
+
' return new Response(null, { status: Number(err.status) || 302, headers: { Location: String(err.url || "") } });',
|
|
161
|
+
' }',
|
|
162
|
+
" if (err.name === 'NotFoundError') {",
|
|
163
|
+
" return new Response(JSON.stringify({ error: 'Not Found' }), { status: 404, headers: { 'Content-Type': 'application/json' } });",
|
|
164
|
+
' }',
|
|
165
|
+
' return new Response(JSON.stringify({ error: err.message }), { status: 500, headers: { \'Content-Type\': \'application/json\' } });',
|
|
166
|
+
' } finally {',
|
|
167
|
+
' globalThis.__vesk_request = prev;',
|
|
168
|
+
' }',
|
|
169
|
+
].join('\n');
|
|
170
|
+
}
|
|
171
|
+
const funcCode = [
|
|
172
|
+
'// Auto-generated by @vesk/adapter',
|
|
173
|
+
'',
|
|
174
|
+
routeSrc.trim(),
|
|
175
|
+
'',
|
|
176
|
+
'// ── Request handler wrapper ──',
|
|
177
|
+
"import { parseCookies } from '../runtime.js';",
|
|
178
|
+
middlewareCode ? "import { parseCookies as __parseCookies } from '../runtime.js';" : '',
|
|
179
|
+
'',
|
|
180
|
+
middlewareCode || '',
|
|
181
|
+
'export async function handle(request) {',
|
|
182
|
+
handleBody,
|
|
183
|
+
'}',
|
|
184
|
+
'',
|
|
185
|
+
].filter(Boolean).join('\n');
|
|
186
|
+
return { funcPath, funcCode, name };
|
|
187
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RouteNode, ClientBundleOptions, ClientBundleResult } from '@vesk/adapter/src/types';
|
|
2
|
+
export declare function generateClientBundle(routeTree: RouteNode[], appDir: string, componentMap?: Map<string, string>, options?: ClientBundleOptions): Promise<ClientBundleResult>;
|
|
3
|
+
export declare function buildRuntimeCode(runtimeDir: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Names the client runtime actually exports, so the tree-shaken bundle only
|
|
6
|
+
* emits the modules reachable from the used set.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runtimeExportNames(runtimeDir: string): Set<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Builds a single self-contained runtime module for the given used names.
|
|
11
|
+
*
|
|
12
|
+
* The runtime's real module graph is bundled by esbuild into one IIFE whose
|
|
13
|
+
* scope is fully closed, so its internal identifiers can never collide with
|
|
14
|
+
* page code. Only the exact names the app uses are re-exported as module-scope
|
|
15
|
+
* const bindings. This replaces the old regex-based file concatenation, which
|
|
16
|
+
* leaked runtime module-scope names into the page scope.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildTreeShakenRuntime(runtimeDir: string, usedNames: string[]): Promise<string>;
|
|
19
|
+
//# sourceMappingURL=client-bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-bundle.d.ts","sourceRoot":"","sources":["../src/client-bundle.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,EAAqC,MAAM,yBAAyB,CAAC;AA2BrI,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,SAAS,EAAE,EACtB,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,kBAAkB,CAAC,CAqN7B;AAMD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA+B3D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAUlE;AAID;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BrG"}
|