@nxgt/typespec 0.13.2 → 0.14.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.
package/README.md CHANGED
@@ -540,6 +540,28 @@ with a reason, or for one operation with
540
540
  `#suppress "@nxgt/typespec/<rule>" "<reason>"`. More, with a failing and a
541
541
  passing example of each rule, in [Linter](docs/guide/linter.md).
542
542
 
543
+ ### Shared responses, headers and path servers
544
+
545
+ Three decorators, written by the emitter `@nxgt/typespec` (with
546
+ `@typespec/openapi3` in `emit` each is `shared-needs-nxgt-emitter`):
547
+
548
+ ```tsp
549
+ @sharedResponse @error
550
+ model Unauthorized {
551
+ @sharedHeader("NoStore") @header("cache-control") cacheControl: "no-store";
552
+ @statusCode code: 401;
553
+ message: string;
554
+ }
555
+
556
+ @route("/users")
557
+ @pathServer("https://users.example.com", "Users")
558
+ @get op listUsers(): { @body users: string[] } | Unauthorized;
559
+ ```
560
+
561
+ `Unauthorized` is emitted once under `components.responses`, its header once
562
+ under `components.headers`, a `$ref` at each use, and `/users` alone gets
563
+ `servers`. More, in [The emitter](docs/guide/emitter.md#shared-responses-shared-headers-and-path-servers).
564
+
543
565
  ## API
544
566
 
545
567
  ### Decorators
@@ -547,6 +569,9 @@ passing example of each rule, in [Linter](docs/guide/linter.md).
547
569
  | Decorator | On | What it does |
548
570
  | --- | --- | --- |
549
571
  | `@queryMethod` | an operation | marks a `@post` as a `QUERY`: needs the emitter `@nxgt/typespec` and OpenAPI 3.2, where the document gets a `query` operation, and is an error otherwise; `@operationIds` checks its verb as a `QUERY`'s |
572
+ | `@sharedResponse(name?)` | a response model | emits the response once under `components.responses`, a `$ref` at each use; needs the emitter `@nxgt/typespec` |
573
+ | `@sharedHeader(name?)` | a `@header` property of a response | emits the header once under `components.headers`, a `$ref` at each use; needs the emitter `@nxgt/typespec` |
574
+ | `@pathServer(url, description?, parameters?)` | an operation | `servers` on its path item, with `@server`'s variables; the other paths keep the document's; needs the emitter `@nxgt/typespec` |
550
575
  | `@operationIds(options?: OperationIdsOptions)` | a namespace or an interface | makes each operation's id its name, as written, or a known verb with the interface's resource (`list` in `Users` is `listUsers`), in the namespace however deep or in the interface, unless it has an `@operationId` |
551
576
 
552
577
  `OperationIdsOptions` is `#{ singular?: string, plural?: string, verbs?: Record<"singular" | "plural"> }`:
@@ -573,6 +598,14 @@ overrides verbs, on a namespace or an interface.
573
598
  | `query-method-not-post` | error: an operation marked `@queryMethod` is not a `@post` |
574
599
  | `query-method-needs-openapi-3.2` | error: the emitter `@nxgt/typespec` is asked for a version below 3.2 (or none, which is 3.0) beside a `@queryMethod`; nothing is emitted |
575
600
  | `query-method-needs-nxgt-emitter` | error: `@typespec/openapi3` is in `emit` beside a `@queryMethod` |
601
+ | `shared-component-conflict` | error: two `@sharedResponse` or two `@sharedHeader` of one name differ; the first is the component, the other stays inline |
602
+ | `shared-response-merged` | error: operations sharing a route reply one status with different responses, one a `@sharedResponse` |
603
+ | `path-server-missing-variable` | error: a `{name}` of a `@pathServer` URL has no property in its parameters |
604
+ | `path-server-invalid-variable` | error: a `@pathServer` variable is not a string, a string enum or a union of strings |
605
+ | `shared-header-misplaced` | error: `@sharedHeader` on a request header or a body property |
606
+ | `invalid-component-name` | error: the name given to `@sharedResponse` or `@sharedHeader` has a character OpenAPI does not allow in a component name |
607
+ | `path-server-conflict` | error: two `@pathServer` of one path give one URL a different description or variables |
608
+ | `shared-needs-nxgt-emitter` | error: `@typespec/openapi3` is in `emit` beside a `@sharedResponse`, `@sharedHeader` or `@pathServer` |
576
609
  | `openapi3-missing` | error: the emitter `@nxgt/typespec` runs `@typespec/openapi3`, which is not installed |
577
610
 
578
611
  ### Linter rules
@@ -734,6 +767,7 @@ envelope and the rate limit's headers.
734
767
  template, the files it writes, and the steps from the spec to a Hono route;
735
768
  - [The emitter](docs/guide/emitter.md): `@nxgt/typespec` in `tspconfig.yaml`,
736
769
  a `@queryMethod` as a real `QUERY` in OpenAPI 3.2, and what that needs;
770
+ shared responses and headers under `components`, and `servers` on a path;
737
771
  - [Error replies](docs/guide/errors.md): the envelope, each response, the
738
772
  aliases by verb, and what the generator makes of them;
739
773
  - [Pagination](docs/guide/pagination.md): offset and cursor pages, and
@@ -0,0 +1,17 @@
1
+ /**
2
+ * `@sharedResponse`, `@sharedHeader` and `@pathServer`: what the spec asks
3
+ * to be emitted once under `components`, or on one path item. A header and
4
+ * an operation carry their mark (`marks.ts`) until `shared-components.ts`
5
+ * rewrites the emitted document; a response is marked at emit time
6
+ * (`response-marks.ts`).
7
+ */
8
+ import { type DecoratorContext, type Model, type ModelProperty, type Operation, type Program } from '@typespec/compiler';
9
+ export declare function sharedResponse(context: DecoratorContext, target: Model, name?: string): void;
10
+ export declare function sharedHeader(context: DecoratorContext, target: ModelProperty, name?: string): void;
11
+ export declare function pathServer(context: DecoratorContext, target: Operation, url: string, description?: string, parameters?: Model): void;
12
+ /**
13
+ * Each marked target must be emitted by `@nxgt/typespec`: `@typespec/openapi3`
14
+ * would write the copies, or drop the servers, without a word.
15
+ */
16
+ export declare function validateComponents(program: Program): void;
17
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACN,KAAK,gBAAgB,EAErB,KAAK,KAAK,EACV,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,MAAM,oBAAoB,CAAC;AAuB5B,wBAAgB,cAAc,CAC7B,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,KAAK,EACb,IAAI,CAAC,EAAE,MAAM,GACX,IAAI,CAKN;AAED,wBAAgB,YAAY,CAC3B,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,aAAa,EACrB,IAAI,CAAC,EAAE,MAAM,GACX,IAAI,CAMN;AAED,wBAAgB,UAAU,CACzB,OAAO,EAAE,gBAAgB,EACzB,MAAM,EAAE,SAAS,EACjB,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,KAAK,GAChB,IAAI,CA+BN;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqBzD"}
@@ -0,0 +1,7 @@
1
+ export type Document = Record<string, unknown>;
2
+ /**
3
+ * The text with `rewrite` applied to its document, and left as it was when
4
+ * `rewrite` says nothing changed.
5
+ */
6
+ export declare function rewriteDocument(content: string, rewrite: (document: Document) => boolean): string;
7
+ //# sourceMappingURL=document-text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-text.d.ts","sourceRoot":"","sources":["../src/document-text.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,GACtC,MAAM,CAeR"}
package/dist/emitter.d.ts CHANGED
@@ -2,7 +2,9 @@
2
2
  * The emitter `@nxgt/typespec`: `@typespec/openapi3`, with its options,
3
3
  * checked by its own schema, and its files, and each `POST` marked
4
4
  * `@queryMethod` a real `QUERY` in an OpenAPI 3.2 document
5
- * (`query-operations.ts`). Only 3.2 has a `QUERY`: a marked operation with
5
+ * (`query-operations.ts`), and what `@sharedResponse`, `@sharedHeader` and
6
+ * `@pathServer` ask: components emitted once, servers on a path item
7
+ * (`shared-components.ts`). Only 3.2 has a `QUERY`: a marked operation with
6
8
  * an older version asked for is an error, and nothing is emitted.
7
9
  * `@typespec/openapi3` is loaded only here, so a spec that only imports the
8
10
  * library does not need it.
@@ -1 +1 @@
1
- {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAGN,KAAK,WAAW,EAEhB,MAAM,oBAAoB,CAAC;AAmE5B,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BjE"}
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../src/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAGN,KAAK,WAAW,EAGhB,MAAM,oBAAoB,CAAC;AAkG5B,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCjE"}
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  * export would declare it a second time, in the global namespace.
8
8
  */
9
9
  import type { Program } from '@typespec/compiler';
10
+ import { pathServer, sharedHeader, sharedResponse } from './components.js';
10
11
  import { operationIds } from './operation-ids.js';
11
12
  import { queryMethod } from './query-method.js';
12
13
  export { $onEmit } from './emitter.js';
@@ -16,7 +17,10 @@ export declare function $onValidate(program: Program): void;
16
17
  export declare const $decorators: {
17
18
  Nxgt: {
18
19
  operationIds: typeof operationIds;
20
+ pathServer: typeof pathServer;
19
21
  queryMethod: typeof queryMethod;
22
+ sharedHeader: typeof sharedHeader;
23
+ sharedResponse: typeof sharedResponse;
20
24
  };
21
25
  };
22
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,YAAY,EAAwB,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAwB,MAAM,gBAAgB,CAAC;AAGnE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAOlD;AAED,eAAO,MAAM,WAAW;;;;;CAEvB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACN,UAAU,EACV,YAAY,EACZ,cAAc,EAEd,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAwB,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAwB,MAAM,gBAAgB,CAAC;AAGnE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQlD;AAED,eAAO,MAAM,WAAW;;;;;;;;CAQvB,CAAC"}