@splendidlabz/utils 1.14.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 (42) 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 +41 -24
  4. package/dist/cjs/dom/pkce.cjs +16 -19
  5. package/dist/cjs/dom/sanitize.cjs +8 -1
  6. package/dist/cjs/lib/checks.cjs +7 -0
  7. package/dist/cjs/lib/form/form-data.cjs +10 -1
  8. package/dist/cjs/lib/form/index.cjs +11 -11
  9. package/dist/cjs/lib/form/sanitize.cjs +12 -10
  10. package/dist/cjs/lib/index.cjs +62 -16
  11. package/dist/cjs/lib/objects/index.cjs +58 -7
  12. package/dist/cjs/lib/objects/normalize-object.cjs +16 -5
  13. package/dist/cjs/lib/objects/omit-empty.cjs +18 -5
  14. package/dist/cjs/lib/objects/remove-invalid.cjs +61 -0
  15. package/dist/cjs/lib/objects/trim-values.cjs +47 -0
  16. package/dist/cjs/lib/promises/index.cjs +16 -5
  17. package/dist/cjs/lib/promises/reject.cjs +16 -5
  18. package/dist/cjs/lib/sse.cjs +16 -5
  19. package/dist/cjs/node/index.cjs +20 -17
  20. package/dist/cjs/node/pkce.cjs +5 -26
  21. package/dist/cjs/node/sanitize.cjs +8 -1
  22. package/dist/esm/dom/pkce.js +14 -10
  23. package/dist/esm/lib/checks.js +6 -0
  24. package/dist/esm/lib/form/form-data.js +2 -1
  25. package/dist/esm/lib/form/sanitize.js +4 -10
  26. package/dist/esm/lib/objects/index.js +2 -0
  27. package/dist/esm/lib/objects/omit-empty.js +10 -5
  28. package/dist/esm/lib/objects/remove-invalid.js +28 -0
  29. package/dist/esm/lib/objects/trim-values.js +14 -0
  30. package/dist/esm/node/pkce.js +5 -8
  31. package/dist/types/dom/index.d.cts +1 -1
  32. package/dist/types/dom/pkce.d.cts +29 -4
  33. package/dist/types/lib/checks.d.cts +12 -2
  34. package/dist/types/lib/form/sanitize.d.cts +2 -2
  35. package/dist/types/lib/index.d.cts +3 -1
  36. package/dist/types/lib/objects/index.d.cts +2 -0
  37. package/dist/types/lib/objects/omit-empty.d.cts +24 -1
  38. package/dist/types/lib/objects/remove-invalid.d.cts +12 -0
  39. package/dist/types/lib/objects/trim-values.d.cts +8 -0
  40. package/dist/types/node/index.d.cts +1 -1
  41. package/dist/types/node/pkce.d.cts +29 -10
  42. package/package.json +1 -1
@@ -1,12 +1,17 @@
1
- function omitEmpty(obj, shallow = false) {
2
- if (typeof obj !== "object" || obj === null) return obj;
3
- if (obj instanceof Date) return obj;
1
+ import { isPlainObject } from "../checks.js";
2
+ function omitEmpty(obj, options = {}) {
3
+ const { shallow = false, omitFalsey = false } = typeof options === "boolean" ? { shallow: options } : options;
4
+ if (!isPlainObject(obj) && !Array.isArray(obj)) return obj;
4
5
  const result = Array.isArray(obj) ? [] : {};
5
6
  for (const [key, value] of Object.entries(obj)) {
6
- if (value === null || value === void 0 || value === "" || typeof value === "object" && !(value instanceof Date) && Object.keys(value).length === 0) {
7
+ if (value === null || value === void 0 || value === "") continue;
8
+ if (omitFalsey && !value) continue;
9
+ if ((isPlainObject(value) || Array.isArray(value)) && Object.keys(value).length === 0) {
7
10
  continue;
8
11
  }
9
- result[key] = shallow ? value : omitEmpty(value);
12
+ const filteredValue = shallow ? value : omitEmpty(value, { omitFalsey });
13
+ if (Array.isArray(result)) result.push(filteredValue);
14
+ else result[key] = filteredValue;
10
15
  }
11
16
  return result;
12
17
  }
@@ -0,0 +1,28 @@
1
+ import { isPlainObject } from "../checks.js";
2
+ function removeInvalid(values, schema) {
3
+ if (!schema) return values;
4
+ if (Array.isArray(values)) {
5
+ const kept2 = [];
6
+ for (const item of values) {
7
+ if (!isValid(item, schema)) continue;
8
+ kept2.push(removeInvalid(item, schema));
9
+ }
10
+ return kept2;
11
+ }
12
+ if (!isPlainObject(values) || !isPlainObject(schema)) return values;
13
+ const kept = {};
14
+ for (const [key, value] of Object.entries(values)) {
15
+ const keySchema = schema[key];
16
+ if (!isValid(value, keySchema)) continue;
17
+ kept[key] = removeInvalid(value, keySchema);
18
+ }
19
+ return kept;
20
+ }
21
+ function isValid(value, pattern) {
22
+ if (typeof value !== "string") return true;
23
+ if (typeof pattern !== "string" && !(pattern instanceof RegExp)) return true;
24
+ return new RegExp(pattern).test(value);
25
+ }
26
+ export {
27
+ removeInvalid
28
+ };
@@ -0,0 +1,14 @@
1
+ import { isPlainObject } from "../checks.js";
2
+ function trimValues(values) {
3
+ if (typeof values === "string") return values.trim();
4
+ if (Array.isArray(values)) return values.map(trimValues);
5
+ if (!isPlainObject(values)) return values;
6
+ const trimmed = {};
7
+ for (const [key, value] of Object.entries(values)) {
8
+ trimmed[key] = trimValues(value);
9
+ }
10
+ return trimmed;
11
+ }
12
+ export {
13
+ trimValues
14
+ };
@@ -1,18 +1,15 @@
1
- import crypto from "node:crypto";
2
- import { randomString } from "./random-string.js";
1
+ import { createHash, randomBytes } from "node:crypto";
3
2
  async function PKCE() {
4
- const codeVerifier = await randomString();
5
- const codeChallenge = await getCodeChallenge(codeVerifier);
3
+ const codeVerifier = randomBytes(32).toString("base64url");
6
4
  return {
7
- state: await randomString(),
5
+ state: randomBytes(32).toString("base64url"),
8
6
  code_verifier: codeVerifier,
9
- code_challenge: codeChallenge,
7
+ code_challenge: getCodeChallenge(codeVerifier),
10
8
  code_challenge_method: "S256"
11
9
  };
12
10
  }
13
11
  function getCodeChallenge(verifier) {
14
- const hash = crypto.createHash("sha256").update(verifier).digest();
15
- return hash.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
12
+ return createHash("sha256").update(verifier).digest("base64url");
16
13
  }
17
14
  export {
18
15
  PKCE,
@@ -18,7 +18,7 @@ export { intersectionObserver } from './observers/intersection-observer.cjs';
18
18
  export { mutationObserver } from './observers/mutation-observer.cjs';
19
19
  export { resizeObserver } from './observers/resize-observer.cjs';
20
20
  export { ScrollObserverOptions, scrollObserver } from './observers/scroll-observer.cjs';
21
- export { PKCE } from './pkce.cjs';
21
+ export { PKCE, PkceParams, getCodeChallenge } from './pkce.cjs';
22
22
  export { queryParams } from './query-params.cjs';
23
23
  export { randomString, uuid } from './random-string.cjs';
24
24
  export { sanitize } from './sanitize.cjs';
@@ -1,8 +1,33 @@
1
- declare function PKCE(): Promise<{
1
+ /**
2
+ * PKCE
3
+ *
4
+ * @typedef {object} PkceParams The authorization request's parameters, named as the query string wants them.
5
+ * @property {string} state
6
+ * @property {string} code_verifier Held back until the token request sends it.
7
+ * @property {string} code_challenge
8
+ * @property {'S256'} code_challenge_method
9
+ *
10
+ * @returns {Promise<PkceParams>}
11
+ */
12
+ declare function PKCE(): Promise<PkceParams>;
13
+ /**
14
+ * getCodeChallenge
15
+ *
16
+ * @param {string} verifier
17
+ * @returns {Promise<string>}
18
+ */
19
+ declare function getCodeChallenge(verifier: string): Promise<string>;
20
+ /**
21
+ * The authorization request's parameters, named as the query string wants them.
22
+ */
23
+ type PkceParams = {
2
24
  state: string;
25
+ /**
26
+ * Held back until the token request sends it.
27
+ */
3
28
  code_verifier: string;
4
29
  code_challenge: string;
5
- code_challenge_method: string;
6
- }>;
30
+ code_challenge_method: "S256";
31
+ };
7
32
 
8
- export { PKCE };
33
+ export { PKCE, type PkceParams, getCodeChallenge };
@@ -8,6 +8,16 @@
8
8
  * isObject(null) // false
9
9
  */
10
10
  declare function isObject(x: unknown): boolean;
11
+ /**
12
+ * Checks if a value is an object literal — one whose prototype is `Object.prototype` or `null`. Class instances and platform objects like `File`, `Blob`, `Date` and `Map` are excluded, so code that walks an object's entries can leave them intact.
13
+ * @param {unknown} x - The value to check
14
+ * @returns {boolean} True if the value is an object literal
15
+ * @example
16
+ * isPlainObject({}) // true
17
+ * isPlainObject(new File([], 'a.png')) // false
18
+ * isPlainObject(new Date()) // false
19
+ */
20
+ declare function isPlainObject(x: unknown): boolean;
11
21
  /**
12
22
  * Checks if a value is an array
13
23
  * @param {unknown} x - The value to check
@@ -27,7 +37,7 @@ declare function isArray(x: unknown): boolean;
27
37
  * notObject({}) // false
28
38
  */
29
39
  declare function notObject(x: unknown): boolean;
30
- declare function getType(x: any): "string" | "integer" | "float" | "boolean" | "function" | "undefined" | "symbol" | "bigint" | "array" | "object" | "unknown";
40
+ declare function getType(x: any): "array" | "string" | "integer" | "float" | "boolean" | "function" | "undefined" | "symbol" | "bigint" | "object" | "unknown";
31
41
  declare function isFunction(x: any): boolean;
32
42
 
33
- export { getType, isArray, isFunction, isObject, notObject };
43
+ export { getType, isArray, isFunction, isObject, isPlainObject, notObject };
@@ -46,7 +46,7 @@ type SanitizeOptions = {
46
46
  */
47
47
  declare function sanitizeArray(arr: any[], { sanitizer, ...rest }: SanitizeOptions): any[];
48
48
  /**
49
- * Sanitizes all string values in an object recursively.
49
+ * Sanitizes all string values in an object recursively. An alias for `sanitize`, which already walks objects and arrays and leaves every other value alone.
50
50
  * Throws if no sanitizer function is not provided.
51
51
  * Any additional properties in options are passed through to the sanitizer function.
52
52
  *
@@ -55,6 +55,6 @@ declare function sanitizeArray(arr: any[], { sanitizer, ...rest }: SanitizeOptio
55
55
  * @throws {Error} If sanitizer function is not provided
56
56
  * @returns {Object} New object with sanitized values
57
57
  */
58
- declare function sanitizeObject(obj: any, { sanitizer, ...options }?: SanitizeOptions): any;
58
+ declare function sanitizeObject(obj: any, options?: SanitizeOptions): any;
59
59
 
60
60
  export { type SanitizeOptions, sanitize, sanitizeArray, sanitizeObject };
@@ -5,7 +5,7 @@ export { sort } from './arrays/sort.cjs';
5
5
  export { splitArray } from './arrays/split-array.cjs';
6
6
  export { uniqueArray } from './arrays/unique.cjs';
7
7
  export { AuthManager, RouteManager } from './auth/route-manager.cjs';
8
- export { getType, isArray, isFunction, isObject, notObject } from './checks.cjs';
8
+ export { getType, isArray, isFunction, isObject, isPlainObject, notObject } from './checks.cjs';
9
9
  export { hexToRgb } from './colors.cjs';
10
10
  export { DAYS } from './date/days.cjs';
11
11
  export { MONTHS } from './date/months.cjs';
@@ -33,8 +33,10 @@ export { concatMix, createMix, mix } from './objects/mix/mix.cjs';
33
33
  export { getNestedProperty, getNestedProperty2, getNestedValue } from './objects/nested-property.cjs';
34
34
  export { normalizeObject } from './objects/normalize-object.cjs';
35
35
  export { omitEmpty } from './objects/omit-empty.cjs';
36
+ export { removeInvalid } from './objects/remove-invalid.cjs';
36
37
  export { sizeOf } from './objects/size.cjs';
37
38
  export { splitObject } from './objects/split.cjs';
39
+ export { trimValues } from './objects/trim-values.cjs';
38
40
  export { reject } from './promises/reject.cjs';
39
41
  export { createSSE, parseSSE } from './sse.cjs';
40
42
  export { toCamel, toKebab, toLower, toPascal, toSentence, toSlug, toTitle, toUpper } from './strings/convert-case/convert-case.cjs';
@@ -9,5 +9,7 @@ export { concatMix, createMix, mix } from './mix/mix.cjs';
9
9
  export { getNestedProperty, getNestedProperty2, getNestedValue } from './nested-property.cjs';
10
10
  export { normalizeObject } from './normalize-object.cjs';
11
11
  export { omitEmpty } from './omit-empty.cjs';
12
+ export { removeInvalid } from './remove-invalid.cjs';
12
13
  export { sizeOf } from './size.cjs';
13
14
  export { splitObject } from './split.cjs';
15
+ export { trimValues } from './trim-values.cjs';
@@ -1,3 +1,26 @@
1
- declare function omitEmpty(obj: any, shallow?: boolean): any;
1
+ /**
2
+ * Drop the keys holding nothing — null, undefined, an empty string, an empty object or an empty array.
3
+ *
4
+ * @overload
5
+ * @param {object} obj Object to filter.
6
+ * @param {object} [options]
7
+ * @param {boolean} [options.shallow=false] Leave nested values alone.
8
+ * @param {boolean} [options.omitFalsey=false] Drop 0, false and NaN too.
9
+ * @returns {object} A copy without the empty keys.
10
+ */
11
+ declare function omitEmpty(obj: object, options?: {
12
+ shallow?: boolean;
13
+ omitFalsey?: boolean;
14
+ }): object;
15
+ /**
16
+ * Drop the keys holding nothing.
17
+ *
18
+ * @overload
19
+ * @param {object} obj Object to filter.
20
+ * @param {boolean} shallow Leave nested values alone.
21
+ * @returns {object} A copy without the empty keys.
22
+ * @deprecated Pass `{ shallow: true }` instead. The boolean goes in 2.0.0.
23
+ */
24
+ declare function omitEmpty(obj: object, shallow: boolean): object;
2
25
 
3
26
  export { omitEmpty };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Remove every string that fails the pattern the schema holds for it, in the shape the values came in as.
3
+ *
4
+ * The schema mirrors the values: a key holds a pattern for what sits at that key, or another schema for what sits under it. An array takes the schema its key holds and applies it to every element, so nothing in the schema says whether a value is an object or an array — the values answer that.
5
+ *
6
+ * @param {any} values
7
+ * @param {object|string|RegExp} [schema] A pattern, or a record of key to pattern or nested schema.
8
+ * @returns {any}
9
+ */
10
+ declare function removeInvalid(values: any, schema?: object | string | RegExp): any;
11
+
12
+ export { removeInvalid };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Trims every string a value holds, in the shape it came in as. A Date, a File and anything else that is not a plain object or an array passes through untouched.
3
+ * @param {any} values
4
+ * @returns {any}
5
+ */
6
+ declare function trimValues(values: any): any;
7
+
8
+ export { trimValues };
@@ -1,7 +1,7 @@
1
1
  export { __dirname, dirname } from './dirname.cjs';
2
2
  export { createCache, fileCache, getLastModifiedTime, getLatestModifiedTime, removeFirstSlash } from './file-cache.cjs';
3
3
  export { sha256Hash } from './hash.cjs';
4
- export { PKCE, getCodeChallenge } from './pkce.cjs';
4
+ export { PKCE, PkceParams, getCodeChallenge } from './pkce.cjs';
5
5
  export { randomString } from './random-string.cjs';
6
6
  export { sanitize } from './sanitize.cjs';
7
7
  export { uuid } from './uuid.cjs';
@@ -1,14 +1,33 @@
1
- declare function PKCE(): Promise<{
2
- state: any;
3
- code_verifier: any;
4
- code_challenge: any;
5
- code_challenge_method: string;
6
- }>;
7
1
  /**
8
- * Generates code challenge in node
2
+ * PKCE
3
+ *
4
+ * @typedef {object} PkceParams The authorization request's parameters, named as the query string wants them.
5
+ * @property {string} state
6
+ * @property {string} code_verifier Held back until the token request sends it.
7
+ * @property {string} code_challenge
8
+ * @property {'S256'} code_challenge_method
9
+ *
10
+ * @returns {Promise<PkceParams>}
11
+ */
12
+ declare function PKCE(): Promise<PkceParams>;
13
+ /**
14
+ * getCodeChallenge
15
+ *
9
16
  * @param {string} verifier
10
- * @returns string
17
+ * @returns {string}
18
+ */
19
+ declare function getCodeChallenge(verifier: string): string;
20
+ /**
21
+ * The authorization request's parameters, named as the query string wants them.
11
22
  */
12
- declare function getCodeChallenge(verifier: string): any;
23
+ type PkceParams = {
24
+ state: string;
25
+ /**
26
+ * Held back until the token request sends it.
27
+ */
28
+ code_verifier: string;
29
+ code_challenge: string;
30
+ code_challenge_method: "S256";
31
+ };
13
32
 
14
- export { PKCE, getCodeChallenge };
33
+ export { PKCE, type PkceParams, getCodeChallenge };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splendidlabz/utils",
3
- "version": "1.14.0",
3
+ "version": "1.15.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "homepage": "https://splendidlabz.com/docs/utils",