@specbook/codegen 0.10.0 → 0.11.1
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/package.json +2 -2
- package/src/browser.ts +1 -0
- package/src/build.ts +30 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@specbook/codegen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Turns an OpenAPI or Swagger document into types, examples, schemas and metadata, in Node or in a browser.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"specbook",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"swagger2openapi": "7.0.8"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@specbook/core": "0.
|
|
47
|
+
"@specbook/core": "0.11.1",
|
|
48
48
|
"@types/node": "24.19.2",
|
|
49
49
|
"@types/swagger2openapi": "7.0.4",
|
|
50
50
|
"typescript": "7.0.2"
|
package/src/browser.ts
CHANGED
package/src/build.ts
CHANGED
|
@@ -73,6 +73,13 @@ interface ExampleDoc {
|
|
|
73
73
|
body?: unknown
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
/** What `docs/<id>.json` says about one response, for the Docs tab. */
|
|
77
|
+
export interface ResponseDoc {
|
|
78
|
+
description?: string
|
|
79
|
+
/** the media type the body is written in, as the spec names it */
|
|
80
|
+
contentType?: string
|
|
81
|
+
}
|
|
82
|
+
|
|
76
83
|
export interface ManifestOperation {
|
|
77
84
|
id: string
|
|
78
85
|
method: string
|
|
@@ -174,6 +181,7 @@ function findJsonLike(content: Record<string, any> | undefined) {
|
|
|
174
181
|
schema: content[mime].schema as Schema | undefined,
|
|
175
182
|
encoding: enc,
|
|
176
183
|
media: content[mime],
|
|
184
|
+
mime,
|
|
177
185
|
}
|
|
178
186
|
}
|
|
179
187
|
const json = Object.keys(content).find((m) => /json/.test(m))
|
|
@@ -182,6 +190,7 @@ function findJsonLike(content: Record<string, any> | undefined) {
|
|
|
182
190
|
schema: content[json].schema as Schema | undefined,
|
|
183
191
|
encoding: 'json',
|
|
184
192
|
media: content[json],
|
|
193
|
+
mime: json,
|
|
185
194
|
}
|
|
186
195
|
const binary = Object.keys(content).find((m) => BINARY_MIME.test(m))
|
|
187
196
|
if (binary)
|
|
@@ -189,6 +198,7 @@ function findJsonLike(content: Record<string, any> | undefined) {
|
|
|
189
198
|
schema: content[binary].schema as Schema | undefined,
|
|
190
199
|
encoding: 'binary',
|
|
191
200
|
media: content[binary],
|
|
201
|
+
mime: binary,
|
|
192
202
|
mediaType: binary,
|
|
193
203
|
}
|
|
194
204
|
// A wildcard stands for whatever the server sends, and a framework that is not told what it produces
|
|
@@ -201,6 +211,7 @@ function findJsonLike(content: Record<string, any> | undefined) {
|
|
|
201
211
|
schema,
|
|
202
212
|
encoding: file ? 'binary' : 'json',
|
|
203
213
|
media: content[any],
|
|
214
|
+
mime: any,
|
|
204
215
|
...(file ? { mediaType: any } : {}),
|
|
205
216
|
}
|
|
206
217
|
}
|
|
@@ -544,6 +555,18 @@ function generateAll(
|
|
|
544
555
|
let defaultSchema: Schema | undefined
|
|
545
556
|
const responseSchemas: Record<string, Schema> = {}
|
|
546
557
|
const mockVariants: NonNullable<ManifestOperation['mockVariants']> = {}
|
|
558
|
+
const responseDocs: Record<string, ResponseDoc> = {}
|
|
559
|
+
let defaultDoc: ResponseDoc | undefined
|
|
560
|
+
const docOf = (res: any, found: { mime?: string } | undefined): ResponseDoc | undefined => {
|
|
561
|
+
const description =
|
|
562
|
+
typeof res?.description === 'string' && res.description.trim()
|
|
563
|
+
? res.description.trim()
|
|
564
|
+
: undefined
|
|
565
|
+
const contentType = found?.mime ?? Object.keys(res?.content ?? {})[0]
|
|
566
|
+
return description || contentType
|
|
567
|
+
? { ...(description ? { description } : {}), ...(contentType ? { contentType } : {}) }
|
|
568
|
+
: undefined
|
|
569
|
+
}
|
|
547
570
|
let defaultVariants: ManifestOperation['mockVariants'] extends infer M
|
|
548
571
|
? M extends Record<string, infer V>
|
|
549
572
|
? V | undefined
|
|
@@ -551,7 +574,9 @@ function generateAll(
|
|
|
551
574
|
: never
|
|
552
575
|
for (const [code, rawRes] of Object.entries<any>(op.responses ?? {})) {
|
|
553
576
|
if (code === 'default') {
|
|
554
|
-
const
|
|
577
|
+
const defaultRes = resolveAny<any>(rawRes)
|
|
578
|
+
const found = findJsonLike(defaultRes?.content)
|
|
579
|
+
defaultDoc = docOf(defaultRes, found)
|
|
555
580
|
if (found?.schema) {
|
|
556
581
|
hasDefault = true
|
|
557
582
|
if (ts) defaultType = tsType(found.schema, ' ', 'T.')
|
|
@@ -569,6 +594,8 @@ function generateAll(
|
|
|
569
594
|
const res = resolveAny<any>(rawRes)
|
|
570
595
|
const found = findJsonLike(res?.content)
|
|
571
596
|
statuses.push(Number(code))
|
|
597
|
+
const responseDoc = docOf(res, found)
|
|
598
|
+
if (responseDoc) responseDocs[code] = responseDoc
|
|
572
599
|
if (found?.schema) responseSchemas[code] = toJsonSchema(found.schema, `${defsId}#/$defs/`)
|
|
573
600
|
if (ts)
|
|
574
601
|
responseTypes.push(
|
|
@@ -587,6 +614,7 @@ function generateAll(
|
|
|
587
614
|
for (const st of DEFAULT_ERROR_STATUSES) {
|
|
588
615
|
if (statuses.includes(st)) continue
|
|
589
616
|
statuses.push(st)
|
|
617
|
+
if (defaultDoc) responseDocs[String(st)] = defaultDoc
|
|
590
618
|
if (defaultSchema) responseSchemas[String(st)] = defaultSchema
|
|
591
619
|
if (defaultVariants) mockVariants[String(st)] = defaultVariants
|
|
592
620
|
if (defaultType) responseTypes.push(`${st}: ${defaultType}`)
|
|
@@ -746,6 +774,7 @@ ${jsdoc({ description: [...new Set([op.summary, op.description].filter(Boolean))
|
|
|
746
774
|
content: `${JSON.stringify({
|
|
747
775
|
...(op.description && op.description !== summary ? { description: op.description } : {}),
|
|
748
776
|
examples: docs.map((d) => ({ name: d.name, title: d.title, source: d.source })),
|
|
777
|
+
...(Object.keys(responseDocs).length ? { responses: responseDocs } : {}),
|
|
749
778
|
})}\n`,
|
|
750
779
|
})
|
|
751
780
|
operations.push({
|