@jimhoyd/urlcode 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/CONTRIBUTING.md +80 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +20 -0
  4. package/README.md +342 -0
  5. package/ROADMAP.md +248 -0
  6. package/SECURITY.md +40 -0
  7. package/data/agents/LICENSES/ai-robots-txt.txt +24 -0
  8. package/data/agents/LICENSES/crawler-user-agents.txt +23 -0
  9. package/data/agents/ai-crawlers.json +1240 -0
  10. package/data/agents/crawlers.json +10515 -0
  11. package/data/agents/index.d.ts +3 -0
  12. package/data/agents/index.js +2453 -0
  13. package/data/agents/monitoring.json +1520 -0
  14. package/data/agents/seo.json +3865 -0
  15. package/dist/BUILD-MANIFEST.json +60 -0
  16. package/dist/adapters.js +59 -0
  17. package/dist/agent-lists.js +59 -0
  18. package/dist/assets.js +129 -0
  19. package/dist/authoring.js +68 -0
  20. package/dist/aws.js +110 -0
  21. package/dist/build-cloudflare.js +164 -0
  22. package/dist/cli.js +185 -0
  23. package/dist/client-address.js +85 -0
  24. package/dist/cloudflare.js +165 -0
  25. package/dist/compliance-rules/baseline.js +98 -0
  26. package/dist/compliance-rules/privacy.js +38 -0
  27. package/dist/compliance-rules/shared.js +62 -0
  28. package/dist/compliance-rules/strict.js +61 -0
  29. package/dist/compliance.js +219 -0
  30. package/dist/config-worker.js +9 -0
  31. package/dist/config.js +172 -0
  32. package/dist/errors.js +8 -0
  33. package/dist/function-sources.js +54 -0
  34. package/dist/function-worker.js +105 -0
  35. package/dist/functions.js +174 -0
  36. package/dist/guest-api.js +114 -0
  37. package/dist/header-validation.js +18 -0
  38. package/dist/http-policy.js +74 -0
  39. package/dist/http-response.js +84 -0
  40. package/dist/index.js +11 -0
  41. package/dist/link-api.js +136 -0
  42. package/dist/link-cli.js +141 -0
  43. package/dist/link-events.js +76 -0
  44. package/dist/link-records.js +31 -0
  45. package/dist/link-store-worker.js +150 -0
  46. package/dist/link-store.js +250 -0
  47. package/dist/logging.js +22 -0
  48. package/dist/management-policy.js +41 -0
  49. package/dist/match.js +124 -0
  50. package/dist/observability.js +242 -0
  51. package/dist/plugins.js +74 -0
  52. package/dist/policies/agents.js +248 -0
  53. package/dist/policies/cache.js +297 -0
  54. package/dist/policies/compression.js +187 -0
  55. package/dist/policies/security.js +0 -0
  56. package/dist/policies/throttle.js +131 -0
  57. package/dist/policies.js +142 -0
  58. package/dist/policy.js +55 -0
  59. package/dist/prerender.js +165 -0
  60. package/dist/project-tests.js +23 -0
  61. package/dist/readiness.js +216 -0
  62. package/dist/router.js +166 -0
  63. package/dist/runtime.js +244 -0
  64. package/dist/scaffold.js +0 -0
  65. package/dist/scripts/operational-drills.js +75 -0
  66. package/dist/server.js +270 -0
  67. package/dist/site.js +0 -0
  68. package/dist/sqlite-version.js +6 -0
  69. package/dist/types/adapters.d.ts +12 -0
  70. package/dist/types/agent-lists.d.ts +5 -0
  71. package/dist/types/assets.d.ts +13 -0
  72. package/dist/types/authoring.d.ts +2 -0
  73. package/dist/types/aws.d.ts +35 -0
  74. package/dist/types/build-cloudflare.d.ts +14 -0
  75. package/dist/types/cli.d.ts +2 -0
  76. package/dist/types/client-address.d.ts +9 -0
  77. package/dist/types/cloudflare.d.ts +75 -0
  78. package/dist/types/compliance-rules/baseline.d.ts +12 -0
  79. package/dist/types/compliance-rules/privacy.d.ts +6 -0
  80. package/dist/types/compliance-rules/shared.d.ts +24 -0
  81. package/dist/types/compliance-rules/strict.d.ts +9 -0
  82. package/dist/types/compliance.d.ts +119 -0
  83. package/dist/types/config-worker.d.ts +1 -0
  84. package/dist/types/config.d.ts +21 -0
  85. package/dist/types/errors.d.ts +7 -0
  86. package/dist/types/function-sources.d.ts +21 -0
  87. package/dist/types/function-worker.d.ts +1 -0
  88. package/dist/types/functions.d.ts +92 -0
  89. package/dist/types/guest-api.d.ts +16 -0
  90. package/dist/types/header-validation.d.ts +2 -0
  91. package/dist/types/http-policy.d.ts +39 -0
  92. package/dist/types/http-response.d.ts +43 -0
  93. package/dist/types/index.d.ts +11 -0
  94. package/dist/types/link-api.d.ts +30 -0
  95. package/dist/types/link-cli.d.ts +36 -0
  96. package/dist/types/link-events.d.ts +27 -0
  97. package/dist/types/link-records.d.ts +11 -0
  98. package/dist/types/link-store-worker.d.ts +1 -0
  99. package/dist/types/link-store.d.ts +130 -0
  100. package/dist/types/logging.d.ts +9 -0
  101. package/dist/types/management-policy.d.ts +9 -0
  102. package/dist/types/match.d.ts +81 -0
  103. package/dist/types/observability.d.ts +104 -0
  104. package/dist/types/plugins.d.ts +27 -0
  105. package/dist/types/policies/agents.d.ts +86 -0
  106. package/dist/types/policies/cache.d.ts +82 -0
  107. package/dist/types/policies/compression.d.ts +41 -0
  108. package/dist/types/policies/security.d.ts +37 -0
  109. package/dist/types/policies/throttle.d.ts +55 -0
  110. package/dist/types/policies.d.ts +36 -0
  111. package/dist/types/policy.d.ts +21 -0
  112. package/dist/types/prerender.d.ts +31 -0
  113. package/dist/types/project-tests.d.ts +13 -0
  114. package/dist/types/readiness.d.ts +121 -0
  115. package/dist/types/router.d.ts +11 -0
  116. package/dist/types/runtime.d.ts +91 -0
  117. package/dist/types/scaffold.d.ts +17 -0
  118. package/dist/types/server.d.ts +37 -0
  119. package/dist/types/site.d.ts +12 -0
  120. package/dist/types/sqlite-version.d.ts +1 -0
  121. package/dist/types/types.d.ts +332 -0
  122. package/dist/types/vercel.d.ts +12 -0
  123. package/dist/types.js +177 -0
  124. package/dist/vercel.js +65 -0
  125. package/docs/AI-AUTHORING.md +113 -0
  126. package/docs/ASSETS.md +106 -0
  127. package/docs/AWS.md +77 -0
  128. package/docs/BEST-PRACTICES.md +267 -0
  129. package/docs/CAPACITY.md +208 -0
  130. package/docs/CLOUDFLARE.md +110 -0
  131. package/docs/COMPLIANCE.md +242 -0
  132. package/docs/DYNAMIC-LINKS.md +561 -0
  133. package/docs/FUNCTION-SECURITY.md +113 -0
  134. package/docs/HTTP.md +129 -0
  135. package/docs/INSTALL.md +90 -0
  136. package/docs/LOAD-TESTING.md +91 -0
  137. package/docs/LOCAL-DEVELOPMENT.md +99 -0
  138. package/docs/MANAGEMENT-SECURITY.md +82 -0
  139. package/docs/MIDDLEWARE.md +83 -0
  140. package/docs/MONITORING.md +132 -0
  141. package/docs/OBSERVABILITY.md +229 -0
  142. package/docs/OPERATIONAL-PROOF.md +42 -0
  143. package/docs/OPERATIONS.md +207 -0
  144. package/docs/ORGANIZATION.md +135 -0
  145. package/docs/PERFORMANCE.md +72 -0
  146. package/docs/PLUGINS.md +234 -0
  147. package/docs/POLICIES.md +489 -0
  148. package/docs/PRERENDER.md +193 -0
  149. package/docs/PROJECT-DIRECTION.md +51 -0
  150. package/docs/READINESS.md +125 -0
  151. package/docs/README.md +58 -0
  152. package/docs/RELEASE-READINESS.md +95 -0
  153. package/docs/RELEASE-SECURITY.md +72 -0
  154. package/docs/RESILIENCE.md +160 -0
  155. package/docs/ROUTING.md +95 -0
  156. package/docs/SANDBOX-REVIEW.md +59 -0
  157. package/docs/SCAFFOLDING.md +72 -0
  158. package/docs/SECURITY-AUDIT.md +124 -0
  159. package/docs/SITE.md +150 -0
  160. package/docs/SPECIFICATION.md +232 -0
  161. package/docs/SPIKE-EXTENSIONS.md +475 -0
  162. package/docs/STANDARDS.md +303 -0
  163. package/docs/STARTERS.md +51 -0
  164. package/docs/TUNNELS.md +75 -0
  165. package/docs/TYPESCRIPT.md +102 -0
  166. package/docs/VERCEL.md +107 -0
  167. package/docs/YAML-GUIDE.md +521 -0
  168. package/docs/YAML-REFERENCE.md +328 -0
  169. package/docs/policies/agents.md +182 -0
  170. package/docs/policies/cache.md +139 -0
  171. package/docs/policies/compression.md +168 -0
  172. package/docs/policies/security.md +160 -0
  173. package/docs/policies/throttle.md +103 -0
  174. package/examples/assets/.env.example +1 -0
  175. package/examples/assets/.gitattributes +2 -0
  176. package/examples/assets/Makefile +30 -0
  177. package/examples/assets/README.md +18 -0
  178. package/examples/assets/functions/hello.mjs +3 -0
  179. package/examples/assets/gitignore.template +7 -0
  180. package/examples/assets/public/about.html +2 -0
  181. package/examples/assets/public/assets/example.txt +1 -0
  182. package/examples/assets/public/guide.txt +1 -0
  183. package/examples/assets/tests/requests.json +44 -0
  184. package/examples/assets/urlcode.yaml +27 -0
  185. package/examples/aws/README.md +13 -0
  186. package/examples/aws/handler.mjs +5 -0
  187. package/examples/aws/public/index.html +3 -0
  188. package/examples/aws/public/notes.txt +1 -0
  189. package/examples/aws/template.yaml +33 -0
  190. package/examples/aws/tests/requests.json +9 -0
  191. package/examples/aws/urlcode.yaml +19 -0
  192. package/examples/cloudflare/README.md +18 -0
  193. package/examples/cloudflare/package.json +14 -0
  194. package/examples/cloudflare/tests/requests.json +9 -0
  195. package/examples/cloudflare/urlcode.yaml +24 -0
  196. package/examples/cloudflare/wrangler.toml +5 -0
  197. package/examples/compliance/README.md +20 -0
  198. package/examples/compliance/rules.mjs +65 -0
  199. package/examples/cookbook/README.md +21 -0
  200. package/examples/cookbook/functions/choice.mjs +4 -0
  201. package/examples/cookbook/functions/echo.mjs +3 -0
  202. package/examples/cookbook/functions/hello.mjs +3 -0
  203. package/examples/cookbook/functions/text.mjs +3 -0
  204. package/examples/cookbook/middleware/headers.mjs +6 -0
  205. package/examples/cookbook/public/about.html +1 -0
  206. package/examples/cookbook/public/assets/index.html +1 -0
  207. package/examples/cookbook/public/assets/site.css +1 -0
  208. package/examples/cookbook/public/favicon.svg +1 -0
  209. package/examples/cookbook/public/guide.txt +1 -0
  210. package/examples/cookbook/public/llms.txt +6 -0
  211. package/examples/cookbook/routes/code.yaml +55 -0
  212. package/examples/cookbook/routes/files.yaml +17 -0
  213. package/examples/cookbook/routes/policies.yaml +28 -0
  214. package/examples/cookbook/routes/redirects.yaml +38 -0
  215. package/examples/cookbook/routes/responses.yaml +26 -0
  216. package/examples/cookbook/tests/requests.json +254 -0
  217. package/examples/cookbook/urlcode.yaml +22 -0
  218. package/examples/live-links/README.md +11 -0
  219. package/examples/live-links/tests/requests.json +6 -0
  220. package/examples/live-links/urlcode.yaml +16 -0
  221. package/examples/monitoring/blackbox-jobs.yaml +37 -0
  222. package/examples/monitoring/prometheus-rules.yaml +88 -0
  223. package/examples/monitoring/prometheus-scrape.yaml +20 -0
  224. package/examples/monitoring/vector.toml +65 -0
  225. package/examples/prerender/README.md +48 -0
  226. package/examples/prerender/functions/page.mjs +6 -0
  227. package/examples/prerender/middleware/template.mjs +29 -0
  228. package/examples/prerender/prerender.d.mts +4 -0
  229. package/examples/prerender/prerender.mjs +63 -0
  230. package/examples/prerender/tests/requests.json +39 -0
  231. package/examples/prerender/urlcode.yaml +50 -0
  232. package/examples/tunnel/dev-with-ngrok.sh +61 -0
  233. package/examples/vercel/README.md +13 -0
  234. package/examples/vercel/api/index.js +5 -0
  235. package/examples/vercel/package.json +8 -0
  236. package/examples/vercel/public/index.html +3 -0
  237. package/examples/vercel/public/notes.txt +1 -0
  238. package/examples/vercel/tests/requests.json +48 -0
  239. package/examples/vercel/urlcode.yaml +19 -0
  240. package/examples/vercel/vercel.json +10 -0
  241. package/llms.txt +46 -0
  242. package/package.json +123 -0
  243. package/schemas/urlcode.schema.json +1230 -0
  244. package/starters/default/.gitattributes +1 -0
  245. package/starters/default/Makefile +30 -0
  246. package/starters/default/README.md +34 -0
  247. package/starters/default/functions/hello.mjs +3 -0
  248. package/starters/default/gitignore.template +8 -0
  249. package/starters/default/middleware/headers.mjs +6 -0
  250. package/starters/default/routes/functions.yaml +20 -0
  251. package/starters/default/routes/marketing/links.yaml +7 -0
  252. package/starters/default/starter.json +5 -0
  253. package/starters/default/tests/requests.json +56 -0
  254. package/starters/default/urlcode.yaml +8 -0
@@ -0,0 +1,91 @@
1
+ import type { ProjectPlan } from './readiness.ts';
2
+ import type { OperatorPolicy } from './policy.ts';
3
+ import type { LinkStoreOptions } from './link-store.ts';
4
+ import type { Plugin } from './plugins.ts';
5
+ import type { MetricsSnapshot, Observer } from './observability.ts';
6
+ import type { HandlerResult, HeaderPair } from './http-response.ts';
7
+ import type { LogFn, PolicyInventory, TargetName } from './types.ts';
8
+ /** A stored link as a link store returns it; the runtime validates the fields it uses. */
9
+ export interface LinkLookup {
10
+ url?: unknown;
11
+ status?: unknown;
12
+ enabled?: unknown;
13
+ expires?: unknown;
14
+ }
15
+ /** What a `linkStores` binding must provide: a reader and, optionally, its health. */
16
+ export interface LinkReader {
17
+ get(collection: string, code: string): Promise<LinkLookup | null | undefined>;
18
+ readonly readHealthy?: boolean;
19
+ readonly healthy?: boolean;
20
+ }
21
+ /** An operator-owned SQLite link store the runtime opens read-only for one collection. */
22
+ export interface LinkStoreBinding extends LinkStoreOptions {
23
+ collection: string;
24
+ }
25
+ export type { OperatorPolicy } from './policy.ts';
26
+ /** An operator plugin (src/plugins.ts). */
27
+ export type HostPlugin = Plugin;
28
+ export type { Observer, MetricsSnapshot } from './observability.ts';
29
+ export interface TestPlan extends ProjectPlan {
30
+ dynamicLinks: boolean;
31
+ policies: Record<string, PolicyInventory>;
32
+ }
33
+ export interface RuntimeOptions {
34
+ observers?: Observer[] | undefined;
35
+ log?: LogFn | undefined;
36
+ origin?: string | undefined;
37
+ local?: boolean | undefined;
38
+ environment?: NodeJS.ProcessEnv | undefined;
39
+ permissions?: OperatorPolicy | undefined;
40
+ linkStore?: LinkStoreBinding | undefined;
41
+ linkStores?: Record<string, LinkReader> | undefined;
42
+ target?: TargetName | undefined;
43
+ plugins?: HostPlugin[] | undefined;
44
+ workers?: number | undefined;
45
+ timeoutMs?: number | undefined;
46
+ maxBytes?: number | undefined;
47
+ }
48
+ /** Per-request facts the host may read after handle() settles; never request text. */
49
+ export interface LinkTrace {
50
+ collection: string;
51
+ code: string | null;
52
+ result: string;
53
+ }
54
+ export interface RequestTrace {
55
+ route?: string;
56
+ probe?: boolean;
57
+ client?: string | null;
58
+ link?: LinkTrace;
59
+ }
60
+ export interface RuntimeRequest {
61
+ target: string;
62
+ method?: string | undefined;
63
+ headers?: Headers | undefined;
64
+ body?: Uint8Array | undefined;
65
+ headerCounts?: Record<string, number> | undefined;
66
+ trace?: RequestTrace | undefined;
67
+ origin?: string | undefined;
68
+ client?: string | undefined;
69
+ }
70
+ export interface Runtime {
71
+ readonly healthy: boolean;
72
+ assetWatch: string[];
73
+ version: string;
74
+ count: number;
75
+ root: string;
76
+ testPlan(): TestPlan;
77
+ readonly plugins: {
78
+ name: string;
79
+ version: string;
80
+ }[];
81
+ readonly workers: {
82
+ healthy: number;
83
+ slots: number;
84
+ };
85
+ metrics(): MetricsSnapshot;
86
+ errorHeaders(error: unknown, origin: string): HeaderPair[];
87
+ requestLimit(target: string): number | undefined;
88
+ handle(request: RuntimeRequest): Promise<HandlerResult>;
89
+ close(): Promise<void>;
90
+ }
91
+ export declare function createRuntime(project: string, rawOptions?: RuntimeOptions): Promise<Runtime>;
@@ -0,0 +1,17 @@
1
+ export interface Unresolved {
2
+ path?: string;
3
+ reason: string;
4
+ collection?: string;
5
+ }
6
+ export interface ScaffoldReport {
7
+ dryRun: boolean;
8
+ dynamicLinks: boolean;
9
+ created: string[];
10
+ preserved: string[];
11
+ unresolved: Unresolved[];
12
+ requiredBindings: string[];
13
+ needsImplementation: true;
14
+ }
15
+ export declare function scaffoldProject(project: string, { dryRun }?: {
16
+ dryRun?: boolean | undefined;
17
+ }): Promise<ScaffoldReport>;
@@ -0,0 +1,37 @@
1
+ import http from 'node:http';
2
+ import type { AddressInfo } from 'node:net';
3
+ import type { RuntimeOptions, TestPlan } from './runtime.ts';
4
+ import type { LinkObserverStats } from './link-events.ts';
5
+ import type { MetricsSnapshot, Observer } from './observability.ts';
6
+ export interface ServerOptions extends Omit<RuntimeOptions, 'observers'> {
7
+ project?: string | undefined;
8
+ host?: string | undefined;
9
+ port?: number | undefined;
10
+ watch?: boolean | undefined;
11
+ maxBodyBytes?: number | undefined;
12
+ maxInFlightRequests?: number | undefined;
13
+ maxInFlightHealthRequests?: number | undefined;
14
+ requestLog?: string | undefined;
15
+ trustRequestId?: boolean | undefined;
16
+ linkEvents?: unknown;
17
+ trustedProxies?: string | string[] | undefined;
18
+ observers?: Observer[] | undefined;
19
+ metrics?: boolean | undefined;
20
+ metricsIntervalMs?: number | undefined;
21
+ }
22
+ export interface Server {
23
+ server: http.Server;
24
+ reload(): Promise<boolean>;
25
+ address: AddressInfo;
26
+ root: string;
27
+ testPlan(): TestPlan;
28
+ linkEventStats(): LinkObserverStats | undefined;
29
+ metrics(): MetricsSnapshot;
30
+ readonly observers: {
31
+ name: string;
32
+ version: string;
33
+ }[];
34
+ origin: string;
35
+ close(): Promise<void>;
36
+ }
37
+ export declare function startServer({ project, host, port, watch, local, log, maxBodyBytes, maxInFlightRequests, maxInFlightHealthRequests, requestLog, trustRequestId, origin, linkEvents, trustedProxies, observers, metrics, metricsIntervalMs, ...runtimeOptions }?: ServerOptions): Promise<Server>;
@@ -0,0 +1,12 @@
1
+ import type { LoadedDocument, LogFn, ProjectDocument, RouteConfig, SiteConfig } from './types.ts';
2
+ export interface SiteOptions {
3
+ origin?: string | undefined;
4
+ log?: LogFn;
5
+ routes?: Record<string, RouteConfig>;
6
+ }
7
+ type SiteKey = keyof SiteConfig;
8
+ export declare const generatedPaths: Readonly<Record<SiteKey, string>>;
9
+ export declare const MAX_SITEMAP_URLS = 50000;
10
+ export declare function expandSite(document: ProjectDocument, root: string, { origin, log, routes }?: SiteOptions): Promise<Record<string, RouteConfig>>;
11
+ export declare function applySite(loaded: LoadedDocument, options?: SiteOptions): Promise<Record<string, RouteConfig>>;
12
+ export {};
@@ -0,0 +1 @@
1
+ export declare function supportsConcurrentWal(version: unknown): boolean;
@@ -0,0 +1,332 @@
1
+ import type { HandlerResult, HeaderPair } from './http-response.ts';
2
+ import type { CompiledParameter, MatchableRoute, ParameterLocation, ParameterSchema, RedirectSpec, Scalar, ValueRef } from './match.ts';
3
+ import type { HttpRoute, Reply, RequestBodyPolicy, RespondSpec } from './http-policy.ts';
4
+ import type { AgentsConfig, AgentsDescription, AgentsState } from './policies/agents.ts';
5
+ import type { SecurityConfig, SecurityDescription, SecurityState } from './policies/security.ts';
6
+ import type { CacheConfig, CacheDescription, CacheState, CacheStore } from './policies/cache.ts';
7
+ import type { CompressionConfig, CompressionDescription, CompressionState } from './policies/compression.ts';
8
+ import type { ThrottleConfig, ThrottleDescription, ThrottleState, ThrottleTable } from './policies/throttle.ts';
9
+ /** An operator log sink; every record is a flat JSON object with an `event` name. */
10
+ export type LogFn = (event: Record<string, unknown>) => void;
11
+ /** One declared input: a path placeholder, a query parameter or a request header. */
12
+ export interface ParameterConfig {
13
+ name: string;
14
+ in: ParameterLocation;
15
+ required?: boolean;
16
+ schema: ParameterSchema;
17
+ }
18
+ /** `env` binding: a literal `value`, or the `env` name to read from the process environment. */
19
+ export interface EnvBinding {
20
+ value?: string;
21
+ env?: string;
22
+ }
23
+ /** `secrets` binding: the `secret` name to read from the process environment. */
24
+ export interface SecretBinding {
25
+ secret: string;
26
+ }
27
+ export interface FunctionConfig {
28
+ source: string;
29
+ export?: string;
30
+ args?: Record<string, ValueRef | Scalar>;
31
+ }
32
+ export interface MiddlewareConfig {
33
+ source: string;
34
+ export?: string;
35
+ }
36
+ export interface LinkConfig {
37
+ collection: string;
38
+ code: ValueRef;
39
+ }
40
+ export interface PageConfig {
41
+ file: string;
42
+ contentType?: string;
43
+ cacheControl?: string;
44
+ }
45
+ export interface DownloadConfig extends PageConfig {
46
+ filename?: string;
47
+ }
48
+ export interface StaticConfig {
49
+ directory: string;
50
+ contentType?: string;
51
+ cacheControl?: string;
52
+ index?: string;
53
+ }
54
+ /** `redirect` as declared: `query.pass` may be `false` (the schema allows it; readers treat it as an empty list). */
55
+ export interface RedirectConfig {
56
+ url: string;
57
+ status?: 301 | 302 | 303 | 307 | 308;
58
+ query?: {
59
+ pass?: string[] | false;
60
+ map?: Record<string, ValueRef | Scalar>;
61
+ };
62
+ }
63
+ export type PolicyName = 'agents' | 'throttle' | 'cache' | 'security' | 'compression';
64
+ /** Each first-party policy's YAML configuration, keyed by its `policies` name. */
65
+ export interface PolicyConfigs {
66
+ agents: AgentsConfig;
67
+ throttle: ThrottleConfig;
68
+ cache: CacheConfig;
69
+ security: SecurityConfig;
70
+ compression: CompressionConfig;
71
+ }
72
+ /** One `policies` block or profile layer: every policy optional, `false` disables it. */
73
+ /** One layer of policy configuration (profile, project or route); a layer may declare part of a policy, the merge supplies the rest. */
74
+ export type PolicyLayer = {
75
+ [K in PolicyName]?: Partial<PolicyConfigs[K]> | false;
76
+ };
77
+ export interface PoliciesConfig extends PolicyLayer {
78
+ profile?: string;
79
+ }
80
+ /** The result of layering profiles and route keys: what compiles, per policy. */
81
+ export type EffectivePolicies = Partial<PolicyConfigs>;
82
+ export interface RobotsConfig {
83
+ disallow?: string[];
84
+ allow?: string[];
85
+ sitemap?: boolean;
86
+ extra?: string[];
87
+ }
88
+ export type Changefreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
89
+ export interface SitemapConfig {
90
+ exclude?: string[];
91
+ changefreq?: Changefreq;
92
+ priority?: number;
93
+ }
94
+ export interface SecurityTxtConfig {
95
+ contact: string[];
96
+ expires: string;
97
+ policy?: string[];
98
+ acknowledgments?: string[];
99
+ preferredLanguages?: string[];
100
+ canonical?: string[];
101
+ encryption?: string[];
102
+ }
103
+ export interface SiteConfig {
104
+ robots?: RobotsConfig;
105
+ sitemap?: true | SitemapConfig;
106
+ favicon?: string;
107
+ securityTxt?: SecurityTxtConfig;
108
+ llms?: string;
109
+ }
110
+ /** One route as declared in YAML (plus `generated`, which site.ts stamps on the routes it adds). */
111
+ export interface RouteConfig {
112
+ methods?: string[];
113
+ enabled?: boolean;
114
+ expires?: string;
115
+ description?: string;
116
+ parameters?: ParameterConfig[];
117
+ redirect?: RedirectConfig;
118
+ function?: FunctionConfig;
119
+ env?: Record<string, EnvBinding>;
120
+ secrets?: Record<string, SecretBinding>;
121
+ page?: PageConfig;
122
+ download?: DownloadConfig;
123
+ static?: StaticConfig;
124
+ request?: {
125
+ body?: RequestBodyPolicy;
126
+ };
127
+ response?: {
128
+ headers?: Record<string, string | string[]>;
129
+ };
130
+ respond?: RespondSpec;
131
+ middleware?: MiddlewareConfig[];
132
+ link?: LinkConfig;
133
+ policies?: PoliciesConfig;
134
+ /** Set by site.ts on a route it generated (`site.<key>`); never declared in YAML. */
135
+ generated?: string;
136
+ }
137
+ export interface ProjectDocument {
138
+ version: '1';
139
+ routes: Record<string, RouteConfig>;
140
+ includes?: string[];
141
+ dynamicLinks?: boolean;
142
+ policies?: PoliciesConfig;
143
+ profiles?: Record<string, PolicyLayer>;
144
+ site?: SiteConfig;
145
+ }
146
+ /** What config.ts returns: the entry document, the merged route table and the files it came from. */
147
+ export interface LoadedDocument {
148
+ root: string;
149
+ document: ProjectDocument;
150
+ routes: Record<string, RouteConfig>;
151
+ files: string[];
152
+ version: string;
153
+ }
154
+ export interface CompiledFunction {
155
+ source: string;
156
+ export: string;
157
+ args?: Record<string, ValueRef | Scalar>;
158
+ }
159
+ export interface CompiledMiddleware {
160
+ source: string;
161
+ export: string;
162
+ }
163
+ /** One file read into the asset snapshot; a static route holds a Map of them keyed by relative path. */
164
+ export interface Asset {
165
+ body: Buffer;
166
+ modified: string;
167
+ type: string;
168
+ attachment: string | undefined;
169
+ etag: string;
170
+ cache: string;
171
+ /** Precompressed variants the compression policy attaches at compile time, keyed by content coding. */
172
+ encoded?: Record<string, Buffer>;
173
+ }
174
+ /** A handler result that came from the asset snapshot, so a later policy can serve a stored variant by identity. */
175
+ export interface AssetResult extends HandlerResult {
176
+ asset?: Asset;
177
+ }
178
+ /** `redirect` once compiled: `query.pass` is a list or absent (a declared `false` is dropped), so match.ts's RedirectSpec holds. */
179
+ export interface CompiledRedirect extends RedirectSpec {
180
+ status?: 301 | 302 | 303 | 307 | 308;
181
+ }
182
+ /**
183
+ * The route the router produces: the YAML route with its bindings resolved,
184
+ * its parameters compiled and everything request-time matching, the HTTP
185
+ * policy and the asset snapshot need. Widens MatchableRoute (match.ts).
186
+ */
187
+ export interface CompiledRoute extends Omit<RouteConfig, 'methods' | 'parameters' | 'env' | 'secrets' | 'function' | 'middleware' | 'redirect'>, MatchableRoute, HttpRoute {
188
+ pattern: string;
189
+ parts: string[];
190
+ names: string[];
191
+ specificity: number;
192
+ methods: string[];
193
+ parameters: CompiledParameter[];
194
+ env: Record<string, string>;
195
+ secrets: Record<string, string>;
196
+ redirect?: CompiledRedirect;
197
+ responseHeaders: HeaderPair[];
198
+ reply?: Reply;
199
+ expiresAt?: number;
200
+ prefix?: string;
201
+ middleware: CompiledMiddleware[];
202
+ function?: CompiledFunction;
203
+ respond?: RespondSpec;
204
+ page?: PageConfig;
205
+ download?: DownloadConfig;
206
+ static?: StaticConfig;
207
+ /** Attached by compileAssets: one asset for page/download, a Map for static. */
208
+ asset?: Asset | Map<string, Asset>;
209
+ /** Attached by the runtime once policies compile; null when the project declares none. */
210
+ policy?: PolicyChain | null;
211
+ /** Attached by build-cloudflare: the compiled policy states shipped in the Worker artifact. */
212
+ compiledPolicies?: Record<string, unknown>;
213
+ }
214
+ export interface CompiledRouteTable {
215
+ exact: Map<string, CompiledRoute>;
216
+ byLength: Map<number, CompiledRoute[]>;
217
+ mounts: CompiledRoute[];
218
+ /** Absolute paths of every function module the routes reference. */
219
+ modules: string[];
220
+ count: number;
221
+ }
222
+ export type TargetName = 'node' | 'vercel' | 'aws' | 'cloudflare';
223
+ export type PolicySupport = 'native' | 'compiled' | 'delegated' | 'refused';
224
+ /** Per-runtime state policies share; released by closePolicies. Each policy owns one key. */
225
+ export interface PolicyShared {
226
+ target?: string;
227
+ log?: LogFn;
228
+ routes?: number;
229
+ /** Clock override for tests. */
230
+ now?: () => number;
231
+ cache?: CacheStore;
232
+ throttle?: ThrottleTable;
233
+ compressionBytes?: number;
234
+ }
235
+ /** The route facts a policy may read at compile time; a CompiledRoute satisfies it, tests pass less. */
236
+ export interface PolicyRoute {
237
+ pattern: string;
238
+ secrets?: Record<string, string>;
239
+ methods?: readonly string[];
240
+ responseHeaders?: readonly HeaderPair[];
241
+ asset?: Asset | Map<string, Asset>;
242
+ policies?: PoliciesConfig;
243
+ }
244
+ export interface PolicyContext {
245
+ route: PolicyRoute;
246
+ shared: PolicyShared;
247
+ target?: TargetName;
248
+ document?: ProjectDocument;
249
+ root?: string;
250
+ }
251
+ /** The request a policy sees (built by policyRequest): runtime objects, never re-parsed text. */
252
+ export interface PolicyRequest {
253
+ method: string;
254
+ target: string;
255
+ path: string;
256
+ params: Record<string, string>;
257
+ query: URLSearchParams;
258
+ /** The Fetch Headers surface (agents.ts reads it on the Worker); the Node host wraps its header map to match. */
259
+ headers: {
260
+ has(name: string): boolean;
261
+ get(name: string): string | null;
262
+ };
263
+ headerCounts: Record<string, number> | undefined;
264
+ client: string | null;
265
+ origin: string | undefined;
266
+ route: string;
267
+ secrets: boolean;
268
+ }
269
+ /**
270
+ * One policy module. Hooks are declared as methods so a module typed with its
271
+ * own Config and State (PolicyModule<CacheConfig, CacheState>) is assignable
272
+ * to the erased PolicyModule the registry and the compiled chain hold.
273
+ */
274
+ export interface PolicyModule<Config = unknown, State = unknown, Description extends object = object> {
275
+ name: string;
276
+ phases: readonly string[];
277
+ targets(config: Config): Record<TargetName, PolicySupport>;
278
+ compile(config: Config, context: PolicyContext): State | Promise<State>;
279
+ onRequest?(state: State, request: PolicyRequest): HandlerResult | undefined | Promise<HandlerResult | undefined>;
280
+ onResponse?(state: State, request: PolicyRequest, result: HandlerResult): HandlerResult | Promise<HandlerResult>;
281
+ onError?(state: State, request: PolicyRequest, error: unknown): HandlerResult | undefined | void | Promise<HandlerResult | undefined | void>;
282
+ /** A JSON summary for the audit and inventory; each module returns its own description shape. */
283
+ describe?(state: State): Description;
284
+ close?(shared: PolicyShared): void | Promise<void>;
285
+ }
286
+ export interface PolicyStates {
287
+ agents: AgentsState;
288
+ throttle: ThrottleState;
289
+ cache: CacheState;
290
+ security: SecurityState;
291
+ compression: CompressionState;
292
+ }
293
+ export interface PolicyDescriptions {
294
+ agents: AgentsDescription;
295
+ throttle: ThrottleDescription;
296
+ cache: CacheDescription;
297
+ security: SecurityDescription;
298
+ compression: CompressionDescription;
299
+ }
300
+ /** A route's policy inventory: each policy's describe() plus the support it got; a delegated policy carries only `target`. */
301
+ export type PolicyInventory = {
302
+ [K in PolicyName]?: Partial<PolicyDescriptions[K]> & {
303
+ target: PolicySupport;
304
+ };
305
+ };
306
+ /** A module paired with the state it compiled for one route, in phase order. */
307
+ export type PolicyEntry = [PolicyModule, unknown];
308
+ /** What compilePolicies returns for a route: ordered hook chains, the audit summary and each state by name. */
309
+ export type PolicyChain = {
310
+ request: PolicyEntry[];
311
+ response: PolicyEntry[];
312
+ error: PolicyEntry[];
313
+ describe: PolicyInventory;
314
+ } & Partial<PolicyStates>;
315
+ export type RouteState = 'active' | 'disabled' | 'expired';
316
+ /** One route in the audit inventory: its handler kind, methods and lifecycle state. */
317
+ export interface PlanInventoryEntry {
318
+ path: string;
319
+ handler: string | undefined;
320
+ methods: string[];
321
+ middleware: number;
322
+ policies: string[];
323
+ generated?: string;
324
+ state: RouteState;
325
+ }
326
+ export interface TestPlan {
327
+ inventory: PlanInventoryEntry[];
328
+ cases: unknown[];
329
+ resolve?(path: string): string | undefined;
330
+ dynamicLinks?: boolean;
331
+ policies?: Record<string, PolicyInventory>;
332
+ }
@@ -0,0 +1,12 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { Environment } from './adapters.ts';
3
+ import type { HostPlugin } from './runtime.ts';
4
+ export interface VercelHandlerOptions {
5
+ project?: string | undefined;
6
+ origin?: string | undefined;
7
+ environment?: Environment | undefined;
8
+ maxBodyBytes?: number | undefined;
9
+ plugins?: HostPlugin[] | undefined;
10
+ }
11
+ export type VercelHandler = (req: IncomingMessage, res: ServerResponse) => Promise<void>;
12
+ export declare function createVercelHandler({ project, origin, environment, maxBodyBytes, plugins }?: VercelHandlerOptions): VercelHandler;