@scalar/mock-server 0.2.19 → 0.2.21

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # @scalar/mock-server
2
2
 
3
+ ## 0.2.21
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [9815191]
8
+ - Updated dependencies [869d255]
9
+ - @scalar/oas-utils@0.2.18
10
+
11
+ ## 0.2.20
12
+
13
+ ### Patch Changes
14
+
15
+ - ad002b9: feat: add headers to mocked responses
16
+ - f4e0edc: fix: imports cause a circular reference
17
+ - ad002b9: feat: support redirects
18
+ - ad002b9: feat: support all content types
19
+
3
20
  ## 0.2.19
4
21
 
5
22
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"createMockServer.d.ts","sourceRoot":"","sources":["../src/createMockServer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAAW,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAiBzC;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAC/C,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC3C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAA;KAAE,KAAK,IAAI,CAAA;CAC/E,uFA8IA"}
1
+ {"version":3,"file":"createMockServer.d.ts","sourceRoot":"","sources":["../src/createMockServer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,OAAO,EAAW,MAAM,wBAAwB,CAAA;AAC9D,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAkBzC;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAC/C,aAAa,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC3C,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC,SAAS,CAAA;KAAE,KAAK,IAAI,CAAA;CAC/E,uFAqLA"}
@@ -1,16 +1,18 @@
1
1
  import { getExampleFromSchema } from '@scalar/oas-utils/spec-getters';
2
2
  import { openapi } from '@scalar/openapi-parser';
3
3
  import { Hono } from 'hono';
4
+ import { accepts } from 'hono/accepts';
4
5
  import { cors } from 'hono/cors';
6
+ import objectToXML from 'object-to-xml';
7
+ import { anyBasicAuthentication } from './utils/anyBasicAuthentication.js';
8
+ import { anyOpenAuthPasswordGrantAuthentication } from './utils/anyOpenAuthPasswordGrantAuthentication.js';
9
+ import { findPreferredResponseKey } from './utils/findPreferredResponseKey.js';
5
10
  import { getOpenAuthTokenUrl } from './utils/getOpenAuthTokenUrl.js';
6
11
  import { getOperations } from './utils/getOperations.js';
7
12
  import { honoRouteFromPath } from './utils/honoRouteFromPath.js';
8
13
  import { isAuthenticationRequired } from './utils/isAuthenticationRequired.js';
9
14
  import { isBasicAuthenticationRequired } from './utils/isBasicAuthenticationRequired.js';
10
- import { anyBasicAuthentication } from './utils/anyBasicAuthentication.js';
11
15
  import { isOpenAuthPasswordGrantRequired } from './utils/isOpenAuthPasswordGrantRequired.js';
12
- import { anyOpenAuthPasswordGrantAuthentication } from './utils/anyOpenAuthPasswordGrantAuthentication.js';
13
- import { findPreferredResponseKey } from './utils/findPreferredResponseKey.js';
14
16
 
15
17
  /**
16
18
  * Create a mock server instance
@@ -94,15 +96,32 @@ async function createMockServer(options) {
94
96
  // Response
95
97
  // default, 200, 201 …
96
98
  const preferredResponseKey = findPreferredResponseKey(Object.keys(operation.responses ?? {}));
97
- // Focus on JSON for now
98
- const jsonResponse = preferredResponseKey
99
- ? operation.responses?.[preferredResponseKey]?.content?.['application/json']
99
+ const preferredResponse = preferredResponseKey
100
+ ? operation.responses?.[preferredResponseKey]
100
101
  : null;
101
- // Get or generate JSON
102
- const response = jsonResponse?.example
103
- ? jsonResponse.example
104
- : jsonResponse?.schema
105
- ? getExampleFromSchema(jsonResponse.schema, {
102
+ const supportedContentTypes = Object.keys(preferredResponse?.content ?? {});
103
+ // Headers
104
+ const headers = preferredResponse?.headers ?? {};
105
+ Object.keys(headers).forEach((header) => {
106
+ c.header(header, headers[header].schema
107
+ ? getExampleFromSchema(headers[header].schema)
108
+ : null);
109
+ });
110
+ // Content-Type
111
+ const acceptedContentType = accepts(c, {
112
+ header: 'Accept',
113
+ supports: supportedContentTypes,
114
+ default: supportedContentTypes.includes('application/json')
115
+ ? 'application/json'
116
+ : supportedContentTypes[0],
117
+ });
118
+ c.header('Content-Type', acceptedContentType);
119
+ const acceptedResponse = preferredResponse?.content?.[acceptedContentType];
120
+ // Body
121
+ const body = acceptedResponse?.example
122
+ ? acceptedResponse.example
123
+ : acceptedResponse?.schema
124
+ ? getExampleFromSchema(acceptedResponse.schema, {
106
125
  emptyString: '…',
107
126
  variables: c.req.param(),
108
127
  })
@@ -111,7 +130,15 @@ async function createMockServer(options) {
111
130
  const statusCode = parseInt(preferredResponseKey === 'default'
112
131
  ? '200'
113
132
  : preferredResponseKey ?? '200', 10);
114
- return c.json(response, statusCode);
133
+ c.status(statusCode);
134
+ return c.body(typeof body === 'object'
135
+ ? // XML
136
+ acceptedContentType?.includes('xml')
137
+ ? `<?xml version="1.0" encoding="UTF-8"?>${objectToXML(body)}`
138
+ : // JSON
139
+ JSON.stringify(body, null, 2)
140
+ : // String
141
+ body);
115
142
  });
116
143
  });
117
144
  });
@@ -1 +1 @@
1
- {"version":3,"file":"findPreferredResponseKey.d.ts","sourceRoot":"","sources":["../../src/utils/findPreferredResponseKey.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,sBAI5D"}
1
+ {"version":3,"file":"findPreferredResponseKey.d.ts","sourceRoot":"","sources":["../../src/utils/findPreferredResponseKey.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,sBAU5D"}
@@ -2,7 +2,12 @@
2
2
  * Find the preferred response key: default, 200, 201 …
3
3
  */
4
4
  function findPreferredResponseKey(responses) {
5
- return ['default', '200', '201', '204', '404', '500'].find((key) => responses?.includes(key) ?? false);
5
+ return (
6
+ // Regular status codes
7
+ ['default', '200', '201', '204', '404', '500'].find((key) => responses?.includes(key) ?? false) ??
8
+ // Lowest status code
9
+ responses?.sort()[0] ??
10
+ undefined);
6
11
  }
7
12
 
8
13
  export { findPreferredResponseKey };
package/package.json CHANGED
@@ -16,7 +16,7 @@
16
16
  "swagger",
17
17
  "cli"
18
18
  ],
19
- "version": "0.2.19",
19
+ "version": "0.2.21",
20
20
  "engines": {
21
21
  "node": ">=18"
22
22
  },
@@ -37,13 +37,14 @@
37
37
  "dependencies": {
38
38
  "@scalar/openapi-parser": "^0.7.2",
39
39
  "hono": "^4.2.7",
40
- "@scalar/oas-utils": "0.2.17"
40
+ "object-to-xml": "^2.0.0",
41
+ "@scalar/oas-utils": "0.2.18"
41
42
  },
42
43
  "devDependencies": {
43
44
  "@hono/node-server": "^1.11.0",
44
45
  "@types/node": "^20.14.10",
45
- "@scalar/galaxy": "0.2.5",
46
- "@scalar/build-tooling": "0.1.10"
46
+ "@scalar/build-tooling": "0.1.10",
47
+ "@scalar/galaxy": "0.2.5"
47
48
  },
48
49
  "scripts": {
49
50
  "build": "scalar-build-rollup",