Skip to content

Commit

Permalink
feat: allow a service to be marked as multipart
Browse files Browse the repository at this point in the history
  • Loading branch information
AshotN committed Jan 17, 2024
1 parent 1211cfe commit 438ec8e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 15 deletions.
4 changes: 2 additions & 2 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ function determineSchemaPrefix (schemas) {
return undefined;
}

exports.createSwaggerServiceOptions = function createSwaggerServiceOptions ({ schemas, docs, transformSchema }) {
const serviceDocs = { schemas: {}, refs: {} };
exports.createSwaggerServiceOptions = function createSwaggerServiceOptions ({ schemas, docs, transformSchema, multipart = false }) {
const serviceDocs = { schemas: {}, refs: {}, multipart };
const transformSchemaFn = transformSchema || exports.defaultTransformSchema;

let unspecificSchemas;
Expand Down
32 changes: 19 additions & 13 deletions lib/v3/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ function filterParameter (refs, ref = 'filterParameter', properties = {}) {
};
}

function jsonSchemaRef (ref) {
function jsonSchemaRef (ref, multipart = false) {
const contentType = multipart ? 'multipart/form-data' : 'application/json';
if (typeof ref === 'object' && ref.refs) {
const { refs, type, ...rest } = ref;

return {
'application/json': {
[contentType]: {
schema: {
[type]: refs.map(innerRef => ({ $ref: `#/components/schemas/${innerRef}` })),
...rest
Expand All @@ -43,7 +44,7 @@ function jsonSchemaRef (ref) {
}

return {
'application/json': {
[contentType]: {
schema: {
$ref: `#/components/schemas/${ref}`
}
Expand Down Expand Up @@ -215,14 +216,15 @@ class OpenApiV3Generator extends AbstractApiGenerator {
security: utils.security('get', securities, security)
};
},
create ({ tags, security, securities, refs, multiOperations }) {
create ({ tags, security, securities, refs, multiOperations, service }) {
const multipart = service.docs.multipart;
const multi = multiOperations.includes('create');
return {
tags,
description: 'Creates a new resource with data.',
requestBody: {
required: true,
content: multi ? jsonSchemaRef(refs.createMultiRequest) : jsonSchemaRef(refs.createRequest)
content: multi ? jsonSchemaRef(refs.createMultiRequest, multipart) : jsonSchemaRef(refs.createRequest, multipart)
},
responses: {
201: {
Expand All @@ -239,14 +241,15 @@ class OpenApiV3Generator extends AbstractApiGenerator {
security: utils.security('create', securities, security)
};
},
update ({ tags, modelName, idName, idType, security, securities, refs }) {
update ({ tags, modelName, idName, idType, security, securities, refs, service }) {
const multipart = service.docs.multipart;
return {
tags,
description: 'Updates the resource identified by id using data.',
parameters: idPathParameters(idName, idType, `ID of ${modelName} to update`),
requestBody: {
required: true,
content: jsonSchemaRef(refs.updateRequest)
content: jsonSchemaRef(refs.updateRequest, multipart)
},
responses: {
200: {
Expand All @@ -266,14 +269,15 @@ class OpenApiV3Generator extends AbstractApiGenerator {
security: utils.security('update', securities, security)
};
},
updateMulti ({ tags, security, securities, refs }) {
updateMulti ({ tags, security, securities, refs, service }) {
const multipart = service.docs.multipart;
return {
tags,
description: 'Updates multiple resources.',
parameters: [],
requestBody: {
required: true,
content: jsonSchemaRef(refs.updateMultiRequest)
content: jsonSchemaRef(refs.updateMultiRequest, multipart)
},
responses: {
200: {
Expand All @@ -290,14 +294,15 @@ class OpenApiV3Generator extends AbstractApiGenerator {
security: utils.security('updateMulti', securities, security)
};
},
patch ({ tags, modelName, idName, idType, security, securities, refs }) {
patch ({ tags, modelName, idName, idType, security, securities, refs, service }) {
const multipart = service.docs.multipart;
return {
tags,
description: 'Updates the resource identified by id using data.',
parameters: idPathParameters(idName, idType, `ID of ${modelName} to update`),
requestBody: {
required: true,
content: jsonSchemaRef(refs.patchRequest)
content: jsonSchemaRef(refs.patchRequest, multipart)
},
responses: {
200: {
Expand All @@ -317,14 +322,15 @@ class OpenApiV3Generator extends AbstractApiGenerator {
security: utils.security('patch', securities, security)
};
},
patchMulti ({ tags, security, securities, refs }) {
patchMulti ({ tags, security, securities, refs, service }) {
const multipart = service.docs.multipart;
return {
tags,
description: 'Updates multiple resources queried by given filters.',
parameters: [filterParameter(refs)],
requestBody: {
required: true,
content: jsonSchemaRef(refs.patchMultiRequest)
content: jsonSchemaRef(refs.patchMultiRequest, multipart)
},
responses: {
200: {
Expand Down
6 changes: 6 additions & 0 deletions test/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ describe('util tests', () => {
});

expect(result).to.deep.equal({
multipart: false,
schemas: {
Message: without$IdAndTypeBoxProperties(messageSchema),
MessageData: without$IdAndTypeBoxProperties(messageDataSchema),
Expand Down Expand Up @@ -245,6 +246,7 @@ describe('util tests', () => {
});

expect(result).to.deep.equal({
multipart: false,
schemas: {
Message: without$IdAndTypeBoxProperties(messageSchema),
MessageData: without$IdAndTypeBoxProperties(messageDataSchema),
Expand Down Expand Up @@ -276,6 +278,7 @@ describe('util tests', () => {
});

expect(result).to.deep.equal({
multipart: false,
description: 'My description',
refs: { createResponse: 'MySchema' },
schemas: {
Expand All @@ -289,6 +292,7 @@ describe('util tests', () => {
const result = createSwaggerServiceOptions({ schemas: { patchRequest: messageDataSchema } });

expect(result).to.deep.equal({
multipart: false,
schemas: {
MessageData: without$IdAndTypeBoxProperties(messageDataSchema)
},
Expand All @@ -302,6 +306,7 @@ describe('util tests', () => {
const result = createSwaggerServiceOptions({ schemas: { getResponse: topicSchema } });

expect(result).to.deep.equal({
multipart: false,
schemas: {
Topic: {
type: 'object',
Expand Down Expand Up @@ -353,6 +358,7 @@ describe('util tests', () => {
});

expect(result).to.deep.equal({
multipart: false,
schemas: {
SimpleIdObject: {
destroyed: true
Expand Down
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ declare namespace feathersSwagger {
},
docs?: ServiceSwaggerOptions,
transformSchema?: (schema: Schema) => Record<string, any>,
multipart?: boolean
}): ServiceSwaggerOptions;

function defaultTransformSchema(schema: Schema): Record<string, any>;
Expand Down

0 comments on commit 438ec8e

Please sign in to comment.