@jimhoyd/urlcode 0.3.0 → 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 +122 -0
- package/.claude/skills/urlcode-operations/SKILL.md +108 -0
- package/.claude-plugin/marketplace.json +18 -0
- package/CONTRIBUTING.md +30 -2
- package/README.md +195 -255
- package/ROADMAP.md +143 -15
- package/SECURITY.md +31 -9
- package/dist/BUILD-MANIFEST.json +72 -47
- package/dist/adapters.js +4 -23
- package/dist/agent-lists.js +1 -1
- package/dist/agents-guide.js +113 -0
- package/dist/authoring-files.js +60 -0
- package/dist/authoring.js +11 -1
- package/dist/aws.js +4 -3
- package/dist/build-cloudflare.js +11 -24
- package/dist/build-static.js +134 -0
- package/dist/bulk.js +37 -0
- package/dist/capabilities.js +262 -0
- package/dist/capability-query.js +71 -0
- package/dist/catalog.js +105 -0
- package/dist/cli.js +165 -34
- package/dist/client-address.js +1 -1
- package/dist/compliance-rules/baseline.js +9 -17
- package/dist/compliance-rules/privacy.js +7 -18
- package/dist/compliance-rules/shared.js +0 -2
- package/dist/compliance-rules/strict.js +5 -5
- package/dist/compliance.js +6 -8
- package/dist/conditions.js +88 -0
- package/dist/config.js +69 -6
- package/dist/context.js +155 -0
- package/dist/ecosystem-cli.js +88 -0
- package/dist/egress.js +98 -0
- package/dist/examples.js +92 -0
- package/dist/explain-cli.js +64 -0
- package/dist/explain.js +131 -0
- package/dist/extensions.js +231 -0
- package/dist/function-sources.js +49 -5
- package/dist/function-worker.js +3 -1
- package/dist/functions.js +84 -13
- package/dist/guest-api.js +29 -3
- package/dist/index.js +40 -6
- package/dist/init-with.js +165 -0
- package/dist/interchange-cli.js +42 -0
- package/dist/interchange.js +189 -0
- package/dist/manifest.js +109 -0
- package/dist/match.js +2 -2
- package/dist/mcp-authoring.js +147 -0
- package/dist/mcp.js +97 -0
- package/dist/observability.js +7 -21
- package/dist/operator-host.js +29 -0
- package/dist/plugins.js +12 -0
- package/dist/policies/agents.js +2 -2
- package/dist/policies/cache.js +8 -3
- package/dist/policies/compression.js +2 -1
- package/dist/policies/security.js +0 -0
- package/dist/policies.js +1 -1
- package/dist/policy.js +56 -15
- package/dist/prerender.js +100 -41
- package/dist/project-tests.js +3 -3
- package/dist/provider-verification.js +92 -0
- package/dist/proxy.js +44 -0
- package/dist/readiness.js +34 -11
- package/dist/recipes.js +41 -0
- package/dist/route-diff.js +106 -0
- package/dist/router.js +45 -7
- package/dist/runtime.js +164 -64
- package/dist/sandbox.js +48 -0
- package/dist/scaffold.js +0 -0
- package/dist/schema-query.js +62 -0
- package/dist/scripts/operational-drills.js +12 -54
- package/dist/server.js +3 -29
- package/dist/signals.js +24 -0
- package/dist/site.js +0 -0
- package/dist/tooling.js +96 -0
- package/dist/trusted-functions.js +210 -0
- package/dist/types/adapters.d.ts +7 -4
- package/dist/types/agent-lists.d.ts +0 -1
- package/dist/types/agents-guide.d.ts +17 -0
- package/dist/types/authoring-files.d.ts +10 -0
- package/dist/types/aws.d.ts +3 -1
- package/dist/types/build-cloudflare.d.ts +1 -0
- package/dist/types/build-static.d.ts +43 -0
- package/dist/types/bulk.d.ts +27 -0
- package/dist/types/capabilities.d.ts +64 -0
- package/dist/types/capability-query.d.ts +24 -0
- package/dist/types/catalog.d.ts +65 -0
- package/dist/types/client-address.d.ts +0 -1
- package/dist/types/compliance-rules/baseline.d.ts +1 -9
- package/dist/types/compliance-rules/privacy.d.ts +1 -4
- package/dist/types/compliance-rules/shared.d.ts +0 -2
- package/dist/types/compliance-rules/strict.d.ts +0 -5
- package/dist/types/compliance.d.ts +0 -3
- package/dist/types/conditions.d.ts +19 -0
- package/dist/types/config.d.ts +21 -2
- package/dist/types/context.d.ts +66 -0
- package/dist/types/ecosystem-cli.d.ts +17 -0
- package/dist/types/egress.d.ts +46 -0
- package/dist/types/examples.d.ts +50 -0
- package/dist/types/explain-cli.d.ts +11 -0
- package/dist/types/explain.d.ts +95 -0
- package/dist/types/extensions.d.ts +177 -0
- package/dist/types/function-sources.d.ts +9 -0
- package/dist/types/functions.d.ts +48 -5
- package/dist/types/guest-api.d.ts +1 -0
- package/dist/types/index.d.ts +36 -6
- package/dist/types/init-with.d.ts +30 -0
- package/dist/types/interchange-cli.d.ts +16 -0
- package/dist/types/interchange.d.ts +42 -0
- package/dist/types/manifest.d.ts +79 -0
- package/dist/types/match.d.ts +1 -0
- package/dist/types/mcp-authoring.d.ts +92 -0
- package/dist/types/mcp.d.ts +12 -0
- package/dist/types/observability.d.ts +3 -14
- package/dist/types/operator-host.d.ts +8 -0
- package/dist/types/plugins.d.ts +2 -0
- package/dist/types/policies/agents.d.ts +0 -2
- package/dist/types/policies/compression.d.ts +2 -0
- package/dist/types/policies/security.d.ts +0 -1
- package/dist/types/policy.d.ts +15 -4
- package/dist/types/project-tests.d.ts +3 -2
- package/dist/types/provider-verification.d.ts +53 -0
- package/dist/types/proxy.d.ts +21 -0
- package/dist/types/readiness.d.ts +10 -3
- package/dist/types/recipes.d.ts +30 -0
- package/dist/types/route-diff.d.ts +27 -0
- package/dist/types/router.d.ts +2 -1
- package/dist/types/runtime.d.ts +11 -27
- package/dist/types/sandbox.d.ts +12 -0
- package/dist/types/scaffold.d.ts +0 -2
- package/dist/types/schema-query.d.ts +12 -0
- package/dist/types/server.d.ts +1 -4
- package/dist/types/signals.d.ts +25 -0
- package/dist/types/site.d.ts +0 -1
- package/dist/types/tooling.d.ts +115 -0
- package/dist/types/trusted-functions.d.ts +29 -0
- package/dist/types/types.d.ts +71 -7
- package/dist/types/typescript-authoring.d.ts +12 -0
- package/dist/types/vercel.d.ts +3 -1
- package/dist/types/verify-deployment.d.ts +47 -0
- package/dist/types.js +37 -5
- package/dist/typescript-authoring.js +142 -0
- package/dist/vercel.js +4 -3
- package/dist/verify-deployment.js +270 -0
- package/docs/AI-AUTHORING.md +232 -15
- package/docs/AWS.md +4 -4
- package/docs/BEST-PRACTICES.md +3 -2
- package/docs/BULK.md +79 -0
- package/docs/CAPABILITIES.md +192 -0
- package/docs/CAPACITY.md +129 -32
- package/docs/CI.md +142 -0
- package/docs/CLOUDFLARE.md +1 -2
- package/docs/COMPLIANCE.md +6 -9
- package/docs/CONDITIONS.md +74 -0
- package/docs/DEPLOYMENT-CHECKS.md +108 -0
- package/docs/EGRESS.md +125 -0
- package/docs/EXTENSIONS.md +398 -0
- package/docs/FRAMEWORK.md +198 -0
- package/docs/FUNCTION-SECURITY.md +129 -32
- package/docs/INSTALL.md +45 -12
- package/docs/INTERCHANGE.md +134 -0
- package/docs/LOAD-TESTING.md +4 -4
- package/docs/MIDDLEWARE-EXAMPLES.md +75 -0
- package/docs/MIDDLEWARE.md +29 -16
- package/docs/MONITORING.md +2 -19
- package/docs/NEXT-PHASE-PLAN.md +98 -0
- package/docs/NEXT-STEPS.md +634 -0
- package/docs/OBSERVABILITY.md +11 -18
- package/docs/OPEN-DECISIONS.md +212 -0
- package/docs/OPERATIONAL-PROOF.md +30 -31
- package/docs/OPERATIONS.md +29 -35
- package/docs/PLUGINS.md +37 -0
- package/docs/POLICIES.md +23 -309
- package/docs/PRERENDER.md +41 -1
- package/docs/PROJECT-DIRECTION.md +75 -8
- package/docs/PROVIDER-VERIFICATION.md +84 -0
- package/docs/READINESS.md +21 -1
- package/docs/README.md +87 -34
- package/docs/RECIPES.md +99 -0
- package/docs/RELEASE-READINESS.md +57 -35
- package/docs/RELEASE-SECURITY.md +116 -7
- 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 +41 -1
- package/docs/SPECIFICATION.md +150 -29
- package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +287 -0
- package/docs/SPIKE-BUSINESS-SUITE.md +1021 -0
- package/docs/SPIKE-CORE-LAYERING.md +337 -0
- package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +209 -0
- package/docs/SPIKE-EXTENSION-MODEL.md +419 -0
- package/docs/SPIKE-EXTENSIONS.md +6 -0
- package/docs/SPIKE-LAMBDA-COMPILE.md +201 -0
- package/docs/SPIKE-MONOREPO.md +322 -0
- package/docs/STANDARDS.md +150 -142
- package/docs/STARTERS.md +21 -1
- package/docs/STATIC.md +94 -0
- package/docs/TOOLING.md +295 -0
- package/docs/TUNNELS.md +0 -3
- package/docs/TYPESCRIPT-AUTHORING.md +82 -0
- package/docs/TYPESCRIPT.md +25 -4
- package/docs/USABILITY-REVIEW.md +129 -0
- package/docs/VERCEL.md +4 -5
- package/docs/VERSION-ALIGNMENT.md +205 -0
- package/docs/YAML-GUIDE.md +15 -479
- package/docs/YAML-REFERENCE.md +143 -22
- package/docs/policies/agents.md +1 -1
- package/docs/policies/cache.md +13 -0
- package/docs/policies/contract.md +52 -0
- package/docs/policies/hardened.md +56 -0
- package/docs/policies/interoperability.md +169 -0
- package/docs/policies/operations.md +45 -0
- package/docs/yaml/assets.md +36 -0
- package/docs/yaml/conditions.md +20 -0
- package/docs/yaml/functions.md +160 -0
- package/docs/yaml/middleware.md +29 -0
- package/docs/yaml/organization.md +74 -0
- package/docs/yaml/policies.md +37 -0
- package/docs/yaml/redirects.md +64 -0
- package/docs/yaml/responses.md +57 -0
- package/docs/yaml/site.md +24 -0
- package/examples/assets/example.yaml +17 -0
- package/examples/aws/example.yaml +20 -0
- package/examples/cloudflare/example.yaml +19 -0
- package/examples/compliance/example.yaml +11 -0
- package/examples/conditions/README.md +12 -0
- package/examples/conditions/example.yaml +19 -0
- package/examples/conditions/tests/requests.json +13 -0
- package/examples/conditions/urlcode.yaml +24 -0
- package/examples/cookbook/README.md +8 -4
- package/examples/cookbook/example.yaml +17 -0
- package/examples/cookbook/functions/catalog.mjs +3 -0
- package/examples/cookbook/functions/fail.mjs +4 -0
- package/examples/cookbook/functions/items.mjs +3 -0
- package/examples/cookbook/functions/profile.mjs +3 -0
- package/examples/cookbook/functions/resource.mjs +3 -0
- package/examples/cookbook/functions/status.mjs +3 -0
- package/examples/cookbook/middleware/auth.mjs +48 -0
- package/examples/cookbook/middleware/body.mjs +15 -0
- package/examples/cookbook/middleware/bucket.mjs +29 -0
- package/examples/cookbook/middleware/cors.mjs +21 -0
- package/examples/cookbook/middleware/debug.mjs +13 -0
- package/examples/cookbook/middleware/envelope.mjs +11 -0
- package/examples/cookbook/middleware/errors.mjs +11 -0
- package/examples/cookbook/middleware/etag.mjs +18 -0
- package/examples/cookbook/middleware/locale.mjs +20 -0
- package/examples/cookbook/middleware/maintenance.mjs +10 -0
- package/examples/cookbook/middleware/methods.mjs +15 -0
- package/examples/cookbook/middleware/negotiate.mjs +20 -0
- package/examples/cookbook/middleware/referer.mjs +12 -0
- package/examples/cookbook/middleware/request-id.mjs +16 -0
- package/examples/cookbook/route-index.json +676 -0
- package/examples/cookbook/routes/middleware.yaml +126 -0
- package/examples/cookbook/tests/requests.json +526 -0
- package/examples/cookbook/urlcode.yaml +1 -0
- package/examples/egress/README.md +22 -0
- package/examples/egress/example.yaml +19 -0
- package/examples/egress/urlcode.yaml +19 -0
- package/examples/extensions/README.md +7 -0
- package/examples/extensions/example.yaml +21 -0
- package/examples/extensions/urlcode.yaml +25 -0
- package/examples/monitoring/example.yaml +8 -0
- package/examples/prerender/README.md +2 -2
- package/examples/prerender/example.yaml +16 -0
- package/examples/provider-conformance/README.md +12 -0
- package/examples/provider-conformance/example.yaml +14 -0
- package/examples/provider-conformance/urlcode.yaml +34 -0
- package/examples/tunnel/example.yaml +8 -0
- package/examples/vercel/example.yaml +19 -0
- package/llms-full.txt +3084 -0
- package/llms.txt +61 -21
- package/package.json +36 -7
- package/packaging/claude-plugin/.claude-plugin/plugin.json +19 -0
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +122 -0
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +108 -0
- package/recipes/authenticated-json-api/README.md +51 -0
- package/recipes/authenticated-json-api/functions/profile.mjs +5 -0
- package/recipes/authenticated-json-api/recipe.yaml +34 -0
- package/recipes/authenticated-json-api/tests/requests.json +39 -0
- package/recipes/authenticated-json-api/urlcode.yaml +12 -0
- package/recipes/contact-form/README.md +25 -0
- package/recipes/contact-form/functions/contact.mjs +17 -0
- package/recipes/contact-form/recipe.yaml +33 -0
- package/recipes/contact-form/tests/requests.json +47 -0
- package/recipes/contact-form/urlcode.yaml +18 -0
- package/recipes/cors-api/README.md +16 -0
- package/recipes/cors-api/functions/items.mjs +3 -0
- package/recipes/cors-api/middleware/cors.mjs +21 -0
- package/recipes/cors-api/recipe.yaml +26 -0
- package/recipes/cors-api/tests/requests.json +65 -0
- package/recipes/cors-api/urlcode.yaml +12 -0
- package/recipes/health-page/README.md +13 -0
- package/recipes/health-page/recipe.yaml +23 -0
- package/recipes/health-page/tests/requests.json +36 -0
- package/recipes/health-page/urlcode.yaml +19 -0
- package/recipes/json-api/README.md +6 -0
- package/recipes/json-api/functions/echo.mjs +3 -0
- package/recipes/json-api/recipe.yaml +25 -0
- package/recipes/json-api/tests/requests.json +34 -0
- package/recipes/json-api/urlcode.yaml +12 -0
- package/recipes/middleware/README.md +34 -0
- package/recipes/middleware/functions/catalog.mjs +3 -0
- package/recipes/middleware/functions/fail.mjs +4 -0
- package/recipes/middleware/functions/items.mjs +3 -0
- package/recipes/middleware/functions/profile.mjs +3 -0
- package/recipes/middleware/functions/resource.mjs +3 -0
- package/recipes/middleware/functions/status.mjs +3 -0
- package/recipes/middleware/middleware/auth.mjs +48 -0
- package/recipes/middleware/middleware/body.mjs +15 -0
- package/recipes/middleware/middleware/bucket.mjs +29 -0
- package/recipes/middleware/middleware/cors.mjs +21 -0
- package/recipes/middleware/middleware/debug.mjs +13 -0
- package/recipes/middleware/middleware/envelope.mjs +11 -0
- package/recipes/middleware/middleware/errors.mjs +11 -0
- package/recipes/middleware/middleware/etag.mjs +18 -0
- package/recipes/middleware/middleware/locale.mjs +20 -0
- package/recipes/middleware/middleware/maintenance.mjs +10 -0
- package/recipes/middleware/middleware/methods.mjs +15 -0
- package/recipes/middleware/middleware/negotiate.mjs +20 -0
- package/recipes/middleware/middleware/referer.mjs +12 -0
- package/recipes/middleware/middleware/request-id.mjs +16 -0
- package/recipes/middleware/public/guide.txt +1 -0
- package/recipes/middleware/recipe.yaml +50 -0
- package/recipes/middleware/tests/requests.json +528 -0
- package/recipes/middleware/urlcode.yaml +127 -0
- package/recipes/protected-download/README.md +22 -0
- package/recipes/protected-download/files/report.txt +1 -0
- package/recipes/protected-download/recipe.yaml +31 -0
- package/recipes/protected-download/tests/requests.json +32 -0
- package/recipes/protected-download/urlcode.yaml +15 -0
- package/recipes/redirect/README.md +7 -0
- package/recipes/redirect/recipe.yaml +25 -0
- package/recipes/redirect/tests/requests.json +19 -0
- package/recipes/redirect/urlcode.yaml +9 -0
- package/recipes/static-plus-api/README.md +15 -0
- package/recipes/static-plus-api/functions/info.mjs +3 -0
- package/recipes/static-plus-api/public/assets/index.html +3 -0
- package/recipes/static-plus-api/public/assets/site.css +1 -0
- package/recipes/static-plus-api/public/index.html +8 -0
- package/recipes/static-plus-api/recipe.yaml +29 -0
- package/recipes/static-plus-api/tests/requests.json +56 -0
- package/recipes/static-plus-api/urlcode.yaml +23 -0
- package/recipes/typescript/README.md +8 -0
- package/recipes/typescript/functions/hello.ts +5 -0
- package/recipes/typescript/recipe.yaml +23 -0
- package/recipes/typescript/tests/requests.json +18 -0
- package/recipes/typescript/urlcode.yaml +5 -0
- package/recipes/webhook-receiver/README.md +20 -0
- package/recipes/webhook-receiver/functions/receive.mjs +16 -0
- package/recipes/webhook-receiver/recipe.yaml +27 -0
- package/recipes/webhook-receiver/tests/requests.json +59 -0
- package/recipes/webhook-receiver/urlcode.yaml +23 -0
- package/schemas/recipe.schema.json +139 -0
- package/schemas/urlcode.schema.json +659 -110
- package/skills/urlcode/SKILL.md +119 -0
- package/starters/default/.github/workflows/urlcode.yml +23 -0
- package/starters/default/.mcp.json +12 -0
- package/starters/default/AGENTS.md +79 -0
- 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 -41
- package/dist/sqlite-version.js +0 -6
- package/dist/types/link-api.d.ts +0 -30
- package/dist/types/link-cli.d.ts +0 -36
- 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 -9
- package/dist/types/sqlite-version.d.ts +0 -1
- package/docs/DYNAMIC-LINKS.md +0 -561
- package/docs/MANAGEMENT-SECURITY.md +0 -82
- package/examples/live-links/README.md +0 -11
- package/examples/live-links/tests/requests.json +0 -6
- package/examples/live-links/urlcode.yaml +0 -16
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import type { HandlerResult } from './http-response.ts';
|
|
2
|
+
import type { ProjectDocument, RouteConfig, TargetName } from './types.ts';
|
|
3
|
+
export type { HandlerResult } from './http-response.ts';
|
|
4
|
+
export interface ExtensionDeclaration {
|
|
5
|
+
version: '1';
|
|
6
|
+
config: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export type ExtensionPolicies = Record<string, Record<string, unknown> | false>;
|
|
9
|
+
/**
|
|
10
|
+
* `root` is the project's resolved absolute directory (the same value
|
|
11
|
+
* `loadDocument()` computes and `functionFile()`/router.ts resolves
|
|
12
|
+
* `function`/`middleware` `source` entries against). It is not the process's
|
|
13
|
+
* `cwd()`: `--project`/`--host-file` are independent paths, a server can be
|
|
14
|
+
* started from any working directory, and the JS API can load a project
|
|
15
|
+
* programmatically with no relationship to `cwd()` at all. An extension that
|
|
16
|
+
* resolves project-relative paths of its own (for example, an alternative
|
|
17
|
+
* middleware source it loads by convention rather than through core's native
|
|
18
|
+
* `middleware:` array) must resolve them against this field, never `cwd()`.
|
|
19
|
+
*/
|
|
20
|
+
export interface ExtensionActivation {
|
|
21
|
+
origin: string;
|
|
22
|
+
target: TargetName;
|
|
23
|
+
projectSha256: string;
|
|
24
|
+
mounts: readonly string[];
|
|
25
|
+
root: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ExtensionRequest {
|
|
28
|
+
method: string;
|
|
29
|
+
target: string;
|
|
30
|
+
path: string;
|
|
31
|
+
query: URLSearchParams;
|
|
32
|
+
headers: Headers;
|
|
33
|
+
headerCounts: Record<string, number>;
|
|
34
|
+
body: Uint8Array;
|
|
35
|
+
origin: string;
|
|
36
|
+
route: string;
|
|
37
|
+
mount: string | null;
|
|
38
|
+
client: string | null;
|
|
39
|
+
}
|
|
40
|
+
export interface ExtensionInstance {
|
|
41
|
+
handle(request: ExtensionRequest): HandlerResult | Promise<HandlerResult>;
|
|
42
|
+
authorize?(requirement: Readonly<Record<string, unknown>>, request: ExtensionRequest): HandlerResult | undefined | Promise<HandlerResult | undefined>;
|
|
43
|
+
/**
|
|
44
|
+
* Wrap semantics, not gate semantics: attached the same way as `authorize`
|
|
45
|
+
* (policies.extensions.<name> on a route, `config` the same validated
|
|
46
|
+
* per-route value `authorize`'s `requirement` receives), but given `next`,
|
|
47
|
+
* a callable invoking the rest of the pipeline for this route (any other
|
|
48
|
+
* declared extension `middleware()` after this one, then the route's own
|
|
49
|
+
* native `middleware:` chain and handler) at most once. Calling it lets
|
|
50
|
+
* this hook run code before and after the rest of the pipeline, inspecting
|
|
51
|
+
* or mutating the `HandlerResult` it resolves to; skipping it short-circuits
|
|
52
|
+
* the rest of the pipeline entirely, the same way `authorize` can. Never
|
|
53
|
+
* touches the native `middleware:` array or its own sandboxed/trusted
|
|
54
|
+
* dispatch, and never runs before `authorize` on the same route.
|
|
55
|
+
*/
|
|
56
|
+
middleware?(config: Readonly<Record<string, unknown>>, request: ExtensionRequest, next: () => Promise<HandlerResult>): HandlerResult | Promise<HandlerResult>;
|
|
57
|
+
close?(): void | Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
/** Trusted operator code only. YAML declares names/configuration, never modules. */
|
|
60
|
+
/**
|
|
61
|
+
* Content-hashed assets under `<mount><prefix>/` may be cached publicly. The
|
|
62
|
+
* extension owns the hashed filename; the runtime only relaxes its no-store floor
|
|
63
|
+
* for a GET/HEAD 200/304 that carries a strong ETag, sets no cookie and does not
|
|
64
|
+
* vary on credentials. Everything else under the mount stays no-store.
|
|
65
|
+
*/
|
|
66
|
+
export interface ExtensionImmutableAssets {
|
|
67
|
+
prefix: string;
|
|
68
|
+
}
|
|
69
|
+
export interface RuntimeExtension {
|
|
70
|
+
name: string;
|
|
71
|
+
version: '1';
|
|
72
|
+
projectSha256: string;
|
|
73
|
+
targets: TargetName[];
|
|
74
|
+
schema: object;
|
|
75
|
+
policySchema?: object;
|
|
76
|
+
credentialHeaders?: string[];
|
|
77
|
+
immutableAssets?: ExtensionImmutableAssets;
|
|
78
|
+
/**
|
|
79
|
+
* Reviewed, operator-declared cache sensitivity for `policies.extensions.<name>`
|
|
80
|
+
* routes (never for an `extension:` mount, which is always treated as
|
|
81
|
+
* sensitive). Omitted or `true`: the current, safe default — the runtime
|
|
82
|
+
* forces `Cache-Control: no-store`, disables compression and applies the
|
|
83
|
+
* extension response's header/size caps, exactly like `authorize`-gating
|
|
84
|
+
* auth/admin extensions. `false` is an explicit, reviewed opt-in a generic,
|
|
85
|
+
* cache-transparent extension (pure request/response middleware with no
|
|
86
|
+
* gating semantics of its own, like `urlcode-middleware`) makes to say its
|
|
87
|
+
* `middleware()` hook never depends on withholding the response from
|
|
88
|
+
* shared caches: the wrapped route's own declared cache headers pass
|
|
89
|
+
* through unchanged, exactly as the native `middleware:` array already
|
|
90
|
+
* does. A route naming more than one extension is treated as sensitive if
|
|
91
|
+
* any of them is (or leaves this unset) — this can only relax the no-store
|
|
92
|
+
* floor, never weaken it, and it never changes whether `authorize()` runs.
|
|
93
|
+
*/
|
|
94
|
+
cacheSensitive?: boolean;
|
|
95
|
+
activate(config: Readonly<Record<string, unknown>>, context: ExtensionActivation): ExtensionInstance | Promise<ExtensionInstance>;
|
|
96
|
+
}
|
|
97
|
+
/** `urlcode init --with <name>` contract: what core hands `@jimhoyd/urlcode-<name>`'s `scaffold` export. Nothing is written by `scaffold`. */
|
|
98
|
+
export interface ScaffoldRequest {
|
|
99
|
+
/** Absolute site directory core creates; `files` paths in the result are relative to it. */
|
|
100
|
+
directory: string;
|
|
101
|
+
/** Absolute route project directory (holds urlcode.yaml), `<directory>/app`. */
|
|
102
|
+
project: string;
|
|
103
|
+
/** Absolute path of the combined host module core writes, `<directory>/host.mjs`. */
|
|
104
|
+
hostFile: string;
|
|
105
|
+
/** Every extension name being scaffolded together, in `--with` order, including this one. */
|
|
106
|
+
names: readonly string[];
|
|
107
|
+
}
|
|
108
|
+
export interface ScaffoldFile {
|
|
109
|
+
path: string;
|
|
110
|
+
content: string | Uint8Array;
|
|
111
|
+
mode?: number;
|
|
112
|
+
}
|
|
113
|
+
export interface ScaffoldResult {
|
|
114
|
+
/** Must equal the requested name. */
|
|
115
|
+
name: string;
|
|
116
|
+
/** Fragments merged into the project's top-level `extensions` and `routes`; duplicate keys are refused. */
|
|
117
|
+
extensions: Record<string, unknown>;
|
|
118
|
+
routes: Record<string, unknown>;
|
|
119
|
+
/** Host module lines: imports, then setup statements, then entries of the `extensions` array, then `close` statements. */
|
|
120
|
+
hostImports: string[];
|
|
121
|
+
hostSetup: string[];
|
|
122
|
+
hostEntries: string[];
|
|
123
|
+
hostClose?: string[];
|
|
124
|
+
/** Files written relative to `directory` with their modes; never inside the project, never overwriting. */
|
|
125
|
+
files: ScaffoldFile[];
|
|
126
|
+
/** Markdown appended to README.md under a heading core adds; the numbered steps merged in `--with` order. */
|
|
127
|
+
readme: string;
|
|
128
|
+
nextSteps: string[];
|
|
129
|
+
/** Environment variables the host reads, with one-line descriptions. */
|
|
130
|
+
env?: Record<string, string>;
|
|
131
|
+
}
|
|
132
|
+
export interface ActiveExtension {
|
|
133
|
+
instance: ExtensionInstance;
|
|
134
|
+
policies: Map<string, Readonly<Record<string, unknown>>>;
|
|
135
|
+
assetPrefixes: readonly string[];
|
|
136
|
+
}
|
|
137
|
+
/** What the runtime knows about the request when it applies the privacy floor. */
|
|
138
|
+
export interface ExtensionAssetContext {
|
|
139
|
+
method: string;
|
|
140
|
+
path: string;
|
|
141
|
+
prefixes: readonly string[];
|
|
142
|
+
}
|
|
143
|
+
export interface ExtensionRegistry {
|
|
144
|
+
entries: Map<string, ActiveExtension>;
|
|
145
|
+
credentialHeaders: string[];
|
|
146
|
+
close(): Promise<void>;
|
|
147
|
+
}
|
|
148
|
+
export declare const immutableCacheControl = "public, max-age=31536000, immutable";
|
|
149
|
+
/** Inspection alone grants nothing; operators must explicitly pin the returned revision. */
|
|
150
|
+
export declare function inspectExtensionRevision(project: string): Promise<string>;
|
|
151
|
+
export declare function effectiveExtensionPolicies(document: ProjectDocument, route: Pick<RouteConfig, 'policies'>): Record<string, Record<string, unknown>>;
|
|
152
|
+
export declare function hasExtensionPolicy(document: ProjectDocument, route: Pick<RouteConfig, 'policies'>): boolean;
|
|
153
|
+
/**
|
|
154
|
+
* Whether a route naming these `policies.extensions` names must be treated as
|
|
155
|
+
* confidential (forced no-store, no compression, extension response caps).
|
|
156
|
+
* `names` with no entries is never confidential. Without a `registrations`
|
|
157
|
+
* list to consult (a build path with no operator host loaded), every name is
|
|
158
|
+
* treated as sensitive: the safe default this can only relax, never weaken.
|
|
159
|
+
* A name whose registration is missing, or declares no `cacheSensitive` (or
|
|
160
|
+
* `true`), counts as sensitive; only an explicit `cacheSensitive: false`
|
|
161
|
+
* excuses it, and one sensitive name among several makes the whole route
|
|
162
|
+
* confidential.
|
|
163
|
+
*/
|
|
164
|
+
export declare function isSensitiveExtensionPolicy(names: readonly string[], registrations?: readonly Pick<RuntimeExtension, 'name' | 'cacheSensitive'>[]): boolean;
|
|
165
|
+
export declare function prepareExtensions(document: ProjectDocument, routes: Record<string, RouteConfig>, registrations: RuntimeExtension[] | undefined, context: Omit<ExtensionActivation, 'mounts'>): {
|
|
166
|
+
activate(): Promise<ExtensionRegistry>;
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* The runtime decides; the extension cannot opt in from a response alone. The
|
|
170
|
+
* declared prefix, the GET/HEAD method, a 200/304 status, one strong ETag, no
|
|
171
|
+
* Set-Cookie and no Vary on Cookie/Authorization are all required. A stricter
|
|
172
|
+
* Cache-Control the extension set (no-store, no-cache, private or a shorter
|
|
173
|
+
* max-age) is preserved.
|
|
174
|
+
*/
|
|
175
|
+
export declare function immutableAssetResponse(result: HandlerResult, asset: ExtensionAssetContext | undefined): boolean;
|
|
176
|
+
/** Mandatory privacy floor after trusted response hooks, with bounded output. */
|
|
177
|
+
export declare function extensionResponse(result: HandlerResult, asset?: ExtensionAssetContext): HandlerResult;
|
|
@@ -17,5 +17,14 @@ export interface FunctionSources {
|
|
|
17
17
|
/** Absolute source path to module name. */
|
|
18
18
|
names: Map<string, string>;
|
|
19
19
|
}
|
|
20
|
+
/** Snapshot budgets: what one set of guest modules may cost. Deliberate bounds
|
|
21
|
+
* of the sandbox contract (docs/FUNCTION-SECURITY.md), not tuning knobs. */
|
|
22
|
+
export declare const MODULE_LIMIT = 128;
|
|
23
|
+
export declare const MODULE_BYTE_LIMIT = 1048576;
|
|
24
|
+
export declare const TOTAL_BYTE_LIMIT = 4194304;
|
|
20
25
|
export declare function routeFunctions<D>(route: FunctionRoute<D>): D[];
|
|
26
|
+
export declare function collectTrustedSources(routes: FunctionRoute[], root: string): Promise<Record<string, string>>;
|
|
27
|
+
export declare function collectSourcesFor(definitions: FunctionDefinition[], root: string): Promise<FunctionSources>;
|
|
28
|
+
/** Route-shaped convenience over `collectSourcesFor`: every existing caller (policy.ts,
|
|
29
|
+
* prerender.ts, typescript-authoring.ts) keeps working unchanged from `FunctionRoute[]`. */
|
|
21
30
|
export declare function collectFunctionSources(routes: FunctionRoute[], root: string): Promise<FunctionSources>;
|
|
@@ -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,11 +1,41 @@
|
|
|
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';
|
|
7
|
+
export { getCapabilities, routeCapabilities, analyzeProjectCapabilities, analyzeCompiledCapabilities, assertTargetCompatibility, normalizeCapabilityTarget } from './capabilities.ts';
|
|
8
|
+
export { capabilityDetails } from './capabilities.ts';
|
|
9
|
+
export type { CapabilityTarget, CapabilityName, CapabilityKind, CapabilityDetail, CapabilitySupport, CapabilityDecision, CapabilityRequirement, CapabilityCatalog, CompatibilityReport } from './capabilities.ts';
|
|
10
|
+
export { importRoutes, exportRoutes } from './interchange.ts';
|
|
11
|
+
export type { InterchangeFormat, ConversionDiagnostic, ConversionCounts, ConversionReport, ImportRoutesOptions, ExportRoutesOptions } from './interchange.ts';
|
|
12
|
+
export { listRecipes, searchRecipes, showRecipe, addRecipe } from './recipes.ts';
|
|
13
|
+
export type { RecipeSummary, Recipe, RecipeAddReport, RecipeSearchResult } from './recipes.ts';
|
|
14
|
+
export { listExamples, searchExamples } from './examples.ts';
|
|
15
|
+
export type { ExampleSummary, ExampleSearchResult, RouteIndex, RouteIndexEntry } from './examples.ts';
|
|
16
|
+
export type { CatalogMetadata, TargetVerdict, Complexity } from './catalog.ts';
|
|
17
|
+
export { buildTypeScriptProject } from './typescript-authoring.ts';
|
|
18
|
+
export type { TypeScriptBuildReport } from './typescript-authoring.ts';
|
|
19
|
+
export { importBulkProject } from './bulk.ts';
|
|
20
|
+
export type { BulkFormat, BulkFilePlan, BulkImportReport } from './bulk.ts';
|
|
21
|
+
export { inspectProject, validateProject, explainRoute, explainProject, previewImport, previewExport, getCapability, getSchemaFragment, schemaPathNames, inspectExtensions, describeExtensions, buildContext, renderContext, estimateTokens, documentationTokens } from './tooling.ts';
|
|
22
|
+
export type { InspectOptions, RouteExplanation, RouteMiss, ExplainedHandler, ExplainedCache, ExplainedExtensionRequirement, ExtensionProvider, TargetSupport, CapabilityEntry, CapabilityUsage, SchemaFragment, ExtensionInspection, ContextOptions, ProjectContext, ContextSection } from './tooling.ts';
|
|
23
|
+
export { buildManifest, renderManifest, MANIFEST_SCHEMA_VERSION } from './manifest.ts';
|
|
24
|
+
export type { Manifest, ManifestRoute, ManifestModule, RecipeProvenance } from './manifest.ts';
|
|
25
|
+
export { serveMcp } from './mcp.ts';
|
|
26
|
+
export type { McpOptions } from './mcp.ts';
|
|
27
|
+
export { providerConformanceCases, runProviderConformance, verifyProviderDeployment } from './provider-verification.ts';
|
|
28
|
+
export type { VerificationTarget, ProviderProbe, ProviderAnswer, ProviderTransport, ProviderVerificationOptions, ProviderFinding, ProviderVerificationReport } from './provider-verification.ts';
|
|
29
|
+
export { normalizeMatch, assertDisjointMatches, matchesRoute } from './conditions.ts';
|
|
30
|
+
export type { RouteMatch, ConditionRequest } from './conditions.ts';
|
|
31
|
+
export { buildCloudflare } from './build-cloudflare.ts';
|
|
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';
|
|
35
|
+
export { runProjectTests } from './project-tests.ts';
|
|
36
|
+
export type { ProjectTestOptions, ProjectTestResult } from './project-tests.ts';
|
|
37
|
+
export { scaffoldProject } from './scaffold.ts';
|
|
38
|
+
export type { ScaffoldReport, Unresolved as ScaffoldUnresolved } from './scaffold.ts';
|
|
39
|
+
export { initProject, addRedirect } from './authoring.ts';
|
|
40
|
+
export { initProjectWith } from './init-with.ts';
|
|
41
|
+
export type { ScaffoldRequest, ScaffoldResult, ScaffoldFile } from './extensions.ts';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ScaffoldRequest, ScaffoldResult } from './extensions.ts';
|
|
2
|
+
/** Directory names inside the generated site. The route project lives under `app/`; everything else is operator-owned. */
|
|
3
|
+
export declare const PROJECT_DIRECTORY = "app", HOST_FILE = "host.mjs", ROUTES_FILE = "routes/extensions.yaml";
|
|
4
|
+
export interface InitWithOptions {
|
|
5
|
+
cwd?: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface InitWithResult {
|
|
8
|
+
directory: string;
|
|
9
|
+
project: string;
|
|
10
|
+
hostFile: string;
|
|
11
|
+
extensions: string[];
|
|
12
|
+
projectSha256: string;
|
|
13
|
+
nextSteps: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function parseWithNames(value: string): string[];
|
|
16
|
+
export declare const packageName: (name: string) => string;
|
|
17
|
+
/**
|
|
18
|
+
* Resolves the extension package from the invoking directory (Node's package resolution with the default
|
|
19
|
+
* conditions), imports it, and calls its `scaffold` export. Nothing is bundled; core never imports these packages
|
|
20
|
+
* at build time. Refuses a missing package or a package without `scaffold` before anything is written.
|
|
21
|
+
*/
|
|
22
|
+
export declare function loadScaffold(name: string, request: ScaffoldRequest, cwd: string): Promise<ScaffoldResult>;
|
|
23
|
+
export declare function renderHost(names: readonly string[], results: readonly ScaffoldResult[]): string;
|
|
24
|
+
export declare function renderReadme(directory: string, names: readonly string[], results: readonly ScaffoldResult[], starter: string, env: Record<string, string>, projectSha256: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* `urlcode init <directory> --with a,b`: the starter under `app/`, every extension's fragments merged into one
|
|
27
|
+
* `urlcode.yaml`, one `host.mjs`, one `README.md` and the extensions' own files. All packages are resolved and
|
|
28
|
+
* their scaffolds computed before anything is written, so a refusal leaves no directory behind.
|
|
29
|
+
*/
|
|
30
|
+
export declare function initProjectWith(destination: string, names: readonly string[], { cwd }?: InitWithOptions): Promise<InitWithResult>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ConversionReport } from './interchange.ts';
|
|
2
|
+
interface InterchangeCliOptions {
|
|
3
|
+
project: string;
|
|
4
|
+
target?: string | undefined;
|
|
5
|
+
format?: string | undefined;
|
|
6
|
+
out?: string | undefined;
|
|
7
|
+
report?: string | undefined;
|
|
8
|
+
dryRun?: boolean | undefined;
|
|
9
|
+
acceptProviderDifferences?: boolean | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function readConversionInput(file: string): Promise<string>;
|
|
12
|
+
export declare function runInterchange(command: 'import' | 'export', args: string[], options: InterchangeCliOptions): Promise<{
|
|
13
|
+
report: ConversionReport;
|
|
14
|
+
text: string;
|
|
15
|
+
}>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProjectDocument } from './types.ts';
|
|
2
|
+
export type InterchangeFormat = 'csv' | 'json' | 'yaml' | 'netlify' | 'cloudflare' | 'vercel' | 'netlify-toml';
|
|
3
|
+
export interface ConversionDiagnostic {
|
|
4
|
+
severity: 'error' | 'warning';
|
|
5
|
+
code: string;
|
|
6
|
+
source: string;
|
|
7
|
+
row?: number;
|
|
8
|
+
path?: string;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ConversionCounts {
|
|
12
|
+
convertedRoutes: number;
|
|
13
|
+
nativeEquivalentRoutes: number;
|
|
14
|
+
runtimeRequiredRoutes: number;
|
|
15
|
+
unsupportedRows: number;
|
|
16
|
+
providerDifferenceRoutes: number;
|
|
17
|
+
fullyScanned: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface ConversionReport {
|
|
20
|
+
counts: ConversionCounts;
|
|
21
|
+
ok: boolean;
|
|
22
|
+
lossless: boolean;
|
|
23
|
+
routeCount: number;
|
|
24
|
+
diagnostics: ConversionDiagnostic[];
|
|
25
|
+
document?: ProjectDocument;
|
|
26
|
+
output?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ImportRoutesOptions {
|
|
29
|
+
format: InterchangeFormat;
|
|
30
|
+
text: string;
|
|
31
|
+
source?: string;
|
|
32
|
+
acceptProviderDifferences?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface ExportRoutesOptions {
|
|
35
|
+
format: InterchangeFormat;
|
|
36
|
+
document: ProjectDocument;
|
|
37
|
+
source?: string;
|
|
38
|
+
acceptProviderDifferences?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** Pure conversion: does not read projects, resolve bindings, execute guests or write files. */
|
|
41
|
+
export declare function importRoutes(options: ImportRoutesOptions): Promise<ConversionReport>;
|
|
42
|
+
export declare function exportRoutes(options: ExportRoutesOptions): Promise<ConversionReport>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CapabilityName, CapabilityTarget } from './capabilities.ts';
|
|
2
|
+
import type { InspectOptions } from './tooling.ts';
|
|
3
|
+
import type { RouteExplanation } from './explain.ts';
|
|
4
|
+
export declare const MANIFEST_SCHEMA_VERSION = 2;
|
|
5
|
+
export interface ManifestRoute {
|
|
6
|
+
path: string;
|
|
7
|
+
methods: string[];
|
|
8
|
+
handler: RouteExplanation['handler'];
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
expires?: string;
|
|
11
|
+
generated?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
middleware: {
|
|
14
|
+
source: string;
|
|
15
|
+
export: string;
|
|
16
|
+
}[];
|
|
17
|
+
parameters: RouteExplanation['inputs']['parameters'];
|
|
18
|
+
body?: RouteExplanation['inputs']['body'];
|
|
19
|
+
policies: string[];
|
|
20
|
+
extensions: Record<string, Record<string, unknown>>;
|
|
21
|
+
cache: RouteExplanation['cache'];
|
|
22
|
+
bindings: {
|
|
23
|
+
env: string[];
|
|
24
|
+
secrets: string[];
|
|
25
|
+
};
|
|
26
|
+
egress: RouteExplanation['egress'];
|
|
27
|
+
capabilities: CapabilityName[];
|
|
28
|
+
targets: Record<CapabilityTarget, boolean>;
|
|
29
|
+
}
|
|
30
|
+
export interface ManifestModule {
|
|
31
|
+
source: string;
|
|
32
|
+
export: string;
|
|
33
|
+
routes: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface RecipeProvenance {
|
|
36
|
+
id: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
version?: string;
|
|
39
|
+
source?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface Manifest {
|
|
42
|
+
schemaVersion: typeof MANIFEST_SCHEMA_VERSION;
|
|
43
|
+
urlcode: string;
|
|
44
|
+
entry: string;
|
|
45
|
+
files: string[];
|
|
46
|
+
revision: string;
|
|
47
|
+
configVersion: string;
|
|
48
|
+
routeCount: number;
|
|
49
|
+
routes: ManifestRoute[];
|
|
50
|
+
capabilities: CapabilityName[];
|
|
51
|
+
extensions: Record<string, {
|
|
52
|
+
version: string;
|
|
53
|
+
configKeys: string[];
|
|
54
|
+
mounts: string[];
|
|
55
|
+
protectedRoutes: string[];
|
|
56
|
+
}>;
|
|
57
|
+
recipes: RecipeProvenance[];
|
|
58
|
+
external: {
|
|
59
|
+
env: string[];
|
|
60
|
+
secrets: string[];
|
|
61
|
+
egress: {
|
|
62
|
+
proxy: string[];
|
|
63
|
+
signals: string[];
|
|
64
|
+
};
|
|
65
|
+
extensions: string[];
|
|
66
|
+
};
|
|
67
|
+
functions: ManifestModule[];
|
|
68
|
+
middleware: ManifestModule[];
|
|
69
|
+
targets: Record<CapabilityTarget, {
|
|
70
|
+
compatible: boolean;
|
|
71
|
+
issues: number;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
74
|
+
/** Build the semantic manifest for a project from its compiled IR. Deterministic for a given project. */
|
|
75
|
+
export declare function buildManifest(project: string, options?: InspectOptions): Promise<Manifest>;
|
|
76
|
+
/** The manifest as `build` writes it: two-space JSON with a trailing newline. */
|
|
77
|
+
export declare function renderManifest(manifest: Manifest): string;
|
|
78
|
+
export declare const manifestFileName = "manifest.json";
|
|
79
|
+
export declare function manifestPath(out: string): string;
|
package/dist/types/match.d.ts
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
export declare const authoringDefinitions: ({
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
properties: {
|
|
5
|
+
path: {
|
|
6
|
+
type: string;
|
|
7
|
+
maxLength: number;
|
|
8
|
+
};
|
|
9
|
+
handler: {
|
|
10
|
+
anyOf: ({
|
|
11
|
+
type: string;
|
|
12
|
+
maxLength: number;
|
|
13
|
+
} | {
|
|
14
|
+
type: string;
|
|
15
|
+
maxLength?: never;
|
|
16
|
+
})[];
|
|
17
|
+
};
|
|
18
|
+
middleware: {
|
|
19
|
+
type: string;
|
|
20
|
+
maxItems: number;
|
|
21
|
+
items: {
|
|
22
|
+
anyOf: ({
|
|
23
|
+
type: string;
|
|
24
|
+
maxLength: number;
|
|
25
|
+
} | {
|
|
26
|
+
type: string;
|
|
27
|
+
maxLength?: never;
|
|
28
|
+
})[];
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
file: {
|
|
32
|
+
type: string;
|
|
33
|
+
maxLength: number;
|
|
34
|
+
};
|
|
35
|
+
name?: never;
|
|
36
|
+
destination?: never;
|
|
37
|
+
dryRun?: never;
|
|
38
|
+
};
|
|
39
|
+
required: string[];
|
|
40
|
+
} | {
|
|
41
|
+
name: string;
|
|
42
|
+
description: string;
|
|
43
|
+
properties: {
|
|
44
|
+
name: {
|
|
45
|
+
type: string;
|
|
46
|
+
maxLength: number;
|
|
47
|
+
};
|
|
48
|
+
destination: {
|
|
49
|
+
type: string;
|
|
50
|
+
maxLength: number;
|
|
51
|
+
};
|
|
52
|
+
dryRun: {
|
|
53
|
+
type: string;
|
|
54
|
+
};
|
|
55
|
+
path?: never;
|
|
56
|
+
handler?: never;
|
|
57
|
+
middleware?: never;
|
|
58
|
+
file?: never;
|
|
59
|
+
};
|
|
60
|
+
required: string[];
|
|
61
|
+
} | {
|
|
62
|
+
name: string;
|
|
63
|
+
description: string;
|
|
64
|
+
properties: {
|
|
65
|
+
dryRun: {
|
|
66
|
+
type: string;
|
|
67
|
+
};
|
|
68
|
+
path?: never;
|
|
69
|
+
handler?: never;
|
|
70
|
+
middleware?: never;
|
|
71
|
+
file?: never;
|
|
72
|
+
name?: never;
|
|
73
|
+
destination?: never;
|
|
74
|
+
};
|
|
75
|
+
required: never[];
|
|
76
|
+
} | {
|
|
77
|
+
name: string;
|
|
78
|
+
description: string;
|
|
79
|
+
properties: {
|
|
80
|
+
path?: never;
|
|
81
|
+
handler?: never;
|
|
82
|
+
middleware?: never;
|
|
83
|
+
file?: never;
|
|
84
|
+
name?: never;
|
|
85
|
+
destination?: never;
|
|
86
|
+
dryRun?: never;
|
|
87
|
+
};
|
|
88
|
+
required: never[];
|
|
89
|
+
})[];
|
|
90
|
+
/** A project-relative path an authoring tool may create or replace: no absolute, `..`, hidden (`.env*`, `.git`), credential or operator names, and no symlink anywhere on the walk. */
|
|
91
|
+
export declare function confinedPath(root: string, path: unknown): Promise<string>;
|
|
92
|
+
export declare function callAuthoringTool(root: string, name: string, args: Record<string, unknown>, origin?: string): Promise<unknown>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Readable, Writable } from 'node:stream';
|
|
2
|
+
/** `allowAuthoring` and `hostFile` are set only by the `--allow-authoring` and `--host-file` command-line flags; tool arguments and the environment never enable them. */
|
|
3
|
+
export interface McpOptions {
|
|
4
|
+
project: string;
|
|
5
|
+
input?: Readable;
|
|
6
|
+
output?: Writable;
|
|
7
|
+
origin?: string;
|
|
8
|
+
allowAuthoring?: boolean;
|
|
9
|
+
hostFile?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Operator selects the only project root. Read tools have no path, credential, write or execution authority; authoring tools write inside that root only. */
|
|
12
|
+
export declare function serveMcp(options: McpOptions): Promise<void>;
|