@splendidlabz/utils 1.13.0 → 1.15.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.
Files changed (51) hide show
  1. package/dist/cjs/dom/actions/index.cjs +16 -5
  2. package/dist/cjs/dom/actions/prefer-horizontal-scroll.cjs +16 -5
  3. package/dist/cjs/dom/index.cjs +47 -25
  4. package/dist/cjs/dom/pkce.cjs +16 -19
  5. package/dist/cjs/dom/query-params.cjs +6 -1
  6. package/dist/cjs/dom/sanitize.cjs +8 -1
  7. package/dist/cjs/lib/checks.cjs +7 -0
  8. package/dist/cjs/lib/form/form-data.cjs +10 -1
  9. package/dist/cjs/lib/form/index.cjs +11 -11
  10. package/dist/cjs/lib/form/sanitize.cjs +12 -10
  11. package/dist/cjs/lib/functions/index.cjs +1 -1
  12. package/dist/cjs/lib/functions/timeout.cjs +1 -1
  13. package/dist/cjs/lib/index.cjs +63 -17
  14. package/dist/cjs/lib/objects/index.cjs +58 -7
  15. package/dist/cjs/lib/objects/normalize-object.cjs +16 -5
  16. package/dist/cjs/lib/objects/omit-empty.cjs +18 -5
  17. package/dist/cjs/lib/objects/remove-invalid.cjs +61 -0
  18. package/dist/cjs/lib/objects/trim-values.cjs +47 -0
  19. package/dist/cjs/lib/promises/index.cjs +16 -5
  20. package/dist/cjs/lib/promises/reject.cjs +16 -5
  21. package/dist/cjs/lib/sse.cjs +16 -5
  22. package/dist/cjs/node/file-cache.cjs +3 -5
  23. package/dist/cjs/node/index.cjs +23 -22
  24. package/dist/cjs/node/pkce.cjs +5 -26
  25. package/dist/cjs/node/sanitize.cjs +8 -1
  26. package/dist/esm/dom/pkce.js +14 -10
  27. package/dist/esm/dom/query-params.js +6 -1
  28. package/dist/esm/lib/checks.js +6 -0
  29. package/dist/esm/lib/form/form-data.js +2 -1
  30. package/dist/esm/lib/form/sanitize.js +4 -10
  31. package/dist/esm/lib/functions/timeout.js +1 -1
  32. package/dist/esm/lib/objects/index.js +2 -0
  33. package/dist/esm/lib/objects/omit-empty.js +10 -5
  34. package/dist/esm/lib/objects/remove-invalid.js +28 -0
  35. package/dist/esm/lib/objects/trim-values.js +14 -0
  36. package/dist/esm/node/file-cache.js +3 -5
  37. package/dist/esm/node/pkce.js +5 -8
  38. package/dist/types/dom/index.d.cts +1 -1
  39. package/dist/types/dom/pkce.d.cts +29 -4
  40. package/dist/types/dom/query-params.d.cts +5 -0
  41. package/dist/types/lib/checks.d.cts +12 -2
  42. package/dist/types/lib/form/sanitize.d.cts +2 -2
  43. package/dist/types/lib/functions/timeout.d.cts +1 -1
  44. package/dist/types/lib/index.d.cts +3 -1
  45. package/dist/types/lib/objects/index.d.cts +2 -0
  46. package/dist/types/lib/objects/omit-empty.d.cts +24 -1
  47. package/dist/types/lib/objects/remove-invalid.d.cts +12 -0
  48. package/dist/types/lib/objects/trim-values.d.cts +8 -0
  49. package/dist/types/node/index.d.cts +1 -1
  50. package/dist/types/node/pkce.d.cts +29 -10
  51. package/package.json +1 -1
@@ -47,8 +47,10 @@ __export(objects_exports, {
47
47
  objectMap: () => objectMap,
48
48
  omitEmpty: () => omitEmpty,
49
49
  parseJSON: () => parseJSON,
50
+ removeInvalid: () => removeInvalid,
50
51
  sizeOf: () => sizeOf,
51
- splitObject: () => splitObject
52
+ splitObject: () => splitObject,
53
+ trimValues: () => trimValues
52
54
  });
53
55
  module.exports = __toCommonJS(objects_exports);
54
56
 
@@ -248,6 +250,11 @@ function extendObject(object) {
248
250
  function isObject(x) {
249
251
  return typeof x === "object" && !Array.isArray(x) && x !== null;
250
252
  }
253
+ function isPlainObject(x) {
254
+ if (typeof x !== "object" || x === null) return false;
255
+ const prototype = Object.getPrototypeOf(x);
256
+ return prototype === Object.prototype || prototype === null;
257
+ }
251
258
 
252
259
  // src/lib/objects/flatten.js
253
260
  function flattenObject(obj, { separator, prefix = "" }) {
@@ -289,15 +296,19 @@ function getNestedValue(object, path) {
289
296
  }
290
297
 
291
298
  // src/lib/objects/omit-empty.js
292
- function omitEmpty(obj, shallow = false) {
293
- if (typeof obj !== "object" || obj === null) return obj;
294
- if (obj instanceof Date) return obj;
299
+ function omitEmpty(obj, options = {}) {
300
+ const { shallow = false, omitFalsey = false } = typeof options === "boolean" ? { shallow: options } : options;
301
+ if (!isPlainObject(obj) && !Array.isArray(obj)) return obj;
295
302
  const result = Array.isArray(obj) ? [] : {};
296
303
  for (const [key, value] of Object.entries(obj)) {
297
- if (value === null || value === void 0 || value === "" || typeof value === "object" && !(value instanceof Date) && Object.keys(value).length === 0) {
304
+ if (value === null || value === void 0 || value === "") continue;
305
+ if (omitFalsey && !value) continue;
306
+ if ((isPlainObject(value) || Array.isArray(value)) && Object.keys(value).length === 0) {
298
307
  continue;
299
308
  }
300
- result[key] = shallow ? value : omitEmpty(value);
309
+ const filteredValue = shallow ? value : omitEmpty(value, { omitFalsey });
310
+ if (Array.isArray(result)) result.push(filteredValue);
311
+ else result[key] = filteredValue;
301
312
  }
302
313
  return result;
303
314
  }
@@ -307,6 +318,32 @@ function normalizeObject(object) {
307
318
  return pipe(omitEmpty, camelCaseKeys)(object);
308
319
  }
309
320
 
321
+ // src/lib/objects/remove-invalid.js
322
+ function removeInvalid(values, schema) {
323
+ if (!schema) return values;
324
+ if (Array.isArray(values)) {
325
+ const kept2 = [];
326
+ for (const item of values) {
327
+ if (!isValid(item, schema)) continue;
328
+ kept2.push(removeInvalid(item, schema));
329
+ }
330
+ return kept2;
331
+ }
332
+ if (!isPlainObject(values) || !isPlainObject(schema)) return values;
333
+ const kept = {};
334
+ for (const [key, value] of Object.entries(values)) {
335
+ const keySchema = schema[key];
336
+ if (!isValid(value, keySchema)) continue;
337
+ kept[key] = removeInvalid(value, keySchema);
338
+ }
339
+ return kept;
340
+ }
341
+ function isValid(value, pattern) {
342
+ if (typeof value !== "string") return true;
343
+ if (typeof pattern !== "string" && !(pattern instanceof RegExp)) return true;
344
+ return new RegExp(pattern).test(value);
345
+ }
346
+
310
347
  // src/lib/objects/size.js
311
348
  function sizeOf(obj) {
312
349
  let bytes = 0;
@@ -356,6 +393,18 @@ function splitObject(obj, keys) {
356
393
  });
357
394
  return { picked, omitted, p: picked, o: omitted };
358
395
  }
396
+
397
+ // src/lib/objects/trim-values.js
398
+ function trimValues(values) {
399
+ if (typeof values === "string") return values.trim();
400
+ if (Array.isArray(values)) return values.map(trimValues);
401
+ if (!isPlainObject(values)) return values;
402
+ const trimmed = {};
403
+ for (const [key, value] of Object.entries(values)) {
404
+ trimmed[key] = trimValues(value);
405
+ }
406
+ return trimmed;
407
+ }
359
408
  // Annotate the CommonJS export names for ESM import in node:
360
409
  0 && (module.exports = {
361
410
  camelCaseKeys,
@@ -376,6 +425,8 @@ function splitObject(obj, keys) {
376
425
  objectMap,
377
426
  omitEmpty,
378
427
  parseJSON,
428
+ removeInvalid,
379
429
  sizeOf,
380
- splitObject
430
+ splitObject,
431
+ trimValues
381
432
  });
@@ -85,16 +85,27 @@ function camelCaseKeys(obj) {
85
85
  return result;
86
86
  }
87
87
 
88
+ // src/lib/checks.js
89
+ function isPlainObject(x) {
90
+ if (typeof x !== "object" || x === null) return false;
91
+ const prototype = Object.getPrototypeOf(x);
92
+ return prototype === Object.prototype || prototype === null;
93
+ }
94
+
88
95
  // src/lib/objects/omit-empty.js
89
- function omitEmpty(obj, shallow = false) {
90
- if (typeof obj !== "object" || obj === null) return obj;
91
- if (obj instanceof Date) return obj;
96
+ function omitEmpty(obj, options = {}) {
97
+ const { shallow = false, omitFalsey = false } = typeof options === "boolean" ? { shallow: options } : options;
98
+ if (!isPlainObject(obj) && !Array.isArray(obj)) return obj;
92
99
  const result = Array.isArray(obj) ? [] : {};
93
100
  for (const [key, value] of Object.entries(obj)) {
94
- if (value === null || value === void 0 || value === "" || typeof value === "object" && !(value instanceof Date) && Object.keys(value).length === 0) {
101
+ if (value === null || value === void 0 || value === "") continue;
102
+ if (omitFalsey && !value) continue;
103
+ if ((isPlainObject(value) || Array.isArray(value)) && Object.keys(value).length === 0) {
95
104
  continue;
96
105
  }
97
- result[key] = shallow ? value : omitEmpty(value);
106
+ const filteredValue = shallow ? value : omitEmpty(value, { omitFalsey });
107
+ if (Array.isArray(result)) result.push(filteredValue);
108
+ else result[key] = filteredValue;
98
109
  }
99
110
  return result;
100
111
  }
@@ -22,15 +22,28 @@ __export(omit_empty_exports, {
22
22
  omitEmpty: () => omitEmpty
23
23
  });
24
24
  module.exports = __toCommonJS(omit_empty_exports);
25
- function omitEmpty(obj, shallow = false) {
26
- if (typeof obj !== "object" || obj === null) return obj;
27
- if (obj instanceof Date) return obj;
25
+
26
+ // src/lib/checks.js
27
+ function isPlainObject(x) {
28
+ if (typeof x !== "object" || x === null) return false;
29
+ const prototype = Object.getPrototypeOf(x);
30
+ return prototype === Object.prototype || prototype === null;
31
+ }
32
+
33
+ // src/lib/objects/omit-empty.js
34
+ function omitEmpty(obj, options = {}) {
35
+ const { shallow = false, omitFalsey = false } = typeof options === "boolean" ? { shallow: options } : options;
36
+ if (!isPlainObject(obj) && !Array.isArray(obj)) return obj;
28
37
  const result = Array.isArray(obj) ? [] : {};
29
38
  for (const [key, value] of Object.entries(obj)) {
30
- if (value === null || value === void 0 || value === "" || typeof value === "object" && !(value instanceof Date) && Object.keys(value).length === 0) {
39
+ if (value === null || value === void 0 || value === "") continue;
40
+ if (omitFalsey && !value) continue;
41
+ if ((isPlainObject(value) || Array.isArray(value)) && Object.keys(value).length === 0) {
31
42
  continue;
32
43
  }
33
- result[key] = shallow ? value : omitEmpty(value);
44
+ const filteredValue = shallow ? value : omitEmpty(value, { omitFalsey });
45
+ if (Array.isArray(result)) result.push(filteredValue);
46
+ else result[key] = filteredValue;
34
47
  }
35
48
  return result;
36
49
  }
@@ -0,0 +1,61 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/lib/objects/remove-invalid.js
20
+ var remove_invalid_exports = {};
21
+ __export(remove_invalid_exports, {
22
+ removeInvalid: () => removeInvalid
23
+ });
24
+ module.exports = __toCommonJS(remove_invalid_exports);
25
+
26
+ // src/lib/checks.js
27
+ function isPlainObject(x) {
28
+ if (typeof x !== "object" || x === null) return false;
29
+ const prototype = Object.getPrototypeOf(x);
30
+ return prototype === Object.prototype || prototype === null;
31
+ }
32
+
33
+ // src/lib/objects/remove-invalid.js
34
+ function removeInvalid(values, schema) {
35
+ if (!schema) return values;
36
+ if (Array.isArray(values)) {
37
+ const kept2 = [];
38
+ for (const item of values) {
39
+ if (!isValid(item, schema)) continue;
40
+ kept2.push(removeInvalid(item, schema));
41
+ }
42
+ return kept2;
43
+ }
44
+ if (!isPlainObject(values) || !isPlainObject(schema)) return values;
45
+ const kept = {};
46
+ for (const [key, value] of Object.entries(values)) {
47
+ const keySchema = schema[key];
48
+ if (!isValid(value, keySchema)) continue;
49
+ kept[key] = removeInvalid(value, keySchema);
50
+ }
51
+ return kept;
52
+ }
53
+ function isValid(value, pattern) {
54
+ if (typeof value !== "string") return true;
55
+ if (typeof pattern !== "string" && !(pattern instanceof RegExp)) return true;
56
+ return new RegExp(pattern).test(value);
57
+ }
58
+ // Annotate the CommonJS export names for ESM import in node:
59
+ 0 && (module.exports = {
60
+ removeInvalid
61
+ });
@@ -0,0 +1,47 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/lib/objects/trim-values.js
20
+ var trim_values_exports = {};
21
+ __export(trim_values_exports, {
22
+ trimValues: () => trimValues
23
+ });
24
+ module.exports = __toCommonJS(trim_values_exports);
25
+
26
+ // src/lib/checks.js
27
+ function isPlainObject(x) {
28
+ if (typeof x !== "object" || x === null) return false;
29
+ const prototype = Object.getPrototypeOf(x);
30
+ return prototype === Object.prototype || prototype === null;
31
+ }
32
+
33
+ // src/lib/objects/trim-values.js
34
+ function trimValues(values) {
35
+ if (typeof values === "string") return values.trim();
36
+ if (Array.isArray(values)) return values.map(trimValues);
37
+ if (!isPlainObject(values)) return values;
38
+ const trimmed = {};
39
+ for (const [key, value] of Object.entries(values)) {
40
+ trimmed[key] = trimValues(value);
41
+ }
42
+ return trimmed;
43
+ }
44
+ // Annotate the CommonJS export names for ESM import in node:
45
+ 0 && (module.exports = {
46
+ trimValues
47
+ });
@@ -23,16 +23,27 @@ __export(promises_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(promises_exports);
25
25
 
26
+ // src/lib/checks.js
27
+ function isPlainObject(x) {
28
+ if (typeof x !== "object" || x === null) return false;
29
+ const prototype = Object.getPrototypeOf(x);
30
+ return prototype === Object.prototype || prototype === null;
31
+ }
32
+
26
33
  // src/lib/objects/omit-empty.js
27
- function omitEmpty(obj, shallow = false) {
28
- if (typeof obj !== "object" || obj === null) return obj;
29
- if (obj instanceof Date) return obj;
34
+ function omitEmpty(obj, options = {}) {
35
+ const { shallow = false, omitFalsey = false } = typeof options === "boolean" ? { shallow: options } : options;
36
+ if (!isPlainObject(obj) && !Array.isArray(obj)) return obj;
30
37
  const result = Array.isArray(obj) ? [] : {};
31
38
  for (const [key, value] of Object.entries(obj)) {
32
- if (value === null || value === void 0 || value === "" || typeof value === "object" && !(value instanceof Date) && Object.keys(value).length === 0) {
39
+ if (value === null || value === void 0 || value === "") continue;
40
+ if (omitFalsey && !value) continue;
41
+ if ((isPlainObject(value) || Array.isArray(value)) && Object.keys(value).length === 0) {
33
42
  continue;
34
43
  }
35
- result[key] = shallow ? value : omitEmpty(value);
44
+ const filteredValue = shallow ? value : omitEmpty(value, { omitFalsey });
45
+ if (Array.isArray(result)) result.push(filteredValue);
46
+ else result[key] = filteredValue;
36
47
  }
37
48
  return result;
38
49
  }
@@ -23,16 +23,27 @@ __export(reject_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(reject_exports);
25
25
 
26
+ // src/lib/checks.js
27
+ function isPlainObject(x) {
28
+ if (typeof x !== "object" || x === null) return false;
29
+ const prototype = Object.getPrototypeOf(x);
30
+ return prototype === Object.prototype || prototype === null;
31
+ }
32
+
26
33
  // src/lib/objects/omit-empty.js
27
- function omitEmpty(obj, shallow = false) {
28
- if (typeof obj !== "object" || obj === null) return obj;
29
- if (obj instanceof Date) return obj;
34
+ function omitEmpty(obj, options = {}) {
35
+ const { shallow = false, omitFalsey = false } = typeof options === "boolean" ? { shallow: options } : options;
36
+ if (!isPlainObject(obj) && !Array.isArray(obj)) return obj;
30
37
  const result = Array.isArray(obj) ? [] : {};
31
38
  for (const [key, value] of Object.entries(obj)) {
32
- if (value === null || value === void 0 || value === "" || typeof value === "object" && !(value instanceof Date) && Object.keys(value).length === 0) {
39
+ if (value === null || value === void 0 || value === "") continue;
40
+ if (omitFalsey && !value) continue;
41
+ if ((isPlainObject(value) || Array.isArray(value)) && Object.keys(value).length === 0) {
33
42
  continue;
34
43
  }
35
- result[key] = shallow ? value : omitEmpty(value);
44
+ const filteredValue = shallow ? value : omitEmpty(value, { omitFalsey });
45
+ if (Array.isArray(result)) result.push(filteredValue);
46
+ else result[key] = filteredValue;
36
47
  }
37
48
  return result;
38
49
  }
@@ -33,16 +33,27 @@ function parseJSON(value, defaultValue = {}) {
33
33
  }
34
34
  }
35
35
 
36
+ // src/lib/checks.js
37
+ function isPlainObject(x) {
38
+ if (typeof x !== "object" || x === null) return false;
39
+ const prototype = Object.getPrototypeOf(x);
40
+ return prototype === Object.prototype || prototype === null;
41
+ }
42
+
36
43
  // src/lib/objects/omit-empty.js
37
- function omitEmpty(obj, shallow = false) {
38
- if (typeof obj !== "object" || obj === null) return obj;
39
- if (obj instanceof Date) return obj;
44
+ function omitEmpty(obj, options = {}) {
45
+ const { shallow = false, omitFalsey = false } = typeof options === "boolean" ? { shallow: options } : options;
46
+ if (!isPlainObject(obj) && !Array.isArray(obj)) return obj;
40
47
  const result = Array.isArray(obj) ? [] : {};
41
48
  for (const [key, value] of Object.entries(obj)) {
42
- if (value === null || value === void 0 || value === "" || typeof value === "object" && !(value instanceof Date) && Object.keys(value).length === 0) {
49
+ if (value === null || value === void 0 || value === "") continue;
50
+ if (omitFalsey && !value) continue;
51
+ if ((isPlainObject(value) || Array.isArray(value)) && Object.keys(value).length === 0) {
43
52
  continue;
44
53
  }
45
- result[key] = shallow ? value : omitEmpty(value);
54
+ const filteredValue = shallow ? value : omitEmpty(value, { omitFalsey });
55
+ if (Array.isArray(result)) result.push(filteredValue);
56
+ else result[key] = filteredValue;
46
57
  }
47
58
  return result;
48
59
  }
@@ -168,17 +168,15 @@ async function fileCache({ dir, file }) {
168
168
  async function getLastModifiedTime(globPath) {
169
169
  let files;
170
170
  if (typeof globPath === "string") {
171
- files = await (0, import_glob.glob)(removeFirstSlash(globPath));
171
+ files = await (0, import_glob.glob)(globPath);
172
172
  }
173
173
  if (Array.isArray(globPath)) {
174
- const a = await Promise.all(
175
- globPath.map((path2) => (0, import_glob.glob)(removeFirstSlash(path2)))
176
- );
174
+ const a = await Promise.all(globPath.map((path2) => (0, import_glob.glob)(path2)));
177
175
  files = a.flat();
178
176
  }
179
177
  const stats = await Promise.all(files.map((file) => import_promises.default.stat(file)));
180
178
  const timestamps = stats.map((stat) => Number(stat.mtimeMs));
181
- const sorted = sort(timestamps, { props: "mtimeMs", reverse: true });
179
+ const sorted = sort(timestamps, { reverse: true });
182
180
  return sorted[0] || 0;
183
181
  }
184
182
  async function getLatestModifiedTime(globPath) {
@@ -189,17 +189,15 @@ async function fileCache({ dir, file }) {
189
189
  async function getLastModifiedTime(globPath) {
190
190
  let files;
191
191
  if (typeof globPath === "string") {
192
- files = await (0, import_glob.glob)(removeFirstSlash(globPath));
192
+ files = await (0, import_glob.glob)(globPath);
193
193
  }
194
194
  if (Array.isArray(globPath)) {
195
- const a = await Promise.all(
196
- globPath.map((path3) => (0, import_glob.glob)(removeFirstSlash(path3)))
197
- );
195
+ const a = await Promise.all(globPath.map((path3) => (0, import_glob.glob)(path3)));
198
196
  files = a.flat();
199
197
  }
200
198
  const stats = await Promise.all(files.map((file) => import_promises.default.stat(file)));
201
199
  const timestamps = stats.map((stat) => Number(stat.mtimeMs));
202
- const sorted = sort(timestamps, { props: "mtimeMs", reverse: true });
200
+ const sorted = sort(timestamps, { reverse: true });
203
201
  return sorted[0] || 0;
204
202
  }
205
203
  async function getLatestModifiedTime(globPath) {
@@ -219,41 +217,44 @@ function sha256Hash(string) {
219
217
  }
220
218
 
221
219
  // src/node/pkce.js
222
- var import_node_crypto3 = __toESM(require("crypto"), 1);
223
-
224
- // src/node/random-string.js
225
- var import_node_crypto2 = __toESM(require("crypto"), 1);
226
- function randomString(length = 32) {
227
- const bytesNeeded = Math.ceil(length * 3 / 4) + 3;
228
- return import_node_crypto2.default.randomBytes(bytesNeeded).toString("base64").slice(0, length);
229
- }
230
-
231
- // src/node/pkce.js
220
+ var import_node_crypto2 = require("crypto");
232
221
  async function PKCE() {
233
- const codeVerifier = await randomString();
234
- const codeChallenge = await getCodeChallenge(codeVerifier);
222
+ const codeVerifier = (0, import_node_crypto2.randomBytes)(32).toString("base64url");
235
223
  return {
236
- state: await randomString(),
224
+ state: (0, import_node_crypto2.randomBytes)(32).toString("base64url"),
237
225
  code_verifier: codeVerifier,
238
- code_challenge: codeChallenge,
226
+ code_challenge: getCodeChallenge(codeVerifier),
239
227
  code_challenge_method: "S256"
240
228
  };
241
229
  }
242
230
  function getCodeChallenge(verifier) {
243
- const hash = import_node_crypto3.default.createHash("sha256").update(verifier).digest();
244
- return hash.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
231
+ return (0, import_node_crypto2.createHash)("sha256").update(verifier).digest("base64url");
232
+ }
233
+
234
+ // src/node/random-string.js
235
+ var import_node_crypto3 = __toESM(require("crypto"), 1);
236
+ function randomString(length = 32) {
237
+ const bytesNeeded = Math.ceil(length * 3 / 4) + 3;
238
+ return import_node_crypto3.default.randomBytes(bytesNeeded).toString("base64").slice(0, length);
245
239
  }
246
240
 
247
241
  // src/node/sanitize.js
248
242
  var import_sanitize_html = __toESM(require("sanitize-html"), 1);
249
243
 
244
+ // src/lib/checks.js
245
+ function isPlainObject(x) {
246
+ if (typeof x !== "object" || x === null) return false;
247
+ const prototype = Object.getPrototypeOf(x);
248
+ return prototype === Object.prototype || prototype === null;
249
+ }
250
+
250
251
  // src/lib/form/sanitize.js
251
252
  function sanitize(value, options = {}) {
252
253
  const { sanitizer, ...rest } = options;
253
254
  if (!sanitizer) throw new Error("sanitizer function is required");
254
255
  if (typeof value === "string") return sanitizer(value, rest);
255
256
  if (Array.isArray(value)) return sanitizeArray(value, { sanitizer, ...rest });
256
- if (value && typeof value === "object") {
257
+ if (isPlainObject(value)) {
257
258
  return Object.fromEntries(
258
259
  Object.entries(value).map(([key, val]) => [
259
260
  key,
@@ -1,8 +1,6 @@
1
- var __create = Object.create;
2
1
  var __defProp = Object.defineProperty;
3
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
5
  var __export = (target, all) => {
8
6
  for (var name in all)
@@ -16,14 +14,6 @@ var __copyProps = (to, from, except, desc) => {
16
14
  }
17
15
  return to;
18
16
  };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
18
 
29
19
  // src/node/pkce.js
@@ -33,29 +23,18 @@ __export(pkce_exports, {
33
23
  getCodeChallenge: () => getCodeChallenge
34
24
  });
35
25
  module.exports = __toCommonJS(pkce_exports);
36
- var import_node_crypto2 = __toESM(require("crypto"), 1);
37
-
38
- // src/node/random-string.js
39
- var import_node_crypto = __toESM(require("crypto"), 1);
40
- function randomString(length = 32) {
41
- const bytesNeeded = Math.ceil(length * 3 / 4) + 3;
42
- return import_node_crypto.default.randomBytes(bytesNeeded).toString("base64").slice(0, length);
43
- }
44
-
45
- // src/node/pkce.js
26
+ var import_node_crypto = require("crypto");
46
27
  async function PKCE() {
47
- const codeVerifier = await randomString();
48
- const codeChallenge = await getCodeChallenge(codeVerifier);
28
+ const codeVerifier = (0, import_node_crypto.randomBytes)(32).toString("base64url");
49
29
  return {
50
- state: await randomString(),
30
+ state: (0, import_node_crypto.randomBytes)(32).toString("base64url"),
51
31
  code_verifier: codeVerifier,
52
- code_challenge: codeChallenge,
32
+ code_challenge: getCodeChallenge(codeVerifier),
53
33
  code_challenge_method: "S256"
54
34
  };
55
35
  }
56
36
  function getCodeChallenge(verifier) {
57
- const hash = import_node_crypto2.default.createHash("sha256").update(verifier).digest();
58
- return hash.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
37
+ return (0, import_node_crypto.createHash)("sha256").update(verifier).digest("base64url");
59
38
  }
60
39
  // Annotate the CommonJS export names for ESM import in node:
61
40
  0 && (module.exports = {
@@ -34,13 +34,20 @@ __export(sanitize_exports, {
34
34
  module.exports = __toCommonJS(sanitize_exports);
35
35
  var import_sanitize_html = __toESM(require("sanitize-html"), 1);
36
36
 
37
+ // src/lib/checks.js
38
+ function isPlainObject(x) {
39
+ if (typeof x !== "object" || x === null) return false;
40
+ const prototype = Object.getPrototypeOf(x);
41
+ return prototype === Object.prototype || prototype === null;
42
+ }
43
+
37
44
  // src/lib/form/sanitize.js
38
45
  function sanitize(value, options = {}) {
39
46
  const { sanitizer, ...rest } = options;
40
47
  if (!sanitizer) throw new Error("sanitizer function is required");
41
48
  if (typeof value === "string") return sanitizer(value, rest);
42
49
  if (Array.isArray(value)) return sanitizeArray(value, { sanitizer, ...rest });
43
- if (value && typeof value === "object") {
50
+ if (isPlainObject(value)) {
44
51
  return Object.fromEntries(
45
52
  Object.entries(value).map(([key, val]) => [
46
53
  key,
@@ -1,20 +1,24 @@
1
- import { randomString } from "./random-string.js";
2
1
  async function PKCE() {
3
- const codeVerifier = await randomString();
4
- const codeChallenge = await getCodeChallenge(codeVerifier);
2
+ const codeVerifier = randomVerifier();
5
3
  return {
6
- state: await randomString(),
4
+ state: randomVerifier(),
7
5
  code_verifier: codeVerifier,
8
- code_challenge: codeChallenge,
6
+ code_challenge: await getCodeChallenge(codeVerifier),
9
7
  code_challenge_method: "S256"
10
8
  };
11
9
  }
12
10
  async function getCodeChallenge(verifier) {
13
- const encoder = new TextEncoder();
14
- const data = encoder.encode(verifier);
15
- const hashed = await window.crypto.subtle.digest("SHA-256", data);
16
- return window.btoa(String.fromCharCode.apply(null, new Uint8Array(hashed))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
11
+ const data = new TextEncoder().encode(verifier);
12
+ const hash = await crypto.subtle.digest("SHA-256", data);
13
+ return toBase64Url(new Uint8Array(hash));
14
+ }
15
+ function randomVerifier() {
16
+ return toBase64Url(crypto.getRandomValues(new Uint8Array(32)));
17
+ }
18
+ function toBase64Url(bytes) {
19
+ return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
17
20
  }
18
21
  export {
19
- PKCE
22
+ PKCE,
23
+ getCodeChallenge
20
24
  };
@@ -3,8 +3,13 @@ const queryParams = {
3
3
  const searchParams = new URLSearchParams(location.search);
4
4
  return searchParams.get(key);
5
5
  },
6
+ /**
7
+ * Converts a params object into a URL query string
8
+ * @param {Object} params - Key-value pairs to stringify
9
+ * @returns {string} URL-encoded query string
10
+ */
6
11
  stringify(params) {
7
- const searchParams = new URLSearchParams(location.search);
12
+ const searchParams = new URLSearchParams(params);
8
13
  return searchParams.toString();
9
14
  }
10
15
  };
@@ -1,6 +1,11 @@
1
1
  function isObject(x) {
2
2
  return typeof x === "object" && !Array.isArray(x) && x !== null;
3
3
  }
4
+ function isPlainObject(x) {
5
+ if (typeof x !== "object" || x === null) return false;
6
+ const prototype = Object.getPrototypeOf(x);
7
+ return prototype === Object.prototype || prototype === null;
8
+ }
4
9
  function isArray(x) {
5
10
  return Array.isArray(x);
6
11
  }
@@ -30,5 +35,6 @@ export {
30
35
  isArray,
31
36
  isFunction,
32
37
  isObject,
38
+ isPlainObject,
33
39
  notObject
34
40
  };
@@ -1,3 +1,4 @@
1
+ import { isPlainObject } from "../checks.js";
1
2
  function formDataToObject(formData) {
2
3
  const obj = {};
3
4
  for (let [key, value] of formData) {
@@ -38,7 +39,7 @@ function flattenArrayFields(inputObject) {
38
39
  }
39
40
  }
40
41
  for (const key in result) {
41
- if (typeof result[key] === "object" && result[key] !== null) {
42
+ if (isPlainObject(result[key]) || Array.isArray(result[key])) {
42
43
  if (Object.keys(result[key]).every((k) => !isNaN(parseInt(k)))) {
43
44
  result[key] = Object.values(result[key]).filter((item) => {
44
45
  if (typeof item === "object") {