@scalar/snippetz 0.9.0 → 0.9.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/dist/clients/index.d.ts.map +1 -1
- package/dist/clients/index.js +2 -1
- package/dist/libs/http.d.ts +29 -0
- package/dist/libs/http.d.ts.map +1 -1
- package/dist/libs/http.js +53 -0
- package/dist/plugins/c/libcurl/libcurl.d.ts.map +1 -1
- package/dist/plugins/c/libcurl/libcurl.js +145 -5
- package/dist/plugins/go/native/native.d.ts.map +1 -1
- package/dist/plugins/go/native/native.js +1 -42
- package/dist/plugins/python/aiohttp/aiohttp.d.ts +6 -0
- package/dist/plugins/python/aiohttp/aiohttp.d.ts.map +1 -0
- package/dist/plugins/python/aiohttp/aiohttp.js +107 -0
- package/dist/plugins/python/aiohttp/index.d.ts +2 -0
- package/dist/plugins/python/aiohttp/index.d.ts.map +1 -0
- package/dist/plugins/python/aiohttp/index.js +1 -0
- package/dist/plugins/python/python3/python3.d.ts.map +1 -1
- package/dist/plugins/python/python3/python3.js +192 -5
- package/dist/plugins/python/requestsLike.d.ts +2 -0
- package/dist/plugins/python/requestsLike.d.ts.map +1 -1
- package/dist/plugins/python/requestsLike.js +9 -9
- package/dist/plugins/swift/nsurlsession/nsurlsession.d.ts.map +1 -1
- package/dist/plugins/swift/nsurlsession/nsurlsession.js +118 -5
- package/dist/snippetz.d.ts +2 -2
- package/package.json +7 -2
- package/dist/httpsnippet-lite/targets/c/libcurl/client.d.ts +0 -3
- package/dist/httpsnippet-lite/targets/c/libcurl/client.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/c/libcurl/client.js +0 -74
- package/dist/httpsnippet-lite/targets/python/python3/client.d.ts +0 -12
- package/dist/httpsnippet-lite/targets/python/python3/client.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/python/python3/client.js +0 -88
- package/dist/httpsnippet-lite/targets/swift/helpers.d.ts +0 -15
- package/dist/httpsnippet-lite/targets/swift/helpers.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/swift/helpers.js +0 -70
- package/dist/httpsnippet-lite/targets/swift/nsurlsession/client.d.ts +0 -12
- package/dist/httpsnippet-lite/targets/swift/nsurlsession/client.d.ts.map +0 -1
- package/dist/httpsnippet-lite/targets/swift/nsurlsession/client.js +0 -128
|
@@ -1,5 +1,133 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { accumulateRepeatedValue, buildQueryString, normalizeRequest } from '../../../libs/http.js';
|
|
2
|
+
import { formatPythonValue } from '../../../plugins/python/requestsLike.js';
|
|
3
|
+
const createBasicAuthToken = (value) => {
|
|
4
|
+
if (typeof globalThis.btoa === 'function') {
|
|
5
|
+
return globalThis.btoa(value);
|
|
6
|
+
}
|
|
7
|
+
if (typeof Buffer !== 'undefined') {
|
|
8
|
+
return Buffer.from(value, 'utf-8').toString('base64');
|
|
9
|
+
}
|
|
10
|
+
throw new Error('Could not encode basic auth credentials');
|
|
11
|
+
};
|
|
12
|
+
const parseRequestUrl = (url) => {
|
|
13
|
+
if (!url) {
|
|
14
|
+
return new URL('https://example.com');
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
return new URL(url);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return new URL(url, 'https://example.com');
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
const mergeQueryString = (url, queryString = []) => {
|
|
24
|
+
if (!queryString.length) {
|
|
25
|
+
return url.search;
|
|
26
|
+
}
|
|
27
|
+
const serializedQuery = buildQueryString(queryString);
|
|
28
|
+
if (!url.search) {
|
|
29
|
+
return serializedQuery;
|
|
30
|
+
}
|
|
31
|
+
return `${url.search}&${serializedQuery.slice(1)}`;
|
|
32
|
+
};
|
|
33
|
+
const formatBytesLiteral = (value) => {
|
|
34
|
+
const escaped = JSON.stringify(value).slice(1, -1);
|
|
35
|
+
return `b"${escaped}"`;
|
|
36
|
+
};
|
|
37
|
+
const buildRequestBody = (request, headers, imports) => {
|
|
38
|
+
const postData = request.postData;
|
|
39
|
+
if (!postData) {
|
|
40
|
+
return {
|
|
41
|
+
payloadLines: [],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const { mimeType, text, params } = postData;
|
|
45
|
+
if (mimeType === 'application/json' && text) {
|
|
46
|
+
try {
|
|
47
|
+
const parsed = JSON.parse(text);
|
|
48
|
+
imports.add('import json');
|
|
49
|
+
return {
|
|
50
|
+
payloadLines: [`payload = json.dumps(${formatPythonValue(parsed, 0)})`],
|
|
51
|
+
payloadVariable: 'payload',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return {
|
|
56
|
+
payloadLines: [`payload = ${JSON.stringify(text)}`],
|
|
57
|
+
payloadVariable: 'payload',
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (mimeType === 'application/octet-stream' && text) {
|
|
62
|
+
return {
|
|
63
|
+
payloadLines: [`payload = ${formatBytesLiteral(text)}`],
|
|
64
|
+
payloadVariable: 'payload',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (mimeType === 'application/x-www-form-urlencoded' && params) {
|
|
68
|
+
imports.add('import urllib.parse');
|
|
69
|
+
const formData = {};
|
|
70
|
+
params.forEach((param) => {
|
|
71
|
+
accumulateRepeatedValue(formData, param.name, param.value ?? '');
|
|
72
|
+
});
|
|
73
|
+
if (!headers['Content-Type']) {
|
|
74
|
+
headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
payloadLines: [`payload = urllib.parse.urlencode(${formatPythonValue(formData, 0)}, doseq=True)`],
|
|
78
|
+
payloadVariable: 'payload',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (mimeType === 'multipart/form-data' && params) {
|
|
82
|
+
const payloadLines = ['boundary = "----ScalarSnippetzBoundary"', 'data_list = []'];
|
|
83
|
+
params.forEach((param) => {
|
|
84
|
+
payloadLines.push('data_list.append("--" + boundary)');
|
|
85
|
+
if (param.fileName !== undefined) {
|
|
86
|
+
payloadLines.push(`data_list.append(${JSON.stringify(`Content-Disposition: form-data; name="${param.name}"; filename="${param.fileName}"`)})`);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
payloadLines.push(`data_list.append(${JSON.stringify(`Content-Disposition: form-data; name="${param.name}"`)})`);
|
|
90
|
+
}
|
|
91
|
+
if (param.contentType) {
|
|
92
|
+
payloadLines.push(`data_list.append(${JSON.stringify(`Content-Type: ${param.contentType}`)})`);
|
|
93
|
+
}
|
|
94
|
+
payloadLines.push('data_list.append("")');
|
|
95
|
+
if (param.fileName !== undefined) {
|
|
96
|
+
payloadLines.push(`data_list.append(open(${JSON.stringify(param.fileName)}, "rb").read().decode("latin-1"))`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
payloadLines.push(`data_list.append(${JSON.stringify(param.value ?? '')})`);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
payloadLines.push('data_list.append("--" + boundary + "--")');
|
|
103
|
+
payloadLines.push('data_list.append("")');
|
|
104
|
+
payloadLines.push('payload = "\\r\\n".join(data_list)');
|
|
105
|
+
headers['Content-Type'] = 'multipart/form-data; boundary=----ScalarSnippetzBoundary';
|
|
106
|
+
return {
|
|
107
|
+
payloadLines,
|
|
108
|
+
payloadVariable: 'payload',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (text) {
|
|
112
|
+
try {
|
|
113
|
+
const parsed = JSON.parse(text);
|
|
114
|
+
imports.add('import json');
|
|
115
|
+
return {
|
|
116
|
+
payloadLines: [`payload = json.dumps(${formatPythonValue(parsed, 0)})`],
|
|
117
|
+
payloadVariable: 'payload',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return {
|
|
122
|
+
payloadLines: [`payload = ${JSON.stringify(text)}`],
|
|
123
|
+
payloadVariable: 'payload',
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
payloadLines: [],
|
|
129
|
+
};
|
|
130
|
+
};
|
|
3
131
|
/**
|
|
4
132
|
* python/python3
|
|
5
133
|
*/
|
|
@@ -7,8 +135,67 @@ export const pythonPython3 = {
|
|
|
7
135
|
target: 'python',
|
|
8
136
|
client: 'python3',
|
|
9
137
|
title: 'http.client',
|
|
10
|
-
generate(request) {
|
|
11
|
-
|
|
12
|
-
|
|
138
|
+
generate(request, configuration) {
|
|
139
|
+
const normalizedRequest = normalizeRequest({
|
|
140
|
+
url: 'https://example.com',
|
|
141
|
+
...request,
|
|
142
|
+
});
|
|
143
|
+
const requestUrl = normalizedRequest.url ?? 'https://example.com';
|
|
144
|
+
const parsedUrl = parseRequestUrl(requestUrl);
|
|
145
|
+
const queryString = mergeQueryString(parsedUrl, normalizedRequest.queryString);
|
|
146
|
+
const path = `${parsedUrl.pathname || '/'}${queryString}`;
|
|
147
|
+
const headers = normalizedRequest.headers?.reduce((acc, header) => {
|
|
148
|
+
if (!(header.name in acc)) {
|
|
149
|
+
acc[header.name] = header.value;
|
|
150
|
+
}
|
|
151
|
+
return acc;
|
|
152
|
+
}, {});
|
|
153
|
+
const preparedHeaders = headers ?? {};
|
|
154
|
+
if (normalizedRequest.cookies?.length) {
|
|
155
|
+
const cookieHeader = normalizedRequest.cookies
|
|
156
|
+
.map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)
|
|
157
|
+
.join('; ');
|
|
158
|
+
if (preparedHeaders.Cookie) {
|
|
159
|
+
preparedHeaders.Cookie = `${preparedHeaders.Cookie}; ${cookieHeader}`;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
preparedHeaders.Cookie = cookieHeader;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (configuration?.auth?.username && configuration.auth.password) {
|
|
166
|
+
const authValue = createBasicAuthToken(`${configuration.auth.username}:${configuration.auth.password}`);
|
|
167
|
+
preparedHeaders.Authorization = `Basic ${authValue}`;
|
|
168
|
+
}
|
|
169
|
+
const imports = new Set(['import http.client']);
|
|
170
|
+
const setupLines = [];
|
|
171
|
+
const bodyResult = buildRequestBody(normalizedRequest, preparedHeaders, imports);
|
|
172
|
+
setupLines.push(...bodyResult.payloadLines);
|
|
173
|
+
if (Object.keys(preparedHeaders).length) {
|
|
174
|
+
setupLines.push(`headers = ${formatPythonValue(preparedHeaders, 0)}`);
|
|
175
|
+
}
|
|
176
|
+
const requestArguments = [JSON.stringify(normalizedRequest.method), JSON.stringify(path)];
|
|
177
|
+
if (bodyResult.payloadVariable) {
|
|
178
|
+
requestArguments.push(`body=${bodyResult.payloadVariable}`);
|
|
179
|
+
}
|
|
180
|
+
if (Object.keys(preparedHeaders).length) {
|
|
181
|
+
requestArguments.push('headers=headers');
|
|
182
|
+
}
|
|
183
|
+
const requestCall = requestArguments.length <= 2
|
|
184
|
+
? `conn.request(${requestArguments.join(', ')})`
|
|
185
|
+
: `conn.request(\n ${requestArguments.join(',\n ')},\n)`;
|
|
186
|
+
const lines = [
|
|
187
|
+
...imports,
|
|
188
|
+
'',
|
|
189
|
+
`conn = http.client.${parsedUrl.protocol === 'https:' ? 'HTTPSConnection' : 'HTTPConnection'}(${JSON.stringify(parsedUrl.host)})`,
|
|
190
|
+
...(setupLines.length ? ['', ...setupLines] : []),
|
|
191
|
+
'',
|
|
192
|
+
requestCall,
|
|
193
|
+
'',
|
|
194
|
+
'response = conn.getresponse()',
|
|
195
|
+
'print(response.read().decode())',
|
|
196
|
+
'',
|
|
197
|
+
'conn.close()',
|
|
198
|
+
];
|
|
199
|
+
return lines.join('\n');
|
|
13
200
|
},
|
|
14
201
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { HarRequest, PluginConfiguration } from '@scalar/types/snippetz';
|
|
2
|
+
export declare const LENGTH_CONSIDERED_AS_SHORT = 40;
|
|
3
|
+
export declare function formatPythonValue(value: unknown, indentation?: number): string;
|
|
2
4
|
export declare function requestsLikeGenerate(clientVar: string, request?: Partial<HarRequest>, configuration?: PluginConfiguration): string;
|
|
3
5
|
//# sourceMappingURL=requestsLike.d.ts.map
|
|
@@ -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;
|
|
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,UAiJpC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { accumulateRepeatedValue, reduceQueryParams } from '../../libs/http.js';
|
|
2
|
-
const LENGTH_CONSIDERED_AS_SHORT = 40;
|
|
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) {
|
|
5
5
|
const replacements = [
|
|
@@ -16,6 +16,12 @@ function convertToPythonSyntax(str) {
|
|
|
16
16
|
}
|
|
17
17
|
return result;
|
|
18
18
|
}
|
|
19
|
+
export function formatPythonValue(value, indentation = 4) {
|
|
20
|
+
return convertToPythonSyntax(JSON.stringify(value, null, 2)
|
|
21
|
+
.split('\n')
|
|
22
|
+
.map((line, index) => (index === 0 ? line : ' '.repeat(indentation) + line))
|
|
23
|
+
.join('\n'));
|
|
24
|
+
}
|
|
19
25
|
export function requestsLikeGenerate(clientVar, request, configuration) {
|
|
20
26
|
// Normalize request with defaults
|
|
21
27
|
const normalizedRequest = {
|
|
@@ -127,10 +133,7 @@ export function requestsLikeGenerate(clientVar, request, configuration) {
|
|
|
127
133
|
formattedParams.push(`${key}=${filesStr}`);
|
|
128
134
|
}
|
|
129
135
|
else if (key === 'json') {
|
|
130
|
-
const jsonString =
|
|
131
|
-
.split('\n')
|
|
132
|
-
.map((line, i) => (i === 0 ? line : ' ' + line))
|
|
133
|
-
.join('\n'));
|
|
136
|
+
const jsonString = formatPythonValue(value);
|
|
134
137
|
formattedParams.push(`${key}=${jsonString}`);
|
|
135
138
|
}
|
|
136
139
|
else if (key === 'data' && normalizedRequest.postData?.mimeType === 'application/octet-stream') {
|
|
@@ -138,10 +141,7 @@ export function requestsLikeGenerate(clientVar, request, configuration) {
|
|
|
138
141
|
formattedParams.push(`${key}=b"${value}"`);
|
|
139
142
|
}
|
|
140
143
|
else {
|
|
141
|
-
const str =
|
|
142
|
-
.split('\n')
|
|
143
|
-
.map((line, i) => (i === 0 ? line : ' ' + line))
|
|
144
|
-
.join('\n'));
|
|
144
|
+
const str = formatPythonValue(value);
|
|
145
145
|
formattedParams.push(`${key}=${str}`);
|
|
146
146
|
}
|
|
147
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nsurlsession.d.ts","sourceRoot":"","sources":["../../../../src/plugins/swift/nsurlsession/nsurlsession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;
|
|
1
|
+
{"version":3,"file":"nsurlsession.d.ts","sourceRoot":"","sources":["../../../../src/plugins/swift/nsurlsession/nsurlsession.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AA+EpD;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,MA2E/B,CAAA"}
|
|
@@ -1,5 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { collectHeaders, joinUrlAndQuery, normalizeMethod, normalizeUrl } from '../../../libs/http.js';
|
|
2
|
+
const swiftStringLiteral = (value) => JSON.stringify(value);
|
|
3
|
+
const rawMultilineStringHashes = (value) => {
|
|
4
|
+
let hashCount = 1;
|
|
5
|
+
while (value.includes(`"""${'#'.repeat(hashCount)}`)) {
|
|
6
|
+
hashCount += 1;
|
|
7
|
+
}
|
|
8
|
+
return '#'.repeat(hashCount);
|
|
9
|
+
};
|
|
10
|
+
const toPrettyJson = (value) => {
|
|
11
|
+
try {
|
|
12
|
+
return JSON.stringify(JSON.parse(value), null, 2);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return value;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const encodeFormComponent = (value) => encodeURIComponent(value);
|
|
19
|
+
const escapeForMultipartHeader = (value) => value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
20
|
+
const buildMultipartBody = (params) => {
|
|
21
|
+
const lines = [
|
|
22
|
+
'let boundary = UUID().uuidString',
|
|
23
|
+
'var body = Data()',
|
|
24
|
+
'',
|
|
25
|
+
'func appendToBody(_ value: String) {',
|
|
26
|
+
' body.append(value.data(using: .utf8)!)',
|
|
27
|
+
'}',
|
|
28
|
+
'',
|
|
29
|
+
];
|
|
30
|
+
params.forEach((param) => {
|
|
31
|
+
const escapedName = escapeForMultipartHeader(param.name);
|
|
32
|
+
const escapedFileName = escapeForMultipartHeader(param.fileName ?? '');
|
|
33
|
+
const escapedContentType = param.contentType ? escapeForMultipartHeader(param.contentType) : undefined;
|
|
34
|
+
lines.push(`appendToBody("--\\(boundary)\\r\\n")`);
|
|
35
|
+
if (param.fileName !== undefined) {
|
|
36
|
+
lines.push(`appendToBody(${swiftStringLiteral(`Content-Disposition: form-data; name="${escapedName}"; filename="${escapedFileName}"\r\n`)})`);
|
|
37
|
+
if (escapedContentType) {
|
|
38
|
+
lines.push(`appendToBody(${swiftStringLiteral(`Content-Type: ${escapedContentType}\r\n`)})`);
|
|
39
|
+
}
|
|
40
|
+
lines.push('appendToBody("\\r\\n")');
|
|
41
|
+
lines.push(`appendToBody(${swiftStringLiteral(`<# File data for ${param.fileName || 'file'} #>\r\n`)})`);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
lines.push(`appendToBody(${swiftStringLiteral(`Content-Disposition: form-data; name="${escapedName}"\r\n`)})`);
|
|
45
|
+
if (escapedContentType) {
|
|
46
|
+
lines.push(`appendToBody(${swiftStringLiteral(`Content-Type: ${escapedContentType}\r\n`)})`);
|
|
47
|
+
}
|
|
48
|
+
lines.push('appendToBody("\\r\\n")');
|
|
49
|
+
lines.push(`appendToBody(${swiftStringLiteral(param.value ?? '')})`);
|
|
50
|
+
lines.push('appendToBody("\\r\\n")');
|
|
51
|
+
}
|
|
52
|
+
lines.push('');
|
|
53
|
+
});
|
|
54
|
+
lines.push('appendToBody("--\\(boundary)--\\r\\n")');
|
|
55
|
+
return lines;
|
|
56
|
+
};
|
|
3
57
|
/**
|
|
4
58
|
* swift/nsurlsession
|
|
5
59
|
*/
|
|
@@ -7,8 +61,67 @@ export const swiftNsurlsession = {
|
|
|
7
61
|
target: 'swift',
|
|
8
62
|
client: 'nsurlsession',
|
|
9
63
|
title: 'NSURLSession',
|
|
10
|
-
generate(request) {
|
|
11
|
-
|
|
12
|
-
|
|
64
|
+
generate(request, configuration) {
|
|
65
|
+
if (!request) {
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
const method = normalizeMethod(request.method);
|
|
69
|
+
const url = normalizeUrl(joinUrlAndQuery(request.url ?? '', request.queryString));
|
|
70
|
+
const headers = collectHeaders(request.headers, request.cookies);
|
|
71
|
+
const lines = [
|
|
72
|
+
'import Foundation',
|
|
73
|
+
'',
|
|
74
|
+
`var request = URLRequest(url: URL(string: ${swiftStringLiteral(url)})!)`,
|
|
75
|
+
];
|
|
76
|
+
lines.push(`request.httpMethod = ${swiftStringLiteral(method)}`);
|
|
77
|
+
headers.forEach((header) => {
|
|
78
|
+
lines.push(`request.setValue(${swiftStringLiteral(header.value)}, forHTTPHeaderField: ${swiftStringLiteral(header.name)})`);
|
|
79
|
+
});
|
|
80
|
+
if (configuration?.auth?.username && configuration?.auth?.password) {
|
|
81
|
+
lines.push(`let credentials = ${swiftStringLiteral(`${configuration.auth.username}:${configuration.auth.password}`)}`);
|
|
82
|
+
lines.push('let encodedCredentials = Data(credentials.utf8).base64EncodedString()');
|
|
83
|
+
lines.push('request.setValue("Basic \\(encodedCredentials)", forHTTPHeaderField: "Authorization")');
|
|
84
|
+
}
|
|
85
|
+
if (request.postData) {
|
|
86
|
+
const { mimeType, text, params } = request.postData;
|
|
87
|
+
if (mimeType === 'application/json' && text !== undefined) {
|
|
88
|
+
const prettyJson = toPrettyJson(text);
|
|
89
|
+
const hashes = rawMultilineStringHashes(prettyJson);
|
|
90
|
+
lines.push(`let jsonBody = ${hashes}"""`);
|
|
91
|
+
lines.push(prettyJson);
|
|
92
|
+
lines.push(`"""${hashes}`);
|
|
93
|
+
lines.push('request.httpBody = jsonBody.data(using: .utf8)');
|
|
94
|
+
}
|
|
95
|
+
else if (mimeType === 'application/x-www-form-urlencoded' && params?.length) {
|
|
96
|
+
const formBody = params
|
|
97
|
+
.map((param) => `${encodeFormComponent(param.name)}=${encodeFormComponent(param.value ?? '')}`)
|
|
98
|
+
.join('&');
|
|
99
|
+
lines.push(`let formBody = ${swiftStringLiteral(formBody)}`);
|
|
100
|
+
lines.push('request.httpBody = formBody.data(using: .utf8)');
|
|
101
|
+
}
|
|
102
|
+
else if (mimeType === 'multipart/form-data' && params?.length) {
|
|
103
|
+
lines.push(...buildMultipartBody(params));
|
|
104
|
+
lines.push('request.setValue("multipart/form-data; boundary=\\(boundary)", forHTTPHeaderField: "Content-Type")');
|
|
105
|
+
lines.push('request.httpBody = body');
|
|
106
|
+
}
|
|
107
|
+
else if (mimeType === 'application/octet-stream') {
|
|
108
|
+
lines.push(`let binaryBody = Data(${swiftStringLiteral(text ?? '')}.utf8)`);
|
|
109
|
+
lines.push('request.httpBody = binaryBody');
|
|
110
|
+
}
|
|
111
|
+
else if (text !== undefined) {
|
|
112
|
+
lines.push(`let rawBody = ${swiftStringLiteral(text)}`);
|
|
113
|
+
lines.push('request.httpBody = rawBody.data(using: .utf8)');
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
lines.push('');
|
|
117
|
+
lines.push('let (data, response) = try await URLSession.shared.data(for: request)');
|
|
118
|
+
lines.push('');
|
|
119
|
+
lines.push('guard let httpResponse = response as? HTTPURLResponse,');
|
|
120
|
+
lines.push(' 200..<300 ~= httpResponse.statusCode else {');
|
|
121
|
+
lines.push(' throw URLError(.badServerResponse)');
|
|
122
|
+
lines.push('}');
|
|
123
|
+
lines.push('');
|
|
124
|
+
lines.push('print(String(data: data, encoding: .utf8) ?? "")');
|
|
125
|
+
return lines.join('\n');
|
|
13
126
|
},
|
|
14
127
|
};
|
package/dist/snippetz.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export declare function snippetz(): {
|
|
|
6
6
|
print<T extends TargetId>(target: T, client: ClientId<T>, request: Partial<HarRequest>): string | undefined;
|
|
7
7
|
clients(): import("@scalar/types/snippetz").Target[];
|
|
8
8
|
plugins(): {
|
|
9
|
-
target: "c" | "clojure" | "csharp" | "
|
|
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" | "
|
|
9
|
+
target: "c" | "clojure" | "csharp" | "dart" | "fsharp" | "go" | "http" | "java" | "js" | "kotlin" | "node" | "objc" | "ocaml" | "php" | "powershell" | "python" | "r" | "ruby" | "rust" | "shell" | "swift";
|
|
10
|
+
client: "http" | "libcurl" | "clj_http" | "httpclient" | "restsharp" | "native" | "http1.1" | "asynchttp" | "nethttp" | "okhttp" | "unirest" | "axios" | "fetch" | "jquery" | "ofetch" | "xhr" | "undici" | "nsurlsession" | "cohttp" | "curl" | "guzzle" | "laravel" | "restmethod" | "webrequest" | "python3" | "requests" | "aiohttp" | "httpx_sync" | "httpx_async" | "httr2" | "reqwest" | "httpie" | "wget";
|
|
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.9.
|
|
12
|
+
"version": "0.9.1",
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">=22"
|
|
15
15
|
},
|
|
@@ -172,6 +172,11 @@
|
|
|
172
172
|
"types": "./dist/plugins/powershell/webrequest/index.d.ts",
|
|
173
173
|
"default": "./dist/plugins/powershell/webrequest/index.js"
|
|
174
174
|
},
|
|
175
|
+
"./plugins/python/aiohttp": {
|
|
176
|
+
"import": "./dist/plugins/python/aiohttp/index.js",
|
|
177
|
+
"types": "./dist/plugins/python/aiohttp/index.d.ts",
|
|
178
|
+
"default": "./dist/plugins/python/aiohttp/index.js"
|
|
179
|
+
},
|
|
175
180
|
"./plugins/python/httpx": {
|
|
176
181
|
"import": "./dist/plugins/python/httpx/index.js",
|
|
177
182
|
"types": "./dist/plugins/python/httpx/index.d.ts",
|
|
@@ -235,7 +240,7 @@
|
|
|
235
240
|
"dependencies": {
|
|
236
241
|
"js-base64": "^3.7.8",
|
|
237
242
|
"stringify-object": "^6.0.0",
|
|
238
|
-
"@scalar/types": "0.9.
|
|
243
|
+
"@scalar/types": "0.9.1"
|
|
239
244
|
},
|
|
240
245
|
"devDependencies": {
|
|
241
246
|
"@types/stringify-object": "^4.0.5",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../../src/httpsnippet-lite/targets/c/libcurl/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAA;AAE/D,eAAO,MAAM,OAAO,EAAE,MAqErB,CAAA"}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { CodeBuilder } from '../../../../httpsnippet-lite/helpers/code-builder.js';
|
|
2
|
-
import { escapeForDoubleQuotes } from '../../../../httpsnippet-lite/helpers/escape.js';
|
|
3
|
-
export const libcurl = {
|
|
4
|
-
info: {
|
|
5
|
-
key: 'libcurl',
|
|
6
|
-
title: 'Libcurl',
|
|
7
|
-
link: 'http://curl.haxx.se/libcurl',
|
|
8
|
-
description: 'Simple REST and HTTP API Client for C',
|
|
9
|
-
},
|
|
10
|
-
convert: ({ method, fullUrl, headersObj, allHeaders, postData }) => {
|
|
11
|
-
const { push, blank, join } = new CodeBuilder({ indent: ' ' });
|
|
12
|
-
push('CURL *hnd = curl_easy_init();');
|
|
13
|
-
blank();
|
|
14
|
-
push(`curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "${method.toUpperCase()}");`);
|
|
15
|
-
push(`curl_easy_setopt(hnd, CURLOPT_URL, "${fullUrl}");`);
|
|
16
|
-
// Add headers, including the cookies
|
|
17
|
-
const headers = Object.keys(headersObj);
|
|
18
|
-
// construct headers
|
|
19
|
-
if (headers.length) {
|
|
20
|
-
blank();
|
|
21
|
-
push('struct curl_slist *headers = NULL;');
|
|
22
|
-
headers.forEach((header) => {
|
|
23
|
-
// See https://curl.se/libcurl/c/httpcustomheader.html for syntax
|
|
24
|
-
if (headersObj[header]) {
|
|
25
|
-
push(`headers = curl_slist_append(headers, "${header}: ${escapeForDoubleQuotes(headersObj[header])}");`);
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
push(`headers = curl_slist_append(headers, "${header};");`);
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
push('curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);');
|
|
32
|
-
}
|
|
33
|
-
// construct cookies
|
|
34
|
-
if (allHeaders.cookie) {
|
|
35
|
-
blank();
|
|
36
|
-
push(`curl_easy_setopt(hnd, CURLOPT_COOKIE, "${allHeaders.cookie}");`);
|
|
37
|
-
}
|
|
38
|
-
if (postData !== null && postData !== void 0) {
|
|
39
|
-
blank();
|
|
40
|
-
if (postData.text) {
|
|
41
|
-
push(`curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, ${JSON.stringify(postData.text)});`);
|
|
42
|
-
}
|
|
43
|
-
else if (postData.mimeType === 'application/x-www-form-urlencoded' && postData.params) {
|
|
44
|
-
const formBody = postData.params
|
|
45
|
-
.map((param) => new URLSearchParams([[param.name, param.value ?? '']]).toString())
|
|
46
|
-
.join('&');
|
|
47
|
-
push(`curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, "${formBody}");`);
|
|
48
|
-
}
|
|
49
|
-
else if (postData.mimeType === 'multipart/form-data' && postData.params) {
|
|
50
|
-
push('curl_mime *mime = curl_mime_init(hnd);');
|
|
51
|
-
postData.params.forEach((param) => {
|
|
52
|
-
blank();
|
|
53
|
-
push('{');
|
|
54
|
-
push('curl_mimepart *part = curl_mime_addpart(mime);', 1);
|
|
55
|
-
if (param.name) {
|
|
56
|
-
push(`curl_mime_name(part, "${param.name}");`, 1);
|
|
57
|
-
}
|
|
58
|
-
if (param.fileName) {
|
|
59
|
-
push(`curl_mime_filedata(part, "${param.fileName}");`, 1);
|
|
60
|
-
}
|
|
61
|
-
else if (param.value) {
|
|
62
|
-
push(`curl_mime_data(part, "${escapeForDoubleQuotes(param.value)}", CURL_ZERO_TERMINATED);`, 1);
|
|
63
|
-
}
|
|
64
|
-
push('}');
|
|
65
|
-
});
|
|
66
|
-
blank();
|
|
67
|
-
push('curl_easy_setopt(hnd, CURLOPT_MIMEPOST, mime);');
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
blank();
|
|
71
|
-
push('CURLcode ret = curl_easy_perform(hnd);');
|
|
72
|
-
return join();
|
|
73
|
-
},
|
|
74
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description
|
|
3
|
-
* HTTP code snippet generator for native Python3.
|
|
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 python3: Client;
|
|
12
|
-
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../../src/httpsnippet-lite/targets/python/python3/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAA;AAE/D,eAAO,MAAM,OAAO,EAAE,MAsErB,CAAA"}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @description
|
|
3
|
-
* HTTP code snippet generator for native Python3.
|
|
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 { CodeBuilder } from '../../../../httpsnippet-lite/helpers/code-builder.js';
|
|
11
|
-
import { escapeForDoubleQuotes } from '../../../../httpsnippet-lite/helpers/escape.js';
|
|
12
|
-
export const python3 = {
|
|
13
|
-
info: {
|
|
14
|
-
key: 'python3',
|
|
15
|
-
title: 'http.client',
|
|
16
|
-
link: 'https://docs.python.org/3/library/http.client.html',
|
|
17
|
-
description: 'Python3 HTTP Client',
|
|
18
|
-
},
|
|
19
|
-
convert: ({ uriObj: { path, protocol, host }, postData, allHeaders, method }, options = {}) => {
|
|
20
|
-
const { insecureSkipVerify = false } = options;
|
|
21
|
-
const { push, blank, join } = new CodeBuilder();
|
|
22
|
-
// Start Request
|
|
23
|
-
push('import http.client');
|
|
24
|
-
if (insecureSkipVerify) {
|
|
25
|
-
push('import ssl');
|
|
26
|
-
}
|
|
27
|
-
blank();
|
|
28
|
-
// Check which protocol to be used for the client connection
|
|
29
|
-
if (protocol === 'https:') {
|
|
30
|
-
const sslContext = insecureSkipVerify ? ', context = ssl._create_unverified_context()' : '';
|
|
31
|
-
push(`conn = http.client.HTTPSConnection("${host}"${sslContext})`);
|
|
32
|
-
blank();
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
push(`conn = http.client.HTTPConnection("${host}")`);
|
|
36
|
-
blank();
|
|
37
|
-
}
|
|
38
|
-
// Create payload string if it exists
|
|
39
|
-
const payload = JSON.stringify(postData === null || postData === void 0 ? void 0 : postData.text);
|
|
40
|
-
if (payload) {
|
|
41
|
-
push(`payload = ${payload}`);
|
|
42
|
-
blank();
|
|
43
|
-
}
|
|
44
|
-
// Create Headers
|
|
45
|
-
const headers = allHeaders;
|
|
46
|
-
const headerCount = Object.keys(headers).length;
|
|
47
|
-
if (headerCount === 1) {
|
|
48
|
-
for (const header in headers) {
|
|
49
|
-
push(`headers = { '${header}': "${escapeForDoubleQuotes(headers[header])}" }`);
|
|
50
|
-
blank();
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
else if (headerCount > 1) {
|
|
54
|
-
let count = 1;
|
|
55
|
-
push('headers = {');
|
|
56
|
-
for (const header in headers) {
|
|
57
|
-
if (count++ !== headerCount) {
|
|
58
|
-
push(` '${header}': "${escapeForDoubleQuotes(headers[header])}",`);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
push(` '${header}': "${escapeForDoubleQuotes(headers[header])}"`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
push('}');
|
|
65
|
-
blank();
|
|
66
|
-
}
|
|
67
|
-
// Make Request
|
|
68
|
-
if (payload && headerCount) {
|
|
69
|
-
push(`conn.request("${method}", "${path}", payload, headers)`);
|
|
70
|
-
}
|
|
71
|
-
else if (payload && !headerCount) {
|
|
72
|
-
push(`conn.request("${method}", "${path}", payload)`);
|
|
73
|
-
}
|
|
74
|
-
else if (!payload && headerCount) {
|
|
75
|
-
push(`conn.request("${method}", "${path}", headers=headers)`);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
push(`conn.request("${method}", "${path}")`);
|
|
79
|
-
}
|
|
80
|
-
// Get Response
|
|
81
|
-
blank();
|
|
82
|
-
push('res = conn.getresponse()');
|
|
83
|
-
push('data = res.read()');
|
|
84
|
-
blank();
|
|
85
|
-
push('print(data.decode("utf-8"))');
|
|
86
|
-
return join();
|
|
87
|
-
},
|
|
88
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
interface Options {
|
|
2
|
-
indent: string;
|
|
3
|
-
pretty: boolean;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Create a string corresponding to a valid declaration and initialization of a Swift array or dictionary literal
|
|
7
|
-
*
|
|
8
|
-
* @param name Desired name of the instance
|
|
9
|
-
* @param parameters Key-value object of parameters to translate to a Swift object literal
|
|
10
|
-
* @param opts Target options
|
|
11
|
-
* @return {string}
|
|
12
|
-
*/
|
|
13
|
-
export declare const literalDeclaration: (name: string, parameters: unknown, opts: Options) => string;
|
|
14
|
-
export {};
|
|
15
|
-
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/httpsnippet-lite/targets/swift/helpers.ts"],"names":[],"mappings":"AAqBA,UAAU,OAAO;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;;GAOG;AAEH,eAAO,MAAM,kBAAkB,GAAI,MAAM,MAAM,EAAE,YAAY,OAAO,EAAE,MAAM,OAAO,WACvB,CAAA"}
|