@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.
- package/dist/cjs/lib/index.cjs +32 -0
- package/dist/cjs/lib/objects/camelcase-keys.cjs +3 -0
- package/dist/cjs/lib/objects/index.cjs +3 -0
- package/dist/cjs/lib/objects/normalize-object.cjs +3 -0
- package/dist/cjs/lib/strings/index.cjs +29 -0
- package/dist/cjs/lib/strings/query-string.cjs +29 -0
- package/dist/esm/lib/objects/camelcase-keys.js +3 -0
- package/dist/esm/lib/strings/query-string.js +28 -0
- package/dist/types/lib/index.d.cts +1 -1
- package/dist/types/lib/strings/index.d.cts +1 -1
- package/dist/types/lib/strings/query-string.d.cts +10 -1
- package/package.json +2 -2
package/dist/cjs/lib/index.cjs
CHANGED
|
@@ -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,
|
|
@@ -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
|
}
|
|
@@ -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.
|
|
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.
|
|
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",
|