@onivoro/isomorphic-common 24.0.0 → 24.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @onivoro/isomorphic-common
2
2
 
3
- Common utilities, functions, types, and constants shared between browser and server environments. This comprehensive library provides essential building blocks for TypeScript applications with a focus on type safety, reliability, and consistent behavior across different runtime environments.
3
+ Common utilities, functions, types, and constants shared between browser and server environments in the Onivoro monorepo. This library provides essential building blocks for TypeScript applications with a focus on type safety and consistent behavior across different runtime environments.
4
4
 
5
5
  ## Installation
6
6
 
@@ -13,379 +13,275 @@ npm install @onivoro/isomorphic-common
13
13
  - **Isomorphic Design**: Works identically in browser and Node.js environments
14
14
  - **String Manipulation**: Case conversion, formatting, and validation utilities
15
15
  - **Array Operations**: Chunking, sorting, deduplication, and transformation functions
16
- - **Date/Time Utilities**: Calendar operations, offset calculations, and formatting
17
- - **Financial Functions**: Currency formatting, money calculations, and validation
18
- - **Type Utilities**: Advanced TypeScript type helpers and interfaces
16
+ - **Date/Time Utilities**: Calendar operations, offset calculations, and time constants
17
+ - **Financial Functions**: Currency formatting and money calculations
18
+ - **Type Utilities**: TypeScript type helpers and interfaces
19
19
  - **Validation Functions**: Data validation and parsing utilities
20
20
  - **Testing Helpers**: Mock functions and test arrangement utilities
21
- - **Constants**: Common values, regex patterns, and configuration constants
21
+ - **Constants**: Authentication headers, regex patterns, and time constants
22
22
 
23
- ## Quick Start
24
-
25
- ### String Operations
23
+ ## Constants
26
24
 
25
+ ### Authentication Headers
27
26
  ```typescript
28
- import {
29
- camelCase,
30
- kebabCase,
31
- snakeCase,
32
- upperFirst,
33
- sanitizeFilename,
34
- formatUsd
35
- } from '@onivoro/isomorphic-common';
27
+ import { apiKeyHeader } from '@onivoro/isomorphic-common';
36
28
 
37
- // Case conversions
38
- camelCase('hello world'); // 'helloWorld'
39
- kebabCase('Hello World'); // 'hello-world'
40
- snakeCase('Hello World'); // 'hello_world'
41
- upperFirst('hello'); // 'Hello'
29
+ // Use in HTTP requests
30
+ const headers = {
31
+ [apiKeyHeader]: 'your-api-key' // 'x-api-key'
32
+ };
33
+ ```
42
34
 
43
- // File operations
44
- sanitizeFilename('My File/Name?.txt'); // 'My File Name .txt'
35
+ ### Time Constants
36
+ ```typescript
37
+ import { MILLIS_PER_DAY, MILLIS_PER_HOUR, MILLIS_PER_MINUTE } from '@onivoro/isomorphic-common';
45
38
 
46
- // Currency formatting
47
- formatUsd(1234.56); // '$1,234.56'
48
- formatUsd('1234.56'); // '$1,234.56'
49
- ```
39
+ // Time constants (calculated from MILLIS_PER_MINUTE base)
40
+ const hoursInDay = MILLIS_PER_DAY / MILLIS_PER_HOUR; // 24
41
+ const minutesInHour = MILLIS_PER_HOUR / MILLIS_PER_MINUTE; // 60
50
42
 
51
- ### Array Manipulation
43
+ // Set timeouts
44
+ setTimeout(() => {}, MILLIS_PER_MINUTE); // 1 minute timeout
45
+ ```
52
46
 
47
+ ### Regular Expressions
53
48
  ```typescript
54
49
  import {
55
- chunk,
56
- toUniqueArray,
57
- removeElementAtIndex,
58
- sortByName,
59
- sortById,
60
- sortNumbers
50
+ email,
51
+ phone,
52
+ zip,
53
+ v4,
54
+ dateIso8601,
55
+ numeric,
56
+ ssn,
57
+ ein
61
58
  } from '@onivoro/isomorphic-common';
62
59
 
63
- // Chunking arrays
64
- chunk([1, 2, 3, 4, 5, 6], 3); // [[1, 2], [3, 4], [5, 6]]
60
+ // Validate email
61
+ const isValidEmail = email.test('user@example.com'); // true
65
62
 
66
- // Remove duplicates
67
- toUniqueArray([1, 2, 2, 3, 3, 4]); // [1, 2, 3, 4]
63
+ // Validate phone number (format: 123-456-7890)
64
+ const isValidPhone = phone.test('123-456-7890'); // true
68
65
 
69
- // Remove element by index
70
- removeElementAtIndex(['a', 'b', 'c'], 1); // ['a', 'c']
66
+ // Validate ZIP code (5 digits)
67
+ const isValidZip = zip.test('12345'); // true
68
+
69
+ // Validate UUID v4
70
+ const isValidUuid = v4.test('550e8400-e29b-41d4-a716-446655440000'); // true
71
71
 
72
- // Sorting utilities
73
- sortByName([{name: 'Bob'}, {name: 'Alice'}]); // [{name: 'Alice'}, {name: 'Bob'}]
74
- sortById([{id: 3}, {id: 1}, {id: 2}]); // [{id: 1}, {id: 2}, {id: 3}]
75
- sortNumbers([3, 1, 4, 1, 5]); // [1, 1, 3, 4, 5]
72
+ // Validate ISO date (YYYY-MM-DD)
73
+ const isValidDate = dateIso8601.test('2023-12-31'); // true
76
74
  ```
77
75
 
78
- ### Date and Time Operations
76
+ ## String Functions
79
77
 
78
+ ### Case Conversion
80
79
  ```typescript
81
- import {
82
- addOffset,
83
- subtractOffset,
84
- getDateRangeForMonth,
85
- splitDateRangeIntoDays,
86
- isValidDate,
87
- tryParseDate,
88
- toCalendarDate,
89
- fromCalendarDate
90
- } from '@onivoro/isomorphic-common';
80
+ import { camelCase, kebabCase, snakeCase } from '@onivoro/isomorphic-common';
91
81
 
92
- // Date offset calculations
93
- const date = new Date('2023-01-15');
94
- addOffset(date, 7); // Add 7 days
95
- subtractOffset(date, 2); // Subtract 2 days
96
-
97
- // Monthly date ranges
98
- getDateRangeForMonth(2023, 0); // January 2023 range
82
+ // camelCase(string: string): string
83
+ camelCase('hello world'); // 'helloWorld'
84
+ camelCase('--foo-bar--'); // 'fooBar'
85
+ camelCase('__FOO_BAR__'); // 'fooBar'
99
86
 
100
- // Date validation
101
- isValidDate(new Date('2023-01-15')); // true
102
- isValidDate(new Date('invalid')); // false
87
+ // kebabCase(string: string): string
88
+ kebabCase('Hello World'); // 'hello-world'
89
+ kebabCase('fooBar'); // 'foo-bar'
103
90
 
104
- // Safe date parsing
105
- tryParseDate('2023-01-15'); // Date object or null
91
+ // snakeCase(string: string): string
92
+ snakeCase('Hello World'); // 'hello_world'
93
+ snakeCase('fooBar'); // 'foo_bar'
106
94
  ```
107
95
 
108
- ### Financial and Money Operations
96
+ ## Array Functions
109
97
 
98
+ ### Array Manipulation
110
99
  ```typescript
111
100
  import {
112
- money,
113
- toDollarsAndCents,
114
- round,
115
- formatUsd
101
+ chunk,
102
+ removeElementAtIndex,
103
+ toUniqueArray
116
104
  } from '@onivoro/isomorphic-common';
117
105
 
118
- // Money calculations (in cents)
119
- const price = money(19.99); // 1999 cents
120
- const tax = money(price * 0.08); // Calculate tax
121
- const total = price + tax;
122
-
123
- // Convert back to dollars
124
- toDollarsAndCents(total); // { dollars: 21, cents: 59 }
106
+ // chunk<T>(array: T[], numDivisions: number): T[][]
107
+ // Divides array into N divisions (NOT chunks of size N)
108
+ chunk([1, 2, 3, 4, 5, 6], 3); // [[1, 2], [3, 4], [5, 6]] - 3 divisions
109
+ chunk([1, 2, 3, 4, 5], 2); // [[1, 2, 3], [4, 5]] - 2 divisions
125
110
 
126
- // Rounding
127
- round(19.999, 2); // 20.00
128
- round(19.994, 2); // 19.99
111
+ // removeElementAtIndex<T>(array: T[], indexToRemove: number): T[]
112
+ removeElementAtIndex(['a', 'b', 'c'], 1); // ['a', 'c']
129
113
 
130
- // Currency display
131
- formatUsd(total / 100); // '$21.59'
114
+ // toUniqueArray<TElement>(elements: TElement[]): TElement[]
115
+ toUniqueArray([1, 2, 2, 3, 3, 4]); // [1, 2, 3, 4]
132
116
  ```
133
117
 
134
- ## Usage Examples
135
-
136
- ### Data Transformation
137
-
118
+ ### Sorting Functions
138
119
  ```typescript
139
120
  import {
140
- mapEnumToOptions,
141
- mapEntitiesToOptions,
142
- convertObjectToLiteral,
143
- propertiestoArray
121
+ sortByName,
122
+ sortById,
123
+ sortNumbers
144
124
  } from '@onivoro/isomorphic-common';
145
125
 
146
- enum Status {
147
- ACTIVE = 'active',
148
- INACTIVE = 'inactive',
149
- PENDING = 'pending'
150
- }
126
+ // sortByName<TEntity extends { name: string }>(a: TEntity, b: TEntity): number
127
+ const users = [{ name: 'Bob' }, { name: 'Alice' }];
128
+ users.sort(sortByName); // [{ name: 'Alice' }, { name: 'Bob' }]
151
129
 
152
- // Convert enum to dropdown options
153
- const statusOptions = mapEnumToOptions(Status);
154
- // [{ label: 'Active', value: 'active' }, ...]
130
+ // sortById<TEntity extends { id: string }>(a: TEntity, b: TEntity): number
131
+ const items = [{ id: '3' }, { id: '1' }, { id: '2' }];
132
+ items.sort(sortById); // [{ id: '1' }, { id: '2' }, { id: '3' }]
155
133
 
156
- // Convert entities to options
157
- const users = [{ id: 1, name: 'John' }, { id: 2, name: 'Jane' }];
158
- const userOptions = mapEntitiesToOptions(users, 'name', 'id');
159
- // [{ label: 'John', value: 1 }, { label: 'Jane', value: 2 }]
134
+ // sortNumbers(a: number, b: number): number
135
+ const numbers = [3, 1, 4, 1, 5];
136
+ numbers.sort(sortNumbers); // [1, 1, 3, 4, 5]
160
137
  ```
161
138
 
162
- ### Boolean and String Parsing
139
+ ## Date/Time Functions
163
140
 
141
+ ### Date Operations
164
142
  ```typescript
165
143
  import {
166
- parseBool,
167
- fromBooleanString,
168
- toBooleanString,
169
- fromCsvString,
170
- toCsvString
144
+ addOffset,
145
+ subtractOffset,
146
+ getDateRangeForMonth
171
147
  } from '@onivoro/isomorphic-common';
172
148
 
173
- // Boolean parsing
174
- parseBool('true'); // true
175
- parseBool('1'); // true
176
- parseBool('yes'); // true
177
- parseBool('false'); // false
149
+ // addOffset(input: string | Date | undefined | null): Date | undefined
150
+ const date = new Date('2023-01-15');
151
+ const withOffset = addOffset(date); // Adds timezone offset
178
152
 
179
- // CSV operations
180
- const items = fromCsvString('apple,banana,cherry');
181
- // ['apple', 'banana', 'cherry']
153
+ // subtractOffset(input: string | Date | undefined | null): Date | undefined
154
+ const withoutOffset = subtractOffset(date); // Subtracts timezone offset
182
155
 
183
- toCsvString(['apple', 'banana', 'cherry']);
184
- // 'apple,banana,cherry'
156
+ // getDateRangeForMonth(year: number, month: number): {startDate: Date, endDate: Date}
157
+ const { startDate, endDate } = getDateRangeForMonth(2023, 0); // January 2023 (month 0-indexed)
185
158
  ```
186
159
 
187
- ### Testing Utilities
188
-
160
+ ### Date Utilities
189
161
  ```typescript
190
162
  import {
191
- arrangeActAssert,
192
- mockCalls
163
+ isValidDate,
164
+ parseBool
193
165
  } from '@onivoro/isomorphic-common';
194
166
 
195
- // Test structure helper
196
- const testCase = arrangeActAssert({
197
- arrange: () => ({ input: 'test data' }),
198
- act: (arranged) => processData(arranged.input),
199
- assert: (result) => expect(result).toBeTruthy()
200
- });
201
-
202
- // Mock function calls tracking
203
- const mockTracker = mockCalls();
204
- mockTracker.track('functionName', ['arg1', 'arg2']);
205
- mockTracker.getCalls('functionName'); // [['arg1', 'arg2']]
206
- ```
207
-
208
- ## API Reference
209
-
210
- ### String Functions
211
-
212
- #### Case Conversion
213
- - `camelCase(string)` - Convert to camelCase
214
- - `kebabCase(string)` - Convert to kebab-case
215
- - `snakeCase(string)` - Convert to snake_case
216
- - `upperFirst(string)` - Capitalize first letter
217
-
218
- #### String Utilities
219
- - `sanitizeFilename(filename)` - Remove invalid filename characters
220
- - `removeAlphaChars(string)` - Remove alphabetic characters
221
- - `words(string)` - Split string into words array
222
- - `toString(value)` - Convert value to string safely
223
-
224
- ### Array Functions
225
-
226
- #### Array Manipulation
227
- - `chunk<T>(array, numDivisions)` - Split array into chunks
228
- - `toUniqueArray<T>(array)` - Remove duplicate elements
229
- - `removeElementAtIndex<T>(array, index)` - Remove element by index
230
-
231
- #### Sorting Functions
232
- - `sortByName<T>(array)` - Sort objects by name property
233
- - `sortById<T>(array)` - Sort objects by id property
234
- - `sortByFullName<T>(array)` - Sort objects by full name
235
- - `sortByCreatedAt<T>(array)` - Sort objects by creation date
236
- - `sortNumbers(array)` - Sort numeric array
237
-
238
- ### Date/Time Functions
239
-
240
- #### Date Operations
241
- - `addOffset(date, days)` - Add days to date
242
- - `subtractOffset(date, days)` - Subtract days from date
243
- - `getDateRangeForMonth(year, month)` - Get month's date range
244
- - `getDateLastMonth()` - Get previous month's date
245
- - `splitDateRangeIntoDays(start, end)` - Split range into daily intervals
167
+ // isValidDate(dateString: string | Date): Date | undefined
168
+ const validDate = isValidDate('2023-01-15'); // Date object
169
+ const invalidDate = isValidDate('invalid'); // undefined
246
170
 
247
- #### Date Utilities
248
- - `isValidDate(date)` - Check if date is valid
249
- - `tryParseDate(string)` - Safely parse date string
250
- - `toCalendarDate(date)` - Convert to calendar format
251
- - `fromCalendarDate(string)` - Parse calendar date string
252
- - `useDate(date)` - React hook for date handling
171
+ // parseBool(asc: string | boolean | null | undefined): boolean
172
+ parseBool('true'); // true
173
+ parseBool('false'); // false
174
+ parseBool(true); // true
175
+ parseBool(null); // false
176
+ ```
253
177
 
254
- #### Time Constants
255
- - `MILLIS_PER_MINUTE` - Milliseconds in a minute
256
- - `MILLIS_PER_HOUR` - Milliseconds in an hour
257
- - `MILLIS_PER_DAY` - Milliseconds in a day
178
+ ## Financial Functions
258
179
 
259
- ### Financial Functions
180
+ ```typescript
181
+ import {
182
+ formatUsd,
183
+ money,
184
+ toDollarsAndCents,
185
+ round
186
+ } from '@onivoro/isomorphic-common';
260
187
 
261
- #### Money Operations
262
- - `money(amount)` - Convert dollars to cents
263
- - `toDollarsAndCents(cents)` - Convert cents to dollars/cents object
264
- - `formatUsd(amount)` - Format as USD currency
265
- - `round(number, precision)` - Round to decimal places
188
+ // formatUsd(rawAmount?: number | string): string
189
+ formatUsd(1234.56); // '$1,234.56'
190
+ formatUsd('1234.56'); // '$1,234.56'
191
+ formatUsd(); // '$0.00'
266
192
 
267
- ### Type Utilities
193
+ // money(rawValue: number | string): string | undefined
194
+ money(19.99); // '$19.99'
195
+ money('abc'); // undefined
268
196
 
269
- #### Interfaces
270
- - `ILookup<T>` - Key-value lookup interface
271
- - `IAccessToken` - Access token structure
272
- - `IEntityProvider<T>` - Entity provider interface
197
+ // toDollarsAndCents(input: string | number): string
198
+ toDollarsAndCents(19.99); // 'nineteen dollars and ninety-nine cents'
199
+ toDollarsAndCents(20); // 'twenty dollars'
273
200
 
274
- #### Type Helpers
275
- - `KeysOf<T>` - Extract keys of type T
276
- - `Createable<T>` - Type for creatable entities
277
- - `Nameable` - Type for entities with name property
278
- - `Company` - Company type definition
201
+ // round(numberToRound: number, scalingFactor: number): number
202
+ round(19.999, 100); // 20.00 (rounds to nearest cent)
203
+ round(19.994, 100); // 19.99
204
+ ```
279
205
 
280
- ### Data Transformation
206
+ ## Data Transformation
281
207
 
282
- #### Enum Utilities
283
- - `mapEnumToOptions(enum)` - Convert enum to option array
284
- - `mapEnumToArrayOfValues(enum)` - Convert enum to value array
285
- - `mapEnumToLookupArray(enum)` - Convert enum to lookup array
208
+ ### Enum Utilities
209
+ ```typescript
210
+ import {
211
+ mapEnumToOptions
212
+ } from '@onivoro/isomorphic-common';
286
213
 
287
- #### Object Utilities
288
- - `convertObjectToLiteral(object)` - Convert to literal object
289
- - `propertiesToArray(object)` - Convert properties to array
290
- - `mapEntitiesToOptions(entities, labelKey, valueKey)` - Convert entities to options
214
+ enum Status {
215
+ ACTIVE = 'active',
216
+ INACTIVE = 'inactive',
217
+ PENDING = 'pending'
218
+ }
291
219
 
292
- ### Validation Functions
220
+ // mapEnumToOptions<TEntity extends object>(enumeration: TEntity, includeBlank = true)
221
+ const options = mapEnumToOptions(Status);
222
+ // [{ display: '', value: '' }, { display: 'ACTIVE', value: 'active' }, ...]
293
223
 
294
- #### Data Validation
295
- - `parseBool(value)` - Parse boolean from various formats
296
- - `isSymbol(value)` - Check if value is symbol
297
- - `tryJsonParse(string)` - Safely parse JSON
298
- - `tryJsonStringify(object)` - Safely stringify JSON
224
+ const optionsNoBlank = mapEnumToOptions(Status, false);
225
+ // [{ display: 'ACTIVE', value: 'active' }, ...]
226
+ ```
299
227
 
300
- #### String Validation
301
- - `fromBooleanString(string)` - Convert string to boolean
302
- - `toBooleanString(boolean)` - Convert boolean to string
303
- - `fromCsvString(string)` - Parse CSV string
304
- - `toCsvString(array)` - Convert array to CSV
228
+ ### Entity Utilities
229
+ ```typescript
230
+ import { getUserFullName } from '@onivoro/isomorphic-common';
305
231
 
306
- ### Utility Functions
232
+ // getUserFullName(user: TNameable | undefined): string
233
+ const user = { firstName: 'John', lastName: 'Doe' };
234
+ getUserFullName(user); // 'John Doe'
235
+ getUserFullName(undefined); // 'undefined undefined'
236
+ ```
307
237
 
308
- #### General Utilities
309
- - `sleep(milliseconds)` - Async sleep function
310
- - `getTag(value)` - Get object type tag
311
- - `getUserFullName(user)` - Get user's full name
312
- - `toDecimalBase(number, base)` - Convert to decimal base
313
-
314
- #### Testing Helpers
315
- - `arrangeActAssert(config)` - Structure test cases
316
- - `mockCalls()` - Track mock function calls
238
+ ## JSON Utilities
317
239
 
318
- ### Constants
319
-
320
- #### Headers and Authentication
321
- - `API_ID_HEADER` - API ID header constant
322
- - `API_KEY_HEADER` - API key header constant
323
- - `AUTH_COOKIE_NAME` - Authentication cookie name
324
-
325
- #### Regular Expressions
326
- - `REGEXES` - Common regex patterns object
327
-
328
- ## Advanced Usage
240
+ ```typescript
241
+ import {
242
+ tryJsonParse,
243
+ tryJsonStringify
244
+ } from '@onivoro/isomorphic-common';
329
245
 
330
- ### Custom Type Guards
246
+ // tryJsonParse<T>(parseable: string | null | undefined): T | null
247
+ const parsed = tryJsonParse<{name: string}>('{"name":"John"}'); // {name: 'John'}
248
+ const failed = tryJsonParse('invalid json'); // null
331
249
 
332
- ```typescript
333
- import { isSymbol, isValidDate } from '@onivoro/isomorphic-common';
334
-
335
- function processValue(value: unknown) {
336
- if (isSymbol(value)) {
337
- return value.toString();
338
- }
339
-
340
- if (value instanceof Date && isValidDate(value)) {
341
- return value.toISOString();
342
- }
343
-
344
- return String(value);
345
- }
250
+ // tryJsonStringify<T>(object: T | null | undefined, fmtr?: any, spaces?: number): string | null
251
+ const json = tryJsonStringify({name: 'John'}); // '{"name":"John"}'
252
+ const formatted = tryJsonStringify({name: 'John'}, null, 2); // Pretty formatted JSON
346
253
  ```
347
254
 
348
- ### Complex Data Transformations
255
+ ## Utility Functions
349
256
 
350
257
  ```typescript
351
- import {
352
- chunk,
353
- mapEntitiesToOptions,
354
- sortByName,
355
- toUniqueArray
356
- } from '@onivoro/isomorphic-common';
258
+ import { sleep } from '@onivoro/isomorphic-common';
357
259
 
358
- function processUserData(users: User[]) {
359
- return chunk(
360
- toUniqueArray(
361
- sortByName(users)
362
- ),
363
- 10 // Process in batches of 10
364
- ).map(batch =>
365
- mapEntitiesToOptions(batch, 'fullName', 'id')
366
- );
367
- }
260
+ // sleep(milliseconds = 0): Promise<void>
261
+ await sleep(1000); // Wait 1 second
262
+ await sleep(); // Wait 0 milliseconds (next tick)
368
263
  ```
369
264
 
370
- ### Date Range Operations
265
+ ## Type Definitions
371
266
 
267
+ ### Interfaces
372
268
  ```typescript
373
269
  import {
374
- getDateRangeForMonth,
375
- splitDateRangeIntoDays,
376
- addOffset,
377
- subtractOffset
270
+ ILookup,
271
+ TNameable
378
272
  } from '@onivoro/isomorphic-common';
379
273
 
380
- function getMonthlyReportDates(year: number, month: number) {
381
- const { start, end } = getDateRangeForMonth(year, month);
382
-
383
- // Add buffer days
384
- const reportStart = subtractOffset(start, 1);
385
- const reportEnd = addOffset(end, 1);
386
-
387
- return splitDateRangeIntoDays(reportStart, reportEnd);
388
- }
274
+ // Lookup interface for key-value pairs
275
+ const lookup: ILookup<string, number> = {
276
+ display: 'Option 1',
277
+ value: 1
278
+ };
279
+
280
+ // Nameable type
281
+ const user: TNameable = {
282
+ firstName: 'John',
283
+ lastName: 'Doe'
284
+ };
389
285
  ```
390
286
 
391
287
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onivoro/isomorphic-common",
3
- "version": "24.0.0",
3
+ "version": "24.0.1",
4
4
  "type": "commonjs",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
package/tsconfig.lib.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
3
  "compilerOptions": {
4
- "declaration": true
4
+ "declaration": true,
5
+ "outDir": "../../../dist/out-tsc"
5
6
  },
6
7
  "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
7
8
  "include": ["src/**/*.ts"]