azurajs-scalar 1.0.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.
- package/LICENSE +43 -0
- package/README.md +212 -0
- package/dist/api-docs.html +41 -0
- package/dist/index.d.ts +116 -0
- package/dist/index.js +245 -0
- package/dist/index.js.map +1 -0
- package/package.json +26 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Eduardo Developer <https://github.com/D3vEduardo>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Contribution Guidelines
|
|
26
|
+
|
|
27
|
+
Contributions to this library are welcome! You can contribute by forking this repository and submitting a pull request.
|
|
28
|
+
|
|
29
|
+
**Important Notes:**
|
|
30
|
+
- All contributions are subject to review and acceptance by the project maintainer
|
|
31
|
+
- Submitting a pull request does not grant contributor copyright or ownership rights to the library
|
|
32
|
+
- The original copyright and ownership remains with Eduardo Developer
|
|
33
|
+
- Contributors are acknowledged in good faith, but do not receive legal ownership or copyright claims
|
|
34
|
+
- By contributing, you agree that your contributions become part of the library under the same MIT License
|
|
35
|
+
|
|
36
|
+
**How to Contribute:**
|
|
37
|
+
1. Fork the repository
|
|
38
|
+
2. Create a feature branch
|
|
39
|
+
3. Make your changes
|
|
40
|
+
4. Submit a pull request
|
|
41
|
+
5. Please read this license carefully before contributing
|
|
42
|
+
|
|
43
|
+
For more information about this license, please refer to the full license text above.
|
package/README.md
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# @azurajs/scalar 📘
|
|
2
|
+
|
|
3
|
+
> Proxy middleware and controller to scalar documentation. 🔗
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚀 Features
|
|
8
|
+
|
|
9
|
+
- ⚡ Fast and lightweight proxy middleware
|
|
10
|
+
- 🎨 Customizable HTML templates
|
|
11
|
+
- 🌐 Seamless integration with Scalar API references
|
|
12
|
+
- 🔧 Easy configuration and setup
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 📦 Installation
|
|
17
|
+
|
|
18
|
+
Choose your favorite package manager:
|
|
19
|
+
|
|
20
|
+
### npm
|
|
21
|
+
```bash
|
|
22
|
+
npm i @azurajs/scalar
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### pnpm
|
|
26
|
+
```bash
|
|
27
|
+
pnpm i @azurajs/scalar
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 🛠️ Usage
|
|
33
|
+
|
|
34
|
+
### Configuration
|
|
35
|
+
|
|
36
|
+
#### src/index.ts
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import { AzuraClient } from "azurajs";
|
|
40
|
+
import { Scalar } from "@azurajs/scalar";
|
|
41
|
+
import path from "path";
|
|
42
|
+
import { fileURLToPath } from "url";
|
|
43
|
+
import { applyDecorators } from "azurajs/decorators";
|
|
44
|
+
import * from "./controllers"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
const app = new AzuraClient();
|
|
48
|
+
|
|
49
|
+
const __filename = fileURLToPath(import.meta.url); // Optional
|
|
50
|
+
const __dirname = path.dirname(__filename); // Optional
|
|
51
|
+
|
|
52
|
+
const scalar = new Scalar({
|
|
53
|
+
apiSpecUrl: "http://localhost:4002/api-spec.json",
|
|
54
|
+
proxyUrl: "http://localhost:4002",
|
|
55
|
+
customHtmlPath: path.join(__dirname, "./public/html/api-docs.html"), // Optional
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
applyDecorators(app, Object.values(Controllers))
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Controller Setup
|
|
62
|
+
|
|
63
|
+
#### src/controllers/docs.controller.ts
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { Controller, Get, Res } from "azurajs/decorators";
|
|
67
|
+
import { ResponseServer } from "azurajs/types";
|
|
68
|
+
import { getScalarDocs } from "@azurajs/scalar";
|
|
69
|
+
|
|
70
|
+
@Controller("/docs")
|
|
71
|
+
export class DocsController {
|
|
72
|
+
@Get("/")
|
|
73
|
+
scalarDocs(@Res() res: ResponseServer) {
|
|
74
|
+
getScalarDocs(res);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Export Controllers
|
|
80
|
+
|
|
81
|
+
#### src/controllers/index.ts
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
export * from "./docs.controller.ts";
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 🎨 Custom HTML Template
|
|
90
|
+
|
|
91
|
+
Create a custom HTML template for your API documentation with full control over styling and layout.
|
|
92
|
+
|
|
93
|
+
### Example:
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<!doctype html>
|
|
97
|
+
<html>
|
|
98
|
+
<head>
|
|
99
|
+
<title>Versum API - Sistine Chapel Theme</title>
|
|
100
|
+
<meta charset="utf-8" />
|
|
101
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
102
|
+
|
|
103
|
+
<link
|
|
104
|
+
href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700&family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&display=swap"
|
|
105
|
+
rel="stylesheet"
|
|
106
|
+
/>
|
|
107
|
+
|
|
108
|
+
<style>
|
|
109
|
+
:root {
|
|
110
|
+
--scalar-font: "Libre Baskerville", serif;
|
|
111
|
+
--scalar-font-code: "Courier New", monospace;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.light-mode {
|
|
115
|
+
--scalar-color-1: #2b2b26;
|
|
116
|
+
--scalar-color-2: #5f5a4f;
|
|
117
|
+
--scalar-color-accent: #8b3f2f;
|
|
118
|
+
--scalar-background-1: #f8f3ea;
|
|
119
|
+
--scalar-background-2: #efe6d6;
|
|
120
|
+
--scalar-background-3: #e3d7c3;
|
|
121
|
+
--scalar-border-color: rgba(139, 63, 47, 0.18);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.dark-mode {
|
|
125
|
+
--scalar-color-1: #f3eadb;
|
|
126
|
+
--scalar-color-2: #d6c7a1;
|
|
127
|
+
--scalar-color-accent: #b86b2f;
|
|
128
|
+
--scalar-background-1: #1c170f;
|
|
129
|
+
--scalar-background-2: #241e14;
|
|
130
|
+
--scalar-background-3: #2e2619;
|
|
131
|
+
--scalar-border-color: rgba(184, 107, 47, 0.25);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
h1,
|
|
135
|
+
h2,
|
|
136
|
+
h3 {
|
|
137
|
+
font-family: "Cinzel", serif;
|
|
138
|
+
font-weight: 700;
|
|
139
|
+
color: var(--scalar-color-accent) !important;
|
|
140
|
+
letter-spacing: 0.5px;
|
|
141
|
+
}
|
|
142
|
+
</style>
|
|
143
|
+
</head>
|
|
144
|
+
|
|
145
|
+
<body>
|
|
146
|
+
<div id="app">Carregando...</div>
|
|
147
|
+
|
|
148
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
149
|
+
<script>
|
|
150
|
+
// Busca o spec da porta 4002
|
|
151
|
+
fetch("&{api_spec_url}")
|
|
152
|
+
.then((res) => {
|
|
153
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
154
|
+
return res.json();
|
|
155
|
+
})
|
|
156
|
+
.then((spec) => {
|
|
157
|
+
console.log("Spec carregado:", spec);
|
|
158
|
+
|
|
159
|
+
Scalar.createApiReference("#app", {
|
|
160
|
+
spec: {
|
|
161
|
+
content: spec,
|
|
162
|
+
},
|
|
163
|
+
proxy: "&{proxy_url}",
|
|
164
|
+
theme: "none",
|
|
165
|
+
showSidebar: true,
|
|
166
|
+
withDefaultFonts: false,
|
|
167
|
+
});
|
|
168
|
+
})
|
|
169
|
+
.catch((err) => {
|
|
170
|
+
console.error("Erro ao carregar spec:", err);
|
|
171
|
+
document.getElementById("app").innerHTML =
|
|
172
|
+
`<pre style="color: red; padding: 20px;">
|
|
173
|
+
Erro ao carregar API spec: ${err.message}
|
|
174
|
+
|
|
175
|
+
Verifique se a API está rodando em &{proxy_url}
|
|
176
|
+
</pre>`;
|
|
177
|
+
});
|
|
178
|
+
</script>
|
|
179
|
+
</body>
|
|
180
|
+
</html>
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 🔧 External Variables
|
|
184
|
+
|
|
185
|
+
- `&{proxy_url}` - The proxy URL configured in your [configuration](####src/index.ts)
|
|
186
|
+
- `&{api_spec_url}` - The API specification URL configured in your [configuration](####src/index.ts)
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 🌐 References
|
|
191
|
+
|
|
192
|
+
- [AzuraJS](https://github.com/azurajs/azura) - The framework this package integrates with
|
|
193
|
+
- [Scalar](https://scalar.com/products/api-references/integrations/html-js) - The API reference tool
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## 👨💻 Author
|
|
198
|
+
|
|
199
|
+
**Eduardo Developer**
|
|
200
|
+
[](https://github.com/D3vEduardo)
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 📄 License
|
|
205
|
+
|
|
206
|
+
This project is licensed under the [MIT License](./LICENSE) - see the LICENSE file for details.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
<p align="center">
|
|
211
|
+
Made with ❤️ by <a href="https://github.com/D3vEduardo">@D3vEduardo</a>
|
|
212
|
+
</p>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Versum API - Sistine Chapel Theme</title>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
+
</head>
|
|
8
|
+
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app">Carregando...</div>
|
|
11
|
+
|
|
12
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
13
|
+
<script>
|
|
14
|
+
fetch("&{api_spec_url}")
|
|
15
|
+
.then((res) => {
|
|
16
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
17
|
+
return res.json();
|
|
18
|
+
})
|
|
19
|
+
.then((spec) => {
|
|
20
|
+
console.log("Spec carregado:", spec);
|
|
21
|
+
|
|
22
|
+
Scalar.createApiReference("#app", {
|
|
23
|
+
spec: {
|
|
24
|
+
content: spec,
|
|
25
|
+
},
|
|
26
|
+
proxy: "&{proxy_url}",
|
|
27
|
+
theme: "default",
|
|
28
|
+
});
|
|
29
|
+
})
|
|
30
|
+
.catch((err) => {
|
|
31
|
+
console.error("Erro ao carregar spec:", err);
|
|
32
|
+
document.getElementById("app").innerHTML =
|
|
33
|
+
`<pre style="color: red; padding: 20px;">
|
|
34
|
+
Erro ao carregar API spec: ${err.message}
|
|
35
|
+
|
|
36
|
+
Verifique se a API está rodando em &{proxy_url}
|
|
37
|
+
</pre>`;
|
|
38
|
+
});
|
|
39
|
+
</script>
|
|
40
|
+
</body>
|
|
41
|
+
</html>
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { RequestServer, ResponseServer, NextFunction } from 'azurajs/types';
|
|
2
|
+
|
|
3
|
+
interface ScalarConfigType {
|
|
4
|
+
apiSpecUrl: string;
|
|
5
|
+
proxyUrl: string;
|
|
6
|
+
customHtmlPath?: string;
|
|
7
|
+
}
|
|
8
|
+
interface ScalarStoreType {
|
|
9
|
+
proxy_url?: string;
|
|
10
|
+
api_spec_url?: string;
|
|
11
|
+
custom_html_path?: string;
|
|
12
|
+
}
|
|
13
|
+
type ProxyMiddlewareType = (req: RequestServer, res: ResponseServer, next?: NextFunction) => Promise<void>;
|
|
14
|
+
interface ProxyOptions {
|
|
15
|
+
apiSpecUrl: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @fileoverview Scalar client for API documentation proxy
|
|
20
|
+
* This module provides a client for setting up API documentation with proxy capabilities
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Scalar client class for managing API documentation proxy
|
|
25
|
+
*/
|
|
26
|
+
declare class Scalar {
|
|
27
|
+
/**
|
|
28
|
+
* Middleware function that handles proxying requests to the API specification
|
|
29
|
+
*/
|
|
30
|
+
proxyMiddleware: ProxyMiddlewareType;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a new Scalar client instance
|
|
33
|
+
* @param config Configuration object for the Scalar client
|
|
34
|
+
*/
|
|
35
|
+
constructor(config: ScalarConfigType);
|
|
36
|
+
/**
|
|
37
|
+
* Validates the provided configuration
|
|
38
|
+
* @param config Configuration object to validate
|
|
39
|
+
* @throws ScalarError if configuration is invalid
|
|
40
|
+
*/
|
|
41
|
+
private validateConfig;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @fileoverview Controller for serving Scalar API documentation
|
|
46
|
+
* This module handles serving the API documentation HTML with proper URL replacements
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Serves the Scalar API documentation HTML page
|
|
51
|
+
* Replaces placeholders in the HTML template with actual URLs from the store
|
|
52
|
+
* @param res Response object to send the HTML to
|
|
53
|
+
* @returns Promise that resolves when the response is sent
|
|
54
|
+
*/
|
|
55
|
+
declare function getScalarDocs(res: ResponseServer): Promise<ResponseServer>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @fileoverview Proxy middleware for API requests
|
|
59
|
+
* This module provides a proxy middleware that forwards requests to the API specification
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Creates a proxy middleware function that forwards requests to the API specification
|
|
64
|
+
* @param options Configuration options for the proxy
|
|
65
|
+
* @returns Middleware function that handles proxying requests
|
|
66
|
+
*/
|
|
67
|
+
declare function proxyMiddleware({ apiSpecUrl, }: ProxyOptions): (req: RequestServer, res: ResponseServer, next?: NextFunction) => Promise<void>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @fileoverview Store utility for managing application state
|
|
71
|
+
* This module provides a typed store for managing scalar configuration values
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Typed store class for managing scalar configuration values
|
|
76
|
+
*/
|
|
77
|
+
declare class ScalarStore {
|
|
78
|
+
private store;
|
|
79
|
+
/**
|
|
80
|
+
* Sets a value in the store
|
|
81
|
+
* @param key The key to set
|
|
82
|
+
* @param value The value to set (if undefined, the key will be removed)
|
|
83
|
+
*/
|
|
84
|
+
set<K extends keyof ScalarStoreType>(key: K, value: ScalarStoreType[K]): void;
|
|
85
|
+
/**
|
|
86
|
+
* Gets a value from the store
|
|
87
|
+
* @param key The key to get
|
|
88
|
+
* @returns The value associated with the key
|
|
89
|
+
*/
|
|
90
|
+
get<K extends keyof ScalarStoreType>(key: K): ScalarStoreType[K];
|
|
91
|
+
/**
|
|
92
|
+
* Checks if a key exists in the store
|
|
93
|
+
* @param key The key to check
|
|
94
|
+
* @returns True if the key exists, false otherwise
|
|
95
|
+
*/
|
|
96
|
+
has(key: keyof ScalarStoreType): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Deletes a key from the store
|
|
99
|
+
* @param key The key to delete
|
|
100
|
+
* @returns True if the key existed and was deleted, false otherwise
|
|
101
|
+
*/
|
|
102
|
+
delete(key: keyof ScalarStoreType): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Clears all values from the store
|
|
105
|
+
*/
|
|
106
|
+
clear(): void;
|
|
107
|
+
/**
|
|
108
|
+
* Gets all values from the store
|
|
109
|
+
* @returns An object containing all key-value pairs in the store
|
|
110
|
+
*/
|
|
111
|
+
getAll(): ScalarStoreType;
|
|
112
|
+
[key: string]: any;
|
|
113
|
+
}
|
|
114
|
+
declare const store: ScalarStore;
|
|
115
|
+
|
|
116
|
+
export { type ProxyMiddlewareType, Scalar, type ScalarConfigType, getScalarDocs, proxyMiddleware, store };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// src/config/types.ts
|
|
2
|
+
var ScalarError = class _ScalarError extends Error {
|
|
3
|
+
constructor(message, code, statusCode) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
Object.setPrototypeOf(this, _ScalarError.prototype);
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
// src/middleware/proxy.ts
|
|
12
|
+
import { logger } from "azurajs/logger";
|
|
13
|
+
function proxyMiddleware({
|
|
14
|
+
apiSpecUrl
|
|
15
|
+
}) {
|
|
16
|
+
return async (req, res, _next) => {
|
|
17
|
+
try {
|
|
18
|
+
if (!req.url || !req.method) {
|
|
19
|
+
res.status(400).json({
|
|
20
|
+
error: "Request URL and method are required",
|
|
21
|
+
code: "INVALID_REQUEST"
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
logger("info", `[PROXY] ${req.method} ${req.url}`);
|
|
26
|
+
const url = new URL(req.url, "http://localhost");
|
|
27
|
+
const targetUrl = apiSpecUrl + url.pathname + url.search;
|
|
28
|
+
logger("info", `[PROXY] Forwarding to: ${targetUrl}`);
|
|
29
|
+
const headers = {};
|
|
30
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
31
|
+
if (value) {
|
|
32
|
+
headers[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
headers.host = new URL(apiSpecUrl).host;
|
|
36
|
+
let body = null;
|
|
37
|
+
if (!["GET", "HEAD"].includes(req.method)) {
|
|
38
|
+
if (req.body) {
|
|
39
|
+
if (typeof req.body === "string") {
|
|
40
|
+
body = req.body;
|
|
41
|
+
} else if (typeof req.body === "object") {
|
|
42
|
+
body = JSON.stringify(req.body);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const proxyRes = await fetch(targetUrl, {
|
|
47
|
+
method: req.method,
|
|
48
|
+
headers,
|
|
49
|
+
body
|
|
50
|
+
});
|
|
51
|
+
logger("info", `[PROXY] Response: ${proxyRes.status}`);
|
|
52
|
+
const responseHeaders = {
|
|
53
|
+
"Access-Control-Allow-Origin": "*",
|
|
54
|
+
"Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,DELETE,OPTIONS",
|
|
55
|
+
"Access-Control-Allow-Headers": "*"
|
|
56
|
+
};
|
|
57
|
+
for (const [key, value] of proxyRes.headers.entries()) {
|
|
58
|
+
if (!key.toLowerCase().startsWith("access-control-")) {
|
|
59
|
+
responseHeaders[key] = value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
res.writeHead(proxyRes.status, responseHeaders);
|
|
63
|
+
if (req.method === "OPTIONS") {
|
|
64
|
+
res.end();
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const buffer = Buffer.from(await proxyRes.arrayBuffer());
|
|
68
|
+
res.end(buffer);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
logger("error", `[PROXY] Error: ${err}`);
|
|
71
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
72
|
+
res.end(JSON.stringify({
|
|
73
|
+
error: "Proxy error",
|
|
74
|
+
details: err instanceof Error ? err.message : String(err),
|
|
75
|
+
code: "PROXY_ERROR"
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/utils/store.ts
|
|
82
|
+
var ScalarStore = class {
|
|
83
|
+
constructor() {
|
|
84
|
+
this.store = /* @__PURE__ */ new Map();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Sets a value in the store
|
|
88
|
+
* @param key The key to set
|
|
89
|
+
* @param value The value to set (if undefined, the key will be removed)
|
|
90
|
+
*/
|
|
91
|
+
set(key, value) {
|
|
92
|
+
this.store.set(key, value);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Gets a value from the store
|
|
96
|
+
* @param key The key to get
|
|
97
|
+
* @returns The value associated with the key
|
|
98
|
+
*/
|
|
99
|
+
get(key) {
|
|
100
|
+
return this.store.get(key);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Checks if a key exists in the store
|
|
104
|
+
* @param key The key to check
|
|
105
|
+
* @returns True if the key exists, false otherwise
|
|
106
|
+
*/
|
|
107
|
+
has(key) {
|
|
108
|
+
return this.store.has(key);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Deletes a key from the store
|
|
112
|
+
* @param key The key to delete
|
|
113
|
+
* @returns True if the key existed and was deleted, false otherwise
|
|
114
|
+
*/
|
|
115
|
+
delete(key) {
|
|
116
|
+
return this.store.delete(key);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Clears all values from the store
|
|
120
|
+
*/
|
|
121
|
+
clear() {
|
|
122
|
+
this.store.clear();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Gets all values from the store
|
|
126
|
+
* @returns An object containing all key-value pairs in the store
|
|
127
|
+
*/
|
|
128
|
+
getAll() {
|
|
129
|
+
const result = {};
|
|
130
|
+
for (const [key, value] of this.store.entries()) {
|
|
131
|
+
result[key] = value;
|
|
132
|
+
}
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
var store = new ScalarStore();
|
|
137
|
+
|
|
138
|
+
// src/client.ts
|
|
139
|
+
var Scalar = class {
|
|
140
|
+
/**
|
|
141
|
+
* Creates a new Scalar client instance
|
|
142
|
+
* @param config Configuration object for the Scalar client
|
|
143
|
+
*/
|
|
144
|
+
constructor(config) {
|
|
145
|
+
this.validateConfig(config);
|
|
146
|
+
store.set("proxy_url", config.proxyUrl);
|
|
147
|
+
store.set("api_spec_url", config.apiSpecUrl);
|
|
148
|
+
store.set("custom_html_path", config.customHtmlPath);
|
|
149
|
+
this.proxyMiddleware = proxyMiddleware({ apiSpecUrl: config.apiSpecUrl });
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Validates the provided configuration
|
|
153
|
+
* @param config Configuration object to validate
|
|
154
|
+
* @throws ScalarError if configuration is invalid
|
|
155
|
+
*/
|
|
156
|
+
validateConfig(config) {
|
|
157
|
+
if (!config.apiSpecUrl) {
|
|
158
|
+
throw new ScalarError(
|
|
159
|
+
"apiSpecUrl is required",
|
|
160
|
+
"MISSING_API_SPEC_URL",
|
|
161
|
+
400
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
if (!config.proxyUrl) {
|
|
165
|
+
throw new ScalarError(
|
|
166
|
+
"proxyUrl is required",
|
|
167
|
+
"MISSING_PROXY_URL",
|
|
168
|
+
400
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
new URL(config.apiSpecUrl);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
throw new ScalarError(
|
|
175
|
+
"apiSpecUrl must be a valid URL",
|
|
176
|
+
"INVALID_API_SPEC_URL",
|
|
177
|
+
400
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
new URL(config.proxyUrl);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
throw new ScalarError(
|
|
184
|
+
"proxyUrl must be a valid URL",
|
|
185
|
+
"INVALID_PROXY_URL",
|
|
186
|
+
400
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
// src/controller.ts
|
|
193
|
+
import { fileURLToPath } from "url";
|
|
194
|
+
import path from "path";
|
|
195
|
+
import fs from "fs";
|
|
196
|
+
import { logger as logger2 } from "azurajs/logger";
|
|
197
|
+
var __filename = fileURLToPath(import.meta.url);
|
|
198
|
+
var __dirname = path.dirname(__filename);
|
|
199
|
+
async function getScalarDocs(res) {
|
|
200
|
+
try {
|
|
201
|
+
const customHtmlPath = store.get("custom_html_path");
|
|
202
|
+
const proxyUrl = store.get("proxy_url");
|
|
203
|
+
const apiSpecUrl = store.get("api_spec_url");
|
|
204
|
+
if (!proxyUrl || !apiSpecUrl) {
|
|
205
|
+
throw new ScalarError(
|
|
206
|
+
"Proxy URL or API Spec URL not defined in store",
|
|
207
|
+
"STORE_VALUES_MISSING",
|
|
208
|
+
500
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
const htmlPath = customHtmlPath || path.join(__dirname, "./api-docs.html");
|
|
212
|
+
if (!fs.existsSync(htmlPath)) {
|
|
213
|
+
throw new ScalarError(
|
|
214
|
+
`HTML template file not found at path: ${htmlPath}`,
|
|
215
|
+
"HTML_TEMPLATE_NOT_FOUND",
|
|
216
|
+
404
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
const html = fs.readFileSync(htmlPath, "utf-8");
|
|
220
|
+
const processedHtml = html.replace(/&{proxy_url}/g, proxyUrl).replace(/&{api_spec_url}/g, apiSpecUrl);
|
|
221
|
+
return res.send(processedHtml);
|
|
222
|
+
} catch (error) {
|
|
223
|
+
if (error instanceof ScalarError) {
|
|
224
|
+
logger2("error", `[ScalarError] ${error.message}`);
|
|
225
|
+
return res.status(error.statusCode).json({
|
|
226
|
+
message: error.message,
|
|
227
|
+
code: error.code
|
|
228
|
+
});
|
|
229
|
+
} else {
|
|
230
|
+
logger2("error", String(error));
|
|
231
|
+
return res.status(500).json({
|
|
232
|
+
message: "Internal server error occurred while serving documentation",
|
|
233
|
+
code: "INTERNAL_SERVER_ERROR"
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
export {
|
|
239
|
+
Scalar,
|
|
240
|
+
ScalarError,
|
|
241
|
+
getScalarDocs,
|
|
242
|
+
proxyMiddleware,
|
|
243
|
+
store
|
|
244
|
+
};
|
|
245
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/types.ts","../src/middleware/proxy.ts","../src/utils/store.ts","../src/client.ts","../src/controller.ts"],"sourcesContent":["import { NextFunction, RequestServer, ResponseServer } from \"azurajs/types\";\n\nexport interface ScalarConfigType {\n apiSpecUrl: string;\n proxyUrl: string;\n customHtmlPath?: string; // Optional since it might not always be provided\n}\n\nexport interface ScalarStoreType {\n proxy_url?: string;\n api_spec_url?: string;\n custom_html_path?: string;\n}\n\nexport type ProxyMiddlewareType = (\n req: RequestServer,\n res: ResponseServer,\n next?: NextFunction,\n) => Promise<void>;\n\n// Define specific error types\nexport class ScalarError extends Error {\n public readonly code: string;\n public readonly statusCode: number;\n\n constructor(message: string, code: string, statusCode: number) {\n super(message);\n this.code = code;\n this.statusCode = statusCode;\n Object.setPrototypeOf(this, ScalarError.prototype);\n }\n}\n\nexport interface ProxyOptions {\n apiSpecUrl: string;\n}\n","/**\n * @fileoverview Proxy middleware for API requests\n * This module provides a proxy middleware that forwards requests to the API specification\n */\n\nimport { ProxyOptions } from \"../config/types\";\nimport { NextFunction, RequestServer, ResponseServer } from \"azurajs/types\";\nimport { logger } from \"azurajs/logger\";\n\n/**\n * Creates a proxy middleware function that forwards requests to the API specification\n * @param options Configuration options for the proxy\n * @returns Middleware function that handles proxying requests\n */\nexport function proxyMiddleware({\n apiSpecUrl,\n}: ProxyOptions): (\n req: RequestServer,\n res: ResponseServer,\n next?: NextFunction,\n) => Promise<void> {\n return async (\n req: RequestServer,\n res: ResponseServer,\n _next?: NextFunction,\n ): Promise<void> => {\n try {\n if (!req.url || !req.method) {\n res.status(400).json({\n error: \"Request URL and method are required\",\n code: \"INVALID_REQUEST\"\n });\n return;\n }\n\n logger(\"info\", `[PROXY] ${req.method} ${req.url}`);\n\n const url = new URL(req.url, \"http://localhost\");\n const targetUrl = apiSpecUrl + url.pathname + url.search;\n\n logger(\"info\", `[PROXY] Forwarding to: ${targetUrl}`);\n\n // Convert Node.js headers to a format compatible with fetch\n const headers: Record<string, string> = {};\n for (const [key, value] of Object.entries(req.headers)) {\n if (value) {\n headers[key] = Array.isArray(value) ? value.join(\", \") : value;\n }\n }\n headers.host = new URL(apiSpecUrl).host;\n\n // Prepare request body\n let body: BodyInit | null = null;\n if (![\"GET\", \"HEAD\"].includes(req.method)) {\n // For non-GET/HEAD requests, we need to properly serialize the body\n // Since req might contain various data types, we need to handle appropriately\n if (req.body) {\n if (typeof req.body === 'string') {\n body = req.body;\n } else if (typeof req.body === 'object') {\n body = JSON.stringify(req.body);\n }\n }\n }\n\n const proxyRes = await fetch(targetUrl, {\n method: req.method,\n headers,\n body,\n });\n\n logger(\"info\", `[PROXY] Response: ${proxyRes.status}`);\n\n // CORS - IMPORTANT: define before copying response headers\n const responseHeaders: Record<string, string> = {\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n \"Access-Control-Allow-Headers\": \"*\",\n };\n\n // Copy response headers, avoiding CORS header conflicts\n for (const [key, value] of proxyRes.headers.entries()) {\n // Don't overwrite CORS headers\n if (!key.toLowerCase().startsWith(\"access-control-\")) {\n responseHeaders[key] = value;\n }\n }\n\n res.writeHead(proxyRes.status, responseHeaders);\n\n if (req.method === \"OPTIONS\") {\n res.end();\n return;\n }\n\n const buffer = Buffer.from(await proxyRes.arrayBuffer());\n res.end(buffer);\n } catch (err) {\n logger(\"error\", `[PROXY] Error: ${err}`);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({\n error: \"Proxy error\",\n details: err instanceof Error ? err.message : String(err),\n code: \"PROXY_ERROR\"\n }));\n }\n };\n}\n","/**\n * @fileoverview Store utility for managing application state\n * This module provides a typed store for managing scalar configuration values\n */\n\nimport { ScalarStoreType } from \"../config/types\";\n\n/**\n * Typed store class for managing scalar configuration values\n */\nclass ScalarStore {\n private store: Map<keyof ScalarStoreType, string | undefined> = new Map();\n\n /**\n * Sets a value in the store\n * @param key The key to set\n * @param value The value to set (if undefined, the key will be removed)\n */\n set<K extends keyof ScalarStoreType>(key: K, value: ScalarStoreType[K]): void {\n this.store.set(key, value as string | undefined);\n }\n\n /**\n * Gets a value from the store\n * @param key The key to get\n * @returns The value associated with the key\n */\n get<K extends keyof ScalarStoreType>(key: K): ScalarStoreType[K] {\n return this.store.get(key) as ScalarStoreType[K];\n }\n\n /**\n * Checks if a key exists in the store\n * @param key The key to check\n * @returns True if the key exists, false otherwise\n */\n has(key: keyof ScalarStoreType): boolean {\n return this.store.has(key);\n }\n\n /**\n * Deletes a key from the store\n * @param key The key to delete\n * @returns True if the key existed and was deleted, false otherwise\n */\n delete(key: keyof ScalarStoreType): boolean {\n return this.store.delete(key);\n }\n\n /**\n * Clears all values from the store\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Gets all values from the store\n * @returns An object containing all key-value pairs in the store\n */\n getAll(): ScalarStoreType {\n const result: Partial<ScalarStoreType> = {};\n for (const [key, value] of this.store.entries()) {\n result[key] = value as ScalarStoreType[keyof ScalarStoreType];\n }\n return result as ScalarStoreType;\n }\n\n // Index signature to allow direct property access\n [key: string]: any;\n}\n\nexport const store = new ScalarStore();\n","/**\n * @fileoverview Scalar client for API documentation proxy\n * This module provides a client for setting up API documentation with proxy capabilities\n */\n\nimport { ProxyMiddlewareType, ScalarConfigType, ScalarError } from \"./config/types\";\nimport { proxyMiddleware } from \"./middleware/proxy\";\nimport { store } from \"./utils/store\";\n\n/**\n * Scalar client class for managing API documentation proxy\n */\nexport class Scalar {\n /**\n * Middleware function that handles proxying requests to the API specification\n */\n public proxyMiddleware: ProxyMiddlewareType;\n\n /**\n * Creates a new Scalar client instance\n * @param config Configuration object for the Scalar client\n */\n constructor(config: ScalarConfigType) {\n this.validateConfig(config);\n\n store.set(\"proxy_url\", config.proxyUrl);\n store.set(\"api_spec_url\", config.apiSpecUrl);\n store.set(\"custom_html_path\", config.customHtmlPath);\n\n this.proxyMiddleware = proxyMiddleware({ apiSpecUrl: config.apiSpecUrl });\n }\n\n /**\n * Validates the provided configuration\n * @param config Configuration object to validate\n * @throws ScalarError if configuration is invalid\n */\n private validateConfig(config: ScalarConfigType): void {\n if (!config.apiSpecUrl) {\n throw new ScalarError(\n \"apiSpecUrl is required\",\n \"MISSING_API_SPEC_URL\",\n 400\n );\n }\n\n if (!config.proxyUrl) {\n throw new ScalarError(\n \"proxyUrl is required\",\n \"MISSING_PROXY_URL\",\n 400\n );\n }\n\n try {\n new URL(config.apiSpecUrl);\n } catch (error) {\n throw new ScalarError(\n \"apiSpecUrl must be a valid URL\",\n \"INVALID_API_SPEC_URL\",\n 400\n );\n }\n\n try {\n new URL(config.proxyUrl);\n } catch (error) {\n throw new ScalarError(\n \"proxyUrl must be a valid URL\",\n \"INVALID_PROXY_URL\",\n 400\n );\n }\n }\n}\n","/**\n * @fileoverview Controller for serving Scalar API documentation\n * This module handles serving the API documentation HTML with proper URL replacements\n */\n\nimport { fileURLToPath } from \"node:url\";\nimport path from \"node:path\";\nimport fs from \"fs\";\nimport { logger } from \"azurajs/logger\";\nimport { ResponseServer } from \"azurajs/types\";\nimport { store } from \"./utils/store\";\nimport { ScalarError } from \"./config/types\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n/**\n * Serves the Scalar API documentation HTML page\n * Replaces placeholders in the HTML template with actual URLs from the store\n * @param res Response object to send the HTML to\n * @returns Promise that resolves when the response is sent\n */\nexport async function getScalarDocs(res: ResponseServer) {\n try {\n const customHtmlPath = store.get(\"custom_html_path\");\n const proxyUrl = store.get(\"proxy_url\");\n const apiSpecUrl = store.get(\"api_spec_url\");\n\n if (!proxyUrl || !apiSpecUrl) {\n throw new ScalarError(\n \"Proxy URL or API Spec URL not defined in store\",\n \"STORE_VALUES_MISSING\",\n 500\n );\n }\n\n const htmlPath = customHtmlPath || path.join(__dirname, \"./api-docs.html\");\n\n if (!fs.existsSync(htmlPath)) {\n throw new ScalarError(\n `HTML template file not found at path: ${htmlPath}`,\n \"HTML_TEMPLATE_NOT_FOUND\",\n 404\n );\n }\n\n const html = fs.readFileSync(htmlPath, \"utf-8\");\n const processedHtml = html\n .replace(/&{proxy_url}/g, proxyUrl)\n .replace(/&{api_spec_url}/g, apiSpecUrl);\n\n return res.send(processedHtml);\n } catch (error) {\n if (error instanceof ScalarError) {\n logger(\"error\", `[ScalarError] ${error.message}`);\n return res.status(error.statusCode).json({\n message: error.message,\n code: error.code,\n });\n } else {\n logger(\"error\", String(error));\n return res.status(500).json({\n message: \"Internal server error occurred while serving documentation\",\n code: \"INTERNAL_SERVER_ERROR\",\n });\n }\n }\n}\n"],"mappings":"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","names":["logger","logger"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "azurajs-scalar",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Proxy middleware and controller to scalar documentation.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"main": "dist/index.js",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup src/index.ts --format esm --dts"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [],
|
|
15
|
+
"author": "",
|
|
16
|
+
"license": "ISC",
|
|
17
|
+
"packageManager": "pnpm@10.25.0",
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"azurajs": "2.6.1-1"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^25.0.10",
|
|
23
|
+
"tsup": "^8.5.1",
|
|
24
|
+
"typescript": "^5.9.3"
|
|
25
|
+
}
|
|
26
|
+
}
|