@scalar/helpers 0.0.13 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @scalar/helpers
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#7289](https://github.com/scalar/scalar/pull/7289) [`9c9dbba`](https://github.com/scalar/scalar/commit/9c9dbbaa940667303f0ace59469fd78c2a741937) Thanks [@amritk](https://github.com/amritk)! - feat: move debounce to helpers and add max wait
8
+
9
+ - [#7252](https://github.com/scalar/scalar/pull/7252) [`4bec1ba`](https://github.com/scalar/scalar/commit/4bec1ba332e919c4ee32dcfbfb07bd8ee42c4d74) Thanks [@hwkr](https://github.com/hwkr)! - fix(api-reference): improve wrapping of long strings
10
+
11
+ ## 0.1.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#7235](https://github.com/scalar/scalar/pull/7235) [`c1ecd0c`](https://github.com/scalar/scalar/commit/c1ecd0c6096f3fbe2e3d8ad3794ea718bb6bce66) Thanks [@marcalexiei](https://github.com/marcalexiei)! - feat(helpers): add `node:path` polyfill
16
+
17
+ ### Patch Changes
18
+
19
+ - [#7266](https://github.com/scalar/scalar/pull/7266) [`fddf294`](https://github.com/scalar/scalar/commit/fddf294b00dd8c9eb5c713c338f2ec6e3f62523d) Thanks [@amritk](https://github.com/amritk)! - fix: remove useage of crypto.subtle in all contexts
20
+
3
21
  ## 0.0.13
4
22
 
5
23
  ### Patch Changes
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Options for configuring the debounce behavior.
3
+ */
4
+ export type DebounceOptions = {
5
+ /** The delay in milliseconds before executing the function. Defaults to 100ms. */
6
+ delay?: number;
7
+ /** Maximum time in milliseconds to wait before forcing execution, even with continuous calls. */
8
+ maxWait?: number;
9
+ };
10
+ /**
11
+ * Creates a debounced function executor that delays execution until after a specified time.
12
+ * Multiple calls with the same key will cancel previous pending executions.
13
+ *
14
+ * This is useful for batching rapid updates (like auto-save or API calls) to avoid
15
+ * unnecessary processing or network requests.
16
+ *
17
+ * @param options - Configuration options for delay, maxWait, and key separator
18
+ * @returns A function that accepts a key array and callback to execute
19
+ *
20
+ * @example
21
+ * const debouncedSave = debounce({ delay: 328 })
22
+ * debouncedSave.execute(['user', '123'], () => saveUser(user))
23
+ *
24
+ * @example
25
+ * // With maxWait to guarantee execution even with continuous calls
26
+ * const debouncedSave = debounce({ delay: 328, maxWait: 2000 })
27
+ * debouncedSave.execute(['user', '123'], () => saveUser(user))
28
+ */
29
+ export declare const debounce: (options?: DebounceOptions) => {
30
+ execute: (key: string, fn: () => unknown | Promise<unknown>) => void;
31
+ cleanup: () => void;
32
+ };
33
+ //# sourceMappingURL=debounce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debounce.d.ts","sourceRoot":"","sources":["../../src/general/debounce.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iGAAiG;IACjG,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,QAAQ,GAAI,UAAS,eAAoB;mBA6C9B,MAAM,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAG,IAAI;mBAvCrD,IAAI;CAiEzB,CAAA"}
@@ -0,0 +1,55 @@
1
+ const debounce = (options = {}) => {
2
+ const { delay = 328, maxWait } = options;
3
+ const timeouts = /* @__PURE__ */ new Map();
4
+ const maxWaitTimeouts = /* @__PURE__ */ new Map();
5
+ const latestFunctions = /* @__PURE__ */ new Map();
6
+ const cleanup = () => {
7
+ timeouts.forEach(clearTimeout);
8
+ maxWaitTimeouts.forEach(clearTimeout);
9
+ timeouts.clear();
10
+ maxWaitTimeouts.clear();
11
+ latestFunctions.clear();
12
+ };
13
+ const executeAndCleanup = (key) => {
14
+ const fn = latestFunctions.get(key);
15
+ const timeout = timeouts.get(key);
16
+ if (timeout !== void 0) {
17
+ clearTimeout(timeout);
18
+ timeouts.delete(key);
19
+ }
20
+ const maxWaitTimeout = maxWaitTimeouts.get(key);
21
+ if (maxWaitTimeout !== void 0) {
22
+ clearTimeout(maxWaitTimeout);
23
+ maxWaitTimeouts.delete(key);
24
+ }
25
+ latestFunctions.delete(key);
26
+ if (fn !== void 0) {
27
+ try {
28
+ fn();
29
+ } catch {
30
+ }
31
+ }
32
+ };
33
+ const execute = (key, fn) => {
34
+ latestFunctions.set(key, fn);
35
+ const existingTimeout = timeouts.get(key);
36
+ if (existingTimeout !== void 0) {
37
+ clearTimeout(existingTimeout);
38
+ }
39
+ timeouts.set(
40
+ key,
41
+ setTimeout(() => executeAndCleanup(key), delay)
42
+ );
43
+ if (maxWait !== void 0 && !maxWaitTimeouts.has(key)) {
44
+ maxWaitTimeouts.set(
45
+ key,
46
+ setTimeout(() => executeAndCleanup(key), maxWait)
47
+ );
48
+ }
49
+ };
50
+ return { execute, cleanup };
51
+ };
52
+ export {
53
+ debounce
54
+ };
55
+ //# sourceMappingURL=debounce.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/general/debounce.ts"],
4
+ "sourcesContent": ["/**\n * Options for configuring the debounce behavior.\n */\nexport type DebounceOptions = {\n /** The delay in milliseconds before executing the function. Defaults to 100ms. */\n delay?: number\n /** Maximum time in milliseconds to wait before forcing execution, even with continuous calls. */\n maxWait?: number\n}\n\n/**\n * Creates a debounced function executor that delays execution until after a specified time.\n * Multiple calls with the same key will cancel previous pending executions.\n *\n * This is useful for batching rapid updates (like auto-save or API calls) to avoid\n * unnecessary processing or network requests.\n *\n * @param options - Configuration options for delay, maxWait, and key separator\n * @returns A function that accepts a key array and callback to execute\n *\n * @example\n * const debouncedSave = debounce({ delay: 328 })\n * debouncedSave.execute(['user', '123'], () => saveUser(user))\n *\n * @example\n * // With maxWait to guarantee execution even with continuous calls\n * const debouncedSave = debounce({ delay: 328, maxWait: 2000 })\n * debouncedSave.execute(['user', '123'], () => saveUser(user))\n */\nexport const debounce = (options: DebounceOptions = {}) => {\n const { delay = 328, maxWait } = options\n const timeouts = new Map<string, ReturnType<typeof setTimeout>>()\n const maxWaitTimeouts = new Map<string, ReturnType<typeof setTimeout>>()\n const latestFunctions = new Map<string, () => unknown | Promise<unknown>>()\n\n const cleanup = (): void => {\n timeouts.forEach(clearTimeout)\n maxWaitTimeouts.forEach(clearTimeout)\n timeouts.clear()\n maxWaitTimeouts.clear()\n latestFunctions.clear()\n }\n\n /** Executes the function and cleans up all associated timeouts */\n const executeAndCleanup = (key: string): void => {\n // Get the latest function for this key\n const fn = latestFunctions.get(key)\n\n // Clear both timeout types\n const timeout = timeouts.get(key)\n if (timeout !== undefined) {\n clearTimeout(timeout)\n timeouts.delete(key)\n }\n\n const maxWaitTimeout = maxWaitTimeouts.get(key)\n if (maxWaitTimeout !== undefined) {\n clearTimeout(maxWaitTimeout)\n maxWaitTimeouts.delete(key)\n }\n\n // Clear the latest function reference\n latestFunctions.delete(key)\n\n // Execute the function if it exists\n if (fn !== undefined) {\n try {\n fn()\n } catch {\n // Errors are silently caught to prevent the debounce mechanism from breaking\n }\n }\n }\n\n const execute = (key: string, fn: () => unknown | Promise<unknown>): void => {\n // Store the latest function for this key\n latestFunctions.set(key, fn)\n\n // Clear existing debounce timeout\n const existingTimeout = timeouts.get(key)\n if (existingTimeout !== undefined) {\n clearTimeout(existingTimeout)\n }\n\n // Set debounce timeout\n timeouts.set(\n key,\n setTimeout(() => executeAndCleanup(key), delay),\n )\n\n // Set maxWait timeout only if configured and this is a new sequence\n if (maxWait !== undefined && !maxWaitTimeouts.has(key)) {\n maxWaitTimeouts.set(\n key,\n setTimeout(() => executeAndCleanup(key), maxWait),\n )\n }\n }\n\n return { execute, cleanup }\n}\n"],
5
+ "mappings": "AA6BO,MAAM,WAAW,CAAC,UAA2B,CAAC,MAAM;AACzD,QAAM,EAAE,QAAQ,KAAK,QAAQ,IAAI;AACjC,QAAM,WAAW,oBAAI,IAA2C;AAChE,QAAM,kBAAkB,oBAAI,IAA2C;AACvE,QAAM,kBAAkB,oBAAI,IAA8C;AAE1E,QAAM,UAAU,MAAY;AAC1B,aAAS,QAAQ,YAAY;AAC7B,oBAAgB,QAAQ,YAAY;AACpC,aAAS,MAAM;AACf,oBAAgB,MAAM;AACtB,oBAAgB,MAAM;AAAA,EACxB;AAGA,QAAM,oBAAoB,CAAC,QAAsB;AAE/C,UAAM,KAAK,gBAAgB,IAAI,GAAG;AAGlC,UAAM,UAAU,SAAS,IAAI,GAAG;AAChC,QAAI,YAAY,QAAW;AACzB,mBAAa,OAAO;AACpB,eAAS,OAAO,GAAG;AAAA,IACrB;AAEA,UAAM,iBAAiB,gBAAgB,IAAI,GAAG;AAC9C,QAAI,mBAAmB,QAAW;AAChC,mBAAa,cAAc;AAC3B,sBAAgB,OAAO,GAAG;AAAA,IAC5B;AAGA,oBAAgB,OAAO,GAAG;AAG1B,QAAI,OAAO,QAAW;AACpB,UAAI;AACF,WAAG;AAAA,MACL,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,CAAC,KAAa,OAA+C;AAE3E,oBAAgB,IAAI,KAAK,EAAE;AAG3B,UAAM,kBAAkB,SAAS,IAAI,GAAG;AACxC,QAAI,oBAAoB,QAAW;AACjC,mBAAa,eAAe;AAAA,IAC9B;AAGA,aAAS;AAAA,MACP;AAAA,MACA,WAAW,MAAM,kBAAkB,GAAG,GAAG,KAAK;AAAA,IAChD;AAGA,QAAI,YAAY,UAAa,CAAC,gBAAgB,IAAI,GAAG,GAAG;AACtD,sBAAgB;AAAA,QACd;AAAA,QACA,WAAW,MAAM,kBAAkB,GAAG,GAAG,OAAO;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,QAAQ;AAC5B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,23 @@
1
+ export declare function resolve(...parameters: Array<string>): string;
2
+ export declare function normalize(inputPath: string): string;
3
+ export declare function isAbsolute(path: string): boolean;
4
+ export declare function join(...paths: string[]): string;
5
+ export declare function relative(from: string, to: string): string;
6
+ export declare const sep = "/";
7
+ export declare const delimiter = ":";
8
+ export declare function dirname(path: string): string;
9
+ export declare function basename(path: string, ext?: string): string;
10
+ export declare function extname(path: string): string;
11
+ export declare const path: {
12
+ extname: typeof extname;
13
+ basename: typeof basename;
14
+ dirname: typeof dirname;
15
+ sep: string;
16
+ delimiter: string;
17
+ relative: typeof relative;
18
+ join: typeof join;
19
+ isAbsolute: typeof isAbsolute;
20
+ normalize: typeof normalize;
21
+ resolve: typeof resolve;
22
+ };
23
+ //# sourceMappingURL=path.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/node/path.ts"],"names":[],"mappings":"AAgEA,wBAAgB,OAAO,CAAC,GAAG,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,UA6BnD;AAID,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAkBnD;AAGD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAGD,wBAAgB,IAAI,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,UAWtC;AAID,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,UA6ChD;AAED,eAAO,MAAM,GAAG,MAAM,CAAA;AACtB,eAAO,MAAM,SAAS,MAAM,CAAA;AAE5B,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgB5C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,eAAO,MAAM,IAAI;;;;;;;;;;;CAWhB,CAAA"}
@@ -0,0 +1,157 @@
1
+ function normalizeArray(parts, allowAboveRoot) {
2
+ let up = 0;
3
+ for (let i = parts.length - 1; i >= 0; i--) {
4
+ const last = parts[i];
5
+ if (last === ".") {
6
+ parts.splice(i, 1);
7
+ } else if (last === "..") {
8
+ parts.splice(i, 1);
9
+ up++;
10
+ } else if (up) {
11
+ parts.splice(i, 1);
12
+ up--;
13
+ }
14
+ }
15
+ if (allowAboveRoot) {
16
+ for (; up--; up) {
17
+ parts.unshift("..");
18
+ }
19
+ }
20
+ return parts;
21
+ }
22
+ const splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^/]+?|)(\.[^./]*|))(?:[/]*)$/;
23
+ const splitPath = (filename) => splitPathRe.exec(filename).slice(1);
24
+ function resolve(...parameters) {
25
+ let resolvedPath = "", resolvedAbsolute = false;
26
+ for (let i = parameters.length - 1; i >= -1 && !resolvedAbsolute; i--) {
27
+ const path2 = i >= 0 ? parameters[i] : "/";
28
+ if (typeof path2 !== "string") {
29
+ throw new TypeError("Arguments to path.resolve must be strings");
30
+ }
31
+ if (!path2) {
32
+ continue;
33
+ }
34
+ resolvedPath = path2 + "/" + resolvedPath;
35
+ resolvedAbsolute = path2.charAt(0) === "/";
36
+ }
37
+ resolvedPath = normalizeArray(
38
+ resolvedPath.split("/").filter((p) => !!p),
39
+ !resolvedAbsolute
40
+ ).join("/");
41
+ return (resolvedAbsolute ? "/" : "") + resolvedPath || ".";
42
+ }
43
+ function normalize(inputPath) {
44
+ const isPathAbsolute = isAbsolute(inputPath), trailingSlash = inputPath.slice(-1) === "/";
45
+ let path2 = normalizeArray(
46
+ inputPath.split("/").filter((p) => !!p),
47
+ !isPathAbsolute
48
+ ).join("/");
49
+ if (!path2 && !isPathAbsolute) {
50
+ path2 = ".";
51
+ }
52
+ if (path2 && trailingSlash) {
53
+ path2 += "/";
54
+ }
55
+ return (isPathAbsolute ? "/" : "") + path2;
56
+ }
57
+ function isAbsolute(path2) {
58
+ return path2.charAt(0) === "/";
59
+ }
60
+ function join(...paths) {
61
+ return normalize(
62
+ paths.filter((p) => {
63
+ if (typeof p !== "string") {
64
+ throw new TypeError("Arguments to path.join must be strings");
65
+ }
66
+ return p;
67
+ }).join("/")
68
+ );
69
+ }
70
+ function relative(from, to) {
71
+ const fromResolved = resolve(from).substring(1);
72
+ const toResolved = resolve(to).substring(1);
73
+ function trim(arr) {
74
+ let start = 0;
75
+ for (; start < arr.length; start++) {
76
+ if (arr[start] !== "") {
77
+ break;
78
+ }
79
+ }
80
+ let end = arr.length - 1;
81
+ for (; end >= 0; end--) {
82
+ if (arr[end] !== "") {
83
+ break;
84
+ }
85
+ }
86
+ if (start > end) {
87
+ return [];
88
+ }
89
+ return arr.slice(start, end - start + 1);
90
+ }
91
+ const fromParts = trim(fromResolved.split("/"));
92
+ const toParts = trim(toResolved.split("/"));
93
+ const length = Math.min(fromParts.length, toParts.length);
94
+ let samePartsLength = length;
95
+ for (let i = 0; i < length; i++) {
96
+ if (fromParts[i] !== toParts[i]) {
97
+ samePartsLength = i;
98
+ break;
99
+ }
100
+ }
101
+ let outputParts = [];
102
+ for (let i = samePartsLength; i < fromParts.length; i++) {
103
+ outputParts.push("..");
104
+ }
105
+ outputParts = outputParts.concat(toParts.slice(samePartsLength));
106
+ return outputParts.join("/");
107
+ }
108
+ const sep = "/";
109
+ const delimiter = ":";
110
+ function dirname(path2) {
111
+ const result = splitPath(path2);
112
+ const root = result[0];
113
+ let dir = result[1];
114
+ if (!root && !dir) {
115
+ return ".";
116
+ }
117
+ if (dir) {
118
+ dir = dir.slice(0, -1);
119
+ }
120
+ return root + dir;
121
+ }
122
+ function basename(path2, ext) {
123
+ let f = splitPath(path2)[2];
124
+ if (ext && f.slice(-ext.length) === ext) {
125
+ f = f.slice(0, -ext.length);
126
+ }
127
+ return f;
128
+ }
129
+ function extname(path2) {
130
+ return splitPath(path2)[3];
131
+ }
132
+ const path = {
133
+ extname,
134
+ basename,
135
+ dirname,
136
+ sep,
137
+ delimiter,
138
+ relative,
139
+ join,
140
+ isAbsolute,
141
+ normalize,
142
+ resolve
143
+ };
144
+ export {
145
+ basename,
146
+ delimiter,
147
+ dirname,
148
+ extname,
149
+ isAbsolute,
150
+ join,
151
+ normalize,
152
+ path,
153
+ relative,
154
+ resolve,
155
+ sep
156
+ };
157
+ //# sourceMappingURL=path.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/node/path.ts"],
4
+ "sourcesContent": ["// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n// resolves . and .. elements in a path array with directory names there\n// must be no slashes, empty elements, or device names (c:\\) in the array\n// (so also no leading and trailing slashes - it does not distinguish\n// relative and absolute paths)\n\n// !! WARNING !!\n// The original implementation included ponyfills for `filters` and `substr`.\n// These have been removed in favor of native implementations supported by the current platforms.\n// See: https://github.com/scalar/scalar/pull/7235#discussion_r2484230212\n\nfunction normalizeArray(parts: Array<string>, allowAboveRoot: boolean): Array<string> {\n // if the path tries to go above the root, `up` ends up > 0\n let up = 0\n for (let i = parts.length - 1; i >= 0; i--) {\n const last = parts[i]\n if (last === '.') {\n parts.splice(i, 1)\n } else if (last === '..') {\n parts.splice(i, 1)\n up++\n } else if (up) {\n parts.splice(i, 1)\n up--\n }\n }\n\n // if the path is allowed to go above the root, restore leading ..s\n if (allowAboveRoot) {\n for (; up--; up) {\n parts.unshift('..')\n }\n }\n\n return parts\n}\n\n// Split a filename into [root, dir, basename, ext], unix version\n// 'root' is just a slash, or nothing.\nconst splitPathRe = /^(\\/?|)([\\s\\S]*?)((?:\\.{1,2}|[^/]+?|)(\\.[^./]*|))(?:[/]*)$/\nconst splitPath = (filename: string): Array<string> | undefined => splitPathRe.exec(filename)!.slice(1)\n\n// path.resolve([from ...], to)\n// posix version\nexport function resolve(...parameters: Array<string>) {\n let resolvedPath = '',\n resolvedAbsolute = false\n\n for (let i = parameters.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n const path = i >= 0 ? parameters[i] : '/'\n\n // Skip empty and invalid entries\n if (typeof path !== 'string') {\n throw new TypeError('Arguments to path.resolve must be strings')\n }\n if (!path) {\n continue\n }\n\n resolvedPath = path + '/' + resolvedPath\n resolvedAbsolute = path.charAt(0) === '/'\n }\n\n // At this point the path should be resolved to a full absolute path, but\n // handle relative paths to be safe (might happen when process.cwd() fails)\n\n // Normalize the path\n resolvedPath = normalizeArray(\n resolvedPath.split('/').filter((p) => !!p),\n !resolvedAbsolute,\n ).join('/')\n\n return (resolvedAbsolute ? '/' : '') + resolvedPath || '.'\n}\n\n// path.normalize(path)\n// posix version\nexport function normalize(inputPath: string): string {\n const isPathAbsolute = isAbsolute(inputPath),\n trailingSlash = inputPath.slice(-1) === '/'\n\n // Normalize the path\n let path = normalizeArray(\n inputPath.split('/').filter((p) => !!p),\n !isPathAbsolute,\n ).join('/')\n\n if (!path && !isPathAbsolute) {\n path = '.'\n }\n if (path && trailingSlash) {\n path += '/'\n }\n\n return (isPathAbsolute ? '/' : '') + path\n}\n\n// posix version\nexport function isAbsolute(path: string): boolean {\n return path.charAt(0) === '/'\n}\n\n// posix version\nexport function join(...paths: string[]) {\n return normalize(\n paths\n .filter((p) => {\n if (typeof p !== 'string') {\n throw new TypeError('Arguments to path.join must be strings')\n }\n return p\n })\n .join('/'),\n )\n}\n\n// path.relative(from, to)\n// posix version\nexport function relative(from: string, to: string) {\n const fromResolved = resolve(from).substring(1)\n const toResolved = resolve(to).substring(1)\n\n function trim(arr: Array<string>): Array<string> {\n let start = 0\n for (; start < arr.length; start++) {\n if (arr[start] !== '') {\n break\n }\n }\n\n let end = arr.length - 1\n for (; end >= 0; end--) {\n if (arr[end] !== '') {\n break\n }\n }\n\n if (start > end) {\n return []\n }\n return arr.slice(start, end - start + 1)\n }\n\n const fromParts = trim(fromResolved.split('/'))\n const toParts = trim(toResolved.split('/'))\n\n const length = Math.min(fromParts.length, toParts.length)\n let samePartsLength = length\n for (let i = 0; i < length; i++) {\n if (fromParts[i] !== toParts[i]) {\n samePartsLength = i\n break\n }\n }\n\n let outputParts = []\n for (let i = samePartsLength; i < fromParts.length; i++) {\n outputParts.push('..')\n }\n\n outputParts = outputParts.concat(toParts.slice(samePartsLength))\n\n return outputParts.join('/')\n}\n\nexport const sep = '/'\nexport const delimiter = ':'\n\nexport function dirname(path: string): string {\n const result = splitPath(path) as Array<string>\n const root = result[0]\n let dir = result[1]\n\n if (!root && !dir) {\n // No dirname whatsoever\n return '.'\n }\n\n if (dir) {\n // It has a dirname, strip trailing slash\n dir = dir.slice(0, -1)\n }\n\n return (root as string) + dir\n}\n\nexport function basename(path: string, ext?: string): string {\n let f = splitPath(path)![2] as string\n // TODO: make this comparison case-insensitive on windows?\n if (ext && f.slice(-ext.length) === ext) {\n f = f.slice(0, -ext.length)\n }\n return f\n}\n\nexport function extname(path: string): string {\n return splitPath(path)![3] as string\n}\n\nexport const path = {\n extname,\n basename,\n dirname,\n sep,\n delimiter,\n relative,\n join,\n isAbsolute,\n normalize,\n resolve,\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path"]
7
+ }
@@ -1,5 +1,12 @@
1
1
  /**
2
2
  * Find all strings wrapped in {} or {{}} in value.
3
+ *
4
+ * @param value - The string to find variables in
5
+ * @param includePath - Whether to include path variables {single}
6
+ * @param includeEnv - Whether to include environment variables {{double}}
3
7
  */
4
- export declare const findVariables: (value: string) => (string | undefined)[];
8
+ export declare const findVariables: (value: string, { includePath, includeEnv }?: {
9
+ includePath?: boolean;
10
+ includeEnv?: boolean;
11
+ }) => string[];
5
12
  //# sourceMappingURL=find-variables.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-variables.d.ts","sourceRoot":"","sources":["../../src/regex/find-variables.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,2BACiE,CAAA"}
1
+ {"version":3,"file":"find-variables.d.ts","sourceRoot":"","sources":["../../src/regex/find-variables.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,EACb,8BAA2C;IAAE,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,KAC9F,MAAM,EAON,CAAA"}
@@ -1,5 +1,7 @@
1
1
  import { REGEX } from "./regex-helpers.js";
2
- const findVariables = (value) => [...value.matchAll(REGEX.PATH), ...value.matchAll(REGEX.VARIABLES)].map((match) => match[1]?.trim()) || [];
2
+ const findVariables = (value, { includePath = true, includeEnv = true } = {}) => [includePath && REGEX.PATH, includeEnv && REGEX.VARIABLES].flatMap(
3
+ (regex) => regex ? [...value.matchAll(regex)].map((match) => match[1]?.trim()).filter((variable) => variable !== void 0) : []
4
+ );
3
5
  export {
4
6
  findVariables
5
7
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/regex/find-variables.ts"],
4
- "sourcesContent": ["import { REGEX } from './regex-helpers'\n\n/**\n * Find all strings wrapped in {} or {{}} in value.\n */\nexport const findVariables = (value: string) =>\n [...value.matchAll(REGEX.PATH), ...value.matchAll(REGEX.VARIABLES)].map((match) => match[1]?.trim()) || []\n"],
5
- "mappings": "AAAA,SAAS,aAAa;AAKf,MAAM,gBAAgB,CAAC,UAC5B,CAAC,GAAG,MAAM,SAAS,MAAM,IAAI,GAAG,GAAG,MAAM,SAAS,MAAM,SAAS,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;",
4
+ "sourcesContent": ["import { REGEX } from './regex-helpers'\n\n/**\n * Find all strings wrapped in {} or {{}} in value.\n *\n * @param value - The string to find variables in\n * @param includePath - Whether to include path variables {single}\n * @param includeEnv - Whether to include environment variables {{double}}\n */\nexport const findVariables = (\n value: string,\n { includePath = true, includeEnv = true }: { includePath?: boolean; includeEnv?: boolean } = {},\n): string[] =>\n [includePath && REGEX.PATH, includeEnv && REGEX.VARIABLES].flatMap((regex) =>\n regex\n ? [...value.matchAll(regex)]\n .map((match) => match[1]?.trim())\n .filter((variable): variable is string => variable !== undefined)\n : [],\n )\n"],
5
+ "mappings": "AAAA,SAAS,aAAa;AASf,MAAM,gBAAgB,CAC3B,OACA,EAAE,cAAc,MAAM,aAAa,KAAK,IAAqD,CAAC,MAE9F,CAAC,eAAe,MAAM,MAAM,cAAc,MAAM,SAAS,EAAE;AAAA,EAAQ,CAAC,UAClE,QACI,CAAC,GAAG,MAAM,SAAS,KAAK,CAAC,EACtB,IAAI,CAAC,UAAU,MAAM,CAAC,GAAG,KAAK,CAAC,EAC/B,OAAO,CAAC,aAAiC,aAAa,MAAS,IAClE,CAAC;AACP;",
6
6
  "names": []
7
7
  }
@@ -1,12 +1,19 @@
1
+ /**
2
+ * Collection of regular expressions used throughout the application.
3
+ * These patterns handle URL parsing, variable detection, and reference path extraction.
4
+ */
1
5
  export declare const REGEX: {
2
6
  /** Checks for a valid scheme */
3
7
  readonly PROTOCOL: RegExp;
4
8
  /** Finds multiple slashes after the scheme to replace with a single slash */
5
9
  readonly MULTIPLE_SLASHES: RegExp;
10
+ /** Finds all variables wrapped in {{double}} */
6
11
  readonly VARIABLES: RegExp;
12
+ /** Finds all variables wrapped in {single} */
7
13
  readonly PATH: RegExp;
8
14
  /** Finds the name of the schema from the ref path */
9
15
  readonly REF_NAME: RegExp;
16
+ /** Finds template variables in multiple formats: {{var}}, {var}, or :var */
10
17
  readonly TEMPLATE_VARIABLE: RegExp;
11
18
  };
12
19
  //# sourceMappingURL=regex-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"regex-helpers.d.ts","sourceRoot":"","sources":["../../src/regex/regex-helpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK;IAChB,gCAAgC;;IAEhC,6EAA6E;;;;IAI7E,qDAAqD;;;CAG7C,CAAA"}
1
+ {"version":3,"file":"regex-helpers.d.ts","sourceRoot":"","sources":["../../src/regex/regex-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,KAAK;IAChB,gCAAgC;;IAEhC,6EAA6E;;IAE7E,gDAAgD;;IAEhD,8CAA8C;;IAE9C,qDAAqD;;IAErD,4EAA4E;;CAEpE,CAAA"}
@@ -3,10 +3,13 @@ const REGEX = {
3
3
  PROTOCOL: /^(?:https?|ftp|file|mailto|tel|data|wss?)*:\/\//,
4
4
  /** Finds multiple slashes after the scheme to replace with a single slash */
5
5
  MULTIPLE_SLASHES: /(?<!:)\/{2,}/g,
6
+ /** Finds all variables wrapped in {{double}} */
6
7
  VARIABLES: /{{((?:[^{}]|{[^{}]*})*)}}/g,
8
+ /** Finds all variables wrapped in {single} */
7
9
  PATH: /(?:{)([^{}]+)}(?!})/g,
8
10
  /** Finds the name of the schema from the ref path */
9
11
  REF_NAME: /\/([^\/]+)$/,
12
+ /** Finds template variables in multiple formats: {{var}}, {var}, or :var */
10
13
  TEMPLATE_VARIABLE: /{{\s*([^}\s]+?)\s*}}|{\s*([^}\s]+?)\s*}|:\b[\w.]+\b/g
11
14
  };
12
15
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/regex/regex-helpers.ts"],
4
- "sourcesContent": ["export const REGEX = {\n /** Checks for a valid scheme */\n PROTOCOL: /^(?:https?|ftp|file|mailto|tel|data|wss?)*:\\/\\//,\n /** Finds multiple slashes after the scheme to replace with a single slash */\n MULTIPLE_SLASHES: /(?<!:)\\/{2,}/g,\n VARIABLES: /{{((?:[^{}]|{[^{}]*})*)}}/g,\n PATH: /(?:{)([^{}]+)}(?!})/g,\n /** Finds the name of the schema from the ref path */\n REF_NAME: /\\/([^\\/]+)$/,\n TEMPLATE_VARIABLE: /{{\\s*([^}\\s]+?)\\s*}}|{\\s*([^}\\s]+?)\\s*}|:\\b[\\w.]+\\b/g,\n} as const\n"],
5
- "mappings": "AAAO,MAAM,QAAQ;AAAA;AAAA,EAEnB,UAAU;AAAA;AAAA,EAEV,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,MAAM;AAAA;AAAA,EAEN,UAAU;AAAA,EACV,mBAAmB;AACrB;",
4
+ "sourcesContent": ["/**\n * Collection of regular expressions used throughout the application.\n * These patterns handle URL parsing, variable detection, and reference path extraction.\n */\nexport const REGEX = {\n /** Checks for a valid scheme */\n PROTOCOL: /^(?:https?|ftp|file|mailto|tel|data|wss?)*:\\/\\//,\n /** Finds multiple slashes after the scheme to replace with a single slash */\n MULTIPLE_SLASHES: /(?<!:)\\/{2,}/g,\n /** Finds all variables wrapped in {{double}} */\n VARIABLES: /{{((?:[^{}]|{[^{}]*})*)}}/g,\n /** Finds all variables wrapped in {single} */\n PATH: /(?:{)([^{}]+)}(?!})/g,\n /** Finds the name of the schema from the ref path */\n REF_NAME: /\\/([^\\/]+)$/,\n /** Finds template variables in multiple formats: {{var}}, {var}, or :var */\n TEMPLATE_VARIABLE: /{{\\s*([^}\\s]+?)\\s*}}|{\\s*([^}\\s]+?)\\s*}|:\\b[\\w.]+\\b/g,\n} as const\n"],
5
+ "mappings": "AAIO,MAAM,QAAQ;AAAA;AAAA,EAEnB,UAAU;AAAA;AAAA,EAEV,kBAAkB;AAAA;AAAA,EAElB,WAAW;AAAA;AAAA,EAEX,MAAM;AAAA;AAAA,EAEN,UAAU;AAAA;AAAA,EAEV,mBAAmB;AACrB;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * A list of preset styles for word breaks
3
+ */
4
+ declare const PRESETS: {
5
+ /** Breaks on `/` and `-` for urls or file paths */
6
+ readonly path: RegExp;
7
+ /**
8
+ * Breaks on capitals, `_` and `.` for properties written in
9
+ * camel, pascal or snake case
10
+ */
11
+ readonly property: RegExp;
12
+ };
13
+ /** Word break options */
14
+ type WordBreakOptions = {
15
+ /**
16
+ * Presets for word wrapping
17
+ */
18
+ preset?: keyof typeof PRESETS;
19
+ /**
20
+ * Explicit regex to allow wrapping on, overrides any `preset`
21
+ */
22
+ regex?: RegExp;
23
+ };
24
+ /**
25
+ * String utility to add word break opportunities
26
+ *
27
+ * Adds a zero-width space before certain characters to allow improved
28
+ * line wrapping in the. Allows wrapping on "/" and * "-" by default.
29
+ */
30
+ export declare const addWordBreaks: (label: string, opts?: WordBreakOptions) => string;
31
+ export {};
32
+ //# sourceMappingURL=add-word-breaks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add-word-breaks.d.ts","sourceRoot":"","sources":["../../src/string/add-word-breaks.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,QAAA,MAAM,OAAO;IACX,mDAAmD;;IAEnD;;;OAGG;;CAEsC,CAAA;AAE3C,yBAAyB;AACzB,KAAK,gBAAgB,GAAG;IACtB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,OAAO,OAAO,CAAA;IAC7B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,EAAE,OAAM,gBAAqB,KAAG,MAI1E,CAAA"}
@@ -0,0 +1,19 @@
1
+ const ZWSP = "\u200B";
2
+ const PRESETS = {
3
+ /** Breaks on `/` and `-` for urls or file paths */
4
+ "path": /[\/-]/,
5
+ /**
6
+ * Breaks on capitals, `_` and `.` for properties written in
7
+ * camel, pascal or snake case
8
+ */
9
+ "property": /[A-Z\_\.-]/
10
+ };
11
+ const addWordBreaks = (label, opts = {}) => {
12
+ const { preset = "path", regex } = opts;
13
+ const wrapRegex = new RegExp(regex ?? PRESETS[preset], "g");
14
+ return label.replace(wrapRegex, `${ZWSP}$&`);
15
+ };
16
+ export {
17
+ addWordBreaks
18
+ };
19
+ //# sourceMappingURL=add-word-breaks.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/string/add-word-breaks.ts"],
4
+ "sourcesContent": ["/**\n * Unicode character for zero-width space\n *\n * @see https://en.wikipedia.org/wiki/Zero-width_space\n */\nconst ZWSP = '\\u200B'\n\n/**\n * A list of preset styles for word breaks\n */\nconst PRESETS = {\n /** Breaks on `/` and `-` for urls or file paths */\n 'path': /[\\/-]/,\n /**\n * Breaks on capitals, `_` and `.` for properties written in\n * camel, pascal or snake case\n */\n 'property': /[A-Z\\_\\.-]/,\n} as const satisfies Record<string, RegExp>\n\n/** Word break options */\ntype WordBreakOptions = {\n /**\n * Presets for word wrapping\n */\n preset?: keyof typeof PRESETS\n /**\n * Explicit regex to allow wrapping on, overrides any `preset`\n */\n regex?: RegExp\n}\n\n/**\n * String utility to add word break opportunities\n *\n * Adds a zero-width space before certain characters to allow improved\n * line wrapping in the. Allows wrapping on \"/\" and * \"-\" by default.\n */\nexport const addWordBreaks = (label: string, opts: WordBreakOptions = {}): string => {\n const { preset = 'path', regex } = opts\n const wrapRegex = new RegExp(regex ?? PRESETS[preset], 'g')\n return label.replace(wrapRegex, `${ZWSP}$&`)\n}\n"],
5
+ "mappings": "AAKA,MAAM,OAAO;AAKb,MAAM,UAAU;AAAA;AAAA,EAEd,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,EAKR,YAAY;AACd;AAoBO,MAAM,gBAAgB,CAAC,OAAe,OAAyB,CAAC,MAAc;AACnF,QAAM,EAAE,SAAS,QAAQ,MAAM,IAAI;AACnC,QAAM,YAAY,IAAI,OAAO,SAAS,QAAQ,MAAM,GAAG,GAAG;AAC1D,SAAO,MAAM,QAAQ,WAAW,GAAG,IAAI,IAAI;AAC7C;",
6
+ "names": []
7
+ }
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Simple 32 bit non-secure hash from a string input
3
3
  *
4
+ * @deprecated Use generateHash from @scalar/json-magic/helpers/generate-hash instead
5
+ *
4
6
  * @see https://stackoverflow.com/a/7616484/1624255
5
7
  */
6
8
  export declare const createHash: (input?: string) => number;
@@ -1 +1 @@
1
- {"version":3,"file":"create-hash.d.ts","sourceRoot":"","sources":["../../src/string/create-hash.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,KAAG,MAe3C,CAAA"}
1
+ {"version":3,"file":"create-hash.d.ts","sourceRoot":"","sources":["../../src/string/create-hash.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,KAAG,MAe3C,CAAA"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/string/create-hash.ts"],
4
- "sourcesContent": ["/**\n * Simple 32 bit non-secure hash from a string input\n *\n * @see https://stackoverflow.com/a/7616484/1624255\n */\nexport const createHash = (input?: string): number => {\n let chr = 0\n let hash = 0\n let i = 0\n\n if (!input?.length) {\n return hash\n }\n\n for (i = 0; i < input.length; i++) {\n chr = input.charCodeAt(i)\n hash = (hash << 5) - hash + chr\n hash |= 0 // Convert to 32bit integer\n }\n return hash\n}\n"],
5
- "mappings": "AAKO,MAAM,aAAa,CAAC,UAA2B;AACpD,MAAI,MAAM;AACV,MAAI,OAAO;AACX,MAAI,IAAI;AAER,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO;AAAA,EACT;AAEA,OAAK,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACjC,UAAM,MAAM,WAAW,CAAC;AACxB,YAAQ,QAAQ,KAAK,OAAO;AAC5B,YAAQ;AAAA,EACV;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["/**\n * Simple 32 bit non-secure hash from a string input\n *\n * @deprecated Use generateHash from @scalar/json-magic/helpers/generate-hash instead\n *\n * @see https://stackoverflow.com/a/7616484/1624255\n */\nexport const createHash = (input?: string): number => {\n let chr = 0\n let hash = 0\n let i = 0\n\n if (!input?.length) {\n return hash\n }\n\n for (i = 0; i < input.length; i++) {\n chr = input.charCodeAt(i)\n hash = (hash << 5) - hash + chr\n hash |= 0 // Convert to 32bit integer\n }\n return hash\n}\n"],
5
+ "mappings": "AAOO,MAAM,aAAa,CAAC,UAA2B;AACpD,MAAI,MAAM;AACV,MAAI,OAAO;AACX,MAAI,IAAI;AAER,MAAI,CAAC,OAAO,QAAQ;AAClB,WAAO;AAAA,EACT;AAEA,OAAK,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACjC,UAAM,MAAM,WAAW,CAAC;AACxB,YAAQ,QAAQ,KAAK,OAAO;AAC5B,YAAQ;AAAA,EACV;AACA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Truncates a string to a specified length and adds an ellipsis if it's longer in JS
3
+ *
4
+ * @param str - The string to truncate
5
+ * @param maxLength - The maximum length before truncation (default: 18)
6
+ * @returns The truncated string with ellipsis if needed
7
+ *
8
+ * @example
9
+ * truncate('Very long name that needs truncation') // 'Very long name th…'
10
+ * truncate('Short') // 'Short'
11
+ */
12
+ export declare const truncate: (str: string, maxLength?: number) => string;
13
+ //# sourceMappingURL=truncate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncate.d.ts","sourceRoot":"","sources":["../../src/string/truncate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,kBAAc,KAAG,MAKtD,CAAA"}
@@ -0,0 +1,10 @@
1
+ const truncate = (str, maxLength = 18) => {
2
+ if (str.length <= maxLength) {
3
+ return str;
4
+ }
5
+ return str.slice(0, maxLength) + "\u2026";
6
+ };
7
+ export {
8
+ truncate
9
+ };
10
+ //# sourceMappingURL=truncate.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/string/truncate.ts"],
4
+ "sourcesContent": ["/**\n * Truncates a string to a specified length and adds an ellipsis if it's longer in JS\n *\n * @param str - The string to truncate\n * @param maxLength - The maximum length before truncation (default: 18)\n * @returns The truncated string with ellipsis if needed\n *\n * @example\n * truncate('Very long name that needs truncation') // 'Very long name th\u2026'\n * truncate('Short') // 'Short'\n */\nexport const truncate = (str: string, maxLength = 18): string => {\n if (str.length <= maxLength) {\n return str\n }\n return str.slice(0, maxLength) + '\u2026'\n}\n"],
5
+ "mappings": "AAWO,MAAM,WAAW,CAAC,KAAa,YAAY,OAAe;AAC/D,MAAI,IAAI,UAAU,WAAW;AAC3B,WAAO;AAAA,EACT;AACA,SAAO,IAAI,MAAM,GAAG,SAAS,IAAI;AACnC;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "helpers",
15
15
  "js"
16
16
  ],
17
- "version": "0.0.13",
17
+ "version": "0.1.1",
18
18
  "engines": {
19
19
  "node": ">=20"
20
20
  },
@@ -46,6 +46,11 @@
46
46
  "types": "./dist/http/*.d.ts",
47
47
  "default": "./dist/http/*.js"
48
48
  },
49
+ "./node/*": {
50
+ "import": "./dist/node/*.js",
51
+ "types": "./dist/node/*.d.ts",
52
+ "default": "./dist/node/*.js"
53
+ },
49
54
  "./object/*": {
50
55
  "import": "./dist/object/*.js",
51
56
  "types": "./dist/object/*.d.ts",
@@ -1,15 +0,0 @@
1
- /**
2
- * Generates a SHA-256 hexadecimal hash for the provided string input.
3
- *
4
- * This function uses the Web Crypto API, returning a lowercase hex string.
5
- * The resulting hash is deterministic for the same input.
6
- *
7
- * @param input - The input string to hash.
8
- * @returns A Promise that resolves to a hexadecimal string representing the SHA-256 hash.
9
- *
10
- * @example
11
- * const hash = await generateHash('hello world')
12
- * console.log(hash) // => 'b94d27b9934d3e08a52e52d7da7dabfadeb...'
13
- */
14
- export declare const generateHash: (input: string) => Promise<string>;
15
- //# sourceMappingURL=generate-hash.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-hash.d.ts","sourceRoot":"","sources":["../../src/crypto/generate-hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,MAAM,CAUhE,CAAA"}
@@ -1,10 +0,0 @@
1
- const generateHash = async (input) => {
2
- const hashBuffer = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input));
3
- const hashArray = Array.from(new Uint8Array(hashBuffer));
4
- const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
5
- return hashHex;
6
- };
7
- export {
8
- generateHash
9
- };
10
- //# sourceMappingURL=generate-hash.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/crypto/generate-hash.ts"],
4
- "sourcesContent": ["/**\n * Generates a SHA-256 hexadecimal hash for the provided string input.\n *\n * This function uses the Web Crypto API, returning a lowercase hex string.\n * The resulting hash is deterministic for the same input.\n *\n * @param input - The input string to hash.\n * @returns A Promise that resolves to a hexadecimal string representing the SHA-256 hash.\n *\n * @example\n * const hash = await generateHash('hello world')\n * console.log(hash) // => 'b94d27b9934d3e08a52e52d7da7dabfadeb...'\n */\nexport const generateHash = async (input: string): Promise<string> => {\n const hashBuffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(input))\n\n // Convert the ArrayBuffer to a Uint8Array\n const hashArray = Array.from(new Uint8Array(hashBuffer))\n\n // Convert each byte to its hexadecimal representation and join them\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')\n\n return hashHex\n}\n"],
5
- "mappings": "AAaO,MAAM,eAAe,OAAO,UAAmC;AACpE,QAAM,aAAa,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI,YAAY,EAAE,OAAO,KAAK,CAAC;AAGxF,QAAM,YAAY,MAAM,KAAK,IAAI,WAAW,UAAU,CAAC;AAGvD,QAAM,UAAU,UAAU,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AAE7E,SAAO;AACT;",
6
- "names": []
7
- }