@kikiutils/shared 15.1.0 → 16.0.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 (81) hide show
  1. package/README.md +1 -1
  2. package/dist/buffer.d.ts.map +1 -1
  3. package/dist/buffer.js.map +1 -1
  4. package/dist/classes/path.d.ts.map +1 -1
  5. package/dist/classes/path.js.map +1 -1
  6. package/dist/classes/precision-number.d.ts.map +1 -1
  7. package/dist/classes/precision-number.js.map +1 -1
  8. package/dist/classes/ssh-client.d.ts +4 -6
  9. package/dist/classes/ssh-client.d.ts.map +1 -1
  10. package/dist/classes/ssh-client.js.map +1 -1
  11. package/dist/clipboard.d.ts.map +1 -1
  12. package/dist/clipboard.js.map +1 -1
  13. package/dist/consola.d.ts +2 -4
  14. package/dist/consola.d.ts.map +1 -1
  15. package/dist/consola.js.map +1 -1
  16. package/dist/crypto-hash.d.ts +11 -11
  17. package/dist/crypto-hash.d.ts.map +1 -1
  18. package/dist/crypto-hash.js +19 -15
  19. package/dist/crypto-hash.js.map +1 -1
  20. package/dist/datetime.d.ts.map +1 -1
  21. package/dist/datetime.js.map +1 -1
  22. package/dist/element-plus.d.ts.map +1 -1
  23. package/dist/element-plus.js.map +1 -1
  24. package/dist/enum.d.ts.map +1 -1
  25. package/dist/enum.js.map +1 -1
  26. package/dist/env.d.ts.map +1 -1
  27. package/dist/env.js.map +1 -1
  28. package/dist/event-awaiter.d.ts.map +1 -1
  29. package/dist/event-awaiter.js.map +1 -1
  30. package/dist/general.d.ts.map +1 -1
  31. package/dist/general.js.map +1 -1
  32. package/dist/hash.d.ts.map +1 -1
  33. package/dist/hash.js.map +1 -1
  34. package/dist/math.d.ts.map +1 -1
  35. package/dist/math.js.map +1 -1
  36. package/dist/number.d.ts.map +1 -1
  37. package/dist/number.js.map +1 -1
  38. package/dist/object.d.ts.map +1 -1
  39. package/dist/object.js.map +1 -1
  40. package/dist/pino.d.ts +2 -4
  41. package/dist/pino.d.ts.map +1 -1
  42. package/dist/pino.js.map +1 -1
  43. package/dist/random.d.ts.map +1 -1
  44. package/dist/random.js.map +1 -1
  45. package/dist/storages/lru/keyed-store.d.ts.map +1 -1
  46. package/dist/storages/lru/keyed-store.js.map +1 -1
  47. package/dist/storages/redis/keyed-store.d.ts +2 -2
  48. package/dist/storages/redis/keyed-store.d.ts.map +1 -1
  49. package/dist/storages/redis/keyed-store.js.map +1 -1
  50. package/dist/storages/redis/msgpack.d.ts.map +1 -1
  51. package/dist/storages/redis/msgpack.js.map +1 -1
  52. package/dist/storages/redis/types.d.ts +2 -4
  53. package/dist/storages/redis/types.d.ts.map +1 -1
  54. package/dist/string.d.ts.map +1 -1
  55. package/dist/string.js +7 -10
  56. package/dist/string.js.map +1 -1
  57. package/dist/time.d.ts.map +1 -1
  58. package/dist/time.js.map +1 -1
  59. package/dist/types/filtered-key-path.d.ts.map +1 -1
  60. package/dist/types/index.d.ts +1 -5
  61. package/dist/types/index.d.ts.map +1 -1
  62. package/dist/types/vue.d.ts +1 -2
  63. package/dist/types/vue.d.ts.map +1 -1
  64. package/dist/url.d.ts +27 -3
  65. package/dist/url.d.ts.map +1 -1
  66. package/dist/url.js +37 -4
  67. package/dist/url.js.map +1 -1
  68. package/dist/vue.d.ts +6 -7
  69. package/dist/vue.d.ts.map +1 -1
  70. package/dist/vue.js +3 -3
  71. package/dist/vue.js.map +1 -1
  72. package/dist/web.d.ts.map +1 -1
  73. package/dist/web.js.map +1 -1
  74. package/package.json +24 -23
  75. package/src/classes/ssh-client.ts +4 -6
  76. package/src/crypto-hash.ts +26 -24
  77. package/src/storages/redis/types.ts +2 -4
  78. package/src/types/index.ts +0 -5
  79. package/src/types/vue.ts +1 -3
  80. package/src/url.ts +39 -7
  81. package/src/vue.ts +6 -7
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/types/index.ts"],"mappings":";;;;;;AAWA;KAAY,SAAA,GAAY,MAAA;;;;KAKZ,WAAA,GAAc,WAAA,GAAc,IAAA,GAAO,MAAA,GAAS,IAAA,GAAO,MAAA,GAAW,MAAA,GAAW,UAAA;;;;KAKzE,UAAA;;;;KAKA,YAAA,MAAkB,OAAA,CAAQ,CAAA,IAAK,CAAA;;;;KAK/B,aAAA,MAAmB,QAAA,CAAS,CAAA,IAAK,CAAA;;;;KAKjC,QAAA,aAAqB,CAAA;;;;KAKrB,SAAA;AApBZ;;;AAAA,KAyBY,aAAA,2BAAwC,OAAA,CAAQ,MAAA,CAAO,CAAA,EAAG,CAAA;;AApBtE;;KAyBY,qBAAA,2BAAgD,QAAA,CAAS,aAAA,CAAc,CAAA,EAAG,CAAA;;;;KAK1E,cAAA,2BAAyC,QAAA,CAAS,MAAA,CAAO,CAAA,EAAG,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/types/index.ts"],"mappings":";;;;;;AAWA;KAAY,SAAA,GAAY,MAAM;;;AAAA;KAKlB,WAAA,GAAc,WAAA,GAAc,IAAA,GAAO,MAAA,GAAS,IAAA,GAAO,MAAA,GAAW,MAAA,GAAW,UAAA;;;;KAKzE,UAAA;;;;KAKA,YAAA,MAAkB,OAAA,CAAQ,CAAA,IAAK,CAAA;;;;KAK/B,aAAA,MAAmB,QAAA,CAAS,CAAA,IAAK,CAAA;;;;KAKjC,SAAA;;;;KAKA,aAAA,2BAAwC,OAAA,CAAQ,MAAA,CAAO,CAAA,EAAG,CAAA;AApBtE;;;AAAA,KAyBY,qBAAA,2BAAgD,QAAA,CAAS,aAAA,CAAc,CAAA,EAAG,CAAA;AAzBhE;AAKtB;;AALsB,KA8BV,cAAA,2BAAyC,QAAA,CAAS,MAAA,CAAO,CAAA,EAAG,CAAA"}
@@ -1,4 +1,3 @@
1
- import { Nullable } from "./index.js";
2
1
  import { GlobalComponents } from "vue";
3
2
 
4
3
  //#region src/types/vue.d.ts
@@ -15,7 +14,7 @@ import { GlobalComponents } from "vue";
15
14
  * const keepAliveRef = ref<ComponentRef<'KeepAlive'>>(null);
16
15
  * ```
17
16
  */
18
- type ComponentRef<K extends keyof GlobalComponents> = Nullable<InstanceType<GlobalComponents[K]>>;
17
+ type ComponentRef<K extends keyof GlobalComponents> = InstanceType<GlobalComponents[K]> | null;
19
18
  //#endregion
20
19
  export { ComponentRef };
21
20
  //# sourceMappingURL=vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"vue.d.ts","names":[],"sources":["../../src/types/vue.ts"],"mappings":";;;;;;AAiBA;;;;;;;;;;;KAAY,YAAA,iBAA6B,gBAAA,IAAoB,QAAA,CAAS,YAAA,CAAa,gBAAA,CAAiB,CAAA"}
1
+ {"version":3,"file":"vue.d.ts","names":[],"sources":["../../src/types/vue.ts"],"mappings":";;;;;AAeA;;;;;;;;;;;KAAY,YAAA,iBAA6B,gBAAA,IAAoB,YAAA,CAAa,gBAAA,CAAiB,CAAA"}
package/dist/url.d.ts CHANGED
@@ -6,13 +6,37 @@
6
6
  *
7
7
  * @param {string} url - The target URL to modify
8
8
  * @param {string} redirectPath - The path to use as the redirect destination
9
- * (must be an absolute path starting with '/')
9
+ * (must be a safe same-origin application path starting with `/`)
10
10
  *
11
11
  * @returns {string} A new URL string with the `redirect` query parameter
12
12
  *
13
- * @throws {Error} If redirectPath is not a valid relative path (must start with '/')
13
+ * @throws {Error} If redirectPath is not a safe same-origin application path
14
14
  */
15
15
  declare function appendRedirectParamToUrl(url: string, redirectPath: string): string;
16
+ /**
17
+ * Returns whether a value is a safe same-origin redirect path.
18
+ *
19
+ * Safe redirect paths are absolute application paths such as `/dashboard`.
20
+ * Protocol-relative URLs (`//example.com`), absolute URLs, backslash paths,
21
+ * and non-string values are rejected.
22
+ *
23
+ * @param {unknown} value - The value to check
24
+ *
25
+ * @returns {boolean} Whether the value is safe to use as an application redirect path
26
+ */
27
+ declare function isSafeRedirectPath(value: unknown): value is string;
28
+ /**
29
+ * Normalizes a redirect value into a safe same-origin application path.
30
+ *
31
+ * If an array is provided, the first value is checked. Unsafe values fall back
32
+ * to the provided fallback path.
33
+ *
34
+ * @param {unknown} value - The redirect value to normalize
35
+ * @param {string} fallback - The safe fallback path
36
+ *
37
+ * @returns {string} A safe redirect path
38
+ */
39
+ declare function normalizeRedirectPath(value: unknown, fallback?: string): string;
16
40
  //#endregion
17
- export { appendRedirectParamToUrl };
41
+ export { appendRedirectParamToUrl, isSafeRedirectPath, normalizeRedirectPath };
18
42
  //# sourceMappingURL=url.d.ts.map
package/dist/url.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"url.d.ts","names":[],"sources":["../src/url.ts"],"mappings":";;AAaA;;;;;;;;;;;;iBAAgB,wBAAA,CAAyB,GAAA,UAAa,YAAA"}
1
+ {"version":3,"file":"url.d.ts","names":[],"sources":["../src/url.ts"],"mappings":";;AAaA;;;;AAA0E;AAuB1E;;;;AAAyD;AAmBzD;;iBA1CgB,wBAAA,CAAyB,GAAA,UAAa,YAAoB;;AA0CN;;;;;;;;;;iBAnBpD,kBAAA,CAAmB,KAAA,YAAiB,KAAK;;;;;;;;;;;;iBAmBzC,qBAAA,CAAsB,KAAA,WAAgB,QAAc"}
package/dist/url.js CHANGED
@@ -6,14 +6,14 @@
6
6
  *
7
7
  * @param {string} url - The target URL to modify
8
8
  * @param {string} redirectPath - The path to use as the redirect destination
9
- * (must be an absolute path starting with '/')
9
+ * (must be a safe same-origin application path starting with `/`)
10
10
  *
11
11
  * @returns {string} A new URL string with the `redirect` query parameter
12
12
  *
13
- * @throws {Error} If redirectPath is not a valid relative path (must start with '/')
13
+ * @throws {Error} If redirectPath is not a safe same-origin application path
14
14
  */
15
15
  function appendRedirectParamToUrl(url, redirectPath) {
16
- if (!redirectPath.startsWith("/")) throw new Error(`Invalid redirect path: "${redirectPath}". Redirect paths must be absolute paths starting with '/'.`);
16
+ if (!isSafeRedirectPath(redirectPath)) throw new Error(`Invalid redirect path: "${redirectPath}". Redirect paths must be safe same-origin paths starting with '/'.`);
17
17
  const [baseAndHash, rawQuery = ""] = url.split("?");
18
18
  const [base, hash] = (baseAndHash || "").split("#");
19
19
  const searchParams = new URLSearchParams(rawQuery);
@@ -21,7 +21,40 @@ function appendRedirectParamToUrl(url, redirectPath) {
21
21
  const queryString = searchParams.toString();
22
22
  return hash ? `${base}?${queryString}#${hash}` : `${base}?${queryString}`;
23
23
  }
24
+ /**
25
+ * Returns whether a value is a safe same-origin redirect path.
26
+ *
27
+ * Safe redirect paths are absolute application paths such as `/dashboard`.
28
+ * Protocol-relative URLs (`//example.com`), absolute URLs, backslash paths,
29
+ * and non-string values are rejected.
30
+ *
31
+ * @param {unknown} value - The value to check
32
+ *
33
+ * @returns {boolean} Whether the value is safe to use as an application redirect path
34
+ */
35
+ function isSafeRedirectPath(value) {
36
+ if (typeof value !== "string") return false;
37
+ if (!value.startsWith("/")) return false;
38
+ if (value.startsWith("//")) return false;
39
+ if (value.includes("\\")) return false;
40
+ return true;
41
+ }
42
+ /**
43
+ * Normalizes a redirect value into a safe same-origin application path.
44
+ *
45
+ * If an array is provided, the first value is checked. Unsafe values fall back
46
+ * to the provided fallback path.
47
+ *
48
+ * @param {unknown} value - The redirect value to normalize
49
+ * @param {string} fallback - The safe fallback path
50
+ *
51
+ * @returns {string} A safe redirect path
52
+ */
53
+ function normalizeRedirectPath(value, fallback = "/") {
54
+ const redirectPath = Array.isArray(value) ? value[0] : value;
55
+ return isSafeRedirectPath(redirectPath) ? redirectPath : fallback;
56
+ }
24
57
  //#endregion
25
- export { appendRedirectParamToUrl };
58
+ export { appendRedirectParamToUrl, isSafeRedirectPath, normalizeRedirectPath };
26
59
 
27
60
  //# sourceMappingURL=url.js.map
package/dist/url.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"url.js","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * Appends or updates the `redirect` query parameter on a given URL.\n *\n * Typically used to preserve the user's current path for post-login navigation.\n *\n * @param {string} url - The target URL to modify\n * @param {string} redirectPath - The path to use as the redirect destination\n * (must be an absolute path starting with '/')\n *\n * @returns {string} A new URL string with the `redirect` query parameter\n *\n * @throws {Error} If redirectPath is not a valid relative path (must start with '/')\n */\nexport function appendRedirectParamToUrl(url: string, redirectPath: string) {\n if (!redirectPath.startsWith('/')) {\n throw new Error(\n `Invalid redirect path: \"${redirectPath}\". Redirect paths must be absolute paths starting with '/'.`,\n );\n }\n\n const [baseAndHash, rawQuery = ''] = url.split('?');\n const [base, hash] = (baseAndHash || '').split('#');\n const searchParams = new URLSearchParams(rawQuery);\n searchParams.set('redirect', redirectPath);\n const queryString = searchParams.toString();\n return hash ? `${base}?${queryString}#${hash}` : `${base}?${queryString}`;\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,yBAAyB,KAAa,cAAsB;CACxE,IAAI,CAAC,aAAa,WAAW,IAAI,EAC7B,MAAM,IAAI,MACN,2BAA2B,aAAa,6DAC3C;CAGL,MAAM,CAAC,aAAa,WAAW,MAAM,IAAI,MAAM,IAAI;CACnD,MAAM,CAAC,MAAM,SAAS,eAAe,IAAI,MAAM,IAAI;CACnD,MAAM,eAAe,IAAI,gBAAgB,SAAS;CAClD,aAAa,IAAI,YAAY,aAAa;CAC1C,MAAM,cAAc,aAAa,UAAU;CAC3C,OAAO,OAAO,GAAG,KAAK,GAAG,YAAY,GAAG,SAAS,GAAG,KAAK,GAAG"}
1
+ {"version":3,"file":"url.js","names":[],"sources":["../src/url.ts"],"sourcesContent":["/**\n * Appends or updates the `redirect` query parameter on a given URL.\n *\n * Typically used to preserve the user's current path for post-login navigation.\n *\n * @param {string} url - The target URL to modify\n * @param {string} redirectPath - The path to use as the redirect destination\n * (must be a safe same-origin application path starting with `/`)\n *\n * @returns {string} A new URL string with the `redirect` query parameter\n *\n * @throws {Error} If redirectPath is not a safe same-origin application path\n */\nexport function appendRedirectParamToUrl(url: string, redirectPath: string) {\n // eslint-disable-next-line style/max-len\n if (!isSafeRedirectPath(redirectPath)) throw new Error(`Invalid redirect path: \"${redirectPath}\". Redirect paths must be safe same-origin paths starting with '/'.`);\n\n const [baseAndHash, rawQuery = ''] = url.split('?');\n const [base, hash] = (baseAndHash || '').split('#');\n const searchParams = new URLSearchParams(rawQuery);\n searchParams.set('redirect', redirectPath);\n const queryString = searchParams.toString();\n return hash ? `${base}?${queryString}#${hash}` : `${base}?${queryString}`;\n}\n\n/**\n * Returns whether a value is a safe same-origin redirect path.\n *\n * Safe redirect paths are absolute application paths such as `/dashboard`.\n * Protocol-relative URLs (`//example.com`), absolute URLs, backslash paths,\n * and non-string values are rejected.\n *\n * @param {unknown} value - The value to check\n *\n * @returns {boolean} Whether the value is safe to use as an application redirect path\n */\nexport function isSafeRedirectPath(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n if (!value.startsWith('/')) return false;\n if (value.startsWith('//')) return false;\n if (value.includes('\\\\')) return false;\n return true;\n}\n\n/**\n * Normalizes a redirect value into a safe same-origin application path.\n *\n * If an array is provided, the first value is checked. Unsafe values fall back\n * to the provided fallback path.\n *\n * @param {unknown} value - The redirect value to normalize\n * @param {string} fallback - The safe fallback path\n *\n * @returns {string} A safe redirect path\n */\nexport function normalizeRedirectPath(value: unknown, fallback = '/') {\n const redirectPath = Array.isArray(value) ? value[0] : value;\n return isSafeRedirectPath(redirectPath) ? redirectPath : fallback;\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,yBAAyB,KAAa,cAAsB;CAExE,IAAI,CAAC,mBAAmB,YAAY,GAAG,MAAM,IAAI,MAAM,2BAA2B,aAAa,oEAAoE;CAEnK,MAAM,CAAC,aAAa,WAAW,MAAM,IAAI,MAAM,GAAG;CAClD,MAAM,CAAC,MAAM,SAAS,eAAe,GAAA,CAAI,MAAM,GAAG;CAClD,MAAM,eAAe,IAAI,gBAAgB,QAAQ;CACjD,aAAa,IAAI,YAAY,YAAY;CACzC,MAAM,cAAc,aAAa,SAAS;CAC1C,OAAO,OAAO,GAAG,KAAK,GAAG,YAAY,GAAG,SAAS,GAAG,KAAK,GAAG;AAChE;;;;;;;;;;;;AAaA,SAAgB,mBAAmB,OAAiC;CAChE,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,CAAC,MAAM,WAAW,GAAG,GAAG,OAAO;CACnC,IAAI,MAAM,WAAW,IAAI,GAAG,OAAO;CACnC,IAAI,MAAM,SAAS,IAAI,GAAG,OAAO;CACjC,OAAO;AACX;;;;;;;;;;;;AAaA,SAAgB,sBAAsB,OAAgB,WAAW,KAAK;CAClE,MAAM,eAAe,MAAM,QAAQ,KAAK,IAAI,MAAM,KAAK;CACvD,OAAO,mBAAmB,YAAY,IAAI,eAAe;AAC7D"}
package/dist/vue.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { Nullable } from "./types/index.js";
2
1
  import { Ref } from "vue";
3
2
 
4
3
  //#region src/vue.d.ts
@@ -13,15 +12,15 @@ declare function appendRedirectParamFromCurrentRouteToUrl(url: string): string;
13
12
  /**
14
13
  * Clears an interval referenced by a Vue ref and sets it to null.
15
14
  *
16
- * @param {Ref<Nullable<ReturnType<typeof setInterval>>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null
15
+ * @param {Ref<null | ReturnType<typeof setInterval>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null
17
16
  */
18
- declare function clearIntervalRef(intervalRef: Ref<Nullable<ReturnType<typeof setInterval>>>): void;
17
+ declare function clearIntervalRef(intervalRef: Ref<null | ReturnType<typeof setInterval>>): void;
19
18
  /**
20
19
  * Clears a timeout referenced by a Vue ref and sets it to null.
21
20
  *
22
- * @param {Ref<Nullable<ReturnType<typeof setTimeout>>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null
21
+ * @param {Ref<null | ReturnType<typeof setTimeout>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null
23
22
  */
24
- declare function clearTimeoutRef(timeoutRef: Ref<Nullable<ReturnType<typeof setTimeout>>>): void;
23
+ declare function clearTimeoutRef(timeoutRef: Ref<null | ReturnType<typeof setTimeout>>): void;
25
24
  /**
26
25
  * A Vue composition function that remembers and restores scroll position
27
26
  * of a scrollable container across route changes and keep-alive activation.
@@ -34,9 +33,9 @@ declare function clearTimeoutRef(timeoutRef: Ref<Nullable<ReturnType<typeof setT
34
33
  *
35
34
  * @template T - The type of the scrollable element (defaults to HTMLElement)
36
35
  *
37
- * @param {Ref<Nullable<T>>} containerRef - A ref to the scrollable HTML element
36
+ * @param {Ref<null | T>} containerRef - A ref to the scrollable HTML element
38
37
  */
39
- declare function usePreserveScroll<T extends Element = HTMLElement>(containerRef: Ref<Nullable<T>>): void;
38
+ declare function usePreserveScroll<T extends Element = HTMLElement>(containerRef: Ref<null | T>): void;
40
39
  //#endregion
41
40
  export { appendRedirectParamFromCurrentRouteToUrl, clearIntervalRef, clearTimeoutRef, usePreserveScroll };
42
41
  //# sourceMappingURL=vue.d.ts.map
package/dist/vue.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vue.d.ts","names":[],"sources":["../src/vue.ts"],"mappings":";;;;;;AAiBA;;;;;iBAAgB,wCAAA,CAAyC,GAAA;;;;;;iBASzC,gBAAA,CAAiB,WAAA,EAAa,GAAA,CAAI,QAAA,CAAS,UAAA,QAAkB,WAAA;;;;;;iBAU7D,eAAA,CAAgB,UAAA,EAAY,GAAA,CAAI,QAAA,CAAS,UAAA,QAAkB,UAAA;;;;AAA3E;;;;;;;;;;;iBAmBgB,iBAAA,WAA4B,OAAA,GAAU,WAAA,CAAA,CAAa,YAAA,EAAc,GAAA,CAAI,QAAA,CAAS,CAAA"}
1
+ {"version":3,"file":"vue.d.ts","names":[],"sources":["../src/vue.ts"],"mappings":";;;;;AAgBA;;;;AAAoE;iBAApD,wCAAA,CAAyC,GAAW;;;;;;iBASpD,gBAAA,CAAiB,WAAA,EAAa,GAAA,QAAW,UAAA,QAAkB,WAAA;;;;;;iBAU3D,eAAA,CAAgB,UAAA,EAAY,GAAA,QAAW,UAAA,QAAkB,UAAA;AAVe;AAUxF;;;;;;;;;;;;;AAVwF,iBA6BxE,iBAAA,WAA4B,OAAA,GAAU,WAAA,EAAa,YAAA,EAAc,GAAA,QAAW,CAAA"}
package/dist/vue.js CHANGED
@@ -15,7 +15,7 @@ function appendRedirectParamFromCurrentRouteToUrl(url) {
15
15
  /**
16
16
  * Clears an interval referenced by a Vue ref and sets it to null.
17
17
  *
18
- * @param {Ref<Nullable<ReturnType<typeof setInterval>>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null
18
+ * @param {Ref<null | ReturnType<typeof setInterval>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null
19
19
  */
20
20
  function clearIntervalRef(intervalRef) {
21
21
  if (intervalRef.value) clearInterval(intervalRef.value);
@@ -24,7 +24,7 @@ function clearIntervalRef(intervalRef) {
24
24
  /**
25
25
  * Clears a timeout referenced by a Vue ref and sets it to null.
26
26
  *
27
- * @param {Ref<Nullable<ReturnType<typeof setTimeout>>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null
27
+ * @param {Ref<null | ReturnType<typeof setTimeout>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null
28
28
  */
29
29
  function clearTimeoutRef(timeoutRef) {
30
30
  if (timeoutRef.value) clearTimeout(timeoutRef.value);
@@ -42,7 +42,7 @@ function clearTimeoutRef(timeoutRef) {
42
42
  *
43
43
  * @template T - The type of the scrollable element (defaults to HTMLElement)
44
44
  *
45
- * @param {Ref<Nullable<T>>} containerRef - A ref to the scrollable HTML element
45
+ * @param {Ref<null | T>} containerRef - A ref to the scrollable HTML element
46
46
  */
47
47
  function usePreserveScroll(containerRef) {
48
48
  let scrollLeft = 0;
package/dist/vue.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"vue.js","names":[],"sources":["../src/vue.ts"],"sourcesContent":["import { onActivated } from 'vue';\nimport type { Ref } from 'vue';\nimport {\n onBeforeRouteLeave,\n useRoute,\n} from 'vue-router';\n\nimport type { Nullable } from './types';\nimport { appendRedirectParamToUrl } from './url';\n\n/**\n * Appends the current Vue Router route's fullPath as the `redirect` query parameter to the given URL.\n *\n * @param {string} url - The base URL to modify\n *\n * @returns {string} A new URL with the current route fullPath as the `redirect` parameter\n */\nexport function appendRedirectParamFromCurrentRouteToUrl(url: string) {\n return appendRedirectParamToUrl(url, useRoute().fullPath);\n}\n\n/**\n * Clears an interval referenced by a Vue ref and sets it to null.\n *\n * @param {Ref<Nullable<ReturnType<typeof setInterval>>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null\n */\nexport function clearIntervalRef(intervalRef: Ref<Nullable<ReturnType<typeof setInterval>>>) {\n if (intervalRef.value) clearInterval(intervalRef.value);\n intervalRef.value = null;\n}\n\n/**\n * Clears a timeout referenced by a Vue ref and sets it to null.\n *\n * @param {Ref<Nullable<ReturnType<typeof setTimeout>>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null\n */\nexport function clearTimeoutRef(timeoutRef: Ref<Nullable<ReturnType<typeof setTimeout>>>) {\n if (timeoutRef.value) clearTimeout(timeoutRef.value);\n timeoutRef.value = null;\n}\n\n/**\n * A Vue composition function that remembers and restores scroll position\n * of a scrollable container across route changes and keep-alive activation.\n *\n * Designed for use with `<KeepAlive>` components. Scroll state is saved on\n * route leave and restored when the component is activated again.\n *\n * Note: Without `<KeepAlive>`, the component state is destroyed on unmount,\n * so scroll position will not be preserved.\n *\n * @template T - The type of the scrollable element (defaults to HTMLElement)\n *\n * @param {Ref<Nullable<T>>} containerRef - A ref to the scrollable HTML element\n */\nexport function usePreserveScroll<T extends Element = HTMLElement>(containerRef: Ref<Nullable<T>>) {\n let scrollLeft = 0;\n let scrollTop = 0;\n onActivated(() => {\n if (!containerRef.value) return;\n containerRef.value.scrollLeft = scrollLeft;\n containerRef.value.scrollTop = scrollTop;\n });\n\n onBeforeRouteLeave(() => {\n scrollLeft = containerRef.value?.scrollLeft || 0;\n scrollTop = containerRef.value?.scrollTop || 0;\n });\n}\n"],"mappings":";;;;;;;;;;;AAiBA,SAAgB,yCAAyC,KAAa;CAClE,OAAO,yBAAyB,KAAK,UAAU,CAAC,SAAS;;;;;;;AAQ7D,SAAgB,iBAAiB,aAA4D;CACzF,IAAI,YAAY,OAAO,cAAc,YAAY,MAAM;CACvD,YAAY,QAAQ;;;;;;;AAQxB,SAAgB,gBAAgB,YAA0D;CACtF,IAAI,WAAW,OAAO,aAAa,WAAW,MAAM;CACpD,WAAW,QAAQ;;;;;;;;;;;;;;;;AAiBvB,SAAgB,kBAAmD,cAAgC;CAC/F,IAAI,aAAa;CACjB,IAAI,YAAY;CAChB,kBAAkB;EACd,IAAI,CAAC,aAAa,OAAO;EACzB,aAAa,MAAM,aAAa;EAChC,aAAa,MAAM,YAAY;GACjC;CAEF,yBAAyB;EACrB,aAAa,aAAa,OAAO,cAAc;EAC/C,YAAY,aAAa,OAAO,aAAa;GAC/C"}
1
+ {"version":3,"file":"vue.js","names":[],"sources":["../src/vue.ts"],"sourcesContent":["import { onActivated } from 'vue';\nimport type { Ref } from 'vue';\nimport {\n onBeforeRouteLeave,\n useRoute,\n} from 'vue-router';\n\nimport { appendRedirectParamToUrl } from './url';\n\n/**\n * Appends the current Vue Router route's fullPath as the `redirect` query parameter to the given URL.\n *\n * @param {string} url - The base URL to modify\n *\n * @returns {string} A new URL with the current route fullPath as the `redirect` parameter\n */\nexport function appendRedirectParamFromCurrentRouteToUrl(url: string) {\n return appendRedirectParamToUrl(url, useRoute().fullPath);\n}\n\n/**\n * Clears an interval referenced by a Vue ref and sets it to null.\n *\n * @param {Ref<null | ReturnType<typeof setInterval>>} intervalRef - A Vue ref holding a NodeJS.Timeout or null\n */\nexport function clearIntervalRef(intervalRef: Ref<null | ReturnType<typeof setInterval>>) {\n if (intervalRef.value) clearInterval(intervalRef.value);\n intervalRef.value = null;\n}\n\n/**\n * Clears a timeout referenced by a Vue ref and sets it to null.\n *\n * @param {Ref<null | ReturnType<typeof setTimeout>>} timeoutRef - A Vue ref holding a NodeJS.Timeout or null\n */\nexport function clearTimeoutRef(timeoutRef: Ref<null | ReturnType<typeof setTimeout>>) {\n if (timeoutRef.value) clearTimeout(timeoutRef.value);\n timeoutRef.value = null;\n}\n\n/**\n * A Vue composition function that remembers and restores scroll position\n * of a scrollable container across route changes and keep-alive activation.\n *\n * Designed for use with `<KeepAlive>` components. Scroll state is saved on\n * route leave and restored when the component is activated again.\n *\n * Note: Without `<KeepAlive>`, the component state is destroyed on unmount,\n * so scroll position will not be preserved.\n *\n * @template T - The type of the scrollable element (defaults to HTMLElement)\n *\n * @param {Ref<null | T>} containerRef - A ref to the scrollable HTML element\n */\nexport function usePreserveScroll<T extends Element = HTMLElement>(containerRef: Ref<null | T>) {\n let scrollLeft = 0;\n let scrollTop = 0;\n onActivated(() => {\n if (!containerRef.value) return;\n containerRef.value.scrollLeft = scrollLeft;\n containerRef.value.scrollTop = scrollTop;\n });\n\n onBeforeRouteLeave(() => {\n scrollLeft = containerRef.value?.scrollLeft || 0;\n scrollTop = containerRef.value?.scrollTop || 0;\n });\n}\n"],"mappings":";;;;;;;;;;;AAgBA,SAAgB,yCAAyC,KAAa;CAClE,OAAO,yBAAyB,KAAK,SAAS,CAAC,CAAC,QAAQ;AAC5D;;;;;;AAOA,SAAgB,iBAAiB,aAAyD;CACtF,IAAI,YAAY,OAAO,cAAc,YAAY,KAAK;CACtD,YAAY,QAAQ;AACxB;;;;;;AAOA,SAAgB,gBAAgB,YAAuD;CACnF,IAAI,WAAW,OAAO,aAAa,WAAW,KAAK;CACnD,WAAW,QAAQ;AACvB;;;;;;;;;;;;;;;AAgBA,SAAgB,kBAAmD,cAA6B;CAC5F,IAAI,aAAa;CACjB,IAAI,YAAY;CAChB,kBAAkB;EACd,IAAI,CAAC,aAAa,OAAO;EACzB,aAAa,MAAM,aAAa;EAChC,aAAa,MAAM,YAAY;CACnC,CAAC;CAED,yBAAyB;EACrB,aAAa,aAAa,OAAO,cAAc;EAC/C,YAAY,aAAa,OAAO,aAAa;CACjD,CAAC;AACL"}
package/dist/web.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","names":[],"sources":["../src/web.ts"],"mappings":";;AASA;;;;;AAeA;iBAfgB,2CAAA,CAA4C,GAAA;;;;;;;;;;;iBAe5C,6CAAA,CAA8C,GAAA,UAAa,OAAA,YAAgB,MAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"web.d.ts","names":[],"sources":["../src/web.ts"],"mappings":";;AASA;;;;AAAuE;AAevE;iBAfgB,2CAAA,CAA4C,GAAW;;;;;;;;AAeoB;;;iBAA3E,6CAAA,CAA8C,GAAA,UAAa,OAAA,YAAgB,MAAA,CAAA,OAAA"}
package/dist/web.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","names":[],"sources":["../src/web.ts"],"sourcesContent":["import { appendRedirectParamToUrl } from './url';\n\n/**\n * Appends the current browser URL (including path, query, and hash) as the `redirect` query parameter to the given URL.\n *\n * @param {string} url - The base URL to modify\n *\n * @returns {string} A new URL with the current location as the `redirect` parameter\n */\nexport function appendRedirectParamFromCurrentLocationToUrl(url: string) {\n const currentPath = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n return appendRedirectParamToUrl(url, currentPath);\n}\n\n/**\n * Navigates to the given URL, appending the current browser location\n * (path, query, and hash) as the `redirect` query parameter.\n *\n * Useful for redirecting to login or other gateways while preserving\n * the current location for post-auth navigation.\n *\n * @param {string} url - The destination URL to navigate to\n * @param {number} [delayMs] - Optional delay in milliseconds before navigation\n */\nexport function assignUrlWithRedirectParamFromCurrentLocation(url: string, delayMs?: number) {\n if (delayMs === undefined) window.location.assign(appendRedirectParamFromCurrentLocationToUrl(url));\n else return setTimeout(() => window.location.assign(appendRedirectParamFromCurrentLocationToUrl(url)), delayMs);\n}\n"],"mappings":";;;;;;;;;AASA,SAAgB,4CAA4C,KAAa;CAErE,OAAO,yBAAyB,KAAK,GADd,OAAO,SAAS,WAAW,OAAO,SAAS,SAAS,OAAO,SAAS,OAC1C;;;;;;;;;;;;AAarD,SAAgB,8CAA8C,KAAa,SAAkB;CACzF,IAAI,YAAY,KAAA,GAAW,OAAO,SAAS,OAAO,4CAA4C,IAAI,CAAC;MAC9F,OAAO,iBAAiB,OAAO,SAAS,OAAO,4CAA4C,IAAI,CAAC,EAAE,QAAQ"}
1
+ {"version":3,"file":"web.js","names":[],"sources":["../src/web.ts"],"sourcesContent":["import { appendRedirectParamToUrl } from './url';\n\n/**\n * Appends the current browser URL (including path, query, and hash) as the `redirect` query parameter to the given URL.\n *\n * @param {string} url - The base URL to modify\n *\n * @returns {string} A new URL with the current location as the `redirect` parameter\n */\nexport function appendRedirectParamFromCurrentLocationToUrl(url: string) {\n const currentPath = `${window.location.pathname}${window.location.search}${window.location.hash}`;\n return appendRedirectParamToUrl(url, currentPath);\n}\n\n/**\n * Navigates to the given URL, appending the current browser location\n * (path, query, and hash) as the `redirect` query parameter.\n *\n * Useful for redirecting to login or other gateways while preserving\n * the current location for post-auth navigation.\n *\n * @param {string} url - The destination URL to navigate to\n * @param {number} [delayMs] - Optional delay in milliseconds before navigation\n */\nexport function assignUrlWithRedirectParamFromCurrentLocation(url: string, delayMs?: number) {\n if (delayMs === undefined) window.location.assign(appendRedirectParamFromCurrentLocationToUrl(url));\n else return setTimeout(() => window.location.assign(appendRedirectParamFromCurrentLocationToUrl(url)), delayMs);\n}\n"],"mappings":";;;;;;;;;AASA,SAAgB,4CAA4C,KAAa;CAErE,OAAO,yBAAyB,KAAK,GADd,OAAO,SAAS,WAAW,OAAO,SAAS,SAAS,OAAO,SAAS,MAC3C;AACpD;;;;;;;;;;;AAYA,SAAgB,8CAA8C,KAAa,SAAkB;CACzF,IAAI,YAAY,KAAA,GAAW,OAAO,SAAS,OAAO,4CAA4C,GAAG,CAAC;MAC7F,OAAO,iBAAiB,OAAO,SAAS,OAAO,4CAA4C,GAAG,CAAC,GAAG,OAAO;AAClH"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kikiutils/shared",
3
3
  "type": "module",
4
- "version": "15.1.0",
4
+ "version": "16.0.0",
5
5
  "description": "A lightweight and modular utility library for modern JavaScript and TypeScript — includes secure hashing, flexible logging, datetime tools, Vue/web helpers, storage abstraction, and more.",
6
6
  "author": "kiki-kanri",
7
7
  "license": "MIT",
@@ -70,18 +70,18 @@
70
70
  "@noble/hashes": "^2.2.0",
71
71
  "@types/ssh2": "^1.15.5",
72
72
  "async-validator": "^4.2.5",
73
- "bson": "^7.2.0",
73
+ "bson": "^7.3.1",
74
74
  "consola": "^3.4.2",
75
- "date-fns": "^4.1.0",
75
+ "date-fns": "^4.4.0",
76
76
  "decimal.js": "^10.6.0",
77
- "element-plus": "^2.13.7",
78
- "lru-cache": "^11.3.5",
77
+ "element-plus": "^2.14.2",
78
+ "lru-cache": "^11.5.2",
79
79
  "millify": "^6.1.0",
80
- "msgpackr": "^2.0.1",
80
+ "msgpackr": "^2.0.4",
81
81
  "node-ssh": "^13.2.1",
82
82
  "pino": "^10.3.1",
83
83
  "pino-pretty": "^13.1.3",
84
- "vue": "^3.5.32",
84
+ "vue": "^3.5.39",
85
85
  "vue-router": ">= 4.6.4"
86
86
  },
87
87
  "peerDependenciesMeta": {
@@ -135,35 +135,36 @@
135
135
  }
136
136
  },
137
137
  "devDependencies": {
138
- "@antfu/eslint-config": "^8.2.0",
139
- "@kikiutils/eslint-config": "^9.1.2",
140
- "@kikiutils/tsconfigs": "^6.0.0",
138
+ "@antfu/eslint-config": "^9.1.0",
139
+ "@kikiutils/eslint-config": "^9.2.0",
140
+ "@kikiutils/tsconfigs": "^7.0.0",
141
141
  "@noble/hashes": "^2.2.0",
142
- "@types/node": "^25.6.2",
142
+ "@types/node": "^26.1.0",
143
143
  "@types/ssh2": "^1.15.5",
144
- "@vitest/coverage-v8": "^4.1.5",
144
+ "@vitest/coverage-v8": "^4.1.10",
145
145
  "async-validator": "^4.2.5",
146
- "bson": "^7.2.0",
146
+ "bson": "^7.3.1",
147
147
  "changelogen": "^0.6.2",
148
148
  "consola": "^3.4.2",
149
149
  "cross-env": "^10.1.0",
150
- "date-fns": "^4.1.0",
150
+ "date-fns": "^4.4.0",
151
151
  "decimal.js": "^10.6.0",
152
- "element-plus": "^2.14.0",
152
+ "element-plus": "^2.14.2",
153
+ "eslint": "^10.6.0",
153
154
  "jsdom": "^29.1.1",
154
- "knip": "^6.12.2",
155
- "lru-cache": "^11.3.6",
155
+ "knip": "^6.25.0",
156
+ "lru-cache": "^11.5.2",
156
157
  "millify": "^6.1.0",
157
- "msgpackr": "^2.0.1",
158
+ "msgpackr": "^2.0.4",
158
159
  "node-ssh": "^13.2.1",
159
160
  "pino": "^10.3.1",
160
161
  "pino-pretty": "^13.1.3",
161
- "publint": "^0.3.20",
162
- "tsdown": "^0.22.0",
162
+ "publint": "^0.3.21",
163
+ "tsdown": "^0.22.3",
163
164
  "typescript": "^6.0.3",
164
165
  "unplugin-unused": "^0.5.7",
165
- "vitest": "^4.1.5",
166
- "vue": "^3.5.34",
167
- "vue-router": "^5.0.6"
166
+ "vitest": "^4.1.10",
167
+ "vue": "^3.5.39",
168
+ "vue-router": "^5.1.0"
168
169
  }
169
170
  }
@@ -12,8 +12,6 @@ import type {
12
12
  TransferOptions,
13
13
  } from 'ssh2';
14
14
 
15
- import type { Nullable } from '../types';
16
-
17
15
  import type { PathLike } from './path';
18
16
 
19
17
  const loggerLevelStringToConsolaLogLevelMap = {
@@ -101,8 +99,8 @@ export class SshClient {
101
99
  async getFile(
102
100
  localFile: PathLike,
103
101
  remoteFile: PathLike,
104
- givenSftp?: Nullable<SFTPWrapper>,
105
- transferOptions?: Nullable<TransferOptions>,
102
+ givenSftp?: null | SFTPWrapper,
103
+ transferOptions?: null | TransferOptions,
106
104
  ) {
107
105
  try {
108
106
  await this.#nodeSsh.getFile(localFile.toString(), remoteFile.toString(), givenSftp, transferOptions);
@@ -141,8 +139,8 @@ export class SshClient {
141
139
  async putFile(
142
140
  localFile: PathLike,
143
141
  remoteFile: PathLike,
144
- givenSftp?: Nullable<SFTPWrapper>,
145
- transferOptions?: Nullable<TransferOptions>,
142
+ givenSftp?: null | SFTPWrapper,
143
+ transferOptions?: null | TransferOptions,
146
144
  ) {
147
145
  try {
148
146
  await this.#nodeSsh.putFile(localFile.toString(), remoteFile.toString(), givenSftp, transferOptions);
@@ -1,14 +1,12 @@
1
+ import { Buffer } from 'node:buffer';
1
2
  import { createHash } from 'node:crypto';
2
- import type {
3
- BinaryLike,
4
- BinaryToTextEncoding,
5
- } from 'node:crypto';
3
+ import type { BinaryLike } from 'node:crypto';
6
4
 
7
5
  /**
8
6
  * Computes the MD5 hash of the given data.
9
7
  *
10
8
  * @param {BinaryLike} data - The input data to hash
11
- * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
9
+ * @param {BufferEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
12
10
  *
13
11
  * @returns {string | Buffer} The hash digest in the specified encoding
14
12
  *
@@ -19,8 +17,8 @@ import type {
19
17
  * console.log(cryptoMd5('test')); // 098f6bcd4621d373cade4e832627b4f6
20
18
  * ```
21
19
  */
22
- export function cryptoMd5(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {
23
- return createHash('md5').update(data).digest(outputEncoding);
20
+ export function cryptoMd5(data: BinaryLike, outputEncoding: BufferEncoding = 'hex') {
21
+ return createHash('md5').update(normalizeHashData(data)).digest(outputEncoding);
24
22
  }
25
23
 
26
24
  /**
@@ -38,14 +36,14 @@ export function cryptoMd5(data: BinaryLike, outputEncoding: BinaryToTextEncoding
38
36
  * ```
39
37
  */
40
38
  export function cryptoMd5ToBuffer(data: BinaryLike) {
41
- return createHash('md5').update(data).digest();
39
+ return createHash('md5').update(normalizeHashData(data)).digest();
42
40
  }
43
41
 
44
42
  /**
45
43
  * Computes the SHA-3 hash of the given data using the 224-bit digest.
46
44
  *
47
45
  * @param {BinaryLike} data - The input data to hash
48
- * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
46
+ * @param {BufferEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
49
47
  *
50
48
  * @returns {string | Buffer} The hash digest in the specified encoding
51
49
  *
@@ -56,8 +54,8 @@ export function cryptoMd5ToBuffer(data: BinaryLike) {
56
54
  * console.log(cryptoSha3224('test')); // 3797bf0afbbfca4a7bbba7602a2b552746876517a7f9b7ce2db0ae7b
57
55
  * ```
58
56
  */
59
- export function cryptoSha3224(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {
60
- return createHash('sha3-224').update(data).digest(outputEncoding);
57
+ export function cryptoSha3224(data: BinaryLike, outputEncoding: BufferEncoding = 'hex') {
58
+ return createHash('sha3-224').update(normalizeHashData(data)).digest(outputEncoding);
61
59
  }
62
60
 
63
61
  /**
@@ -75,14 +73,14 @@ export function cryptoSha3224(data: BinaryLike, outputEncoding: BinaryToTextEnco
75
73
  * ```
76
74
  */
77
75
  export function cryptoSha3224ToBuffer(data: BinaryLike) {
78
- return createHash('sha3-224').update(data).digest();
76
+ return createHash('sha3-224').update(normalizeHashData(data)).digest();
79
77
  }
80
78
 
81
79
  /**
82
80
  * Computes the SHA-3 hash of the given data using the 256-bit digest.
83
81
  *
84
82
  * @param {BinaryLike} data - The input data to hash
85
- * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
83
+ * @param {BufferEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
86
84
  *
87
85
  * @returns {string | Buffer} The hash digest in the specified encoding
88
86
  *
@@ -93,8 +91,8 @@ export function cryptoSha3224ToBuffer(data: BinaryLike) {
93
91
  * console.log(cryptoSha3256('test')); // 36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80
94
92
  * ```
95
93
  */
96
- export function cryptoSha3256(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {
97
- return createHash('sha3-256').update(data).digest(outputEncoding);
94
+ export function cryptoSha3256(data: BinaryLike, outputEncoding: BufferEncoding = 'hex') {
95
+ return createHash('sha3-256').update(normalizeHashData(data)).digest(outputEncoding);
98
96
  }
99
97
 
100
98
  /**
@@ -112,14 +110,14 @@ export function cryptoSha3256(data: BinaryLike, outputEncoding: BinaryToTextEnco
112
110
  * ```
113
111
  */
114
112
  export function cryptoSha3256ToBuffer(data: BinaryLike) {
115
- return createHash('sha3-256').update(data).digest();
113
+ return createHash('sha3-256').update(normalizeHashData(data)).digest();
116
114
  }
117
115
 
118
116
  /**
119
117
  * Computes the SHA-3 hash of the given data using the 384-bit digest.
120
118
  *
121
119
  * @param {BinaryLike} data - The input data to hash
122
- * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
120
+ * @param {BufferEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
123
121
  *
124
122
  * @returns {string | Buffer} The hash digest in the specified encoding
125
123
  *
@@ -130,8 +128,8 @@ export function cryptoSha3256ToBuffer(data: BinaryLike) {
130
128
  * console.log(cryptoSha3384('test')); // e516dabb23b6e30026863543282780a3ae0dccf05551cf0295178d7f...
131
129
  * ```
132
130
  */
133
- export function cryptoSha3384(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {
134
- return createHash('sha3-384').update(data).digest(outputEncoding);
131
+ export function cryptoSha3384(data: BinaryLike, outputEncoding: BufferEncoding = 'hex') {
132
+ return createHash('sha3-384').update(normalizeHashData(data)).digest(outputEncoding);
135
133
  }
136
134
 
137
135
  /**
@@ -149,14 +147,14 @@ export function cryptoSha3384(data: BinaryLike, outputEncoding: BinaryToTextEnco
149
147
  * ```
150
148
  */
151
149
  export function cryptoSha3384ToBuffer(data: BinaryLike) {
152
- return createHash('sha3-384').update(data).digest();
150
+ return createHash('sha3-384').update(normalizeHashData(data)).digest();
153
151
  }
154
152
 
155
153
  /**
156
154
  * Computes the SHA-3 hash of the given data using the 512-bit digest.
157
155
  *
158
156
  * @param {BinaryLike} data - The input data to hash
159
- * @param {BinaryToTextEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
157
+ * @param {BufferEncoding} [outputEncoding] - The output encoding (default: `'hex'`)
160
158
  *
161
159
  * @returns {string | Buffer} The hash digest in the specified encoding
162
160
  *
@@ -167,8 +165,8 @@ export function cryptoSha3384ToBuffer(data: BinaryLike) {
167
165
  * console.log(cryptoSha3512('test')); // 9ece086e9bac491fac5c1d1046ca11d737b92a2b2ebd93f005d7...
168
166
  * ```
169
167
  */
170
- export function cryptoSha3512(data: BinaryLike, outputEncoding: BinaryToTextEncoding = 'hex') {
171
- return createHash('sha3-512').update(data).digest(outputEncoding);
168
+ export function cryptoSha3512(data: BinaryLike, outputEncoding: BufferEncoding = 'hex') {
169
+ return createHash('sha3-512').update(normalizeHashData(data)).digest(outputEncoding);
172
170
  }
173
171
 
174
172
  /**
@@ -186,5 +184,9 @@ export function cryptoSha3512(data: BinaryLike, outputEncoding: BinaryToTextEnco
186
184
  * ```
187
185
  */
188
186
  export function cryptoSha3512ToBuffer(data: BinaryLike) {
189
- return createHash('sha3-512').update(data).digest();
187
+ return createHash('sha3-512').update(normalizeHashData(data)).digest();
188
+ }
189
+
190
+ function normalizeHashData(data: BinaryLike): NodeJS.ArrayBufferView | string {
191
+ return typeof data === 'string' || ArrayBuffer.isView(data) ? data : Buffer.from(data);
190
192
  }
@@ -1,5 +1,3 @@
1
- import type { Nullable } from '../../types';
2
-
3
1
  /**
4
2
  * Low-level Redis-like adapter interface for raw buffer operations.
5
3
  */
@@ -12,7 +10,7 @@ export interface RedisLikeAdapter {
12
10
  /**
13
11
  * Gets the raw buffer value for a key.
14
12
  */
15
- getBuffer: (key: string) => Promise<Nullable<Uint8Array>>;
13
+ getBuffer: (key: string) => Promise<null | Uint8Array>;
16
14
 
17
15
  /**
18
16
  * Checks if a key exists.
@@ -42,7 +40,7 @@ export interface RedisLikeStorage {
42
40
  /**
43
41
  * Gets a deserialized value by key.
44
42
  */
45
- getItem: <T = unknown>(key: string) => Promise<Nullable<T>>;
43
+ getItem: <T = unknown>(key: string) => Promise<null | T>;
46
44
 
47
45
  /**
48
46
  * Gets the TTL of a key in seconds.
@@ -31,11 +31,6 @@ export type MaybePartial<T> = Partial<T> | T;
31
31
  */
32
32
  export type MaybeReadonly<T> = Readonly<T> | T;
33
33
 
34
- /**
35
- * Explicitly nullable value helper.
36
- */
37
- export type Nullable<T> = null | T;
38
-
39
34
  /**
40
35
  * Number-like value represented as a number or a numeric string.
41
36
  */
package/src/types/vue.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  import type { GlobalComponents } from 'vue';
2
2
 
3
- import type { Nullable } from './';
4
-
5
3
  /**
6
4
  * A type that represents a reference to a Vue component instance.
7
5
  * The reference can be either an instance of the specified component or null.
@@ -15,4 +13,4 @@ import type { Nullable } from './';
15
13
  * const keepAliveRef = ref<ComponentRef<'KeepAlive'>>(null);
16
14
  * ```
17
15
  */
18
- export type ComponentRef<K extends keyof GlobalComponents> = Nullable<InstanceType<GlobalComponents[K]>>;
16
+ export type ComponentRef<K extends keyof GlobalComponents> = InstanceType<GlobalComponents[K]> | null;
package/src/url.ts CHANGED
@@ -5,18 +5,15 @@
5
5
  *
6
6
  * @param {string} url - The target URL to modify
7
7
  * @param {string} redirectPath - The path to use as the redirect destination
8
- * (must be an absolute path starting with '/')
8
+ * (must be a safe same-origin application path starting with `/`)
9
9
  *
10
10
  * @returns {string} A new URL string with the `redirect` query parameter
11
11
  *
12
- * @throws {Error} If redirectPath is not a valid relative path (must start with '/')
12
+ * @throws {Error} If redirectPath is not a safe same-origin application path
13
13
  */
14
14
  export function appendRedirectParamToUrl(url: string, redirectPath: string) {
15
- if (!redirectPath.startsWith('/')) {
16
- throw new Error(
17
- `Invalid redirect path: "${redirectPath}". Redirect paths must be absolute paths starting with '/'.`,
18
- );
19
- }
15
+ // eslint-disable-next-line style/max-len
16
+ if (!isSafeRedirectPath(redirectPath)) throw new Error(`Invalid redirect path: "${redirectPath}". Redirect paths must be safe same-origin paths starting with '/'.`);
20
17
 
21
18
  const [baseAndHash, rawQuery = ''] = url.split('?');
22
19
  const [base, hash] = (baseAndHash || '').split('#');
@@ -25,3 +22,38 @@ export function appendRedirectParamToUrl(url: string, redirectPath: string) {
25
22
  const queryString = searchParams.toString();
26
23
  return hash ? `${base}?${queryString}#${hash}` : `${base}?${queryString}`;
27
24
  }
25
+
26
+ /**
27
+ * Returns whether a value is a safe same-origin redirect path.
28
+ *
29
+ * Safe redirect paths are absolute application paths such as `/dashboard`.
30
+ * Protocol-relative URLs (`//example.com`), absolute URLs, backslash paths,
31
+ * and non-string values are rejected.
32
+ *
33
+ * @param {unknown} value - The value to check
34
+ *
35
+ * @returns {boolean} Whether the value is safe to use as an application redirect path
36
+ */
37
+ export function isSafeRedirectPath(value: unknown): value is string {
38
+ if (typeof value !== 'string') return false;
39
+ if (!value.startsWith('/')) return false;
40
+ if (value.startsWith('//')) return false;
41
+ if (value.includes('\\')) return false;
42
+ return true;
43
+ }
44
+
45
+ /**
46
+ * Normalizes a redirect value into a safe same-origin application path.
47
+ *
48
+ * If an array is provided, the first value is checked. Unsafe values fall back
49
+ * to the provided fallback path.
50
+ *
51
+ * @param {unknown} value - The redirect value to normalize
52
+ * @param {string} fallback - The safe fallback path
53
+ *
54
+ * @returns {string} A safe redirect path
55
+ */
56
+ export function normalizeRedirectPath(value: unknown, fallback = '/') {
57
+ const redirectPath = Array.isArray(value) ? value[0] : value;
58
+ return isSafeRedirectPath(redirectPath) ? redirectPath : fallback;
59
+ }