@settlemint/sdk-utils 2.3.2-pref69a5a3 → 2.3.2-preff27199

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +51 -7
  2. package/dist/environment.cjs +17705 -384
  3. package/dist/environment.cjs.map +1 -1
  4. package/dist/environment.d.cts +263 -98
  5. package/dist/environment.d.ts +263 -98
  6. package/dist/environment.js +17743 -0
  7. package/dist/environment.js.map +1 -0
  8. package/dist/filesystem.cjs +6746 -113
  9. package/dist/filesystem.cjs.map +1 -1
  10. package/dist/filesystem.d.cts +22 -1
  11. package/dist/filesystem.d.ts +22 -1
  12. package/dist/filesystem.js +6766 -0
  13. package/dist/filesystem.js.map +1 -0
  14. package/dist/http.cjs +214 -94
  15. package/dist/http.cjs.map +1 -1
  16. package/dist/http.d.cts +9 -1
  17. package/dist/http.d.ts +9 -1
  18. package/dist/http.js +226 -0
  19. package/dist/http.js.map +1 -0
  20. package/dist/index.cjs +292 -110
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +9 -0
  23. package/dist/index.d.ts +9 -0
  24. package/dist/index.js +306 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/json.cjs +83 -0
  27. package/dist/json.cjs.map +1 -0
  28. package/dist/json.d.cts +56 -0
  29. package/dist/json.d.ts +56 -0
  30. package/dist/json.js +80 -0
  31. package/dist/json.js.map +1 -0
  32. package/dist/logging.cjs +209 -137
  33. package/dist/logging.cjs.map +1 -1
  34. package/dist/logging.d.cts +23 -14
  35. package/dist/logging.d.ts +23 -14
  36. package/dist/logging.js +221 -0
  37. package/dist/logging.js.map +1 -0
  38. package/dist/package-manager.cjs +7350 -173
  39. package/dist/package-manager.cjs.map +1 -1
  40. package/dist/package-manager.d.cts +26 -3
  41. package/dist/package-manager.d.ts +26 -3
  42. package/dist/package-manager.js +7382 -0
  43. package/dist/package-manager.js.map +1 -0
  44. package/dist/retry.cjs +137 -0
  45. package/dist/retry.cjs.map +1 -0
  46. package/dist/retry.d.cts +19 -0
  47. package/dist/retry.d.ts +19 -0
  48. package/dist/retry.js +136 -0
  49. package/dist/retry.js.map +1 -0
  50. package/dist/runtime.cjs +58 -40
  51. package/dist/runtime.cjs.map +1 -1
  52. package/dist/runtime.d.cts +3 -0
  53. package/dist/runtime.d.ts +3 -0
  54. package/dist/runtime.js +45 -0
  55. package/dist/runtime.js.map +1 -0
  56. package/dist/string.cjs +76 -0
  57. package/dist/string.cjs.map +1 -0
  58. package/dist/string.d.cts +58 -0
  59. package/dist/string.d.ts +58 -0
  60. package/dist/string.js +72 -0
  61. package/dist/string.js.map +1 -0
  62. package/dist/terminal.cjs +423 -229
  63. package/dist/terminal.cjs.map +1 -1
  64. package/dist/terminal.d.cts +54 -24
  65. package/dist/terminal.d.ts +54 -24
  66. package/dist/terminal.js +438 -0
  67. package/dist/terminal.js.map +1 -0
  68. package/dist/url.cjs +25 -0
  69. package/dist/url.cjs.map +1 -0
  70. package/dist/url.d.cts +20 -0
  71. package/dist/url.d.ts +20 -0
  72. package/dist/url.js +24 -0
  73. package/dist/url.js.map +1 -0
  74. package/dist/validation.cjs +10486 -193
  75. package/dist/validation.cjs.map +1 -1
  76. package/dist/validation.d.cts +124 -94
  77. package/dist/validation.d.ts +124 -94
  78. package/dist/validation.js +10482 -0
  79. package/dist/validation.js.map +1 -0
  80. package/package.json +6 -6
  81. package/dist/environment.mjs +0 -384
  82. package/dist/environment.mjs.map +0 -1
  83. package/dist/filesystem.mjs +0 -105
  84. package/dist/filesystem.mjs.map +0 -1
  85. package/dist/http.mjs +0 -80
  86. package/dist/http.mjs.map +0 -1
  87. package/dist/index.mjs +0 -98
  88. package/dist/index.mjs.map +0 -1
  89. package/dist/logging.mjs +0 -123
  90. package/dist/logging.mjs.map +0 -1
  91. package/dist/package-manager.mjs +0 -167
  92. package/dist/package-manager.mjs.map +0 -1
  93. package/dist/runtime.mjs +0 -23
  94. package/dist/runtime.mjs.map +0 -1
  95. package/dist/terminal.mjs +0 -230
  96. package/dist/terminal.mjs.map +0 -1
  97. package/dist/validation.mjs +0 -161
  98. package/dist/validation.mjs.map +0 -1
@@ -0,0 +1,221 @@
1
+ //#region src/logging/mask-tokens.ts
2
+ /**
3
+ * Masks sensitive SettleMint tokens in output text by replacing them with asterisks.
4
+ * Handles personal access tokens (PAT), application access tokens (AAT), and service account tokens (SAT).
5
+ *
6
+ * @param output - The text string that may contain sensitive tokens
7
+ * @returns The text with any sensitive tokens masked with asterisks
8
+ * @example
9
+ * import { maskTokens } from "@settlemint/sdk-utils/terminal";
10
+ *
11
+ * // Masks a token in text
12
+ * const masked = maskTokens("Token: sm_pat_****"); // "Token: ***"
13
+ */
14
+ const maskTokens = (output) => {
15
+ return output.replace(/sm_(pat|aat|sat)_[0-9a-zA-Z]+/g, "***");
16
+ };
17
+
18
+ //#endregion
19
+ //#region src/logging/logger.ts
20
+ /**
21
+ * Creates a simple logger with configurable log level
22
+ *
23
+ * @param options - Configuration options for the logger
24
+ * @param options.level - The minimum log level to output (default: warn)
25
+ * @param options.prefix - The prefix to add to the log message (default: "")
26
+ * @returns A logger instance with debug, info, warn, and error methods
27
+ *
28
+ * @example
29
+ * import { createLogger } from "@/utils/logging/logger";
30
+ *
31
+ * const logger = createLogger({ level: 'info' });
32
+ *
33
+ * logger.info('User logged in', { userId: '123' });
34
+ * logger.error('Operation failed', new Error('Connection timeout'));
35
+ */
36
+ function createLogger(options = {}) {
37
+ const { level = "warn", prefix = "" } = options;
38
+ const logLevels = {
39
+ debug: 0,
40
+ info: 1,
41
+ warn: 2,
42
+ error: 3,
43
+ none: 4
44
+ };
45
+ const currentLevelValue = logLevels[level];
46
+ const formatArgs = (args) => {
47
+ if (args.length === 0 || args.every((arg) => arg === undefined || arg === null)) {
48
+ return "";
49
+ }
50
+ const formatted = args.map((arg) => {
51
+ if (arg instanceof Error) {
52
+ return `\n${arg.stack || arg.message}`;
53
+ }
54
+ if (typeof arg === "object" && arg !== null) {
55
+ return `\n${JSON.stringify(arg, null, 2)}`;
56
+ }
57
+ return ` ${String(arg)}`;
58
+ }).join("");
59
+ return `, args:${formatted}`;
60
+ };
61
+ const shouldLog = (level$1) => {
62
+ return logLevels[level$1] >= currentLevelValue;
63
+ };
64
+ return {
65
+ debug: (message, ...args) => {
66
+ if (shouldLog("debug")) {
67
+ console.debug(`\x1b[32m${prefix}[DEBUG] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1b[0m`);
68
+ }
69
+ },
70
+ info: (message, ...args) => {
71
+ if (shouldLog("info")) {
72
+ console.info(`\x1b[34m${prefix}[INFO] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1b[0m`);
73
+ }
74
+ },
75
+ warn: (message, ...args) => {
76
+ if (shouldLog("warn")) {
77
+ console.warn(`\x1b[33m${prefix}[WARN] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1b[0m`);
78
+ }
79
+ },
80
+ error: (message, ...args) => {
81
+ if (shouldLog("error")) {
82
+ console.error(`\x1b[31m${prefix}[ERROR] ${maskTokens(message)}${maskTokens(formatArgs(args))}\x1b[0m`);
83
+ }
84
+ }
85
+ };
86
+ }
87
+ /**
88
+ * Default logger instance with standard configuration
89
+ */
90
+ const logger = createLogger();
91
+
92
+ //#endregion
93
+ //#region src/string.ts
94
+ /**
95
+ * Capitalizes the first letter of a string.
96
+ *
97
+ * @param val - The string to capitalize
98
+ * @returns The input string with its first letter capitalized
99
+ *
100
+ * @example
101
+ * import { capitalizeFirstLetter } from "@settlemint/sdk-utils";
102
+ *
103
+ * const capitalized = capitalizeFirstLetter("hello");
104
+ * // Returns: "Hello"
105
+ */
106
+ function capitalizeFirstLetter(val) {
107
+ return String(val).charAt(0).toUpperCase() + String(val).slice(1);
108
+ }
109
+ /**
110
+ * Converts a camelCase string to a human-readable string.
111
+ *
112
+ * @param s - The camelCase string to convert
113
+ * @returns The human-readable string
114
+ *
115
+ * @example
116
+ * import { camelCaseToWords } from "@settlemint/sdk-utils";
117
+ *
118
+ * const words = camelCaseToWords("camelCaseString");
119
+ * // Returns: "Camel Case String"
120
+ */
121
+ function camelCaseToWords(s) {
122
+ const result = s.replace(/([a-z])([A-Z])/g, "$1 $2");
123
+ const withSpaces = result.replace(/([A-Z])([a-z])/g, " $1$2");
124
+ const capitalized = capitalizeFirstLetter(withSpaces);
125
+ return capitalized.replace(/\s+/g, " ").trim();
126
+ }
127
+ /**
128
+ * Replaces underscores and hyphens with spaces.
129
+ *
130
+ * @param s - The string to replace underscores and hyphens with spaces
131
+ * @returns The input string with underscores and hyphens replaced with spaces
132
+ *
133
+ * @example
134
+ * import { replaceUnderscoresAndHyphensWithSpaces } from "@settlemint/sdk-utils";
135
+ *
136
+ * const result = replaceUnderscoresAndHyphensWithSpaces("Already_Spaced-Second");
137
+ * // Returns: "Already Spaced Second"
138
+ */
139
+ function replaceUnderscoresAndHyphensWithSpaces(s) {
140
+ return s.replace(/[-_]/g, " ");
141
+ }
142
+ /**
143
+ * Truncates a string to a maximum length and appends "..." if it is longer.
144
+ *
145
+ * @param value - The string to truncate
146
+ * @param maxLength - The maximum length of the string
147
+ * @returns The truncated string or the original string if it is shorter than the maximum length
148
+ *
149
+ * @example
150
+ * import { truncate } from "@settlemint/sdk-utils";
151
+ *
152
+ * const truncated = truncate("Hello, world!", 10);
153
+ * // Returns: "Hello, wor..."
154
+ */
155
+ function truncate(value, maxLength) {
156
+ if (value.length <= maxLength) {
157
+ return value;
158
+ }
159
+ return `${value.slice(0, maxLength)}...`;
160
+ }
161
+
162
+ //#endregion
163
+ //#region src/logging/request-logger.ts
164
+ const WARNING_THRESHOLD = 500;
165
+ const TRUNCATE_LENGTH = 50;
166
+ /**
167
+ * Logs the request and duration of a fetch call (> 500ms is logged as warn, otherwise info)
168
+ * @param logger - The logger to use
169
+ * @param name - The name of the request
170
+ * @param fn - The fetch function to use
171
+ * @returns The fetch function
172
+ */
173
+ function requestLogger(logger$1, name, fn) {
174
+ return async (...args) => {
175
+ const start = Date.now();
176
+ try {
177
+ return await fn(...args);
178
+ } finally {
179
+ const end = Date.now();
180
+ const duration = end - start;
181
+ const body = extractInfoFromBody(args[1]?.body ?? "{}");
182
+ const message = `${name} path: ${args[0]}, took ${formatDuration(duration)}`;
183
+ if (duration > WARNING_THRESHOLD) {
184
+ logger$1.warn(message, body);
185
+ } else {
186
+ logger$1.info(message, body);
187
+ }
188
+ }
189
+ };
190
+ }
191
+ function formatDuration(duration) {
192
+ return duration < 1e3 ? `${duration}ms` : `${(duration / 1e3).toFixed(3)}s`;
193
+ }
194
+ function extractInfoFromBody(body) {
195
+ try {
196
+ const parsedBody = typeof body === "string" ? JSON.parse(body) : body;
197
+ if (parsedBody === null || parsedBody === undefined || Object.keys(parsedBody).length === 0) {
198
+ return null;
199
+ }
200
+ const dataToKeep = {};
201
+ if ("query" in parsedBody) {
202
+ dataToKeep.query = truncate(parsedBody.query, TRUNCATE_LENGTH);
203
+ }
204
+ if ("variables" in parsedBody) {
205
+ dataToKeep.variables = truncate(JSON.stringify(parsedBody.variables), TRUNCATE_LENGTH);
206
+ }
207
+ if ("operationName" in parsedBody) {
208
+ dataToKeep.operationName = truncate(parsedBody.operationName, TRUNCATE_LENGTH);
209
+ }
210
+ if (Object.keys(dataToKeep).length > 0) {
211
+ return JSON.stringify(dataToKeep);
212
+ }
213
+ return truncate(JSON.stringify(parsedBody || "{}"), TRUNCATE_LENGTH);
214
+ } catch {
215
+ return "{}";
216
+ }
217
+ }
218
+
219
+ //#endregion
220
+ export { createLogger, maskTokens, requestLogger };
221
+ //# sourceMappingURL=logging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","names":["output: string","options: LoggerOptions","logLevels: Record<LogLevel, number>","args: unknown[]","level: LogLevel","level","message: string","val: string","s: string","value: string","maxLength: number","logger: Logger","name: string","fn: typeof fetch","duration: number","body: BodyInit","dataToKeep: Record<string, unknown>"],"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":"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"}