@jimhoyd/urlcode 0.4.0-alpha.1 → 0.4.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/.claude/skills/urlcode-authoring/SKILL.md +24 -8
  2. package/.claude/skills/urlcode-operations/SKILL.md +10 -16
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/README.md +75 -62
  5. package/ROADMAP.md +61 -16
  6. package/SECURITY.md +23 -8
  7. package/dist/BUILD-MANIFEST.json +38 -43
  8. package/dist/agents-guide.js +18 -18
  9. package/dist/build-static.js +134 -0
  10. package/dist/capabilities.js +85 -31
  11. package/dist/capability-query.js +0 -1
  12. package/dist/cli.js +23 -31
  13. package/dist/compliance-rules/baseline.js +2 -10
  14. package/dist/compliance-rules/privacy.js +5 -16
  15. package/dist/compliance-rules/shared.js +0 -2
  16. package/dist/compliance.js +6 -8
  17. package/dist/config.js +15 -8
  18. package/dist/context.js +9 -10
  19. package/dist/examples.js +2 -2
  20. package/dist/explain-cli.js +3 -3
  21. package/dist/explain.js +5 -6
  22. package/dist/extensions.js +61 -2
  23. package/dist/function-sources.js +34 -2
  24. package/dist/function-worker.js +3 -1
  25. package/dist/functions.js +84 -13
  26. package/dist/guest-api.js +29 -3
  27. package/dist/index.js +3 -6
  28. package/dist/manifest.js +5 -7
  29. package/dist/mcp.js +1 -1
  30. package/dist/observability.js +1 -21
  31. package/dist/policies/cache.js +8 -3
  32. package/dist/policy.js +28 -9
  33. package/dist/project-tests.js +3 -3
  34. package/dist/readiness.js +32 -9
  35. package/dist/router.js +5 -7
  36. package/dist/runtime.js +77 -58
  37. package/dist/sandbox.js +48 -0
  38. package/dist/scaffold.js +0 -0
  39. package/dist/scripts/operational-drills.js +12 -54
  40. package/dist/server.js +3 -29
  41. package/dist/tooling.js +1 -1
  42. package/dist/trusted-functions.js +210 -0
  43. package/dist/types/build-static.d.ts +43 -0
  44. package/dist/types/capabilities.d.ts +14 -5
  45. package/dist/types/compliance-rules/shared.d.ts +0 -2
  46. package/dist/types/compliance.d.ts +0 -3
  47. package/dist/types/config.d.ts +2 -1
  48. package/dist/types/context.d.ts +2 -1
  49. package/dist/types/examples.d.ts +1 -1
  50. package/dist/types/extensions.d.ts +55 -0
  51. package/dist/types/function-sources.d.ts +4 -0
  52. package/dist/types/functions.d.ts +48 -5
  53. package/dist/types/guest-api.d.ts +1 -0
  54. package/dist/types/index.d.ts +3 -6
  55. package/dist/types/manifest.d.ts +1 -3
  56. package/dist/types/observability.d.ts +1 -14
  57. package/dist/types/project-tests.d.ts +1 -2
  58. package/dist/types/readiness.d.ts +10 -3
  59. package/dist/types/router.d.ts +2 -1
  60. package/dist/types/runtime.d.ts +0 -27
  61. package/dist/types/sandbox.d.ts +12 -0
  62. package/dist/types/scaffold.d.ts +0 -2
  63. package/dist/types/server.d.ts +1 -4
  64. package/dist/types/tooling.d.ts +3 -3
  65. package/dist/types/trusted-functions.d.ts +29 -0
  66. package/dist/types/types.d.ts +14 -7
  67. package/dist/types/verify-deployment.d.ts +2 -2
  68. package/dist/types.js +17 -4
  69. package/dist/typescript-authoring.js +55 -17
  70. package/dist/verify-deployment.js +3 -3
  71. package/docs/AI-AUTHORING.md +104 -9
  72. package/docs/AWS.md +4 -4
  73. package/docs/BEST-PRACTICES.md +3 -2
  74. package/docs/CAPABILITIES.md +29 -16
  75. package/docs/CAPACITY.md +128 -31
  76. package/docs/CLOUDFLARE.md +1 -2
  77. package/docs/COMPLIANCE.md +6 -9
  78. package/docs/DEPLOYMENT-CHECKS.md +1 -1
  79. package/docs/EXTENSIONS.md +183 -11
  80. package/docs/FRAMEWORK.md +35 -19
  81. package/docs/FUNCTION-SECURITY.md +129 -32
  82. package/docs/INSTALL.md +0 -5
  83. package/docs/LOAD-TESTING.md +4 -4
  84. package/docs/MIDDLEWARE.md +27 -16
  85. package/docs/MONITORING.md +2 -19
  86. package/docs/NEXT-PHASE-PLAN.md +12 -4
  87. package/docs/NEXT-STEPS.md +259 -40
  88. package/docs/OBSERVABILITY.md +7 -16
  89. package/docs/OPEN-DECISIONS.md +212 -0
  90. package/docs/OPERATIONAL-PROOF.md +26 -30
  91. package/docs/OPERATIONS.md +23 -32
  92. package/docs/POLICIES.md +15 -4
  93. package/docs/PRERENDER.md +2 -2
  94. package/docs/PROJECT-DIRECTION.md +34 -9
  95. package/docs/README.md +13 -11
  96. package/docs/RELEASE-READINESS.md +49 -29
  97. package/docs/RELEASE-SECURITY.md +89 -3
  98. package/docs/RESILIENCE.md +16 -15
  99. package/docs/ROUTING.md +8 -10
  100. package/docs/SANDBOX-REVIEW.md +19 -6
  101. package/docs/SCAFFOLDING.md +0 -2
  102. package/docs/SECURITY-AUDIT.md +40 -0
  103. package/docs/SPECIFICATION.md +60 -26
  104. package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +287 -0
  105. package/docs/SPIKE-BUSINESS-SUITE.md +8 -0
  106. package/docs/SPIKE-CORE-LAYERING.md +337 -0
  107. package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +209 -0
  108. package/docs/SPIKE-EXTENSION-MODEL.md +2 -2
  109. package/docs/SPIKE-EXTENSIONS.md +5 -0
  110. package/docs/SPIKE-LAMBDA-COMPILE.md +4 -2
  111. package/docs/SPIKE-MONOREPO.md +322 -0
  112. package/docs/STARTERS.md +1 -1
  113. package/docs/STATIC.md +94 -0
  114. package/docs/TOOLING.md +13 -9
  115. package/docs/TUNNELS.md +0 -3
  116. package/docs/TYPESCRIPT-AUTHORING.md +27 -12
  117. package/docs/TYPESCRIPT.md +25 -4
  118. package/docs/USABILITY-REVIEW.md +7 -1
  119. package/docs/VERCEL.md +4 -5
  120. package/docs/VERSION-ALIGNMENT.md +205 -0
  121. package/docs/YAML-GUIDE.md +0 -3
  122. package/docs/YAML-REFERENCE.md +16 -6
  123. package/docs/policies/cache.md +13 -0
  124. package/examples/assets/example.yaml +1 -1
  125. package/examples/aws/example.yaml +1 -1
  126. package/examples/cloudflare/example.yaml +1 -1
  127. package/examples/conditions/example.yaml +1 -1
  128. package/examples/cookbook/example.yaml +1 -1
  129. package/examples/cookbook/middleware/bucket.mjs +12 -2
  130. package/examples/cookbook/middleware/locale.mjs +7 -3
  131. package/examples/egress/example.yaml +1 -1
  132. package/examples/extensions/example.yaml +1 -1
  133. package/examples/prerender/README.md +2 -2
  134. package/examples/prerender/example.yaml +1 -1
  135. package/examples/provider-conformance/example.yaml +1 -1
  136. package/examples/vercel/example.yaml +1 -1
  137. package/llms-full.txt +594 -219
  138. package/llms.txt +23 -12
  139. package/package.json +10 -3
  140. package/packaging/claude-plugin/.claude-plugin/plugin.json +1 -1
  141. package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +24 -8
  142. package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +10 -16
  143. package/recipes/authenticated-json-api/recipe.yaml +1 -1
  144. package/recipes/contact-form/recipe.yaml +1 -1
  145. package/recipes/cors-api/recipe.yaml +1 -1
  146. package/recipes/health-page/recipe.yaml +1 -1
  147. package/recipes/json-api/recipe.yaml +1 -1
  148. package/recipes/middleware/middleware/bucket.mjs +12 -2
  149. package/recipes/middleware/middleware/locale.mjs +7 -3
  150. package/recipes/middleware/recipe.yaml +1 -1
  151. package/recipes/protected-download/recipe.yaml +1 -1
  152. package/recipes/redirect/recipe.yaml +1 -1
  153. package/recipes/static-plus-api/recipe.yaml +1 -1
  154. package/recipes/typescript/README.md +2 -1
  155. package/recipes/typescript/recipe.yaml +1 -1
  156. package/recipes/webhook-receiver/README.md +5 -1
  157. package/recipes/webhook-receiver/recipe.yaml +2 -1
  158. package/recipes/webhook-receiver/urlcode.yaml +7 -0
  159. package/schemas/recipe.schema.json +4 -3
  160. package/schemas/urlcode.schema.json +14 -41
  161. package/skills/urlcode/SKILL.md +29 -8
  162. package/starters/default/AGENTS.md +18 -18
  163. package/starters/default/urlcode.yaml +0 -1
  164. package/dist/link-api.js +0 -136
  165. package/dist/link-cli.js +0 -141
  166. package/dist/link-events.js +0 -76
  167. package/dist/link-records.js +0 -31
  168. package/dist/link-store-worker.js +0 -150
  169. package/dist/link-store.js +0 -250
  170. package/dist/management-policy.js +0 -40
  171. package/dist/sqlite-version.js +0 -6
  172. package/dist/types/link-api.d.ts +0 -30
  173. package/dist/types/link-cli.d.ts +0 -37
  174. package/dist/types/link-events.d.ts +0 -27
  175. package/dist/types/link-records.d.ts +0 -11
  176. package/dist/types/link-store-worker.d.ts +0 -1
  177. package/dist/types/link-store.d.ts +0 -130
  178. package/dist/types/management-policy.d.ts +0 -8
  179. package/dist/types/sqlite-version.d.ts +0 -1
  180. package/docs/DYNAMIC-LINKS.md +0 -61
  181. package/docs/MANAGEMENT-SECURITY.md +0 -82
  182. package/docs/links/cli.md +0 -110
  183. package/docs/links/limits.md +0 -175
  184. package/docs/links/management-api.md +0 -80
  185. package/docs/links/pools.md +0 -75
  186. package/docs/links/setup.md +0 -135
  187. package/docs/yaml/links.md +0 -30
  188. package/examples/live-links/README.md +0 -11
  189. package/examples/live-links/example.yaml +0 -21
  190. package/examples/live-links/tests/requests.json +0 -6
  191. package/examples/live-links/urlcode.yaml +0 -16
@@ -1,75 +0,0 @@
1
- # Dynamic links: Reader and writer pools
2
-
3
- Part of [dynamic links](../DYNAMIC-LINKS.md), which indexes every page.
4
-
5
- ## Separate reader and writer pools
6
-
7
- Pool sizes are operator infrastructure settings, not portable behavior YAML.
8
- `dynamicLinks: true` and logical collection names stay the same across targets.
9
-
10
- ```sh
11
- urlcode serve --project ./my-links \
12
- --link-store links=/absolute/links.sqlite \
13
- --link-readers 4 --link-read-limit 32
14
-
15
- urlcode links api --project ./my-links \
16
- --store /absolute/links.sqlite --token-file /absolute/link-admin.token \
17
- --link-readers 2 --link-read-limit 16 --link-write-limit 8
18
- ```
19
-
20
- | Control | Default | Meaning |
21
- |---|---|---|
22
- | `--link-readers` / JS `readers` | 2 | 1–8 read-only connections per store instance |
23
- | `--link-read-limit` / JS `maxReads` | 32 | 1–32 admitted reads across all readers, not per reader |
24
- | `--link-write-limit` / JS `maxWrites` | 32 | 1–32 admitted mutations across the single writer |
25
-
26
- `get` and `list` use the least-busy healthy reader. `create`, `update` and `delete`
27
- use the writer. Each worker serializes its own accepted operations. There is no
28
- additional unbounded acquisition queue. A read flood cannot take writer admission
29
- and a mutation backlog cannot take reader admission. CPU, disk, database locks
30
- and the event loop remain shared resources: separation is not an isolation SLA.
31
- A write response resolves after commit; a subsequent awaited read sees committed
32
- data on the same database. Reads started before the commit may see the old value.
33
- There is no replica lag or application cache in this adapter.
34
-
35
- `openLinkStore({file, project, readOnly, readers, maxReads, maxWrites})` exposes
36
- `stats()` with separate read/write connection counts, healthy counts, in-flight
37
- counts, limits, completed/failed/rejected totals and cumulative durationMs. These
38
- process-local counters reset at restart and are for trusted operator monitoring;
39
- there is no public metrics endpoint/exporter yet. `readHealthy` and `writeHealthy`
40
- are separate. Public runtime readiness uses `readHealthy` when available; management
41
- operators must monitor writer health separately. A read-only pool has zero writers
42
- and rejects mutations. Shutdown drains both groups and rejects new admission.
43
-
44
- Do not multiply connection counts blindly across processes: N public replicas at
45
- R readers use N×R connections, plus management readers/writers. Each connection
46
- has its own worker and memory budget. Measure mixed load and lock contention;
47
- adding readers can reduce performance on an already saturated disk.
48
-
49
- SQLite WAL supports simultaneous readers and a single active writer across the
50
- database. Multiple writer connections cannot create parallel write throughput.
51
- All connections must access the same local database on one host; never mount it
52
- across hosts over a network filesystem. See [SQLite WAL](https://www.sqlite.org/wal.html).
53
- We require a Node build with SQLite 3.51.3+ or patched branches 3.50.7+/3.44.6+
54
- to avoid the documented [WAL-reset concurrency bug](https://www.sqlite.org/wal.html#the_wal_reset_bug).
55
- Live-link initialization checks this before opening files and verifies WAL mode.
56
- Use `urlcode doctor` to inspect the bundled SQLite version; upgrade Node when
57
- rejected. Static YAML projects do not require SQLite.
58
-
59
- For multi-host scaling, a future server-database adapter must provide distinct
60
- read/write credentials and pool budgets, connect/acquire/query deadlines,
61
- transactional version checks, primary-read or explicit replica consistency,
62
- replica-lag monitoring, migration coordination, backup/restore and failover drills.
63
- These are adapter acceptance requirements, not implemented PostgreSQL support.
64
- Keep writes on the primary and avoid automatic retries of ambiguous commits.
65
- The existing operator adapter boundary remains available, but deploying a custom
66
- adapter requires its own conformance/load/recovery evidence.
67
-
68
- ## Shutdown and management defaults
69
-
70
- `links api` defaults to private address `127.0.0.1:3001`; public serving defaults
71
- to port 3000. Endpoint method errors return 405 with an `Allow` header.
72
- Store shutdown rejects new work, drains accepted operations within each connection and
73
- then closes SQLite. Repeated `close()` calls share completion. Existing operation
74
- deadlines still apply: a timeout can leave a mutation outcome unknown, so read
75
- the record before retrying. Missing/invalid revision metadata rejects startup.
@@ -1,135 +0,0 @@
1
- # Dynamic links: Setup: requirements, YAML and the example
2
-
3
- Part of [dynamic links](../DYNAMIC-LINKS.md), which indexes every page.
4
-
5
- ## Node build requirement
6
-
7
- Live links need a Node build carrying the patched SQLite WAL fix: SQLite 3.51.3
8
- or newer, 3.50.7 or 3.44.6. Node bundles SQLite, so this is a property of the
9
- build, not something you can install separately, and some current releases on a
10
- supported Node line ship an unpatched version. Run `urlcode doctor` and check
11
- `liveLinks`; activation fails closed and names the detected version when the
12
- build is unsuitable. Everything except live links works on any supported Node.
13
-
14
- Available in URLCode 0.1.0. Define a stable route once; create, update and delete
15
- short-code records while `serve` keeps running. No YAML rewrite, route snapshot
16
- rebuild, Git commit or public-server restart is needed for record changes.
17
-
18
- This first adapter uses optional SQLite storage on one host. Multiple processes
19
- on that host can share it. No database is required for ordinary YAML-defined
20
- routes. Network filesystems, multi-host replication and serverless ephemeral disks
21
- are not supported by this adapter. SQLite WAL requires processes on the same
22
- host; see [SQLite WAL](https://www.sqlite.org/wal.html).
23
-
24
- ## Behavior in YAML, data outside Git
25
-
26
- ```yaml
27
- version: "1"
28
- dynamicLinks: true
29
- routes:
30
- /r/{code}:
31
- parameters:
32
- - name: code
33
- in: path
34
- required: true
35
- schema: {type: string, minLength: 1, maxLength: 128}
36
- link:
37
- collection: links
38
- code: {from: path, name: code}
39
- ```
40
-
41
- `link` is a seventh primary handler, exclusive with `function`, `redirect`,
42
- `respond`, `page`, `static` and `download`. Its `code` is a declared path-input
43
- reference. `collection` is a logical name, not a filesystem path. GET and HEAD
44
- are supported; normal route precedence, lifecycle and input validation apply.
45
- An exact YAML route can intentionally shadow a stored code's URL.
46
-
47
- The operator binds `links` to a database outside the project. YAML cannot choose
48
- a database file or grant itself storage. The built-in public binding opens it
49
- read-only. It performs an indexed database lookup for each request, with no
50
- application cache or negative cache. Requests starting after an acknowledged
51
- mutation can see it immediately; an already-running request can finish with an
52
- older result. Browser/proxy caches remain outside that guarantee.
53
-
54
- Missing or disabled record: 404. Expired record: 410. Unavailable/overloaded
55
- store: 503. Invalid code syntax: 404 after route input validation. Redirects
56
- default to 302 and no-store. Query strings are not forwarded. A record's URL is
57
- literal HTTP(S), with no embedded credentials, control characters or interpolation.
58
- It is a redirect, not a server-side fetch. The store does not verify destination
59
- ownership, safety or availability; application abuse prevention remains necessary.
60
-
61
- ## Run the included example
62
-
63
- From the runtime checkout, choose a private data directory **outside the app**.
64
- Its parent directory must already exist. The following POSIX-shell example uses
65
- an operator-created directory; on Windows use an absolute local drive path.
66
-
67
- ```sh
68
- mkdir -p ../urlcode-data
69
- URLCODE_DATA="$(cd ../urlcode-data && pwd)"
70
- node src/cli.ts links init --store "$URLCODE_DATA/links.sqlite"
71
- node src/cli.ts links create --store "$URLCODE_DATA/links.sqlite" \
72
- --code demo --destination https://example.com/demo
73
- node src/cli.ts serve --project examples/live-links \
74
- --link-store "links=$URLCODE_DATA/links.sqlite" --port 3000
75
- ```
76
-
77
- Open `/r/demo`. In a second terminal, run another `links create` with an unused
78
- code against the same absolute file; its URL works immediately. Omit `--code`
79
- to generate a cryptographically random 16-character base64url code. Codes allow
80
- 1–128 letters, digits, underscores and hyphens; collection names begin with a
81
- letter and contain at most 64 letters/digits/underscores/hyphens.
82
-
83
- The CLI defaults to collection `links`; specify `--collection` to manage another.
84
- Serving currently accepts one `--link-store collection=/absolute/file` binding;
85
- embedded applications may supply multiple adapters. Commands do not copy records
86
- into YAML or create route definitions automatically.
87
-
88
- ## Explicit project opt-in
89
-
90
- Only the entry `urlcode.yaml` may set `dynamicLinks: true`. It defaults to false;
91
- the starter writes `dynamicLinks: false` explicitly. Included route files cannot
92
- set or override it. Any `link` handler, including a disabled route, or runtime
93
- link-store binding requires the opt-in. This flag means live stored-link records,
94
- not parameterized redirects, custom functions, middleware or development reload.
95
-
96
- `validate`, `routes`, `audit` and `scaffold` reports expose `dynamicLinks` as a
97
- boolean. Enabling it grants no storage access to guest code and starts no
98
- management endpoint. The operator still supplies the external store binding;
99
- management remains a separate authenticated service. Standalone `links` CRUD/API
100
- commands operate the operator's store independently of this public-runtime flag.
101
-
102
- Migration: existing live-link projects must add `dynamicLinks: true` to their
103
- entry file. Refresh revision-pinned function policies for those projects using
104
- the normal operator review flow; enabling the capability changes the approval
105
- digest. Projects that omit it or explicitly set false retain their prior digest.
106
- To disable, remove `link` declarations and serving-store bindings, then set false
107
- and validate/redeploy. Editing the flag alone does not stop an already running
108
- production process or management API. Invalid reloads retain the last-good state.
109
-
110
- ## Middleware, sandbox and tests
111
-
112
- Middleware may wrap a successful link response; the usual native metadata/body
113
- rules apply. Lookup/missing/disabled/expiry errors happen before middleware. The
114
- handler does not make database objects available to guest code. Functions still
115
- have no filesystem, SQL, fetch, storage broker or management token capability.
116
- Link changes do not alter configuration/source digests or invalidate unrelated
117
- function-binding grants. Changing YAML still does.
118
-
119
- `routes` and `audit --expect-routes` count definitions, not stored records. Link
120
- routes require explicit successful GET/HEAD fixtures; there is no assumed fixture
121
- for live data. Seed a disposable test database, then pass `--link-store` to
122
- validate/test/audit/benchmark. Do not run mutation tests against production.
123
-
124
- ```sh
125
- node src/cli.ts test --project examples/live-links --link-store links=/absolute/test-links.sqlite
126
- node src/cli.ts audit --project examples/live-links --link-store links=/absolute/test-links.sqlite --expect-routes 2
127
- ```
128
-
129
- The example expects `demo -> https://example.com/demo` and an unused `not-created`
130
- code. Tests cover create/update/delete visibility without reload, persistence,
131
- concurrent conflicts, expiry/disabled semantics, scope, public/admin separation,
132
- body/token boundaries, overload and acknowledged writes after abrupt writer exit.
133
- Production durability, sustained load and recovery drills still require validation
134
- on your actual storage. General application state, WebRTC sessions, user-account
135
- APIs and arbitrary runtime code registration remain separate future work.
@@ -1,30 +0,0 @@
1
- # YAML guide: Live short-link records
2
-
3
- Snippets are entries under `routes:` unless stated otherwise; the [guide index](../YAML-GUIDE.md) lists every page.
4
-
5
- ## 15. Live short-link records
6
-
7
- Set `dynamicLinks: true` in the entry `urlcode.yaml` before adding this route.
8
- It defaults to false and cannot be enabled by an included file.
9
-
10
- ```yaml
11
- /r/{code}:
12
- parameters:
13
- - name: code
14
- in: path
15
- required: true
16
- schema: {type: string, minLength: 1, maxLength: 128}
17
- link:
18
- collection: links
19
- code: {from: path, name: code}
20
- ```
21
-
22
- The seventh handler resolves stored records without rebuilding YAML. It requires
23
- an external operator store binding; the [live-link example](../../examples/live-links/README.md)
24
- has separate setup and fixtures. See [dynamic links](../DYNAMIC-LINKS.md) for CLI/API
25
- creation, optimistic updates, disabled/expired records, persistence and backups.
26
- This is not a general database capability for sandboxed functions.
27
-
28
- Live-link recipes require `dynamicLinks: true` in the entry `urlcode.yaml`. It is
29
- false by default and cannot be set in included route files. Parameterized routes
30
- and functions alone do not need it. See [dynamic-link opt-in](../DYNAMIC-LINKS.md#explicit-project-opt-in).
@@ -1,11 +0,0 @@
1
- # Live links without route reloads
2
-
3
- Follow [the dynamic-link guide](../../docs/DYNAMIC-LINKS.md) to create an external
4
- SQLite store and seed `demo -> https://example.com/demo`. Then start this project
5
- with `--link-store links=/absolute/path/links.sqlite`. Its fixtures expect that
6
- seed and an unused `not-created` code; use a disposable test store, not production.
7
-
8
- Create/update/delete records through the CLI or separate authenticated API while
9
- the public server keeps serving. YAML, code, route counts and health version do
10
- not change per link. This example deliberately requires explicit operator storage
11
- binding; the default starter still runs without a database.
@@ -1,21 +0,0 @@
1
- id: live-links
2
- description: Stored links served from an external SQLite store without a route reload, with dynamicLinks enabled in the entry file.
3
- tags: [links, live, dynamic, sqlite, store, short-links, link, redirect]
4
- complexity: intermediate
5
- capabilities: [dynamicLinks, enabled, link, methods, parameters, respond]
6
- targets: {self-hosted: compatible, aws: refused, vercel: refused, cloudflare: refused}
7
- routes: 2
8
- services:
9
- - name: link store
10
- description: An operator-owned SQLite store passed as --link-store, seeded with demo -> https://example.com/demo.
11
- grants:
12
- - kind: link-store
13
- description: The store binding is an operator flag, never a project file.
14
- files: [urlcode.yaml, tests/requests.json, README.md]
15
- tests:
16
- fixtures: tests/requests.json
17
- commands:
18
- - node src/cli.ts links init --store /absolute/links.sqlite
19
- - node src/cli.ts test --project examples/live-links --link-store links=/absolute/links.sqlite
20
- behavior:
21
- - "/r/{code} answers the stored destination for a seeded code and 404 for one that was never created"
@@ -1,6 +0,0 @@
1
- [
2
- {"path":"/r/demo","status":302,"expectHeaders":{"location":"https://example.com/demo","cache-control":"no-store"}},
3
- {"path":"/r/demo","method":"HEAD","status":302,"expectBody":"","expectHeaders":{"location":"https://example.com/demo"}},
4
- {"path":"/r/not-created","status":404},
5
- {"path":"/r/demo","method":"POST","status":405,"expectHeaders":{"allow":"GET, HEAD"}}
6
- ]
@@ -1,16 +0,0 @@
1
- # yaml-language-server: $schema=https://raw.githubusercontent.com/jimhoyd-com/urlcode/669632fb4f188f293a0f622847f87ee019c0627f/schemas/urlcode.schema.json
2
- version: "1"
3
- dynamicLinks: true
4
- routes:
5
- /r/{code}:
6
- parameters:
7
- - name: code
8
- in: path
9
- required: true
10
- schema: {type: string, minLength: 1, maxLength: 128}
11
- link:
12
- collection: links
13
- code: {from: path, name: code}
14
- /about:
15
- respond:
16
- text: Links are stored separately from this YAML.