|
7 | 7 | getMetaDescription, |
8 | 8 | isFieldOmitted, |
9 | 9 | isFilterKindIncluded, |
| 10 | + isOperationIncluded, |
10 | 11 | isProcedureIncluded, |
11 | 12 | } from '../common/spec-utils'; |
12 | 13 | import type { OpenApiSpecOptions } from '../common/types'; |
@@ -88,10 +89,16 @@ export class RestApiSpecGenerator<Schema extends SchemaDef = SchemaDef> { |
88 | 89 | const tag = lowerCaseFirst(modelName); |
89 | 90 |
|
90 | 91 | // Collection: GET (list) + POST (create) |
91 | | - paths[`/${modelPath}`] = this.buildCollectionPath(modelName, modelDef, tag) as any; |
| 92 | + const collectionPath = this.buildCollectionPath(modelName, modelDef, tag); |
| 93 | + if (Object.keys(collectionPath).length > 0) { |
| 94 | + paths[`/${modelPath}`] = collectionPath; |
| 95 | + } |
92 | 96 |
|
93 | 97 | // Single resource: GET + PATCH + DELETE |
94 | | - paths[`/${modelPath}/{id}`] = this.buildSinglePath(modelName, tag) as any; |
| 98 | + const singlePath = this.buildSinglePath(modelName, tag); |
| 99 | + if (Object.keys(singlePath).length > 0) { |
| 100 | + paths[`/${modelPath}/{id}`] = singlePath; |
| 101 | + } |
95 | 102 |
|
96 | 103 | // Relation paths |
97 | 104 | for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) { |
@@ -191,69 +198,83 @@ export class RestApiSpecGenerator<Schema extends SchemaDef = SchemaDef> { |
191 | 198 | }, |
192 | 199 | }; |
193 | 200 |
|
194 | | - return { get: listOp, post: createOp }; |
| 201 | + const result: Record<string, any> = {}; |
| 202 | + if (isOperationIncluded(modelName, 'findMany', this.queryOptions)) { |
| 203 | + result['get'] = listOp; |
| 204 | + } |
| 205 | + if (isOperationIncluded(modelName, 'create', this.queryOptions)) { |
| 206 | + result['post'] = createOp; |
| 207 | + } |
| 208 | + return result; |
195 | 209 | } |
196 | 210 |
|
197 | 211 | private buildSinglePath(modelName: string, tag: string): Record<string, any> { |
198 | 212 | const idParam = { $ref: '#/components/parameters/id' }; |
| 213 | + const result: Record<string, any> = {}; |
199 | 214 |
|
200 | | - const getOp = { |
201 | | - tags: [tag], |
202 | | - summary: `Get a ${modelName} resource by ID`, |
203 | | - operationId: `get${modelName}`, |
204 | | - parameters: [idParam, { $ref: '#/components/parameters/include' }], |
205 | | - responses: { |
206 | | - '200': { |
207 | | - description: `${modelName} resource`, |
208 | | - content: { |
209 | | - 'application/vnd.api+json': { |
210 | | - schema: { $ref: `#/components/schemas/${modelName}Response` }, |
| 215 | + if (isOperationIncluded(modelName, 'findUnique', this.queryOptions)) { |
| 216 | + result['get'] = { |
| 217 | + tags: [tag], |
| 218 | + summary: `Get a ${modelName} resource by ID`, |
| 219 | + operationId: `get${modelName}`, |
| 220 | + parameters: [idParam, { $ref: '#/components/parameters/include' }], |
| 221 | + responses: { |
| 222 | + '200': { |
| 223 | + description: `${modelName} resource`, |
| 224 | + content: { |
| 225 | + 'application/vnd.api+json': { |
| 226 | + schema: { $ref: `#/components/schemas/${modelName}Response` }, |
| 227 | + }, |
211 | 228 | }, |
212 | 229 | }, |
| 230 | + '404': { $ref: '#/components/schemas/_errorResponse' }, |
213 | 231 | }, |
214 | | - '404': { $ref: '#/components/schemas/_errorResponse' }, |
215 | | - }, |
216 | | - }; |
| 232 | + }; |
| 233 | + } |
217 | 234 |
|
218 | | - const patchOp = { |
219 | | - tags: [tag], |
220 | | - summary: `Update a ${modelName} resource`, |
221 | | - operationId: `update${modelName}`, |
222 | | - parameters: [idParam], |
223 | | - requestBody: { |
224 | | - required: true, |
225 | | - content: { |
226 | | - 'application/vnd.api+json': { |
227 | | - schema: { $ref: `#/components/schemas/${modelName}UpdateRequest` }, |
228 | | - }, |
229 | | - }, |
230 | | - }, |
231 | | - responses: { |
232 | | - '200': { |
233 | | - description: `Updated ${modelName} resource`, |
| 235 | + if (isOperationIncluded(modelName, 'update', this.queryOptions)) { |
| 236 | + result['patch'] = { |
| 237 | + tags: [tag], |
| 238 | + summary: `Update a ${modelName} resource`, |
| 239 | + operationId: `update${modelName}`, |
| 240 | + parameters: [idParam], |
| 241 | + requestBody: { |
| 242 | + required: true, |
234 | 243 | content: { |
235 | 244 | 'application/vnd.api+json': { |
236 | | - schema: { $ref: `#/components/schemas/${modelName}Response` }, |
| 245 | + schema: { $ref: `#/components/schemas/${modelName}UpdateRequest` }, |
237 | 246 | }, |
238 | 247 | }, |
239 | 248 | }, |
240 | | - '400': { $ref: '#/components/schemas/_errorResponse' }, |
241 | | - '404': { $ref: '#/components/schemas/_errorResponse' }, |
242 | | - }, |
243 | | - }; |
| 249 | + responses: { |
| 250 | + '200': { |
| 251 | + description: `Updated ${modelName} resource`, |
| 252 | + content: { |
| 253 | + 'application/vnd.api+json': { |
| 254 | + schema: { $ref: `#/components/schemas/${modelName}Response` }, |
| 255 | + }, |
| 256 | + }, |
| 257 | + }, |
| 258 | + '400': { $ref: '#/components/schemas/_errorResponse' }, |
| 259 | + '404': { $ref: '#/components/schemas/_errorResponse' }, |
| 260 | + }, |
| 261 | + }; |
| 262 | + } |
244 | 263 |
|
245 | | - const deleteOp = { |
246 | | - tags: [tag], |
247 | | - summary: `Delete a ${modelName} resource`, |
248 | | - operationId: `delete${modelName}`, |
249 | | - parameters: [idParam], |
250 | | - responses: { |
251 | | - '200': { description: 'Deleted successfully' }, |
252 | | - '404': { $ref: '#/components/schemas/_errorResponse' }, |
253 | | - }, |
254 | | - }; |
| 264 | + if (isOperationIncluded(modelName, 'delete', this.queryOptions)) { |
| 265 | + result['delete'] = { |
| 266 | + tags: [tag], |
| 267 | + summary: `Delete a ${modelName} resource`, |
| 268 | + operationId: `delete${modelName}`, |
| 269 | + parameters: [idParam], |
| 270 | + responses: { |
| 271 | + '200': { description: 'Deleted successfully' }, |
| 272 | + '404': { $ref: '#/components/schemas/_errorResponse' }, |
| 273 | + }, |
| 274 | + }; |
| 275 | + } |
255 | 276 |
|
256 | | - return { get: getOp, patch: patchOp, delete: deleteOp }; |
| 277 | + return result; |
257 | 278 | } |
258 | 279 |
|
259 | 280 | private buildFetchRelatedPath( |
@@ -683,6 +704,10 @@ export class RestApiSpecGenerator<Schema extends SchemaDef = SchemaDef> { |
683 | 704 | if (isFieldOmitted(modelName, fieldName, this.queryOptions)) continue; |
684 | 705 |
|
685 | 706 | const schema = this.fieldToSchema(fieldDef); |
| 707 | + const fieldDescription = getMetaDescription(fieldDef.attributes); |
| 708 | + if (fieldDescription && !('$ref' in schema)) { |
| 709 | + schema.description = fieldDescription; |
| 710 | + } |
686 | 711 | properties[fieldName] = schema; |
687 | 712 |
|
688 | 713 | if (!fieldDef.optional && !fieldDef.array) { |
|
0 commit comments