@scalar/snippetz 0.9.32 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/libs/browser-request.d.ts.map +1 -1
- package/dist/libs/browser-request.js +17 -6
- package/dist/libs/http.d.ts.map +1 -1
- package/dist/libs/http.js +3 -2
- package/dist/libs/javascript.d.ts +3 -1
- package/dist/libs/javascript.d.ts.map +1 -1
- package/dist/libs/javascript.js +23 -24
- package/dist/plugins/c/libcurl/libcurl.js +1 -1
- package/dist/plugins/csharp/httpclient/httpclient.js +2 -2
- package/dist/plugins/csharp/restsharp/restsharp.d.ts.map +1 -1
- package/dist/plugins/csharp/restsharp/restsharp.js +7 -15
- package/dist/plugins/dart/http/http.d.ts.map +1 -1
- package/dist/plugins/dart/http/http.js +19 -2
- package/dist/plugins/http/http11/http11.d.ts.map +1 -1
- package/dist/plugins/http/http11/http11.js +2 -1
- package/dist/plugins/js/fetch/fetch.js +2 -2
- package/dist/plugins/js/ofetch/ofetch.js +2 -2
- package/dist/plugins/node/fetch/fetch.js +2 -2
- package/dist/plugins/node/ofetch/ofetch.js +2 -2
- package/dist/plugins/node/undici/undici.js +2 -2
- package/dist/plugins/php/curl/curl.d.ts.map +1 -1
- package/dist/plugins/php/curl/curl.js +2 -1
- package/dist/plugins/php/guzzle/guzzle.js +2 -2
- package/dist/plugins/php/laravel/laravel.js +2 -2
- package/dist/plugins/python/aiohttp/aiohttp.d.ts.map +1 -1
- package/dist/plugins/python/aiohttp/aiohttp.js +9 -5
- package/dist/plugins/python/requestsLike.d.ts.map +1 -1
- package/dist/plugins/python/requestsLike.js +6 -2
- package/dist/plugins/r/httr2/httr2.js +2 -2
- package/dist/plugins/ruby/native/native.d.ts.map +1 -1
- package/dist/plugins/ruby/native/native.js +4 -4
- package/dist/plugins/rust/reqwest/reqwest.js +5 -2
- package/dist/plugins/shared/axios.d.ts.map +1 -1
- package/dist/plugins/shared/axios.js +9 -25
- package/dist/plugins/shell/curl/curl.d.ts.map +1 -1
- package/dist/plugins/shell/curl/curl.js +11 -16
- package/dist/plugins/shell/wget/wget.d.ts.map +1 -1
- package/dist/plugins/shell/wget/wget.js +5 -16
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -102,3 +102,15 @@ We are API nerds. You too? Let's chat on Discord: <https://discord.gg/scalar>
|
|
|
102
102
|
## License
|
|
103
103
|
|
|
104
104
|
The source code in this repository is licensed under [MIT](https://github.com/scalar/scalar/blob/main/LICENSE).
|
|
105
|
+
|
|
106
|
+
## Cookies in browser examples
|
|
107
|
+
|
|
108
|
+
XHR and jQuery examples use `document.cookie` and enable `withCredentials` whenever the HAR contains cookie values, including an explicit `Cookie` header without OpenAPI cookie-style parameters. This intentionally changes those legacy examples: browsers forbid setting the `Cookie` request header directly. Requests without cookies remain uncredentialed.
|
|
109
|
+
|
|
110
|
+
The setup writes cookies for the page's domain and cannot set cookies for an unrelated API domain or create HttpOnly cookies. For a cross-origin API, obtain cookies through that API's authentication flow instead. Cookie domain, path, Secure, SameSite, and browser third-party-cookie policies still apply.
|
|
111
|
+
|
|
112
|
+
[Credentialed cross-origin responses](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS#requests_with_credentials) must permit credentials and the specific calling origin through CORS (`Access-Control-Allow-Credentials: true` and a non-wildcard `Access-Control-Allow-Origin`). Enabling credentials does not itself require preflight; if the request otherwise requires preflight, that check must also succeed.
|
|
113
|
+
|
|
114
|
+
Cookie-style values remain serialized as authored, while legacy structured HAR cookies are percent-encoded. Do not decode and re-encode a combined Cookie header uniformly. Other generators retain their existing environment-specific header behavior.
|
|
115
|
+
|
|
116
|
+
For OpenAPI 3.2 `in: cookie, style: cookie` parameters, omit `explode` or set it to `true`. `explode: false` is invalid for cookies because comma-separated values violate cookie syntax. Scalar tolerates that invalid combination by expanding arrays and objects into separate cookie entries; it emits a developer-console warning once per parameter name. Values are passed through unchanged, so provide any required escaping in the API description.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-request.d.ts","sourceRoot":"","sources":["../../src/libs/browser-request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAK7E,wFAAwF;AACxF,eAAO,MAAM,qBAAqB,GAChC,UAAS,OAAO,CAAC,UAAU,CAAM,EACjC,gBAAgB,mBAAmB,KAClC;IACD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC1C,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"browser-request.d.ts","sourceRoot":"","sources":["../../src/libs/browser-request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAK7E,wFAAwF;AACxF,eAAO,MAAM,qBAAqB,GAChC,UAAS,OAAO,CAAC,UAAU,CAAM,EACjC,gBAAgB,mBAAmB,KAClC;IACD,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC1C,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,OAAO,CAAA;CAuEzB,CAAA"}
|
|
@@ -2,7 +2,16 @@ import { Base64 } from 'js-base64';
|
|
|
2
2
|
import { joinUrlAndQuery, normalizeMethod } from './http.js';
|
|
3
3
|
/** Builds browser request values without collapsing repeated headers or form fields. */
|
|
4
4
|
export const prepareBrowserRequest = (request = {}, configuration) => {
|
|
5
|
-
|
|
5
|
+
// Browsers forbid setting Cookie directly. Header values are already serialized,
|
|
6
|
+
// so preserve their escaping when transferring them to the browser cookie store.
|
|
7
|
+
const cookieValues = [
|
|
8
|
+
...(request.cookies ?? []).map(({ name, value }) => `${encodeURIComponent(name)}=${encodeURIComponent(value)}`),
|
|
9
|
+
...(request.headers ?? [])
|
|
10
|
+
.filter(({ name }) => name.toLowerCase() === 'cookie')
|
|
11
|
+
.flatMap(({ value }) => (value ?? '').split(';').map((cookie) => cookie.trim()))
|
|
12
|
+
.filter((cookie) => cookie.includes('=')),
|
|
13
|
+
];
|
|
14
|
+
const headers = (request.headers ?? []).filter(({ name }) => name.toLowerCase() !== 'cookie');
|
|
6
15
|
if (configuration?.auth?.username && configuration.auth.password) {
|
|
7
16
|
headers.push({
|
|
8
17
|
name: 'Authorization',
|
|
@@ -10,10 +19,10 @@ export const prepareBrowserRequest = (request = {}, configuration) => {
|
|
|
10
19
|
});
|
|
11
20
|
}
|
|
12
21
|
const setup = [];
|
|
13
|
-
if (
|
|
14
|
-
setup.push(
|
|
15
|
-
for (const
|
|
16
|
-
setup.push(`document.cookie = ${JSON.stringify(`${
|
|
22
|
+
if (cookieValues.length) {
|
|
23
|
+
setup.push("// Run on the request origin; document.cookie writes cookies for the current page's domain.");
|
|
24
|
+
for (const cookie of cookieValues) {
|
|
25
|
+
setup.push(`document.cookie = ${JSON.stringify(`${cookie}; path=/`)};`);
|
|
17
26
|
}
|
|
18
27
|
}
|
|
19
28
|
const postData = request.postData;
|
|
@@ -58,7 +67,9 @@ export const prepareBrowserRequest = (request = {}, configuration) => {
|
|
|
58
67
|
// The browser must supply the boundary matching its FormData serialization.
|
|
59
68
|
headers: multipart ? headers.filter(({ name }) => name.toLowerCase() !== 'content-type') : headers,
|
|
60
69
|
setup,
|
|
61
|
-
|
|
70
|
+
// This intentionally includes explicit Cookie headers, even without cookie-style parameters.
|
|
71
|
+
// Cross-origin use additionally requires credentialed CORS and eligible stored cookies.
|
|
72
|
+
withCredentials: Boolean(cookieValues.length),
|
|
62
73
|
body: multipart ? 'body' : formBody,
|
|
63
74
|
};
|
|
64
75
|
};
|
package/dist/libs/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/libs/http.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/libs/http.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAExD,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAKvG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAO7F;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,MAC0D,CAAA;AAE5G;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,MAgB1C,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,MAAM,EAAE,cAAc,aAAa,EAAE,KAAG,MAY5E,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,GAAI,UAAU,qBAAqB,EAAE,EAAE,UAAU,aAAa,EAAE,KAAG,UAAU,EAiBvG,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,MAAM,EAAE,OAAO,MAAM,KAAG,IAU9G,CAAA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,UAAU,CAAC,aAAa,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAK1G;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBnF"}
|
package/dist/libs/http.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { isHttpMethod } from '@scalar/helpers/http/is-http-method';
|
|
1
2
|
/**
|
|
2
3
|
* Normalizes the request object with defaults
|
|
3
4
|
*/
|
|
4
5
|
export function normalizeRequest(request) {
|
|
5
6
|
return {
|
|
6
7
|
...request,
|
|
7
|
-
method: (request.method
|
|
8
|
+
method: normalizeMethod(request.method),
|
|
8
9
|
};
|
|
9
10
|
}
|
|
10
11
|
/**
|
|
@@ -20,7 +21,7 @@ export function buildQueryString(queryParams) {
|
|
|
20
21
|
/**
|
|
21
22
|
* Normalizes a request method.
|
|
22
23
|
*/
|
|
23
|
-
export const normalizeMethod = (method) => (method
|
|
24
|
+
export const normalizeMethod = (method) => method ? (isHttpMethod(method) && method === method.toLowerCase() ? method.toUpperCase() : method) : 'GET';
|
|
24
25
|
/**
|
|
25
26
|
* Normalizes URL formatting while preserving origin-only paths.
|
|
26
27
|
*/
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Escapes a value for a single-quoted JavaScript string literal. */
|
|
2
|
+
export declare const escapeJsString: (value: string) => string;
|
|
1
3
|
/**
|
|
2
4
|
* Represents a raw code that should not be quoted, e.g. `JSON.stringify(...)`.
|
|
3
5
|
* If consists of multiple lines, they will be indented properly.
|
|
@@ -11,5 +13,5 @@ export declare class Raw {
|
|
|
11
13
|
*
|
|
12
14
|
* Handles nested objects, arrays, and special string values
|
|
13
15
|
*/
|
|
14
|
-
export declare function objectToString(obj:
|
|
16
|
+
export declare function objectToString(obj: object, indent?: number): string;
|
|
15
17
|
//# sourceMappingURL=javascript.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../src/libs/javascript.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../src/libs/javascript.ts"],"names":[],"mappings":"AASA,qEAAqE;AACrE,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,KAAG,MAE9C,CAAA;AAED;;;GAGG;AACH,qBAAa,GAAG;IACK,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;CACjC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,MAAM,CA4D9D"}
|
package/dist/libs/javascript.js
CHANGED
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
function needsQuotes(key) {
|
|
7
7
|
return !/^[$A-Z_][0-9A-Z_$]*$/i.test(key);
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
/** Escapes a value for a single-quoted JavaScript string literal. */
|
|
10
|
+
export const escapeJsString = (value) => {
|
|
11
|
+
return value.replaceAll('\\', '\\\\').replaceAll('\n', '\\n').replaceAll('\r', '\\r').replaceAll("'", "\\'");
|
|
12
|
+
};
|
|
12
13
|
/**
|
|
13
14
|
* Represents a raw code that should not be quoted, e.g. `JSON.stringify(...)`.
|
|
14
15
|
* If consists of multiple lines, they will be indented properly.
|
|
@@ -28,11 +29,28 @@ export function objectToString(obj, indent = 0) {
|
|
|
28
29
|
const parts = [];
|
|
29
30
|
const indentation = ' '.repeat(indent);
|
|
30
31
|
const innerIndentation = ' '.repeat(indent + 2);
|
|
32
|
+
// Arrays must be handled before Object.entries turns their indexes into object keys.
|
|
33
|
+
if (Array.isArray(obj)) {
|
|
34
|
+
const items = obj.map((item) => {
|
|
35
|
+
if (typeof item === 'string') {
|
|
36
|
+
return `'${escapeJsString(item)}'`;
|
|
37
|
+
}
|
|
38
|
+
if (item && typeof item === 'object') {
|
|
39
|
+
return objectToString(item);
|
|
40
|
+
}
|
|
41
|
+
return JSON.stringify(item);
|
|
42
|
+
});
|
|
43
|
+
if (items.some((item) => item.includes('\n'))) {
|
|
44
|
+
const arrayString = items.map((item) => indentString(item, indent + 2)).join(',\n');
|
|
45
|
+
return `[\n${arrayString}\n${indentation}]`;
|
|
46
|
+
}
|
|
47
|
+
return `[${items.join(', ')}]`;
|
|
48
|
+
}
|
|
31
49
|
if (Object.keys(obj).length === 0) {
|
|
32
50
|
return '{}';
|
|
33
51
|
}
|
|
34
52
|
for (const [key, value] of Object.entries(obj)) {
|
|
35
|
-
const formattedKey = needsQuotes(key) ? `'${
|
|
53
|
+
const formattedKey = needsQuotes(key) ? `'${escapeJsString(key)}'` : key;
|
|
36
54
|
if (value instanceof Raw) {
|
|
37
55
|
const lines = value.value.split('\n');
|
|
38
56
|
let formattedValue = `${value.value}`;
|
|
@@ -48,30 +66,11 @@ export function objectToString(obj, indent = 0) {
|
|
|
48
66
|
}
|
|
49
67
|
parts.push(`${innerIndentation}${formattedKey}: ${formattedValue}`);
|
|
50
68
|
}
|
|
51
|
-
else if (Array.isArray(value)) {
|
|
52
|
-
const items = value.map((item) => {
|
|
53
|
-
if (typeof item === 'string') {
|
|
54
|
-
return `'${item}'`;
|
|
55
|
-
}
|
|
56
|
-
if (item && typeof item === 'object') {
|
|
57
|
-
return objectToString(item);
|
|
58
|
-
}
|
|
59
|
-
return JSON.stringify(item);
|
|
60
|
-
});
|
|
61
|
-
if (items.some((item) => item.includes('\n'))) {
|
|
62
|
-
// format vertically if any array element contains a newline
|
|
63
|
-
const arrayString = items.map((item) => indentString(item, indent + 4)).join(',\n');
|
|
64
|
-
parts.push(`${innerIndentation}${formattedKey}: [\n${arrayString}\n${innerIndentation}]`);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
parts.push(`${innerIndentation}${formattedKey}: [${items.join(', ')}]`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
69
|
else if (value && typeof value === 'object') {
|
|
71
70
|
parts.push(`${innerIndentation}${formattedKey}: ${objectToString(value, indent + 2)}`);
|
|
72
71
|
}
|
|
73
72
|
else if (typeof value === 'string') {
|
|
74
|
-
const formattedValue = `'${value}'`;
|
|
73
|
+
const formattedValue = `'${escapeJsString(value)}'`;
|
|
75
74
|
parts.push(`${innerIndentation}${formattedKey}: ${formattedValue}`);
|
|
76
75
|
}
|
|
77
76
|
else {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { encode } from 'js-base64';
|
|
2
|
-
import { buildQueryString } from '../../../libs/http.js';
|
|
2
|
+
import { buildQueryString, normalizeMethod } from '../../../libs/http.js';
|
|
3
3
|
/**
|
|
4
4
|
* csharp/httpclient
|
|
5
5
|
*/
|
|
@@ -15,7 +15,7 @@ export const csharpHttpclient = {
|
|
|
15
15
|
...request,
|
|
16
16
|
};
|
|
17
17
|
// Normalization
|
|
18
|
-
normalizedRequest.method = normalizedRequest.method
|
|
18
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
19
19
|
// Build URL with query string
|
|
20
20
|
const queryString = buildQueryString(normalizedRequest.queryString);
|
|
21
21
|
const url = `${normalizedRequest.url}${queryString}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restsharp.d.ts","sourceRoot":"","sources":["../../../../src/plugins/csharp/restsharp/restsharp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"restsharp.d.ts","sourceRoot":"","sources":["../../../../src/plugins/csharp/restsharp/restsharp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAsCpD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,MAyH7B,CAAA"}
|
|
@@ -1,18 +1,7 @@
|
|
|
1
|
+
import { isJsonMediaType } from '@scalar/helpers/http/is-json-media-type';
|
|
1
2
|
import { parseMimeType } from '@scalar/helpers/http/mime-type';
|
|
2
3
|
import { encode } from 'js-base64';
|
|
3
|
-
import { joinUrlAndQuery } from '../../../libs/http.js';
|
|
4
|
-
/**
|
|
5
|
-
* True for `application/json`, any RFC 6839 `+json` structured-syntax suffix
|
|
6
|
-
* (e.g. `application/vnd.api+json`), and parameterized variants
|
|
7
|
-
* (e.g. `application/json;charset=utf-8`). Case-insensitive.
|
|
8
|
-
*/
|
|
9
|
-
const isJsonContentType = (value) => {
|
|
10
|
-
if (!value) {
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
13
|
-
const { subtype } = parseMimeType(value);
|
|
14
|
-
return subtype === 'json' || subtype.endsWith('+json');
|
|
15
|
-
};
|
|
4
|
+
import { joinUrlAndQuery, normalizeMethod } from '../../../libs/http.js';
|
|
16
5
|
/**
|
|
17
6
|
* Maps an HTTP method to a RestSharp `Method` enum member. The enum uses
|
|
18
7
|
* PascalCase members (`Method.Get`, `Method.Post`, ...), so we title-case the
|
|
@@ -57,7 +46,10 @@ export const csharpRestsharp = {
|
|
|
57
46
|
...request,
|
|
58
47
|
};
|
|
59
48
|
// Normalization
|
|
60
|
-
normalizedRequest.method = normalizedRequest.method
|
|
49
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
50
|
+
if (!['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS', 'COPY', 'SEARCH', 'MERGE'].includes(normalizedRequest.method)) {
|
|
51
|
+
return '// RestSharp does not support this HTTP method. Select HttpClient for a custom method.';
|
|
52
|
+
}
|
|
61
53
|
// Build the full URL, appending the query string with the correct separator
|
|
62
54
|
// (joinUrlAndQuery uses `&` when the URL already carries a query string)
|
|
63
55
|
const url = joinUrlAndQuery(normalizedRequest.url, normalizedRequest.queryString);
|
|
@@ -97,7 +89,7 @@ export const csharpRestsharp = {
|
|
|
97
89
|
// Compare against the essence so parameterized values (e.g. a `boundary` or
|
|
98
90
|
// `charset`) still match the form, multipart, and octet-stream branches.
|
|
99
91
|
const essence = mimeType ? parseMimeType(mimeType).essence : undefined;
|
|
100
|
-
if (
|
|
92
|
+
if (isJsonMediaType(mimeType)) {
|
|
101
93
|
if (text) {
|
|
102
94
|
let body = text;
|
|
103
95
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/plugins/dart/http/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../src/plugins/dart/http/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAIpD;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,MAqHtB,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeMethod } from '../../../libs/http.js';
|
|
1
2
|
/**
|
|
2
3
|
* dart/http
|
|
3
4
|
*/
|
|
@@ -12,7 +13,7 @@ export const dartHttp = {
|
|
|
12
13
|
...request,
|
|
13
14
|
};
|
|
14
15
|
// Normalize method to uppercase
|
|
15
|
-
normalizedRequest.method = normalizedRequest.method
|
|
16
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
16
17
|
// Start building the Dart code
|
|
17
18
|
let code = `import 'package:http/http.dart' as http;\n\nvoid main() async {\n`;
|
|
18
19
|
// Handle cookies
|
|
@@ -88,7 +89,23 @@ export const dartHttp = {
|
|
|
88
89
|
const method = normalizedRequest.method.toLowerCase();
|
|
89
90
|
const headersPart = Object.keys(headers).length > 0 ? ', headers: headers' : '';
|
|
90
91
|
const bodyPart = body ? ', body: body' : '';
|
|
91
|
-
|
|
92
|
+
if (['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'].includes(normalizedRequest.method)) {
|
|
93
|
+
code += ` final response = await http.${method}(Uri.parse('${url}')${headersPart}${bodyPart});\n`;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
const wireMethod = normalizedRequest.method.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/\$/g, '\\$');
|
|
97
|
+
code += ` final request = http.Request('${wireMethod}', Uri.parse('${url}'));\n`;
|
|
98
|
+
if (Object.keys(headers).length > 0) {
|
|
99
|
+
code += ' request.headers.addAll(headers);\n';
|
|
100
|
+
}
|
|
101
|
+
if (body) {
|
|
102
|
+
code +=
|
|
103
|
+
normalizedRequest.postData?.mimeType === 'multipart/form-data'
|
|
104
|
+
? ' request.bodyFields = body;\n'
|
|
105
|
+
: ' request.body = body;\n';
|
|
106
|
+
}
|
|
107
|
+
code += ' final response = await http.Response.fromStream(await request.send());\n';
|
|
108
|
+
}
|
|
92
109
|
code += ' print(response.body);\n';
|
|
93
110
|
code += '}';
|
|
94
111
|
return code;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http11.d.ts","sourceRoot":"","sources":["../../../../src/plugins/http/http11/http11.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"http11.d.ts","sourceRoot":"","sources":["../../../../src/plugins/http/http11/http11.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAIpD;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAkHxB,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeMethod } from '../../../libs/http.js';
|
|
1
2
|
/**
|
|
2
3
|
* http/http1.1
|
|
3
4
|
*/
|
|
@@ -14,7 +15,7 @@ export const httpHttp11 = {
|
|
|
14
15
|
...request,
|
|
15
16
|
};
|
|
16
17
|
// Normalize method
|
|
17
|
-
normalizedRequest.method = normalizedRequest.method
|
|
18
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
18
19
|
// Parse URL with error handling
|
|
19
20
|
let url;
|
|
20
21
|
let path;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildQueryString } from '../../../libs/http.js';
|
|
1
|
+
import { buildQueryString, normalizeMethod } from '../../../libs/http.js';
|
|
2
2
|
import { Raw, objectToString } from '../../../libs/javascript.js';
|
|
3
3
|
/**
|
|
4
4
|
* js/fetch
|
|
@@ -15,7 +15,7 @@ export const jsFetch = {
|
|
|
15
15
|
};
|
|
16
16
|
let prefix = '';
|
|
17
17
|
// Normalization
|
|
18
|
-
normalizedRequest.method = normalizedRequest.method
|
|
18
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
19
19
|
// Reset fetch defaults
|
|
20
20
|
const options = {
|
|
21
21
|
method: normalizedRequest.method === 'GET' ? undefined : normalizedRequest.method,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { reduceQueryParams } from '../../../libs/http.js';
|
|
1
|
+
import { normalizeMethod, reduceQueryParams } from '../../../libs/http.js';
|
|
2
2
|
import { objectToString } from '../../../libs/javascript.js';
|
|
3
3
|
/**
|
|
4
4
|
* js/ofetch
|
|
@@ -14,7 +14,7 @@ export const jsOfetch = {
|
|
|
14
14
|
...request,
|
|
15
15
|
};
|
|
16
16
|
// Normalization
|
|
17
|
-
normalizedRequest.method = normalizedRequest.method
|
|
17
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
18
18
|
// Reset fetch defaults
|
|
19
19
|
const options = {
|
|
20
20
|
method: normalizedRequest.method === 'GET' ? undefined : normalizedRequest.method,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildQueryString } from '../../../libs/http.js';
|
|
1
|
+
import { buildQueryString, normalizeMethod } from '../../../libs/http.js';
|
|
2
2
|
import { Raw, objectToString } from '../../../libs/javascript.js';
|
|
3
3
|
/**
|
|
4
4
|
* node/fetch
|
|
@@ -15,7 +15,7 @@ export const nodeFetch = {
|
|
|
15
15
|
};
|
|
16
16
|
let prefix = '';
|
|
17
17
|
// Normalization
|
|
18
|
-
normalizedRequest.method = normalizedRequest.method
|
|
18
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
19
19
|
// Reset fetch defaults
|
|
20
20
|
const options = {
|
|
21
21
|
method: normalizedRequest.method === 'GET' ? undefined : normalizedRequest.method,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { reduceQueryParams } from '../../../libs/http.js';
|
|
1
|
+
import { normalizeMethod, reduceQueryParams } from '../../../libs/http.js';
|
|
2
2
|
import { objectToString } from '../../../libs/javascript.js';
|
|
3
3
|
/**
|
|
4
4
|
* node/ofetch
|
|
@@ -14,7 +14,7 @@ export const nodeOfetch = {
|
|
|
14
14
|
...request,
|
|
15
15
|
};
|
|
16
16
|
// Normalization
|
|
17
|
-
normalizedRequest.method = normalizedRequest.method
|
|
17
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
18
18
|
// Reset fetch defaults
|
|
19
19
|
const options = {
|
|
20
20
|
method: normalizedRequest.method === 'GET' ? undefined : normalizedRequest.method,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildQueryString } from '../../../libs/http.js';
|
|
1
|
+
import { buildQueryString, normalizeMethod } from '../../../libs/http.js';
|
|
2
2
|
import { Raw, objectToString } from '../../../libs/javascript.js';
|
|
3
3
|
/**
|
|
4
4
|
* node/undici
|
|
@@ -14,7 +14,7 @@ export const nodeUndici = {
|
|
|
14
14
|
...request,
|
|
15
15
|
};
|
|
16
16
|
// Normalization
|
|
17
|
-
normalizedRequest.method = normalizedRequest.method
|
|
17
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
18
18
|
// Reset undici defaults
|
|
19
19
|
const options = {
|
|
20
20
|
method: normalizedRequest.method === 'GET' ? undefined : normalizedRequest.method,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"curl.d.ts","sourceRoot":"","sources":["../../../../src/plugins/php/curl/curl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"curl.d.ts","sourceRoot":"","sources":["../../../../src/plugins/php/curl/curl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAKpD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAiKrB,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeMethod } from '../../../libs/http.js';
|
|
1
2
|
import { objectToString } from '../../../libs/php.js';
|
|
2
3
|
/**
|
|
3
4
|
* php/curl
|
|
@@ -13,7 +14,7 @@ export const phpCurl = {
|
|
|
13
14
|
...request,
|
|
14
15
|
};
|
|
15
16
|
// Normalization
|
|
16
|
-
normalizedRequest.method = normalizedRequest.method
|
|
17
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
17
18
|
// Build PHP cURL code parts
|
|
18
19
|
const parts = [];
|
|
19
20
|
let hasMultipartMimeBody = false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { reduceQueryParams } from '../../../libs/http.js';
|
|
1
|
+
import { normalizeMethod, reduceQueryParams } from '../../../libs/http.js';
|
|
2
2
|
import { Raw, objectToString } from '../../../libs/php.js';
|
|
3
3
|
/**
|
|
4
4
|
* php/guzzle
|
|
@@ -12,7 +12,7 @@ export const phpGuzzle = {
|
|
|
12
12
|
return '';
|
|
13
13
|
}
|
|
14
14
|
const options = {};
|
|
15
|
-
const method = (request.method
|
|
15
|
+
const method = normalizeMethod(request.method);
|
|
16
16
|
const url = request.url || '';
|
|
17
17
|
// Handle headers
|
|
18
18
|
if (request.headers && Array.isArray(request.headers) && request.headers.length > 0) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isObjectLike } from '@scalar/helpers/object/is-object';
|
|
2
|
-
import { accumulateRepeatedValue, buildQueryString } from '../../../libs/http.js';
|
|
2
|
+
import { accumulateRepeatedValue, buildQueryString, normalizeMethod } from '../../../libs/http.js';
|
|
3
3
|
import { objectToString } from '../../../libs/php.js';
|
|
4
4
|
const escapePhpString = (value) => value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
5
5
|
const quotePhpString = (value) => `'${escapePhpString(value)}'`;
|
|
@@ -39,7 +39,7 @@ export const phpLaravel = {
|
|
|
39
39
|
method: 'GET',
|
|
40
40
|
...request,
|
|
41
41
|
};
|
|
42
|
-
normalizedRequest.method = normalizedRequest.method
|
|
42
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
43
43
|
const queryString = buildQueryString(normalizedRequest.queryString);
|
|
44
44
|
const url = `${normalizedRequest.url ?? ''}${queryString}`;
|
|
45
45
|
const chain = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiohttp.d.ts","sourceRoot":"","sources":["../../../../src/plugins/python/aiohttp/aiohttp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"aiohttp.d.ts","sourceRoot":"","sources":["../../../../src/plugins/python/aiohttp/aiohttp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,wBAAwB,CAAA;AA6BhE;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,MA4G3B,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { accumulateRepeatedValue, reduceQueryParams } from '../../../libs/http.js';
|
|
1
|
+
import { accumulateRepeatedValue, normalizeMethod, reduceQueryParams } from '../../../libs/http.js';
|
|
2
2
|
import { LENGTH_CONSIDERED_AS_SHORT, formatPythonValue } from '../../../plugins/python/requestsLike.js';
|
|
3
3
|
const indent = (value, prefix = ' ') => value
|
|
4
4
|
.split('\n')
|
|
@@ -6,13 +6,17 @@ const indent = (value, prefix = ' ') => value
|
|
|
6
6
|
.join('\n');
|
|
7
7
|
const formatRequestCall = (clientVar, method, url, args) => {
|
|
8
8
|
const urlParam = JSON.stringify(url);
|
|
9
|
+
if (!['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'].includes(method)) {
|
|
10
|
+
return `${clientVar}.request(${[JSON.stringify(method), urlParam, ...args].join(', ')})`;
|
|
11
|
+
}
|
|
12
|
+
const shortcut = method.toLowerCase();
|
|
9
13
|
if (url.length > LENGTH_CONSIDERED_AS_SHORT) {
|
|
10
|
-
return `${clientVar}.${
|
|
14
|
+
return `${clientVar}.${shortcut}(\n ${[urlParam, ...args].join(',\n ')}\n)`;
|
|
11
15
|
}
|
|
12
16
|
if (args.length === 0) {
|
|
13
|
-
return `${clientVar}.${
|
|
17
|
+
return `${clientVar}.${shortcut}(${urlParam})`;
|
|
14
18
|
}
|
|
15
|
-
return `${clientVar}.${
|
|
19
|
+
return `${clientVar}.${shortcut}(${urlParam},\n ${args.join(',\n ')}\n)`;
|
|
16
20
|
};
|
|
17
21
|
/**
|
|
18
22
|
* python/aiohttp
|
|
@@ -27,7 +31,7 @@ export const pythonAiohttp = {
|
|
|
27
31
|
method: 'get',
|
|
28
32
|
...request,
|
|
29
33
|
};
|
|
30
|
-
const method = normalizedRequest.method
|
|
34
|
+
const method = normalizeMethod(normalizedRequest.method);
|
|
31
35
|
const requestArgs = [];
|
|
32
36
|
const sessionArgs = [];
|
|
33
37
|
const setupLines = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestsLike.d.ts","sourceRoot":"","sources":["../../../src/plugins/python/requestsLike.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAI7E,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAsB5C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,SAAI,GAAG,MAAM,CAOzE;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAC7B,aAAa,CAAC,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"requestsLike.d.ts","sourceRoot":"","sources":["../../../src/plugins/python/requestsLike.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AAI7E,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAsB5C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,SAAI,GAAG,MAAM,CAOzE;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAC7B,aAAa,CAAC,EAAE,mBAAmB,UAmJpC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { accumulateRepeatedValue, reduceQueryParams } from '../../libs/http.js';
|
|
1
|
+
import { accumulateRepeatedValue, normalizeMethod, reduceQueryParams } from '../../libs/http.js';
|
|
2
2
|
export const LENGTH_CONSIDERED_AS_SHORT = 40;
|
|
3
3
|
// Function to convert JavaScript boolean and null values to Python equivalents
|
|
4
4
|
function convertToPythonSyntax(str) {
|
|
@@ -30,7 +30,8 @@ export function requestsLikeGenerate(clientVar, request, configuration) {
|
|
|
30
30
|
...request,
|
|
31
31
|
};
|
|
32
32
|
// Normalize method to lowercase for requests library
|
|
33
|
-
const
|
|
33
|
+
const wireMethod = normalizeMethod(normalizedRequest.method);
|
|
34
|
+
const method = wireMethod.toLowerCase();
|
|
34
35
|
// Build options object
|
|
35
36
|
const options = {};
|
|
36
37
|
// Add headers if present
|
|
@@ -145,6 +146,9 @@ export function requestsLikeGenerate(clientVar, request, configuration) {
|
|
|
145
146
|
formattedParams.push(`${key}=${str}`);
|
|
146
147
|
}
|
|
147
148
|
}
|
|
149
|
+
if (!['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'].includes(wireMethod)) {
|
|
150
|
+
return `${clientVar}.request(${[JSON.stringify(wireMethod), urlParam, ...formattedParams.slice(1)].join(', ')})`;
|
|
151
|
+
}
|
|
148
152
|
// Build the final request string with conditional URL formatting
|
|
149
153
|
if (normalizedRequest.url.length > LENGTH_CONSIDERED_AS_SHORT) {
|
|
150
154
|
return `${clientVar}.${method}(\n ${formattedParams.join(',\n ')}\n)`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isObjectLike } from '@scalar/helpers/object/is-object';
|
|
2
|
-
import { reduceQueryParams } from '../../../libs/http.js';
|
|
2
|
+
import { normalizeMethod, reduceQueryParams } from '../../../libs/http.js';
|
|
3
3
|
/**
|
|
4
4
|
* Formats JSON text as an R list structure
|
|
5
5
|
*/
|
|
@@ -58,7 +58,7 @@ export const rHttr2 = {
|
|
|
58
58
|
method: 'GET',
|
|
59
59
|
...request,
|
|
60
60
|
};
|
|
61
|
-
const method = normalizedRequest.method
|
|
61
|
+
const method = normalizeMethod(normalizedRequest.method);
|
|
62
62
|
const lines = ['library(httr2)', ''];
|
|
63
63
|
// Start the pipe chain
|
|
64
64
|
lines.push(`response <- request("${normalizedRequest.url}") |>`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../../src/plugins/ruby/native/native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../../src/plugins/ruby/native/native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AA+DpD;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAuGxB,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildQueryString } from '../../../libs/http.js';
|
|
1
|
+
import { buildQueryString, normalizeMethod } from '../../../libs/http.js';
|
|
2
2
|
const escapeRubyDoubleQuoted = (value) => value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
3
3
|
const escapeRubySingleQuoted = (value) => value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
4
4
|
const encodeFormComponent = (value) => encodeURIComponent(value).replace(/'/g, '%27');
|
|
@@ -16,14 +16,14 @@ const standardMethods = new Set([
|
|
|
16
16
|
'MOVE',
|
|
17
17
|
'TRACE',
|
|
18
18
|
]);
|
|
19
|
-
const toRubyMethodClass = (method) => method.charAt(0) + method.slice(1).toLowerCase();
|
|
19
|
+
const toRubyMethodClass = (method) => standardMethods.has(method) ? method.charAt(0) + method.slice(1).toLowerCase() : 'CustomRequest';
|
|
20
20
|
const maybeAddCustomMethodClass = (lines, method, hasBody) => {
|
|
21
21
|
if (standardMethods.has(method)) {
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
const methodClass = toRubyMethodClass(method);
|
|
25
25
|
lines.push(`class Net::HTTP::${methodClass} < Net::HTTPRequest`);
|
|
26
|
-
lines.push(` METHOD = '${method}'`);
|
|
26
|
+
lines.push(` METHOD = '${escapeRubySingleQuoted(method)}'`);
|
|
27
27
|
lines.push(` REQUEST_HAS_BODY = '${hasBody ? 'true' : 'false'}'`);
|
|
28
28
|
lines.push(' RESPONSE_HAS_BODY = true');
|
|
29
29
|
lines.push('end');
|
|
@@ -58,7 +58,7 @@ export const rubyNative = {
|
|
|
58
58
|
method: 'GET',
|
|
59
59
|
...request,
|
|
60
60
|
};
|
|
61
|
-
normalizedRequest.method = normalizedRequest.method
|
|
61
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
62
62
|
const queryString = buildQueryString(normalizedRequest.queryString);
|
|
63
63
|
const rawUrl = `${normalizedRequest.url ?? ''}${queryString}`;
|
|
64
64
|
const encodedUrl = encodeUrlWithPathPreservedBrackets(rawUrl);
|
|
@@ -119,15 +119,18 @@ const createBodyCall = (postData) => {
|
|
|
119
119
|
*/
|
|
120
120
|
const buildRustCode = (url, method, chainedCalls) => {
|
|
121
121
|
const code = ['let client = reqwest::Client::new();', ''];
|
|
122
|
+
const request = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD'].includes(method)
|
|
123
|
+
? `${method.toLowerCase()}(${wrapInDoubleQuotes(url)})`
|
|
124
|
+
: `request(reqwest::Method::from_bytes(${wrapInDoubleQuotes(method)}.as_bytes())?, ${wrapInDoubleQuotes(url)})`;
|
|
122
125
|
// Add chained calls with proper formatting
|
|
123
126
|
if (chainedCalls.length > 0) {
|
|
124
127
|
code.push('let request = client');
|
|
125
|
-
code.push(indent(1, `.${
|
|
128
|
+
code.push(indent(1, `.${request}`));
|
|
126
129
|
// Add a newline before the first chained call
|
|
127
130
|
code.push(...chainedCalls);
|
|
128
131
|
}
|
|
129
132
|
else {
|
|
130
|
-
code.push(`let request = client.${
|
|
133
|
+
code.push(`let request = client.${request}`);
|
|
131
134
|
}
|
|
132
135
|
// Add semicolon to the last chained call
|
|
133
136
|
const lastPart = code[code.length - 1];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../../src/plugins/shared/axios.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../../src/plugins/shared/axios.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAkH9D,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,OAAO,CAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC,EAAE,QAAQ,CAAC,KAAG,MAmDxF,CAAA"}
|
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
import { accumulateRepeatedValue, reduceQueryParams } from '../../libs/http.js';
|
|
2
|
-
import { Raw, objectToString } from '../../libs/javascript.js';
|
|
3
|
-
const escapeJsString = (value) => value.replaceAll('\\', '\\\\').replaceAll('\n', '\\n').replaceAll('\r', '\\r').replaceAll("'", "\\'");
|
|
4
|
-
const sanitizeForGeneratedCode = (value) => {
|
|
5
|
-
if (typeof value === 'string') {
|
|
6
|
-
return escapeJsString(value);
|
|
7
|
-
}
|
|
8
|
-
if (Array.isArray(value)) {
|
|
9
|
-
return value.map((item) => sanitizeForGeneratedCode(item));
|
|
10
|
-
}
|
|
11
|
-
if (value && typeof value === 'object' && !(value instanceof Raw)) {
|
|
12
|
-
return Object.entries(value).reduce((acc, [key, objectValue]) => {
|
|
13
|
-
acc[key] = sanitizeForGeneratedCode(objectValue);
|
|
14
|
-
return acc;
|
|
15
|
-
}, {});
|
|
16
|
-
}
|
|
17
|
-
return value;
|
|
18
|
-
};
|
|
1
|
+
import { accumulateRepeatedValue, normalizeMethod, reduceQueryParams } from '../../libs/http.js';
|
|
2
|
+
import { Raw, escapeJsString, objectToString } from '../../libs/javascript.js';
|
|
19
3
|
const addHeaderValue = (headers, name, value) => {
|
|
20
4
|
if (value === '') {
|
|
21
5
|
headers[name] = value;
|
|
@@ -110,28 +94,28 @@ export const createAxiosPlugin = (target) => ({
|
|
|
110
94
|
method: 'GET',
|
|
111
95
|
...request,
|
|
112
96
|
};
|
|
113
|
-
normalizedRequest.method = normalizedRequest.method
|
|
97
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
114
98
|
const options = {
|
|
115
99
|
method: normalizedRequest.method,
|
|
116
|
-
url:
|
|
100
|
+
url: normalizedRequest.url ?? '',
|
|
117
101
|
};
|
|
118
102
|
const params = reduceQueryParams(normalizedRequest.queryString);
|
|
119
103
|
if (Object.keys(params).length) {
|
|
120
|
-
options.params =
|
|
104
|
+
options.params = params;
|
|
121
105
|
}
|
|
122
106
|
const headers = buildHeaders(normalizedRequest);
|
|
123
107
|
if (headers) {
|
|
124
|
-
options.headers =
|
|
108
|
+
options.headers = headers;
|
|
125
109
|
}
|
|
126
110
|
if (configuration?.auth?.username && configuration?.auth?.password) {
|
|
127
111
|
options.auth = {
|
|
128
|
-
username:
|
|
129
|
-
password:
|
|
112
|
+
username: configuration.auth.username,
|
|
113
|
+
password: configuration.auth.password,
|
|
130
114
|
};
|
|
131
115
|
}
|
|
132
116
|
const { setup, data } = buildData(normalizedRequest);
|
|
133
117
|
if (data !== undefined) {
|
|
134
|
-
options.data = data
|
|
118
|
+
options.data = data;
|
|
135
119
|
}
|
|
136
120
|
const setupBlock = setup.length ? `${setup.join('\n')}\n\n` : '';
|
|
137
121
|
return `import axios from 'axios'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"curl.d.ts","sourceRoot":"","sources":["../../../../src/plugins/shell/curl/curl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"curl.d.ts","sourceRoot":"","sources":["../../../../src/plugins/shell/curl/curl.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAKpD;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,MAiKvB,CAAA"}
|
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isJsonMediaType } from '@scalar/helpers/http/is-json-media-type';
|
|
2
|
+
import { isStreamingContentType } from '@scalar/helpers/http/is-streaming-content-type';
|
|
3
|
+
import { normalizeMethod } from '../../../libs/http.js';
|
|
2
4
|
import { escapeSingleQuotes } from '../../../libs/shell.js';
|
|
3
|
-
/**
|
|
4
|
-
* True for `application/json`, any RFC 6839 `+json` structured-syntax suffix
|
|
5
|
-
* (e.g. `application/vnd.api+json`), and parameterized variants
|
|
6
|
-
* (e.g. `application/json;charset=utf-8`). Case-insensitive.
|
|
7
|
-
*/
|
|
8
|
-
const isJsonContentType = (value) => {
|
|
9
|
-
if (!value) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
const { subtype } = parseMimeType(value);
|
|
13
|
-
return subtype === 'json' || subtype.endsWith('+json');
|
|
14
|
-
};
|
|
15
5
|
/**
|
|
16
6
|
* shell/curl
|
|
17
7
|
*/
|
|
@@ -26,7 +16,7 @@ export const shellCurl = {
|
|
|
26
16
|
...request,
|
|
27
17
|
};
|
|
28
18
|
// Normalization
|
|
29
|
-
normalizedRequest.method = normalizedRequest.method
|
|
19
|
+
normalizedRequest.method = normalizeMethod(normalizedRequest.method);
|
|
30
20
|
// Build curl command parts
|
|
31
21
|
const parts = ['curl'];
|
|
32
22
|
// Build the URL, joining extra query parameters with `&` when the URL already carries a query string
|
|
@@ -93,7 +83,7 @@ export const shellCurl = {
|
|
|
93
83
|
}
|
|
94
84
|
// Body
|
|
95
85
|
if (normalizedRequest.postData) {
|
|
96
|
-
if (
|
|
86
|
+
if (isJsonMediaType(normalizedRequest.postData.mimeType)) {
|
|
97
87
|
// Pretty print JSON data
|
|
98
88
|
if (normalizedRequest.postData.text) {
|
|
99
89
|
try {
|
|
@@ -109,6 +99,11 @@ export const shellCurl = {
|
|
|
109
99
|
}
|
|
110
100
|
}
|
|
111
101
|
}
|
|
102
|
+
else if (isStreamingContentType(normalizedRequest.postData.mimeType ?? '')) {
|
|
103
|
+
// Use the explicit binary mode consistently for framed streaming media types.
|
|
104
|
+
const escapedText = escapeSingleQuotes(normalizedRequest.postData.text ?? '');
|
|
105
|
+
parts.push(`--data-binary '${escapedText}'`);
|
|
106
|
+
}
|
|
112
107
|
else if (normalizedRequest.postData.mimeType === 'application/octet-stream') {
|
|
113
108
|
const escapedText = escapeSingleQuotes(normalizedRequest.postData.text ?? '');
|
|
114
109
|
parts.push(`--data-binary '${escapedText}'`);
|
|
@@ -136,7 +131,7 @@ export const shellCurl = {
|
|
|
136
131
|
const rawValue = param.value ?? '';
|
|
137
132
|
// Pretty-print parts whose contentType is JSON so the snippet stays readable,
|
|
138
133
|
// mirroring what we already do for `--data` JSON bodies above.
|
|
139
|
-
const isJsonPart =
|
|
134
|
+
const isJsonPart = isJsonMediaType(param.contentType);
|
|
140
135
|
let displayValue = rawValue;
|
|
141
136
|
if (isJsonPart && rawValue) {
|
|
142
137
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wget.d.ts","sourceRoot":"","sources":["../../../../src/plugins/shell/wget/wget.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"wget.d.ts","sourceRoot":"","sources":["../../../../src/plugins/shell/wget/wget.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAiBpD;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,MAsFvB,CAAA"}
|
|
@@ -1,17 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isJsonMediaType } from '@scalar/helpers/http/is-json-media-type';
|
|
2
|
+
import { normalizeMethod } from '../../../libs/http.js';
|
|
2
3
|
import { escapeSingleQuotes } from '../../../libs/shell.js';
|
|
3
|
-
/**
|
|
4
|
-
* True for `application/json`, any RFC 6839 `+json` structured-syntax suffix
|
|
5
|
-
* (e.g. `application/vnd.api+json`), and parameterized variants
|
|
6
|
-
* (e.g. `application/json;charset=utf-8`). Case-insensitive.
|
|
7
|
-
*/
|
|
8
|
-
const isJsonContentType = (value) => {
|
|
9
|
-
if (!value) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
const { subtype } = parseMimeType(value);
|
|
13
|
-
return subtype === 'json' || subtype.endsWith('+json');
|
|
14
|
-
};
|
|
15
4
|
/**
|
|
16
5
|
* Pretty-prints a JSON string and falls back to the original value when it
|
|
17
6
|
* cannot be parsed. Keeps the generated snippet readable, mirroring curl.
|
|
@@ -36,7 +25,7 @@ export const shellWget = {
|
|
|
36
25
|
// against an explicit `method: undefined`, which would otherwise overwrite the default.
|
|
37
26
|
const normalizedRequest = {
|
|
38
27
|
...request,
|
|
39
|
-
method: (request?.method
|
|
28
|
+
method: normalizeMethod(request?.method),
|
|
40
29
|
};
|
|
41
30
|
// Build the URL, joining extra query parameters with `&` when the URL already carries a query string
|
|
42
31
|
const baseUrl = normalizedRequest.url ?? '';
|
|
@@ -72,7 +61,7 @@ export const shellWget = {
|
|
|
72
61
|
// Body
|
|
73
62
|
if (normalizedRequest.postData) {
|
|
74
63
|
const { mimeType, text, params } = normalizedRequest.postData;
|
|
75
|
-
if (
|
|
64
|
+
if (isJsonMediaType(mimeType)) {
|
|
76
65
|
if (text) {
|
|
77
66
|
parts.push(`--body-data '${escapeSingleQuotes(prettyPrintJson(text))}'`);
|
|
78
67
|
}
|
|
@@ -96,7 +85,7 @@ export const shellWget = {
|
|
|
96
85
|
}
|
|
97
86
|
else {
|
|
98
87
|
const rawValue = param.value ?? '';
|
|
99
|
-
const displayValue =
|
|
88
|
+
const displayValue = isJsonMediaType(param.contentType) && rawValue ? prettyPrintJson(rawValue) : rawValue;
|
|
100
89
|
parts.push(`--body-data '${escapeSingleQuotes(`${param.name}=${displayValue}`)}'`);
|
|
101
90
|
}
|
|
102
91
|
});
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"url": "git+https://github.com/scalar/scalar.git",
|
|
10
10
|
"directory": "packages/snippetz"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.10.1",
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">=22"
|
|
15
15
|
},
|
|
@@ -238,8 +238,8 @@
|
|
|
238
238
|
"CHANGELOG"
|
|
239
239
|
],
|
|
240
240
|
"dependencies": {
|
|
241
|
-
"@scalar/helpers": "0.
|
|
242
|
-
"@scalar/types": "0.
|
|
241
|
+
"@scalar/helpers": "0.14.0",
|
|
242
|
+
"@scalar/types": "0.22.0",
|
|
243
243
|
"js-base64": "^3.9.2"
|
|
244
244
|
},
|
|
245
245
|
"devDependencies": {
|