@flink-app/api-docs-plugin 0.12.1-alpha.9 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BUILD.md +52 -0
- package/CHANGELOG.md +13 -0
- package/DEVELOPMENT.md +64 -0
- package/dist/dev-server.d.ts +1 -0
- package/dist/dev-server.js +46 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +9 -14
- package/dist/react-app/api-docs-favicon.svg +14 -0
- package/dist/react-app/assets/index-DZQKCGSz.css +1 -0
- package/dist/react-app/assets/index-Ds6xtmfB.js +57 -0
- package/dist/react-app/assets/index-Ds6xtmfB.js.map +1 -0
- package/dist/react-app/index.html +14 -0
- package/dist/react-app/vite.svg +1 -0
- package/package.json +29 -29
- package/readme.md +111 -18
- package/dist/views/index.pug +0 -22
- package/nodemon.json +0 -6
- package/src/index.ts +0 -52
- package/src/views/index.pug +0 -22
- package/tsconfig.json +0 -23
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="./api-docs-favicon.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>API Docs</title>
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-Ds6xtmfB.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-DZQKCGSz.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div id="root"></div>
|
|
13
|
+
</body>
|
|
14
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
package/package.json
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
2
|
+
"name": "@flink-app/api-docs-plugin",
|
|
3
|
+
"version": "0.13.1",
|
|
4
|
+
"description": "Flink plugin that generates API documentation based on JSON schemas",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist/**/*",
|
|
7
|
+
"*.md"
|
|
8
|
+
],
|
|
9
|
+
"author": "joel@frost.se",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/node": "22.13.10",
|
|
15
|
+
"ts-node": "^10.9.2",
|
|
16
|
+
"tsc-watch": "^4.2.9",
|
|
17
|
+
"@flink-app/flink": "0.13.1"
|
|
18
|
+
},
|
|
19
|
+
"gitHead": "4243e3b3cd6d4e1ca001a61baa8436bf2bbe4113",
|
|
20
|
+
"scripts": {
|
|
21
|
+
"test": "echo \"Error: no test specified\"",
|
|
22
|
+
"build": "npm run build:react && tsc && npm run copy:assets",
|
|
23
|
+
"build:react": "cd react-app && npm run build",
|
|
24
|
+
"copy:assets": "mkdir -p dist/react-app && cp -r react-app/dist/* dist/react-app/",
|
|
25
|
+
"watch": "tsc-watch",
|
|
26
|
+
"dev:mock-api": "ts-node src/dev-server.ts",
|
|
27
|
+
"dev:react": "cd react-app && npm run dev",
|
|
28
|
+
"clean": "rimraf dist .flink react-app/dist"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/readme.md
CHANGED
|
@@ -1,33 +1,126 @@
|
|
|
1
|
-
# Flink API Docs
|
|
1
|
+
# Flink API Docs Plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A FLINK plugin that automatically generates beautiful API documentation based on your app's registered routes and schemas. This plugin provides a modern, Swagger-like interface for exploring and understanding your API endpoints.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
registered routes and schemas.
|
|
5
|
+
## Features
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
- 🚀 Automatic API documentation generation
|
|
8
|
+
- 🔍 Detailed request/response schema documentation
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Installation
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Install the plugin to your Flink app project:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
13
15
|
npm i -S @flink-app/api-docs-plugin
|
|
14
16
|
```
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
## Usage
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
Add and configure the plugin in your app startup (typically in your root `index.ts`):
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
19
23
|
import { apiDocPlugin } from "@flink-app/api-docs-plugin";
|
|
20
24
|
|
|
21
25
|
function start() {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
new FlinkApp<AppContext>({
|
|
27
|
+
name: "My app",
|
|
28
|
+
plugins: [
|
|
29
|
+
// Register plugin with custom options
|
|
30
|
+
apiDocPlugin({
|
|
31
|
+
title: "API Docs: My app",
|
|
32
|
+
path: "/docs", // Optional: defaults to "/docs"
|
|
33
|
+
apiPath: "/docs/api", // Optional: defaults to "/docs/api"
|
|
34
|
+
}),
|
|
35
|
+
],
|
|
36
|
+
}).start();
|
|
31
37
|
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Configuration Options
|
|
41
|
+
|
|
42
|
+
The plugin accepts the following configuration options:
|
|
43
|
+
|
|
44
|
+
| Option | Type | Default | Description |
|
|
45
|
+
| ------------- | ------- | ----------- | ---------------------------------------------- |
|
|
46
|
+
| `path` | string | `/docs` | The URL path where the documentation is served |
|
|
47
|
+
| `apiPath` | string | `/docs/api` | The URL path where the API data is served |
|
|
48
|
+
| `name` | string | - | Custom name for the plugin instance |
|
|
49
|
+
| `title` | string | `API Docs` | The title displayed in the documentation UI |
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## How It Works
|
|
54
|
+
|
|
55
|
+
The plugin automatically:
|
|
56
|
+
|
|
57
|
+
1. Sets up a static file server at the specified path (defaults to `/docs`)
|
|
58
|
+
2. Creates an API endpoint at `/docs/api` that exposes route information
|
|
59
|
+
3. Serves a React application that fetches and displays your API documentation
|
|
60
|
+
4. Groups endpoints by resource for better organization
|
|
61
|
+
5. Displays detailed request/response schemas with proper TypeScript types
|
|
62
|
+
|
|
63
|
+
## Development
|
|
64
|
+
|
|
65
|
+
For local development of the API documentation UI:
|
|
66
|
+
|
|
67
|
+
1. Start the mock API server:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm run dev:mock-api
|
|
71
|
+
```
|
|
32
72
|
|
|
73
|
+
2. In another terminal, start the React development server:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npm run dev:react
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
3. Open http://localhost:5173 in your browser
|
|
80
|
+
|
|
81
|
+
The development setup includes hot-reloading for the React application, allowing you to see changes instantly as you modify the UI components.
|
|
82
|
+
|
|
83
|
+
## Architecture
|
|
84
|
+
|
|
85
|
+
The plugin consists of two main parts:
|
|
86
|
+
|
|
87
|
+
1. **Express Plugin**: Integrates with your Flink application to serve the documentation
|
|
88
|
+
2. **React Application**: Modern UI that displays the API documentation
|
|
89
|
+
|
|
90
|
+
The React app uses:
|
|
91
|
+
|
|
92
|
+
- Tailwind CSS for styling
|
|
93
|
+
- TypeScript for type safety
|
|
94
|
+
- Vite for fast development and building
|
|
95
|
+
|
|
96
|
+
## Requirements
|
|
97
|
+
|
|
98
|
+
- Node.js v20.17.0 or higher (as specified in root .nvmrc)
|
|
99
|
+
- A Flink application with Express initialized
|
|
100
|
+
|
|
101
|
+
## UI Features
|
|
102
|
+
|
|
103
|
+
- **Method Badges**: Color-coded HTTP method indicators (GET, POST, PUT, DELETE, etc.)
|
|
104
|
+
- **Expandable Sections**: Click on endpoints to view detailed information
|
|
105
|
+
- **Schema Tables**: Well-formatted tables showing request/response properties
|
|
106
|
+
- **Type Information**: Clear display of property types and requirements
|
|
107
|
+
- **Description Support**: Built-in support for endpoint and property descriptions
|
|
108
|
+
- **Mock Endpoint Indicators**: Visual indicators for mocked endpoints
|
|
109
|
+
- **Responsive Design**: Works seamlessly on desktop and mobile devices
|
|
110
|
+
- **TypeScript Interface Generation**: Copy TypeScript interfaces for request/response bodies
|
|
111
|
+
|
|
112
|
+
## Building
|
|
113
|
+
|
|
114
|
+
To build the complete plugin:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm run prepare
|
|
33
118
|
```
|
|
119
|
+
|
|
120
|
+
This will:
|
|
121
|
+
|
|
122
|
+
1. Build the React application
|
|
123
|
+
2. Compile TypeScript files
|
|
124
|
+
3. Copy all necessary assets to the dist directory
|
|
125
|
+
|
|
126
|
+
The built plugin can then be published to npm and used in any Flink application.
|
package/dist/views/index.pug
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
html
|
|
2
|
-
head
|
|
3
|
-
title= title
|
|
4
|
-
body
|
|
5
|
-
h1= "API Documentation"
|
|
6
|
-
|
|
7
|
-
ul
|
|
8
|
-
each handler in handlers
|
|
9
|
-
li
|
|
10
|
-
h2 #{handler.routeProps.method.toUpperCase()} #{handler.routeProps.path} #{handler.routeProps.mockApi ? " (mocked)" : ""}
|
|
11
|
-
h3 Request schema
|
|
12
|
-
pre
|
|
13
|
-
code #{handler.schema.reqSchema ? JSON.stringify(handler.schema.reqSchema, null, 2) : "n/a"}
|
|
14
|
-
h3 Response schema
|
|
15
|
-
pre
|
|
16
|
-
code #{handler.schema.resSchema ? JSON.stringify(handler.schema.resSchema || {}, null, 2) : "n/a"}
|
|
17
|
-
h3 Query
|
|
18
|
-
pre
|
|
19
|
-
code #{handler.queryMetadata ? JSON.stringify(handler.queryMetadata || {}, null, 2) : "n/a"}
|
|
20
|
-
h3 Params
|
|
21
|
-
pre
|
|
22
|
-
code #{handler.paramsMetadata ? JSON.stringify(handler.paramsMetadata || {}, null, 2) : "n/a"}
|
package/nodemon.json
DELETED
package/src/index.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { FlinkApp, FlinkPlugin } from "@flink-app/flink";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
|
|
4
|
-
export type ApiDocOptions = {
|
|
5
|
-
/**
|
|
6
|
-
* Path to where api docs can be accessed
|
|
7
|
-
*/
|
|
8
|
-
path?: string;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Name of plugin
|
|
12
|
-
*/
|
|
13
|
-
name?: string;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Title of API Docs, shown to end user who accesses API docs in browser.
|
|
17
|
-
*/
|
|
18
|
-
title?: string;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export const apiDocPlugin = (options: ApiDocOptions = {}): FlinkPlugin => {
|
|
22
|
-
return {
|
|
23
|
-
id: "apiDocs",
|
|
24
|
-
init: (app) => init(app, options),
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
function init(app: FlinkApp<any>, options: ApiDocOptions) {
|
|
29
|
-
// TODO: Use parsedHandlerConfig
|
|
30
|
-
const { expressApp, handlers } = app;
|
|
31
|
-
|
|
32
|
-
if (!expressApp) {
|
|
33
|
-
// should not happen
|
|
34
|
-
throw new Error("Express app not initialized");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// NOTE: This will probably break if any other plugin "claims" pug as view engine
|
|
38
|
-
expressApp.engine("pug", require("pug").__express);
|
|
39
|
-
expressApp.set("views", join(__dirname, "views"));
|
|
40
|
-
expressApp.set("view engine", "pug");
|
|
41
|
-
|
|
42
|
-
expressApp?.get(options.path || "/docs", (req, res) => {
|
|
43
|
-
const sortedHandlers = handlers.sort((routeA, routeB) =>
|
|
44
|
-
routeA.routeProps.path.localeCompare(routeB.routeProps.path)
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
res.render("index", {
|
|
48
|
-
title: options.title || "API Docs",
|
|
49
|
-
handlers: sortedHandlers,
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
}
|
package/src/views/index.pug
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
html
|
|
2
|
-
head
|
|
3
|
-
title= title
|
|
4
|
-
body
|
|
5
|
-
h1= "API Documentation"
|
|
6
|
-
|
|
7
|
-
ul
|
|
8
|
-
each handler in handlers
|
|
9
|
-
li
|
|
10
|
-
h2 #{handler.routeProps.method.toUpperCase()} #{handler.routeProps.path} #{handler.routeProps.mockApi ? " (mocked)" : ""}
|
|
11
|
-
h3 Request schema
|
|
12
|
-
pre
|
|
13
|
-
code #{handler.schema.reqSchema ? JSON.stringify(handler.schema.reqSchema, null, 2) : "n/a"}
|
|
14
|
-
h3 Response schema
|
|
15
|
-
pre
|
|
16
|
-
code #{handler.schema.resSchema ? JSON.stringify(handler.schema.resSchema || {}, null, 2) : "n/a"}
|
|
17
|
-
h3 Query
|
|
18
|
-
pre
|
|
19
|
-
code #{handler.queryMetadata ? JSON.stringify(handler.queryMetadata || {}, null, 2) : "n/a"}
|
|
20
|
-
h3 Params
|
|
21
|
-
pre
|
|
22
|
-
code #{handler.paramsMetadata ? JSON.stringify(handler.paramsMetadata || {}, null, 2) : "n/a"}
|
package/tsconfig.json
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "es5",
|
|
4
|
-
"lib": ["esnext", "es2016"],
|
|
5
|
-
"allowJs": true,
|
|
6
|
-
"skipLibCheck": true,
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"allowSyntheticDefaultImports": true,
|
|
9
|
-
"strict": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"module": "commonjs",
|
|
12
|
-
"moduleResolution": "node",
|
|
13
|
-
"resolveJsonModule": true,
|
|
14
|
-
"isolatedModules": true,
|
|
15
|
-
"noEmit": false,
|
|
16
|
-
"declaration": true,
|
|
17
|
-
"experimentalDecorators": true,
|
|
18
|
-
"checkJs": true,
|
|
19
|
-
"outDir": "dist"
|
|
20
|
-
},
|
|
21
|
-
"include": ["./src/*"],
|
|
22
|
-
"exclude": ["./node_modules/*"]
|
|
23
|
-
}
|