azurajs-scalar 1.0.3 → 2.0.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/README.md +12 -33
- package/azurajs-scalar-2.0.0.tgz +0 -0
- package/dist/api-docs.html +29 -41
- package/dist/index.d.ts +27 -44
- package/dist/index.js +207 -118
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -48,44 +48,23 @@ import * from "./controllers"
|
|
|
48
48
|
|
|
49
49
|
const app = new AzuraClient();
|
|
50
50
|
|
|
51
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
52
|
-
const __dirname = path.dirname(__filename);
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
52
|
+
const __dirname = path.dirname(__filename);
|
|
53
|
+
|
|
54
|
+
const baseUrl = env.APP_URL || "http://localhost:4002";
|
|
55
|
+
|
|
56
|
+
new Scalar({
|
|
57
|
+
apiSpecPath: "/api-spec.json",
|
|
58
|
+
proxyPath: "/scalar/proxy/",
|
|
59
|
+
docPath: "/docs/",
|
|
60
|
+
customHtmlPath: path.join(__dirname, "./public/html/api-docs.html"),
|
|
61
|
+
app,
|
|
62
|
+
baseUrl,
|
|
58
63
|
});
|
|
59
64
|
|
|
60
65
|
applyDecorators(app, Object.values(Controllers))
|
|
61
66
|
```
|
|
62
67
|
|
|
63
|
-
### Controller Setup
|
|
64
|
-
|
|
65
|
-
#### src/controllers/docs.controller.ts
|
|
66
|
-
|
|
67
|
-
```ts
|
|
68
|
-
import { Controller, Get, Res } from "azurajs/decorators";
|
|
69
|
-
import { ResponseServer } from "azurajs/types";
|
|
70
|
-
import { getScalarDocs } from "azurajs-scalar";
|
|
71
|
-
|
|
72
|
-
@Controller("/docs")
|
|
73
|
-
export class DocsController {
|
|
74
|
-
@Get("/")
|
|
75
|
-
scalarDocs(@Res() res: ResponseServer) {
|
|
76
|
-
getScalarDocs(res);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### Export Controllers
|
|
82
|
-
|
|
83
|
-
#### src/controllers/index.ts
|
|
84
|
-
|
|
85
|
-
```ts
|
|
86
|
-
export * from "./docs.controller.ts";
|
|
87
|
-
```
|
|
88
|
-
|
|
89
68
|
---
|
|
90
69
|
|
|
91
70
|
## 🎨 Custom HTML Template
|
|
Binary file
|
package/dist/api-docs.html
CHANGED
|
@@ -1,41 +1,29 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<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">
|
|
11
|
-
|
|
12
|
-
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
13
|
-
<script>
|
|
14
|
-
fetch("&{api_spec_url}")
|
|
15
|
-
.then(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
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>
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Scalar API Documentation</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">Loading...</div>
|
|
11
|
+
|
|
12
|
+
<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
|
|
13
|
+
<script>
|
|
14
|
+
fetch("&{api_spec_url}")
|
|
15
|
+
.then(res => res.json())
|
|
16
|
+
.then(spec => {
|
|
17
|
+
Scalar.createApiReference("#app", {
|
|
18
|
+
spec: { content: spec },
|
|
19
|
+
proxy: "&{proxy_url}",
|
|
20
|
+
theme: "default"
|
|
21
|
+
});
|
|
22
|
+
})
|
|
23
|
+
.catch(err => {
|
|
24
|
+
document.getElementById("app").innerHTML =
|
|
25
|
+
`<pre>Error loading API spec: ${err.message}</pre>`;
|
|
26
|
+
});
|
|
27
|
+
</script>
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
package/dist/index.d.ts
CHANGED
|
@@ -1,70 +1,53 @@
|
|
|
1
|
+
import { AzuraClient } from 'azurajs';
|
|
1
2
|
import { RequestServer, ResponseServer, NextFunction } from 'azurajs/types';
|
|
2
3
|
|
|
3
4
|
interface ScalarConfigType {
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
proxyPath?: string;
|
|
7
|
+
docPath?: string;
|
|
8
|
+
apiSpecPath?: string;
|
|
6
9
|
customHtmlPath?: string;
|
|
10
|
+
app: AzuraClient;
|
|
7
11
|
}
|
|
8
12
|
interface ScalarStoreType {
|
|
9
13
|
proxy_url?: string;
|
|
10
14
|
api_spec_url?: string;
|
|
15
|
+
doc_url?: string;
|
|
11
16
|
custom_html_path?: string;
|
|
12
17
|
}
|
|
13
18
|
type ProxyMiddlewareType = (req: RequestServer, res: ResponseServer, next?: NextFunction) => Promise<void>;
|
|
19
|
+
declare class ScalarError extends Error {
|
|
20
|
+
readonly message: string;
|
|
21
|
+
readonly code: string;
|
|
22
|
+
readonly statusCode: number;
|
|
23
|
+
constructor(message: string, code: string, statusCode: number);
|
|
24
|
+
}
|
|
14
25
|
interface ProxyOptions {
|
|
15
26
|
apiSpecUrl: string;
|
|
27
|
+
proxyUrlPath: string;
|
|
28
|
+
app: AzuraClient;
|
|
29
|
+
}
|
|
30
|
+
interface SetupDocsRouteOptions extends ScalarConfigType {
|
|
31
|
+
docPath: string;
|
|
32
|
+
proxyUrl: string;
|
|
33
|
+
apiSpecUrl: string;
|
|
16
34
|
}
|
|
17
35
|
|
|
18
36
|
/**
|
|
19
|
-
*
|
|
20
|
-
* This module provides a client for setting up API documentation with proxy capabilities
|
|
37
|
+
* Scalar client for API documentation
|
|
21
38
|
*/
|
|
22
39
|
|
|
23
|
-
/**
|
|
24
|
-
* Scalar client class for managing API documentation proxy
|
|
25
|
-
*/
|
|
26
40
|
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
41
|
constructor(config: ScalarConfigType);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* @param config Configuration object to validate
|
|
39
|
-
* @throws ScalarError if configuration is invalid
|
|
40
|
-
*/
|
|
42
|
+
private joinUrl;
|
|
43
|
+
private normalizeBaseUrl;
|
|
41
44
|
private validateConfig;
|
|
45
|
+
private isValidPath;
|
|
42
46
|
}
|
|
43
47
|
|
|
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
|
-
*/
|
|
48
|
+
declare function setupScalarDocs({ app, docPath, customHtmlPath, apiSpecUrl, proxyUrl, }: SetupDocsRouteOptions): Promise<void>;
|
|
61
49
|
|
|
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>;
|
|
50
|
+
declare function proxyMiddleware({ apiSpecUrl, app, proxyUrlPath, }: ProxyOptions): void;
|
|
68
51
|
|
|
69
52
|
/**
|
|
70
53
|
* @fileoverview Store utility for managing application state
|
|
@@ -113,4 +96,4 @@ declare class ScalarStore {
|
|
|
113
96
|
}
|
|
114
97
|
declare const store: ScalarStore;
|
|
115
98
|
|
|
116
|
-
export { type ProxyMiddlewareType, Scalar, type ScalarConfigType,
|
|
99
|
+
export { type ProxyMiddlewareType, type ProxyOptions, Scalar, type ScalarConfigType, ScalarError, type ScalarStoreType, type SetupDocsRouteOptions, proxyMiddleware, setupScalarDocs, store };
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
var ScalarError = class _ScalarError extends Error {
|
|
3
3
|
constructor(message, code, statusCode) {
|
|
4
4
|
super(message);
|
|
5
|
+
this.message = message;
|
|
5
6
|
this.code = code;
|
|
6
7
|
this.statusCode = statusCode;
|
|
7
8
|
Object.setPrototypeOf(this, _ScalarError.prototype);
|
|
@@ -10,21 +11,53 @@ var ScalarError = class _ScalarError extends Error {
|
|
|
10
11
|
|
|
11
12
|
// src/middleware/proxy.ts
|
|
12
13
|
import { logger } from "azurajs/logger";
|
|
14
|
+
|
|
15
|
+
// src/utils/debug.ts
|
|
16
|
+
function debug(message, ...optionalParams) {
|
|
17
|
+
if (process.env.DEBUG === "true" || process.env.DEBUG === "1") {
|
|
18
|
+
console.log(`[DEBUG] ${message}`, ...optionalParams);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// src/middleware/proxy.ts
|
|
13
23
|
function proxyMiddleware({
|
|
14
|
-
apiSpecUrl
|
|
24
|
+
apiSpecUrl,
|
|
25
|
+
app,
|
|
26
|
+
proxyUrlPath
|
|
15
27
|
}) {
|
|
16
|
-
|
|
28
|
+
debug("Setting up proxy middleware with options:", {
|
|
29
|
+
apiSpecUrl,
|
|
30
|
+
proxyUrlPath
|
|
31
|
+
});
|
|
32
|
+
app.get(proxyUrlPath, () => {
|
|
33
|
+
});
|
|
34
|
+
return app.use(proxyUrlPath, async (req, res) => {
|
|
35
|
+
debug("Proxy middleware hit with request:", req.method, req.url, "headers:", req.headers);
|
|
17
36
|
try {
|
|
18
37
|
if (!req.url || !req.method) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
code: "INVALID_REQUEST"
|
|
22
|
-
});
|
|
38
|
+
debug("Invalid request - missing url or method");
|
|
39
|
+
res.status(400).json({ error: "Invalid request" });
|
|
23
40
|
return;
|
|
24
41
|
}
|
|
25
42
|
logger("info", `[PROXY] ${req.method} ${req.url}`);
|
|
26
|
-
const url = new URL(req.url
|
|
27
|
-
const
|
|
43
|
+
const url = new URL(`http://localhost${req.url}`);
|
|
44
|
+
const scalarUrl = url.searchParams.get("scalar_url");
|
|
45
|
+
debug("Extracted scalar_url from query params:", scalarUrl);
|
|
46
|
+
const targetUrl = scalarUrl || apiSpecUrl + url.pathname + url.search;
|
|
47
|
+
debug("Determined target URL:", targetUrl);
|
|
48
|
+
const target = new URL(targetUrl);
|
|
49
|
+
const apiBase = new URL(apiSpecUrl);
|
|
50
|
+
debug(
|
|
51
|
+
"Validating same origin - target origin:",
|
|
52
|
+
target.origin,
|
|
53
|
+
"apiBase origin:",
|
|
54
|
+
apiBase.origin
|
|
55
|
+
);
|
|
56
|
+
if (target.origin !== apiBase.origin) {
|
|
57
|
+
logger("warn", `Blocked cross-origin: ${targetUrl}`);
|
|
58
|
+
res.status(403).json({ error: "Cross-origin blocked" });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
28
61
|
logger("info", `[PROXY] Forwarding to: ${targetUrl}`);
|
|
29
62
|
const headers = {};
|
|
30
63
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
@@ -32,50 +65,99 @@ function proxyMiddleware({
|
|
|
32
65
|
headers[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
33
66
|
}
|
|
34
67
|
}
|
|
35
|
-
headers.host =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
body = req.body;
|
|
41
|
-
} else if (typeof req.body === "object") {
|
|
42
|
-
body = JSON.stringify(req.body);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
68
|
+
headers.host = apiBase.host;
|
|
69
|
+
debug("Prepared headers:", headers);
|
|
70
|
+
const body = ["GET", "HEAD"].includes(req.method) ? void 0 : typeof req.body === "string" ? req.body : JSON.stringify(req.body);
|
|
71
|
+
debug("Request body:", body);
|
|
72
|
+
debug("Making fetch request to target URL:", targetUrl);
|
|
46
73
|
const proxyRes = await fetch(targetUrl, {
|
|
47
74
|
method: req.method,
|
|
48
75
|
headers,
|
|
49
76
|
body
|
|
50
77
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
78
|
+
debug(
|
|
79
|
+
"Fetch response received with status:",
|
|
80
|
+
proxyRes.status
|
|
81
|
+
);
|
|
82
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
83
|
+
res.setHeader(
|
|
84
|
+
"Access-Control-Allow-Methods",
|
|
85
|
+
"GET,POST,PUT,PATCH,DELETE,OPTIONS"
|
|
86
|
+
);
|
|
87
|
+
res.setHeader("Access-Control-Allow-Headers", "*");
|
|
57
88
|
for (const [key, value] of proxyRes.headers.entries()) {
|
|
58
89
|
if (!key.toLowerCase().startsWith("access-control-")) {
|
|
59
|
-
|
|
90
|
+
res.setHeader(key, value);
|
|
60
91
|
}
|
|
61
92
|
}
|
|
62
|
-
res.writeHead(proxyRes.status, responseHeaders);
|
|
63
93
|
if (req.method === "OPTIONS") {
|
|
94
|
+
debug("OPTIONS request, ending response");
|
|
64
95
|
res.end();
|
|
65
96
|
return;
|
|
66
97
|
}
|
|
67
98
|
const buffer = Buffer.from(await proxyRes.arrayBuffer());
|
|
68
|
-
|
|
99
|
+
debug(
|
|
100
|
+
"Response buffer created with length:",
|
|
101
|
+
buffer.length
|
|
102
|
+
);
|
|
103
|
+
res.send(buffer);
|
|
69
104
|
} catch (err) {
|
|
105
|
+
debug("Error in proxy middleware:", err);
|
|
70
106
|
logger("error", `[PROXY] Error: ${err}`);
|
|
71
|
-
res.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
107
|
+
res.status(500).json({ error: "Proxy error", details: String(err) });
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/setupDocsRoute.ts
|
|
113
|
+
import { logger as logger2 } from "azurajs/logger";
|
|
114
|
+
import fs from "fs";
|
|
115
|
+
import path from "path";
|
|
116
|
+
async function setupScalarDocs({
|
|
117
|
+
app,
|
|
118
|
+
docPath,
|
|
119
|
+
customHtmlPath,
|
|
120
|
+
apiSpecUrl,
|
|
121
|
+
proxyUrl
|
|
122
|
+
}) {
|
|
123
|
+
debug("Setting up docs route with options:", { docPath, customHtmlPath, apiSpecUrl, proxyUrl });
|
|
124
|
+
return app.get(docPath, (req, res) => {
|
|
125
|
+
debug("Docs route hit with request:", req.method, req.url);
|
|
126
|
+
try {
|
|
127
|
+
if (!proxyUrl || !apiSpecUrl) {
|
|
128
|
+
debug("Missing required URLs - proxyUrl:", proxyUrl, "apiSpecUrl:", apiSpecUrl);
|
|
129
|
+
throw new ScalarError(
|
|
130
|
+
"Missing required URLs",
|
|
131
|
+
"STORE_VALUES_MISSING",
|
|
132
|
+
500
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
const htmlPath = customHtmlPath || path.join(__dirname, "../api-docs.html");
|
|
136
|
+
debug("HTML template path:", htmlPath);
|
|
137
|
+
if (!fs.existsSync(htmlPath)) {
|
|
138
|
+
debug("HTML template not found at path:", htmlPath);
|
|
139
|
+
throw new ScalarError(
|
|
140
|
+
"HTML template not found",
|
|
141
|
+
"HTML_TEMPLATE_NOT_FOUND",
|
|
142
|
+
404
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
const html = fs.readFileSync(htmlPath, "utf-8");
|
|
146
|
+
debug("HTML template read successfully, length:", html.length);
|
|
147
|
+
const processedHtml = html.replace(/&{proxy_url}/g, proxyUrl).replace(/&{api_spec_url}/g, apiSpecUrl);
|
|
148
|
+
debug("HTML template processed with proxyUrl and apiSpecUrl");
|
|
149
|
+
return res.send(processedHtml);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
debug("Error in docs route:", error);
|
|
152
|
+
if (error instanceof ScalarError) {
|
|
153
|
+
logger2("error", `[ScalarError] ${error.message}`);
|
|
154
|
+
return res.status(error.statusCode).json({ message: error.message });
|
|
155
|
+
} else {
|
|
156
|
+
logger2("error", String(error));
|
|
157
|
+
return res.status(500).json({ message: "Server error" });
|
|
158
|
+
}
|
|
77
159
|
}
|
|
78
|
-
};
|
|
160
|
+
});
|
|
79
161
|
}
|
|
80
162
|
|
|
81
163
|
// src/utils/store.ts
|
|
@@ -137,109 +219,116 @@ var store = new ScalarStore();
|
|
|
137
219
|
|
|
138
220
|
// src/client.ts
|
|
139
221
|
var Scalar = class {
|
|
140
|
-
/**
|
|
141
|
-
* Creates a new Scalar client instance
|
|
142
|
-
* @param config Configuration object for the Scalar client
|
|
143
|
-
*/
|
|
144
222
|
constructor(config) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
this.
|
|
223
|
+
debug("Scalar constructor called with config:", config);
|
|
224
|
+
const normalizedConfig = { ...config };
|
|
225
|
+
normalizedConfig.baseUrl = this.normalizeBaseUrl(config.baseUrl);
|
|
226
|
+
debug("Normalized config:", normalizedConfig);
|
|
227
|
+
this.validateConfig(normalizedConfig);
|
|
228
|
+
const proxyPath = normalizedConfig.proxyPath || "/scalar/proxy";
|
|
229
|
+
const docPath = normalizedConfig.docPath || "/docs";
|
|
230
|
+
const apiSpecPath = normalizedConfig.apiSpecPath || "";
|
|
231
|
+
debug(
|
|
232
|
+
"Using paths - proxyPath:",
|
|
233
|
+
proxyPath,
|
|
234
|
+
"docPath:",
|
|
235
|
+
docPath,
|
|
236
|
+
"apiSpecPath:",
|
|
237
|
+
apiSpecPath
|
|
238
|
+
);
|
|
239
|
+
const proxyUrl = this.joinUrl(normalizedConfig.baseUrl, proxyPath);
|
|
240
|
+
const docUrl = this.joinUrl(normalizedConfig.baseUrl, docPath);
|
|
241
|
+
const apiSpecUrl = this.joinUrl(normalizedConfig.baseUrl, apiSpecPath);
|
|
242
|
+
debug(
|
|
243
|
+
"Calculated URLs - proxyUrl:",
|
|
244
|
+
proxyUrl,
|
|
245
|
+
"docUrl:",
|
|
246
|
+
docUrl,
|
|
247
|
+
"apiSpecUrl:",
|
|
248
|
+
apiSpecUrl
|
|
249
|
+
);
|
|
250
|
+
store.set("proxy_url", proxyUrl);
|
|
251
|
+
store.set("api_spec_url", apiSpecUrl);
|
|
252
|
+
store.set("doc_url", docUrl);
|
|
253
|
+
debug("Stored URLs in store");
|
|
254
|
+
setupScalarDocs({
|
|
255
|
+
...normalizedConfig,
|
|
256
|
+
proxyUrl,
|
|
257
|
+
docPath,
|
|
258
|
+
apiSpecUrl
|
|
259
|
+
});
|
|
260
|
+
debug("setupScalarDocs called");
|
|
261
|
+
proxyMiddleware({
|
|
262
|
+
apiSpecUrl,
|
|
263
|
+
proxyUrlPath: proxyPath,
|
|
264
|
+
app: normalizedConfig.app
|
|
265
|
+
});
|
|
266
|
+
debug("proxyMiddleware called");
|
|
150
267
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
if (!
|
|
268
|
+
joinUrl(baseUrl, path2) {
|
|
269
|
+
const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/";
|
|
270
|
+
const normalizedPath = path2.startsWith("/") ? path2 : "/" + path2;
|
|
271
|
+
return normalizedBaseUrl.replace(/\/$/, "") + normalizedPath;
|
|
272
|
+
}
|
|
273
|
+
normalizeBaseUrl(baseUrl) {
|
|
274
|
+
if (!baseUrl) {
|
|
158
275
|
throw new ScalarError(
|
|
159
|
-
"
|
|
160
|
-
"
|
|
276
|
+
"baseUrl is required",
|
|
277
|
+
"MISSING_REQUIRED_CONFIG",
|
|
161
278
|
400
|
|
162
279
|
);
|
|
163
280
|
}
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
"proxyUrl is required",
|
|
167
|
-
"MISSING_PROXY_URL",
|
|
168
|
-
400
|
|
169
|
-
);
|
|
281
|
+
if (!/^https?:\/\//i.test(baseUrl)) {
|
|
282
|
+
return "http://" + baseUrl;
|
|
170
283
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
284
|
+
return baseUrl;
|
|
285
|
+
}
|
|
286
|
+
validateConfig(config) {
|
|
287
|
+
if (!config.baseUrl) {
|
|
174
288
|
throw new ScalarError(
|
|
175
|
-
"
|
|
176
|
-
"
|
|
289
|
+
"baseUrl is required",
|
|
290
|
+
"MISSING_REQUIRED_CONFIG",
|
|
177
291
|
400
|
|
178
292
|
);
|
|
179
293
|
}
|
|
180
294
|
try {
|
|
181
|
-
|
|
295
|
+
debug("Validating baseUrl:", config.baseUrl);
|
|
296
|
+
new URL(config.baseUrl);
|
|
297
|
+
if (config.proxyPath) {
|
|
298
|
+
debug("Validating proxyPath:", config.proxyPath);
|
|
299
|
+
if (!this.isValidPath(config.proxyPath)) {
|
|
300
|
+
debug("proxyPath validation FAILED");
|
|
301
|
+
throw new Error("Invalid proxyPath");
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (config.docPath) {
|
|
305
|
+
debug("Validating docPath:", config.docPath);
|
|
306
|
+
if (!this.isValidPath(config.docPath)) {
|
|
307
|
+
debug("docPath validation FAILED");
|
|
308
|
+
throw new Error("Invalid docPath");
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (config.apiSpecPath) {
|
|
312
|
+
debug("Validating apiSpecPath:", config.apiSpecPath);
|
|
313
|
+
if (!this.isValidPath(config.apiSpecPath)) {
|
|
314
|
+
debug("apiSpecPath validation FAILED");
|
|
315
|
+
throw new Error("Invalid apiSpecPath");
|
|
316
|
+
}
|
|
317
|
+
}
|
|
182
318
|
} catch (error) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
"INVALID_PROXY_URL",
|
|
186
|
-
400
|
|
187
|
-
);
|
|
319
|
+
debug("Validation error:", error);
|
|
320
|
+
throw new ScalarError("Invalid URL provided", "INVALID_URL", 400);
|
|
188
321
|
}
|
|
189
322
|
}
|
|
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
|
-
}
|
|
323
|
+
isValidPath(path2) {
|
|
324
|
+
return typeof path2 === "string" && /^\/[a-zA-Z0-9\-._~:\/@!$&'()*+,;=]*\/?$/.test(path2);
|
|
236
325
|
}
|
|
237
|
-
}
|
|
326
|
+
};
|
|
238
327
|
export {
|
|
239
328
|
Scalar,
|
|
240
329
|
ScalarError,
|
|
241
|
-
getScalarDocs,
|
|
242
330
|
proxyMiddleware,
|
|
331
|
+
setupScalarDocs,
|
|
243
332
|
store
|
|
244
333
|
};
|
|
245
334
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +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"]}
|
|
1
|
+
{"version":3,"sources":["../src/config/types.ts","../src/middleware/proxy.ts","../src/utils/debug.ts","../src/setupDocsRoute.ts","../src/utils/store.ts","../src/client.ts"],"sourcesContent":["import { AzuraClient } from \"azurajs\";\nimport { NextFunction, RequestServer, ResponseServer } from \"azurajs/types\";\n\nexport interface ScalarConfigType {\n baseUrl: string;\n proxyPath?: string;\n docPath?: string;\n apiSpecPath?: string;\n customHtmlPath?: string;\n app: AzuraClient;\n}\n\nexport interface ScalarStoreType {\n proxy_url?: string;\n api_spec_url?: string;\n doc_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\nexport class ScalarError extends Error {\n constructor(\n public readonly message: string,\n public readonly code: string,\n public readonly statusCode: number,\n ) {\n super(message);\n Object.setPrototypeOf(this, ScalarError.prototype);\n }\n}\n\nexport interface ProxyOptions {\n apiSpecUrl: string;\n proxyUrlPath: string;\n app: AzuraClient;\n}\n\nexport interface SetupDocsRouteOptions extends ScalarConfigType {\n docPath: string;\n proxyUrl: string;\n apiSpecUrl: string;\n}\n","import { ProxyOptions } from \"../config/types\";\nimport { logger } from \"azurajs/logger\";\nimport { debug } from \"../utils/debug\";\n\nexport function proxyMiddleware({\n apiSpecUrl,\n app,\n proxyUrlPath,\n}: ProxyOptions) {\n debug(\"Setting up proxy middleware with options:\", {\n apiSpecUrl,\n proxyUrlPath,\n });\n app.get(proxyUrlPath, () => {});\n return app.use(proxyUrlPath, async (req, res) => {\n debug(\"Proxy middleware hit with request:\", req.method, req.url, \"headers:\", req.headers);\n try {\n if (!req.url || !req.method) {\n debug(\"Invalid request - missing url or method\");\n res.status(400).json({ error: \"Invalid request\" });\n return;\n }\n\n logger(\"info\", `[PROXY] ${req.method} ${req.url}`);\n\n // Extract target URL from scalar_url query param\n const url = new URL(`http://localhost${req.url}`);\n const scalarUrl = url.searchParams.get(\"scalar_url\");\n debug(\"Extracted scalar_url from query params:\", scalarUrl);\n\n // Determine target URL\n const targetUrl = scalarUrl || apiSpecUrl + url.pathname + url.search;\n debug(\"Determined target URL:\", targetUrl);\n\n // Validate same origin for security\n const target = new URL(targetUrl);\n const apiBase = new URL(apiSpecUrl);\n debug(\n \"Validating same origin - target origin:\",\n target.origin,\n \"apiBase origin:\",\n apiBase.origin,\n );\n if (target.origin !== apiBase.origin) {\n logger(\"warn\", `Blocked cross-origin: ${targetUrl}`);\n res.status(403).json({ error: \"Cross-origin blocked\" });\n return;\n }\n\n logger(\"info\", `[PROXY] Forwarding to: ${targetUrl}`);\n\n // Prepare headers and body\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 = apiBase.host;\n debug(\"Prepared headers:\", headers);\n\n const body = [\"GET\", \"HEAD\"].includes(req.method)\n ? undefined\n : typeof req.body === \"string\"\n ? req.body\n : JSON.stringify(req.body);\n debug(\"Request body:\", body);\n\n // Make request to target\n debug(\"Making fetch request to target URL:\", targetUrl);\n const proxyRes = await fetch(targetUrl, {\n method: req.method,\n headers,\n body,\n });\n debug(\n \"Fetch response received with status:\",\n proxyRes.status,\n );\n\n // Set response headers\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\n \"Access-Control-Allow-Methods\",\n \"GET,POST,PUT,PATCH,DELETE,OPTIONS\",\n );\n res.setHeader(\"Access-Control-Allow-Headers\", \"*\");\n\n for (const [key, value] of proxyRes.headers.entries()) {\n if (!key.toLowerCase().startsWith(\"access-control-\")) {\n res.setHeader(key, value);\n }\n }\n\n if (req.method === \"OPTIONS\") {\n debug(\"OPTIONS request, ending response\");\n res.end();\n return;\n }\n\n const buffer = Buffer.from(await proxyRes.arrayBuffer());\n debug(\n \"Response buffer created with length:\",\n buffer.length,\n );\n res.send(buffer);\n } catch (err) {\n debug(\"Error in proxy middleware:\", err);\n logger(\"error\", `[PROXY] Error: ${err}`);\n res.status(500).json({ error: \"Proxy error\", details: String(err) });\n }\n });\n}\n","/**\n * Debug utility function that only logs when DEBUG environment variable is set to 'true'\n */\n\nexport function debug(message: string, ...optionalParams: any[]) {\n if (process.env.DEBUG === 'true' || process.env.DEBUG === '1') {\n console.log(`[DEBUG] ${message}`, ...optionalParams);\n }\n}","import { logger } from \"azurajs/logger\";\nimport fs from \"fs\";\nimport path from \"node:path\";\nimport { ScalarError, SetupDocsRouteOptions } from \"./config/types\";\nimport { debug } from \"./utils/debug\";\n\nexport async function setupScalarDocs({\n app,\n docPath,\n customHtmlPath,\n apiSpecUrl,\n proxyUrl,\n}: SetupDocsRouteOptions) {\n debug(\"Setting up docs route with options:\", { docPath, customHtmlPath, apiSpecUrl, proxyUrl });\n\n return app.get(docPath, (req, res) => {\n debug(\"Docs route hit with request:\", req.method, req.url);\n try {\n if (!proxyUrl || !apiSpecUrl) {\n debug(\"Missing required URLs - proxyUrl:\", proxyUrl, \"apiSpecUrl:\", apiSpecUrl);\n throw new ScalarError(\n \"Missing required URLs\",\n \"STORE_VALUES_MISSING\",\n 500,\n );\n }\n\n const htmlPath =\n customHtmlPath || path.join(__dirname, \"../api-docs.html\");\n debug(\"HTML template path:\", htmlPath);\n\n if (!fs.existsSync(htmlPath)) {\n debug(\"HTML template not found at path:\", htmlPath);\n throw new ScalarError(\n \"HTML template not found\",\n \"HTML_TEMPLATE_NOT_FOUND\",\n 404,\n );\n }\n\n const html = fs.readFileSync(htmlPath, \"utf-8\");\n debug(\"HTML template read successfully, length:\", html.length);\n\n const processedHtml = html\n .replace(/&{proxy_url}/g, proxyUrl)\n .replace(/&{api_spec_url}/g, apiSpecUrl);\n debug(\"HTML template processed with proxyUrl and apiSpecUrl\");\n\n return res.send(processedHtml);\n } catch (error) {\n debug(\"Error in docs route:\", error);\n if (error instanceof ScalarError) {\n logger(\"error\", `[ScalarError] ${error.message}`);\n return res.status(error.statusCode).json({ message: error.message });\n } else {\n logger(\"error\", String(error));\n return res.status(500).json({ message: \"Server 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>(\n key: K,\n value: ScalarStoreType[K],\n ): 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 * Scalar client for API documentation\n */\nimport {\n ScalarConfigType,\n ScalarError,\n SetupDocsRouteOptions,\n} from \"./config/types\";\nimport { proxyMiddleware } from \"./middleware/proxy\";\nimport { setupScalarDocs } from \"./setupDocsRoute\";\nimport { store } from \"./utils/store\";\nimport { debug } from \"./utils/debug\";\n\nexport class Scalar {\n constructor(config: ScalarConfigType) {\n debug(\"Scalar constructor called with config:\", config);\n\n // Normalize baseUrl to ensure it's a valid absolute URL before validation\n const normalizedConfig = { ...config };\n normalizedConfig.baseUrl = this.normalizeBaseUrl(config.baseUrl);\n debug(\"Normalized config:\", normalizedConfig);\n\n // Validate the configuration\n this.validateConfig(normalizedConfig);\n\n // Set default paths if not provided\n const proxyPath = normalizedConfig.proxyPath || \"/scalar/proxy\";\n const docPath = normalizedConfig.docPath || \"/docs\";\n const apiSpecPath = normalizedConfig.apiSpecPath || \"\";\n debug(\n \"Using paths - proxyPath:\",\n proxyPath,\n \"docPath:\",\n docPath,\n \"apiSpecPath:\",\n apiSpecPath,\n );\n\n // Calculate full URLs from baseUrl and paths\n const proxyUrl = this.joinUrl(normalizedConfig.baseUrl, proxyPath);\n const docUrl = this.joinUrl(normalizedConfig.baseUrl, docPath);\n const apiSpecUrl = this.joinUrl(normalizedConfig.baseUrl, apiSpecPath);\n debug(\n \"Calculated URLs - proxyUrl:\",\n proxyUrl,\n \"docUrl:\",\n docUrl,\n \"apiSpecUrl:\",\n apiSpecUrl,\n );\n\n // Store the calculated URLs\n store.set(\"proxy_url\", proxyUrl);\n store.set(\"api_spec_url\", apiSpecUrl);\n store.set(\"doc_url\", docUrl);\n debug(\"Stored URLs in store\");\n\n // Call setup with the calculated URLs\n setupScalarDocs({\n ...normalizedConfig,\n proxyUrl,\n docPath,\n apiSpecUrl,\n });\n debug(\"setupScalarDocs called\");\n\n // Setup proxy middleware\n proxyMiddleware({\n apiSpecUrl,\n proxyUrlPath: proxyPath,\n app: normalizedConfig.app,\n });\n debug(\"proxyMiddleware called\");\n }\n\n private joinUrl(baseUrl: string, path: string): string {\n // Normalize the baseUrl to ensure it ends with a slash\n const normalizedBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl : baseUrl + \"/\";\n\n // Normalize the path to ensure it starts with a slash\n const normalizedPath = path.startsWith(\"/\") ? path : \"/\" + path;\n\n // Join the baseUrl and path, removing any double slashes\n return normalizedBaseUrl.replace(/\\/$/, \"\") + normalizedPath;\n }\n\n private normalizeBaseUrl(baseUrl: string): string {\n if (!baseUrl) {\n throw new ScalarError(\n \"baseUrl is required\",\n \"MISSING_REQUIRED_CONFIG\",\n 400,\n );\n }\n\n // If baseUrl doesn't start with a protocol, prepend http://\n if (!/^https?:\\/\\//i.test(baseUrl)) {\n return \"http://\" + baseUrl;\n }\n\n return baseUrl;\n }\n\n private validateConfig(config: ScalarConfigType): void {\n if (!config.baseUrl) {\n throw new ScalarError(\n \"baseUrl is required\",\n \"MISSING_REQUIRED_CONFIG\",\n 400,\n );\n }\n\n try {\n // Validate baseUrl\n debug(\"Validating baseUrl:\", config.baseUrl);\n new URL(config.baseUrl);\n\n // Validate paths if provided\n if (config.proxyPath) {\n debug(\"Validating proxyPath:\", config.proxyPath);\n if (!this.isValidPath(config.proxyPath)) {\n debug(\"proxyPath validation FAILED\");\n throw new Error(\"Invalid proxyPath\");\n }\n }\n\n if (config.docPath) {\n debug(\"Validating docPath:\", config.docPath);\n if (!this.isValidPath(config.docPath)) {\n debug(\"docPath validation FAILED\");\n throw new Error(\"Invalid docPath\");\n }\n }\n\n if (config.apiSpecPath) {\n debug(\"Validating apiSpecPath:\", config.apiSpecPath);\n if (!this.isValidPath(config.apiSpecPath)) {\n debug(\"apiSpecPath validation FAILED\");\n throw new Error(\"Invalid apiSpecPath\");\n }\n }\n } catch (error) {\n debug(\"Validation error:\", error);\n throw new ScalarError(\"Invalid URL provided\", \"INVALID_URL\", 400);\n }\n }\n\n private isValidPath(path: string): boolean {\n // Aceita paths relativos com barras no meio e no final\n return (\n typeof path === \"string\" &&\n /^\\/[a-zA-Z0-9\\-._~:\\/@!$&'()*+,;=]*\\/?$/.test(path)\n );\n }\n}\n"],"mappings":"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","names":["logger","logger","path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "azurajs-scalar",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Proxy middleware and controller to scalar documentation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
10
10
|
"main": "dist/index.js",
|
|
11
11
|
"scripts": {
|
|
12
|
-
"build": "tsup
|
|
12
|
+
"build": "tsup"
|
|
13
13
|
},
|
|
14
14
|
"keywords": [],
|
|
15
15
|
"author": "",
|