@scalar/snippetz 0.8.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.
Files changed (82) hide show
  1. package/dist/clients/index.d.ts.map +1 -1
  2. package/dist/clients/index.js +7 -5
  3. package/dist/libs/http.d.ts +29 -0
  4. package/dist/libs/http.d.ts.map +1 -1
  5. package/dist/libs/http.js +53 -0
  6. package/dist/libs/javascript.d.ts.map +1 -1
  7. package/dist/libs/javascript.js +6 -3
  8. package/dist/plugins/c/libcurl/libcurl.d.ts.map +1 -1
  9. package/dist/plugins/c/libcurl/libcurl.js +145 -5
  10. package/dist/plugins/go/native/native.d.ts.map +1 -1
  11. package/dist/plugins/go/native/native.js +150 -5
  12. package/dist/plugins/js/axios/axios.d.ts +1 -2
  13. package/dist/plugins/js/axios/axios.d.ts.map +1 -1
  14. package/dist/plugins/js/axios/axios.js +2 -11
  15. package/dist/plugins/node/axios/axios.d.ts +1 -2
  16. package/dist/plugins/node/axios/axios.d.ts.map +1 -1
  17. package/dist/plugins/node/axios/axios.js +2 -11
  18. package/dist/plugins/php/laravel/index.d.ts +2 -0
  19. package/dist/plugins/php/laravel/index.d.ts.map +1 -0
  20. package/dist/plugins/php/laravel/index.js +1 -0
  21. package/dist/plugins/php/laravel/laravel.d.ts +6 -0
  22. package/dist/plugins/php/laravel/laravel.d.ts.map +1 -0
  23. package/dist/plugins/php/laravel/laravel.js +134 -0
  24. package/dist/plugins/python/aiohttp/aiohttp.d.ts +6 -0
  25. package/dist/plugins/python/aiohttp/aiohttp.d.ts.map +1 -0
  26. package/dist/plugins/python/aiohttp/aiohttp.js +107 -0
  27. package/dist/plugins/python/aiohttp/index.d.ts +2 -0
  28. package/dist/plugins/python/aiohttp/index.d.ts.map +1 -0
  29. package/dist/plugins/python/aiohttp/index.js +1 -0
  30. package/dist/plugins/python/python3/python3.d.ts.map +1 -1
  31. package/dist/plugins/python/python3/python3.js +192 -5
  32. package/dist/plugins/python/requestsLike.d.ts +2 -0
  33. package/dist/plugins/python/requestsLike.d.ts.map +1 -1
  34. package/dist/plugins/python/requestsLike.js +9 -9
  35. package/dist/plugins/r/httr2/httr2.d.ts +6 -0
  36. package/dist/plugins/r/httr2/httr2.d.ts.map +1 -0
  37. package/dist/plugins/r/httr2/httr2.js +159 -0
  38. package/dist/plugins/r/httr2/index.d.ts +2 -0
  39. package/dist/plugins/r/httr2/index.d.ts.map +1 -0
  40. package/dist/plugins/r/httr2/index.js +1 -0
  41. package/dist/plugins/ruby/native/native.d.ts.map +1 -1
  42. package/dist/plugins/ruby/native/native.js +138 -5
  43. package/dist/plugins/shared/axios.d.ts +3 -0
  44. package/dist/plugins/shared/axios.d.ts.map +1 -0
  45. package/dist/plugins/shared/axios.js +148 -0
  46. package/dist/plugins/swift/nsurlsession/nsurlsession.d.ts.map +1 -1
  47. package/dist/plugins/swift/nsurlsession/nsurlsession.js +118 -5
  48. package/dist/snippetz.d.ts +2 -2
  49. package/package.json +17 -7
  50. package/dist/httpsnippet-lite/targets/c/libcurl/client.d.ts +0 -3
  51. package/dist/httpsnippet-lite/targets/c/libcurl/client.d.ts.map +0 -1
  52. package/dist/httpsnippet-lite/targets/c/libcurl/client.js +0 -74
  53. package/dist/httpsnippet-lite/targets/go/native/client.d.ts +0 -12
  54. package/dist/httpsnippet-lite/targets/go/native/client.d.ts.map +0 -1
  55. package/dist/httpsnippet-lite/targets/go/native/client.js +0 -157
  56. package/dist/httpsnippet-lite/targets/javascript/axios/client.d.ts +0 -12
  57. package/dist/httpsnippet-lite/targets/javascript/axios/client.d.ts.map +0 -1
  58. package/dist/httpsnippet-lite/targets/javascript/axios/client.js +0 -86
  59. package/dist/httpsnippet-lite/targets/node/axios/client.d.ts +0 -3
  60. package/dist/httpsnippet-lite/targets/node/axios/client.d.ts.map +0 -1
  61. package/dist/httpsnippet-lite/targets/node/axios/client.js +0 -78
  62. package/dist/httpsnippet-lite/targets/python/python3/client.d.ts +0 -12
  63. package/dist/httpsnippet-lite/targets/python/python3/client.d.ts.map +0 -1
  64. package/dist/httpsnippet-lite/targets/python/python3/client.js +0 -88
  65. package/dist/httpsnippet-lite/targets/r/httr/client.d.ts +0 -12
  66. package/dist/httpsnippet-lite/targets/r/httr/client.d.ts.map +0 -1
  67. package/dist/httpsnippet-lite/targets/r/httr/client.js +0 -115
  68. package/dist/httpsnippet-lite/targets/ruby/native/client.d.ts +0 -3
  69. package/dist/httpsnippet-lite/targets/ruby/native/client.d.ts.map +0 -1
  70. package/dist/httpsnippet-lite/targets/ruby/native/client.js +0 -67
  71. package/dist/httpsnippet-lite/targets/swift/helpers.d.ts +0 -15
  72. package/dist/httpsnippet-lite/targets/swift/helpers.d.ts.map +0 -1
  73. package/dist/httpsnippet-lite/targets/swift/helpers.js +0 -70
  74. package/dist/httpsnippet-lite/targets/swift/nsurlsession/client.d.ts +0 -12
  75. package/dist/httpsnippet-lite/targets/swift/nsurlsession/client.d.ts.map +0 -1
  76. package/dist/httpsnippet-lite/targets/swift/nsurlsession/client.js +0 -128
  77. package/dist/plugins/r/httr/httr.d.ts +0 -6
  78. package/dist/plugins/r/httr/httr.d.ts.map +0 -1
  79. package/dist/plugins/r/httr/httr.js +0 -14
  80. package/dist/plugins/r/httr/index.d.ts +0 -2
  81. package/dist/plugins/r/httr/index.d.ts.map +0 -1
  82. package/dist/plugins/r/httr/index.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAyCpD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,EA+H3B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/clients/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AA2CpD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAAM,EA+H3B,CAAA"}
@@ -24,12 +24,14 @@ import { objcNsurlsession } from '../plugins/objc/nsurlsession/index.js';
24
24
  import { ocamlCohttp } from '../plugins/ocaml/cohttp/index.js';
25
25
  import { phpCurl } from '../plugins/php/curl/index.js';
26
26
  import { phpGuzzle } from '../plugins/php/guzzle/index.js';
27
+ import { phpLaravel } from '../plugins/php/laravel/index.js';
27
28
  import { powershellRestmethod } from '../plugins/powershell/restmethod/index.js';
28
29
  import { powershellWebrequest } from '../plugins/powershell/webrequest/index.js';
30
+ import { pythonAiohttp } from '../plugins/python/aiohttp/index.js';
29
31
  import { pythonHttpxAsync, pythonHttpxSync } from '../plugins/python/httpx/index.js';
30
32
  import { pythonPython3 } from '../plugins/python/python3/index.js';
31
33
  import { pythonRequests } from '../plugins/python/requests/index.js';
32
- import { rHttr } from '../plugins/r/httr/index.js';
34
+ import { rHttr2 } from '../plugins/r/httr2/index.js';
33
35
  import { rubyNative } from '../plugins/ruby/native/index.js';
34
36
  import { rustReqwest } from '../plugins/rust/reqwest/index.js';
35
37
  import { shellCurl } from '../plugins/shell/curl/index.js';
@@ -122,7 +124,7 @@ export const clients = [
122
124
  key: 'php',
123
125
  title: 'PHP',
124
126
  default: 'curl',
125
- clients: [phpCurl, phpGuzzle],
127
+ clients: [phpCurl, phpGuzzle, phpLaravel],
126
128
  },
127
129
  {
128
130
  key: 'powershell',
@@ -134,13 +136,13 @@ export const clients = [
134
136
  key: 'python',
135
137
  title: 'Python',
136
138
  default: 'python3',
137
- clients: [pythonPython3, pythonRequests, pythonHttpxSync, pythonHttpxAsync],
139
+ clients: [pythonPython3, pythonRequests, pythonAiohttp, pythonHttpxSync, pythonHttpxAsync],
138
140
  },
139
141
  {
140
142
  key: 'r',
141
143
  title: 'R',
142
- default: 'httr',
143
- clients: [rHttr],
144
+ default: 'httr2',
145
+ clients: [rHttr2],
144
146
  },
145
147
  {
146
148
  key: 'ruby',
@@ -1,4 +1,16 @@
1
1
  import type { HarRequest } from '@scalar/types/snippetz';
2
+ type HeaderPair = {
3
+ name: string;
4
+ value: string;
5
+ };
6
+ type NameValuePair = {
7
+ name: string;
8
+ value: string;
9
+ };
10
+ type NameOptionalValuePair = {
11
+ name: string;
12
+ value?: string;
13
+ };
2
14
  /**
3
15
  * Normalizes the request object with defaults
4
16
  */
@@ -12,6 +24,22 @@ export declare function buildQueryString(queryParams?: Array<{
12
24
  name: string;
13
25
  value: string;
14
26
  }>): string;
27
+ /**
28
+ * Normalizes a request method.
29
+ */
30
+ export declare const normalizeMethod: (method?: string) => string;
31
+ /**
32
+ * Normalizes URL formatting while preserving origin-only paths.
33
+ */
34
+ export declare const normalizeUrl: (url: string) => string;
35
+ /**
36
+ * Joins URL and query string while preserving existing query values.
37
+ */
38
+ export declare const joinUrlAndQuery: (url: string, queryString?: NameValuePair[]) => string;
39
+ /**
40
+ * Collects deduplicated headers and optional cookie headers.
41
+ */
42
+ export declare const collectHeaders: (headers?: NameOptionalValuePair[], cookies?: NameValuePair[]) => HeaderPair[];
15
43
  /**
16
44
  * Adds a named value while preserving repeated keys as arrays.
17
45
  */
@@ -28,4 +56,5 @@ export declare function buildUrl(baseUrl: string, queryString: string): string;
28
56
  * Processes headers and cookies into a headers object
29
57
  */
30
58
  export declare function processHeaders(request: Partial<HarRequest>): Record<string, string>;
59
+ export {};
31
60
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/libs/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAExD;;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,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,CAQ1G;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"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/libs/http.ts"],"names":[],"mappings":"AAAA,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,MAAyC,CAAA;AAE3F;;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,CAQ1G;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
@@ -17,6 +17,59 @@ export function buildQueryString(queryParams) {
17
17
  const queryPairs = queryParams.map((param) => `${param.name}=${param.value}`);
18
18
  return `?${queryPairs.join('&')}`;
19
19
  }
20
+ /**
21
+ * Normalizes a request method.
22
+ */
23
+ export const normalizeMethod = (method) => (method || 'GET').toUpperCase();
24
+ /**
25
+ * Normalizes URL formatting while preserving origin-only paths.
26
+ */
27
+ export const normalizeUrl = (url) => {
28
+ if (!url) {
29
+ return '';
30
+ }
31
+ try {
32
+ const parsedUrl = new URL(url);
33
+ if (parsedUrl.pathname === '/') {
34
+ return `${parsedUrl.origin}${parsedUrl.search}${parsedUrl.hash}`;
35
+ }
36
+ return parsedUrl.toString();
37
+ }
38
+ catch {
39
+ return url;
40
+ }
41
+ };
42
+ /**
43
+ * Joins URL and query string while preserving existing query values.
44
+ */
45
+ export const joinUrlAndQuery = (url, queryString) => {
46
+ const query = buildQueryString(queryString);
47
+ if (!query) {
48
+ return url;
49
+ }
50
+ if (!url) {
51
+ return query;
52
+ }
53
+ return `${url}${url.includes('?') ? '&' : '?'}${query.slice(1)}`;
54
+ };
55
+ /**
56
+ * Collects deduplicated headers and optional cookie headers.
57
+ */
58
+ export const collectHeaders = (headers, cookies) => {
59
+ const dedupedHeaders = new Map();
60
+ headers?.forEach((header) => {
61
+ if (header.name) {
62
+ dedupedHeaders.set(header.name, header.value ?? '');
63
+ }
64
+ });
65
+ if (cookies?.length) {
66
+ const cookieHeader = cookies
67
+ .map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`)
68
+ .join('; ');
69
+ dedupedHeaders.set('Cookie', cookieHeader);
70
+ }
71
+ return Array.from(dedupedHeaders.entries()).map(([name, value]) => ({ name, value }));
72
+ };
20
73
  /**
21
74
  * Adds a named value while preserving repeated keys as arrays.
22
75
  */
@@ -1 +1 @@
1
- {"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../src/libs/javascript.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,qBAAa,GAAG;IACK,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;CACjC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,SAAI,GAAG,MAAM,CA2D3E"}
1
+ {"version":3,"file":"javascript.d.ts","sourceRoot":"","sources":["../../src/libs/javascript.ts"],"names":[],"mappings":"AAaA;;;GAGG;AACH,qBAAa,GAAG;IACK,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;CACjC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,SAAI,GAAG,MAAM,CA2D3E"}
@@ -1,10 +1,13 @@
1
1
  /**
2
2
  * Checks if a key needs to be wrapped in quotes when used as an object property
3
3
  *
4
- * Returns true if the key contains spaces or hyphens
4
+ * Returns true when the key is not a valid JavaScript identifier.
5
5
  */
6
6
  function needsQuotes(key) {
7
- return /\s|-/.test(key);
7
+ return !/^[$A-Z_][0-9A-Z_$]*$/i.test(key);
8
+ }
9
+ function escapeObjectKey(key) {
10
+ return key.replaceAll('\\', '\\\\').replaceAll('\n', '\\n').replaceAll('\r', '\\r').replaceAll("'", "\\'");
8
11
  }
9
12
  /**
10
13
  * Represents a raw code that should not be quoted, e.g. `JSON.stringify(...)`.
@@ -29,7 +32,7 @@ export function objectToString(obj, indent = 0) {
29
32
  return '{}';
30
33
  }
31
34
  for (const [key, value] of Object.entries(obj)) {
32
- const formattedKey = needsQuotes(key) ? `'${key}'` : key;
35
+ const formattedKey = needsQuotes(key) ? `'${escapeObjectKey(key)}'` : key;
33
36
  if (value instanceof Raw) {
34
37
  const lines = value.value.split('\n');
35
38
  let formattedValue = `${value.value}`;
@@ -1 +1 @@
1
- {"version":3,"file":"libcurl.d.ts","sourceRoot":"","sources":["../../../../src/plugins/c/libcurl/libcurl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAKpD;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,MAQtB,CAAA"}
1
+ {"version":3,"file":"libcurl.d.ts","sourceRoot":"","sources":["../../../../src/plugins/c/libcurl/libcurl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,wBAAwB,CAAA;AAsEzE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,MAqHtB,CAAA"}
@@ -1,5 +1,57 @@
1
- import { libcurl } from '../../../httpsnippet-lite/targets/c/libcurl/client.js';
2
- import { convertWithHttpSnippetLite } from '../../../utils/convertWithHttpSnippetLite.js';
1
+ const normalizeMethod = (method) => (method || 'GET').toUpperCase();
2
+ const escapeCString = (value) => value
3
+ .replaceAll('\\', '\\\\')
4
+ .replaceAll('"', '\\"')
5
+ .replaceAll('\n', '\\n')
6
+ .replaceAll('\r', '\\r')
7
+ .replaceAll('\t', '\\t');
8
+ const normalizeUrl = (url) => {
9
+ if (!url) {
10
+ return '';
11
+ }
12
+ try {
13
+ const parsedUrl = new URL(url);
14
+ const shouldOmitTrailingSlash = parsedUrl.pathname === '/' && !url.endsWith('/') && !url.includes('?') && !url.includes('#');
15
+ const pathname = shouldOmitTrailingSlash ? '' : parsedUrl.pathname;
16
+ return `${parsedUrl.protocol}//${parsedUrl.host}${pathname}${parsedUrl.search}${parsedUrl.hash}`;
17
+ }
18
+ catch {
19
+ return url;
20
+ }
21
+ };
22
+ const buildUrlWithQuery = (url, queryString) => {
23
+ const query = queryString?.length ? queryString.map((param) => `${param.name}=${param.value}`).join('&') : '';
24
+ if (!query) {
25
+ return url;
26
+ }
27
+ if (!url) {
28
+ return `?${query}`;
29
+ }
30
+ return `${url}${url.includes('?') ? '&' : '?'}${query}`;
31
+ };
32
+ const buildCookieString = (cookies) => {
33
+ if (!cookies?.length) {
34
+ return null;
35
+ }
36
+ return cookies.map((cookie) => `${encodeURIComponent(cookie.name)}=${encodeURIComponent(cookie.value)}`).join('; ');
37
+ };
38
+ const buildFormUrlEncodedBody = (params) => {
39
+ if (!params?.length) {
40
+ return null;
41
+ }
42
+ return params.map((param) => new URLSearchParams([[param.name, param.value ?? '']]).toString()).join('&');
43
+ };
44
+ const formatJsonBody = (text) => {
45
+ if (text === undefined) {
46
+ return '';
47
+ }
48
+ try {
49
+ return JSON.stringify(JSON.parse(text), null, 2);
50
+ }
51
+ catch {
52
+ return text;
53
+ }
54
+ };
3
55
  /**
4
56
  * c/libcurl
5
57
  */
@@ -7,8 +59,96 @@ export const cLibcurl = {
7
59
  target: 'c',
8
60
  client: 'libcurl',
9
61
  title: 'Libcurl',
10
- generate(request) {
11
- // TODO: Write an own converter
12
- return convertWithHttpSnippetLite(libcurl, request);
62
+ generate(request, configuration) {
63
+ if (!request) {
64
+ return '';
65
+ }
66
+ const method = normalizeMethod(request.method);
67
+ const normalizedUrl = normalizeUrl(request.url ?? '');
68
+ const fullUrl = buildUrlWithQuery(normalizedUrl, request.queryString);
69
+ const hasHeaders = Boolean(request.headers?.length);
70
+ const hasCookies = Boolean(request.cookies?.length);
71
+ const body = request.postData;
72
+ const isMultipartBody = body?.mimeType === 'multipart/form-data' && Boolean(body.params?.length);
73
+ const headers = request.headers ?? [];
74
+ const shouldEnableCompression = headers.some((header) => header.name.toLowerCase() === 'accept-encoding' && /gzip|deflate/.test(header.value));
75
+ const lines = [
76
+ '#include <curl/curl.h>',
77
+ '',
78
+ 'int main(void) {',
79
+ ' curl_global_init(CURL_GLOBAL_DEFAULT);',
80
+ ' CURL *curl = curl_easy_init();',
81
+ ' if (!curl) {',
82
+ ' curl_global_cleanup();',
83
+ ' return 1;',
84
+ ' }',
85
+ '',
86
+ ` curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "${escapeCString(method)}");`,
87
+ ` curl_easy_setopt(curl, CURLOPT_URL, "${escapeCString(fullUrl)}");`,
88
+ ];
89
+ if (configuration?.auth?.username && configuration.auth.password) {
90
+ lines.push(` curl_easy_setopt(curl, CURLOPT_USERPWD, "${escapeCString(`${configuration.auth.username}:${configuration.auth.password}`)}");`);
91
+ }
92
+ if (hasHeaders) {
93
+ lines.push('', ' struct curl_slist *headers = NULL;');
94
+ headers.forEach((header) => {
95
+ lines.push(` headers = curl_slist_append(headers, "${escapeCString(`${header.name}: ${header.value}`)}");`);
96
+ });
97
+ lines.push(' curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);');
98
+ }
99
+ if (hasCookies) {
100
+ const cookieString = buildCookieString(request.cookies);
101
+ if (cookieString) {
102
+ lines.push('', ` curl_easy_setopt(curl, CURLOPT_COOKIE, "${escapeCString(cookieString)}");`);
103
+ }
104
+ }
105
+ if (shouldEnableCompression) {
106
+ lines.push('', ' curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");');
107
+ }
108
+ if (body) {
109
+ if (isMultipartBody && body.params) {
110
+ lines.push('', ' curl_mime *mime = curl_mime_init(curl);');
111
+ body.params.forEach((param) => {
112
+ lines.push('', ' {', ' curl_mimepart *part = curl_mime_addpart(mime);');
113
+ if (param.name) {
114
+ lines.push(` curl_mime_name(part, "${escapeCString(param.name)}");`);
115
+ }
116
+ if (param.fileName !== undefined) {
117
+ lines.push(` curl_mime_filedata(part, "${escapeCString(param.fileName)}");`);
118
+ }
119
+ else {
120
+ lines.push(` curl_mime_data(part, "${escapeCString(param.value ?? '')}", CURL_ZERO_TERMINATED);`);
121
+ }
122
+ if (param.contentType) {
123
+ lines.push(` curl_mime_type(part, "${escapeCString(param.contentType)}");`);
124
+ }
125
+ lines.push(' }');
126
+ });
127
+ lines.push('', ' curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);');
128
+ }
129
+ else if (body.mimeType === 'application/x-www-form-urlencoded' && body.params?.length) {
130
+ const formBody = buildFormUrlEncodedBody(body.params);
131
+ if (formBody !== null) {
132
+ lines.push('', ` curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "${escapeCString(formBody)}");`);
133
+ }
134
+ }
135
+ else if (body.mimeType === 'application/json' && body.text !== undefined) {
136
+ lines.push('', ` curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "${escapeCString(formatJsonBody(body.text))}");`);
137
+ }
138
+ else if (body.text !== undefined) {
139
+ const fallbackBody = body.mimeType === 'application/octet-stream' ? body.text : formatJsonBody(body.text);
140
+ lines.push('', ` curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "${escapeCString(fallbackBody)}");`);
141
+ }
142
+ }
143
+ lines.push('', ' CURLcode res = curl_easy_perform(curl);');
144
+ lines.push(' curl_easy_cleanup(curl);');
145
+ if (isMultipartBody) {
146
+ lines.push(' curl_mime_free(mime);');
147
+ }
148
+ if (hasHeaders) {
149
+ lines.push(' curl_slist_free_all(headers);');
150
+ }
151
+ lines.push(' curl_global_cleanup();', '', ' return (int)res;', '}');
152
+ return lines.join('\n');
13
153
  },
14
154
  };
@@ -1 +1 @@
1
- {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../../src/plugins/go/native/native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAKpD;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,MAQtB,CAAA"}
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../../src/plugins/go/native/native.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAwIpD;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,MAqEtB,CAAA"}
@@ -1,5 +1,103 @@
1
- import { native } from '../../../httpsnippet-lite/targets/go/native/client.js';
2
- import { convertWithHttpSnippetLite } from '../../../utils/convertWithHttpSnippetLite.js';
1
+ import { collectHeaders, joinUrlAndQuery, normalizeMethod, normalizeUrl } from '../../../libs/http.js';
2
+ const formatImport = (entry) => {
3
+ if (entry.includes(' ')) {
4
+ return entry;
5
+ }
6
+ return goString(entry);
7
+ };
8
+ const goString = (value) => JSON.stringify(value);
9
+ const toPrettyJson = (text) => {
10
+ if (text === undefined) {
11
+ return '';
12
+ }
13
+ try {
14
+ return JSON.stringify(JSON.parse(text), null, 2);
15
+ }
16
+ catch {
17
+ return text;
18
+ }
19
+ };
20
+ const canUseRawStringLiteral = (value) => {
21
+ return !value.includes('`');
22
+ };
23
+ const toGoStringLiteral = (value, preferRawLiteral = false) => {
24
+ if (preferRawLiteral && canUseRawStringLiteral(value)) {
25
+ return `\`${value}\``;
26
+ }
27
+ return goString(value);
28
+ };
29
+ const buildBodySection = (postData) => {
30
+ const imports = new Set();
31
+ if (!postData) {
32
+ return {
33
+ imports,
34
+ setupLines: [],
35
+ requestBody: 'nil',
36
+ needsMultipartContentTypeHeader: false,
37
+ };
38
+ }
39
+ if (postData.mimeType === 'application/x-www-form-urlencoded' && postData.params?.length) {
40
+ imports.add('neturl "net/url"');
41
+ imports.add('strings');
42
+ return {
43
+ imports,
44
+ setupLines: [
45
+ 'postData := neturl.Values{}',
46
+ ...postData.params.map((param) => `postData.Set(${goString(param.name)}, ${goString(param.value ?? '')})`),
47
+ ],
48
+ requestBody: 'strings.NewReader(postData.Encode())',
49
+ needsMultipartContentTypeHeader: false,
50
+ };
51
+ }
52
+ if (postData.mimeType === 'multipart/form-data' && postData.params?.length) {
53
+ imports.add('bytes');
54
+ imports.add('mime/multipart');
55
+ const setupLines = ['payload := &bytes.Buffer{}', 'writer := multipart.NewWriter(payload)'];
56
+ const hasFile = postData.params.some((param) => param.fileName !== undefined);
57
+ let hasDeclaredPart = false;
58
+ let hasDeclaredFile = false;
59
+ if (hasFile) {
60
+ imports.add('os');
61
+ imports.add('io');
62
+ }
63
+ postData.params.forEach((param) => {
64
+ setupLines.push('');
65
+ if (param.fileName !== undefined) {
66
+ setupLines.push(`part, _ ${hasDeclaredPart ? '=' : ':='} writer.CreateFormFile(${goString(param.name)}, ${goString(param.fileName)})`);
67
+ setupLines.push('');
68
+ setupLines.push(`f, _ ${hasDeclaredFile ? '=' : ':='} os.Open(${goString(param.fileName)})`);
69
+ setupLines.push('defer f.Close()');
70
+ setupLines.push('');
71
+ setupLines.push('_, _ = io.Copy(part, f)');
72
+ hasDeclaredPart = true;
73
+ hasDeclaredFile = true;
74
+ }
75
+ else {
76
+ setupLines.push(`_ = writer.WriteField(${goString(param.name)}, ${goString(param.value ?? '')})`);
77
+ }
78
+ });
79
+ setupLines.push('writer.Close()');
80
+ return {
81
+ imports,
82
+ setupLines,
83
+ requestBody: 'payload',
84
+ needsMultipartContentTypeHeader: true,
85
+ };
86
+ }
87
+ imports.add('strings');
88
+ const payload = postData.mimeType === 'application/json' ? toPrettyJson(postData.text) : (postData.text ?? '');
89
+ return {
90
+ imports,
91
+ setupLines: [
92
+ `payload := strings.NewReader(${toGoStringLiteral(payload, postData.mimeType === 'application/json')})`,
93
+ ],
94
+ requestBody: 'payload',
95
+ needsMultipartContentTypeHeader: false,
96
+ };
97
+ };
98
+ const buildImports = (bodyImports) => {
99
+ return Array.from(new Set(['fmt', 'io', 'net/http', ...bodyImports])).sort();
100
+ };
3
101
  /**
4
102
  * go/native
5
103
  */
@@ -7,8 +105,55 @@ export const goNative = {
7
105
  target: 'go',
8
106
  client: 'native',
9
107
  title: 'NewRequest',
10
- generate(request) {
11
- // TODO: Write an own converter
12
- return convertWithHttpSnippetLite(native, request);
108
+ generate(request, configuration) {
109
+ if (!request) {
110
+ return '';
111
+ }
112
+ const method = normalizeMethod(request.method);
113
+ const fullUrl = normalizeUrl(joinUrlAndQuery(request.url ?? '', request.queryString));
114
+ const headers = collectHeaders(request.headers, request.cookies);
115
+ const bodySection = buildBodySection(request.postData);
116
+ const imports = buildImports(bodySection.imports);
117
+ const lines = [
118
+ 'package main',
119
+ '',
120
+ 'import (',
121
+ ...imports.map((entry) => `\t${formatImport(entry)}`),
122
+ ')',
123
+ '',
124
+ 'func main() {',
125
+ `\trequestUrl := ${goString(fullUrl)}`,
126
+ '',
127
+ ...bodySection.setupLines.map((line) => (line ? `\t${line}` : '')),
128
+ ];
129
+ if (bodySection.setupLines.length) {
130
+ lines.push('');
131
+ }
132
+ lines.push(`\treq, _ := http.NewRequest(${goString(method)}, requestUrl, ${bodySection.requestBody})`);
133
+ lines.push('');
134
+ if (bodySection.needsMultipartContentTypeHeader) {
135
+ lines.push('\treq.Header.Set("Content-Type", writer.FormDataContentType())');
136
+ }
137
+ if (configuration?.auth?.username && configuration?.auth?.password) {
138
+ lines.push(`\treq.SetBasicAuth(${goString(configuration.auth.username)}, ${goString(configuration.auth.password)})`);
139
+ }
140
+ headers.forEach((header) => {
141
+ lines.push(`\treq.Header.Add(${goString(header.name)}, ${goString(header.value)})`);
142
+ });
143
+ if (bodySection.needsMultipartContentTypeHeader ||
144
+ headers.length ||
145
+ (configuration?.auth?.username && configuration.auth.password)) {
146
+ lines.push('');
147
+ }
148
+ lines.push('\tres, _ := http.DefaultClient.Do(req)');
149
+ lines.push('');
150
+ lines.push('\tdefer res.Body.Close()');
151
+ lines.push('\tbody, _ := io.ReadAll(res.Body)');
152
+ lines.push('');
153
+ lines.push('\tfmt.Println(res)');
154
+ lines.push('\tfmt.Println(string(body))');
155
+ lines.push('');
156
+ lines.push('}');
157
+ return lines.join('\n');
13
158
  },
14
159
  };
@@ -1,6 +1,5 @@
1
- import type { Plugin } from '@scalar/types/snippetz';
2
1
  /**
3
2
  * js/axios
4
3
  */
5
- export declare const jsAxios: Plugin;
4
+ export declare const jsAxios: import("@scalar/types/snippetz").Plugin;
6
5
  //# sourceMappingURL=axios.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../../../src/plugins/js/axios/axios.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAKpD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAQrB,CAAA"}
1
+ {"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../../../src/plugins/js/axios/axios.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,OAAO,yCAA0B,CAAA"}
@@ -1,14 +1,5 @@
1
- import { axios } from '../../../httpsnippet-lite/targets/javascript/axios/client.js';
2
- import { convertWithHttpSnippetLite } from '../../../utils/convertWithHttpSnippetLite.js';
1
+ import { createAxiosPlugin } from '../../../plugins/shared/axios.js';
3
2
  /**
4
3
  * js/axios
5
4
  */
6
- export const jsAxios = {
7
- target: 'js',
8
- client: 'axios',
9
- title: 'Axios',
10
- generate(request) {
11
- // TODO: Write an own converter
12
- return convertWithHttpSnippetLite(axios, request);
13
- },
14
- };
5
+ export const jsAxios = createAxiosPlugin('js');
@@ -1,6 +1,5 @@
1
- import type { Plugin } from '@scalar/types/snippetz';
2
1
  /**
3
2
  * node/axios
4
3
  */
5
- export declare const nodeAxios: Plugin;
4
+ export declare const nodeAxios: import("@scalar/types/snippetz").Plugin;
6
5
  //# sourceMappingURL=axios.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../../../src/plugins/node/axios/axios.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAKpD;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,MAQvB,CAAA"}
1
+ {"version":3,"file":"axios.d.ts","sourceRoot":"","sources":["../../../../src/plugins/node/axios/axios.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,SAAS,yCAA4B,CAAA"}
@@ -1,14 +1,5 @@
1
- import { axios } from '../../../httpsnippet-lite/targets/node/axios/client.js';
2
- import { convertWithHttpSnippetLite } from '../../../utils/convertWithHttpSnippetLite.js';
1
+ import { createAxiosPlugin } from '../../../plugins/shared/axios.js';
3
2
  /**
4
3
  * node/axios
5
4
  */
6
- export const nodeAxios = {
7
- target: 'node',
8
- client: 'axios',
9
- title: 'Axios',
10
- generate(request) {
11
- // TODO: Write an own converter
12
- return convertWithHttpSnippetLite(axios, request);
13
- },
14
- };
5
+ export const nodeAxios = createAxiosPlugin('node');
@@ -0,0 +1,2 @@
1
+ export { phpLaravel } from './laravel.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/php/laravel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1 @@
1
+ export { phpLaravel } from './laravel.js';
@@ -0,0 +1,6 @@
1
+ import type { Plugin } from '@scalar/types/snippetz';
2
+ /**
3
+ * php/laravel
4
+ */
5
+ export declare const phpLaravel: Plugin;
6
+ //# sourceMappingURL=laravel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"laravel.d.ts","sourceRoot":"","sources":["../../../../src/plugins/php/laravel/laravel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAyCpD;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,MAiIxB,CAAA"}