@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.
Files changed (52) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/createMockServer.d.ts +1 -1
  3. package/dist/createMockServer.d.ts.map +1 -1
  4. package/dist/createMockServer.js +36 -48
  5. package/dist/createMockServer.js.map +7 -0
  6. package/dist/createMockServer.test.js +598 -0
  7. package/dist/createMockServer.test.js.map +7 -0
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +5 -1
  11. package/dist/index.js.map +7 -0
  12. package/dist/routes/mockAnyResponse.d.ts +1 -1
  13. package/dist/routes/mockAnyResponse.d.ts.map +1 -1
  14. package/dist/routes/mockAnyResponse.js +56 -64
  15. package/dist/routes/mockAnyResponse.js.map +7 -0
  16. package/dist/routes/respondWithAuthorizePage.js +39 -31
  17. package/dist/routes/respondWithAuthorizePage.js.map +7 -0
  18. package/dist/routes/respondWithOpenApiDocument.js +35 -35
  19. package/dist/routes/respondWithOpenApiDocument.js.map +7 -0
  20. package/dist/routes/respondWithToken.js +44 -41
  21. package/dist/routes/respondWithToken.js.map +7 -0
  22. package/dist/types.js +5 -4
  23. package/dist/types.js.map +7 -0
  24. package/dist/utils/createOpenApiDefinition.js +11 -0
  25. package/dist/utils/createOpenApiDefinition.js.map +7 -0
  26. package/dist/utils/findPreferredResponseKey.js +8 -10
  27. package/dist/utils/findPreferredResponseKey.js.map +7 -0
  28. package/dist/utils/findPreferredResponseKey.test.js +20 -0
  29. package/dist/utils/findPreferredResponseKey.test.js.map +7 -0
  30. package/dist/utils/getOpenAuthTokenUrls.js +33 -45
  31. package/dist/utils/getOpenAuthTokenUrls.js.map +7 -0
  32. package/dist/utils/getOpenAuthTokenUrls.test.js +127 -0
  33. package/dist/utils/getOpenAuthTokenUrls.test.js.map +7 -0
  34. package/dist/utils/getOperations.d.ts +1 -1
  35. package/dist/utils/getOperations.d.ts.map +1 -1
  36. package/dist/utils/getOperations.js +11 -14
  37. package/dist/utils/getOperations.js.map +7 -0
  38. package/dist/utils/handleAuthentication.js +95 -101
  39. package/dist/utils/handleAuthentication.js.map +7 -0
  40. package/dist/utils/honoRouteFromPath.js +5 -7
  41. package/dist/utils/honoRouteFromPath.js.map +7 -0
  42. package/dist/utils/honoRouteFromPath.test.js +32 -0
  43. package/dist/utils/honoRouteFromPath.test.js.map +7 -0
  44. package/dist/utils/isAuthenticationRequired.js +14 -18
  45. package/dist/utils/isAuthenticationRequired.js.map +7 -0
  46. package/dist/utils/isAuthenticationRequired.test.js +23 -0
  47. package/dist/utils/isAuthenticationRequired.test.js.map +7 -0
  48. package/dist/utils/logAuthenticationInstructions.js +109 -107
  49. package/dist/utils/logAuthenticationInstructions.js.map +7 -0
  50. package/dist/utils/setupAuthenticationRoutes.js +76 -82
  51. package/dist/utils/setupAuthenticationRoutes.js.map +7 -0
  52. package/package.json +7 -9
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/isAuthenticationRequired.ts"],
4
+ "sourcesContent": ["import type { OpenAPIV3 } from '@scalar/openapi-types'\n\n/**\n * Check whether the given security scheme key is in the `security` configuration for this operation.\n */\nexport function isAuthenticationRequired(security?: OpenAPIV3.SecurityRequirementObject[]): boolean {\n // If security is not defined, auth is not required.\n if (!security) {\n return false\n }\n\n // Don\u2019t require auth if security is just an empty array []\n if (Array.isArray(security) && !security.length) {\n return false\n }\n\n // Includes empty object = auth is not required\n if ((security ?? []).some((securityRequirement) => !Object.keys(securityRequirement).length)) {\n return false\n }\n\n return true\n}\n"],
5
+ "mappings": "AAKO,SAAS,yBAAyB,UAA2D;AAElG,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAGA,MAAI,MAAM,QAAQ,QAAQ,KAAK,CAAC,SAAS,QAAQ;AAC/C,WAAO;AAAA,EACT;AAGA,OAAK,YAAY,CAAC,GAAG,KAAK,CAAC,wBAAwB,CAAC,OAAO,KAAK,mBAAmB,EAAE,MAAM,GAAG;AAC5F,WAAO;AAAA,EACT;AAEA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,23 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { isAuthenticationRequired } from "./isAuthenticationRequired.js";
3
+ describe("isAuthenticationRequired", () => {
4
+ it("returns false when security is undefined", () => {
5
+ expect(isAuthenticationRequired(void 0)).toBe(false);
6
+ });
7
+ it("returns false when security is an empty array", () => {
8
+ expect(isAuthenticationRequired([])).toBe(false);
9
+ });
10
+ it("returns false when security includes an empty object", () => {
11
+ expect(isAuthenticationRequired([{}])).toBe(false);
12
+ });
13
+ it("returns true when security is defined and not empty", () => {
14
+ expect(isAuthenticationRequired([{ apiKey: [] }])).toBe(true);
15
+ });
16
+ it("returns true when security has multiple schemes", () => {
17
+ expect(isAuthenticationRequired([{ apiKey: [] }, { oauth2: ["read", "write"] }])).toBe(true);
18
+ });
19
+ it("returns false when security is an array with an empty object among non-empty objects", () => {
20
+ expect(isAuthenticationRequired([{ apiKey: [] }, {}, { oauth2: ["read"] }])).toBe(false);
21
+ });
22
+ });
23
+ //# sourceMappingURL=isAuthenticationRequired.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/isAuthenticationRequired.test.ts"],
4
+ "sourcesContent": ["import { describe, expect, it } from 'vitest'\n\nimport { isAuthenticationRequired } from './isAuthenticationRequired'\n\ndescribe('isAuthenticationRequired', () => {\n it('returns false when security is undefined', () => {\n expect(isAuthenticationRequired(undefined)).toBe(false)\n })\n\n it('returns false when security is an empty array', () => {\n expect(isAuthenticationRequired([])).toBe(false)\n })\n\n it('returns false when security includes an empty object', () => {\n expect(isAuthenticationRequired([{}])).toBe(false)\n })\n\n it('returns true when security is defined and not empty', () => {\n expect(isAuthenticationRequired([{ apiKey: [] }])).toBe(true)\n })\n\n it('returns true when security has multiple schemes', () => {\n expect(isAuthenticationRequired([{ apiKey: [] }, { oauth2: ['read', 'write'] }])).toBe(true)\n })\n\n it('returns false when security is an array with an empty object among non-empty objects', () => {\n expect(isAuthenticationRequired([{ apiKey: [] }, {}, { oauth2: ['read'] }])).toBe(false)\n })\n})\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,QAAQ,UAAU;AAErC,SAAS,gCAAgC;AAEzC,SAAS,4BAA4B,MAAM;AACzC,KAAG,4CAA4C,MAAM;AACnD,WAAO,yBAAyB,MAAS,CAAC,EAAE,KAAK,KAAK;AAAA,EACxD,CAAC;AAED,KAAG,iDAAiD,MAAM;AACxD,WAAO,yBAAyB,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK;AAAA,EACjD,CAAC;AAED,KAAG,wDAAwD,MAAM;AAC/D,WAAO,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK;AAAA,EACnD,CAAC;AAED,KAAG,uDAAuD,MAAM;AAC9D,WAAO,yBAAyB,CAAC,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAAA,EAC9D,CAAC;AAED,KAAG,mDAAmD,MAAM;AAC1D,WAAO,yBAAyB,CAAC,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,QAAQ,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAAA,EAC7F,CAAC;AAED,KAAG,wFAAwF,MAAM;AAC/F,WAAO,yBAAyB,CAAC,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK;AAAA,EACzF,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
@@ -1,116 +1,118 @@
1
- import { getPathFromUrl } from './getOpenAuthTokenUrls.js';
2
-
3
- /**
4
- * Log authentication instructions for different security schemes
5
- */
1
+ import { getPathFromUrl } from "./getOpenAuthTokenUrls.js";
6
2
  function logAuthenticationInstructions(securitySchemes) {
7
- if (!securitySchemes || Object.keys(securitySchemes).length === 0) {
8
- return;
9
- }
10
- console.log('Authentication:');
11
- console.log();
12
- Object.entries(securitySchemes).forEach(([_, scheme]) => {
13
- switch (scheme.type) {
14
- case 'apiKey':
15
- if (scheme.in === 'header') {
16
- console.log('✅ API Key Authentication');
17
- console.log(` Use any API key in the ${scheme.name} header`);
18
- console.log();
19
- console.log(` ${scheme.name}: YOUR_API_KEY_HERE`);
20
- console.log();
21
- }
22
- else if (scheme.in === 'query') {
23
- console.log('✅ API Key Authentication');
24
- console.log(` Use any API key in the ${scheme.name} query parameter:`);
25
- console.log();
26
- console.log(` ?${scheme.name}=YOUR_API_KEY_HERE`);
27
- console.log();
28
- }
29
- else if (scheme.in === 'cookie') {
30
- console.log('✅ API Key Authentication');
31
- console.log(` Use any API key in the ${scheme.name} cookie:`);
32
- console.log();
33
- console.log(` Cookie: ${scheme.name}=YOUR_API_KEY_HERE`);
34
- console.log();
35
- }
36
- else {
37
- console.error(`❌ Unsupported API Key Location: ${scheme.in}`);
38
- }
3
+ if (!securitySchemes || Object.keys(securitySchemes).length === 0) {
4
+ return;
5
+ }
6
+ console.log("Authentication:");
7
+ console.log();
8
+ Object.entries(securitySchemes).forEach(([_, scheme]) => {
9
+ switch (scheme.type) {
10
+ case "apiKey":
11
+ if (scheme.in === "header") {
12
+ console.log("\u2705 API Key Authentication");
13
+ console.log(` Use any API key in the ${scheme.name} header`);
14
+ console.log();
15
+ console.log(` ${scheme.name}: YOUR_API_KEY_HERE`);
16
+ console.log();
17
+ } else if (scheme.in === "query") {
18
+ console.log("\u2705 API Key Authentication");
19
+ console.log(` Use any API key in the ${scheme.name} query parameter:`);
20
+ console.log();
21
+ console.log(` ?${scheme.name}=YOUR_API_KEY_HERE`);
22
+ console.log();
23
+ } else if (scheme.in === "cookie") {
24
+ console.log("\u2705 API Key Authentication");
25
+ console.log(` Use any API key in the ${scheme.name} cookie:`);
26
+ console.log();
27
+ console.log(` Cookie: ${scheme.name}=YOUR_API_KEY_HERE`);
28
+ console.log();
29
+ } else {
30
+ console.error(`\u274C Unsupported API Key Location: ${scheme.in}`);
31
+ }
32
+ break;
33
+ case "http":
34
+ if (scheme.scheme === "basic") {
35
+ console.log("\u2705 HTTP Basic Authentication");
36
+ console.log(' Use an Authorization header with any credentials ("username:password" in base64):');
37
+ console.log();
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();
39
62
  break;
40
- case 'http':
41
- if (scheme.scheme === 'basic') {
42
- console.log('✅ HTTP Basic Authentication');
43
- console.log(' Use an Authorization header with any credentials ("username:password" in base64):');
44
- console.log();
45
- console.log(' Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=');
46
- console.log();
47
- }
48
- else if (scheme.scheme === 'bearer') {
49
- console.log('✅ Bearer Token Authentication');
50
- console.log(' Use an Authorization header with any bearer token');
51
- console.log();
52
- console.log(' Authorization: Bearer YOUR_TOKEN_HERE');
53
- console.log();
54
- }
55
- else {
56
- console.error('❌ Unknown Security Scheme:', scheme);
57
- }
63
+ case "password":
64
+ console.log("\u2705 OAuth 2.0 Password Flow");
65
+ console.log(" Use the following URL to obtain an access token:");
66
+ console.log();
67
+ console.log(` POST ${getPathFromUrl(scheme?.flows?.password?.tokenUrl || "/oauth/token")}`);
68
+ console.log(" Content-Type: application/x-www-form-urlencoded");
69
+ console.log();
70
+ console.log(
71
+ " grant_type=password&username=YOUR_USERNAME&password=YOUR_PASSWORD&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
72
+ );
73
+ console.log();
58
74
  break;
59
- case 'oauth2':
60
- if (scheme.flows) {
61
- Object.keys(scheme.flows).forEach((flow) => {
62
- switch (flow) {
63
- case 'implicit':
64
- console.log('✅ OAuth 2.0 Implicit Flow');
65
- console.log(' Use the following URL to initiate the OAuth 2.0 Implicit Flow:');
66
- console.log();
67
- 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`);
68
- console.log();
69
- break;
70
- case 'password':
71
- console.log('✅ OAuth 2.0 Password Flow');
72
- console.log(' Use the following URL to obtain an access token:');
73
- console.log();
74
- console.log(` POST ${getPathFromUrl(scheme?.flows?.password?.tokenUrl || '/oauth/token')}`);
75
- console.log(' Content-Type: application/x-www-form-urlencoded');
76
- console.log();
77
- console.log(' grant_type=password&username=YOUR_USERNAME&password=YOUR_PASSWORD&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET');
78
- console.log();
79
- break;
80
- case 'clientCredentials':
81
- console.log('✅ OAuth 2.0 Client Credentials Flow');
82
- console.log(' Use the following URL to obtain an access token:');
83
- console.log();
84
- console.log(` POST ${getPathFromUrl(scheme?.flows?.clientCredentials?.tokenUrl || '/oauth/token')}`);
85
- console.log(' Content-Type: application/x-www-form-urlencoded');
86
- console.log();
87
- console.log(' grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET');
88
- console.log();
89
- break;
90
- case 'authorizationCode':
91
- console.log('✅ OAuth 2.0 Authorization Code Flow');
92
- console.log(' Use the following URL to initiate the OAuth 2.0 Authorization Code Flow:');
93
- console.log();
94
- console.log(' GET', `${getPathFromUrl(scheme?.flows?.authorizationCode?.authorizationUrl || '/oauth/authorize')}?redirect_uri=https://YOUR_REDIRECT_URI_HERE`);
95
- console.log();
96
- break;
97
- default:
98
- console.warn(`Unsupported OAuth 2.0 flow: ${flow}`);
99
- }
100
- });
101
- }
75
+ case "clientCredentials":
76
+ console.log("\u2705 OAuth 2.0 Client Credentials Flow");
77
+ console.log(" Use the following URL to obtain an access token:");
78
+ console.log();
79
+ console.log(` POST ${getPathFromUrl(scheme?.flows?.clientCredentials?.tokenUrl || "/oauth/token")}`);
80
+ console.log(" Content-Type: application/x-www-form-urlencoded");
81
+ console.log();
82
+ console.log(
83
+ " grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET"
84
+ );
85
+ console.log();
102
86
  break;
103
- case 'openIdConnect':
104
- console.log('✅ OpenID Connect Authentication');
105
- console.log(' Use the following OpenID Connect discovery URL:');
87
+ case "authorizationCode":
88
+ console.log("\u2705 OAuth 2.0 Authorization Code Flow");
89
+ console.log(" Use the following URL to initiate the OAuth 2.0 Authorization Code Flow:");
106
90
  console.log();
107
- console.log(` ${getPathFromUrl(scheme.openIdConnectUrl || '/.well-known/openid-configuration')}`);
91
+ console.log(
92
+ " GET",
93
+ `${getPathFromUrl(scheme?.flows?.authorizationCode?.authorizationUrl || "/oauth/authorize")}?redirect_uri=https://YOUR_REDIRECT_URI_HERE`
94
+ );
108
95
  console.log();
109
96
  break;
110
- default:
111
- console.warn(`Unsupported security scheme type: ${scheme.type}`);
97
+ default:
98
+ console.warn(`Unsupported OAuth 2.0 flow: ${flow}`);
99
+ }
100
+ });
112
101
  }
113
- });
102
+ break;
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
+ });
114
114
  }
115
-
116
- export { logAuthenticationInstructions };
115
+ export {
116
+ logAuthenticationInstructions
117
+ };
118
+ //# sourceMappingURL=logAuthenticationInstructions.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/logAuthenticationInstructions.ts"],
4
+ "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\n\nimport { getPathFromUrl } from './getOpenAuthTokenUrls'\n\n/**\n * Log authentication instructions for different security schemes\n */\nexport function logAuthenticationInstructions(securitySchemes: Record<string, OpenAPIV3_1.SecuritySchemeObject>) {\n if (!securitySchemes || Object.keys(securitySchemes).length === 0) {\n return\n }\n\n console.log('Authentication:')\n console.log()\n\n Object.entries(securitySchemes).forEach(([_, scheme]) => {\n switch (scheme.type) {\n case 'apiKey':\n if (scheme.in === 'header') {\n console.log('\u2705 API Key Authentication')\n console.log(` Use any API key in the ${scheme.name} header`)\n console.log()\n console.log(` ${scheme.name}: YOUR_API_KEY_HERE`)\n console.log()\n } else if (scheme.in === 'query') {\n console.log('\u2705 API Key Authentication')\n console.log(` Use any API key in the ${scheme.name} query parameter:`)\n console.log()\n console.log(` ?${scheme.name}=YOUR_API_KEY_HERE`)\n console.log()\n } else if (scheme.in === 'cookie') {\n console.log('\u2705 API Key Authentication')\n console.log(` Use any API key in the ${scheme.name} cookie:`)\n console.log()\n console.log(` Cookie: ${scheme.name}=YOUR_API_KEY_HERE`)\n console.log()\n } else {\n console.error(`\u274C Unsupported API Key Location: ${scheme.in}`)\n }\n break\n case 'http':\n if (scheme.scheme === 'basic') {\n console.log('\u2705 HTTP Basic Authentication')\n console.log(' Use an Authorization header with any credentials (\"username:password\" in base64):')\n console.log()\n console.log(' Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=')\n console.log()\n } else if (scheme.scheme === 'bearer') {\n console.log('\u2705 Bearer Token Authentication')\n console.log(' Use an Authorization header with any bearer token')\n console.log()\n console.log(' Authorization: Bearer YOUR_TOKEN_HERE')\n console.log()\n } else {\n console.error('\u274C Unknown Security Scheme:', scheme)\n }\n\n break\n case 'oauth2':\n if (scheme.flows) {\n Object.keys(scheme.flows).forEach((flow) => {\n switch (flow) {\n case 'implicit':\n console.log('\u2705 OAuth 2.0 Implicit Flow')\n console.log(' Use the following URL to initiate the OAuth 2.0 Implicit Flow:')\n console.log()\n console.log(\n ` GET ${scheme?.flows?.implicit?.authorizationUrl || '/oauth/authorize'}?response_type=token&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=YOUR_SCOPES`,\n )\n console.log()\n break\n case 'password':\n console.log('\u2705 OAuth 2.0 Password Flow')\n console.log(' Use the following URL to obtain an access token:')\n console.log()\n console.log(` POST ${getPathFromUrl(scheme?.flows?.password?.tokenUrl || '/oauth/token')}`)\n console.log(' Content-Type: application/x-www-form-urlencoded')\n console.log()\n console.log(\n ' grant_type=password&username=YOUR_USERNAME&password=YOUR_PASSWORD&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET',\n )\n console.log()\n break\n case 'clientCredentials':\n console.log('\u2705 OAuth 2.0 Client Credentials Flow')\n console.log(' Use the following URL to obtain an access token:')\n console.log()\n console.log(` POST ${getPathFromUrl(scheme?.flows?.clientCredentials?.tokenUrl || '/oauth/token')}`)\n console.log(' Content-Type: application/x-www-form-urlencoded')\n console.log()\n console.log(\n ' grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET',\n )\n console.log()\n break\n case 'authorizationCode':\n console.log('\u2705 OAuth 2.0 Authorization Code Flow')\n console.log(' Use the following URL to initiate the OAuth 2.0 Authorization Code Flow:')\n console.log()\n console.log(\n ' GET',\n `${getPathFromUrl(scheme?.flows?.authorizationCode?.authorizationUrl || '/oauth/authorize')}?redirect_uri=https://YOUR_REDIRECT_URI_HERE`,\n )\n console.log()\n break\n default:\n console.warn(`Unsupported OAuth 2.0 flow: ${flow}`)\n }\n })\n }\n break\n case 'openIdConnect':\n console.log('\u2705 OpenID Connect Authentication')\n console.log(' Use the following OpenID Connect discovery URL:')\n console.log()\n console.log(` ${getPathFromUrl(scheme.openIdConnectUrl || '/.well-known/openid-configuration')}`)\n console.log()\n break\n default:\n console.warn(`Unsupported security scheme type: ${scheme.type}`)\n }\n })\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -1,86 +1,80 @@
1
- import { respondWithAuthorizePage } from '../routes/respondWithAuthorizePage.js';
2
- import { respondWithToken } from '../routes/respondWithToken.js';
3
- import { getOpenAuthTokenUrls, getPathFromUrl } from './getOpenAuthTokenUrls.js';
4
-
5
- /**
6
- * Helper function to set up authentication routes for OAuth 2.0 flows
7
- */
1
+ import { respondWithAuthorizePage } from "../routes/respondWithAuthorizePage.js";
2
+ import { respondWithToken } from "../routes/respondWithToken.js";
3
+ import { getOpenAuthTokenUrls, getPathFromUrl } from "./getOpenAuthTokenUrls.js";
8
4
  function setupAuthenticationRoutes(app, schema) {
9
- const securitySchemes = schema?.components?.securitySchemes || {};
10
- // Set up authentication routes for OAuth 2.0 flows
11
- getOpenAuthTokenUrls(schema).forEach((tokenUrl) => {
12
- app.post(tokenUrl, (c) => {
13
- return c.json({
14
- access_token: 'super-secret-access-token',
15
- token_type: 'Bearer',
16
- expires_in: 3600,
17
- refresh_token: 'example-refresh-token',
18
- }, 200, {
19
- /**
20
- * When responding with an access token, the server must also include the additional
21
- * Cache-Control: no-store HTTP header to ensure clients do not cache this request.
22
- *
23
- * @see https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/
24
- */
25
- 'Cache-Control': 'no-store',
26
- });
27
- });
28
- });
29
- // Set up routes for different OAuth 2.0 flows
30
- const authorizeUrls = new Set();
31
- const tokenUrls = new Set();
32
- Object.entries(securitySchemes).forEach(([_, scheme]) => {
33
- if (scheme.type === 'oauth2') {
34
- if (scheme.flows?.authorizationCode) {
35
- const authorizeRoute = scheme.flows.authorizationCode.authorizationUrl ?? '/oauth/authorize';
36
- const tokenRoute = scheme.flows.authorizationCode.tokenUrl ?? '/oauth/token';
37
- authorizeUrls.add(getPathFromUrl(authorizeRoute));
38
- tokenUrls.add(tokenRoute);
39
- }
40
- if (scheme.flows?.implicit) {
41
- const authorizeRoute = scheme.flows.implicit.authorizationUrl ?? '/oauth/authorize';
42
- authorizeUrls.add(getPathFromUrl(authorizeRoute));
43
- }
44
- if (scheme.flows?.password) {
45
- const tokenRoute = scheme.flows.password.tokenUrl ?? '/oauth/token';
46
- tokenUrls.add(tokenRoute);
47
- }
48
- if (scheme.flows?.clientCredentials) {
49
- const tokenRoute = scheme.flows.clientCredentials.tokenUrl ?? '/oauth/token';
50
- tokenUrls.add(tokenRoute);
51
- }
52
- }
53
- else if (scheme.type === 'openIdConnect') {
54
- // Handle OpenID Connect configuration
55
- if (scheme.openIdConnectUrl) {
56
- const configPath = getPathFromUrl(scheme.openIdConnectUrl ?? '/.well-known/openid-configuration');
57
- // Add route for OpenID Connect configuration
58
- app.get(configPath, (c) => {
59
- return c.json({
60
- issuer: 'https://example.com',
61
- authorization_endpoint: '/oauth/authorize',
62
- token_endpoint: '/oauth/token',
63
- response_types_supported: ['code', 'token', 'id_token'],
64
- subject_types_supported: ['public'],
65
- id_token_signing_alg_values_supported: ['RS256'],
66
- });
67
- });
68
- // Add standard endpoints
69
- const authorizeRoute = '/oauth/authorize';
70
- const tokenRoute = '/oauth/token';
71
- authorizeUrls.add(getPathFromUrl(authorizeRoute));
72
- tokenUrls.add(tokenRoute);
73
- }
5
+ const securitySchemes = schema?.components?.securitySchemes || {};
6
+ getOpenAuthTokenUrls(schema).forEach((tokenUrl) => {
7
+ app.post(tokenUrl, (c) => {
8
+ return c.json(
9
+ {
10
+ access_token: "super-secret-access-token",
11
+ token_type: "Bearer",
12
+ expires_in: 3600,
13
+ refresh_token: "example-refresh-token"
14
+ },
15
+ 200,
16
+ {
17
+ /**
18
+ * When responding with an access token, the server must also include the additional
19
+ * Cache-Control: no-store HTTP header to ensure clients do not cache this request.
20
+ *
21
+ * @see https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/
22
+ */
23
+ "Cache-Control": "no-store"
74
24
  }
25
+ );
75
26
  });
76
- // Set up unique authorization routes
77
- authorizeUrls.forEach((authorizeUrl) => {
78
- app.get(authorizeUrl, (c) => respondWithAuthorizePage(c, schema?.info?.title));
79
- });
80
- // Set up unique token routes
81
- tokenUrls.forEach((tokenUrl) => {
82
- app.post(tokenUrl, respondWithToken);
83
- });
27
+ });
28
+ const authorizeUrls = /* @__PURE__ */ new Set();
29
+ const tokenUrls = /* @__PURE__ */ new Set();
30
+ Object.entries(securitySchemes).forEach(([_, scheme]) => {
31
+ if (scheme.type === "oauth2") {
32
+ if (scheme.flows?.authorizationCode) {
33
+ const authorizeRoute = scheme.flows.authorizationCode.authorizationUrl ?? "/oauth/authorize";
34
+ const tokenRoute = scheme.flows.authorizationCode.tokenUrl ?? "/oauth/token";
35
+ authorizeUrls.add(getPathFromUrl(authorizeRoute));
36
+ tokenUrls.add(tokenRoute);
37
+ }
38
+ if (scheme.flows?.implicit) {
39
+ const authorizeRoute = scheme.flows.implicit.authorizationUrl ?? "/oauth/authorize";
40
+ authorizeUrls.add(getPathFromUrl(authorizeRoute));
41
+ }
42
+ if (scheme.flows?.password) {
43
+ const tokenRoute = scheme.flows.password.tokenUrl ?? "/oauth/token";
44
+ tokenUrls.add(tokenRoute);
45
+ }
46
+ if (scheme.flows?.clientCredentials) {
47
+ const tokenRoute = scheme.flows.clientCredentials.tokenUrl ?? "/oauth/token";
48
+ tokenUrls.add(tokenRoute);
49
+ }
50
+ } else if (scheme.type === "openIdConnect") {
51
+ if (scheme.openIdConnectUrl) {
52
+ const configPath = getPathFromUrl(scheme.openIdConnectUrl ?? "/.well-known/openid-configuration");
53
+ app.get(configPath, (c) => {
54
+ return c.json({
55
+ issuer: "https://example.com",
56
+ authorization_endpoint: "/oauth/authorize",
57
+ token_endpoint: "/oauth/token",
58
+ response_types_supported: ["code", "token", "id_token"],
59
+ subject_types_supported: ["public"],
60
+ id_token_signing_alg_values_supported: ["RS256"]
61
+ });
62
+ });
63
+ const authorizeRoute = "/oauth/authorize";
64
+ const tokenRoute = "/oauth/token";
65
+ authorizeUrls.add(getPathFromUrl(authorizeRoute));
66
+ tokenUrls.add(tokenRoute);
67
+ }
68
+ }
69
+ });
70
+ authorizeUrls.forEach((authorizeUrl) => {
71
+ app.get(authorizeUrl, (c) => respondWithAuthorizePage(c, schema?.info?.title));
72
+ });
73
+ tokenUrls.forEach((tokenUrl) => {
74
+ app.post(tokenUrl, respondWithToken);
75
+ });
84
76
  }
85
-
86
- export { setupAuthenticationRoutes };
77
+ export {
78
+ setupAuthenticationRoutes
79
+ };
80
+ //# sourceMappingURL=setupAuthenticationRoutes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/setupAuthenticationRoutes.ts"],
4
+ "sourcesContent": ["import type { OpenAPI, OpenAPIV3, OpenAPIV3_1 } from '@scalar/openapi-types'\nimport type { Hono } from 'hono'\n\nimport { respondWithAuthorizePage } from '@/routes/respondWithAuthorizePage'\nimport { respondWithToken } from '@/routes/respondWithToken'\n\nimport { getOpenAuthTokenUrls, getPathFromUrl } from './getOpenAuthTokenUrls'\n\n/**\n * Helper function to set up authentication routes for OAuth 2.0 flows\n */\nexport function setupAuthenticationRoutes(app: Hono, schema?: OpenAPI.Document) {\n const securitySchemes: Record<string, OpenAPIV3.SecuritySchemeObject | OpenAPIV3_1.SecuritySchemeObject> =\n schema?.components?.securitySchemes || {}\n\n // Set up authentication routes for OAuth 2.0 flows\n getOpenAuthTokenUrls(schema).forEach((tokenUrl) => {\n app.post(tokenUrl, (c) => {\n return c.json(\n {\n access_token: 'super-secret-access-token',\n token_type: 'Bearer',\n expires_in: 3600,\n refresh_token: 'example-refresh-token',\n },\n 200,\n {\n /**\n * When responding with an access token, the server must also include the additional\n * Cache-Control: no-store HTTP header to ensure clients do not cache this request.\n *\n * @see https://www.oauth.com/oauth2-servers/access-tokens/access-token-response/\n */\n 'Cache-Control': 'no-store',\n },\n )\n })\n })\n\n // Set up routes for different OAuth 2.0 flows\n const authorizeUrls = new Set<string>()\n const tokenUrls = new Set<string>()\n\n Object.entries(securitySchemes).forEach(([_, scheme]) => {\n if (scheme.type === 'oauth2') {\n if (scheme.flows?.authorizationCode) {\n const authorizeRoute = scheme.flows.authorizationCode.authorizationUrl ?? '/oauth/authorize'\n const tokenRoute = scheme.flows.authorizationCode.tokenUrl ?? '/oauth/token'\n\n authorizeUrls.add(getPathFromUrl(authorizeRoute))\n tokenUrls.add(tokenRoute)\n }\n\n if (scheme.flows?.implicit) {\n const authorizeRoute = scheme.flows.implicit.authorizationUrl ?? '/oauth/authorize'\n authorizeUrls.add(getPathFromUrl(authorizeRoute))\n }\n\n if (scheme.flows?.password) {\n const tokenRoute = scheme.flows.password.tokenUrl ?? '/oauth/token'\n tokenUrls.add(tokenRoute)\n }\n\n if (scheme.flows?.clientCredentials) {\n const tokenRoute = scheme.flows.clientCredentials.tokenUrl ?? '/oauth/token'\n tokenUrls.add(tokenRoute)\n }\n } else if (scheme.type === 'openIdConnect') {\n // Handle OpenID Connect configuration\n if (scheme.openIdConnectUrl) {\n const configPath = getPathFromUrl(scheme.openIdConnectUrl ?? '/.well-known/openid-configuration')\n\n // Add route for OpenID Connect configuration\n app.get(configPath, (c) => {\n return c.json({\n issuer: 'https://example.com',\n authorization_endpoint: '/oauth/authorize',\n token_endpoint: '/oauth/token',\n response_types_supported: ['code', 'token', 'id_token'],\n subject_types_supported: ['public'],\n id_token_signing_alg_values_supported: ['RS256'],\n })\n })\n\n // Add standard endpoints\n const authorizeRoute = '/oauth/authorize'\n const tokenRoute = '/oauth/token'\n\n authorizeUrls.add(getPathFromUrl(authorizeRoute))\n tokenUrls.add(tokenRoute)\n }\n }\n })\n\n // Set up unique authorization routes\n authorizeUrls.forEach((authorizeUrl) => {\n app.get(authorizeUrl, (c) => respondWithAuthorizePage(c, schema?.info?.title))\n })\n\n // Set up unique token routes\n tokenUrls.forEach((tokenUrl) => {\n app.post(tokenUrl, respondWithToken)\n })\n}\n"],
5
+ "mappings": "AAGA,SAAS,gCAAgC;AACzC,SAAS,wBAAwB;AAEjC,SAAS,sBAAsB,sBAAsB;AAK9C,SAAS,0BAA0B,KAAW,QAA2B;AAC9E,QAAM,kBACJ,QAAQ,YAAY,mBAAmB,CAAC;AAG1C,uBAAqB,MAAM,EAAE,QAAQ,CAAC,aAAa;AACjD,QAAI,KAAK,UAAU,CAAC,MAAM;AACxB,aAAO,EAAE;AAAA,QACP;AAAA,UACE,cAAc;AAAA,UACd,YAAY;AAAA,UACZ,YAAY;AAAA,UACZ,eAAe;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAOE,iBAAiB;AAAA,QACnB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAGD,QAAM,gBAAgB,oBAAI,IAAY;AACtC,QAAM,YAAY,oBAAI,IAAY;AAElC,SAAO,QAAQ,eAAe,EAAE,QAAQ,CAAC,CAAC,GAAG,MAAM,MAAM;AACvD,QAAI,OAAO,SAAS,UAAU;AAC5B,UAAI,OAAO,OAAO,mBAAmB;AACnC,cAAM,iBAAiB,OAAO,MAAM,kBAAkB,oBAAoB;AAC1E,cAAM,aAAa,OAAO,MAAM,kBAAkB,YAAY;AAE9D,sBAAc,IAAI,eAAe,cAAc,CAAC;AAChD,kBAAU,IAAI,UAAU;AAAA,MAC1B;AAEA,UAAI,OAAO,OAAO,UAAU;AAC1B,cAAM,iBAAiB,OAAO,MAAM,SAAS,oBAAoB;AACjE,sBAAc,IAAI,eAAe,cAAc,CAAC;AAAA,MAClD;AAEA,UAAI,OAAO,OAAO,UAAU;AAC1B,cAAM,aAAa,OAAO,MAAM,SAAS,YAAY;AACrD,kBAAU,IAAI,UAAU;AAAA,MAC1B;AAEA,UAAI,OAAO,OAAO,mBAAmB;AACnC,cAAM,aAAa,OAAO,MAAM,kBAAkB,YAAY;AAC9D,kBAAU,IAAI,UAAU;AAAA,MAC1B;AAAA,IACF,WAAW,OAAO,SAAS,iBAAiB;AAE1C,UAAI,OAAO,kBAAkB;AAC3B,cAAM,aAAa,eAAe,OAAO,oBAAoB,mCAAmC;AAGhG,YAAI,IAAI,YAAY,CAAC,MAAM;AACzB,iBAAO,EAAE,KAAK;AAAA,YACZ,QAAQ;AAAA,YACR,wBAAwB;AAAA,YACxB,gBAAgB;AAAA,YAChB,0BAA0B,CAAC,QAAQ,SAAS,UAAU;AAAA,YACtD,yBAAyB,CAAC,QAAQ;AAAA,YAClC,uCAAuC,CAAC,OAAO;AAAA,UACjD,CAAC;AAAA,QACH,CAAC;AAGD,cAAM,iBAAiB;AACvB,cAAM,aAAa;AAEnB,sBAAc,IAAI,eAAe,cAAc,CAAC;AAChD,kBAAU,IAAI,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,EACF,CAAC;AAGD,gBAAc,QAAQ,CAAC,iBAAiB;AACtC,QAAI,IAAI,cAAc,CAAC,MAAM,yBAAyB,GAAG,QAAQ,MAAM,KAAK,CAAC;AAAA,EAC/E,CAAC;AAGD,YAAU,QAAQ,CAAC,aAAa;AAC9B,QAAI,KAAK,UAAU,gBAAgB;AAAA,EACrC,CAAC;AACH;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "swagger",
17
17
  "cli"
18
18
  ],
19
- "version": "0.3.23",
19
+ "version": "0.3.25",
20
20
  "engines": {
21
21
  "node": ">=18"
22
22
  },
@@ -38,22 +38,20 @@
38
38
  "dependencies": {
39
39
  "hono": "^4.6.5",
40
40
  "object-to-xml": "^2.0.0",
41
- "@scalar/oas-utils": "0.2.139",
42
- "@scalar/openapi-parser": "0.10.16",
43
- "@scalar/openapi-types": "0.2.1"
41
+ "@scalar/oas-utils": "0.2.141",
42
+ "@scalar/openapi-types": "0.2.2",
43
+ "@scalar/openapi-parser": "0.10.17"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@hono/node-server": "^1.11.0",
47
47
  "@types/node": "^20.17.10",
48
48
  "vite": "^5.4.10",
49
- "@scalar/build-tooling": "0.1.18",
50
- "@scalar/hono-api-reference": "0.8.6"
49
+ "@scalar/hono-api-reference": "0.8.8",
50
+ "@scalar/build-tooling": "0.1.19"
51
51
  },
52
52
  "scripts": {
53
- "build": "scalar-build-rollup",
53
+ "build": "scalar-build-esbuild",
54
54
  "dev": "nodemon --exec \"vite-node playground/index.ts\" --ext ts --quiet",
55
- "format": "scalar-format",
56
- "format:check": "scalar-format-check",
57
55
  "lint:check": "scalar-lint-check",
58
56
  "lint:fix": "scalar-lint-fix",
59
57
  "test": "vitest",