@scalar/mock-server 0.9.8 → 0.9.10
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/CHANGELOG.md +17 -0
- package/dist/create-mock-server.js +79 -68
- package/dist/index.js +1 -5
- package/dist/libs/store.js +66 -65
- package/dist/routes/mock-any-response.js +70 -63
- package/dist/routes/mock-handler-response.js +140 -100
- package/dist/routes/respond-with-authorize-page.js +89 -80
- package/dist/routes/respond-with-openapi-document.js +32 -35
- package/dist/routes/respond-with-token.js +40 -45
- package/dist/types.js +2 -5
- package/dist/utils/build-handler-context.js +83 -70
- package/dist/utils/build-seed-context.js +59 -52
- package/dist/utils/create-openapi-definition.js +7 -10
- package/dist/utils/execute-handler.js +16 -18
- package/dist/utils/execute-seed.js +22 -21
- package/dist/utils/find-preferred-response-key.js +9 -9
- package/dist/utils/get-open-auth-token-urls.js +45 -35
- package/dist/utils/get-operation.js +12 -12
- package/dist/utils/handle-authentication.js +106 -101
- package/dist/utils/hono-route-from-path.js +6 -6
- package/dist/utils/is-authentication-required.js +17 -15
- package/dist/utils/log-authentication-instructions.js +105 -110
- package/dist/utils/process-openapi-document.js +71 -58
- package/dist/utils/set-up-authentication-routes.js +80 -77
- package/dist/utils/store-wrapper.js +40 -39
- package/package.json +10 -14
- package/dist/create-mock-server.js.map +0 -7
- package/dist/index.js.map +0 -7
- package/dist/libs/store.js.map +0 -7
- package/dist/routes/mock-any-response.js.map +0 -7
- package/dist/routes/mock-handler-response.js.map +0 -7
- package/dist/routes/respond-with-authorize-page.js.map +0 -7
- package/dist/routes/respond-with-openapi-document.js.map +0 -7
- package/dist/routes/respond-with-token.js.map +0 -7
- package/dist/types.js.map +0 -7
- package/dist/utils/build-handler-context.js.map +0 -7
- package/dist/utils/build-seed-context.js.map +0 -7
- package/dist/utils/create-openapi-definition.js.map +0 -7
- package/dist/utils/execute-handler.js.map +0 -7
- package/dist/utils/execute-seed.js.map +0 -7
- package/dist/utils/find-preferred-response-key.js.map +0 -7
- package/dist/utils/get-open-auth-token-urls.js.map +0 -7
- package/dist/utils/get-operation.js.map +0 -7
- package/dist/utils/handle-authentication.js.map +0 -7
- package/dist/utils/hono-route-from-path.js.map +0 -7
- package/dist/utils/is-authentication-required.js.map +0 -7
- package/dist/utils/log-authentication-instructions.js.map +0 -7
- package/dist/utils/process-openapi-document.js.map +0 -7
- package/dist/utils/set-up-authentication-routes.js.map +0 -7
- package/dist/utils/store-wrapper.js.map +0 -7
|
@@ -1,110 +1,115 @@
|
|
|
1
|
-
import { getCookie } from
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
case "http":
|
|
19
|
-
if ("scheme" in securityScheme && securityScheme.scheme === "basic") {
|
|
20
|
-
authScheme = "Basic";
|
|
21
|
-
const authHeader = c.req.header("Authorization");
|
|
22
|
-
if (authHeader?.startsWith("Basic ")) {
|
|
23
|
-
isAuthenticated = true;
|
|
24
|
-
}
|
|
25
|
-
} else if ("scheme" in securityScheme && securityScheme.scheme === "bearer") {
|
|
26
|
-
authScheme = "Bearer";
|
|
27
|
-
const authHeader = c.req.header("Authorization");
|
|
28
|
-
if (authHeader?.startsWith("Bearer ")) {
|
|
29
|
-
isAuthenticated = true;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
break;
|
|
33
|
-
case "apiKey":
|
|
34
|
-
if ("name" in securityScheme && "in" in securityScheme && securityScheme.name) {
|
|
35
|
-
authScheme = `ApiKey ${securityScheme.name}`;
|
|
36
|
-
if (securityScheme.in === "header") {
|
|
37
|
-
const apiKey = c.req.header(securityScheme.name);
|
|
38
|
-
if (apiKey) {
|
|
39
|
-
isAuthenticated = true;
|
|
1
|
+
import { getCookie } from 'hono/cookie';
|
|
2
|
+
/**
|
|
3
|
+
* Handles authentication for incoming requests based on the OpenAPI document.
|
|
4
|
+
*/
|
|
5
|
+
export function handleAuthentication(schema, operation) {
|
|
6
|
+
return async (c, next) => {
|
|
7
|
+
const operationSecuritySchemes = operation?.security || schema?.security;
|
|
8
|
+
if (operationSecuritySchemes && operationSecuritySchemes.length > 0) {
|
|
9
|
+
let isAuthenticated = false;
|
|
10
|
+
let authScheme = '';
|
|
11
|
+
for (const securityRequirement of operationSecuritySchemes) {
|
|
12
|
+
let securitySchemeAuthenticated = true;
|
|
13
|
+
for (const [schemeName] of Object.entries(securityRequirement)) {
|
|
14
|
+
const scheme = schema?.components?.securitySchemes?.[schemeName];
|
|
15
|
+
// Skip if scheme is a reference object (should be dereferenced already, but check to be safe)
|
|
16
|
+
if (scheme && '$ref' in scheme) {
|
|
17
|
+
continue;
|
|
40
18
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
19
|
+
if (scheme && 'type' in scheme) {
|
|
20
|
+
const securityScheme = scheme;
|
|
21
|
+
switch (securityScheme.type) {
|
|
22
|
+
case 'http':
|
|
23
|
+
if ('scheme' in securityScheme && securityScheme.scheme === 'basic') {
|
|
24
|
+
authScheme = 'Basic';
|
|
25
|
+
const authHeader = c.req.header('Authorization');
|
|
26
|
+
if (authHeader?.startsWith('Basic ')) {
|
|
27
|
+
isAuthenticated = true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else if ('scheme' in securityScheme && securityScheme.scheme === 'bearer') {
|
|
31
|
+
authScheme = 'Bearer';
|
|
32
|
+
const authHeader = c.req.header('Authorization');
|
|
33
|
+
if (authHeader?.startsWith('Bearer ')) {
|
|
34
|
+
isAuthenticated = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
case 'apiKey':
|
|
39
|
+
if ('name' in securityScheme && 'in' in securityScheme && securityScheme.name) {
|
|
40
|
+
authScheme = `ApiKey ${securityScheme.name}`;
|
|
41
|
+
if (securityScheme.in === 'header') {
|
|
42
|
+
const apiKey = c.req.header(securityScheme.name);
|
|
43
|
+
if (apiKey) {
|
|
44
|
+
isAuthenticated = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
else if (securityScheme.in === 'query') {
|
|
48
|
+
const apiKey = c.req.query(securityScheme.name);
|
|
49
|
+
if (apiKey) {
|
|
50
|
+
isAuthenticated = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else if (securityScheme.in === 'cookie') {
|
|
54
|
+
const apiKey = getCookie(c, securityScheme.name);
|
|
55
|
+
if (apiKey) {
|
|
56
|
+
isAuthenticated = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
case 'oauth2':
|
|
62
|
+
authScheme = 'Bearer';
|
|
63
|
+
// Handle OAuth 2.0 flows, including password grant
|
|
64
|
+
if (c.req.header('Authorization')?.startsWith('Bearer ')) {
|
|
65
|
+
isAuthenticated = true;
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
case 'openIdConnect':
|
|
69
|
+
authScheme = 'Bearer';
|
|
70
|
+
// Handle OpenID Connect similar to OAuth2
|
|
71
|
+
if (c.req.header('Authorization')?.startsWith('Bearer ')) {
|
|
72
|
+
isAuthenticated = true;
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
45
76
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
isAuthenticated = true;
|
|
77
|
+
if (!isAuthenticated) {
|
|
78
|
+
securitySchemeAuthenticated = false;
|
|
79
|
+
break;
|
|
50
80
|
}
|
|
51
|
-
}
|
|
52
81
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (c.req.header("Authorization")?.startsWith("Bearer ")) {
|
|
57
|
-
isAuthenticated = true;
|
|
82
|
+
if (securitySchemeAuthenticated) {
|
|
83
|
+
isAuthenticated = true;
|
|
84
|
+
break;
|
|
58
85
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
|
|
86
|
+
}
|
|
87
|
+
if (!isAuthenticated) {
|
|
88
|
+
let wwwAuthenticateValue = authScheme;
|
|
89
|
+
if (authScheme.startsWith('ApiKey')) {
|
|
90
|
+
wwwAuthenticateValue += ` realm="Scalar Mock Server", error="invalid_token", error_description="Invalid or missing API key"`;
|
|
64
91
|
}
|
|
65
|
-
|
|
92
|
+
else {
|
|
93
|
+
switch (authScheme) {
|
|
94
|
+
case 'Basic':
|
|
95
|
+
wwwAuthenticateValue += ' realm="Scalar Mock Server", charset="UTF-8"';
|
|
96
|
+
break;
|
|
97
|
+
case 'Bearer':
|
|
98
|
+
wwwAuthenticateValue +=
|
|
99
|
+
' realm="Scalar Mock Server", error="invalid_token", error_description="The access token is invalid or has expired"';
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
wwwAuthenticateValue = 'Bearer realm="Scalar Mock Server"';
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
c.header('WWW-Authenticate', wwwAuthenticateValue);
|
|
106
|
+
return c.json({
|
|
107
|
+
error: 'Unauthorized',
|
|
108
|
+
message: 'Authentication is required to access this resource.',
|
|
109
|
+
}, 401);
|
|
66
110
|
}
|
|
67
|
-
}
|
|
68
|
-
if (!isAuthenticated) {
|
|
69
|
-
securitySchemeAuthenticated = false;
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (securitySchemeAuthenticated) {
|
|
74
|
-
isAuthenticated = true;
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
if (!isAuthenticated) {
|
|
79
|
-
let wwwAuthenticateValue = authScheme;
|
|
80
|
-
if (authScheme.startsWith("ApiKey")) {
|
|
81
|
-
wwwAuthenticateValue += ` realm="Scalar Mock Server", error="invalid_token", error_description="Invalid or missing API key"`;
|
|
82
|
-
} else {
|
|
83
|
-
switch (authScheme) {
|
|
84
|
-
case "Basic":
|
|
85
|
-
wwwAuthenticateValue += ' realm="Scalar Mock Server", charset="UTF-8"';
|
|
86
|
-
break;
|
|
87
|
-
case "Bearer":
|
|
88
|
-
wwwAuthenticateValue += ' realm="Scalar Mock Server", error="invalid_token", error_description="The access token is invalid or has expired"';
|
|
89
|
-
break;
|
|
90
|
-
default:
|
|
91
|
-
wwwAuthenticateValue = 'Bearer realm="Scalar Mock Server"';
|
|
92
|
-
}
|
|
93
111
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
error: "Unauthorized",
|
|
98
|
-
message: "Authentication is required to access this resource."
|
|
99
|
-
},
|
|
100
|
-
401
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
await next();
|
|
105
|
-
};
|
|
112
|
+
// If all checks pass, continue to the next middleware
|
|
113
|
+
await next();
|
|
114
|
+
};
|
|
106
115
|
}
|
|
107
|
-
export {
|
|
108
|
-
handleAuthentication
|
|
109
|
-
};
|
|
110
|
-
//# sourceMappingURL=handle-authentication.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Convert path to route
|
|
3
|
+
* Example: /posts/{id} -> /posts/:id
|
|
4
|
+
*/
|
|
5
|
+
export function honoRouteFromPath(path) {
|
|
6
|
+
return path.replace(/{/g, ':').replace(/}/g, '');
|
|
3
7
|
}
|
|
4
|
-
export {
|
|
5
|
-
honoRouteFromPath
|
|
6
|
-
};
|
|
7
|
-
//# sourceMappingURL=hono-route-from-path.js.map
|
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Check whether the given security scheme key is in the `security` configuration for this operation.
|
|
3
|
+
*/
|
|
4
|
+
export function isAuthenticationRequired(security) {
|
|
5
|
+
// If security is not defined, auth is not required.
|
|
6
|
+
if (!security) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
// Don't require auth if security is just an empty array []
|
|
10
|
+
if (Array.isArray(security) && !security.length) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
// Includes empty object = auth is not required
|
|
14
|
+
if ((security ?? []).some((securityRequirement) => !Object.keys(securityRequirement).length)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
12
18
|
}
|
|
13
|
-
export {
|
|
14
|
-
isAuthenticationRequired
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=is-authentication-required.js.map
|
|
@@ -1,118 +1,113 @@
|
|
|
1
|
-
import { getPathFromUrl } from
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
console.log(" Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=");
|
|
39
|
-
console.log();
|
|
40
|
-
} else if (scheme.scheme === "bearer") {
|
|
41
|
-
console.log("\u2705 Bearer Token Authentication");
|
|
42
|
-
console.log(" Use an Authorization header with any bearer token");
|
|
43
|
-
console.log();
|
|
44
|
-
console.log(" Authorization: Bearer YOUR_TOKEN_HERE");
|
|
45
|
-
console.log();
|
|
46
|
-
} else {
|
|
47
|
-
console.error("\u274C Unknown Security Scheme:", scheme);
|
|
48
|
-
}
|
|
49
|
-
break;
|
|
50
|
-
case "oauth2":
|
|
51
|
-
if (scheme.flows) {
|
|
52
|
-
Object.keys(scheme.flows).forEach((flow) => {
|
|
53
|
-
switch (flow) {
|
|
54
|
-
case "implicit":
|
|
55
|
-
console.log("\u2705 OAuth 2.0 Implicit Flow");
|
|
56
|
-
console.log(" Use the following URL to initiate the OAuth 2.0 Implicit Flow:");
|
|
57
|
-
console.log();
|
|
58
|
-
console.log(
|
|
59
|
-
` GET ${scheme?.flows?.implicit?.authorizationUrl || "/oauth/authorize"}?response_type=token&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=YOUR_SCOPES`
|
|
60
|
-
);
|
|
61
|
-
console.log();
|
|
1
|
+
import { getPathFromUrl } from './get-open-auth-token-urls.js';
|
|
2
|
+
/**
|
|
3
|
+
* Log authentication instructions for different security schemes
|
|
4
|
+
*/
|
|
5
|
+
export function logAuthenticationInstructions(securitySchemes) {
|
|
6
|
+
if (!securitySchemes || Object.keys(securitySchemes).length === 0) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
console.log('Authentication:');
|
|
10
|
+
console.log();
|
|
11
|
+
Object.entries(securitySchemes).forEach(([_, scheme]) => {
|
|
12
|
+
switch (scheme.type) {
|
|
13
|
+
case 'apiKey':
|
|
14
|
+
if (scheme.in === 'header') {
|
|
15
|
+
console.log('✅ API Key Authentication');
|
|
16
|
+
console.log(` Use any API key in the ${scheme.name} header`);
|
|
17
|
+
console.log();
|
|
18
|
+
console.log(` ${scheme.name}: YOUR_API_KEY_HERE`);
|
|
19
|
+
console.log();
|
|
20
|
+
}
|
|
21
|
+
else if (scheme.in === 'query') {
|
|
22
|
+
console.log('✅ API Key Authentication');
|
|
23
|
+
console.log(` Use any API key in the ${scheme.name} query parameter:`);
|
|
24
|
+
console.log();
|
|
25
|
+
console.log(` ?${scheme.name}=YOUR_API_KEY_HERE`);
|
|
26
|
+
console.log();
|
|
27
|
+
}
|
|
28
|
+
else if (scheme.in === 'cookie') {
|
|
29
|
+
console.log('✅ API Key Authentication');
|
|
30
|
+
console.log(` Use any API key in the ${scheme.name} cookie:`);
|
|
31
|
+
console.log();
|
|
32
|
+
console.log(` Cookie: ${scheme.name}=YOUR_API_KEY_HERE`);
|
|
33
|
+
console.log();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.error(`❌ Unsupported API Key Location: ${scheme.in}`);
|
|
37
|
+
}
|
|
62
38
|
break;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
39
|
+
case 'http':
|
|
40
|
+
if (scheme.scheme === 'basic') {
|
|
41
|
+
console.log('✅ HTTP Basic Authentication');
|
|
42
|
+
console.log(' Use an Authorization header with any credentials ("username:password" in base64):');
|
|
43
|
+
console.log();
|
|
44
|
+
console.log(' Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=');
|
|
45
|
+
console.log();
|
|
46
|
+
}
|
|
47
|
+
else if (scheme.scheme === 'bearer') {
|
|
48
|
+
console.log('✅ Bearer Token Authentication');
|
|
49
|
+
console.log(' Use an Authorization header with any bearer token');
|
|
50
|
+
console.log();
|
|
51
|
+
console.log(' Authorization: Bearer YOUR_TOKEN_HERE');
|
|
52
|
+
console.log();
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.error('❌ Unknown Security Scheme:', scheme);
|
|
56
|
+
}
|
|
74
57
|
break;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
58
|
+
case 'oauth2':
|
|
59
|
+
if (scheme.flows) {
|
|
60
|
+
Object.keys(scheme.flows).forEach((flow) => {
|
|
61
|
+
switch (flow) {
|
|
62
|
+
case 'implicit':
|
|
63
|
+
console.log('✅ OAuth 2.0 Implicit Flow');
|
|
64
|
+
console.log(' Use the following URL to initiate the OAuth 2.0 Implicit Flow:');
|
|
65
|
+
console.log();
|
|
66
|
+
console.log(` GET ${scheme?.flows?.implicit?.authorizationUrl || '/oauth/authorize'}?response_type=token&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=YOUR_SCOPES`);
|
|
67
|
+
console.log();
|
|
68
|
+
break;
|
|
69
|
+
case 'password':
|
|
70
|
+
console.log('✅ OAuth 2.0 Password Flow');
|
|
71
|
+
console.log(' Use the following URL to obtain an access token:');
|
|
72
|
+
console.log();
|
|
73
|
+
console.log(` POST ${getPathFromUrl(scheme?.flows?.password?.tokenUrl || '/oauth/token')}`);
|
|
74
|
+
console.log(' Content-Type: application/x-www-form-urlencoded');
|
|
75
|
+
console.log();
|
|
76
|
+
console.log(' grant_type=password&username=YOUR_USERNAME&password=YOUR_PASSWORD&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET');
|
|
77
|
+
console.log();
|
|
78
|
+
break;
|
|
79
|
+
case 'clientCredentials':
|
|
80
|
+
console.log('✅ OAuth 2.0 Client Credentials Flow');
|
|
81
|
+
console.log(' Use the following URL to obtain an access token:');
|
|
82
|
+
console.log();
|
|
83
|
+
console.log(` POST ${getPathFromUrl(scheme?.flows?.clientCredentials?.tokenUrl || '/oauth/token')}`);
|
|
84
|
+
console.log(' Content-Type: application/x-www-form-urlencoded');
|
|
85
|
+
console.log();
|
|
86
|
+
console.log(' grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET');
|
|
87
|
+
console.log();
|
|
88
|
+
break;
|
|
89
|
+
case 'authorizationCode':
|
|
90
|
+
console.log('✅ OAuth 2.0 Authorization Code Flow');
|
|
91
|
+
console.log(' Use the following URL to initiate the OAuth 2.0 Authorization Code Flow:');
|
|
92
|
+
console.log();
|
|
93
|
+
console.log(' GET', `${getPathFromUrl(scheme?.flows?.authorizationCode?.authorizationUrl || '/oauth/authorize')}?redirect_uri=https://YOUR_REDIRECT_URI_HERE`);
|
|
94
|
+
console.log();
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
console.warn(`Unsupported OAuth 2.0 flow: ${flow}`);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
86
101
|
break;
|
|
87
|
-
|
|
88
|
-
console.log(
|
|
89
|
-
console.log(
|
|
102
|
+
case 'openIdConnect':
|
|
103
|
+
console.log('✅ OpenID Connect Authentication');
|
|
104
|
+
console.log(' Use the following OpenID Connect discovery URL:');
|
|
90
105
|
console.log();
|
|
91
|
-
console.log(
|
|
92
|
-
" GET",
|
|
93
|
-
`${getPathFromUrl(scheme?.flows?.authorizationCode?.authorizationUrl || "/oauth/authorize")}?redirect_uri=https://YOUR_REDIRECT_URI_HERE`
|
|
94
|
-
);
|
|
106
|
+
console.log(` ${getPathFromUrl(scheme.openIdConnectUrl || '/.well-known/openid-configuration')}`);
|
|
95
107
|
console.log();
|
|
96
108
|
break;
|
|
97
|
-
|
|
98
|
-
console.warn(`Unsupported
|
|
99
|
-
}
|
|
100
|
-
});
|
|
109
|
+
default:
|
|
110
|
+
console.warn(`Unsupported security scheme type: ${scheme.type}`);
|
|
101
111
|
}
|
|
102
|
-
|
|
103
|
-
case "openIdConnect":
|
|
104
|
-
console.log("\u2705 OpenID Connect Authentication");
|
|
105
|
-
console.log(" Use the following OpenID Connect discovery URL:");
|
|
106
|
-
console.log();
|
|
107
|
-
console.log(` ${getPathFromUrl(scheme.openIdConnectUrl || "/.well-known/openid-configuration")}`);
|
|
108
|
-
console.log();
|
|
109
|
-
break;
|
|
110
|
-
default:
|
|
111
|
-
console.warn(`Unsupported security scheme type: ${scheme.type}`);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
112
|
+
});
|
|
114
113
|
}
|
|
115
|
-
export {
|
|
116
|
-
logAuthenticationInstructions
|
|
117
|
-
};
|
|
118
|
-
//# sourceMappingURL=log-authentication-instructions.js.map
|
|
@@ -1,59 +1,72 @@
|
|
|
1
|
-
import { bundle } from
|
|
2
|
-
import { parseJson } from
|
|
3
|
-
import { parseYaml } from
|
|
4
|
-
import { readFiles } from
|
|
5
|
-
import { fetchUrls } from
|
|
6
|
-
import { dereference } from
|
|
7
|
-
import { upgrade } from
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
1
|
+
import { bundle } from '@scalar/json-magic/bundle';
|
|
2
|
+
import { parseJson } from '@scalar/json-magic/bundle/plugins/node';
|
|
3
|
+
import { parseYaml } from '@scalar/json-magic/bundle/plugins/node';
|
|
4
|
+
import { readFiles } from '@scalar/json-magic/bundle/plugins/node';
|
|
5
|
+
import { fetchUrls } from '@scalar/json-magic/bundle/plugins/node';
|
|
6
|
+
import { dereference } from '@scalar/openapi-parser';
|
|
7
|
+
import { upgrade } from '@scalar/openapi-upgrader';
|
|
8
|
+
/**
|
|
9
|
+
* Processes an OpenAPI document by bundling external references, upgrading to OpenAPI 3.1,
|
|
10
|
+
* and dereferencing the document.
|
|
11
|
+
*
|
|
12
|
+
* @param document - The OpenAPI document to process. Can be a string (URL/path) or an object.
|
|
13
|
+
* @returns A promise that resolves to the dereferenced OpenAPI 3.1 document.
|
|
14
|
+
* @throws Error if the document cannot be processed or is invalid.
|
|
15
|
+
*/
|
|
16
|
+
export async function processOpenApiDocument(document) {
|
|
17
|
+
// Handle empty/undefined input gracefully
|
|
18
|
+
if (!document || (typeof document === 'object' && Object.keys(document).length === 0)) {
|
|
19
|
+
// Return a minimal valid OpenAPI 3.1 document
|
|
20
|
+
return {
|
|
21
|
+
openapi: '3.1.0',
|
|
22
|
+
info: {
|
|
23
|
+
title: 'Mock API',
|
|
24
|
+
version: '1.0.0',
|
|
25
|
+
},
|
|
26
|
+
paths: {},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
let bundled;
|
|
30
|
+
try {
|
|
31
|
+
// Bundle external references with Node.js plugins
|
|
32
|
+
// Include parseJson and parseYaml to handle string inputs
|
|
33
|
+
bundled = await bundle(document, {
|
|
34
|
+
plugins: [parseJson(), parseYaml(), readFiles(), fetchUrls()],
|
|
35
|
+
treeShake: false,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new Error(`Failed to bundle OpenAPI document: ${error instanceof Error ? error.message : String(error)}`);
|
|
40
|
+
}
|
|
41
|
+
if (!bundled || typeof bundled !== 'object') {
|
|
42
|
+
throw new Error('Bundled document is invalid: expected an object');
|
|
43
|
+
}
|
|
44
|
+
let upgraded;
|
|
45
|
+
try {
|
|
46
|
+
// Upgrade to OpenAPI 3.1
|
|
47
|
+
upgraded = upgrade(bundled, '3.1');
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new Error(`Failed to upgrade OpenAPI document to 3.1: ${error instanceof Error ? error.message : String(error)}`);
|
|
51
|
+
}
|
|
52
|
+
if (!upgraded) {
|
|
53
|
+
throw new Error('Upgraded document is invalid: upgrade returned null or undefined');
|
|
54
|
+
}
|
|
55
|
+
// Dereference the document
|
|
56
|
+
const dereferenceResult = dereference(upgraded);
|
|
57
|
+
// Check for dereference errors
|
|
58
|
+
if (dereferenceResult.errors && dereferenceResult.errors.length > 0) {
|
|
59
|
+
const errorMessages = dereferenceResult.errors.map((err) => err.message).join(', ');
|
|
60
|
+
throw new Error(`Failed to dereference OpenAPI document: ${errorMessages}`);
|
|
61
|
+
}
|
|
62
|
+
// Extract the schema from the dereference result
|
|
63
|
+
const schema = dereferenceResult.schema;
|
|
64
|
+
if (!schema) {
|
|
65
|
+
throw new Error('Dereference result does not contain a schema');
|
|
66
|
+
}
|
|
67
|
+
// Ensure the schema is a valid OpenAPI 3.1 document
|
|
68
|
+
if (typeof schema !== 'object') {
|
|
69
|
+
throw new Error('Dereferenced schema is invalid: expected an object');
|
|
70
|
+
}
|
|
71
|
+
return schema;
|
|
55
72
|
}
|
|
56
|
-
export {
|
|
57
|
-
processOpenApiDocument
|
|
58
|
-
};
|
|
59
|
-
//# sourceMappingURL=process-openapi-document.js.map
|