zod-openapi 0.0.0-semantically-released → 0.2.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.
Files changed (152) hide show
  1. package/README.md +341 -75
  2. package/lib-commonjs/create/components.js +108 -0
  3. package/lib-commonjs/create/components.js.map +1 -0
  4. package/lib-commonjs/create/content.js +32 -0
  5. package/lib-commonjs/create/content.js.map +1 -0
  6. package/lib-commonjs/create/document.js +28 -0
  7. package/lib-commonjs/create/document.js.map +1 -0
  8. package/lib-commonjs/create/parameters.js +84 -0
  9. package/lib-commonjs/create/parameters.js.map +1 -0
  10. package/lib-commonjs/create/paths.js +68 -0
  11. package/lib-commonjs/create/paths.js.map +1 -0
  12. package/lib-commonjs/create/responses.js +93 -0
  13. package/lib-commonjs/create/responses.js.map +1 -0
  14. package/lib-commonjs/create/schema/array.js +17 -0
  15. package/lib-commonjs/create/schema/array.js.map +1 -0
  16. package/lib-commonjs/create/schema/boolean.js +8 -0
  17. package/lib-commonjs/create/schema/boolean.js.map +1 -0
  18. package/lib-commonjs/create/schema/date.js +8 -0
  19. package/lib-commonjs/create/schema/date.js.map +1 -0
  20. package/lib-commonjs/create/schema/default.js +14 -0
  21. package/lib-commonjs/create/schema/default.js.map +1 -0
  22. package/lib-commonjs/create/schema/discriminatedUnion.js +43 -0
  23. package/lib-commonjs/create/schema/discriminatedUnion.js.map +1 -0
  24. package/lib-commonjs/create/schema/effects.js +7 -0
  25. package/lib-commonjs/create/schema/effects.js.map +1 -0
  26. package/lib-commonjs/create/schema/enum.js +10 -0
  27. package/lib-commonjs/create/schema/enum.js.map +1 -0
  28. package/lib-commonjs/create/schema/index.js +127 -0
  29. package/lib-commonjs/create/schema/index.js.map +1 -0
  30. package/lib-commonjs/create/schema/intersection.js +12 -0
  31. package/lib-commonjs/create/schema/intersection.js.map +1 -0
  32. package/lib-commonjs/create/schema/literal.js +9 -0
  33. package/lib-commonjs/create/schema/literal.js.map +1 -0
  34. package/lib-commonjs/create/schema/metadata.js +38 -0
  35. package/lib-commonjs/create/schema/metadata.js.map +1 -0
  36. package/lib-commonjs/create/schema/nativeEnum.js +35 -0
  37. package/lib-commonjs/create/schema/nativeEnum.js.map +1 -0
  38. package/lib-commonjs/create/schema/null.js +8 -0
  39. package/lib-commonjs/create/schema/null.js.map +1 -0
  40. package/lib-commonjs/create/schema/nullable.js +52 -0
  41. package/lib-commonjs/create/schema/nullable.js.map +1 -0
  42. package/lib-commonjs/create/schema/number.js +28 -0
  43. package/lib-commonjs/create/schema/number.js.map +1 -0
  44. package/lib-commonjs/create/schema/object.js +51 -0
  45. package/lib-commonjs/create/schema/object.js.map +1 -0
  46. package/lib-commonjs/create/schema/optional.js +9 -0
  47. package/lib-commonjs/create/schema/optional.js.map +1 -0
  48. package/lib-commonjs/create/schema/record.js +10 -0
  49. package/lib-commonjs/create/schema/record.js.map +1 -0
  50. package/lib-commonjs/create/schema/string.js +46 -0
  51. package/lib-commonjs/create/schema/string.js.map +1 -0
  52. package/lib-commonjs/create/schema/tuple.js +29 -0
  53. package/lib-commonjs/create/schema/tuple.js.map +1 -0
  54. package/lib-commonjs/create/schema/union.js +13 -0
  55. package/lib-commonjs/create/schema/union.js.map +1 -0
  56. package/lib-commonjs/create/specificationExtension.js +6 -0
  57. package/lib-commonjs/create/specificationExtension.js.map +1 -0
  58. package/lib-commonjs/extendZod.js +49 -0
  59. package/lib-commonjs/extendZod.js.map +1 -0
  60. package/lib-commonjs/index.js +16 -9
  61. package/lib-commonjs/index.js.map +1 -1
  62. package/lib-es2015/create/components.js +102 -0
  63. package/lib-es2015/create/components.js.map +1 -0
  64. package/lib-es2015/create/content.js +28 -0
  65. package/lib-es2015/create/content.js.map +1 -0
  66. package/lib-es2015/create/document.js +22 -0
  67. package/lib-es2015/create/document.js.map +1 -0
  68. package/lib-es2015/create/parameters.js +78 -0
  69. package/lib-es2015/create/parameters.js.map +1 -0
  70. package/lib-es2015/create/paths.js +64 -0
  71. package/lib-es2015/create/paths.js.map +1 -0
  72. package/lib-es2015/create/responses.js +86 -0
  73. package/lib-es2015/create/responses.js.map +1 -0
  74. package/lib-es2015/create/schema/array.js +13 -0
  75. package/lib-es2015/create/schema/array.js.map +1 -0
  76. package/lib-es2015/create/schema/boolean.js +4 -0
  77. package/lib-es2015/create/schema/boolean.js.map +1 -0
  78. package/lib-es2015/create/schema/date.js +4 -0
  79. package/lib-es2015/create/schema/date.js.map +1 -0
  80. package/lib-es2015/create/schema/default.js +10 -0
  81. package/lib-es2015/create/schema/default.js.map +1 -0
  82. package/lib-es2015/create/schema/discriminatedUnion.js +38 -0
  83. package/lib-es2015/create/schema/discriminatedUnion.js.map +1 -0
  84. package/lib-es2015/create/schema/effects.js +3 -0
  85. package/lib-es2015/create/schema/effects.js.map +1 -0
  86. package/lib-es2015/create/schema/enum.js +6 -0
  87. package/lib-es2015/create/schema/enum.js.map +1 -0
  88. package/lib-es2015/create/schema/index.js +121 -0
  89. package/lib-es2015/create/schema/index.js.map +1 -0
  90. package/lib-es2015/create/schema/intersection.js +8 -0
  91. package/lib-es2015/create/schema/intersection.js.map +1 -0
  92. package/lib-es2015/create/schema/literal.js +5 -0
  93. package/lib-es2015/create/schema/literal.js.map +1 -0
  94. package/lib-es2015/create/schema/metadata.js +33 -0
  95. package/lib-es2015/create/schema/metadata.js.map +1 -0
  96. package/lib-es2015/create/schema/nativeEnum.js +29 -0
  97. package/lib-es2015/create/schema/nativeEnum.js.map +1 -0
  98. package/lib-es2015/create/schema/null.js +4 -0
  99. package/lib-es2015/create/schema/null.js.map +1 -0
  100. package/lib-es2015/create/schema/nullable.js +47 -0
  101. package/lib-es2015/create/schema/nullable.js.map +1 -0
  102. package/lib-es2015/create/schema/number.js +24 -0
  103. package/lib-es2015/create/schema/number.js.map +1 -0
  104. package/lib-es2015/create/schema/object.js +43 -0
  105. package/lib-es2015/create/schema/object.js.map +1 -0
  106. package/lib-es2015/create/schema/optional.js +5 -0
  107. package/lib-es2015/create/schema/optional.js.map +1 -0
  108. package/lib-es2015/create/schema/record.js +6 -0
  109. package/lib-es2015/create/schema/record.js.map +1 -0
  110. package/lib-es2015/create/schema/string.js +42 -0
  111. package/lib-es2015/create/schema/string.js.map +1 -0
  112. package/lib-es2015/create/schema/tuple.js +25 -0
  113. package/lib-es2015/create/schema/tuple.js.map +1 -0
  114. package/lib-es2015/create/schema/union.js +9 -0
  115. package/lib-es2015/create/schema/union.js.map +1 -0
  116. package/lib-es2015/create/specificationExtension.js +2 -0
  117. package/lib-es2015/create/specificationExtension.js.map +1 -0
  118. package/lib-es2015/extendZod.js +45 -0
  119. package/lib-es2015/extendZod.js.map +1 -0
  120. package/lib-es2015/index.js +2 -7
  121. package/lib-es2015/index.js.map +1 -1
  122. package/lib-types/create/components.d.ts +33 -0
  123. package/lib-types/create/content.d.ts +4 -0
  124. package/lib-types/create/document.d.ts +62 -0
  125. package/lib-types/create/parameters.d.ts +7 -0
  126. package/lib-types/create/paths.d.ts +4 -0
  127. package/lib-types/create/responses.d.ts +8 -0
  128. package/lib-types/create/schema/array.d.ts +4 -0
  129. package/lib-types/create/schema/boolean.d.ts +3 -0
  130. package/lib-types/create/schema/date.d.ts +3 -0
  131. package/lib-types/create/schema/default.d.ts +4 -0
  132. package/lib-types/create/schema/discriminatedUnion.d.ts +10 -0
  133. package/lib-types/create/schema/effects.d.ts +4 -0
  134. package/lib-types/create/schema/enum.d.ts +3 -0
  135. package/lib-types/create/schema/index.d.ts +6 -0
  136. package/lib-types/create/schema/intersection.d.ts +4 -0
  137. package/lib-types/create/schema/literal.d.ts +3 -0
  138. package/lib-types/create/schema/metadata.d.ts +5 -0
  139. package/lib-types/create/schema/nativeEnum.d.ts +10 -0
  140. package/lib-types/create/schema/null.d.ts +3 -0
  141. package/lib-types/create/schema/nullable.d.ts +5 -0
  142. package/lib-types/create/schema/number.d.ts +3 -0
  143. package/lib-types/create/schema/object.d.ts +8 -0
  144. package/lib-types/create/schema/optional.d.ts +4 -0
  145. package/lib-types/create/schema/record.d.ts +4 -0
  146. package/lib-types/create/schema/string.d.ts +3 -0
  147. package/lib-types/create/schema/tuple.d.ts +4 -0
  148. package/lib-types/create/schema/union.d.ts +4 -0
  149. package/lib-types/create/specificationExtension.d.ts +1 -0
  150. package/lib-types/extendZod.d.ts +36 -0
  151. package/lib-types/index.d.ts +2 -5
  152. package/package.json +14 -7
package/README.md CHANGED
@@ -2,36 +2,354 @@
2
2
 
3
3
  [![Powered by skuba](https://img.shields.io/badge/🤿%20skuba-powered-009DC4)](https://github.com/seek-oss/skuba)
4
4
 
5
- This package is intended to be public on [seek-oss].
6
- To create an internal package,
7
- run `skuba init` and select the `private-npm-package` template.
5
+ A Typescript library to create full OpenAPI 3.1 documentation from Zod Schemas.
8
6
 
9
- Next steps:
7
+ ## API
10
8
 
11
- 1. [ ] Read [SEEK's Open Source RFC].
12
- 2. [ ] Create a new repository in the [seek-oss] GitHub organisation.
13
- 3. [ ] Push local commits to the upstream GitHub branch.
14
- 4. [ ] Configure [GitHub repository settings].
15
- 5. [ ] Keep dependencies up to date with [Renovate];
16
- request installation in [#open-source].
17
- 6. [ ] Delete this checklist 😌.
9
+ ### `extendZodWithOpenApi`
18
10
 
19
- [#open-source]: https://slack.com/app_redirect?channel=C39P1H2SU
20
- [github repository settings]: https://github.com/seek-oss/zod-openapi/settings
21
- [renovate]: https://github.com/apps/renovate
22
- [seek's open source rfc]: https://rfc.skinfra.xyz/RFC016-Open-Source.html
11
+ Mutates Zod with an `.openapi()` method and extra metadata. Make a side-effectful import at the top of your entry point(s).
23
12
 
24
- ## API
13
+ ```typescript
14
+ import { z } from 'zod';
15
+ import { extendZodWithOpenApi } from 'zod-openapi';
16
+
17
+ extendZodWithOpenApi(z);
18
+
19
+ z.string().openapi({ description: 'hello world!', example: 'hello world' });
20
+ ```
21
+
22
+ ### `createDocument`
23
+
24
+ Creates an OpenAPI documentation object
25
+
26
+ ```typescript
27
+ import { z } from 'zod';
28
+ import { createDocument, extendZodWithOpenApi } from 'zod-openapi';
29
+
30
+ extendZodWithOpenApi(z);
31
+
32
+ const jobId = z.string().openapi({
33
+ description: 'Job ID',
34
+ examples: ['12345'],
35
+ });
36
+
37
+ const title = z.string().openapi({
38
+ description: 'Job title',
39
+ examples: ['My job'],
40
+ });
41
+
42
+ const document = createDocument({
43
+ openapi: '3.1.0',
44
+ info: {
45
+ title: 'My API',
46
+ version: '1.0.0',
47
+ },
48
+ paths: {
49
+ '/jobs/{jobId}': {
50
+ put: {
51
+ requestParams: { path: z.object({ jobId }) },
52
+ requestBody: {
53
+ content: {
54
+ 'application/json': { schema: z.object({ title }) },
55
+ },
56
+ },
57
+ responses: {
58
+ '200': {
59
+ description: '200 OK',
60
+ content: {
61
+ 'application/json': { schema: z.object({ jobId, title }) },
62
+ },
63
+ },
64
+ },
65
+ },
66
+ },
67
+ },
68
+ });
69
+ ```
70
+
71
+ Generates the following object:
72
+
73
+ ```json
74
+ {
75
+ "openapi": "3.1.0",
76
+ "info": {
77
+ "title": "My API",
78
+ "version": "1.0.0"
79
+ },
80
+ "paths": {
81
+ "/jobs/{jobId}": {
82
+ "put": {
83
+ "requestBody": {
84
+ "content": {
85
+ "application/json": {
86
+ "schema": {
87
+ "type": "object",
88
+ "properties": {
89
+ "title": {
90
+ "type": "string",
91
+ "description": "Job title",
92
+ "examples": ["My job"]
93
+ }
94
+ },
95
+ "required": ["title"]
96
+ }
97
+ }
98
+ }
99
+ },
100
+ "responses": {
101
+ "200": {
102
+ "description": "200 OK",
103
+ "content": {
104
+ "application/json": {
105
+ "schema": {
106
+ "type": "object",
107
+ "properties": {
108
+ "jobId": {
109
+ "type": "string",
110
+ "description": "Job ID",
111
+ "examples": ["12345"]
112
+ },
113
+ "title": {
114
+ "type": "string",
115
+ "description": "Job title",
116
+ "examples": ["My job"]
117
+ }
118
+ },
119
+ "required": ["jobId", "title"]
120
+ }
121
+ }
122
+ }
123
+ }
124
+ },
125
+ "parameters": [
126
+ {
127
+ "in": "path",
128
+ "name": "jobId",
129
+ "schema": {
130
+ "type": "string",
131
+ "description": "Job ID",
132
+ "examples": ["12345"]
133
+ }
134
+ }
135
+ ]
136
+ }
137
+ }
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### `createDocumentJson`
143
+
144
+ In the background it calls `createDocument` but instead outputs it as a JSON string using `JSON.stringify`. It takes an optional options object as the second parameter which can customize how the JSON string is outputted.
145
+
146
+ ```typescript
147
+ const document = createDocumentJson(
148
+ {
149
+ openapi: '3.1.0',
150
+ info: {
151
+ title: 'My API',
152
+ version: '1.0.0',
153
+ },
154
+ },
155
+ { options: 2 },
156
+ );
157
+ ```
158
+
159
+ ### `createDocumentYaml`
160
+
161
+ In the background it calls `createDocument` but instead outputs it as a YAML string using the [yaml](https://github.com/eemeli/yaml) library. It takes an optional options object as the second parameter which can customize how the YAML string is outputted.
162
+
163
+ ```typescript
164
+ const document = createDocumentYaml(
165
+ {
166
+ openapi: '3.1.0',
167
+ info: {
168
+ title: 'My API',
169
+ version: '1.0.0',
170
+ },
171
+ },
172
+ { options: { uniqueKeys: false } },
173
+ );
174
+ ```
175
+
176
+ ## Usage
177
+
178
+ ### Request Parameters
179
+
180
+ Query, Path, Header & Cookie parameters can be created using the `requestParams` key under the `method` key as follows:
181
+
182
+ ```typescript
183
+ createDocument({
184
+ paths: {
185
+ '/jobs/:a': {
186
+ put: {
187
+ requestParams: {
188
+ path: z.object({ a: z.string() }),
189
+ query: z.object({ b: z.string() }),
190
+ cookie: z.object({ cookie: z.string() }),
191
+ header: z.object({ 'custom-header': z.string() }),
192
+ },
193
+ },
194
+ },
195
+ },
196
+ });
197
+ ```
198
+
199
+ If you would like to declare parameters using OpenAPI syntax you may also declare them using the [parameters](https://swagger.io/docs/specification/describing-parameters/) key. The definitions will then all be combined.
200
+
201
+ ### Request Body
202
+
203
+ Where you would normally declare the [media type](https://swagger.io/docs/specification/media-types/), instead declare the `content` as `application/json` and set the `schema` as your Zod Schema as follows.
204
+
205
+ ```typescript
206
+ createDocument({
207
+ paths: {
208
+ '/jobs': {
209
+ get: {
210
+ requestBody: {
211
+ content: {
212
+ 'application/json': { schema: z.object({ a: z.string() }) },
213
+ },
214
+ },
215
+ },
216
+ },
217
+ },
218
+ });
219
+ ```
220
+
221
+ If you wish to use OpenAPI syntax for your schemas, simply add an OpenAPI schema to the `schema` field instead.
222
+
223
+ ### Responses
224
+
225
+ Similarly to the [Request Body](#request-body), simply set the `schema` as your Zod Schema as follows. You can set the response headers using the `responseHeaders` key.
226
+
227
+ ```typescript
228
+ createDocument({
229
+ paths: {
230
+ '/jobs': {
231
+ get: {
232
+ responses: {
233
+ 200: {
234
+ description: '200 OK',
235
+ content: {
236
+ 'application/json': { schema: z.object({ a: z.string() }) },
237
+ },
238
+ responseHeaders: z.object({
239
+ 'header-key': z.string(),
240
+ }),
241
+ },
242
+ },
243
+ },
244
+ },
245
+ },
246
+ });
247
+ ```
248
+
249
+ ### Creating Components
250
+
251
+ OpenAPI allows you to define reusable [components](https://swagger.io/docs/specification/components/) and this library allows you to replicate that in a simple way.
252
+
253
+ #### Schema
254
+
255
+ If we take the example in `createDocument` and instead create `title` as follows
256
+
257
+ ```typescript
258
+ const title = z.string().openapi({
259
+ description: 'Job title',
260
+ examples: ['My job'],
261
+ ref: 'jobTitle', // <- new field
262
+ });
263
+ ```
264
+
265
+ Wherever `title` is used in schemas across the document, it will instead be created as a reference.
25
266
 
26
- ### `log`
267
+ ```json
268
+ {
269
+ "title": { "$ref": "#/components/schemas/jobTitle" }
270
+ }
271
+ ```
272
+
273
+ `title` will then be outputted as a schema within the components section of the documentation.
274
+
275
+ ```json
276
+ {
277
+ "components": {
278
+ "schemas": {
279
+ "jobTitle": {
280
+ "type": "string",
281
+ "description": "Job title",
282
+ "examples": ["My job"]
283
+ }
284
+ }
285
+ }
286
+ }
287
+ ```
288
+
289
+ This can be an extremely powerful way to generate better Open API documentation. There are some Open API features like [discriminator mapping](https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/) which require all schemas in the union to contain a ref.
290
+
291
+ #### Parameters
27
292
 
28
- Writes the module name to stdout.
29
- Thrilling stuff.
293
+ Query, Path, Header & Cookie parameters can be similarly registered:
30
294
 
31
295
  ```typescript
32
- import { log } from 'zod-openapi';
296
+ const jobId = z.string().openapi({
297
+ description: 'Job ID',
298
+ examples: ['1234'],
299
+ param: { ref: 'jobId' },
300
+ });
301
+ ```
302
+
303
+ #### Response Headers
304
+
305
+ Response headers can be similarly registered:
33
306
 
34
- log();
307
+ ```typescript
308
+ const header = z.string().openapi({
309
+ description: 'Job ID',
310
+ examples: ['1234'],
311
+ header: { ref: 'some-header' },
312
+ });
313
+ ```
314
+
315
+ ## Supported Zod Schema
316
+
317
+ - ZodArray
318
+ - `minItems`/`maxItems` mapping for `.length()`, `.min()`, `.max()`
319
+ - ZodBoolean
320
+ - ZodDate
321
+ - `string` `type` mapping by default
322
+ - ZodDefault
323
+ - ZodDiscriminatedUnion
324
+ - `discriminator` mapping when all schemas in the union contain a `ref`.
325
+ - ZodEffects
326
+ - `pre-process` and `refine` support
327
+ - ZodEnum
328
+ - ZodLiteral
329
+ - ZodNativeEnum
330
+ - supporting `string`, `number` and combined enums.
331
+ - ZodNull
332
+ - ZodNullable
333
+ - ZodNumber
334
+ - `integer` `type` mapping for `.int()`
335
+ - `exclusiveMin`/`min`/`exclusiveMax`/`max` mapping for `.min()`, `.max()`, `lt()`, `gt()`
336
+ - ZodObject
337
+ - ZodOptional
338
+ - ZodRecord
339
+ - ZodString
340
+ - `format` mapping for `.url()`, `.uuid()`, `.email()`, `.datetime()`
341
+ - `minLength`/`maxLength` mapping for `.length()`, `.min()`, `.max()`
342
+ - `pattern` mapping for `.regex()`
343
+ - ZodTuple
344
+ - `items` mapping for `.rest()`
345
+ - ZodUnion
346
+
347
+ If this library cannot determine a type for a Zod Schema, it will throw an error. To avoid this, declare a manual `type` in the `.openapi()` section of that schema.
348
+
349
+ eg.
350
+
351
+ ```typescript
352
+ z.custom().openapi({ type: 'string' });
35
353
  ```
36
354
 
37
355
  ## Development
@@ -71,58 +389,6 @@ yarn build
71
389
  npm pack
72
390
  ```
73
391
 
74
- ## Release
75
-
76
- This package is published to the public npm registry with a GitHub Actions [release workflow].
77
-
78
- The workflow runs on select branches:
79
-
80
- ```yaml
81
- on:
82
- push:
83
- branches:
84
- # add others as necessary
85
- - beta
86
- - master
87
- # - alpha
88
- ```
89
-
90
- It depends on this repo being hosted on [seek-oss] with appropriate access.
91
-
92
- To set up this repo for publishing, follow the instructions in our [OSS npm package guidance].
93
-
94
- ### Commit messages
95
-
96
- This package is published with **[semantic-release]**, which requires a particular commit format to manage semantic versioning.
97
- You can run the interactive `yarn commit` command in place of `git commit` to generate a compliant commit title and message.
98
- If you use the `Squash and merge` option on pull requests, take extra care to format the squashed commit in the GitHub UI before merging.
99
-
100
- ### Releasing latest
101
-
102
- Commits to the `master` branch will be released with the `latest` tag,
103
- which is the default used when running `npm install` or `yarn install`.
104
-
105
- ### Releasing other dist-tags
106
-
107
- **[semantic-release]** prescribes a branch-based workflow for managing [distribution tags].
108
-
109
- You can push to other branches to manage betas, maintenance updates to prior major versions, and more.
110
-
111
- Here are some branches that **semantic-release** supports by default:
112
-
113
- | Git branch | npm dist-tag |
114
- | :--------- | :----------- |
115
- | master | latest |
116
- | alpha | alpha |
117
- | beta | beta |
118
- | next | next |
119
- | 1.x | release-1.x |
120
-
121
- For more information, see the **semantic-release** docs on [triggering a release].
392
+ ## Credits
122
393
 
123
- [distribution tags]: https://docs.npmjs.com/adding-dist-tags-to-packages
124
- [oss npm package guidance]: https://github.com/SEEK-Jobs/seek-oss-ci/blob/master/NPM_PACKAGES.md#access-to-publish-to-npm
125
- [release workflow]: .github/workflows/release.yml
126
- [seek-oss]: https://github.com/seek-oss
127
- [semantic-release]: https://github.com/semantic-release/semantic-release
128
- [triggering a release]: https://github.com/semantic-release/semantic-release/#triggering-a-release
394
+ - [@asteasolutions/zod-to-openapi](https://github.com/asteasolutions/zod-to-openapi) - zod-openapi was created while trying to re-write the wonderful library to support auto registering schemas. However, the underlying structure of the library which consists of tightly coupled classes would not allow for this be done easily. As a result zod-openapi was born with the goal of keeping the Zod Schemas independent from the generation of the documentation.
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createComponents = exports.createComponentSchemaRef = exports.getDefaultComponents = void 0;
4
+ const zod_1 = require("zod");
5
+ const schema_1 = require("./schema");
6
+ const getDefaultComponents = (componentsObject) => {
7
+ const defaultComponents = { schemas: {}, parameters: {}, headers: {} };
8
+ if (!componentsObject) {
9
+ return defaultComponents;
10
+ }
11
+ createSchemas(componentsObject.schemas, defaultComponents);
12
+ createParameters(componentsObject.parameters, defaultComponents);
13
+ createHeaders(componentsObject.headers, defaultComponents);
14
+ return defaultComponents;
15
+ };
16
+ exports.getDefaultComponents = getDefaultComponents;
17
+ const createSchemas = (schemas, components) => {
18
+ if (!schemas) {
19
+ return;
20
+ }
21
+ return Object.entries(schemas).forEach(([key, schema]) => {
22
+ const component = components.schemas[key];
23
+ if (component) {
24
+ throw new Error(`schemaRef "${key}" is already registered`);
25
+ }
26
+ if (schema instanceof zod_1.ZodType) {
27
+ components.schemas[key] = {
28
+ schemaObject: (0, schema_1.createSchemaOrRef)(schema, components),
29
+ zodSchema: schema,
30
+ };
31
+ return;
32
+ }
33
+ components.schemas[key] = {
34
+ schemaObject: schema,
35
+ };
36
+ });
37
+ };
38
+ const createParameters = (parameters, components) => {
39
+ if (!parameters) {
40
+ return;
41
+ }
42
+ return Object.entries(parameters).forEach(([key, schema]) => {
43
+ const component = components.parameters[key];
44
+ if (component) {
45
+ throw new Error(`parameter "${key}" is already registered`);
46
+ }
47
+ components.parameters[key] = {
48
+ paramObject: schema,
49
+ };
50
+ });
51
+ };
52
+ const createHeaders = (headers, components) => {
53
+ if (!headers) {
54
+ return;
55
+ }
56
+ return Object.entries(headers).forEach(([key, schema]) => {
57
+ const component = components.headers[key];
58
+ if (component) {
59
+ throw new Error(`header "${key}" is already registered`);
60
+ }
61
+ components.headers[key] = {
62
+ headerObject: schema,
63
+ };
64
+ });
65
+ };
66
+ const createComponentSchemaRef = (schemaRef) => `#/components/schemas/${schemaRef}`;
67
+ exports.createComponentSchemaRef = createComponentSchemaRef;
68
+ const createComponents = (componentsObject, components) => {
69
+ const schemas = createSchemaComponents(components.schemas);
70
+ const parameters = createParamComponents(components.parameters);
71
+ const headers = createHeaderComponents(components.headers);
72
+ const finalComponents = {
73
+ ...componentsObject,
74
+ ...(schemas && { schemas }),
75
+ ...(parameters && { parameters }),
76
+ ...(headers && { headers }),
77
+ };
78
+ return Object.keys(finalComponents).length ? finalComponents : undefined;
79
+ };
80
+ exports.createComponents = createComponents;
81
+ const createSchemaComponents = (component) => {
82
+ const components = Object.entries(component).reduce((acc, [key, value]) => {
83
+ if (value) {
84
+ acc[key] = value.schemaObject;
85
+ }
86
+ return acc;
87
+ }, {});
88
+ return Object.keys(components).length ? components : undefined;
89
+ };
90
+ const createParamComponents = (component) => {
91
+ const components = Object.entries(component).reduce((acc, [key, value]) => {
92
+ if (value) {
93
+ acc[key] = value.paramObject;
94
+ }
95
+ return acc;
96
+ }, {});
97
+ return Object.keys(components).length ? components : undefined;
98
+ };
99
+ const createHeaderComponents = (component) => {
100
+ const components = Object.entries(component).reduce((acc, [key, value]) => {
101
+ if (value) {
102
+ acc[key] = value.headerObject;
103
+ }
104
+ return acc;
105
+ }, {});
106
+ return Object.keys(components).length ? components : undefined;
107
+ };
108
+ //# sourceMappingURL=components.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../../src/create/components.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createContent = void 0;
4
+ const zod_1 = require("zod");
5
+ const schema_1 = require("./schema");
6
+ const createMediaTypeSchema = (schemaObject, components) => {
7
+ if (!schemaObject) {
8
+ return undefined;
9
+ }
10
+ if (!(schemaObject instanceof zod_1.ZodType)) {
11
+ return schemaObject;
12
+ }
13
+ return (0, schema_1.createSchemaOrRef)(schemaObject, components);
14
+ };
15
+ const createMediaTypeObject = (mediaTypeObject, components) => {
16
+ if (!mediaTypeObject) {
17
+ return undefined;
18
+ }
19
+ return {
20
+ ...mediaTypeObject,
21
+ schema: createMediaTypeSchema(mediaTypeObject.schema, components),
22
+ };
23
+ };
24
+ const createContent = (contentObject, components) => Object.entries(contentObject).reduce((acc, [path, zodOpenApiMediaTypeObject]) => {
25
+ const mediaTypeObject = createMediaTypeObject(zodOpenApiMediaTypeObject, components);
26
+ if (mediaTypeObject) {
27
+ acc[path] = mediaTypeObject;
28
+ }
29
+ return acc;
30
+ }, {});
31
+ exports.createContent = createContent;
32
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/create/content.ts"],"names":[],"mappings":";;;AACA,6BAA4C;AAI5C,qCAA6C;AAE7C,MAAM,qBAAqB,GAAG,CAC5B,YAIa,EACb,UAA4B,EAC4B,EAAE;IAC1D,IAAI,CAAC,YAAY,EAAE;QACjB,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,CAAC,CAAC,YAAY,YAAY,aAAO,CAAC,EAAE;QACtC,OAAO,YAAY,CAAC;KACrB;IAED,OAAO,IAAA,0BAAiB,EAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AACrD,CAAC,CAAC;AAEF,MAAM,qBAAqB,GAAG,CAC5B,eAAsD,EACtD,UAA4B,EACO,EAAE;IACrC,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,SAAS,CAAC;KAClB;IAED,OAAO;QACL,GAAG,eAAe;QAClB,MAAM,EAAE,qBAAqB,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC;KAClE,CAAC;AACJ,CAAC,CAAC;AAEK,MAAM,aAAa,GAAG,CAC3B,aAAsC,EACtC,UAA4B,EACP,EAAE,CACvB,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,MAAM,CAClC,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,yBAAyB,CAAC,EAAuB,EAAE;IAC9D,MAAM,eAAe,GAAG,qBAAqB,CAC3C,yBAAyB,EACzB,UAAU,CACX,CAAC;IAEF,IAAI,eAAe,EAAE;QACnB,GAAG,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC;KAC7B;IACD,OAAO,GAAG,CAAC;AACb,CAAC,EACD,EAAE,CACH,CAAC;AAjBS,QAAA,aAAa,iBAiBtB"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDocumentYaml = exports.createDocumentJson = exports.createDocument = void 0;
4
+ const yaml_1 = require("yaml");
5
+ const components_1 = require("./components");
6
+ const paths_1 = require("./paths");
7
+ const createDocument = (zodOpenApiObject) => {
8
+ const { schemas, parameters, headers, ...rest } = zodOpenApiObject.components ?? {};
9
+ const components = (0, components_1.getDefaultComponents)({ headers, schemas, parameters });
10
+ return {
11
+ ...zodOpenApiObject,
12
+ paths: (0, paths_1.createPaths)(zodOpenApiObject.paths, components),
13
+ webhooks: (0, paths_1.createPaths)(zodOpenApiObject.webhooks, components),
14
+ components: (0, components_1.createComponents)(rest, components),
15
+ };
16
+ };
17
+ exports.createDocument = createDocument;
18
+ const createDocumentJson = (params, jsonOptions) => {
19
+ const document = (0, exports.createDocument)(params);
20
+ return JSON.stringify(document, jsonOptions?.replacer, jsonOptions?.options ?? 2);
21
+ };
22
+ exports.createDocumentJson = createDocumentJson;
23
+ const createDocumentYaml = (params, yamlOptions = {}) => {
24
+ const document = (0, exports.createDocument)(params);
25
+ return (0, yaml_1.stringify)(document, yamlOptions.replacer, yamlOptions.options);
26
+ };
27
+ exports.createDocumentYaml = createDocumentYaml;
28
+ //# sourceMappingURL=document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.js","sourceRoot":"","sources":["../../src/create/document.ts"],"names":[],"mappings":";;;AACA,+BAAiC;AAGjC,6CAAsE;AACtE,mCAAsC;AA+E/B,MAAM,cAAc,GAAG,CAC5B,gBAAkC,EACb,EAAE;IACvB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAC7C,gBAAgB,CAAC,UAAU,IAAI,EAAE,CAAC;IACpC,MAAM,UAAU,GAAG,IAAA,iCAAoB,EAAC,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAE1E,OAAO;QACL,GAAG,gBAAgB;QACnB,KAAK,EAAE,IAAA,mBAAW,EAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC;QACtD,QAAQ,EAAE,IAAA,mBAAW,EAAC,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC;QAC5D,UAAU,EAAE,IAAA,6BAAgB,EAAC,IAAI,EAAE,UAAU,CAAC;KAC/C,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,cAAc,kBAazB;AAEK,MAAM,kBAAkB,GAAG,CAChC,MAAwB,EACxB,WAGC,EACO,EAAE;IACV,MAAM,QAAQ,GAAG,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IACxC,OAAO,IAAI,CAAC,SAAS,CACnB,QAAQ,EACR,WAAW,EAAE,QAAQ,EACrB,WAAW,EAAE,OAAO,IAAI,CAAC,CAC1B,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,kBAAkB,sBAa7B;AAEK,MAAM,kBAAkB,GAAG,CAChC,MAAwB,EACxB,cAGI,EAAE,EACE,EAAE;IACV,MAAM,QAAQ,GAAG,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAC;IACxC,OAAO,IAAA,gBAAS,EAAC,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;AACxE,CAAC,CAAC;AATW,QAAA,kBAAkB,sBAS7B"}