@vesk/compiler 0.1.14 → 0.2.8

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 (42) hide show
  1. package/dist/api-routes.d.ts +6 -1
  2. package/dist/api-routes.d.ts.map +1 -1
  3. package/dist/api-routes.js +52 -7
  4. package/dist/client-codegen.d.ts +15 -0
  5. package/dist/client-codegen.d.ts.map +1 -1
  6. package/dist/client-codegen.js +73 -10
  7. package/dist/config.d.ts +2 -0
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +25 -0
  10. package/dist/errors.d.ts.map +1 -1
  11. package/dist/errors.js +33 -4
  12. package/dist/ir-generator.d.ts.map +1 -1
  13. package/dist/ir-generator.js +109 -1
  14. package/dist/md-inline.d.ts +17 -0
  15. package/dist/md-inline.d.ts.map +1 -0
  16. package/dist/md-inline.js +149 -0
  17. package/dist/middleware.d.ts.map +1 -1
  18. package/dist/middleware.js +42 -7
  19. package/dist/router.d.ts +2 -0
  20. package/dist/router.d.ts.map +1 -1
  21. package/dist/router.js +48 -3
  22. package/dist/server-codegen.d.ts +1 -1
  23. package/dist/server-codegen.d.ts.map +1 -1
  24. package/dist/server-codegen.js +1 -1
  25. package/dist/server-jsgen.js +1 -1
  26. package/dist/server-render.d.ts.map +1 -1
  27. package/dist/server-render.js +14 -8
  28. package/dist/server-utils.d.ts +31 -0
  29. package/dist/server-utils.d.ts.map +1 -1
  30. package/dist/server-utils.js +478 -52
  31. package/dist/typecheck.d.ts +2 -2
  32. package/dist/typecheck.d.ts.map +1 -1
  33. package/dist/typecheck.js +66 -27
  34. package/dist/types.d.ts +4 -129
  35. package/dist/types.d.ts.map +1 -1
  36. package/dist/types.js +1 -0
  37. package/dist/vesk-plugin.d.ts +2 -0
  38. package/dist/vesk-plugin.d.ts.map +1 -1
  39. package/dist/vesk-plugin.js +152 -0
  40. package/dist/vsk-tsx.d.ts.map +1 -1
  41. package/dist/vsk-tsx.js +15 -5
  42. package/package.json +2 -1
@@ -0,0 +1,149 @@
1
+ import { readFileSync, existsSync } from 'node:fs';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ // =============================================================
4
+ // Inline resolution of <Md content="path/to/file.md"> attributes.
5
+ //
6
+ // When a `content="..."` attribute on an <Md> element is a static string
7
+ // ending in .md/.markdown, the file is read at COMPILE time and inlined
8
+ // into the source as a module-level const, so SSR, client chunks, SSG and
9
+ // production all work without runtime filesystem access.
10
+ //
11
+ // Resolution order for the specifier:
12
+ // - './x.md' / '../x.md' → relative to the importing .vsk file
13
+ // - '/x.md' → candidate roots (project dir / public),
14
+ // tried as <root>/public/x.md then <root>/x.md
15
+ // =============================================================
16
+ const MD_EXT_MARKER = '.md';
17
+ function looksLikeMarkdownPath(value) {
18
+ const v = value.trim();
19
+ if (v.length === 0 || v.length > 4096)
20
+ return false;
21
+ if (v.includes('\n') || v.includes('\r'))
22
+ return false;
23
+ const lower = v.toLowerCase();
24
+ return lower.endsWith(MD_EXT_MARKER) || lower.endsWith('.markdown');
25
+ }
26
+ function isRelativeSpecifier(v) {
27
+ return v.startsWith('./') || v.startsWith('../');
28
+ }
29
+ /** Walks up from `start` looking for the first directory containing `marker`. */
30
+ function findUp(start, marker) {
31
+ let cur = start;
32
+ for (let i = 0; i < 32; i++) {
33
+ if (existsSync(join(cur, marker)))
34
+ return cur;
35
+ const parent = dirname(cur);
36
+ if (parent === cur)
37
+ return null;
38
+ cur = parent;
39
+ }
40
+ return null;
41
+ }
42
+ /**
43
+ * Rewrites static `content="<file>.md"` attributes on <Md> elements into
44
+ * inlined constants. Returns the transformed source; when nothing matches,
45
+ * the original string is returned untouched.
46
+ *
47
+ * `mdRoots` are candidate project roots for absolute-style specifiers
48
+ * ("/x.md"); each root is tried as <root>/public<x> and <root><x>.
49
+ */
50
+ export function inlineMdContentAttrs(source, importerDir, mdRoots = []) {
51
+ if (!source.includes('content=') && !source.includes('content ='))
52
+ return source;
53
+ if (!importerDir && mdRoots.length === 0)
54
+ return source;
55
+ let out = '';
56
+ let i = 0;
57
+ const n = source.length;
58
+ let counter = 0;
59
+ const decls = [];
60
+ const prefix = 'content=';
61
+ while (i < n) {
62
+ if (source.startsWith(prefix, i)) {
63
+ // attribute position: ensure this is a JSX-ish attribute (preceded by whitespace/start)
64
+ const prev = i > 0 ? source[i - 1] : ' ';
65
+ if (prev === ' ' || prev === '\t' || prev === '\n' || prev === '\r') {
66
+ let j = i + prefix.length;
67
+ const quote = source[j];
68
+ if (quote === '"' || quote === "'") {
69
+ j++;
70
+ const valStart = j;
71
+ while (j < n && source[j] !== quote)
72
+ j++;
73
+ if (j < n) {
74
+ const value = source.slice(valStart, j);
75
+ if (looksLikeMarkdownPath(value)) {
76
+ const abs = resolveMdPath(value, importerDir, mdRoots);
77
+ if (abs !== null) {
78
+ let contents;
79
+ try {
80
+ contents = readFileSync(abs, 'utf-8');
81
+ }
82
+ catch {
83
+ out += source[i];
84
+ i++;
85
+ continue;
86
+ }
87
+ const varName = `__vesk_md_${counter++}`;
88
+ decls.push(`const ${varName} = ${JSON.stringify(contents)};`);
89
+ out += `${prefix}{${varName}}`;
90
+ i = j + 1;
91
+ continue;
92
+ }
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ out += source[i];
99
+ i++;
100
+ }
101
+ if (decls.length === 0)
102
+ return source;
103
+ return decls.join('\n') + '\n' + out;
104
+ }
105
+ function resolveMdPath(specifier, importerDir, roots) {
106
+ const spec = specifier.trim();
107
+ if (isRelativeSpecifier(spec)) {
108
+ if (!importerDir)
109
+ return null;
110
+ const abs = resolve(importerDir, spec);
111
+ return existsSync(abs) ? abs : null;
112
+ }
113
+ if (spec.startsWith('/')) {
114
+ for (const root of roots) {
115
+ const pub = join(root, 'public', spec);
116
+ if (existsSync(pub))
117
+ return pub;
118
+ const direct = join(root, spec);
119
+ if (existsSync(direct))
120
+ return direct;
121
+ }
122
+ }
123
+ return null;
124
+ }
125
+ /**
126
+ * Candidate project roots for absolute-style specifiers: walks up from
127
+ * `dir` collecting directories that contain a package.json (bounded).
128
+ */
129
+ export function guessProjectRoots(dir) {
130
+ if (!dir)
131
+ return [];
132
+ const roots = [];
133
+ let cur = dir;
134
+ for (let i = 0; i < 6; i++) {
135
+ roots.push(cur);
136
+ if (existsSync(join(cur, 'package.json')))
137
+ break;
138
+ const parent = dirname(cur);
139
+ if (parent === cur)
140
+ break;
141
+ cur = parent;
142
+ }
143
+ return roots;
144
+ }
145
+ /** Convenience wrapper used by pipelines that already know the file dir. */
146
+ export function inlineMdImportsFrom(source, importerFile, mdRoots = []) {
147
+ const dir = importerFile ? dirname(importerFile) : null;
148
+ return inlineMdContentAttrs(source, dir, mdRoots.length > 0 ? mdRoots : [dir || process.cwd()]);
149
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAiC,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEtG,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE,CAsE7G;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAevG;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,eAAe,EAAE,EACxB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC;IAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAoGzH"}
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAiC,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEtG,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,EAAE,CAsE7G;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,CAiBvG;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,eAAe,EAAE,EACxB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC;IAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAkIzH"}
@@ -75,7 +75,9 @@ export async function loadMiddleware(sourcePath) {
75
75
  }
76
76
  if (sourcePath.endsWith('.js') || sourcePath.endsWith('.ts')) {
77
77
  try {
78
- const mod = await import(sourcePath);
78
+ const url = new URL('file://' + sourcePath);
79
+ url.searchParams.set('t', String(Date.now()) + Math.random().toString(36).slice(2));
80
+ const mod = await import(url.href);
79
81
  return (mod.middleware || mod.default || null);
80
82
  }
81
83
  catch {
@@ -132,21 +134,37 @@ export async function executeMiddlewareChain(chain, request, params, options = {
132
134
  }
133
135
  let rewriteUrl = null;
134
136
  if (chain.length === 0) {
137
+ if (onLast) {
138
+ const prev = globalThis.__vesk_request;
139
+ globalThis.__vesk_request = ctx;
140
+ try {
141
+ const loneResponse = await onLast(rewriteUrl, ctx);
142
+ return { response: loneResponse ?? null, redirected: !!loneResponse && loneResponse.status >= 300 && loneResponse.status < 400, locals, rewriteUrl };
143
+ }
144
+ finally {
145
+ globalThis.__vesk_request = prev;
146
+ }
147
+ }
135
148
  return { response: null, redirected: false, locals, rewriteUrl: null };
136
149
  }
137
150
  async function runMiddleware(index) {
138
151
  if (index >= chain.length) {
139
152
  if (onLast) {
140
- return onLast(rewriteUrl);
153
+ return onLast(rewriteUrl, ctx);
141
154
  }
142
- return new Response(null, { status: 204 });
155
+ return null;
143
156
  }
144
157
  const { sourcePath } = chain[index];
145
158
  const fn = await loadMiddleware(sourcePath);
146
159
  if (!fn) {
147
160
  return runMiddleware(index + 1);
148
161
  }
162
+ let nextCalled = false;
163
+ let nextResult = null;
149
164
  async function next(rewrite) {
165
+ if (nextCalled)
166
+ return null;
167
+ nextCalled = true;
150
168
  if (rewrite) {
151
169
  rewriteUrl = rewrite;
152
170
  try {
@@ -158,14 +176,21 @@ export async function executeMiddlewareChain(chain, request, params, options = {
158
176
  ctx.url = new URL(rewrite, base.origin);
159
177
  }
160
178
  }
161
- return runMiddleware(index + 1);
179
+ nextResult = await runMiddleware(index + 1);
180
+ return nextResult;
162
181
  }
163
182
  try {
164
183
  const result = await fn(ctx, next);
165
184
  if (result instanceof Response) {
166
185
  return result;
167
186
  }
168
- return new Response(null, { status: 204 });
187
+ if (nextResult !== null && nextResult instanceof Response) {
188
+ return nextResult;
189
+ }
190
+ if (!nextCalled) {
191
+ return runMiddleware(index + 1);
192
+ }
193
+ return null;
169
194
  }
170
195
  catch (e) {
171
196
  const err = e;
@@ -178,6 +203,16 @@ export async function executeMiddlewareChain(chain, request, params, options = {
178
203
  throw e;
179
204
  }
180
205
  }
181
- const response = await runMiddleware(0);
182
- return { response, redirected: response?.status >= 300 && response?.status < 400, locals, rewriteUrl };
206
+ // Ensure the outermost ctx is available as __vesk_request during the chain,
207
+ // so that server locals / onLast rendering sees middleware locals.
208
+ const prevOuter = globalThis.__vesk_request;
209
+ globalThis.__vesk_request = ctx;
210
+ let response;
211
+ try {
212
+ response = await runMiddleware(0);
213
+ }
214
+ finally {
215
+ globalThis.__vesk_request = prevOuter;
216
+ }
217
+ return { response, redirected: !!response && response.status >= 300 && response.status < 400, locals, rewriteUrl };
183
218
  }
package/dist/router.d.ts CHANGED
@@ -15,6 +15,8 @@ export interface MatchResult {
15
15
  * handled correctly; falls back to the old regex + brace balance when the
16
16
  * source does not parse.
17
17
  */
18
+ /** Collapses runs of `/` into single slashes (no regex). */
19
+ export declare function collapseSlashes(p: string): string;
18
20
  export declare function extractMiddlewareParts(src: string): {
19
21
  params: string;
20
22
  body: string;
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAM1D,MAAM,WAAW,WAAW;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsB3F;AAkDD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUnE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,SAAS,EAAE,CAKjF;AAMD,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA2BzE;AAmHD,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAcrE;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAgCnG;AAkBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAiFhF"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAM1D,MAAM,WAAW,WAAW;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;GAMG;AACH,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB3F;AAkDD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAUnE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,SAAS,EAAE,CAKjF;AAMD,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA2BzE;AA2HD,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgBrE;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAkCnG;AAoBD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAiFhF"}
package/dist/router.js CHANGED
@@ -11,6 +11,23 @@ import { hasTsSyntax, stripCodeTypes } from '@vesk/compiler/src/strip-ts';
11
11
  * handled correctly; falls back to the old regex + brace balance when the
12
12
  * source does not parse.
13
13
  */
14
+ /** Collapses runs of `/` into single slashes (no regex). */
15
+ export function collapseSlashes(p) {
16
+ let out = '';
17
+ let prevSlash = false;
18
+ for (const c of p) {
19
+ if (c === '/') {
20
+ if (!prevSlash)
21
+ out += '/';
22
+ prevSlash = true;
23
+ }
24
+ else {
25
+ out += c;
26
+ prevSlash = false;
27
+ }
28
+ }
29
+ return out;
30
+ }
14
31
  export function extractMiddlewareParts(src) {
15
32
  try {
16
33
  let ast = parse(src, { filename: 'middleware.ts' });
@@ -180,6 +197,8 @@ function scanDirectory(rootDir, dir, parentPath, options) {
180
197
  let hasLoading = false;
181
198
  let hasError = false;
182
199
  let hasNotFound = false;
200
+ let hasOffline = false;
201
+ let hasNetwork = false;
183
202
  let hasMiddleware = false;
184
203
  for (const entry of entries) {
185
204
  if (entry === 'layout.vsk') {
@@ -202,6 +221,14 @@ function scanDirectory(rootDir, dir, parentPath, options) {
202
221
  hasNotFound = true;
203
222
  continue;
204
223
  }
224
+ if (entry === 'offline.vsk') {
225
+ hasOffline = true;
226
+ continue;
227
+ }
228
+ if (entry === 'network.vsk') {
229
+ hasNetwork = true;
230
+ continue;
231
+ }
205
232
  if (entry === 'middleware.ts') {
206
233
  hasMiddleware = true;
207
234
  continue;
@@ -235,7 +262,7 @@ function scanDirectory(rootDir, dir, parentPath, options) {
235
262
  : (parentPath || '/');
236
263
  const node = {
237
264
  path: seg,
238
- fullPath: fullPath.replace(/\/+/g, '/') || '/',
265
+ fullPath: collapseSlashes(fullPath) || '/',
239
266
  isGroup,
240
267
  isDynamic,
241
268
  isCatchAll,
@@ -244,6 +271,8 @@ function scanDirectory(rootDir, dir, parentPath, options) {
244
271
  loading: hasLoading ? extractComponentName(dir, 'loading', rootDir) : null,
245
272
  error: hasError ? extractComponentName(dir, 'error', rootDir) : null,
246
273
  notFound: hasNotFound ? extractComponentName(dir, 'not-found', rootDir) : null,
274
+ offline: hasOffline ? extractComponentName(dir, 'offline', rootDir) : null,
275
+ network: hasNetwork ? extractComponentName(dir, 'network', rootDir) : null,
247
276
  hasMiddleware,
248
277
  children: [],
249
278
  sourceDir: dir,
@@ -292,6 +321,10 @@ function extractComponentName(dir, type, rootDir) {
292
321
  return 'Error_' + capitalized;
293
322
  if (type === 'not-found')
294
323
  return 'NotFound_' + capitalized;
324
+ if (type === 'offline')
325
+ return 'Offline_' + capitalized;
326
+ if (type === 'network')
327
+ return 'Network_' + capitalized;
295
328
  return type + '_' + capitalized;
296
329
  }
297
330
  export function collectSources(tree) {
@@ -308,6 +341,10 @@ export function collectSources(tree) {
308
341
  map.set(node.error, join(node.sourceDir, 'error.vsk'));
309
342
  if (node.notFound)
310
343
  map.set(node.notFound, join(node.sourceDir, 'not-found.vsk'));
344
+ if (node.offline)
345
+ map.set(node.offline, join(node.sourceDir, 'offline.vsk'));
346
+ if (node.network)
347
+ map.set(node.network, join(node.sourceDir, 'network.vsk'));
311
348
  walk(node.children);
312
349
  }
313
350
  }
@@ -328,9 +365,13 @@ export function generateRouteManifest(tree, options = {}) {
328
365
  parts.push(`error: ${node.error}`);
329
366
  if (node.notFound)
330
367
  parts.push(`notFound: ${node.notFound}`);
368
+ if (node.offline)
369
+ parts.push(`offline: ${node.offline}`);
370
+ if (node.network)
371
+ parts.push(`network: ${node.network}`);
331
372
  if (node.children.length > 0) {
332
- const childCodes = node.children.map(c => genNode(c));
333
- parts.push(`children: [\n${childCodes.map(c => '\t\t' + c).join(',\n')}\n\t]`);
373
+ const childCodes = node.children.map((c) => genNode(c));
374
+ parts.push(`children: [\n${childCodes.map((c) => '\t\t' + c).join(',\n')}\n\t]`);
334
375
  }
335
376
  const pathStr = JSON.stringify(node.fullPath);
336
377
  const groupStr = node.isGroup ? `, isGroup: true` : '';
@@ -363,6 +404,10 @@ function flattenSources(tree) {
363
404
  map.set(node.error, node.sourceDir + '/error.vsk');
364
405
  if (node.notFound)
365
406
  map.set(node.notFound, node.sourceDir + '/not-found.vsk');
407
+ if (node.offline)
408
+ map.set(node.offline, node.sourceDir + '/offline.vsk');
409
+ if (node.network)
410
+ map.set(node.network, node.sourceDir + '/network.vsk');
366
411
  walk(node.children);
367
412
  }
368
413
  }
@@ -1,4 +1,4 @@
1
- export { setRuntimeModule, prettifyHtml, isStatic, escapeHtml, raw, exprJS, tryEvalExpr, childrenToHTML, extractTopLevelNames, extractRuntimeNames, buildParamInit, resolveComponentName, loadRuntimeImports, evalTopLevelCode, callStaticProps, callLoadFunction, __vskHydrate, __vskId, __vskImportedNames, resetVskState, setVskHydrate, setVskImportedNames, securityHeaders, corsHeaders, corsPreflight, csrfToken, verifyCsrfToken, csrfGuard, signCookie, unsignCookie, setSignedCookie, readSignedCookie, securityComment, redactLog, setRedactLogging, createRateLimiter, getClientIp, getClientProtocol, applyTrustProxy, } from '@vesk/compiler/src/server-utils';
1
+ export { setRuntimeModule, prettifyHtml, isStatic, escapeHtml, quoteAttr, safeJsonForScript, randomToken, DEFAULT_MAX_BODY_BYTES, raw, exprJS, tryEvalExpr, childrenToHTML, extractTopLevelNames, extractRuntimeNames, buildParamInit, resolveComponentName, loadRuntimeImports, evalTopLevelCode, callStaticProps, callLoadFunction, __vskHydrate, __vskId, __vskImportedNames, resetVskState, setVskHydrate, setVskImportedNames, securityHeaders, corsHeaders, corsPreflight, csrfToken, verifyCsrfToken, csrfGuard, csrfHmac, assertSameOrigin, signCookie, unsignCookie, setSignedCookie, readSignedCookie, securityComment, redactLog, setRedactLogging, createRateLimiter, getClientIp, getClientProtocol, applyTrustProxy, } from '@vesk/compiler/src/server-utils';
2
2
  export { renderHeadHtml, mergeHeadHtml, } from '@vesk/compiler/src/server-head';
3
3
  export { irNodeToJS, generateFunctionBody, buildComponentMap, } from '@vesk/compiler/src/server-jsgen';
4
4
  export { compileFile, render, renderPage, ssg, renderFullPage, renderPageStream, buildDataScripts, } from '@vesk/compiler/src/server-render';
@@ -1 +1 @@
1
- {"version":3,"file":"server-codegen.d.ts","sourceRoot":"","sources":["../src/server-codegen.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,GAAG,EACH,MAAM,EACN,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,aAAa,EACb,SAAS,EACT,eAAe,EACf,SAAS,EACT,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,GAChB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,cAAc,EACd,aAAa,GACd,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,WAAW,EACX,MAAM,EACN,UAAU,EACV,GAAG,EACH,cAAc,EACd,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"server-codegen.d.ts","sourceRoot":"","sources":["../src/server-codegen.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,WAAW,EACX,sBAAsB,EACtB,GAAG,EACH,MAAM,EACN,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,aAAa,EACb,SAAS,EACT,eAAe,EACf,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,GAChB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,cAAc,EACd,aAAa,GACd,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,WAAW,EACX,MAAM,EACN,UAAU,EACV,GAAG,EACH,cAAc,EACd,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC"}
@@ -1,4 +1,4 @@
1
- export { setRuntimeModule, prettifyHtml, isStatic, escapeHtml, raw, exprJS, tryEvalExpr, childrenToHTML, extractTopLevelNames, extractRuntimeNames, buildParamInit, resolveComponentName, loadRuntimeImports, evalTopLevelCode, callStaticProps, callLoadFunction, __vskHydrate, __vskId, __vskImportedNames, resetVskState, setVskHydrate, setVskImportedNames, securityHeaders, corsHeaders, corsPreflight, csrfToken, verifyCsrfToken, csrfGuard, signCookie, unsignCookie, setSignedCookie, readSignedCookie, securityComment, redactLog, setRedactLogging, createRateLimiter, getClientIp, getClientProtocol, applyTrustProxy, } from '@vesk/compiler/src/server-utils';
1
+ export { setRuntimeModule, prettifyHtml, isStatic, escapeHtml, quoteAttr, safeJsonForScript, randomToken, DEFAULT_MAX_BODY_BYTES, raw, exprJS, tryEvalExpr, childrenToHTML, extractTopLevelNames, extractRuntimeNames, buildParamInit, resolveComponentName, loadRuntimeImports, evalTopLevelCode, callStaticProps, callLoadFunction, __vskHydrate, __vskId, __vskImportedNames, resetVskState, setVskHydrate, setVskImportedNames, securityHeaders, corsHeaders, corsPreflight, csrfToken, verifyCsrfToken, csrfGuard, csrfHmac, assertSameOrigin, signCookie, unsignCookie, setSignedCookie, readSignedCookie, securityComment, redactLog, setRedactLogging, createRateLimiter, getClientIp, getClientProtocol, applyTrustProxy, } from '@vesk/compiler/src/server-utils';
2
2
  export { renderHeadHtml, mergeHeadHtml, } from '@vesk/compiler/src/server-head';
3
3
  export { irNodeToJS, generateFunctionBody, buildComponentMap, } from '@vesk/compiler/src/server-jsgen';
4
4
  export { compileFile, render, renderPage, ssg, renderFullPage, renderPageStream, buildDataScripts, } from '@vesk/compiler/src/server-render';
@@ -378,7 +378,7 @@ export function generateFunctionBody(comp, importedNames) {
378
378
  lines.push(`const __prev = __ga();`);
379
379
  lines.push(`__sa({ c: null, p: __prev });`);
380
380
  lines.push(`try {`);
381
- lines.push(`const __escape = (s) => String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/\x22/g,'&quot;');`);
381
+ lines.push(`const __escape = (s) => { s = String(s); return s.split('&').join('&amp;').split('<').join('&lt;').split('>').join('&gt;').split(${JSON.stringify('"')}).join('&quot;'); };`);
382
382
  lines.push(`const raw = (s) => s == null ? '' : String(s);`);
383
383
  lines.push(`const __tk = globalThis.__vsk_ssr_token || '';`);
384
384
  if (asyncMode) {
@@ -1 +1 @@
1
- {"version":3,"file":"server-render.d.ts","sourceRoot":"","sources":["../src/server-render.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAqB,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAcvJ,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,CAEhG;AA0BD,wBAAgB,MAAM,CACpB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC1B;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiE9C;AAcD,wBAAsB,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAO,GAC9G,OAAO,CAAC,SAAS,CAAC,CA8DpB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACpD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,GACnC,MAAM,EAAE,CAuBV;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAoEjB;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAAC,MAAM,CAAC,CAkFxB"}
1
+ {"version":3,"file":"server-render.d.ts","sourceRoot":"","sources":["../src/server-render.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAqB,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAgBvJ,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,CAEhG;AA8BD,wBAAgB,MAAM,CACpB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC1B;AAED,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACpC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiE9C;AAcD,wBAAsB,GAAG,CACvB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAO,GAC9G,OAAO,CAAC,SAAS,CAAC,CA8DpB;AAED,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACpD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,GACnC,MAAM,EAAE,CAuBV;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAoEjB;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACnC,QAAQ,GAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAa,EAC3C,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAAC,MAAM,CAAC,CAkFxB"}
@@ -1,18 +1,24 @@
1
1
  import { readFileSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
2
3
  import { MapRegion } from '@vesk/compiler/src/ir';
3
4
  import { parse } from '@vesk/compiler/src/parser';
4
5
  import { generateIR } from '@vesk/compiler/src/ir-generator';
5
6
  import { compileClient, isStaticIR } from '@vesk/compiler/src/client-codegen';
6
- import { isStatic, prettifyHtml, resetVskState, loadRuntimeImports, evalTopLevelCode, callStaticProps, callLoadFunction, } from '@vesk/compiler/src/server-utils';
7
+ import { isStatic, prettifyHtml, resetVskState, loadRuntimeImports, evalTopLevelCode, callStaticProps, callLoadFunction, safeJsonForScript, quoteAttr, } from '@vesk/compiler/src/server-utils';
7
8
  import { renderHeadHtml, mergeHeadHtml } from '@vesk/compiler/src/server-head';
8
9
  import { buildComponentMap } from '@vesk/compiler/src/server-jsgen';
9
10
  import { transformTopLevelForActions } from '@vesk/compiler/src/actions';
10
11
  import { collectVskImportPaths } from '@vesk/compiler/src/vsk-imports';
12
+ import { inlineMdImportsFrom, guessProjectRoots } from '@vesk/compiler/src/md-inline';
11
13
  import { withSsrStore, ssrSink } from '@vesk/compiler/src/ssr-store';
12
14
  export function compileFile(source, options) {
13
15
  return compileFileInternal(source, options?.sourcePath, new Set());
14
16
  }
15
17
  function compileFileInternal(source, sourcePath, seenImportFiles) {
18
+ if (sourcePath) {
19
+ const dir = dirname(sourcePath);
20
+ source = inlineMdImportsFrom(source, sourcePath, guessProjectRoots(dir));
21
+ }
16
22
  const ast = parse(source);
17
23
  const ir = generateIR(ast, source);
18
24
  const componentMap = buildComponentMap(ir, true);
@@ -190,7 +196,7 @@ export async function ssg(source, componentName, customProps, options = {}) {
190
196
  const clientCode = needsClient
191
197
  ? compileClient(source, null, { hydrate: true })
192
198
  : '';
193
- const serializedProps = JSON.stringify(props);
199
+ const serializedProps = safeJsonForScript(JSON.stringify(props));
194
200
  const hasClient = clientCode.length > 0;
195
201
  const scriptBlock = hasClient
196
202
  ? `\n<script>const __vesk_props = ${serializedProps};\n<\/script>\n<script>${clientCode}</script>\n`
@@ -240,9 +246,9 @@ export function buildDataScripts(ssrProps, ssrData, external) {
240
246
  }
241
247
  const scripts = [];
242
248
  if (hasProps)
243
- scripts.push(`\t<script>const __vesk_props = ${JSON.stringify(payload.props)};</script>`);
249
+ scripts.push(`\t<script>const __vesk_props = ${safeJsonForScript(JSON.stringify(payload.props))};</script>`);
244
250
  if (hasData)
245
- scripts.push(`\t<script>globalThis.__vsk_ssr_data = ${JSON.stringify(ssrData)};</script>`);
251
+ scripts.push(`\t<script>globalThis.__vsk_ssr_data = ${safeJsonForScript(JSON.stringify(ssrData))};</script>`);
246
252
  return scripts;
247
253
  }
248
254
  export async function renderFullPage(source, componentName, props = {}, registry = new Map(), options = {}) {
@@ -293,9 +299,9 @@ export async function renderFullPage(source, componentName, props = {}, registry
293
299
  if (options.security) {
294
300
  const sec = options.security;
295
301
  if (sec.referrerPolicy !== false)
296
- headLines.push(`\t<meta name="referrer" content="${sec.referrerPolicy || 'strict-origin-when-cross-origin'}" />`);
302
+ headLines.push(`\t<meta name="referrer" content="${quoteAttr(sec.referrerPolicy || 'strict-origin-when-cross-origin')}" />`);
297
303
  if (sec.contentSecurityPolicy !== false)
298
- headLines.push(`\t<meta http-equiv="Content-Security-Policy" content="${(sec.contentSecurityPolicy || "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'").replace(/"/g, '&quot;')}" />`);
304
+ headLines.push(`\t<meta http-equiv="Content-Security-Policy" content="${quoteAttr(sec.contentSecurityPolicy || "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'")}" />`);
299
305
  if (sec.autoEscape !== false)
300
306
  headLines.push(`\t<!-- vesk: auto-escape enabled -->`);
301
307
  }
@@ -348,9 +354,9 @@ export function renderPageStream(source, componentName, props = {}, registry = n
348
354
  if (options.security) {
349
355
  const sec = options.security;
350
356
  if (sec.referrerPolicy !== false)
351
- yield `\t<meta name="referrer" content="${sec.referrerPolicy || 'strict-origin-when-cross-origin'}" />\n`;
357
+ yield `\t<meta name="referrer" content="${quoteAttr(sec.referrerPolicy || 'strict-origin-when-cross-origin')}" />\n`;
352
358
  if (sec.contentSecurityPolicy !== false)
353
- yield `\t<meta http-equiv="Content-Security-Policy" content="${(sec.contentSecurityPolicy || "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'").replace(/"/g, '&quot;')}" />\n`;
359
+ yield `\t<meta http-equiv="Content-Security-Policy" content="${quoteAttr(sec.contentSecurityPolicy || "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; frame-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'")}" />\n`;
354
360
  if (sec.autoEscape !== false)
355
361
  yield `\t<!-- vesk: auto-escape enabled -->\n`;
356
362
  }
@@ -12,12 +12,36 @@ export declare function nextVskId(): number;
12
12
  export declare function prettifyHtml(html: string): string;
13
13
  export declare function isStatic(body: IRNode[]): boolean;
14
14
  export declare function escapeHtml(str: string): string;
15
+ /** Escapes double quotes for embedding text inside a double-quoted attribute. */
16
+ export declare function quoteAttr(str: string): string;
17
+ /**
18
+ * Makes JSON output safe to embed inside an inline <script> block.
19
+ * Escapes `<` (breaks out of script context via `</script>`), line
20
+ * separators U+2028/U+2029 (valid JSON but invalid JS string literals).
21
+ */
22
+ export declare function safeJsonForScript(json: string): string;
23
+ /** Cryptographically strong random hex token (WebCrypto CSPRNG). */
24
+ export declare function randomToken(bytes?: number): string;
25
+ /** Default request-body cap (bytes) for servers and action/API handlers. */
26
+ export declare const DEFAULT_MAX_BODY_BYTES: number;
15
27
  export declare function redactLog(str: string): string;
16
28
  export declare function setRedactLogging(enabled: boolean): void;
17
29
  export declare function raw(value: unknown): string;
30
+ /** HMAC-SHA256 over `value` keyed by `secret`, hex-encoded. */
31
+ export declare function csrfHmac(value: string, secret: string): string;
18
32
  export declare function csrfToken(sessionId?: string, host?: string): string;
19
33
  export declare function verifyCsrfToken(token: string, host?: string): boolean;
20
34
  export declare function csrfGuard(request: Record<string, unknown>, host?: string): void;
35
+ /** Extracts the authority (host[:port]) part of an absolute URL. */
36
+ export declare function urlAuthority(url: string): string;
37
+ /**
38
+ * Default CSRF defense: unsafe methods must present an Origin or Referer
39
+ * whose authority matches the request Host. Browsers always attach Origin
40
+ * to cross-site POSTs, so mismatches are blocked; non-browser clients that
41
+ * send no Origin/Referer are allowed (they cannot be CSRF'd).
42
+ * Throws a 403-status error on mismatch.
43
+ */
44
+ export declare function assertSameOrigin(request: Record<string, unknown>): void;
21
45
  export declare function signCookie(name: string, value: string, host?: string): Promise<string>;
22
46
  export declare function unsignCookie(name: string, signedValue: string, host?: string): Promise<string | null>;
23
47
  export interface CookieOptions {
@@ -63,6 +87,8 @@ export interface RateLimitOptions {
63
87
  windowMs?: number;
64
88
  max?: number;
65
89
  cleanupIntervalMs?: number;
90
+ /** Only honor proxy headers (x-forwarded-for etc.) when explicitly trusted. */
91
+ trustProxy?: boolean;
66
92
  }
67
93
  export declare function createRateLimiter(options?: RateLimitOptions): {
68
94
  check: (key: string) => boolean;
@@ -74,6 +100,11 @@ export declare function createRateLimiter(options?: RateLimitOptions): {
74
100
  };
75
101
  middleware: (request: Record<string, unknown>, response?: Record<string, unknown>) => boolean;
76
102
  };
103
+ /**
104
+ * Resolves the client IP. Proxy headers (`x-forwarded-for`, `x-real-ip`) are
105
+ * only honored when `trustProxy` is explicitly enabled — otherwise any
106
+ * client could spoof its identity (and defeat rate limiting) with a header.
107
+ */
77
108
  export declare function getClientIp(request: Record<string, unknown> | undefined, trustProxy?: boolean | string): string;
78
109
  export declare function getClientProtocol(request: Record<string, unknown> | undefined, trustProxy?: boolean | string): string;
79
110
  export declare function applyTrustProxy(ctx: Record<string, unknown>, trustProxy: boolean | string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"server-utils.d.ts","sourceRoot":"","sources":["../src/server-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server-utils.d.ts","sourceRoot":"","sources":["../src/server-utils.ts"],"names":[],"mappings":"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"}