@scalar/snippetz 0.7.6 → 0.7.8

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.
@@ -16,6 +16,10 @@ export declare function buildQueryString(queryParams?: Array<{
16
16
  * Creates a new URL search params object and sets query params so we can handle arrays
17
17
  */
18
18
  export declare const createSearchParams: (query?: HarRequest["queryString"]) => URLSearchParams;
19
+ /**
20
+ * Adds a named value while preserving repeated keys as arrays.
21
+ */
22
+ export declare const accumulateRepeatedValue: (data: Record<string, string | string[]>, name: string, value: string) => void;
19
23
  /**
20
24
  * Reduces query parameters into an object while preserving repeated keys as arrays.
21
25
  */
@@ -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,kBAAkB,GAAI,QAAO,UAAU,CAAC,aAAa,CAAM,oBAQvE,CAAA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,GAAE,UAAU,CAAC,aAAa,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAiB1G;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;;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,kBAAkB,GAAI,QAAO,UAAU,CAAC,aAAa,CAAM,oBAQvE,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
@@ -27,21 +27,27 @@ export const createSearchParams = (query = []) => {
27
27
  });
28
28
  return searchParams;
29
29
  };
30
+ /**
31
+ * Adds a named value while preserving repeated keys as arrays.
32
+ */
33
+ export const accumulateRepeatedValue = (data, name, value) => {
34
+ const existingValue = data[name];
35
+ if (existingValue === undefined) {
36
+ data[name] = value;
37
+ }
38
+ else if (Array.isArray(existingValue)) {
39
+ existingValue.push(value);
40
+ }
41
+ else {
42
+ data[name] = [existingValue, value];
43
+ }
44
+ };
30
45
  /**
31
46
  * Reduces query parameters into an object while preserving repeated keys as arrays.
32
47
  */
33
48
  export function reduceQueryParams(query = []) {
34
49
  return query.reduce((acc, { name, value }) => {
35
- const existingValue = acc[name];
36
- if (existingValue === undefined) {
37
- acc[name] = value;
38
- }
39
- else if (Array.isArray(existingValue)) {
40
- existingValue.push(value);
41
- }
42
- else {
43
- acc[name] = [existingValue, value];
44
- }
50
+ accumulateRepeatedValue(acc, name, value);
45
51
  return acc;
46
52
  }, {});
47
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"curl.d.ts","sourceRoot":"","sources":["../../../../src/plugins/php/curl/curl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAIpD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAyJrB,CAAA"}
1
+ {"version":3,"file":"curl.d.ts","sourceRoot":"","sources":["../../../../src/plugins/php/curl/curl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAIpD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,MAiKrB,CAAA"}
@@ -16,6 +16,7 @@ export const phpCurl = {
16
16
  normalizedRequest.method = normalizedRequest.method.toUpperCase();
17
17
  // Build PHP cURL code parts
18
18
  const parts = [];
19
+ let hasMultipartMimeBody = false;
19
20
  // Initialize cURL
20
21
  // URL (with query parameters)
21
22
  const queryString = normalizedRequest.queryString?.length
@@ -46,12 +47,7 @@ export const phpCurl = {
46
47
  const hasContentType = () => allHeaders.some((h) => h.name.toLowerCase() === 'content-type');
47
48
  // Determine Content-Type from body before emitting headers
48
49
  if (normalizedRequest.postData) {
49
- if (normalizedRequest.postData.mimeType === 'multipart/form-data' &&
50
- normalizedRequest.postData.params &&
51
- !hasContentType()) {
52
- allHeaders.push({ name: 'Content-Type', value: 'multipart/form-data' });
53
- }
54
- else if (normalizedRequest.postData.mimeType === 'application/x-www-form-urlencoded' &&
50
+ if (normalizedRequest.postData.mimeType === 'application/x-www-form-urlencoded' &&
55
51
  normalizedRequest.postData.params &&
56
52
  !hasContentType()) {
57
53
  allHeaders.push({ name: 'Content-Type', value: 'application/x-www-form-urlencoded' });
@@ -97,17 +93,24 @@ export const phpCurl = {
97
93
  }
98
94
  }
99
95
  else if (normalizedRequest.postData.mimeType === 'multipart/form-data' && normalizedRequest.postData.params) {
100
- // Handle multipart form data
101
- const formData = normalizedRequest.postData.params.reduce((acc, param) => {
96
+ // Build multipart payload with curl_mime_* so duplicate keys remain distinct parts.
97
+ hasMultipartMimeBody = true;
98
+ parts.push('$mime = curl_mime_init($ch);');
99
+ normalizedRequest.postData.params.forEach((param, index) => {
100
+ const partName = `$part${index}`;
101
+ parts.push(`${partName} = curl_mime_addpart($mime);`);
102
+ parts.push(`curl_mime_name(${partName}, '${param.name}');`);
102
103
  if (param.fileName !== undefined) {
103
- acc.push(`'${param.name}' => '@${param.fileName}'`);
104
+ parts.push(`curl_mime_filedata(${partName}, '${param.fileName}');`);
104
105
  }
105
106
  else if (param.value !== undefined) {
106
- acc.push(`'${param.name}' => '${param.value}'`);
107
+ parts.push(`curl_mime_data(${partName}, '${param.value}');`);
108
+ }
109
+ if (param.contentType) {
110
+ parts.push(`curl_mime_type(${partName}, '${param.contentType}');`);
107
111
  }
108
- return acc;
109
- }, []);
110
- parts.push(`curl_setopt($ch, CURLOPT_POSTFIELDS, [${formData.join(', ')}]);`);
112
+ });
113
+ parts.push('curl_setopt($ch, CURLOPT_MIMEPOST, $mime);');
111
114
  }
112
115
  else if (normalizedRequest.postData.mimeType === 'application/x-www-form-urlencoded' &&
113
116
  normalizedRequest.postData.params) {
@@ -139,6 +142,9 @@ export const phpCurl = {
139
142
  // Execute and close
140
143
  parts.push('');
141
144
  parts.push('curl_exec($ch);');
145
+ if (hasMultipartMimeBody) {
146
+ parts.push('curl_mime_free($mime);');
147
+ }
142
148
  parts.push('');
143
149
  parts.push('curl_close($ch);');
144
150
  return parts.join('\n').replace(/\n\n\n/g, '\n\n');
@@ -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;AA0B7E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAC7B,aAAa,CAAC,EAAE,mBAAmB,UAuJpC"}
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;AA0B7E,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,EAC7B,aAAa,CAAC,EAAE,mBAAmB,UA2JpC"}
@@ -1,4 +1,4 @@
1
- import { reduceQueryParams } from '../../libs/http.js';
1
+ import { accumulateRepeatedValue, reduceQueryParams } from '../../libs/http.js';
2
2
  const LENGTH_CONSIDERED_AS_SHORT = 40;
3
3
  // Function to convert JavaScript boolean and null values to Python equivalents
4
4
  function convertToPythonSyntax(str) {
@@ -86,7 +86,7 @@ export function requestsLikeGenerate(clientVar, request, configuration) {
86
86
  files.push(`(${name}, (None, ${value}, ${contentType}))`);
87
87
  }
88
88
  else {
89
- formData[param.name] = param.value;
89
+ accumulateRepeatedValue(formData, param.name, param.value);
90
90
  }
91
91
  }
92
92
  });
@@ -98,7 +98,11 @@ export function requestsLikeGenerate(clientVar, request, configuration) {
98
98
  }
99
99
  }
100
100
  else if (mimeType === 'application/x-www-form-urlencoded' && params) {
101
- options.data = Object.fromEntries(params.map((p) => [p.name, p.value]));
101
+ const formData = {};
102
+ params.forEach((param) => {
103
+ accumulateRepeatedValue(formData, param.name, param.value ?? '');
104
+ });
105
+ options.data = formData;
102
106
  }
103
107
  }
104
108
  // Format all parameters
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.7.6",
12
+ "version": "0.7.8",
13
13
  "engines": {
14
14
  "node": ">=22"
15
15
  },
@@ -230,7 +230,7 @@
230
230
  "dependencies": {
231
231
  "js-base64": "^3.7.8",
232
232
  "stringify-object": "^6.0.0",
233
- "@scalar/types": "0.7.4"
233
+ "@scalar/types": "0.7.6"
234
234
  },
235
235
  "devDependencies": {
236
236
  "@types/stringify-object": "^4.0.5",