Fix unauthorized error handling (#6835)
from @BOHEUS comments in #6640 - fix bad 500 error when authentication invalid - remove "id", "createdAt", "updatedAt", etc from creation and update paths schema - improve error message - remove "id" from test body - improve secondaryLink schema description - improve depth parameter description - remove required from response body - improve examples - improve error message formatting - fix filter by position - answered to negative float position @BOHEUS comment Also: - fix secondary field openapi field description - remove schema display in playground Screenshots  
This commit is contained in:
@ -156,7 +156,23 @@ const fieldRatingMock = {
|
|||||||
name: 'fieldRating',
|
name: 'fieldRating',
|
||||||
type: FieldMetadataType.RATING,
|
type: FieldMetadataType.RATING,
|
||||||
isNullable: true,
|
isNullable: true,
|
||||||
defaultValue: null,
|
defaultValue: 'RATING_1',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
id: '9a519a86-422b-4598-88ae-78751353f683',
|
||||||
|
color: 'red',
|
||||||
|
label: 'Opt 1',
|
||||||
|
value: 'RATING_1',
|
||||||
|
position: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '33f28d51-bc82-4e1d-ae4b-d9e4c0ed0ab4',
|
||||||
|
color: 'purple',
|
||||||
|
label: 'Opt 2',
|
||||||
|
value: 'RATING_2',
|
||||||
|
position: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
const fieldPositionMock = {
|
const fieldPositionMock = {
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
import { Controller, Post, Req, Res } from '@nestjs/common';
|
import { Controller, Post, Req, Res, UseGuards } from '@nestjs/common';
|
||||||
|
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
|
||||||
import { RestApiCoreService } from 'src/engine/api/rest/core/rest-api-core.service';
|
import { RestApiCoreService } from 'src/engine/api/rest/core/rest-api-core.service';
|
||||||
import { cleanGraphQLResponse } from 'src/engine/api/rest/utils/clean-graphql-response.utils';
|
import { cleanGraphQLResponse } from 'src/engine/api/rest/utils/clean-graphql-response.utils';
|
||||||
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
|
|
||||||
@Controller('rest/batch/*')
|
@Controller('rest/batch/*')
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
export class RestApiCoreBatchController {
|
export class RestApiCoreBatchController {
|
||||||
constructor(private readonly restApiCoreService: RestApiCoreService) {}
|
constructor(private readonly restApiCoreService: RestApiCoreService) {}
|
||||||
|
|
||||||
|
|||||||
@ -7,14 +7,17 @@ import {
|
|||||||
Put,
|
Put,
|
||||||
Req,
|
Req,
|
||||||
Res,
|
Res,
|
||||||
|
UseGuards,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
|
||||||
import { RestApiCoreService } from 'src/engine/api/rest/core/rest-api-core.service';
|
import { RestApiCoreService } from 'src/engine/api/rest/core/rest-api-core.service';
|
||||||
import { cleanGraphQLResponse } from 'src/engine/api/rest/utils/clean-graphql-response.utils';
|
import { cleanGraphQLResponse } from 'src/engine/api/rest/utils/clean-graphql-response.utils';
|
||||||
|
import { JwtAuthGuard } from 'src/engine/guards/jwt.auth.guard';
|
||||||
|
|
||||||
@Controller('rest/*')
|
@Controller('rest/*')
|
||||||
|
@UseGuards(JwtAuthGuard)
|
||||||
export class RestApiCoreController {
|
export class RestApiCoreController {
|
||||||
constructor(private readonly restApiCoreService: RestApiCoreService) {}
|
constructor(private readonly restApiCoreService: RestApiCoreService) {}
|
||||||
|
|
||||||
|
|||||||
@ -23,12 +23,16 @@ export const formatFieldValue = (
|
|||||||
if (comparator === 'is') {
|
if (comparator === 'is') {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
if (fieldType === FieldMetadataType.NUMBER) {
|
switch (fieldType) {
|
||||||
return parseInt(value);
|
case FieldMetadataType.NUMERIC:
|
||||||
}
|
return parseInt(value);
|
||||||
if (fieldType === FieldMetadataType.BOOLEAN) {
|
case FieldMetadataType.NUMBER:
|
||||||
return value.toLowerCase() === 'true';
|
case FieldMetadataType.POSITION:
|
||||||
|
return parseFloat(value);
|
||||||
|
case FieldMetadataType.BOOLEAN:
|
||||||
|
return value.toLowerCase() === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(value[0] === '"' || value[0] === "'") &&
|
(value[0] === '"' || value[0] === "'") &&
|
||||||
(value.charAt(value.length - 1) === '"' ||
|
(value.charAt(value.length - 1) === '"' ||
|
||||||
|
|||||||
@ -2,22 +2,34 @@ import { BadRequestException } from '@nestjs/common';
|
|||||||
|
|
||||||
import { BaseGraphQLError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
import { BaseGraphQLError } from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||||
|
|
||||||
const formatMessage = (message: BaseGraphQLError) => {
|
const formatMessage = (error: BaseGraphQLError) => {
|
||||||
if (message.extensions) {
|
let formattedMessage = error.extensions
|
||||||
return message.extensions.response.message || message.extensions.response;
|
? error.extensions.response?.error ||
|
||||||
|
error.extensions.response ||
|
||||||
|
error.message
|
||||||
|
: error.error;
|
||||||
|
|
||||||
|
formattedMessage = formattedMessage
|
||||||
|
.replace(/"/g, "'")
|
||||||
|
.replace("Variable '$data' got i", 'I')
|
||||||
|
.replace("Variable '$input' got i", 'I');
|
||||||
|
|
||||||
|
const regex = /Field '[^']+' is not defined by type .*/;
|
||||||
|
|
||||||
|
const match = formattedMessage.match(regex);
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
formattedMessage = match[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
return message.message;
|
return formattedMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class RestApiException extends BadRequestException {
|
export class RestApiException extends BadRequestException {
|
||||||
constructor(errors: BaseGraphQLError[]) {
|
constructor(errors: BaseGraphQLError[]) {
|
||||||
super({
|
super({
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
message:
|
messages: errors.map((error) => formatMessage(error)),
|
||||||
errors.length === 1
|
|
||||||
? formatMessage(errors[0])
|
|
||||||
: JSON.stringify(errors.map((error) => formatMessage(error))),
|
|
||||||
error: 'Bad Request',
|
error: 'Bad Request',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,28 @@
|
|||||||
export const fetchMetadataFields = (objectNamePlural: string) => {
|
export const fetchMetadataFields = (objectNamePlural: string) => {
|
||||||
|
const fromRelations = `
|
||||||
|
toObjectMetadata {
|
||||||
|
id
|
||||||
|
dataSourceId
|
||||||
|
nameSingular
|
||||||
|
namePlural
|
||||||
|
isSystem
|
||||||
|
isRemote
|
||||||
|
}
|
||||||
|
toFieldMetadataId
|
||||||
|
`;
|
||||||
|
|
||||||
|
const toRelations = `
|
||||||
|
fromObjectMetadata {
|
||||||
|
id
|
||||||
|
dataSourceId
|
||||||
|
nameSingular
|
||||||
|
namePlural
|
||||||
|
isSystem
|
||||||
|
isRemote
|
||||||
|
}
|
||||||
|
fromFieldMetadataId
|
||||||
|
`;
|
||||||
|
|
||||||
const fields = `
|
const fields = `
|
||||||
type
|
type
|
||||||
name
|
name
|
||||||
@ -14,26 +38,12 @@ export const fetchMetadataFields = (objectNamePlural: string) => {
|
|||||||
fromRelationMetadata {
|
fromRelationMetadata {
|
||||||
id
|
id
|
||||||
relationType
|
relationType
|
||||||
toObjectMetadata {
|
${fromRelations}
|
||||||
id
|
|
||||||
dataSourceId
|
|
||||||
nameSingular
|
|
||||||
namePlural
|
|
||||||
isSystem
|
|
||||||
}
|
|
||||||
toFieldMetadataId
|
|
||||||
}
|
}
|
||||||
toRelationMetadata {
|
toRelationMetadata {
|
||||||
id
|
id
|
||||||
relationType
|
relationType
|
||||||
fromObjectMetadata {
|
${toRelations}
|
||||||
id
|
|
||||||
dataSourceId
|
|
||||||
nameSingular
|
|
||||||
namePlural
|
|
||||||
isSystem
|
|
||||||
}
|
|
||||||
fromFieldMetadataId
|
|
||||||
}
|
}
|
||||||
defaultValue
|
defaultValue
|
||||||
options
|
options
|
||||||
@ -69,25 +79,10 @@ export const fetchMetadataFields = (objectNamePlural: string) => {
|
|||||||
return fields;
|
return fields;
|
||||||
case 'relations':
|
case 'relations':
|
||||||
return `
|
return `
|
||||||
|
id
|
||||||
relationType
|
relationType
|
||||||
fromObjectMetadata {
|
${fromRelations}
|
||||||
id
|
${toRelations}
|
||||||
dataSourceId
|
|
||||||
nameSingular
|
|
||||||
namePlural
|
|
||||||
isSystem
|
|
||||||
}
|
|
||||||
fromObjectMetadataId
|
|
||||||
toObjectMetadata {
|
|
||||||
id
|
|
||||||
dataSourceId
|
|
||||||
nameSingular
|
|
||||||
namePlural
|
|
||||||
isSystem
|
|
||||||
}
|
|
||||||
toObjectMetadataId
|
|
||||||
fromFieldMetadataId
|
|
||||||
toFieldMetadataId
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -22,7 +22,10 @@ import {
|
|||||||
computeManyResultPath,
|
computeManyResultPath,
|
||||||
computeSingleResultPath,
|
computeSingleResultPath,
|
||||||
} from 'src/engine/core-modules/open-api/utils/path.utils';
|
} from 'src/engine/core-modules/open-api/utils/path.utils';
|
||||||
import { getRequestBody } from 'src/engine/core-modules/open-api/utils/request-body.utils';
|
import {
|
||||||
|
getRequestBody,
|
||||||
|
getUpdateRequestBody,
|
||||||
|
} from 'src/engine/core-modules/open-api/utils/request-body.utils';
|
||||||
import {
|
import {
|
||||||
getCreateOneResponse201,
|
getCreateOneResponse201,
|
||||||
getDeleteResponse200,
|
getDeleteResponse200,
|
||||||
@ -165,7 +168,7 @@ export class OpenApiService {
|
|||||||
summary: `Find One ${item.nameSingular}`,
|
summary: `Find One ${item.nameSingular}`,
|
||||||
parameters: [{ $ref: '#/components/parameters/idPath' }],
|
parameters: [{ $ref: '#/components/parameters/idPath' }],
|
||||||
responses: {
|
responses: {
|
||||||
'200': getFindOneResponse200(item, true),
|
'200': getFindOneResponse200(item),
|
||||||
'400': { $ref: '#/components/responses/400' },
|
'400': { $ref: '#/components/responses/400' },
|
||||||
'401': { $ref: '#/components/responses/401' },
|
'401': { $ref: '#/components/responses/401' },
|
||||||
},
|
},
|
||||||
@ -187,7 +190,7 @@ export class OpenApiService {
|
|||||||
summary: `Update One ${item.nameSingular}`,
|
summary: `Update One ${item.nameSingular}`,
|
||||||
operationId: `updateOne${capitalize(item.nameSingular)}`,
|
operationId: `updateOne${capitalize(item.nameSingular)}`,
|
||||||
parameters: [{ $ref: '#/components/parameters/idPath' }],
|
parameters: [{ $ref: '#/components/parameters/idPath' }],
|
||||||
requestBody: getRequestBody(capitalize(item.nameSingular)),
|
requestBody: getUpdateRequestBody(capitalize(item.nameSingular)),
|
||||||
responses: {
|
responses: {
|
||||||
'200': getUpdateOneResponse200(item, true),
|
'200': getUpdateOneResponse200(item, true),
|
||||||
'400': { $ref: '#/components/responses/400' },
|
'400': { $ref: '#/components/responses/400' },
|
||||||
|
|||||||
@ -22,9 +22,6 @@ describe('computeSchemaComponents', () => {
|
|||||||
).toEqual({
|
).toEqual({
|
||||||
ObjectName: {
|
ObjectName: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
description: undefined,
|
|
||||||
required: ['fieldNumber'],
|
|
||||||
example: { fieldNumber: '' },
|
|
||||||
properties: {
|
properties: {
|
||||||
fieldUuid: {
|
fieldUuid: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -40,9 +37,20 @@ describe('computeSchemaComponents', () => {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'email',
|
format: 'email',
|
||||||
},
|
},
|
||||||
|
fieldEmails: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
primaryEmail: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
additionalEmails: {
|
||||||
|
type: 'object',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
fieldDateTime: {
|
fieldDateTime: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'date',
|
format: 'date-time',
|
||||||
},
|
},
|
||||||
fieldDate: {
|
fieldDate: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -58,21 +66,44 @@ describe('computeSchemaComponents', () => {
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
fieldLinks: {
|
fieldLinks: {
|
||||||
properties: {
|
|
||||||
primaryLinkLabel: { type: 'string' },
|
|
||||||
primaryLinkUrl: { type: 'string' },
|
|
||||||
secondaryLinks: { type: 'object' },
|
|
||||||
},
|
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
primaryLinkLabel: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
primaryLinkUrl: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
secondaryLinks: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
description: 'A secondary link',
|
||||||
|
properties: {
|
||||||
|
url: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fieldCurrency: {
|
fieldCurrency: {
|
||||||
properties: {
|
|
||||||
amountMicros: { type: 'number' },
|
|
||||||
currencyCode: { type: 'string' },
|
|
||||||
},
|
|
||||||
type: 'object',
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
amountMicros: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
currencyCode: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fieldFullName: {
|
fieldFullName: {
|
||||||
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
firstName: {
|
firstName: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -81,10 +112,10 @@ describe('computeSchemaComponents', () => {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type: 'object',
|
|
||||||
},
|
},
|
||||||
fieldRating: {
|
fieldRating: {
|
||||||
type: 'number',
|
type: 'string',
|
||||||
|
enum: ['RATING_1', 'RATING_2'],
|
||||||
},
|
},
|
||||||
fieldSelect: {
|
fieldSelect: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -98,10 +129,23 @@ describe('computeSchemaComponents', () => {
|
|||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
fieldAddress: {
|
fieldAddress: {
|
||||||
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
addressStreet1: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressStreet2: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
addressCity: {
|
addressCity: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
|
addressPostcode: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressState: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
addressCountry: {
|
addressCountry: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
@ -111,20 +155,7 @@ describe('computeSchemaComponents', () => {
|
|||||||
addressLng: {
|
addressLng: {
|
||||||
type: 'number',
|
type: 'number',
|
||||||
},
|
},
|
||||||
addressPostcode: {
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
addressState: {
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
addressStreet1: {
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
addressStreet2: {
|
|
||||||
type: 'string',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
type: 'object',
|
|
||||||
},
|
},
|
||||||
fieldRawJson: {
|
fieldRawJson: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@ -133,9 +164,341 @@ describe('computeSchemaComponents', () => {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
fieldActor: {
|
fieldActor: {
|
||||||
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
source: {
|
source: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
enum: [
|
||||||
|
'EMAIL',
|
||||||
|
'CALENDAR',
|
||||||
|
'WORKFLOW',
|
||||||
|
'API',
|
||||||
|
'IMPORT',
|
||||||
|
'MANUAL',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['fieldNumber'],
|
||||||
|
},
|
||||||
|
'ObjectName for Update': {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
fieldUuid: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
},
|
||||||
|
fieldText: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
fieldPhone: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
fieldEmail: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'email',
|
||||||
|
},
|
||||||
|
fieldEmails: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
primaryEmail: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
additionalEmails: {
|
||||||
|
type: 'object',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldDateTime: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date-time',
|
||||||
|
},
|
||||||
|
fieldDate: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date',
|
||||||
|
},
|
||||||
|
fieldBoolean: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
fieldNumber: {
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
fieldNumeric: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
fieldLinks: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
primaryLinkLabel: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
primaryLinkUrl: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
secondaryLinks: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
description: 'A secondary link',
|
||||||
|
properties: {
|
||||||
|
url: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldCurrency: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
amountMicros: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
currencyCode: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldFullName: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
firstName: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
lastName: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldRating: {
|
||||||
|
type: 'string',
|
||||||
|
enum: ['RATING_1', 'RATING_2'],
|
||||||
|
},
|
||||||
|
fieldSelect: {
|
||||||
|
type: 'string',
|
||||||
|
enum: ['OPTION_1', 'OPTION_2'],
|
||||||
|
},
|
||||||
|
fieldMultiSelect: {
|
||||||
|
type: 'string',
|
||||||
|
enum: ['OPTION_1', 'OPTION_2'],
|
||||||
|
},
|
||||||
|
fieldPosition: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
fieldAddress: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
addressStreet1: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressStreet2: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressCity: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressPostcode: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressState: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressCountry: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressLat: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
addressLng: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldRawJson: {
|
||||||
|
type: 'object',
|
||||||
|
},
|
||||||
|
fieldRichText: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
fieldActor: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
source: {
|
||||||
|
type: 'string',
|
||||||
|
enum: [
|
||||||
|
'EMAIL',
|
||||||
|
'CALENDAR',
|
||||||
|
'WORKFLOW',
|
||||||
|
'API',
|
||||||
|
'IMPORT',
|
||||||
|
'MANUAL',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'ObjectName for Response': {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
fieldUuid: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
},
|
||||||
|
fieldText: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
fieldPhone: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
fieldEmail: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'email',
|
||||||
|
},
|
||||||
|
fieldEmails: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
primaryEmail: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
additionalEmails: {
|
||||||
|
type: 'object',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldDateTime: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date-time',
|
||||||
|
},
|
||||||
|
fieldDate: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date',
|
||||||
|
},
|
||||||
|
fieldBoolean: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
fieldNumber: {
|
||||||
|
type: 'integer',
|
||||||
|
},
|
||||||
|
fieldNumeric: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
fieldLinks: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
primaryLinkLabel: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
primaryLinkUrl: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
secondaryLinks: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
description: 'A secondary link',
|
||||||
|
properties: {
|
||||||
|
url: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldCurrency: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
amountMicros: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
currencyCode: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldFullName: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
firstName: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
lastName: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldRating: {
|
||||||
|
type: 'string',
|
||||||
|
enum: ['RATING_1', 'RATING_2'],
|
||||||
|
},
|
||||||
|
fieldSelect: {
|
||||||
|
type: 'string',
|
||||||
|
enum: ['OPTION_1', 'OPTION_2'],
|
||||||
|
},
|
||||||
|
fieldMultiSelect: {
|
||||||
|
type: 'string',
|
||||||
|
enum: ['OPTION_1', 'OPTION_2'],
|
||||||
|
},
|
||||||
|
fieldPosition: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
fieldAddress: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
addressStreet1: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressStreet2: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressCity: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressPostcode: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressState: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressCountry: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
addressLat: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
addressLng: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fieldRawJson: {
|
||||||
|
type: 'object',
|
||||||
|
},
|
||||||
|
fieldRichText: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
fieldActor: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
source: {
|
||||||
|
type: 'string',
|
||||||
|
enum: [
|
||||||
|
'EMAIL',
|
||||||
|
'CALENDAR',
|
||||||
|
'WORKFLOW',
|
||||||
|
'API',
|
||||||
|
'IMPORT',
|
||||||
|
'MANUAL',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
workspaceMemberId: {
|
workspaceMemberId: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -145,44 +508,15 @@ describe('computeSchemaComponents', () => {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type: 'object',
|
|
||||||
},
|
},
|
||||||
fieldEmails: {
|
fieldRelation: {
|
||||||
properties: {
|
type: 'array',
|
||||||
primaryEmail: {
|
items: {
|
||||||
type: 'string',
|
$ref: '#/components/schemas/ToObjectMetadataName for Response',
|
||||||
},
|
|
||||||
additionalEmails: {
|
|
||||||
type: 'object',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
type: 'object',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'ObjectName with Relations': {
|
|
||||||
allOf: [
|
|
||||||
{
|
|
||||||
$ref: '#/components/schemas/ObjectName',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
properties: {
|
|
||||||
fieldRelation: {
|
|
||||||
type: 'array',
|
|
||||||
items: {
|
|
||||||
$ref: '#/components/schemas/ToObjectMetadataName',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
type: 'object',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
description: undefined,
|
|
||||||
example: {
|
|
||||||
fieldNumber: '',
|
|
||||||
},
|
|
||||||
required: ['fieldNumber'],
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -64,7 +64,10 @@ describe('computeParameters', () => {
|
|||||||
expect(computeDepthParameters()).toEqual({
|
expect(computeDepthParameters()).toEqual({
|
||||||
name: 'depth',
|
name: 'depth',
|
||||||
in: 'query',
|
in: 'query',
|
||||||
description: 'Limits the depth objects returned.',
|
description: `Determines the level of nested related objects to include in the response.
|
||||||
|
- 0: Returns only the primary object's information.
|
||||||
|
- 1: Returns the primary object along with its directly related objects (with no additional nesting for related objects).
|
||||||
|
- 2: Returns the primary object, its directly related objects, and the related objects of those related objects.`,
|
||||||
required: false,
|
required: false,
|
||||||
schema: {
|
schema: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import { OpenAPIV3_1 } from 'openapi-types';
|
import { OpenAPIV3_1 } from 'openapi-types';
|
||||||
|
|
||||||
|
import { FieldMetadataOptions } from 'src/engine/metadata-modules/field-metadata/interfaces/field-metadata-options.interface';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
computeDepthParameters,
|
computeDepthParameters,
|
||||||
computeEndingBeforeParameters,
|
computeEndingBeforeParameters,
|
||||||
@ -10,9 +12,13 @@ import {
|
|||||||
computeStartingAfterParameters,
|
computeStartingAfterParameters,
|
||||||
} from 'src/engine/core-modules/open-api/utils/parameters.utils';
|
} from 'src/engine/core-modules/open-api/utils/parameters.utils';
|
||||||
import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types';
|
import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types';
|
||||||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
import {
|
||||||
|
FieldMetadataEntity,
|
||||||
|
FieldMetadataType,
|
||||||
|
} from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||||
import { capitalize } from 'src/utils/capitalize';
|
import { capitalize } from 'src/utils/capitalize';
|
||||||
|
import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity';
|
||||||
|
|
||||||
type Property = OpenAPIV3_1.SchemaObject;
|
type Property = OpenAPIV3_1.SchemaObject;
|
||||||
|
|
||||||
@ -20,8 +26,33 @@ type Properties = {
|
|||||||
[name: string]: Property;
|
[name: string]: Property;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFieldProperties = (type: FieldMetadataType): Property => {
|
const isFieldAvailable = (field: FieldMetadataEntity, forResponse: boolean) => {
|
||||||
|
if (forResponse) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
switch (field.name) {
|
||||||
|
case 'id':
|
||||||
|
case 'createdAt':
|
||||||
|
case 'updatedAt':
|
||||||
|
case 'deletedAt':
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFieldProperties = (
|
||||||
|
type: FieldMetadataType,
|
||||||
|
propertyName?: string,
|
||||||
|
options?: FieldMetadataOptions,
|
||||||
|
): Property => {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case FieldMetadataType.SELECT:
|
||||||
|
case FieldMetadataType.MULTI_SELECT:
|
||||||
|
return {
|
||||||
|
type: 'string',
|
||||||
|
enum: options?.map((option: { value: string }) => option.value),
|
||||||
|
};
|
||||||
case FieldMetadataType.UUID:
|
case FieldMetadataType.UUID:
|
||||||
return { type: 'string', format: 'uuid' };
|
return { type: 'string', format: 'uuid' };
|
||||||
case FieldMetadataType.TEXT:
|
case FieldMetadataType.TEXT:
|
||||||
@ -31,28 +62,55 @@ const getFieldProperties = (type: FieldMetadataType): Property => {
|
|||||||
case FieldMetadataType.EMAIL:
|
case FieldMetadataType.EMAIL:
|
||||||
return { type: 'string', format: 'email' };
|
return { type: 'string', format: 'email' };
|
||||||
case FieldMetadataType.DATE_TIME:
|
case FieldMetadataType.DATE_TIME:
|
||||||
|
return { type: 'string', format: 'date-time' };
|
||||||
case FieldMetadataType.DATE:
|
case FieldMetadataType.DATE:
|
||||||
return { type: 'string', format: 'date' };
|
return { type: 'string', format: 'date' };
|
||||||
case FieldMetadataType.NUMBER:
|
case FieldMetadataType.NUMBER:
|
||||||
return { type: 'integer' };
|
return { type: 'integer' };
|
||||||
case FieldMetadataType.NUMERIC:
|
|
||||||
case FieldMetadataType.RATING:
|
case FieldMetadataType.RATING:
|
||||||
|
return {
|
||||||
|
type: 'string',
|
||||||
|
enum: options?.map((option: { value: string }) => option.value),
|
||||||
|
};
|
||||||
|
case FieldMetadataType.NUMERIC:
|
||||||
case FieldMetadataType.POSITION:
|
case FieldMetadataType.POSITION:
|
||||||
return { type: 'number' };
|
return { type: 'number' };
|
||||||
case FieldMetadataType.BOOLEAN:
|
case FieldMetadataType.BOOLEAN:
|
||||||
return { type: 'boolean' };
|
return { type: 'boolean' };
|
||||||
case FieldMetadataType.RAW_JSON:
|
case FieldMetadataType.RAW_JSON:
|
||||||
|
if (propertyName === 'secondaryLinks') {
|
||||||
|
return {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'object',
|
||||||
|
description: `A secondary link`,
|
||||||
|
properties: {
|
||||||
|
url: { type: 'string' },
|
||||||
|
label: { type: 'string' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return { type: 'object' };
|
return { type: 'object' };
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return { type: 'string' };
|
return { type: 'string' };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSchemaComponentsProperties = (
|
const getSchemaComponentsProperties = ({
|
||||||
item: ObjectMetadataEntity,
|
item,
|
||||||
): Properties => {
|
forResponse,
|
||||||
|
}: {
|
||||||
|
item: ObjectMetadataEntity;
|
||||||
|
forResponse: boolean;
|
||||||
|
}): Properties => {
|
||||||
return item.fields.reduce((node, field) => {
|
return item.fields.reduce((node, field) => {
|
||||||
if (field.type == FieldMetadataType.RELATION) {
|
if (
|
||||||
|
!isFieldAvailable(field, forResponse) ||
|
||||||
|
field.type === FieldMetadataType.RELATION
|
||||||
|
) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,6 +124,12 @@ const getSchemaComponentsProperties = (
|
|||||||
enum: field.options.map((option: { value: string }) => option.value),
|
enum: field.options.map((option: { value: string }) => option.value),
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
|
case FieldMetadataType.RATING:
|
||||||
|
itemProperty = {
|
||||||
|
type: 'string',
|
||||||
|
enum: field.options.map((option: { value: string }) => option.value),
|
||||||
|
};
|
||||||
|
break;
|
||||||
case FieldMetadataType.LINK:
|
case FieldMetadataType.LINK:
|
||||||
case FieldMetadataType.LINKS:
|
case FieldMetadataType.LINKS:
|
||||||
case FieldMetadataType.CURRENCY:
|
case FieldMetadataType.CURRENCY:
|
||||||
@ -78,7 +142,18 @@ const getSchemaComponentsProperties = (
|
|||||||
properties: compositeTypeDefinitions
|
properties: compositeTypeDefinitions
|
||||||
.get(field.type)
|
.get(field.type)
|
||||||
?.properties?.reduce((properties, property) => {
|
?.properties?.reduce((properties, property) => {
|
||||||
properties[property.name] = getFieldProperties(property.type);
|
if (
|
||||||
|
property.hidden === true ||
|
||||||
|
(property.hidden === 'input' && !forResponse) ||
|
||||||
|
(property.hidden === 'output' && forResponse)
|
||||||
|
) {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
properties[property.name] = getFieldProperties(
|
||||||
|
property.type,
|
||||||
|
property.name,
|
||||||
|
property.options,
|
||||||
|
);
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
}, {} as Properties),
|
}, {} as Properties),
|
||||||
@ -105,19 +180,21 @@ const getSchemaComponentsRelationProperties = (
|
|||||||
item: ObjectMetadataEntity,
|
item: ObjectMetadataEntity,
|
||||||
): Properties => {
|
): Properties => {
|
||||||
return item.fields.reduce((node, field) => {
|
return item.fields.reduce((node, field) => {
|
||||||
|
if (field.type !== FieldMetadataType.RELATION) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
let itemProperty = {} as Property;
|
let itemProperty = {} as Property;
|
||||||
|
|
||||||
if (field.type == FieldMetadataType.RELATION) {
|
if (field.fromRelationMetadata?.toObjectMetadata.nameSingular) {
|
||||||
if (field.fromRelationMetadata?.toObjectMetadata.nameSingular) {
|
itemProperty = {
|
||||||
itemProperty = {
|
type: 'array',
|
||||||
type: 'array',
|
items: {
|
||||||
items: {
|
$ref: `#/components/schemas/${capitalize(
|
||||||
$ref: `#/components/schemas/${capitalize(
|
field.fromRelationMetadata?.toObjectMetadata.nameSingular,
|
||||||
field.fromRelationMetadata?.toObjectMetadata.nameSingular || '',
|
)} for Response`,
|
||||||
)}`,
|
},
|
||||||
},
|
};
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.description) {
|
if (field.description) {
|
||||||
@ -144,62 +221,38 @@ const getRequiredFields = (item: ObjectMetadataEntity): string[] => {
|
|||||||
}, [] as string[]);
|
}, [] as string[]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const computeSchemaComponent = (
|
const computeSchemaComponent = ({
|
||||||
item: ObjectMetadataEntity,
|
item,
|
||||||
): OpenAPIV3_1.SchemaObject => {
|
withRequiredFields,
|
||||||
|
forResponse,
|
||||||
|
withRelations,
|
||||||
|
}: {
|
||||||
|
item: ObjectMetadataEntity;
|
||||||
|
withRequiredFields: boolean;
|
||||||
|
forResponse: boolean;
|
||||||
|
withRelations: boolean;
|
||||||
|
}): OpenAPIV3_1.SchemaObject => {
|
||||||
const result = {
|
const result = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
description: item.description,
|
description: item.description,
|
||||||
properties: getSchemaComponentsProperties(item),
|
properties: getSchemaComponentsProperties({ item, forResponse }),
|
||||||
example: {},
|
|
||||||
} as OpenAPIV3_1.SchemaObject;
|
} as OpenAPIV3_1.SchemaObject;
|
||||||
|
|
||||||
const requiredFields = getRequiredFields(item);
|
if (withRelations) {
|
||||||
|
result.properties = {
|
||||||
if (requiredFields?.length) {
|
...result.properties,
|
||||||
result.required = requiredFields;
|
...getSchemaComponentsRelationProperties(item),
|
||||||
result.example = requiredFields.reduce(
|
};
|
||||||
(example, requiredField) => {
|
|
||||||
example[requiredField] = '';
|
|
||||||
|
|
||||||
return example;
|
|
||||||
},
|
|
||||||
{} as Record<string, string>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
if (!withRequiredFields) {
|
||||||
};
|
return result;
|
||||||
|
}
|
||||||
const computeRelationSchemaComponent = (
|
|
||||||
item: ObjectMetadataEntity,
|
|
||||||
): OpenAPIV3_1.SchemaObject => {
|
|
||||||
const result = {
|
|
||||||
description: item.description,
|
|
||||||
allOf: [
|
|
||||||
{
|
|
||||||
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'object',
|
|
||||||
properties: getSchemaComponentsRelationProperties(item),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
example: {},
|
|
||||||
} as OpenAPIV3_1.SchemaObject;
|
|
||||||
|
|
||||||
const requiredFields = getRequiredFields(item);
|
const requiredFields = getRequiredFields(item);
|
||||||
|
|
||||||
if (requiredFields?.length) {
|
if (requiredFields?.length) {
|
||||||
result.required = requiredFields;
|
result.required = requiredFields;
|
||||||
result.example = requiredFields.reduce(
|
|
||||||
(example, requiredField) => {
|
|
||||||
example[requiredField] = '';
|
|
||||||
|
|
||||||
return example;
|
|
||||||
},
|
|
||||||
{} as Record<string, string>,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -210,9 +263,26 @@ export const computeSchemaComponents = (
|
|||||||
): Record<string, OpenAPIV3_1.SchemaObject> => {
|
): Record<string, OpenAPIV3_1.SchemaObject> => {
|
||||||
return objectMetadataItems.reduce(
|
return objectMetadataItems.reduce(
|
||||||
(schemas, item) => {
|
(schemas, item) => {
|
||||||
schemas[capitalize(item.nameSingular)] = computeSchemaComponent(item);
|
schemas[capitalize(item.nameSingular)] = computeSchemaComponent({
|
||||||
schemas[capitalize(item.nameSingular) + ' with Relations'] =
|
item,
|
||||||
computeRelationSchemaComponent(item);
|
withRequiredFields: true,
|
||||||
|
forResponse: false,
|
||||||
|
withRelations: false,
|
||||||
|
});
|
||||||
|
schemas[capitalize(item.nameSingular) + ' for Update'] =
|
||||||
|
computeSchemaComponent({
|
||||||
|
item,
|
||||||
|
withRequiredFields: false,
|
||||||
|
forResponse: false,
|
||||||
|
withRelations: false,
|
||||||
|
});
|
||||||
|
schemas[capitalize(item.nameSingular) + ' for Response'] =
|
||||||
|
computeSchemaComponent({
|
||||||
|
item,
|
||||||
|
withRequiredFields: false,
|
||||||
|
forResponse: true,
|
||||||
|
withRelations: true,
|
||||||
|
});
|
||||||
|
|
||||||
return schemas;
|
return schemas;
|
||||||
},
|
},
|
||||||
@ -245,21 +315,47 @@ export const computeMetadataSchemaComponents = (
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
description: `An object`,
|
description: `An object`,
|
||||||
properties: {
|
properties: {
|
||||||
dataSourceId: { type: 'string' },
|
|
||||||
nameSingular: { type: 'string' },
|
nameSingular: { type: 'string' },
|
||||||
namePlural: { type: 'string' },
|
namePlural: { type: 'string' },
|
||||||
labelSingular: { type: 'string' },
|
labelSingular: { type: 'string' },
|
||||||
labelPlural: { type: 'string' },
|
labelPlural: { type: 'string' },
|
||||||
description: { type: 'string' },
|
description: { type: 'string' },
|
||||||
icon: { type: 'string' },
|
icon: { type: 'string' },
|
||||||
|
labelIdentifierFieldMetadataId: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
},
|
||||||
|
imageIdentifierFieldMetadataId: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
schemas[`${capitalize(item.namePlural)}`] = {
|
||||||
|
type: 'array',
|
||||||
|
description: `A list of ${item.namePlural}`,
|
||||||
|
items: {
|
||||||
|
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
schemas[`${capitalize(item.nameSingular)} for Update`] = {
|
||||||
|
type: 'object',
|
||||||
|
description: `An object`,
|
||||||
|
properties: {
|
||||||
|
isActive: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
schemas[`${capitalize(item.nameSingular)} for Response`] = {
|
||||||
|
...schemas[`${capitalize(item.nameSingular)}`],
|
||||||
|
properties: {
|
||||||
|
...schemas[`${capitalize(item.nameSingular)}`].properties,
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
dataSourceId: { type: 'string', format: 'uuid' },
|
||||||
isCustom: { type: 'boolean' },
|
isCustom: { type: 'boolean' },
|
||||||
isRemote: { type: 'boolean' },
|
|
||||||
isActive: { type: 'boolean' },
|
isActive: { type: 'boolean' },
|
||||||
isSystem: { type: 'boolean' },
|
isSystem: { type: 'boolean' },
|
||||||
createdAt: { type: 'string' },
|
createdAt: { type: 'string', format: 'date-time' },
|
||||||
updatedAt: { type: 'string' },
|
updatedAt: { type: 'string', format: 'date-time' },
|
||||||
labelIdentifierFieldMetadataId: { type: 'string' },
|
|
||||||
imageIdentifierFieldMetadataId: { type: 'string' },
|
|
||||||
fields: {
|
fields: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
@ -269,7 +365,7 @@ export const computeMetadataSchemaComponents = (
|
|||||||
node: {
|
node: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: {
|
items: {
|
||||||
$ref: '#/components/schemas/Field',
|
$ref: '#/components/schemas/Field for Response',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -277,15 +373,13 @@ export const computeMetadataSchemaComponents = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
example: {},
|
|
||||||
};
|
};
|
||||||
schemas[`${capitalize(item.namePlural)}`] = {
|
schemas[`${capitalize(item.namePlural)} for Response`] = {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
description: `A list of ${item.namePlural}`,
|
description: `A list of ${item.namePlural}`,
|
||||||
items: {
|
items: {
|
||||||
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
$ref: `#/components/schemas/${capitalize(item.nameSingular)} for Response`,
|
||||||
},
|
},
|
||||||
example: [{}],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return schemas;
|
return schemas;
|
||||||
@ -295,57 +389,17 @@ export const computeMetadataSchemaComponents = (
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
description: `A field`,
|
description: `A field`,
|
||||||
properties: {
|
properties: {
|
||||||
type: { type: 'string' },
|
type: {
|
||||||
|
type: 'string',
|
||||||
|
enum: Object.keys(FieldMetadataType),
|
||||||
|
},
|
||||||
name: { type: 'string' },
|
name: { type: 'string' },
|
||||||
label: { type: 'string' },
|
label: { type: 'string' },
|
||||||
description: { type: 'string' },
|
description: { type: 'string' },
|
||||||
icon: { type: 'string' },
|
icon: { type: 'string' },
|
||||||
isCustom: { type: 'boolean' },
|
|
||||||
isActive: { type: 'boolean' },
|
|
||||||
isSystem: { type: 'boolean' },
|
|
||||||
isNullable: { type: 'boolean' },
|
isNullable: { type: 'boolean' },
|
||||||
createdAt: { type: 'string' },
|
objectMetadataId: { type: 'string', format: 'uuid' },
|
||||||
updatedAt: { type: 'string' },
|
|
||||||
fromRelationMetadata: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
id: { type: 'string' },
|
|
||||||
relationType: { type: 'string' },
|
|
||||||
toObjectMetadata: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
id: { type: 'string' },
|
|
||||||
dataSourceId: { type: 'string' },
|
|
||||||
nameSingular: { type: 'string' },
|
|
||||||
namePlural: { type: 'string' },
|
|
||||||
isSystem: { type: 'boolean' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
toFieldMetadataId: { type: 'string' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
toRelationMetadata: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
id: { type: 'string' },
|
|
||||||
relationType: { type: 'string' },
|
|
||||||
fromObjectMetadata: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
id: { type: 'string' },
|
|
||||||
dataSourceId: { type: 'string' },
|
|
||||||
nameSingular: { type: 'string' },
|
|
||||||
namePlural: { type: 'string' },
|
|
||||||
isSystem: { type: 'boolean' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fromFieldMetadataId: { type: 'string' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
defaultValue: { type: 'object' },
|
|
||||||
options: { type: 'object' },
|
|
||||||
},
|
},
|
||||||
example: {},
|
|
||||||
};
|
};
|
||||||
schemas[`${capitalize(item.namePlural)}`] = {
|
schemas[`${capitalize(item.namePlural)}`] = {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
@ -353,7 +407,93 @@ export const computeMetadataSchemaComponents = (
|
|||||||
items: {
|
items: {
|
||||||
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
||||||
},
|
},
|
||||||
example: [{}],
|
};
|
||||||
|
schemas[`${capitalize(item.nameSingular)} for Update`] = {
|
||||||
|
type: 'object',
|
||||||
|
description: `An object`,
|
||||||
|
properties: {
|
||||||
|
description: { type: 'string' },
|
||||||
|
icon: { type: 'string' },
|
||||||
|
isActive: { type: 'boolean' },
|
||||||
|
isCustom: { type: 'boolean' },
|
||||||
|
isNullable: { type: 'boolean' },
|
||||||
|
isSystem: { type: 'boolean' },
|
||||||
|
label: { type: 'string' },
|
||||||
|
name: { type: 'string' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
schemas[`${capitalize(item.nameSingular)} for Response`] = {
|
||||||
|
...schemas[`${capitalize(item.nameSingular)}`],
|
||||||
|
properties: {
|
||||||
|
type: {
|
||||||
|
type: 'string',
|
||||||
|
enum: Object.keys(FieldMetadataType),
|
||||||
|
},
|
||||||
|
name: { type: 'string' },
|
||||||
|
label: { type: 'string' },
|
||||||
|
description: { type: 'string' },
|
||||||
|
icon: { type: 'string' },
|
||||||
|
isNullable: { type: 'boolean' },
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
isCustom: { type: 'boolean' },
|
||||||
|
isActive: { type: 'boolean' },
|
||||||
|
isSystem: { type: 'boolean' },
|
||||||
|
defaultValue: { type: 'object' },
|
||||||
|
options: { type: 'object' },
|
||||||
|
createdAt: { type: 'string', format: 'date-time' },
|
||||||
|
updatedAt: { type: 'string', format: 'date-time' },
|
||||||
|
fromRelationMetadata: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
relationType: {
|
||||||
|
type: 'string',
|
||||||
|
enum: Object.keys(RelationMetadataType),
|
||||||
|
},
|
||||||
|
toObjectMetadata: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
dataSourceId: { type: 'string', format: 'uuid' },
|
||||||
|
nameSingular: { type: 'string' },
|
||||||
|
namePlural: { type: 'string' },
|
||||||
|
isSystem: { type: 'boolean' },
|
||||||
|
isRemote: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
toFieldMetadataId: { type: 'string', format: 'uuid' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
toRelationMetadata: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
relationType: {
|
||||||
|
type: 'string',
|
||||||
|
enum: Object.keys(RelationMetadataType),
|
||||||
|
},
|
||||||
|
fromObjectMetadata: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
dataSourceId: { type: 'string', format: 'uuid' },
|
||||||
|
nameSingular: { type: 'string' },
|
||||||
|
namePlural: { type: 'string' },
|
||||||
|
isSystem: { type: 'boolean' },
|
||||||
|
isRemote: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fromFieldMetadataId: { type: 'string', format: 'uuid' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
schemas[`${capitalize(item.namePlural)} for Response`] = {
|
||||||
|
type: 'array',
|
||||||
|
description: `A list of ${item.namePlural}`,
|
||||||
|
items: {
|
||||||
|
$ref: `#/components/schemas/${capitalize(item.nameSingular)} for Response`,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
return schemas;
|
return schemas;
|
||||||
@ -363,33 +503,17 @@ export const computeMetadataSchemaComponents = (
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
description: 'A relation',
|
description: 'A relation',
|
||||||
properties: {
|
properties: {
|
||||||
relationType: { type: 'string' },
|
relationType: {
|
||||||
fromObjectMetadata: {
|
type: 'string',
|
||||||
type: 'object',
|
enum: Object.keys(RelationMetadataType),
|
||||||
properties: {
|
|
||||||
id: { type: 'string' },
|
|
||||||
dataSourceId: { type: 'string' },
|
|
||||||
nameSingular: { type: 'string' },
|
|
||||||
namePlural: { type: 'string' },
|
|
||||||
isSystem: { type: 'boolean' },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
fromObjectMetadataId: { type: 'string' },
|
fromObjectMetadataId: { type: 'string', format: 'uuid' },
|
||||||
toObjectMetadata: {
|
toObjectMetadataId: { type: 'string', format: 'uuid' },
|
||||||
type: 'object',
|
fromName: { type: 'string' },
|
||||||
properties: {
|
fromLabel: { type: 'string' },
|
||||||
id: { type: 'string' },
|
toName: { type: 'string' },
|
||||||
dataSourceId: { type: 'string' },
|
toLabel: { type: 'string' },
|
||||||
nameSingular: { type: 'string' },
|
|
||||||
namePlural: { type: 'string' },
|
|
||||||
isSystem: { type: 'boolean' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
toObjectMetadataId: { type: 'string' },
|
|
||||||
fromFieldMetadataId: { type: 'string' },
|
|
||||||
toFieldMetadataId: { type: 'string' },
|
|
||||||
},
|
},
|
||||||
example: {},
|
|
||||||
};
|
};
|
||||||
schemas[`${capitalize(item.namePlural)}`] = {
|
schemas[`${capitalize(item.namePlural)}`] = {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
@ -397,7 +521,47 @@ export const computeMetadataSchemaComponents = (
|
|||||||
items: {
|
items: {
|
||||||
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
||||||
},
|
},
|
||||||
example: [{}],
|
};
|
||||||
|
schemas[`${capitalize(item.nameSingular)} for Response`] = {
|
||||||
|
...schemas[`${capitalize(item.nameSingular)}`],
|
||||||
|
properties: {
|
||||||
|
relationType: {
|
||||||
|
type: 'string',
|
||||||
|
enum: Object.keys(RelationMetadataType),
|
||||||
|
},
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
fromFieldMetadataId: { type: 'string', format: 'uuid' },
|
||||||
|
toFieldMetadataId: { type: 'string', format: 'uuid' },
|
||||||
|
fromObjectMetadata: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
dataSourceId: { type: 'string', format: 'uuid' },
|
||||||
|
nameSingular: { type: 'string' },
|
||||||
|
namePlural: { type: 'string' },
|
||||||
|
isSystem: { type: 'boolean' },
|
||||||
|
isRemote: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
toObjectMetadata: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: { type: 'string', format: 'uuid' },
|
||||||
|
dataSourceId: { type: 'string', format: 'uuid' },
|
||||||
|
nameSingular: { type: 'string' },
|
||||||
|
namePlural: { type: 'string' },
|
||||||
|
isSystem: { type: 'boolean' },
|
||||||
|
isRemote: { type: 'boolean' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
schemas[`${capitalize(item.namePlural)} for Response`] = {
|
||||||
|
type: 'array',
|
||||||
|
description: `A list of ${item.namePlural}`,
|
||||||
|
items: {
|
||||||
|
$ref: `#/components/schemas/${capitalize(item.nameSingular)} for Response`,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export const get400ErrorResponses = (): OpenAPIV3_1.ResponseObject => {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
statusCode: { type: 'number' },
|
statusCode: { type: 'number' },
|
||||||
message: { type: 'string' },
|
messages: { type: 'array', items: { type: 'string' } },
|
||||||
error: { type: 'string' },
|
error: { type: 'string' },
|
||||||
},
|
},
|
||||||
example: {
|
example: {
|
||||||
|
|||||||
@ -55,7 +55,10 @@ export const computeDepthParameters = (): OpenAPIV3_1.ParameterObject => {
|
|||||||
return {
|
return {
|
||||||
name: 'depth',
|
name: 'depth',
|
||||||
in: 'query',
|
in: 'query',
|
||||||
description: 'Limits the depth objects returned.',
|
description: `Determines the level of nested related objects to include in the response.
|
||||||
|
- 0: Returns only the primary object's information.
|
||||||
|
- 1: Returns the primary object along with its directly related objects (with no additional nesting for related objects).
|
||||||
|
- 2: Returns the primary object, its directly related objects, and the related objects of those related objects.`,
|
||||||
required: false,
|
required: false,
|
||||||
schema: {
|
schema: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
getArrayRequestBody,
|
getArrayRequestBody,
|
||||||
getFindDuplicatesRequestBody,
|
getFindDuplicatesRequestBody,
|
||||||
getRequestBody,
|
getRequestBody,
|
||||||
|
getUpdateRequestBody,
|
||||||
} from 'src/engine/core-modules/open-api/utils/request-body.utils';
|
} from 'src/engine/core-modules/open-api/utils/request-body.utils';
|
||||||
import {
|
import {
|
||||||
getCreateManyResponse201,
|
getCreateManyResponse201,
|
||||||
@ -113,7 +114,7 @@ export const computeSingleResultPath = (
|
|||||||
{ $ref: '#/components/parameters/idPath' },
|
{ $ref: '#/components/parameters/idPath' },
|
||||||
{ $ref: '#/components/parameters/depth' },
|
{ $ref: '#/components/parameters/depth' },
|
||||||
],
|
],
|
||||||
requestBody: getRequestBody(capitalize(item.nameSingular)),
|
requestBody: getUpdateRequestBody(capitalize(item.nameSingular)),
|
||||||
responses: {
|
responses: {
|
||||||
'200': getUpdateOneResponse200(item),
|
'200': getUpdateOneResponse200(item),
|
||||||
'400': { $ref: '#/components/responses/400' },
|
'400': { $ref: '#/components/responses/400' },
|
||||||
|
|||||||
@ -12,6 +12,20 @@ export const getRequestBody = (name: string) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getUpdateRequestBody = (name: string) => {
|
||||||
|
return {
|
||||||
|
description: 'body',
|
||||||
|
required: true,
|
||||||
|
content: {
|
||||||
|
'application/json': {
|
||||||
|
schema: {
|
||||||
|
$ref: `#/components/schemas/${name} for Update`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const getArrayRequestBody = (name: string) => {
|
export const getArrayRequestBody = (name: string) => {
|
||||||
return {
|
return {
|
||||||
required: true,
|
required: true,
|
||||||
@ -45,10 +59,6 @@ export const getFindDuplicatesRequestBody = (name: string) => {
|
|||||||
},
|
},
|
||||||
ids: {
|
ids: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: {
|
|
||||||
type: 'string',
|
|
||||||
format: 'uuid',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,6 +5,10 @@ export const getFindManyResponse200 = (
|
|||||||
item: Pick<ObjectMetadataEntity, 'nameSingular' | 'namePlural'>,
|
item: Pick<ObjectMetadataEntity, 'nameSingular' | 'namePlural'>,
|
||||||
fromMetadata = false,
|
fromMetadata = false,
|
||||||
) => {
|
) => {
|
||||||
|
const schemaRef = `#/components/schemas/${capitalize(
|
||||||
|
item.nameSingular,
|
||||||
|
)} for Response`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: 'Successful operation',
|
description: 'Successful operation',
|
||||||
content: {
|
content: {
|
||||||
@ -18,9 +22,7 @@ export const getFindManyResponse200 = (
|
|||||||
[item.namePlural]: {
|
[item.namePlural]: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: {
|
items: {
|
||||||
$ref: `#/components/schemas/${capitalize(
|
$ref: schemaRef,
|
||||||
item.nameSingular,
|
|
||||||
)}${!fromMetadata ? ' with Relations' : ''}`,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -29,8 +31,14 @@ export const getFindManyResponse200 = (
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
hasNextPage: { type: 'boolean' },
|
hasNextPage: { type: 'boolean' },
|
||||||
startCursor: { type: 'string' },
|
startCursor: {
|
||||||
endCursor: { type: 'string' },
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
},
|
||||||
|
endCursor: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...(!fromMetadata && {
|
...(!fromMetadata && {
|
||||||
@ -39,21 +47,6 @@ export const getFindManyResponse200 = (
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
example: {
|
|
||||||
data: {
|
|
||||||
[item.namePlural]: [
|
|
||||||
`${capitalize(item.nameSingular)}Object1`,
|
|
||||||
`${capitalize(item.nameSingular)}Object2`,
|
|
||||||
'...',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
pageInfo: {
|
|
||||||
hasNextPage: true,
|
|
||||||
startCursor: '56f411fb-0900-4ffb-b942-d7e8d6709eff',
|
|
||||||
endCursor: '93adf3c6-6cf7-4a86-adcd-75f77857ba67',
|
|
||||||
},
|
|
||||||
totalCount: 132,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -62,8 +55,9 @@ export const getFindManyResponse200 = (
|
|||||||
|
|
||||||
export const getFindOneResponse200 = (
|
export const getFindOneResponse200 = (
|
||||||
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
|
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
|
||||||
fromMetadata = false,
|
|
||||||
) => {
|
) => {
|
||||||
|
const schemaRef = `#/components/schemas/${capitalize(item.nameSingular)} for Response`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: 'Successful operation',
|
description: 'Successful operation',
|
||||||
content: {
|
content: {
|
||||||
@ -75,18 +69,11 @@ export const getFindOneResponse200 = (
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
[item.nameSingular]: {
|
[item.nameSingular]: {
|
||||||
$ref: `#/components/schemas/${capitalize(item.nameSingular)}${
|
$ref: schemaRef,
|
||||||
!fromMetadata ? ' with Relations' : ''
|
|
||||||
}`,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
example: {
|
|
||||||
data: {
|
|
||||||
[item.nameSingular]: `${capitalize(item.nameSingular)}Object`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -98,6 +85,7 @@ export const getCreateOneResponse201 = (
|
|||||||
fromMetadata = false,
|
fromMetadata = false,
|
||||||
) => {
|
) => {
|
||||||
const one = fromMetadata ? 'One' : '';
|
const one = fromMetadata ? 'One' : '';
|
||||||
|
const schemaRef = `#/components/schemas/${capitalize(item.nameSingular)} for Response`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: 'Successful operation',
|
description: 'Successful operation',
|
||||||
@ -110,18 +98,11 @@ export const getCreateOneResponse201 = (
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
[`create${one}${capitalize(item.nameSingular)}`]: {
|
[`create${one}${capitalize(item.nameSingular)}`]: {
|
||||||
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
$ref: schemaRef,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
example: {
|
|
||||||
data: {
|
|
||||||
[`create${one}${capitalize(item.nameSingular)}`]: `${capitalize(
|
|
||||||
item.nameSingular,
|
|
||||||
)}Object`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -131,6 +112,10 @@ export const getCreateOneResponse201 = (
|
|||||||
export const getCreateManyResponse201 = (
|
export const getCreateManyResponse201 = (
|
||||||
item: Pick<ObjectMetadataEntity, 'nameSingular' | 'namePlural'>,
|
item: Pick<ObjectMetadataEntity, 'nameSingular' | 'namePlural'>,
|
||||||
) => {
|
) => {
|
||||||
|
const schemaRef = `#/components/schemas/${capitalize(
|
||||||
|
item.nameSingular,
|
||||||
|
)} for Response`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: 'Successful operation',
|
description: 'Successful operation',
|
||||||
content: {
|
content: {
|
||||||
@ -144,23 +129,12 @@ export const getCreateManyResponse201 = (
|
|||||||
[`create${capitalize(item.namePlural)}`]: {
|
[`create${capitalize(item.namePlural)}`]: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: {
|
items: {
|
||||||
$ref: `#/components/schemas/${capitalize(
|
$ref: schemaRef,
|
||||||
item.nameSingular,
|
|
||||||
)}`,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
example: {
|
|
||||||
data: {
|
|
||||||
[`create${capitalize(item.namePlural)}`]: [
|
|
||||||
`${capitalize(item.nameSingular)}Object1`,
|
|
||||||
`${capitalize(item.nameSingular)}Object2`,
|
|
||||||
'...',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -172,6 +146,7 @@ export const getUpdateOneResponse200 = (
|
|||||||
fromMetadata = false,
|
fromMetadata = false,
|
||||||
) => {
|
) => {
|
||||||
const one = fromMetadata ? 'One' : '';
|
const one = fromMetadata ? 'One' : '';
|
||||||
|
const schemaRef = `#/components/schemas/${capitalize(item.nameSingular)} for Response`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: 'Successful operation',
|
description: 'Successful operation',
|
||||||
@ -184,18 +159,11 @@ export const getUpdateOneResponse200 = (
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
[`update${one}${capitalize(item.nameSingular)}`]: {
|
[`update${one}${capitalize(item.nameSingular)}`]: {
|
||||||
$ref: `#/components/schemas/${capitalize(item.nameSingular)}`,
|
$ref: schemaRef,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
example: {
|
|
||||||
data: {
|
|
||||||
[`update${one}${capitalize(item.nameSingular)}`]: `${capitalize(
|
|
||||||
item.nameSingular,
|
|
||||||
)}Object`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -230,13 +198,6 @@ export const getDeleteResponse200 = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
example: {
|
|
||||||
data: {
|
|
||||||
[`delete${one}${capitalize(item.nameSingular)}`]: {
|
|
||||||
id: 'ffe75ac3-9786-4846-b56f-640685c3631e',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -302,6 +263,10 @@ export const getJsonResponse = () => {
|
|||||||
export const getFindDuplicatesResponse200 = (
|
export const getFindDuplicatesResponse200 = (
|
||||||
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
|
item: Pick<ObjectMetadataEntity, 'nameSingular'>,
|
||||||
) => {
|
) => {
|
||||||
|
const schemaRef = `#/components/schemas/${capitalize(
|
||||||
|
item.nameSingular,
|
||||||
|
)} for Response`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
description: 'Successful operation',
|
description: 'Successful operation',
|
||||||
content: {
|
content: {
|
||||||
@ -319,16 +284,20 @@ export const getFindDuplicatesResponse200 = (
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
hasNextPage: { type: 'boolean' },
|
hasNextPage: { type: 'boolean' },
|
||||||
startCursor: { type: 'string' },
|
startCursor: {
|
||||||
endCursor: { type: 'string' },
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
},
|
||||||
|
endCursor: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'uuid',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
companyDuplicates: {
|
companyDuplicates: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: {
|
items: {
|
||||||
$ref: `#/components/schemas/${capitalize(
|
$ref: schemaRef,
|
||||||
item.nameSingular,
|
|
||||||
)}`,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -23,7 +23,11 @@ export const RestApiWrapper = ({ openApiJson }: { openApiJson: any }) => {
|
|||||||
overflow: 'auto',
|
overflow: 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<API apiDescriptionDocument={JSON.stringify(openApiJson)} router="hash" />
|
<API
|
||||||
|
apiDescriptionDocument={JSON.stringify(openApiJson)}
|
||||||
|
hideSchemas={true}
|
||||||
|
router="hash"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user