@specbook/codegen 0.9.1 → 0.10.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/package.json +2 -2
- package/src/browser.ts +1 -0
- package/src/build.ts +55 -4
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@specbook/codegen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
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.10.0",
|
|
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
|
@@ -89,9 +89,55 @@ export interface ManifestOperation {
|
|
|
89
89
|
examples: ManifestExample[]
|
|
90
90
|
/** the spec requires credentials for this operation */
|
|
91
91
|
secured?: boolean
|
|
92
|
+
/** any one of these is enough; every scheme in one entry must apply together, with the scopes it needs */
|
|
93
|
+
security?: Record<string, string[]>[]
|
|
92
94
|
file: string
|
|
93
95
|
}
|
|
94
96
|
|
|
97
|
+
/** What a security scheme is, without addresses or descriptions: enough to say how an operation is secured. */
|
|
98
|
+
export interface ManifestSecurityScheme {
|
|
99
|
+
type: string
|
|
100
|
+
in?: string
|
|
101
|
+
name?: string
|
|
102
|
+
scheme?: string
|
|
103
|
+
openIdConnectUrl?: string
|
|
104
|
+
/** flow name -> its scope names */
|
|
105
|
+
flows?: Record<string, { scopes: string[] }>
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** The document's security schemes in the manifest's compact form. */
|
|
109
|
+
export function securitySchemesOf(doc: any): Record<string, ManifestSecurityScheme> {
|
|
110
|
+
const out: Record<string, ManifestSecurityScheme> = {}
|
|
111
|
+
for (const [name, s] of Object.entries<any>(doc.components?.securitySchemes ?? {})) {
|
|
112
|
+
if (!s || typeof s.type !== 'string') continue
|
|
113
|
+
const flows = Object.fromEntries(
|
|
114
|
+
Object.entries<any>(s.flows ?? {}).map(([f, v]) => [
|
|
115
|
+
f,
|
|
116
|
+
{ scopes: Object.keys(v?.scopes ?? {}) },
|
|
117
|
+
]),
|
|
118
|
+
)
|
|
119
|
+
out[name] = {
|
|
120
|
+
type: s.type,
|
|
121
|
+
...(typeof s.in === 'string' ? { in: s.in } : {}),
|
|
122
|
+
...(typeof s.name === 'string' ? { name: s.name } : {}),
|
|
123
|
+
...(typeof s.scheme === 'string' ? { scheme: s.scheme } : {}),
|
|
124
|
+
...(typeof s.openIdConnectUrl === 'string' ? { openIdConnectUrl: s.openIdConnectUrl } : {}),
|
|
125
|
+
...(Object.keys(flows).length ? { flows } : {}),
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return out
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** An operation's requirements as a plain list of `{ scheme: scopes }`. */
|
|
132
|
+
function requirementsFrom(effective: unknown): Record<string, string[]>[] {
|
|
133
|
+
if (!Array.isArray(effective)) return []
|
|
134
|
+
return effective.map((r: any) =>
|
|
135
|
+
Object.fromEntries(
|
|
136
|
+
Object.entries(r ?? {}).map(([k, v]) => [k, Array.isArray(v) ? v.map(String) : []]),
|
|
137
|
+
),
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
95
141
|
/** `info.x-logo` (a Redoc convention): only absolute http(s) or data-image URLs are trusted. */
|
|
96
142
|
export function logoOf(
|
|
97
143
|
info: any,
|
|
@@ -245,7 +291,8 @@ export interface OperationMeta {
|
|
|
245
291
|
mediaType?: string
|
|
246
292
|
files?: string[]
|
|
247
293
|
formArrays?: Record<string, string>
|
|
248
|
-
security
|
|
294
|
+
/** `false` = none required; otherwise any one of the requirements (see `ManifestOperation.security`) */
|
|
295
|
+
security?: false | Record<string, string[]>[]
|
|
249
296
|
}
|
|
250
297
|
|
|
251
298
|
/** The generator proper, from an OpenAPI 3 document that is already parsed and bundled. */
|
|
@@ -643,9 +690,10 @@ function generateAll(
|
|
|
643
690
|
|
|
644
691
|
const effective = op.security ?? doc.security
|
|
645
692
|
const secured = hasSchemes && Array.isArray(effective) && effective.length > 0
|
|
693
|
+
const requirements = requirementsFrom(effective)
|
|
646
694
|
const securityLine = !hasSchemes
|
|
647
695
|
? ''
|
|
648
|
-
: `, security: ${
|
|
696
|
+
: `, security: ${requirements.length > 0 ? JSON.stringify(requirements) : 'false'}`
|
|
649
697
|
// a binary body's declared type (`application/octet-stream`) is what the server expects as Content-Type
|
|
650
698
|
const mediaType =
|
|
651
699
|
body &&
|
|
@@ -673,7 +721,9 @@ function generateAll(
|
|
|
673
721
|
...(mediaType ? { mediaType } : {}),
|
|
674
722
|
...(fileFieldPaths.length ? { files: fileFieldPaths } : {}),
|
|
675
723
|
...(Object.keys(arrayStyles).length ? { formArrays: arrayStyles } : {}),
|
|
676
|
-
...(hasSchemes
|
|
724
|
+
...(hasSchemes
|
|
725
|
+
? { security: requirements.length > 0 ? requirements : (false as const) }
|
|
726
|
+
: {}),
|
|
677
727
|
}
|
|
678
728
|
if (ts)
|
|
679
729
|
files.push({
|
|
@@ -708,7 +758,7 @@ ${jsdoc({ description: [...new Set([op.summary, op.description].filter(Boolean))
|
|
|
708
758
|
statuses,
|
|
709
759
|
...(Object.keys(mockVariants).length ? { mockVariants } : {}),
|
|
710
760
|
examples: docs.map((d) => ({ name: d.name, title: d.title, source: d.source })),
|
|
711
|
-
...(secured ? { secured: true } : {}),
|
|
761
|
+
...(secured ? { secured: true, security: requirements } : {}),
|
|
712
762
|
file: `operations/${id}.ts`,
|
|
713
763
|
})
|
|
714
764
|
}
|
|
@@ -742,6 +792,7 @@ ${jsdoc({ description: [...new Set([op.summary, op.description].filter(Boolean))
|
|
|
742
792
|
version: doc.info?.version,
|
|
743
793
|
...(logoOf(doc.info) ? { logo: logoOf(doc.info) } : {}),
|
|
744
794
|
servers: (doc.servers ?? []).map((s: any) => s.url),
|
|
795
|
+
...(hasSchemes ? { securitySchemes: securitySchemesOf(doc) } : {}),
|
|
745
796
|
tags: [...byTag.keys()],
|
|
746
797
|
operations,
|
|
747
798
|
},
|