@jimhoyd/urlcode 0.4.0-alpha.1 → 0.4.0-alpha.2
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/.claude/skills/urlcode-authoring/SKILL.md +24 -8
- package/.claude/skills/urlcode-operations/SKILL.md +10 -16
- package/.claude-plugin/marketplace.json +1 -1
- package/README.md +75 -62
- package/ROADMAP.md +61 -16
- package/SECURITY.md +23 -8
- package/dist/BUILD-MANIFEST.json +38 -43
- package/dist/agents-guide.js +18 -18
- package/dist/build-static.js +134 -0
- package/dist/capabilities.js +85 -31
- package/dist/capability-query.js +0 -1
- package/dist/cli.js +23 -31
- package/dist/compliance-rules/baseline.js +2 -10
- package/dist/compliance-rules/privacy.js +5 -16
- package/dist/compliance-rules/shared.js +0 -2
- package/dist/compliance.js +6 -8
- package/dist/config.js +15 -8
- package/dist/context.js +9 -10
- package/dist/examples.js +2 -2
- package/dist/explain-cli.js +3 -3
- package/dist/explain.js +5 -6
- package/dist/extensions.js +61 -2
- package/dist/function-sources.js +34 -2
- package/dist/function-worker.js +3 -1
- package/dist/functions.js +84 -13
- package/dist/guest-api.js +29 -3
- package/dist/index.js +3 -6
- package/dist/manifest.js +5 -7
- package/dist/mcp.js +1 -1
- package/dist/observability.js +1 -21
- package/dist/policies/cache.js +8 -3
- package/dist/policy.js +28 -9
- package/dist/project-tests.js +3 -3
- package/dist/readiness.js +32 -9
- package/dist/router.js +5 -7
- package/dist/runtime.js +77 -58
- package/dist/sandbox.js +48 -0
- package/dist/scaffold.js +0 -0
- package/dist/scripts/operational-drills.js +12 -54
- package/dist/server.js +3 -29
- package/dist/tooling.js +1 -1
- package/dist/trusted-functions.js +210 -0
- package/dist/types/build-static.d.ts +43 -0
- package/dist/types/capabilities.d.ts +14 -5
- package/dist/types/compliance-rules/shared.d.ts +0 -2
- package/dist/types/compliance.d.ts +0 -3
- package/dist/types/config.d.ts +2 -1
- package/dist/types/context.d.ts +2 -1
- package/dist/types/examples.d.ts +1 -1
- package/dist/types/extensions.d.ts +55 -0
- package/dist/types/function-sources.d.ts +4 -0
- package/dist/types/functions.d.ts +48 -5
- package/dist/types/guest-api.d.ts +1 -0
- package/dist/types/index.d.ts +3 -6
- package/dist/types/manifest.d.ts +1 -3
- package/dist/types/observability.d.ts +1 -14
- package/dist/types/project-tests.d.ts +1 -2
- package/dist/types/readiness.d.ts +10 -3
- package/dist/types/router.d.ts +2 -1
- package/dist/types/runtime.d.ts +0 -27
- package/dist/types/sandbox.d.ts +12 -0
- package/dist/types/scaffold.d.ts +0 -2
- package/dist/types/server.d.ts +1 -4
- package/dist/types/tooling.d.ts +3 -3
- package/dist/types/trusted-functions.d.ts +29 -0
- package/dist/types/types.d.ts +14 -7
- package/dist/types/verify-deployment.d.ts +2 -2
- package/dist/types.js +17 -4
- package/dist/typescript-authoring.js +55 -17
- package/dist/verify-deployment.js +3 -3
- package/docs/AI-AUTHORING.md +104 -9
- package/docs/AWS.md +4 -4
- package/docs/BEST-PRACTICES.md +3 -2
- package/docs/CAPABILITIES.md +29 -16
- package/docs/CAPACITY.md +128 -31
- package/docs/CLOUDFLARE.md +1 -2
- package/docs/COMPLIANCE.md +6 -9
- package/docs/DEPLOYMENT-CHECKS.md +1 -1
- package/docs/EXTENSIONS.md +183 -11
- package/docs/FRAMEWORK.md +35 -19
- package/docs/FUNCTION-SECURITY.md +129 -32
- package/docs/INSTALL.md +0 -5
- package/docs/LOAD-TESTING.md +4 -4
- package/docs/MIDDLEWARE.md +27 -16
- package/docs/MONITORING.md +2 -19
- package/docs/NEXT-PHASE-PLAN.md +12 -4
- package/docs/NEXT-STEPS.md +259 -40
- package/docs/OBSERVABILITY.md +7 -16
- package/docs/OPEN-DECISIONS.md +212 -0
- package/docs/OPERATIONAL-PROOF.md +26 -30
- package/docs/OPERATIONS.md +23 -32
- package/docs/POLICIES.md +15 -4
- package/docs/PRERENDER.md +2 -2
- package/docs/PROJECT-DIRECTION.md +34 -9
- package/docs/README.md +13 -11
- package/docs/RELEASE-READINESS.md +49 -29
- package/docs/RELEASE-SECURITY.md +89 -3
- package/docs/RESILIENCE.md +16 -15
- package/docs/ROUTING.md +8 -10
- package/docs/SANDBOX-REVIEW.md +19 -6
- package/docs/SCAFFOLDING.md +0 -2
- package/docs/SECURITY-AUDIT.md +40 -0
- package/docs/SPECIFICATION.md +60 -26
- package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +287 -0
- package/docs/SPIKE-BUSINESS-SUITE.md +8 -0
- package/docs/SPIKE-CORE-LAYERING.md +337 -0
- package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +209 -0
- package/docs/SPIKE-EXTENSION-MODEL.md +2 -2
- package/docs/SPIKE-EXTENSIONS.md +5 -0
- package/docs/SPIKE-LAMBDA-COMPILE.md +4 -2
- package/docs/SPIKE-MONOREPO.md +322 -0
- package/docs/STARTERS.md +1 -1
- package/docs/STATIC.md +94 -0
- package/docs/TOOLING.md +13 -9
- package/docs/TUNNELS.md +0 -3
- package/docs/TYPESCRIPT-AUTHORING.md +27 -12
- package/docs/TYPESCRIPT.md +25 -4
- package/docs/USABILITY-REVIEW.md +7 -1
- package/docs/VERCEL.md +4 -5
- package/docs/VERSION-ALIGNMENT.md +205 -0
- package/docs/YAML-GUIDE.md +0 -3
- package/docs/YAML-REFERENCE.md +16 -6
- package/docs/policies/cache.md +13 -0
- package/examples/assets/example.yaml +1 -1
- package/examples/aws/example.yaml +1 -1
- package/examples/cloudflare/example.yaml +1 -1
- package/examples/conditions/example.yaml +1 -1
- package/examples/cookbook/example.yaml +1 -1
- package/examples/cookbook/middleware/bucket.mjs +12 -2
- package/examples/cookbook/middleware/locale.mjs +7 -3
- package/examples/egress/example.yaml +1 -1
- package/examples/extensions/example.yaml +1 -1
- package/examples/prerender/README.md +2 -2
- package/examples/prerender/example.yaml +1 -1
- package/examples/provider-conformance/example.yaml +1 -1
- package/examples/vercel/example.yaml +1 -1
- package/llms-full.txt +594 -219
- package/llms.txt +23 -12
- package/package.json +10 -3
- package/packaging/claude-plugin/.claude-plugin/plugin.json +1 -1
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +24 -8
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +10 -16
- package/recipes/authenticated-json-api/recipe.yaml +1 -1
- package/recipes/contact-form/recipe.yaml +1 -1
- package/recipes/cors-api/recipe.yaml +1 -1
- package/recipes/health-page/recipe.yaml +1 -1
- package/recipes/json-api/recipe.yaml +1 -1
- package/recipes/middleware/middleware/bucket.mjs +12 -2
- package/recipes/middleware/middleware/locale.mjs +7 -3
- package/recipes/middleware/recipe.yaml +1 -1
- package/recipes/protected-download/recipe.yaml +1 -1
- package/recipes/redirect/recipe.yaml +1 -1
- package/recipes/static-plus-api/recipe.yaml +1 -1
- package/recipes/typescript/README.md +2 -1
- package/recipes/typescript/recipe.yaml +1 -1
- package/recipes/webhook-receiver/README.md +5 -1
- package/recipes/webhook-receiver/recipe.yaml +2 -1
- package/recipes/webhook-receiver/urlcode.yaml +7 -0
- package/schemas/recipe.schema.json +4 -3
- package/schemas/urlcode.schema.json +14 -41
- package/skills/urlcode/SKILL.md +29 -8
- package/starters/default/AGENTS.md +18 -18
- package/starters/default/urlcode.yaml +0 -1
- package/dist/link-api.js +0 -136
- package/dist/link-cli.js +0 -141
- package/dist/link-events.js +0 -76
- package/dist/link-records.js +0 -31
- package/dist/link-store-worker.js +0 -150
- package/dist/link-store.js +0 -250
- package/dist/management-policy.js +0 -40
- package/dist/sqlite-version.js +0 -6
- package/dist/types/link-api.d.ts +0 -30
- package/dist/types/link-cli.d.ts +0 -37
- package/dist/types/link-events.d.ts +0 -27
- package/dist/types/link-records.d.ts +0 -11
- package/dist/types/link-store-worker.d.ts +0 -1
- package/dist/types/link-store.d.ts +0 -130
- package/dist/types/management-policy.d.ts +0 -8
- package/dist/types/sqlite-version.d.ts +0 -1
- package/docs/DYNAMIC-LINKS.md +0 -61
- package/docs/MANAGEMENT-SECURITY.md +0 -82
- package/docs/links/cli.md +0 -110
- package/docs/links/limits.md +0 -175
- package/docs/links/management-api.md +0 -80
- package/docs/links/pools.md +0 -75
- package/docs/links/setup.md +0 -135
- package/docs/yaml/links.md +0 -30
- package/examples/live-links/README.md +0 -11
- package/examples/live-links/example.yaml +0 -21
- package/examples/live-links/tests/requests.json +0 -6
- package/examples/live-links/urlcode.yaml +0 -16
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
import { Worker } from 'node:worker_threads';
|
|
2
|
-
import type { FunctionRoute, FunctionSources } from './function-sources.ts';
|
|
2
|
+
import type { FunctionDefinition, FunctionRoute, FunctionSources } from './function-sources.ts';
|
|
3
3
|
import type { HandlerResult, HeaderPair } from './http-response.ts';
|
|
4
4
|
import type { ParameterValue, RequestContext } from './match.ts';
|
|
5
5
|
import type { LogFn } from './types.ts';
|
|
6
6
|
import type { GuestRequestPayload } from './guest-api.ts';
|
|
7
7
|
export type { FunctionDefinition, FunctionRoute } from './function-sources.ts';
|
|
8
8
|
export type { GuestRequestPayload, GuestResponsePayload } from './guest-api.ts';
|
|
9
|
-
|
|
9
|
+
/** A module entry point the sandbox must load: an absolute source file path
|
|
10
|
+
* (already resolved and validated, e.g. via `functionFile()`) plus which
|
|
11
|
+
* export of it needs to be reachable. The same shape a `FunctionDefinition`
|
|
12
|
+
* already uses for `function`/`middleware` routes. */
|
|
13
|
+
export type SandboxEntry = FunctionDefinition;
|
|
14
|
+
/** What one `SandboxPool.execute()` call invokes: the same `{source, export}`
|
|
15
|
+
* shape as a `SandboxEntry`, naming one of the pool's declared entries. */
|
|
16
|
+
export type SandboxTarget = FunctionDefinition;
|
|
17
|
+
/** `entry` runs last (the route's `function`/handler); `chain` runs first, in
|
|
18
|
+
* order, each with `(request, context, next)` — the same wrap/middleware
|
|
19
|
+
* semantics `__invokePipeline` already gives sandboxed routes. Neither is
|
|
20
|
+
* required: an empty invocation with a `native` reply just returns it. */
|
|
21
|
+
export interface SandboxInvocation {
|
|
22
|
+
entry?: SandboxTarget | undefined;
|
|
23
|
+
chain?: SandboxTarget[] | undefined;
|
|
24
|
+
}
|
|
25
|
+
export interface SandboxPoolOptions {
|
|
10
26
|
root?: string | undefined;
|
|
11
27
|
snapshot?: FunctionSources | undefined;
|
|
12
28
|
workers?: number | undefined;
|
|
@@ -14,6 +30,7 @@ export interface FunctionPoolOptions {
|
|
|
14
30
|
maxBytes?: number | undefined;
|
|
15
31
|
log?: LogFn | undefined;
|
|
16
32
|
}
|
|
33
|
+
export type FunctionPoolOptions = SandboxPoolOptions;
|
|
17
34
|
export interface FunctionWorkerData {
|
|
18
35
|
sources: Record<string, string>;
|
|
19
36
|
dependencies: Record<string, string[]>;
|
|
@@ -52,6 +69,7 @@ export type FunctionWorkerMessage = {
|
|
|
52
69
|
headers: HeaderPair[];
|
|
53
70
|
body: Uint8Array;
|
|
54
71
|
nativeBody: boolean;
|
|
72
|
+
contentLength?: number;
|
|
55
73
|
} | {
|
|
56
74
|
id: string;
|
|
57
75
|
error: true;
|
|
@@ -67,9 +85,9 @@ interface Slot {
|
|
|
67
85
|
ready: boolean;
|
|
68
86
|
pending: Pending | null;
|
|
69
87
|
}
|
|
70
|
-
export declare class
|
|
88
|
+
export declare class SandboxPool {
|
|
71
89
|
root: string | undefined;
|
|
72
|
-
|
|
90
|
+
entries: SandboxEntry[];
|
|
73
91
|
preparedSnapshot: FunctionSources | undefined;
|
|
74
92
|
snapshot: FunctionSources | undefined;
|
|
75
93
|
restarts: Map<number, number>;
|
|
@@ -81,12 +99,37 @@ export declare class FunctionPool {
|
|
|
81
99
|
size: number;
|
|
82
100
|
slots: (Slot | undefined)[];
|
|
83
101
|
closed: boolean;
|
|
84
|
-
constructor(
|
|
102
|
+
constructor(entries: SandboxEntry[], { root, snapshot, workers, timeoutMs, maxBytes, log }?: SandboxPoolOptions);
|
|
85
103
|
start(): Promise<this>;
|
|
86
104
|
spawn(index: number): Promise<void>;
|
|
87
105
|
report(status: string, index: number, extra?: object): void;
|
|
88
106
|
scheduleRespawn(index: number): void;
|
|
89
107
|
get healthy(): boolean;
|
|
108
|
+
/** `invocation.entry` runs last (chain-wrapped), `invocation.chain` first, in
|
|
109
|
+
* declared order — the same `__invokePipeline` wrap/middleware discipline
|
|
110
|
+
* (`next()` callable at most once) the sandboxed route path already
|
|
111
|
+
* enforces; there is no second dispatch mechanism for this. Every entry and
|
|
112
|
+
* chain source named here must already be one of this pool's declared
|
|
113
|
+
* `entries` (constructor), or the worker's own module allowlist denies it. */
|
|
114
|
+
execute(invocation: SandboxInvocation, request: GuestRequestPayload, context: FunctionContext, native: HandlerResult | undefined): Promise<FunctionResult>;
|
|
115
|
+
close(): Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
export declare class FunctionPool {
|
|
118
|
+
routes: FunctionRoute[];
|
|
119
|
+
private pool;
|
|
120
|
+
constructor(routes: FunctionRoute[], options?: FunctionPoolOptions);
|
|
121
|
+
start(): Promise<this>;
|
|
90
122
|
execute(route: FunctionRoute, request: GuestRequestPayload, context: FunctionContext, native: HandlerResult | undefined): Promise<FunctionResult>;
|
|
123
|
+
scheduleRespawn(index: number): void;
|
|
91
124
|
close(): Promise<void>;
|
|
125
|
+
get healthy(): boolean;
|
|
126
|
+
get restarts(): Map<number, number>;
|
|
127
|
+
get restartTimers(): Set<NodeJS.Timeout>;
|
|
128
|
+
get slots(): (Slot | undefined)[];
|
|
129
|
+
get size(): number;
|
|
130
|
+
get closed(): boolean;
|
|
131
|
+
get snapshot(): FunctionSources | undefined;
|
|
132
|
+
get log(): LogFn;
|
|
133
|
+
get timeoutMs(): number;
|
|
134
|
+
get maxBytes(): number;
|
|
92
135
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
export { createRuntime } from './runtime.ts';
|
|
2
|
-
export type { Runtime, RuntimeOptions, RuntimeRequest, RequestTrace,
|
|
2
|
+
export type { Runtime, RuntimeOptions, RuntimeRequest, RequestTrace, HostPlugin, Observer, TestPlan } from './runtime.ts';
|
|
3
3
|
export { startServer } from './server.ts';
|
|
4
4
|
export type { Server, ServerOptions } from './server.ts';
|
|
5
5
|
export { loadDocument, validateDocument, parseYaml } from './config.ts';
|
|
6
|
-
export { openLinkStore } from './link-store.ts';
|
|
7
|
-
export type { LinkStore, LinkRow, LinkStoreOptions } from './link-store.ts';
|
|
8
|
-
export { startLinkApi } from './link-api.ts';
|
|
9
|
-
export type { LinkApi, LinkApiOptions } from './link-api.ts';
|
|
10
|
-
export type { LinkEvent, LinkObserverOptions, LinkObserverStats } from './link-events.ts';
|
|
11
6
|
export { events as observabilityEvents, validateObservers, createObserverSink, createMetrics, renderPrometheus } from './observability.ts';
|
|
12
7
|
export { getCapabilities, routeCapabilities, analyzeProjectCapabilities, analyzeCompiledCapabilities, assertTargetCompatibility, normalizeCapabilityTarget } from './capabilities.ts';
|
|
13
8
|
export { capabilityDetails } from './capabilities.ts';
|
|
@@ -35,6 +30,8 @@ export { normalizeMatch, assertDisjointMatches, matchesRoute } from './condition
|
|
|
35
30
|
export type { RouteMatch, ConditionRequest } from './conditions.ts';
|
|
36
31
|
export { buildCloudflare } from './build-cloudflare.ts';
|
|
37
32
|
export type { BuildOptions as CloudflareBuildOptions, BuildReport as CloudflareBuildReport } from './build-cloudflare.ts';
|
|
33
|
+
export { buildStatic } from './build-static.ts';
|
|
34
|
+
export type { BuildOptions as StaticBuildOptions, BuildReport as StaticBuildReport, StaticRedirect, StaticObject, RedirectManifest, ObjectManifest } from './build-static.ts';
|
|
38
35
|
export { runProjectTests } from './project-tests.ts';
|
|
39
36
|
export type { ProjectTestOptions, ProjectTestResult } from './project-tests.ts';
|
|
40
37
|
export { scaffoldProject } from './scaffold.ts';
|
package/dist/types/manifest.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CapabilityName, CapabilityTarget } from './capabilities.ts';
|
|
2
2
|
import type { InspectOptions } from './tooling.ts';
|
|
3
3
|
import type { RouteExplanation } from './explain.ts';
|
|
4
|
-
export declare const MANIFEST_SCHEMA_VERSION =
|
|
4
|
+
export declare const MANIFEST_SCHEMA_VERSION = 2;
|
|
5
5
|
export interface ManifestRoute {
|
|
6
6
|
path: string;
|
|
7
7
|
methods: string[];
|
|
@@ -63,8 +63,6 @@ export interface Manifest {
|
|
|
63
63
|
signals: string[];
|
|
64
64
|
};
|
|
65
65
|
extensions: string[];
|
|
66
|
-
linkStores: string[];
|
|
67
|
-
dynamicLinks: boolean;
|
|
68
66
|
};
|
|
69
67
|
functions: ManifestModule[];
|
|
70
68
|
middleware: ManifestModule[];
|
|
@@ -4,12 +4,8 @@ export declare const events: Readonly<{
|
|
|
4
4
|
reload: readonly string[];
|
|
5
5
|
watch: readonly string[];
|
|
6
6
|
function_worker: readonly string[];
|
|
7
|
-
link_store_worker: readonly string[];
|
|
8
|
-
link_request: readonly string[];
|
|
9
|
-
link_observer: readonly string[];
|
|
10
7
|
logs_dropped: readonly string[];
|
|
11
8
|
observer: readonly string[];
|
|
12
|
-
management_request: readonly string[];
|
|
13
9
|
throttle: readonly string[];
|
|
14
10
|
agents: readonly string[];
|
|
15
11
|
cache: readonly string[];
|
|
@@ -62,21 +58,12 @@ export interface MetricsSnapshot {
|
|
|
62
58
|
healthySlots: number;
|
|
63
59
|
slots: number;
|
|
64
60
|
};
|
|
65
|
-
linkStoreWorkers: {
|
|
66
|
-
started: number;
|
|
67
|
-
restarts: number;
|
|
68
|
-
};
|
|
69
61
|
policies: {
|
|
70
62
|
throttle: Counters;
|
|
71
63
|
agents: Counters;
|
|
72
64
|
cache: Counters;
|
|
73
65
|
};
|
|
74
66
|
signals: Counters;
|
|
75
|
-
linkRequests: Counters;
|
|
76
|
-
linkObserver: {
|
|
77
|
-
failed: number;
|
|
78
|
-
dropped: number;
|
|
79
|
-
};
|
|
80
67
|
logsDropped: number;
|
|
81
68
|
observers: {
|
|
82
69
|
errors: number;
|
|
@@ -99,7 +86,7 @@ export type ObserverSink = ((event: ObserverEvent, context?: RecordContext) => v
|
|
|
99
86
|
close(): Promise<void>;
|
|
100
87
|
};
|
|
101
88
|
export declare function validateObservers(observers?: unknown): Observer[];
|
|
102
|
-
export declare const SNAPSHOT_VERSION =
|
|
89
|
+
export declare const SNAPSHOT_VERSION = 2;
|
|
103
90
|
export declare function createMetrics(): Metrics;
|
|
104
91
|
export declare function createObserverSink(observers?: unknown, fallbackLog?: (event: ObserverEvent) => void, metrics?: Metrics): ObserverSink;
|
|
105
92
|
export declare function renderPrometheus(snapshot: Partial<MetricsSnapshot>): string;
|
|
@@ -5,11 +5,10 @@ export interface ProjectTestOptions {
|
|
|
5
5
|
plugins?: ServerOptions['plugins'];
|
|
6
6
|
log?: LogFn | undefined;
|
|
7
7
|
permissions?: ServerOptions['permissions'];
|
|
8
|
-
linkStore?: ServerOptions['linkStore'];
|
|
9
8
|
origin?: string | undefined;
|
|
10
9
|
}
|
|
11
10
|
export interface ProjectTestResult {
|
|
12
11
|
total: number;
|
|
13
12
|
failed: number;
|
|
14
13
|
}
|
|
15
|
-
export declare function runProjectTests(project: string, { log, permissions,
|
|
14
|
+
export declare function runProjectTests(project: string, { log, permissions, origin, extensions, plugins }?: ProjectTestOptions): Promise<ProjectTestResult>;
|
|
@@ -4,10 +4,13 @@ import type { CompiledRedirect, CompiledRoute, LogFn, PlanInventoryEntry, Policy
|
|
|
4
4
|
import type { ComplianceOptions, ComplianceReport } from './compliance.ts';
|
|
5
5
|
import type { CompiledRoutes } from './match.ts';
|
|
6
6
|
export type { RouteState } from './types.ts';
|
|
7
|
-
export type HandlerName = 'extension' | 'proxy' | 'conditional' | 'redirect' | 'function' | 'page' | 'static' | 'download' | 'respond'
|
|
7
|
+
export type HandlerName = 'extension' | 'proxy' | 'conditional' | 'redirect' | 'function' | 'page' | 'static' | 'download' | 'respond';
|
|
8
8
|
/** One configured route as the inventory reports it: a PlanInventoryEntry with the handler kind named. */
|
|
9
9
|
export interface RouteInventory extends PlanInventoryEntry {
|
|
10
10
|
handler: HandlerName | undefined;
|
|
11
|
+
/** Non-blocking `audit` observations about this route (e.g. a webhook-shaped
|
|
12
|
+
* route with no declared `sandbox`/`sandboxReason`); never affects `ready`. */
|
|
13
|
+
advisories?: string[];
|
|
11
14
|
}
|
|
12
15
|
/** One request case: a generated probe or a `tests/requests.json` fixture. */
|
|
13
16
|
export interface RequestCase {
|
|
@@ -40,7 +43,6 @@ export interface AuditableApp {
|
|
|
40
43
|
address: AddressInfo;
|
|
41
44
|
root: string;
|
|
42
45
|
testPlan(): ProjectPlan & {
|
|
43
|
-
dynamicLinks?: boolean;
|
|
44
46
|
policies?: Record<string, PolicyInventory>;
|
|
45
47
|
};
|
|
46
48
|
}
|
|
@@ -51,7 +53,6 @@ export interface AuditOptions {
|
|
|
51
53
|
compliance?: ComplianceOptions | undefined;
|
|
52
54
|
}
|
|
53
55
|
export interface AuditReport {
|
|
54
|
-
dynamicLinks: boolean | undefined;
|
|
55
56
|
elapsedMs: number;
|
|
56
57
|
ready: boolean;
|
|
57
58
|
counts: {
|
|
@@ -74,6 +75,12 @@ export interface AuditReport {
|
|
|
74
75
|
}[];
|
|
75
76
|
policies: Record<string, PolicyInventory>;
|
|
76
77
|
compliance: ComplianceReport | null;
|
|
78
|
+
/** Non-blocking `audit` observations, e.g. a route that looks webhook-shaped
|
|
79
|
+
* but declares neither `sandbox: true` nor `sandboxReason`. Never affects `ready`. */
|
|
80
|
+
advisories: {
|
|
81
|
+
route: string;
|
|
82
|
+
message: string;
|
|
83
|
+
}[];
|
|
77
84
|
}
|
|
78
85
|
export interface BenchmarkOptions {
|
|
79
86
|
requests?: number | undefined;
|
package/dist/types/router.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RuntimeExtension } from './extensions.ts';
|
|
1
2
|
import type { CompiledRouteTable, LoadedDocument } from './types.ts';
|
|
2
3
|
export { parseTarget, matchRoute, contextFor, resolveValue, redirectLocation } from './match.ts';
|
|
3
4
|
/** The grants compileRoutes consults: a validated OperatorPolicy (policy.ts) or nothing, which denies every binding. */
|
|
@@ -8,4 +9,4 @@ export interface BindingPermissions {
|
|
|
8
9
|
secrets?: string[];
|
|
9
10
|
}>;
|
|
10
11
|
}
|
|
11
|
-
export declare function compileRoutes(loaded: LoadedDocument, bindings: Record<string, string | undefined>, permissions?: BindingPermissions, projectSha256?: string): Promise<CompiledRouteTable>;
|
|
12
|
+
export declare function compileRoutes(loaded: LoadedDocument, bindings: Record<string, string | undefined>, permissions?: BindingPermissions, projectSha256?: string, extensions?: readonly Pick<RuntimeExtension, 'name' | 'cacheSensitive'>[]): Promise<CompiledRouteTable>;
|
package/dist/types/runtime.d.ts
CHANGED
|
@@ -2,34 +2,15 @@ import type { RuntimeExtension } from './extensions.ts';
|
|
|
2
2
|
import type { EgressDependencies } from './egress.ts';
|
|
3
3
|
import type { ProjectPlan } from './readiness.ts';
|
|
4
4
|
import type { OperatorPolicy } from './policy.ts';
|
|
5
|
-
import type { LinkStoreOptions } from './link-store.ts';
|
|
6
5
|
import type { Plugin } from './plugins.ts';
|
|
7
6
|
import type { MetricsSnapshot, Observer } from './observability.ts';
|
|
8
7
|
import type { HandlerResult, HeaderPair } from './http-response.ts';
|
|
9
8
|
import type { LogFn, PolicyInventory, TargetName } from './types.ts';
|
|
10
|
-
/** A stored link as a link store returns it; the runtime validates the fields it uses. */
|
|
11
|
-
export interface LinkLookup {
|
|
12
|
-
url?: unknown;
|
|
13
|
-
status?: unknown;
|
|
14
|
-
enabled?: unknown;
|
|
15
|
-
expires?: unknown;
|
|
16
|
-
}
|
|
17
|
-
/** What a `linkStores` binding must provide: a reader and, optionally, its health. */
|
|
18
|
-
export interface LinkReader {
|
|
19
|
-
get(collection: string, code: string): Promise<LinkLookup | null | undefined>;
|
|
20
|
-
readonly readHealthy?: boolean;
|
|
21
|
-
readonly healthy?: boolean;
|
|
22
|
-
}
|
|
23
|
-
/** An operator-owned SQLite link store the runtime opens read-only for one collection. */
|
|
24
|
-
export interface LinkStoreBinding extends LinkStoreOptions {
|
|
25
|
-
collection: string;
|
|
26
|
-
}
|
|
27
9
|
export type { OperatorPolicy } from './policy.ts';
|
|
28
10
|
/** An operator plugin (src/plugins.ts). */
|
|
29
11
|
export type HostPlugin = Plugin;
|
|
30
12
|
export type { Observer, MetricsSnapshot } from './observability.ts';
|
|
31
13
|
export interface TestPlan extends ProjectPlan {
|
|
32
|
-
dynamicLinks: boolean;
|
|
33
14
|
policies: Record<string, PolicyInventory>;
|
|
34
15
|
}
|
|
35
16
|
export interface RuntimeOptions {
|
|
@@ -42,8 +23,6 @@ export interface RuntimeOptions {
|
|
|
42
23
|
local?: boolean | undefined;
|
|
43
24
|
environment?: NodeJS.ProcessEnv | undefined;
|
|
44
25
|
permissions?: OperatorPolicy | undefined;
|
|
45
|
-
linkStore?: LinkStoreBinding | undefined;
|
|
46
|
-
linkStores?: Record<string, LinkReader> | undefined;
|
|
47
26
|
target?: TargetName | undefined;
|
|
48
27
|
plugins?: HostPlugin[] | undefined;
|
|
49
28
|
workers?: number | undefined;
|
|
@@ -57,16 +36,10 @@ export interface RuntimeOptions {
|
|
|
57
36
|
only?: readonly string[] | undefined;
|
|
58
37
|
}
|
|
59
38
|
/** Per-request facts the host may read after handle() settles; never request text. */
|
|
60
|
-
export interface LinkTrace {
|
|
61
|
-
collection: string;
|
|
62
|
-
code: string | null;
|
|
63
|
-
result: string;
|
|
64
|
-
}
|
|
65
39
|
export interface RequestTrace {
|
|
66
40
|
route?: string;
|
|
67
41
|
probe?: boolean;
|
|
68
42
|
client?: string | null;
|
|
69
|
-
link?: LinkTrace;
|
|
70
43
|
}
|
|
71
44
|
export interface RuntimeRequest {
|
|
72
45
|
target: string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { SandboxPool } from './functions.ts';
|
|
2
|
+
export type { SandboxEntry, SandboxTarget, SandboxInvocation, SandboxPoolOptions, FunctionContext, FunctionResult, } from './functions.ts';
|
|
3
|
+
export type { GuestRequestPayload, GuestResponsePayload } from './guest-api.ts';
|
|
4
|
+
export type { HandlerResult, HeaderPair } from './http-response.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Resolves a project-relative hook source string the same way a native
|
|
7
|
+
* `function`/`middleware` route's `source` is resolved (`.mjs`/`.js` only, no
|
|
8
|
+
* path traversal outside the project root) into the absolute path
|
|
9
|
+
* `SandboxPool`'s entries and `execute()` targets expect. `root` must be the
|
|
10
|
+
* project's resolved directory (`ExtensionActivation.root`, never `cwd()`).
|
|
11
|
+
*/
|
|
12
|
+
export { functionFile } from './config.ts';
|
package/dist/types/scaffold.d.ts
CHANGED
package/dist/types/server.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import http from 'node:http';
|
|
2
2
|
import type { AddressInfo } from 'node:net';
|
|
3
3
|
import type { RuntimeOptions, TestPlan } from './runtime.ts';
|
|
4
|
-
import type { LinkObserverStats } from './link-events.ts';
|
|
5
4
|
import type { MetricsSnapshot, Observer } from './observability.ts';
|
|
6
5
|
export interface ServerOptions extends Omit<RuntimeOptions, 'observers'> {
|
|
7
6
|
project?: string | undefined;
|
|
@@ -13,7 +12,6 @@ export interface ServerOptions extends Omit<RuntimeOptions, 'observers'> {
|
|
|
13
12
|
maxInFlightHealthRequests?: number | undefined;
|
|
14
13
|
requestLog?: string | undefined;
|
|
15
14
|
trustRequestId?: boolean | undefined;
|
|
16
|
-
linkEvents?: unknown;
|
|
17
15
|
trustedProxies?: string | string[] | undefined;
|
|
18
16
|
observers?: Observer[] | undefined;
|
|
19
17
|
metrics?: boolean | undefined;
|
|
@@ -25,7 +23,6 @@ export interface Server {
|
|
|
25
23
|
address: AddressInfo;
|
|
26
24
|
root: string;
|
|
27
25
|
testPlan(): TestPlan;
|
|
28
|
-
linkEventStats(): LinkObserverStats | undefined;
|
|
29
26
|
metrics(): MetricsSnapshot;
|
|
30
27
|
readonly observers: {
|
|
31
28
|
name: string;
|
|
@@ -34,4 +31,4 @@ export interface Server {
|
|
|
34
31
|
origin: string;
|
|
35
32
|
close(): Promise<void>;
|
|
36
33
|
}
|
|
37
|
-
export declare function startServer({ project, host, port, watch, local, log, maxBodyBytes, maxInFlightRequests, maxInFlightHealthRequests, requestLog, trustRequestId, origin,
|
|
34
|
+
export declare function startServer({ project, host, port, watch, local, log, maxBodyBytes, maxInFlightRequests, maxInFlightHealthRequests, requestLog, trustRequestId, origin, trustedProxies, observers, metrics, metricsIntervalMs, ...runtimeOptions }?: ServerOptions): Promise<Server>;
|
package/dist/types/tooling.d.ts
CHANGED
|
@@ -39,14 +39,14 @@ export declare function inspectProject(project: string, options?: InspectOptions
|
|
|
39
39
|
path: string;
|
|
40
40
|
methods: string[];
|
|
41
41
|
enabled: boolean;
|
|
42
|
-
capabilities: ("function" | "
|
|
42
|
+
capabilities: ("function" | "expires" | "middleware" | "extension" | "proxy" | "signals" | "conditional" | "methods" | "enabled" | "parameters" | "redirect" | "page" | "download" | "static" | "respond" | "policies.extensions" | "conditions" | "request.body" | "response.headers" | "bindings" | "policies.agents" | "policies.security" | "policies.cache" | "policies.compression" | "policies.throttle")[];
|
|
43
43
|
}[];
|
|
44
44
|
compatibility: {
|
|
45
45
|
offset: number;
|
|
46
46
|
limit: number;
|
|
47
47
|
hasMore: boolean;
|
|
48
48
|
issues: import("./capabilities.ts").CapabilityRequirement[];
|
|
49
|
-
target: "vercel" | "aws" | "cloudflare" | "self-hosted";
|
|
49
|
+
target: "vercel" | "aws" | "cloudflare" | "static" | "self-hosted";
|
|
50
50
|
compatible: boolean;
|
|
51
51
|
deployment: "local-runtime" | "unverified";
|
|
52
52
|
requirementCount: number;
|
|
@@ -58,7 +58,7 @@ export declare function validateProject(project: string, options?: InspectOption
|
|
|
58
58
|
projectSha256: string;
|
|
59
59
|
routeCount: number;
|
|
60
60
|
compatibility: {
|
|
61
|
-
target: "vercel" | "aws" | "cloudflare" | "self-hosted";
|
|
61
|
+
target: "vercel" | "aws" | "cloudflare" | "static" | "self-hosted";
|
|
62
62
|
compatible: boolean;
|
|
63
63
|
deployment: "local-runtime" | "unverified";
|
|
64
64
|
requirementCount: number;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { FunctionRoute } from './function-sources.ts';
|
|
2
|
+
import type { FunctionContext, FunctionResult } from './functions.ts';
|
|
3
|
+
import type { GuestRequestPayload } from './guest-api.ts';
|
|
4
|
+
import type { HandlerResult } from './http-response.ts';
|
|
5
|
+
import type { LogFn } from './types.ts';
|
|
6
|
+
export interface TrustedFunctionsOptions {
|
|
7
|
+
timeoutMs?: number | undefined;
|
|
8
|
+
maxBytes?: number | undefined;
|
|
9
|
+
log?: LogFn | undefined;
|
|
10
|
+
}
|
|
11
|
+
interface TrustedDefinition {
|
|
12
|
+
source: string;
|
|
13
|
+
export: string;
|
|
14
|
+
}
|
|
15
|
+
export type TrustedRoute = FunctionRoute<TrustedDefinition>;
|
|
16
|
+
export declare class TrustedFunctions {
|
|
17
|
+
timeoutMs: number;
|
|
18
|
+
maxBytes: number;
|
|
19
|
+
log: LogFn;
|
|
20
|
+
private readonly epoch;
|
|
21
|
+
constructor({ timeoutMs, maxBytes, log }?: TrustedFunctionsOptions);
|
|
22
|
+
start(routes: TrustedRoute[]): Promise<this>;
|
|
23
|
+
private loadExport;
|
|
24
|
+
execute(route: TrustedRoute, request: GuestRequestPayload, context: FunctionContext, native: HandlerResult | undefined): Promise<FunctionResult>;
|
|
25
|
+
private readBody;
|
|
26
|
+
private invoke;
|
|
27
|
+
close(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -42,10 +42,6 @@ export type AuthoredRouteConfig = Omit<RouteConfig, 'function' | 'middleware'> &
|
|
|
42
42
|
function?: string | FunctionConfig;
|
|
43
43
|
middleware?: (string | MiddlewareConfig)[];
|
|
44
44
|
};
|
|
45
|
-
export interface LinkConfig {
|
|
46
|
-
collection: string;
|
|
47
|
-
code: ValueRef;
|
|
48
|
-
}
|
|
49
45
|
export interface PageConfig {
|
|
50
46
|
file: string;
|
|
51
47
|
contentType?: string;
|
|
@@ -151,6 +147,8 @@ export interface RouteAuthConfig {
|
|
|
151
147
|
export interface RouteConfig {
|
|
152
148
|
extension?: string;
|
|
153
149
|
auth?: true | RouteAuthConfig;
|
|
150
|
+
/** Route-level `cache` short form: the same object accepted by `policies.cache`, expanded to it before anything else reads the project. */
|
|
151
|
+
cache?: CacheConfig;
|
|
154
152
|
proxy?: ProxyConfig;
|
|
155
153
|
signals?: SignalConfig[];
|
|
156
154
|
match?: RouteMatch;
|
|
@@ -159,6 +157,18 @@ export interface RouteConfig {
|
|
|
159
157
|
enabled?: boolean;
|
|
160
158
|
expires?: string;
|
|
161
159
|
description?: string;
|
|
160
|
+
/** Opt into the isolated QuickJS/WASM worker pool for this route's `function`/`middleware`
|
|
161
|
+
* chain (docs/FUNCTION-SECURITY.md). Default false: trusted, in-process, unsandboxed
|
|
162
|
+
* execution (docs/SPIKE-DEFAULT-TRUST-MODEL.md). Applies uniformly to the whole
|
|
163
|
+
* chain — `function` and any `middleware` on the same route run in the same mode. */
|
|
164
|
+
sandbox?: boolean;
|
|
165
|
+
/** Optional, human-authored justification for this route's sandbox decision — why it
|
|
166
|
+
* needs isolation when `sandbox: true`, or why it is safe to trust when it is not.
|
|
167
|
+
* Parsed and schema-validated (max 500 characters, schemas/urlcode.schema.json), stored
|
|
168
|
+
* on the compiled route and surfaced by `explain`/`context`/manifest next to `sandbox`.
|
|
169
|
+
* Never inferred or enforced: the trust decision remains the author's judgment call
|
|
170
|
+
* (docs/AI-AUTHORING.md, "Deciding when a route needs sandbox: true"). */
|
|
171
|
+
sandboxReason?: string;
|
|
162
172
|
parameters?: ParameterConfig[];
|
|
163
173
|
redirect?: RedirectConfig;
|
|
164
174
|
function?: FunctionConfig;
|
|
@@ -175,7 +185,6 @@ export interface RouteConfig {
|
|
|
175
185
|
};
|
|
176
186
|
respond?: RespondSpec;
|
|
177
187
|
middleware?: MiddlewareConfig[];
|
|
178
|
-
link?: LinkConfig;
|
|
179
188
|
policies?: PoliciesConfig;
|
|
180
189
|
/** Set by site.ts on a route it generated (`site.<key>`); never declared in YAML. */
|
|
181
190
|
generated?: string;
|
|
@@ -185,7 +194,6 @@ export interface ProjectDocument {
|
|
|
185
194
|
extensions?: Record<string, ExtensionDeclaration>;
|
|
186
195
|
routes: Record<string, RouteConfig>;
|
|
187
196
|
includes?: string[];
|
|
188
|
-
dynamicLinks?: boolean;
|
|
189
197
|
policies?: PoliciesConfig;
|
|
190
198
|
profiles?: Record<string, PolicyLayer>;
|
|
191
199
|
site?: SiteConfig;
|
|
@@ -384,6 +392,5 @@ export interface TestPlan {
|
|
|
384
392
|
inventory: PlanInventoryEntry[];
|
|
385
393
|
cases: unknown[];
|
|
386
394
|
resolve?(path: string): string | undefined;
|
|
387
|
-
dynamicLinks?: boolean;
|
|
388
395
|
policies?: Record<string, PolicyInventory>;
|
|
389
396
|
}
|
|
@@ -12,7 +12,7 @@ export interface VerifyFinding {
|
|
|
12
12
|
expected?: string;
|
|
13
13
|
observed?: string;
|
|
14
14
|
}
|
|
15
|
-
export interface VerifyOptions extends Pick<RuntimeOptions, 'permissions'
|
|
15
|
+
export interface VerifyOptions extends Pick<RuntimeOptions, 'permissions'> {
|
|
16
16
|
target: string;
|
|
17
17
|
origin?: string | undefined;
|
|
18
18
|
expectRoutes?: number | undefined;
|
|
@@ -44,4 +44,4 @@ export interface VerifyReport {
|
|
|
44
44
|
compliance: ComplianceReport | null;
|
|
45
45
|
}
|
|
46
46
|
export declare const failLevels: readonly FailOn[];
|
|
47
|
-
export declare function verifyDeployment(project: string, { target, origin, expectRoutes, timeoutMs, expectMetrics, failOn, compliance, complianceWarn, log, permissions
|
|
47
|
+
export declare function verifyDeployment(project: string, { target, origin, expectRoutes, timeoutMs, expectMetrics, failOn, compliance, complianceWarn, log, permissions }: VerifyOptions): Promise<VerifyReport>;
|
package/dist/types.js
CHANGED
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
|
|
35
35
|
/** A route as YAML may spell it before normalization: `function` and middleware entries may be short-form module paths. */
|
|
36
36
|
|
|
37
|
-
|
|
38
37
|
|
|
39
38
|
|
|
40
39
|
|
|
@@ -67,19 +66,33 @@
|
|
|
67
66
|
|
|
68
67
|
|
|
69
68
|
|
|
69
|
+
|
|
70
|
+
|
|
70
71
|
|
|
71
72
|
|
|
72
73
|
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
73
86
|
|
|
74
87
|
|
|
75
88
|
|
|
76
89
|
|
|
77
|
-
|
|
90
|
+
|
|
78
91
|
|
|
79
92
|
|
|
80
93
|
|
|
81
94
|
|
|
82
|
-
|
|
95
|
+
|
|
83
96
|
|
|
84
97
|
|
|
85
98
|
/** What config.ts returns: the entry document, the merged route table and the files it came from. */
|
|
@@ -192,5 +205,5 @@
|
|
|
192
205
|
|
|
193
206
|
|
|
194
207
|
|
|
195
|
-
|
|
208
|
+
|
|
196
209
|
|