@teselagen/file-utils 0.0.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": ["../../.eslintrc.json"],
3
+ "ignorePatterns": ["!**/*"],
4
+ "overrides": [
5
+ {
6
+ "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7
+ "rules": {}
8
+ },
9
+ {
10
+ "files": ["*.ts", "*.tsx"],
11
+ "rules": {}
12
+ },
13
+ {
14
+ "files": ["*.js", "*.jsx"],
15
+ "rules": {}
16
+ }
17
+ ]
18
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,26 @@
1
+ # Changelog
2
+
3
+ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
+
5
+ ## [0.2.0](https://github.com/TeselaGen/tg-oss/compare/file-utils-0.1.0...file-utils-0.2.0) (2023-05-30)
6
+
7
+
8
+ ### Features
9
+
10
+ * more work on packaging up files ([67c8a69](https://github.com/TeselaGen/tg-oss/commit/67c8a6983b2ca772cc72700b4bf344b4adccf26d))
11
+
12
+ ## [0.2.0](https://github.com/TeselaGen/tg-oss/compare/file-utils-0.1.0...file-utils-0.2.0) (2023-05-30)
13
+
14
+
15
+ ### Features
16
+
17
+ * more work on packaging up files ([67c8a69](https://github.com/TeselaGen/tg-oss/commit/67c8a6983b2ca772cc72700b4bf344b4adccf26d))
18
+
19
+ ## 0.1.0 (2023-05-30)
20
+
21
+
22
+ ### Features
23
+
24
+ * more work adding more repos ([f320d76](https://github.com/TeselaGen/tg-oss/commit/f320d76a7a2e0db34d68d1a51803efa24f6831df))
25
+ * wip adding a bunch of repos to tg-oss ([6040094](https://github.com/TeselaGen/tg-oss/commit/60400941f0d7f72c02bf19b90896d9a35d32634d))
26
+ * wip setting up nx ([24a1952](https://github.com/TeselaGen/tg-oss/commit/24a1952fdbadc2c733223109d620cbc508c94a28))
package/jest.config.js ADDED
@@ -0,0 +1,10 @@
1
+ /* eslint-disable */
2
+ module.exports = {
3
+ displayName: 'file-utils',
4
+ preset: '../../jest.preset.js',
5
+ transform: {
6
+ '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
7
+ },
8
+ moduleFileExtensions: ['ts', 'js', 'html'],
9
+ coverageDirectory: '../../coverage/packages/file-utils',
10
+ };
package/package.json CHANGED
@@ -1,13 +1,11 @@
1
1
  {
2
2
  "name": "@teselagen/file-utils",
3
- "version": "0.0.3",
4
- "type": "module",
3
+ "version": "0.2.0",
4
+ "type": "commonjs",
5
5
  "dependencies": {
6
6
  "bluebird": "^3.7.2",
7
7
  "jszip": "^3.10.1",
8
8
  "lodash": "^4.17.21",
9
9
  "papaparse": "^5.4.1"
10
- },
11
- "module": "index.js",
12
- "main": "index.js"
10
+ }
13
11
  }
package/project.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "file-utils",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "packages/file-utils/src",
5
+ "projectType": "library",
6
+ "targets": {
7
+ "version": {
8
+ "executor": "@jscutlery/semver:version",
9
+ "options": {
10
+ "preset": "conventional"
11
+ }
12
+ },
13
+ "build": {
14
+ "executor": "@nx/esbuild:esbuild",
15
+ "outputs": ["{options.outputPath}"],
16
+ "options": {
17
+ "outputPath": "dist/packages/file-utils",
18
+ "main": "packages/file-utils/src/index.js",
19
+ "tsConfig": "packages/file-utils/tsconfig.lib.json",
20
+ "assets": ["packages/file-utils/*.md"],
21
+ "generatePackageJson": true
22
+ }
23
+ },
24
+ "publish": {
25
+ "command": "node tools/scripts/publish.mjs file-utils {args.ver} {args.tag}",
26
+ "dependsOn": ["build"]
27
+ },
28
+ "lint": {
29
+ "executor": "@nx/linter:eslint",
30
+ "outputs": ["{options.outputFile}"],
31
+ "options": {
32
+ "lintFilePatterns": ["packages/file-utils/**/*.js"]
33
+ }
34
+ },
35
+ "test": {
36
+ "executor": "@nx/jest:jest",
37
+ "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
38
+ "options": {
39
+ "jestConfig": "packages/file-utils/jest.config.js",
40
+ "passWithNoTests": true
41
+ },
42
+ "configurations": {
43
+ "ci": {
44
+ "ci": true,
45
+ "codeCoverage": true
46
+ }
47
+ }
48
+ }
49
+ },
50
+ "tags": []
51
+ }
@@ -1,40 +1,45 @@
1
- // packages/file-utils/src/lib/file-utils.js
1
+ /* Copyright (C) 2018 TeselaGen Biotechnology, Inc. */
2
2
  import { camelCase, flatMap, remove, startsWith, snakeCase } from "lodash";
3
3
  import { loadAsync } from "jszip";
4
- import Promise2 from "bluebird";
4
+ import Promise from "bluebird";
5
5
  import { parse, unparse } from "papaparse";
6
- var logDebug = (...args) => {
6
+
7
+ const logDebug = (...args) => {
7
8
  if (process.env.DEBUG_CSV_PARSING) {
9
+ // eslint-disable-next-line no-console
8
10
  console.log(...args);
9
11
  }
10
12
  };
11
- var allowedCsvFileTypes = [".csv", ".txt", ".xlsx"];
12
- var isZipFile = (file) => {
13
+
14
+ export const allowedCsvFileTypes = [".csv", ".txt", ".xlsx"];
15
+
16
+ export const isZipFile = file => {
13
17
  const type = file.mimetype || file.type;
14
18
  return type === "application/zip" || type === "application/x-zip-compressed";
15
19
  };
16
- var getExt = (file) => file.name.split(".").pop();
17
- var isExcelFile = (file) => getExt(file) === "xlsx";
18
- var isCsvFile = (file) => getExt(file) === "csv";
19
- var isTextFile = (file) => ["text", "txt"].includes(getExt(file));
20
- var isCsvOrExcelFile = (file) => isCsvFile(file) || isExcelFile(file);
21
- var extractZipFiles = async (allFiles) => {
22
- if (!Array.isArray(allFiles))
23
- allFiles = [allFiles];
20
+
21
+ export const getExt = file => file.name.split(".").pop();
22
+ export const isExcelFile = file => getExt(file) === "xlsx";
23
+ export const isCsvFile = file => getExt(file) === "csv";
24
+ export const isTextFile = file => ["text", "txt"].includes(getExt(file));
25
+
26
+ export const isCsvOrExcelFile = file => isCsvFile(file) || isExcelFile(file);
27
+
28
+ export const extractZipFiles = async allFiles => {
29
+ if (!Array.isArray(allFiles)) allFiles = [allFiles];
30
+ // make a copy so we don't mutate the form value
24
31
  allFiles = [...allFiles];
25
32
  const zipFiles = remove(allFiles, isZipFile);
26
- if (!zipFiles.length)
27
- return allFiles;
33
+ if (!zipFiles.length) return allFiles;
28
34
  const zipFilesArray = Array.isArray(zipFiles) ? zipFiles : [zipFiles];
29
- const parsedZips = await Promise2.map(
30
- zipFilesArray,
31
- (file) => loadAsync(file instanceof Blob ? file : file.originFileObj)
35
+ const parsedZips = await Promise.map(zipFilesArray, file =>
36
+ loadAsync(file instanceof Blob ? file : file.originFileObj)
32
37
  );
33
- const zippedFiles = flatMap(
34
- parsedZips,
35
- (zip) => Object.keys(zip.files).map((key) => zip.files[key])
38
+ const zippedFiles = flatMap(parsedZips, zip =>
39
+ Object.keys(zip.files).map(key => zip.files[key])
36
40
  );
37
- const unzippedFiles = await Promise2.map(zippedFiles, (file) => {
41
+ const unzippedFiles = await Promise.map(zippedFiles, file => {
42
+ // converts the compressed file to a string of its contents
38
43
  return file.async("blob").then(function(fileData) {
39
44
  const newFileObj = new File([fileData], file.name);
40
45
  return {
@@ -47,32 +52,38 @@ var extractZipFiles = async (allFiles) => {
47
52
  if (unzippedFiles.length) {
48
53
  return allFiles.concat(
49
54
  unzippedFiles.filter(
50
- ({ name, originFileObj }) => !name.includes("__MACOSX") && !name.includes(".DS_Store") && originFileObj.size !== 0
55
+ ({ name, originFileObj }) =>
56
+ !name.includes("__MACOSX") &&
57
+ !name.includes(".DS_Store") &&
58
+ originFileObj.size !== 0
51
59
  )
52
60
  );
53
61
  } else {
54
62
  return allFiles;
55
63
  }
56
64
  };
57
- var defaultCsvParserOptions = {
65
+
66
+ const defaultCsvParserOptions = {
58
67
  header: true,
59
68
  skipEmptyLines: "greedy",
60
69
  trimHeaders: true
61
70
  };
62
- var setupCsvParserOptions = (parserOptions = {}) => {
71
+ export const setupCsvParserOptions = (parserOptions = {}) => {
63
72
  const {
64
73
  camelCaseHeaders = false,
65
74
  lowerCaseHeaders = false,
66
75
  ...rest
67
76
  } = parserOptions;
77
+
68
78
  const papaParseOpts = { ...rest };
69
79
  if (camelCaseHeaders) {
70
80
  logDebug("[CSV-PARSER] camelCasing headers");
71
- papaParseOpts.transformHeader = (header) => {
81
+ papaParseOpts.transformHeader = header => {
72
82
  let transHeader = header;
73
83
  if (!startsWith(header.trim(), "ext-")) {
74
84
  transHeader = camelCase(header);
75
85
  }
86
+
76
87
  if (transHeader) {
77
88
  logDebug(
78
89
  `[CSV-PARSER] Transformed header from: ${header} to: ${transHeader}`
@@ -81,14 +92,16 @@ var setupCsvParserOptions = (parserOptions = {}) => {
81
92
  } else {
82
93
  logDebug(`[CSV-PARSER] Not transforming header: ${header}`);
83
94
  }
95
+
84
96
  return transHeader;
85
97
  };
86
98
  } else if (lowerCaseHeaders) {
87
- papaParseOpts.transformHeader = (header) => {
99
+ papaParseOpts.transformHeader = header => {
88
100
  let transHeader = header;
89
101
  if (!startsWith(header, "ext-")) {
90
102
  transHeader = header.toLowerCase();
91
103
  }
104
+
92
105
  if (transHeader) {
93
106
  logDebug(
94
107
  `[CSV-PARSER] Transformed header from: ${header} to: ${transHeader}`
@@ -97,30 +110,35 @@ var setupCsvParserOptions = (parserOptions = {}) => {
97
110
  } else {
98
111
  logDebug(`[CSV-PARSER] Not transforming header: ${header}`);
99
112
  }
113
+
100
114
  return transHeader;
101
115
  };
102
116
  }
117
+
103
118
  return papaParseOpts;
104
119
  };
105
- var normalizeCsvHeaderHelper = (h) => snakeCase(h.toUpperCase()).toUpperCase();
106
- function normalizeCsvHeader(header) {
120
+
121
+ const normalizeCsvHeaderHelper = h => snakeCase(h.toUpperCase()).toUpperCase();
122
+
123
+ export function normalizeCsvHeader(header) {
107
124
  if (header.startsWith("ext-") || header.startsWith("EXT-")) {
108
125
  return header;
109
126
  }
110
127
  return normalizeCsvHeaderHelper(header);
111
128
  }
112
- var parseCsvFile = (csvFile, parserOptions = {}) => {
113
- return new Promise2((resolve, reject) => {
129
+
130
+ export const parseCsvFile = (csvFile, parserOptions = {}) => {
131
+ return new Promise((resolve, reject) => {
114
132
  const opts = {
115
133
  ...defaultCsvParserOptions,
116
134
  ...setupCsvParserOptions(parserOptions),
117
- complete: (results) => {
135
+ complete: results => {
118
136
  if (results && results.errors && results.errors.length) {
119
137
  return reject("Error in csv: " + JSON.stringify(results.errors));
120
138
  }
121
139
  resolve(results);
122
140
  },
123
- error: (error) => {
141
+ error: error => {
124
142
  reject(error);
125
143
  }
126
144
  };
@@ -128,11 +146,28 @@ var parseCsvFile = (csvFile, parserOptions = {}) => {
128
146
  parse(csvFile.originFileObj, opts);
129
147
  });
130
148
  };
131
- var jsonToCsv = (jsonData, options = {}) => {
149
+
150
+ /**
151
+ * Gets a properly formatted json object into s csv string
152
+ * https://www.papaparse.com/docs#json-to-csv
153
+ * const options = {
154
+ quotes: false, //or array of booleans
155
+ quoteChar: '"',
156
+ escapeChar: '"',
157
+ delimiter: ",",
158
+ header: true,
159
+ newline: "\r\n",
160
+ skipEmptyLines: false, //other option is 'greedy', meaning skip delimiters, quotes, and whitespace.
161
+ columns: null //or array of strings
162
+ }
163
+ * @returns csv as string
164
+ */
165
+ export const jsonToCsv = (jsonData, options = {}) => {
132
166
  const csv = unparse(jsonData, options);
133
167
  return csv;
134
168
  };
135
- var parseCsvString = (csvString, parserOptions = {}) => {
169
+
170
+ export const parseCsvString = (csvString, parserOptions = {}) => {
136
171
  const opts = {
137
172
  ...defaultCsvParserOptions,
138
173
  ...setupCsvParserOptions(parserOptions)
@@ -140,25 +175,27 @@ var parseCsvString = (csvString, parserOptions = {}) => {
140
175
  logDebug(`[CSV-PARSER] parseCsvString opts:`, opts);
141
176
  return parse(csvString, opts);
142
177
  };
143
- async function parseCsvOrExcelFile(fileOrFiles, { csvParserOptions } = {}) {
178
+
179
+ export async function parseCsvOrExcelFile(
180
+ fileOrFiles,
181
+ { csvParserOptions } = {}
182
+ ) {
144
183
  let csvFile, excelFile, txtFile;
145
184
  if (Array.isArray(fileOrFiles)) {
146
185
  csvFile = fileOrFiles.find(isCsvFile);
147
186
  excelFile = fileOrFiles.find(isExcelFile);
148
187
  txtFile = fileOrFiles.find(isTextFile);
149
188
  } else {
150
- if (isExcelFile(fileOrFiles))
151
- excelFile = fileOrFiles;
152
- else if (isCsvFile(fileOrFiles))
153
- csvFile = fileOrFiles;
154
- else if (isTextFile(fileOrFiles))
155
- txtFile = fileOrFiles;
189
+ if (isExcelFile(fileOrFiles)) excelFile = fileOrFiles;
190
+ else if (isCsvFile(fileOrFiles)) csvFile = fileOrFiles;
191
+ else if (isTextFile(fileOrFiles)) txtFile = fileOrFiles;
156
192
  }
157
193
  if (!csvFile && !excelFile && !txtFile) {
158
194
  throw new Error("No csv or excel files found");
159
195
  }
160
- if (!csvFile && !excelFile)
161
- csvFile = txtFile;
196
+
197
+ if (!csvFile && !excelFile) csvFile = txtFile;
198
+
162
199
  if (!csvFile && excelFile && window.parseExcelToCsv) {
163
200
  csvFile = await window.parseExcelToCsv(
164
201
  excelFile.originFileObj || excelFile
@@ -173,8 +210,13 @@ async function parseCsvOrExcelFile(fileOrFiles, { csvParserOptions } = {}) {
173
210
  parsedCsv.originalFile = csvFile;
174
211
  return parsedCsv;
175
212
  }
176
- var validateCSVRequiredHeaders = (fields, requiredHeaders, filename) => {
177
- const missingRequiredHeaders = requiredHeaders.filter((field) => {
213
+
214
+ export const validateCSVRequiredHeaders = (
215
+ fields,
216
+ requiredHeaders,
217
+ filename
218
+ ) => {
219
+ const missingRequiredHeaders = requiredHeaders.filter(field => {
178
220
  return !fields.includes(field);
179
221
  });
180
222
  if (missingRequiredHeaders.length) {
@@ -184,64 +226,91 @@ var validateCSVRequiredHeaders = (fields, requiredHeaders, filename) => {
184
226
  )})`;
185
227
  }
186
228
  };
187
- var validateCSVRow = (row, requiredHeaders, index) => {
188
- const missingRequiredFields = requiredHeaders.filter((field) => !row[field]);
229
+
230
+ export const validateCSVRow = (row, requiredHeaders, index) => {
231
+ const missingRequiredFields = requiredHeaders.filter(field => !row[field]);
189
232
  if (missingRequiredFields.length) {
190
233
  if (missingRequiredFields.length === 1) {
191
- return `Row ${index + 1} is missing the required field "${missingRequiredFields[0]}"`;
234
+ return `Row ${index + 1} is missing the required field "${
235
+ missingRequiredFields[0]
236
+ }"`;
192
237
  } else {
193
- return `Row ${index + 1} is missing these required fields: ${missingRequiredFields.join(
238
+ return `Row ${index +
239
+ 1} is missing these required fields: ${missingRequiredFields.join(
194
240
  ", "
195
241
  )}`;
196
242
  }
197
243
  }
198
244
  };
199
- var cleanCommaSeparatedCell = (cellData) => (cellData || "").split(",").map((n) => n.trim()).filter((n) => n);
200
- var cleanCsvExport = (rows) => {
245
+
246
+ export const cleanCommaSeparatedCell = cellData =>
247
+ (cellData || "")
248
+ .split(",")
249
+ .map(n => n.trim())
250
+ .filter(n => n);
251
+
252
+ /**
253
+ * Because the csv rows might not have the same header keys in some cases (extended properties)
254
+ * this function will make sure that each row will have all headers so that the export
255
+ * does not drop fields
256
+ * @param {*} rows
257
+ */
258
+ export const cleanCsvExport = rows => {
201
259
  const allHeaders = [];
202
- rows.forEach((row) => {
203
- Object.keys(row).forEach((header) => {
260
+ rows.forEach(row => {
261
+ Object.keys(row).forEach(header => {
204
262
  if (!allHeaders.includes(header)) {
205
263
  allHeaders.push(header);
206
264
  }
207
265
  });
208
266
  });
209
- rows.forEach((row) => {
210
- allHeaders.forEach((header) => {
267
+ rows.forEach(row => {
268
+ allHeaders.forEach(header => {
211
269
  row[header] = row[header] || "";
212
270
  });
213
271
  });
214
272
  return rows;
215
273
  };
216
- var filterFilesInZip = async (file, accepted) => {
274
+
275
+ export const filterFilesInZip = async (file, accepted) => {
217
276
  const zipExtracted = await extractZipFiles(file);
218
277
  const acceptedFiles = [];
219
278
  for (const extFile of zipExtracted) {
220
279
  const extension = "." + getExt(extFile);
221
- if (accepted.some((ext) => ext === extension)) {
280
+ if (accepted.some(ext => ext === extension)) {
222
281
  acceptedFiles.push(extFile);
223
282
  }
224
283
  }
284
+
225
285
  if (acceptedFiles.length && acceptedFiles.length < zipExtracted.length)
226
286
  window.toastr.warning("Some files don't have the proper file extension.");
287
+
227
288
  if (!acceptedFiles.length)
228
289
  window.toastr.warning("No files with the proper extension were found.");
290
+
229
291
  return acceptedFiles;
230
292
  };
231
- function removeExt(filename) {
293
+
294
+ export function removeExt(filename) {
232
295
  if (filename && filename.includes(".")) {
233
- return filename.split(".").slice(0, -1).join(".");
296
+ return filename
297
+ .split(".")
298
+ .slice(0, -1)
299
+ .join(".");
234
300
  } else {
235
301
  return filename;
236
302
  }
237
303
  }
238
- async function uploadAndProcessFiles(files = []) {
239
- if (!files.length)
240
- return null;
304
+
305
+ export async function uploadAndProcessFiles(files = []) {
306
+ if (!files.length) return null;
307
+
241
308
  const formData = new FormData();
242
309
  files.forEach(({ originFileObj }) => formData.append("file", originFileObj));
310
+
243
311
  const response = await window.api.post("/user_uploads/", formData);
244
- return response.data.map((d) => ({
312
+
313
+ return response.data.map(d => ({
245
314
  encoding: d.encoding,
246
315
  mimetype: d.mimetype,
247
316
  originalname: d.originalname,
@@ -249,7 +318,8 @@ async function uploadAndProcessFiles(files = []) {
249
318
  size: d.size
250
319
  }));
251
320
  }
252
- async function encodeFilesForRequest(files) {
321
+
322
+ export async function encodeFilesForRequest(files) {
253
323
  const encodedFiles = [];
254
324
  for (const file of files) {
255
325
  const encoded = await fileToBase64(file.originalFileObj);
@@ -262,36 +332,16 @@ async function encodeFilesForRequest(files) {
262
332
  }
263
333
  return encodedFiles;
264
334
  }
265
- var fileToBase64 = (file) => {
266
- return new Promise2((resolve) => {
335
+
336
+ const fileToBase64 = file => {
337
+ return new Promise(resolve => {
267
338
  const reader = new FileReader();
339
+ // Read file content on file loaded event
268
340
  reader.onload = function(event) {
269
341
  resolve(event.target.result);
270
342
  };
343
+
344
+ // Convert data to base64
271
345
  reader.readAsDataURL(file);
272
346
  });
273
347
  };
274
- export {
275
- allowedCsvFileTypes,
276
- cleanCommaSeparatedCell,
277
- cleanCsvExport,
278
- encodeFilesForRequest,
279
- extractZipFiles,
280
- filterFilesInZip,
281
- getExt,
282
- isCsvFile,
283
- isCsvOrExcelFile,
284
- isExcelFile,
285
- isTextFile,
286
- isZipFile,
287
- jsonToCsv,
288
- normalizeCsvHeader,
289
- parseCsvFile,
290
- parseCsvOrExcelFile,
291
- parseCsvString,
292
- removeExt,
293
- setupCsvParserOptions,
294
- uploadAndProcessFiles,
295
- validateCSVRequiredHeaders,
296
- validateCSVRow
297
- };
@@ -0,0 +1,6 @@
1
+ import { fileUtils } from './file-utils';
2
+ describe('fileUtils', () => {
3
+ it('should work', () => {
4
+ expect(fileUtils()).toEqual('file-utils');
5
+ });
6
+ });
package/src/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './file-utils';
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "module": "commonjs",
5
+ "allowJs": true,
6
+ "forceConsistentCasingInFileNames": true,
7
+ "strict": true,
8
+ "noImplicitOverride": true,
9
+ "noPropertyAccessFromIndexSignature": true,
10
+ "noImplicitReturns": true,
11
+ "noFallthroughCasesInSwitch": true
12
+ },
13
+ "files": [],
14
+ "include": [],
15
+ "references": [
16
+ {
17
+ "path": "./tsconfig.lib.json"
18
+ },
19
+ {
20
+ "path": "./tsconfig.spec.json"
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "declaration": true,
6
+ "types": ["node"]
7
+ },
8
+ "include": ["src/**/*.ts", "src/**/*.js"],
9
+ "exclude": [
10
+ "jest.config.ts",
11
+ "src/**/*.spec.ts",
12
+ "src/**/*.test.ts",
13
+ "src/**/*.spec.js",
14
+ "src/**/*.test.js"
15
+ ]
16
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "../../dist/out-tsc",
5
+ "module": "commonjs",
6
+ "types": ["jest", "node"]
7
+ },
8
+ "include": [
9
+ "jest.config.ts",
10
+ "src/**/*.test.ts",
11
+ "src/**/*.spec.ts",
12
+ "src/**/*.d.ts"
13
+ ]
14
+ }