@scalar/mock-server 0.3.23 → 0.3.25
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 +18 -0
- package/dist/createMockServer.d.ts +1 -1
- package/dist/createMockServer.d.ts.map +1 -1
- package/dist/createMockServer.js +36 -48
- package/dist/createMockServer.js.map +7 -0
- package/dist/createMockServer.test.js +598 -0
- package/dist/createMockServer.test.js.map +7 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +7 -0
- package/dist/routes/mockAnyResponse.d.ts +1 -1
- package/dist/routes/mockAnyResponse.d.ts.map +1 -1
- package/dist/routes/mockAnyResponse.js +56 -64
- package/dist/routes/mockAnyResponse.js.map +7 -0
- package/dist/routes/respondWithAuthorizePage.js +39 -31
- package/dist/routes/respondWithAuthorizePage.js.map +7 -0
- package/dist/routes/respondWithOpenApiDocument.js +35 -35
- package/dist/routes/respondWithOpenApiDocument.js.map +7 -0
- package/dist/routes/respondWithToken.js +44 -41
- package/dist/routes/respondWithToken.js.map +7 -0
- package/dist/types.js +5 -4
- package/dist/types.js.map +7 -0
- package/dist/utils/createOpenApiDefinition.js +11 -0
- package/dist/utils/createOpenApiDefinition.js.map +7 -0
- package/dist/utils/findPreferredResponseKey.js +8 -10
- package/dist/utils/findPreferredResponseKey.js.map +7 -0
- package/dist/utils/findPreferredResponseKey.test.js +20 -0
- package/dist/utils/findPreferredResponseKey.test.js.map +7 -0
- package/dist/utils/getOpenAuthTokenUrls.js +33 -45
- package/dist/utils/getOpenAuthTokenUrls.js.map +7 -0
- package/dist/utils/getOpenAuthTokenUrls.test.js +127 -0
- package/dist/utils/getOpenAuthTokenUrls.test.js.map +7 -0
- package/dist/utils/getOperations.d.ts +1 -1
- package/dist/utils/getOperations.d.ts.map +1 -1
- package/dist/utils/getOperations.js +11 -14
- package/dist/utils/getOperations.js.map +7 -0
- package/dist/utils/handleAuthentication.js +95 -101
- package/dist/utils/handleAuthentication.js.map +7 -0
- package/dist/utils/honoRouteFromPath.js +5 -7
- package/dist/utils/honoRouteFromPath.js.map +7 -0
- package/dist/utils/honoRouteFromPath.test.js +32 -0
- package/dist/utils/honoRouteFromPath.test.js.map +7 -0
- package/dist/utils/isAuthenticationRequired.js +14 -18
- package/dist/utils/isAuthenticationRequired.js.map +7 -0
- package/dist/utils/isAuthenticationRequired.test.js +23 -0
- package/dist/utils/isAuthenticationRequired.test.js.map +7 -0
- package/dist/utils/logAuthenticationInstructions.js +109 -107
- package/dist/utils/logAuthenticationInstructions.js.map +7 -0
- package/dist/utils/setupAuthenticationRoutes.js +76 -82
- package/dist/utils/setupAuthenticationRoutes.js.map +7 -0
- package/package.json +7 -9
|
@@ -1,54 +1,42 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extract path from URL
|
|
3
|
-
*/
|
|
4
1
|
function getPathFromUrl(url) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
catch {
|
|
13
|
-
// If URL is invalid, return the original string
|
|
14
|
-
return url;
|
|
15
|
-
}
|
|
2
|
+
try {
|
|
3
|
+
const urlObject = url.startsWith("http") ? new URL(url) : new URL(url, "http://example.com");
|
|
4
|
+
const path = urlObject.pathname;
|
|
5
|
+
return path === "/" ? path : path.replace(/\/$/, "");
|
|
6
|
+
} catch {
|
|
7
|
+
return url;
|
|
8
|
+
}
|
|
16
9
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Returns all token URLs mentioned in the securitySchemes, without the domain
|
|
19
|
-
*/
|
|
20
|
-
// Type guard for OAuth2 security scheme
|
|
21
10
|
function isOAuth2Scheme(scheme) {
|
|
22
|
-
|
|
11
|
+
return scheme.type === "oauth2";
|
|
23
12
|
}
|
|
24
|
-
// Validate token URL
|
|
25
13
|
function isValidTokenUrl(url) {
|
|
26
|
-
|
|
14
|
+
return url.trim().length > 0;
|
|
27
15
|
}
|
|
28
16
|
function getOpenAuthTokenUrls(schema) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (!isOAuth2Scheme(scheme)) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
const flows = scheme.flows; // Type assertion no longer needed
|
|
41
|
-
// Helper to safely add valid token URLs
|
|
42
|
-
const addTokenUrl = (url) => {
|
|
43
|
-
if (url && isValidTokenUrl(url)) {
|
|
44
|
-
tokenUrls.add(getPathFromUrl(url));
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
addTokenUrl(flows?.password?.tokenUrl);
|
|
48
|
-
addTokenUrl(flows?.clientCredentials?.tokenUrl);
|
|
49
|
-
addTokenUrl(flows?.authorizationCode?.tokenUrl);
|
|
17
|
+
if (!schema?.components?.securitySchemes) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
const securitySchemes = schema.components.securitySchemes;
|
|
21
|
+
const tokenUrls = /* @__PURE__ */ new Set();
|
|
22
|
+
for (const scheme of Object.values(securitySchemes)) {
|
|
23
|
+
if (!isOAuth2Scheme(scheme)) {
|
|
24
|
+
continue;
|
|
50
25
|
}
|
|
51
|
-
|
|
26
|
+
const flows = scheme.flows;
|
|
27
|
+
const addTokenUrl = (url) => {
|
|
28
|
+
if (url && isValidTokenUrl(url)) {
|
|
29
|
+
tokenUrls.add(getPathFromUrl(url));
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
addTokenUrl(flows?.password?.tokenUrl);
|
|
33
|
+
addTokenUrl(flows?.clientCredentials?.tokenUrl);
|
|
34
|
+
addTokenUrl(flows?.authorizationCode?.tokenUrl);
|
|
35
|
+
}
|
|
36
|
+
return Array.from(tokenUrls);
|
|
52
37
|
}
|
|
53
|
-
|
|
54
|
-
|
|
38
|
+
export {
|
|
39
|
+
getOpenAuthTokenUrls,
|
|
40
|
+
getPathFromUrl
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=getOpenAuthTokenUrls.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/getOpenAuthTokenUrls.ts"],
|
|
4
|
+
"sourcesContent": ["import type { OpenAPI, OpenAPIV3, OpenAPIV3_1 } from '@scalar/openapi-types'\n\n/**\n * Extract path from URL\n */\nexport function getPathFromUrl(url: string): string {\n try {\n // Handle relative URLs by prepending a base\n const urlObject = url.startsWith('http') ? new URL(url) : new URL(url, 'http://example.com')\n\n // Normalize: remove trailing slash except for root path\n const path = urlObject.pathname\n return path === '/' ? path : path.replace(/\\/$/, '')\n } catch {\n // If URL is invalid, return the original string\n return url\n }\n}\n\n/**\n * Returns all token URLs mentioned in the securitySchemes, without the domain\n */\n// Type guard for OAuth2 security scheme\nfunction isOAuth2Scheme(\n scheme: OpenAPIV3.SecuritySchemeObject | OpenAPIV3_1.SecuritySchemeObject,\n): scheme is OpenAPIV3.OAuth2SecurityScheme | OpenAPIV3_1.OAuth2SecurityScheme {\n return scheme.type === 'oauth2'\n}\n\n// Validate token URL\nfunction isValidTokenUrl(url: string): boolean {\n return url.trim().length > 0\n}\n\nexport function getOpenAuthTokenUrls(schema?: OpenAPI.Document): string[] {\n if (!schema?.components?.securitySchemes) {\n return []\n }\n\n const securitySchemes: Record<string, OpenAPIV3.SecuritySchemeObject | OpenAPIV3_1.SecuritySchemeObject> =\n schema.components.securitySchemes\n\n // Use Set from the start for better memory efficiency\n const tokenUrls = new Set<string>()\n\n // Iterate through all security schemes\n for (const scheme of Object.values(securitySchemes)) {\n if (!isOAuth2Scheme(scheme)) {\n continue\n }\n\n const flows = scheme.flows // Type assertion no longer needed\n\n // Helper to safely add valid token URLs\n const addTokenUrl = (url?: string) => {\n if (url && isValidTokenUrl(url)) {\n tokenUrls.add(getPathFromUrl(url))\n }\n }\n\n addTokenUrl(flows?.password?.tokenUrl)\n addTokenUrl(flows?.clientCredentials?.tokenUrl)\n addTokenUrl(flows?.authorizationCode?.tokenUrl)\n }\n\n return Array.from(tokenUrls)\n}\n"],
|
|
5
|
+
"mappings": "AAKO,SAAS,eAAe,KAAqB;AAClD,MAAI;AAEF,UAAM,YAAY,IAAI,WAAW,MAAM,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,KAAK,oBAAoB;AAG3F,UAAM,OAAO,UAAU;AACvB,WAAO,SAAS,MAAM,OAAO,KAAK,QAAQ,OAAO,EAAE;AAAA,EACrD,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAMA,SAAS,eACP,QAC6E;AAC7E,SAAO,OAAO,SAAS;AACzB;AAGA,SAAS,gBAAgB,KAAsB;AAC7C,SAAO,IAAI,KAAK,EAAE,SAAS;AAC7B;AAEO,SAAS,qBAAqB,QAAqC;AACxE,MAAI,CAAC,QAAQ,YAAY,iBAAiB;AACxC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,kBACJ,OAAO,WAAW;AAGpB,QAAM,YAAY,oBAAI,IAAY;AAGlC,aAAW,UAAU,OAAO,OAAO,eAAe,GAAG;AACnD,QAAI,CAAC,eAAe,MAAM,GAAG;AAC3B;AAAA,IACF;AAEA,UAAM,QAAQ,OAAO;AAGrB,UAAM,cAAc,CAAC,QAAiB;AACpC,UAAI,OAAO,gBAAgB,GAAG,GAAG;AAC/B,kBAAU,IAAI,eAAe,GAAG,CAAC;AAAA,MACnC;AAAA,IACF;AAEA,gBAAY,OAAO,UAAU,QAAQ;AACrC,gBAAY,OAAO,mBAAmB,QAAQ;AAC9C,gBAAY,OAAO,mBAAmB,QAAQ;AAAA,EAChD;AAEA,SAAO,MAAM,KAAK,SAAS;AAC7B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { createOpenApiDefinition } from "./createOpenApiDefinition.js";
|
|
3
|
+
import { getOpenAuthTokenUrls, getPathFromUrl } from "./getOpenAuthTokenUrls.js";
|
|
4
|
+
describe("getOpenAuthTokenUrls", () => {
|
|
5
|
+
it("returns an empty array for schema without securitySchemes", () => {
|
|
6
|
+
const schema = createOpenApiDefinition({});
|
|
7
|
+
expect(getOpenAuthTokenUrls(schema)).toEqual([]);
|
|
8
|
+
});
|
|
9
|
+
it("returns token URLs from OAuth2 password flow", () => {
|
|
10
|
+
const schema = createOpenApiDefinition({
|
|
11
|
+
oauth2Password: {
|
|
12
|
+
type: "oauth2",
|
|
13
|
+
flows: {
|
|
14
|
+
password: {
|
|
15
|
+
tokenUrl: "https://api.example.com/oauth/token"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
expect(getOpenAuthTokenUrls(schema)).toEqual(["/oauth/token"]);
|
|
21
|
+
});
|
|
22
|
+
it("returns token URLs from OAuth2 clientCredentials flow", () => {
|
|
23
|
+
const schema = createOpenApiDefinition({
|
|
24
|
+
oauth2ClientCredentials: {
|
|
25
|
+
type: "oauth2",
|
|
26
|
+
flows: {
|
|
27
|
+
clientCredentials: {
|
|
28
|
+
tokenUrl: "https://api.example.com/oauth/client_token"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
expect(getOpenAuthTokenUrls(schema)).toEqual(["/oauth/client_token"]);
|
|
34
|
+
});
|
|
35
|
+
it("returns token URLs from OAuth2 authorizationCode flow", () => {
|
|
36
|
+
const schema = createOpenApiDefinition({
|
|
37
|
+
oauth2AuthCode: {
|
|
38
|
+
type: "oauth2",
|
|
39
|
+
flows: {
|
|
40
|
+
authorizationCode: {
|
|
41
|
+
authorizationUrl: "https://api.example.com/oauth/authorize",
|
|
42
|
+
tokenUrl: "https://api.example.com/oauth/token"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
expect(getOpenAuthTokenUrls(schema)).toEqual(["/oauth/token"]);
|
|
48
|
+
});
|
|
49
|
+
it("returns multiple token URLs from different OAuth2 flows", () => {
|
|
50
|
+
const schema = createOpenApiDefinition({
|
|
51
|
+
oauth2Password: {
|
|
52
|
+
type: "oauth2",
|
|
53
|
+
flows: {
|
|
54
|
+
password: {
|
|
55
|
+
tokenUrl: "https://api.example.com/oauth/password_token"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
oauth2ClientCredentials: {
|
|
60
|
+
type: "oauth2",
|
|
61
|
+
flows: {
|
|
62
|
+
clientCredentials: {
|
|
63
|
+
tokenUrl: "https://api.example.com/oauth/client_token"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
expect(getOpenAuthTokenUrls(schema)).toEqual(["/oauth/password_token", "/oauth/client_token"]);
|
|
69
|
+
});
|
|
70
|
+
it("ignores non-OAuth2 security schemes", () => {
|
|
71
|
+
const schema = createOpenApiDefinition({
|
|
72
|
+
basicAuth: {
|
|
73
|
+
type: "http",
|
|
74
|
+
scheme: "basic"
|
|
75
|
+
},
|
|
76
|
+
oauth2Password: {
|
|
77
|
+
type: "oauth2",
|
|
78
|
+
flows: {
|
|
79
|
+
password: {
|
|
80
|
+
tokenUrl: "https://api.example.com/oauth/token"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
expect(getOpenAuthTokenUrls(schema)).toEqual(["/oauth/token"]);
|
|
86
|
+
});
|
|
87
|
+
it("returns unique token URLs", () => {
|
|
88
|
+
const schema = createOpenApiDefinition({
|
|
89
|
+
oauth2Password: {
|
|
90
|
+
type: "oauth2",
|
|
91
|
+
flows: {
|
|
92
|
+
password: {
|
|
93
|
+
tokenUrl: "https://api.example.com/oauth/token"
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
oauth2ClientCredentials: {
|
|
98
|
+
type: "oauth2",
|
|
99
|
+
flows: {
|
|
100
|
+
clientCredentials: {
|
|
101
|
+
tokenUrl: "https://api.example.com/oauth/token"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
expect(getOpenAuthTokenUrls(schema)).toEqual(["/oauth/token"]);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe("getPathFromUrl", () => {
|
|
110
|
+
it("returns the path from a valid URL", () => {
|
|
111
|
+
const url = "https://api.example.com/oauth/token";
|
|
112
|
+
expect(getPathFromUrl(url)).toBe("/oauth/token");
|
|
113
|
+
});
|
|
114
|
+
it("handles URLs with query parameters", () => {
|
|
115
|
+
const url = "https://api.example.com/oauth/token?param=value";
|
|
116
|
+
expect(getPathFromUrl(url)).toBe("/oauth/token");
|
|
117
|
+
});
|
|
118
|
+
it("handles URLs with fragments", () => {
|
|
119
|
+
const url = "https://api.example.com/oauth/token#fragment";
|
|
120
|
+
expect(getPathFromUrl(url)).toBe("/oauth/token");
|
|
121
|
+
});
|
|
122
|
+
it("handles URLs without paths", () => {
|
|
123
|
+
const url = "https://api.example.com";
|
|
124
|
+
expect(getPathFromUrl(url)).toBe("/");
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=getOpenAuthTokenUrls.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/getOpenAuthTokenUrls.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { describe, expect, it } from 'vitest'\n\nimport { createOpenApiDefinition } from './createOpenApiDefinition'\nimport { getOpenAuthTokenUrls, getPathFromUrl } from './getOpenAuthTokenUrls'\n\ndescribe('getOpenAuthTokenUrls', () => {\n it('returns an empty array for schema without securitySchemes', () => {\n const schema = createOpenApiDefinition({})\n expect(getOpenAuthTokenUrls(schema)).toEqual([])\n })\n\n it('returns token URLs from OAuth2 password flow', () => {\n const schema = createOpenApiDefinition({\n oauth2Password: {\n type: 'oauth2',\n flows: {\n password: {\n tokenUrl: 'https://api.example.com/oauth/token',\n },\n },\n },\n })\n expect(getOpenAuthTokenUrls(schema)).toEqual(['/oauth/token'])\n })\n\n it('returns token URLs from OAuth2 clientCredentials flow', () => {\n const schema = createOpenApiDefinition({\n oauth2ClientCredentials: {\n type: 'oauth2',\n flows: {\n clientCredentials: {\n tokenUrl: 'https://api.example.com/oauth/client_token',\n },\n },\n },\n })\n expect(getOpenAuthTokenUrls(schema)).toEqual(['/oauth/client_token'])\n })\n\n it('returns token URLs from OAuth2 authorizationCode flow', () => {\n const schema = createOpenApiDefinition({\n oauth2AuthCode: {\n type: 'oauth2',\n flows: {\n authorizationCode: {\n authorizationUrl: 'https://api.example.com/oauth/authorize',\n tokenUrl: 'https://api.example.com/oauth/token',\n },\n },\n },\n })\n expect(getOpenAuthTokenUrls(schema)).toEqual(['/oauth/token'])\n })\n\n it('returns multiple token URLs from different OAuth2 flows', () => {\n const schema = createOpenApiDefinition({\n oauth2Password: {\n type: 'oauth2',\n flows: {\n password: {\n tokenUrl: 'https://api.example.com/oauth/password_token',\n },\n },\n },\n oauth2ClientCredentials: {\n type: 'oauth2',\n flows: {\n clientCredentials: {\n tokenUrl: 'https://api.example.com/oauth/client_token',\n },\n },\n },\n })\n expect(getOpenAuthTokenUrls(schema)).toEqual(['/oauth/password_token', '/oauth/client_token'])\n })\n\n it('ignores non-OAuth2 security schemes', () => {\n const schema = createOpenApiDefinition({\n basicAuth: {\n type: 'http',\n scheme: 'basic',\n },\n oauth2Password: {\n type: 'oauth2',\n flows: {\n password: {\n tokenUrl: 'https://api.example.com/oauth/token',\n },\n },\n },\n })\n expect(getOpenAuthTokenUrls(schema)).toEqual(['/oauth/token'])\n })\n\n it('returns unique token URLs', () => {\n const schema = createOpenApiDefinition({\n oauth2Password: {\n type: 'oauth2',\n flows: {\n password: {\n tokenUrl: 'https://api.example.com/oauth/token',\n },\n },\n },\n oauth2ClientCredentials: {\n type: 'oauth2',\n flows: {\n clientCredentials: {\n tokenUrl: 'https://api.example.com/oauth/token',\n },\n },\n },\n })\n expect(getOpenAuthTokenUrls(schema)).toEqual(['/oauth/token'])\n })\n})\n\ndescribe('getPathFromUrl', () => {\n it('returns the path from a valid URL', () => {\n const url = 'https://api.example.com/oauth/token'\n expect(getPathFromUrl(url)).toBe('/oauth/token')\n })\n\n it('handles URLs with query parameters', () => {\n const url = 'https://api.example.com/oauth/token?param=value'\n expect(getPathFromUrl(url)).toBe('/oauth/token')\n })\n\n it('handles URLs with fragments', () => {\n const url = 'https://api.example.com/oauth/token#fragment'\n expect(getPathFromUrl(url)).toBe('/oauth/token')\n })\n\n it('handles URLs without paths', () => {\n const url = 'https://api.example.com'\n expect(getPathFromUrl(url)).toBe('/')\n })\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OpenAPI, OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from '@scalar/openapi-types';
|
|
2
|
-
import { type HttpMethod } from '../types.
|
|
2
|
+
import { type HttpMethod } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Takes a dereferenced OpenAPI document and returns all operations.
|
|
5
5
|
* Ignores other attributes, like summary, parameters, etc.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getOperations.d.ts","sourceRoot":"","sources":["../../src/utils/getOperations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEvF,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,
|
|
1
|
+
{"version":3,"file":"getOperations.d.ts","sourceRoot":"","sources":["../../src/utils/getOperations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAEvF,OAAO,EAAE,KAAK,UAAU,EAAe,MAAM,SAAS,CAAA;AAEtD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,CAAC,EAAE,SAAS,CAAC,cAAc,GAAG,SAAS,CAAC,cAAc,GAAG,WAAW,CAAC,cAAc,GACtF,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC,CAUvC"}
|
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import { httpMethods } from
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Takes a dereferenced OpenAPI document and returns all operations.
|
|
5
|
-
* Ignores other attributes, like summary, parameters, etc.
|
|
6
|
-
*/
|
|
1
|
+
import { httpMethods } from "../types.js";
|
|
7
2
|
function getOperations(path) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
3
|
+
const operations = {};
|
|
4
|
+
for (const method of httpMethods) {
|
|
5
|
+
if (path?.[method]) {
|
|
6
|
+
operations[method] = path?.[method];
|
|
13
7
|
}
|
|
14
|
-
|
|
8
|
+
}
|
|
9
|
+
return operations;
|
|
15
10
|
}
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
export {
|
|
12
|
+
getOperations
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=getOperations.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/getOperations.ts"],
|
|
4
|
+
"sourcesContent": ["import type { OpenAPI, OpenAPIV2, OpenAPIV3, OpenAPIV3_1 } from '@scalar/openapi-types'\n\nimport { type HttpMethod, httpMethods } from '@/types'\n\n/**\n * Takes a dereferenced OpenAPI document and returns all operations.\n * Ignores other attributes, like summary, parameters, etc.\n */\nexport function getOperations(\n path?: OpenAPIV2.PathItemObject | OpenAPIV3.PathItemObject | OpenAPIV3_1.PathItemObject,\n): Record<HttpMethod, OpenAPI.Operation> {\n const operations = {} as Record<HttpMethod, OpenAPI.Operation>\n\n for (const method of httpMethods) {\n if (path?.[method]) {\n operations[method] = path?.[method]\n }\n }\n\n return operations\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAA0B,mBAAmB;AAMtC,SAAS,cACd,MACuC;AACvC,QAAM,aAAa,CAAC;AAEpB,aAAW,UAAU,aAAa;AAChC,QAAI,OAAO,MAAM,GAAG;AAClB,iBAAW,MAAM,IAAI,OAAO,MAAM;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,109 +1,103 @@
|
|
|
1
|
-
import { getCookie } from
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Handles authentication for incoming requests based on the OpenAPI specification.
|
|
5
|
-
*/
|
|
1
|
+
import { getCookie } from "hono/cookie";
|
|
6
2
|
function handleAuthentication(schema, operation) {
|
|
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
|
-
break;
|
|
34
|
-
case 'apiKey':
|
|
35
|
-
authScheme = `ApiKey ${scheme.name}`;
|
|
36
|
-
if (scheme.in === 'header') {
|
|
37
|
-
const apiKey = c.req.header(scheme.name);
|
|
38
|
-
if (apiKey) {
|
|
39
|
-
isAuthenticated = true;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
else if (scheme.in === 'query') {
|
|
43
|
-
const apiKey = c.req.query(scheme.name);
|
|
44
|
-
if (apiKey) {
|
|
45
|
-
isAuthenticated = true;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
else if (scheme.in === 'cookie') {
|
|
49
|
-
const apiKey = getCookie(c, scheme.name);
|
|
50
|
-
if (apiKey) {
|
|
51
|
-
isAuthenticated = true;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
break;
|
|
55
|
-
case 'oauth2':
|
|
56
|
-
authScheme = 'Bearer';
|
|
57
|
-
// Handle OAuth 2.0 flows, including password grant
|
|
58
|
-
if (c.req.header('Authorization')?.startsWith('Bearer ')) {
|
|
59
|
-
isAuthenticated = true;
|
|
60
|
-
}
|
|
61
|
-
break;
|
|
62
|
-
case 'openIdConnect':
|
|
63
|
-
authScheme = 'Bearer';
|
|
64
|
-
// Handle OpenID Connect similar to OAuth2
|
|
65
|
-
if (c.req.header('Authorization')?.startsWith('Bearer ')) {
|
|
66
|
-
isAuthenticated = true;
|
|
67
|
-
}
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (!isAuthenticated) {
|
|
72
|
-
securitySchemeAuthenticated = false;
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
3
|
+
return async (c, next) => {
|
|
4
|
+
const operationSecuritySchemes = operation?.security || schema?.security;
|
|
5
|
+
if (operationSecuritySchemes && operationSecuritySchemes.length > 0) {
|
|
6
|
+
let isAuthenticated = false;
|
|
7
|
+
let authScheme = "";
|
|
8
|
+
for (const securityRequirement of operationSecuritySchemes) {
|
|
9
|
+
let securitySchemeAuthenticated = true;
|
|
10
|
+
for (const [schemeName] of Object.entries(securityRequirement)) {
|
|
11
|
+
const scheme = schema?.components?.securitySchemes?.[schemeName];
|
|
12
|
+
if (scheme) {
|
|
13
|
+
switch (scheme.type) {
|
|
14
|
+
case "http":
|
|
15
|
+
if (scheme.scheme === "basic") {
|
|
16
|
+
authScheme = "Basic";
|
|
17
|
+
const authHeader = c.req.header("Authorization");
|
|
18
|
+
if (authHeader?.startsWith("Basic ")) {
|
|
19
|
+
isAuthenticated = true;
|
|
20
|
+
}
|
|
21
|
+
} else if (scheme.scheme === "bearer") {
|
|
22
|
+
authScheme = "Bearer";
|
|
23
|
+
const authHeader = c.req.header("Authorization");
|
|
24
|
+
if (authHeader?.startsWith("Bearer ")) {
|
|
25
|
+
isAuthenticated = true;
|
|
26
|
+
}
|
|
75
27
|
}
|
|
76
|
-
|
|
28
|
+
break;
|
|
29
|
+
case "apiKey":
|
|
30
|
+
authScheme = `ApiKey ${scheme.name}`;
|
|
31
|
+
if (scheme.in === "header") {
|
|
32
|
+
const apiKey = c.req.header(scheme.name);
|
|
33
|
+
if (apiKey) {
|
|
34
|
+
isAuthenticated = true;
|
|
35
|
+
}
|
|
36
|
+
} else if (scheme.in === "query") {
|
|
37
|
+
const apiKey = c.req.query(scheme.name);
|
|
38
|
+
if (apiKey) {
|
|
39
|
+
isAuthenticated = true;
|
|
40
|
+
}
|
|
41
|
+
} else if (scheme.in === "cookie") {
|
|
42
|
+
const apiKey = getCookie(c, scheme.name);
|
|
43
|
+
if (apiKey) {
|
|
77
44
|
isAuthenticated = true;
|
|
78
|
-
|
|
45
|
+
}
|
|
79
46
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
case 'ApiKey':
|
|
92
|
-
wwwAuthenticateValue += ` realm="Scalar Mock Server", error="invalid_token", error_description="Invalid or missing API key"`;
|
|
93
|
-
break;
|
|
94
|
-
default:
|
|
95
|
-
wwwAuthenticateValue = 'Bearer realm="Scalar Mock Server"';
|
|
47
|
+
break;
|
|
48
|
+
case "oauth2":
|
|
49
|
+
authScheme = "Bearer";
|
|
50
|
+
if (c.req.header("Authorization")?.startsWith("Bearer ")) {
|
|
51
|
+
isAuthenticated = true;
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
case "openIdConnect":
|
|
55
|
+
authScheme = "Bearer";
|
|
56
|
+
if (c.req.header("Authorization")?.startsWith("Bearer ")) {
|
|
57
|
+
isAuthenticated = true;
|
|
96
58
|
}
|
|
97
|
-
|
|
98
|
-
return c.json({
|
|
99
|
-
error: 'Unauthorized',
|
|
100
|
-
message: 'Authentication is required to access this resource.',
|
|
101
|
-
}, 401);
|
|
59
|
+
break;
|
|
102
60
|
}
|
|
61
|
+
}
|
|
62
|
+
if (!isAuthenticated) {
|
|
63
|
+
securitySchemeAuthenticated = false;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (securitySchemeAuthenticated) {
|
|
68
|
+
isAuthenticated = true;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!isAuthenticated) {
|
|
73
|
+
let wwwAuthenticateValue = authScheme;
|
|
74
|
+
switch (authScheme) {
|
|
75
|
+
case "Basic":
|
|
76
|
+
wwwAuthenticateValue += ' realm="Scalar Mock Server", charset="UTF-8"';
|
|
77
|
+
break;
|
|
78
|
+
case "Bearer":
|
|
79
|
+
wwwAuthenticateValue += ' realm="Scalar Mock Server", error="invalid_token", error_description="The access token is invalid or has expired"';
|
|
80
|
+
break;
|
|
81
|
+
case "ApiKey":
|
|
82
|
+
wwwAuthenticateValue += ` realm="Scalar Mock Server", error="invalid_token", error_description="Invalid or missing API key"`;
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
wwwAuthenticateValue = 'Bearer realm="Scalar Mock Server"';
|
|
103
86
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
87
|
+
c.header("WWW-Authenticate", wwwAuthenticateValue);
|
|
88
|
+
return c.json(
|
|
89
|
+
{
|
|
90
|
+
error: "Unauthorized",
|
|
91
|
+
message: "Authentication is required to access this resource."
|
|
92
|
+
},
|
|
93
|
+
401
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
await next();
|
|
98
|
+
};
|
|
107
99
|
}
|
|
108
|
-
|
|
109
|
-
|
|
100
|
+
export {
|
|
101
|
+
handleAuthentication
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=handleAuthentication.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/handleAuthentication.ts"],
|
|
4
|
+
"sourcesContent": ["import type { OpenAPI } from '@scalar/openapi-types'\nimport type { Context } from 'hono'\nimport { getCookie } from 'hono/cookie'\n\n/**\n * Handles authentication for incoming requests based on the OpenAPI specification.\n */\nexport function handleAuthentication(schema?: OpenAPI.Document, operation?: OpenAPI.Operation) {\n return async (c: Context, next: () => Promise<void>): Promise<Response | void> => {\n const operationSecuritySchemes = operation?.security || schema?.security\n\n if (operationSecuritySchemes && operationSecuritySchemes.length > 0) {\n let isAuthenticated = false\n let authScheme = ''\n\n for (const securityRequirement of operationSecuritySchemes) {\n let securitySchemeAuthenticated = true\n\n for (const [schemeName] of Object.entries(securityRequirement)) {\n const scheme = schema?.components?.securitySchemes?.[schemeName]\n\n if (scheme) {\n switch (scheme.type) {\n case 'http':\n if (scheme.scheme === 'basic') {\n authScheme = 'Basic'\n const authHeader = c.req.header('Authorization')\n\n if (authHeader?.startsWith('Basic ')) {\n isAuthenticated = true\n }\n } else if (scheme.scheme === 'bearer') {\n authScheme = 'Bearer'\n const authHeader = c.req.header('Authorization')\n\n if (authHeader?.startsWith('Bearer ')) {\n isAuthenticated = true\n }\n }\n break\n case 'apiKey':\n authScheme = `ApiKey ${scheme.name}`\n\n if (scheme.in === 'header') {\n const apiKey = c.req.header(scheme.name)\n if (apiKey) {\n isAuthenticated = true\n }\n } else if (scheme.in === 'query') {\n const apiKey = c.req.query(scheme.name)\n\n if (apiKey) {\n isAuthenticated = true\n }\n } else if (scheme.in === 'cookie') {\n const apiKey = getCookie(c, scheme.name)\n\n if (apiKey) {\n isAuthenticated = true\n }\n }\n break\n case 'oauth2':\n authScheme = 'Bearer'\n // Handle OAuth 2.0 flows, including password grant\n if (c.req.header('Authorization')?.startsWith('Bearer ')) {\n isAuthenticated = true\n }\n break\n case 'openIdConnect':\n authScheme = 'Bearer'\n // Handle OpenID Connect similar to OAuth2\n if (c.req.header('Authorization')?.startsWith('Bearer ')) {\n isAuthenticated = true\n }\n break\n }\n }\n\n if (!isAuthenticated) {\n securitySchemeAuthenticated = false\n break\n }\n }\n\n if (securitySchemeAuthenticated) {\n isAuthenticated = true\n break\n }\n }\n\n if (!isAuthenticated) {\n let wwwAuthenticateValue = authScheme\n\n switch (authScheme) {\n case 'Basic':\n wwwAuthenticateValue += ' realm=\"Scalar Mock Server\", charset=\"UTF-8\"'\n break\n case 'Bearer':\n wwwAuthenticateValue +=\n ' realm=\"Scalar Mock Server\", error=\"invalid_token\", error_description=\"The access token is invalid or has expired\"'\n break\n case 'ApiKey':\n wwwAuthenticateValue += ` realm=\"Scalar Mock Server\", error=\"invalid_token\", error_description=\"Invalid or missing API key\"`\n break\n default:\n wwwAuthenticateValue = 'Bearer realm=\"Scalar Mock Server\"'\n }\n\n c.header('WWW-Authenticate', wwwAuthenticateValue)\n return c.json(\n {\n error: 'Unauthorized',\n message: 'Authentication is required to access this resource.',\n },\n 401,\n )\n }\n }\n\n // If all checks pass, continue to the next middleware\n await next()\n }\n}\n"],
|
|
5
|
+
"mappings": "AAEA,SAAS,iBAAiB;AAKnB,SAAS,qBAAqB,QAA2B,WAA+B;AAC7F,SAAO,OAAO,GAAY,SAAwD;AAChF,UAAM,2BAA2B,WAAW,YAAY,QAAQ;AAEhE,QAAI,4BAA4B,yBAAyB,SAAS,GAAG;AACnE,UAAI,kBAAkB;AACtB,UAAI,aAAa;AAEjB,iBAAW,uBAAuB,0BAA0B;AAC1D,YAAI,8BAA8B;AAElC,mBAAW,CAAC,UAAU,KAAK,OAAO,QAAQ,mBAAmB,GAAG;AAC9D,gBAAM,SAAS,QAAQ,YAAY,kBAAkB,UAAU;AAE/D,cAAI,QAAQ;AACV,oBAAQ,OAAO,MAAM;AAAA,cACnB,KAAK;AACH,oBAAI,OAAO,WAAW,SAAS;AAC7B,+BAAa;AACb,wBAAM,aAAa,EAAE,IAAI,OAAO,eAAe;AAE/C,sBAAI,YAAY,WAAW,QAAQ,GAAG;AACpC,sCAAkB;AAAA,kBACpB;AAAA,gBACF,WAAW,OAAO,WAAW,UAAU;AACrC,+BAAa;AACb,wBAAM,aAAa,EAAE,IAAI,OAAO,eAAe;AAE/C,sBAAI,YAAY,WAAW,SAAS,GAAG;AACrC,sCAAkB;AAAA,kBACpB;AAAA,gBACF;AACA;AAAA,cACF,KAAK;AACH,6BAAa,UAAU,OAAO,IAAI;AAElC,oBAAI,OAAO,OAAO,UAAU;AAC1B,wBAAM,SAAS,EAAE,IAAI,OAAO,OAAO,IAAI;AACvC,sBAAI,QAAQ;AACV,sCAAkB;AAAA,kBACpB;AAAA,gBACF,WAAW,OAAO,OAAO,SAAS;AAChC,wBAAM,SAAS,EAAE,IAAI,MAAM,OAAO,IAAI;AAEtC,sBAAI,QAAQ;AACV,sCAAkB;AAAA,kBACpB;AAAA,gBACF,WAAW,OAAO,OAAO,UAAU;AACjC,wBAAM,SAAS,UAAU,GAAG,OAAO,IAAI;AAEvC,sBAAI,QAAQ;AACV,sCAAkB;AAAA,kBACpB;AAAA,gBACF;AACA;AAAA,cACF,KAAK;AACH,6BAAa;AAEb,oBAAI,EAAE,IAAI,OAAO,eAAe,GAAG,WAAW,SAAS,GAAG;AACxD,oCAAkB;AAAA,gBACpB;AACA;AAAA,cACF,KAAK;AACH,6BAAa;AAEb,oBAAI,EAAE,IAAI,OAAO,eAAe,GAAG,WAAW,SAAS,GAAG;AACxD,oCAAkB;AAAA,gBACpB;AACA;AAAA,YACJ;AAAA,UACF;AAEA,cAAI,CAAC,iBAAiB;AACpB,0CAA8B;AAC9B;AAAA,UACF;AAAA,QACF;AAEA,YAAI,6BAA6B;AAC/B,4BAAkB;AAClB;AAAA,QACF;AAAA,MACF;AAEA,UAAI,CAAC,iBAAiB;AACpB,YAAI,uBAAuB;AAE3B,gBAAQ,YAAY;AAAA,UAClB,KAAK;AACH,oCAAwB;AACxB;AAAA,UACF,KAAK;AACH,oCACE;AACF;AAAA,UACF,KAAK;AACH,oCAAwB;AACxB;AAAA,UACF;AACE,mCAAuB;AAAA,QAC3B;AAEA,UAAE,OAAO,oBAAoB,oBAAoB;AACjD,eAAO,EAAE;AAAA,UACP;AAAA,YACE,OAAO;AAAA,YACP,SAAS;AAAA,UACX;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,UAAM,KAAK;AAAA,EACb;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Convert path to route
|
|
3
|
-
* Example: /posts/{id} -> /posts/:id
|
|
4
|
-
*/
|
|
5
1
|
function honoRouteFromPath(path) {
|
|
6
|
-
|
|
2
|
+
return path.replace(/{/g, ":").replace(/}/g, "");
|
|
7
3
|
}
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
export {
|
|
5
|
+
honoRouteFromPath
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=honoRouteFromPath.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/honoRouteFromPath.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Convert path to route\n * Example: /posts/{id} -> /posts/:id\n */\nexport function honoRouteFromPath(path: string) {\n return path.replace(/{/g, ':').replace(/}/g, '')\n}\n"],
|
|
5
|
+
"mappings": "AAIO,SAAS,kBAAkB,MAAc;AAC9C,SAAO,KAAK,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,EAAE;AACjD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { honoRouteFromPath } from "./honoRouteFromPath.js";
|
|
3
|
+
describe("honoRouteFromPath", () => {
|
|
4
|
+
it("returns correct route for a simple path", () => {
|
|
5
|
+
expect(honoRouteFromPath("/foobar")).toBe("/foobar");
|
|
6
|
+
});
|
|
7
|
+
it("returns correct route for a path with an ID", () => {
|
|
8
|
+
expect(honoRouteFromPath("/foobar/{id}")).toBe("/foobar/:id");
|
|
9
|
+
});
|
|
10
|
+
it("returns correct route for a path with multiple parameters", () => {
|
|
11
|
+
expect(honoRouteFromPath("/users/{userId}/posts/{postId}")).toBe("/users/:userId/posts/:postId");
|
|
12
|
+
});
|
|
13
|
+
it("returns correct route for a path with a parameter in the middle", () => {
|
|
14
|
+
expect(honoRouteFromPath("/api/{version}/users")).toBe("/api/:version/users");
|
|
15
|
+
});
|
|
16
|
+
it("returns correct route for a path with special characters", () => {
|
|
17
|
+
expect(honoRouteFromPath("/items/{item-id}")).toBe("/items/:item-id");
|
|
18
|
+
});
|
|
19
|
+
it("returns correct route for a path with numbers", () => {
|
|
20
|
+
expect(honoRouteFromPath("/v1/products/{productId}")).toBe("/v1/products/:productId");
|
|
21
|
+
});
|
|
22
|
+
it.skip("handles invalid parameter syntax gracefully", () => {
|
|
23
|
+
expect(() => honoRouteFromPath("/{invalid{}param}")).toThrow();
|
|
24
|
+
});
|
|
25
|
+
it("handles multiple consecutive parameters", () => {
|
|
26
|
+
expect(honoRouteFromPath("/users/{userId}{postId}")).toBe("/users/:userId:postId");
|
|
27
|
+
});
|
|
28
|
+
it("handles parameters with special naming patterns", () => {
|
|
29
|
+
expect(honoRouteFromPath("/api/{api.version}/{user_id}")).toBe("/api/:api.version/:user_id");
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=honoRouteFromPath.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/utils/honoRouteFromPath.test.ts"],
|
|
4
|
+
"sourcesContent": ["import { describe, expect, it } from 'vitest'\n\nimport { honoRouteFromPath } from './honoRouteFromPath'\n\ndescribe('honoRouteFromPath', () => {\n it('returns correct route for a simple path', () => {\n expect(honoRouteFromPath('/foobar')).toBe('/foobar')\n })\n\n it('returns correct route for a path with an ID', () => {\n expect(honoRouteFromPath('/foobar/{id}')).toBe('/foobar/:id')\n })\n\n it('returns correct route for a path with multiple parameters', () => {\n expect(honoRouteFromPath('/users/{userId}/posts/{postId}')).toBe('/users/:userId/posts/:postId')\n })\n\n it('returns correct route for a path with a parameter in the middle', () => {\n expect(honoRouteFromPath('/api/{version}/users')).toBe('/api/:version/users')\n })\n\n it('returns correct route for a path with special characters', () => {\n expect(honoRouteFromPath('/items/{item-id}')).toBe('/items/:item-id')\n })\n\n it('returns correct route for a path with numbers', () => {\n expect(honoRouteFromPath('/v1/products/{productId}')).toBe('/v1/products/:productId')\n })\n\n it.skip('handles invalid parameter syntax gracefully', () => {\n expect(() => honoRouteFromPath('/{invalid{}param}')).toThrow()\n })\n\n it('handles multiple consecutive parameters', () => {\n expect(honoRouteFromPath('/users/{userId}{postId}')).toBe('/users/:userId:postId')\n })\n\n it('handles parameters with special naming patterns', () => {\n expect(honoRouteFromPath('/api/{api.version}/{user_id}')).toBe('/api/:api.version/:user_id')\n })\n})\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AAErC,SAAS,yBAAyB;AAElC,SAAS,qBAAqB,MAAM;AAClC,KAAG,2CAA2C,MAAM;AAClD,WAAO,kBAAkB,SAAS,CAAC,EAAE,KAAK,SAAS;AAAA,EACrD,CAAC;AAED,KAAG,+CAA+C,MAAM;AACtD,WAAO,kBAAkB,cAAc,CAAC,EAAE,KAAK,aAAa;AAAA,EAC9D,CAAC;AAED,KAAG,6DAA6D,MAAM;AACpE,WAAO,kBAAkB,gCAAgC,CAAC,EAAE,KAAK,8BAA8B;AAAA,EACjG,CAAC;AAED,KAAG,mEAAmE,MAAM;AAC1E,WAAO,kBAAkB,sBAAsB,CAAC,EAAE,KAAK,qBAAqB;AAAA,EAC9E,CAAC;AAED,KAAG,4DAA4D,MAAM;AACnE,WAAO,kBAAkB,kBAAkB,CAAC,EAAE,KAAK,iBAAiB;AAAA,EACtE,CAAC;AAED,KAAG,iDAAiD,MAAM;AACxD,WAAO,kBAAkB,0BAA0B,CAAC,EAAE,KAAK,yBAAyB;AAAA,EACtF,CAAC;AAED,KAAG,KAAK,+CAA+C,MAAM;AAC3D,WAAO,MAAM,kBAAkB,mBAAmB,CAAC,EAAE,QAAQ;AAAA,EAC/D,CAAC;AAED,KAAG,2CAA2C,MAAM;AAClD,WAAO,kBAAkB,yBAAyB,CAAC,EAAE,KAAK,uBAAuB;AAAA,EACnF,CAAC;AAED,KAAG,mDAAmD,MAAM;AAC1D,WAAO,kBAAkB,8BAA8B,CAAC,EAAE,KAAK,4BAA4B;AAAA,EAC7F,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Check whether the given security scheme key is in the `security` configuration for this operation.
|
|
3
|
-
*/
|
|
4
1
|
function isAuthenticationRequired(security) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
return true;
|
|
2
|
+
if (!security) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
5
|
+
if (Array.isArray(security) && !security.length) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if ((security ?? []).some((securityRequirement) => !Object.keys(securityRequirement).length)) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return true;
|
|
18
12
|
}
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
export {
|
|
14
|
+
isAuthenticationRequired
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=isAuthenticationRequired.js.map
|