@finesoft/front 0.5.3 → 0.5.4
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/dist/{browser-kFMjlLGT.d.mts → browser-CrZcKSpr.d.mts} +4 -4
- package/dist/{browser-CR5vhgXg.mjs → browser-D6If-9VF.mjs} +2 -2
- package/dist/browser.d.mts +6 -6
- package/dist/browser.mjs +4 -4
- package/dist/{cookies-BiRlUanX.d.mts → cookies-BXCwZoS_.d.mts} +4 -4
- package/dist/{fetch-policy-BHT8RtrL.mjs → fetch-policy-Cxk7F-Cu.mjs} +2 -2
- package/dist/{host-guard-DDWxLpFL.mjs → host-guard-DX4e3-45.mjs} +5 -1
- package/dist/{http-B6CJqDyf.d.mts → http-B8r7MWao.d.mts} +2 -2
- package/dist/http.d.mts +1 -1
- package/dist/index-node.d.mts +11 -11
- package/dist/index-node.mjs +7 -7
- package/dist/index.d.mts +15 -15
- package/dist/index.mjs +6 -6
- package/dist/{native-contract-DuR25hYB.d.mts → native-contract-B_2pn5ST.d.mts} +2 -2
- package/dist/native-contract.d.mts +1 -1
- package/dist/{node-D9hB4dsz.d.mts → node-DbGzbatF.d.mts} +4 -4
- package/dist/node.d.mts +1 -1
- package/dist/node.mjs +1 -1
- package/dist/{path-CXT6xGPO.d.mts → path-C-b1ChKq.d.mts} +6 -1
- package/dist/portable.d.mts +8 -8
- package/dist/portable.mjs +6 -6
- package/dist/{proxy-z02VvGIj.mjs → proxy-BkKVP3Ha.mjs} +2 -2
- package/dist/{react-DhwBRw01.d.mts → react-C8AnI9sx.d.mts} +2 -2
- package/dist/react.d.mts +2 -2
- package/dist/{secure-fetch-Xlht2jd7.d.mts → secure-fetch--QwYr5uJ.d.mts} +5 -1
- package/dist/{server-controller-proxy-BkVuVWVD.d.mts → server-controller-proxy-CFdU_nGs.d.mts} +3 -3
- package/dist/{session-DnB4ZC3x.d.mts → session-BR1vd3yY.d.mts} +3 -3
- package/dist/{src-BQBfaaPO.mjs → src-D_Bzbr80.mjs} +16 -7
- package/dist/{ssr-Tn4YkuxM.mjs → ssr-DqwPGqOd.mjs} +3 -3
- package/dist/{ssr-BLzYP4wU.d.mts → ssr-lzuGJ2ux.d.mts} +6 -6
- package/dist/ssr.d.mts +1 -1
- package/dist/ssr.mjs +2 -2
- package/dist/{svelte-Dr5to3SE.d.mts → svelte-CMFFDLBi.d.mts} +2 -2
- package/dist/svelte.d.mts +2 -2
- package/dist/{types-B1BT0N3t.mjs → types-DD09OkGZ.mjs} +3 -3
- package/dist/{vite-Cj4SPA8D.d.mts → vite-BjWtbemg.d.mts} +10 -4
- package/dist/vite.d.mts +2 -2
- package/dist/vite.mjs +218 -44
- package/dist/{vue-DGmzuKho.d.mts → vue-DsZIYP1c.d.mts} +2 -2
- package/dist/vue.d.mts +2 -2
- package/dist/web.d.mts +5 -5
- package/dist/web.mjs +3 -3
- package/dist/worker.d.mts +1 -1
- package/docs/02-routing-and-controllers.md +2 -0
- package/docs/06-http-client.md +4 -0
- package/docs/09-server-and-deployment.md +13 -0
- package/docs/11-navigation.md +2 -0
- package/docs/advanced/multi-tenant-scopes.md +24 -0
- package/docs/zh/02-routing-and-controllers.md +2 -0
- package/docs/zh/09-server-and-deployment.md +13 -0
- package/package.json +22 -22
package/dist/vite.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as isPublicSSRResult, i as matchRenderModeOverride, n as registerProxyRoutes, r as createSSRHandler, t as generateProxyCode } from "./proxy-
|
|
2
|
-
import { r as dynamicImport, t as nodeSafeFetchOptions } from "./fetch-policy-
|
|
1
|
+
import { a as isPublicSSRResult, i as matchRenderModeOverride, n as registerProxyRoutes, r as createSSRHandler, t as generateProxyCode } from "./proxy-BkKVP3Ha.mjs";
|
|
2
|
+
import { r as dynamicImport, t as nodeSafeFetchOptions } from "./fetch-policy-Cxk7F-Cu.mjs";
|
|
3
3
|
import { n as createControllerTypeWatcher, r as generateControllerTypes, t as generateFrontTypes } from "./public-types-BcJM-AYc.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import fs from "node:fs";
|
|
@@ -85,8 +85,8 @@ const RENDER_MODES = ${JSON.stringify(ctx.renderModes ?? {})};
|
|
|
85
85
|
const DEFAULT_LOCALE = ${JSON.stringify(ctx.defaultLocale ?? null)};
|
|
86
86
|
${opts.platformCache ?? ""}
|
|
87
87
|
const app = new Hono();
|
|
88
|
-
${generateProxyCode(ctx.proxies ?? [])}
|
|
89
88
|
${ctx.setupPath ? "await _setupDefault(app);" : ""}
|
|
89
|
+
${generateProxyCode(ctx.proxies ?? [])}
|
|
90
90
|
${opts.platformMiddleware ?? ""}
|
|
91
91
|
const ssr = createSSRHandler({
|
|
92
92
|
ownRenderers: true,
|
|
@@ -95,7 +95,7 @@ const ssr = createSSRHandler({
|
|
|
95
95
|
serializeServerData,
|
|
96
96
|
renderModes: RENDER_MODES,
|
|
97
97
|
defaultLocale: DEFAULT_LOCALE,
|
|
98
|
-
safeFetch: ${opts.dnsPolicy === "hostname" ?
|
|
98
|
+
safeFetch: ${opts.dnsPolicy === "hostname" ? JSON.stringify({ trustedOrigins: opts.trustedOrigins ?? [] }) : "_safeFetchOptions"},
|
|
99
99
|
fetch: (request, bindings) => app.fetch(request, bindings),
|
|
100
100
|
${opts.platformCache ? "cache: {get: platformCacheGet, set: platformCacheSet}," : ""}
|
|
101
101
|
${opts.publicCacheHeaders ? `publicCacheHeaders: ${JSON.stringify(opts.publicCacheHeaders)},` : ""}
|
|
@@ -224,7 +224,12 @@ async function prerenderRoutes(ctx) {
|
|
|
224
224
|
* 注意:Cloudflare Workers 不支持原生 Node.js API。
|
|
225
225
|
* 若 setup 代理使用了 process.env,需在 wrangler.toml 启用 nodejs_compat。
|
|
226
226
|
*/
|
|
227
|
-
function cloudflareAdapter() {
|
|
227
|
+
function cloudflareAdapter(options = {}) {
|
|
228
|
+
const trustedOrigins = [...options.trustedOrigins ?? []];
|
|
229
|
+
for (const origin of trustedOrigins) {
|
|
230
|
+
const parsed = new URL(origin);
|
|
231
|
+
if (parsed.origin !== origin || !["https:", "http:"].includes(parsed.protocol)) throw new TypeError(`Expected an exact HTTP(S) origin: ${origin}`);
|
|
232
|
+
}
|
|
228
233
|
return {
|
|
229
234
|
name: "cloudflare",
|
|
230
235
|
async build(ctx) {
|
|
@@ -236,6 +241,7 @@ function cloudflareAdapter() {
|
|
|
236
241
|
});
|
|
237
242
|
await buildGeneratedEntry(ctx, ".cf-entry.tmp.mjs", generateSSREntry(ctx, {
|
|
238
243
|
dnsPolicy: "hostname",
|
|
244
|
+
trustedOrigins,
|
|
239
245
|
platformImport: ``,
|
|
240
246
|
platformExport: `export default app;`,
|
|
241
247
|
platformCache: `
|
|
@@ -334,7 +340,7 @@ function nodeAdapter() {
|
|
|
334
340
|
await buildGeneratedEntry(ctx, ".node-entry.tmp.mjs", generateSSREntry(ctx, {
|
|
335
341
|
platformImport: `import { startNodeHandler } from "@finesoft/front";
|
|
336
342
|
import { readFileSync, existsSync } from "node:fs";
|
|
337
|
-
import { resolve, dirname } from "node:path";
|
|
343
|
+
import { resolve, dirname, relative, isAbsolute, sep } from "node:path";
|
|
338
344
|
import { fileURLToPath } from "node:url";`,
|
|
339
345
|
platformMiddleware: `
|
|
340
346
|
// 预渲染文件中间件:检查 dist/prerender/ 下是否有对应的静态 HTML
|
|
@@ -349,6 +355,8 @@ app.use("*", async (c, next) => {
|
|
|
349
355
|
];
|
|
350
356
|
if (urlPath === "/") candidates.unshift(resolve(prerenderDir, "index.html"));
|
|
351
357
|
for (const f of candidates) {
|
|
358
|
+
const contained = relative(prerenderDir, f);
|
|
359
|
+
if (contained === ".." || contained.startsWith(".." + sep) || isAbsolute(contained)) continue;
|
|
352
360
|
if (existsSync(f)) {
|
|
353
361
|
const html = readFileSync(f, "utf-8");
|
|
354
362
|
return c.html(html);
|
|
@@ -604,7 +612,99 @@ function serverControllerModules(getRoot) {
|
|
|
604
612
|
return source;
|
|
605
613
|
};
|
|
606
614
|
const has = (node, kind) => getCompiler().canHaveModifiers(node) && getCompiler().getModifiers(node)?.some((m) => m.kind === kind);
|
|
607
|
-
|
|
615
|
+
function unwrap(node) {
|
|
616
|
+
const c = getCompiler();
|
|
617
|
+
while (c.isParenthesizedExpression(node) || c.isAsExpression(node) || c.isTypeAssertionExpression(node) || c.isNonNullExpression(node) || c.isSatisfiesExpression(node)) node = node.expression;
|
|
618
|
+
return node;
|
|
619
|
+
}
|
|
620
|
+
function propertyName(node) {
|
|
621
|
+
const c = getCompiler();
|
|
622
|
+
if (c.isIdentifier(node) || c.isStringLiteralLike(node) || c.isNumericLiteral(node)) return node.text;
|
|
623
|
+
return c.isComputedPropertyName(node) && c.isStringLiteralLike(unwrap(node.expression)) ? unwrap(node.expression).text : void 0;
|
|
624
|
+
}
|
|
625
|
+
function bindingPath(node, name) {
|
|
626
|
+
const c = getCompiler();
|
|
627
|
+
if (c.isIdentifier(node)) return node.text === name ? [] : void 0;
|
|
628
|
+
for (let index = 0; index < node.elements.length; index++) {
|
|
629
|
+
const item = node.elements[index];
|
|
630
|
+
if (!c.isBindingElement(item) || item.dotDotDotToken) continue;
|
|
631
|
+
const nested = bindingPath(item.name, name);
|
|
632
|
+
const member = c.isArrayBindingPattern(node) ? String(index) : item.propertyName ? propertyName(item.propertyName) : c.isIdentifier(item.name) ? item.name.text : void 0;
|
|
633
|
+
if (nested && member !== void 0) return [member, ...nested];
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
async function exportedMember(context, specifier, importer, name, members, seen, baseOnly) {
|
|
637
|
+
if (!members.length) return exported(context, specifier, importer, name, seen, baseOnly);
|
|
638
|
+
if (specifier.startsWith("@finesoft/")) return false;
|
|
639
|
+
const file = (await context.resolve(specifier, importer, { skipSelf: true }))?.id.split("?")[0];
|
|
640
|
+
if (!file) return false;
|
|
641
|
+
const key = `${file}:export-member:${JSON.stringify([name, ...members])}`;
|
|
642
|
+
if (seen.has(key)) return false;
|
|
643
|
+
seen.add(key);
|
|
644
|
+
const source = read(file);
|
|
645
|
+
if (!source) return false;
|
|
646
|
+
context.addWatchFile(file);
|
|
647
|
+
const c = getCompiler();
|
|
648
|
+
for (const statement of source.statements) {
|
|
649
|
+
if (c.isExportDeclaration(statement) && !statement.isTypeOnly) {
|
|
650
|
+
const module = statement.moduleSpecifier && c.isStringLiteral(statement.moduleSpecifier) ? statement.moduleSpecifier.text : void 0;
|
|
651
|
+
const clause = statement.exportClause;
|
|
652
|
+
if (module && clause && c.isNamespaceExport(clause) && clause.name.text === name) return exportedMember(context, module, file, members[0], members.slice(1), seen, baseOnly);
|
|
653
|
+
if (module && !clause && await exportedMember(context, module, file, name, members, new Set(seen), baseOnly)) return true;
|
|
654
|
+
if (clause && c.isNamedExports(clause)) for (const item of clause.elements) {
|
|
655
|
+
if (item.isTypeOnly || item.name.text !== name) continue;
|
|
656
|
+
const local = item.propertyName ?? item.name;
|
|
657
|
+
return module ? exportedMember(context, module, file, local.text, members, seen, baseOnly) : memberExpression(context, source, local, members, seen, baseOnly);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
if (c.isVariableStatement(statement) && has(statement, c.SyntaxKind.ExportKeyword)) {
|
|
661
|
+
for (const item of statement.declarationList.declarations) if (c.isIdentifier(item.name) && item.name.text === name && item.initializer) return memberExpression(context, source, item.initializer, members, seen, baseOnly);
|
|
662
|
+
}
|
|
663
|
+
if (name === "default" && c.isExportAssignment(statement)) return memberExpression(context, source, statement.expression, members, seen, baseOnly);
|
|
664
|
+
}
|
|
665
|
+
return false;
|
|
666
|
+
}
|
|
667
|
+
async function memberExpression(context, source, node, members, seen, baseOnly) {
|
|
668
|
+
if (!members.length) return expression(context, source, node, seen, baseOnly);
|
|
669
|
+
node = unwrap(node);
|
|
670
|
+
const key = `${source.fileName}:member:${node.pos}:${node.end}:${JSON.stringify(members)}`;
|
|
671
|
+
if (seen.has(key)) return false;
|
|
672
|
+
seen.add(key);
|
|
673
|
+
const c = getCompiler();
|
|
674
|
+
if (c.isPropertyAccessExpression(node)) return memberExpression(context, source, node.expression, [node.name.text, ...members], seen, baseOnly);
|
|
675
|
+
if (c.isElementAccessExpression(node) && c.isStringLiteralLike(node.argumentExpression)) return memberExpression(context, source, node.expression, [node.argumentExpression.text, ...members], seen, baseOnly);
|
|
676
|
+
if (c.isObjectLiteralExpression(node)) for (const item of [...node.properties].reverse()) {
|
|
677
|
+
if (c.isSpreadAssignment(item)) {
|
|
678
|
+
if (await memberExpression(context, source, item.expression, members, new Set(seen), baseOnly)) return true;
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
if (propertyName(item.name) !== members[0]) continue;
|
|
682
|
+
if (c.isPropertyAssignment(item)) return memberExpression(context, source, item.initializer, members.slice(1), seen, baseOnly);
|
|
683
|
+
if (c.isShorthandPropertyAssignment(item)) return memberExpression(context, source, item.name, members.slice(1), seen, baseOnly);
|
|
684
|
+
}
|
|
685
|
+
if (c.isArrayLiteralExpression(node)) {
|
|
686
|
+
const item = node.elements[Number(members[0])];
|
|
687
|
+
return !!item && memberExpression(context, source, item, members.slice(1), seen, baseOnly);
|
|
688
|
+
}
|
|
689
|
+
if (!c.isIdentifier(node)) return false;
|
|
690
|
+
for (const statement of source.statements) {
|
|
691
|
+
if (c.isVariableStatement(statement)) for (const item of statement.declarationList.declarations) {
|
|
692
|
+
const prefix = bindingPath(item.name, node.text);
|
|
693
|
+
if (prefix && item.initializer) return memberExpression(context, source, item.initializer, [...prefix, ...members], seen, baseOnly);
|
|
694
|
+
}
|
|
695
|
+
if (!c.isImportDeclaration(statement) || !c.isStringLiteral(statement.moduleSpecifier) || statement.importClause?.isTypeOnly) continue;
|
|
696
|
+
const clause = statement.importClause;
|
|
697
|
+
const binding = clause?.namedBindings;
|
|
698
|
+
const specifier = statement.moduleSpecifier.text;
|
|
699
|
+
if (binding && c.isNamespaceImport(binding) && binding.name.text === node.text) return exportedMember(context, specifier, source.fileName, members[0], members.slice(1), seen, baseOnly);
|
|
700
|
+
if (clause?.name?.text === node.text) return exportedMember(context, specifier, source.fileName, "default", members, seen, baseOnly);
|
|
701
|
+
if (binding && c.isNamedImports(binding)) {
|
|
702
|
+
for (const item of binding.elements) if (!item.isTypeOnly && item.name.text === node.text) return exportedMember(context, specifier, source.fileName, (item.propertyName ?? item.name).text, members, seen, baseOnly);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
return false;
|
|
706
|
+
}
|
|
707
|
+
async function exported(context, specifier, importer, name, seen, baseOnly = false) {
|
|
608
708
|
if (specifier === "@finesoft/front" || serverEntries.has(specifier)) return name === "BaseServerController";
|
|
609
709
|
if (specifier.startsWith("@finesoft/")) return false;
|
|
610
710
|
const resolved = await context.resolve(specifier, importer, { skipSelf: true });
|
|
@@ -619,52 +719,55 @@ function serverControllerModules(getRoot) {
|
|
|
619
719
|
const c = getCompiler();
|
|
620
720
|
for (const statement of source.statements) {
|
|
621
721
|
if (c.isClassDeclaration(statement) && has(statement, c.SyntaxKind.ExportKeyword)) {
|
|
622
|
-
if ((has(statement, c.SyntaxKind.DefaultKeyword) ? "default" : statement.name?.text) === name) return serverClass(context, source, statement, seen);
|
|
722
|
+
if ((has(statement, c.SyntaxKind.DefaultKeyword) ? "default" : statement.name?.text) === name) return !baseOnly && serverClass(context, source, statement, seen);
|
|
723
|
+
}
|
|
724
|
+
if (c.isVariableStatement(statement) && has(statement, c.SyntaxKind.ExportKeyword)) {
|
|
725
|
+
for (const item of statement.declarationList.declarations) if (c.isIdentifier(item.name) && item.name.text === name && item.initializer) return expression(context, source, item.initializer, seen, baseOnly);
|
|
623
726
|
}
|
|
624
727
|
if (c.isExportDeclaration(statement) && !statement.isTypeOnly) {
|
|
625
728
|
const module = statement.moduleSpecifier && c.isStringLiteral(statement.moduleSpecifier) ? statement.moduleSpecifier.text : void 0;
|
|
626
|
-
if (!statement.exportClause && module && await exported(context, module, file, name, new Set(seen))) return true;
|
|
729
|
+
if (!statement.exportClause && module && await exported(context, module, file, name, new Set(seen), baseOnly)) return true;
|
|
627
730
|
if (statement.exportClause && c.isNamedExports(statement.exportClause)) for (const item of statement.exportClause.elements) {
|
|
628
731
|
if (item.isTypeOnly || item.name.text !== name) continue;
|
|
629
732
|
const local = (item.propertyName ?? item.name).text;
|
|
630
|
-
return module ? exported(context, module, file, local, seen) : identifier(context, source, local, seen);
|
|
733
|
+
return module ? exported(context, module, file, local, seen, baseOnly) : identifier(context, source, local, seen, baseOnly);
|
|
631
734
|
}
|
|
632
735
|
}
|
|
633
|
-
if (name === "default" && c.isExportAssignment(statement)) return expression(context, source, statement.expression, seen);
|
|
736
|
+
if (name === "default" && c.isExportAssignment(statement)) return expression(context, source, statement.expression, seen, baseOnly);
|
|
634
737
|
}
|
|
635
738
|
return false;
|
|
636
739
|
}
|
|
637
|
-
async function identifier(context, source, name, seen) {
|
|
740
|
+
async function identifier(context, source, name, seen, baseOnly = false) {
|
|
638
741
|
const key = `${source.fileName}:local:${name}`;
|
|
639
742
|
if (seen.has(key)) return false;
|
|
640
743
|
seen.add(key);
|
|
641
744
|
const c = getCompiler();
|
|
642
745
|
for (const statement of source.statements) {
|
|
643
|
-
if (c.isClassDeclaration(statement) && statement.name?.text === name) return serverClass(context, source, statement, seen);
|
|
644
|
-
if (c.isVariableStatement(statement)) {
|
|
645
|
-
|
|
746
|
+
if (c.isClassDeclaration(statement) && statement.name?.text === name) return !baseOnly && serverClass(context, source, statement, seen);
|
|
747
|
+
if (c.isVariableStatement(statement)) for (const item of statement.declarationList.declarations) {
|
|
748
|
+
const members = bindingPath(item.name, name);
|
|
749
|
+
if (members && item.initializer) return memberExpression(context, source, item.initializer, members, seen, baseOnly);
|
|
646
750
|
}
|
|
647
751
|
if (!c.isImportDeclaration(statement) || !c.isStringLiteral(statement.moduleSpecifier) || statement.importClause?.isTypeOnly) continue;
|
|
648
752
|
const clause = statement.importClause;
|
|
649
|
-
if (clause?.name?.text === name) return exported(context, statement.moduleSpecifier.text, source.fileName, "default", seen);
|
|
753
|
+
if (clause?.name?.text === name) return exported(context, statement.moduleSpecifier.text, source.fileName, "default", seen, baseOnly);
|
|
650
754
|
if (clause?.namedBindings && c.isNamedImports(clause.namedBindings)) {
|
|
651
|
-
for (const item of clause.namedBindings.elements) if (!item.isTypeOnly && item.name.text === name) return exported(context, statement.moduleSpecifier.text, source.fileName, (item.propertyName ?? item.name).text, seen);
|
|
755
|
+
for (const item of clause.namedBindings.elements) if (!item.isTypeOnly && item.name.text === name) return exported(context, statement.moduleSpecifier.text, source.fileName, (item.propertyName ?? item.name).text, seen, baseOnly);
|
|
652
756
|
}
|
|
653
757
|
}
|
|
654
758
|
return false;
|
|
655
759
|
}
|
|
656
|
-
async function expression(context, source, node, seen) {
|
|
760
|
+
async function expression(context, source, node, seen, baseOnly = false) {
|
|
657
761
|
const c = getCompiler();
|
|
658
|
-
|
|
659
|
-
if (c.
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (c.isClassExpression(node)) return serverClass(context, source, node, seen);
|
|
762
|
+
node = unwrap(node);
|
|
763
|
+
if (c.isIdentifier(node)) return identifier(context, source, node.text, seen, baseOnly);
|
|
764
|
+
const member = c.isPropertyAccessExpression(node) ? node.name.text : c.isElementAccessExpression(node) && c.isStringLiteralLike(node.argumentExpression) ? node.argumentExpression.text : void 0;
|
|
765
|
+
if (member && (c.isPropertyAccessExpression(node) || c.isElementAccessExpression(node))) return memberExpression(context, source, node.expression, [member], seen, baseOnly);
|
|
766
|
+
if (baseOnly && c.isElementAccessExpression(node) && !member) return memberExpression(context, source, node.expression, ["BaseServerController"], seen, true);
|
|
767
|
+
if (c.isClassExpression(node)) return !baseOnly && serverClass(context, source, node, seen);
|
|
665
768
|
if (c.isCallExpression(node)) {
|
|
666
|
-
if (await expression(context, source, node.expression, new Set(seen))) return true;
|
|
667
|
-
for (const argument of node.arguments) if (await expression(context, source, argument, new Set(seen))) return true;
|
|
769
|
+
if (!baseOnly && await expression(context, source, node.expression, new Set(seen))) return true;
|
|
770
|
+
for (const argument of node.arguments) if (await expression(context, source, argument, new Set(seen), baseOnly) || baseOnly && await memberExpression(context, source, argument, ["BaseServerController"], new Set(seen), true)) return true;
|
|
668
771
|
}
|
|
669
772
|
return false;
|
|
670
773
|
}
|
|
@@ -672,6 +775,77 @@ function serverControllerModules(getRoot) {
|
|
|
672
775
|
const base = node.heritageClauses?.find((clause) => clause.token === getCompiler().SyntaxKind.ExtendsKeyword)?.types[0];
|
|
673
776
|
return !!base && expression(context, source, base.expression, seen);
|
|
674
777
|
}
|
|
778
|
+
/** One classification drives cold dependency indexing and every browser load form. */
|
|
779
|
+
async function classify(context, source) {
|
|
780
|
+
const c = getCompiler();
|
|
781
|
+
const classes = [];
|
|
782
|
+
const uses = [];
|
|
783
|
+
const visit = (node) => {
|
|
784
|
+
if (c.isImportDeclaration(node) || c.isExportDeclaration(node) || c.isTypeNode(node)) return;
|
|
785
|
+
if (c.isClassDeclaration(node) || c.isClassExpression(node)) classes.push(node);
|
|
786
|
+
if (c.isIdentifier(node) || c.isPropertyAccessExpression(node) || c.isElementAccessExpression(node) || c.isCallExpression(node)) uses.push(node);
|
|
787
|
+
c.forEachChild(node, visit);
|
|
788
|
+
};
|
|
789
|
+
visit(source);
|
|
790
|
+
const owned = /* @__PURE__ */ new Set();
|
|
791
|
+
for (const node of classes) if (await serverClass(context, source, node, /* @__PURE__ */ new Set())) owned.add(node);
|
|
792
|
+
const names = /* @__PURE__ */ new Map();
|
|
793
|
+
const defaultNames = /* @__PURE__ */ new Map();
|
|
794
|
+
const reserved = new Set(uses.filter(c.isIdentifier).map((node) => node.text));
|
|
795
|
+
const generatedName = (prefix) => {
|
|
796
|
+
let name = prefix;
|
|
797
|
+
while (reserved.has(name)) name += "_";
|
|
798
|
+
reserved.add(name);
|
|
799
|
+
return name;
|
|
800
|
+
};
|
|
801
|
+
for (const statement of source.statements) {
|
|
802
|
+
if (c.isClassDeclaration(statement) && owned.has(statement)) {
|
|
803
|
+
const name = statement.name?.text ?? "__ServerController";
|
|
804
|
+
names.set(name, name);
|
|
805
|
+
}
|
|
806
|
+
if (c.isVariableStatement(statement)) {
|
|
807
|
+
for (const item of statement.declarationList.declarations) if (c.isIdentifier(item.name) && item.initializer && owned.has(unwrap(item.initializer))) names.set(item.name.text, item.name.text);
|
|
808
|
+
}
|
|
809
|
+
if (c.isExportAssignment(statement) && owned.has(unwrap(statement.expression))) {
|
|
810
|
+
const name = generatedName("__ServerControllerDefault");
|
|
811
|
+
defaultNames.set(statement, name);
|
|
812
|
+
names.set(name, name);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
let changed = true;
|
|
816
|
+
while (changed) {
|
|
817
|
+
changed = false;
|
|
818
|
+
for (const statement of source.statements) {
|
|
819
|
+
if (!c.isVariableStatement(statement)) continue;
|
|
820
|
+
for (const item of statement.declarationList.declarations) {
|
|
821
|
+
if (!c.isIdentifier(item.name) || !item.initializer || names.has(item.name.text)) continue;
|
|
822
|
+
const value = unwrap(item.initializer);
|
|
823
|
+
if (c.isIdentifier(value) && names.has(value.text)) {
|
|
824
|
+
names.set(item.name.text, names.get(value.text));
|
|
825
|
+
changed = true;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
let server = owned.size > 0;
|
|
831
|
+
if (!server) {
|
|
832
|
+
const checked = /* @__PURE__ */ new Set();
|
|
833
|
+
for (const use of uses) {
|
|
834
|
+
const key = use.getText(source);
|
|
835
|
+
if (checked.has(key)) continue;
|
|
836
|
+
checked.add(key);
|
|
837
|
+
if (await expression(context, source, use, /* @__PURE__ */ new Set(), true)) {
|
|
838
|
+
server = true;
|
|
839
|
+
break;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
return {
|
|
844
|
+
server,
|
|
845
|
+
names,
|
|
846
|
+
defaultNames
|
|
847
|
+
};
|
|
848
|
+
}
|
|
675
849
|
async function protectDependencies(context, file, seen = /* @__PURE__ */ new Set()) {
|
|
676
850
|
if (seen.has(file)) return;
|
|
677
851
|
seen.add(file);
|
|
@@ -719,12 +893,11 @@ function serverControllerModules(getRoot) {
|
|
|
719
893
|
}
|
|
720
894
|
if (!pending.size) return;
|
|
721
895
|
indexing = (async () => {
|
|
722
|
-
const c = getCompiler();
|
|
723
896
|
for (const file of pending) {
|
|
724
897
|
pending.delete(file);
|
|
725
898
|
const source = read(file);
|
|
726
899
|
if (!source) continue;
|
|
727
|
-
if (privateFiles.has(file) || (await
|
|
900
|
+
if (privateFiles.has(file) || (await classify(context, source)).server) await protectDependencies(context, file);
|
|
728
901
|
}
|
|
729
902
|
})();
|
|
730
903
|
try {
|
|
@@ -748,12 +921,8 @@ function serverControllerModules(getRoot) {
|
|
|
748
921
|
return null;
|
|
749
922
|
}
|
|
750
923
|
const c = getCompiler();
|
|
751
|
-
const names
|
|
752
|
-
|
|
753
|
-
const name = statement.name?.text ?? "__ServerController";
|
|
754
|
-
names.set(name, name);
|
|
755
|
-
}
|
|
756
|
-
if (!names.size) {
|
|
924
|
+
const { server, names, defaultNames } = await classify(context, source);
|
|
925
|
+
if (!server) {
|
|
757
926
|
if (privateFiles.has(file)) throw Error(`Server controller dependency cannot be loaded by the browser: ${file}`);
|
|
758
927
|
return null;
|
|
759
928
|
}
|
|
@@ -763,6 +932,7 @@ function serverControllerModules(getRoot) {
|
|
|
763
932
|
"v",
|
|
764
933
|
"import"
|
|
765
934
|
].includes(key))) throw Error(`Server controller source cannot be loaded as an asset: ${file}`);
|
|
935
|
+
if (!names.size) throw Error(`Unsupported server controller syntax; use a module-scope class: ${file}`);
|
|
766
936
|
const exports = [];
|
|
767
937
|
for (const statement of source.statements) {
|
|
768
938
|
if (c.isInterfaceDeclaration(statement) || c.isTypeAliasDeclaration(statement)) continue;
|
|
@@ -770,7 +940,11 @@ function serverControllerModules(getRoot) {
|
|
|
770
940
|
const name = statement.name?.text ?? "__ServerController";
|
|
771
941
|
if (!names.has(name)) throw Error(`Server controller modules cannot export shared implementations: ${file}`);
|
|
772
942
|
exports.push(has(statement, c.SyntaxKind.DefaultKeyword) ? `export default ${name};` : `export { ${name} };`);
|
|
773
|
-
} else if (c.
|
|
943
|
+
} else if (c.isVariableStatement(statement) && has(statement, c.SyntaxKind.ExportKeyword)) for (const item of statement.declarationList.declarations) {
|
|
944
|
+
if (!c.isIdentifier(item.name) || !names.has(item.name.text)) throw Error(`Server controller modules can only export controllers and types: ${file}`);
|
|
945
|
+
exports.push(`export { ${item.name.text} };`);
|
|
946
|
+
}
|
|
947
|
+
else if (c.isExportDeclaration(statement) && !statement.isTypeOnly) {
|
|
774
948
|
if (statement.moduleSpecifier || !statement.exportClause || !c.isNamedExports(statement.exportClause)) throw Error(`Move re-exports out of the server controller implementation module: ${file}`);
|
|
775
949
|
for (const item of statement.exportClause.elements) {
|
|
776
950
|
if (item.isTypeOnly) continue;
|
|
@@ -779,12 +953,14 @@ function serverControllerModules(getRoot) {
|
|
|
779
953
|
exports.push(`export { ${name} as ${item.name.text} };`);
|
|
780
954
|
}
|
|
781
955
|
} else if (c.isExportAssignment(statement)) {
|
|
782
|
-
|
|
783
|
-
|
|
956
|
+
const value = unwrap(statement.expression);
|
|
957
|
+
const name = defaultNames.get(statement) ?? (c.isIdentifier(value) ? value.text : void 0);
|
|
958
|
+
if (!name || !names.has(name)) throw Error(`Invalid server controller default export: ${file}`);
|
|
959
|
+
exports.push(`export default ${name};`);
|
|
784
960
|
} else if (has(statement, c.SyntaxKind.ExportKeyword)) throw Error(`Server controller modules can only export controllers and types: ${file}`);
|
|
785
961
|
}
|
|
786
962
|
return {
|
|
787
|
-
code: `import { ServerControllerProxy as __Proxy } from "@finesoft/front";\n${[...names].map(([name]) => `class ${name} extends __Proxy {}`).join("\n")}\n${exports.join("\n")}`,
|
|
963
|
+
code: `import { ServerControllerProxy as __Proxy } from "@finesoft/front";\n${[...names].map(([name, original]) => name === original ? `class ${name} extends __Proxy {}` : `const ${name} = ${original};`).join("\n")}\n${exports.join("\n")}`,
|
|
788
964
|
map: {
|
|
789
965
|
version: 3,
|
|
790
966
|
sources: [],
|
|
@@ -2202,9 +2378,9 @@ export async function loadMessages(locale) {
|
|
|
2202
2378
|
const { getRequestListener } = await dynamicImport("@hono/node-server");
|
|
2203
2379
|
printDevSafetyBanner();
|
|
2204
2380
|
const app = new HonoClass();
|
|
2205
|
-
if (options.proxies?.length) registerProxyRoutes(app, options.proxies);
|
|
2206
2381
|
if (typeof options.setup === "function") await options.setup(app);
|
|
2207
2382
|
else if (typeof options.setup === "string") await (await server.ssrLoadModule("/" + options.setup)).default(app);
|
|
2383
|
+
if (options.proxies?.length) registerProxyRoutes(app, options.proxies);
|
|
2208
2384
|
const ssrApp = createSSRApp({
|
|
2209
2385
|
root,
|
|
2210
2386
|
vite: server,
|
|
@@ -2236,14 +2412,12 @@ export async function loadMessages(locale) {
|
|
|
2236
2412
|
const { Hono: HonoClass } = await dynamicImport("hono");
|
|
2237
2413
|
const { getRequestListener } = await dynamicImport("@hono/node-server");
|
|
2238
2414
|
const app = new HonoClass();
|
|
2239
|
-
if (options.proxies?.length) registerProxyRoutes(app, options.proxies);
|
|
2240
2415
|
if (typeof options.setup === "function") await options.setup(app);
|
|
2241
|
-
else if (typeof options.setup === "string")
|
|
2416
|
+
else if (typeof options.setup === "string") {
|
|
2242
2417
|
const setupPath = pathToFileURL(path.resolve(root, "dist/server/setup.mjs")).href;
|
|
2243
2418
|
await (await dynamicImport(setupPath)).default(app);
|
|
2244
|
-
} catch {
|
|
2245
|
-
console.warn("[finesoft] Could not load setup module for preview. API routes disabled.");
|
|
2246
2419
|
}
|
|
2420
|
+
if (options.proxies?.length) registerProxyRoutes(app, options.proxies);
|
|
2247
2421
|
const template = readFileSync(path.resolve(root, "dist/client/index.html"), "utf-8");
|
|
2248
2422
|
const ssrPath = pathToFileURL(path.resolve(root, "dist/server/ssr.js")).href;
|
|
2249
2423
|
const ssrModule = await dynamicImport(ssrPath);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as AppSnapshot, g as WebAppView, h as ViewProps } from "./session-
|
|
1
|
+
import { f as AppSnapshot, g as WebAppView, h as ViewProps } from "./session-BR1vd3yY.mjs";
|
|
2
2
|
import { Component, PropType } from "vue";
|
|
3
3
|
declare namespace vue_d_exports {
|
|
4
4
|
export { NativeView, NativeViews, Outlet, ViewProps, WebAppView, useSnapshot };
|
|
@@ -29,4 +29,4 @@ declare const Outlet: import("vue").DefineComponent<import("vue").ExtractPropTyp
|
|
|
29
29
|
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
30
30
|
//#endregion
|
|
31
31
|
export { vue_d_exports as a, useSnapshot as i, NativeViews as n, Outlet as r, NativeView as t };
|
|
32
|
-
//# sourceMappingURL=vue-
|
|
32
|
+
//# sourceMappingURL=vue-DsZIYP1c.d.mts.map
|
package/dist/vue.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { g as WebAppView, h as ViewProps } from "./session-
|
|
2
|
-
import { i as useSnapshot, n as NativeViews, r as Outlet, t as NativeView } from "./vue-
|
|
1
|
+
import { g as WebAppView, h as ViewProps } from "./session-BR1vd3yY.mjs";
|
|
2
|
+
import { i as useSnapshot, n as NativeViews, r as Outlet, t as NativeView } from "./vue-DsZIYP1c.mjs";
|
|
3
3
|
export { NativeView, NativeViews, Outlet, type ViewProps, type WebAppView, useSnapshot };
|
package/dist/web.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as makeSchema, C as ImpressionEntry, D as StandardIssue, E as ParamSchema, F as Token, I as createToken, M as Provider, N as ProviderContext, O as StandardResult, P as provide, S as EventRecorder, T as InferOutput, _ as OperationPolicy, a as compilePath, b as RuntimeOptions, c as ExecutionContext, d as ExecutionHandle, f as Implementation, g as OperationHandler, h as Operation, i as PathParams, j as Container, k as StandardSchemaV1, l as ExecutionError, m as ModuleDefinition, n as PathDescriptor, o as AnyOperation, p as Invocation, r as PathParameterDescriptor, s as AppDefinition, t as CompiledPath, u as ExecutionErrorCode, v as QueryCache, w as MetricsFieldsProvider, x as executionErrorFromHttp, y as RuntimeHandle } from "./path-
|
|
2
|
-
import { $ as createActiveLeafCodec, $n as list, $t as MiddlewareResult, A as SessionStore, An as PlatformInfo, At as isCompoundAction, B as ControllerContext, Bn as ConsoleLoggerFactory, Bt as NavigationPath, C as SessionFailure, Cn as Storage, Ct as ACTION_KINDS, D as SessionSlice, Dn as LocaleInfo, Dt as ExternalUrlAction, E as SessionRestoreResult, En as LocaleAttributes, Et as CompoundAction, F as WebRuntime, Fn as ReportCallback, Ft as LeafNode, G as controllerContext, Gn as InferParams, Gt as SplitColumn, H as SERVER_CONTROLLER, Hn as Logger, Ht as NavigationSnapshot, I as WebRuntimeOptions, In as ReportingLogger, It as NAVIGATION_NODE_KINDS, J as resolveConfiguredMessages, Jn as QuerySchemaMap, Jt as StackNode, K as MessagesLoader, Kn as InferQuery, Kt as SplitNode, L as createWebRuntime, Ln as ReportingLoggerFactory, Lt as NavigationError, M as SessionWriteResult, Mn as BaseController, Mt as isFlowAction, N as StorageUnavailableError, Nn as ControllerFailure, Nt as makeExternalUrlAction, O as SessionSnapshot, On as TextDirection, Ot as FlowAction, P as WebConfiguration, Pn as ControllerInput, Pt as makeFlowAction, Q as NavigationRouterLike, Qn as isMultiValueSchema, Qt as DenyResult, R as PageControllerDefinition, Rn as ReportingLoggerOptions, Rt as NavigationNode, S as SessionErrorContext, Sn as FeatureFlagsProvider, St as ActionHandler, T as SessionNavigation, Tn as resolveMessages, Tt as ActionInvocation, U as SERVER_REQUEST, Un as LoggerFactory, Ut as ResolvedDestination, V as PageControllerInput, Vn as LogFilter, Vt as NavigationPathStep, W as ServerRequestState, Wn as ExtractParamNames, Wt as SPLIT_VISIBILITIES, X as FullStateCodecOptions, Xn as ListOptions, Xt as AfterLoadGuard, Y as DEFAULT_NAV_PARAM, Yn as StripOptional, Yt as TabsNode, Z as NavigationCodec, Zn as MultiValueSchema, Zt as BeforeLoadGuard, _ as AsyncStorage, _n as RouteInput, _t as PrefetchedIntents, a as NavigationCommitContext, an as deny, at as SerializedSplit, b as SESSION_DEFAULT_VERSION, bn as DEP_KEYS, bt as Router, c as NavigationTransactionContext, cn as rewrite, ct as SerializedTabs, d as createWebSession, dn as FINESOFT_PUBLIC, dt as serializeNavigationStable, en as NavigationContext, er as Intent, et as createFullStateCodec, f as AppSnapshot, fn as PublicProjection, ft as PageRoute, g as WebAppView, gn as markPublic, gt as PrefetchedIntent, h as ViewProps, hn as isPublicMarked, ht as route, i as BeforeNavigateResult, in as RewriteResult, it as SerializedNavigation, j as SessionStoreOptions, jn as detectPlatform, jt as isExternalUrlAction, k as SessionStateProvider, kn as Translator, kt as TreeAction, l as WebSession, ln as BASE_PAGE_FIELDS, lt as deserializeNavigation, m as ViewEntry, mn as getPublicFields, mt as RouteDefinition, n as BeforeCommitResult, nn as PostLoadContext, nt as encodeNavigationTreeParam, o as NavigationCommitError, on as next, ot as SerializedSplitColumn, p as NavigationSummary, pn as PublicValueCodec, pt as RenderMode, q as MessagesLoaderContext, qn as ParamsFor, qt as SplitVisibility, r as BeforeNavigatePolicy, rn as RedirectResult, rt as SerializedLeaf, s as NavigationContextInput, sn as redirect, st as SerializedStack, t as BeforeCommitPolicy, tn as NextResult, tt as decodeNavigationTreeParam, u as WebSessionOptions, un as BasePage, ut as serializeNavigation, v as NavigationScopedState, vn as RouteIntent, vt as RouteAddOptions, w as SessionLoadResult, wn as TranslationMessages, wt as Action, x as SessionError, xn as FeatureFlags, xt as ActionDispatcher, y as SESSION_DEFAULT_KEY, yn as RouteParams, yt as RouteMatch, z as WebAppDefinition, zn as ConsoleLogger, zt as NavigationNodeKind } from "./session-
|
|
3
|
-
import { $ as SimpleTranslator, $t as str, A as setVisibility, At as pipeAsync, B as split, Bt as HostGuardError, C as popTo, Ct as isNone, D as resolveActivePath, Dt as Mapper, E as replaceTop, Et as AsyncMapper, F as isLeafNode, Ft as HttpClient, G as SafeErrorPageOptions, Gt as optional, H as tabs, Ht as stableStringify, I as isSplitNode, It as HttpClientConfig, J as defineApp, Jt as StrOptions, K as safeErrorPage, Kt as withDefault, L as isStackNode, Lt as HttpRequestOptions, M as resourceKey, Mt as HostCheckResult, N as SplitColumnInit, Nt as classifyHost, O as selectColumn, Ot as mapEach, P as TabsInit, Pt as classifyUrl, Q as implementOperation, Qt as oneOf, R as isTabsNode, Rt as RequestInterceptor, S as pop, St as Optional, T as push, Tt as LruMap, U as RouteInputFor, Ut as CompositeLogger, V as stack, Vt as HttpError, W as createHydrationDigest, Wt as CompositeLoggerFactory, X as defineOperation, Xt as int, Y as defineModule, Yt as bool, Z as implementController, Zt as num, _ as collectAllLeaves, _t as getBaseUrl, a as LoadPageOptions, at as resolveLocaleFromUrl, b as findNode, bt as removeScheme, c as defineWebApp, ct as englishPlural, d as runBeforeLoadGuards, dt as WithFieldsRecorder, en as uuid, et as SimpleTranslatorOptions, f as createSessionStore, ft as VoidEventRecorder, g as encodeSnapshot, gt as buildUrl, h as decodeSnapshot, ht as generateUuid, i as resolveInitialNavigation, it as makeLocaleInfo, j as visibleSplitColumns, jt as fetchWithRedirects, k as selectTab, kt as pipe, l as getWebPlan, lt as interpolate, m as createNavigationScopedState, mt as CompositeEventRecorder, n as PageReference, nt as getTextDirection, o as PageLoadResult, ot as PluralCategory, p as collectLeafKeys, pt as ConsoleEventRecorder, q as createRuntime, qt as NumOptions, r as definePage, rt as isRtl, s as loadPage, st as PluralRuleProvider, t as parseCookieString, tt as getLocaleAttributes, u as runAfterLoadGuards, ut as resolvePluralKey, v as collectVisibleDestinations, vt as removeHost, w as popToRoot, wt as isSome, x as mapNavigationLeaves, xt as None, y as findNearestStack, yt as removeQueryParams, z as leaf, zt as ResponseInterceptor } from "./cookies-
|
|
4
|
-
import { a as enforceHostGuard, i as TargetGuardOptions, n as secureFetch, r as DnsLookup, t as SecureFetchOptions } from "./secure-fetch
|
|
5
|
-
import { a as WebHydration, c as decodeWireEnvelope, i as FRAMEWORK_PROTOCOL_VERSION, l as getFrameworkBuildId, n as ServerControllerProxy, o as WireDecodeResult, r as ServerControllerRequest, s as WireEnvelope, t as SERVER_CONTROLLER_PATH } from "./server-controller-proxy-
|
|
1
|
+
import { A as makeSchema, C as ImpressionEntry, D as StandardIssue, E as ParamSchema, F as Token, I as createToken, M as Provider, N as ProviderContext, O as StandardResult, P as provide, S as EventRecorder, T as InferOutput, _ as OperationPolicy, a as compilePath, b as RuntimeOptions, c as ExecutionContext, d as ExecutionHandle, f as Implementation, g as OperationHandler, h as Operation, i as PathParams, j as Container, k as StandardSchemaV1, l as ExecutionError, m as ModuleDefinition, n as PathDescriptor, o as AnyOperation, p as Invocation, r as PathParameterDescriptor, s as AppDefinition, t as CompiledPath, u as ExecutionErrorCode, v as QueryCache, w as MetricsFieldsProvider, x as executionErrorFromHttp, y as RuntimeHandle } from "./path-C-b1ChKq.mjs";
|
|
2
|
+
import { $ as createActiveLeafCodec, $n as list, $t as MiddlewareResult, A as SessionStore, An as PlatformInfo, At as isCompoundAction, B as ControllerContext, Bn as ConsoleLoggerFactory, Bt as NavigationPath, C as SessionFailure, Cn as Storage, Ct as ACTION_KINDS, D as SessionSlice, Dn as LocaleInfo, Dt as ExternalUrlAction, E as SessionRestoreResult, En as LocaleAttributes, Et as CompoundAction, F as WebRuntime, Fn as ReportCallback, Ft as LeafNode, G as controllerContext, Gn as InferParams, Gt as SplitColumn, H as SERVER_CONTROLLER, Hn as Logger, Ht as NavigationSnapshot, I as WebRuntimeOptions, In as ReportingLogger, It as NAVIGATION_NODE_KINDS, J as resolveConfiguredMessages, Jn as QuerySchemaMap, Jt as StackNode, K as MessagesLoader, Kn as InferQuery, Kt as SplitNode, L as createWebRuntime, Ln as ReportingLoggerFactory, Lt as NavigationError, M as SessionWriteResult, Mn as BaseController, Mt as isFlowAction, N as StorageUnavailableError, Nn as ControllerFailure, Nt as makeExternalUrlAction, O as SessionSnapshot, On as TextDirection, Ot as FlowAction, P as WebConfiguration, Pn as ControllerInput, Pt as makeFlowAction, Q as NavigationRouterLike, Qn as isMultiValueSchema, Qt as DenyResult, R as PageControllerDefinition, Rn as ReportingLoggerOptions, Rt as NavigationNode, S as SessionErrorContext, Sn as FeatureFlagsProvider, St as ActionHandler, T as SessionNavigation, Tn as resolveMessages, Tt as ActionInvocation, U as SERVER_REQUEST, Un as LoggerFactory, Ut as ResolvedDestination, V as PageControllerInput, Vn as LogFilter, Vt as NavigationPathStep, W as ServerRequestState, Wn as ExtractParamNames, Wt as SPLIT_VISIBILITIES, X as FullStateCodecOptions, Xn as ListOptions, Xt as AfterLoadGuard, Y as DEFAULT_NAV_PARAM, Yn as StripOptional, Yt as TabsNode, Z as NavigationCodec, Zn as MultiValueSchema, Zt as BeforeLoadGuard, _ as AsyncStorage, _n as RouteInput, _t as PrefetchedIntents, a as NavigationCommitContext, an as deny, at as SerializedSplit, b as SESSION_DEFAULT_VERSION, bn as DEP_KEYS, bt as Router, c as NavigationTransactionContext, cn as rewrite, ct as SerializedTabs, d as createWebSession, dn as FINESOFT_PUBLIC, dt as serializeNavigationStable, en as NavigationContext, er as Intent, et as createFullStateCodec, f as AppSnapshot, fn as PublicProjection, ft as PageRoute, g as WebAppView, gn as markPublic, gt as PrefetchedIntent, h as ViewProps, hn as isPublicMarked, ht as route, i as BeforeNavigateResult, in as RewriteResult, it as SerializedNavigation, j as SessionStoreOptions, jn as detectPlatform, jt as isExternalUrlAction, k as SessionStateProvider, kn as Translator, kt as TreeAction, l as WebSession, ln as BASE_PAGE_FIELDS, lt as deserializeNavigation, m as ViewEntry, mn as getPublicFields, mt as RouteDefinition, n as BeforeCommitResult, nn as PostLoadContext, nt as encodeNavigationTreeParam, o as NavigationCommitError, on as next, ot as SerializedSplitColumn, p as NavigationSummary, pn as PublicValueCodec, pt as RenderMode, q as MessagesLoaderContext, qn as ParamsFor, qt as SplitVisibility, r as BeforeNavigatePolicy, rn as RedirectResult, rt as SerializedLeaf, s as NavigationContextInput, sn as redirect, st as SerializedStack, t as BeforeCommitPolicy, tn as NextResult, tt as decodeNavigationTreeParam, u as WebSessionOptions, un as BasePage, ut as serializeNavigation, v as NavigationScopedState, vn as RouteIntent, vt as RouteAddOptions, w as SessionLoadResult, wn as TranslationMessages, wt as Action, x as SessionError, xn as FeatureFlags, xt as ActionDispatcher, y as SESSION_DEFAULT_KEY, yn as RouteParams, yt as RouteMatch, z as WebAppDefinition, zn as ConsoleLogger, zt as NavigationNodeKind } from "./session-BR1vd3yY.mjs";
|
|
3
|
+
import { $ as SimpleTranslator, $t as str, A as setVisibility, At as pipeAsync, B as split, Bt as HostGuardError, C as popTo, Ct as isNone, D as resolveActivePath, Dt as Mapper, E as replaceTop, Et as AsyncMapper, F as isLeafNode, Ft as HttpClient, G as SafeErrorPageOptions, Gt as optional, H as tabs, Ht as stableStringify, I as isSplitNode, It as HttpClientConfig, J as defineApp, Jt as StrOptions, K as safeErrorPage, Kt as withDefault, L as isStackNode, Lt as HttpRequestOptions, M as resourceKey, Mt as HostCheckResult, N as SplitColumnInit, Nt as classifyHost, O as selectColumn, Ot as mapEach, P as TabsInit, Pt as classifyUrl, Q as implementOperation, Qt as oneOf, R as isTabsNode, Rt as RequestInterceptor, S as pop, St as Optional, T as push, Tt as LruMap, U as RouteInputFor, Ut as CompositeLogger, V as stack, Vt as HttpError, W as createHydrationDigest, Wt as CompositeLoggerFactory, X as defineOperation, Xt as int, Y as defineModule, Yt as bool, Z as implementController, Zt as num, _ as collectAllLeaves, _t as getBaseUrl, a as LoadPageOptions, at as resolveLocaleFromUrl, b as findNode, bt as removeScheme, c as defineWebApp, ct as englishPlural, d as runBeforeLoadGuards, dt as WithFieldsRecorder, en as uuid, et as SimpleTranslatorOptions, f as createSessionStore, ft as VoidEventRecorder, g as encodeSnapshot, gt as buildUrl, h as decodeSnapshot, ht as generateUuid, i as resolveInitialNavigation, it as makeLocaleInfo, j as visibleSplitColumns, jt as fetchWithRedirects, k as selectTab, kt as pipe, l as getWebPlan, lt as interpolate, m as createNavigationScopedState, mt as CompositeEventRecorder, n as PageReference, nt as getTextDirection, o as PageLoadResult, ot as PluralCategory, p as collectLeafKeys, pt as ConsoleEventRecorder, q as createRuntime, qt as NumOptions, r as definePage, rt as isRtl, s as loadPage, st as PluralRuleProvider, t as parseCookieString, tt as getLocaleAttributes, u as runAfterLoadGuards, ut as resolvePluralKey, v as collectVisibleDestinations, vt as removeHost, w as popToRoot, wt as isSome, x as mapNavigationLeaves, xt as None, y as findNearestStack, yt as removeQueryParams, z as leaf, zt as ResponseInterceptor } from "./cookies-BXCwZoS_.mjs";
|
|
4
|
+
import { a as enforceHostGuard, i as TargetGuardOptions, n as secureFetch, r as DnsLookup, t as SecureFetchOptions } from "./secure-fetch--QwYr5uJ.mjs";
|
|
5
|
+
import { a as WebHydration, c as decodeWireEnvelope, i as FRAMEWORK_PROTOCOL_VERSION, l as getFrameworkBuildId, n as ServerControllerProxy, o as WireDecodeResult, r as ServerControllerRequest, s as WireEnvelope, t as SERVER_CONTROLLER_PATH } from "./server-controller-proxy-CFdU_nGs.mjs";
|
|
6
6
|
export { ACTION_KINDS, type Action, ActionDispatcher, type ActionHandler, type ActionInvocation, type AfterLoadGuard, AnyOperation, AppDefinition, AppSnapshot, type AsyncMapper, type AsyncStorage, BASE_PAGE_FIELDS, BaseController, type BasePage, type BeforeCommitPolicy, type BeforeCommitResult, type BeforeLoadGuard, type BeforeNavigatePolicy, type BeforeNavigateResult, type CompiledPath, CompositeEventRecorder, CompositeLogger, CompositeLoggerFactory, type CompoundAction, ConsoleEventRecorder, ConsoleLogger, ConsoleLoggerFactory, Container, ControllerContext, type ControllerFailure, type ControllerInput, DEFAULT_NAV_PARAM, DEP_KEYS, type DenyResult, type DnsLookup, type EventRecorder, ExecutionContext, ExecutionError, ExecutionErrorCode, ExecutionHandle, type ExternalUrlAction, type ExtractParamNames, FINESOFT_PUBLIC, FRAMEWORK_PROTOCOL_VERSION, type FeatureFlags, type FeatureFlagsProvider, type FlowAction, type FullStateCodecOptions, type HostCheckResult, HostGuardError, HttpClient, type HttpClientConfig, HttpError, type HttpRequestOptions, Implementation, type ImpressionEntry, type InferOutput, type InferParams, type InferQuery, type Intent, Invocation, type LeafNode, type ListOptions, type LoadPageOptions, type LocaleAttributes, type LocaleInfo, type LogFilter, type Logger, type LoggerFactory, LruMap, type Mapper, type MessagesLoader, type MessagesLoaderContext, type MetricsFieldsProvider, type MiddlewareResult, ModuleDefinition, type MultiValueSchema, NAVIGATION_NODE_KINDS, type NavigationCodec, type NavigationCommitContext, NavigationCommitError, type NavigationContext, type NavigationContextInput, NavigationError, type NavigationNode, type NavigationNodeKind, type NavigationPath, type NavigationPathStep, type NavigationRouterLike, type NavigationScopedState, type NavigationSnapshot, NavigationSummary, type NavigationTransactionContext, type NextResult, type None, type NumOptions, Operation, OperationHandler, OperationPolicy, type Optional, type PageControllerDefinition, PageControllerInput, type PageLoadResult, type PageReference, type PageRoute, type ParamSchema, type ParamsFor, type PathDescriptor, type PathParameterDescriptor, type PathParams, type PlatformInfo, type PluralCategory, type PluralRuleProvider, type PostLoadContext, type PrefetchedIntent, PrefetchedIntents, type Provider, type ProviderContext, type PublicProjection, type PublicValueCodec, QueryCache, type QuerySchemaMap, type RedirectResult, type RenderMode, type ReportCallback, ReportingLogger, ReportingLoggerFactory, type ReportingLoggerOptions, type RequestInterceptor, type ResolvedDestination, type ResponseInterceptor, type RewriteResult, type RouteAddOptions, type RouteDefinition, type RouteInput, type RouteInputFor, type RouteIntent, type RouteMatch, type RouteParams, Router, RuntimeHandle, RuntimeOptions, SERVER_CONTROLLER, SERVER_CONTROLLER_PATH, SERVER_REQUEST, SESSION_DEFAULT_KEY, SESSION_DEFAULT_VERSION, SPLIT_VISIBILITIES, type SafeErrorPageOptions, type SecureFetchOptions, type SerializedLeaf, type SerializedNavigation, type SerializedSplit, type SerializedSplitColumn, type SerializedStack, type SerializedTabs, ServerControllerProxy, type ServerControllerRequest, ServerRequestState, SessionError, type SessionErrorContext, type SessionFailure, type SessionLoadResult, type SessionNavigation, type SessionRestoreResult, type SessionSlice, type SessionSnapshot, type SessionStateProvider, type SessionStore, type SessionStoreOptions, type SessionWriteResult, SimpleTranslator, type SimpleTranslatorOptions, type SplitColumn, type SplitColumnInit, type SplitNode, type SplitVisibility, type StackNode, type StandardIssue, type StandardResult, type StandardSchemaV1, type Storage, StorageUnavailableError, type StrOptions, type StripOptional, type TabsInit, type TabsNode, type TargetGuardOptions, type TextDirection, type Token, type TranslationMessages, type Translator, type TreeAction, ViewEntry, ViewProps, VoidEventRecorder, type WebAppDefinition, WebAppView, type WebConfiguration, type WebHydration, type WebRuntime, type WebRuntimeOptions, type WebSession, type WebSessionOptions, type WireDecodeResult, type WireEnvelope, WithFieldsRecorder, bool, buildUrl, classifyHost, classifyUrl, collectAllLeaves, collectLeafKeys, collectVisibleDestinations, compilePath, controllerContext, createActiveLeafCodec, createFullStateCodec, createHydrationDigest, createNavigationScopedState, createRuntime, createSessionStore, createToken, createWebRuntime, createWebSession, decodeNavigationTreeParam, decodeSnapshot, decodeWireEnvelope, defineApp, defineModule, defineOperation, definePage, defineWebApp, deny, deserializeNavigation, detectPlatform, encodeNavigationTreeParam, encodeSnapshot, enforceHostGuard, englishPlural, executionErrorFromHttp, fetchWithRedirects, findNearestStack, findNode, generateUuid, getBaseUrl, getFrameworkBuildId, getLocaleAttributes, getPublicFields, getTextDirection, getWebPlan, implementController, implementOperation, int, interpolate, isCompoundAction, isExternalUrlAction, isFlowAction, isLeafNode, isMultiValueSchema, isNone, isPublicMarked, isRtl, isSome, isSplitNode, isStackNode, isTabsNode, leaf, list, loadPage, makeExternalUrlAction, makeFlowAction, makeLocaleInfo, makeSchema, mapEach, mapNavigationLeaves, markPublic, next, num, oneOf, optional, parseCookieString, pipe, pipeAsync, pop, popTo, popToRoot, provide, push, redirect, removeHost, removeQueryParams, removeScheme, replaceTop, resolveActivePath, resolveConfiguredMessages, resolveInitialNavigation, resolveLocaleFromUrl, resolveMessages, resolvePluralKey, resourceKey, rewrite, route, runAfterLoadGuards, runBeforeLoadGuards, safeErrorPage, secureFetch, selectColumn, selectTab, serializeNavigation, serializeNavigationStable, setVisibility, split, stableStringify, stack, str, tabs, uuid, visibleSplitColumns, withDefault };
|
package/dist/web.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $ as isLeafNode, A as createActiveLeafCodec, At as getLocaleAttributes, B as findNode, Bt as secureFetch, C as runBeforeLoadGuards, Ct as defineApp, D as SERVER_REQUEST, Dt as implementOperation, E as SERVER_CONTROLLER, Et as implementController, F as serializeNavigation, Ft as englishPlural, G as push, Gt as ReportingLoggerFactory, H as pop, Ht as enforceHostGuard, I as serializeNavigationStable, It as interpolate, J as selectColumn, Jt as CompositeLogger, K as replaceTop, Kt as ConsoleLogger, L as collectAllLeaves, Lt as resolvePluralKey, M as decodeNavigationTreeParam, Mt as isRtl, N as encodeNavigationTreeParam, Nt as makeLocaleInfo, O as controllerContext, Ot as SimpleTranslator, P as deserializeNavigation, Pt as resolveLocaleFromUrl, Q as resourceKey, Qt as Container, R as collectVisibleDestinations, Rt as generateUuid, S as runAfterLoadGuards, St as createRuntime, T as getWebPlan, Tt as defineOperation, U as popTo, Ut as stableStringify, V as mapNavigationLeaves, Vt as fetchWithRedirects, W as popToRoot, Wt as ReportingLogger, X as setVisibility, Xt as isMultiValueSchema, Y as selectTab, Yt as CompositeLoggerFactory, Z as visibleSplitColumns, Zt as list, _ as SERVER_CONTROLLER_PATH, _t as isExternalUrlAction, a as createSessionStore, at as stack, b as decodeWireEnvelope, bt as makeFlowAction, c as decodeSnapshot, ct as NavigationError, d as createWebSession, dt as createHydrationDigest, et as isSplitNode, f as SESSION_DEFAULT_KEY, ft as PrefetchedIntents, g as loadPage, gt as isCompoundAction, h as StorageUnavailableError, ht as ACTION_KINDS, i as createWebRuntime, it as split, j as createFullStateCodec, jt as getTextDirection, k as DEFAULT_NAV_PARAM, kt as resolveMessages, l as encodeSnapshot, lt as SPLIT_VISIBILITIES, m as SessionError, mt as ActionDispatcher, n as definePage, nt as isTabsNode, o as collectLeafKeys, ot as tabs, p as SESSION_DEFAULT_VERSION, pt as Router, q as resolveActivePath, qt as ConsoleLoggerFactory, r as resolveInitialNavigation, rt as leaf, s as createNavigationScopedState, st as NAVIGATION_NODE_KINDS, t as parseCookieString, tt as isStackNode, u as NavigationCommitError, ut as route, v as ServerControllerProxy, vt as isFlowAction, w as defineWebApp, wt as defineModule, x as getFrameworkBuildId, xt as provide, y as FRAMEWORK_PROTOCOL_VERSION, yt as makeExternalUrlAction, z as findNearestStack, zt as detectPlatform } from "./src-
|
|
2
|
-
import { C as bool, D as str, E as oneOf, O as uuid, S as withDefault, T as num, _ as mapEach, a as safeErrorPage, b as HttpClient, c as ConsoleEventRecorder, d as getBaseUrl, f as removeHost, g as isSome, h as isNone, i as rewrite, k as makeSchema, l as CompositeEventRecorder, m as removeScheme, n as next, o as WithFieldsRecorder, p as removeQueryParams, r as redirect, s as VoidEventRecorder, t as deny, u as buildUrl, v as pipe, w as int, x as optional, y as pipeAsync } from "./types-
|
|
3
|
-
import { i as HttpError, n as classifyUrl, r as HostGuardError, t as classifyHost } from "./host-guard-
|
|
1
|
+
import { $ as isLeafNode, A as createActiveLeafCodec, At as getLocaleAttributes, B as findNode, Bt as secureFetch, C as runBeforeLoadGuards, Ct as defineApp, D as SERVER_REQUEST, Dt as implementOperation, E as SERVER_CONTROLLER, Et as implementController, F as serializeNavigation, Ft as englishPlural, G as push, Gt as ReportingLoggerFactory, H as pop, Ht as enforceHostGuard, I as serializeNavigationStable, It as interpolate, J as selectColumn, Jt as CompositeLogger, K as replaceTop, Kt as ConsoleLogger, L as collectAllLeaves, Lt as resolvePluralKey, M as decodeNavigationTreeParam, Mt as isRtl, N as encodeNavigationTreeParam, Nt as makeLocaleInfo, O as controllerContext, Ot as SimpleTranslator, P as deserializeNavigation, Pt as resolveLocaleFromUrl, Q as resourceKey, Qt as Container, R as collectVisibleDestinations, Rt as generateUuid, S as runAfterLoadGuards, St as createRuntime, T as getWebPlan, Tt as defineOperation, U as popTo, Ut as stableStringify, V as mapNavigationLeaves, Vt as fetchWithRedirects, W as popToRoot, Wt as ReportingLogger, X as setVisibility, Xt as isMultiValueSchema, Y as selectTab, Yt as CompositeLoggerFactory, Z as visibleSplitColumns, Zt as list, _ as SERVER_CONTROLLER_PATH, _t as isExternalUrlAction, a as createSessionStore, at as stack, b as decodeWireEnvelope, bt as makeFlowAction, c as decodeSnapshot, ct as NavigationError, d as createWebSession, dt as createHydrationDigest, et as isSplitNode, f as SESSION_DEFAULT_KEY, ft as PrefetchedIntents, g as loadPage, gt as isCompoundAction, h as StorageUnavailableError, ht as ACTION_KINDS, i as createWebRuntime, it as split, j as createFullStateCodec, jt as getTextDirection, k as DEFAULT_NAV_PARAM, kt as resolveMessages, l as encodeSnapshot, lt as SPLIT_VISIBILITIES, m as SessionError, mt as ActionDispatcher, n as definePage, nt as isTabsNode, o as collectLeafKeys, ot as tabs, p as SESSION_DEFAULT_VERSION, pt as Router, q as resolveActivePath, qt as ConsoleLoggerFactory, r as resolveInitialNavigation, rt as leaf, s as createNavigationScopedState, st as NAVIGATION_NODE_KINDS, t as parseCookieString, tt as isStackNode, u as NavigationCommitError, ut as route, v as ServerControllerProxy, vt as isFlowAction, w as defineWebApp, wt as defineModule, x as getFrameworkBuildId, xt as provide, y as FRAMEWORK_PROTOCOL_VERSION, yt as makeExternalUrlAction, z as findNearestStack, zt as detectPlatform } from "./src-D_Bzbr80.mjs";
|
|
2
|
+
import { C as bool, D as str, E as oneOf, O as uuid, S as withDefault, T as num, _ as mapEach, a as safeErrorPage, b as HttpClient, c as ConsoleEventRecorder, d as getBaseUrl, f as removeHost, g as isSome, h as isNone, i as rewrite, k as makeSchema, l as CompositeEventRecorder, m as removeScheme, n as next, o as WithFieldsRecorder, p as removeQueryParams, r as redirect, s as VoidEventRecorder, t as deny, u as buildUrl, v as pipe, w as int, x as optional, y as pipeAsync } from "./types-DD09OkGZ.mjs";
|
|
3
|
+
import { i as HttpError, n as classifyUrl, r as HostGuardError, t as classifyHost } from "./host-guard-DX4e3-45.mjs";
|
|
4
4
|
import { n as ExecutionError, r as executionErrorFromHttp, t as compilePath } from "./path-CGFl2w7D.mjs";
|
|
5
5
|
import { a as isPublicMarked, i as getPublicFields, n as BASE_PAGE_FIELDS, o as markPublic, r as FINESOFT_PUBLIC, s as BaseController, t as resolveConfiguredMessages } from "./messages-CAt2QdGr.mjs";
|
|
6
6
|
import { t as LruMap } from "./lru-map-BKoUAySU.mjs";
|
package/dist/worker.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as HttpHost, i as HttpHandlerOptions, l as runManagedTask, o as ManagedTask, r as HttpHandler, s as createHttpHandler } from "./http-
|
|
1
|
+
import { a as HttpHost, i as HttpHandlerOptions, l as runManagedTask, o as ManagedTask, r as HttpHandler, s as createHttpHandler } from "./http-B8r7MWao.mjs";
|
|
2
2
|
export { type HttpHandler, type HttpHandlerOptions, type HttpHost, type ManagedTask, createHttpHandler, runManagedTask };
|
|
@@ -199,6 +199,8 @@ Generated page inputs use `ControllerContext` or `ServerControllerContext`. Port
|
|
|
199
199
|
|
|
200
200
|
A server controller module may export controller classes and types only. Its local runtime imports are also private to the server; importing these dependencies from client code fails. Use `import type` for shared contracts and separate modules for client implementations. Keep secret-dependent construction inside the protected module or server configuration, rather than arguments to the shared `create` factory.
|
|
201
201
|
|
|
202
|
+
The compiler recognizes module-scope class declarations, variable-bound and default class expressions, transparent parentheses/type assertions, local aliases, namespace imports and static re-exports. Unsupported factories or computed selections involving the raw server base fail the browser build instead of returning original source. Prefer a module-scope class when that diagnostic occurs. Pure re-export barrels and ordinary consumers of the generated controller references remain shared.
|
|
203
|
+
|
|
202
204
|
Client bundles and source maps omit the replaced implementation. The development plugin rejects raw controller assets and direct browser source requests for protected dependencies. It indexes modules once, caches ASTs, and reanalyzes changed files. Dependencies remain protected for the lifetime of a development server; restart when intentionally moving one back into shared code. Computed file paths, `public/` assets, and independently copied source are outside the static import boundary. Development servers still belong on trusted development networks.
|
|
203
205
|
|
|
204
206
|
Use the framework Vite plugin and a request host such as Node or Worker. Static-only hosting cannot run the remote endpoint. The endpoint loads registered server page controllers; it does not expose arbitrary methods or replace explicit login/registration command endpoints.
|
package/docs/06-http-client.md
CHANGED
|
@@ -34,10 +34,14 @@ const api = new UserApi({ baseUrl: "https://api.example.com", fetch, ...nodeSafe
|
|
|
34
34
|
|
|
35
35
|
Browser code may construct the same class with an absolute API URL, its chosen fetch implementation and `validateDns: false`. That explicitly gives DNS resolution to the browser. Do not silently disable a required server capability. Internal/loopback targets are blocked by default; host configuration must deliberately opt in where required.
|
|
36
36
|
|
|
37
|
+
The shared literal/connection policy also rejects the non-public benchmark range `198.18.0.0/15`, including mapped IPv6 forms. For hosts without a DNS policy, `trustedOrigins` lists exact origins that the application explicitly trusts without DNS checks; all other hostnames still require a resolver. These exceptions are checked on every redirect and do not allow private IP literals. Cloudflare adapter configuration is described in [Deployment hosts](./09-server-and-deployment.md).
|
|
38
|
+
|
|
37
39
|
The Node entry includes its connection transport as a lazy chunk; consumers need no extra transport package. Standard Node/Vercel/Netlify, development and preview hosts use `nodeSafeFetchOptions`: all DNS answers are checked inside connection creation, and those exact addresses reach the socket while hostname, TLS SNI, cancellation and pooling remain intact. The pool loads lazily and stays outside browser/Worker graphs. Custom Node fetch implementations must honor Undici's `dispatcher` option. `nodeDnsLookup` alone is only a preflight and does not prevent a DNS change before connection.
|
|
38
40
|
|
|
39
41
|
Protected fetch checks each redirect, follows at most 20 hops and removes authentication/cookie headers across origins. Explicit `manual` / `error` modes retain their meaning. Opaque browser redirects are rejected because their destination is unreadable. Redirects requiring replay of `Request.body` or a streamed body are rejected without unbounded tee buffering; use a replayable `RequestInit.body` (such as a string) or the final URL. `allowInternalHosts: true` explicitly opts out of these protections.
|
|
40
42
|
|
|
41
43
|
For scoped business services, declare a typed provider and acquire it with `context.get(token)`; see [Dependencies](./07-di-container.md). Bind the invocation's fetch and signal so request cancellation propagates. A cancelled command may already have performed a write; cancellation is not rollback. The operation runtime does not implicitly retry or cache commands.
|
|
42
44
|
|
|
45
|
+
The full-template `ApiClient` forwards the entire configuration before applying its `/api` and JSON-header defaults. Subclasses should preserve `wrapFetch`, `context`, `trustedOrigins` and interceptors together with the other options; copying `validateDns: false` without its Node transport wrapper removes connection-address protection.
|
|
46
|
+
|
|
43
47
|
Request and response interceptors run in registration order. `HttpError` represents non-success HTTP results. The generic result type describes expected data; validate untrusted response payloads at the business boundary when necessary. The lower-level protected methods are `get`, `post`, `put`, `del` and `request`; `get`/`del` accept query parameters before request options.
|
|
@@ -77,6 +77,19 @@ Node’s host requires `@hono/node-server`. Worker fetch has no Node compatibili
|
|
|
77
77
|
|
|
78
78
|
When `setup` is a module path, that module must `export default` its setup function. Development, preview and generated hosts use this explicit export; named functions are not discovered automatically.
|
|
79
79
|
|
|
80
|
+
Setup runs before declared proxies, so `app.use(...)` authentication covers proxy requests as well as application routes. Register guards before terminal handlers in setup. A terminal setup route can override a proxy on the same path. A configured setup that fails to load aborts preview startup. Proxy `auth` supplies an upstream credential; it does not authenticate the incoming caller. Proxies without application guards remain public.
|
|
81
|
+
|
|
82
|
+
Cloudflare output fails closed for arbitrary `SAFE_FETCH` hostnames because the adapter has no connection-time DNS enforcement. To use a known trusted API, configure exact origins explicitly:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import { cloudflareAdapter, finesoftFrontViteConfig } from "@finesoft/front";
|
|
86
|
+
finesoftFrontViteConfig({
|
|
87
|
+
adapter: cloudflareAdapter({ trustedOrigins: ["https://api.example.com"] }),
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This is an explicit trust exception for those origins, not DNS pinning. The origin includes scheme and port; no wildcards, paths or prefix matching are used. Redirects are checked again and private IP literals remain blocked. Relative in-process API calls retain their behavior. The `"cloudflare"` adapter shortcut has an empty trusted-origin list.
|
|
92
|
+
|
|
80
93
|
## Static hosting boundary
|
|
81
94
|
|
|
82
95
|
`staticAdapter` reads built `render.routes` by default, uses the same SSR host to generate HTML and awaits cleanup. `dynamicRoutes` supplies concrete dynamic paths; `routesExport` is an explicit extension. Discovery and rendering failures fail the build. Plain HTML cannot express redirects, error status, Set-Cookie or custom HTTP response headers, so the adapter rejects these responses; choose a request host when they are required.
|
package/docs/11-navigation.md
CHANGED
|
@@ -205,6 +205,8 @@ Admission receives `from`, candidate `tree`, stable `transitionId`, active `exec
|
|
|
205
205
|
|
|
206
206
|
A denial returns an uncommitted snapshot with `rejection`, including for empty trees. Session restore rejects it before replacing scopes or slices. Initial browser denial renders the error without committing navigation or recording a page visit; later denial preserves the displayed draft. Both flat and navigation SSR honor these policies and emit no rejected page data or public-cache permission. CSR shells still defer navigation to the browser.
|
|
207
207
|
|
|
208
|
+
If any visible page fails during initial navigation, the whole candidate stays uncommitted and only its error presentation is exposed. Successful siblings are withheld from the native view and SSR hydration data until a successful retry passes the commit boundary. Initial browser redirects that hand off to an external site likewise withhold successful siblings while the browser leaves. Page failures do not invoke `beforeCommit`; later failed navigation preserves the previously committed view.
|
|
209
|
+
|
|
208
210
|
Owned back/forward rejection compensates to the committed history entry and restores its scroll identity. Additive history metadata preserves ownership and position across reloads. Entries without compatible ownership metadata are diagnosed; the framework cannot infer a safe traversal distance for external entries.
|
|
209
211
|
|
|
210
212
|
Low-level hosts configuring `createWebSession({ createContext })` return a `NavigationContext` directly. The execution supplies its DI container and cancellation signal; request cookies and headers stay in the host context. The session uses the application's `getErrorPage` unless explicitly overridden.
|
|
@@ -15,3 +15,27 @@ await runtime.execute(operation, input, {
|
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Use `provide({ token, lifetime: "scope", create, dispose })` for per-request resources. Concurrent initialization deduplicates and a failed initialization may retry. Runtime-scoped providers cannot depend on request-scoped values. Externally supplied values remain external unless owned explicitly; created values are released in dependency order. A command is not retried or cached automatically; cancellation does not roll back an already applied mutation.
|
|
18
|
+
|
|
19
|
+
## Query cache partitions
|
|
20
|
+
|
|
21
|
+
Cached queries with invocation bindings or an invocation-specific `fetch` default to execution-local reuse, even with `scope: "runtime"`. Bindings can contain opaque resources and tenant-specific providers, so the runtime does not serialize them into a shared key. Web and SSR hosts also supply bindings and therefore use this isolation by default. Queries without invocation bindings/fetch retain runtime reuse partitioned by identity, locale and input.
|
|
22
|
+
|
|
23
|
+
To share completed results across executions, explicitly declare the complete trusted security partition:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
const tenantSummary = defineOperation({
|
|
27
|
+
id: "tenant-summary",
|
|
28
|
+
kind: "query",
|
|
29
|
+
cache: {
|
|
30
|
+
ttlMs: 10_000,
|
|
31
|
+
partition: (context) => {
|
|
32
|
+
const tenant = context.bindings.tenant;
|
|
33
|
+
if (typeof tenant !== "string") throw new ExecutionError("configuration");
|
|
34
|
+
return tenant;
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
handler: loadTenantSummary,
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The partition must cover every result-affecting binding and fetch authority in addition to the existing identity, locale and input key. A constant partition asserts that the result is independent of all other invocation state. `cache.key(input)` still controls only the input key; it cannot enable shared caching by itself. Policies run before every cache hit, invalidation still applies across partitions, and `scope: "execution"` always remains local.
|
|
@@ -150,6 +150,8 @@ export class AccountController extends BaseServerController {
|
|
|
150
150
|
|
|
151
151
|
服务端 Controller 模块只导出 Controller 类和类型。该模块的本地运行时依赖也属于服务端边界;客户端直接导入这些依赖会报错。共享类型请使用 `import type`,共享的客户端实现放在独立模块。构造函数内的依赖创建属于受保护模块;不要在共享的 `create` 工厂参数、共享配置或页面组件中写入机密。
|
|
152
152
|
|
|
153
|
+
编译器识别模块级类声明、绑定到变量或默认导出的类表达式、括号/类型断言、本地别名、命名空间导入及静态转导出。涉及原始服务端基类但无法安全代理的工厂或计算属性形式会令浏览器构建报错,不再直接返回原始源码;出现该诊断时改用模块级类。纯转导出模块和使用生成代理的普通业务模块仍可共享。
|
|
154
|
+
|
|
153
155
|
生产客户端 JS / source map 不包含被替换的实现。开发服务拒绝 Controller 的原始资源导入和受保护依赖的源码请求。模块与依赖索引在启动时建立,后续缓存 AST,只重新分析变更文件;开发期间已识别的私有依赖保持保护,若要将它迁回共享模块,应重启开发服务。动态计算的文件路径、`public/` 资源和另行复制的源码不属于静态导入边界。开发服务器仍只用于受信任的开发环境。
|
|
154
156
|
|
|
155
157
|
使用框架 Vite 插件及具有 SSR 请求处理能力的 Node / Worker 等宿主。纯静态托管没有远程执行端点。此入口用于注册的服务端页面 Controller,不会自动发布任意方法或代替登录、注册等命令端点。
|