@scalar/snippetz 0.8.0 → 0.9.0
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/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +5 -4
- package/dist/libs/javascript.d.ts.map +1 -1
- package/dist/libs/javascript.js +6 -3
- package/dist/plugins/go/native/native.d.ts.map +1 -1
- package/dist/plugins/go/native/native.js +191 -5
- package/dist/plugins/js/axios/axios.d.ts +1 -2
- package/dist/plugins/js/axios/axios.d.ts.map +1 -1
- package/dist/plugins/js/axios/axios.js +2 -11
- package/dist/plugins/node/axios/axios.d.ts +1 -2
- package/dist/plugins/node/axios/axios.d.ts.map +1 -1
- package/dist/plugins/node/axios/axios.js +2 -11
- package/dist/plugins/php/laravel/index.d.ts +2 -0
- package/dist/plugins/php/laravel/index.d.ts.map +1 -0
- package/dist/plugins/php/laravel/index.js +1 -0
- package/dist/plugins/php/laravel/laravel.d.ts +6 -0
- package/dist/plugins/php/laravel/laravel.d.ts.map +1 -0
- package/dist/plugins/php/laravel/laravel.js +134 -0
- package/dist/plugins/r/httr2/httr2.d.ts +6 -0
- package/dist/plugins/r/httr2/httr2.d.ts.map +1 -0
- package/dist/plugins/r/httr2/httr2.js +159 -0
- package/dist/plugins/r/httr2/index.d.ts +2 -0
- package/dist/plugins/r/httr2/index.d.ts.map +1 -0
- package/dist/plugins/r/httr2/index.js +1 -0
- package/dist/plugins/ruby/native/native.d.ts.map +1 -1
- package/dist/plugins/ruby/native/native.js +138 -5
- package/dist/plugins/shared/axios.d.ts +3 -0
- package/dist/plugins/shared/axios.d.ts.map +1 -0
- package/dist/plugins/shared/axios.js +148 -0
- package/dist/snippetz.d.ts +1 -1
- package/package.json +12 -7
- package/dist/httpsnippet-lite/targets/go/native/client.d.ts +0 -12
- package/dist/httpsnippet-lite/targets/go/native/client.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/go/native/client.js +0 -157
- package/dist/httpsnippet-lite/targets/javascript/axios/client.d.ts +0 -12
- package/dist/httpsnippet-lite/targets/javascript/axios/client.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/javascript/axios/client.js +0 -86
- package/dist/httpsnippet-lite/targets/node/axios/client.d.ts +0 -3
- package/dist/httpsnippet-lite/targets/node/axios/client.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/node/axios/client.js +0 -78
- package/dist/httpsnippet-lite/targets/r/httr/client.d.ts +0 -12
- package/dist/httpsnippet-lite/targets/r/httr/client.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/r/httr/client.js +0 -115
- package/dist/httpsnippet-lite/targets/ruby/native/client.d.ts +0 -3
- package/dist/httpsnippet-lite/targets/ruby/native/client.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/ruby/native/client.js +0 -67
- package/dist/plugins/r/httr/httr.d.ts +0 -6
- package/dist/plugins/r/httr/httr.d.ts.map +0 -1
- package/dist/plugins/r/httr/httr.js +0 -14
- package/dist/plugins/r/httr/index.d.ts +0 -2
- package/dist/plugins/r/httr/index.d.ts.map +0 -1
- package/dist/plugins/r/httr/index.js +0 -1
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { reduceQueryParams } from '../../../libs/http.js';
|
|
2
|
+
/**
|
|
3
|
+
* Formats JSON text as an R list structure
|
|
4
|
+
*/
|
|
5
|
+
const jsonToRList = (text, indent) => {
|
|
6
|
+
try {
|
|
7
|
+
const obj = JSON.parse(text);
|
|
8
|
+
return formatRValue(obj, indent);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return `"${text}"`;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Recursively formats a JS value as R syntax
|
|
16
|
+
*/
|
|
17
|
+
const formatRValue = (value, indent) => {
|
|
18
|
+
if (value === null || value === undefined) {
|
|
19
|
+
return 'NULL';
|
|
20
|
+
}
|
|
21
|
+
if (typeof value === 'boolean') {
|
|
22
|
+
return value ? 'TRUE' : 'FALSE';
|
|
23
|
+
}
|
|
24
|
+
if (typeof value === 'number') {
|
|
25
|
+
return String(value);
|
|
26
|
+
}
|
|
27
|
+
if (typeof value === 'string') {
|
|
28
|
+
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
29
|
+
}
|
|
30
|
+
if (Array.isArray(value)) {
|
|
31
|
+
if (value.length === 0) {
|
|
32
|
+
return 'list()';
|
|
33
|
+
}
|
|
34
|
+
const items = value.map((v) => `${indent} ${formatRValue(v, indent + ' ')}`).join(',\n');
|
|
35
|
+
return `list(\n${items}\n${indent})`;
|
|
36
|
+
}
|
|
37
|
+
if (typeof value === 'object') {
|
|
38
|
+
const entries = Object.entries(value);
|
|
39
|
+
if (entries.length === 0) {
|
|
40
|
+
return 'list()';
|
|
41
|
+
}
|
|
42
|
+
const items = entries.map(([k, v]) => `${indent} ${k} = ${formatRValue(v, indent + ' ')}`).join(',\n');
|
|
43
|
+
return `list(\n${items}\n${indent})`;
|
|
44
|
+
}
|
|
45
|
+
return String(value);
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* r/httr2
|
|
49
|
+
*/
|
|
50
|
+
export const rHttr2 = {
|
|
51
|
+
target: 'r',
|
|
52
|
+
client: 'httr2',
|
|
53
|
+
title: 'httr2',
|
|
54
|
+
generate(request, configuration) {
|
|
55
|
+
const normalizedRequest = {
|
|
56
|
+
url: 'https://example.com',
|
|
57
|
+
method: 'GET',
|
|
58
|
+
...request,
|
|
59
|
+
};
|
|
60
|
+
const method = normalizedRequest.method.toUpperCase();
|
|
61
|
+
const lines = ['library(httr2)', ''];
|
|
62
|
+
// Start the pipe chain
|
|
63
|
+
lines.push(`response <- request("${normalizedRequest.url}") |>`);
|
|
64
|
+
// Collect pipe steps
|
|
65
|
+
const steps = [];
|
|
66
|
+
// Method (GET is default, so only add for non-GET)
|
|
67
|
+
if (method !== 'GET') {
|
|
68
|
+
steps.push(` req_method("${method}")`);
|
|
69
|
+
}
|
|
70
|
+
// Headers
|
|
71
|
+
const headers = {};
|
|
72
|
+
if (normalizedRequest.headers?.length) {
|
|
73
|
+
for (const header of normalizedRequest.headers) {
|
|
74
|
+
headers[header.name] = header.value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Cookies as Cookie header
|
|
78
|
+
if (normalizedRequest.cookies?.length) {
|
|
79
|
+
const cookieString = normalizedRequest.cookies.map((c) => `${c.name}=${c.value}`).join('; ');
|
|
80
|
+
headers['Cookie'] = cookieString;
|
|
81
|
+
}
|
|
82
|
+
// Auth
|
|
83
|
+
if (configuration?.auth?.username && configuration?.auth?.password) {
|
|
84
|
+
steps.push(` req_auth_basic("${configuration.auth.username}", "${configuration.auth.password}")`);
|
|
85
|
+
}
|
|
86
|
+
if (Object.keys(headers).length) {
|
|
87
|
+
const headerEntries = Object.entries(headers);
|
|
88
|
+
if (headerEntries.length === 1) {
|
|
89
|
+
const [name, value] = headerEntries[0];
|
|
90
|
+
steps.push(` req_headers("${name}" = "${value}")`);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const headerLines = headerEntries.map(([name, value]) => ` "${name}" = "${value}"`).join(',\n');
|
|
94
|
+
steps.push(` req_headers(\n${headerLines}\n )`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Query parameters
|
|
98
|
+
if (normalizedRequest.queryString?.length) {
|
|
99
|
+
const params = reduceQueryParams(normalizedRequest.queryString);
|
|
100
|
+
const entries = Object.entries(params);
|
|
101
|
+
if (entries.length === 1) {
|
|
102
|
+
const [name, value] = entries[0];
|
|
103
|
+
if (Array.isArray(value)) {
|
|
104
|
+
const items = value.map((v) => `"${v}"`).join(', ');
|
|
105
|
+
steps.push(` req_url_query("${name}" = c(${items}))`);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
steps.push(` req_url_query("${name}" = "${value}")`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
const paramLines = entries
|
|
113
|
+
.map(([name, value]) => {
|
|
114
|
+
if (Array.isArray(value)) {
|
|
115
|
+
const items = value.map((v) => `"${v}"`).join(', ');
|
|
116
|
+
return ` "${name}" = c(${items})`;
|
|
117
|
+
}
|
|
118
|
+
return ` "${name}" = "${value}"`;
|
|
119
|
+
})
|
|
120
|
+
.join(',\n');
|
|
121
|
+
steps.push(` req_url_query(\n${paramLines}\n )`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Body
|
|
125
|
+
if (normalizedRequest.postData) {
|
|
126
|
+
const { mimeType, text, params } = normalizedRequest.postData;
|
|
127
|
+
if (mimeType === 'application/json' && text) {
|
|
128
|
+
const rList = jsonToRList(text, ' ');
|
|
129
|
+
steps.push(` req_body_json(${rList})`);
|
|
130
|
+
}
|
|
131
|
+
else if (mimeType === 'multipart/form-data' && params) {
|
|
132
|
+
const paramLines = params
|
|
133
|
+
.map((p) => {
|
|
134
|
+
if (p.fileName !== undefined) {
|
|
135
|
+
return ` ${p.name} = curl::form_file("${p.fileName}")`;
|
|
136
|
+
}
|
|
137
|
+
return ` ${p.name} = "${p.value ?? ''}"`;
|
|
138
|
+
})
|
|
139
|
+
.join(',\n');
|
|
140
|
+
steps.push(` req_body_multipart(\n${paramLines}\n )`);
|
|
141
|
+
}
|
|
142
|
+
else if (mimeType === 'application/x-www-form-urlencoded' && params) {
|
|
143
|
+
const paramLines = params.map((p) => ` "${p.name}" = "${p.value ?? ''}"`).join(',\n');
|
|
144
|
+
steps.push(` req_body_form(\n${paramLines}\n )`);
|
|
145
|
+
}
|
|
146
|
+
else if (text) {
|
|
147
|
+
steps.push(` req_body_raw("${text}", type = "${mimeType ?? 'application/octet-stream'}")`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Always end with req_perform
|
|
151
|
+
steps.push(' req_perform()');
|
|
152
|
+
// Join steps with pipe operator
|
|
153
|
+
lines[lines.length - 1] = `response <- request("${normalizedRequest.url}") |>`;
|
|
154
|
+
lines.push(steps.join(' |>\n'));
|
|
155
|
+
lines.push('');
|
|
156
|
+
lines.push('resp_body_string(response)');
|
|
157
|
+
return lines.join('\n');
|
|
158
|
+
},
|
|
159
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/r/httr2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { rHttr2 } from './httr2.js';
|
|
@@ -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;AA8DpD;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAuGxB,CAAA"}
|
|
@@ -1,5 +1,51 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { buildQueryString } from '../../../libs/http.js';
|
|
2
|
+
const escapeRubyDoubleQuoted = (value) => value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
3
|
+
const escapeRubySingleQuoted = (value) => value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
4
|
+
const encodeFormComponent = (value) => encodeURIComponent(value).replace(/'/g, '%27');
|
|
5
|
+
const standardMethods = new Set([
|
|
6
|
+
'GET',
|
|
7
|
+
'POST',
|
|
8
|
+
'HEAD',
|
|
9
|
+
'DELETE',
|
|
10
|
+
'PATCH',
|
|
11
|
+
'PUT',
|
|
12
|
+
'OPTIONS',
|
|
13
|
+
'COPY',
|
|
14
|
+
'LOCK',
|
|
15
|
+
'UNLOCK',
|
|
16
|
+
'MOVE',
|
|
17
|
+
'TRACE',
|
|
18
|
+
]);
|
|
19
|
+
const toRubyMethodClass = (method) => method.charAt(0) + method.slice(1).toLowerCase();
|
|
20
|
+
const maybeAddCustomMethodClass = (lines, method, hasBody) => {
|
|
21
|
+
if (standardMethods.has(method)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const methodClass = toRubyMethodClass(method);
|
|
25
|
+
lines.push(`class Net::HTTP::${methodClass} < Net::HTTPRequest`);
|
|
26
|
+
lines.push(` METHOD = '${method}'`);
|
|
27
|
+
lines.push(` REQUEST_HAS_BODY = '${hasBody ? 'true' : 'false'}'`);
|
|
28
|
+
lines.push(' RESPONSE_HAS_BODY = true');
|
|
29
|
+
lines.push('end');
|
|
30
|
+
lines.push('');
|
|
31
|
+
};
|
|
32
|
+
const encodeUrlWithPathPreservedBrackets = (url) => {
|
|
33
|
+
try {
|
|
34
|
+
const parsedUrl = new URL(url);
|
|
35
|
+
const encodedPath = parsedUrl.pathname
|
|
36
|
+
.split('/')
|
|
37
|
+
.map((segment) => encodeURIComponent(decodeURIComponent(segment)).replace(/%5B/g, '[').replace(/%5D/g, ']').replace(/%24/g, '$'))
|
|
38
|
+
.join('/');
|
|
39
|
+
// Keep legacy behavior from the previous converter: omit trailing slash for origin-only URLs.
|
|
40
|
+
if (parsedUrl.pathname === '/') {
|
|
41
|
+
return `${parsedUrl.origin}${parsedUrl.search}${parsedUrl.hash}`;
|
|
42
|
+
}
|
|
43
|
+
return `${parsedUrl.origin}${encodedPath}${parsedUrl.search}${parsedUrl.hash}`;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return url;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
3
49
|
/**
|
|
4
50
|
* ruby/native
|
|
5
51
|
*/
|
|
@@ -7,8 +53,95 @@ export const rubyNative = {
|
|
|
7
53
|
target: 'ruby',
|
|
8
54
|
client: 'native',
|
|
9
55
|
title: 'net::http',
|
|
10
|
-
generate(request) {
|
|
11
|
-
|
|
12
|
-
|
|
56
|
+
generate(request, configuration) {
|
|
57
|
+
const normalizedRequest = {
|
|
58
|
+
method: 'GET',
|
|
59
|
+
...request,
|
|
60
|
+
};
|
|
61
|
+
normalizedRequest.method = normalizedRequest.method.toUpperCase();
|
|
62
|
+
const queryString = buildQueryString(normalizedRequest.queryString);
|
|
63
|
+
const rawUrl = `${normalizedRequest.url ?? ''}${queryString}`;
|
|
64
|
+
const encodedUrl = encodeUrlWithPathPreservedBrackets(rawUrl);
|
|
65
|
+
const lines = ["require 'uri'", "require 'net/http'", ''];
|
|
66
|
+
maybeAddCustomMethodClass(lines, normalizedRequest.method, Boolean(normalizedRequest.postData?.text));
|
|
67
|
+
lines.push(`url = URI("${escapeRubyDoubleQuoted(encodedUrl)}")`, '');
|
|
68
|
+
lines.push('http = Net::HTTP.new(url.host, url.port)');
|
|
69
|
+
if (encodedUrl.startsWith('https://')) {
|
|
70
|
+
lines.push('http.use_ssl = true');
|
|
71
|
+
}
|
|
72
|
+
lines.push('');
|
|
73
|
+
const methodClass = toRubyMethodClass(normalizedRequest.method);
|
|
74
|
+
lines.push(`request = Net::HTTP::${methodClass}.new(url)`);
|
|
75
|
+
if (configuration?.auth?.username && configuration?.auth?.password) {
|
|
76
|
+
const username = escapeRubyDoubleQuoted(configuration.auth.username);
|
|
77
|
+
const password = escapeRubyDoubleQuoted(configuration.auth.password);
|
|
78
|
+
lines.push(`request.basic_auth("${username}", "${password}")`);
|
|
79
|
+
}
|
|
80
|
+
if (normalizedRequest.headers?.length) {
|
|
81
|
+
normalizedRequest.headers.forEach((header) => {
|
|
82
|
+
lines.push(`request["${escapeRubyDoubleQuoted(header.name)}"] = '${escapeRubySingleQuoted(header.value)}'`);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (normalizedRequest.cookies?.length) {
|
|
86
|
+
const cookieString = normalizedRequest.cookies
|
|
87
|
+
.map((cookie) => `${encodeFormComponent(cookie.name)}=${encodeFormComponent(cookie.value)}`)
|
|
88
|
+
.join('; ');
|
|
89
|
+
lines.push(`request["Cookie"] = '${escapeRubySingleQuoted(cookieString)}'`);
|
|
90
|
+
}
|
|
91
|
+
if (normalizedRequest.postData) {
|
|
92
|
+
const { mimeType, text, params } = normalizedRequest.postData;
|
|
93
|
+
if (mimeType === 'application/json' && text !== undefined) {
|
|
94
|
+
try {
|
|
95
|
+
const parsed = JSON.parse(text);
|
|
96
|
+
const prettyJson = JSON.stringify(parsed, null, 2);
|
|
97
|
+
lines.push('request.body = <<~JSON');
|
|
98
|
+
lines.push(prettyJson);
|
|
99
|
+
lines.push('JSON');
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
lines.push(`request.body = ${JSON.stringify(text)}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (mimeType === 'application/x-www-form-urlencoded' && params) {
|
|
106
|
+
const encodedForm = params
|
|
107
|
+
.map((param) => `${encodeFormComponent(param.name)}=${encodeFormComponent(param.value ?? '')}`)
|
|
108
|
+
.join('&');
|
|
109
|
+
lines.push(`request.body = '${escapeRubySingleQuoted(encodedForm)}'`);
|
|
110
|
+
}
|
|
111
|
+
else if (mimeType === 'multipart/form-data' && params) {
|
|
112
|
+
lines.push('form_data = []');
|
|
113
|
+
params.forEach((param) => {
|
|
114
|
+
const name = escapeRubySingleQuoted(param.name);
|
|
115
|
+
if (param.fileName !== undefined) {
|
|
116
|
+
const fileName = escapeRubySingleQuoted(param.fileName);
|
|
117
|
+
if (param.contentType) {
|
|
118
|
+
const contentType = escapeRubySingleQuoted(param.contentType);
|
|
119
|
+
lines.push(`form_data << ['${name}', File.open('${fileName}'), { filename: '${fileName}', content_type: '${contentType}' }]`);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
lines.push(`form_data << ['${name}', File.open('${fileName}')]`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else if (param.contentType) {
|
|
126
|
+
const value = escapeRubySingleQuoted(param.value ?? '');
|
|
127
|
+
const contentType = escapeRubySingleQuoted(param.contentType);
|
|
128
|
+
lines.push(`form_data << ['${name}', '${value}', { content_type: '${contentType}' }]`);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
const value = escapeRubySingleQuoted(param.value ?? '');
|
|
132
|
+
lines.push(`form_data << ['${name}', '${value}']`);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
lines.push("request.set_form(form_data, 'multipart/form-data')");
|
|
136
|
+
}
|
|
137
|
+
else if (mimeType === 'application/octet-stream') {
|
|
138
|
+
lines.push(`request.body = ${JSON.stringify(text ?? '')}`);
|
|
139
|
+
}
|
|
140
|
+
else if (text !== undefined) {
|
|
141
|
+
lines.push(`request.body = ${JSON.stringify(text)}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
lines.push('', 'response = http.request(request)', 'puts response.read_body');
|
|
145
|
+
return lines.join('\n');
|
|
13
146
|
},
|
|
14
147
|
};
|
|
@@ -0,0 +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;AA4I9D,eAAO,MAAM,iBAAiB,GAAI,QAAQ,OAAO,CAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,CAAC,KAAG,MAmD3E,CAAA"}
|
|
@@ -0,0 +1,148 @@
|
|
|
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
|
+
};
|
|
19
|
+
const addHeaderValue = (headers, name, value) => {
|
|
20
|
+
if (value === '') {
|
|
21
|
+
headers[name] = value;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
accumulateRepeatedValue(headers, name, value);
|
|
25
|
+
};
|
|
26
|
+
const buildHeaders = (request) => {
|
|
27
|
+
const headers = {};
|
|
28
|
+
request?.headers?.forEach((header) => {
|
|
29
|
+
addHeaderValue(headers, header.name, header.value);
|
|
30
|
+
});
|
|
31
|
+
if (request?.cookies?.length) {
|
|
32
|
+
const cookieValue = request.cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join('; ');
|
|
33
|
+
addHeaderValue(headers, 'Cookie', cookieValue);
|
|
34
|
+
}
|
|
35
|
+
return Object.keys(headers).length ? headers : undefined;
|
|
36
|
+
};
|
|
37
|
+
const buildData = (request) => {
|
|
38
|
+
const setup = [];
|
|
39
|
+
const postData = request?.postData;
|
|
40
|
+
if (!postData) {
|
|
41
|
+
return { setup };
|
|
42
|
+
}
|
|
43
|
+
if (postData.mimeType === 'application/json') {
|
|
44
|
+
if (!postData.text) {
|
|
45
|
+
return { setup };
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return {
|
|
49
|
+
setup,
|
|
50
|
+
data: JSON.parse(postData.text),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return {
|
|
55
|
+
setup,
|
|
56
|
+
data: postData.text,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (postData.mimeType === 'application/x-www-form-urlencoded' && postData.params?.length) {
|
|
61
|
+
setup.push('const encodedParams = new URLSearchParams()');
|
|
62
|
+
postData.params.forEach((param) => {
|
|
63
|
+
const encodedName = escapeJsString(param.name);
|
|
64
|
+
const encodedValue = escapeJsString(param.value ?? '');
|
|
65
|
+
setup.push(`encodedParams.append('${encodedName}', '${encodedValue}')`);
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
setup,
|
|
69
|
+
data: new Raw('encodedParams'),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (postData.mimeType === 'multipart/form-data' && postData.params?.length) {
|
|
73
|
+
setup.push('const formData = new FormData()');
|
|
74
|
+
postData.params.forEach((param) => {
|
|
75
|
+
const encodedName = escapeJsString(param.name);
|
|
76
|
+
if (param.fileName !== undefined) {
|
|
77
|
+
const encodedFileName = escapeJsString(param.fileName);
|
|
78
|
+
const blobWithType = param.contentType ? `, { type: '${escapeJsString(param.contentType)}' }` : '';
|
|
79
|
+
setup.push(`formData.append('${encodedName}', new Blob([]${blobWithType}), '${encodedFileName}')`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (param.contentType) {
|
|
83
|
+
const encodedContentType = escapeJsString(param.contentType);
|
|
84
|
+
const encodedValue = escapeJsString(param.value ?? '');
|
|
85
|
+
setup.push(`formData.append('${encodedName}', new Blob(['${encodedValue}'], { type: '${encodedContentType}' }))`);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const encodedValue = escapeJsString(param.value ?? '');
|
|
89
|
+
setup.push(`formData.append('${encodedName}', '${encodedValue}')`);
|
|
90
|
+
});
|
|
91
|
+
return {
|
|
92
|
+
setup,
|
|
93
|
+
data: new Raw('formData'),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (!postData.text) {
|
|
97
|
+
return { setup };
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
setup,
|
|
101
|
+
data: postData.text,
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
export const createAxiosPlugin = (target) => ({
|
|
105
|
+
target,
|
|
106
|
+
client: 'axios',
|
|
107
|
+
title: 'Axios',
|
|
108
|
+
generate(request, configuration) {
|
|
109
|
+
const normalizedRequest = {
|
|
110
|
+
method: 'GET',
|
|
111
|
+
...request,
|
|
112
|
+
};
|
|
113
|
+
normalizedRequest.method = normalizedRequest.method.toUpperCase();
|
|
114
|
+
const options = {
|
|
115
|
+
method: normalizedRequest.method,
|
|
116
|
+
url: escapeJsString(normalizedRequest.url ?? ''),
|
|
117
|
+
};
|
|
118
|
+
const params = reduceQueryParams(normalizedRequest.queryString);
|
|
119
|
+
if (Object.keys(params).length) {
|
|
120
|
+
options.params = sanitizeForGeneratedCode(params);
|
|
121
|
+
}
|
|
122
|
+
const headers = buildHeaders(normalizedRequest);
|
|
123
|
+
if (headers) {
|
|
124
|
+
options.headers = sanitizeForGeneratedCode(headers);
|
|
125
|
+
}
|
|
126
|
+
if (configuration?.auth?.username && configuration?.auth?.password) {
|
|
127
|
+
options.auth = {
|
|
128
|
+
username: escapeJsString(configuration.auth.username),
|
|
129
|
+
password: escapeJsString(configuration.auth.password),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const { setup, data } = buildData(normalizedRequest);
|
|
133
|
+
if (data !== undefined) {
|
|
134
|
+
options.data = data instanceof Raw ? data : sanitizeForGeneratedCode(data);
|
|
135
|
+
}
|
|
136
|
+
const setupBlock = setup.length ? `${setup.join('\n')}\n\n` : '';
|
|
137
|
+
return `import axios from 'axios'
|
|
138
|
+
|
|
139
|
+
${setupBlock}const options = ${objectToString(options)}
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const { data } = await axios.request(options)
|
|
143
|
+
console.log(data)
|
|
144
|
+
} catch (error) {
|
|
145
|
+
console.error(error)
|
|
146
|
+
}`;
|
|
147
|
+
},
|
|
148
|
+
});
|
package/dist/snippetz.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare function snippetz(): {
|
|
|
7
7
|
clients(): import("@scalar/types/snippetz").Target[];
|
|
8
8
|
plugins(): {
|
|
9
9
|
target: "c" | "clojure" | "csharp" | "go" | "http" | "java" | "kotlin" | "node" | "objc" | "ocaml" | "php" | "powershell" | "python" | "r" | "ruby" | "shell" | "swift" | "dart" | "fsharp" | "js" | "rust";
|
|
10
|
-
client: "http" | "libcurl" | "clj_http" | "httpclient" | "restsharp" | "native" | "http1.1" | "asynchttp" | "nethttp" | "okhttp" | "unirest" | "axios" | "fetch" | "ofetch" | "undici" | "nsurlsession" | "cohttp" | "curl" | "guzzle" | "restmethod" | "webrequest" | "python3" | "requests" | "httpx_sync" | "httpx_async" | "
|
|
10
|
+
client: "http" | "libcurl" | "clj_http" | "httpclient" | "restsharp" | "native" | "http1.1" | "asynchttp" | "nethttp" | "okhttp" | "unirest" | "axios" | "fetch" | "ofetch" | "undici" | "nsurlsession" | "cohttp" | "curl" | "guzzle" | "laravel" | "restmethod" | "webrequest" | "python3" | "requests" | "httpx_sync" | "httpx_async" | "httr2" | "httpie" | "wget" | "jquery" | "xhr" | "reqwest";
|
|
11
11
|
}[];
|
|
12
12
|
findPlugin: <T extends TargetId>(target: T | string, client: ClientId<T> | string) => import("@scalar/types/snippetz").Plugin | undefined;
|
|
13
13
|
hasPlugin<T extends TargetId>(target: T | string, client: ClientId<T> | string): boolean;
|
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.9.0",
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">=22"
|
|
15
15
|
},
|
|
@@ -157,6 +157,11 @@
|
|
|
157
157
|
"types": "./dist/plugins/php/guzzle/index.d.ts",
|
|
158
158
|
"default": "./dist/plugins/php/guzzle/index.js"
|
|
159
159
|
},
|
|
160
|
+
"./plugins/php/laravel": {
|
|
161
|
+
"import": "./dist/plugins/php/laravel/index.js",
|
|
162
|
+
"types": "./dist/plugins/php/laravel/index.d.ts",
|
|
163
|
+
"default": "./dist/plugins/php/laravel/index.js"
|
|
164
|
+
},
|
|
160
165
|
"./plugins/powershell/restmethod": {
|
|
161
166
|
"import": "./dist/plugins/powershell/restmethod/index.js",
|
|
162
167
|
"types": "./dist/plugins/powershell/restmethod/index.d.ts",
|
|
@@ -182,10 +187,10 @@
|
|
|
182
187
|
"types": "./dist/plugins/python/requests/index.d.ts",
|
|
183
188
|
"default": "./dist/plugins/python/requests/index.js"
|
|
184
189
|
},
|
|
185
|
-
"./plugins/r/
|
|
186
|
-
"import": "./dist/plugins/r/
|
|
187
|
-
"types": "./dist/plugins/r/
|
|
188
|
-
"default": "./dist/plugins/r/
|
|
190
|
+
"./plugins/r/httr2": {
|
|
191
|
+
"import": "./dist/plugins/r/httr2/index.js",
|
|
192
|
+
"types": "./dist/plugins/r/httr2/index.d.ts",
|
|
193
|
+
"default": "./dist/plugins/r/httr2/index.js"
|
|
189
194
|
},
|
|
190
195
|
"./plugins/ruby/native": {
|
|
191
196
|
"import": "./dist/plugins/ruby/native/index.js",
|
|
@@ -230,7 +235,7 @@
|
|
|
230
235
|
"dependencies": {
|
|
231
236
|
"js-base64": "^3.7.8",
|
|
232
237
|
"stringify-object": "^6.0.0",
|
|
233
|
-
"@scalar/types": "0.
|
|
238
|
+
"@scalar/types": "0.9.0"
|
|
234
239
|
},
|
|
235
240
|
"devDependencies": {
|
|
236
241
|
"@types/stringify-object": "^4.0.5",
|
|
@@ -242,7 +247,7 @@
|
|
|
242
247
|
"generate:java-enums": "tsx scripts/generate-java-enums.ts",
|
|
243
248
|
"generate:markdown-docs": "tsx scripts/generate-markdown-docs.ts",
|
|
244
249
|
"postbuild": "pnpm generate:dotnet-enums && pnpm generate:java-enums && pnpm generate:markdown-docs",
|
|
245
|
-
"test": "vitest",
|
|
250
|
+
"test": "vitest --run",
|
|
246
251
|
"types:check": "tsc --noEmit"
|
|
247
252
|
}
|
|
248
253
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description
|
|
3
|
-
* HTTP code snippet generator for native Go.
|
|
4
|
-
*
|
|
5
|
-
* @author
|
|
6
|
-
* @montanaflynn
|
|
7
|
-
*
|
|
8
|
-
* for any questions or issues regarding the generated code snippet, please open an issue mentioning the author.
|
|
9
|
-
*/
|
|
10
|
-
import type { Client } from '../../../../httpsnippet-lite/targets/target.js';
|
|
11
|
-
export declare const native: Client;
|
|
12
|
-
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../../src/httpsnippet-lite/targets/go/native/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAA;AAE/D,eAAO,MAAM,MAAM,EAAE,MA+JpB,CAAA"}
|