@ls-stack/utils 3.30.1 → 3.32.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.
@@ -0,0 +1,57 @@
1
+ // src/stringUtils.ts
2
+ function concatStrings(...args) {
3
+ const strings = [];
4
+ for (let i = 0; i < args.length; i++) {
5
+ const arg = args[i];
6
+ if (!arg) continue;
7
+ if (Array.isArray(arg)) {
8
+ strings.push(concatStrings(...arg));
9
+ continue;
10
+ }
11
+ strings.push(arg);
12
+ }
13
+ return strings.join("");
14
+ }
15
+ var joinStrings = concatStrings;
16
+ function formatNum(num, maxDecimalsOrOptions = 2) {
17
+ const options = typeof maxDecimalsOrOptions === "number" ? {
18
+ maximumFractionDigits: maxDecimalsOrOptions
19
+ } : maxDecimalsOrOptions;
20
+ return num.toLocaleString("en-US", options);
21
+ }
22
+ function isSnakeCase(str) {
23
+ return /^[a-z0-9_]+$/.test(str);
24
+ }
25
+ function convertToSnakeCase(str) {
26
+ return str.replace(/[\s\-.]+/g, "_").replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9_]/g, "").replace(/^_+|_+$/g, "").replace(/_+/g, "_");
27
+ }
28
+ function convertToPascalCase(str) {
29
+ return str.split(/[\s_-]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
30
+ }
31
+ function convertToCamelCase(str) {
32
+ const pascalCase = convertToPascalCase(str);
33
+ return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);
34
+ }
35
+ function convertToSentenceCase(str) {
36
+ return str.split(/[\s_-]+/).map((word) => word.toLowerCase()).join(" ").replace(/^\w/, (char) => char.toUpperCase());
37
+ }
38
+ function convertToTitleCase(str) {
39
+ return str.split(/[\s_-]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
40
+ }
41
+ function truncateString(str, length, ellipsis = "\u2026") {
42
+ if (str.length <= length) return str;
43
+ return str.slice(0, length - 1) + ellipsis;
44
+ }
45
+
46
+ export {
47
+ concatStrings,
48
+ joinStrings,
49
+ formatNum,
50
+ isSnakeCase,
51
+ convertToSnakeCase,
52
+ convertToPascalCase,
53
+ convertToCamelCase,
54
+ convertToSentenceCase,
55
+ convertToTitleCase,
56
+ truncateString
57
+ };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-IATIXMCE.js";
4
4
  import {
5
5
  truncateString
6
- } from "./chunk-4REIIZQY.js";
6
+ } from "./chunk-3LZQMZAS.js";
7
7
  import {
8
8
  isObject,
9
9
  isPlainObject
@@ -23,7 +23,9 @@ __export(concurrentCalls_exports, {
23
23
  ConcurrentCallsAggregateError: () => ConcurrentCallsAggregateError,
24
24
  ConcurrentCallsWithMetadataAggregateError: () => ConcurrentCallsWithMetadataAggregateError,
25
25
  concurrentCalls: () => concurrentCalls,
26
- concurrentCallsWithMetadata: () => concurrentCallsWithMetadata
26
+ concurrentCallsWithMetadata: () => concurrentCallsWithMetadata,
27
+ concurrentResultCalls: () => concurrentResultCalls,
28
+ concurrentResultsWithMetadata: () => concurrentResultsWithMetadata
27
29
  });
28
30
  module.exports = __toCommonJS(concurrentCalls_exports);
29
31
  var import_t_result = require("t-result");
@@ -60,6 +62,15 @@ function truncateArray(array, maxLength, appendIfTruncated) {
60
62
  return result;
61
63
  }
62
64
 
65
+ // src/safeJson.ts
66
+ function safeJsonStringify(value) {
67
+ try {
68
+ return JSON.stringify(value);
69
+ } catch (_) {
70
+ return void 0;
71
+ }
72
+ }
73
+
63
74
  // src/sleep.ts
64
75
  function sleep(ms) {
65
76
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -93,7 +104,10 @@ var ConcurrentCallsAggregateError = class extends AggregateError {
93
104
  failed = 0;
94
105
  constructor(errors, total, failed) {
95
106
  const messages = errors.map(
96
- (error) => `- ${truncateString(error.message, 100)}`
107
+ (error) => `- ${truncateString(
108
+ error instanceof Error ? error.message : safeJsonStringify(error) ?? "???",
109
+ 100
110
+ )}`
97
111
  );
98
112
  const message = formatErrorMessagesWithCounts(messages, failed, total);
99
113
  super(errors, message);
@@ -122,7 +136,10 @@ var ConcurrentCallsWithMetadataAggregateError = class extends AggregateError {
122
136
  }
123
137
  } catch (_) {
124
138
  }
125
- return `- ${metadataPrefix}${truncateString(error.message, 100)}`;
139
+ return `- ${metadataPrefix}${truncateString(
140
+ error instanceof Error ? error.message : safeJsonStringify(error) ?? "???",
141
+ 100
142
+ )}`;
126
143
  });
127
144
  const message = formatErrorMessagesWithCounts(messages, failed, total);
128
145
  const errorInstances = errors.map((e) => e.error);
@@ -136,11 +153,20 @@ var ConcurrentCallsWithMetadataAggregateError = class extends AggregateError {
136
153
  var ConcurrentCalls = class {
137
154
  #pendingCalls = [];
138
155
  #alreadyRun = false;
156
+ allowResultify = true;
157
+ constructor(allowResultify) {
158
+ this.allowResultify = allowResultify;
159
+ }
139
160
  add(...calls) {
140
161
  this.#pendingCalls.push(...calls);
141
162
  return this;
142
163
  }
143
164
  resultifyAdd(...calls) {
165
+ if (!this.allowResultify) {
166
+ throw new Error(
167
+ "resultifyAdd is not allowed when using concurrentResults"
168
+ );
169
+ }
144
170
  const processedCalls = calls.map((call) => {
145
171
  return async () => {
146
172
  try {
@@ -221,11 +247,15 @@ var ConcurrentCalls = class {
221
247
  }
222
248
  };
223
249
  function concurrentCalls() {
224
- return new ConcurrentCalls();
250
+ return new ConcurrentCalls(true);
225
251
  }
226
252
  var ConcurrentCallsWithMetadata = class {
227
253
  #pendingCalls = [];
228
254
  #alreadyRun = false;
255
+ allowResultify = true;
256
+ constructor(allowResultify) {
257
+ this.allowResultify = allowResultify;
258
+ }
229
259
  add(...calls) {
230
260
  invariant(
231
261
  !this.#alreadyRun,
@@ -235,6 +265,11 @@ var ConcurrentCallsWithMetadata = class {
235
265
  return this;
236
266
  }
237
267
  resultifyAdd(...items) {
268
+ if (!this.allowResultify) {
269
+ throw new Error(
270
+ "resultifyAdd is not allowed when using concurrentResultsWithMetadata"
271
+ );
272
+ }
238
273
  const processedItems = items.map(({ fn, metadata }) => {
239
274
  const cb = () => (0, import_t_result.resultify)(async () => {
240
275
  const valueOrPromise = fn();
@@ -352,12 +387,20 @@ var ConcurrentCallsWithMetadata = class {
352
387
  }
353
388
  };
354
389
  function concurrentCallsWithMetadata() {
355
- return new ConcurrentCallsWithMetadata();
390
+ return new ConcurrentCallsWithMetadata(true);
391
+ }
392
+ function concurrentResultCalls() {
393
+ return new ConcurrentCalls(false);
394
+ }
395
+ function concurrentResultsWithMetadata() {
396
+ return new ConcurrentCallsWithMetadata(false);
356
397
  }
357
398
  // Annotate the CommonJS export names for ESM import in node:
358
399
  0 && (module.exports = {
359
400
  ConcurrentCallsAggregateError,
360
401
  ConcurrentCallsWithMetadataAggregateError,
361
402
  concurrentCalls,
362
- concurrentCallsWithMetadata
403
+ concurrentCallsWithMetadata,
404
+ concurrentResultCalls,
405
+ concurrentResultsWithMetadata
363
406
  });
@@ -1,21 +1,21 @@
1
- import { Result } from 't-result';
1
+ import { ResultValidErrors, Result } from 't-result';
2
2
 
3
3
  declare class ConcurrentCallsAggregateError extends AggregateError {
4
- errors: Error[];
4
+ errors: ResultValidErrors[];
5
5
  total: number;
6
6
  failed: number;
7
- constructor(errors: Error[], total: number, failed: number);
7
+ constructor(errors: ResultValidErrors[], total: number, failed: number);
8
8
  }
9
9
  declare class ConcurrentCallsWithMetadataAggregateError<M extends ValidMetadata> extends AggregateError {
10
- errors: Error[];
10
+ errors: ResultValidErrors[];
11
11
  errorsWithMetadata: {
12
- error: Error;
12
+ error: ResultValidErrors;
13
13
  metadata: M;
14
14
  }[];
15
15
  total: number;
16
16
  failed: number;
17
17
  constructor(errors: {
18
- error: Error;
18
+ error: ResultValidErrors;
19
19
  metadata: M;
20
20
  }[], total: number, failed: number);
21
21
  }
@@ -27,12 +27,12 @@ type SucceededCall<R, M> = {
27
27
  value: R;
28
28
  metadata: M;
29
29
  };
30
- type FailedCall<M, E extends Error = Error> = {
30
+ type FailedCall<M, E extends ResultValidErrors = Error> = {
31
31
  metadata: M;
32
32
  error: E;
33
33
  };
34
- type Action<R, E extends Error> = () => Promise<Result<R, E>>;
35
- type SettledResultWithMetadata<R, M, E extends Error = Error> = {
34
+ type Action<R, E extends ResultValidErrors> = () => Promise<Result<R, E>>;
35
+ type SettledResultWithMetadata<R, M, E extends ResultValidErrors = Error> = {
36
36
  ok: true;
37
37
  value: R;
38
38
  metadata: M;
@@ -42,8 +42,10 @@ type SettledResultWithMetadata<R, M, E extends Error = Error> = {
42
42
  error: E;
43
43
  metadata: M;
44
44
  };
45
- declare class ConcurrentCalls<R = unknown, E extends Error = Error> {
45
+ declare class ConcurrentCalls<R = unknown, E extends ResultValidErrors = Error> {
46
46
  #private;
47
+ allowResultify: boolean;
48
+ constructor(allowResultify: boolean);
47
49
  add(...calls: Action<R, E>[]): this;
48
50
  resultifyAdd(...calls: ((() => R) | (() => Promise<R>))[]): this;
49
51
  runAll({ delayStart }?: RunProps): Promise<Result<R[], E>>;
@@ -59,11 +61,12 @@ declare class ConcurrentCalls<R = unknown, E extends Error = Error> {
59
61
  * Executes multiple asynchronous calls concurrently and collects the results in a easier to use format.
60
62
  *
61
63
  * @template R - The type of the result value.
62
- * @template E - The type of the error.
63
64
  */
64
65
  declare function concurrentCalls<R = unknown>(): ConcurrentCalls<R, Error>;
65
- declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown, E extends Error = Error> {
66
+ declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown, E extends ResultValidErrors = Error> {
66
67
  #private;
68
+ allowResultify: boolean;
69
+ constructor(allowResultify: boolean);
67
70
  add(...calls: {
68
71
  fn: Action<R, E>;
69
72
  metadata: M;
@@ -85,12 +88,25 @@ declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown,
85
88
  }>;
86
89
  }
87
90
  /**
88
- * Executes multiple asynchronous calls concurrently and collects the results in a easier to use format.
91
+ * Executes multiple asynchronous calls concurrently with metadata for each call and collects the results in a easier to use format.
89
92
  *
90
93
  * @template M - The type of the call metadata.
91
94
  * @template R - The type of the result value.
92
- * @template E - The type of the error from individual Result objects.
93
95
  */
94
96
  declare function concurrentCallsWithMetadata<M extends ValidMetadata, R = unknown>(): ConcurrentCallsWithMetadata<M, R, Error>;
97
+ type ValueFromResult<R> = R extends Result<infer T, any> ? T : never;
98
+ type ErrorFromResult<R> = R extends Result<any, infer E> ? E : never;
99
+ /**
100
+ * Executes multiple asynchronous result calls concurrently and collects the results in a easier to use format.
101
+ *
102
+ * @template R - The type of the result function that will be called.
103
+ */
104
+ declare function concurrentResultCalls<ResultFn extends (...args: any[]) => Promise<Result<unknown, ResultValidErrors>>>(): ConcurrentCalls<ValueFromResult<Awaited<ReturnType<ResultFn>>>, ErrorFromResult<Awaited<ReturnType<ResultFn>>>>;
105
+ /**
106
+ * Executes multiple asynchronous result calls concurrently with metadata for each call and collects the results in a easier to use format.
107
+ *
108
+ * @template ResultFn - The type of the result function that will be called.
109
+ */
110
+ declare function concurrentResultsWithMetadata<M extends ValidMetadata, ResultFn extends (...args: any[]) => Promise<Result<unknown, ResultValidErrors>>>(): ConcurrentCallsWithMetadata<M, ValueFromResult<Awaited<ReturnType<ResultFn>>>, ErrorFromResult<Awaited<ReturnType<ResultFn>>>>;
95
111
 
96
- export { ConcurrentCallsAggregateError, ConcurrentCallsWithMetadataAggregateError, concurrentCalls, concurrentCallsWithMetadata };
112
+ export { ConcurrentCallsAggregateError, ConcurrentCallsWithMetadataAggregateError, concurrentCalls, concurrentCallsWithMetadata, concurrentResultCalls, concurrentResultsWithMetadata };
@@ -1,21 +1,21 @@
1
- import { Result } from 't-result';
1
+ import { ResultValidErrors, Result } from 't-result';
2
2
 
3
3
  declare class ConcurrentCallsAggregateError extends AggregateError {
4
- errors: Error[];
4
+ errors: ResultValidErrors[];
5
5
  total: number;
6
6
  failed: number;
7
- constructor(errors: Error[], total: number, failed: number);
7
+ constructor(errors: ResultValidErrors[], total: number, failed: number);
8
8
  }
9
9
  declare class ConcurrentCallsWithMetadataAggregateError<M extends ValidMetadata> extends AggregateError {
10
- errors: Error[];
10
+ errors: ResultValidErrors[];
11
11
  errorsWithMetadata: {
12
- error: Error;
12
+ error: ResultValidErrors;
13
13
  metadata: M;
14
14
  }[];
15
15
  total: number;
16
16
  failed: number;
17
17
  constructor(errors: {
18
- error: Error;
18
+ error: ResultValidErrors;
19
19
  metadata: M;
20
20
  }[], total: number, failed: number);
21
21
  }
@@ -27,12 +27,12 @@ type SucceededCall<R, M> = {
27
27
  value: R;
28
28
  metadata: M;
29
29
  };
30
- type FailedCall<M, E extends Error = Error> = {
30
+ type FailedCall<M, E extends ResultValidErrors = Error> = {
31
31
  metadata: M;
32
32
  error: E;
33
33
  };
34
- type Action<R, E extends Error> = () => Promise<Result<R, E>>;
35
- type SettledResultWithMetadata<R, M, E extends Error = Error> = {
34
+ type Action<R, E extends ResultValidErrors> = () => Promise<Result<R, E>>;
35
+ type SettledResultWithMetadata<R, M, E extends ResultValidErrors = Error> = {
36
36
  ok: true;
37
37
  value: R;
38
38
  metadata: M;
@@ -42,8 +42,10 @@ type SettledResultWithMetadata<R, M, E extends Error = Error> = {
42
42
  error: E;
43
43
  metadata: M;
44
44
  };
45
- declare class ConcurrentCalls<R = unknown, E extends Error = Error> {
45
+ declare class ConcurrentCalls<R = unknown, E extends ResultValidErrors = Error> {
46
46
  #private;
47
+ allowResultify: boolean;
48
+ constructor(allowResultify: boolean);
47
49
  add(...calls: Action<R, E>[]): this;
48
50
  resultifyAdd(...calls: ((() => R) | (() => Promise<R>))[]): this;
49
51
  runAll({ delayStart }?: RunProps): Promise<Result<R[], E>>;
@@ -59,11 +61,12 @@ declare class ConcurrentCalls<R = unknown, E extends Error = Error> {
59
61
  * Executes multiple asynchronous calls concurrently and collects the results in a easier to use format.
60
62
  *
61
63
  * @template R - The type of the result value.
62
- * @template E - The type of the error.
63
64
  */
64
65
  declare function concurrentCalls<R = unknown>(): ConcurrentCalls<R, Error>;
65
- declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown, E extends Error = Error> {
66
+ declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown, E extends ResultValidErrors = Error> {
66
67
  #private;
68
+ allowResultify: boolean;
69
+ constructor(allowResultify: boolean);
67
70
  add(...calls: {
68
71
  fn: Action<R, E>;
69
72
  metadata: M;
@@ -85,12 +88,25 @@ declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown,
85
88
  }>;
86
89
  }
87
90
  /**
88
- * Executes multiple asynchronous calls concurrently and collects the results in a easier to use format.
91
+ * Executes multiple asynchronous calls concurrently with metadata for each call and collects the results in a easier to use format.
89
92
  *
90
93
  * @template M - The type of the call metadata.
91
94
  * @template R - The type of the result value.
92
- * @template E - The type of the error from individual Result objects.
93
95
  */
94
96
  declare function concurrentCallsWithMetadata<M extends ValidMetadata, R = unknown>(): ConcurrentCallsWithMetadata<M, R, Error>;
97
+ type ValueFromResult<R> = R extends Result<infer T, any> ? T : never;
98
+ type ErrorFromResult<R> = R extends Result<any, infer E> ? E : never;
99
+ /**
100
+ * Executes multiple asynchronous result calls concurrently and collects the results in a easier to use format.
101
+ *
102
+ * @template R - The type of the result function that will be called.
103
+ */
104
+ declare function concurrentResultCalls<ResultFn extends (...args: any[]) => Promise<Result<unknown, ResultValidErrors>>>(): ConcurrentCalls<ValueFromResult<Awaited<ReturnType<ResultFn>>>, ErrorFromResult<Awaited<ReturnType<ResultFn>>>>;
105
+ /**
106
+ * Executes multiple asynchronous result calls concurrently with metadata for each call and collects the results in a easier to use format.
107
+ *
108
+ * @template ResultFn - The type of the result function that will be called.
109
+ */
110
+ declare function concurrentResultsWithMetadata<M extends ValidMetadata, ResultFn extends (...args: any[]) => Promise<Result<unknown, ResultValidErrors>>>(): ConcurrentCallsWithMetadata<M, ValueFromResult<Awaited<ReturnType<ResultFn>>>, ErrorFromResult<Awaited<ReturnType<ResultFn>>>>;
95
111
 
96
- export { ConcurrentCallsAggregateError, ConcurrentCallsWithMetadataAggregateError, concurrentCalls, concurrentCallsWithMetadata };
112
+ export { ConcurrentCallsAggregateError, ConcurrentCallsWithMetadataAggregateError, concurrentCalls, concurrentCallsWithMetadata, concurrentResultCalls, concurrentResultsWithMetadata };
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  truncateString
3
- } from "./chunk-4REIIZQY.js";
3
+ } from "./chunk-3LZQMZAS.js";
4
4
  import {
5
5
  sleep
6
6
  } from "./chunk-5DZT3Z5Z.js";
7
+ import {
8
+ safeJsonStringify
9
+ } from "./chunk-VAAMRG4K.js";
7
10
  import {
8
11
  truncateArray
9
12
  } from "./chunk-SRVMMYSW.js";
@@ -16,7 +19,11 @@ import {
16
19
  } from "./chunk-JF2MDHOJ.js";
17
20
 
18
21
  // src/concurrentCalls.ts
19
- import { Result, resultify, unknownToError } from "t-result";
22
+ import {
23
+ Result,
24
+ resultify,
25
+ unknownToError
26
+ } from "t-result";
20
27
  function formatErrorMessagesWithCounts(messages, failed, total) {
21
28
  const errorMessageCounts = /* @__PURE__ */ new Map();
22
29
  for (const message of messages) {
@@ -38,7 +45,10 @@ var ConcurrentCallsAggregateError = class extends AggregateError {
38
45
  failed = 0;
39
46
  constructor(errors, total, failed) {
40
47
  const messages = errors.map(
41
- (error) => `- ${truncateString(error.message, 100)}`
48
+ (error) => `- ${truncateString(
49
+ error instanceof Error ? error.message : safeJsonStringify(error) ?? "???",
50
+ 100
51
+ )}`
42
52
  );
43
53
  const message = formatErrorMessagesWithCounts(messages, failed, total);
44
54
  super(errors, message);
@@ -67,7 +77,10 @@ var ConcurrentCallsWithMetadataAggregateError = class extends AggregateError {
67
77
  }
68
78
  } catch (_) {
69
79
  }
70
- return `- ${metadataPrefix}${truncateString(error.message, 100)}`;
80
+ return `- ${metadataPrefix}${truncateString(
81
+ error instanceof Error ? error.message : safeJsonStringify(error) ?? "???",
82
+ 100
83
+ )}`;
71
84
  });
72
85
  const message = formatErrorMessagesWithCounts(messages, failed, total);
73
86
  const errorInstances = errors.map((e) => e.error);
@@ -81,11 +94,20 @@ var ConcurrentCallsWithMetadataAggregateError = class extends AggregateError {
81
94
  var ConcurrentCalls = class {
82
95
  #pendingCalls = [];
83
96
  #alreadyRun = false;
97
+ allowResultify = true;
98
+ constructor(allowResultify) {
99
+ this.allowResultify = allowResultify;
100
+ }
84
101
  add(...calls) {
85
102
  this.#pendingCalls.push(...calls);
86
103
  return this;
87
104
  }
88
105
  resultifyAdd(...calls) {
106
+ if (!this.allowResultify) {
107
+ throw new Error(
108
+ "resultifyAdd is not allowed when using concurrentResults"
109
+ );
110
+ }
89
111
  const processedCalls = calls.map((call) => {
90
112
  return async () => {
91
113
  try {
@@ -166,11 +188,15 @@ var ConcurrentCalls = class {
166
188
  }
167
189
  };
168
190
  function concurrentCalls() {
169
- return new ConcurrentCalls();
191
+ return new ConcurrentCalls(true);
170
192
  }
171
193
  var ConcurrentCallsWithMetadata = class {
172
194
  #pendingCalls = [];
173
195
  #alreadyRun = false;
196
+ allowResultify = true;
197
+ constructor(allowResultify) {
198
+ this.allowResultify = allowResultify;
199
+ }
174
200
  add(...calls) {
175
201
  invariant(
176
202
  !this.#alreadyRun,
@@ -180,6 +206,11 @@ var ConcurrentCallsWithMetadata = class {
180
206
  return this;
181
207
  }
182
208
  resultifyAdd(...items) {
209
+ if (!this.allowResultify) {
210
+ throw new Error(
211
+ "resultifyAdd is not allowed when using concurrentResultsWithMetadata"
212
+ );
213
+ }
183
214
  const processedItems = items.map(({ fn, metadata }) => {
184
215
  const cb = () => resultify(async () => {
185
216
  const valueOrPromise = fn();
@@ -297,11 +328,19 @@ var ConcurrentCallsWithMetadata = class {
297
328
  }
298
329
  };
299
330
  function concurrentCallsWithMetadata() {
300
- return new ConcurrentCallsWithMetadata();
331
+ return new ConcurrentCallsWithMetadata(true);
332
+ }
333
+ function concurrentResultCalls() {
334
+ return new ConcurrentCalls(false);
335
+ }
336
+ function concurrentResultsWithMetadata() {
337
+ return new ConcurrentCallsWithMetadata(false);
301
338
  }
302
339
  export {
303
340
  ConcurrentCallsAggregateError,
304
341
  ConcurrentCallsWithMetadataAggregateError,
305
342
  concurrentCalls,
306
- concurrentCallsWithMetadata
343
+ concurrentCallsWithMetadata,
344
+ concurrentResultCalls,
345
+ concurrentResultsWithMetadata
307
346
  };
@@ -21,7 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var stringUtils_exports = {};
22
22
  __export(stringUtils_exports, {
23
23
  concatStrings: () => concatStrings,
24
+ convertToCamelCase: () => convertToCamelCase,
25
+ convertToPascalCase: () => convertToPascalCase,
26
+ convertToSentenceCase: () => convertToSentenceCase,
24
27
  convertToSnakeCase: () => convertToSnakeCase,
28
+ convertToTitleCase: () => convertToTitleCase,
25
29
  formatNum: () => formatNum,
26
30
  isSnakeCase: () => isSnakeCase,
27
31
  joinStrings: () => joinStrings,
@@ -42,17 +46,30 @@ function concatStrings(...args) {
42
46
  return strings.join("");
43
47
  }
44
48
  var joinStrings = concatStrings;
45
- function formatNum(num) {
46
- return num.toLocaleString("en-US", {
47
- minimumFractionDigits: 2,
48
- maximumFractionDigits: 2
49
- });
49
+ function formatNum(num, maxDecimalsOrOptions = 2) {
50
+ const options = typeof maxDecimalsOrOptions === "number" ? {
51
+ maximumFractionDigits: maxDecimalsOrOptions
52
+ } : maxDecimalsOrOptions;
53
+ return num.toLocaleString("en-US", options);
50
54
  }
51
55
  function isSnakeCase(str) {
52
56
  return /^[a-z0-9_]+$/.test(str);
53
57
  }
54
58
  function convertToSnakeCase(str) {
55
- return str.replace(/([A-Z])/g, "_$1").replace(/[^a-z0-9_]/g, "").toLowerCase();
59
+ return str.replace(/[\s\-.]+/g, "_").replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9_]/g, "").replace(/^_+|_+$/g, "").replace(/_+/g, "_");
60
+ }
61
+ function convertToPascalCase(str) {
62
+ return str.split(/[\s_-]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
63
+ }
64
+ function convertToCamelCase(str) {
65
+ const pascalCase = convertToPascalCase(str);
66
+ return pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1);
67
+ }
68
+ function convertToSentenceCase(str) {
69
+ return str.split(/[\s_-]+/).map((word) => word.toLowerCase()).join(" ").replace(/^\w/, (char) => char.toUpperCase());
70
+ }
71
+ function convertToTitleCase(str) {
72
+ return str.split(/[\s_-]+/).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
56
73
  }
57
74
  function truncateString(str, length, ellipsis = "\u2026") {
58
75
  if (str.length <= length) return str;
@@ -61,7 +78,11 @@ function truncateString(str, length, ellipsis = "\u2026") {
61
78
  // Annotate the CommonJS export names for ESM import in node:
62
79
  0 && (module.exports = {
63
80
  concatStrings,
81
+ convertToCamelCase,
82
+ convertToPascalCase,
83
+ convertToSentenceCase,
64
84
  convertToSnakeCase,
85
+ convertToTitleCase,
65
86
  formatNum,
66
87
  isSnakeCase,
67
88
  joinStrings,
@@ -13,9 +13,13 @@ declare function concatStrings(...args: (Arg | Arg[])[]): string;
13
13
  * @deprecated Use {@link concatStrings} instead
14
14
  */
15
15
  declare const joinStrings: typeof concatStrings;
16
- declare function formatNum(num: number): string;
16
+ declare function formatNum(num: number, maxDecimalsOrOptions?: number | Intl.NumberFormatOptions): string;
17
17
  declare function isSnakeCase(str: string): boolean;
18
18
  declare function convertToSnakeCase(str: string): string;
19
+ declare function convertToPascalCase(str: string): string;
20
+ declare function convertToCamelCase(str: string): string;
21
+ declare function convertToSentenceCase(str: string): string;
22
+ declare function convertToTitleCase(str: string): string;
19
23
  declare function truncateString(str: string, length: number, ellipsis?: string): string;
20
24
 
21
- export { concatStrings, convertToSnakeCase, formatNum, isSnakeCase, joinStrings, truncateString };
25
+ export { concatStrings, convertToCamelCase, convertToPascalCase, convertToSentenceCase, convertToSnakeCase, convertToTitleCase, formatNum, isSnakeCase, joinStrings, truncateString };
@@ -13,9 +13,13 @@ declare function concatStrings(...args: (Arg | Arg[])[]): string;
13
13
  * @deprecated Use {@link concatStrings} instead
14
14
  */
15
15
  declare const joinStrings: typeof concatStrings;
16
- declare function formatNum(num: number): string;
16
+ declare function formatNum(num: number, maxDecimalsOrOptions?: number | Intl.NumberFormatOptions): string;
17
17
  declare function isSnakeCase(str: string): boolean;
18
18
  declare function convertToSnakeCase(str: string): string;
19
+ declare function convertToPascalCase(str: string): string;
20
+ declare function convertToCamelCase(str: string): string;
21
+ declare function convertToSentenceCase(str: string): string;
22
+ declare function convertToTitleCase(str: string): string;
19
23
  declare function truncateString(str: string, length: number, ellipsis?: string): string;
20
24
 
21
- export { concatStrings, convertToSnakeCase, formatNum, isSnakeCase, joinStrings, truncateString };
25
+ export { concatStrings, convertToCamelCase, convertToPascalCase, convertToSentenceCase, convertToSnakeCase, convertToTitleCase, formatNum, isSnakeCase, joinStrings, truncateString };
@@ -1,14 +1,22 @@
1
1
  import {
2
2
  concatStrings,
3
+ convertToCamelCase,
4
+ convertToPascalCase,
5
+ convertToSentenceCase,
3
6
  convertToSnakeCase,
7
+ convertToTitleCase,
4
8
  formatNum,
5
9
  isSnakeCase,
6
10
  joinStrings,
7
11
  truncateString
8
- } from "./chunk-4REIIZQY.js";
12
+ } from "./chunk-3LZQMZAS.js";
9
13
  export {
10
14
  concatStrings,
15
+ convertToCamelCase,
16
+ convertToPascalCase,
17
+ convertToSentenceCase,
11
18
  convertToSnakeCase,
19
+ convertToTitleCase,
12
20
  formatNum,
13
21
  isSnakeCase,
14
22
  joinStrings,
package/lib/testUtils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  yamlStringify
3
- } from "./chunk-QLD7KG5I.js";
3
+ } from "./chunk-IY3KYH32.js";
4
4
  import {
5
5
  omit,
6
6
  pick
@@ -18,7 +18,7 @@ import {
18
18
  import {
19
19
  clampMin
20
20
  } from "./chunk-HTCYUMDR.js";
21
- import "./chunk-4REIIZQY.js";
21
+ import "./chunk-3LZQMZAS.js";
22
22
  import {
23
23
  arrayWithPrevAndIndex,
24
24
  filterAndMap
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  yamlStringify
3
- } from "./chunk-QLD7KG5I.js";
3
+ } from "./chunk-IY3KYH32.js";
4
4
  import "./chunk-IATIXMCE.js";
5
- import "./chunk-4REIIZQY.js";
5
+ import "./chunk-3LZQMZAS.js";
6
6
  import "./chunk-JF2MDHOJ.js";
7
7
  export {
8
8
  yamlStringify
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ls-stack/utils",
3
3
  "description": "Universal TypeScript utilities for browser and Node.js",
4
- "version": "3.30.1",
4
+ "version": "3.32.0",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "lib",