@n8n/utils 1.37.1 → 1.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assert.cjs +11 -2
- package/dist/assert.cjs.map +1 -0
- package/dist/assert.d.cts +5 -2
- package/dist/assert.d.mts +5 -2
- package/dist/assert.mjs +10 -2
- package/dist/assert.mjs.map +1 -0
- package/dist/client-assertion.cjs +49 -0
- package/dist/client-assertion.cjs.map +1 -0
- package/dist/client-assertion.d.cts +12 -0
- package/dist/client-assertion.d.mts +12 -0
- package/dist/client-assertion.mjs +48 -0
- package/dist/client-assertion.mjs.map +1 -0
- package/dist/create-event-queue.cjs +40 -2
- package/dist/create-event-queue.cjs.map +1 -0
- package/dist/create-event-queue.d.cts +7 -2
- package/dist/create-event-queue.d.mts +7 -2
- package/dist/create-event-queue.mjs +39 -2
- package/dist/create-event-queue.mjs.map +1 -0
- package/dist/ensure-error.cjs +15 -0
- package/dist/ensure-error.cjs.map +1 -0
- package/dist/ensure-error.mjs +9 -0
- package/dist/ensure-error.mjs.map +1 -0
- package/dist/errors/ensure-error.cjs +3 -0
- package/dist/errors/ensure-error.d.cts +5 -0
- package/dist/errors/ensure-error.d.mts +5 -0
- package/dist/errors/ensure-error.mjs +3 -0
- package/dist/event-bus.cjs +43 -2
- package/dist/event-bus.cjs.map +1 -0
- package/dist/event-bus.d.cts +14 -2
- package/dist/event-bus.d.mts +14 -2
- package/dist/event-bus.mjs +42 -2
- package/dist/event-bus.mjs.map +1 -0
- package/dist/files/is-windows-file-path.cjs +11 -2
- package/dist/files/is-windows-file-path.cjs.map +1 -0
- package/dist/files/is-windows-file-path.d.cts +5 -2
- package/dist/files/is-windows-file-path.d.mts +5 -2
- package/dist/files/is-windows-file-path.mjs +10 -2
- package/dist/files/is-windows-file-path.mjs.map +1 -0
- package/dist/files/sanitize-filename.cjs +61 -2
- package/dist/files/sanitize-filename.cjs.map +1 -0
- package/dist/files/sanitize-filename.d.cts +5 -2
- package/dist/files/sanitize-filename.d.mts +5 -2
- package/dist/files/sanitize-filename.mjs +60 -2
- package/dist/files/sanitize-filename.mjs.map +1 -0
- package/dist/format-pem-block.d.cts +5 -2
- package/dist/format-pem-block.d.mts +5 -2
- package/dist/generate-nano-id.cjs +28 -2
- package/dist/generate-nano-id.cjs.map +1 -0
- package/dist/generate-nano-id.d.cts +5 -2
- package/dist/generate-nano-id.d.mts +5 -2
- package/dist/generate-nano-id.mjs +28 -2
- package/dist/generate-nano-id.mjs.map +1 -0
- package/dist/get-jwt-expiry.cjs +22 -2
- package/dist/get-jwt-expiry.cjs.map +1 -0
- package/dist/get-jwt-expiry.d.cts +5 -2
- package/dist/get-jwt-expiry.d.mts +5 -2
- package/dist/get-jwt-expiry.mjs +21 -2
- package/dist/get-jwt-expiry.mjs.map +1 -0
- package/dist/is-record.cjs +8 -2
- package/dist/is-record.cjs.map +1 -0
- package/dist/is-record.d.cts +5 -2
- package/dist/is-record.d.mts +5 -2
- package/dist/is-record.mjs +7 -2
- package/dist/is-record.mjs.map +1 -0
- package/dist/number/smart-decimal.cjs +10 -2
- package/dist/number/smart-decimal.cjs.map +1 -0
- package/dist/number/smart-decimal.d.cts +5 -2
- package/dist/number/smart-decimal.d.mts +5 -2
- package/dist/number/smart-decimal.mjs +9 -2
- package/dist/number/smart-decimal.mjs.map +1 -0
- package/dist/placeholder.cjs +80 -7
- package/dist/placeholder.cjs.map +1 -0
- package/dist/placeholder.d.cts +14 -2
- package/dist/placeholder.d.mts +14 -2
- package/dist/placeholder.mjs +74 -2
- package/dist/placeholder.mjs.map +1 -0
- package/dist/promise/deferred-promise.cjs +14 -0
- package/dist/promise/deferred-promise.cjs.map +1 -0
- package/dist/promise/deferred-promise.d.cts +12 -0
- package/dist/promise/deferred-promise.d.mts +12 -0
- package/dist/promise/deferred-promise.mjs +13 -0
- package/dist/promise/deferred-promise.mjs.map +1 -0
- package/dist/result.cjs +30 -0
- package/dist/result.cjs.map +1 -0
- package/dist/result.d.cts +16 -0
- package/dist/result.d.mts +16 -0
- package/dist/result.mjs +28 -0
- package/dist/result.mjs.map +1 -0
- package/dist/retry.cjs +39 -2
- package/dist/retry.cjs.map +1 -0
- package/dist/retry.d.cts +6 -2
- package/dist/retry.d.mts +6 -2
- package/dist/retry.mjs +38 -2
- package/dist/retry.mjs.map +1 -0
- package/dist/scrub-secrets.cjs +44 -4
- package/dist/scrub-secrets.cjs.map +1 -0
- package/dist/scrub-secrets.d.cts +7 -2
- package/dist/scrub-secrets.d.mts +7 -2
- package/dist/scrub-secrets.mjs +41 -2
- package/dist/scrub-secrets.mjs.map +1 -0
- package/dist/search/re-rank-search-results.cjs +19 -2
- package/dist/search/re-rank-search-results.cjs.map +1 -0
- package/dist/search/re-rank-search-results.d.cts +13 -2
- package/dist/search/re-rank-search-results.d.mts +13 -2
- package/dist/search/re-rank-search-results.mjs +18 -2
- package/dist/search/re-rank-search-results.mjs.map +1 -0
- package/dist/search/sublime-search.cjs +182 -3
- package/dist/search/sublime-search.cjs.map +1 -0
- package/dist/search/sublime-search.d.cts +15 -2
- package/dist/search/sublime-search.d.mts +15 -2
- package/dist/search/sublime-search.mjs +180 -2
- package/dist/search/sublime-search.mjs.map +1 -0
- package/dist/sort/sort-by-property.cjs +12 -2
- package/dist/sort/sort-by-property.cjs.map +1 -0
- package/dist/sort/sort-by-property.d.cts +5 -2
- package/dist/sort/sort-by-property.d.mts +5 -2
- package/dist/sort/sort-by-property.mjs +11 -2
- package/dist/sort/sort-by-property.mjs.map +1 -0
- package/dist/string/truncate.cjs +32 -3
- package/dist/string/truncate.cjs.map +1 -0
- package/dist/string/truncate.d.cts +6 -2
- package/dist/string/truncate.d.mts +6 -2
- package/dist/string/truncate.mjs +30 -2
- package/dist/string/truncate.mjs.map +1 -0
- package/dist/types.d.cts +5 -2
- package/dist/types.d.mts +5 -2
- package/package.json +11 -12
- package/dist/assert2.cjs +0 -17
- package/dist/assert2.cjs.map +0 -1
- package/dist/assert2.d.cts +0 -5
- package/dist/assert2.d.mts +0 -5
- package/dist/assert2.mjs +0 -11
- package/dist/assert2.mjs.map +0 -1
- package/dist/create-event-queue2.cjs +0 -46
- package/dist/create-event-queue2.cjs.map +0 -1
- package/dist/create-event-queue2.d.cts +0 -7
- package/dist/create-event-queue2.d.mts +0 -7
- package/dist/create-event-queue2.mjs +0 -40
- package/dist/create-event-queue2.mjs.map +0 -1
- package/dist/event-bus2.cjs +0 -49
- package/dist/event-bus2.cjs.map +0 -1
- package/dist/event-bus2.d.cts +0 -14
- package/dist/event-bus2.d.mts +0 -14
- package/dist/event-bus2.mjs +0 -43
- package/dist/event-bus2.mjs.map +0 -1
- package/dist/format-pem-block2.d.cts +0 -5
- package/dist/format-pem-block2.d.mts +0 -5
- package/dist/generate-nano-id2.cjs +0 -34
- package/dist/generate-nano-id2.cjs.map +0 -1
- package/dist/generate-nano-id2.d.cts +0 -5
- package/dist/generate-nano-id2.d.mts +0 -5
- package/dist/generate-nano-id2.mjs +0 -29
- package/dist/generate-nano-id2.mjs.map +0 -1
- package/dist/get-jwt-expiry2.cjs +0 -28
- package/dist/get-jwt-expiry2.cjs.map +0 -1
- package/dist/get-jwt-expiry2.d.cts +0 -5
- package/dist/get-jwt-expiry2.d.mts +0 -5
- package/dist/get-jwt-expiry2.mjs +0 -22
- package/dist/get-jwt-expiry2.mjs.map +0 -1
- package/dist/index.cjs +0 -44
- package/dist/index.d.cts +0 -19
- package/dist/index.d.mts +0 -19
- package/dist/index.mjs +0 -19
- package/dist/is-record2.cjs +0 -14
- package/dist/is-record2.cjs.map +0 -1
- package/dist/is-record2.d.cts +0 -5
- package/dist/is-record2.d.mts +0 -5
- package/dist/is-record2.mjs +0 -8
- package/dist/is-record2.mjs.map +0 -1
- package/dist/is-windows-file-path.cjs +0 -17
- package/dist/is-windows-file-path.cjs.map +0 -1
- package/dist/is-windows-file-path.d.cts +0 -5
- package/dist/is-windows-file-path.d.mts +0 -5
- package/dist/is-windows-file-path.mjs +0 -11
- package/dist/is-windows-file-path.mjs.map +0 -1
- package/dist/placeholder2.cjs +0 -111
- package/dist/placeholder2.cjs.map +0 -1
- package/dist/placeholder2.d.cts +0 -14
- package/dist/placeholder2.d.mts +0 -14
- package/dist/placeholder2.mjs +0 -75
- package/dist/placeholder2.mjs.map +0 -1
- package/dist/re-rank-search-results.cjs +0 -25
- package/dist/re-rank-search-results.cjs.map +0 -1
- package/dist/re-rank-search-results.d.cts +0 -13
- package/dist/re-rank-search-results.d.mts +0 -13
- package/dist/re-rank-search-results.mjs +0 -19
- package/dist/re-rank-search-results.mjs.map +0 -1
- package/dist/retry2.cjs +0 -45
- package/dist/retry2.cjs.map +0 -1
- package/dist/retry2.d.cts +0 -6
- package/dist/retry2.d.mts +0 -6
- package/dist/retry2.mjs +0 -39
- package/dist/retry2.mjs.map +0 -1
- package/dist/sanitize-filename.cjs +0 -67
- package/dist/sanitize-filename.cjs.map +0 -1
- package/dist/sanitize-filename.d.cts +0 -5
- package/dist/sanitize-filename.d.mts +0 -5
- package/dist/sanitize-filename.mjs +0 -61
- package/dist/sanitize-filename.mjs.map +0 -1
- package/dist/scrub-secrets2.cjs +0 -59
- package/dist/scrub-secrets2.cjs.map +0 -1
- package/dist/scrub-secrets2.d.cts +0 -7
- package/dist/scrub-secrets2.d.mts +0 -7
- package/dist/scrub-secrets2.mjs +0 -41
- package/dist/scrub-secrets2.mjs.map +0 -1
- package/dist/smart-decimal.cjs +0 -16
- package/dist/smart-decimal.cjs.map +0 -1
- package/dist/smart-decimal.d.cts +0 -5
- package/dist/smart-decimal.d.mts +0 -5
- package/dist/smart-decimal.mjs +0 -10
- package/dist/smart-decimal.mjs.map +0 -1
- package/dist/sort-by-property.cjs +0 -18
- package/dist/sort-by-property.cjs.map +0 -1
- package/dist/sort-by-property.d.cts +0 -5
- package/dist/sort-by-property.d.mts +0 -5
- package/dist/sort-by-property.mjs +0 -12
- package/dist/sort-by-property.mjs.map +0 -1
- package/dist/sublime-search.cjs +0 -193
- package/dist/sublime-search.cjs.map +0 -1
- package/dist/sublime-search.d.cts +0 -15
- package/dist/sublime-search.d.mts +0 -15
- package/dist/sublime-search.mjs +0 -181
- package/dist/sublime-search.mjs.map +0 -1
- package/dist/truncate.cjs +0 -43
- package/dist/truncate.cjs.map +0 -1
- package/dist/truncate.d.cts +0 -6
- package/dist/truncate.d.mts +0 -6
- package/dist/truncate.mjs +0 -31
- package/dist/truncate.mjs.map +0 -1
- package/dist/types2.d.cts +0 -5
- package/dist/types2.d.mts +0 -5
|
@@ -1,3 +1,62 @@
|
|
|
1
|
-
const require_sanitize_filename = require('../sanitize-filename.cjs');
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
//#region src/files/sanitize-filename.ts
|
|
3
|
+
const INVALID_CHARS_REGEX = /[<>:"/\\|?*\u0000-\u001F\u007F-\u009F]/g;
|
|
4
|
+
const ZERO_WIDTH_CHARS_REGEX = /[\u200B-\u200D\u2060\uFEFF]/g;
|
|
5
|
+
const UNICODE_SPACES_REGEX = /[\u00A0\u2000-\u200A]/g;
|
|
6
|
+
const LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\s.]+|[\s.]+$/g;
|
|
7
|
+
const WINDOWS_RESERVED_NAMES = new Set([
|
|
8
|
+
"CON",
|
|
9
|
+
"PRN",
|
|
10
|
+
"AUX",
|
|
11
|
+
"NUL",
|
|
12
|
+
"COM1",
|
|
13
|
+
"COM2",
|
|
14
|
+
"COM3",
|
|
15
|
+
"COM4",
|
|
16
|
+
"COM5",
|
|
17
|
+
"COM6",
|
|
18
|
+
"COM7",
|
|
19
|
+
"COM8",
|
|
20
|
+
"COM9",
|
|
21
|
+
"LPT1",
|
|
22
|
+
"LPT2",
|
|
23
|
+
"LPT3",
|
|
24
|
+
"LPT4",
|
|
25
|
+
"LPT5",
|
|
26
|
+
"LPT6",
|
|
27
|
+
"LPT7",
|
|
28
|
+
"LPT8",
|
|
29
|
+
"LPT9"
|
|
30
|
+
]);
|
|
31
|
+
const DEFAULT_FALLBACK_NAME = "untitled";
|
|
32
|
+
const MAX_FILENAME_LENGTH = 200;
|
|
33
|
+
/**
|
|
34
|
+
* Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems
|
|
35
|
+
*
|
|
36
|
+
* Main features:
|
|
37
|
+
* - Replace invalid characters (e.g. ":" in hello:world)
|
|
38
|
+
* - Handle Windows reserved names
|
|
39
|
+
* - Limit filename length
|
|
40
|
+
* - Normalize Unicode characters
|
|
41
|
+
*
|
|
42
|
+
* @param filename - The filename to sanitize (without extension)
|
|
43
|
+
* @param maxLength - Maximum filename length (default: 200)
|
|
44
|
+
* @returns A sanitized filename (without extension)
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* sanitizeFilename('hello:world') // returns 'hello_world'
|
|
48
|
+
* sanitizeFilename('CON') // returns '_CON'
|
|
49
|
+
* sanitizeFilename('') // returns 'untitled'
|
|
50
|
+
*/
|
|
51
|
+
const sanitizeFilename = (filename, maxLength = MAX_FILENAME_LENGTH) => {
|
|
52
|
+
if (!filename) return DEFAULT_FALLBACK_NAME;
|
|
53
|
+
let baseName = filename.trim().replace(INVALID_CHARS_REGEX, "_").replace(ZERO_WIDTH_CHARS_REGEX, "").replace(UNICODE_SPACES_REGEX, " ").replace(LEADING_TRAILING_DOTS_SPACES_REGEX, "");
|
|
54
|
+
if (!baseName) baseName = DEFAULT_FALLBACK_NAME;
|
|
55
|
+
if (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) baseName = `_${baseName}`;
|
|
56
|
+
if (baseName.length > maxLength) baseName = baseName.slice(0, maxLength);
|
|
57
|
+
return baseName;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
exports.sanitizeFilename = sanitizeFilename;
|
|
62
|
+
//# sourceMappingURL=sanitize-filename.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize-filename.cjs","names":[],"sources":["../../src/files/sanitize-filename.ts"],"sourcesContent":["// Constants definition\n/* eslint-disable no-control-regex */\nconst INVALID_CHARS_REGEX = /[<>:\"/\\\\|?*\\u0000-\\u001F\\u007F-\\u009F]/g;\nconst ZERO_WIDTH_CHARS_REGEX = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\nconst UNICODE_SPACES_REGEX = /[\\u00A0\\u2000-\\u200A]/g;\nconst LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\\s.]+|[\\s.]+$/g;\n/* eslint-enable no-control-regex */\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n\t'CON',\n\t'PRN',\n\t'AUX',\n\t'NUL',\n\t'COM1',\n\t'COM2',\n\t'COM3',\n\t'COM4',\n\t'COM5',\n\t'COM6',\n\t'COM7',\n\t'COM8',\n\t'COM9',\n\t'LPT1',\n\t'LPT2',\n\t'LPT3',\n\t'LPT4',\n\t'LPT5',\n\t'LPT6',\n\t'LPT7',\n\t'LPT8',\n\t'LPT9',\n]);\n\nconst DEFAULT_FALLBACK_NAME = 'untitled';\nconst MAX_FILENAME_LENGTH = 200;\n\n/**\n * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems\n *\n * Main features:\n * - Replace invalid characters (e.g. \":\" in hello:world)\n * - Handle Windows reserved names\n * - Limit filename length\n * - Normalize Unicode characters\n *\n * @param filename - The filename to sanitize (without extension)\n * @param maxLength - Maximum filename length (default: 200)\n * @returns A sanitized filename (without extension)\n *\n * @example\n * sanitizeFilename('hello:world') // returns 'hello_world'\n * sanitizeFilename('CON') // returns '_CON'\n * sanitizeFilename('') // returns 'untitled'\n */\nexport const sanitizeFilename = (\n\tfilename: string,\n\tmaxLength: number = MAX_FILENAME_LENGTH,\n): string => {\n\t// Input validation\n\tif (!filename) {\n\t\treturn DEFAULT_FALLBACK_NAME;\n\t}\n\n\tlet baseName = filename\n\t\t.trim()\n\t\t.replace(INVALID_CHARS_REGEX, '_')\n\t\t.replace(ZERO_WIDTH_CHARS_REGEX, '')\n\t\t.replace(UNICODE_SPACES_REGEX, ' ')\n\t\t.replace(LEADING_TRAILING_DOTS_SPACES_REGEX, '');\n\n\t// Handle empty or invalid filenames after cleaning\n\tif (!baseName) {\n\t\tbaseName = DEFAULT_FALLBACK_NAME;\n\t}\n\n\t// Handle Windows reserved names\n\tif (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) {\n\t\tbaseName = `_${baseName}`;\n\t}\n\n\t// Truncate if too long\n\tif (baseName.length > maxLength) {\n\t\tbaseName = baseName.slice(0, maxLength);\n\t}\n\n\treturn baseName;\n};\n"],"mappings":";;AAEA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,qCAAqC;AAG3C,MAAM,yBAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAM,wBAAwB;AAC9B,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;AAoB5B,MAAa,oBACZ,UACA,YAAoB,wBACR;AAEZ,KAAI,CAAC,SACJ,QAAO;CAGR,IAAI,WAAW,SACb,MAAM,CACN,QAAQ,qBAAqB,IAAI,CACjC,QAAQ,wBAAwB,GAAG,CACnC,QAAQ,sBAAsB,IAAI,CAClC,QAAQ,oCAAoC,GAAG;AAGjD,KAAI,CAAC,SACJ,YAAW;AAIZ,KAAI,uBAAuB,IAAI,SAAS,aAAa,CAAC,CACrD,YAAW,IAAI;AAIhB,KAAI,SAAS,SAAS,UACrB,YAAW,SAAS,MAAM,GAAG,UAAU;AAGxC,QAAO"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/files/sanitize-filename.d.ts
|
|
2
|
+
declare const sanitizeFilename: (filename: string, maxLength?: number) => string;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { sanitizeFilename };
|
|
5
|
+
//# sourceMappingURL=sanitize-filename.d.cts.map
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/files/sanitize-filename.d.ts
|
|
2
|
+
declare const sanitizeFilename: (filename: string, maxLength?: number) => string;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { sanitizeFilename };
|
|
5
|
+
//# sourceMappingURL=sanitize-filename.d.mts.map
|
|
@@ -1,3 +1,61 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/files/sanitize-filename.ts
|
|
2
|
+
const INVALID_CHARS_REGEX = /[<>:"/\\|?*\u0000-\u001F\u007F-\u009F]/g;
|
|
3
|
+
const ZERO_WIDTH_CHARS_REGEX = /[\u200B-\u200D\u2060\uFEFF]/g;
|
|
4
|
+
const UNICODE_SPACES_REGEX = /[\u00A0\u2000-\u200A]/g;
|
|
5
|
+
const LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\s.]+|[\s.]+$/g;
|
|
6
|
+
const WINDOWS_RESERVED_NAMES = new Set([
|
|
7
|
+
"CON",
|
|
8
|
+
"PRN",
|
|
9
|
+
"AUX",
|
|
10
|
+
"NUL",
|
|
11
|
+
"COM1",
|
|
12
|
+
"COM2",
|
|
13
|
+
"COM3",
|
|
14
|
+
"COM4",
|
|
15
|
+
"COM5",
|
|
16
|
+
"COM6",
|
|
17
|
+
"COM7",
|
|
18
|
+
"COM8",
|
|
19
|
+
"COM9",
|
|
20
|
+
"LPT1",
|
|
21
|
+
"LPT2",
|
|
22
|
+
"LPT3",
|
|
23
|
+
"LPT4",
|
|
24
|
+
"LPT5",
|
|
25
|
+
"LPT6",
|
|
26
|
+
"LPT7",
|
|
27
|
+
"LPT8",
|
|
28
|
+
"LPT9"
|
|
29
|
+
]);
|
|
30
|
+
const DEFAULT_FALLBACK_NAME = "untitled";
|
|
31
|
+
const MAX_FILENAME_LENGTH = 200;
|
|
32
|
+
/**
|
|
33
|
+
* Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems
|
|
34
|
+
*
|
|
35
|
+
* Main features:
|
|
36
|
+
* - Replace invalid characters (e.g. ":" in hello:world)
|
|
37
|
+
* - Handle Windows reserved names
|
|
38
|
+
* - Limit filename length
|
|
39
|
+
* - Normalize Unicode characters
|
|
40
|
+
*
|
|
41
|
+
* @param filename - The filename to sanitize (without extension)
|
|
42
|
+
* @param maxLength - Maximum filename length (default: 200)
|
|
43
|
+
* @returns A sanitized filename (without extension)
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* sanitizeFilename('hello:world') // returns 'hello_world'
|
|
47
|
+
* sanitizeFilename('CON') // returns '_CON'
|
|
48
|
+
* sanitizeFilename('') // returns 'untitled'
|
|
49
|
+
*/
|
|
50
|
+
const sanitizeFilename = (filename, maxLength = MAX_FILENAME_LENGTH) => {
|
|
51
|
+
if (!filename) return DEFAULT_FALLBACK_NAME;
|
|
52
|
+
let baseName = filename.trim().replace(INVALID_CHARS_REGEX, "_").replace(ZERO_WIDTH_CHARS_REGEX, "").replace(UNICODE_SPACES_REGEX, " ").replace(LEADING_TRAILING_DOTS_SPACES_REGEX, "");
|
|
53
|
+
if (!baseName) baseName = DEFAULT_FALLBACK_NAME;
|
|
54
|
+
if (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) baseName = `_${baseName}`;
|
|
55
|
+
if (baseName.length > maxLength) baseName = baseName.slice(0, maxLength);
|
|
56
|
+
return baseName;
|
|
57
|
+
};
|
|
2
58
|
|
|
3
|
-
|
|
59
|
+
//#endregion
|
|
60
|
+
export { sanitizeFilename };
|
|
61
|
+
//# sourceMappingURL=sanitize-filename.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitize-filename.mjs","names":[],"sources":["../../src/files/sanitize-filename.ts"],"sourcesContent":["// Constants definition\n/* eslint-disable no-control-regex */\nconst INVALID_CHARS_REGEX = /[<>:\"/\\\\|?*\\u0000-\\u001F\\u007F-\\u009F]/g;\nconst ZERO_WIDTH_CHARS_REGEX = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\nconst UNICODE_SPACES_REGEX = /[\\u00A0\\u2000-\\u200A]/g;\nconst LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\\s.]+|[\\s.]+$/g;\n/* eslint-enable no-control-regex */\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n\t'CON',\n\t'PRN',\n\t'AUX',\n\t'NUL',\n\t'COM1',\n\t'COM2',\n\t'COM3',\n\t'COM4',\n\t'COM5',\n\t'COM6',\n\t'COM7',\n\t'COM8',\n\t'COM9',\n\t'LPT1',\n\t'LPT2',\n\t'LPT3',\n\t'LPT4',\n\t'LPT5',\n\t'LPT6',\n\t'LPT7',\n\t'LPT8',\n\t'LPT9',\n]);\n\nconst DEFAULT_FALLBACK_NAME = 'untitled';\nconst MAX_FILENAME_LENGTH = 200;\n\n/**\n * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems\n *\n * Main features:\n * - Replace invalid characters (e.g. \":\" in hello:world)\n * - Handle Windows reserved names\n * - Limit filename length\n * - Normalize Unicode characters\n *\n * @param filename - The filename to sanitize (without extension)\n * @param maxLength - Maximum filename length (default: 200)\n * @returns A sanitized filename (without extension)\n *\n * @example\n * sanitizeFilename('hello:world') // returns 'hello_world'\n * sanitizeFilename('CON') // returns '_CON'\n * sanitizeFilename('') // returns 'untitled'\n */\nexport const sanitizeFilename = (\n\tfilename: string,\n\tmaxLength: number = MAX_FILENAME_LENGTH,\n): string => {\n\t// Input validation\n\tif (!filename) {\n\t\treturn DEFAULT_FALLBACK_NAME;\n\t}\n\n\tlet baseName = filename\n\t\t.trim()\n\t\t.replace(INVALID_CHARS_REGEX, '_')\n\t\t.replace(ZERO_WIDTH_CHARS_REGEX, '')\n\t\t.replace(UNICODE_SPACES_REGEX, ' ')\n\t\t.replace(LEADING_TRAILING_DOTS_SPACES_REGEX, '');\n\n\t// Handle empty or invalid filenames after cleaning\n\tif (!baseName) {\n\t\tbaseName = DEFAULT_FALLBACK_NAME;\n\t}\n\n\t// Handle Windows reserved names\n\tif (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) {\n\t\tbaseName = `_${baseName}`;\n\t}\n\n\t// Truncate if too long\n\tif (baseName.length > maxLength) {\n\t\tbaseName = baseName.slice(0, maxLength);\n\t}\n\n\treturn baseName;\n};\n"],"mappings":";AAEA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,qCAAqC;AAG3C,MAAM,yBAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAM,wBAAwB;AAC9B,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;AAoB5B,MAAa,oBACZ,UACA,YAAoB,wBACR;AAEZ,KAAI,CAAC,SACJ,QAAO;CAGR,IAAI,WAAW,SACb,MAAM,CACN,QAAQ,qBAAqB,IAAI,CACjC,QAAQ,wBAAwB,GAAG,CACnC,QAAQ,sBAAsB,IAAI,CAClC,QAAQ,oCAAoC,GAAG;AAGjD,KAAI,CAAC,SACJ,YAAW;AAIZ,KAAI,uBAAuB,IAAI,SAAS,aAAa,CAAC,CACrD,YAAW,IAAI;AAIhB,KAAI,SAAS,SAAS,UACrB,YAAW,SAAS,MAAM,GAAG,UAAU;AAGxC,QAAO"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/format-pem-block.d.ts
|
|
2
|
+
declare function formatPemBlock(pem: string, isPublic?: boolean): string;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { formatPemBlock };
|
|
5
|
+
//# sourceMappingURL=format-pem-block.d.cts.map
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/format-pem-block.d.ts
|
|
2
|
+
declare function formatPemBlock(pem: string, isPublic?: boolean): string;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { formatPemBlock };
|
|
5
|
+
//# sourceMappingURL=format-pem-block.d.mts.map
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
let __n8n_constants = require("@n8n/constants");
|
|
2
|
+
let nanoid = require("nanoid");
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
//#region src/generate-nano-id.ts
|
|
5
|
+
/**
|
|
6
|
+
* Generates a unique 16-character nanoid.
|
|
7
|
+
*
|
|
8
|
+
* This is the canonical ID generator used across the entire n8n codebase for:
|
|
9
|
+
* - Workflow IDs
|
|
10
|
+
* - Project IDs
|
|
11
|
+
* - Variable IDs
|
|
12
|
+
* - API Key IDs
|
|
13
|
+
* - And other entity IDs
|
|
14
|
+
*
|
|
15
|
+
* Both frontend and backend MUST use this function to ensure consistency.
|
|
16
|
+
*
|
|
17
|
+
* @returns A 16-character ID
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const id = generateNanoId();
|
|
22
|
+
* // => 'aBcDeFgHiJkLmNoP' (16 characters)
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
const generateNanoId = (0, nanoid.customAlphabet)(__n8n_constants.NANOID_ALPHABET, 16);
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
exports.generateNanoId = generateNanoId;
|
|
29
|
+
//# sourceMappingURL=generate-nano-id.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-nano-id.cjs","names":["NANOID_ALPHABET"],"sources":["../src/generate-nano-id.ts"],"sourcesContent":["import { NANOID_ALPHABET } from '@n8n/constants';\nimport { customAlphabet } from 'nanoid';\n\n/**\n * Generates a unique 16-character nanoid.\n *\n * This is the canonical ID generator used across the entire n8n codebase for:\n * - Workflow IDs\n * - Project IDs\n * - Variable IDs\n * - API Key IDs\n * - And other entity IDs\n *\n * Both frontend and backend MUST use this function to ensure consistency.\n *\n * @returns A 16-character ID\n *\n * @example\n * ```ts\n * const id = generateNanoId();\n * // => 'aBcDeFgHiJkLmNoP' (16 characters)\n * ```\n */\nexport const generateNanoId = customAlphabet(NANOID_ALPHABET, 16);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,4CAAgCA,iCAAiB,GAAG"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/generate-nano-id.d.ts
|
|
2
|
+
declare const generateNanoId: (size?: number) => string;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { generateNanoId };
|
|
5
|
+
//# sourceMappingURL=generate-nano-id.d.cts.map
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/generate-nano-id.d.ts
|
|
2
|
+
declare const generateNanoId: (size?: number) => string;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { generateNanoId };
|
|
5
|
+
//# sourceMappingURL=generate-nano-id.d.mts.map
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NANOID_ALPHABET } from "@n8n/constants";
|
|
2
|
+
import { customAlphabet } from "nanoid";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
//#region src/generate-nano-id.ts
|
|
5
|
+
/**
|
|
6
|
+
* Generates a unique 16-character nanoid.
|
|
7
|
+
*
|
|
8
|
+
* This is the canonical ID generator used across the entire n8n codebase for:
|
|
9
|
+
* - Workflow IDs
|
|
10
|
+
* - Project IDs
|
|
11
|
+
* - Variable IDs
|
|
12
|
+
* - API Key IDs
|
|
13
|
+
* - And other entity IDs
|
|
14
|
+
*
|
|
15
|
+
* Both frontend and backend MUST use this function to ensure consistency.
|
|
16
|
+
*
|
|
17
|
+
* @returns A 16-character ID
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const id = generateNanoId();
|
|
22
|
+
* // => 'aBcDeFgHiJkLmNoP' (16 characters)
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
const generateNanoId = customAlphabet(NANOID_ALPHABET, 16);
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
export { generateNanoId };
|
|
29
|
+
//# sourceMappingURL=generate-nano-id.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-nano-id.mjs","names":[],"sources":["../src/generate-nano-id.ts"],"sourcesContent":["import { NANOID_ALPHABET } from '@n8n/constants';\nimport { customAlphabet } from 'nanoid';\n\n/**\n * Generates a unique 16-character nanoid.\n *\n * This is the canonical ID generator used across the entire n8n codebase for:\n * - Workflow IDs\n * - Project IDs\n * - Variable IDs\n * - API Key IDs\n * - And other entity IDs\n *\n * Both frontend and backend MUST use this function to ensure consistency.\n *\n * @returns A 16-character ID\n *\n * @example\n * ```ts\n * const id = generateNanoId();\n * // => 'aBcDeFgHiJkLmNoP' (16 characters)\n * ```\n */\nexport const generateNanoId = customAlphabet(NANOID_ALPHABET, 16);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAa,iBAAiB,eAAe,iBAAiB,GAAG"}
|
package/dist/get-jwt-expiry.cjs
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
const require_get_jwt_expiry = require('./get-jwt-expiry2.cjs');
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
//#region src/get-jwt-expiry.ts
|
|
3
|
+
/**
|
|
4
|
+
* Decode the payload of a JWT without verifying the signature.
|
|
5
|
+
* Returns the `exp` claim (seconds since epoch) or undefined.
|
|
6
|
+
*
|
|
7
|
+
* Use only for trusted tokens (e.g. ones we just received from our own proxy)
|
|
8
|
+
* where the goal is scheduling refresh, not authenticating the issuer.
|
|
9
|
+
*/
|
|
10
|
+
function getJwtExpiry(jwt) {
|
|
11
|
+
const parts = jwt.split(".");
|
|
12
|
+
if (parts.length !== 3) return void 0;
|
|
13
|
+
try {
|
|
14
|
+
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
|
|
15
|
+
return typeof payload.exp === "number" ? payload.exp : void 0;
|
|
16
|
+
} catch {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
exports.getJwtExpiry = getJwtExpiry;
|
|
23
|
+
//# sourceMappingURL=get-jwt-expiry.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-jwt-expiry.cjs","names":[],"sources":["../src/get-jwt-expiry.ts"],"sourcesContent":["/**\n * Decode the payload of a JWT without verifying the signature.\n * Returns the `exp` claim (seconds since epoch) or undefined.\n *\n * Use only for trusted tokens (e.g. ones we just received from our own proxy)\n * where the goal is scheduling refresh, not authenticating the issuer.\n */\nexport function getJwtExpiry(jwt: string): number | undefined {\n\tconst parts = jwt.split('.');\n\tif (parts.length !== 3) return undefined;\n\ttry {\n\t\tconst payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString()) as {\n\t\t\texp?: number;\n\t\t};\n\t\treturn typeof payload.exp === 'number' ? payload.exp : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"],"mappings":";;;;;;;;;AAOA,SAAgB,aAAa,KAAiC;CAC7D,MAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,KAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,KAAI;EACH,MAAM,UAAU,KAAK,MAAM,OAAO,KAAK,MAAM,IAAI,YAAY,CAAC,UAAU,CAAC;AAGzE,SAAO,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM;SAChD;AACP"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/get-jwt-expiry.d.ts
|
|
2
|
+
declare function getJwtExpiry(jwt: string): number | undefined;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { getJwtExpiry };
|
|
5
|
+
//# sourceMappingURL=get-jwt-expiry.d.cts.map
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/get-jwt-expiry.d.ts
|
|
2
|
+
declare function getJwtExpiry(jwt: string): number | undefined;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { getJwtExpiry };
|
|
5
|
+
//# sourceMappingURL=get-jwt-expiry.d.mts.map
|
package/dist/get-jwt-expiry.mjs
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/get-jwt-expiry.ts
|
|
2
|
+
/**
|
|
3
|
+
* Decode the payload of a JWT without verifying the signature.
|
|
4
|
+
* Returns the `exp` claim (seconds since epoch) or undefined.
|
|
5
|
+
*
|
|
6
|
+
* Use only for trusted tokens (e.g. ones we just received from our own proxy)
|
|
7
|
+
* where the goal is scheduling refresh, not authenticating the issuer.
|
|
8
|
+
*/
|
|
9
|
+
function getJwtExpiry(jwt) {
|
|
10
|
+
const parts = jwt.split(".");
|
|
11
|
+
if (parts.length !== 3) return void 0;
|
|
12
|
+
try {
|
|
13
|
+
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
|
|
14
|
+
return typeof payload.exp === "number" ? payload.exp : void 0;
|
|
15
|
+
} catch {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
2
19
|
|
|
3
|
-
|
|
20
|
+
//#endregion
|
|
21
|
+
export { getJwtExpiry };
|
|
22
|
+
//# sourceMappingURL=get-jwt-expiry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-jwt-expiry.mjs","names":[],"sources":["../src/get-jwt-expiry.ts"],"sourcesContent":["/**\n * Decode the payload of a JWT without verifying the signature.\n * Returns the `exp` claim (seconds since epoch) or undefined.\n *\n * Use only for trusted tokens (e.g. ones we just received from our own proxy)\n * where the goal is scheduling refresh, not authenticating the issuer.\n */\nexport function getJwtExpiry(jwt: string): number | undefined {\n\tconst parts = jwt.split('.');\n\tif (parts.length !== 3) return undefined;\n\ttry {\n\t\tconst payload = JSON.parse(Buffer.from(parts[1], 'base64url').toString()) as {\n\t\t\texp?: number;\n\t\t};\n\t\treturn typeof payload.exp === 'number' ? payload.exp : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,aAAa,KAAiC;CAC7D,MAAM,QAAQ,IAAI,MAAM,IAAI;AAC5B,KAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,KAAI;EACH,MAAM,UAAU,KAAK,MAAM,OAAO,KAAK,MAAM,IAAI,YAAY,CAAC,UAAU,CAAC;AAGzE,SAAO,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM;SAChD;AACP"}
|
package/dist/is-record.cjs
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
-
const require_is_record = require('./is-record2.cjs');
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
//#region src/is-record.ts
|
|
3
|
+
function isRecord(value) {
|
|
4
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
//#endregion
|
|
8
|
+
exports.isRecord = isRecord;
|
|
9
|
+
//# sourceMappingURL=is-record.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-record.cjs","names":[],"sources":["../src/is-record.ts"],"sourcesContent":["export function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"],"mappings":";;AAAA,SAAgB,SAAS,OAAkD;AAC1E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
|
package/dist/is-record.d.cts
CHANGED
package/dist/is-record.d.mts
CHANGED
package/dist/is-record.mjs
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/is-record.ts
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
//#endregion
|
|
7
|
+
export { isRecord };
|
|
8
|
+
//# sourceMappingURL=is-record.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-record.mjs","names":[],"sources":["../src/is-record.ts"],"sourcesContent":["export function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n"],"mappings":";AAAA,SAAgB,SAAS,OAAkD;AAC1E,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
const require_smart_decimal = require('../smart-decimal.cjs');
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
//#region src/number/smart-decimal.ts
|
|
3
|
+
const smartDecimal = (value, decimals = 2) => {
|
|
4
|
+
if (Number.isInteger(value)) return value;
|
|
5
|
+
if (value.toString().split(".")[1].length <= decimals) return value;
|
|
6
|
+
return Number(value.toFixed(decimals));
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
exports.smartDecimal = smartDecimal;
|
|
11
|
+
//# sourceMappingURL=smart-decimal.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-decimal.cjs","names":[],"sources":["../../src/number/smart-decimal.ts"],"sourcesContent":["export const smartDecimal = (value: number, decimals = 2): number => {\n\t// Check if integer\n\tif (Number.isInteger(value)) {\n\t\treturn value;\n\t}\n\n\t// Check if it has only one decimal place\n\tif (value.toString().split('.')[1].length <= decimals) {\n\t\treturn value;\n\t}\n\n\treturn Number(value.toFixed(decimals));\n};\n"],"mappings":";;AAAA,MAAa,gBAAgB,OAAe,WAAW,MAAc;AAEpE,KAAI,OAAO,UAAU,MAAM,CAC1B,QAAO;AAIR,KAAI,MAAM,UAAU,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,SAC5C,QAAO;AAGR,QAAO,OAAO,MAAM,QAAQ,SAAS,CAAC"}
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/number/smart-decimal.d.ts
|
|
2
|
+
declare const smartDecimal: (value: number, decimals?: number) => number;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { smartDecimal };
|
|
5
|
+
//# sourceMappingURL=smart-decimal.d.cts.map
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/number/smart-decimal.d.ts
|
|
2
|
+
declare const smartDecimal: (value: number, decimals?: number) => number;
|
|
3
|
+
//#endregion
|
|
4
|
+
export { smartDecimal };
|
|
5
|
+
//# sourceMappingURL=smart-decimal.d.mts.map
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/number/smart-decimal.ts
|
|
2
|
+
const smartDecimal = (value, decimals = 2) => {
|
|
3
|
+
if (Number.isInteger(value)) return value;
|
|
4
|
+
if (value.toString().split(".")[1].length <= decimals) return value;
|
|
5
|
+
return Number(value.toFixed(decimals));
|
|
6
|
+
};
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
//#endregion
|
|
9
|
+
export { smartDecimal };
|
|
10
|
+
//# sourceMappingURL=smart-decimal.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smart-decimal.mjs","names":[],"sources":["../../src/number/smart-decimal.ts"],"sourcesContent":["export const smartDecimal = (value: number, decimals = 2): number => {\n\t// Check if integer\n\tif (Number.isInteger(value)) {\n\t\treturn value;\n\t}\n\n\t// Check if it has only one decimal place\n\tif (value.toString().split('.')[1].length <= decimals) {\n\t\treturn value;\n\t}\n\n\treturn Number(value.toFixed(decimals));\n};\n"],"mappings":";AAAA,MAAa,gBAAgB,OAAe,WAAW,MAAc;AAEpE,KAAI,OAAO,UAAU,MAAM,CAC1B,QAAO;AAIR,KAAI,MAAM,UAAU,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,SAC5C,QAAO;AAGR,QAAO,OAAO,MAAM,QAAQ,SAAS,CAAC"}
|
package/dist/placeholder.cjs
CHANGED
|
@@ -1,8 +1,81 @@
|
|
|
1
|
-
const require_placeholder = require('./placeholder2.cjs');
|
|
2
1
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
//#region src/placeholder.ts
|
|
3
|
+
const PLACEHOLDER_SUFFIX = "__>";
|
|
4
|
+
const PLACEHOLDER_VALUE_PREFIX = "<__PLACEHOLDER_VALUE__";
|
|
5
|
+
const PLACEHOLDER_REGEX = /<__PLACEHOLDER.*?__>/;
|
|
6
|
+
/** Check if a value is a placeholder sentinel string (format: `<__PLACEHOLDER_VALUE__hint__>`). */
|
|
7
|
+
function isPlaceholderString(value) {
|
|
8
|
+
return typeof value === "string" && value.startsWith(PLACEHOLDER_VALUE_PREFIX) && value.endsWith(PLACEHOLDER_SUFFIX);
|
|
9
|
+
}
|
|
10
|
+
/** Recursively check if a value (string, array, or object) contains any placeholder sentinel strings. */
|
|
11
|
+
function hasPlaceholderDeep(value) {
|
|
12
|
+
if (typeof value === "string") return isPlaceholderString(value);
|
|
13
|
+
if (Array.isArray(value)) return value.some(hasPlaceholderDeep);
|
|
14
|
+
if (value !== null && typeof value === "object") return Object.values(value).some(hasPlaceholderDeep);
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
/** Checks if a value is a placeholder value (matches the placeholder regex pattern). */
|
|
18
|
+
function isPlaceholderValue(value) {
|
|
19
|
+
if (typeof value !== "string") return false;
|
|
20
|
+
return !!value.match(PLACEHOLDER_REGEX);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Extracts the label from a single placeholder string.
|
|
24
|
+
* Handles formats like:
|
|
25
|
+
* - <__PLACEHOLDER_VALUE__label__>
|
|
26
|
+
* - <__PLACEHOLDER__: label__>
|
|
27
|
+
*/
|
|
28
|
+
function extractLabelFromPlaceholder(placeholder) {
|
|
29
|
+
let label = placeholder.slice(14, -3);
|
|
30
|
+
if (label.startsWith("_VALUE__")) label = label.slice(8);
|
|
31
|
+
else if (label.startsWith("__:")) label = label.slice(3);
|
|
32
|
+
else if (label.startsWith("__")) label = label.slice(2);
|
|
33
|
+
return label.trim();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Extracts all placeholder labels from a string value.
|
|
37
|
+
* Handles both cases where the entire value is a placeholder and where
|
|
38
|
+
* placeholders are embedded within code (e.g., Code node).
|
|
39
|
+
* Returns an array of labels found.
|
|
40
|
+
*/
|
|
41
|
+
function extractPlaceholderLabels(value) {
|
|
42
|
+
if (typeof value !== "string") return [];
|
|
43
|
+
const labels = [];
|
|
44
|
+
const regex = new RegExp(PLACEHOLDER_REGEX.source, "g");
|
|
45
|
+
let match;
|
|
46
|
+
while ((match = regex.exec(value)) !== null) {
|
|
47
|
+
const label = extractLabelFromPlaceholder(match[0]);
|
|
48
|
+
if (label.length > 0) labels.push(label);
|
|
49
|
+
}
|
|
50
|
+
return labels;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Recursively searches through a value (object, array, or primitive) to find
|
|
54
|
+
* all placeholder values and their paths.
|
|
55
|
+
*/
|
|
56
|
+
function findPlaceholderDetails(value, path = []) {
|
|
57
|
+
if (typeof value === "string") return extractPlaceholderLabels(value).map((label) => ({
|
|
58
|
+
path,
|
|
59
|
+
label
|
|
60
|
+
}));
|
|
61
|
+
if (Array.isArray(value)) return value.flatMap((item, index) => findPlaceholderDetails(item, [...path, `[${index}]`]));
|
|
62
|
+
if (value !== null && typeof value === "object") return Object.entries(value).flatMap(([key, nested]) => findPlaceholderDetails(nested, [...path, key]));
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Formats a path array into a dot-notation string for display.
|
|
67
|
+
* Array indices are preserved as [N] without leading dots.
|
|
68
|
+
*/
|
|
69
|
+
function formatPlaceholderPath(path) {
|
|
70
|
+
if (path.length === 0) return "parameters";
|
|
71
|
+
return path.map((segment, index) => segment.startsWith("[") || index === 0 ? segment : `.${segment}`).join("");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//#endregion
|
|
75
|
+
exports.extractPlaceholderLabels = extractPlaceholderLabels;
|
|
76
|
+
exports.findPlaceholderDetails = findPlaceholderDetails;
|
|
77
|
+
exports.formatPlaceholderPath = formatPlaceholderPath;
|
|
78
|
+
exports.hasPlaceholderDeep = hasPlaceholderDeep;
|
|
79
|
+
exports.isPlaceholderString = isPlaceholderString;
|
|
80
|
+
exports.isPlaceholderValue = isPlaceholderValue;
|
|
81
|
+
//# sourceMappingURL=placeholder.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeholder.cjs","names":["labels: string[]"],"sources":["../src/placeholder.ts"],"sourcesContent":["const PLACEHOLDER_PREFIX = '<__PLACEHOLDER';\nconst PLACEHOLDER_SUFFIX = '__>';\nconst PLACEHOLDER_VALUE_PREFIX = '<__PLACEHOLDER_VALUE__';\n\nconst PLACEHOLDER_REGEX = /<__PLACEHOLDER.*?__>/;\n\nexport interface PlaceholderDetail {\n\tpath: string[];\n\tlabel: string;\n}\n\n/** Check if a value is a placeholder sentinel string (format: `<__PLACEHOLDER_VALUE__hint__>`). */\nexport function isPlaceholderString(value: unknown): boolean {\n\treturn (\n\t\ttypeof value === 'string' &&\n\t\tvalue.startsWith(PLACEHOLDER_VALUE_PREFIX) &&\n\t\tvalue.endsWith(PLACEHOLDER_SUFFIX)\n\t);\n}\n\n/** Recursively check if a value (string, array, or object) contains any placeholder sentinel strings. */\nexport function hasPlaceholderDeep(value: unknown): boolean {\n\tif (typeof value === 'string') return isPlaceholderString(value);\n\tif (Array.isArray(value)) return value.some(hasPlaceholderDeep);\n\tif (value !== null && typeof value === 'object') {\n\t\treturn Object.values(value as Record<string, unknown>).some(hasPlaceholderDeep);\n\t}\n\treturn false;\n}\n\n/** Checks if a value is a placeholder value (matches the placeholder regex pattern). */\nexport function isPlaceholderValue(value: unknown): boolean {\n\tif (typeof value !== 'string') return false;\n\treturn !!value.match(PLACEHOLDER_REGEX);\n}\n\n/**\n * Extracts the label from a single placeholder string.\n * Handles formats like:\n * - <__PLACEHOLDER_VALUE__label__>\n * - <__PLACEHOLDER__: label__>\n */\nfunction extractLabelFromPlaceholder(placeholder: string): string {\n\tlet label = placeholder.slice(PLACEHOLDER_PREFIX.length, -PLACEHOLDER_SUFFIX.length);\n\n\tif (label.startsWith('_VALUE__')) {\n\t\tlabel = label.slice('_VALUE__'.length);\n\t} else if (label.startsWith('__:')) {\n\t\tlabel = label.slice('__:'.length);\n\t} else if (label.startsWith('__')) {\n\t\tlabel = label.slice('__'.length);\n\t}\n\n\treturn label.trim();\n}\n\n/**\n * Extracts all placeholder labels from a string value.\n * Handles both cases where the entire value is a placeholder and where\n * placeholders are embedded within code (e.g., Code node).\n * Returns an array of labels found.\n */\nexport function extractPlaceholderLabels(value: unknown): string[] {\n\tif (typeof value !== 'string') return [];\n\n\tconst labels: string[] = [];\n\tconst regex = new RegExp(PLACEHOLDER_REGEX.source, 'g');\n\tlet match;\n\n\twhile ((match = regex.exec(value)) !== null) {\n\t\tconst label = extractLabelFromPlaceholder(match[0]);\n\t\tif (label.length > 0) {\n\t\t\tlabels.push(label);\n\t\t}\n\t}\n\n\treturn labels;\n}\n\n/**\n * Recursively searches through a value (object, array, or primitive) to find\n * all placeholder values and their paths.\n */\nexport function findPlaceholderDetails(value: unknown, path: string[] = []): PlaceholderDetail[] {\n\tif (typeof value === 'string') {\n\t\tconst labels = extractPlaceholderLabels(value);\n\t\treturn labels.map((label) => ({ path, label }));\n\t}\n\n\tif (Array.isArray(value)) {\n\t\treturn value.flatMap((item, index) => findPlaceholderDetails(item, [...path, `[${index}]`]));\n\t}\n\n\tif (value !== null && typeof value === 'object') {\n\t\treturn Object.entries(value).flatMap(([key, nested]) =>\n\t\t\tfindPlaceholderDetails(nested, [...path, key]),\n\t\t);\n\t}\n\n\treturn [];\n}\n\n/**\n * Formats a path array into a dot-notation string for display.\n * Array indices are preserved as [N] without leading dots.\n */\nexport function formatPlaceholderPath(path: string[]): string {\n\tif (path.length === 0) return 'parameters';\n\n\treturn path\n\t\t.map((segment, index) => (segment.startsWith('[') || index === 0 ? segment : `.${segment}`))\n\t\t.join('');\n}\n"],"mappings":";;AACA,MAAM,qBAAqB;AAC3B,MAAM,2BAA2B;AAEjC,MAAM,oBAAoB;;AAQ1B,SAAgB,oBAAoB,OAAyB;AAC5D,QACC,OAAO,UAAU,YACjB,MAAM,WAAW,yBAAyB,IAC1C,MAAM,SAAS,mBAAmB;;;AAKpC,SAAgB,mBAAmB,OAAyB;AAC3D,KAAI,OAAO,UAAU,SAAU,QAAO,oBAAoB,MAAM;AAChE,KAAI,MAAM,QAAQ,MAAM,CAAE,QAAO,MAAM,KAAK,mBAAmB;AAC/D,KAAI,UAAU,QAAQ,OAAO,UAAU,SACtC,QAAO,OAAO,OAAO,MAAiC,CAAC,KAAK,mBAAmB;AAEhF,QAAO;;;AAIR,SAAgB,mBAAmB,OAAyB;AAC3D,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAO,CAAC,CAAC,MAAM,MAAM,kBAAkB;;;;;;;;AASxC,SAAS,4BAA4B,aAA6B;CACjE,IAAI,QAAQ,YAAY,MAAM,IAA2B,GAA2B;AAEpF,KAAI,MAAM,WAAW,WAAW,CAC/B,SAAQ,MAAM,MAAM,EAAkB;UAC5B,MAAM,WAAW,MAAM,CACjC,SAAQ,MAAM,MAAM,EAAa;UACvB,MAAM,WAAW,KAAK,CAChC,SAAQ,MAAM,MAAM,EAAY;AAGjC,QAAO,MAAM,MAAM;;;;;;;;AASpB,SAAgB,yBAAyB,OAA0B;AAClE,KAAI,OAAO,UAAU,SAAU,QAAO,EAAE;CAExC,MAAMA,SAAmB,EAAE;CAC3B,MAAM,QAAQ,IAAI,OAAO,kBAAkB,QAAQ,IAAI;CACvD,IAAI;AAEJ,SAAQ,QAAQ,MAAM,KAAK,MAAM,MAAM,MAAM;EAC5C,MAAM,QAAQ,4BAA4B,MAAM,GAAG;AACnD,MAAI,MAAM,SAAS,EAClB,QAAO,KAAK,MAAM;;AAIpB,QAAO;;;;;;AAOR,SAAgB,uBAAuB,OAAgB,OAAiB,EAAE,EAAuB;AAChG,KAAI,OAAO,UAAU,SAEpB,QADe,yBAAyB,MAAM,CAChC,KAAK,WAAW;EAAE;EAAM;EAAO,EAAE;AAGhD,KAAI,MAAM,QAAQ,MAAM,CACvB,QAAO,MAAM,SAAS,MAAM,UAAU,uBAAuB,MAAM,CAAC,GAAG,MAAM,IAAI,MAAM,GAAG,CAAC,CAAC;AAG7F,KAAI,UAAU,QAAQ,OAAO,UAAU,SACtC,QAAO,OAAO,QAAQ,MAAM,CAAC,SAAS,CAAC,KAAK,YAC3C,uBAAuB,QAAQ,CAAC,GAAG,MAAM,IAAI,CAAC,CAC9C;AAGF,QAAO,EAAE;;;;;;AAOV,SAAgB,sBAAsB,MAAwB;AAC7D,KAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,QAAO,KACL,KAAK,SAAS,UAAW,QAAQ,WAAW,IAAI,IAAI,UAAU,IAAI,UAAU,IAAI,UAAW,CAC3F,KAAK,GAAG"}
|
package/dist/placeholder.d.cts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/placeholder.d.ts
|
|
2
|
+
interface PlaceholderDetail {
|
|
3
|
+
path: string[];
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
declare function isPlaceholderString(value: unknown): boolean;
|
|
7
|
+
declare function hasPlaceholderDeep(value: unknown): boolean;
|
|
8
|
+
declare function isPlaceholderValue(value: unknown): boolean;
|
|
9
|
+
declare function extractPlaceholderLabels(value: unknown): string[];
|
|
10
|
+
declare function findPlaceholderDetails(value: unknown, path?: string[]): PlaceholderDetail[];
|
|
11
|
+
declare function formatPlaceholderPath(path: string[]): string;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { PlaceholderDetail, extractPlaceholderLabels, findPlaceholderDetails, formatPlaceholderPath, hasPlaceholderDeep, isPlaceholderString, isPlaceholderValue };
|
|
14
|
+
//# sourceMappingURL=placeholder.d.cts.map
|
package/dist/placeholder.d.mts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/placeholder.d.ts
|
|
2
|
+
interface PlaceholderDetail {
|
|
3
|
+
path: string[];
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
declare function isPlaceholderString(value: unknown): boolean;
|
|
7
|
+
declare function hasPlaceholderDeep(value: unknown): boolean;
|
|
8
|
+
declare function isPlaceholderValue(value: unknown): boolean;
|
|
9
|
+
declare function extractPlaceholderLabels(value: unknown): string[];
|
|
10
|
+
declare function findPlaceholderDetails(value: unknown, path?: string[]): PlaceholderDetail[];
|
|
11
|
+
declare function formatPlaceholderPath(path: string[]): string;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { PlaceholderDetail, extractPlaceholderLabels, findPlaceholderDetails, formatPlaceholderPath, hasPlaceholderDeep, isPlaceholderString, isPlaceholderValue };
|
|
14
|
+
//# sourceMappingURL=placeholder.d.mts.map
|