@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.
Files changed (60) hide show
  1. package/README.md +21 -0
  2. package/dist/api-function.d.ts +7 -0
  3. package/dist/api-function.d.ts.map +1 -0
  4. package/dist/api-function.js +187 -0
  5. package/dist/client-bundle.d.ts +19 -0
  6. package/dist/client-bundle.d.ts.map +1 -0
  7. package/dist/client-bundle.js +491 -0
  8. package/dist/dev-server.d.ts +4 -0
  9. package/dist/dev-server.d.ts.map +1 -0
  10. package/dist/dev-server.js +358 -0
  11. package/dist/esbuild-fallback.d.ts +3 -0
  12. package/dist/esbuild-fallback.d.ts.map +1 -0
  13. package/dist/esbuild-fallback.js +64 -0
  14. package/dist/hmr.d.ts +7 -0
  15. package/dist/hmr.d.ts.map +1 -0
  16. package/dist/hmr.js +411 -0
  17. package/dist/image-pipeline.d.ts +3 -0
  18. package/dist/image-pipeline.d.ts.map +1 -0
  19. package/dist/image-pipeline.js +120 -0
  20. package/dist/index.d.ts +4 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +291 -0
  23. package/dist/manifest.d.ts +3 -0
  24. package/dist/manifest.d.ts.map +1 -0
  25. package/dist/manifest.js +47 -0
  26. package/dist/middleware.d.ts +4 -0
  27. package/dist/middleware.d.ts.map +1 -0
  28. package/dist/middleware.js +96 -0
  29. package/dist/package.json +15 -0
  30. package/dist/platform-deploy.d.ts +18 -0
  31. package/dist/platform-deploy.d.ts.map +1 -0
  32. package/dist/platform-deploy.js +354 -0
  33. package/dist/platform-handler.d.ts +32 -0
  34. package/dist/platform-handler.d.ts.map +1 -0
  35. package/dist/platform-handler.js +211 -0
  36. package/dist/platform-output.d.ts +30 -0
  37. package/dist/platform-output.d.ts.map +1 -0
  38. package/dist/platform-output.js +119 -0
  39. package/dist/platform.d.ts +17 -0
  40. package/dist/platform.d.ts.map +1 -0
  41. package/dist/platform.js +35 -0
  42. package/dist/prod-server.d.ts +5 -0
  43. package/dist/prod-server.d.ts.map +1 -0
  44. package/dist/prod-server.js +429 -0
  45. package/dist/runtime-bundle.d.ts +2 -0
  46. package/dist/runtime-bundle.d.ts.map +1 -0
  47. package/dist/runtime-bundle.js +140 -0
  48. package/dist/seo-audit.d.ts +3 -0
  49. package/dist/seo-audit.d.ts.map +1 -0
  50. package/dist/seo-audit.js +169 -0
  51. package/dist/ssr-function.d.ts +8 -0
  52. package/dist/ssr-function.d.ts.map +1 -0
  53. package/dist/ssr-function.js +415 -0
  54. package/dist/static.d.ts +8 -0
  55. package/dist/static.d.ts.map +1 -0
  56. package/dist/static.js +130 -0
  57. package/dist/types.d.ts +182 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +1 -0
  60. 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"}