@splendidlabz/utils 1.11.5 → 1.12.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.
@@ -76,6 +76,7 @@ __export(lib_exports, {
76
76
  omitEmpty: () => omitEmpty,
77
77
  parseFullName: () => parseFullName,
78
78
  parseJSON: () => parseJSON,
79
+ parseQueryString: () => parseQueryString,
79
80
  parseSSE: () => parseSSE,
80
81
  pipe: () => pipe,
81
82
  pipeAsync: () => pipeAsync,
@@ -713,6 +714,9 @@ function isDigit(char) {
713
714
 
714
715
  // src/lib/objects/camelcase-keys.js
715
716
  function camelCaseKeys(obj) {
717
+ if (Array.isArray(obj)) {
718
+ return obj.map((value) => camelCaseKeys(value));
719
+ }
716
720
  if (typeof obj !== "object" || obj === null) {
717
721
  return obj;
718
722
  }
@@ -1059,6 +1063,33 @@ function toQueryString(object) {
1059
1063
  const searchParams = new URLSearchParams(object);
1060
1064
  return searchParams.toString();
1061
1065
  }
1066
+ function parseQueryString(string = "") {
1067
+ const query = string.startsWith("?") ? string.slice(1) : string;
1068
+ const result = {};
1069
+ if (!query) return result;
1070
+ const decode = (str) => decodeURIComponent(str.replace(/\+/g, " "));
1071
+ const keyToPath = (key) => key.replace(/\]/g, "").split("[").map(decode);
1072
+ for (const pair of query.split("&")) {
1073
+ if (!pair) continue;
1074
+ const eq = pair.indexOf("=");
1075
+ const path = keyToPath(eq === -1 ? pair : pair.slice(0, eq));
1076
+ const value = decode(eq === -1 ? "" : pair.slice(eq + 1));
1077
+ let current = result;
1078
+ path.forEach((key, i) => {
1079
+ const index = Array.isArray(current) ? Number(key) : key;
1080
+ if (i === path.length - 1) {
1081
+ if (key === "") current.push(value);
1082
+ else current[index] = value;
1083
+ return;
1084
+ }
1085
+ const next = path[i + 1];
1086
+ const childIsArray = next === "" || /^\d+$/.test(next);
1087
+ if (current[index] == null) current[index] = childIsArray ? [] : {};
1088
+ current = current[index];
1089
+ });
1090
+ }
1091
+ return result;
1092
+ }
1062
1093
  function plural(count, noun, suffix = "s") {
1063
1094
  console.warn("plural is deprecated. Use pluralize instead");
1064
1095
  return `${count} ${noun}${count !== 1 ? suffix : ""}`;
@@ -1135,6 +1166,7 @@ function getSymbolValue(object, description) {
1135
1166
  omitEmpty,
1136
1167
  parseFullName,
1137
1168
  parseJSON,
1169
+ parseQueryString,
1138
1170
  parseSSE,
1139
1171
  pipe,
1140
1172
  pipeAsync,
@@ -64,6 +64,9 @@ function isDigit(char) {
64
64
 
65
65
  // src/lib/objects/camelcase-keys.js
66
66
  function camelCaseKeys(obj) {
67
+ if (Array.isArray(obj)) {
68
+ return obj.map((value) => camelCaseKeys(value));
69
+ }
67
70
  if (typeof obj !== "object" || obj === null) {
68
71
  return obj;
69
72
  }
@@ -98,6 +98,9 @@ function isDigit(char) {
98
98
 
99
99
  // src/lib/objects/camelcase-keys.js
100
100
  function camelCaseKeys(obj) {
101
+ if (Array.isArray(obj)) {
102
+ return obj.map((value) => camelCaseKeys(value));
103
+ }
101
104
  if (typeof obj !== "object" || obj === null) {
102
105
  return obj;
103
106
  }
@@ -71,6 +71,9 @@ function isDigit(char) {
71
71
 
72
72
  // src/lib/objects/camelcase-keys.js
73
73
  function camelCaseKeys(obj) {
74
+ if (Array.isArray(obj)) {
75
+ return obj.map((value) => camelCaseKeys(value));
76
+ }
74
77
  if (typeof obj !== "object" || obj === null) {
75
78
  return obj;
76
79
  }
@@ -31,6 +31,7 @@ var strings_exports = {};
31
31
  __export(strings_exports, {
32
32
  markdown: () => markdown,
33
33
  parseFullName: () => parseFullName,
34
+ parseQueryString: () => parseQueryString,
34
35
  plural: () => plural,
35
36
  pluralize: () => pluralize,
36
37
  stripNumbers: () => stripNumbers,
@@ -170,6 +171,33 @@ function toQueryString(object) {
170
171
  const searchParams = new URLSearchParams(object);
171
172
  return searchParams.toString();
172
173
  }
174
+ function parseQueryString(string = "") {
175
+ const query = string.startsWith("?") ? string.slice(1) : string;
176
+ const result = {};
177
+ if (!query) return result;
178
+ const decode = (str) => decodeURIComponent(str.replace(/\+/g, " "));
179
+ const keyToPath = (key) => key.replace(/\]/g, "").split("[").map(decode);
180
+ for (const pair of query.split("&")) {
181
+ if (!pair) continue;
182
+ const eq = pair.indexOf("=");
183
+ const path = keyToPath(eq === -1 ? pair : pair.slice(0, eq));
184
+ const value = decode(eq === -1 ? "" : pair.slice(eq + 1));
185
+ let current = result;
186
+ path.forEach((key, i) => {
187
+ const index = Array.isArray(current) ? Number(key) : key;
188
+ if (i === path.length - 1) {
189
+ if (key === "") current.push(value);
190
+ else current[index] = value;
191
+ return;
192
+ }
193
+ const next = path[i + 1];
194
+ const childIsArray = next === "" || /^\d+$/.test(next);
195
+ if (current[index] == null) current[index] = childIsArray ? [] : {};
196
+ current = current[index];
197
+ });
198
+ }
199
+ return result;
200
+ }
173
201
  function plural(count, noun, suffix = "s") {
174
202
  console.warn("plural is deprecated. Use pluralize instead");
175
203
  return `${count} ${noun}${count !== 1 ? suffix : ""}`;
@@ -181,6 +209,7 @@ function stripNumbers(string) {
181
209
  0 && (module.exports = {
182
210
  markdown,
183
211
  parseFullName,
212
+ parseQueryString,
184
213
  plural,
185
214
  pluralize,
186
215
  stripNumbers,
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/lib/strings/query-string.js
20
20
  var query_string_exports = {};
21
21
  __export(query_string_exports, {
22
+ parseQueryString: () => parseQueryString,
22
23
  plural: () => plural,
23
24
  stripNumbers: () => stripNumbers,
24
25
  toQueryString: () => toQueryString
@@ -28,6 +29,33 @@ function toQueryString(object) {
28
29
  const searchParams = new URLSearchParams(object);
29
30
  return searchParams.toString();
30
31
  }
32
+ function parseQueryString(string = "") {
33
+ const query = string.startsWith("?") ? string.slice(1) : string;
34
+ const result = {};
35
+ if (!query) return result;
36
+ const decode = (str) => decodeURIComponent(str.replace(/\+/g, " "));
37
+ const keyToPath = (key) => key.replace(/\]/g, "").split("[").map(decode);
38
+ for (const pair of query.split("&")) {
39
+ if (!pair) continue;
40
+ const eq = pair.indexOf("=");
41
+ const path = keyToPath(eq === -1 ? pair : pair.slice(0, eq));
42
+ const value = decode(eq === -1 ? "" : pair.slice(eq + 1));
43
+ let current = result;
44
+ path.forEach((key, i) => {
45
+ const index = Array.isArray(current) ? Number(key) : key;
46
+ if (i === path.length - 1) {
47
+ if (key === "") current.push(value);
48
+ else current[index] = value;
49
+ return;
50
+ }
51
+ const next = path[i + 1];
52
+ const childIsArray = next === "" || /^\d+$/.test(next);
53
+ if (current[index] == null) current[index] = childIsArray ? [] : {};
54
+ current = current[index];
55
+ });
56
+ }
57
+ return result;
58
+ }
31
59
  function plural(count, noun, suffix = "s") {
32
60
  console.warn("plural is deprecated. Use pluralize instead");
33
61
  return `${count} ${noun}${count !== 1 ? suffix : ""}`;
@@ -37,6 +65,7 @@ function stripNumbers(string) {
37
65
  }
38
66
  // Annotate the CommonJS export names for ESM import in node:
39
67
  0 && (module.exports = {
68
+ parseQueryString,
40
69
  plural,
41
70
  stripNumbers,
42
71
  toQueryString
@@ -1,6 +1,9 @@
1
1
  import { objectForEach } from "./loop.js";
2
2
  import { toCamel } from "../strings/convert-case/convert-case.js";
3
3
  function camelCaseKeys(obj) {
4
+ if (Array.isArray(obj)) {
5
+ return obj.map((value) => camelCaseKeys(value));
6
+ }
4
7
  if (typeof obj !== "object" || obj === null) {
5
8
  return obj;
6
9
  }
@@ -2,6 +2,33 @@ function toQueryString(object) {
2
2
  const searchParams = new URLSearchParams(object);
3
3
  return searchParams.toString();
4
4
  }
5
+ function parseQueryString(string = "") {
6
+ const query = string.startsWith("?") ? string.slice(1) : string;
7
+ const result = {};
8
+ if (!query) return result;
9
+ const decode = (str) => decodeURIComponent(str.replace(/\+/g, " "));
10
+ const keyToPath = (key) => key.replace(/\]/g, "").split("[").map(decode);
11
+ for (const pair of query.split("&")) {
12
+ if (!pair) continue;
13
+ const eq = pair.indexOf("=");
14
+ const path = keyToPath(eq === -1 ? pair : pair.slice(0, eq));
15
+ const value = decode(eq === -1 ? "" : pair.slice(eq + 1));
16
+ let current = result;
17
+ path.forEach((key, i) => {
18
+ const index = Array.isArray(current) ? Number(key) : key;
19
+ if (i === path.length - 1) {
20
+ if (key === "") current.push(value);
21
+ else current[index] = value;
22
+ return;
23
+ }
24
+ const next = path[i + 1];
25
+ const childIsArray = next === "" || /^\d+$/.test(next);
26
+ if (current[index] == null) current[index] = childIsArray ? [] : {};
27
+ current = current[index];
28
+ });
29
+ }
30
+ return result;
31
+ }
5
32
  function plural(count, noun, suffix = "s") {
6
33
  console.warn("plural is deprecated. Use pluralize instead");
7
34
  return `${count} ${noun}${count !== 1 ? suffix : ""}`;
@@ -10,6 +37,7 @@ function stripNumbers(string) {
10
37
  return string.replace(/\d*/, "");
11
38
  }
12
39
  export {
40
+ parseQueryString,
13
41
  plural,
14
42
  stripNumbers,
15
43
  toQueryString
@@ -37,7 +37,7 @@ export { toCamel, toKebab, toLower, toPascal, toSentence, toSlug, toTitle, toUpp
37
37
  export { markdown, treatMarkdownWhitespace } from './strings/markdown.cjs';
38
38
  export { parseFullName } from './strings/name.cjs';
39
39
  export { pluralize } from './strings/pluralize.cjs';
40
- export { plural, stripNumbers, toQueryString } from './strings/query-string.cjs';
40
+ export { parseQueryString, plural, stripNumbers, toQueryString } from './strings/query-string.cjs';
41
41
  export { toStyleString } from './style/index.cjs';
42
42
  export { getSymbol, getSymbolValue } from './symbols/symbols.cjs';
43
43
  export { toDegrees, toRadians } from './numbers/math.cjs';
@@ -2,4 +2,4 @@ export { toCamel, toKebab, toLower, toPascal, toSentence, toSlug, toTitle, toUpp
2
2
  export { markdown, treatMarkdownWhitespace } from './markdown.cjs';
3
3
  export { parseFullName } from './name.cjs';
4
4
  export { pluralize } from './pluralize.cjs';
5
- export { plural, stripNumbers, toQueryString } from './query-string.cjs';
5
+ export { parseQueryString, plural, stripNumbers, toQueryString } from './query-string.cjs';
@@ -4,7 +4,16 @@
4
4
  * @returns
5
5
  */
6
6
  declare function toQueryString(object: any): string;
7
+ /**
8
+ * Parses a query string into an object, expanding bracket-notation keys into
9
+ * nested objects and arrays (e.g. `order[charges][0][reference]=23`). Decodes
10
+ * percent-encoding and treats `+` as a space. Mirrors the subset of `qs.parse`
11
+ * needed for form-urlencoded webhook payloads.
12
+ * @param {string} [string]
13
+ * @returns {Object}
14
+ */
15
+ declare function parseQueryString(string?: string): any;
7
16
  declare function plural(count: any, noun: any, suffix?: string): string;
8
17
  declare function stripNumbers(string: any): any;
9
18
 
10
- export { plural, stripNumbers, toQueryString };
19
+ export { parseQueryString, plural, stripNumbers, toQueryString };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splendidlabz/utils",
3
- "version": "1.11.5",
3
+ "version": "1.12.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "homepage": "https://splendidlabz.com/docs/utils",
@@ -69,7 +69,7 @@
69
69
  "statuses": "^2.0.2"
70
70
  },
71
71
  "devDependencies": {
72
- "@splendidlabz/eslint-config": "2.1.4",
72
+ "@splendidlabz/eslint-config": "2.1.5",
73
73
  "jsdom": "^29.0.2",
74
74
  "np": "^11.1.0",
75
75
  "tsup": "^8.5.1",