@fougere/adapter-rest 0.5.0-alpha.1 → 0.7.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,13 +3,6 @@
3
3
  */
4
4
  import type { HttpRouter } from '@fougere/http';
5
5
  import type { RouteDefinition } from './routes.js';
6
- /**
7
- * Register all route definitions on an HttpRouter.
8
- *
9
- * ```ts
10
- * const routes = generateRoutes(app, { prefix: '/api' });
11
- * registerRoutes(router, routes);
12
- * ```
13
- */
6
+ /** Register all route definitions on an HttpRouter. */
14
7
  export declare function registerRoutes(router: HttpRouter, routes: RouteDefinition[]): void;
15
8
  //# sourceMappingURL=register.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,eAAe,EAAE,GACxB,IAAI,CA0CN"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,uDAAuD;AACvD,wBAAgB,cAAc,CAC5B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,eAAe,EAAE,GACxB,IAAI,CA0CN"}
package/dist/register.js CHANGED
@@ -1,12 +1,5 @@
1
1
  import { toHttpError } from '@fougere/core';
2
- /**
3
- * Register all route definitions on an HttpRouter.
4
- *
5
- * ```ts
6
- * const routes = generateRoutes(app, { prefix: '/api' });
7
- * registerRoutes(router, routes);
8
- * ```
9
- */
2
+ /** Register all route definitions on an HttpRouter. */
10
3
  export function registerRoutes(router, routes) {
11
4
  for (const route of routes) {
12
5
  router.on(route.method, route.path, async (ctx) => {
@@ -14,7 +7,7 @@ export function registerRoutes(router, routes) {
14
7
  const invocation = {
15
8
  params: ctx.params,
16
9
  query: ctx.query,
17
- body,
10
+ input: body,
18
11
  state: ctx.state,
19
12
  };
20
13
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAkB,EAClB,MAAyB;IAEzB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAChD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAwC,CAAC;YAEvE,MAAM,UAAU,GAAG;gBACjB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,IAAI;gBACJ,KAAK,EAAE,GAAG,CAAC,KAAK;aACjB,CAAC;YAEF,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAE/C,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC,IAAI,KAAK,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;oBACpF,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC;gBACvD,CAAC;gBACD,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;oBACxD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBACrC,CAAC;gBACD,IAAI,MAAM,KAAK,KAAK,IAAI,KAAK,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;oBACzD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC;gBACvD,CAAC;gBAED,kFAAkF;gBAClF,qFAAqF;gBACrF,mFAAmF;gBACnF,0EAA0E;gBAE1E,OAAO;oBACL,MAAM,EAAE,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;oBAC7E,4EAA4E;oBAC5E,6EAA6E;oBAC7E,IAAI,EAAE,MAAM;iBACb,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;gBAC1C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAChC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,uDAAuD;AACvD,MAAM,UAAU,cAAc,CAC5B,MAAkB,EAClB,MAAyB;IAEzB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAChD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAwC,CAAC;YAEvE,MAAM,UAAU,GAAG;gBACjB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,GAAG,CAAC,KAAK;aACjB,CAAC;YAEF,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAE/C,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,IAAI,CAAC,IAAI,KAAK,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;oBACpF,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC;gBACvD,CAAC;gBACD,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;oBACxD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;gBACrC,CAAC;gBACD,IAAI,MAAM,KAAK,KAAK,IAAI,KAAK,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;oBACzD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC;gBACvD,CAAC;gBAED,kFAAkF;gBAClF,qFAAqF;gBACrF,mFAAmF;gBACnF,0EAA0E;gBAE1E,OAAO;oBACL,MAAM,EAAE,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;oBAC7E,4EAA4E;oBAC5E,6EAA6E;oBAC7E,IAAI,EAAE,MAAM;iBACb,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;gBAC1C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAChC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
package/dist/routes.d.ts CHANGED
@@ -1,9 +1,5 @@
1
- /**
2
- * @fougere/adapter-rest — generates REST route definitions from fougere handlers.
3
- *
4
- * Framework-agnostic: produces RouteDefinition[], consumed by an adapter (Fastify, Express, etc).
5
- */
6
- import type { Fields, SchemaOrCard } from '@fougere/schema';
1
+ /** @fougere/adapter-rest — generates REST route definitions from fougere handlers. */
2
+ import type { Fields, SchemaView } from '@fougere/schema';
7
3
  import type { HandlerEntry as CoreHandlerEntry } from '@fougere/core';
8
4
  export type { HttpMethod } from '@fougere/http';
9
5
  import type { HttpMethod } from '@fougere/http';
@@ -20,20 +16,12 @@ export interface RouteDefinition {
20
16
  outputFields?: Fields;
21
17
  /** Explicit success status. Defaults to 201 only for the canonical `create` op. */
22
18
  successStatus?: number;
23
- /**
24
- * The operation in words — the method's own doc sentence, carried by the contract.
25
- *
26
- * A route is what an OpenAPI `summary` is generated FROM, and the sentence reached
27
- * this file already through core's `EffectiveOperation` table;
28
- * only this type had no name for it, so every generated route was undocumented while
29
- * the sentence sat one property away. Carried, not rendered: emitting OpenAPI is a
30
- * reader's job, and this is what it reads.
31
- */
19
+ /** The operation in words — the method's own doc sentence, carried by the contract. */
32
20
  description?: string;
33
21
  }
34
22
  interface OperationMeta {
35
- input?: SchemaOrCard;
36
- output?: SchemaOrCard;
23
+ input?: SchemaView;
24
+ output?: SchemaView;
37
25
  /** Canonical kind from core's EffectiveOperation. */
38
26
  kind: 'query' | 'command';
39
27
  /** The operation in words — see `RouteDefinition.description`. */
@@ -42,36 +30,16 @@ interface OperationMeta {
42
30
  interface EntityEntry {
43
31
  name: string;
44
32
  /** A live class in-process, a card from a frond whose class never crossed. */
45
- entityClass: SchemaOrCard;
33
+ entityClass: SchemaView;
46
34
  exposed?: boolean;
47
35
  }
48
- /**
49
- * Only what this projection reads of a scanned handler — five fields of nine.
50
- *
51
- * The narrowness is deliberate: a consumer that declares what it consumes accepts a
52
- * minimal literal in a test and does not break when a field it ignores moves. What was
53
- * NOT deliberate is that the two names it does read were spelled again here, so renaming
54
- * `entityName` to `address` in core left this file compiling against a field the runtime
55
- * object no longer carried — a silent break, caught only because the same commit touched
56
- * the reads. `Pick` keeps the narrow view and makes core the one place the names live.
57
- *
58
- * `schema-graphql` holds a copy of this shape and cannot do the same: it depends on
59
- * `@fougere/schema` and `@fougere/http`, never on core, which is what lets a projection
60
- * package stay structurally typed. There the duplication is the doctrine, not an oversight.
61
- */
36
+ /** Only what this projection reads of a scanned handler — five fields of nine. */
62
37
  type HandlerEntry = Pick<CoreHandlerEntry, 'address' | 'surface'> & {
63
38
  /** `Crud(Post, PostPublic)` — the handler-wide output view, scoping every op. */
64
- outputOverride?: SchemaOrCard;
65
- /**
66
- * The scanned constructor, which carries the same statement made on the class.
67
- *
68
- * Typed as a constructor that MAY carry the static, not as `{ __output?: … }` alone:
69
- * a type whose every property is optional is weak, and TS refuses a constructor that
70
- * happens not to carry it — *has no properties in common*. So the narrow view was
71
- * unassignable from the real entry for a second reason after `operations`.
72
- */
39
+ outputOverride?: SchemaView;
40
+ /** The scanned constructor, which carries the same statement made on the class. */
73
41
  ctor?: (new (...args: never[]) => unknown) & {
74
- __output?: SchemaOrCard;
42
+ __output?: SchemaView;
75
43
  };
76
44
  };
77
45
  interface PresenterEntry {
@@ -106,19 +74,6 @@ export interface GenerateRoutesOptions {
106
74
  /** Surface name for filtering (e.g. 'rest', 'graphql'). Uses frond.config.ts surfaces if set. */
107
75
  surface?: string;
108
76
  }
109
- /**
110
- * Generate REST route definitions from a fougere App.
111
- *
112
- * Conventions:
113
- * - Entity name → pluralized base path (/posts, /authors)
114
- * - list → GET /posts
115
- * - findById → GET /posts/:id
116
- * - create → POST /posts
117
- * - update → PUT /posts/:id
118
- * - delete → DELETE /posts/:id
119
- * - Custom: searchByTitle → GET /posts/search-by-title
120
- * - Custom with ById: archiveById → POST /posts/:id/archive
121
- * - Override any route via options.overrides
122
- */
77
+ /** Generate REST route definitions from a fougere App. */
123
78
  export declare function generateRoutes(app: AppLike, options?: GenerateRoutesOptions): RouteDefinition[];
124
79
  //# sourceMappingURL=routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
package/dist/routes.js CHANGED
@@ -1,4 +1,4 @@
1
- import { fieldsOf, Visibility } from '@fougere/schema';
1
+ import { Visibility } from '@fougere/schema';
2
2
  // ─── Naming conventions ─────────────────────────
3
3
  function hasById(name) {
4
4
  return name.includes('ById') || name === 'findById' || name === 'update' || name === 'delete';
@@ -44,20 +44,7 @@ function derivePath(entityName, opName) {
44
44
  const segment = cleanName.replace(/[A-Z]/g, (c) => '-' + c.toLowerCase());
45
45
  return withId ? `${base}/:id/${segment}` : `${base}/${segment}`;
46
46
  }
47
- /**
48
- * Generate REST route definitions from a fougere App.
49
- *
50
- * Conventions:
51
- * - Entity name → pluralized base path (/posts, /authors)
52
- * - list → GET /posts
53
- * - findById → GET /posts/:id
54
- * - create → POST /posts
55
- * - update → PUT /posts/:id
56
- * - delete → DELETE /posts/:id
57
- * - Custom: searchByTitle → GET /posts/search-by-title
58
- * - Custom with ById: archiveById → POST /posts/:id/archive
59
- * - Override any route via options.overrides
60
- */
47
+ /** Generate REST route definitions from a fougere App. */
61
48
  export function generateRoutes(app, options) {
62
49
  const prefix = options?.prefix ?? '';
63
50
  const overrides = options?.overrides ?? {};
@@ -85,13 +72,12 @@ export function generateRoutes(app, options) {
85
72
  // proxy facades, which intentionally cannot enumerate their keys before discovery.
86
73
  const opNames = [...effectiveOperations.keys()];
87
74
  const entityOverrides = overrides[entity.name] ?? {};
88
- // Use handler's output schema if declared, otherwise entity. A live class or a
89
- // card — `fieldsOf` takes both, so a frond whose class never crossed the wire
90
- // projects the same routes as a local one.
75
+ // Use handler's output schema if declared, otherwise entity. A frond whose class
76
+ // never crossed the wire arrives as one too: boot rebuilds the card before here.
91
77
  const outputSchema = handler?.outputOverride
92
78
  ?? handler?.ctor?.__output
93
79
  ?? entity.entityClass;
94
- const fields = fieldsOf(outputSchema);
80
+ const fields = outputSchema.getFields();
95
81
  for (const opName of opNames) {
96
82
  const meta = effectiveOperations.get(opName);
97
83
  if (!meta) {
@@ -105,13 +91,13 @@ export function generateRoutes(app, options) {
105
91
  let inputFields;
106
92
  let outputFields = Visibility.of(fields).output;
107
93
  if (meta?.input) {
108
- inputFields = fieldsOf(meta.input);
94
+ inputFields = meta.input.getFields();
109
95
  }
110
96
  else if (opName === 'create' || opName === 'update') {
111
97
  inputFields = Visibility.of(fields).input;
112
98
  }
113
99
  if (meta?.output)
114
- outputFields = Visibility.of(fieldsOf(meta.output)).output;
100
+ outputFields = Visibility.of(meta.output.getFields()).output;
115
101
  // Handler/method overrides are already executed by the facade from the same
116
102
  // EffectiveOperation local and RPC use. The adapter never resolves DI itself.
117
103
  const op = facade[opName];
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAoF7C,mDAAmD;AAGnD,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,QAAQ,CAAC;AAChG,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QACvB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK;QAC3B,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;AACjB,CAAC;AAED,kFAAkF;AAClF,SAAS,YAAY,CACnB,MAAc,EACd,YAAmC;IAEnC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,wBAAwB,MAAM,yCAAyC;cACrE,uFAAuF,CAC1F,CAAC;IACJ,CAAC;IACD,IAAI,YAAY,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/C,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3E,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,2DAA2D;AAC3D,SAAS,UAAU,CAAC,UAAkB,EAAE,MAAc;IACpD,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC;IAEzC,gBAAgB;IAChB,IAAI,MAAM,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,GAAG,IAAI,MAAM,CAAC;IAChD,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,GAAG,IAAI,MAAM,CAAC;IAC9C,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,GAAG,IAAI,MAAM,CAAC;IAE9C,0CAA0C;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAE1E,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,QAAQ,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;AAClE,CAAC;AAqBD,0DAA0D;AAC1D,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,OAA+B;IAC1E,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,EAAE,CAAC;IACrC,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAsB,EAAE,CAAC;IAErC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAEhG,MAAM,WAAW,GAAG,OAAO,EAAE,OAAO,CAAC;QAErC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpC,mFAAmF;YACnF,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAA8B,CAAC;YACpF,IAAI,CAAC,MAAM;gBAAE,SAAS;YAEtB,IAAI,OAAO,EAAE,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YACrE,IAAI,CAAC,WAAW,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK;gBAAE,SAAS;YAEvD,MAAM,OAAO,GAAG,CAAC,WAAW;gBAC1B,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC;gBACpF,CAAC,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,mBAAmB,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YACxE,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CACb,wBAAwB,MAAM,CAAC,IAAI,yCAAyC,CAC7E,CAAC;YACJ,CAAC;YACD,kFAAkF;YAClF,mFAAmF;YACnF,MAAM,OAAO,GAAG,CAAC,GAAG,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACrD,iFAAiF;YACjF,iFAAiF;YACjF,MAAM,YAAY,GAAe,OAAO,EAAE,cAAc;mBACnD,OAAO,EAAE,IAAI,EAAE,QAAQ;mBACvB,MAAM,CAAC,WAAW,CAAC;YACxB,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC;YAExC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,MAAM,IAAI,GAAG,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,MAAM,IAAI,KAAK,CACb,gBAAgB,MAAM,CAAC,IAAI,cAAc,MAAM,8CAA8C,CAC9F,CAAC;gBACJ,CAAC;gBACD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;gBACzC,MAAM,MAAM,GAAG,QAAQ,EAAE,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBACpE,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;gBAE1E,kFAAkF;gBAClF,mFAAmF;gBACnF,IAAI,WAA+B,CAAC;gBACpC,IAAI,YAAY,GAAuB,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;gBACpE,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;oBAChB,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACvC,CAAC;qBAAM,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;oBACtD,WAAW,GAAG,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC;gBAC5C,CAAC;gBACD,IAAI,IAAI,EAAE,MAAM;oBAAE,YAAY,GAAG,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;gBAE/E,4EAA4E;gBAC5E,8EAA8E;gBAC9E,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1B,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;oBAC7B,MAAM,IAAI,KAAK,CACb,0CAA0C,MAAM,4BAA4B,CAC7E,CAAC;gBACJ,CAAC;gBAED,MAAM,CAAC,IAAI,CAAC;oBACV,MAAM;oBACN,IAAI;oBACJ,aAAa,EAAE,MAAM;oBACrB,UAAU,EAAE,MAAM,CAAC,IAAI;oBACvB,OAAO,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC;oBACvC,WAAW;oBACX,YAAY;oBACZ,aAAa,EAAE,QAAQ,EAAE,MAAM;oBAC/B,GAAG,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;iBAC5D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fougere/adapter-rest",
3
- "version": "0.5.0-alpha.1",
3
+ "version": "0.7.0-alpha.0",
4
4
  "description": "Entity → REST routes.",
5
5
  "keywords": [
6
6
  "fougere",
@@ -29,9 +29,9 @@
29
29
  "src"
30
30
  ],
31
31
  "dependencies": {
32
- "@fougere/core": "0.5.0-alpha.1",
33
- "@fougere/schema": "0.5.0-alpha.1",
34
- "@fougere/http": "0.5.0-alpha.1"
32
+ "@fougere/core": "0.7.0-alpha.0",
33
+ "@fougere/http": "0.7.0-alpha.0",
34
+ "@fougere/schema": "0.7.0-alpha.0"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public"
package/src/register.ts CHANGED
@@ -5,14 +5,7 @@ import type { HttpRouter } from '@fougere/http';
5
5
  import { toHttpError } from '@fougere/core';
6
6
  import type { RouteDefinition } from './routes.js';
7
7
 
8
- /**
9
- * Register all route definitions on an HttpRouter.
10
- *
11
- * ```ts
12
- * const routes = generateRoutes(app, { prefix: '/api' });
13
- * registerRoutes(router, routes);
14
- * ```
15
- */
8
+ /** Register all route definitions on an HttpRouter. */
16
9
  export function registerRoutes(
17
10
  router: HttpRouter,
18
11
  routes: RouteDefinition[],
@@ -24,7 +17,7 @@ export function registerRoutes(
24
17
  const invocation = {
25
18
  params: ctx.params,
26
19
  query: ctx.query,
27
- body,
20
+ input: body,
28
21
  state: ctx.state,
29
22
  };
30
23
 
package/src/routes.ts CHANGED
@@ -1,10 +1,6 @@
1
- /**
2
- * @fougere/adapter-rest — generates REST route definitions from fougere handlers.
3
- *
4
- * Framework-agnostic: produces RouteDefinition[], consumed by an adapter (Fastify, Express, etc).
5
- */
6
- import type { Field, Fields, SchemaOrCard } from '@fougere/schema';
7
- import { fieldsOf, Visibility } from '@fougere/schema';
1
+ /** @fougere/adapter-rest — generates REST route definitions from fougere handlers. */
2
+ import type { Field, Fields, SchemaView } from '@fougere/schema';
3
+ import { Visibility } from '@fougere/schema';
8
4
  import type { HandlerEntry as CoreHandlerEntry } from '@fougere/core';
9
5
 
10
6
  // ─── Types ──────────────────────────────────────
@@ -27,15 +23,7 @@ export interface RouteDefinition {
27
23
  outputFields?: Fields;
28
24
  /** Explicit success status. Defaults to 201 only for the canonical `create` op. */
29
25
  successStatus?: number;
30
- /**
31
- * The operation in words — the method's own doc sentence, carried by the contract.
32
- *
33
- * A route is what an OpenAPI `summary` is generated FROM, and the sentence reached
34
- * this file already through core's `EffectiveOperation` table;
35
- * only this type had no name for it, so every generated route was undocumented while
36
- * the sentence sat one property away. Carried, not rendered: emitting OpenAPI is a
37
- * reader's job, and this is what it reads.
38
- */
26
+ /** The operation in words — the method's own doc sentence, carried by the contract. */
39
27
  description?: string;
40
28
  // No presenter here. A route used to carry the instance and its field names so the
41
29
  // registration could enrich each row; the façade does that for every door now
@@ -43,8 +31,8 @@ export interface RouteDefinition {
43
31
  }
44
32
 
45
33
  interface OperationMeta {
46
- input?: SchemaOrCard;
47
- output?: SchemaOrCard;
34
+ input?: SchemaView;
35
+ output?: SchemaView;
48
36
  /** Canonical kind from core's EffectiveOperation. */
49
37
  kind: 'query' | 'command';
50
38
  /** The operation in words — see `RouteDefinition.description`. */
@@ -54,36 +42,16 @@ interface OperationMeta {
54
42
  interface EntityEntry {
55
43
  name: string;
56
44
  /** A live class in-process, a card from a frond whose class never crossed. */
57
- entityClass: SchemaOrCard;
45
+ entityClass: SchemaView;
58
46
  exposed?: boolean;
59
47
  }
60
48
 
61
- /**
62
- * Only what this projection reads of a scanned handler — five fields of nine.
63
- *
64
- * The narrowness is deliberate: a consumer that declares what it consumes accepts a
65
- * minimal literal in a test and does not break when a field it ignores moves. What was
66
- * NOT deliberate is that the two names it does read were spelled again here, so renaming
67
- * `entityName` to `address` in core left this file compiling against a field the runtime
68
- * object no longer carried — a silent break, caught only because the same commit touched
69
- * the reads. `Pick` keeps the narrow view and makes core the one place the names live.
70
- *
71
- * `schema-graphql` holds a copy of this shape and cannot do the same: it depends on
72
- * `@fougere/schema` and `@fougere/http`, never on core, which is what lets a projection
73
- * package stay structurally typed. There the duplication is the doctrine, not an oversight.
74
- */
49
+ /** Only what this projection reads of a scanned handler — five fields of nine. */
75
50
  type HandlerEntry = Pick<CoreHandlerEntry, 'address' | 'surface'> & {
76
51
  /** `Crud(Post, PostPublic)` — the handler-wide output view, scoping every op. */
77
- outputOverride?: SchemaOrCard;
78
- /**
79
- * The scanned constructor, which carries the same statement made on the class.
80
- *
81
- * Typed as a constructor that MAY carry the static, not as `{ __output?: … }` alone:
82
- * a type whose every property is optional is weak, and TS refuses a constructor that
83
- * happens not to carry it — *has no properties in common*. So the narrow view was
84
- * unassignable from the real entry for a second reason after `operations`.
85
- */
86
- ctor?: (new (...args: never[]) => unknown) & { __output?: SchemaOrCard };
52
+ outputOverride?: SchemaView;
53
+ /** The scanned constructor, which carries the same statement made on the class. */
54
+ ctor?: (new (...args: never[]) => unknown) & { __output?: SchemaView };
87
55
  };
88
56
  // No `operations` here, and its absence is the point. It was declared, never read — this
89
57
  // file takes its table from `app.operationsFor()` — and it carried `OperationMeta`, whose
@@ -185,20 +153,7 @@ export interface GenerateRoutesOptions {
185
153
  surface?: string;
186
154
  }
187
155
 
188
- /**
189
- * Generate REST route definitions from a fougere App.
190
- *
191
- * Conventions:
192
- * - Entity name → pluralized base path (/posts, /authors)
193
- * - list → GET /posts
194
- * - findById → GET /posts/:id
195
- * - create → POST /posts
196
- * - update → PUT /posts/:id
197
- * - delete → DELETE /posts/:id
198
- * - Custom: searchByTitle → GET /posts/search-by-title
199
- * - Custom with ById: archiveById → POST /posts/:id/archive
200
- * - Override any route via options.overrides
201
- */
156
+ /** Generate REST route definitions from a fougere App. */
202
157
  export function generateRoutes(app: AppLike, options?: GenerateRoutesOptions): RouteDefinition[] {
203
158
  const prefix = options?.prefix ?? '';
204
159
  const overrides = options?.overrides ?? {};
@@ -230,13 +185,12 @@ export function generateRoutes(app: AppLike, options?: GenerateRoutesOptions): R
230
185
  // proxy facades, which intentionally cannot enumerate their keys before discovery.
231
186
  const opNames = [...effectiveOperations.keys()];
232
187
  const entityOverrides = overrides[entity.name] ?? {};
233
- // Use handler's output schema if declared, otherwise entity. A live class or a
234
- // card — `fieldsOf` takes both, so a frond whose class never crossed the wire
235
- // projects the same routes as a local one.
236
- const outputSchema: SchemaOrCard = handler?.outputOverride
188
+ // Use handler's output schema if declared, otherwise entity. A frond whose class
189
+ // never crossed the wire arrives as one too: boot rebuilds the card before here.
190
+ const outputSchema: SchemaView = handler?.outputOverride
237
191
  ?? handler?.ctor?.__output
238
192
  ?? entity.entityClass;
239
- const fields = fieldsOf(outputSchema);
193
+ const fields = outputSchema.getFields();
240
194
 
241
195
  for (const opName of opNames) {
242
196
  const meta = effectiveOperations.get(opName);
@@ -254,11 +208,11 @@ export function generateRoutes(app: AppLike, options?: GenerateRoutesOptions): R
254
208
  let inputFields: Fields | undefined;
255
209
  let outputFields: Fields | undefined = Visibility.of(fields).output;
256
210
  if (meta?.input) {
257
- inputFields = fieldsOf(meta.input);
211
+ inputFields = meta.input.getFields();
258
212
  } else if (opName === 'create' || opName === 'update') {
259
213
  inputFields = Visibility.of(fields).input;
260
214
  }
261
- if (meta?.output) outputFields = Visibility.of(fieldsOf(meta.output)).output;
215
+ if (meta?.output) outputFields = Visibility.of(meta.output.getFields()).output;
262
216
 
263
217
  // Handler/method overrides are already executed by the facade from the same
264
218
  // EffectiveOperation local and RPC use. The adapter never resolves DI itself.