@vesk/compiler 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 (84) hide show
  1. package/README.md +23 -0
  2. package/dist/acorn-ts-plugin/index.d.ts +482 -0
  3. package/dist/acorn-ts-plugin/index.d.ts.map +1 -0
  4. package/dist/acorn-ts-plugin/index.js +5028 -0
  5. package/dist/actions.d.ts +22 -0
  6. package/dist/actions.d.ts.map +1 -0
  7. package/dist/actions.js +167 -0
  8. package/dist/api-routes.d.ts +30 -0
  9. package/dist/api-routes.d.ts.map +1 -0
  10. package/dist/api-routes.js +350 -0
  11. package/dist/client-codegen.d.ts +19 -0
  12. package/dist/client-codegen.d.ts.map +1 -0
  13. package/dist/client-codegen.js +1523 -0
  14. package/dist/config.d.ts +6 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +106 -0
  17. package/dist/errors.d.ts +33 -0
  18. package/dist/errors.d.ts.map +1 -0
  19. package/dist/errors.js +210 -0
  20. package/dist/index.d.ts +16 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +8 -0
  23. package/dist/ir-generator.d.ts +10 -0
  24. package/dist/ir-generator.d.ts.map +1 -0
  25. package/dist/ir-generator.js +1062 -0
  26. package/dist/ir.d.ts +160 -0
  27. package/dist/ir.d.ts.map +1 -0
  28. package/dist/ir.js +219 -0
  29. package/dist/middleware.d.ts +15 -0
  30. package/dist/middleware.d.ts.map +1 -0
  31. package/dist/middleware.js +183 -0
  32. package/dist/package.json +15 -0
  33. package/dist/parser.d.ts +38 -0
  34. package/dist/parser.d.ts.map +1 -0
  35. package/dist/parser.js +242 -0
  36. package/dist/router.d.ts +31 -0
  37. package/dist/router.d.ts.map +1 -0
  38. package/dist/router.js +451 -0
  39. package/dist/scan.d.ts +106 -0
  40. package/dist/scan.d.ts.map +1 -0
  41. package/dist/scan.js +438 -0
  42. package/dist/server-codegen.d.ts +5 -0
  43. package/dist/server-codegen.d.ts.map +1 -0
  44. package/dist/server-codegen.js +4 -0
  45. package/dist/server-cookies.d.ts +2 -0
  46. package/dist/server-cookies.d.ts.map +1 -0
  47. package/dist/server-cookies.js +15 -0
  48. package/dist/server-head.d.ts +10 -0
  49. package/dist/server-head.d.ts.map +1 -0
  50. package/dist/server-head.js +289 -0
  51. package/dist/server-jsgen.d.ts +6 -0
  52. package/dist/server-jsgen.d.ts.map +1 -0
  53. package/dist/server-jsgen.js +446 -0
  54. package/dist/server-render.d.ts +16 -0
  55. package/dist/server-render.d.ts.map +1 -0
  56. package/dist/server-render.js +397 -0
  57. package/dist/server-utils.d.ts +93 -0
  58. package/dist/server-utils.d.ts.map +1 -0
  59. package/dist/server-utils.js +747 -0
  60. package/dist/ssr-store.d.ts +4 -0
  61. package/dist/ssr-store.d.ts.map +1 -0
  62. package/dist/ssr-store.js +29 -0
  63. package/dist/strip-ts.d.ts +25 -0
  64. package/dist/strip-ts.d.ts.map +1 -0
  65. package/dist/strip-ts.js +171 -0
  66. package/dist/tokens.d.ts +50 -0
  67. package/dist/tokens.d.ts.map +1 -0
  68. package/dist/tokens.js +334 -0
  69. package/dist/typecheck.d.ts +19 -0
  70. package/dist/typecheck.d.ts.map +1 -0
  71. package/dist/typecheck.js +365 -0
  72. package/dist/types.d.ts +147 -0
  73. package/dist/types.d.ts.map +1 -0
  74. package/dist/types.js +13 -0
  75. package/dist/vesk-plugin.d.ts +53 -0
  76. package/dist/vesk-plugin.d.ts.map +1 -0
  77. package/dist/vesk-plugin.js +413 -0
  78. package/dist/vsk-imports.d.ts +30 -0
  79. package/dist/vsk-imports.d.ts.map +1 -0
  80. package/dist/vsk-imports.js +141 -0
  81. package/dist/vsk-tsx.d.ts +3 -0
  82. package/dist/vsk-tsx.d.ts.map +1 -0
  83. package/dist/vsk-tsx.js +604 -0
  84. package/package.json +52 -0
@@ -0,0 +1,365 @@
1
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
2
+ import { join, dirname, normalize, relative, resolve, sep } from 'node:path';
3
+ import * as ts from 'typescript';
4
+ import { parse } from '@vesk/compiler/src/parser';
5
+ import { vskToTsx, generateVskDts } from '@vesk/compiler/src/vsk-tsx';
6
+ const SKIP_DIRS = new Set(['node_modules', '.vesk', '.git', 'dist', 'tarballs', '.next']);
7
+ const SKIP_FILES = new Set(['__vesk_ambient.d.ts', '__vesk_runtime_override.d.ts']);
8
+ const AMBIENT = `
9
+ declare namespace JSX {
10
+ interface IntrinsicElements {
11
+ [elemName: string]: unknown;
12
+ }
13
+ }
14
+ declare const Head: (props: { children?: unknown }) => unknown;
15
+ declare class Cell<T> {
16
+ get(): T;
17
+ set(value: T): boolean;
18
+ peek(): T;
19
+ update(fn: (current: T) => T): boolean;
20
+ unsubscribe(effect: unknown): void;
21
+ }
22
+ declare function track<T>(initialValue: T): Cell<T>;
23
+ declare function derived<T>(fn: () => T): Cell<T>;
24
+ declare function effect(fn: () => void): unknown;
25
+ declare function untrack<T>(fn: () => T): T;
26
+ declare function peek<T>(fn: () => T): T;
27
+ declare function tick(): Promise<void>;
28
+ declare function flushSync(fn: () => void): void;
29
+ declare function on_destroy(fn: () => void): void;
30
+ declare function createContext<T>(defaultValue?: T): { id: symbol; defaultValue: T | undefined };
31
+ declare function useFetch<T = unknown>(...args: unknown[]): T;
32
+ declare function useRouter(): unknown;
33
+ declare function useParams(): Record<string, string>;
34
+ declare function usePathname(): string;
35
+ declare function useSearchParams(): URLSearchParams;
36
+ declare function useNavigate(): (to: string) => void;
37
+ declare function defineAction(...args: unknown[]): unknown;
38
+ declare const Form: (props: { [k: string]: unknown; children?: unknown }) => unknown;
39
+ declare const Field: (props: { [k: string]: unknown; children?: unknown }) => unknown;
40
+ declare function required(...args: unknown[]): unknown;
41
+ declare function email(...args: unknown[]): unknown;
42
+ declare function minLength(...args: unknown[]): unknown;
43
+ declare function maxLength(...args: unknown[]): unknown;
44
+ declare function pattern(...args: unknown[]): unknown;
45
+ declare function custom(...args: unknown[]): unknown;
46
+ declare const Link: (props: { [k: string]: unknown; children?: unknown }) => unknown;
47
+ declare const NavLink: (props: { [k: string]: unknown; children?: unknown }) => unknown;
48
+ declare const Outlet: (props: { [k: string]: unknown; children?: unknown }) => unknown;
49
+ declare const Image: (props: { [k: string]: unknown; children?: unknown }) => unknown;
50
+ declare const Portal: (props: { [k: string]: unknown; children?: unknown }) => unknown;
51
+ declare const Experiment: (props: { [k: string]: unknown; children?: unknown }) => unknown;
52
+ declare const JsonLd: (props: { [k: string]: unknown; children?: unknown }) => unknown;
53
+ declare const ArticleSchema: (props: { [k: string]: unknown; children?: unknown }) => unknown;
54
+ declare const ProductSchema: (props: { [k: string]: unknown; children?: unknown }) => unknown;
55
+ declare const FAQPageSchema: (props: { [k: string]: unknown; children?: unknown }) => unknown;
56
+ declare const BreadcrumbListSchema: (props: { [k: string]: unknown; children?: unknown }) => unknown;
57
+ declare const OrganizationSchema: (props: { [k: string]: unknown; children?: unknown }) => unknown;
58
+ declare const LocalBusinessSchema: (props: { [k: string]: unknown; children?: unknown }) => unknown;
59
+ declare const VideoSchema: (props: { [k: string]: unknown; children?: unknown }) => unknown;
60
+ declare function redirect(...args: unknown[]): unknown;
61
+ declare function permanentRedirect(...args: unknown[]): unknown;
62
+ declare function notFound(...args: unknown[]): never;
63
+ declare class NotFoundError extends Error {}
64
+ declare function createResource(...args: unknown[]): unknown;
65
+ declare function getAction(...args: unknown[]): unknown;
66
+ declare function validateActionInput(...args: unknown[]): unknown;
67
+ declare function issuesToFieldMap(...args: unknown[]): unknown;
68
+ declare function isFormAction(...args: unknown[]): unknown;
69
+ `;
70
+ const RUNTIME_OVERRIDE = `
71
+ import '@vesk/runtime';
72
+ declare module '@vesk/runtime' {
73
+ export function track<T>(initialValue: T): Cell<T>;
74
+ export function derived<T>(fn: () => T): Cell<T>;
75
+ }
76
+ `;
77
+ function walkProjectFiles(projectRoot) {
78
+ const code = [];
79
+ const js = [];
80
+ const walk = (dir) => {
81
+ let entries = [];
82
+ try {
83
+ entries = readdirSync(dir);
84
+ }
85
+ catch {
86
+ return;
87
+ }
88
+ for (const e of entries) {
89
+ const p = join(dir, e);
90
+ let st;
91
+ try {
92
+ st = statSync(p);
93
+ }
94
+ catch {
95
+ continue;
96
+ }
97
+ if (st.isDirectory()) {
98
+ if (SKIP_DIRS.has(e))
99
+ continue;
100
+ walk(p);
101
+ }
102
+ else if (e.endsWith('.vsk')) {
103
+ code.push(p);
104
+ }
105
+ else if (e.endsWith('.ts') || e.endsWith('.tsx')) {
106
+ if (SKIP_FILES.has(e) || e.endsWith('.vsk.d.ts'))
107
+ continue;
108
+ code.push(p);
109
+ }
110
+ else if (e.endsWith('.js')) {
111
+ if (e.endsWith('.vsk.js'))
112
+ continue;
113
+ js.push(p);
114
+ }
115
+ }
116
+ };
117
+ walk(projectRoot);
118
+ return { code, js };
119
+ }
120
+ function isUnder(dir, file) {
121
+ const base = resolve(dir);
122
+ const abs = resolve(file);
123
+ return abs === base || abs.startsWith(base + sep);
124
+ }
125
+ function structureWarning(rel, message) {
126
+ return { file: rel, line: 1, column: 1, code: 'vesk-structure', message };
127
+ }
128
+ function checkStructureFile(appDir, file) {
129
+ const rel = relative(appDir, file);
130
+ const parts = rel.split('\\').join('/').split('/');
131
+ const name = parts[parts.length - 1] ?? '';
132
+ const isApi = parts.includes('api');
133
+ if (name === 'middleware.vsk') {
134
+ return structureWarning(rel, 'middleware must live in a TypeScript file and was skipped: rename middleware.vsk to middleware.ts.');
135
+ }
136
+ if (name === 'middleware.js') {
137
+ return structureWarning(rel, 'middleware must live in a TypeScript file: rename middleware.js to middleware.ts.');
138
+ }
139
+ if (isApi && name === 'route.vsk') {
140
+ return structureWarning(rel, 'API routes must live in a TypeScript file and was skipped: rename route.vsk to route.ts.');
141
+ }
142
+ if (isApi && name === 'route.js') {
143
+ return structureWarning(rel, 'API routes must be TypeScript (.ts): convert route.js to route.ts for typed request/response handling. Route was ignored.');
144
+ }
145
+ return null;
146
+ }
147
+ function createTypecheckHost(projectRoot, appDir, vskFiles) {
148
+ const ambientPath = join(appDir, '__vesk_ambient.d.ts');
149
+ const overridePath = join(appDir, '__vesk_runtime_override.d.ts');
150
+ const cached = new Map();
151
+ const scriptKindFor = (file) => file.endsWith('.vsk') ? ts.ScriptKind.TSX : ts.ScriptKind.TS;
152
+ const host = {
153
+ getSourceFile(file, langVersion, onError, shouldCreateNewSourceFile) {
154
+ if (!shouldCreateNewSourceFile && cached.has(file))
155
+ return cached.get(file);
156
+ let content;
157
+ if (file === ambientPath) {
158
+ content = AMBIENT;
159
+ }
160
+ else if (file === overridePath) {
161
+ content = RUNTIME_OVERRIDE;
162
+ }
163
+ else if (file.endsWith('.vsk.d.ts')) {
164
+ const vskPath = file.slice(0, -'.d.ts'.length);
165
+ const src = vskFiles.get(vskPath) ?? (ts.sys.fileExists(vskPath) ? ts.sys.readFile(vskPath) : undefined);
166
+ content = src !== undefined ? generateVskDts(src) : undefined;
167
+ }
168
+ else if (file.endsWith('.css.d.ts')) {
169
+ content = '';
170
+ }
171
+ else if (vskFiles.has(file)) {
172
+ content = vskToTsx(vskFiles.get(file));
173
+ }
174
+ else if (ts.sys.fileExists(file)) {
175
+ content = ts.sys.readFile(file);
176
+ }
177
+ if (content === undefined) {
178
+ if (onError)
179
+ onError(`File not found: ${file}`);
180
+ return undefined;
181
+ }
182
+ const sf = ts.createSourceFile(file, content, langVersion, true, scriptKindFor(file));
183
+ cached.set(file, sf);
184
+ return sf;
185
+ },
186
+ fileExists(file) {
187
+ if (file === ambientPath)
188
+ return true;
189
+ if (file === overridePath)
190
+ return true;
191
+ if (file.endsWith('.vsk.d.ts')) {
192
+ const vskPath = file.slice(0, -'.d.ts'.length);
193
+ return vskFiles.has(vskPath) || ts.sys.fileExists(vskPath);
194
+ }
195
+ if (file.endsWith('.css.d.ts'))
196
+ return true;
197
+ if (vskFiles.has(file))
198
+ return true;
199
+ return ts.sys.fileExists(file);
200
+ },
201
+ readFile(file) {
202
+ if (file === ambientPath)
203
+ return AMBIENT;
204
+ if (file === overridePath)
205
+ return RUNTIME_OVERRIDE;
206
+ if (file.endsWith('.vsk.d.ts')) {
207
+ const vskPath = file.slice(0, -'.d.ts'.length);
208
+ const src = vskFiles.get(vskPath) ?? (ts.sys.fileExists(vskPath) ? ts.sys.readFile(vskPath) : undefined);
209
+ return src !== undefined ? generateVskDts(src) : undefined;
210
+ }
211
+ if (file.endsWith('.css.d.ts'))
212
+ return '';
213
+ if (vskFiles.has(file))
214
+ return vskToTsx(vskFiles.get(file));
215
+ return ts.sys.readFile(file);
216
+ },
217
+ writeFile: () => { },
218
+ getCurrentDirectory: () => projectRoot,
219
+ getDefaultLibFileName: (o) => ts.getDefaultLibFilePath(o),
220
+ directoryExists: (dir) => ts.sys.directoryExists(dir),
221
+ getDirectories: (dir) => {
222
+ try {
223
+ return readdirSync(dir, { withFileTypes: true })
224
+ .filter((d) => d.isDirectory())
225
+ .map((d) => join(dir, d.name));
226
+ }
227
+ catch {
228
+ return [];
229
+ }
230
+ },
231
+ getCanonicalFileName: (f) => normalize(f),
232
+ useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
233
+ getNewLine: () => '\n',
234
+ resolveModuleNameLiterals(moduleLiterals, containingFile, redirectedReference, options) {
235
+ return moduleLiterals.map(({ text }) => {
236
+ if (text.endsWith('.vsk')) {
237
+ const abs = normalize(join(dirname(containingFile), text));
238
+ return {
239
+ resolvedModule: {
240
+ resolvedFileName: abs + '.d.ts',
241
+ extension: ts.Extension.Dts,
242
+ isExternalLibraryImport: false,
243
+ },
244
+ failedLookupLocations: [],
245
+ };
246
+ }
247
+ if (text.endsWith('.css')) {
248
+ const abs = normalize(join(dirname(containingFile), text));
249
+ return {
250
+ resolvedModule: {
251
+ resolvedFileName: abs + '.d.ts',
252
+ extension: ts.Extension.Dts,
253
+ isExternalLibraryImport: false,
254
+ },
255
+ failedLookupLocations: [],
256
+ };
257
+ }
258
+ const res = ts.resolveModuleName(text, containingFile, options, host);
259
+ return { resolvedModule: res.resolvedModule, failedLookupLocations: [] };
260
+ });
261
+ },
262
+ };
263
+ return host;
264
+ }
265
+ export function typecheckProject(projectRoot, opts = {}) {
266
+ const appDir = opts.appDir ?? join(projectRoot, 'app');
267
+ const vskFiles = new Map();
268
+ const parseErrors = [];
269
+ const warnings = [];
270
+ const walked = walkProjectFiles(projectRoot);
271
+ const rootNames = [];
272
+ for (const f of walked.js) {
273
+ if (!isUnder(appDir, f))
274
+ continue;
275
+ const warn = checkStructureFile(appDir, f);
276
+ if (warn)
277
+ warnings.push(warn);
278
+ }
279
+ for (const f of walked.code) {
280
+ if (isUnder(appDir, f)) {
281
+ const warn = checkStructureFile(appDir, f);
282
+ if (warn) {
283
+ warnings.push(warn);
284
+ continue;
285
+ }
286
+ }
287
+ if (f.endsWith('.vsk')) {
288
+ const src = readFileSync(f, 'utf-8');
289
+ try {
290
+ parse(src);
291
+ }
292
+ catch (e) {
293
+ parseErrors.push({
294
+ file: relative(projectRoot, f),
295
+ line: 1,
296
+ column: 1,
297
+ code: 'vesk-parse',
298
+ message: `could not parse .vsk file: ${e.message}`,
299
+ });
300
+ continue;
301
+ }
302
+ vskFiles.set(f, src);
303
+ }
304
+ rootNames.push(f);
305
+ }
306
+ const ambientPath = join(appDir, '__vesk_ambient.d.ts');
307
+ const overridePath = join(appDir, '__vesk_runtime_override.d.ts');
308
+ rootNames.push(ambientPath);
309
+ rootNames.push(overridePath);
310
+ const options = {
311
+ target: ts.ScriptTarget.ES2022,
312
+ module: ts.ModuleKind.ESNext,
313
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
314
+ strict: opts.strict !== false,
315
+ jsx: ts.JsxEmit.Preserve,
316
+ noEmit: true,
317
+ skipLibCheck: true,
318
+ esModuleInterop: true,
319
+ allowSyntheticDefaultImports: true,
320
+ allowImportingTsExtensions: true,
321
+ allowNonTsExtensions: true,
322
+ resolveJsonModule: true,
323
+ lib: ['lib.es2022.d.ts', 'lib.dom.d.ts', 'lib.dom.iterable.d.ts'],
324
+ types: [],
325
+ allowJs: false,
326
+ };
327
+ const host = createTypecheckHost(projectRoot, appDir, vskFiles);
328
+ const program = ts.createProgram({ rootNames, options, host });
329
+ const rootSet = new Set(rootNames.map(normalize));
330
+ const vskSet = new Set();
331
+ for (const p of vskFiles.keys())
332
+ vskSet.add(normalize(p));
333
+ const errors = [...parseErrors];
334
+ for (const diag of ts.getPreEmitDiagnostics(program)) {
335
+ const file = diag.file;
336
+ if (!file)
337
+ continue;
338
+ let filePath = normalize(file.fileName);
339
+ if (filePath.endsWith('.vsk.d.ts')) {
340
+ filePath = filePath.slice(0, -'.d.ts'.length);
341
+ }
342
+ if (!rootSet.has(filePath) && !vskSet.has(filePath))
343
+ continue;
344
+ const pos = file.getLineAndCharacterOfPosition(diag.start ?? 0);
345
+ const code = typeof diag.code === 'number' ? `TS${diag.code}` : String(diag.code);
346
+ errors.push({
347
+ file: relative(projectRoot, filePath),
348
+ line: pos.line + 1,
349
+ column: pos.character + 1,
350
+ code,
351
+ message: ts.flattenDiagnosticMessageText(diag.messageText, '\n'),
352
+ });
353
+ }
354
+ return { errors, warnings };
355
+ }
356
+ export function formatTypecheckErrors(errors) {
357
+ return errors
358
+ .map((e) => `${e.file}(${e.line},${e.column}): ${e.code}: ${e.message}`)
359
+ .join('\n');
360
+ }
361
+ export function formatTypecheckWarnings(warnings) {
362
+ return warnings
363
+ .map((w) => `${w.file}: ${w.code}: ${w.message}`)
364
+ .join('\n');
365
+ }
@@ -0,0 +1,147 @@
1
+ import type { IRRoot } from '@vesk/compiler/src/ir';
2
+ export interface RouteNode {
3
+ path: string;
4
+ fullPath: string;
5
+ isGroup: boolean;
6
+ isDynamic: boolean;
7
+ isCatchAll: boolean;
8
+ page: string | null;
9
+ layout: string | null;
10
+ loading: string | null;
11
+ error: string | null;
12
+ notFound: string | null;
13
+ hasMiddleware: boolean;
14
+ children: RouteNode[];
15
+ sourceDir: string;
16
+ segmentCount: number;
17
+ }
18
+ export interface ApiRouteNode {
19
+ path: string;
20
+ fullPath: string;
21
+ isDynamic: boolean;
22
+ isCatchAll: boolean;
23
+ filePath: string | null;
24
+ children: ApiRouteNode[];
25
+ }
26
+ export interface MiddlewareContext {
27
+ request: Request;
28
+ params: Record<string, string>;
29
+ url: URL;
30
+ locals: Record<string, unknown>;
31
+ cookies: Record<string, string>;
32
+ set(key: string, value: unknown): void;
33
+ get(key: string): unknown;
34
+ [key: string]: unknown;
35
+ }
36
+ export interface VeskPlugin {
37
+ name: string;
38
+ provides?: Record<string, (() => unknown | Promise<unknown>) | unknown>;
39
+ onRequest?: (ctx: MiddlewareContext) => void | Promise<void>;
40
+ onCSS?: (content: string, filePath: string) => string | null | Promise<string | null>;
41
+ onFileWatch?: (filePath: string) => {
42
+ handled: boolean;
43
+ } | Promise<{
44
+ handled: boolean;
45
+ }>;
46
+ onTransformJS?: (code: string, filePath: string) => string | null | Promise<string | null>;
47
+ onBuildStart?: () => void | Promise<void>;
48
+ onBuildEnd?: () => void | Promise<void>;
49
+ }
50
+ export interface VeskCors {
51
+ origin: string | string[];
52
+ methods?: string;
53
+ headers?: string;
54
+ credentials?: boolean;
55
+ maxAge?: number;
56
+ }
57
+ export interface VeskRateLimit {
58
+ windowMs?: number;
59
+ max?: number;
60
+ }
61
+ export type VeskSecurityPreset = 'strict' | 'default' | 'minimal' | 'off';
62
+ export interface VeskSecurity {
63
+ xFrameOptions?: string | false;
64
+ hsts?: string | false;
65
+ referrerPolicy?: string | false;
66
+ contentSecurityPolicy?: boolean | string;
67
+ autoEscape?: boolean;
68
+ csrf?: boolean;
69
+ cors?: VeskCors;
70
+ trustProxy?: boolean | string;
71
+ rateLimit?: VeskRateLimit;
72
+ redactLogs?: boolean;
73
+ }
74
+ export interface VeskConfig {
75
+ appDir?: string;
76
+ outDir?: string;
77
+ publicDir?: string;
78
+ ssg?: {
79
+ getStaticPaths?: () => Promise<{
80
+ paths: Array<{
81
+ params: Record<string, string>;
82
+ }>;
83
+ }>;
84
+ };
85
+ plugins?: VeskPlugin[];
86
+ security?: VeskSecurity | VeskSecurityPreset | false | ((preset: (name: string, overrides?: VeskSecurity) => VeskSecurity) => VeskSecurity);
87
+ /** Client router route-data freshness TTL in milliseconds. The SPA router
88
+ * refetches a route's server data when it is older than this. Default 0 =
89
+ * always fetch fresh data on every SPA visit. */
90
+ routeDataCache?: number;
91
+ }
92
+ export interface MiddlewareEntry {
93
+ sourcePath: string;
94
+ node: RouteNode;
95
+ }
96
+ export interface MiddlewareChainOptions {
97
+ onLast?: (rewriteUrl: string | null) => Response | Promise<Response>;
98
+ plugins?: VeskPlugin[];
99
+ }
100
+ export interface CompileFileResult {
101
+ ir: IRRoot;
102
+ componentMap: Map<string, Function>;
103
+ __vesk: Record<string, unknown>;
104
+ }
105
+ export interface RenderPageResult {
106
+ body: string;
107
+ head: string;
108
+ props: Record<string, unknown>;
109
+ }
110
+ export interface SSGResult {
111
+ html: string;
112
+ body: string;
113
+ head: string;
114
+ props: string;
115
+ clientCode: string;
116
+ static: boolean;
117
+ staticLists: boolean;
118
+ }
119
+ export interface DataScriptPayload {
120
+ props?: Record<string, unknown>;
121
+ ssrData?: Record<string, unknown>;
122
+ }
123
+ /**
124
+ * When provided, hydration data (serialized props + useFetch SSR data) is
125
+ * served as an external classic script (`<script src="...">`) instead of an
126
+ * inline `<script>globalThis.__vsk_ssr_data = ...</script>`. Inline data
127
+ * scripts are blocked by strict Content-Security-Policy headers
128
+ * (`script-src 'self'` without `'unsafe-inline'`), so servers must deliver
129
+ * the payload through an origin-served file. The callback stores the payload
130
+ * server-side and returns the script src URL (or null to fall back to inline).
131
+ */
132
+ export type ExternalDataScript = (payload: DataScriptPayload) => string | null;
133
+ export interface FullPageOptions {
134
+ cssUrl?: string;
135
+ cssUrls?: string[];
136
+ clientScriptUrl?: string;
137
+ pageHead?: string;
138
+ security?: VeskSecurity;
139
+ __vesk?: Record<string, unknown>;
140
+ hydrate?: boolean;
141
+ sourcePath?: string;
142
+ externalDataScript?: ExternalDataScript;
143
+ cached?: CompileFileResult;
144
+ }
145
+ export declare const VESK_BUILTINS: readonly ["useFetch", "useRouter", "useParams", "usePathname", "useSearchParams", "useNavigate", "useHead", "useTitle", "Form", "Field", "Link", "NavLink", "Outlet", "Image", "Portal", "Experiment", "defineAction", "required", "email", "minLength", "maxLength", "pattern", "custom", "track", "get", "set", "derived", "effect", "batch", "untrack", "cookies", "headers", "locals", "VeskResponse", "VeskRequest", "ServerRequest", "ServerResponse", "redirect", "permanentRedirect", "notFound"];
146
+ export type VeskBuiltin = typeof VESK_BUILTINS[number];
147
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ export const VESK_BUILTINS = [
2
+ 'useFetch', 'useRouter', 'useParams', 'usePathname', 'useSearchParams',
3
+ 'useNavigate', 'useHead', 'useTitle',
4
+ 'Form', 'Field', 'Link', 'NavLink', 'Outlet',
5
+ 'Image', 'Portal',
6
+ 'Experiment',
7
+ 'defineAction',
8
+ 'required', 'email', 'minLength', 'maxLength', 'pattern', 'custom',
9
+ 'track', 'get', 'set', 'derived', 'effect', 'batch', 'untrack',
10
+ 'cookies', 'headers', 'locals',
11
+ 'VeskResponse', 'VeskRequest', 'ServerRequest', 'ServerResponse',
12
+ 'redirect', 'permanentRedirect', 'notFound',
13
+ ];
@@ -0,0 +1,53 @@
1
+ import * as acorn from 'acorn';
2
+ declare module 'acorn' {
3
+ interface Parser {
4
+ pos: number;
5
+ start: number;
6
+ end: number;
7
+ type: any;
8
+ value: any;
9
+ exprAllowed: boolean;
10
+ inType: boolean;
11
+ curContext(): any;
12
+ readToken(code: number): any;
13
+ isLet(context: any): boolean;
14
+ parseBindingAtom(): any;
15
+ parseExpression(noIn: boolean, refDestructuringErrors: any): any;
16
+ parseStatement(context: any, ...args: any[]): any;
17
+ parseBlock(createNewLexicalScope?: boolean, node?: any, exitStrict?: boolean): any;
18
+ startNode(): any;
19
+ finishNode(node: any, type: string): any;
20
+ finishToken(type: any, value?: any): any;
21
+ expect(token: any): void;
22
+ enterScope(flags: number): void;
23
+ exitScope(): void;
24
+ semicolon(): void;
25
+ raise(pos: number, message: string): void;
26
+ next(): void;
27
+ eat(token: any): boolean;
28
+ jsx_parseElementAt(startPos: number, startLoc?: any): any;
29
+ jsx_parseElement(): any;
30
+ jsx_parseExpressionContainer(): any;
31
+ jsx_parseClosingElementAt(pos: number, loc: any): any;
32
+ jsx_parseElementName(): any;
33
+ parseIdent(allowBinding?: boolean): any;
34
+ parseFunctionParams(node: any): void;
35
+ parseExprAtom(): any;
36
+ isContextual(name: string): boolean;
37
+ startLoc: any;
38
+ endLoc: any;
39
+ lastTokEnd: number;
40
+ lastTokStart: number;
41
+ lastTokEndLoc: any;
42
+ lastTokStartLoc: any;
43
+ curLine: number;
44
+ lineStart: number;
45
+ startNodeAt(pos: number, loc?: any): any;
46
+ checkUnreserved(ref: any): any;
47
+ }
48
+ }
49
+ export interface VeskPluginConfig {
50
+ [key: string]: unknown;
51
+ }
52
+ export declare function VeskParserPlugin(config?: VeskPluginConfig): (Parser: typeof acorn.Parser) => typeof acorn.Parser;
53
+ //# sourceMappingURL=vesk-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vesk-plugin.d.ts","sourceRoot":"","sources":["../src/vesk-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,QAAQ,OAAO,CAAC;IACrB,UAAU,MAAM;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,GAAG,CAAC;QACV,KAAK,EAAE,GAAG,CAAC;QACX,WAAW,EAAE,OAAO,CAAC;QACrB,MAAM,EAAE,OAAO,CAAC;QAChB,UAAU,IAAI,GAAG,CAAC;QAClB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC;QAC7B,KAAK,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC;QAC7B,gBAAgB,IAAI,GAAG,CAAC;QACxB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,sBAAsB,EAAE,GAAG,GAAG,GAAG,CAAC;QACjE,cAAc,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;QAClD,UAAU,CAAC,qBAAqB,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,EAAE,OAAO,GAAG,GAAG,CAAC;QACnF,SAAS,IAAI,GAAG,CAAC;QACjB,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC;QACzC,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;QACzC,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;QACzB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,SAAS,IAAI,IAAI,CAAC;QAClB,SAAS,IAAI,IAAI,CAAC;QAClB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1C,IAAI,IAAI,IAAI,CAAC;QACb,GAAG,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC;QACzB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;QAC1D,gBAAgB,IAAI,GAAG,CAAC;QACxB,4BAA4B,IAAI,GAAG,CAAC;QACpC,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC;QACtD,oBAAoB,IAAI,GAAG,CAAC;QAC5B,UAAU,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,GAAG,CAAC;QACxC,mBAAmB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC;QACrC,aAAa,IAAI,GAAG,CAAC;QACrB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QACpC,QAAQ,EAAE,GAAG,CAAC;QACd,MAAM,EAAE,GAAG,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,GAAG,CAAC;QACnB,eAAe,EAAE,GAAG,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;QACzC,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC;KAChC;CACF;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA2BD,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,gBAAqB,IACpD,QAAQ,OAAO,KAAK,CAAC,MAAM,KAAG,OAAO,KAAK,CAAC,MAAM,CAka1D"}