@nxgt/typespec 0.13.1 → 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 +36 -1
- package/dist/components.d.ts +17 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/document-text.d.ts +7 -0
- package/dist/document-text.d.ts.map +1 -0
- package/dist/emitter.d.ts +3 -1
- package/dist/emitter.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +501 -38
- package/dist/index.js.map +13 -7
- package/dist/lib.d.ts +25 -1
- package/dist/lib.d.ts.map +1 -1
- package/dist/marks.d.ts +32 -0
- package/dist/marks.d.ts.map +1 -0
- package/dist/query-operations.d.ts +1 -6
- package/dist/query-operations.d.ts.map +1 -1
- package/dist/response-marks.d.ts +10 -0
- package/dist/response-marks.d.ts.map +1 -0
- package/dist/server-variables.d.ts +10 -0
- package/dist/server-variables.d.ts.map +1 -0
- package/dist/shared-components.d.ts +11 -0
- package/dist/shared-components.d.ts.map +1 -0
- package/docs/README.md +1 -1
- package/docs/guide/emitter.md +147 -1
- package/docs/guide/scalars.md +6 -3
- package/docs/roadmap.md +18 -3
- package/docs/troubleshooting.md +105 -7
- package/lib/components.tsp +65 -0
- package/lib/main.tsp +1 -0
- package/package.json +3 -2
package/docs/guide/emitter.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
`@nxgt/typespec` is a TypeSpec emitter as well as a library: it compiles a
|
|
4
4
|
spec to OpenAPI with `@typespec/openapi3`, and writes each `@queryMethod` as a
|
|
5
|
-
real `QUERY` when the document is OpenAPI 3.2.
|
|
5
|
+
real `QUERY` when the document is OpenAPI 3.2. It also emits a shared
|
|
6
|
+
response or header once under `components`, and `servers` on one path
|
|
7
|
+
([below](#shared-responses-shared-headers-and-path-servers)).
|
|
6
8
|
|
|
7
9
|
## The smallest setup
|
|
8
10
|
|
|
@@ -98,6 +100,150 @@ where `@typespec/openapi3` wrote `tsp-output/@typespec/openapi3`. Set
|
|
|
98
100
|
`@typespec/openapi3` is loaded only when emitting, so a spec that only
|
|
99
101
|
imports the library, `tsp compile --no-emit`, does not need it installed.
|
|
100
102
|
|
|
103
|
+
## Shared responses, shared headers and path servers
|
|
104
|
+
|
|
105
|
+
`@typespec/openapi3` writes every response and header in full at each
|
|
106
|
+
operation, and `@server` only reaches the document's `servers`. Three
|
|
107
|
+
decorators ask the emitter for the rest, with no post-processing of the JSON.
|
|
108
|
+
They need this emitter: with `@typespec/openapi3` in `emit` each is the error
|
|
109
|
+
`shared-needs-nxgt-emitter`, since it would write the copies or drop the
|
|
110
|
+
servers without a word.
|
|
111
|
+
|
|
112
|
+
```tsp
|
|
113
|
+
import "@typespec/http";
|
|
114
|
+
import "@nxgt/typespec";
|
|
115
|
+
|
|
116
|
+
using Http;
|
|
117
|
+
using Nxgt;
|
|
118
|
+
|
|
119
|
+
@service(#{ title: "Example" })
|
|
120
|
+
@server("https://api.example.com", "Main")
|
|
121
|
+
namespace Example;
|
|
122
|
+
|
|
123
|
+
model NoStore {
|
|
124
|
+
@sharedHeader("NoStore")
|
|
125
|
+
@header("cache-control")
|
|
126
|
+
cacheControl: "no-store";
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@sharedResponse
|
|
130
|
+
@error
|
|
131
|
+
model Unauthorized {
|
|
132
|
+
...NoStore;
|
|
133
|
+
@statusCode code: 401;
|
|
134
|
+
message: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
@route("/items") @get op listItems(): { @body items: string[] } | Unauthorized;
|
|
138
|
+
|
|
139
|
+
@route("/users")
|
|
140
|
+
@pathServer("https://users.example.com", "Users")
|
|
141
|
+
@get op listUsers(): { @body users: string[] } | Unauthorized;
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```yaml
|
|
145
|
+
# openapi.yaml (extract)
|
|
146
|
+
paths:
|
|
147
|
+
/items:
|
|
148
|
+
get:
|
|
149
|
+
responses:
|
|
150
|
+
'401':
|
|
151
|
+
$ref: '#/components/responses/Unauthorized'
|
|
152
|
+
/users:
|
|
153
|
+
servers:
|
|
154
|
+
- url: https://users.example.com
|
|
155
|
+
description: Users
|
|
156
|
+
get:
|
|
157
|
+
responses:
|
|
158
|
+
'401':
|
|
159
|
+
$ref: '#/components/responses/Unauthorized'
|
|
160
|
+
components:
|
|
161
|
+
headers:
|
|
162
|
+
NoStore:
|
|
163
|
+
required: true
|
|
164
|
+
schema: { type: string, enum: [no-store] }
|
|
165
|
+
responses:
|
|
166
|
+
Unauthorized:
|
|
167
|
+
description: Access is unauthorized.
|
|
168
|
+
headers:
|
|
169
|
+
cache-control:
|
|
170
|
+
$ref: '#/components/headers/NoStore'
|
|
171
|
+
content:
|
|
172
|
+
application/json:
|
|
173
|
+
schema:
|
|
174
|
+
$ref: '#/components/schemas/Unauthorized'
|
|
175
|
+
servers:
|
|
176
|
+
- url: https://api.example.com
|
|
177
|
+
description: Main
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
| Decorator | On | Result |
|
|
181
|
+
| --- | --- | --- |
|
|
182
|
+
| `@sharedResponse(name?)` | a response model | each reply of that model, whatever the operation, is one entry of `components.responses` (named after the model unless `name` is given) and a `$ref` at each use |
|
|
183
|
+
| `@sharedHeader(name?)` | a model property that is a `@header` | the header is one entry of `components.headers` (named after the property unless `name` is given) and a `$ref` at each response that carries it |
|
|
184
|
+
| `@pathServer(url, description?, parameters?)` | an operation | `servers` on the operation's path item; the other paths keep the document's. Repeated on the operations of one path, the servers add up |
|
|
185
|
+
|
|
186
|
+
What to know:
|
|
187
|
+
|
|
188
|
+
- **A response header only.** `components.headers` holds response headers.
|
|
189
|
+
`@sharedHeader` on a request `@header` or on a body property is the error
|
|
190
|
+
`shared-header-misplaced`; the mark never stays in the document.
|
|
191
|
+
- **A shared response is the whole reply**: description, headers and content.
|
|
192
|
+
A model with several statuses (`@statusCode code: 400 | 404`) is one
|
|
193
|
+
component per status, `Name400` and `Name404`, since their descriptions
|
|
194
|
+
differ.
|
|
195
|
+
Two shared responses, or two shared headers, of one name that differ are the
|
|
196
|
+
error `shared-component-conflict`: the first is the component, the other
|
|
197
|
+
stays inline. A name is letters,
|
|
198
|
+
digits, `.`, `_` and `-` (`invalid-component-name` otherwise).
|
|
199
|
+
- **A `@pathServer` is for a path item, not an operation**: `get` and `post`
|
|
200
|
+
of one route share it. The same server on several operations of one path is
|
|
201
|
+
written once; one URL with a different description or variables on another
|
|
202
|
+
is the error `path-server-conflict`, and the first is the one emitted.
|
|
203
|
+
- **Server variables** are `@server`'s third parameter: each property is a
|
|
204
|
+
variable, its default the variable's `default` (`""` without one), its
|
|
205
|
+
`@doc` the `description`, and a literal, enum or union of literals type its
|
|
206
|
+
`enum`. As with `@server`, a variable is a string (a string, a string enum
|
|
207
|
+
or a union of strings: `path-server-invalid-variable` otherwise), and each
|
|
208
|
+
`{name}` of the URL needs its property (`path-server-missing-variable`).
|
|
209
|
+
|
|
210
|
+
```tsp
|
|
211
|
+
@route("/jmap")
|
|
212
|
+
@pathServer("{origin}{basePath}", "Mail", {
|
|
213
|
+
@doc("The mail origin") origin: string = "https://mail.example.com",
|
|
214
|
+
@doc("Where it is mounted") basePath: string = "/jmap",
|
|
215
|
+
})
|
|
216
|
+
@get op session(): string;
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
```yaml
|
|
220
|
+
/jmap:
|
|
221
|
+
servers:
|
|
222
|
+
- url: '{origin}{basePath}'
|
|
223
|
+
description: Mail
|
|
224
|
+
variables:
|
|
225
|
+
origin:
|
|
226
|
+
default: https://mail.example.com
|
|
227
|
+
description: The mail origin
|
|
228
|
+
basePath:
|
|
229
|
+
default: /jmap
|
|
230
|
+
description: Where it is mounted
|
|
231
|
+
```
|
|
232
|
+
- **Several services** keep their own: each decorator marks the object the
|
|
233
|
+
emitter writes for its own operation or header, and the emitter reads and
|
|
234
|
+
takes off those marks per document, so the same path in two services, a
|
|
235
|
+
dotted service name or a nested service never mixes them.
|
|
236
|
+
- **Operations of a `@sharedRoute`** merge into one in the document; their
|
|
237
|
+
servers add up, and each one's shared responses are hoisted.
|
|
238
|
+
- **`@typespec/versioning` is not verified.** A shared response is marked on
|
|
239
|
+
the operation at emit time, and nothing here tests a versioned service,
|
|
240
|
+
whose operations the versioning library clones: shared responses on a
|
|
241
|
+
versioned service may stay inline, and a `@pathServer`'s servers may be missing.
|
|
242
|
+
- **Nothing changes without them.** A spec that uses none of the three emits
|
|
243
|
+
byte-identical output, and the hoisting is the same in 3.1 and 3.2.
|
|
244
|
+
- `@nxgt/openapi-codegen` generates a document with `$ref` responses and
|
|
245
|
+
headers as it does the inline copies.
|
|
246
|
+
|
|
101
247
|
## What follows downstream
|
|
102
248
|
|
|
103
249
|
| Step | What it does with the `query` operation |
|
package/docs/guide/scalars.md
CHANGED
|
@@ -67,9 +67,12 @@ components:
|
|
|
67
67
|
| `description` | The rule in words, and what the pattern leaves out. |
|
|
68
68
|
|
|
69
69
|
A generator that knows nothing of `x-nxgt-scalar` still validates the pattern
|
|
70
|
-
and the bounds.
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
and the bounds. `@nxgt/openapi-codegen` with
|
|
71
|
+
[`scalars: 'exact'`](https://github.com/softistx/nxgt-http/blob/develop/packages/openapi-codegen/docs/guide/options.md#scalars) maps it to the exact Zod
|
|
72
|
+
schema from `@nxgt/zod`, the checksum, the list or the `Intl` rule included;
|
|
73
|
+
with the default `'pattern'`, what a scalar leaves out is not checked. The
|
|
74
|
+
codecs (`dateTime`, `timestamp`, `bigInt`, `long`) keep their pattern under
|
|
75
|
+
`'exact'` too.
|
|
73
76
|
|
|
74
77
|
## Names
|
|
75
78
|
|
package/docs/roadmap.md
CHANGED
|
@@ -10,9 +10,7 @@ Nothing in progress.
|
|
|
10
10
|
|
|
11
11
|
## Next
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
`x-nxgt-scalar` to the exact Zod schema from `@nxgt/zod`: the checksums,
|
|
15
|
-
the ISO and IANA lists and the `Intl` rules the patterns leave out.
|
|
13
|
+
Nothing planned beyond what is under Later.
|
|
16
14
|
|
|
17
15
|
## Later
|
|
18
16
|
|
|
@@ -27,6 +25,23 @@ Nothing in progress.
|
|
|
27
25
|
|
|
28
26
|
## Shipped
|
|
29
27
|
|
|
28
|
+
### 0.14.0
|
|
29
|
+
|
|
30
|
+
- **Shared responses, shared headers and path servers.** `@sharedResponse`
|
|
31
|
+
and `@sharedHeader` emit a response and a header once under
|
|
32
|
+
`components.responses` and `components.headers`, a `$ref` at each use, and
|
|
33
|
+
`@pathServer` puts `servers` on one path item, from the spec alone with no
|
|
34
|
+
post-processing, with `@server`'s variables.
|
|
35
|
+
|
|
36
|
+
### 0.13.2
|
|
37
|
+
|
|
38
|
+
- **Exact scalar rules in the generated code.** `@nxgt/openapi-codegen`
|
|
39
|
+
with `scalars: 'exact'` maps `x-nxgt-scalar` to the exact Zod schema from
|
|
40
|
+
`@nxgt/zod`: the checksums, the ISO and IANA lists, the `Intl` rules and the
|
|
41
|
+
refusal of `-0` the patterns leave out. The codecs keep their pattern until
|
|
42
|
+
`@nxgt/zod` offers their wire schemas. The guides and the troubleshooting
|
|
43
|
+
entries say so.
|
|
44
|
+
|
|
30
45
|
### 0.13.0
|
|
31
46
|
|
|
32
47
|
- **The emitter `@nxgt/typespec`.** `emit: ["@nxgt/typespec"]` runs
|
package/docs/troubleshooting.md
CHANGED
|
@@ -361,6 +361,98 @@ options:
|
|
|
361
361
|
openapi-versions: ['3.2.0']
|
|
362
362
|
```
|
|
363
363
|
|
|
364
|
+
## `The server URL https://{tenant}.example.com of listUsers has {tenant}, which is not a property of its parameters. Add the variable, or take the braces out.`
|
|
365
|
+
|
|
366
|
+
**When:** `tsp compile`; the error `path-server-missing-variable` on a
|
|
367
|
+
`@pathServer` whose URL has a `{name}` its third parameter lacks.
|
|
368
|
+
|
|
369
|
+
**Fix:** add the variable, as `@server` asks:
|
|
370
|
+
|
|
371
|
+
```tsp
|
|
372
|
+
@pathServer("https://{tenant}.example.com", "Tenant", { tenant: string = "main" })
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## `The variable port of the @pathServer of listUsers is not a string, a string enum or a union of strings: an OpenAPI server variable is a string.`
|
|
376
|
+
|
|
377
|
+
**When:** `tsp compile`; the error `path-server-invalid-variable`, for a
|
|
378
|
+
variable typed `int32`, `boolean`… The default of a server variable is a string.
|
|
379
|
+
|
|
380
|
+
**Fix:** type it as a string: `port: string = "443"`, or `"443" | "8443"`.
|
|
381
|
+
|
|
382
|
+
## `Trace is marked @sharedHeader outside a response header: it applies to a @header of a reply only, not to a request header or a body property.`
|
|
383
|
+
|
|
384
|
+
**When:** `tsp compile`; the error `shared-header-misplaced`, for a
|
|
385
|
+
`@sharedHeader` property that ends up in a request (a `@header` parameter) or
|
|
386
|
+
in a body schema.
|
|
387
|
+
|
|
388
|
+
**Why:** `components.headers` holds response headers; a request header is a
|
|
389
|
+
parameter and a body property is a schema.
|
|
390
|
+
|
|
391
|
+
**Fix:** take `@sharedHeader` off, or keep it on a `@header` of a reply model.
|
|
392
|
+
|
|
393
|
+
## `Operations sharing the route GET /m reply 400 with different responses, one of them a @sharedResponse: @sharedRoute merges them into one reply, which cannot be a component. Give them the same shared response, or none.`
|
|
394
|
+
|
|
395
|
+
**When:** `tsp compile`; the error `shared-response-merged`, for operations
|
|
396
|
+
with `@sharedRoute` that answer one status with different responses (two shared
|
|
397
|
+
ones of different names, or a shared one and a plain one).
|
|
398
|
+
|
|
399
|
+
**Why:** the operations are one in the document, with one reply per status,
|
|
400
|
+
which cannot be a component and something else.
|
|
401
|
+
|
|
402
|
+
**Fix:** answer that status with the same `@sharedResponse` in each, or with
|
|
403
|
+
none:
|
|
404
|
+
|
|
405
|
+
```tsp
|
|
406
|
+
@route("/m") @sharedRoute @get op one(): string | Gone;
|
|
407
|
+
@route("/m") @sharedRoute @get op two(): string | Gone;
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
## `Two shared responses named Failure differ: a component is emitted once. Give each its own name, or make them the same.`
|
|
411
|
+
|
|
412
|
+
**When:** `tsp compile`; the error `shared-component-conflict`, for two
|
|
413
|
+
`@sharedResponse` models (or two `@sharedHeader` properties, as `headers`) that
|
|
414
|
+
take one name and do not emit the same response or header.
|
|
415
|
+
|
|
416
|
+
**Why:** a component has one definition, and the emitter will not pick one.
|
|
417
|
+
The first is the component; the other stays inline in the document.
|
|
418
|
+
|
|
419
|
+
**Fix:** give each its own name, or make them one model:
|
|
420
|
+
|
|
421
|
+
```tsp
|
|
422
|
+
@sharedResponse("BadInput") @error model A { @statusCode code: 400; a: string; }
|
|
423
|
+
@sharedResponse("Refused") @error model B { @statusCode code: 400; b: string; }
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
## `Two @pathServer of /users give the server https://a.example.com a description or variables that differ. Give the path one definition of it.`
|
|
427
|
+
|
|
428
|
+
**When:** `tsp compile`; the error `path-server-conflict`. The first definition is emitted.
|
|
429
|
+
|
|
430
|
+
**Why:** operations of one path share its `servers`; the same URL cannot be
|
|
431
|
+
described two ways. The first definition is the one emitted.
|
|
432
|
+
|
|
433
|
+
**Fix:** give every `@pathServer` of that URL on the path the same
|
|
434
|
+
description and variables, or put it on one operation.
|
|
435
|
+
|
|
436
|
+
## `"not ok" is not a name OpenAPI allows for a component: use letters, digits, '.', '_' and '-'.`
|
|
437
|
+
|
|
438
|
+
**When:** `tsp compile`; the error `invalid-component-name`, on a name given to
|
|
439
|
+
`@sharedResponse` or `@sharedHeader` (or a model or property name used as one).
|
|
440
|
+
|
|
441
|
+
**Fix:** pass a name of letters, digits, `.`, `_` and `-`:
|
|
442
|
+
`@sharedResponse("NotOk")`.
|
|
443
|
+
|
|
444
|
+
## `Unauthorized is marked @sharedResponse: emit with @nxgt/typespec, which writes it; @typespec/openapi3 would write it inline or drop it.`
|
|
445
|
+
|
|
446
|
+
**When:** `tsp compile` with `@typespec/openapi3` in `emit`; the error
|
|
447
|
+
`shared-needs-nxgt-emitter` for each `@sharedResponse`, `@sharedHeader` and
|
|
448
|
+
`@pathServer`.
|
|
449
|
+
|
|
450
|
+
**Why:** only the emitter `@nxgt/typespec` reads them: `@typespec/openapi3`
|
|
451
|
+
would write the copies, leak `x-nxgt-component` on a header, or leave out the
|
|
452
|
+
path's `servers`.
|
|
453
|
+
|
|
454
|
+
**Fix:** emit with `@nxgt/typespec` ([The emitter](guide/emitter.md)).
|
|
455
|
+
|
|
364
456
|
## `The emitter @nxgt/typespec runs @typespec/openapi3, which is not installed: add it beside @nxgt/typespec.`
|
|
365
457
|
|
|
366
458
|
**When:** `tsp compile` with `@nxgt/typespec` in `emit`; the error
|
|
@@ -628,12 +720,17 @@ one.
|
|
|
628
720
|
|
|
629
721
|
**Why:** the scalar's pattern checks the shape. A list (`countryCode`,
|
|
630
722
|
`currency`, `timeZone`, `locale`) or a checksum (`iban`, ISBN) does not fit in
|
|
631
|
-
a pattern. `x-nxgt-scalar` names the exact rule,
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
`
|
|
723
|
+
a pattern. `x-nxgt-scalar` names the exact rule, and `@nxgt/openapi-codegen`
|
|
724
|
+
maps it to the `@nxgt/zod` schema only with `scalars: 'exact'`; the default is
|
|
725
|
+
`'pattern'`.
|
|
726
|
+
|
|
727
|
+
**Fix:** generate with
|
|
728
|
+
[`scalars: 'exact'`](https://github.com/softistx/nxgt-http/blob/develop/packages/openapi-codegen/docs/guide/options.md#scalars)
|
|
729
|
+
(`bun add @nxgt/zod`, then `generate({ …, scalars: 'exact' })`): `iban` is
|
|
730
|
+
checked by `ibanSchema`, `countryCode` by its list of assigned codes. If you
|
|
731
|
+
cannot, check the value in the handler against the exact rule, the list or the
|
|
732
|
+
checksum, from `@nxgt/zod` or your own table, and answer `400` as the generated
|
|
733
|
+
validator does:
|
|
637
734
|
|
|
638
735
|
```ts
|
|
639
736
|
if (!knownCountries.has(body.country)) {
|
|
@@ -651,7 +748,8 @@ where `@nxgt/graphql-scalars` refuses it.
|
|
|
651
748
|
tell from `0`. For `nonNegativeInt`, `nonPositiveInt`, `port`, the bound holds,
|
|
652
749
|
so the value passes (`positiveInt` and `negativeInt` refuse it by their bound).
|
|
653
750
|
|
|
654
|
-
**Fix:**
|
|
751
|
+
**Fix:** generate with [`scalars: 'exact'`](https://github.com/softistx/nxgt-http/blob/develop/packages/openapi-codegen/docs/guide/options.md#scalars), whose schemas refuse `-0` for
|
|
752
|
+
an integer scalar. Otherwise normalise in the handler when the sign matters:
|
|
655
753
|
|
|
656
754
|
```ts
|
|
657
755
|
const quantity = Object.is(body.quantity, -0) ? 0 : body.quantity;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import "../dist/index.js";
|
|
2
|
+
|
|
3
|
+
using TypeSpec.Reflection;
|
|
4
|
+
|
|
5
|
+
namespace Nxgt;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Emits a response model once, under `components.responses`, with a `$ref`
|
|
9
|
+
* at each operation that returns it, instead of a full copy at each. The
|
|
10
|
+
* name is the model's unless one is given. Two shared responses of one name
|
|
11
|
+
* that differ are the error `shared-component-conflict`. Only
|
|
12
|
+
* `@nxgt/typespec` writes it: `@typespec/openapi3` would write the copies.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typespec
|
|
16
|
+
* @sharedResponse
|
|
17
|
+
* @error model Unauthorized { @statusCode code: 401; message: string; }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
extern dec sharedResponse(target: Model, name?: valueof string);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Emits a response header once, under `components.headers`, with a `$ref`
|
|
24
|
+
* at each response that carries it. The name is the property's unless one is
|
|
25
|
+
* given. For a response header only; a request header is a parameter.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typespec
|
|
29
|
+
* model NoStore {
|
|
30
|
+
* @sharedHeader("NoStore") @header("cache-control") cacheControl: "no-store";
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
extern dec sharedHeader(target: ModelProperty, name?: valueof string);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Puts `servers` on the path item of the operation: the other paths keep the
|
|
38
|
+
* document's. Repeated on the operations of one path, the servers add up; the
|
|
39
|
+
* same server twice is one, and one URL with two different definitions is the
|
|
40
|
+
* error `path-server-conflict`. The third parameter is `@server`'s: each
|
|
41
|
+
* property is a variable of the URL, its default the variable's `default`
|
|
42
|
+
* and its doc comment the `description`.
|
|
43
|
+
*
|
|
44
|
+
* @param url The server's URL, with `{variable}` placeholders if any.
|
|
45
|
+
* @param description What the server is.
|
|
46
|
+
* @param parameters The URL's variables.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typespec
|
|
50
|
+
* @route("/files")
|
|
51
|
+
* @pathServer("{origin}{basePath}", "Files", {
|
|
52
|
+
* @doc("The server's origin")
|
|
53
|
+
* origin: string = "https://files.example.com",
|
|
54
|
+
* @doc("Where the API is mounted")
|
|
55
|
+
* basePath: string = "/files",
|
|
56
|
+
* })
|
|
57
|
+
* @get op listFiles(): string[];
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
extern dec pathServer(
|
|
61
|
+
target: Operation,
|
|
62
|
+
url: valueof string,
|
|
63
|
+
description?: valueof string,
|
|
64
|
+
parameters?: Record<unknown>
|
|
65
|
+
);
|
package/lib/main.tsp
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/typespec",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -61,8 +61,9 @@
|
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@nxgt/openapi-codegen": "^0.
|
|
64
|
+
"@nxgt/openapi-codegen": "^0.11.0",
|
|
65
65
|
"@nxgt/openapi-hono": "^0.3.3",
|
|
66
|
+
"@nxgt/zod": "^0.1.3",
|
|
66
67
|
"@types/bun": "^1.4.0",
|
|
67
68
|
"@typespec/compiler": "1.17.0",
|
|
68
69
|
"@typespec/http": "1.17.0",
|