typeshi 1.7.17 → 1.7.19

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,5 +1,5 @@
1
1
  import { StringCaseOptions, StringPadOptions, StringStripOptions, CleanStringOptions } from "../regex";
2
- import { FileData, FileExtension } from "./types/Io";
2
+ import { DirectoryFileOptions, FileData, FileExtension } from "./types/Io";
3
3
  import { DelimiterCharacterEnum } from "./types";
4
4
  /** checks if `pathString (value)` points to an existing directory */
5
5
  export declare function isDirectory(value: any): value is string;
@@ -124,8 +124,8 @@ export declare function handleFileArgument(arg1: string | FileData | Record<stri
124
124
  * - `if true`, returned array elements are of form: `path.basename(file)`
125
125
  * - `if false`, returned array elements are of form: `path.join(dir, file)`
126
126
  * @param targetExtensions `string[] (optional)` - array of file extensions to filter files by.
127
- * - `If` not provided, all files in the directory will be returned.
128
- * - `If` provided, only files with extensions matching the array will be returned.
127
+ * - `if undefined`, all files in the directory will be returned.
128
+ * - `if defined`, only files with extensions matching the array will be returned.
129
129
  * @returns **`targetFiles`** `string[]` array of file paths
130
130
  */
131
131
  export declare function getDirectoryFiles(dir: string, basenameOnly: boolean, ...targetExtensions: string[]): string[];
@@ -133,11 +133,28 @@ export declare function getDirectoryFiles(dir: string, basenameOnly: boolean, ..
133
133
  * `sync`
134
134
  * @param dir `string` path to target directory
135
135
  * @param targetExtensions `string[] (optional)` - array of file extensions to filter files by.
136
- * - `If` not provided, all files in the directory will be returned.
137
- * - `If` provided, only files with extensions matching the array will be returned.
136
+ * - `if undefined`, all files in the directory will be returned.
137
+ * - `if defined`, only files with extensions matching the array will be returned.
138
138
  * @returns **`targetFiles`** `string[]` array of `full` file paths
139
139
  */
140
140
  export declare function getDirectoryFiles(dir: string, ...targetExtensions: string[]): string[];
141
+ /**
142
+ * `sync`
143
+ * @param dir `string` path to target directory
144
+ * @param options {@link DirectoryFileOptions}
145
+ * = `{ basenameOnly?: boolean, recursive?: boolean, targetExtensions?: string[] }`
146
+ * @param options.basenameOnly `boolean (optional)` `default` = `false`
147
+ * - `if true`, returned array elements are of form: `path.basename(file)`
148
+ * - `if false`, returned array elements are of form: `path.join(dir, file)`
149
+ * @param options.recursive `boolean (optional)` `default` = `false`
150
+ * - `true` - get files from `dir` and all of its subdirectories
151
+ * - `false` - only get files from `dir` (i.e. direct descendants of `dir`)
152
+ * @param options.targetExtensions `string[] (optional)` - array of file extensions to filter files by.
153
+ * - `if undefined`, all files in the directory will be returned.
154
+ * - `if defined`, only files with extensions matching the array will be returned.
155
+ * @returns **`targetFiles`** `string[]` array of file paths
156
+ */
157
+ export declare function getDirectoryFiles(dir: string, options: DirectoryFileOptions): string[];
141
158
  /**
142
159
  * @param dataSource `string | FileData | Record<string, any>[]`
143
160
  * @param keyColumn `string`
@@ -573,23 +573,29 @@ async function handleFileArgument(arg1, invocationSource, requiredHeaders = [],
573
573
  /**
574
574
  * `sync`
575
575
  * @param dir `string` path to target directory
576
- * @param arg2 `boolean (optional)` `default` = `false`
576
+ * @param arg2 `boolean (optional)` (`basenameOnly`) `default` = `false`
577
577
  * - `if true`, returned array elements are of form: `path.basename(file)`
578
578
  * - `if false`, returned array elements are of form: `path.join(dir, file)`
579
579
  * @param targetExtensions `string[] (optional)` - array of file extensions to filter files by.
580
- * - `If` not provided, all files in the directory will be returned.
581
- * - `If` provided, only files with extensions matching the array will be returned.
580
+ * - `if undefined`, all files in the directory will be returned.
581
+ * - `if defined` provided, only files with extensions matching the array will be returned.
582
582
  * @returns **`targetFiles`** `string[]` array of file paths
583
583
  */
584
584
  function getDirectoryFiles(dir, arg2, ...targetExtensions) {
585
585
  const source = (0, logging_1.getSourceString)(__filename, getDirectoryFiles.name);
586
586
  let basenameOnly = false;
587
+ let recursive = false;
587
588
  if ((0, typeValidation_1.isBoolean)(arg2)) {
588
589
  basenameOnly = arg2;
589
590
  }
590
591
  else if ((0, typeValidation_1.isNonEmptyString)(arg2)) {
591
592
  targetExtensions = [arg2, ...targetExtensions];
592
593
  }
594
+ else if ((0, types_1.isDirectoryFileOptions)(arg2)) {
595
+ basenameOnly = arg2.basenameOnly ?? basenameOnly;
596
+ targetExtensions = arg2.targetExtensions ?? [];
597
+ recursive = arg2.recursive ?? false;
598
+ }
593
599
  const targetFiles = [];
594
600
  try {
595
601
  validate.existingDirectoryArgument(source, { dir });
@@ -601,11 +607,23 @@ function getDirectoryFiles(dir, arg2, ...targetExtensions) {
601
607
  targetExtensions[i] = `.${ext}`;
602
608
  }
603
609
  }
604
- targetFiles.push(...fs_1.default.readdirSync(dir)
610
+ const dirContent = fs_1.default.readdirSync(dir);
611
+ targetFiles.push(...dirContent
605
612
  .filter(f => (0, typeValidation_1.isNonEmptyArray)(targetExtensions)
606
613
  ? (0, regex_1.stringEndsWithAnyOf)(f, targetExtensions, regex_1.RegExpFlagsEnum.IGNORE_CASE)
607
- : true // get all files in dir, regardless of extension
614
+ : fs_1.default.statSync(node_path_1.default.join(dir, f)).isFile() // get all files in dir, regardless of extension
608
615
  ).map(f => basenameOnly ? f : node_path_1.default.join(dir, f)));
616
+ if (recursive) {
617
+ const childDirs = dirContent
618
+ .filter(c => isDirectory(node_path_1.default.join(dir, c)))
619
+ .map(c => node_path_1.default.join(dir, c));
620
+ for (let childDir of childDirs) {
621
+ targetFiles.push(...getDirectoryFiles(childDir, {
622
+ basenameOnly, recursive, targetExtensions
623
+ }));
624
+ }
625
+ }
626
+ return targetFiles;
609
627
  }
610
628
  catch (error) {
611
629
  config_1.typeshiLogger.error([`${source} Error retrieving directory files, returning empty array`,
@@ -616,7 +634,6 @@ function getDirectoryFiles(dir, arg2, ...targetExtensions) {
616
634
  ].join(config_1.INDENT_LOG_LINE));
617
635
  return [];
618
636
  }
619
- return targetFiles;
620
637
  }
621
638
  /**
622
639
  * @param dataSource `string | FileData | Record<string, any>[]`
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file src/utils/io/types/typeGuards.ts
3
3
  */
4
- import { FileData, NodeLeaves, NodeStructure, RowDictionary, RowSourceMetaData, WriteJsonOptions } from "..";
4
+ import { FileData, NodeLeaves, NodeStructure, DirectoryFileOptions, RowDictionary, RowSourceMetaData, WriteJsonOptions } from ".";
5
5
  /**
6
6
  * @param value `any`
7
7
  * @returns **`isRowSourceMetaData`** `boolean`
@@ -29,3 +29,4 @@ export declare function isWriteJsonOptions(value: any): value is WriteJsonOption
29
29
  * - **`false`** `otherwise`.
30
30
  */
31
31
  export declare function isFileData(value: any): value is FileData;
32
+ export declare function isDirectoryFileOptions(value: unknown): value is DirectoryFileOptions;
@@ -9,6 +9,7 @@ exports.isNodeStructure = isNodeStructure;
9
9
  exports.isNodeLeaves = isNodeLeaves;
10
10
  exports.isWriteJsonOptions = isWriteJsonOptions;
11
11
  exports.isFileData = isFileData;
12
+ exports.isDirectoryFileOptions = isDirectoryFileOptions;
12
13
  const typeValidation_1 = require("../../typeValidation");
13
14
  /**
14
15
  * @param value `any`
@@ -36,26 +37,21 @@ function isRowDictionary(value) {
36
37
  && typeof value[key] === 'object' && !Array.isArray(value[key])));
37
38
  }
38
39
  function isNodeStructure(value) {
39
- return (value && typeof value === 'object'
40
- && !Array.isArray(value)
41
- && Object.keys(value).length > 0
42
- && Object.entries(value).every(([key, value]) => typeof key === 'string'
43
- && (isNodeStructure(value) || isNodeLeaves(value))));
40
+ const candidate = value;
41
+ return ((0, typeValidation_1.isObject)(candidate)
42
+ && Object.entries(candidate).every(([k, v]) => (0, typeValidation_1.isNonEmptyString)(k) && (isNodeLeaves(v) || isNodeStructure(v))));
44
43
  }
45
44
  function isNodeLeaves(value) {
46
45
  return ((Array.isArray(value) && value.every(v => typeof v === 'number'))
47
46
  || isRowDictionary(value));
48
47
  }
49
48
  function isWriteJsonOptions(value) {
50
- return (value && typeof value === 'object'
51
- && !Array.isArray(value)
52
- && value.data !== undefined
53
- && (typeof value.data === 'object' || typeof value.data === 'string')
54
- && (0, typeValidation_1.isNonEmptyString)(value.filePath)
55
- && (value.indent === undefined
56
- || (typeof value.indent === 'number' && value.indent >= 0))
57
- && (value.enableOverwrite === undefined
58
- || typeof value.enableOverwrite === 'boolean'));
49
+ const candidate = value;
50
+ return ((0, typeValidation_1.isObject)(candidate)
51
+ && (typeof candidate.data === 'string' || (0, typeValidation_1.isObject)(candidate.data))
52
+ && (0, typeValidation_1.isNonEmptyString)(candidate.filePath)
53
+ && typeValidation_1.isUndefinedOr.positiveInteger(candidate.indent)
54
+ && typeValidation_1.isUndefinedOr.boolean(candidate.enableOverwrite));
59
55
  }
60
56
  /**
61
57
  * @consideration `FILE_NAME_WITH_EXTENSION_PATTERN = /^[^/\\:*?"<>|]+(\.[^/\\:*?"<>|]+)$/`
@@ -67,9 +63,15 @@ function isWriteJsonOptions(value) {
67
63
  * - **`false`** `otherwise`.
68
64
  */
69
65
  function isFileData(value) {
70
- return (value && typeof value === 'object'
71
- && (0, typeValidation_1.hasKeys)(value, ['fileName', 'fileContent'])
72
- && (0, typeValidation_1.isNonEmptyString)(value.fileName)
73
- // && fileNamePattern.test(value.fileName)
74
- && (0, typeValidation_1.isNonEmptyString)(value.fileContent));
66
+ const candidate = value;
67
+ return ((0, typeValidation_1.isObject)(candidate)
68
+ && (0, typeValidation_1.isNonEmptyString)(candidate.fileName)
69
+ && (0, typeValidation_1.isNonEmptyString)(candidate.fileContent));
70
+ }
71
+ function isDirectoryFileOptions(value) {
72
+ const candidate = value;
73
+ return ((0, typeValidation_1.isObject)(candidate, false)
74
+ && typeValidation_1.isOptional.stringArray(candidate.targetExtensions)
75
+ && typeValidation_1.isOptional.boolean(candidate.basenameOnly)
76
+ && typeValidation_1.isOptional.boolean(candidate.recursive));
75
77
  }
@@ -51,3 +51,25 @@ export type ParseOneToManyOptions = {
51
51
  * common file extensions handled as input/output
52
52
  */
53
53
  export type FileExtension = '.csv' | '.tsv' | '.txt' | '.json' | '.xlsx' | '.xls' | '.xml' | '.yaml' | '.yml';
54
+ /**
55
+ * @interface **`DirectoryFileOptions`** `getDirectoryFiles(parentDir: string, options: DirectoryFileOptions)`
56
+ */
57
+ export interface DirectoryFileOptions {
58
+ /**
59
+ * - `true` - returned array elements are of form: `path.basename(file)`
60
+ * - `false` - returned array elements are of form: `path.join(dir, file)` (i.e. complete file paths)
61
+ * */
62
+ basenameOnly?: boolean;
63
+ /**
64
+ * `default` = `false`
65
+ * - `true` - get files in the `parentDir` and all of its subdirectories
66
+ * - `false` - only get files in the `parentDir`
67
+ * */
68
+ recursive?: boolean;
69
+ /**
70
+ * `(optional)` - array of file extensions to filter files by.
71
+ * - `If` not provided, all files in the directory will be returned.
72
+ * - `If` provided, only files with extensions matching those in the array will be returned.
73
+ * */
74
+ targetExtensions?: string[];
75
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "typeshi",
3
- "version": "1.7.17",
3
+ "version": "1.7.19",
4
4
  "description": "TypeScript utility modules",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",