@ontrails/http 1.0.0-beta.13 → 1.0.0-beta.14
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/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +11 -0
- package/dist/build.d.ts +2 -0
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +7 -1
- package/dist/build.js.map +1 -1
- package/dist/hono/trailhead.d.ts +3 -0
- package/dist/hono/trailhead.d.ts.map +1 -1
- package/dist/hono/trailhead.js +5 -15
- package/dist/hono/trailhead.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/build.test.ts +16 -1
- package/src/build.ts +10 -0
- package/src/hono/trailhead.ts +5 -17
package/.turbo/turbo-lint.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @ontrails/http
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.14
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 69057e9: Add hierarchical CLI command trees and structured input, enforce established-only topo exports across trailheads, move developer topo and tracker state onto shared `trails.db` with pins and maintenance flows, and ship schema-derived stores through `@ontrails/store` and its Drizzle runtime.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [69057e9]
|
|
12
|
+
- @ontrails/core@1.0.0-beta.14
|
|
13
|
+
|
|
3
14
|
## 1.0.0-beta.13
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
package/dist/build.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface BuildHttpRoutesOptions {
|
|
|
14
14
|
readonly createContext?: (() => TrailContextInit | Promise<TrailContextInit>) | undefined;
|
|
15
15
|
readonly gates?: readonly Gate[] | undefined;
|
|
16
16
|
readonly provisions?: ProvisionOverrideMap | undefined;
|
|
17
|
+
/** Set to `false` to skip topo validation while building routes. */
|
|
18
|
+
readonly validate?: boolean | undefined;
|
|
17
19
|
}
|
|
18
20
|
export type HttpMethod = 'GET' | 'POST' | 'DELETE';
|
|
19
21
|
/** Input source derived from the HTTP method. */
|
package/dist/build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,MAAM,
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,MAAM,EAKP,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,IAAI,EACJ,oBAAoB,EACpB,IAAI,EACJ,KAAK,EACL,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AAMxB,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,0FAA0F;IAC1F,QAAQ,CAAC,YAAY,CAAC,EAClB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GACjD,SAAS,CAAC;IACd,QAAQ,CAAC,aAAa,CAAC,EACnB,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,GACpD,SAAS,CAAC;IACd,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,IAAI,EAAE,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnD,iDAAiD;AACjD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACxC;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,CAChB,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,EAC9B,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,KAClC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;CACtC;AAoJD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,IAAI,EACT,UAAS,sBAA2B,KACnC,MAAM,CAAC,mBAAmB,EAAE,EAAE,KAAK,CAWrC,CAAC"}
|
package/dist/build.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `execute` function that validates input, composes gates, and runs the
|
|
6
6
|
* implementation -- all without referencing any HTTP framework types.
|
|
7
7
|
*/
|
|
8
|
-
import { Result, TRAILHEAD_KEY, ValidationError, executeTrail, } from '@ontrails/core';
|
|
8
|
+
import { Result, TRAILHEAD_KEY, ValidationError, executeTrail, validateEstablishedTopo, } from '@ontrails/core';
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
10
10
|
// Internal helpers
|
|
11
11
|
// ---------------------------------------------------------------------------
|
|
@@ -114,6 +114,12 @@ const accumulateRoutes = (trails, basePath, gates, options) => {
|
|
|
114
114
|
* (method, path) pair. Returns `Result.ok(routes)` on success.
|
|
115
115
|
*/
|
|
116
116
|
export const buildHttpRoutes = (app, options = {}) => {
|
|
117
|
+
if (options.validate !== false) {
|
|
118
|
+
const validated = validateEstablishedTopo(app);
|
|
119
|
+
if (validated.isErr()) {
|
|
120
|
+
return Result.err(validated.error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
117
123
|
const basePath = (options.basePath ?? '').replace(/\/+$/, '');
|
|
118
124
|
const gates = options.gates ?? [];
|
|
119
125
|
return accumulateRoutes(eligibleTrails(app), basePath, gates, options);
|
package/dist/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,MAAM,EACN,aAAa,EACb,eAAe,EACf,YAAY,
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,MAAM,EACN,aAAa,EACb,eAAe,EACf,YAAY,EACZ,uBAAuB,GACxB,MAAM,gBAAgB,CAAC;AAwDxB,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,6CAA6C;AAC7C,MAAM,cAAc,GAA+B;IACjD,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,KAAK;IACX,KAAK,EAAE,MAAM;CACd,CAAC;AAEF,4CAA4C;AAC5C,MAAM,YAAY,GAAG,CAAC,KAA8B,EAAc,EAAE,CAClE,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;AAEzC,uEAAuE;AACvE,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAE,OAAe,EAAU,EAAE;IAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACvE,OAAO,GAAG,IAAI,IAAI,QAAQ,EAAE,CAAC;AAC/B,CAAC,CAAC;AAEF,4CAA4C;AAC5C,MAAM,iBAAiB,GAAG,CAAC,MAAkB,EAAe,EAAE,CAC5D,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAEtC,kEAAkE;AAClE,MAAM,aAAa,GAAG,CAAC,KAA8B,EAAW,EAAE,CAChE,KAAK,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;AAEpC,0EAA0E;AAC1E,MAAM,iBAAiB,GAAG,CACxB,SAA6B,EACF,EAAE,CAAC,CAAC;IAC/B,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;IACjD,UAAU,EAAE;QACV,CAAC,aAAa,CAAC,EAAE,MAAe;KACjC;CACF,CAAC,CAAC;AAEH,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,aAAa,GACjB,CACE,CAA0B,EAC1B,KAAsB,EACtB,OAA+B,EACC,EAAE,CACpC,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,CAChC,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE;IACrB,WAAW;IACX,YAAY,EAAE,OAAO,CAAC,YAAY;IAClC,aAAa,EAAE,OAAO,CAAC,aAAa;IACpC,GAAG,EAAE,iBAAiB,CAAC,SAAS,CAAC;IACjC,KAAK;IACL,UAAU,EAAE,OAAO,CAAC,UAAU;CAC/B,CAAC,CAAC;AAEP,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,4CAA4C;AAC5C,MAAM,cAAc,GAAG,CAAC,GAAS,EAA6B,EAAE,CAC9D,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;AAErD,oDAAoD;AACpD,MAAM,UAAU,GAAG,CACjB,KAA8B,EAC9B,QAAgB,EAChB,KAAsB,EACtB,OAA+B,EACV,EAAE;IACvB,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5C,OAAO;QACL,OAAO,EAAE,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC;QAC7C,WAAW,EAAE,iBAAiB,CAAC,MAAM,CAAC;QACtC,MAAM;QACN,IAAI;QACJ,KAAK;QACL,OAAO,EAAE,KAAK,CAAC,EAAE;KAClB,CAAC;AACJ,CAAC,CAAC;AAEF,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,oEAAoE;AACpE,MAAM,QAAQ,GAAG,CAAC,KAA0B,EAAyB,EAAE,CACrE,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;AAElC,gEAAgE;AAChE,MAAM,aAAa,GAAG,CACpB,KAA0B,EAC1B,UAA+B,EAC/B,MAA6B,EACR,EAAE;IACvB,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,UAAU,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,GAAG,CACf,IAAI,eAAe,CACjB,iCAAiC,UAAU,UAAU,KAAK,CAAC,OAAO,iBAAiB,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAChH,CACF,CAAC;IACJ,CAAC;IACD,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,OAAO,MAAM,CAAC,EAAE,EAAE,CAAC;AACrB,CAAC,CAAC;AAEF,4EAA4E;AAC5E,MAAM,gBAAgB,GAAG,CACvB,MAAiC,EACjC,QAAgB,EAChB,KAAsB,EACtB,OAA+B,EACO,EAAE;IACxC,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1D,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QAC5D,IAAI,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;YACvB,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;AAC3B,CAAC,CAAC;AAEF,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,GAAS,EACT,UAAkC,EAAE,EACE,EAAE;IACxC,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,OAAO,gBAAgB,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC,CAAC"}
|
package/dist/hono/trailhead.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export interface TrailheadHttpOptions {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Build HTTP routes from a topo, create a Hono app, and optionally start serving.
|
|
31
|
+
*
|
|
32
|
+
* Topo validation runs before route construction — pass `validate: false`
|
|
33
|
+
* to skip it (e.g. during hot-reload or progressive startup).
|
|
31
34
|
*/
|
|
32
35
|
export declare const trailhead: (app: Topo, options?: TrailheadHttpOptions) => Promise<Hono>;
|
|
33
36
|
//# sourceMappingURL=trailhead.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trailhead.d.ts","sourceRoot":"","sources":["../../src/hono/trailhead.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EACV,IAAI,EACJ,oBAAoB,EACpB,IAAI,EACJ,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAY5B,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,0FAA0F;IAC1F,QAAQ,CAAC,YAAY,CAAC,EAClB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GACjD,SAAS,CAAC;IACd,QAAQ,CAAC,aAAa,CAAC,EACnB,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,GACpD,SAAS,CAAC;IACd,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,IAAI,EAAE,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD,kEAAkE;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;
|
|
1
|
+
{"version":3,"file":"trailhead.d.ts","sourceRoot":"","sources":["../../src/hono/trailhead.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EACV,IAAI,EACJ,oBAAoB,EACpB,IAAI,EACJ,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAY5B,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,0FAA0F;IAC1F,QAAQ,CAAC,YAAY,CAAC,EAClB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GACjD,SAAS,CAAC;IACd,QAAQ,CAAC,aAAa,CAAC,EACnB,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,GACpD,SAAS,CAAC;IACd,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,IAAI,EAAE,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IACvD,kEAAkE;IAClE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACzC;AA2PD;;;;;GAKG;AAEH,eAAO,MAAM,SAAS,GACpB,KAAK,IAAI,EACT,UAAS,oBAAyB,KACjC,OAAO,CAAC,IAAI,CA6Bd,CAAC"}
|
package/dist/hono/trailhead.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* await trailhead(app, { port: 3000 });
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
|
-
import { isTrailsError, statusCodeMap
|
|
12
|
+
import { isTrailsError, statusCodeMap } from '@ontrails/core';
|
|
13
13
|
import { Hono } from 'hono';
|
|
14
14
|
import { buildHttpRoutes } from '../build.js';
|
|
15
15
|
/** Unwrap optional/default wrappers to reach the underlying Zod type name. */
|
|
@@ -185,28 +185,17 @@ const registerErrorHandler = (hono) => {
|
|
|
185
185
|
// ---------------------------------------------------------------------------
|
|
186
186
|
// Validation
|
|
187
187
|
// ---------------------------------------------------------------------------
|
|
188
|
-
/**
|
|
189
|
-
* Throw a ValidationError if the topo has structural issues.
|
|
190
|
-
* Pass `skip: true` to bypass validation (e.g. when `validate: false` is set).
|
|
191
|
-
*/
|
|
192
|
-
const assertValidTopo = (app, skip = false) => {
|
|
193
|
-
if (skip) {
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
const validated = validateTopo(app);
|
|
197
|
-
if (validated.isErr()) {
|
|
198
|
-
throw validated.error;
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
188
|
// ---------------------------------------------------------------------------
|
|
202
189
|
// trailhead
|
|
203
190
|
// ---------------------------------------------------------------------------
|
|
204
191
|
/**
|
|
205
192
|
* Build HTTP routes from a topo, create a Hono app, and optionally start serving.
|
|
193
|
+
*
|
|
194
|
+
* Topo validation runs before route construction — pass `validate: false`
|
|
195
|
+
* to skip it (e.g. during hot-reload or progressive startup).
|
|
206
196
|
*/
|
|
207
197
|
// oxlint-disable-next-line require-await -- async for consistency with other trailhead() entrypoints
|
|
208
198
|
export const trailhead = async (app, options = {}) => {
|
|
209
|
-
assertValidTopo(app, options.validate === false);
|
|
210
199
|
const hono = new Hono();
|
|
211
200
|
registerErrorHandler(hono);
|
|
212
201
|
const routesResult = buildHttpRoutes(app, {
|
|
@@ -215,6 +204,7 @@ export const trailhead = async (app, options = {}) => {
|
|
|
215
204
|
createContext: options.createContext,
|
|
216
205
|
gates: options.gates,
|
|
217
206
|
provisions: options.provisions,
|
|
207
|
+
validate: options.validate,
|
|
218
208
|
});
|
|
219
209
|
if (routesResult.isErr()) {
|
|
220
210
|
throw routesResult.error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trailhead.js","sourceRoot":"","sources":["../../src/hono/trailhead.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"trailhead.js","sourceRoot":"","sources":["../../src/hono/trailhead.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ontrails/http",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./src/index.ts",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"clean": "rm -rf dist *.tsbuildinfo"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@ontrails/core": "^1.0.0-beta.
|
|
18
|
+
"@ontrails/core": "^1.0.0-beta.13"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"hono": "^4.7.0",
|
|
@@ -333,7 +333,7 @@ describe('buildHttpRoutes', () => {
|
|
|
333
333
|
provisions: [dbProvision],
|
|
334
334
|
});
|
|
335
335
|
|
|
336
|
-
const app = topo('testapp', { provisionTrail });
|
|
336
|
+
const app = topo('testapp', { dbProvision, provisionTrail });
|
|
337
337
|
const buildResult = buildHttpRoutes(app, {
|
|
338
338
|
provisions: { 'db.main': { source: 'override' } },
|
|
339
339
|
});
|
|
@@ -476,4 +476,19 @@ describe('buildHttpRoutes', () => {
|
|
|
476
476
|
expect(result.error?.message).toContain('entity');
|
|
477
477
|
});
|
|
478
478
|
});
|
|
479
|
+
|
|
480
|
+
describe('established graph enforcement', () => {
|
|
481
|
+
test('returns err when draft contamination remains', () => {
|
|
482
|
+
const draftTrail = trail('entity.export', {
|
|
483
|
+
blaze: () => Result.ok({ ok: true }),
|
|
484
|
+
crosses: ['_draft.entity.prepare'],
|
|
485
|
+
input: z.object({}),
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
const result = buildHttpRoutes(topo('testapp', { draftTrail }));
|
|
489
|
+
|
|
490
|
+
expect(result.isErr()).toBe(true);
|
|
491
|
+
expect(result.error?.message).toMatch(/draft/i);
|
|
492
|
+
});
|
|
493
|
+
});
|
|
479
494
|
});
|
package/src/build.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
TRAILHEAD_KEY,
|
|
12
12
|
ValidationError,
|
|
13
13
|
executeTrail,
|
|
14
|
+
validateEstablishedTopo,
|
|
14
15
|
} from '@ontrails/core';
|
|
15
16
|
import type {
|
|
16
17
|
Gate,
|
|
@@ -35,6 +36,8 @@ export interface BuildHttpRoutesOptions {
|
|
|
35
36
|
| undefined;
|
|
36
37
|
readonly gates?: readonly Gate[] | undefined;
|
|
37
38
|
readonly provisions?: ProvisionOverrideMap | undefined;
|
|
39
|
+
/** Set to `false` to skip topo validation while building routes. */
|
|
40
|
+
readonly validate?: boolean | undefined;
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
export type HttpMethod = 'GET' | 'POST' | 'DELETE';
|
|
@@ -227,6 +230,13 @@ export const buildHttpRoutes = (
|
|
|
227
230
|
app: Topo,
|
|
228
231
|
options: BuildHttpRoutesOptions = {}
|
|
229
232
|
): Result<HttpRouteDefinition[], Error> => {
|
|
233
|
+
if (options.validate !== false) {
|
|
234
|
+
const validated = validateEstablishedTopo(app);
|
|
235
|
+
if (validated.isErr()) {
|
|
236
|
+
return Result.err(validated.error);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
230
240
|
const basePath = (options.basePath ?? '').replace(/\/+$/, '');
|
|
231
241
|
const gates = options.gates ?? [];
|
|
232
242
|
return accumulateRoutes(eligibleTrails(app), basePath, gates, options);
|
package/src/hono/trailhead.ts
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { isTrailsError, statusCodeMap
|
|
13
|
+
import { isTrailsError, statusCodeMap } from '@ontrails/core';
|
|
14
14
|
import type {
|
|
15
15
|
Gate,
|
|
16
16
|
ProvisionOverrideMap,
|
|
@@ -294,34 +294,21 @@ const registerErrorHandler = (hono: Hono): void => {
|
|
|
294
294
|
// Validation
|
|
295
295
|
// ---------------------------------------------------------------------------
|
|
296
296
|
|
|
297
|
-
/**
|
|
298
|
-
* Throw a ValidationError if the topo has structural issues.
|
|
299
|
-
* Pass `skip: true` to bypass validation (e.g. when `validate: false` is set).
|
|
300
|
-
*/
|
|
301
|
-
const assertValidTopo = (app: Topo, skip = false): void => {
|
|
302
|
-
if (skip) {
|
|
303
|
-
return;
|
|
304
|
-
}
|
|
305
|
-
const validated = validateTopo(app);
|
|
306
|
-
if (validated.isErr()) {
|
|
307
|
-
throw validated.error;
|
|
308
|
-
}
|
|
309
|
-
};
|
|
310
|
-
|
|
311
297
|
// ---------------------------------------------------------------------------
|
|
312
298
|
// trailhead
|
|
313
299
|
// ---------------------------------------------------------------------------
|
|
314
300
|
|
|
315
301
|
/**
|
|
316
302
|
* Build HTTP routes from a topo, create a Hono app, and optionally start serving.
|
|
303
|
+
*
|
|
304
|
+
* Topo validation runs before route construction — pass `validate: false`
|
|
305
|
+
* to skip it (e.g. during hot-reload or progressive startup).
|
|
317
306
|
*/
|
|
318
307
|
// oxlint-disable-next-line require-await -- async for consistency with other trailhead() entrypoints
|
|
319
308
|
export const trailhead = async (
|
|
320
309
|
app: Topo,
|
|
321
310
|
options: TrailheadHttpOptions = {}
|
|
322
311
|
): Promise<Hono> => {
|
|
323
|
-
assertValidTopo(app, options.validate === false);
|
|
324
|
-
|
|
325
312
|
const hono = new Hono();
|
|
326
313
|
|
|
327
314
|
registerErrorHandler(hono);
|
|
@@ -332,6 +319,7 @@ export const trailhead = async (
|
|
|
332
319
|
createContext: options.createContext,
|
|
333
320
|
gates: options.gates,
|
|
334
321
|
provisions: options.provisions,
|
|
322
|
+
validate: options.validate,
|
|
335
323
|
});
|
|
336
324
|
|
|
337
325
|
if (routesResult.isErr()) {
|