Skip to content

Commit

Permalink
fix: Re-add missing query parameters for shortcut blueprint create
Browse files Browse the repository at this point in the history
Two recent changes (aeda736 and f49fab3) conflicted.

This fix corrects shortcut create blueprints which generate query
parameters from the model schema but did not account for the change
to `required` handling (which ensured required was not enforced
for update blueprints).
  • Loading branch information
danielsharvey authored and theoomoregbee committed Jun 6, 2020
1 parent f49fab3 commit f60e61a
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 5 deletions.
4 changes: 2 additions & 2 deletions lib/generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import forEach from 'lodash/forEach';
import { OpenApi } from '../types/openapi';
import set from 'lodash/set';
import { map, omit, isEqual, reduce } from 'lodash';
import { attributeValidations, resolveRef } from './utils';
import { attributeValidations, resolveRef, unrollSchema } from './utils';


/**
Expand Down Expand Up @@ -478,7 +478,7 @@ export const generatePaths = (routes: SwaggerRouteInfo[], templates: BlueprintAc
if(route.actionType === 'shortcutBlueprint') {
const schema = specification!.components!.schemas?.[route.model!.identity];
if (schema) {
const resolvedSchema = resolveRef(specification, schema);
const resolvedSchema = unrollSchema(specification, schema);
if (resolvedSchema) {
generateSchemaAsQueryParameters(resolvedSchema as OpenApi.UpdatedSchema).map(p => {
if (isParam('query', p.name)) return;
Expand Down
33 changes: 32 additions & 1 deletion lib/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BluePrintAction } from '../interfaces';
import swaggerJSDoc from 'swagger-jsdoc';
import { OpenApi } from '../../types/openapi';
import { get } from 'lodash';
import { get, cloneDeep, defaultsDeep } from 'lodash';
import { Reference } from 'swagger-schema-official';

export const blueprintActions: Array<BluePrintAction> = ['findone', 'find', 'create', 'update', 'destroy', 'populate', 'add', 'remove', 'replace'];
Expand Down Expand Up @@ -73,3 +73,34 @@ export const resolveRef = (specification: OpenApi.OpenApi, obj: (Reference | unk
return obj;

}

/**
* Provides limited dereferencing, or unrolling, of schemas.
*
* Background: The generator `generateSchemas()` produces two variants:
* 1. The `without-required-constraint` variant containing the properties but without
* the specifying required fields (used for update blueprint).
* 2. A primary variant containing an `allOf` union of the variant above
* and the `required` constraint (used for the create blueprint).
*
* This method handles this simple case, resolving references and unrolling
* into a simple cloned schema with directly contained properties.
*
* Otherwise, schema returned as clone but unmodified.
*
* @param specification
* @param schema
*/
export const unrollSchema = (specification: OpenApi.OpenApi, schema: OpenApi.UpdatedSchema | Reference): OpenApi.UpdatedSchema => {

const ret: OpenApi.UpdatedSchema = cloneDeep(resolveRef(specification, schema) as OpenApi.UpdatedSchema);

if(ret.allOf) {
const allOf = ret.allOf;
delete ret.allOf;
allOf.map(s => defaultsDeep(ret, resolveRef(specification, s)));
}

return ret;

}
141 changes: 139 additions & 2 deletions test/fixtures/generatedSwagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -1000,7 +1000,55 @@
"tags": [
"Pet"
],
"parameters": [],
"parameters": [
{
"in": "query",
"name": "petID",
"schema": {
"type": "integer",
"format": "int64",
"uniqueItems": true,
"description": "Note Sails special attributes: autoIncrement",
"readOnly": true
},
"description": "Note Sails special attributes: autoIncrement"
},
{
"in": "query",
"name": "names",
"schema": {
"type": "string",
"example": "Pet's full name"
},
"required": true
},
{
"in": "query",
"name": "owner",
"schema": {
"description": "JSON dictionary representing the **user** instance or FK when creating / updating / not populated",
"oneOf": [
{
"$ref": "#/components/schemas/user"
}
]
},
"description": "JSON dictionary representing the **user** instance or FK when creating / updating / not populated"
},
{
"in": "query",
"name": "caredForBy",
"schema": {
"description": "JSON dictionary representing the **user** instance or FK when creating / updating / not populated",
"oneOf": [
{
"$ref": "#/components/schemas/user"
}
]
},
"description": "JSON dictionary representing the **user** instance or FK when creating / updating / not populated"
}
],
"responses": {
"200": {
"description": "Responds with a JSON dictionary representing the newly created **Pet** instance",
Expand Down Expand Up @@ -1300,7 +1348,96 @@
"User (ORM duplicate)",
"User (ORM)"
],
"parameters": [],
"parameters": [
{
"in": "query",
"name": "id",
"schema": {
"type": "integer",
"format": "int64",
"uniqueItems": true,
"description": "Note Sails special attributes: autoIncrement"
},
"description": "Note Sails special attributes: autoIncrement"
},
{
"in": "query",
"name": "names",
"schema": {
"type": "string",
"example": "First Middle Last"
},
"required": true
},
{
"in": "query",
"name": "email",
"schema": {
"type": "string",
"format": "email",
"description": "Just any old email"
},
"description": "Just any old email"
},
{
"in": "query",
"name": "sex",
"schema": {
"type": "string",
"enum": [
"Male",
"Female"
]
}
},
{
"in": "query",
"name": "ageLimit",
"schema": {
"type": "number",
"format": "double",
"maximum": 100,
"minimum": 15
}
},
{
"in": "query",
"name": "pets",
"schema": {
"description": "Array of **pet**'s or array of FK's when creating / updating / not populated",
"type": "array",
"items": {
"$ref": "#/components/schemas/pet"
}
},
"description": "Array of **pet**'s or array of FK's when creating / updating / not populated"
},
{
"in": "query",
"name": "favouritePet",
"schema": {
"description": "JSON dictionary representing the **pet** instance or FK when creating / updating / not populated",
"oneOf": [
{
"$ref": "#/components/schemas/pet"
}
]
},
"description": "JSON dictionary representing the **pet** instance or FK when creating / updating / not populated"
},
{
"in": "query",
"name": "neighboursPets",
"schema": {
"description": "Array of **pet**'s or array of FK's when creating / updating / not populated",
"type": "array",
"items": {
"$ref": "#/components/schemas/pet"
}
},
"description": "Array of **pet**'s or array of FK's when creating / updating / not populated"
}
],
"responses": {
"200": {
"description": "Responds with a JSON dictionary representing the newly created **User** instance",
Expand Down

0 comments on commit f60e61a

Please sign in to comment.