@kubb/adapter-oas 5.0.0-beta.63 → 5.0.0-beta.65

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/src/operation.ts DELETED
@@ -1,194 +0,0 @@
1
- import { SUPPORTED_METHODS } from './constants.ts'
2
- import { isReference } from './guards.ts'
3
- import { isJsonMimeType } from './mime.ts'
4
- import { resolveRef } from './refs.ts'
5
- import type { Document, MediaTypeObject, OperationObject, PathItemObject, ReferenceObject, RequestBodyObject, ResponseObject } from './types.ts'
6
-
7
- /**
8
- * A single OpenAPI operation: its URL path, HTTP method, and the raw operation object.
9
- *
10
- * `schema` is a live reference into the document, so any in-place `$ref` resolution the resolvers
11
- * perform is visible here too.
12
- */
13
- export type Operation = {
14
- path: string
15
- method: string
16
- schema: OperationObject
17
- }
18
-
19
- /**
20
- * The document plus the operation being read. Shared by the request/response accessors so they can
21
- * resolve `$ref`s against the document.
22
- */
23
- type OperationContext = {
24
- document: Document
25
- operation: Operation
26
- }
27
-
28
- /**
29
- * Slugifies a path for the `operationId` fallback: non-alphanumerics collapse to single dashes,
30
- * with no leading or trailing dash.
31
- */
32
- function slugify(value: string): string {
33
- return value
34
- .replace(/[^a-zA-Z0-9]/g, '-')
35
- .replace(/-{2,}/g, '-')
36
- .replace(/^-|-$/g, '')
37
- }
38
-
39
- /**
40
- * Returns the operation's `operationId`, falling back to `<method>_<slugified-path>` when absent.
41
- */
42
- export function getOperationId({ path, method, schema }: Operation): string {
43
- const { operationId } = schema
44
- if (typeof operationId === 'string' && operationId.length > 0) {
45
- return operationId
46
- }
47
- return `${method}_${slugify(path).toLowerCase()}`
48
- }
49
-
50
- /**
51
- * Returns the declared response status codes, skipping `x-` extensions and non-object entries.
52
- */
53
- export function getResponseStatusCodes({ schema }: Operation): Array<string> {
54
- const responses = schema.responses as Record<string, unknown> | undefined
55
- if (!responses || isReference(responses)) {
56
- return []
57
- }
58
- return Object.keys(responses).filter((key) => !key.startsWith('x-') && !!responses[key] && typeof responses[key] === 'object')
59
- }
60
-
61
- /**
62
- * Returns the response object for a status code, resolving a `$ref` in place. `false` when absent.
63
- */
64
- export function getResponseByStatusCode({ document, operation, statusCode }: OperationContext & { statusCode: string | number }): ResponseObject | false {
65
- const responses = operation.schema.responses as Record<string, ResponseObject | ReferenceObject> | undefined
66
- if (!responses || isReference(responses)) {
67
- return false
68
- }
69
- const response = responses[statusCode]
70
- if (!response) {
71
- return false
72
- }
73
- if (isReference(response)) {
74
- const resolved = resolveRef<ResponseObject>(document, response.$ref)
75
- responses[statusCode] = resolved as ResponseObject
76
- if (!resolved || isReference(resolved)) {
77
- return false
78
- }
79
- return resolved
80
- }
81
- return response
82
- }
83
-
84
- /**
85
- * Resolves the request body (dereferencing a `$ref` in place) and returns its content map, or
86
- * `undefined` when the operation has no request body.
87
- */
88
- function getRequestBodyContent({ document, operation }: OperationContext): Record<string, MediaTypeObject> | undefined {
89
- const { schema } = operation
90
- let requestBody = schema.requestBody as RequestBodyObject | ReferenceObject | undefined
91
- if (!requestBody) {
92
- return undefined
93
- }
94
- if (isReference(requestBody)) {
95
- const resolved = resolveRef<RequestBodyObject>(document, requestBody.$ref)
96
- ;(schema as { requestBody?: unknown }).requestBody = resolved
97
- if (!resolved || isReference(resolved)) {
98
- return undefined
99
- }
100
- requestBody = resolved
101
- }
102
- return requestBody.content
103
- }
104
-
105
- /**
106
- * Returns the request body media type. With `mediaType` set, returns that entry or `false`.
107
- * Otherwise picks the first JSON-like media type, then the first declared one, as a
108
- * `[mediaType, object]` tuple.
109
- */
110
- export function getRequestContent({
111
- document,
112
- operation,
113
- mediaType,
114
- }: OperationContext & { mediaType?: string }): MediaTypeObject | false | [string, MediaTypeObject] {
115
- const content = getRequestBodyContent({ document, operation })
116
- if (!content) {
117
- return false
118
- }
119
- if (mediaType) {
120
- return mediaType in content ? content[mediaType]! : false
121
- }
122
- const mediaTypes = Object.keys(content)
123
- const available = mediaTypes.find((mt) => isJsonMimeType(mt)) ?? mediaTypes[0]
124
- return available ? [available, content[available]!] : false
125
- }
126
-
127
- /**
128
- * Returns the primary request content type. Prefers a JSON-like media type (the last one wins
129
- * when several are declared), then the first declared one, defaulting to `'application/json'`.
130
- */
131
- export function getRequestContentType({ document, operation }: OperationContext): string {
132
- const content = getRequestBodyContent({ document, operation })
133
- const mediaTypes = content ? Object.keys(content) : []
134
-
135
- let result = mediaTypes[0] ?? 'application/json'
136
- for (const mt of mediaTypes) {
137
- if (isJsonMimeType(mt)) {
138
- result = mt
139
- }
140
- }
141
- return result
142
- }
143
-
144
- /**
145
- * Builds an `Operation` for every supported HTTP method on every path, in document order.
146
- * `x-` path keys and unresolvable path-item `$ref`s are skipped.
147
- *
148
- * @example
149
- * ```ts
150
- * for (const operation of getOperations(document)) {
151
- * parseOperation(options, operation)
152
- * }
153
- * ```
154
- */
155
- export function getOperations(document: Document): Array<Operation> {
156
- const operations: Array<Operation> = []
157
- const paths = document.paths
158
- if (!paths) {
159
- return operations
160
- }
161
-
162
- for (const path of Object.keys(paths)) {
163
- if (path.startsWith('x-')) {
164
- continue
165
- }
166
-
167
- let pathItem = paths[path] as PathItemObject | ReferenceObject | undefined
168
- if (!pathItem) {
169
- continue
170
- }
171
- if (isReference(pathItem)) {
172
- const resolved = resolveRef<PathItemObject>(document, pathItem.$ref)
173
- ;(paths as Record<string, unknown>)[path] = resolved
174
- if (!resolved || isReference(resolved)) {
175
- continue
176
- }
177
- pathItem = resolved
178
- }
179
-
180
- const item = pathItem as Record<string, unknown>
181
- for (const method of Object.keys(item)) {
182
- if (!SUPPORTED_METHODS.has(method)) {
183
- continue
184
- }
185
- const schema = item[method]
186
- if (!schema || typeof schema !== 'object') {
187
- continue
188
- }
189
- operations.push({ path, method, schema: schema as OperationObject })
190
- }
191
- }
192
-
193
- return operations
194
- }