@strapi/plugin-documentation 0.0.0-experimental.6340da17068c3bed7fb006e7bcc554c71129e282 → 0.0.0-experimental.63624e21eb5b0713345a0cf2f68f1c40eab427bc

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 (78) hide show
  1. package/README.md +1 -1
  2. package/dist/admin/pages/App.js.map +1 -1
  3. package/dist/admin/pages/App.mjs.map +1 -1
  4. package/dist/admin/pages/Settings.js +2 -2
  5. package/dist/admin/pages/Settings.js.map +1 -1
  6. package/dist/admin/pages/Settings.mjs +2 -2
  7. package/dist/admin/pages/Settings.mjs.map +1 -1
  8. package/dist/admin/src/services/api.d.ts +4 -4
  9. package/dist/admin/translations/ko.json.js +4 -1
  10. package/dist/admin/translations/ko.json.js.map +1 -1
  11. package/dist/admin/translations/ko.json.mjs +4 -1
  12. package/dist/admin/translations/ko.json.mjs.map +1 -1
  13. package/dist/server/controllers/documentation.js +6 -1
  14. package/dist/server/controllers/documentation.js.map +1 -1
  15. package/dist/server/controllers/documentation.mjs +6 -1
  16. package/dist/server/controllers/documentation.mjs.map +1 -1
  17. package/dist/server/controllers/index.js.map +1 -1
  18. package/dist/server/controllers/index.mjs.map +1 -1
  19. package/dist/server/index.js.map +1 -1
  20. package/dist/server/index.mjs.map +1 -1
  21. package/dist/server/routes/index.js +2 -1
  22. package/dist/server/routes/index.js.map +1 -1
  23. package/dist/server/routes/index.mjs +2 -1
  24. package/dist/server/routes/index.mjs.map +1 -1
  25. package/dist/server/services/documentation.js +40 -8
  26. package/dist/server/services/documentation.js.map +1 -1
  27. package/dist/server/services/documentation.mjs +41 -9
  28. package/dist/server/services/documentation.mjs.map +1 -1
  29. package/dist/server/services/helpers/build-component-schema.js +21 -6
  30. package/dist/server/services/helpers/build-component-schema.js.map +1 -1
  31. package/dist/server/services/helpers/build-component-schema.mjs +18 -6
  32. package/dist/server/services/helpers/build-component-schema.mjs.map +1 -1
  33. package/dist/server/services/helpers/utils/clean-schema-attributes.js +14 -13
  34. package/dist/server/services/helpers/utils/clean-schema-attributes.js.map +1 -1
  35. package/dist/server/services/helpers/utils/clean-schema-attributes.mjs +14 -13
  36. package/dist/server/services/helpers/utils/clean-schema-attributes.mjs.map +1 -1
  37. package/dist/server/services/helpers/utils/loop-content-type-names.js +1 -0
  38. package/dist/server/services/helpers/utils/loop-content-type-names.js.map +1 -1
  39. package/dist/server/services/helpers/utils/loop-content-type-names.mjs +1 -0
  40. package/dist/server/services/helpers/utils/loop-content-type-names.mjs.map +1 -1
  41. package/dist/server/services/helpers/utils/query-params.js +11 -1
  42. package/dist/server/services/helpers/utils/query-params.js.map +1 -1
  43. package/dist/server/services/helpers/utils/query-params.mjs +11 -1
  44. package/dist/server/services/helpers/utils/query-params.mjs.map +1 -1
  45. package/dist/server/services/index.js.map +1 -1
  46. package/dist/server/services/index.mjs.map +1 -1
  47. package/dist/server/services/override.js +19 -3
  48. package/dist/server/services/override.js.map +1 -1
  49. package/dist/server/services/override.mjs +19 -3
  50. package/dist/server/services/override.mjs.map +1 -1
  51. package/dist/server/src/config/index.d.ts +1 -1
  52. package/dist/server/src/controllers/documentation.d.ts.map +1 -1
  53. package/dist/server/src/controllers/index.d.ts.map +1 -1
  54. package/dist/server/src/index.d.ts +5 -2
  55. package/dist/server/src/index.d.ts.map +1 -1
  56. package/dist/server/src/routes/index.d.ts +4 -3
  57. package/dist/server/src/routes/index.d.ts.map +1 -1
  58. package/dist/server/src/services/documentation.d.ts +35 -0
  59. package/dist/server/src/services/documentation.d.ts.map +1 -1
  60. package/dist/server/src/services/helpers/build-component-schema.d.ts +3 -1
  61. package/dist/server/src/services/helpers/build-component-schema.d.ts.map +1 -1
  62. package/dist/server/src/services/helpers/index.d.ts +2 -2
  63. package/dist/server/src/services/helpers/index.d.ts.map +1 -1
  64. package/dist/server/src/services/helpers/utils/clean-schema-attributes.d.ts +2 -2
  65. package/dist/server/src/services/helpers/utils/clean-schema-attributes.d.ts.map +1 -1
  66. package/dist/server/src/services/helpers/utils/loop-content-type-names.d.ts.map +1 -1
  67. package/dist/server/src/services/helpers/utils/query-params.d.ts.map +1 -1
  68. package/dist/server/src/services/index.d.ts +5 -4
  69. package/dist/server/src/services/index.d.ts.map +1 -1
  70. package/dist/server/src/services/override.d.ts +16 -0
  71. package/dist/server/src/services/override.d.ts.map +1 -1
  72. package/dist/server/src/types/controllers.d.ts +26 -0
  73. package/dist/server/src/types/controllers.d.ts.map +1 -0
  74. package/dist/server/src/types/services.d.ts +47 -0
  75. package/dist/server/src/types/services.d.ts.map +1 -0
  76. package/dist/server/src/types.d.ts +1 -0
  77. package/dist/server/src/types.d.ts.map +1 -1
  78. package/package.json +28 -16
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../server/src/routes/index.ts"],"sourcesContent":["import restrictAccess from '../middlewares/restrict-access';\n\nexport default [\n {\n method: 'GET',\n path: '/',\n handler: 'documentation.index',\n config: {\n auth: false,\n middlewares: [restrictAccess],\n },\n },\n {\n method: 'GET',\n path: '/v:major(\\\\d+).:minor(\\\\d+).:patch(\\\\d+)',\n handler: 'documentation.index',\n config: {\n auth: false,\n middlewares: [restrictAccess],\n },\n },\n {\n method: 'GET',\n path: '/login',\n handler: 'documentation.loginView',\n config: {\n auth: false,\n },\n },\n {\n method: 'POST',\n path: '/login',\n handler: 'documentation.login',\n config: {\n auth: false,\n },\n },\n {\n method: 'GET',\n path: '/getInfos',\n handler: 'documentation.getInfos',\n config: {\n policies: [\n { name: 'admin::hasPermissions', config: { actions: ['plugin::documentation.read'] } },\n ],\n },\n },\n {\n method: 'POST',\n path: '/regenerateDoc',\n handler: 'documentation.regenerateDoc',\n config: {\n policies: [\n {\n name: 'admin::hasPermissions',\n config: { actions: ['plugin::documentation.settings.regenerate'] },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/updateSettings',\n handler: 'documentation.updateSettings',\n config: {\n policies: [\n {\n name: 'admin::hasPermissions',\n config: { actions: ['plugin::documentation.settings.update'] },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/deleteDoc/:version',\n handler: 'documentation.deleteDoc',\n config: {\n policies: [],\n },\n },\n];\n"],"names":["method","path","handler","config","auth","middlewares","restrictAccess","policies","name","actions"],"mappings":";;;;AAEA,aAAe;AACb,IAAA;QACEA,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,GAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM,KAAA;YACNC,WAAAA,EAAa;AAACC,gBAAAA;AAAe;AAC/B;AACF,KAAA;AACA,IAAA;QACEN,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,0CAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM,KAAA;YACNC,WAAAA,EAAa;AAACC,gBAAAA;AAAe;AAC/B;AACF,KAAA;AACA,IAAA;QACEN,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,QAAA;QACNC,OAAAA,EAAS,yBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM;AACR;AACF,KAAA;AACA,IAAA;QACEJ,MAAAA,EAAQ,MAAA;QACRC,IAAAA,EAAM,QAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM;AACR;AACF,KAAA;AACA,IAAA;QACEJ,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,WAAA;QACNC,OAAAA,EAAS,wBAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBAAEC,IAAAA,EAAM,uBAAA;oBAAyBL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAA6B;AAAC;AAAE;AACtF;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,MAAA;QACRC,IAAAA,EAAM,gBAAA;QACNC,OAAAA,EAAS,6BAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBACEC,IAAAA,EAAM,uBAAA;oBACNL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAA4C;AAAC;AACnE;AACD;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,iBAAA;QACNC,OAAAA,EAAS,8BAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBACEC,IAAAA,EAAM,uBAAA;oBACNL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAAwC;AAAC;AAC/D;AACD;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,QAAA;QACRC,IAAAA,EAAM,qBAAA;QACNC,OAAAA,EAAS,yBAAA;QACTC,MAAAA,EAAQ;AACNI,YAAAA,QAAAA,EAAU;AACZ;AACF;CACD;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../server/src/routes/index.ts"],"sourcesContent":["import type Koa from 'koa';\nimport type { Core } from '@strapi/types';\nimport type { Controllers } from '../types/controllers';\nimport restrictAccess from '../middlewares/restrict-access';\n\n// The published type stays the one develop infers; `satisfies` checks the literals.\nconst routes: (\n | {\n method: string;\n path: string;\n handler: string;\n config: {\n auth: boolean;\n middlewares: ((ctx: Koa.Context, next: Koa.Next) => Promise<any>)[];\n policies?: undefined;\n };\n }\n | {\n method: string;\n path: string;\n handler: string;\n config: {\n auth: boolean;\n middlewares?: undefined;\n policies?: undefined;\n };\n }\n | {\n method: string;\n path: string;\n handler: string;\n config: {\n policies: { name: string; config: { actions: string[] } }[];\n auth?: undefined;\n middlewares?: undefined;\n };\n }\n)[] = [\n {\n method: 'GET',\n path: '/',\n handler: 'documentation.index',\n config: {\n auth: false,\n middlewares: [restrictAccess],\n },\n },\n {\n method: 'GET',\n path: '/v:major(\\\\d+).:minor(\\\\d+).:patch(\\\\d+)',\n handler: 'documentation.index',\n config: {\n auth: false,\n middlewares: [restrictAccess],\n },\n },\n {\n method: 'GET',\n path: '/login',\n handler: 'documentation.loginView',\n config: {\n auth: false,\n },\n },\n {\n method: 'POST',\n path: '/login',\n handler: 'documentation.login',\n config: {\n auth: false,\n },\n },\n {\n method: 'GET',\n path: '/getInfos',\n handler: 'documentation.getInfos',\n config: {\n policies: [\n { name: 'admin::hasPermissions', config: { actions: ['plugin::documentation.read'] } },\n ],\n },\n },\n {\n method: 'POST',\n path: '/regenerateDoc',\n handler: 'documentation.regenerateDoc',\n config: {\n policies: [\n {\n name: 'admin::hasPermissions',\n config: { actions: ['plugin::documentation.settings.regenerate'] },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/updateSettings',\n handler: 'documentation.updateSettings',\n config: {\n policies: [\n {\n name: 'admin::hasPermissions',\n config: { actions: ['plugin::documentation.settings.update'] },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/deleteDoc/:version',\n handler: 'documentation.deleteDoc',\n config: {\n policies: [],\n },\n },\n] satisfies Core.RouteInputFor<Controllers, 'plugin::documentation'>[];\n\nexport default routes;\n"],"names":["routes","method","path","handler","config","auth","middlewares","restrictAccess","policies","name","actions"],"mappings":";;;;AAKA;AACA,MAAMA,MAAAA,GA+BA;AACJ,IAAA;QACEC,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,GAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM,KAAA;YACNC,WAAAA,EAAa;AAACC,gBAAAA;AAAe;AAC/B;AACF,KAAA;AACA,IAAA;QACEN,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,0CAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM,KAAA;YACNC,WAAAA,EAAa;AAACC,gBAAAA;AAAe;AAC/B;AACF,KAAA;AACA,IAAA;QACEN,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,QAAA;QACNC,OAAAA,EAAS,yBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM;AACR;AACF,KAAA;AACA,IAAA;QACEJ,MAAAA,EAAQ,MAAA;QACRC,IAAAA,EAAM,QAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM;AACR;AACF,KAAA;AACA,IAAA;QACEJ,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,WAAA;QACNC,OAAAA,EAAS,wBAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBAAEC,IAAAA,EAAM,uBAAA;oBAAyBL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAA6B;AAAC;AAAE;AACtF;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,MAAA;QACRC,IAAAA,EAAM,gBAAA;QACNC,OAAAA,EAAS,6BAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBACEC,IAAAA,EAAM,uBAAA;oBACNL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAA4C;AAAC;AACnE;AACD;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,iBAAA;QACNC,OAAAA,EAAS,8BAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBACEC,IAAAA,EAAM,uBAAA;oBACNL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAAwC;AAAC;AAC/D;AACD;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,QAAA;QACRC,IAAAA,EAAM,qBAAA;QACNC,OAAAA,EAAS,yBAAA;QACTC,MAAAA,EAAQ;AACNI,YAAAA,QAAAA,EAAU;AACZ;AACF;AACD;;;;"}
@@ -1,6 +1,7 @@
1
1
  import restrictAccess from '../middlewares/restrict-access.mjs';
2
2
 
3
- var routes = [
3
+ // The published type stays the one develop infers; `satisfies` checks the literals.
4
+ const routes = [
4
5
  {
5
6
  method: 'GET',
6
7
  path: '/',
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../../../server/src/routes/index.ts"],"sourcesContent":["import restrictAccess from '../middlewares/restrict-access';\n\nexport default [\n {\n method: 'GET',\n path: '/',\n handler: 'documentation.index',\n config: {\n auth: false,\n middlewares: [restrictAccess],\n },\n },\n {\n method: 'GET',\n path: '/v:major(\\\\d+).:minor(\\\\d+).:patch(\\\\d+)',\n handler: 'documentation.index',\n config: {\n auth: false,\n middlewares: [restrictAccess],\n },\n },\n {\n method: 'GET',\n path: '/login',\n handler: 'documentation.loginView',\n config: {\n auth: false,\n },\n },\n {\n method: 'POST',\n path: '/login',\n handler: 'documentation.login',\n config: {\n auth: false,\n },\n },\n {\n method: 'GET',\n path: '/getInfos',\n handler: 'documentation.getInfos',\n config: {\n policies: [\n { name: 'admin::hasPermissions', config: { actions: ['plugin::documentation.read'] } },\n ],\n },\n },\n {\n method: 'POST',\n path: '/regenerateDoc',\n handler: 'documentation.regenerateDoc',\n config: {\n policies: [\n {\n name: 'admin::hasPermissions',\n config: { actions: ['plugin::documentation.settings.regenerate'] },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/updateSettings',\n handler: 'documentation.updateSettings',\n config: {\n policies: [\n {\n name: 'admin::hasPermissions',\n config: { actions: ['plugin::documentation.settings.update'] },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/deleteDoc/:version',\n handler: 'documentation.deleteDoc',\n config: {\n policies: [],\n },\n },\n];\n"],"names":["method","path","handler","config","auth","middlewares","restrictAccess","policies","name","actions"],"mappings":";;AAEA,aAAe;AACb,IAAA;QACEA,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,GAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM,KAAA;YACNC,WAAAA,EAAa;AAACC,gBAAAA;AAAe;AAC/B;AACF,KAAA;AACA,IAAA;QACEN,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,0CAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM,KAAA;YACNC,WAAAA,EAAa;AAACC,gBAAAA;AAAe;AAC/B;AACF,KAAA;AACA,IAAA;QACEN,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,QAAA;QACNC,OAAAA,EAAS,yBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM;AACR;AACF,KAAA;AACA,IAAA;QACEJ,MAAAA,EAAQ,MAAA;QACRC,IAAAA,EAAM,QAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM;AACR;AACF,KAAA;AACA,IAAA;QACEJ,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,WAAA;QACNC,OAAAA,EAAS,wBAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBAAEC,IAAAA,EAAM,uBAAA;oBAAyBL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAA6B;AAAC;AAAE;AACtF;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,MAAA;QACRC,IAAAA,EAAM,gBAAA;QACNC,OAAAA,EAAS,6BAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBACEC,IAAAA,EAAM,uBAAA;oBACNL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAA4C;AAAC;AACnE;AACD;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,iBAAA;QACNC,OAAAA,EAAS,8BAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBACEC,IAAAA,EAAM,uBAAA;oBACNL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAAwC;AAAC;AAC/D;AACD;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,QAAA;QACRC,IAAAA,EAAM,qBAAA;QACNC,OAAAA,EAAS,yBAAA;QACTC,MAAAA,EAAQ;AACNI,YAAAA,QAAAA,EAAU;AACZ;AACF;CACD;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../../server/src/routes/index.ts"],"sourcesContent":["import type Koa from 'koa';\nimport type { Core } from '@strapi/types';\nimport type { Controllers } from '../types/controllers';\nimport restrictAccess from '../middlewares/restrict-access';\n\n// The published type stays the one develop infers; `satisfies` checks the literals.\nconst routes: (\n | {\n method: string;\n path: string;\n handler: string;\n config: {\n auth: boolean;\n middlewares: ((ctx: Koa.Context, next: Koa.Next) => Promise<any>)[];\n policies?: undefined;\n };\n }\n | {\n method: string;\n path: string;\n handler: string;\n config: {\n auth: boolean;\n middlewares?: undefined;\n policies?: undefined;\n };\n }\n | {\n method: string;\n path: string;\n handler: string;\n config: {\n policies: { name: string; config: { actions: string[] } }[];\n auth?: undefined;\n middlewares?: undefined;\n };\n }\n)[] = [\n {\n method: 'GET',\n path: '/',\n handler: 'documentation.index',\n config: {\n auth: false,\n middlewares: [restrictAccess],\n },\n },\n {\n method: 'GET',\n path: '/v:major(\\\\d+).:minor(\\\\d+).:patch(\\\\d+)',\n handler: 'documentation.index',\n config: {\n auth: false,\n middlewares: [restrictAccess],\n },\n },\n {\n method: 'GET',\n path: '/login',\n handler: 'documentation.loginView',\n config: {\n auth: false,\n },\n },\n {\n method: 'POST',\n path: '/login',\n handler: 'documentation.login',\n config: {\n auth: false,\n },\n },\n {\n method: 'GET',\n path: '/getInfos',\n handler: 'documentation.getInfos',\n config: {\n policies: [\n { name: 'admin::hasPermissions', config: { actions: ['plugin::documentation.read'] } },\n ],\n },\n },\n {\n method: 'POST',\n path: '/regenerateDoc',\n handler: 'documentation.regenerateDoc',\n config: {\n policies: [\n {\n name: 'admin::hasPermissions',\n config: { actions: ['plugin::documentation.settings.regenerate'] },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/updateSettings',\n handler: 'documentation.updateSettings',\n config: {\n policies: [\n {\n name: 'admin::hasPermissions',\n config: { actions: ['plugin::documentation.settings.update'] },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/deleteDoc/:version',\n handler: 'documentation.deleteDoc',\n config: {\n policies: [],\n },\n },\n] satisfies Core.RouteInputFor<Controllers, 'plugin::documentation'>[];\n\nexport default routes;\n"],"names":["routes","method","path","handler","config","auth","middlewares","restrictAccess","policies","name","actions"],"mappings":";;AAKA;AACA,MAAMA,MAAAA,GA+BA;AACJ,IAAA;QACEC,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,GAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM,KAAA;YACNC,WAAAA,EAAa;AAACC,gBAAAA;AAAe;AAC/B;AACF,KAAA;AACA,IAAA;QACEN,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,0CAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM,KAAA;YACNC,WAAAA,EAAa;AAACC,gBAAAA;AAAe;AAC/B;AACF,KAAA;AACA,IAAA;QACEN,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,QAAA;QACNC,OAAAA,EAAS,yBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM;AACR;AACF,KAAA;AACA,IAAA;QACEJ,MAAAA,EAAQ,MAAA;QACRC,IAAAA,EAAM,QAAA;QACNC,OAAAA,EAAS,qBAAA;QACTC,MAAAA,EAAQ;YACNC,IAAAA,EAAM;AACR;AACF,KAAA;AACA,IAAA;QACEJ,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,WAAA;QACNC,OAAAA,EAAS,wBAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBAAEC,IAAAA,EAAM,uBAAA;oBAAyBL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAA6B;AAAC;AAAE;AACtF;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,MAAA;QACRC,IAAAA,EAAM,gBAAA;QACNC,OAAAA,EAAS,6BAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBACEC,IAAAA,EAAM,uBAAA;oBACNL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAA4C;AAAC;AACnE;AACD;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,KAAA;QACRC,IAAAA,EAAM,iBAAA;QACNC,OAAAA,EAAS,8BAAA;QACTC,MAAAA,EAAQ;YACNI,QAAAA,EAAU;AACR,gBAAA;oBACEC,IAAAA,EAAM,uBAAA;oBACNL,MAAAA,EAAQ;wBAAEM,OAAAA,EAAS;AAAC,4BAAA;AAAwC;AAAC;AAC/D;AACD;AACH;AACF,KAAA;AACA,IAAA;QACET,MAAAA,EAAQ,QAAA;QACRC,IAAAA,EAAM,qBAAA;QACNC,OAAAA,EAAS,yBAAA;QACTC,MAAAA,EAAQ;AACNI,YAAAA,QAAAA,EAAU;AACZ;AACF;AACD;;;;"}
@@ -18,16 +18,29 @@ const createService = ({ strapi })=>{
18
18
  const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation.getPluginsThatNeedDocumentation(config);
19
19
  const overrideService = utils.getService('override');
20
20
  return {
21
- getDocumentationVersion () {
21
+ /**
22
+ * The documentation version of the plugin config (`info.version`).
23
+ *
24
+ * @internal
25
+ */ getDocumentationVersion () {
22
26
  return config.info.version;
23
27
  },
24
- getFullDocumentationPath () {
28
+ /**
29
+ * The folder that holds one folder per generated version, each with its
30
+ * `full_documentation.json`.
31
+ *
32
+ * @internal
33
+ */ getFullDocumentationPath () {
25
34
  // In production, documentation files live under dist/src/extensions/
26
35
  // after the build step. Use dist.extensions for reading.
27
36
  const extensionsDir = strapi.config.environment === 'production' ? strapi.dirs.dist.extensions : strapi.dirs.app.extensions;
28
37
  return path__default.default.join(extensionsDir, 'documentation', 'documentation');
29
38
  },
30
- getDocumentationVersions () {
39
+ /**
40
+ * The generated versions. A version whose file cannot be read is left out.
41
+ *
42
+ * @internal
43
+ */ getDocumentationVersions () {
31
44
  return fs__default.default.readdirSync(this.getFullDocumentationPath()).map((version)=>{
32
45
  try {
33
46
  const filePath = path__default.default.resolve(this.getFullDocumentationPath(), version, 'full_documentation.json');
@@ -38,13 +51,15 @@ const createService = ({ strapi })=>{
38
51
  generatedDate,
39
52
  url: ''
40
53
  };
41
- } catch (err) {
54
+ } catch {
42
55
  return null;
43
56
  }
44
57
  }).filter((x)=>x);
45
58
  },
46
59
  /**
47
60
  * Returns settings stored in core-store
61
+ *
62
+ * @internal
48
63
  */ async getDocumentationAccess () {
49
64
  const { restrictedAccess } = await strapi.store({
50
65
  environment: '',
@@ -56,7 +71,11 @@ const createService = ({ strapi })=>{
56
71
  restrictedAccess
57
72
  };
58
73
  },
59
- getApiDocumentationPath (api) {
74
+ /**
75
+ * The documentation folder of an API (`getter: 'api'`) or of a plugin (`getter: 'plugin'`).
76
+ *
77
+ * @internal
78
+ */ getApiDocumentationPath (api) {
60
79
  const isProduction = strapi.config.environment === 'production';
61
80
  if (api.getter === 'plugin') {
62
81
  const extensionsDir = isProduction ? strapi.dirs.dist.extensions : strapi.dirs.app.extensions;
@@ -65,14 +84,22 @@ const createService = ({ strapi })=>{
65
84
  const apiDir = isProduction ? strapi.dirs.dist.api : strapi.dirs.app.api;
66
85
  return path__default.default.join(apiDir, api.name, 'documentation');
67
86
  },
68
- async deleteDocumentation (version) {
87
+ /**
88
+ * Removes the files of a version. A version that was never generated resolves without error.
89
+ *
90
+ * @internal
91
+ */ async deleteDocumentation (version) {
69
92
  const apis = this.getPluginAndApiInfo();
70
93
  for (const api of apis){
71
94
  await fs__default.default.remove(path__default.default.join(this.getApiDocumentationPath(api), version));
72
95
  }
73
96
  await fs__default.default.remove(path__default.default.join(this.getFullDocumentationPath(), version));
74
97
  },
75
- getPluginAndApiInfo () {
98
+ /**
99
+ * The APIs, then the documented plugins, with the names of their content types.
100
+ *
101
+ * @internal
102
+ */ getPluginAndApiInfo () {
76
103
  const pluginsToDocument = pluginsThatNeedDocumentation.map((plugin)=>{
77
104
  return {
78
105
  name: plugin,
@@ -94,6 +121,8 @@ const createService = ({ strapi })=>{
94
121
  },
95
122
  /**
96
123
  * @description - Creates the Swagger json files
124
+ *
125
+ * @internal
97
126
  */ async generateFullDoc (versionOpt) {
98
127
  const version = versionOpt ?? this.getDocumentationVersion();
99
128
  const apis = this.getPluginAndApiInfo();
@@ -120,10 +149,13 @@ const createService = ({ strapi })=>{
120
149
  draft['x-strapi-config'].plugins = pluginsThatNeedDocumentation;
121
150
  // Delete the mutateDocumentation key from the config so it doesn't end up in the spec
122
151
  delete draft['x-strapi-config'].mutateDocumentation;
152
+ const relationTargetSchemaNames = new Map(apisThatNeedGeneratedDocumentation.flatMap((api)=>[
153
+ ...buildComponentSchema.getRelationTargetSchemaNames(api)
154
+ ]));
123
155
  // Generate the documentation for each api and update the generatedDocumentation
124
156
  for (const api of apisThatNeedGeneratedDocumentation){
125
157
  const newApiPath = buildApiEndpointPath(api);
126
- const generatedSchemas = buildComponentSchema(api);
158
+ const generatedSchemas = buildComponentSchema.default(api, relationTargetSchemaNames);
127
159
  if (generatedSchemas) {
128
160
  draft.components.schemas = {
129
161
  ...draft.components.schemas,
@@ -1 +1 @@
1
- {"version":3,"file":"documentation.js","sources":["../../../server/src/services/documentation.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs-extra';\nimport { produce } from 'immer';\nimport type { Core } from '@strapi/types';\n\nimport { builApiEndpointPath, buildComponentSchema } from './helpers';\nimport { getPluginsThatNeedDocumentation } from './utils/get-plugins-that-need-documentation';\nimport { getService } from '../utils';\n\nimport type { Config, PluginConfig } from '../types';\n\nexport type Version = {\n version: string;\n generatedDate: string;\n url: string;\n};\n\nexport type DocumentationService = ReturnType<typeof createService>;\n\nconst createService = ({ strapi }: { strapi: Core.Strapi }) => {\n const config = strapi.config.get('plugin::documentation') as PluginConfig;\n const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(config);\n const overrideService = getService('override');\n\n return {\n getDocumentationVersion() {\n return config.info.version;\n },\n\n getFullDocumentationPath() {\n // In production, documentation files live under dist/src/extensions/\n // after the build step. Use dist.extensions for reading.\n const extensionsDir =\n strapi.config.environment === 'production'\n ? strapi.dirs.dist.extensions\n : strapi.dirs.app.extensions;\n\n return path.join(extensionsDir, 'documentation', 'documentation');\n },\n\n getDocumentationVersions(): Version[] {\n return fs\n .readdirSync(this.getFullDocumentationPath())\n .map((version) => {\n try {\n const filePath = path.resolve(\n this.getFullDocumentationPath(),\n version,\n 'full_documentation.json'\n );\n\n const doc = JSON.parse(fs.readFileSync(filePath).toString());\n\n const generatedDate = doc.info['x-generation-date'];\n\n return { version, generatedDate, url: '' };\n } catch (err) {\n return null;\n }\n })\n .filter((x) => x) as Version[];\n },\n\n /**\n * Returns settings stored in core-store\n */\n async getDocumentationAccess() {\n const { restrictedAccess } = (await strapi.store!({\n environment: '',\n type: 'plugin',\n name: 'documentation',\n key: 'config',\n }).get()) as Config;\n\n return { restrictedAccess };\n },\n\n getApiDocumentationPath(api: { name: string; getter: string }) {\n const isProduction = strapi.config.environment === 'production';\n\n if (api.getter === 'plugin') {\n const extensionsDir = isProduction\n ? strapi.dirs.dist.extensions\n : strapi.dirs.app.extensions;\n return path.join(extensionsDir, api.name, 'documentation');\n }\n\n const apiDir = isProduction ? strapi.dirs.dist.api : strapi.dirs.app.api;\n return path.join(apiDir, api.name, 'documentation');\n },\n\n async deleteDocumentation(version: string) {\n const apis = this.getPluginAndApiInfo();\n for (const api of apis) {\n await fs.remove(path.join(this.getApiDocumentationPath(api), version));\n }\n\n await fs.remove(path.join(this.getFullDocumentationPath(), version));\n },\n\n getPluginAndApiInfo() {\n const pluginsToDocument = pluginsThatNeedDocumentation.map((plugin) => {\n return {\n name: plugin,\n getter: 'plugin',\n ctNames: Object.keys(strapi.plugin(plugin).contentTypes),\n };\n });\n\n const apisToDocument = Object.keys(strapi.apis).map((api) => {\n return {\n name: api,\n getter: 'api',\n ctNames: Object.keys(strapi.api(api).contentTypes),\n };\n });\n\n return [...apisToDocument, ...pluginsToDocument];\n },\n\n /**\n * @description - Creates the Swagger json files\n */\n async generateFullDoc(versionOpt?: string) {\n const version = versionOpt ?? this.getDocumentationVersion();\n\n const apis = this.getPluginAndApiInfo();\n const apisThatNeedGeneratedDocumentation = apis.filter(\n ({ name }) => !overrideService.isEnabled(name)\n );\n\n // Initialize the generated documentation with defaults\n const generatedDocumentation = await produce(config, async (draft) => {\n if (draft.servers?.length === 0) {\n // When no servers found set the defaults\n const serverUrl = strapi.config.get('server.absoluteUrl');\n const apiPath = strapi.config.get('api.rest.prefix');\n draft.servers = [\n {\n url: `${serverUrl}${apiPath}`,\n description: 'Development server',\n },\n ];\n }\n\n if (!draft.components) {\n draft.components = {};\n }\n\n // Set the generated date\n draft.info['x-generation-date'] = new Date().toISOString();\n // Set the plugins that need documentation\n draft['x-strapi-config'].plugins = pluginsThatNeedDocumentation;\n\n // Delete the mutateDocumentation key from the config so it doesn't end up in the spec\n delete draft['x-strapi-config'].mutateDocumentation;\n\n // Generate the documentation for each api and update the generatedDocumentation\n for (const api of apisThatNeedGeneratedDocumentation) {\n const newApiPath = builApiEndpointPath(api);\n const generatedSchemas = buildComponentSchema(api);\n\n if (generatedSchemas) {\n draft.components.schemas = { ...draft.components.schemas, ...generatedSchemas };\n }\n\n if (newApiPath) {\n draft.paths = { ...draft.paths, ...newApiPath };\n }\n }\n\n // When overrides are present update the generatedDocumentation\n if (overrideService.registeredOverrides.length > 0) {\n overrideService.registeredOverrides.forEach((override: Partial<PluginConfig>) => {\n // Only run the overrrides when no override version is provided,\n // or when the generated documentation version matches the override version\n if (!override?.info?.version || override.info.version === version) {\n if (override.tags) {\n // Merge override tags with the generated tags\n draft.tags = draft.tags || [];\n draft.tags.push(...override.tags);\n }\n\n if (override.paths) {\n // Merge override paths with the generated paths\n // The override will add a new path or replace the value of an existing path\n draft.paths = { ...draft.paths, ...override.paths };\n }\n\n if (override.components) {\n const keys = Object.keys(override.components) as Array<\n keyof typeof override.components\n >;\n\n keys.forEach((overrideKey) => {\n draft.components = draft.components || {};\n\n const overrideValue = override.components?.[overrideKey];\n const originalValue = draft.components?.[overrideKey];\n\n Object.assign(draft.components, {\n [overrideKey]: {\n ...originalValue,\n ...overrideValue,\n },\n });\n });\n }\n }\n });\n }\n });\n\n // Escape hatch, allow the user to provide a mutateDocumentation function that can alter any part of\n // the generated documentation before it is written to the file system\n const userMutatesDocumentation = config['x-strapi-config'].mutateDocumentation;\n\n const finalDocumentation = userMutatesDocumentation\n ? produce(generatedDocumentation, userMutatesDocumentation)\n : generatedDocumentation;\n\n // Get the file path for the final documentation\n const fullDocJsonPath = path.join(\n this.getFullDocumentationPath(),\n version,\n 'full_documentation.json'\n );\n // Write the documentation to the file system\n await fs.ensureFile(fullDocJsonPath);\n await fs.writeJson(fullDocJsonPath, finalDocumentation, { spaces: 2 });\n },\n };\n};\n\nexport default createService;\n"],"names":["createService","strapi","config","get","pluginsThatNeedDocumentation","getPluginsThatNeedDocumentation","overrideService","getService","getDocumentationVersion","info","version","getFullDocumentationPath","extensionsDir","environment","dirs","dist","extensions","app","path","join","getDocumentationVersions","fs","readdirSync","map","filePath","resolve","doc","JSON","parse","readFileSync","toString","generatedDate","url","err","filter","x","getDocumentationAccess","restrictedAccess","store","type","name","key","getApiDocumentationPath","api","isProduction","getter","apiDir","deleteDocumentation","apis","getPluginAndApiInfo","remove","pluginsToDocument","plugin","ctNames","Object","keys","contentTypes","apisToDocument","generateFullDoc","versionOpt","apisThatNeedGeneratedDocumentation","isEnabled","generatedDocumentation","produce","draft","servers","length","serverUrl","apiPath","description","components","Date","toISOString","plugins","mutateDocumentation","newApiPath","builApiEndpointPath","generatedSchemas","buildComponentSchema","schemas","paths","registeredOverrides","forEach","override","tags","push","overrideKey","overrideValue","originalValue","assign","userMutatesDocumentation","finalDocumentation","fullDocJsonPath","ensureFile","writeJson","spaces"],"mappings":"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"}
1
+ {"version":3,"file":"documentation.js","sources":["../../../server/src/services/documentation.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs-extra';\nimport { produce } from 'immer';\nimport type { Core } from '@strapi/types';\n\nimport { builApiEndpointPath, buildComponentSchema, getRelationTargetSchemaNames } from './helpers';\nimport { getPluginsThatNeedDocumentation } from './utils/get-plugins-that-need-documentation';\nimport { getService } from '../utils';\n\nimport type { Config, PluginConfig } from '../types';\n\nexport type Version = {\n version: string;\n generatedDate: string;\n url: string;\n};\n\nexport type DocumentationService = ReturnType<typeof createService>;\n\nconst createService = ({ strapi }: { strapi: Core.Strapi }) => {\n const config = strapi.config.get('plugin::documentation') as PluginConfig;\n const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(config);\n const overrideService = getService('override');\n\n return {\n /**\n * The documentation version of the plugin config (`info.version`).\n *\n * @internal\n */\n getDocumentationVersion() {\n return config.info.version;\n },\n\n /**\n * The folder that holds one folder per generated version, each with its\n * `full_documentation.json`.\n *\n * @internal\n */\n getFullDocumentationPath() {\n // In production, documentation files live under dist/src/extensions/\n // after the build step. Use dist.extensions for reading.\n const extensionsDir =\n strapi.config.environment === 'production'\n ? strapi.dirs.dist.extensions\n : strapi.dirs.app.extensions;\n\n return path.join(extensionsDir, 'documentation', 'documentation');\n },\n\n /**\n * The generated versions. A version whose file cannot be read is left out.\n *\n * @internal\n */\n getDocumentationVersions(): Version[] {\n return fs\n .readdirSync(this.getFullDocumentationPath())\n .map((version) => {\n try {\n const filePath = path.resolve(\n this.getFullDocumentationPath(),\n version,\n 'full_documentation.json'\n );\n\n const doc = JSON.parse(fs.readFileSync(filePath).toString());\n\n const generatedDate = doc.info['x-generation-date'];\n\n return { version, generatedDate, url: '' };\n } catch {\n return null;\n }\n })\n .filter((x) => x) as Version[];\n },\n\n /**\n * Returns settings stored in core-store\n *\n * @internal\n */\n async getDocumentationAccess() {\n const { restrictedAccess } = (await strapi.store!({\n environment: '',\n type: 'plugin',\n name: 'documentation',\n key: 'config',\n }).get()) as Config;\n\n return { restrictedAccess };\n },\n\n /**\n * The documentation folder of an API (`getter: 'api'`) or of a plugin (`getter: 'plugin'`).\n *\n * @internal\n */\n getApiDocumentationPath(api: { name: string; getter: string }) {\n const isProduction = strapi.config.environment === 'production';\n\n if (api.getter === 'plugin') {\n const extensionsDir = isProduction\n ? strapi.dirs.dist.extensions\n : strapi.dirs.app.extensions;\n return path.join(extensionsDir, api.name, 'documentation');\n }\n\n const apiDir = isProduction ? strapi.dirs.dist.api : strapi.dirs.app.api;\n return path.join(apiDir, api.name, 'documentation');\n },\n\n /**\n * Removes the files of a version. A version that was never generated resolves without error.\n *\n * @internal\n */\n async deleteDocumentation(version: string) {\n const apis = this.getPluginAndApiInfo();\n for (const api of apis) {\n await fs.remove(path.join(this.getApiDocumentationPath(api), version));\n }\n\n await fs.remove(path.join(this.getFullDocumentationPath(), version));\n },\n\n /**\n * The APIs, then the documented plugins, with the names of their content types.\n *\n * @internal\n */\n getPluginAndApiInfo() {\n const pluginsToDocument = pluginsThatNeedDocumentation.map((plugin) => {\n return {\n name: plugin,\n getter: 'plugin',\n ctNames: Object.keys(strapi.plugin(plugin).contentTypes),\n };\n });\n\n const apisToDocument = Object.keys(strapi.apis).map((api) => {\n return {\n name: api,\n getter: 'api',\n ctNames: Object.keys(strapi.api(api).contentTypes),\n };\n });\n\n return [...apisToDocument, ...pluginsToDocument];\n },\n\n /**\n * @description - Creates the Swagger json files\n *\n * @internal\n */\n async generateFullDoc(versionOpt?: string) {\n const version = versionOpt ?? this.getDocumentationVersion();\n\n const apis = this.getPluginAndApiInfo();\n const apisThatNeedGeneratedDocumentation = apis.filter(\n ({ name }) => !overrideService.isEnabled(name)\n );\n\n // Initialize the generated documentation with defaults\n const generatedDocumentation = await produce(config, async (draft) => {\n if (draft.servers?.length === 0) {\n // When no servers found set the defaults\n const serverUrl = strapi.config.get('server.absoluteUrl');\n const apiPath = strapi.config.get('api.rest.prefix');\n draft.servers = [\n {\n url: `${serverUrl}${apiPath}`,\n description: 'Development server',\n },\n ];\n }\n\n if (!draft.components) {\n draft.components = {};\n }\n\n // Set the generated date\n draft.info['x-generation-date'] = new Date().toISOString();\n // Set the plugins that need documentation\n draft['x-strapi-config'].plugins = pluginsThatNeedDocumentation;\n\n // Delete the mutateDocumentation key from the config so it doesn't end up in the spec\n delete draft['x-strapi-config'].mutateDocumentation;\n\n const relationTargetSchemaNames = new Map(\n apisThatNeedGeneratedDocumentation.flatMap((api) => [\n ...getRelationTargetSchemaNames(api),\n ])\n );\n\n // Generate the documentation for each api and update the generatedDocumentation\n for (const api of apisThatNeedGeneratedDocumentation) {\n const newApiPath = builApiEndpointPath(api);\n const generatedSchemas = buildComponentSchema(api, relationTargetSchemaNames);\n\n if (generatedSchemas) {\n draft.components.schemas = { ...draft.components.schemas, ...generatedSchemas };\n }\n\n if (newApiPath) {\n draft.paths = { ...draft.paths, ...newApiPath };\n }\n }\n\n // When overrides are present update the generatedDocumentation\n if (overrideService.registeredOverrides.length > 0) {\n overrideService.registeredOverrides.forEach((override: Partial<PluginConfig>) => {\n // Only run the overrrides when no override version is provided,\n // or when the generated documentation version matches the override version\n if (!override?.info?.version || override.info.version === version) {\n if (override.tags) {\n // Merge override tags with the generated tags\n draft.tags = draft.tags || [];\n draft.tags.push(...override.tags);\n }\n\n if (override.paths) {\n // Merge override paths with the generated paths\n // The override will add a new path or replace the value of an existing path\n draft.paths = { ...draft.paths, ...override.paths };\n }\n\n if (override.components) {\n const keys = Object.keys(override.components) as Array<\n keyof typeof override.components\n >;\n\n keys.forEach((overrideKey) => {\n draft.components = draft.components || {};\n\n const overrideValue = override.components?.[overrideKey];\n const originalValue = draft.components?.[overrideKey];\n\n Object.assign(draft.components, {\n [overrideKey]: {\n ...originalValue,\n ...overrideValue,\n },\n });\n });\n }\n }\n });\n }\n });\n\n // Escape hatch, allow the user to provide a mutateDocumentation function that can alter any part of\n // the generated documentation before it is written to the file system\n const userMutatesDocumentation = config['x-strapi-config'].mutateDocumentation;\n\n const finalDocumentation = userMutatesDocumentation\n ? produce(generatedDocumentation, userMutatesDocumentation)\n : generatedDocumentation;\n\n // Get the file path for the final documentation\n const fullDocJsonPath = path.join(\n this.getFullDocumentationPath(),\n version,\n 'full_documentation.json'\n );\n // Write the documentation to the file system\n await fs.ensureFile(fullDocJsonPath);\n await fs.writeJson(fullDocJsonPath, finalDocumentation, { spaces: 2 });\n },\n };\n};\n\nexport default createService;\n"],"names":["createService","strapi","config","get","pluginsThatNeedDocumentation","getPluginsThatNeedDocumentation","overrideService","getService","getDocumentationVersion","info","version","getFullDocumentationPath","extensionsDir","environment","dirs","dist","extensions","app","path","join","getDocumentationVersions","fs","readdirSync","map","filePath","resolve","doc","JSON","parse","readFileSync","toString","generatedDate","url","filter","x","getDocumentationAccess","restrictedAccess","store","type","name","key","getApiDocumentationPath","api","isProduction","getter","apiDir","deleteDocumentation","apis","getPluginAndApiInfo","remove","pluginsToDocument","plugin","ctNames","Object","keys","contentTypes","apisToDocument","generateFullDoc","versionOpt","apisThatNeedGeneratedDocumentation","isEnabled","generatedDocumentation","produce","draft","servers","length","serverUrl","apiPath","description","components","Date","toISOString","plugins","mutateDocumentation","relationTargetSchemaNames","Map","flatMap","getRelationTargetSchemaNames","newApiPath","builApiEndpointPath","generatedSchemas","buildComponentSchema","schemas","paths","registeredOverrides","forEach","override","tags","push","overrideKey","overrideValue","originalValue","assign","userMutatesDocumentation","finalDocumentation","fullDocJsonPath","ensureFile","writeJson","spaces"],"mappings":"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"}
@@ -2,7 +2,7 @@ import path from 'path';
2
2
  import fs from 'fs-extra';
3
3
  import { produce } from 'immer';
4
4
  import buildApiEndpointPath from './helpers/build-api-endpoint-path.mjs';
5
- import buildComponentSchema from './helpers/build-component-schema.mjs';
5
+ import buildComponentSchema, { getRelationTargetSchemaNames } from './helpers/build-component-schema.mjs';
6
6
  import { getPluginsThatNeedDocumentation } from './utils/get-plugins-that-need-documentation.mjs';
7
7
  import { getService } from '../utils.mjs';
8
8
 
@@ -11,16 +11,29 @@ const createService = ({ strapi })=>{
11
11
  const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(config);
12
12
  const overrideService = getService('override');
13
13
  return {
14
- getDocumentationVersion () {
14
+ /**
15
+ * The documentation version of the plugin config (`info.version`).
16
+ *
17
+ * @internal
18
+ */ getDocumentationVersion () {
15
19
  return config.info.version;
16
20
  },
17
- getFullDocumentationPath () {
21
+ /**
22
+ * The folder that holds one folder per generated version, each with its
23
+ * `full_documentation.json`.
24
+ *
25
+ * @internal
26
+ */ getFullDocumentationPath () {
18
27
  // In production, documentation files live under dist/src/extensions/
19
28
  // after the build step. Use dist.extensions for reading.
20
29
  const extensionsDir = strapi.config.environment === 'production' ? strapi.dirs.dist.extensions : strapi.dirs.app.extensions;
21
30
  return path.join(extensionsDir, 'documentation', 'documentation');
22
31
  },
23
- getDocumentationVersions () {
32
+ /**
33
+ * The generated versions. A version whose file cannot be read is left out.
34
+ *
35
+ * @internal
36
+ */ getDocumentationVersions () {
24
37
  return fs.readdirSync(this.getFullDocumentationPath()).map((version)=>{
25
38
  try {
26
39
  const filePath = path.resolve(this.getFullDocumentationPath(), version, 'full_documentation.json');
@@ -31,13 +44,15 @@ const createService = ({ strapi })=>{
31
44
  generatedDate,
32
45
  url: ''
33
46
  };
34
- } catch (err) {
47
+ } catch {
35
48
  return null;
36
49
  }
37
50
  }).filter((x)=>x);
38
51
  },
39
52
  /**
40
53
  * Returns settings stored in core-store
54
+ *
55
+ * @internal
41
56
  */ async getDocumentationAccess () {
42
57
  const { restrictedAccess } = await strapi.store({
43
58
  environment: '',
@@ -49,7 +64,11 @@ const createService = ({ strapi })=>{
49
64
  restrictedAccess
50
65
  };
51
66
  },
52
- getApiDocumentationPath (api) {
67
+ /**
68
+ * The documentation folder of an API (`getter: 'api'`) or of a plugin (`getter: 'plugin'`).
69
+ *
70
+ * @internal
71
+ */ getApiDocumentationPath (api) {
53
72
  const isProduction = strapi.config.environment === 'production';
54
73
  if (api.getter === 'plugin') {
55
74
  const extensionsDir = isProduction ? strapi.dirs.dist.extensions : strapi.dirs.app.extensions;
@@ -58,14 +77,22 @@ const createService = ({ strapi })=>{
58
77
  const apiDir = isProduction ? strapi.dirs.dist.api : strapi.dirs.app.api;
59
78
  return path.join(apiDir, api.name, 'documentation');
60
79
  },
61
- async deleteDocumentation (version) {
80
+ /**
81
+ * Removes the files of a version. A version that was never generated resolves without error.
82
+ *
83
+ * @internal
84
+ */ async deleteDocumentation (version) {
62
85
  const apis = this.getPluginAndApiInfo();
63
86
  for (const api of apis){
64
87
  await fs.remove(path.join(this.getApiDocumentationPath(api), version));
65
88
  }
66
89
  await fs.remove(path.join(this.getFullDocumentationPath(), version));
67
90
  },
68
- getPluginAndApiInfo () {
91
+ /**
92
+ * The APIs, then the documented plugins, with the names of their content types.
93
+ *
94
+ * @internal
95
+ */ getPluginAndApiInfo () {
69
96
  const pluginsToDocument = pluginsThatNeedDocumentation.map((plugin)=>{
70
97
  return {
71
98
  name: plugin,
@@ -87,6 +114,8 @@ const createService = ({ strapi })=>{
87
114
  },
88
115
  /**
89
116
  * @description - Creates the Swagger json files
117
+ *
118
+ * @internal
90
119
  */ async generateFullDoc (versionOpt) {
91
120
  const version = versionOpt ?? this.getDocumentationVersion();
92
121
  const apis = this.getPluginAndApiInfo();
@@ -113,10 +142,13 @@ const createService = ({ strapi })=>{
113
142
  draft['x-strapi-config'].plugins = pluginsThatNeedDocumentation;
114
143
  // Delete the mutateDocumentation key from the config so it doesn't end up in the spec
115
144
  delete draft['x-strapi-config'].mutateDocumentation;
145
+ const relationTargetSchemaNames = new Map(apisThatNeedGeneratedDocumentation.flatMap((api)=>[
146
+ ...getRelationTargetSchemaNames(api)
147
+ ]));
116
148
  // Generate the documentation for each api and update the generatedDocumentation
117
149
  for (const api of apisThatNeedGeneratedDocumentation){
118
150
  const newApiPath = buildApiEndpointPath(api);
119
- const generatedSchemas = buildComponentSchema(api);
151
+ const generatedSchemas = buildComponentSchema(api, relationTargetSchemaNames);
120
152
  if (generatedSchemas) {
121
153
  draft.components.schemas = {
122
154
  ...draft.components.schemas,
@@ -1 +1 @@
1
- {"version":3,"file":"documentation.mjs","sources":["../../../server/src/services/documentation.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs-extra';\nimport { produce } from 'immer';\nimport type { Core } from '@strapi/types';\n\nimport { builApiEndpointPath, buildComponentSchema } from './helpers';\nimport { getPluginsThatNeedDocumentation } from './utils/get-plugins-that-need-documentation';\nimport { getService } from '../utils';\n\nimport type { Config, PluginConfig } from '../types';\n\nexport type Version = {\n version: string;\n generatedDate: string;\n url: string;\n};\n\nexport type DocumentationService = ReturnType<typeof createService>;\n\nconst createService = ({ strapi }: { strapi: Core.Strapi }) => {\n const config = strapi.config.get('plugin::documentation') as PluginConfig;\n const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(config);\n const overrideService = getService('override');\n\n return {\n getDocumentationVersion() {\n return config.info.version;\n },\n\n getFullDocumentationPath() {\n // In production, documentation files live under dist/src/extensions/\n // after the build step. Use dist.extensions for reading.\n const extensionsDir =\n strapi.config.environment === 'production'\n ? strapi.dirs.dist.extensions\n : strapi.dirs.app.extensions;\n\n return path.join(extensionsDir, 'documentation', 'documentation');\n },\n\n getDocumentationVersions(): Version[] {\n return fs\n .readdirSync(this.getFullDocumentationPath())\n .map((version) => {\n try {\n const filePath = path.resolve(\n this.getFullDocumentationPath(),\n version,\n 'full_documentation.json'\n );\n\n const doc = JSON.parse(fs.readFileSync(filePath).toString());\n\n const generatedDate = doc.info['x-generation-date'];\n\n return { version, generatedDate, url: '' };\n } catch (err) {\n return null;\n }\n })\n .filter((x) => x) as Version[];\n },\n\n /**\n * Returns settings stored in core-store\n */\n async getDocumentationAccess() {\n const { restrictedAccess } = (await strapi.store!({\n environment: '',\n type: 'plugin',\n name: 'documentation',\n key: 'config',\n }).get()) as Config;\n\n return { restrictedAccess };\n },\n\n getApiDocumentationPath(api: { name: string; getter: string }) {\n const isProduction = strapi.config.environment === 'production';\n\n if (api.getter === 'plugin') {\n const extensionsDir = isProduction\n ? strapi.dirs.dist.extensions\n : strapi.dirs.app.extensions;\n return path.join(extensionsDir, api.name, 'documentation');\n }\n\n const apiDir = isProduction ? strapi.dirs.dist.api : strapi.dirs.app.api;\n return path.join(apiDir, api.name, 'documentation');\n },\n\n async deleteDocumentation(version: string) {\n const apis = this.getPluginAndApiInfo();\n for (const api of apis) {\n await fs.remove(path.join(this.getApiDocumentationPath(api), version));\n }\n\n await fs.remove(path.join(this.getFullDocumentationPath(), version));\n },\n\n getPluginAndApiInfo() {\n const pluginsToDocument = pluginsThatNeedDocumentation.map((plugin) => {\n return {\n name: plugin,\n getter: 'plugin',\n ctNames: Object.keys(strapi.plugin(plugin).contentTypes),\n };\n });\n\n const apisToDocument = Object.keys(strapi.apis).map((api) => {\n return {\n name: api,\n getter: 'api',\n ctNames: Object.keys(strapi.api(api).contentTypes),\n };\n });\n\n return [...apisToDocument, ...pluginsToDocument];\n },\n\n /**\n * @description - Creates the Swagger json files\n */\n async generateFullDoc(versionOpt?: string) {\n const version = versionOpt ?? this.getDocumentationVersion();\n\n const apis = this.getPluginAndApiInfo();\n const apisThatNeedGeneratedDocumentation = apis.filter(\n ({ name }) => !overrideService.isEnabled(name)\n );\n\n // Initialize the generated documentation with defaults\n const generatedDocumentation = await produce(config, async (draft) => {\n if (draft.servers?.length === 0) {\n // When no servers found set the defaults\n const serverUrl = strapi.config.get('server.absoluteUrl');\n const apiPath = strapi.config.get('api.rest.prefix');\n draft.servers = [\n {\n url: `${serverUrl}${apiPath}`,\n description: 'Development server',\n },\n ];\n }\n\n if (!draft.components) {\n draft.components = {};\n }\n\n // Set the generated date\n draft.info['x-generation-date'] = new Date().toISOString();\n // Set the plugins that need documentation\n draft['x-strapi-config'].plugins = pluginsThatNeedDocumentation;\n\n // Delete the mutateDocumentation key from the config so it doesn't end up in the spec\n delete draft['x-strapi-config'].mutateDocumentation;\n\n // Generate the documentation for each api and update the generatedDocumentation\n for (const api of apisThatNeedGeneratedDocumentation) {\n const newApiPath = builApiEndpointPath(api);\n const generatedSchemas = buildComponentSchema(api);\n\n if (generatedSchemas) {\n draft.components.schemas = { ...draft.components.schemas, ...generatedSchemas };\n }\n\n if (newApiPath) {\n draft.paths = { ...draft.paths, ...newApiPath };\n }\n }\n\n // When overrides are present update the generatedDocumentation\n if (overrideService.registeredOverrides.length > 0) {\n overrideService.registeredOverrides.forEach((override: Partial<PluginConfig>) => {\n // Only run the overrrides when no override version is provided,\n // or when the generated documentation version matches the override version\n if (!override?.info?.version || override.info.version === version) {\n if (override.tags) {\n // Merge override tags with the generated tags\n draft.tags = draft.tags || [];\n draft.tags.push(...override.tags);\n }\n\n if (override.paths) {\n // Merge override paths with the generated paths\n // The override will add a new path or replace the value of an existing path\n draft.paths = { ...draft.paths, ...override.paths };\n }\n\n if (override.components) {\n const keys = Object.keys(override.components) as Array<\n keyof typeof override.components\n >;\n\n keys.forEach((overrideKey) => {\n draft.components = draft.components || {};\n\n const overrideValue = override.components?.[overrideKey];\n const originalValue = draft.components?.[overrideKey];\n\n Object.assign(draft.components, {\n [overrideKey]: {\n ...originalValue,\n ...overrideValue,\n },\n });\n });\n }\n }\n });\n }\n });\n\n // Escape hatch, allow the user to provide a mutateDocumentation function that can alter any part of\n // the generated documentation before it is written to the file system\n const userMutatesDocumentation = config['x-strapi-config'].mutateDocumentation;\n\n const finalDocumentation = userMutatesDocumentation\n ? produce(generatedDocumentation, userMutatesDocumentation)\n : generatedDocumentation;\n\n // Get the file path for the final documentation\n const fullDocJsonPath = path.join(\n this.getFullDocumentationPath(),\n version,\n 'full_documentation.json'\n );\n // Write the documentation to the file system\n await fs.ensureFile(fullDocJsonPath);\n await fs.writeJson(fullDocJsonPath, finalDocumentation, { spaces: 2 });\n },\n };\n};\n\nexport default createService;\n"],"names":["createService","strapi","config","get","pluginsThatNeedDocumentation","getPluginsThatNeedDocumentation","overrideService","getService","getDocumentationVersion","info","version","getFullDocumentationPath","extensionsDir","environment","dirs","dist","extensions","app","path","join","getDocumentationVersions","fs","readdirSync","map","filePath","resolve","doc","JSON","parse","readFileSync","toString","generatedDate","url","err","filter","x","getDocumentationAccess","restrictedAccess","store","type","name","key","getApiDocumentationPath","api","isProduction","getter","apiDir","deleteDocumentation","apis","getPluginAndApiInfo","remove","pluginsToDocument","plugin","ctNames","Object","keys","contentTypes","apisToDocument","generateFullDoc","versionOpt","apisThatNeedGeneratedDocumentation","isEnabled","generatedDocumentation","produce","draft","servers","length","serverUrl","apiPath","description","components","Date","toISOString","plugins","mutateDocumentation","newApiPath","builApiEndpointPath","generatedSchemas","buildComponentSchema","schemas","paths","registeredOverrides","forEach","override","tags","push","overrideKey","overrideValue","originalValue","assign","userMutatesDocumentation","finalDocumentation","fullDocJsonPath","ensureFile","writeJson","spaces"],"mappings":"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"}
1
+ {"version":3,"file":"documentation.mjs","sources":["../../../server/src/services/documentation.ts"],"sourcesContent":["import path from 'path';\nimport fs from 'fs-extra';\nimport { produce } from 'immer';\nimport type { Core } from '@strapi/types';\n\nimport { builApiEndpointPath, buildComponentSchema, getRelationTargetSchemaNames } from './helpers';\nimport { getPluginsThatNeedDocumentation } from './utils/get-plugins-that-need-documentation';\nimport { getService } from '../utils';\n\nimport type { Config, PluginConfig } from '../types';\n\nexport type Version = {\n version: string;\n generatedDate: string;\n url: string;\n};\n\nexport type DocumentationService = ReturnType<typeof createService>;\n\nconst createService = ({ strapi }: { strapi: Core.Strapi }) => {\n const config = strapi.config.get('plugin::documentation') as PluginConfig;\n const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(config);\n const overrideService = getService('override');\n\n return {\n /**\n * The documentation version of the plugin config (`info.version`).\n *\n * @internal\n */\n getDocumentationVersion() {\n return config.info.version;\n },\n\n /**\n * The folder that holds one folder per generated version, each with its\n * `full_documentation.json`.\n *\n * @internal\n */\n getFullDocumentationPath() {\n // In production, documentation files live under dist/src/extensions/\n // after the build step. Use dist.extensions for reading.\n const extensionsDir =\n strapi.config.environment === 'production'\n ? strapi.dirs.dist.extensions\n : strapi.dirs.app.extensions;\n\n return path.join(extensionsDir, 'documentation', 'documentation');\n },\n\n /**\n * The generated versions. A version whose file cannot be read is left out.\n *\n * @internal\n */\n getDocumentationVersions(): Version[] {\n return fs\n .readdirSync(this.getFullDocumentationPath())\n .map((version) => {\n try {\n const filePath = path.resolve(\n this.getFullDocumentationPath(),\n version,\n 'full_documentation.json'\n );\n\n const doc = JSON.parse(fs.readFileSync(filePath).toString());\n\n const generatedDate = doc.info['x-generation-date'];\n\n return { version, generatedDate, url: '' };\n } catch {\n return null;\n }\n })\n .filter((x) => x) as Version[];\n },\n\n /**\n * Returns settings stored in core-store\n *\n * @internal\n */\n async getDocumentationAccess() {\n const { restrictedAccess } = (await strapi.store!({\n environment: '',\n type: 'plugin',\n name: 'documentation',\n key: 'config',\n }).get()) as Config;\n\n return { restrictedAccess };\n },\n\n /**\n * The documentation folder of an API (`getter: 'api'`) or of a plugin (`getter: 'plugin'`).\n *\n * @internal\n */\n getApiDocumentationPath(api: { name: string; getter: string }) {\n const isProduction = strapi.config.environment === 'production';\n\n if (api.getter === 'plugin') {\n const extensionsDir = isProduction\n ? strapi.dirs.dist.extensions\n : strapi.dirs.app.extensions;\n return path.join(extensionsDir, api.name, 'documentation');\n }\n\n const apiDir = isProduction ? strapi.dirs.dist.api : strapi.dirs.app.api;\n return path.join(apiDir, api.name, 'documentation');\n },\n\n /**\n * Removes the files of a version. A version that was never generated resolves without error.\n *\n * @internal\n */\n async deleteDocumentation(version: string) {\n const apis = this.getPluginAndApiInfo();\n for (const api of apis) {\n await fs.remove(path.join(this.getApiDocumentationPath(api), version));\n }\n\n await fs.remove(path.join(this.getFullDocumentationPath(), version));\n },\n\n /**\n * The APIs, then the documented plugins, with the names of their content types.\n *\n * @internal\n */\n getPluginAndApiInfo() {\n const pluginsToDocument = pluginsThatNeedDocumentation.map((plugin) => {\n return {\n name: plugin,\n getter: 'plugin',\n ctNames: Object.keys(strapi.plugin(plugin).contentTypes),\n };\n });\n\n const apisToDocument = Object.keys(strapi.apis).map((api) => {\n return {\n name: api,\n getter: 'api',\n ctNames: Object.keys(strapi.api(api).contentTypes),\n };\n });\n\n return [...apisToDocument, ...pluginsToDocument];\n },\n\n /**\n * @description - Creates the Swagger json files\n *\n * @internal\n */\n async generateFullDoc(versionOpt?: string) {\n const version = versionOpt ?? this.getDocumentationVersion();\n\n const apis = this.getPluginAndApiInfo();\n const apisThatNeedGeneratedDocumentation = apis.filter(\n ({ name }) => !overrideService.isEnabled(name)\n );\n\n // Initialize the generated documentation with defaults\n const generatedDocumentation = await produce(config, async (draft) => {\n if (draft.servers?.length === 0) {\n // When no servers found set the defaults\n const serverUrl = strapi.config.get('server.absoluteUrl');\n const apiPath = strapi.config.get('api.rest.prefix');\n draft.servers = [\n {\n url: `${serverUrl}${apiPath}`,\n description: 'Development server',\n },\n ];\n }\n\n if (!draft.components) {\n draft.components = {};\n }\n\n // Set the generated date\n draft.info['x-generation-date'] = new Date().toISOString();\n // Set the plugins that need documentation\n draft['x-strapi-config'].plugins = pluginsThatNeedDocumentation;\n\n // Delete the mutateDocumentation key from the config so it doesn't end up in the spec\n delete draft['x-strapi-config'].mutateDocumentation;\n\n const relationTargetSchemaNames = new Map(\n apisThatNeedGeneratedDocumentation.flatMap((api) => [\n ...getRelationTargetSchemaNames(api),\n ])\n );\n\n // Generate the documentation for each api and update the generatedDocumentation\n for (const api of apisThatNeedGeneratedDocumentation) {\n const newApiPath = builApiEndpointPath(api);\n const generatedSchemas = buildComponentSchema(api, relationTargetSchemaNames);\n\n if (generatedSchemas) {\n draft.components.schemas = { ...draft.components.schemas, ...generatedSchemas };\n }\n\n if (newApiPath) {\n draft.paths = { ...draft.paths, ...newApiPath };\n }\n }\n\n // When overrides are present update the generatedDocumentation\n if (overrideService.registeredOverrides.length > 0) {\n overrideService.registeredOverrides.forEach((override: Partial<PluginConfig>) => {\n // Only run the overrrides when no override version is provided,\n // or when the generated documentation version matches the override version\n if (!override?.info?.version || override.info.version === version) {\n if (override.tags) {\n // Merge override tags with the generated tags\n draft.tags = draft.tags || [];\n draft.tags.push(...override.tags);\n }\n\n if (override.paths) {\n // Merge override paths with the generated paths\n // The override will add a new path or replace the value of an existing path\n draft.paths = { ...draft.paths, ...override.paths };\n }\n\n if (override.components) {\n const keys = Object.keys(override.components) as Array<\n keyof typeof override.components\n >;\n\n keys.forEach((overrideKey) => {\n draft.components = draft.components || {};\n\n const overrideValue = override.components?.[overrideKey];\n const originalValue = draft.components?.[overrideKey];\n\n Object.assign(draft.components, {\n [overrideKey]: {\n ...originalValue,\n ...overrideValue,\n },\n });\n });\n }\n }\n });\n }\n });\n\n // Escape hatch, allow the user to provide a mutateDocumentation function that can alter any part of\n // the generated documentation before it is written to the file system\n const userMutatesDocumentation = config['x-strapi-config'].mutateDocumentation;\n\n const finalDocumentation = userMutatesDocumentation\n ? produce(generatedDocumentation, userMutatesDocumentation)\n : generatedDocumentation;\n\n // Get the file path for the final documentation\n const fullDocJsonPath = path.join(\n this.getFullDocumentationPath(),\n version,\n 'full_documentation.json'\n );\n // Write the documentation to the file system\n await fs.ensureFile(fullDocJsonPath);\n await fs.writeJson(fullDocJsonPath, finalDocumentation, { spaces: 2 });\n },\n };\n};\n\nexport default createService;\n"],"names":["createService","strapi","config","get","pluginsThatNeedDocumentation","getPluginsThatNeedDocumentation","overrideService","getService","getDocumentationVersion","info","version","getFullDocumentationPath","extensionsDir","environment","dirs","dist","extensions","app","path","join","getDocumentationVersions","fs","readdirSync","map","filePath","resolve","doc","JSON","parse","readFileSync","toString","generatedDate","url","filter","x","getDocumentationAccess","restrictedAccess","store","type","name","key","getApiDocumentationPath","api","isProduction","getter","apiDir","deleteDocumentation","apis","getPluginAndApiInfo","remove","pluginsToDocument","plugin","ctNames","Object","keys","contentTypes","apisToDocument","generateFullDoc","versionOpt","apisThatNeedGeneratedDocumentation","isEnabled","generatedDocumentation","produce","draft","servers","length","serverUrl","apiPath","description","components","Date","toISOString","plugins","mutateDocumentation","relationTargetSchemaNames","Map","flatMap","getRelationTargetSchemaNames","newApiPath","builApiEndpointPath","generatedSchemas","buildComponentSchema","schemas","paths","registeredOverrides","forEach","override","tags","push","overrideKey","overrideValue","originalValue","assign","userMutatesDocumentation","finalDocumentation","fullDocJsonPath","ensureFile","writeJson","spaces"],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  var _ = require('lodash');
4
6
  var cleanSchemaAttributes = require('./utils/clean-schema-attributes.js');
5
7
  var loopContentTypeNames = require('./utils/loop-content-type-names.js');
@@ -28,7 +30,7 @@ const getRequiredAttributes = (allAttributes)=>{
28
30
  * @property {object} apiInfo.routeInfo - The routes for the api
29
31
  *
30
32
  * @returns {object} Open API schemas
31
- */ const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName })=>{
33
+ */ const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName, relationTargetSchemaNames })=>{
32
34
  // Store response and request schemas in an object
33
35
  let strapiComponentSchemas = {};
34
36
  const schemas = {};
@@ -44,7 +46,7 @@ const getRequiredAttributes = (allAttributes)=>{
44
46
  return true;
45
47
  };
46
48
  // Get all the route methods
47
- const routeMethods = routeInfo.routes.map((route)=>route.method);
49
+ const routeMethods = new Set(routeInfo.routes.map((route)=>route.method));
48
50
  const attributesToOmit = [
49
51
  'createdAt',
50
52
  'updatedAt',
@@ -57,7 +59,7 @@ const getRequiredAttributes = (allAttributes)=>{
57
59
  // Get a list of required attribute names
58
60
  const requiredRequestAttributes = getRequiredAttributes(attributesForRequest);
59
61
  // Build the request schemas when the route has POST or PUT methods
60
- if (routeMethods.includes('POST') || routeMethods.includes('PUT')) {
62
+ if (routeMethods.has('POST') || routeMethods.has('PUT')) {
61
63
  // Build localization requests schemas
62
64
  // Build the request schema
63
65
  Object.assign(schemas, {
@@ -146,6 +148,7 @@ const getRequiredAttributes = (allAttributes)=>{
146
148
  type: 'string'
147
149
  },
148
150
  ...cleanSchemaAttributes(attributes, {
151
+ relationTargetSchemaNames,
149
152
  didAddStrapiComponentsToSchemas
150
153
  })
151
154
  }
@@ -167,12 +170,24 @@ const getRequiredAttributes = (allAttributes)=>{
167
170
  ...strapiComponentSchemas
168
171
  };
169
172
  };
170
- const buildComponentSchema = (api)=>{
173
+ const getRelationTargetSchemaNames = (api)=>{
174
+ const relationTargetSchemaNames = new Map();
175
+ loopContentTypeNames(api, ({ uid, uniqueName })=>{
176
+ relationTargetSchemaNames.set(uid, pascalCase(uniqueName));
177
+ return {};
178
+ });
179
+ return relationTargetSchemaNames;
180
+ };
181
+ const buildComponentSchema = (api, relationTargetSchemaNames = getRelationTargetSchemaNames(api))=>{
171
182
  // A reusable loop for building paths and component schemas
172
183
  // Uses the api param to build a new set of params for each content type
173
184
  // Passes these new params to the function provided
174
- return loopContentTypeNames(api, getAllSchemasForContentType);
185
+ return loopContentTypeNames(api, (apiInfo)=>getAllSchemasForContentType({
186
+ ...apiInfo,
187
+ relationTargetSchemaNames
188
+ }));
175
189
  };
176
190
 
177
- module.exports = buildComponentSchema;
191
+ exports.default = buildComponentSchema;
192
+ exports.getRelationTargetSchemaNames = getRelationTargetSchemaNames;
178
193
  //# sourceMappingURL=build-component-schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-component-schema.js","sources":["../../../../server/src/services/helpers/build-component-schema.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport type { OpenAPIV3 } from 'openapi-types';\nimport type { Core, Struct } from '@strapi/types';\n\nimport cleanSchemaAttributes from './utils/clean-schema-attributes';\nimport loopContentTypeNames from './utils/loop-content-type-names';\nimport pascalCase from './utils/pascal-case';\nimport { hasFindMethod } from './utils/routes';\n\nimport type { Api, ApiInfo } from '../../types';\n\nconst getRequiredAttributes = (allAttributes: Struct.SchemaAttributes) => {\n const requiredAttributes: string[] = [];\n\n for (const key in allAttributes) {\n if (allAttributes[key].required) {\n requiredAttributes.push(key);\n }\n }\n\n return requiredAttributes;\n};\n\n/**\n * @description Get all open api schema objects for a given content type\n *\n * @param {object} apiInfo\n * @property {string} apiInfo.uniqueName - Api name | Api name + Content type name\n * @property {object} apiInfo.attributes - Attributes on content type\n * @property {object} apiInfo.routeInfo - The routes for the api\n *\n * @returns {object} Open API schemas\n */\nconst getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }: ApiInfo) => {\n // Store response and request schemas in an object\n let strapiComponentSchemas = {};\n const schemas: OpenAPIV3.ComponentsObject = {};\n const typeName = pascalCase(uniqueName);\n\n // adds a ComponentSchema to the Schemas so it can be used as Ref\n const didAddStrapiComponentsToSchemas = (schemaName: string, schema: OpenAPIV3.SchemaObject) => {\n if (!Object.keys(schema) || !Object.keys(schema.properties!)) return false;\n\n // Add the Strapi components to the schema\n strapiComponentSchemas = {\n ...strapiComponentSchemas,\n [schemaName]: schema,\n };\n\n return true;\n };\n\n // Get all the route methods\n const routeMethods = routeInfo.routes.map((route: Core.Route) => route.method);\n\n const attributesToOmit = [\n 'createdAt',\n 'updatedAt',\n 'publishedAt',\n 'publishedBy',\n 'updatedBy',\n 'createdBy',\n ];\n\n const attributesForRequest = _.omit(attributes, attributesToOmit);\n // Get a list of required attribute names\n const requiredRequestAttributes = getRequiredAttributes(attributesForRequest);\n // Build the request schemas when the route has POST or PUT methods\n if (routeMethods.includes('POST') || routeMethods.includes('PUT')) {\n // Build localization requests schemas\n\n // Build the request schema\n Object.assign(schemas, {\n [`${typeName}Request`]: {\n type: 'object',\n required: ['data'],\n properties: {\n data: {\n ...(requiredRequestAttributes.length && { required: requiredRequestAttributes }),\n type: 'object',\n properties: cleanSchemaAttributes(attributesForRequest, {\n isRequest: true,\n didAddStrapiComponentsToSchemas,\n }),\n },\n },\n },\n });\n }\n\n // Check for routes that need to return a list\n const hasListOfEntities = routeInfo.routes.filter((route: Core.Route) =>\n hasFindMethod(route.handler)\n ).length;\n\n if (hasListOfEntities) {\n // Build the list response schema\n Object.assign(schemas, {\n [`${typeName}ListResponse`]: {\n type: 'object',\n properties: {\n data: {\n type: 'array',\n items: {\n $ref: `#/components/schemas/${typeName}`,\n },\n },\n meta: {\n type: 'object',\n properties: {\n pagination: {\n type: 'object',\n properties: {\n page: { type: 'integer' },\n pageSize: { type: 'integer', minimum: 25 },\n pageCount: { type: 'integer', maximum: 1 },\n total: { type: 'integer' },\n },\n },\n },\n },\n },\n },\n });\n }\n\n const requiredAttributes = getRequiredAttributes(attributes);\n // Build the response schema\n Object.assign(schemas, {\n [`${typeName}`]: {\n type: 'object',\n ...(requiredAttributes.length && { required: requiredAttributes }),\n properties: {\n id: { oneOf: [{ type: 'string' }, { type: 'number' }] },\n documentId: { type: 'string' },\n ...cleanSchemaAttributes(attributes, { didAddStrapiComponentsToSchemas }),\n },\n },\n\n [`${typeName}Response`]: {\n type: 'object',\n properties: {\n data: {\n $ref: `#/components/schemas/${typeName}`,\n },\n meta: { type: 'object' },\n },\n },\n });\n\n return { ...schemas, ...strapiComponentSchemas };\n};\n\nconst buildComponentSchema = (api: Api) => {\n // A reusable loop for building paths and component schemas\n // Uses the api param to build a new set of params for each content type\n // Passes these new params to the function provided\n return loopContentTypeNames(api, getAllSchemasForContentType);\n};\n\nexport default buildComponentSchema;\n"],"names":["getRequiredAttributes","allAttributes","requiredAttributes","key","required","push","getAllSchemasForContentType","routeInfo","attributes","uniqueName","strapiComponentSchemas","schemas","typeName","pascalCase","didAddStrapiComponentsToSchemas","schemaName","schema","Object","keys","properties","routeMethods","routes","map","route","method","attributesToOmit","attributesForRequest","_","omit","requiredRequestAttributes","includes","assign","type","data","length","cleanSchemaAttributes","isRequest","hasListOfEntities","filter","hasFindMethod","handler","items","$ref","meta","pagination","page","pageSize","minimum","pageCount","maximum","total","id","oneOf","documentId","buildComponentSchema","api","loopContentTypeNames"],"mappings":"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"}
1
+ {"version":3,"file":"build-component-schema.js","sources":["../../../../server/src/services/helpers/build-component-schema.ts"],"sourcesContent":["import _ from 'lodash';\n\nimport type { OpenAPIV3 } from 'openapi-types';\nimport type { Core, Struct } from '@strapi/types';\n\nimport cleanSchemaAttributes from './utils/clean-schema-attributes';\nimport loopContentTypeNames from './utils/loop-content-type-names';\nimport pascalCase from './utils/pascal-case';\nimport { hasFindMethod } from './utils/routes';\n\nimport type { Api, ApiInfo } from '../../types';\n\nconst getRequiredAttributes = (allAttributes: Struct.SchemaAttributes) => {\n const requiredAttributes: string[] = [];\n\n for (const key in allAttributes) {\n if (allAttributes[key].required) {\n requiredAttributes.push(key);\n }\n }\n\n return requiredAttributes;\n};\n\n/**\n * @description Get all open api schema objects for a given content type\n *\n * @param {object} apiInfo\n * @property {string} apiInfo.uniqueName - Api name | Api name + Content type name\n * @property {object} apiInfo.attributes - Attributes on content type\n * @property {object} apiInfo.routeInfo - The routes for the api\n *\n * @returns {object} Open API schemas\n */\nconst getAllSchemasForContentType = ({\n routeInfo,\n attributes,\n uniqueName,\n relationTargetSchemaNames,\n}: ApiInfo & { relationTargetSchemaNames: Map<string, string> }) => {\n // Store response and request schemas in an object\n let strapiComponentSchemas = {};\n const schemas: OpenAPIV3.ComponentsObject = {};\n const typeName = pascalCase(uniqueName);\n\n // adds a ComponentSchema to the Schemas so it can be used as Ref\n const didAddStrapiComponentsToSchemas = (schemaName: string, schema: OpenAPIV3.SchemaObject) => {\n if (!Object.keys(schema) || !Object.keys(schema.properties!)) return false;\n\n // Add the Strapi components to the schema\n strapiComponentSchemas = {\n ...strapiComponentSchemas,\n [schemaName]: schema,\n };\n\n return true;\n };\n\n // Get all the route methods\n const routeMethods = new Set(routeInfo.routes.map((route: Core.Route) => route.method));\n\n const attributesToOmit = [\n 'createdAt',\n 'updatedAt',\n 'publishedAt',\n 'publishedBy',\n 'updatedBy',\n 'createdBy',\n ];\n\n const attributesForRequest = _.omit(attributes, attributesToOmit);\n // Get a list of required attribute names\n const requiredRequestAttributes = getRequiredAttributes(attributesForRequest);\n // Build the request schemas when the route has POST or PUT methods\n if (routeMethods.has('POST') || routeMethods.has('PUT')) {\n // Build localization requests schemas\n\n // Build the request schema\n Object.assign(schemas, {\n [`${typeName}Request`]: {\n type: 'object',\n required: ['data'],\n properties: {\n data: {\n ...(requiredRequestAttributes.length && { required: requiredRequestAttributes }),\n type: 'object',\n properties: cleanSchemaAttributes(attributesForRequest, {\n isRequest: true,\n didAddStrapiComponentsToSchemas,\n }),\n },\n },\n },\n });\n }\n\n // Check for routes that need to return a list\n const hasListOfEntities = routeInfo.routes.filter((route: Core.Route) =>\n hasFindMethod(route.handler)\n ).length;\n\n if (hasListOfEntities) {\n // Build the list response schema\n Object.assign(schemas, {\n [`${typeName}ListResponse`]: {\n type: 'object',\n properties: {\n data: {\n type: 'array',\n items: {\n $ref: `#/components/schemas/${typeName}`,\n },\n },\n meta: {\n type: 'object',\n properties: {\n pagination: {\n type: 'object',\n properties: {\n page: { type: 'integer' },\n pageSize: { type: 'integer', minimum: 25 },\n pageCount: { type: 'integer', maximum: 1 },\n total: { type: 'integer' },\n },\n },\n },\n },\n },\n },\n });\n }\n\n const requiredAttributes = getRequiredAttributes(attributes);\n // Build the response schema\n Object.assign(schemas, {\n [`${typeName}`]: {\n type: 'object',\n ...(requiredAttributes.length && { required: requiredAttributes }),\n properties: {\n id: { oneOf: [{ type: 'string' }, { type: 'number' }] },\n documentId: { type: 'string' },\n ...cleanSchemaAttributes(attributes, {\n relationTargetSchemaNames,\n didAddStrapiComponentsToSchemas,\n }),\n },\n },\n\n [`${typeName}Response`]: {\n type: 'object',\n properties: {\n data: {\n $ref: `#/components/schemas/${typeName}`,\n },\n meta: { type: 'object' },\n },\n },\n });\n\n return { ...schemas, ...strapiComponentSchemas };\n};\n\nconst getRelationTargetSchemaNames = (api: Api) => {\n const relationTargetSchemaNames = new Map<string, string>();\n\n loopContentTypeNames(api, ({ uid, uniqueName }) => {\n relationTargetSchemaNames.set(uid, pascalCase(uniqueName));\n return {};\n });\n\n return relationTargetSchemaNames;\n};\n\nconst buildComponentSchema = (\n api: Api,\n relationTargetSchemaNames = getRelationTargetSchemaNames(api)\n) => {\n // A reusable loop for building paths and component schemas\n // Uses the api param to build a new set of params for each content type\n // Passes these new params to the function provided\n return loopContentTypeNames(api, (apiInfo) =>\n getAllSchemasForContentType({ ...apiInfo, relationTargetSchemaNames })\n );\n};\n\nexport default buildComponentSchema;\nexport { getRelationTargetSchemaNames };\n"],"names":["getRequiredAttributes","allAttributes","requiredAttributes","key","required","push","getAllSchemasForContentType","routeInfo","attributes","uniqueName","relationTargetSchemaNames","strapiComponentSchemas","schemas","typeName","pascalCase","didAddStrapiComponentsToSchemas","schemaName","schema","Object","keys","properties","routeMethods","Set","routes","map","route","method","attributesToOmit","attributesForRequest","_","omit","requiredRequestAttributes","has","assign","type","data","length","cleanSchemaAttributes","isRequest","hasListOfEntities","filter","hasFindMethod","handler","items","$ref","meta","pagination","page","pageSize","minimum","pageCount","maximum","total","id","oneOf","documentId","getRelationTargetSchemaNames","api","Map","loopContentTypeNames","uid","set","buildComponentSchema","apiInfo"],"mappings":"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"}