directus-extension-api-docs 1.3.5 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +67 -62
  2. package/dist/index.js +1 -1
  3. package/package.json +62 -61
package/README.md CHANGED
@@ -22,77 +22,82 @@ Ref: https://github.com/directus/directus
22
22
 
23
23
  For include you custom endpoints.
24
24
 
25
- Create a `oasconfig.js` file under `/extensions/endpoints` folder.
25
+ Create a `oasconfig.yaml` file under `/extensions/endpoints` folder.
26
26
 
27
27
  Options:
28
28
 
29
29
  - `docsPath` _optional_ path where the interface will be (default 'api-docs')
30
+ - `tags` _optional_ openapi custom tags (will be merged with all standard and all customs tags)
31
+ - `paths` _optional_ openapi custom paths (will be merged with all standard and all customs paths)
32
+ - `components` _optional_ openapi custom components (will be merged with all standard and all customs tags)
33
+
34
+ Example below:
35
+
36
+ ```
37
+ docsPath: 'api-docs'
38
+ tags:
39
+ - name: MyCustomTag
40
+ description: MyCustomTag description
41
+ components:
42
+ schemas:
43
+ UserId:
44
+ type: object
45
+ required:
46
+ - user_id
47
+ x-collection: directus_users
48
+ properties:
49
+ user_id:
50
+ description: Unique identifier for the user.
51
+ example: 63716273-0f29-4648-8a2a-2af2948f6f78
52
+ type: string
53
+
54
+ ```
55
+
56
+ ## Definitions (optional)
57
+
58
+ For each custom endpoints group, you can define openapi including a file `oas.yaml` on root of your group folder.
59
+
60
+ Properties:
61
+
30
62
  - `tags` _optional_ openapi custom tags
31
63
  - `paths` _optional_ openapi custom paths
32
- - `components` _optional_ openapi custom components (you can ref to directus standard components declaring them empty)
64
+ - `components` _optional_ openapi custom components
33
65
 
34
- Example below:
66
+ Exemple below (`./extensions/endpoints/my-custom-path/oas.yaml`) :
35
67
 
36
68
  ```
37
- module.exports = {
38
- docsPath: 'api-docs'
39
- tags: [
40
- {
41
- name: 'MyCustomTag',
42
- description: 'MyCustomTag description',
43
- },
44
- ],
45
- paths: {
46
- '/my-custom-path/my-endpoint': {
47
- post: {
48
- summary: 'do something',
49
- description: 'do something',
50
- requestBody: {
51
- content: {
52
- 'application/json': {
53
- schema: {
54
- type: 'object',
55
- required: ['field'],
56
- properties: {
57
- field: {
58
- type: 'string',
59
- },
60
- },
61
- },
62
- },
63
- },
64
- responses: {
65
- '200': {
66
- description: 'Successful request',
67
- content: {
68
- 'application/json': {
69
- schema: {
70
- type: 'object',
71
- properties: {
72
- field: {
73
- type: 'string',
74
- },
75
- },
76
- },
77
- },
78
- },
79
- },
80
- '401': {
81
- description: 'Unauthorized',
82
- content: {},
83
- },
84
- '404': {
85
- description: 'Not Found',
86
- content: {},
87
- },
88
- },
89
- tags: ['MyCustomTag', 'Assets'],
90
- },
91
- },
92
- },
93
- },
94
- components: {},
95
- };
69
+ tags:
70
+ - name: MyCustomTag2
71
+ description: MyCustomTag description2
72
+ paths:
73
+ "/my-custom-path/my-endpoint":
74
+ post:
75
+ summary: Validate email
76
+ description: Validate email
77
+ tags:
78
+ - MyCustomTag2
79
+ - MyCustomTag
80
+ requestBody:
81
+ content:
82
+ application/json:
83
+ schema:
84
+ "$ref": "#/components/schemas/Users"
85
+ responses:
86
+ '200':
87
+ description: Successful request
88
+ content:
89
+ application/json:
90
+ schema:
91
+ "$ref": "#/components/schemas/User" // you can ref to standard components
92
+ '401':
93
+ description: Unauthorized
94
+ content: {}
95
+ '422':
96
+ description: Unprocessable Entity
97
+ content: {}
98
+ '500':
99
+ description: Server Error
100
+ content: {}
96
101
  ```
97
102
 
98
103
  ## Validations (optional)
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";const e=require("path"),s=process.cwd();let t;async function n(e,s){if(t)return JSON.parse(t);const{SpecificationService:n}=e,o=new n({accountability:{admin:!0},schema:s});return t=JSON.stringify(await o.oas.generate()),JSON.parse(t)}function o(e,s){return Object.entries(s).reduce(((e,[s,t])=>(e[s]=t&&"object"==typeof t?o(e[s]=e[s]||(Array.isArray(t)?[]:{}),t):t,e)),e)}const i=require("swagger-ui-express"),r=require("express-openapi-validator"),{findWorkspaceDir:a}=require("@pnpm/find-workspace-dir"),c=function(){try{return require(e.join(s,"./extensions/endpoints/oasconfig.js"))}catch(e){return{}}}(),p=(null==c?void 0:c.docsPath)||"api-docs";var u={id:p,validate:async function(e,s,t,o){if(null==c?void 0:c.paths){const i=await n(s,t);if(o)for(const e of o)i.paths[e]=c.paths[e];else i.paths=c.paths;c.components?i.components=c.components:(delete i.components.definitions,delete i.components.schemas),e.use(r.middleware({apiSpec:i})),e.use(((e,s,t,n)=>{t.status(e.status||500).json({message:e.message,errors:e.errors})}))}return e},handler:(e,{services:s,exceptions:t,logger:r,getSchema:u})=>{const{ServiceUnavailableException:d}=t,f={swaggerOptions:{url:`/${p}/oas`}};e.use("/",i.serve),e.get("/",i.setup({},f)),e.get("/oas",(async(e,t,i)=>{try{const e=await u(),i=await n(s,e),p=require(`${await a(".")}/package.json`);i.info.title=p.name,i.info.version=p.version,i.info.description=p.description;try{if(null==c?void 0:c.paths)for(const e in c.paths)i.paths[e]=c.paths[e];if(null==c?void 0:c.tags)for(const e of c.tags)i.tags.push(e);(null==c?void 0:c.components)&&(i.components=o(c.components,i.components))}catch(e){r.info("No custom definitions")}t.json(i)}catch(e){return i(new d(e.message||e[0].message))}}))}};module.exports=u;
1
+ "use strict";const e=require("js-yaml"),s=require("path"),n=require("fs"),t=process.cwd();let o;async function i(e,s){if(o)return JSON.parse(o);const{SpecificationService:n}=e,t=new n({accountability:{admin:!0},schema:s});return o=JSON.stringify(await t.oas.generate()),JSON.parse(o)}function a(e,s){return Object.entries(s).reduce(((e,[s,n])=>(e[s]=n&&"object"==typeof n?a(e[s]=e[s]||(Array.isArray(n)?[]:{}),n):n,e)),e)}const r=require("swagger-ui-express"),c=require("express-openapi-validator"),{findWorkspaceDir:p}=require("@pnpm/find-workspace-dir"),u=function(){try{const o=s.join(t,"./extensions/endpoints/oasconfig.json"),i=e.load(n.readFileSync(o,{encoding:"utf-8"})),a=s.join(t,"./extensions/endpoints"),r=n.readdirSync(a,{withFileTypes:!0});for(const s of r){const t=`${a}/${s.name}/oas.yaml`;if(s.isDirectory()&&n.existsSync(t)){const s=e.load(n.readFileSync(t,{encoding:"utf-8"}));i.tags=[...i.tags,...s.tags],i.paths={...i.paths,...s.paths},i.components={...i.components,...s.components}}}return i}catch(e){return{}}}(),d=(null==u?void 0:u.docsPath)||"api-docs";var f={id:d,validate:async function(e,s,n,t){if(null==u?void 0:u.paths){const o=await i(s,n);if(t)for(const e of t)o.paths[e]=u.paths[e];else o.paths=u.paths;u.components?o.components=u.components:(delete o.components.definitions,delete o.components.schemas),e.use(c.middleware({apiSpec:o})),e.use(((e,s,n,t)=>{n.status(e.status||500).json({message:e.message,errors:e.errors})}))}return e},handler:(e,{services:s,exceptions:n,logger:t,getSchema:o})=>{const{ServiceUnavailableException:c}=n,f={swaggerOptions:{url:`/${d}/oas`}};e.use("/",r.serve),e.get("/",r.setup({},f)),e.get("/oas",(async(e,n,r)=>{try{const e=await o(),r=await i(s,e),c=require(`${await p(".")}/package.json`);r.info.title=c.name,r.info.version=c.version,r.info.description=c.description;try{if(null==u?void 0:u.paths)for(const e in u.paths)r.paths[e]=u.paths[e];if(null==u?void 0:u.tags)for(const e of u.tags)r.tags.push(e);(null==u?void 0:u.components)&&(r.components=a(u.components,r.components))}catch(e){t.info("No custom definitions")}n.json(r)}catch(e){return r(new c(e.message||e[0].message))}}))}};module.exports=f;
package/package.json CHANGED
@@ -1,62 +1,63 @@
1
- {
2
- "name": "directus-extension-api-docs",
3
- "version": "1.3.5",
4
- "description": "directus extension for swagger interface and custom endpoints definitions",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "files": [
8
- "dist",
9
- "!*.map"
10
- ],
11
- "repository": "https://github.com/sacconazzo/directus-extension-api-docs",
12
- "homepage": "https://github.com/sacconazzo/directus-extension-api-docs#readme",
13
- "keywords": [
14
- "directus",
15
- "directus-extension",
16
- "directus-custom-endpoint",
17
- "swagger",
18
- "custom endpoints",
19
- "openapi definition",
20
- "openapi"
21
- ],
22
- "directus:extension": {
23
- "type": "endpoint",
24
- "path": "dist/index.js",
25
- "source": "src/index.ts",
26
- "host": "^9.19.2"
27
- },
28
- "scripts": {
29
- "test": "jest --verbose=true",
30
- "lint": "eslint --ignore-path .gitignore --ext .ts tests/ src/",
31
- "lint:fix": "pnpm lint --fix",
32
- "build": "directus-extension build",
33
- "dev": "directus-extension build -w --no-minify"
34
- },
35
- "dependencies": {
36
- "@pnpm/find-workspace-dir": "^5.0.0",
37
- "express-openapi-validator": "^4.13.8",
38
- "swagger-ui-express": "^4.6.0"
39
- },
40
- "devDependencies": {
41
- "@babel/preset-env": "^7.20.2",
42
- "@directus/extensions-sdk": "^9.20.4",
43
- "@types/express": "^4.17.14",
44
- "@types/jest": "^29.2.2",
45
- "@types/node": "^18.11.9",
46
- "@typescript-eslint/eslint-plugin": "^5.43.0",
47
- "@typescript-eslint/parser": "^5.43.0",
48
- "babel-jest": "^29.3.1",
49
- "eslint": "^8.27.0",
50
- "eslint-config-prettier": "^8.5.0",
51
- "eslint-plugin-import": "^2.26.0",
52
- "eslint-plugin-prettier": "^4.2.1",
53
- "express": "^4.18.2",
54
- "jest": "^29.3.1",
55
- "jest-extended": "^3.1.0",
56
- "openapi-schema-validator": "^12.0.2",
57
- "prettier": "^2.7.1",
58
- "ts-jest": "^29.0.3",
59
- "ts-node": "^10.9.1",
60
- "typescript": "^4.8.4"
61
- }
1
+ {
2
+ "name": "directus-extension-api-docs",
3
+ "version": "1.4.0",
4
+ "description": "directus extension for swagger interface and custom endpoints definitions",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "!*.map"
10
+ ],
11
+ "repository": "https://github.com/sacconazzo/directus-extension-api-docs",
12
+ "homepage": "https://github.com/sacconazzo/directus-extension-api-docs#readme",
13
+ "keywords": [
14
+ "directus",
15
+ "directus-extension",
16
+ "directus-custom-endpoint",
17
+ "swagger",
18
+ "custom endpoints",
19
+ "openapi definition",
20
+ "openapi"
21
+ ],
22
+ "directus:extension": {
23
+ "type": "endpoint",
24
+ "path": "dist/index.js",
25
+ "source": "src/index.ts",
26
+ "host": "^9.19.2"
27
+ },
28
+ "scripts": {
29
+ "test": "jest --verbose=true",
30
+ "lint": "eslint --ignore-path .gitignore --ext .ts tests/ src/",
31
+ "lint:fix": "pnpm lint --fix",
32
+ "build": "directus-extension build",
33
+ "dev": "directus-extension build -w --no-minify"
34
+ },
35
+ "dependencies": {
36
+ "@pnpm/find-workspace-dir": "^5.0.0",
37
+ "express-openapi-validator": "^4.13.8",
38
+ "js-yaml": "^4.1.0",
39
+ "swagger-ui-express": "^4.6.0"
40
+ },
41
+ "devDependencies": {
42
+ "@babel/preset-env": "^7.20.2",
43
+ "@directus/extensions-sdk": "^9.20.4",
44
+ "@types/express": "^4.17.14",
45
+ "@types/jest": "^29.2.3",
46
+ "@types/node": "^18.11.9",
47
+ "@typescript-eslint/eslint-plugin": "^5.43.0",
48
+ "@typescript-eslint/parser": "^5.43.0",
49
+ "babel-jest": "^29.3.1",
50
+ "eslint": "^8.27.0",
51
+ "eslint-config-prettier": "^8.5.0",
52
+ "eslint-plugin-import": "^2.26.0",
53
+ "eslint-plugin-prettier": "^4.2.1",
54
+ "express": "^4.18.2",
55
+ "jest": "^29.3.1",
56
+ "jest-extended": "^3.1.0",
57
+ "openapi-schema-validator": "^12.0.2",
58
+ "prettier": "^2.7.1",
59
+ "ts-jest": "^29.0.3",
60
+ "ts-node": "^10.9.1",
61
+ "typescript": "^4.9.3"
62
+ }
62
63
  }