@strapi/plugin-documentation 0.0.0-e6cac9fe30 → 0.0.0-e90885ab911e40d21aca1728d8abca8f13d582d5

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.
@@ -0,0 +1,39 @@
1
+ {
2
+ "coming-soon": "Det här innehållet är för närvarande under uppbyggnad och kommer tillbaka om några veckor!",
3
+ "components.Row.open": "Öppen",
4
+ "components.Row.regenerate": "Återskapa",
5
+ "containers.HomePage.Block.title": "Versioner",
6
+ "containers.HomePage.Button.update": "Uppdatera",
7
+ "containers.HomePage.PluginHeader.title": "Dokumentation - Inställningar",
8
+ "containers.HomePage.PopUpWarning.confirm": "Jag förstår",
9
+ "containers.HomePage.PopUpWarning.message": "Är du säker på att du vill ta bort denna versionen?",
10
+ "containers.HomePage.copied": "Token har kopierats till urklipp",
11
+ "containers.HomePage.form.jwtToken": "Hämta din jwt-token",
12
+ "containers.HomePage.form.jwtToken.description": "Kopiera denna token och använd den i swagger för att göra förfrågningar",
13
+ "containers.HomePage.form.password": "Lösenord",
14
+ "containers.HomePage.form.password.inputDescription": "Ställ in lösenordet som ska behövas för att komma åt dokumentationen",
15
+ "containers.HomePage.form.restrictedAccess": "Begränsad åtkomst",
16
+ "containers.HomePage.form.restrictedAccess.inputDescription": "Gör dokumentationensrutten privat. Som standard är åtkomsten publik",
17
+ "containers.HomePage.form.showGeneratedFiles": "Visa genererade filer",
18
+ "containers.HomePage.form.showGeneratedFiles.inputDescription": "Användbart när du vill överskrida den automatiskt genererade dokumentationen. \nPluginet genererar filer uppdelade efter modell och plugin. \nGenom att aktivera det här blir det lättare att anpassa din dokumentation",
19
+ "error.deleteDoc.versionMissing": "Den version du försöker ta bort finns inte.",
20
+ "error.noVersion": "En version krävs",
21
+ "error.regenerateDoc": "Ett fel uppstod när dokumentet återskapades",
22
+ "error.regenerateDoc.versionMissing": "Den version du försöker generera finns inte",
23
+ "notification.delete.success": "Dokument raderat",
24
+ "notification.generate.success": "Dokument genererat",
25
+ "notification.update.success": "Inställningarna har uppdaterats",
26
+ "pages.PluginPage.Button.open": "Öppna dokumentation",
27
+ "pages.PluginPage.header.description": "Konfigurera dokumentationspluginet",
28
+ "pages.PluginPage.table.generated": "Senast genererade",
29
+ "pages.PluginPage.table.icon.regenerate": "Återskapa {target}",
30
+ "pages.PluginPage.table.icon.show": "Öppna {target}",
31
+ "pages.PluginPage.table.version": "Version",
32
+ "pages.SettingsPage.Button.description": "Konfigurera dokumentationspluginet",
33
+ "pages.SettingsPage.header.save": "Spara",
34
+ "pages.SettingsPage.toggle.hint": "Gör dokumentationensrutten privat",
35
+ "pages.SettingsPage.toggle.label": "Begränsad åtkomst",
36
+ "plugin.description.long": "Skapa ett OpenAPI-dokument och visualisera din API med SWAGGER UI.",
37
+ "plugin.description.short": "Skapa ett OpenAPI-dokument och visualisera din API med SWAGGER UI.",
38
+ "plugin.name": "Dokumentation"
39
+ }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "coming-soon": "此內容目前正在構建,將在幾周後回歸!",
2
3
  "components.Row.open": "開啟",
3
4
  "components.Row.regenerate": "重新產生",
4
5
  "containers.HomePage.Block.title": "版本",
@@ -6,19 +7,33 @@
6
7
  "containers.HomePage.PluginHeader.title": "文件資料 - 設定",
7
8
  "containers.HomePage.PopUpWarning.confirm": "我了解了",
8
9
  "containers.HomePage.PopUpWarning.message": "你確定要刪除這個版本嗎?",
9
- "containers.HomePage.copied": "Token 已經複製到剪貼簿",
10
- "containers.HomePage.form.jwtToken": "存取你的 jwt token",
11
- "containers.HomePage.form.jwtToken.description": "複製這個token並於swagger中使用於發出請求",
10
+ "containers.HomePage.copied": "權杖已經複製到剪貼簿",
11
+ "containers.HomePage.form.jwtToken": "存取你的 jwt 權杖",
12
+ "containers.HomePage.form.jwtToken.description": "複製這個權杖並於 swagger 中使用於發出請求",
12
13
  "containers.HomePage.form.password": "密碼",
13
14
  "containers.HomePage.form.password.inputDescription": "設定密碼存取權限",
14
15
  "containers.HomePage.form.restrictedAccess": "存取受到限制",
15
- "containers.HomePage.form.restrictedAccess.inputDescription": "將endpoints設定為私密的. 預設是對外公開的",
16
+ "containers.HomePage.form.restrictedAccess.inputDescription": "將 endpoints 設定為私密的。預設是對外公開的",
16
17
  "containers.HomePage.form.showGeneratedFiles": "顯示產生的檔案",
17
- "containers.HomePage.form.showGeneratedFiles.inputDescription": "用於覆寫產生的文件檔案時. \n擴充套件會依照model及plugin分別產生檔案. \n啟用這個選項將會方便你客製化文件資料",
18
+ "containers.HomePage.form.showGeneratedFiles.inputDescription": "用於覆寫產生的文件檔案時。\n擴充套件會依照model及plugin分別產生檔案。\n啟用這個選項將會方便你客製化文件資料",
18
19
  "error.deleteDoc.versionMissing": "你想刪除的版本不存在",
19
20
  "error.noVersion": "版本是必填欄位",
20
21
  "error.regenerateDoc": "重新產生文件資料時發生了錯誤",
21
22
  "error.regenerateDoc.versionMissing": "你想產生的版本不存在",
23
+ "notification.delete.success": "文件已刪除",
24
+ "notification.generate.success": "文件已重新產生",
22
25
  "notification.update.success": "更新設定成功",
26
+ "pages.PluginPage.Button.open": "開啟說明文件",
27
+ "pages.PluginPage.header.description": "設定說明文件外掛程式",
28
+ "pages.PluginPage.table.generated": "最後產生時間",
29
+ "pages.PluginPage.table.icon.regenerate": "重新產生 {target}",
30
+ "pages.PluginPage.table.icon.show": "開啟 {target}",
31
+ "pages.PluginPage.table.version": "版本",
32
+ "pages.SettingsPage.Button.description": "設定說明文件外掛程式",
33
+ "pages.SettingsPage.header.save": "儲存",
34
+ "pages.SettingsPage.toggle.hint": "將說明文件端點設為私人",
35
+ "pages.SettingsPage.toggle.label": "受限存取",
36
+ "plugin.description.long": "建立 OpenAPI 文件,並透過 SWAGGER UI 可視化您的 API。",
37
+ "plugin.description.short": "建立 OpenAPI 文件,並透過 SWAGGER UI 可視化您的 API。",
23
38
  "plugin.name": "文件資料"
24
39
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/plugin-documentation",
3
- "version": "0.0.0-e6cac9fe30",
3
+ "version": "0.0.0-e90885ab911e40d21aca1728d8abca8f13d582d5",
4
4
  "description": "Create an OpenAPI Document and visualize your API with SWAGGER UI.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,8 +24,8 @@
24
24
  "test": "echo \"no tests yet\""
25
25
  },
26
26
  "dependencies": {
27
- "@strapi/helper-plugin": "0.0.0-e6cac9fe30",
28
- "@strapi/utils": "0.0.0-e6cac9fe30",
27
+ "@strapi/helper-plugin": "0.0.0-e90885ab911e40d21aca1728d8abca8f13d582d5",
28
+ "@strapi/utils": "0.0.0-e90885ab911e40d21aca1728d8abca8f13d582d5",
29
29
  "bcryptjs": "2.4.3",
30
30
  "cheerio": "^1.0.0-rc.12",
31
31
  "fs-extra": "10.0.0",
@@ -36,20 +36,24 @@
36
36
  "react": "^17.0.2",
37
37
  "react-copy-to-clipboard": "^5.1.0",
38
38
  "react-dom": "^17.0.2",
39
- "react-intl": "5.20.2",
39
+ "react-intl": "5.25.1",
40
40
  "react-redux": "7.2.8",
41
41
  "react-router": "^5.2.0",
42
- "react-router-dom": "5.2.0",
42
+ "react-router-dom": "5.3.4",
43
43
  "redux": "^4.0.1",
44
44
  "reselect": "^4.0.0",
45
- "swagger-ui-dist": "4.12.0",
45
+ "swagger-ui-dist": "4.15.5",
46
46
  "yaml": "1.10.2"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "@strapi/strapi": "^4.0.0"
50
50
  },
51
+ "devDependencies": {
52
+ "@testing-library/react": "12.1.4",
53
+ "msw": "0.49.1"
54
+ },
51
55
  "engines": {
52
- "node": ">=14.19.1 <=16.x.x",
56
+ "node": ">=14.19.1 <=18.x.x",
53
57
  "npm": ">=6.0.0"
54
58
  },
55
59
  "strapi": {
@@ -58,5 +62,5 @@
58
62
  "description": "Create an OpenAPI Document and visualize your API with SWAGGER UI.",
59
63
  "kind": "plugin"
60
64
  },
61
- "gitHead": "e6cac9fe309b80c9c59cde56d6b25fc6cd40bc8d"
65
+ "gitHead": "e90885ab911e40d21aca1728d8abca8f13d582d5"
62
66
  }
@@ -15,12 +15,13 @@ module.exports = ({ strapi }) => {
15
15
 
16
16
  return {
17
17
  registerDoc(doc) {
18
+ let registeredDoc = doc;
18
19
  // parseYaml
19
20
  if (typeof doc === 'string') {
20
- doc = require('yaml').parse(doc);
21
+ registeredDoc = require('yaml').parse(registeredDoc);
21
22
  }
22
23
  // receive an object we can register it directly
23
- registeredDocs.push(doc);
24
+ registeredDocs.push(registeredDoc);
24
25
  },
25
26
  getDocumentationVersion() {
26
27
  return _.get(config, 'info.version');
@@ -46,7 +46,7 @@ const getPathParams = (routePath) => {
46
46
  description: '',
47
47
  deprecated: false,
48
48
  required: true,
49
- schema: { type: 'string' },
49
+ schema: { type: 'number' },
50
50
  };
51
51
  });
52
52
  };
@@ -20,6 +20,18 @@ const { hasFindMethod, isLocalizedPath } = require('./utils/routes');
20
20
  const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }) => {
21
21
  // Store response and request schemas in an object
22
22
  let schemas = {};
23
+ let componentSchemas = {};
24
+ // adds a ComponentSchema to the Schemas so it can be used as Ref
25
+ const addComponentSchema = (schemaName, schema) => {
26
+ if (!Object.keys(schema) || !Object.keys(schema.properties)) {
27
+ return false;
28
+ }
29
+ componentSchemas = {
30
+ ...componentSchemas,
31
+ [schemaName]: schema,
32
+ };
33
+ return true;
34
+ };
23
35
  // Get all the route methods
24
36
  const routeMethods = routeInfo.routes.map((route) => route.method);
25
37
  // Check for localized paths
@@ -56,7 +68,10 @@ const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }) => {
56
68
  [`${pascalCase(uniqueName)}LocalizationRequest`]: {
57
69
  required: [...requiredAttributes, 'locale'],
58
70
  type: 'object',
59
- properties: cleanSchemaAttributes(attributesForRequest, { isRequest: true }),
71
+ properties: cleanSchemaAttributes(attributesForRequest, {
72
+ isRequest: true,
73
+ addComponentSchema,
74
+ }),
60
75
  },
61
76
  };
62
77
  }
@@ -71,7 +86,10 @@ const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }) => {
71
86
  data: {
72
87
  required: requiredAttributes,
73
88
  type: 'object',
74
- properties: cleanSchemaAttributes(attributesForRequest, { isRequest: true }),
89
+ properties: cleanSchemaAttributes(attributesForRequest, {
90
+ isRequest: true,
91
+ addComponentSchema,
92
+ }),
75
93
  },
76
94
  },
77
95
  },
@@ -84,8 +102,8 @@ const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }) => {
84
102
  [`${pascalCase(uniqueName)}LocalizationResponse`]: {
85
103
  type: 'object',
86
104
  properties: {
87
- id: { type: 'string' },
88
- ...cleanSchemaAttributes(attributes),
105
+ id: { type: 'number' },
106
+ ...cleanSchemaAttributes(attributes, { addComponentSchema }),
89
107
  },
90
108
  },
91
109
  };
@@ -97,17 +115,37 @@ const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }) => {
97
115
  // Build the list response schema
98
116
  schemas = {
99
117
  ...schemas,
100
- [`${pascalCase(uniqueName)}ListResponse`]: {
118
+ [`${pascalCase(uniqueName)}ListResponseDataItem`]: {
101
119
  type: 'object',
120
+ properties: {
121
+ id: { type: 'number' },
122
+ attributes: {
123
+ type: 'object',
124
+ properties: cleanSchemaAttributes(attributes, {
125
+ addComponentSchema,
126
+ componentSchemaRefName: `#/components/schemas/${pascalCase(
127
+ uniqueName
128
+ )}ListResponseDataItemLocalized`,
129
+ }),
130
+ },
131
+ },
132
+ },
133
+ [`${pascalCase(uniqueName)}ListResponseDataItemLocalized`]: {
134
+ type: 'object',
135
+ properties: {
136
+ id: { type: 'number' },
137
+ attributes: {
138
+ type: 'object',
139
+ properties: cleanSchemaAttributes(attributes, { addComponentSchema }),
140
+ },
141
+ },
142
+ },
143
+ [`${pascalCase(uniqueName)}ListResponse`]: {
102
144
  properties: {
103
145
  data: {
104
146
  type: 'array',
105
147
  items: {
106
- type: 'object',
107
- properties: {
108
- id: { type: 'string' },
109
- attributes: { type: 'object', properties: cleanSchemaAttributes(attributes) },
110
- },
148
+ $ref: `#/components/schemas/${pascalCase(uniqueName)}ListResponseDataItem`,
111
149
  },
112
150
  },
113
151
  meta: {
@@ -131,22 +169,41 @@ const getAllSchemasForContentType = ({ routeInfo, attributes, uniqueName }) => {
131
169
  // Build the response schema
132
170
  schemas = {
133
171
  ...schemas,
134
- [`${pascalCase(uniqueName)}Response`]: {
172
+ [`${pascalCase(uniqueName)}ResponseDataObject`]: {
135
173
  type: 'object',
136
174
  properties: {
137
- data: {
175
+ id: { type: 'number' },
176
+ attributes: {
138
177
  type: 'object',
139
- properties: {
140
- id: { type: 'string' },
141
- attributes: { type: 'object', properties: cleanSchemaAttributes(attributes) },
142
- },
178
+ properties: cleanSchemaAttributes(attributes, {
179
+ addComponentSchema,
180
+ componentSchemaRefName: `#/components/schemas/${pascalCase(
181
+ uniqueName
182
+ )}ResponseDataObjectLocalized`,
183
+ }),
184
+ },
185
+ },
186
+ },
187
+ [`${pascalCase(uniqueName)}ResponseDataObjectLocalized`]: {
188
+ type: 'object',
189
+ properties: {
190
+ id: { type: 'number' },
191
+ attributes: {
192
+ type: 'object',
193
+ properties: cleanSchemaAttributes(attributes, { addComponentSchema }),
194
+ },
195
+ },
196
+ },
197
+ [`${pascalCase(uniqueName)}Response`]: {
198
+ properties: {
199
+ data: {
200
+ $ref: `#/components/schemas/${pascalCase(uniqueName)}ResponseDataObject`,
143
201
  },
144
202
  meta: { type: 'object' },
145
203
  },
146
204
  },
147
205
  };
148
-
149
- return schemas;
206
+ return { ...schemas, ...componentSchemas };
150
207
  };
151
208
 
152
209
  const buildComponentSchema = (api) => {
@@ -2,15 +2,23 @@
2
2
 
3
3
  const _ = require('lodash');
4
4
  const getSchemaData = require('./get-schema-data');
5
-
5
+ const pascalCase = require('./pascal-case');
6
6
  /**
7
7
  * @description - Converts types found on attributes to OpenAPI acceptable data types
8
8
  *
9
9
  * @param {object} attributes - The attributes found on a contentType
10
- * @param {{ typeMap: Map, isRequest: boolean }} opts
10
+ * @param {{ typeMap: Map, isRequest: boolean, addComponentSchema: function, componentSchemaRefName: string }} opts
11
11
  * @returns Attributes using OpenAPI acceptable data types
12
12
  */
13
- const cleanSchemaAttributes = (attributes, { typeMap = new Map(), isRequest = false } = {}) => {
13
+ const cleanSchemaAttributes = (
14
+ attributes,
15
+ {
16
+ typeMap = new Map(),
17
+ isRequest = false,
18
+ addComponentSchema = () => {},
19
+ componentSchemaRefName = '',
20
+ } = {}
21
+ ) => {
14
22
  const attributesCopy = _.cloneDeep(attributes);
15
23
 
16
24
  for (const prop of Object.keys(attributesCopy)) {
@@ -86,43 +94,53 @@ const cleanSchemaAttributes = (attributes, { typeMap = new Map(), isRequest = fa
86
94
  }
87
95
  case 'component': {
88
96
  const componentAttributes = strapi.components[attribute.component].attributes;
89
-
97
+ const rawComponentSchema = {
98
+ type: 'object',
99
+ properties: {
100
+ ...(isRequest ? {} : { id: { type: 'number' } }),
101
+ ...cleanSchemaAttributes(componentAttributes, {
102
+ typeMap,
103
+ isRequest,
104
+ }),
105
+ },
106
+ };
107
+ const refComponentSchema = {
108
+ $ref: `#/components/schemas/${pascalCase(attribute.component)}Component`,
109
+ };
110
+ const componentExists = addComponentSchema(
111
+ `${pascalCase(attribute.component)}Component`,
112
+ rawComponentSchema
113
+ );
114
+ const finalComponentSchema = componentExists ? refComponentSchema : rawComponentSchema;
90
115
  if (attribute.repeatable) {
91
116
  attributesCopy[prop] = {
92
117
  type: 'array',
93
- items: {
94
- type: 'object',
95
- properties: {
96
- ...(isRequest ? {} : { id: { type: 'string' } }),
97
- ...cleanSchemaAttributes(componentAttributes, { typeMap, isRequest }),
98
- },
99
- },
118
+ items: finalComponentSchema,
100
119
  };
101
120
  } else {
102
- attributesCopy[prop] = {
103
- type: 'object',
104
- properties: {
105
- ...(isRequest ? {} : { id: { type: 'string' } }),
106
- ...cleanSchemaAttributes(componentAttributes, {
107
- typeMap,
108
- isRequest,
109
- }),
110
- },
111
- };
121
+ attributesCopy[prop] = finalComponentSchema;
112
122
  }
113
123
  break;
114
124
  }
115
125
  case 'dynamiczone': {
116
126
  const components = attribute.components.map((component) => {
117
127
  const componentAttributes = strapi.components[component].attributes;
118
- return {
128
+ const rawComponentSchema = {
119
129
  type: 'object',
120
130
  properties: {
121
- ...(isRequest ? {} : { id: { type: 'string' } }),
131
+ ...(isRequest ? {} : { id: { type: 'number' } }),
122
132
  __component: { type: 'string' },
123
- ...cleanSchemaAttributes(componentAttributes, { typeMap, isRequest }),
133
+ ...cleanSchemaAttributes(componentAttributes, {
134
+ typeMap,
135
+ isRequest,
136
+ addComponentSchema,
137
+ }),
124
138
  },
125
139
  };
140
+ const refComponentSchema = { $ref: `#/components/schemas/${pascalCase(component)}` };
141
+ const componentExists = addComponentSchema(pascalCase(component), rawComponentSchema);
142
+ const finalComponentSchema = componentExists ? refComponentSchema : rawComponentSchema;
143
+ return finalComponentSchema;
126
144
  });
127
145
 
128
146
  attributesCopy[prop] = {
@@ -171,8 +189,13 @@ const cleanSchemaAttributes = (attributes, { typeMap = new Map(), isRequest = fa
171
189
 
172
190
  if (prop === 'localizations') {
173
191
  attributesCopy[prop] = {
174
- type: 'array',
175
- items: { type: 'object', properties: {} },
192
+ type: 'object',
193
+ properties: {
194
+ data: {
195
+ type: 'array',
196
+ items: componentSchemaRefName.length ? { $ref: componentSchemaRefName } : {},
197
+ },
198
+ },
176
199
  };
177
200
  break;
178
201
  }
@@ -15,7 +15,7 @@ module.exports = (isListOfEntities, attributes) => {
15
15
  items: {
16
16
  type: 'object',
17
17
  properties: {
18
- id: { type: 'string' },
18
+ id: { type: 'number' },
19
19
  attributes: { type: 'object', properties: attributes },
20
20
  },
21
21
  },
@@ -25,7 +25,7 @@ module.exports = (isListOfEntities, attributes) => {
25
25
  return {
26
26
  type: 'object',
27
27
  properties: {
28
- id: { type: 'string' },
28
+ id: { type: 'number' },
29
29
  attributes: { type: 'object', properties: attributes },
30
30
  },
31
31
  };
@@ -14,7 +14,7 @@ module.exports = [
14
14
  {
15
15
  name: 'pagination[withCount]',
16
16
  in: 'query',
17
- description: 'Retun page/pageSize (default: true)',
17
+ description: 'Return page/pageSize (default: true)',
18
18
  deprecated: false,
19
19
  required: false,
20
20
  schema: {
@@ -81,4 +81,25 @@ module.exports = [
81
81
  type: 'string',
82
82
  },
83
83
  },
84
+ {
85
+ name: 'filters',
86
+ in: 'query',
87
+ description: 'Filters to apply',
88
+ deprecated: false,
89
+ required: false,
90
+ schema: {
91
+ type: 'object',
92
+ },
93
+ style: 'deepObject',
94
+ },
95
+ {
96
+ name: 'locale',
97
+ in: 'query',
98
+ description: 'Locale to apply',
99
+ deprecated: false,
100
+ required: false,
101
+ schema: {
102
+ type: 'string',
103
+ },
104
+ },
84
105
  ];