@settlemint/sdk-utils 2.0.0 → 2.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/json.ts","../src/retry.ts","../src/string.ts"],"sourcesContent":["export * from \"./json.js\";\nexport * from \"./retry.js\";\nexport * from \"./string.js\";\n","/**\n * Attempts to parse a JSON string into a typed value, returning a default value if parsing fails.\n *\n * @param value - The JSON string to parse\n * @param defaultValue - The value to return if parsing fails or results in null/undefined\n * @returns The parsed JSON value as type T, or the default value if parsing fails\n *\n * @example\n * import { tryParseJson } from \"@settlemint/sdk-utils\";\n *\n * const config = tryParseJson<{ port: number }>(\n * '{\"port\": 3000}',\n * { port: 8080 }\n * );\n * // Returns: { port: 3000 }\n *\n * const invalid = tryParseJson<string[]>(\n * 'invalid json',\n * []\n * );\n * // Returns: []\n */\nexport function tryParseJson<T>(value: string, defaultValue: T | null = null): T | null {\n try {\n const parsed = JSON.parse(value) as T;\n if (parsed === undefined || parsed === null) {\n return defaultValue;\n }\n return parsed;\n } catch (err) {\n // Invalid json\n return defaultValue;\n }\n}\n","/**\n * Retry a function when it fails.\n * @param fn - The function to retry.\n * @param maxRetries - The maximum number of retries.\n * @param initialSleepTime - The initial time to sleep between exponential backoff retries.\n * @param stopOnError - The function to stop on error.\n * @returns The result of the function or undefined if it fails.\n * @example\n * import { retryWhenFailed } from \"@settlemint/sdk-utils\";\n * import { readFile } from \"node:fs/promises\";\n *\n * const result = await retryWhenFailed(() => readFile(\"/path/to/file.txt\"), 3, 1_000);\n */\nexport async function retryWhenFailed<T>(\n fn: () => Promise<T>,\n maxRetries = 5,\n initialSleepTime = 1_000,\n stopOnError?: (error: Error) => boolean,\n): Promise<T> {\n let attempt = 0;\n\n while (attempt < maxRetries) {\n try {\n return await fn();\n } catch (e) {\n if (typeof stopOnError === \"function\") {\n const error = e as Error;\n if (stopOnError(error)) {\n throw error;\n }\n }\n attempt += 1;\n if (attempt >= maxRetries) {\n throw e;\n }\n // Exponential backoff with full jitter to prevent thundering herd\n const jitter = Math.random();\n const delay = 2 ** attempt * initialSleepTime * jitter; // 0-1x of 1s, 2s, 4s base\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw new Error(\"Retry failed\");\n}\n","/**\n * Capitalizes the first letter of a string.\n *\n * @param val - The string to capitalize\n * @returns The input string with its first letter capitalized\n *\n * @example\n * import { capitalizeFirstLetter } from \"@settlemint/sdk-utils\";\n *\n * const capitalized = capitalizeFirstLetter(\"hello\");\n * // Returns: \"Hello\"\n */\nexport function capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1);\n}\n\n/**\n * Converts a camelCase string to a human-readable string.\n *\n * @param s - The camelCase string to convert\n * @returns The human-readable string\n *\n * @example\n * import { camelCaseToWords } from \"@settlemint/sdk-utils\";\n *\n * const words = camelCaseToWords(\"camelCaseString\");\n * // Returns: \"Camel Case String\"\n */\nexport function camelCaseToWords(s: string) {\n const result = s.replace(/([a-z])([A-Z])/g, \"$1 $2\");\n const withSpaces = result.replace(/([A-Z])([a-z])/g, \" $1$2\");\n const capitalized = capitalizeFirstLetter(withSpaces);\n return capitalized.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Replaces underscores and hyphens with spaces.\n *\n * @param s - The string to replace underscores and hyphens with spaces\n * @returns The input string with underscores and hyphens replaced with spaces\n *\n * @example\n * import { replaceUnderscoresAndHyphensWithSpaces } from \"@settlemint/sdk-utils\";\n *\n * const result = replaceUnderscoresAndHyphensWithSpaces(\"Already_Spaced-Second\");\n * // Returns: \"Already Spaced Second\"\n */\nexport function replaceUnderscoresAndHyphensWithSpaces(s: string) {\n return s.replace(/[-_]/g, \" \");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACsBO,SAAS,aAAgB,OAAe,eAAyB,MAAgB;AACtF,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,WAAW,UAAa,WAAW,MAAM;AAC3C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,KAAK;AAEZ,WAAO;AAAA,EACT;AACF;;;ACpBA,eAAsB,gBACpB,IACA,aAAa,GACb,mBAAmB,KACnB,aACY;AACZ,MAAI,UAAU;AAEd,SAAO,UAAU,YAAY;AAC3B,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,GAAG;AACV,UAAI,OAAO,gBAAgB,YAAY;AACrC,cAAM,QAAQ;AACd,YAAI,YAAY,KAAK,GAAG;AACtB,gBAAM;AAAA,QACR;AAAA,MACF;AACA,iBAAW;AACX,UAAI,WAAW,YAAY;AACzB,cAAM;AAAA,MACR;AAEA,YAAM,SAAS,KAAK,OAAO;AAC3B,YAAM,QAAQ,KAAK,UAAU,mBAAmB;AAChD,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AAAA,IAC3D;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,cAAc;AAChC;;;AC/BO,SAAS,sBAAsB,KAAa;AACjD,SAAO,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,GAAG,EAAE,MAAM,CAAC;AAClE;AAcO,SAAS,iBAAiB,GAAW;AAC1C,QAAM,SAAS,EAAE,QAAQ,mBAAmB,OAAO;AACnD,QAAM,aAAa,OAAO,QAAQ,mBAAmB,OAAO;AAC5D,QAAM,cAAc,sBAAsB,UAAU;AACpD,SAAO,YAAY,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC/C;AAcO,SAAS,uCAAuC,GAAW;AAChE,SAAO,EAAE,QAAQ,SAAS,GAAG;AAC/B;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/json.ts","../src/retry.ts","../src/string.ts"],"sourcesContent":["export * from \"./json.js\";\nexport * from \"./retry.js\";\nexport * from \"./string.js\";\n","/**\n * Attempts to parse a JSON string into a typed value, returning a default value if parsing fails.\n *\n * @param value - The JSON string to parse\n * @param defaultValue - The value to return if parsing fails or results in null/undefined\n * @returns The parsed JSON value as type T, or the default value if parsing fails\n *\n * @example\n * import { tryParseJson } from \"@settlemint/sdk-utils\";\n *\n * const config = tryParseJson<{ port: number }>(\n * '{\"port\": 3000}',\n * { port: 8080 }\n * );\n * // Returns: { port: 3000 }\n *\n * const invalid = tryParseJson<string[]>(\n * 'invalid json',\n * []\n * );\n * // Returns: []\n */\nexport function tryParseJson<T>(value: string, defaultValue: T | null = null): T | null {\n try {\n const parsed = JSON.parse(value) as T;\n if (parsed === undefined || parsed === null) {\n return defaultValue;\n }\n return parsed;\n } catch (err) {\n // Invalid json\n return defaultValue;\n }\n}\n","/**\n * Retry a function when it fails.\n * @param fn - The function to retry.\n * @param maxRetries - The maximum number of retries.\n * @param initialSleepTime - The initial time to sleep between exponential backoff retries.\n * @param stopOnError - The function to stop on error.\n * @returns The result of the function or undefined if it fails.\n * @example\n * import { retryWhenFailed } from \"@settlemint/sdk-utils\";\n * import { readFile } from \"node:fs/promises\";\n *\n * const result = await retryWhenFailed(() => readFile(\"/path/to/file.txt\"), 3, 1_000);\n */\nexport async function retryWhenFailed<T>(\n fn: () => Promise<T>,\n maxRetries = 5,\n initialSleepTime = 1_000,\n stopOnError?: (error: Error) => boolean,\n): Promise<T> {\n let attempt = 0;\n\n while (attempt < maxRetries) {\n try {\n return await fn();\n } catch (e) {\n if (typeof stopOnError === \"function\") {\n const error = e as Error;\n if (stopOnError(error)) {\n throw error;\n }\n }\n attempt += 1;\n if (attempt >= maxRetries) {\n throw e;\n }\n // Exponential backoff with full jitter to prevent thundering herd\n const jitter = Math.random();\n const delay = 2 ** attempt * initialSleepTime * jitter; // 0-1x of 1s, 2s, 4s base\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw new Error(\"Retry failed\");\n}\n","/**\n * Capitalizes the first letter of a string.\n *\n * @param val - The string to capitalize\n * @returns The input string with its first letter capitalized\n *\n * @example\n * import { capitalizeFirstLetter } from \"@settlemint/sdk-utils\";\n *\n * const capitalized = capitalizeFirstLetter(\"hello\");\n * // Returns: \"Hello\"\n */\nexport function capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1);\n}\n\n/**\n * Converts a camelCase string to a human-readable string.\n *\n * @param s - The camelCase string to convert\n * @returns The human-readable string\n *\n * @example\n * import { camelCaseToWords } from \"@settlemint/sdk-utils\";\n *\n * const words = camelCaseToWords(\"camelCaseString\");\n * // Returns: \"Camel Case String\"\n */\nexport function camelCaseToWords(s: string) {\n const result = s.replace(/([a-z])([A-Z])/g, \"$1 $2\");\n const withSpaces = result.replace(/([A-Z])([a-z])/g, \" $1$2\");\n const capitalized = capitalizeFirstLetter(withSpaces);\n return capitalized.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Replaces underscores and hyphens with spaces.\n *\n * @param s - The string to replace underscores and hyphens with spaces\n * @returns The input string with underscores and hyphens replaced with spaces\n *\n * @example\n * import { replaceUnderscoresAndHyphensWithSpaces } from \"@settlemint/sdk-utils\";\n *\n * const result = replaceUnderscoresAndHyphensWithSpaces(\"Already_Spaced-Second\");\n * // Returns: \"Already Spaced Second\"\n */\nexport function replaceUnderscoresAndHyphensWithSpaces(s: string) {\n return s.replace(/[-_]/g, \" \");\n}\n\n/**\n * Truncates a string to a maximum length and appends \"...\" if it is longer.\n *\n * @param value - The string to truncate\n * @param maxLength - The maximum length of the string\n * @returns The truncated string or the original string if it is shorter than the maximum length\n *\n * @example\n * import { truncate } from \"@settlemint/sdk-utils\";\n *\n * const truncated = truncate(\"Hello, world!\", 10);\n * // Returns: \"Hello, wor...\"\n */\nexport function truncate(value: string, maxLength: number) {\n if (value.length <= maxLength) {\n return value;\n }\n return `${value.slice(0, maxLength)}...`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACsBO,SAAS,aAAgB,OAAe,eAAyB,MAAgB;AACtF,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,WAAW,UAAa,WAAW,MAAM;AAC3C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,KAAK;AAEZ,WAAO;AAAA,EACT;AACF;;;ACpBA,eAAsB,gBACpB,IACA,aAAa,GACb,mBAAmB,KACnB,aACY;AACZ,MAAI,UAAU;AAEd,SAAO,UAAU,YAAY;AAC3B,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,GAAG;AACV,UAAI,OAAO,gBAAgB,YAAY;AACrC,cAAM,QAAQ;AACd,YAAI,YAAY,KAAK,GAAG;AACtB,gBAAM;AAAA,QACR;AAAA,MACF;AACA,iBAAW;AACX,UAAI,WAAW,YAAY;AACzB,cAAM;AAAA,MACR;AAEA,YAAM,SAAS,KAAK,OAAO;AAC3B,YAAM,QAAQ,KAAK,UAAU,mBAAmB;AAChD,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AAAA,IAC3D;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,cAAc;AAChC;;;AC/BO,SAAS,sBAAsB,KAAa;AACjD,SAAO,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,GAAG,EAAE,MAAM,CAAC;AAClE;AAcO,SAAS,iBAAiB,GAAW;AAC1C,QAAM,SAAS,EAAE,QAAQ,mBAAmB,OAAO;AACnD,QAAM,aAAa,OAAO,QAAQ,mBAAmB,OAAO;AAC5D,QAAM,cAAc,sBAAsB,UAAU;AACpD,SAAO,YAAY,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC/C;AAcO,SAAS,uCAAuC,GAAW;AAChE,SAAO,EAAE,QAAQ,SAAS,GAAG;AAC/B;AAeO,SAAS,SAAS,OAAe,WAAmB;AACzD,MAAI,MAAM,UAAU,WAAW;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,GAAG,MAAM,MAAM,GAAG,SAAS,CAAC;AACrC;","names":[]}
package/dist/index.d.cts CHANGED
@@ -76,5 +76,19 @@ declare function camelCaseToWords(s: string): string;
76
76
  * // Returns: "Already Spaced Second"
77
77
  */
78
78
  declare function replaceUnderscoresAndHyphensWithSpaces(s: string): string;
79
+ /**
80
+ * Truncates a string to a maximum length and appends "..." if it is longer.
81
+ *
82
+ * @param value - The string to truncate
83
+ * @param maxLength - The maximum length of the string
84
+ * @returns The truncated string or the original string if it is shorter than the maximum length
85
+ *
86
+ * @example
87
+ * import { truncate } from "@settlemint/sdk-utils";
88
+ *
89
+ * const truncated = truncate("Hello, world!", 10);
90
+ * // Returns: "Hello, wor..."
91
+ */
92
+ declare function truncate(value: string, maxLength: number): string;
79
93
 
80
- export { camelCaseToWords, capitalizeFirstLetter, replaceUnderscoresAndHyphensWithSpaces, retryWhenFailed, tryParseJson };
94
+ export { camelCaseToWords, capitalizeFirstLetter, replaceUnderscoresAndHyphensWithSpaces, retryWhenFailed, truncate, tryParseJson };
package/dist/index.d.ts CHANGED
@@ -76,5 +76,19 @@ declare function camelCaseToWords(s: string): string;
76
76
  * // Returns: "Already Spaced Second"
77
77
  */
78
78
  declare function replaceUnderscoresAndHyphensWithSpaces(s: string): string;
79
+ /**
80
+ * Truncates a string to a maximum length and appends "..." if it is longer.
81
+ *
82
+ * @param value - The string to truncate
83
+ * @param maxLength - The maximum length of the string
84
+ * @returns The truncated string or the original string if it is shorter than the maximum length
85
+ *
86
+ * @example
87
+ * import { truncate } from "@settlemint/sdk-utils";
88
+ *
89
+ * const truncated = truncate("Hello, world!", 10);
90
+ * // Returns: "Hello, wor..."
91
+ */
92
+ declare function truncate(value: string, maxLength: number): string;
79
93
 
80
- export { camelCaseToWords, capitalizeFirstLetter, replaceUnderscoresAndHyphensWithSpaces, retryWhenFailed, tryParseJson };
94
+ export { camelCaseToWords, capitalizeFirstLetter, replaceUnderscoresAndHyphensWithSpaces, retryWhenFailed, truncate, tryParseJson };
package/dist/index.mjs CHANGED
@@ -49,11 +49,18 @@ function camelCaseToWords(s) {
49
49
  function replaceUnderscoresAndHyphensWithSpaces(s) {
50
50
  return s.replace(/[-_]/g, " ");
51
51
  }
52
+ function truncate(value, maxLength) {
53
+ if (value.length <= maxLength) {
54
+ return value;
55
+ }
56
+ return `${value.slice(0, maxLength)}...`;
57
+ }
52
58
  export {
53
59
  camelCaseToWords,
54
60
  capitalizeFirstLetter,
55
61
  replaceUnderscoresAndHyphensWithSpaces,
56
62
  retryWhenFailed,
63
+ truncate,
57
64
  tryParseJson
58
65
  };
59
66
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/json.ts","../src/retry.ts","../src/string.ts"],"sourcesContent":["/**\n * Attempts to parse a JSON string into a typed value, returning a default value if parsing fails.\n *\n * @param value - The JSON string to parse\n * @param defaultValue - The value to return if parsing fails or results in null/undefined\n * @returns The parsed JSON value as type T, or the default value if parsing fails\n *\n * @example\n * import { tryParseJson } from \"@settlemint/sdk-utils\";\n *\n * const config = tryParseJson<{ port: number }>(\n * '{\"port\": 3000}',\n * { port: 8080 }\n * );\n * // Returns: { port: 3000 }\n *\n * const invalid = tryParseJson<string[]>(\n * 'invalid json',\n * []\n * );\n * // Returns: []\n */\nexport function tryParseJson<T>(value: string, defaultValue: T | null = null): T | null {\n try {\n const parsed = JSON.parse(value) as T;\n if (parsed === undefined || parsed === null) {\n return defaultValue;\n }\n return parsed;\n } catch (err) {\n // Invalid json\n return defaultValue;\n }\n}\n","/**\n * Retry a function when it fails.\n * @param fn - The function to retry.\n * @param maxRetries - The maximum number of retries.\n * @param initialSleepTime - The initial time to sleep between exponential backoff retries.\n * @param stopOnError - The function to stop on error.\n * @returns The result of the function or undefined if it fails.\n * @example\n * import { retryWhenFailed } from \"@settlemint/sdk-utils\";\n * import { readFile } from \"node:fs/promises\";\n *\n * const result = await retryWhenFailed(() => readFile(\"/path/to/file.txt\"), 3, 1_000);\n */\nexport async function retryWhenFailed<T>(\n fn: () => Promise<T>,\n maxRetries = 5,\n initialSleepTime = 1_000,\n stopOnError?: (error: Error) => boolean,\n): Promise<T> {\n let attempt = 0;\n\n while (attempt < maxRetries) {\n try {\n return await fn();\n } catch (e) {\n if (typeof stopOnError === \"function\") {\n const error = e as Error;\n if (stopOnError(error)) {\n throw error;\n }\n }\n attempt += 1;\n if (attempt >= maxRetries) {\n throw e;\n }\n // Exponential backoff with full jitter to prevent thundering herd\n const jitter = Math.random();\n const delay = 2 ** attempt * initialSleepTime * jitter; // 0-1x of 1s, 2s, 4s base\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw new Error(\"Retry failed\");\n}\n","/**\n * Capitalizes the first letter of a string.\n *\n * @param val - The string to capitalize\n * @returns The input string with its first letter capitalized\n *\n * @example\n * import { capitalizeFirstLetter } from \"@settlemint/sdk-utils\";\n *\n * const capitalized = capitalizeFirstLetter(\"hello\");\n * // Returns: \"Hello\"\n */\nexport function capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1);\n}\n\n/**\n * Converts a camelCase string to a human-readable string.\n *\n * @param s - The camelCase string to convert\n * @returns The human-readable string\n *\n * @example\n * import { camelCaseToWords } from \"@settlemint/sdk-utils\";\n *\n * const words = camelCaseToWords(\"camelCaseString\");\n * // Returns: \"Camel Case String\"\n */\nexport function camelCaseToWords(s: string) {\n const result = s.replace(/([a-z])([A-Z])/g, \"$1 $2\");\n const withSpaces = result.replace(/([A-Z])([a-z])/g, \" $1$2\");\n const capitalized = capitalizeFirstLetter(withSpaces);\n return capitalized.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Replaces underscores and hyphens with spaces.\n *\n * @param s - The string to replace underscores and hyphens with spaces\n * @returns The input string with underscores and hyphens replaced with spaces\n *\n * @example\n * import { replaceUnderscoresAndHyphensWithSpaces } from \"@settlemint/sdk-utils\";\n *\n * const result = replaceUnderscoresAndHyphensWithSpaces(\"Already_Spaced-Second\");\n * // Returns: \"Already Spaced Second\"\n */\nexport function replaceUnderscoresAndHyphensWithSpaces(s: string) {\n return s.replace(/[-_]/g, \" \");\n}\n"],"mappings":";AAsBO,SAAS,aAAgB,OAAe,eAAyB,MAAgB;AACtF,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,WAAW,UAAa,WAAW,MAAM;AAC3C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,KAAK;AAEZ,WAAO;AAAA,EACT;AACF;;;ACpBA,eAAsB,gBACpB,IACA,aAAa,GACb,mBAAmB,KACnB,aACY;AACZ,MAAI,UAAU;AAEd,SAAO,UAAU,YAAY;AAC3B,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,GAAG;AACV,UAAI,OAAO,gBAAgB,YAAY;AACrC,cAAM,QAAQ;AACd,YAAI,YAAY,KAAK,GAAG;AACtB,gBAAM;AAAA,QACR;AAAA,MACF;AACA,iBAAW;AACX,UAAI,WAAW,YAAY;AACzB,cAAM;AAAA,MACR;AAEA,YAAM,SAAS,KAAK,OAAO;AAC3B,YAAM,QAAQ,KAAK,UAAU,mBAAmB;AAChD,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AAAA,IAC3D;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,cAAc;AAChC;;;AC/BO,SAAS,sBAAsB,KAAa;AACjD,SAAO,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,GAAG,EAAE,MAAM,CAAC;AAClE;AAcO,SAAS,iBAAiB,GAAW;AAC1C,QAAM,SAAS,EAAE,QAAQ,mBAAmB,OAAO;AACnD,QAAM,aAAa,OAAO,QAAQ,mBAAmB,OAAO;AAC5D,QAAM,cAAc,sBAAsB,UAAU;AACpD,SAAO,YAAY,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC/C;AAcO,SAAS,uCAAuC,GAAW;AAChE,SAAO,EAAE,QAAQ,SAAS,GAAG;AAC/B;","names":[]}
1
+ {"version":3,"sources":["../src/json.ts","../src/retry.ts","../src/string.ts"],"sourcesContent":["/**\n * Attempts to parse a JSON string into a typed value, returning a default value if parsing fails.\n *\n * @param value - The JSON string to parse\n * @param defaultValue - The value to return if parsing fails or results in null/undefined\n * @returns The parsed JSON value as type T, or the default value if parsing fails\n *\n * @example\n * import { tryParseJson } from \"@settlemint/sdk-utils\";\n *\n * const config = tryParseJson<{ port: number }>(\n * '{\"port\": 3000}',\n * { port: 8080 }\n * );\n * // Returns: { port: 3000 }\n *\n * const invalid = tryParseJson<string[]>(\n * 'invalid json',\n * []\n * );\n * // Returns: []\n */\nexport function tryParseJson<T>(value: string, defaultValue: T | null = null): T | null {\n try {\n const parsed = JSON.parse(value) as T;\n if (parsed === undefined || parsed === null) {\n return defaultValue;\n }\n return parsed;\n } catch (err) {\n // Invalid json\n return defaultValue;\n }\n}\n","/**\n * Retry a function when it fails.\n * @param fn - The function to retry.\n * @param maxRetries - The maximum number of retries.\n * @param initialSleepTime - The initial time to sleep between exponential backoff retries.\n * @param stopOnError - The function to stop on error.\n * @returns The result of the function or undefined if it fails.\n * @example\n * import { retryWhenFailed } from \"@settlemint/sdk-utils\";\n * import { readFile } from \"node:fs/promises\";\n *\n * const result = await retryWhenFailed(() => readFile(\"/path/to/file.txt\"), 3, 1_000);\n */\nexport async function retryWhenFailed<T>(\n fn: () => Promise<T>,\n maxRetries = 5,\n initialSleepTime = 1_000,\n stopOnError?: (error: Error) => boolean,\n): Promise<T> {\n let attempt = 0;\n\n while (attempt < maxRetries) {\n try {\n return await fn();\n } catch (e) {\n if (typeof stopOnError === \"function\") {\n const error = e as Error;\n if (stopOnError(error)) {\n throw error;\n }\n }\n attempt += 1;\n if (attempt >= maxRetries) {\n throw e;\n }\n // Exponential backoff with full jitter to prevent thundering herd\n const jitter = Math.random();\n const delay = 2 ** attempt * initialSleepTime * jitter; // 0-1x of 1s, 2s, 4s base\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n\n throw new Error(\"Retry failed\");\n}\n","/**\n * Capitalizes the first letter of a string.\n *\n * @param val - The string to capitalize\n * @returns The input string with its first letter capitalized\n *\n * @example\n * import { capitalizeFirstLetter } from \"@settlemint/sdk-utils\";\n *\n * const capitalized = capitalizeFirstLetter(\"hello\");\n * // Returns: \"Hello\"\n */\nexport function capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1);\n}\n\n/**\n * Converts a camelCase string to a human-readable string.\n *\n * @param s - The camelCase string to convert\n * @returns The human-readable string\n *\n * @example\n * import { camelCaseToWords } from \"@settlemint/sdk-utils\";\n *\n * const words = camelCaseToWords(\"camelCaseString\");\n * // Returns: \"Camel Case String\"\n */\nexport function camelCaseToWords(s: string) {\n const result = s.replace(/([a-z])([A-Z])/g, \"$1 $2\");\n const withSpaces = result.replace(/([A-Z])([a-z])/g, \" $1$2\");\n const capitalized = capitalizeFirstLetter(withSpaces);\n return capitalized.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Replaces underscores and hyphens with spaces.\n *\n * @param s - The string to replace underscores and hyphens with spaces\n * @returns The input string with underscores and hyphens replaced with spaces\n *\n * @example\n * import { replaceUnderscoresAndHyphensWithSpaces } from \"@settlemint/sdk-utils\";\n *\n * const result = replaceUnderscoresAndHyphensWithSpaces(\"Already_Spaced-Second\");\n * // Returns: \"Already Spaced Second\"\n */\nexport function replaceUnderscoresAndHyphensWithSpaces(s: string) {\n return s.replace(/[-_]/g, \" \");\n}\n\n/**\n * Truncates a string to a maximum length and appends \"...\" if it is longer.\n *\n * @param value - The string to truncate\n * @param maxLength - The maximum length of the string\n * @returns The truncated string or the original string if it is shorter than the maximum length\n *\n * @example\n * import { truncate } from \"@settlemint/sdk-utils\";\n *\n * const truncated = truncate(\"Hello, world!\", 10);\n * // Returns: \"Hello, wor...\"\n */\nexport function truncate(value: string, maxLength: number) {\n if (value.length <= maxLength) {\n return value;\n }\n return `${value.slice(0, maxLength)}...`;\n}\n"],"mappings":";AAsBO,SAAS,aAAgB,OAAe,eAAyB,MAAgB;AACtF,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,WAAW,UAAa,WAAW,MAAM;AAC3C,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,SAAS,KAAK;AAEZ,WAAO;AAAA,EACT;AACF;;;ACpBA,eAAsB,gBACpB,IACA,aAAa,GACb,mBAAmB,KACnB,aACY;AACZ,MAAI,UAAU;AAEd,SAAO,UAAU,YAAY;AAC3B,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,GAAG;AACV,UAAI,OAAO,gBAAgB,YAAY;AACrC,cAAM,QAAQ;AACd,YAAI,YAAY,KAAK,GAAG;AACtB,gBAAM;AAAA,QACR;AAAA,MACF;AACA,iBAAW;AACX,UAAI,WAAW,YAAY;AACzB,cAAM;AAAA,MACR;AAEA,YAAM,SAAS,KAAK,OAAO;AAC3B,YAAM,QAAQ,KAAK,UAAU,mBAAmB;AAChD,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,KAAK,CAAC;AAAA,IAC3D;AAAA,EACF;AAEA,QAAM,IAAI,MAAM,cAAc;AAChC;;;AC/BO,SAAS,sBAAsB,KAAa;AACjD,SAAO,OAAO,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,GAAG,EAAE,MAAM,CAAC;AAClE;AAcO,SAAS,iBAAiB,GAAW;AAC1C,QAAM,SAAS,EAAE,QAAQ,mBAAmB,OAAO;AACnD,QAAM,aAAa,OAAO,QAAQ,mBAAmB,OAAO;AAC5D,QAAM,cAAc,sBAAsB,UAAU;AACpD,SAAO,YAAY,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC/C;AAcO,SAAS,uCAAuC,GAAW;AAChE,SAAO,EAAE,QAAQ,SAAS,GAAG;AAC/B;AAeO,SAAS,SAAS,OAAe,WAAmB;AACzD,MAAI,MAAM,UAAU,WAAW;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,GAAG,MAAM,MAAM,GAAG,SAAS,CAAC;AACrC;","names":[]}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/logging.ts
21
+ var logging_exports = {};
22
+ __export(logging_exports, {
23
+ createLogger: () => createLogger,
24
+ maskTokens: () => maskTokens,
25
+ requestLogger: () => requestLogger
26
+ });
27
+ module.exports = __toCommonJS(logging_exports);
28
+
29
+ // src/logging/mask-tokens.ts
30
+ var maskTokens = (output) => {
31
+ return output.replace(/sm_(pat|aat|sat)_[0-9a-zA-Z]+/g, "***");
32
+ };
33
+
34
+ // src/logging/logger.ts
35
+ function createLogger(options = {}) {
36
+ const { level = "warn", prefix = "" } = options;
37
+ const logLevels = {
38
+ debug: 0,
39
+ info: 1,
40
+ warn: 2,
41
+ error: 3,
42
+ none: 4
43
+ };
44
+ const currentLevelValue = logLevels[level];
45
+ const formatArgs = (args) => {
46
+ if (args.length === 0 || args.every((arg) => arg === void 0 || arg === null)) {
47
+ return "";
48
+ }
49
+ const formatted = args.map((arg) => {
50
+ if (arg instanceof Error) {
51
+ return `
52
+ ${arg.stack || arg.message}`;
53
+ }
54
+ if (typeof arg === "object" && arg !== null) {
55
+ return `
56
+ ${JSON.stringify(arg, null, 2)}`;
57
+ }
58
+ return ` ${String(arg)}`;
59
+ }).join("");
60
+ return `, args:${formatted}`;
61
+ };
62
+ const shouldLog = (level2) => {
63
+ return logLevels[level2] >= currentLevelValue;
64
+ };
65
+ return {
66
+ debug: (message, ...args) => {
67
+ if (shouldLog("debug")) {
68
+ console.debug(`\x1B[32m${prefix}[DEBUG] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1B[0m`);
69
+ }
70
+ },
71
+ info: (message, ...args) => {
72
+ if (shouldLog("info")) {
73
+ console.info(`\x1B[34m${prefix}[INFO] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1B[0m`);
74
+ }
75
+ },
76
+ warn: (message, ...args) => {
77
+ if (shouldLog("warn")) {
78
+ console.warn(`\x1B[33m${prefix}[WARN] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1B[0m`);
79
+ }
80
+ },
81
+ error: (message, ...args) => {
82
+ if (shouldLog("error")) {
83
+ console.error(`\x1B[31m${prefix}[ERROR] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1B[0m`);
84
+ }
85
+ }
86
+ };
87
+ }
88
+ var logger = createLogger();
89
+
90
+ // src/string.ts
91
+ function truncate(value, maxLength) {
92
+ if (value.length <= maxLength) {
93
+ return value;
94
+ }
95
+ return `${value.slice(0, maxLength)}...`;
96
+ }
97
+
98
+ // src/logging/request-logger.ts
99
+ var WARNING_THRESHOLD = 500;
100
+ var TRUNCATE_LENGTH = 50;
101
+ function requestLogger(logger2, name, fn) {
102
+ return async (...args) => {
103
+ const start = Date.now();
104
+ try {
105
+ return await fn(...args);
106
+ } finally {
107
+ const end = Date.now();
108
+ const duration = end - start;
109
+ const body = extractInfoFromBody(args[1]?.body ?? "{}");
110
+ const message = `${name} path: ${args[0]}, took ${formatDuration(duration)}`;
111
+ if (duration > WARNING_THRESHOLD) {
112
+ logger2.warn(message, body);
113
+ } else {
114
+ logger2.info(message, body);
115
+ }
116
+ }
117
+ };
118
+ }
119
+ function formatDuration(duration) {
120
+ return duration < 1e3 ? `${duration}ms` : `${(duration / 1e3).toFixed(3)}s`;
121
+ }
122
+ function extractInfoFromBody(body) {
123
+ try {
124
+ const parsedBody = typeof body === "string" ? JSON.parse(body) : body;
125
+ if (parsedBody === null || parsedBody === void 0 || Object.keys(parsedBody).length === 0) {
126
+ return null;
127
+ }
128
+ const dataToKeep = {};
129
+ if ("query" in parsedBody) {
130
+ dataToKeep.query = truncate(parsedBody.query, TRUNCATE_LENGTH);
131
+ }
132
+ if ("variables" in parsedBody) {
133
+ dataToKeep.variables = truncate(JSON.stringify(parsedBody.variables), TRUNCATE_LENGTH);
134
+ }
135
+ if ("operationName" in parsedBody) {
136
+ dataToKeep.operationName = truncate(parsedBody.operationName, TRUNCATE_LENGTH);
137
+ }
138
+ if (Object.keys(dataToKeep).length > 0) {
139
+ return JSON.stringify(dataToKeep);
140
+ }
141
+ return truncate(JSON.stringify(parsedBody || "{}"), TRUNCATE_LENGTH);
142
+ } catch {
143
+ return "{}";
144
+ }
145
+ }
146
+ // Annotate the CommonJS export names for ESM import in node:
147
+ 0 && (module.exports = {
148
+ createLogger,
149
+ maskTokens,
150
+ requestLogger
151
+ });
152
+ //# sourceMappingURL=logging.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logging.ts","../src/logging/mask-tokens.ts","../src/logging/logger.ts","../src/string.ts","../src/logging/request-logger.ts"],"sourcesContent":["export { createLogger, type Logger, type LoggerOptions, type LogLevel } from \"./logging/logger.js\";\nexport { requestLogger } from \"./logging/request-logger.js\";\nexport { maskTokens } from \"./logging/mask-tokens.js\";\n","/**\n * Masks sensitive SettleMint tokens in output text by replacing them with asterisks.\n * Handles personal access tokens (PAT), application access tokens (AAT), and service account tokens (SAT).\n *\n * @param output - The text string that may contain sensitive tokens\n * @returns The text with any sensitive tokens masked with asterisks\n * @example\n * import { maskTokens } from \"@settlemint/sdk-utils/terminal\";\n *\n * // Masks a token in text\n * const masked = maskTokens(\"Token: sm_pat_****\"); // \"Token: ***\"\n */\nexport const maskTokens = (output: string): string => {\n return output.replace(/sm_(pat|aat|sat)_[0-9a-zA-Z]+/g, \"***\");\n};\n","import { maskTokens } from \"./mask-tokens.js\";\n\n/**\n * Log levels supported by the logger\n */\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"none\";\n\n/**\n * Configuration options for the logger\n * @interface LoggerOptions\n */\nexport interface LoggerOptions {\n /** The minimum log level to output */\n level?: LogLevel;\n /** The prefix to add to the log message */\n prefix?: string;\n}\n\n/**\n * Simple logger interface with basic logging methods\n * @interface Logger\n */\nexport interface Logger {\n /** Log debug information */\n debug: (message: string, ...args: unknown[]) => void;\n /** Log general information */\n info: (message: string, ...args: unknown[]) => void;\n /** Log warnings */\n warn: (message: string, ...args: unknown[]) => void;\n /** Log errors */\n error: (message: string, ...args: unknown[]) => void;\n}\n\n/**\n * Creates a simple logger with configurable log level\n *\n * @param options - Configuration options for the logger\n * @param options.level - The minimum log level to output (default: warn)\n * @param options.prefix - The prefix to add to the log message (default: \"\")\n * @returns A logger instance with debug, info, warn, and error methods\n *\n * @example\n * import { createLogger } from \"@/utils/logging/logger\";\n *\n * const logger = createLogger({ level: 'info' });\n *\n * logger.info('User logged in', { userId: '123' });\n * logger.error('Operation failed', new Error('Connection timeout'));\n */\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const { level = \"warn\", prefix = \"\" } = options;\n\n const logLevels: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n none: 4,\n };\n\n const currentLevelValue = logLevels[level];\n\n const formatArgs = (args: unknown[]): string => {\n if (args.length === 0 || args.every((arg) => arg === undefined || arg === null)) {\n return \"\";\n }\n\n const formatted = args\n .map((arg) => {\n if (arg instanceof Error) {\n return `\\n${arg.stack || arg.message}`;\n }\n if (typeof arg === \"object\" && arg !== null) {\n return `\\n${JSON.stringify(arg, null, 2)}`;\n }\n return ` ${String(arg)}`;\n })\n .join(\"\");\n\n return `, args:${formatted}`;\n };\n\n const shouldLog = (level: LogLevel): boolean => {\n return logLevels[level] >= currentLevelValue;\n };\n\n return {\n debug: (message: string, ...args: unknown[]) => {\n if (shouldLog(\"debug\")) {\n console.debug(`\\x1b[32m${prefix}[DEBUG] ${maskTokens(message)}${maskTokens(formatArgs(args))}\\x1b[0m`);\n }\n },\n info: (message: string, ...args: unknown[]) => {\n if (shouldLog(\"info\")) {\n console.info(`\\x1b[34m${prefix}[INFO] ${maskTokens(message)}${maskTokens(formatArgs(args))}\\x1b[0m`);\n }\n },\n warn: (message: string, ...args: unknown[]) => {\n if (shouldLog(\"warn\")) {\n console.warn(`\\x1b[33m${prefix}[WARN] ${maskTokens(message)}${maskTokens(formatArgs(args))}\\x1b[0m`);\n }\n },\n error: (message: string, ...args: unknown[]) => {\n if (shouldLog(\"error\")) {\n console.error(`\\x1b[31m${prefix}[ERROR] ${maskTokens(message)}${maskTokens(formatArgs(args))}\\x1b[0m`);\n }\n },\n };\n}\n\n/**\n * Default logger instance with standard configuration\n */\nexport const logger = createLogger();\n","/**\n * Capitalizes the first letter of a string.\n *\n * @param val - The string to capitalize\n * @returns The input string with its first letter capitalized\n *\n * @example\n * import { capitalizeFirstLetter } from \"@settlemint/sdk-utils\";\n *\n * const capitalized = capitalizeFirstLetter(\"hello\");\n * // Returns: \"Hello\"\n */\nexport function capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1);\n}\n\n/**\n * Converts a camelCase string to a human-readable string.\n *\n * @param s - The camelCase string to convert\n * @returns The human-readable string\n *\n * @example\n * import { camelCaseToWords } from \"@settlemint/sdk-utils\";\n *\n * const words = camelCaseToWords(\"camelCaseString\");\n * // Returns: \"Camel Case String\"\n */\nexport function camelCaseToWords(s: string) {\n const result = s.replace(/([a-z])([A-Z])/g, \"$1 $2\");\n const withSpaces = result.replace(/([A-Z])([a-z])/g, \" $1$2\");\n const capitalized = capitalizeFirstLetter(withSpaces);\n return capitalized.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Replaces underscores and hyphens with spaces.\n *\n * @param s - The string to replace underscores and hyphens with spaces\n * @returns The input string with underscores and hyphens replaced with spaces\n *\n * @example\n * import { replaceUnderscoresAndHyphensWithSpaces } from \"@settlemint/sdk-utils\";\n *\n * const result = replaceUnderscoresAndHyphensWithSpaces(\"Already_Spaced-Second\");\n * // Returns: \"Already Spaced Second\"\n */\nexport function replaceUnderscoresAndHyphensWithSpaces(s: string) {\n return s.replace(/[-_]/g, \" \");\n}\n\n/**\n * Truncates a string to a maximum length and appends \"...\" if it is longer.\n *\n * @param value - The string to truncate\n * @param maxLength - The maximum length of the string\n * @returns The truncated string or the original string if it is shorter than the maximum length\n *\n * @example\n * import { truncate } from \"@settlemint/sdk-utils\";\n *\n * const truncated = truncate(\"Hello, world!\", 10);\n * // Returns: \"Hello, wor...\"\n */\nexport function truncate(value: string, maxLength: number) {\n if (value.length <= maxLength) {\n return value;\n }\n return `${value.slice(0, maxLength)}...`;\n}\n","import { truncate } from \"../string.js\";\nimport type { Logger } from \"./logger.js\";\n\nconst WARNING_THRESHOLD = 500;\nconst TRUNCATE_LENGTH = 50;\n\n/**\n * Logs the request and duration of a fetch call (> 500ms is logged as warn, otherwise info)\n * @param logger - The logger to use\n * @param name - The name of the request\n * @param fn - The fetch function to use\n * @returns The fetch function\n */\nexport function requestLogger(logger: Logger, name: string, fn: typeof fetch) {\n return async (...args: Parameters<typeof fetch>) => {\n const start = Date.now();\n try {\n return await fn(...args);\n } finally {\n const end = Date.now();\n const duration = end - start;\n const body = extractInfoFromBody(args[1]?.body ?? \"{}\");\n const message = `${name} path: ${args[0]}, took ${formatDuration(duration)}`;\n if (duration > WARNING_THRESHOLD) {\n logger.warn(message, body);\n } else {\n logger.info(message, body);\n }\n }\n };\n}\n\nfunction formatDuration(duration: number) {\n return duration < 1000 ? `${duration}ms` : `${(duration / 1000).toFixed(3)}s`;\n}\n\nfunction extractInfoFromBody(body: BodyInit) {\n try {\n const parsedBody = typeof body === \"string\" ? JSON.parse(body) : body;\n\n if (parsedBody === null || parsedBody === undefined || Object.keys(parsedBody).length === 0) {\n return null;\n }\n\n const dataToKeep: Record<string, unknown> = {};\n // Check for graphql fields\n if (\"query\" in parsedBody) {\n dataToKeep.query = truncate(parsedBody.query, TRUNCATE_LENGTH);\n }\n if (\"variables\" in parsedBody) {\n dataToKeep.variables = truncate(JSON.stringify(parsedBody.variables), TRUNCATE_LENGTH);\n }\n if (\"operationName\" in parsedBody) {\n dataToKeep.operationName = truncate(parsedBody.operationName, TRUNCATE_LENGTH);\n }\n\n if (Object.keys(dataToKeep).length > 0) {\n return JSON.stringify(dataToKeep);\n }\n\n // Not graphql, return the body as is\n return truncate(JSON.stringify(parsedBody || \"{}\"), TRUNCATE_LENGTH);\n } catch {\n return \"{}\";\n }\n}\n"],"mappings":"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","names":["level","logger"]}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Log levels supported by the logger
3
+ */
4
+ type LogLevel = "debug" | "info" | "warn" | "error" | "none";
5
+ /**
6
+ * Configuration options for the logger
7
+ * @interface LoggerOptions
8
+ */
9
+ interface LoggerOptions {
10
+ /** The minimum log level to output */
11
+ level?: LogLevel;
12
+ /** The prefix to add to the log message */
13
+ prefix?: string;
14
+ }
15
+ /**
16
+ * Simple logger interface with basic logging methods
17
+ * @interface Logger
18
+ */
19
+ interface Logger {
20
+ /** Log debug information */
21
+ debug: (message: string, ...args: unknown[]) => void;
22
+ /** Log general information */
23
+ info: (message: string, ...args: unknown[]) => void;
24
+ /** Log warnings */
25
+ warn: (message: string, ...args: unknown[]) => void;
26
+ /** Log errors */
27
+ error: (message: string, ...args: unknown[]) => void;
28
+ }
29
+ /**
30
+ * Creates a simple logger with configurable log level
31
+ *
32
+ * @param options - Configuration options for the logger
33
+ * @param options.level - The minimum log level to output (default: warn)
34
+ * @param options.prefix - The prefix to add to the log message (default: "")
35
+ * @returns A logger instance with debug, info, warn, and error methods
36
+ *
37
+ * @example
38
+ * import { createLogger } from "@/utils/logging/logger";
39
+ *
40
+ * const logger = createLogger({ level: 'info' });
41
+ *
42
+ * logger.info('User logged in', { userId: '123' });
43
+ * logger.error('Operation failed', new Error('Connection timeout'));
44
+ */
45
+ declare function createLogger(options?: LoggerOptions): Logger;
46
+
47
+ /**
48
+ * Logs the request and duration of a fetch call (> 500ms is logged as warn, otherwise info)
49
+ * @param logger - The logger to use
50
+ * @param name - The name of the request
51
+ * @param fn - The fetch function to use
52
+ * @returns The fetch function
53
+ */
54
+ declare function requestLogger(logger: Logger, name: string, fn: typeof fetch): (...args: Parameters<typeof fetch>) => Promise<Response>;
55
+
56
+ /**
57
+ * Masks sensitive SettleMint tokens in output text by replacing them with asterisks.
58
+ * Handles personal access tokens (PAT), application access tokens (AAT), and service account tokens (SAT).
59
+ *
60
+ * @param output - The text string that may contain sensitive tokens
61
+ * @returns The text with any sensitive tokens masked with asterisks
62
+ * @example
63
+ * import { maskTokens } from "@settlemint/sdk-utils/terminal";
64
+ *
65
+ * // Masks a token in text
66
+ * const masked = maskTokens("Token: sm_pat_****"); // "Token: ***"
67
+ */
68
+ declare const maskTokens: (output: string) => string;
69
+
70
+ export { type LogLevel, type Logger, type LoggerOptions, createLogger, maskTokens, requestLogger };
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Log levels supported by the logger
3
+ */
4
+ type LogLevel = "debug" | "info" | "warn" | "error" | "none";
5
+ /**
6
+ * Configuration options for the logger
7
+ * @interface LoggerOptions
8
+ */
9
+ interface LoggerOptions {
10
+ /** The minimum log level to output */
11
+ level?: LogLevel;
12
+ /** The prefix to add to the log message */
13
+ prefix?: string;
14
+ }
15
+ /**
16
+ * Simple logger interface with basic logging methods
17
+ * @interface Logger
18
+ */
19
+ interface Logger {
20
+ /** Log debug information */
21
+ debug: (message: string, ...args: unknown[]) => void;
22
+ /** Log general information */
23
+ info: (message: string, ...args: unknown[]) => void;
24
+ /** Log warnings */
25
+ warn: (message: string, ...args: unknown[]) => void;
26
+ /** Log errors */
27
+ error: (message: string, ...args: unknown[]) => void;
28
+ }
29
+ /**
30
+ * Creates a simple logger with configurable log level
31
+ *
32
+ * @param options - Configuration options for the logger
33
+ * @param options.level - The minimum log level to output (default: warn)
34
+ * @param options.prefix - The prefix to add to the log message (default: "")
35
+ * @returns A logger instance with debug, info, warn, and error methods
36
+ *
37
+ * @example
38
+ * import { createLogger } from "@/utils/logging/logger";
39
+ *
40
+ * const logger = createLogger({ level: 'info' });
41
+ *
42
+ * logger.info('User logged in', { userId: '123' });
43
+ * logger.error('Operation failed', new Error('Connection timeout'));
44
+ */
45
+ declare function createLogger(options?: LoggerOptions): Logger;
46
+
47
+ /**
48
+ * Logs the request and duration of a fetch call (> 500ms is logged as warn, otherwise info)
49
+ * @param logger - The logger to use
50
+ * @param name - The name of the request
51
+ * @param fn - The fetch function to use
52
+ * @returns The fetch function
53
+ */
54
+ declare function requestLogger(logger: Logger, name: string, fn: typeof fetch): (...args: Parameters<typeof fetch>) => Promise<Response>;
55
+
56
+ /**
57
+ * Masks sensitive SettleMint tokens in output text by replacing them with asterisks.
58
+ * Handles personal access tokens (PAT), application access tokens (AAT), and service account tokens (SAT).
59
+ *
60
+ * @param output - The text string that may contain sensitive tokens
61
+ * @returns The text with any sensitive tokens masked with asterisks
62
+ * @example
63
+ * import { maskTokens } from "@settlemint/sdk-utils/terminal";
64
+ *
65
+ * // Masks a token in text
66
+ * const masked = maskTokens("Token: sm_pat_****"); // "Token: ***"
67
+ */
68
+ declare const maskTokens: (output: string) => string;
69
+
70
+ export { type LogLevel, type Logger, type LoggerOptions, createLogger, maskTokens, requestLogger };
@@ -0,0 +1,123 @@
1
+ // src/logging/mask-tokens.ts
2
+ var maskTokens = (output) => {
3
+ return output.replace(/sm_(pat|aat|sat)_[0-9a-zA-Z]+/g, "***");
4
+ };
5
+
6
+ // src/logging/logger.ts
7
+ function createLogger(options = {}) {
8
+ const { level = "warn", prefix = "" } = options;
9
+ const logLevels = {
10
+ debug: 0,
11
+ info: 1,
12
+ warn: 2,
13
+ error: 3,
14
+ none: 4
15
+ };
16
+ const currentLevelValue = logLevels[level];
17
+ const formatArgs = (args) => {
18
+ if (args.length === 0 || args.every((arg) => arg === void 0 || arg === null)) {
19
+ return "";
20
+ }
21
+ const formatted = args.map((arg) => {
22
+ if (arg instanceof Error) {
23
+ return `
24
+ ${arg.stack || arg.message}`;
25
+ }
26
+ if (typeof arg === "object" && arg !== null) {
27
+ return `
28
+ ${JSON.stringify(arg, null, 2)}`;
29
+ }
30
+ return ` ${String(arg)}`;
31
+ }).join("");
32
+ return `, args:${formatted}`;
33
+ };
34
+ const shouldLog = (level2) => {
35
+ return logLevels[level2] >= currentLevelValue;
36
+ };
37
+ return {
38
+ debug: (message, ...args) => {
39
+ if (shouldLog("debug")) {
40
+ console.debug(`\x1B[32m${prefix}[DEBUG] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1B[0m`);
41
+ }
42
+ },
43
+ info: (message, ...args) => {
44
+ if (shouldLog("info")) {
45
+ console.info(`\x1B[34m${prefix}[INFO] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1B[0m`);
46
+ }
47
+ },
48
+ warn: (message, ...args) => {
49
+ if (shouldLog("warn")) {
50
+ console.warn(`\x1B[33m${prefix}[WARN] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1B[0m`);
51
+ }
52
+ },
53
+ error: (message, ...args) => {
54
+ if (shouldLog("error")) {
55
+ console.error(`\x1B[31m${prefix}[ERROR] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1B[0m`);
56
+ }
57
+ }
58
+ };
59
+ }
60
+ var logger = createLogger();
61
+
62
+ // src/string.ts
63
+ function truncate(value, maxLength) {
64
+ if (value.length <= maxLength) {
65
+ return value;
66
+ }
67
+ return `${value.slice(0, maxLength)}...`;
68
+ }
69
+
70
+ // src/logging/request-logger.ts
71
+ var WARNING_THRESHOLD = 500;
72
+ var TRUNCATE_LENGTH = 50;
73
+ function requestLogger(logger2, name, fn) {
74
+ return async (...args) => {
75
+ const start = Date.now();
76
+ try {
77
+ return await fn(...args);
78
+ } finally {
79
+ const end = Date.now();
80
+ const duration = end - start;
81
+ const body = extractInfoFromBody(args[1]?.body ?? "{}");
82
+ const message = `${name} path: ${args[0]}, took ${formatDuration(duration)}`;
83
+ if (duration > WARNING_THRESHOLD) {
84
+ logger2.warn(message, body);
85
+ } else {
86
+ logger2.info(message, body);
87
+ }
88
+ }
89
+ };
90
+ }
91
+ function formatDuration(duration) {
92
+ return duration < 1e3 ? `${duration}ms` : `${(duration / 1e3).toFixed(3)}s`;
93
+ }
94
+ function extractInfoFromBody(body) {
95
+ try {
96
+ const parsedBody = typeof body === "string" ? JSON.parse(body) : body;
97
+ if (parsedBody === null || parsedBody === void 0 || Object.keys(parsedBody).length === 0) {
98
+ return null;
99
+ }
100
+ const dataToKeep = {};
101
+ if ("query" in parsedBody) {
102
+ dataToKeep.query = truncate(parsedBody.query, TRUNCATE_LENGTH);
103
+ }
104
+ if ("variables" in parsedBody) {
105
+ dataToKeep.variables = truncate(JSON.stringify(parsedBody.variables), TRUNCATE_LENGTH);
106
+ }
107
+ if ("operationName" in parsedBody) {
108
+ dataToKeep.operationName = truncate(parsedBody.operationName, TRUNCATE_LENGTH);
109
+ }
110
+ if (Object.keys(dataToKeep).length > 0) {
111
+ return JSON.stringify(dataToKeep);
112
+ }
113
+ return truncate(JSON.stringify(parsedBody || "{}"), TRUNCATE_LENGTH);
114
+ } catch {
115
+ return "{}";
116
+ }
117
+ }
118
+ export {
119
+ createLogger,
120
+ maskTokens,
121
+ requestLogger
122
+ };
123
+ //# sourceMappingURL=logging.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logging/mask-tokens.ts","../src/logging/logger.ts","../src/string.ts","../src/logging/request-logger.ts"],"sourcesContent":["/**\n * Masks sensitive SettleMint tokens in output text by replacing them with asterisks.\n * Handles personal access tokens (PAT), application access tokens (AAT), and service account tokens (SAT).\n *\n * @param output - The text string that may contain sensitive tokens\n * @returns The text with any sensitive tokens masked with asterisks\n * @example\n * import { maskTokens } from \"@settlemint/sdk-utils/terminal\";\n *\n * // Masks a token in text\n * const masked = maskTokens(\"Token: sm_pat_****\"); // \"Token: ***\"\n */\nexport const maskTokens = (output: string): string => {\n return output.replace(/sm_(pat|aat|sat)_[0-9a-zA-Z]+/g, \"***\");\n};\n","import { maskTokens } from \"./mask-tokens.js\";\n\n/**\n * Log levels supported by the logger\n */\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"none\";\n\n/**\n * Configuration options for the logger\n * @interface LoggerOptions\n */\nexport interface LoggerOptions {\n /** The minimum log level to output */\n level?: LogLevel;\n /** The prefix to add to the log message */\n prefix?: string;\n}\n\n/**\n * Simple logger interface with basic logging methods\n * @interface Logger\n */\nexport interface Logger {\n /** Log debug information */\n debug: (message: string, ...args: unknown[]) => void;\n /** Log general information */\n info: (message: string, ...args: unknown[]) => void;\n /** Log warnings */\n warn: (message: string, ...args: unknown[]) => void;\n /** Log errors */\n error: (message: string, ...args: unknown[]) => void;\n}\n\n/**\n * Creates a simple logger with configurable log level\n *\n * @param options - Configuration options for the logger\n * @param options.level - The minimum log level to output (default: warn)\n * @param options.prefix - The prefix to add to the log message (default: \"\")\n * @returns A logger instance with debug, info, warn, and error methods\n *\n * @example\n * import { createLogger } from \"@/utils/logging/logger\";\n *\n * const logger = createLogger({ level: 'info' });\n *\n * logger.info('User logged in', { userId: '123' });\n * logger.error('Operation failed', new Error('Connection timeout'));\n */\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const { level = \"warn\", prefix = \"\" } = options;\n\n const logLevels: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n none: 4,\n };\n\n const currentLevelValue = logLevels[level];\n\n const formatArgs = (args: unknown[]): string => {\n if (args.length === 0 || args.every((arg) => arg === undefined || arg === null)) {\n return \"\";\n }\n\n const formatted = args\n .map((arg) => {\n if (arg instanceof Error) {\n return `\\n${arg.stack || arg.message}`;\n }\n if (typeof arg === \"object\" && arg !== null) {\n return `\\n${JSON.stringify(arg, null, 2)}`;\n }\n return ` ${String(arg)}`;\n })\n .join(\"\");\n\n return `, args:${formatted}`;\n };\n\n const shouldLog = (level: LogLevel): boolean => {\n return logLevels[level] >= currentLevelValue;\n };\n\n return {\n debug: (message: string, ...args: unknown[]) => {\n if (shouldLog(\"debug\")) {\n console.debug(`\\x1b[32m${prefix}[DEBUG] ${maskTokens(message)}${maskTokens(formatArgs(args))}\\x1b[0m`);\n }\n },\n info: (message: string, ...args: unknown[]) => {\n if (shouldLog(\"info\")) {\n console.info(`\\x1b[34m${prefix}[INFO] ${maskTokens(message)}${maskTokens(formatArgs(args))}\\x1b[0m`);\n }\n },\n warn: (message: string, ...args: unknown[]) => {\n if (shouldLog(\"warn\")) {\n console.warn(`\\x1b[33m${prefix}[WARN] ${maskTokens(message)}${maskTokens(formatArgs(args))}\\x1b[0m`);\n }\n },\n error: (message: string, ...args: unknown[]) => {\n if (shouldLog(\"error\")) {\n console.error(`\\x1b[31m${prefix}[ERROR] ${maskTokens(message)}${maskTokens(formatArgs(args))}\\x1b[0m`);\n }\n },\n };\n}\n\n/**\n * Default logger instance with standard configuration\n */\nexport const logger = createLogger();\n","/**\n * Capitalizes the first letter of a string.\n *\n * @param val - The string to capitalize\n * @returns The input string with its first letter capitalized\n *\n * @example\n * import { capitalizeFirstLetter } from \"@settlemint/sdk-utils\";\n *\n * const capitalized = capitalizeFirstLetter(\"hello\");\n * // Returns: \"Hello\"\n */\nexport function capitalizeFirstLetter(val: string) {\n return String(val).charAt(0).toUpperCase() + String(val).slice(1);\n}\n\n/**\n * Converts a camelCase string to a human-readable string.\n *\n * @param s - The camelCase string to convert\n * @returns The human-readable string\n *\n * @example\n * import { camelCaseToWords } from \"@settlemint/sdk-utils\";\n *\n * const words = camelCaseToWords(\"camelCaseString\");\n * // Returns: \"Camel Case String\"\n */\nexport function camelCaseToWords(s: string) {\n const result = s.replace(/([a-z])([A-Z])/g, \"$1 $2\");\n const withSpaces = result.replace(/([A-Z])([a-z])/g, \" $1$2\");\n const capitalized = capitalizeFirstLetter(withSpaces);\n return capitalized.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Replaces underscores and hyphens with spaces.\n *\n * @param s - The string to replace underscores and hyphens with spaces\n * @returns The input string with underscores and hyphens replaced with spaces\n *\n * @example\n * import { replaceUnderscoresAndHyphensWithSpaces } from \"@settlemint/sdk-utils\";\n *\n * const result = replaceUnderscoresAndHyphensWithSpaces(\"Already_Spaced-Second\");\n * // Returns: \"Already Spaced Second\"\n */\nexport function replaceUnderscoresAndHyphensWithSpaces(s: string) {\n return s.replace(/[-_]/g, \" \");\n}\n\n/**\n * Truncates a string to a maximum length and appends \"...\" if it is longer.\n *\n * @param value - The string to truncate\n * @param maxLength - The maximum length of the string\n * @returns The truncated string or the original string if it is shorter than the maximum length\n *\n * @example\n * import { truncate } from \"@settlemint/sdk-utils\";\n *\n * const truncated = truncate(\"Hello, world!\", 10);\n * // Returns: \"Hello, wor...\"\n */\nexport function truncate(value: string, maxLength: number) {\n if (value.length <= maxLength) {\n return value;\n }\n return `${value.slice(0, maxLength)}...`;\n}\n","import { truncate } from \"../string.js\";\nimport type { Logger } from \"./logger.js\";\n\nconst WARNING_THRESHOLD = 500;\nconst TRUNCATE_LENGTH = 50;\n\n/**\n * Logs the request and duration of a fetch call (> 500ms is logged as warn, otherwise info)\n * @param logger - The logger to use\n * @param name - The name of the request\n * @param fn - The fetch function to use\n * @returns The fetch function\n */\nexport function requestLogger(logger: Logger, name: string, fn: typeof fetch) {\n return async (...args: Parameters<typeof fetch>) => {\n const start = Date.now();\n try {\n return await fn(...args);\n } finally {\n const end = Date.now();\n const duration = end - start;\n const body = extractInfoFromBody(args[1]?.body ?? \"{}\");\n const message = `${name} path: ${args[0]}, took ${formatDuration(duration)}`;\n if (duration > WARNING_THRESHOLD) {\n logger.warn(message, body);\n } else {\n logger.info(message, body);\n }\n }\n };\n}\n\nfunction formatDuration(duration: number) {\n return duration < 1000 ? `${duration}ms` : `${(duration / 1000).toFixed(3)}s`;\n}\n\nfunction extractInfoFromBody(body: BodyInit) {\n try {\n const parsedBody = typeof body === \"string\" ? JSON.parse(body) : body;\n\n if (parsedBody === null || parsedBody === undefined || Object.keys(parsedBody).length === 0) {\n return null;\n }\n\n const dataToKeep: Record<string, unknown> = {};\n // Check for graphql fields\n if (\"query\" in parsedBody) {\n dataToKeep.query = truncate(parsedBody.query, TRUNCATE_LENGTH);\n }\n if (\"variables\" in parsedBody) {\n dataToKeep.variables = truncate(JSON.stringify(parsedBody.variables), TRUNCATE_LENGTH);\n }\n if (\"operationName\" in parsedBody) {\n dataToKeep.operationName = truncate(parsedBody.operationName, TRUNCATE_LENGTH);\n }\n\n if (Object.keys(dataToKeep).length > 0) {\n return JSON.stringify(dataToKeep);\n }\n\n // Not graphql, return the body as is\n return truncate(JSON.stringify(parsedBody || \"{}\"), TRUNCATE_LENGTH);\n } catch {\n return \"{}\";\n }\n}\n"],"mappings":";AAYO,IAAM,aAAa,CAAC,WAA2B;AACpD,SAAO,OAAO,QAAQ,kCAAkC,KAAK;AAC/D;;;ACmCO,SAAS,aAAa,UAAyB,CAAC,GAAW;AAChE,QAAM,EAAE,QAAQ,QAAQ,SAAS,GAAG,IAAI;AAExC,QAAM,YAAsC;AAAA,IAC1C,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM;AAAA,EACR;AAEA,QAAM,oBAAoB,UAAU,KAAK;AAEzC,QAAM,aAAa,CAAC,SAA4B;AAC9C,QAAI,KAAK,WAAW,KAAK,KAAK,MAAM,CAAC,QAAQ,QAAQ,UAAa,QAAQ,IAAI,GAAG;AAC/E,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,KACf,IAAI,CAAC,QAAQ;AACZ,UAAI,eAAe,OAAO;AACxB,eAAO;AAAA,EAAK,IAAI,SAAS,IAAI,OAAO;AAAA,MACtC;AACA,UAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AAC3C,eAAO;AAAA,EAAK,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC;AAAA,MAC1C;AACA,aAAO,IAAI,OAAO,GAAG,CAAC;AAAA,IACxB,CAAC,EACA,KAAK,EAAE;AAEV,WAAO,UAAU,SAAS;AAAA,EAC5B;AAEA,QAAM,YAAY,CAACA,WAA6B;AAC9C,WAAO,UAAUA,MAAK,KAAK;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL,OAAO,CAAC,YAAoB,SAAoB;AAC9C,UAAI,UAAU,OAAO,GAAG;AACtB,gBAAQ,MAAM,WAAW,MAAM,WAAW,WAAW,OAAO,CAAC,GAAG,WAAW,WAAW,IAAI,CAAC,CAAC,SAAS;AAAA,MACvG;AAAA,IACF;AAAA,IACA,MAAM,CAAC,YAAoB,SAAoB;AAC7C,UAAI,UAAU,MAAM,GAAG;AACrB,gBAAQ,KAAK,WAAW,MAAM,UAAU,WAAW,OAAO,CAAC,GAAG,WAAW,WAAW,IAAI,CAAC,CAAC,SAAS;AAAA,MACrG;AAAA,IACF;AAAA,IACA,MAAM,CAAC,YAAoB,SAAoB;AAC7C,UAAI,UAAU,MAAM,GAAG;AACrB,gBAAQ,KAAK,WAAW,MAAM,UAAU,WAAW,OAAO,CAAC,GAAG,WAAW,WAAW,IAAI,CAAC,CAAC,SAAS;AAAA,MACrG;AAAA,IACF;AAAA,IACA,OAAO,CAAC,YAAoB,SAAoB;AAC9C,UAAI,UAAU,OAAO,GAAG;AACtB,gBAAQ,MAAM,WAAW,MAAM,WAAW,WAAW,OAAO,CAAC,GAAG,WAAW,WAAW,IAAI,CAAC,CAAC,SAAS;AAAA,MACvG;AAAA,IACF;AAAA,EACF;AACF;AAKO,IAAM,SAAS,aAAa;;;ACjD5B,SAAS,SAAS,OAAe,WAAmB;AACzD,MAAI,MAAM,UAAU,WAAW;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,GAAG,MAAM,MAAM,GAAG,SAAS,CAAC;AACrC;;;AClEA,IAAM,oBAAoB;AAC1B,IAAM,kBAAkB;AASjB,SAAS,cAAcC,SAAgB,MAAc,IAAkB;AAC5E,SAAO,UAAU,SAAmC;AAClD,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI;AACF,aAAO,MAAM,GAAG,GAAG,IAAI;AAAA,IACzB,UAAE;AACA,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,WAAW,MAAM;AACvB,YAAM,OAAO,oBAAoB,KAAK,CAAC,GAAG,QAAQ,IAAI;AACtD,YAAM,UAAU,GAAG,IAAI,UAAU,KAAK,CAAC,CAAC,UAAU,eAAe,QAAQ,CAAC;AAC1E,UAAI,WAAW,mBAAmB;AAChC,QAAAA,QAAO,KAAK,SAAS,IAAI;AAAA,MAC3B,OAAO;AACL,QAAAA,QAAO,KAAK,SAAS,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,eAAe,UAAkB;AACxC,SAAO,WAAW,MAAO,GAAG,QAAQ,OAAO,IAAI,WAAW,KAAM,QAAQ,CAAC,CAAC;AAC5E;AAEA,SAAS,oBAAoB,MAAgB;AAC3C,MAAI;AACF,UAAM,aAAa,OAAO,SAAS,WAAW,KAAK,MAAM,IAAI,IAAI;AAEjE,QAAI,eAAe,QAAQ,eAAe,UAAa,OAAO,KAAK,UAAU,EAAE,WAAW,GAAG;AAC3F,aAAO;AAAA,IACT;AAEA,UAAM,aAAsC,CAAC;AAE7C,QAAI,WAAW,YAAY;AACzB,iBAAW,QAAQ,SAAS,WAAW,OAAO,eAAe;AAAA,IAC/D;AACA,QAAI,eAAe,YAAY;AAC7B,iBAAW,YAAY,SAAS,KAAK,UAAU,WAAW,SAAS,GAAG,eAAe;AAAA,IACvF;AACA,QAAI,mBAAmB,YAAY;AACjC,iBAAW,gBAAgB,SAAS,WAAW,eAAe,eAAe;AAAA,IAC/E;AAEA,QAAI,OAAO,KAAK,UAAU,EAAE,SAAS,GAAG;AACtC,aAAO,KAAK,UAAU,UAAU;AAAA,IAClC;AAGA,WAAO,SAAS,KAAK,UAAU,cAAc,IAAI,GAAG,eAAe;AAAA,EACrE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":["level","logger"]}
@@ -119,7 +119,7 @@ var import_install_pkg = require("@antfu/install-pkg");
119
119
  // src/terminal/ascii.ts
120
120
  var import_yoctocolors = require("yoctocolors");
121
121
 
122
- // src/terminal/mask-tokens.ts
122
+ // src/logging/mask-tokens.ts
123
123
  var maskTokens = (output) => {
124
124
  return output.replace(/sm_(pat|aat|sat)_[0-9a-zA-Z]+/g, "***");
125
125
  };