@strapi/plugin-documentation 4.2.0-beta.2 → 4.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.
- package/__mocks__/strapi.js +41 -0
- package/__tests__/build-component-schema.test.js +271 -0
- package/package.json +6 -6
- package/server/config/{default-config.js → default-plugin-config.js} +30 -1
- package/server/config/index.js +2 -2
- package/server/controllers/documentation.js +5 -9
- package/server/services/documentation.js +28 -22
- package/server/services/helpers/build-api-endpoint-path.js +185 -0
- package/server/services/helpers/build-component-schema.js +156 -0
- package/server/services/helpers/index.js +9 -0
- package/server/{utils → services/helpers/utils}/clean-schema-attributes.js +9 -2
- package/server/services/helpers/utils/get-api-responses.js +105 -0
- package/server/{utils → services/helpers/utils}/get-schema-data.js +0 -0
- package/server/services/helpers/utils/loop-content-type-names.js +52 -0
- package/server/services/helpers/utils/pascal-case.js +9 -0
- package/server/{utils → services/helpers/utils}/query-params.js +0 -0
- package/server/services/helpers/utils/routes.js +10 -0
- package/server/services/utils/components.json +0 -25
- package/server/services/utils/parametersOptions.json +0 -134
- package/server/services/utils/unknownComponent.json +0 -11
- package/server/utils/builders/build-api-endpoint-path.js +0 -180
- package/server/utils/builders/build-api-requests.js +0 -41
- package/server/utils/builders/build-api-responses.js +0 -109
- package/server/utils/builders/index.js +0 -11
- package/server/utils/error-response.js +0 -22
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const pathToRegexp = require('path-to-regexp');
|
|
5
|
+
|
|
6
|
+
const pascalCase = require('./utils/pascal-case');
|
|
7
|
+
const queryParams = require('./utils/query-params');
|
|
8
|
+
const loopContentTypeNames = require('./utils/loop-content-type-names');
|
|
9
|
+
const getApiResponses = require('./utils/get-api-responses');
|
|
10
|
+
const { hasFindMethod, isLocalizedPath } = require('./utils/routes');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @description Parses a route with ':variable'
|
|
14
|
+
*
|
|
15
|
+
* @param {string} routePath - The route's path property
|
|
16
|
+
* @returns {string}
|
|
17
|
+
*/
|
|
18
|
+
const parsePathWithVariables = routePath => {
|
|
19
|
+
return pathToRegexp
|
|
20
|
+
.parse(routePath)
|
|
21
|
+
.map(token => {
|
|
22
|
+
if (_.isObject(token)) {
|
|
23
|
+
return token.prefix + '{' + token.name + '}';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return token;
|
|
27
|
+
})
|
|
28
|
+
.join('');
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @description Builds the required object for a path parameter
|
|
33
|
+
*
|
|
34
|
+
* @param {string} routePath - The route's path property
|
|
35
|
+
*
|
|
36
|
+
* @returns {object } Swagger path params object
|
|
37
|
+
*/
|
|
38
|
+
const getPathParams = routePath => {
|
|
39
|
+
return pathToRegexp
|
|
40
|
+
.parse(routePath)
|
|
41
|
+
.filter(token => _.isObject(token))
|
|
42
|
+
.map(param => {
|
|
43
|
+
return {
|
|
44
|
+
name: param.name,
|
|
45
|
+
in: 'path',
|
|
46
|
+
description: '',
|
|
47
|
+
deprecated: false,
|
|
48
|
+
required: true,
|
|
49
|
+
schema: { type: 'string' },
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @param {string} prefix - The prefix found on the routes object
|
|
57
|
+
* @param {string} route - The current route
|
|
58
|
+
* @property {string} route.path - The current route's path
|
|
59
|
+
* @property {object} route.config - The current route's config object
|
|
60
|
+
*
|
|
61
|
+
* @returns {string}
|
|
62
|
+
*/
|
|
63
|
+
const getPathWithPrefix = (prefix, route) => {
|
|
64
|
+
// When the prefix is set on the routes and
|
|
65
|
+
// the current route is not trying to remove it
|
|
66
|
+
if (prefix && !_.has(route.config, 'prefix')) {
|
|
67
|
+
// Add the prefix to the path
|
|
68
|
+
return prefix.concat(route.path);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Otherwise just return path
|
|
72
|
+
return route.path;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* @description Gets all paths based on routes
|
|
76
|
+
*
|
|
77
|
+
* @param {object} apiInfo
|
|
78
|
+
* @property {object} apiInfo.routeInfo - The api routes object
|
|
79
|
+
* @property {string} apiInfo.uniqueName - Content type name | Api name + Content type name
|
|
80
|
+
* @property {object} apiInfo.contentTypeInfo - The info object found on content type schemas
|
|
81
|
+
*
|
|
82
|
+
* @returns {object}
|
|
83
|
+
*/
|
|
84
|
+
const getPaths = ({ routeInfo, uniqueName, contentTypeInfo }) => {
|
|
85
|
+
// Get the routes for the current content type
|
|
86
|
+
const contentTypeRoutes = routeInfo.routes.filter(route => {
|
|
87
|
+
return (
|
|
88
|
+
route.path.includes(contentTypeInfo.pluralName) ||
|
|
89
|
+
route.path.includes(contentTypeInfo.singularName)
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const paths = contentTypeRoutes.reduce((acc, route) => {
|
|
94
|
+
// TODO: Find a more reliable way to determine list of entities vs a single entity
|
|
95
|
+
const isListOfEntities = hasFindMethod(route.handler);
|
|
96
|
+
const isLocalizationPath = isLocalizedPath(route.path);
|
|
97
|
+
const methodVerb = route.method.toLowerCase();
|
|
98
|
+
const hasPathParams = route.path.includes('/:');
|
|
99
|
+
const pathWithPrefix = getPathWithPrefix(routeInfo.prefix, route);
|
|
100
|
+
const routePath = hasPathParams ? parsePathWithVariables(pathWithPrefix) : pathWithPrefix;
|
|
101
|
+
const { responses } = getApiResponses({
|
|
102
|
+
uniqueName,
|
|
103
|
+
route,
|
|
104
|
+
isListOfEntities,
|
|
105
|
+
isLocalizationPath,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const swaggerConfig = {
|
|
109
|
+
responses,
|
|
110
|
+
tags: [_.upperFirst(uniqueName)],
|
|
111
|
+
parameters: [],
|
|
112
|
+
operationId: `${methodVerb}${routePath}`,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
if (isListOfEntities) {
|
|
116
|
+
swaggerConfig.parameters.push(...queryParams);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (hasPathParams) {
|
|
120
|
+
const pathParams = getPathParams(route.path);
|
|
121
|
+
swaggerConfig.parameters.push(...pathParams);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (['post', 'put'].includes(methodVerb)) {
|
|
125
|
+
const refName = isLocalizationPath ? 'LocalizationRequest' : 'Request';
|
|
126
|
+
const requestBody = {
|
|
127
|
+
required: true,
|
|
128
|
+
content: {
|
|
129
|
+
'application/json': {
|
|
130
|
+
schema: {
|
|
131
|
+
$ref: `#/components/schemas/${pascalCase(uniqueName)}${refName}`,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
swaggerConfig.requestBody = requestBody;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
_.set(acc, `${routePath}.${methodVerb}`, swaggerConfig);
|
|
141
|
+
|
|
142
|
+
return acc;
|
|
143
|
+
}, {});
|
|
144
|
+
|
|
145
|
+
return paths;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @decription Gets all open api paths object for a given content type
|
|
150
|
+
*
|
|
151
|
+
* @param {object} apiInfo
|
|
152
|
+
*
|
|
153
|
+
* @returns {object} Open API paths
|
|
154
|
+
*/
|
|
155
|
+
const getAllPathsForContentType = apiInfo => {
|
|
156
|
+
let paths = {};
|
|
157
|
+
|
|
158
|
+
const pathsObject = getPaths(apiInfo);
|
|
159
|
+
|
|
160
|
+
paths = {
|
|
161
|
+
...paths,
|
|
162
|
+
...pathsObject,
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
return paths;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @description - Builds the Swagger paths object for each api
|
|
170
|
+
*
|
|
171
|
+
* @param {object} api - Information about the current api
|
|
172
|
+
* @property {string} api.name - The name of the api
|
|
173
|
+
* @property {string} api.getter - The getter for the api (api | plugin)
|
|
174
|
+
* @property {array} api.ctNames - The name of all contentTypes found on the api
|
|
175
|
+
*
|
|
176
|
+
* @returns {object}
|
|
177
|
+
*/
|
|
178
|
+
const buildApiEndpointPath = api => {
|
|
179
|
+
// A reusable loop for building paths and component schemas
|
|
180
|
+
// Uses the api param to build a new set of params for each content type
|
|
181
|
+
// Passes these new params to the function provided
|
|
182
|
+
return loopContentTypeNames(api, getAllPathsForContentType);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
module.exports = buildApiEndpointPath;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
|
|
4
|
+
const cleanSchemaAttributes = require('./utils/clean-schema-attributes');
|
|
5
|
+
const loopContentTypeNames = require('./utils/loop-content-type-names');
|
|
6
|
+
const pascalCase = require('./utils/pascal-case');
|
|
7
|
+
const { hasFindMethod, isLocalizedPath } = require('./utils/routes');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @decription Get all open api schema objects for a given content type
|
|
11
|
+
*
|
|
12
|
+
* @param {object} apiInfo
|
|
13
|
+
* @property {string} apiInfo.uniqueName - Api name | Api name + Content type name
|
|
14
|
+
* @property {object} apiInfo.attributes - Attributes on content type
|
|
15
|
+
* @property {object} apiInfo.routeInfo - The routes for the api
|
|
16
|
+
*
|
|
17
|
+
* @returns {object} Open API schemas
|
|
18
|
+
*/
|
|
19
|
+
const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }) => {
|
|
20
|
+
// Store response and request schemas in an object
|
|
21
|
+
let schemas = {};
|
|
22
|
+
// Get all the route methods
|
|
23
|
+
const routeMethods = routeInfo.routes.map(route => route.method);
|
|
24
|
+
// Check for localized paths
|
|
25
|
+
const hasLocalizationPath = routeInfo.routes.filter(route => isLocalizedPath(route.path)).length;
|
|
26
|
+
// When the route methods contain any post or put requests
|
|
27
|
+
if (routeMethods.includes('POST') || routeMethods.includes('PUT')) {
|
|
28
|
+
const attributesToOmit = [
|
|
29
|
+
'createdAt',
|
|
30
|
+
'updatedAt',
|
|
31
|
+
'publishedAt',
|
|
32
|
+
'publishedBy',
|
|
33
|
+
'updatedBy',
|
|
34
|
+
'createdBy',
|
|
35
|
+
'localizations',
|
|
36
|
+
];
|
|
37
|
+
const attributesForRequest = _.omit(attributes, attributesToOmit);
|
|
38
|
+
|
|
39
|
+
// Get a list of required attribute names
|
|
40
|
+
const requiredAttributes = Object.entries(attributesForRequest).reduce((acc, attribute) => {
|
|
41
|
+
const [attributeKey, attributeValue] = attribute;
|
|
42
|
+
|
|
43
|
+
if (attributeValue.required) {
|
|
44
|
+
acc.push(attributeKey);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return acc;
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
if (hasLocalizationPath) {
|
|
51
|
+
schemas = {
|
|
52
|
+
...schemas,
|
|
53
|
+
[`${pascalCase(uniqueName)}LocalizationRequest`]: {
|
|
54
|
+
required: [...requiredAttributes, 'locale'],
|
|
55
|
+
type: 'object',
|
|
56
|
+
properties: cleanSchemaAttributes(attributesForRequest, { isRequest: true }),
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Build the request schema
|
|
62
|
+
schemas = {
|
|
63
|
+
...schemas,
|
|
64
|
+
[`${pascalCase(uniqueName)}Request`]: {
|
|
65
|
+
type: 'object',
|
|
66
|
+
required: ['data'],
|
|
67
|
+
properties: {
|
|
68
|
+
data: {
|
|
69
|
+
required: requiredAttributes,
|
|
70
|
+
type: 'object',
|
|
71
|
+
properties: cleanSchemaAttributes(attributesForRequest, { isRequest: true }),
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (hasLocalizationPath) {
|
|
79
|
+
schemas = {
|
|
80
|
+
...schemas,
|
|
81
|
+
[`${pascalCase(uniqueName)}LocalizationResponse`]: {
|
|
82
|
+
type: 'object',
|
|
83
|
+
properties: {
|
|
84
|
+
id: { type: 'string' },
|
|
85
|
+
...cleanSchemaAttributes(attributes),
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Check for routes that need to return a list
|
|
92
|
+
const hasListOfEntities = routeInfo.routes.filter(route => hasFindMethod(route.handler)).length;
|
|
93
|
+
if (hasListOfEntities) {
|
|
94
|
+
// Build the list response schema
|
|
95
|
+
schemas = {
|
|
96
|
+
...schemas,
|
|
97
|
+
[`${pascalCase(uniqueName)}ListResponse`]: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
data: {
|
|
101
|
+
type: 'array',
|
|
102
|
+
items: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
properties: {
|
|
105
|
+
id: { type: 'string' },
|
|
106
|
+
attributes: { type: 'object', properties: cleanSchemaAttributes(attributes) },
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
meta: {
|
|
111
|
+
type: 'object',
|
|
112
|
+
properties: {
|
|
113
|
+
pagination: {
|
|
114
|
+
properties: {
|
|
115
|
+
page: { type: 'integer' },
|
|
116
|
+
pageSize: { type: 'integer', minimum: 25 },
|
|
117
|
+
pageCount: { type: 'integer', maximum: 1 },
|
|
118
|
+
total: { type: 'integer' },
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Build the response schema
|
|
129
|
+
schemas = {
|
|
130
|
+
...schemas,
|
|
131
|
+
[`${pascalCase(uniqueName)}Response`]: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: {
|
|
134
|
+
data: {
|
|
135
|
+
type: 'object',
|
|
136
|
+
properties: {
|
|
137
|
+
id: { type: 'string' },
|
|
138
|
+
attributes: { type: 'object', properties: cleanSchemaAttributes(attributes) },
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
meta: { type: 'object' },
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
return schemas;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const buildComponentSchema = api => {
|
|
150
|
+
// A reusable loop for building paths and component schemas
|
|
151
|
+
// Uses the api param to build a new set of params for each content type
|
|
152
|
+
// Passes these new params to the function provided
|
|
153
|
+
return loopContentTypeNames(api, getAllSchemasForContentType);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
module.exports = buildComponentSchema;
|
|
@@ -4,13 +4,12 @@ const _ = require('lodash');
|
|
|
4
4
|
const getSchemaData = require('./get-schema-data');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @description - Converts types found on attributes to OpenAPI
|
|
7
|
+
* @description - Converts types found on attributes to OpenAPI acceptable data types
|
|
8
8
|
*
|
|
9
9
|
* @param {object} attributes - The attributes found on a contentType
|
|
10
10
|
* @param {{ typeMap: Map, isRequest: boolean }} opts
|
|
11
11
|
* @returns Attributes using OpenAPI acceptable data types
|
|
12
12
|
*/
|
|
13
|
-
|
|
14
13
|
const cleanSchemaAttributes = (attributes, { typeMap = new Map(), isRequest = false } = {}) => {
|
|
15
14
|
const attributesCopy = _.cloneDeep(attributes);
|
|
16
15
|
|
|
@@ -170,6 +169,14 @@ const cleanSchemaAttributes = (attributes, { typeMap = new Map(), isRequest = fa
|
|
|
170
169
|
break;
|
|
171
170
|
}
|
|
172
171
|
|
|
172
|
+
if (prop === 'localizations') {
|
|
173
|
+
attributesCopy[prop] = {
|
|
174
|
+
type: 'array',
|
|
175
|
+
items: { type: 'object', properties: {} },
|
|
176
|
+
};
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
|
|
173
180
|
if (!attribute.target || typeMap.has(attribute.target)) {
|
|
174
181
|
attributesCopy[prop] = {
|
|
175
182
|
type: 'object',
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const pascalCase = require('./pascal-case');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @description - Builds the Swagger response object for a given api
|
|
7
|
+
*
|
|
8
|
+
* @param {object} name - Name of the api or plugin
|
|
9
|
+
* @param {object} route - The current route
|
|
10
|
+
* @param {boolean} isListOfEntities - Checks for a list of entitities
|
|
11
|
+
*
|
|
12
|
+
* @returns The Swagger responses
|
|
13
|
+
*/
|
|
14
|
+
const getApiResponse = ({
|
|
15
|
+
uniqueName,
|
|
16
|
+
route,
|
|
17
|
+
isListOfEntities = false,
|
|
18
|
+
isLocalizationPath = false,
|
|
19
|
+
}) => {
|
|
20
|
+
const getSchema = () => {
|
|
21
|
+
if (route.method === 'DELETE') {
|
|
22
|
+
return {
|
|
23
|
+
type: 'integer',
|
|
24
|
+
format: 'int64',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (isLocalizationPath) {
|
|
29
|
+
return { $ref: `#/components/schemas/${pascalCase(uniqueName)}LocalizationResponse` };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (isListOfEntities) {
|
|
33
|
+
return { $ref: `#/components/schemas/${pascalCase(uniqueName)}ListResponse` };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return { $ref: `#/components/schemas/${pascalCase(uniqueName)}Response` };
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const schema = getSchema();
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
responses: {
|
|
43
|
+
200: {
|
|
44
|
+
description: 'OK',
|
|
45
|
+
content: {
|
|
46
|
+
'application/json': {
|
|
47
|
+
schema,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
400: {
|
|
52
|
+
description: 'Bad Request',
|
|
53
|
+
content: {
|
|
54
|
+
'application/json': {
|
|
55
|
+
schema: {
|
|
56
|
+
$ref: '#/components/schemas/Error',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
401: {
|
|
62
|
+
description: 'Unauthorized',
|
|
63
|
+
content: {
|
|
64
|
+
'application/json': {
|
|
65
|
+
schema: {
|
|
66
|
+
$ref: '#/components/schemas/Error',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
403: {
|
|
72
|
+
description: 'Forbidden',
|
|
73
|
+
content: {
|
|
74
|
+
'application/json': {
|
|
75
|
+
schema: {
|
|
76
|
+
$ref: '#/components/schemas/Error',
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
404: {
|
|
82
|
+
description: 'Not Found',
|
|
83
|
+
content: {
|
|
84
|
+
'application/json': {
|
|
85
|
+
schema: {
|
|
86
|
+
$ref: '#/components/schemas/Error',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
500: {
|
|
92
|
+
description: 'Internal Server Error',
|
|
93
|
+
content: {
|
|
94
|
+
'application/json': {
|
|
95
|
+
schema: {
|
|
96
|
+
$ref: '#/components/schemas/Error',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
module.exports = getApiResponse;
|
|
File without changes
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @description A reusable loop for building api endpoint paths and component schemas
|
|
6
|
+
*
|
|
7
|
+
* @param {object} api - Api information to pass to the callback
|
|
8
|
+
* @param {function} callback - Logic to execute for the given api
|
|
9
|
+
*
|
|
10
|
+
* @returns {object}
|
|
11
|
+
*/
|
|
12
|
+
const loopContentTypeNames = (api, callback) => {
|
|
13
|
+
let result = {};
|
|
14
|
+
for (const contentTypeName of api.ctNames) {
|
|
15
|
+
// Get the attributes found on the api's contentType
|
|
16
|
+
const uid = `${api.getter}::${api.name}.${contentTypeName}`;
|
|
17
|
+
const { attributes, info: contentTypeInfo } = strapi.contentType(uid);
|
|
18
|
+
|
|
19
|
+
// Get the routes for the current api
|
|
20
|
+
const routeInfo =
|
|
21
|
+
api.getter === 'plugin'
|
|
22
|
+
? strapi.plugin(api.name).routes['content-api']
|
|
23
|
+
: strapi.api[api.name].routes[contentTypeName];
|
|
24
|
+
|
|
25
|
+
// Continue to next iteration if routeInfo is undefined
|
|
26
|
+
if (!routeInfo) continue;
|
|
27
|
+
|
|
28
|
+
// Uppercase the first letter of the api name
|
|
29
|
+
const apiName = _.upperFirst(api.name);
|
|
30
|
+
|
|
31
|
+
// Create a unique name if the api name and contentType name don't match
|
|
32
|
+
const uniqueName =
|
|
33
|
+
api.name === contentTypeName ? apiName : `${apiName} - ${_.upperFirst(contentTypeName)}`;
|
|
34
|
+
|
|
35
|
+
const apiInfo = {
|
|
36
|
+
...api,
|
|
37
|
+
routeInfo,
|
|
38
|
+
attributes,
|
|
39
|
+
uniqueName,
|
|
40
|
+
contentTypeInfo,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
result = {
|
|
44
|
+
...result,
|
|
45
|
+
...callback(apiInfo),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
module.exports = loopContentTypeNames;
|
|
File without changes
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"components": {
|
|
3
|
-
"securitySchemes": {
|
|
4
|
-
"bearerAuth": {
|
|
5
|
-
"type": "http",
|
|
6
|
-
"scheme": "bearer",
|
|
7
|
-
"bearerFormat": "JWT"
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
"schemas": {
|
|
11
|
-
"Error": {
|
|
12
|
-
"required": ["code", "message"],
|
|
13
|
-
"properties": {
|
|
14
|
-
"code": {
|
|
15
|
-
"type": "integer",
|
|
16
|
-
"format": "int32"
|
|
17
|
-
},
|
|
18
|
-
"message": {
|
|
19
|
-
"type": "string"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|