@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
package/README.md
CHANGED
|
@@ -1,37 +1,115 @@
|
|
|
1
1
|
# URLCode
|
|
2
2
|
|
|
3
|
-
**A portable runtime for programmable URL behavior
|
|
4
|
-
public URL surface in YAML, add
|
|
5
|
-
handlers are not enough, and run the same
|
|
6
|
-
|
|
3
|
+
**A portable runtime for programmable URL behavior, and the framework that grows
|
|
4
|
+
from it.** Declare an application's public URL surface in YAML, add JavaScript
|
|
5
|
+
only where declarative handlers are not enough, and run the same
|
|
6
|
+
project locally, in a container, on your own infrastructure or on a provider
|
|
7
|
+
adapter. When the project gets serious, add accounts and an administration
|
|
8
|
+
console as operator-installed extensions instead of building them again.
|
|
9
|
+
**URL behavior as code.**
|
|
7
10
|
|
|
8
11
|
[](https://github.com/jimhoyd-com/urlcode/actions/workflows/ci.yml)
|
|
9
12
|
|
|
10
|
-
[Documentation](docs/README.md) · [Starter](https://github.com/jimhoyd-com/urlcode-template) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md)
|
|
13
|
+
[Documentation](docs/README.md) · [The framework](docs/FRAMEWORK.md) · [For AI agents](llms.txt) · [Starter](https://github.com/jimhoyd-com/urlcode-template) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md)
|
|
14
|
+
|
|
15
|
+
**Your AI should build your application, not your framework.** Coding agents
|
|
16
|
+
rebuild the same routing, validation, middleware, policies and authentication
|
|
17
|
+
plumbing on every project, and the person ends up owning the plumbing. URLCode
|
|
18
|
+
represents those behaviors as a strict, portable YAML contract that both people
|
|
19
|
+
and agents can read: the agent describes what, the runtime owns how, and
|
|
20
|
+
generated code goes to the part that is actually the application. It is
|
|
21
|
+
infrastructure for AI-built software, not a framework for building AI models.
|
|
22
|
+
[Why](docs/PROJECT-DIRECTION.md#why-your-ai-should-build-your-application-not-your-framework) ·
|
|
23
|
+
[next steps](docs/NEXT-STEPS.md).
|
|
24
|
+
|
|
25
|
+
## What it is
|
|
26
|
+
|
|
27
|
+
A project is a `urlcode.yaml` with `version: "1"`. Each route has exactly one
|
|
28
|
+
handler: `redirect`, `respond`, `page`, `static`, `download`, `function`,
|
|
29
|
+
`proxy`, `conditional` or an `extension` mount, with optional ordered
|
|
30
|
+
`middleware`. The runtime validates the whole project before serving it,
|
|
31
|
+
compiles it once, and refuses anything a target cannot enforce with the route
|
|
32
|
+
named. Functions and middleware run trusted, in-process, with full Node
|
|
33
|
+
access by default; a route opts into an isolated QuickJS/WebAssembly sandbox
|
|
34
|
+
with a fresh heap per call and no Node, filesystem or network by declaring
|
|
35
|
+
`sandbox: true`. Either way, secrets reach them only through operator grants
|
|
36
|
+
pinned to the project revision.
|
|
37
|
+
|
|
38
|
+
URLCode is not a URL shortener: stored short links are an operator-installed
|
|
39
|
+
extension, not core's job. It is not a
|
|
40
|
+
general Node web framework: routing, validation, middleware wiring and
|
|
41
|
+
policies are declared in YAML, not hand-wired; isolating a specific route's
|
|
42
|
+
code from the host is an explicit `sandbox: true` opt-in, not something every
|
|
43
|
+
route gets by writing a handler. It is not a provider configuration format:
|
|
44
|
+
infrastructure settings stay out of route YAML.
|
|
45
|
+
See [project direction](docs/PROJECT-DIRECTION.md).
|
|
46
|
+
|
|
47
|
+
## The framework
|
|
48
|
+
|
|
49
|
+
Four packages, one project shape. A project climbs from redirects to a full
|
|
50
|
+
application by adding YAML; the operator wires trusted packages in one host
|
|
51
|
+
file outside the project. The full map, the composition contract and the rules
|
|
52
|
+
an AI agent must follow are in [the framework](docs/FRAMEWORK.md).
|
|
53
|
+
|
|
54
|
+
| Package | Adds | Status |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| [urlcode](https://github.com/jimhoyd-com/urlcode) (this repository) | Runtime, CLI, policies, provider adapters, extension contract | `0.4.0-alpha.2` (alpha) on top of the `0.3.0` release, Apache-2.0 |
|
|
57
|
+
| [urlcode-ui](https://github.com/jimhoyd-com/urlcode-ui) | Shared presentation: escaped templates, shadcn/ui partials, themes, translations | `0.1.0-alpha.5` on npm, alpha: review pending |
|
|
58
|
+
| [urlcode-auth](https://github.com/jimhoyd-com/urlcode-auth) | Accounts: password, passkeys, OIDC, email codes, TOTP, sessions, roles, account page | `0.1.0-alpha.3` on npm, alpha: review pending |
|
|
59
|
+
| [urlcode-admin](https://github.com/jimhoyd-com/urlcode-admin) | Administration: users, sessions, roles, audit, approvals, cases, impersonation | `0.1.0-alpha.3` on npm, alpha: review pending |
|
|
60
|
+
| [urlcode-dynamic-link](https://github.com/jimhoyd-com/urlcode-dynamic-link) | Stored short links: the mount-based successor to core's removed `link` handler | `0.1.0-alpha.2` on npm, alpha: review pending |
|
|
61
|
+
| [urlcode-middleware](https://github.com/jimhoyd-com/urlcode-middleware) | Per-route middleware through the extension seam, alongside core's native array | `0.1.0-alpha.2` on npm, alpha: review pending |
|
|
62
|
+
| [urlcode-short](https://github.com/jimhoyd-com/urlcode-short) | A complete link shortener assembled from the packages above | `0.1.0-alpha.2` on npm, alpha: review pending |
|
|
63
|
+
|
|
64
|
+
Every version in this table is the one published to npm under the `alpha`
|
|
65
|
+
dist-tag, and they are released together in the order core → ui → auth →
|
|
66
|
+
admin → dynamic-link/middleware → short. The authoritative cross-repository
|
|
67
|
+
register, including each package's declared peer ranges and the rules that
|
|
68
|
+
keep them consistent, is
|
|
69
|
+
[docs/VERSION-ALIGNMENT.md](docs/VERSION-ALIGNMENT.md).
|
|
11
70
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
71
|
+
```yaml
|
|
72
|
+
version: "1"
|
|
73
|
+
extensions:
|
|
74
|
+
auth: { version: "1", config: { registration: "off" } }
|
|
75
|
+
admin: { version: "1", config: {} }
|
|
76
|
+
routes:
|
|
77
|
+
/go: { redirect: { url: https://example.com, status: 302 } }
|
|
78
|
+
/account/*: { extension: auth, methods: [GET, HEAD, POST] }
|
|
79
|
+
/admin/*: { extension: admin, methods: [GET, HEAD, POST] }
|
|
80
|
+
/private:
|
|
81
|
+
respond: { text: Signed in }
|
|
82
|
+
policies: { extensions: { auth: {} } }
|
|
83
|
+
```
|
|
17
84
|
|
|
18
|
-
|
|
19
|
-
the
|
|
85
|
+
The YAML names logical extensions; it never names packages, code, databases
|
|
86
|
+
or credentials. `urlcode-auth init` writes the operator host, keys and a
|
|
87
|
+
private data directory beside the project; `urlcode serve --host-file` loads
|
|
88
|
+
it. Cross-repository acceptance is tracked in
|
|
89
|
+
[issue 58](https://github.com/jimhoyd-com/urlcode/issues/58).
|
|
20
90
|
|
|
21
91
|
## Status
|
|
22
92
|
|
|
23
|
-
`0.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
93
|
+
`0.4.0-alpha.2` is the current release of the extension contract and the
|
|
94
|
+
agent tooling, on top of the `0.3.0` self-hosted release. `0.4.0-alpha.1`
|
|
95
|
+
added the extension contract, capabilities and provider conformance, strict
|
|
96
|
+
redirect interchange, bulk import, recipes and search, TypeScript guest
|
|
97
|
+
authoring, conditions, bounded proxy and signals, and the MCP read and
|
|
98
|
+
authoring modes. `0.4.0-alpha.2` then made `function` and `middleware` routes
|
|
99
|
+
run trusted and unsandboxed by default, with `sandbox: true` as a per-route
|
|
100
|
+
opt-in, and removed the native `link:`/`dynamicLinks:` YAML shape. That is a
|
|
101
|
+
behaviour change for existing projects with no YAML edit; read
|
|
102
|
+
[the roadmap entry](ROADMAP.md) before upgrading. Use the schema and docs from
|
|
103
|
+
the runtime revision you run.
|
|
104
|
+
The [roadmap](ROADMAP.md) separates implemented from planned, and
|
|
105
|
+
[release readiness](docs/RELEASE-READINESS.md) records what is proven and
|
|
106
|
+
what is not: provider deployments, soak and independent security review
|
|
107
|
+
remain open.
|
|
108
|
+
|
|
109
|
+
Stored short links have moved out of core into
|
|
110
|
+
[urlcode-dynamic-link](https://github.com/jimhoyd-com/urlcode-dynamic-link)
|
|
111
|
+
(mount-based, like `auth`/`admin`, published on npm); core no longer has a
|
|
112
|
+
native `link` handler.
|
|
35
113
|
|
|
36
114
|
URLCode is free and open-source software licensed under the
|
|
37
115
|
[Apache License 2.0](LICENSE). Commercial use, modification, redistribution and
|
|
@@ -42,7 +120,9 @@ self-hosting are permitted under its terms.
|
|
|
42
120
|
Start with the [YAML guide and recipe book](docs/YAML-GUIDE.md),
|
|
43
121
|
[complete field reference](docs/YAML-REFERENCE.md), and
|
|
44
122
|
[runnable 25-route cookbook](examples/cookbook/README.md). For AI-assisted
|
|
45
|
-
authoring, use [the AI guide](docs/AI-AUTHORING.md)
|
|
123
|
+
authoring, use [the AI guide](docs/AI-AUTHORING.md), the bundled agent skills
|
|
124
|
+
([authoring](.claude/skills/urlcode-authoring/SKILL.md),
|
|
125
|
+
[operations](.claude/skills/urlcode-operations/SKILL.md)) and [llms.txt](llms.txt).
|
|
46
126
|
Follow [organization and readability practices](docs/BEST-PRACTICES.md) as your
|
|
47
127
|
project grows. Operators should read [capacity/concurrency](docs/CAPACITY.md) and the
|
|
48
128
|
[DDoS and recovery playbook](docs/RESILIENCE.md). Embedding the runtime from
|
|
@@ -62,281 +142,141 @@ npm ci
|
|
|
62
142
|
npm run dev
|
|
63
143
|
```
|
|
64
144
|
|
|
65
|
-
Live stored-link routes require **`dynamicLinks: true`** in the entry `urlcode.yaml`;
|
|
66
|
-
the starter explicitly sets false. Ordinary functions and parameterized redirects
|
|
67
|
-
do not need it. [Live-link setup](docs/DYNAMIC-LINKS.md).
|
|
68
|
-
|
|
69
145
|
## Built with URLCode
|
|
70
146
|
|
|
71
|
-
[urlcode-
|
|
72
|
-
standalone, account-free demo built on URLCode's public runtime
|
|
147
|
+
[urlcode-short](https://github.com/jimhoyd-com/urlcode-short) is a
|
|
148
|
+
standalone, account-free demo built on URLCode's public runtime. It predates
|
|
149
|
+
this repository's removal of the native link-store API from core; its
|
|
150
|
+
retrospective should be read alongside that change, not as current guidance.
|
|
73
151
|
It combines short links that expire after one hour or less, QR downloads, and a
|
|
74
|
-
shadcn/ui + Tailwind frontend. URLCode handles the page/assets and
|
|
75
|
-
|
|
152
|
+
shadcn/ui + Tailwind frontend. URLCode handles the page/assets and routing; the
|
|
153
|
+
application adds anonymous creation, stored-link storage and its own limits.
|
|
76
154
|
|
|
77
|
-
Read its [build retrospective](https://github.com/jimhoyd-com/urlcode-
|
|
155
|
+
Read its [build retrospective](https://github.com/jimhoyd-com/urlcode-short/blob/main/docs/BUILD-RETROSPECTIVE.md)
|
|
78
156
|
for what the runtime supplied, what the application still needed, and proposed
|
|
79
157
|
improvements. The demo's license, hosting and production validation remain open;
|
|
80
158
|
it does not change URLCode's Apache-2.0 license or guest isolation model.
|
|
81
159
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
for reuse, integration work and upstream improvements. Hosting and a public domain
|
|
89
|
-
are not yet selected; the original site-code license is pending.
|
|
160
|
+
`urlcode-docs` demonstrates URLCode hosting a static documentation site with
|
|
161
|
+
shadcn/ui and Tailwind: content authored directly in that repository, applying
|
|
162
|
+
templates through its own sandbox-opted-in (`sandbox: true`) middleware during
|
|
163
|
+
the build, served through native page/static/download routes. That repository
|
|
164
|
+
is currently private, so it isn't publicly browsable yet. Hosting and a public
|
|
165
|
+
domain are not yet selected; the original site-code license is pending.
|
|
90
166
|
|
|
91
167
|
## Start from YAML
|
|
92
168
|
|
|
93
169
|
Already wrote `urlcode.yaml`? Run `urlcode scaffold --project ./my-links --dry-run`,
|
|
94
170
|
then remove `--dry-run` to create missing modules, pages and directories. Existing
|
|
95
171
|
files are preserved; code placeholders return 501 until implemented.
|
|
96
|
-
[Scaffolding guide](docs/SCAFFOLDING.md).
|
|
172
|
+
[Scaffolding guide](docs/SCAFFOLDING.md). Node 22.13+ installed, 22.18+ to run
|
|
173
|
+
the TypeScript source; the separate `urlcode-auth` extension may have its own
|
|
174
|
+
SQLite build requirement, unverified from this repository.
|
|
97
175
|
|
|
98
176
|
## Try it
|
|
99
177
|
|
|
100
|
-
Requires Node.js 22.13+ and npm; CI targets Node 22, 24 and 26 on macOS, Linux and
|
|
101
|
-
Windows.
|
|
102
|
-
|
|
103
178
|
```sh
|
|
104
|
-
npm install --global urlcode
|
|
179
|
+
npm install --global @jimhoyd/urlcode # or: brew tap jimhoyd-com/urlcode && brew install urlcode
|
|
105
180
|
urlcode init my-urls && cd my-urls
|
|
106
181
|
urlcode dev
|
|
107
182
|
```
|
|
108
183
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
git clone
|
|
114
|
-
cd urlcode
|
|
115
|
-
make dev
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
`make dev` installs dependencies if needed and starts the included function/redirect demo.
|
|
119
|
-
No global install, account, database, Docker or configuration step is required.
|
|
120
|
-
A clone runs the TypeScript source directly (`node src/cli.ts`, which needs
|
|
121
|
-
Node 22.18+); the installed package runs the built `dist/cli.js`.
|
|
122
|
-
Without Make (including Windows), use:
|
|
123
|
-
|
|
124
|
-
```sh
|
|
125
|
-
npm ci
|
|
126
|
-
npm run dev
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Open `http://127.0.0.1:3000/hello/Ada` to run your custom function,
|
|
130
|
-
`/go` for a regular redirect.
|
|
131
|
-
Edit `starters/default/routes/` or `functions/hello.mjs` under
|
|
132
|
-
that starter; valid changes reload automatically. Press Ctrl+C to stop.
|
|
133
|
-
In another terminal, run `make test-project` or `npm run test:project`.
|
|
134
|
-
|
|
135
|
-
To create your own independent project:
|
|
136
|
-
|
|
137
|
-
```sh
|
|
138
|
-
make init DEST=../my-links
|
|
139
|
-
make dev PROJECT=../my-links PORT=3001
|
|
140
|
-
# Without Make:
|
|
141
|
-
npm run init -- ../my-links
|
|
142
|
-
npm run dev -- --project ../my-links --port 3001
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
Choose either command pair; initialization refuses to overwrite existing work.
|
|
146
|
-
[Starters](docs/STARTERS.md) are ordinary application files, independent of the
|
|
147
|
-
runtime checkout. Own them in your own Git repository. Global `npm link` remains
|
|
148
|
-
optional if you want the `urlcode` command everywhere. See
|
|
149
|
-
[local development](docs/LOCAL-DEVELOPMENT.md) for commands and troubleshooting.
|
|
184
|
+
Open `http://127.0.0.1:3000/hello/Ada` for the function route and `/go` for
|
|
185
|
+
the redirect. Edit the YAML; valid changes reload. `urlcode test` runs the
|
|
186
|
+
project's HTTP fixtures. The [install guide](docs/INSTALL.md) covers the
|
|
187
|
+
checksum-verified script, project-local installs, the container image and
|
|
188
|
+
signed provenance. To work from a clone: `git clone … && make dev`.
|
|
150
189
|
|
|
151
190
|
## A URL that runs your function
|
|
152
191
|
|
|
153
|
-
A request to `/hello/Ada` runs your JavaScript and returns
|
|
154
|
-
`{"message":"Hello, Ada!"}`. Put this in `urlcode.yaml`:
|
|
155
|
-
|
|
156
192
|
```yaml
|
|
157
193
|
version: "1"
|
|
158
194
|
routes:
|
|
159
195
|
/hello/{name}:
|
|
160
196
|
parameters:
|
|
161
|
-
- name: name
|
|
162
|
-
in: path
|
|
163
|
-
required: true
|
|
164
|
-
schema: {type: string, minLength: 1, maxLength: 80}
|
|
197
|
+
- { name: name, in: path, required: true, schema: { type: string, minLength: 1, maxLength: 80 } }
|
|
165
198
|
function:
|
|
166
199
|
source: functions/hello.mjs
|
|
167
|
-
args:
|
|
168
|
-
name: {from: path, name: name}
|
|
200
|
+
args: { name: { from: path, name: name } }
|
|
169
201
|
env:
|
|
170
|
-
GREETING: {value: Hello}
|
|
202
|
+
GREETING: { value: Hello }
|
|
171
203
|
```
|
|
172
204
|
|
|
173
|
-
And in `functions/hello.mjs`:
|
|
174
|
-
|
|
175
205
|
```js
|
|
176
206
|
export default function hello(request, { args, env }) {
|
|
177
207
|
return Response.json({ message: `${env.GREETING}, ${args.name}!` });
|
|
178
208
|
}
|
|
179
209
|
```
|
|
180
210
|
|
|
181
|
-
|
|
182
|
-
`
|
|
183
|
-
|
|
184
|
-
|
|
211
|
+
Add `middleware: [{ source: middleware/headers.mjs }]` to wrap any handler with
|
|
212
|
+
`await next()`. Fourteen ready-made middleware patterns ship in the cookbook
|
|
213
|
+
and as `urlcode recipes add middleware`. See [functions and the sandbox](docs/FUNCTION-SECURITY.md)
|
|
214
|
+
and [middleware](docs/MIDDLEWARE.md).
|
|
215
|
+
|
|
216
|
+
## Everything else in YAML
|
|
217
|
+
|
|
218
|
+
- **Pages, files, downloads:** `page`, `static`, `download` with MIME detection,
|
|
219
|
+
ETags, ranges and safety limits. [Assets](docs/ASSETS.md).
|
|
220
|
+
- **HTTP:** methods, validated path/query/header inputs, body limits, response
|
|
221
|
+
headers and cookies. [HTTP](docs/HTTP.md).
|
|
222
|
+
- **Policies and site conventions:** throttle, agents, security headers,
|
|
223
|
+
compression, cache; robots, sitemap, favicon, security.txt, llms.txt.
|
|
224
|
+
[Policies](docs/POLICIES.md), [site](docs/SITE.md).
|
|
225
|
+
- **Conditions, proxy, signals:** exact predicates with disjoint cases; a bounded
|
|
226
|
+
HTTPS proxy and best-effort webhooks behind operator grants.
|
|
227
|
+
[Conditions](docs/CONDITIONS.md), [egress](docs/EGRESS.md).
|
|
228
|
+
- **Organization:** `includes` across folders; strict CSV/JSON/YAML and
|
|
229
|
+
provider-file import; searchable recipes and examples. [Organization](docs/ORGANIZATION.md),
|
|
230
|
+
[interchange](docs/INTERCHANGE.md), [bulk](docs/BULK.md), [recipes](docs/RECIPES.md).
|
|
231
|
+
- **Checks:** `validate`, `test`, `routes`, `audit --expect-routes`, `benchmark`,
|
|
232
|
+
`capabilities`, deployment verification and a GitHub Action.
|
|
233
|
+
[Readiness](docs/READINESS.md), [CI](docs/CI.md).
|
|
234
|
+
|
|
235
|
+
## Deploy
|
|
236
|
+
|
|
237
|
+
Self-hosted Node process or container first. `@jimhoyd/urlcode/vercel` and
|
|
238
|
+
`@jimhoyd/urlcode/aws` serve declarative projects as native handlers;
|
|
239
|
+
`urlcode build --target cloudflare` compiles redirects and declared responses
|
|
240
|
+
into a Worker; `urlcode build --target static` compiles redirects and static
|
|
241
|
+
files into plain objects and redirect metadata for S3 + CloudFront, with no
|
|
242
|
+
server at all. Each target refuses at activation or build time what it cannot
|
|
243
|
+
run, with the route named. None has been exercised on its provider yet; the
|
|
244
|
+
adapters have local conformance tests only. [Operations](docs/OPERATIONS.md),
|
|
245
|
+
[capabilities](docs/CAPABILITIES.md), [Vercel](docs/VERCEL.md), [AWS](docs/AWS.md),
|
|
246
|
+
[Cloudflare](docs/CLOUDFLARE.md), [static hosting](docs/STATIC.md).
|
|
247
|
+
|
|
248
|
+
## For AI agents
|
|
249
|
+
|
|
250
|
+
[llms.txt](llms.txt) is the compact index; [the framework](docs/FRAMEWORK.md)
|
|
251
|
+
is the map; [AI authoring](docs/AI-AUTHORING.md) is the contract with the
|
|
252
|
+
capability matrix and a copyable task prompt. `urlcode mcp` exposes read-only
|
|
253
|
+
inspection, validation and conversion previews over stdio, and
|
|
254
|
+
`--allow-authoring` adds project-confined authoring tools
|
|
255
|
+
([tooling](docs/TOOLING.md)).
|
|
185
256
|
|
|
186
|
-
##
|
|
187
|
-
|
|
188
|
-
Add an ordered `middleware` list alongside any route handler:
|
|
189
|
-
|
|
190
|
-
```yaml
|
|
191
|
-
middleware:
|
|
192
|
-
- source: middleware/headers.mjs
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
```js
|
|
196
|
-
export default async function headers(request, context, next) {
|
|
197
|
-
const response = await next();
|
|
198
|
-
response.headers.set('x-example-middleware', 'active');
|
|
199
|
-
return response;
|
|
200
|
-
}
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Middleware can return a response early, share request-local `context.state`, or
|
|
204
|
-
wrap the handler with `await next()`. It runs in the same isolated sandbox and
|
|
205
|
-
under one deadline for the whole chain. The starter's function route includes
|
|
206
|
-
this example. See [middleware semantics and limits](docs/MIDDLEWARE.md).
|
|
207
|
-
|
|
208
|
-
## A URL that redirects
|
|
209
|
-
|
|
210
|
-
```yaml
|
|
211
|
-
version: "1"
|
|
212
|
-
routes:
|
|
213
|
-
/go:
|
|
214
|
-
redirect:
|
|
215
|
-
url: https://example.com
|
|
216
|
-
status: 302
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
Ordinary redirects use an indexed lookup: no database, Lambda or per-route
|
|
220
|
-
user function. Configuration is compiled at startup, not parsed per request.
|
|
221
|
-
Literal paths win over parameterized routes; conflicting definitions fail validation.
|
|
222
|
-
|
|
223
|
-
Custom functions are ES modules using a documented text/JSON `Request`/`Response`
|
|
224
|
-
subset and validated context. See the
|
|
225
|
-
[starter](starters/default/urlcode.yaml) and [function](starters/default/functions/hello.mjs).
|
|
226
|
-
Functions are treated as untrusted and run inside a QuickJS/WebAssembly sandbox,
|
|
227
|
-
with a fresh heap per invocation. No Node APIs, filesystem, shell, network or
|
|
228
|
-
ambient environment is exposed. Independent worker deadlines bound execution.
|
|
229
|
-
External env/secret bindings require route-scoped operator grants pinned to the
|
|
230
|
-
project revision. See the [security model](docs/FUNCTION-SECURITY.md).
|
|
231
|
-
|
|
232
|
-
## Pages, files and downloads
|
|
233
|
-
|
|
234
|
-
Add these routes alongside your functions and redirects:
|
|
235
|
-
|
|
236
|
-
```yaml
|
|
237
|
-
/about:
|
|
238
|
-
page:
|
|
239
|
-
file: public/about.html
|
|
240
|
-
/assets/*:
|
|
241
|
-
static:
|
|
242
|
-
directory: public/assets
|
|
243
|
-
/download:
|
|
244
|
-
download:
|
|
245
|
-
file: public/guide.txt
|
|
246
|
-
filename: urlcode-guide.txt
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
Create the referenced files first. MIME types are detected from file extensions;
|
|
250
|
-
unknown types use `application/octet-stream`. Downloads set attachment headers.
|
|
251
|
-
Optional `contentType` overrides detection. HEAD, ETags, conditional requests and
|
|
252
|
-
single byte ranges are supported. Files are served natively without executing a
|
|
253
|
-
function. See [asset configuration and safety limits](docs/ASSETS.md).
|
|
254
|
-
|
|
255
|
-
## Organize routes across files
|
|
257
|
+
## Documentation
|
|
256
258
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
259
|
+
Full documentation is authored in a separate `urlcode-docs` repository, where
|
|
260
|
+
new guides, references and recipes belong — but that repository is currently
|
|
261
|
+
private, so its content isn't publicly browsable yet. Until it's made public,
|
|
262
|
+
the practical reference is this README and [`docs/`](docs/README.md) in this
|
|
263
|
+
repository.
|
|
261
264
|
|
|
262
|
-
|
|
265
|
+
`docs/` in this repository is contributor and maintainer material — local
|
|
266
|
+
development, CI, the release process, reviews and the generated field
|
|
267
|
+
reference. Reader-facing pages still under `docs/` are being migrated.
|
|
263
268
|
|
|
264
|
-
|
|
265
|
-
`/r/{code}`. Only static-file mounts support a trailing `/*`; regex routing is
|
|
266
|
-
not supported. `dev` swaps validated configuration snapshots when YAML changes;
|
|
267
|
-
`serve` requires restart/redeployment for YAML changes. Stored short links can
|
|
268
|
-
now be created/updated/deleted live without reloads through the optional
|
|
269
|
-
[dynamic-link handler and management API](docs/DYNAMIC-LINKS.md). See [matching, precedence and dynamic-link behavior](docs/ROUTING.md).
|
|
269
|
+
## Built with URLCode
|
|
270
270
|
|
|
271
|
-
|
|
271
|
+
[urlcode-short](https://github.com/jimhoyd-com/urlcode-short), an
|
|
272
|
+
account-free short-link demo with a shadcn/ui front end, and `urlcode-docs`, a
|
|
273
|
+
static documentation site rendered through its own sandbox-opted-in middleware
|
|
274
|
+
at build time (currently a private repository). Both are ordinary consumers of
|
|
275
|
+
the public runtime; urlcode-short's retrospective lists what the runtime
|
|
276
|
+
supplied and what it still had to build.
|
|
272
277
|
|
|
273
|
-
|
|
274
|
-
/r/{code}:
|
|
275
|
-
parameters:
|
|
276
|
-
- name: code
|
|
277
|
-
in: path
|
|
278
|
-
required: true
|
|
279
|
-
schema: {type: string, minLength: 1, maxLength: 128}
|
|
280
|
-
link:
|
|
281
|
-
collection: links
|
|
282
|
-
code: {from: path, name: code}
|
|
283
|
-
```
|
|
278
|
+
## License and contributing
|
|
284
279
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
record changes are visible without rewriting YAML or rebuilding the route table.
|
|
289
|
-
Ordinary YAML routes still need no database. See [setup, API and limitations](docs/DYNAMIC-LINKS.md).
|
|
290
|
-
|
|
291
|
-
## HTTP in YAML
|
|
292
|
-
|
|
293
|
-
Configure methods and validated path/query/header inputs, request body size and
|
|
294
|
-
media types, response headers, cookies, and declared text/JSON responses.
|
|
295
|
-
See the [HTTP configuration reference](docs/HTTP.md) for supported fields and
|
|
296
|
-
examples. Runtime framing and asset validators stay protected.
|
|
297
|
-
|
|
298
|
-
## Check your links before release
|
|
299
|
-
|
|
300
|
-
`urlcode routes` lists the configured routes. `urlcode audit --expect-routes 2`
|
|
301
|
-
checks the count, generates native response checks and reports missing route/method
|
|
302
|
-
coverage in your request fixtures. `urlcode benchmark --requests 1000 --concurrency 2`
|
|
303
|
-
measures your local project without following external redirects. Each command
|
|
304
|
-
accepts `--project`. See [readiness and release checks](docs/READINESS.md).
|
|
305
|
-
|
|
306
|
-
## Commands available
|
|
307
|
-
|
|
308
|
-
| Command | Purpose |
|
|
309
|
-
|---|---|
|
|
310
|
-
| `init <directory>` | Create an independent starter; refuse existing destinations |
|
|
311
|
-
| `add <url> --alias <code>` | Validate and atomically add a redirect; generate a code if omitted |
|
|
312
|
-
| `validate --local` | Validate config, references, bindings and function initialization; read `.env.local` |
|
|
313
|
-
| `dev` | Local server, watched reload and `.env.local` |
|
|
314
|
-
| `serve` | Fixed production process snapshot; environment injection, no dotenv loading |
|
|
315
|
-
| `test` | Local HTTP assertions from `tests/requests.json`; never follow redirects |
|
|
316
|
-
| `permissions` | Inspect requested bindings and project digest without executing code; grants nothing |
|
|
317
|
-
| `doctor` | Report runtime/platform details and implemented provider scope |
|
|
318
|
-
|
|
319
|
-
Use `--project <directory>` to select an app. Servers accept `--host`, `--port`
|
|
320
|
-
and `--origin` (public URL origin for functions). Bind defaults to `127.0.0.1`.
|
|
321
|
-
|
|
322
|
-
## Production direction
|
|
323
|
-
|
|
324
|
-
The free runtime is meant to be useful and production-capable for people who
|
|
325
|
-
operate it themselves. Current hardening includes strict YAML/schema checks,
|
|
326
|
-
request/response limits, worker deadlines, bounded function concurrency, safe
|
|
327
|
-
configuration replacement, graceful shutdown, health/readiness and structured
|
|
328
|
-
logs without request content. It still needs broader deployment/soak validation
|
|
329
|
-
and the remaining release features. Read [operations](docs/OPERATIONS.md) before
|
|
330
|
-
exposing a server. [Benchmark instructions and measurements](docs/PERFORMANCE.md)
|
|
331
|
-
are available; measurements are not capacity guarantees.
|
|
332
|
-
|
|
333
|
-
Git owns definitions and code. Secrets stay in ignored `.env.local` for development
|
|
334
|
-
or injected environment values for serving, accessible to functions only through
|
|
335
|
-
an explicit operator policy. Vercel, AWS Lambda and Cloudflare Workers each have a
|
|
336
|
-
target guide in [docs](docs/README.md); none has been deployed to its platform
|
|
337
|
-
yet. Provider secret-store integration, CSV tools, templates/signals,
|
|
338
|
-
Homebrew and richer monitoring are future work. Unsupported config fails rather
|
|
339
|
-
than silently losing behavior. There is no required admin UI or database.
|
|
340
|
-
|
|
341
|
-
See [contributing](CONTRIBUTING.md), [security](SECURITY.md), and the
|
|
342
|
-
[roadmap](ROADMAP.md).
|
|
280
|
+
Apache-2.0. Commercial use, modification, redistribution and self-hosting are
|
|
281
|
+
permitted. See [contributing](CONTRIBUTING.md), [security](SECURITY.md),
|
|
282
|
+
[governance](GOVERNANCE.md) and the [roadmap](ROADMAP.md).
|