@strapi/plugin-documentation 5.0.0-beta.0 → 5.0.0-beta.1

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.
Files changed (184) hide show
  1. package/README.md +0 -1
  2. package/dist/_chunks/{index-7xstUX8_.mjs → App-ig-uE4do.mjs} +48 -14
  3. package/dist/_chunks/App-ig-uE4do.mjs.map +1 -0
  4. package/dist/_chunks/{index-D1KkfApT.js → App-o4uH8gaQ.js} +73 -20
  5. package/dist/_chunks/App-o4uH8gaQ.js.map +1 -0
  6. package/dist/_chunks/{index-VpLAJXMs.mjs → Settings-3hsPOP_b.mjs} +64 -33
  7. package/dist/_chunks/Settings-3hsPOP_b.mjs.map +1 -0
  8. package/dist/_chunks/{index-NbPCucJl.js → Settings-XmOzLTUn.js} +69 -37
  9. package/dist/_chunks/Settings-XmOzLTUn.js.map +1 -0
  10. package/dist/_chunks/getTrad-bnElvR8_.js +5 -0
  11. package/dist/_chunks/getTrad-bnElvR8_.js.map +1 -0
  12. package/dist/_chunks/getTrad-md7Tjpcv.mjs +6 -0
  13. package/dist/_chunks/getTrad-md7Tjpcv.mjs.map +1 -0
  14. package/{server/public/index.html → dist/_chunks/index-MKWIGajW.mjs} +9 -4
  15. package/dist/_chunks/index-MKWIGajW.mjs.map +1 -0
  16. package/dist/_chunks/index-WbbYm9_u.js +75 -0
  17. package/dist/_chunks/index-WbbYm9_u.js.map +1 -0
  18. package/dist/_chunks/{index-NvJ4m2q5.mjs → index-jpDwTC-Q.mjs} +121 -117
  19. package/dist/_chunks/index-jpDwTC-Q.mjs.map +1 -0
  20. package/dist/_chunks/{index-r7HsQTou.js → index-vNbIS1u2.js} +119 -115
  21. package/dist/_chunks/index-vNbIS1u2.js.map +1 -0
  22. package/dist/_chunks/login-HAajOKpu.js +150 -0
  23. package/dist/_chunks/login-HAajOKpu.js.map +1 -0
  24. package/{server/public/login.html → dist/_chunks/login-slUa679p.mjs} +6 -1
  25. package/dist/_chunks/login-slUa679p.mjs.map +1 -0
  26. package/dist/admin/index.js +1 -1
  27. package/dist/admin/index.mjs +2 -2
  28. package/dist/admin/src/components/SettingsForm.d.ts +8 -0
  29. package/dist/admin/src/constants.d.ts +18 -0
  30. package/dist/admin/src/index.d.ts +14 -0
  31. package/dist/admin/src/pages/App.d.ts +2 -0
  32. package/dist/admin/src/pages/Settings.d.ts +2 -0
  33. package/dist/admin/src/pluginId.d.ts +1 -0
  34. package/dist/admin/src/services/api.d.ts +25 -0
  35. package/dist/admin/src/types.d.ts +16 -0
  36. package/dist/admin/src/utils/baseQuery.d.ts +20 -0
  37. package/dist/admin/src/utils/getTrad.d.ts +1 -0
  38. package/dist/admin/src/utils/index.d.ts +2 -0
  39. package/dist/admin/src/utils/prefixPluginTranslations.d.ts +2 -0
  40. package/dist/server/index.js +1263 -0
  41. package/dist/server/index.js.map +1 -0
  42. package/dist/server/index.mjs +1238 -0
  43. package/dist/server/index.mjs.map +1 -0
  44. package/dist/server/src/bootstrap.d.ts +5 -0
  45. package/dist/server/src/bootstrap.d.ts.map +1 -0
  46. package/dist/server/src/config/default-plugin-config.d.ts +3 -0
  47. package/dist/server/src/config/default-plugin-config.d.ts.map +1 -0
  48. package/dist/server/src/config/index.d.ts +4 -0
  49. package/dist/server/src/config/index.d.ts.map +1 -0
  50. package/dist/server/src/controllers/documentation.d.ts +12 -0
  51. package/dist/server/src/controllers/documentation.d.ts.map +1 -0
  52. package/dist/server/src/controllers/index.d.ts +14 -0
  53. package/dist/server/src/controllers/index.d.ts.map +1 -0
  54. package/dist/server/src/index.d.ts +91 -0
  55. package/dist/server/src/index.d.ts.map +1 -0
  56. package/dist/server/src/middlewares/documentation.d.ts +5 -0
  57. package/dist/server/src/middlewares/documentation.d.ts.map +1 -0
  58. package/dist/server/src/middlewares/restrict-access.d.ts +4 -0
  59. package/dist/server/src/middlewares/restrict-access.d.ts.map +1 -0
  60. package/dist/server/src/register.d.ts +5 -0
  61. package/dist/server/src/register.d.ts.map +1 -0
  62. package/dist/server/src/routes/index.d.ts +36 -0
  63. package/dist/server/src/routes/index.d.ts.map +1 -0
  64. package/dist/server/src/services/__mocks__/mock-content-types.d.ts +449 -0
  65. package/dist/server/src/services/__mocks__/mock-content-types.d.ts.map +1 -0
  66. package/dist/server/src/services/__mocks__/mock-strapi-data.d.ts +592 -0
  67. package/dist/server/src/services/__mocks__/mock-strapi-data.d.ts.map +1 -0
  68. package/dist/server/src/services/documentation.d.ts +36 -0
  69. package/dist/server/src/services/documentation.d.ts.map +1 -0
  70. package/dist/server/src/services/helpers/build-api-endpoint-path.d.ts +7 -0
  71. package/dist/server/src/services/helpers/build-api-endpoint-path.d.ts.map +1 -0
  72. package/dist/server/src/services/helpers/build-component-schema.d.ts +4 -0
  73. package/dist/server/src/services/helpers/build-component-schema.d.ts.map +1 -0
  74. package/dist/server/src/services/helpers/index.d.ts +4 -0
  75. package/dist/server/src/services/helpers/index.d.ts.map +1 -0
  76. package/dist/server/src/services/helpers/utils/clean-schema-attributes.d.ts +15 -0
  77. package/dist/server/src/services/helpers/utils/clean-schema-attributes.d.ts.map +1 -0
  78. package/dist/server/src/services/helpers/utils/get-api-responses.d.ts +15 -0
  79. package/dist/server/src/services/helpers/utils/get-api-responses.d.ts.map +1 -0
  80. package/dist/server/src/services/helpers/utils/get-schema-data.d.ts +12 -0
  81. package/dist/server/src/services/helpers/utils/get-schema-data.d.ts.map +1 -0
  82. package/dist/server/src/services/helpers/utils/loop-content-type-names.d.ts +7 -0
  83. package/dist/server/src/services/helpers/utils/loop-content-type-names.d.ts.map +1 -0
  84. package/dist/server/src/services/helpers/utils/pascal-case.d.ts +3 -0
  85. package/dist/server/src/services/helpers/utils/pascal-case.d.ts.map +1 -0
  86. package/dist/server/src/services/helpers/utils/query-params.d.ts +4 -0
  87. package/dist/server/src/services/helpers/utils/query-params.d.ts.map +1 -0
  88. package/dist/server/src/services/helpers/utils/routes.d.ts +3 -0
  89. package/dist/server/src/services/helpers/utils/routes.d.ts.map +1 -0
  90. package/dist/server/src/services/index.d.ts +43 -0
  91. package/dist/server/src/services/index.d.ts.map +1 -0
  92. package/dist/server/src/services/override.d.ts +21 -0
  93. package/dist/server/src/services/override.d.ts.map +1 -0
  94. package/dist/server/src/services/utils/get-plugins-that-need-documentation.d.ts +4 -0
  95. package/dist/server/src/services/utils/get-plugins-that-need-documentation.d.ts.map +1 -0
  96. package/dist/server/src/types.d.ts +28 -0
  97. package/dist/server/src/types.d.ts.map +1 -0
  98. package/dist/server/src/utils.d.ts +12 -0
  99. package/dist/server/src/utils.d.ts.map +1 -0
  100. package/package.json +33 -15
  101. package/strapi-server.js +1 -1
  102. package/.eslintignore +0 -1
  103. package/.eslintrc +0 -17
  104. package/admin/src/constants.js +0 -17
  105. package/admin/src/hooks/useDocumentation.js +0 -81
  106. package/admin/src/index.js +0 -62
  107. package/admin/src/pages/PluginPage/index.jsx +0 -212
  108. package/admin/src/pages/PluginPage/tests/index.test.jsx +0 -160
  109. package/admin/src/pages/SettingsPage/index.jsx +0 -202
  110. package/admin/src/pages/SettingsPage/tests/index.test.jsx +0 -72
  111. package/admin/src/pluginId.js +0 -5
  112. package/admin/src/translations/ar.json +0 -20
  113. package/admin/src/translations/cs.json +0 -21
  114. package/admin/src/translations/de.json +0 -26
  115. package/admin/src/translations/dk.json +0 -39
  116. package/admin/src/translations/en.json +0 -39
  117. package/admin/src/translations/es.json +0 -39
  118. package/admin/src/translations/fr.json +0 -26
  119. package/admin/src/translations/id.json +0 -24
  120. package/admin/src/translations/it.json +0 -26
  121. package/admin/src/translations/ko.json +0 -39
  122. package/admin/src/translations/ms.json +0 -23
  123. package/admin/src/translations/nl.json +0 -21
  124. package/admin/src/translations/pl.json +0 -39
  125. package/admin/src/translations/pt-BR.json +0 -21
  126. package/admin/src/translations/pt.json +0 -21
  127. package/admin/src/translations/ru.json +0 -39
  128. package/admin/src/translations/sk.json +0 -24
  129. package/admin/src/translations/sv.json +0 -39
  130. package/admin/src/translations/th.json +0 -24
  131. package/admin/src/translations/tr.json +0 -39
  132. package/admin/src/translations/uk.json +0 -23
  133. package/admin/src/translations/vi.json +0 -24
  134. package/admin/src/translations/zh-Hans.json +0 -28
  135. package/admin/src/translations/zh.json +0 -39
  136. package/admin/src/utils/getTrad.js +0 -5
  137. package/admin/src/utils/index.js +0 -2
  138. package/admin/src/utils/prefixPluginTranslations.js +0 -13
  139. package/dist/_chunks/index-7xstUX8_.mjs.map +0 -1
  140. package/dist/_chunks/index-D1KkfApT.js.map +0 -1
  141. package/dist/_chunks/index-NbPCucJl.js.map +0 -1
  142. package/dist/_chunks/index-NvJ4m2q5.mjs.map +0 -1
  143. package/dist/_chunks/index-VpLAJXMs.mjs.map +0 -1
  144. package/dist/_chunks/index-r7HsQTou.js.map +0 -1
  145. package/dist/_chunks/useDocumentation-6Ks-_Ms6.mjs +0 -68
  146. package/dist/_chunks/useDocumentation-6Ks-_Ms6.mjs.map +0 -1
  147. package/dist/_chunks/useDocumentation-S0e4mU-U.js +0 -67
  148. package/dist/_chunks/useDocumentation-S0e4mU-U.js.map +0 -1
  149. package/jest.config.front.js +0 -7
  150. package/jest.config.js +0 -6
  151. package/packup.config.ts +0 -22
  152. package/server/bootstrap.js +0 -54
  153. package/server/config/default-plugin-config.js +0 -35
  154. package/server/config/index.js +0 -7
  155. package/server/controllers/documentation.js +0 -241
  156. package/server/controllers/index.js +0 -7
  157. package/server/index.js +0 -17
  158. package/server/middlewares/documentation.js +0 -25
  159. package/server/middlewares/index.js +0 -7
  160. package/server/middlewares/restrict-access.js +0 -24
  161. package/server/register.js +0 -11
  162. package/server/routes/index.js +0 -84
  163. package/server/services/__mocks__/mock-content-types.js +0 -264
  164. package/server/services/__mocks__/mock-strapi-data.js +0 -183
  165. package/server/services/__tests__/build-component-schema.test.js +0 -761
  166. package/server/services/__tests__/documentation.test.js +0 -481
  167. package/server/services/__tests__/override.test.js +0 -85
  168. package/server/services/documentation.js +0 -246
  169. package/server/services/helpers/build-api-endpoint-path.js +0 -186
  170. package/server/services/helpers/build-component-schema.js +0 -254
  171. package/server/services/helpers/index.js +0 -9
  172. package/server/services/helpers/utils/clean-schema-attributes.js +0 -246
  173. package/server/services/helpers/utils/get-api-responses.js +0 -105
  174. package/server/services/helpers/utils/get-schema-data.js +0 -32
  175. package/server/services/helpers/utils/loop-content-type-names.js +0 -55
  176. package/server/services/helpers/utils/pascal-case.js +0 -9
  177. package/server/services/helpers/utils/query-params.js +0 -105
  178. package/server/services/helpers/utils/routes.js +0 -10
  179. package/server/services/index.js +0 -9
  180. package/server/services/override.js +0 -52
  181. package/server/services/utils/default-openapi-components.js +0 -40
  182. package/server/services/utils/get-plugins-that-need-documentation.js +0 -24
  183. package/tests/server.js +0 -37
  184. package/tests/setup.js +0 -15
@@ -0,0 +1,1263 @@
1
+ "use strict";
2
+ const path = require("path");
3
+ const koaStatic = require("koa-static");
4
+ const swaggerUi = require("swagger-ui-dist");
5
+ const fs = require("fs-extra");
6
+ const immer = require("immer");
7
+ const _ = require("lodash");
8
+ const pathToRegexp = require("path-to-regexp");
9
+ const bcrypt = require("bcryptjs");
10
+ const utils = require("@strapi/utils");
11
+ const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
12
+ function _interopNamespace(e) {
13
+ if (e && e.__esModule)
14
+ return e;
15
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
16
+ if (e) {
17
+ for (const k in e) {
18
+ if (k !== "default") {
19
+ const d = Object.getOwnPropertyDescriptor(e, k);
20
+ Object.defineProperty(n, k, d.get ? d : {
21
+ enumerable: true,
22
+ get: () => e[k]
23
+ });
24
+ }
25
+ }
26
+ }
27
+ n.default = e;
28
+ return Object.freeze(n);
29
+ }
30
+ const path__default = /* @__PURE__ */ _interopDefault(path);
31
+ const koaStatic__default = /* @__PURE__ */ _interopDefault(koaStatic);
32
+ const swaggerUi__default = /* @__PURE__ */ _interopDefault(swaggerUi);
33
+ const fs__default = /* @__PURE__ */ _interopDefault(fs);
34
+ const ___default = /* @__PURE__ */ _interopDefault(_);
35
+ const pathToRegexp__namespace = /* @__PURE__ */ _interopNamespace(pathToRegexp);
36
+ const bcrypt__default = /* @__PURE__ */ _interopDefault(bcrypt);
37
+ const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
38
+ return strapi2.plugin("documentation").service(name);
39
+ };
40
+ const RBAC_ACTIONS = [
41
+ {
42
+ section: "plugins",
43
+ displayName: "Access the Documentation",
44
+ uid: "read",
45
+ pluginName: "documentation"
46
+ },
47
+ {
48
+ section: "plugins",
49
+ displayName: "Update and delete",
50
+ uid: "settings.update",
51
+ pluginName: "documentation"
52
+ },
53
+ {
54
+ section: "plugins",
55
+ displayName: "Regenerate",
56
+ uid: "settings.regenerate",
57
+ pluginName: "documentation"
58
+ },
59
+ {
60
+ section: "settings",
61
+ displayName: "Access the documentation settings page",
62
+ uid: "settings.read",
63
+ pluginName: "documentation",
64
+ category: "documentation"
65
+ }
66
+ ];
67
+ async function bootstrap({ strapi: strapi2 }) {
68
+ await strapi2.admin?.services.permission.actionProvider.registerMany(RBAC_ACTIONS);
69
+ const pluginStore = strapi2.store({
70
+ environment: "",
71
+ type: "plugin",
72
+ name: "documentation"
73
+ });
74
+ const config2 = await pluginStore.get({ key: "config" });
75
+ if (!config2) {
76
+ pluginStore.set({ key: "config", value: { restrictedAccess: false } });
77
+ }
78
+ await getService("documentation").generateFullDoc();
79
+ }
80
+ const addDocumentMiddlewares = async ({ strapi: strapi2 }) => {
81
+ strapi2.server.routes([
82
+ {
83
+ method: "GET",
84
+ path: "/plugins/documentation/(.*)",
85
+ async handler(ctx, next) {
86
+ ctx.url = path__default.default.basename(ctx.url);
87
+ return koaStatic__default.default(swaggerUi__default.default.getAbsoluteFSPath(), {
88
+ maxage: 864e5,
89
+ defer: true
90
+ })(ctx, next);
91
+ },
92
+ config: {
93
+ auth: false
94
+ }
95
+ }
96
+ ]);
97
+ };
98
+ async function register({ strapi: strapi2 }) {
99
+ await addDocumentMiddlewares({ strapi: strapi2 });
100
+ }
101
+ const pascalCase = (string) => {
102
+ return ___default.default.upperFirst(___default.default.camelCase(string));
103
+ };
104
+ const params = [
105
+ {
106
+ name: "sort",
107
+ in: "query",
108
+ description: "Sort by attributes ascending (asc) or descending (desc)",
109
+ deprecated: false,
110
+ required: false,
111
+ schema: {
112
+ type: "string"
113
+ }
114
+ },
115
+ {
116
+ name: "pagination[withCount]",
117
+ in: "query",
118
+ description: "Return page/pageSize (default: true)",
119
+ deprecated: false,
120
+ required: false,
121
+ schema: {
122
+ type: "boolean"
123
+ }
124
+ },
125
+ {
126
+ name: "pagination[page]",
127
+ in: "query",
128
+ description: "Page number (default: 0)",
129
+ deprecated: false,
130
+ required: false,
131
+ schema: {
132
+ type: "integer"
133
+ }
134
+ },
135
+ {
136
+ name: "pagination[pageSize]",
137
+ in: "query",
138
+ description: "Page size (default: 25)",
139
+ deprecated: false,
140
+ required: false,
141
+ schema: {
142
+ type: "integer"
143
+ }
144
+ },
145
+ {
146
+ name: "pagination[start]",
147
+ in: "query",
148
+ description: "Offset value (default: 0)",
149
+ deprecated: false,
150
+ required: false,
151
+ schema: {
152
+ type: "integer"
153
+ }
154
+ },
155
+ {
156
+ name: "pagination[limit]",
157
+ in: "query",
158
+ description: "Number of entities to return (default: 25)",
159
+ deprecated: false,
160
+ required: false,
161
+ schema: {
162
+ type: "integer"
163
+ }
164
+ },
165
+ {
166
+ name: "fields",
167
+ in: "query",
168
+ description: "Fields to return (ex: title,author)",
169
+ deprecated: false,
170
+ required: false,
171
+ schema: {
172
+ type: "string"
173
+ }
174
+ },
175
+ {
176
+ name: "populate",
177
+ in: "query",
178
+ description: "Relations to return",
179
+ deprecated: false,
180
+ required: false,
181
+ schema: {
182
+ type: "string"
183
+ }
184
+ },
185
+ {
186
+ name: "filters",
187
+ in: "query",
188
+ description: "Filters to apply",
189
+ deprecated: false,
190
+ required: false,
191
+ schema: {
192
+ type: "object"
193
+ },
194
+ style: "deepObject"
195
+ },
196
+ {
197
+ name: "locale",
198
+ in: "query",
199
+ description: "Locale to apply",
200
+ deprecated: false,
201
+ required: false,
202
+ schema: {
203
+ type: "string"
204
+ }
205
+ }
206
+ ];
207
+ const loopContentTypeNames = (api, callback) => {
208
+ let result = {};
209
+ for (const contentTypeName of api.ctNames) {
210
+ const uid = `${api.getter}::${api.name}.${contentTypeName}`;
211
+ const { attributes, info: contentTypeInfo, kind } = strapi.contentType(uid);
212
+ const routeInfo = api.getter === "plugin" ? (
213
+ // @ts-expect-error - This is a valid check
214
+ strapi.plugin(api.name).routes["content-api"]
215
+ ) : strapi.api[api.name].routes[contentTypeName];
216
+ if (!routeInfo) {
217
+ continue;
218
+ }
219
+ const apiName = ___default.default.upperFirst(api.name);
220
+ const uniqueName = api.name === contentTypeName ? apiName : `${apiName} - ${___default.default.upperFirst(contentTypeName)}`;
221
+ const apiInfo = {
222
+ ...api,
223
+ routeInfo,
224
+ attributes,
225
+ uniqueName,
226
+ contentTypeInfo,
227
+ kind
228
+ };
229
+ result = {
230
+ ...result,
231
+ ...callback(apiInfo)
232
+ };
233
+ }
234
+ return result;
235
+ };
236
+ const getApiResponse = ({
237
+ uniqueName,
238
+ route,
239
+ isListOfEntities = false
240
+ }) => {
241
+ const getSchema = () => {
242
+ if (route.method === "DELETE") {
243
+ return {
244
+ type: "integer",
245
+ format: "int64"
246
+ };
247
+ }
248
+ if (isListOfEntities) {
249
+ return { $ref: `#/components/schemas/${pascalCase(uniqueName)}ListResponse` };
250
+ }
251
+ return { $ref: `#/components/schemas/${pascalCase(uniqueName)}Response` };
252
+ };
253
+ const schema = getSchema();
254
+ return {
255
+ 200: {
256
+ description: "OK",
257
+ content: {
258
+ "application/json": {
259
+ schema
260
+ }
261
+ }
262
+ },
263
+ 400: {
264
+ description: "Bad Request",
265
+ content: {
266
+ "application/json": {
267
+ schema: {
268
+ $ref: "#/components/schemas/Error"
269
+ }
270
+ }
271
+ }
272
+ },
273
+ 401: {
274
+ description: "Unauthorized",
275
+ content: {
276
+ "application/json": {
277
+ schema: {
278
+ $ref: "#/components/schemas/Error"
279
+ }
280
+ }
281
+ }
282
+ },
283
+ 403: {
284
+ description: "Forbidden",
285
+ content: {
286
+ "application/json": {
287
+ schema: {
288
+ $ref: "#/components/schemas/Error"
289
+ }
290
+ }
291
+ }
292
+ },
293
+ 404: {
294
+ description: "Not Found",
295
+ content: {
296
+ "application/json": {
297
+ schema: {
298
+ $ref: "#/components/schemas/Error"
299
+ }
300
+ }
301
+ }
302
+ },
303
+ 500: {
304
+ description: "Internal Server Error",
305
+ content: {
306
+ "application/json": {
307
+ schema: {
308
+ $ref: "#/components/schemas/Error"
309
+ }
310
+ }
311
+ }
312
+ }
313
+ };
314
+ };
315
+ const hasFindMethod = (handler) => {
316
+ if (typeof handler === "string") {
317
+ return handler.split(".").pop() === "find";
318
+ }
319
+ return false;
320
+ };
321
+ const parsePathWithVariables = (routePath) => {
322
+ return pathToRegexp__namespace.parse(routePath).map((token) => {
323
+ if (___default.default.isObject(token)) {
324
+ return `${token.prefix}{${token.name}}`;
325
+ }
326
+ return token;
327
+ }).join("");
328
+ };
329
+ const getPathParams = (routePath) => {
330
+ return pathToRegexp__namespace.parse(routePath).reduce((acc, param) => {
331
+ if (!(typeof param === "object")) {
332
+ return acc;
333
+ }
334
+ acc.push({
335
+ name: `${param.name}`,
336
+ in: "path",
337
+ description: "",
338
+ deprecated: false,
339
+ required: true,
340
+ schema: { type: "number" }
341
+ });
342
+ return acc;
343
+ }, []);
344
+ };
345
+ const getPathWithPrefix = (prefix, route) => {
346
+ if (prefix && !___default.default.has(route.config, "prefix")) {
347
+ return prefix.concat(route.path);
348
+ }
349
+ return route.path;
350
+ };
351
+ const getPaths = ({ routeInfo, uniqueName, contentTypeInfo, kind }) => {
352
+ const contentTypeRoutes = routeInfo.routes.filter((route) => {
353
+ return route.path.includes(contentTypeInfo.pluralName) || route.path.includes(contentTypeInfo.singularName);
354
+ });
355
+ const paths = contentTypeRoutes.reduce((acc, route) => {
356
+ const isListOfEntities = hasFindMethod(route.handler);
357
+ const methodVerb = route.method.toLowerCase();
358
+ const hasPathParams = route.path.includes("/:");
359
+ const pathWithPrefix = getPathWithPrefix(routeInfo.prefix, route);
360
+ const routePath = hasPathParams ? parsePathWithVariables(pathWithPrefix) : pathWithPrefix;
361
+ const responses = getApiResponse({
362
+ uniqueName,
363
+ route,
364
+ isListOfEntities: kind !== "singleType" && isListOfEntities
365
+ });
366
+ const swaggerConfig = {
367
+ responses,
368
+ tags: [___default.default.upperFirst(uniqueName)],
369
+ parameters: [],
370
+ operationId: `${methodVerb}${routePath}`
371
+ };
372
+ if (isListOfEntities) {
373
+ swaggerConfig.parameters?.push(...params);
374
+ }
375
+ if (hasPathParams) {
376
+ const pathParams = getPathParams(route.path);
377
+ swaggerConfig.parameters?.push(...pathParams);
378
+ }
379
+ if (["post", "put"].includes(methodVerb)) {
380
+ const refName = "Request";
381
+ const requestBody = {
382
+ required: true,
383
+ content: {
384
+ "application/json": {
385
+ schema: {
386
+ $ref: `#/components/schemas/${pascalCase(uniqueName)}${refName}`
387
+ }
388
+ }
389
+ }
390
+ };
391
+ swaggerConfig.requestBody = requestBody;
392
+ }
393
+ ___default.default.set(acc, `${routePath}.${methodVerb}`, swaggerConfig);
394
+ return acc;
395
+ }, {});
396
+ return paths;
397
+ };
398
+ const buildApiEndpointPath = (api) => {
399
+ return loopContentTypeNames(api, getPaths);
400
+ };
401
+ const getSchemaData = (isListOfEntities, attributes) => {
402
+ if (isListOfEntities) {
403
+ return {
404
+ type: "array",
405
+ items: {
406
+ type: "object",
407
+ properties: {
408
+ id: { type: "number" },
409
+ documentId: { type: "string" },
410
+ ...attributes
411
+ }
412
+ }
413
+ };
414
+ }
415
+ return {
416
+ type: "object",
417
+ properties: {
418
+ id: { type: "number" },
419
+ documentId: { type: "string" },
420
+ ...attributes
421
+ }
422
+ };
423
+ };
424
+ const cleanSchemaAttributes = (attributes, { typeMap = /* @__PURE__ */ new Map(), isRequest = false, didAddStrapiComponentsToSchemas }) => {
425
+ const schemaAttributes = {};
426
+ for (const prop of Object.keys(attributes)) {
427
+ const attribute = attributes[prop];
428
+ switch (attribute.type) {
429
+ case "password": {
430
+ if (!isRequest) {
431
+ break;
432
+ }
433
+ schemaAttributes[prop] = { type: "string", format: "password", example: "*******" };
434
+ break;
435
+ }
436
+ case "email": {
437
+ schemaAttributes[prop] = { type: "string", format: "email" };
438
+ break;
439
+ }
440
+ case "string":
441
+ case "text":
442
+ case "richtext": {
443
+ schemaAttributes[prop] = { type: "string" };
444
+ break;
445
+ }
446
+ case "timestamp": {
447
+ schemaAttributes[prop] = { type: "string", format: "timestamp", example: Date.now() };
448
+ break;
449
+ }
450
+ case "time": {
451
+ schemaAttributes[prop] = { type: "string", format: "time", example: "12:54.000" };
452
+ break;
453
+ }
454
+ case "date": {
455
+ schemaAttributes[prop] = { type: "string", format: "date" };
456
+ break;
457
+ }
458
+ case "datetime": {
459
+ schemaAttributes[prop] = { type: "string", format: "date-time" };
460
+ break;
461
+ }
462
+ case "boolean": {
463
+ schemaAttributes[prop] = { type: "boolean" };
464
+ break;
465
+ }
466
+ case "enumeration": {
467
+ schemaAttributes[prop] = { type: "string", enum: [...attribute.enum] };
468
+ break;
469
+ }
470
+ case "decimal":
471
+ case "float": {
472
+ schemaAttributes[prop] = { type: "number", format: "float" };
473
+ break;
474
+ }
475
+ case "integer": {
476
+ schemaAttributes[prop] = { type: "integer" };
477
+ break;
478
+ }
479
+ case "biginteger": {
480
+ schemaAttributes[prop] = { type: "string", pattern: "^\\d*$", example: "123456789" };
481
+ break;
482
+ }
483
+ case "json":
484
+ case "blocks": {
485
+ schemaAttributes[prop] = {};
486
+ break;
487
+ }
488
+ case "uid": {
489
+ schemaAttributes[prop] = { type: "string" };
490
+ break;
491
+ }
492
+ case "component": {
493
+ const componentAttributes = strapi.components[attribute.component].attributes;
494
+ const rawComponentSchema = {
495
+ type: "object",
496
+ properties: {
497
+ ...isRequest ? {} : { id: { type: "number" } },
498
+ ...cleanSchemaAttributes(componentAttributes, {
499
+ typeMap,
500
+ isRequest,
501
+ didAddStrapiComponentsToSchemas
502
+ })
503
+ }
504
+ };
505
+ const refComponentSchema = {
506
+ $ref: `#/components/schemas/${pascalCase(attribute.component)}Component`
507
+ };
508
+ const componentExists = didAddStrapiComponentsToSchemas(
509
+ `${pascalCase(attribute.component)}Component`,
510
+ rawComponentSchema
511
+ );
512
+ const finalComponentSchema = componentExists ? refComponentSchema : rawComponentSchema;
513
+ if (attribute.repeatable) {
514
+ schemaAttributes[prop] = {
515
+ type: "array",
516
+ items: finalComponentSchema
517
+ };
518
+ } else {
519
+ schemaAttributes[prop] = finalComponentSchema;
520
+ }
521
+ break;
522
+ }
523
+ case "dynamiczone": {
524
+ const components = attribute.components.map((component) => {
525
+ const componentAttributes = strapi.components[component].attributes;
526
+ const rawComponentSchema = {
527
+ type: "object",
528
+ properties: {
529
+ ...isRequest ? {} : { id: { type: "number" } },
530
+ __component: { type: "string" },
531
+ ...cleanSchemaAttributes(componentAttributes, {
532
+ typeMap,
533
+ isRequest,
534
+ didAddStrapiComponentsToSchemas
535
+ })
536
+ }
537
+ };
538
+ const refComponentSchema = {
539
+ $ref: `#/components/schemas/${pascalCase(component)}Component`
540
+ };
541
+ const componentExists = didAddStrapiComponentsToSchemas(
542
+ `${pascalCase(component)}Component`,
543
+ rawComponentSchema
544
+ );
545
+ const finalComponentSchema = componentExists ? refComponentSchema : rawComponentSchema;
546
+ return finalComponentSchema;
547
+ });
548
+ schemaAttributes[prop] = {
549
+ type: "array",
550
+ items: {
551
+ anyOf: components
552
+ }
553
+ };
554
+ break;
555
+ }
556
+ case "media": {
557
+ const imageAttributes = strapi.contentType("plugin::upload.file").attributes;
558
+ const isListOfEntities = attribute.multiple ?? false;
559
+ if (isRequest) {
560
+ const oneOfType = {
561
+ oneOf: [{ type: "integer" }, { type: "string" }],
562
+ example: "string or id"
563
+ };
564
+ schemaAttributes[prop] = isListOfEntities ? { type: "array", items: oneOfType } : oneOfType;
565
+ break;
566
+ }
567
+ schemaAttributes[prop] = getSchemaData(
568
+ isListOfEntities,
569
+ cleanSchemaAttributes(imageAttributes, { typeMap, didAddStrapiComponentsToSchemas })
570
+ );
571
+ break;
572
+ }
573
+ case "relation": {
574
+ const isListOfEntities = attribute.relation.includes("ToMany");
575
+ if (isRequest) {
576
+ const oneOfType = {
577
+ oneOf: [{ type: "integer" }, { type: "string" }],
578
+ example: "string or id"
579
+ };
580
+ schemaAttributes[prop] = isListOfEntities ? { type: "array", items: oneOfType } : oneOfType;
581
+ break;
582
+ }
583
+ if (!("target" in attribute) || !attribute.target || typeMap.has(attribute.target)) {
584
+ schemaAttributes[prop] = getSchemaData(isListOfEntities, {});
585
+ break;
586
+ }
587
+ typeMap.set(attribute.target, true);
588
+ const targetAttributes = strapi.contentType(attribute.target).attributes;
589
+ schemaAttributes[prop] = getSchemaData(
590
+ isListOfEntities,
591
+ cleanSchemaAttributes(targetAttributes, {
592
+ typeMap,
593
+ isRequest,
594
+ didAddStrapiComponentsToSchemas
595
+ })
596
+ );
597
+ break;
598
+ }
599
+ default: {
600
+ throw new Error(`Invalid type ${attribute.type} while generating open api schema.`);
601
+ }
602
+ }
603
+ }
604
+ return schemaAttributes;
605
+ };
606
+ const getRequiredAttributes = (allAttributes) => {
607
+ const requiredAttributes = [];
608
+ for (const key in allAttributes) {
609
+ if (allAttributes[key].required) {
610
+ requiredAttributes.push(key);
611
+ }
612
+ }
613
+ return requiredAttributes;
614
+ };
615
+ const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }) => {
616
+ let strapiComponentSchemas = {};
617
+ const schemas = {};
618
+ const typeName = pascalCase(uniqueName);
619
+ const didAddStrapiComponentsToSchemas = (schemaName, schema) => {
620
+ if (!Object.keys(schema) || !Object.keys(schema.properties))
621
+ return false;
622
+ strapiComponentSchemas = {
623
+ ...strapiComponentSchemas,
624
+ [schemaName]: schema
625
+ };
626
+ return true;
627
+ };
628
+ const routeMethods = routeInfo.routes.map((route) => route.method);
629
+ const attributesToOmit = [
630
+ "createdAt",
631
+ "updatedAt",
632
+ "publishedAt",
633
+ "publishedBy",
634
+ "updatedBy",
635
+ "createdBy"
636
+ ];
637
+ const attributesForRequest = ___default.default.omit(attributes, attributesToOmit);
638
+ const requiredRequestAttributes = getRequiredAttributes(attributesForRequest);
639
+ if (routeMethods.includes("POST") || routeMethods.includes("PUT")) {
640
+ Object.assign(schemas, {
641
+ [`${typeName}Request`]: {
642
+ type: "object",
643
+ required: ["data"],
644
+ properties: {
645
+ data: {
646
+ ...requiredRequestAttributes.length && { required: requiredRequestAttributes },
647
+ type: "object",
648
+ properties: cleanSchemaAttributes(attributesForRequest, {
649
+ isRequest: true,
650
+ didAddStrapiComponentsToSchemas
651
+ })
652
+ }
653
+ }
654
+ }
655
+ });
656
+ }
657
+ const hasListOfEntities = routeInfo.routes.filter(
658
+ (route) => hasFindMethod(route.handler)
659
+ ).length;
660
+ if (hasListOfEntities) {
661
+ Object.assign(schemas, {
662
+ [`${typeName}ListResponse`]: {
663
+ type: "object",
664
+ properties: {
665
+ data: {
666
+ type: "array",
667
+ items: {
668
+ $ref: `#/components/schemas/${typeName}`
669
+ }
670
+ },
671
+ meta: {
672
+ type: "object",
673
+ properties: {
674
+ pagination: {
675
+ type: "object",
676
+ properties: {
677
+ page: { type: "integer" },
678
+ pageSize: { type: "integer", minimum: 25 },
679
+ pageCount: { type: "integer", maximum: 1 },
680
+ total: { type: "integer" }
681
+ }
682
+ }
683
+ }
684
+ }
685
+ }
686
+ }
687
+ });
688
+ }
689
+ const requiredAttributes = getRequiredAttributes(attributes);
690
+ Object.assign(schemas, {
691
+ [`${typeName}`]: {
692
+ type: "object",
693
+ ...requiredAttributes.length && { required: requiredAttributes },
694
+ properties: {
695
+ id: { type: "number" },
696
+ documentId: { type: "string" },
697
+ ...cleanSchemaAttributes(attributes, { didAddStrapiComponentsToSchemas })
698
+ }
699
+ },
700
+ [`${typeName}Response`]: {
701
+ type: "object",
702
+ properties: {
703
+ data: {
704
+ $ref: `#/components/schemas/${typeName}`
705
+ },
706
+ meta: { type: "object" }
707
+ }
708
+ }
709
+ });
710
+ return { ...schemas, ...strapiComponentSchemas };
711
+ };
712
+ const buildComponentSchema = (api) => {
713
+ return loopContentTypeNames(api, getAllSchemasForContentType);
714
+ };
715
+ const getPluginsThatNeedDocumentation = (config2) => {
716
+ const defaultPlugins = ["upload", "users-permissions"];
717
+ const userPluginsConfig = config2["x-strapi-config"].plugins;
718
+ if (userPluginsConfig === null) {
719
+ return defaultPlugins;
720
+ }
721
+ if (userPluginsConfig.length) {
722
+ return userPluginsConfig;
723
+ }
724
+ return [];
725
+ };
726
+ const createService$1 = ({ strapi: strapi2 }) => {
727
+ const config2 = strapi2.config.get("plugin::documentation");
728
+ const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(config2);
729
+ const overrideService = getService("override");
730
+ return {
731
+ getDocumentationVersion() {
732
+ return config2.info.version;
733
+ },
734
+ getFullDocumentationPath() {
735
+ return path__default.default.join(strapi2.dirs.app.extensions, "documentation", "documentation");
736
+ },
737
+ getDocumentationVersions() {
738
+ return fs__default.default.readdirSync(this.getFullDocumentationPath()).map((version) => {
739
+ try {
740
+ const filePath = path__default.default.resolve(
741
+ this.getFullDocumentationPath(),
742
+ version,
743
+ "full_documentation.json"
744
+ );
745
+ const doc = JSON.parse(fs__default.default.readFileSync(filePath).toString());
746
+ const generatedDate = doc.info["x-generation-date"];
747
+ return { version, generatedDate, url: "" };
748
+ } catch (err) {
749
+ return null;
750
+ }
751
+ }).filter((x) => x);
752
+ },
753
+ /**
754
+ * Returns settings stored in core-store
755
+ */
756
+ async getDocumentationAccess() {
757
+ const { restrictedAccess } = await strapi2.store({
758
+ environment: "",
759
+ type: "plugin",
760
+ name: "documentation",
761
+ key: "config"
762
+ }).get();
763
+ return { restrictedAccess };
764
+ },
765
+ getApiDocumentationPath(api) {
766
+ if (api.getter === "plugin") {
767
+ return path__default.default.join(strapi2.dirs.app.extensions, api.name, "documentation");
768
+ }
769
+ return path__default.default.join(strapi2.dirs.app.api, api.name, "documentation");
770
+ },
771
+ async deleteDocumentation(version) {
772
+ const apis = this.getPluginAndApiInfo();
773
+ for (const api of apis) {
774
+ await fs__default.default.remove(path__default.default.join(this.getApiDocumentationPath(api), version));
775
+ }
776
+ await fs__default.default.remove(path__default.default.join(this.getFullDocumentationPath(), version));
777
+ },
778
+ getPluginAndApiInfo() {
779
+ const pluginsToDocument = pluginsThatNeedDocumentation.map((plugin) => {
780
+ return {
781
+ name: plugin,
782
+ getter: "plugin",
783
+ ctNames: Object.keys(strapi2.plugin(plugin).contentTypes)
784
+ };
785
+ });
786
+ const apisToDocument = Object.keys(strapi2.api).map((api) => {
787
+ return {
788
+ name: api,
789
+ getter: "api",
790
+ ctNames: Object.keys(strapi2.api[api].contentTypes)
791
+ };
792
+ });
793
+ return [...apisToDocument, ...pluginsToDocument];
794
+ },
795
+ /**
796
+ * @description - Creates the Swagger json files
797
+ */
798
+ async generateFullDoc(versionOpt) {
799
+ const version = versionOpt ?? this.getDocumentationVersion();
800
+ const apis = this.getPluginAndApiInfo();
801
+ const apisThatNeedGeneratedDocumentation = apis.filter(
802
+ ({ name }) => !overrideService.isEnabled(name)
803
+ );
804
+ const generatedDocumentation = await immer.produce(config2, async (draft) => {
805
+ if (draft.servers?.length === 0) {
806
+ const serverUrl = strapi2.config.get("server.absoluteUrl");
807
+ const apiPath = strapi2.config.get("api.rest.prefix");
808
+ draft.servers = [
809
+ {
810
+ url: `${serverUrl}${apiPath}`,
811
+ description: "Development server"
812
+ }
813
+ ];
814
+ }
815
+ if (!draft.components) {
816
+ draft.components = {};
817
+ }
818
+ draft.info["x-generation-date"] = (/* @__PURE__ */ new Date()).toISOString();
819
+ draft["x-strapi-config"].plugins = pluginsThatNeedDocumentation;
820
+ delete draft["x-strapi-config"].mutateDocumentation;
821
+ for (const api of apisThatNeedGeneratedDocumentation) {
822
+ const newApiPath = buildApiEndpointPath(api);
823
+ const generatedSchemas = buildComponentSchema(api);
824
+ if (generatedSchemas) {
825
+ draft.components.schemas = { ...draft.components.schemas, ...generatedSchemas };
826
+ }
827
+ if (newApiPath) {
828
+ draft.paths = { ...draft.paths, ...newApiPath };
829
+ }
830
+ }
831
+ if (overrideService.registeredOverrides.length > 0) {
832
+ overrideService.registeredOverrides.forEach((override) => {
833
+ if (!override?.info?.version || override.info.version === version) {
834
+ if (override.tags) {
835
+ draft.tags = draft.tags || [];
836
+ draft.tags.push(...override.tags);
837
+ }
838
+ if (override.paths) {
839
+ draft.paths = { ...draft.paths, ...override.paths };
840
+ }
841
+ if (override.components) {
842
+ const keys = Object.keys(override.components);
843
+ keys.forEach((overrideKey) => {
844
+ draft.components = draft.components || {};
845
+ const overrideValue = override.components?.[overrideKey];
846
+ const originalValue = draft.components?.[overrideKey];
847
+ Object.assign(draft.components, {
848
+ [overrideKey]: {
849
+ ...originalValue,
850
+ ...overrideValue
851
+ }
852
+ });
853
+ });
854
+ }
855
+ }
856
+ });
857
+ }
858
+ });
859
+ const userMutatesDocumentation = config2["x-strapi-config"].mutateDocumentation;
860
+ const finalDocumentation = userMutatesDocumentation ? immer.produce(generatedDocumentation, userMutatesDocumentation) : generatedDocumentation;
861
+ const fullDocJsonPath = path__default.default.join(
862
+ this.getFullDocumentationPath(),
863
+ version,
864
+ "full_documentation.json"
865
+ );
866
+ await fs__default.default.ensureFile(fullDocJsonPath);
867
+ await fs__default.default.writeJson(fullDocJsonPath, finalDocumentation, { spaces: 2 });
868
+ }
869
+ };
870
+ };
871
+ const createService = ({ strapi: strapi2 }) => {
872
+ const registeredOverrides = [];
873
+ const excludedFromGeneration = [];
874
+ return {
875
+ registeredOverrides,
876
+ excludedFromGeneration,
877
+ /**
878
+ *
879
+ * @param {(string | string[])} api - The name of the api or and array of apis to exclude from generation
880
+ */
881
+ excludeFromGeneration(api) {
882
+ if (Array.isArray(api)) {
883
+ excludedFromGeneration.push(...api);
884
+ return;
885
+ }
886
+ excludedFromGeneration.push(api);
887
+ },
888
+ isEnabled(name) {
889
+ return excludedFromGeneration.includes(name);
890
+ },
891
+ registerOverride(override, opts) {
892
+ const { pluginOrigin, excludeFromGeneration = [] } = opts ?? {};
893
+ const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(
894
+ strapi2.config.get("plugin::documentation")
895
+ );
896
+ if (pluginOrigin && !pluginsThatNeedDocumentation.includes(pluginOrigin))
897
+ return;
898
+ if (excludeFromGeneration.length) {
899
+ this.excludeFromGeneration(excludeFromGeneration);
900
+ }
901
+ let overrideToRegister = override;
902
+ if (typeof override === "string") {
903
+ overrideToRegister = require("yaml").parse(overrideToRegister);
904
+ }
905
+ registeredOverrides.push(overrideToRegister);
906
+ }
907
+ };
908
+ };
909
+ const services = {
910
+ documentation: createService$1,
911
+ override: createService
912
+ };
913
+ const restrictAccess = async (ctx, next) => {
914
+ const pluginStore = strapi.store({ type: "plugin", name: "documentation" });
915
+ const config2 = await pluginStore.get({ key: "config" });
916
+ if (!config2.restrictedAccess) {
917
+ return next();
918
+ }
919
+ if (!ctx.session || !ctx.session.documentation || !ctx.session.documentation.logged) {
920
+ const querystring = ctx.querystring ? `?${ctx.querystring}` : "";
921
+ return ctx.redirect(`${strapi.config.server.url}/documentation/login${querystring}`);
922
+ }
923
+ return next();
924
+ };
925
+ const routes = [
926
+ {
927
+ method: "GET",
928
+ path: "/",
929
+ handler: "documentation.index",
930
+ config: {
931
+ auth: false,
932
+ middlewares: [restrictAccess]
933
+ }
934
+ },
935
+ {
936
+ method: "GET",
937
+ path: "/v:major(\\d+).:minor(\\d+).:patch(\\d+)",
938
+ handler: "documentation.index",
939
+ config: {
940
+ auth: false,
941
+ middlewares: [restrictAccess]
942
+ }
943
+ },
944
+ {
945
+ method: "GET",
946
+ path: "/login",
947
+ handler: "documentation.loginView",
948
+ config: {
949
+ auth: false
950
+ }
951
+ },
952
+ {
953
+ method: "POST",
954
+ path: "/login",
955
+ handler: "documentation.login",
956
+ config: {
957
+ auth: false
958
+ }
959
+ },
960
+ {
961
+ method: "GET",
962
+ path: "/getInfos",
963
+ handler: "documentation.getInfos",
964
+ config: {
965
+ policies: [
966
+ { name: "admin::hasPermissions", config: { actions: ["plugin::documentation.read"] } }
967
+ ]
968
+ }
969
+ },
970
+ {
971
+ method: "POST",
972
+ path: "/regenerateDoc",
973
+ handler: "documentation.regenerateDoc",
974
+ config: {
975
+ policies: [
976
+ {
977
+ name: "admin::hasPermissions",
978
+ config: { actions: ["plugin::documentation.settings.regenerate"] }
979
+ }
980
+ ]
981
+ }
982
+ },
983
+ {
984
+ method: "PUT",
985
+ path: "/updateSettings",
986
+ handler: "documentation.updateSettings",
987
+ config: {
988
+ policies: [
989
+ {
990
+ name: "admin::hasPermissions",
991
+ config: { actions: ["plugin::documentation.settings.update"] }
992
+ }
993
+ ]
994
+ }
995
+ },
996
+ {
997
+ method: "DELETE",
998
+ path: "/deleteDoc/:version",
999
+ handler: "documentation.deleteDoc",
1000
+ config: {
1001
+ policies: []
1002
+ }
1003
+ }
1004
+ ];
1005
+ const validation = {
1006
+ validatSettings: utils.validateYupSchema(
1007
+ utils.yup.object().shape({
1008
+ restrictedAccess: utils.yup.boolean(),
1009
+ password: utils.yup.string().min(8).matches(/[a-z]/, "${path} must contain at least one lowercase character").matches(/[A-Z]/, "${path} must contain at least one uppercase character").matches(/\d/, "${path} must contain at least one number").when("restrictedAccess", (value, initSchema) => {
1010
+ return value ? initSchema.required("password is required") : initSchema;
1011
+ })
1012
+ })
1013
+ )
1014
+ };
1015
+ const documentation = {
1016
+ async getInfos(ctx) {
1017
+ try {
1018
+ const docService = getService("documentation");
1019
+ const docVersions = docService.getDocumentationVersions();
1020
+ const documentationAccess = await docService.getDocumentationAccess();
1021
+ ctx.send({
1022
+ docVersions,
1023
+ currentVersion: docService.getDocumentationVersion(),
1024
+ prefix: "/documentation",
1025
+ documentationAccess
1026
+ });
1027
+ } catch (err) {
1028
+ strapi.log.error(err);
1029
+ ctx.badRequest();
1030
+ }
1031
+ },
1032
+ async index(ctx, next) {
1033
+ try {
1034
+ const { major, minor, patch } = ctx.params;
1035
+ const version = major && minor && patch ? `${major}.${minor}.${patch}` : getService("documentation").getDocumentationVersion();
1036
+ const openAPISpecsPath = path__default.default.join(
1037
+ strapi.dirs.app.extensions,
1038
+ "documentation",
1039
+ "documentation",
1040
+ version,
1041
+ "full_documentation.json"
1042
+ );
1043
+ try {
1044
+ const documentation2 = fs__default.default.readFileSync(openAPISpecsPath, "utf8");
1045
+ const layout = (await Promise.resolve().then(() => require("../_chunks/index-WbbYm9_u.js"))).default;
1046
+ const filledLayout = ___default.default.template(layout)({
1047
+ backendUrl: strapi.config.server.url,
1048
+ spec: JSON.stringify(JSON.parse(documentation2))
1049
+ });
1050
+ try {
1051
+ const layoutPath = path__default.default.resolve(
1052
+ strapi.dirs.app.extensions,
1053
+ "documentation",
1054
+ "public",
1055
+ "index.html"
1056
+ );
1057
+ await fs__default.default.ensureFile(layoutPath);
1058
+ await fs__default.default.writeFile(layoutPath, filledLayout);
1059
+ ctx.url = path__default.default.basename(`${ctx.url}/index.html`);
1060
+ try {
1061
+ const staticFolder = path__default.default.resolve(
1062
+ strapi.dirs.app.extensions,
1063
+ "documentation",
1064
+ "public"
1065
+ );
1066
+ return koaStatic__default.default(staticFolder)(ctx, next);
1067
+ } catch (e) {
1068
+ strapi.log.error(e);
1069
+ }
1070
+ } catch (e) {
1071
+ strapi.log.error(e);
1072
+ }
1073
+ } catch (e) {
1074
+ strapi.log.error(e);
1075
+ }
1076
+ } catch (e) {
1077
+ strapi.log.error(e);
1078
+ }
1079
+ },
1080
+ async loginView(ctx, next) {
1081
+ const cheerio = require("cheerio");
1082
+ const { error } = ctx.query;
1083
+ try {
1084
+ const layout = (await Promise.resolve().then(() => require("../_chunks/login-HAajOKpu.js"))).default;
1085
+ const filledLayout = ___default.default.template(layout.toString())({
1086
+ actionUrl: `${strapi.config.server.url}/documentation/login`
1087
+ });
1088
+ const $ = cheerio.load(filledLayout);
1089
+ $(".error").text(___default.default.isEmpty(error) ? "" : "Wrong password...");
1090
+ try {
1091
+ const layoutPath = path__default.default.resolve(
1092
+ strapi.dirs.app.extensions,
1093
+ "documentation",
1094
+ "public",
1095
+ "login.html"
1096
+ );
1097
+ await fs__default.default.ensureFile(layoutPath);
1098
+ await fs__default.default.writeFile(layoutPath, $.html());
1099
+ ctx.url = path__default.default.basename(`${ctx.url}/login.html`);
1100
+ try {
1101
+ const staticFolder = path__default.default.resolve(strapi.dirs.app.extensions, "documentation", "public");
1102
+ return koaStatic__default.default(staticFolder)(ctx, next);
1103
+ } catch (e) {
1104
+ strapi.log.error(e);
1105
+ }
1106
+ } catch (e) {
1107
+ strapi.log.error(e);
1108
+ }
1109
+ } catch (e) {
1110
+ strapi.log.error(e);
1111
+ }
1112
+ },
1113
+ async login(ctx) {
1114
+ const {
1115
+ body: { password }
1116
+ } = ctx.request;
1117
+ const { password: hash } = await strapi.store({ type: "plugin", name: "documentation", key: "config" }).get();
1118
+ const isValid = await bcrypt__default.default.compare(password, hash);
1119
+ let querystring = "?error=password";
1120
+ if (isValid && ctx.session) {
1121
+ ctx.session.documentation = {
1122
+ logged: true
1123
+ };
1124
+ querystring = "";
1125
+ }
1126
+ ctx.redirect(`${strapi.config.server.url}/documentation${querystring}`);
1127
+ },
1128
+ async regenerateDoc(ctx) {
1129
+ const { version } = ctx.request.body;
1130
+ const service = getService("documentation");
1131
+ const documentationVersions = service.getDocumentationVersions().map((el) => el.version);
1132
+ if (___default.default.isEmpty(version)) {
1133
+ return ctx.badRequest("Please provide a version.");
1134
+ }
1135
+ if (!documentationVersions.includes(version)) {
1136
+ return ctx.badRequest("The version you are trying to generate does not exist.");
1137
+ }
1138
+ try {
1139
+ strapi.reload.isWatching = false;
1140
+ await service.generateFullDoc(version);
1141
+ ctx.send({ ok: true });
1142
+ } finally {
1143
+ strapi.reload.isWatching = true;
1144
+ }
1145
+ },
1146
+ async deleteDoc(ctx) {
1147
+ const { version } = ctx.params;
1148
+ const service = getService("documentation");
1149
+ const documentationVersions = service.getDocumentationVersions().map((el) => el.version);
1150
+ if (___default.default.isEmpty(version)) {
1151
+ return ctx.badRequest("Please provide a version.");
1152
+ }
1153
+ if (!documentationVersions.includes(version)) {
1154
+ return ctx.badRequest("The version you are trying to delete does not exist.");
1155
+ }
1156
+ try {
1157
+ strapi.reload.isWatching = false;
1158
+ await service.deleteDocumentation(version);
1159
+ ctx.send({ ok: true });
1160
+ } finally {
1161
+ strapi.reload.isWatching = true;
1162
+ }
1163
+ },
1164
+ async updateSettings(ctx) {
1165
+ const pluginStore = strapi.store({ type: "plugin", name: "documentation" });
1166
+ const data = await validation.validatSettings(ctx.request.body);
1167
+ const config2 = {
1168
+ restrictedAccess: Boolean(data.restrictedAccess)
1169
+ };
1170
+ if (data.password) {
1171
+ config2.password = await bcrypt__default.default.hash(data.password, 10);
1172
+ }
1173
+ await pluginStore.set({ key: "config", value: config2 });
1174
+ return ctx.send({ ok: true });
1175
+ }
1176
+ };
1177
+ const controllers = {
1178
+ documentation
1179
+ };
1180
+ const defaultConfig = {
1181
+ openapi: "3.0.0",
1182
+ info: {
1183
+ version: "1.0.0",
1184
+ title: "DOCUMENTATION",
1185
+ description: "",
1186
+ termsOfService: "YOUR_TERMS_OF_SERVICE_URL",
1187
+ contact: {
1188
+ name: "TEAM",
1189
+ email: "contact-email@something.io",
1190
+ url: "mywebsite.io"
1191
+ },
1192
+ license: {
1193
+ name: "Apache 2.0",
1194
+ url: "https://www.apache.org/licenses/LICENSE-2.0.html"
1195
+ }
1196
+ },
1197
+ "x-strapi-config": {
1198
+ plugins: null,
1199
+ mutateDocumentation: null
1200
+ },
1201
+ servers: [],
1202
+ externalDocs: {
1203
+ description: "Find out more",
1204
+ url: "https://docs.strapi.io/developer-docs/latest/getting-started/introduction.html"
1205
+ },
1206
+ security: [
1207
+ {
1208
+ bearerAuth: []
1209
+ }
1210
+ ],
1211
+ paths: {},
1212
+ components: {
1213
+ securitySchemes: {
1214
+ bearerAuth: {
1215
+ type: "http",
1216
+ scheme: "bearer",
1217
+ bearerFormat: "JWT"
1218
+ }
1219
+ },
1220
+ schemas: {
1221
+ Error: {
1222
+ type: "object",
1223
+ required: ["error"],
1224
+ properties: {
1225
+ data: {
1226
+ nullable: true,
1227
+ oneOf: [{ type: "object" }, { type: "array", items: { type: "object" } }]
1228
+ },
1229
+ error: {
1230
+ type: "object",
1231
+ properties: {
1232
+ status: {
1233
+ type: "integer"
1234
+ },
1235
+ name: {
1236
+ type: "string"
1237
+ },
1238
+ message: {
1239
+ type: "string"
1240
+ },
1241
+ details: {
1242
+ type: "object"
1243
+ }
1244
+ }
1245
+ }
1246
+ }
1247
+ }
1248
+ }
1249
+ }
1250
+ };
1251
+ const config = {
1252
+ default: defaultConfig
1253
+ };
1254
+ const index = {
1255
+ bootstrap,
1256
+ config,
1257
+ routes,
1258
+ controllers,
1259
+ register,
1260
+ services
1261
+ };
1262
+ module.exports = index;
1263
+ //# sourceMappingURL=index.js.map