my-gadgetry 1.1.2 → 1.2.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.
@@ -1,9 +1,18 @@
1
1
  export interface Options {
2
- include: string[];
3
- exclude: string[];
2
+ include?: string[];
3
+ exclude?: string[];
4
+ depth?: number;
5
+ startDir?: string;
4
6
  }
5
7
  export declare const OPTIONS: {
6
8
  include: never[];
7
9
  exclude: never[];
10
+ depth: number;
8
11
  };
9
- export declare const getAllFiles: (dir: string, _files?: string[], { include, exclude }?: Options) => string[];
12
+ export interface Stacks {
13
+ files: string[];
14
+ depth: number;
15
+ }
16
+ export declare const getDepth: (path: string) => number;
17
+ export declare const isShallow: (from: string, to: string, depth: number) => boolean;
18
+ export declare const getAllFiles: (startDir: string, _options?: Options) => string[];
package/dist/_core/fs.js CHANGED
@@ -1,24 +1,49 @@
1
1
  import { statSync, readdirSync } from 'fs';
2
+ import { relative } from 'path';
2
3
  import { minimatch } from 'minimatch';
3
4
  export const OPTIONS = {
4
5
  include: [],
5
6
  exclude: [],
7
+ depth: 0,
6
8
  };
7
9
  const isMatch = (path, patterns) => {
8
10
  return patterns.some(pattern => minimatch(path, pattern));
9
11
  };
10
- export const getAllFiles = (dir, _files = [], { include, exclude } = OPTIONS) => {
12
+ export const getDepth = (path) => {
13
+ if (!path) {
14
+ return 0;
15
+ }
16
+ let depth = 0;
17
+ for (const p of path.replace(/^\.?\/(.*$)/, '$1').split('/')) {
18
+ switch (p) {
19
+ case '..':
20
+ --depth;
21
+ break;
22
+ default:
23
+ ++depth;
24
+ break;
25
+ }
26
+ }
27
+ return depth;
28
+ };
29
+ export const isShallow = (from, to, depth) => {
30
+ return getDepth(relative(from, to)) <= depth;
31
+ };
32
+ const _getAllFiles = (dir, options, _files = []) => {
11
33
  const files = readdirSync(dir);
12
34
  for (const file of files) {
13
- const name = dir + '/' + file;
14
- if (isMatch(name, exclude)) {
35
+ const name = `${dir}/${file}`;
36
+ if (isMatch(name, options.exclude)) {
37
+ continue;
38
+ }
39
+ if (options.depth >= 1 && !isShallow(options.startDir, name, options.depth)) {
15
40
  continue;
16
41
  }
17
42
  if (statSync(name).isDirectory()) {
18
- getAllFiles(name, _files, { include, exclude });
43
+ _getAllFiles(name, options, _files);
19
44
  }
20
45
  else {
21
- if (include.length > 0 && !isMatch(name, include)) {
46
+ if (options.include.length > 0 && !isMatch(name, options.include)) {
22
47
  continue;
23
48
  }
24
49
  _files.push(name);
@@ -26,3 +51,9 @@ export const getAllFiles = (dir, _files = [], { include, exclude } = OPTIONS) =>
26
51
  }
27
52
  return _files;
28
53
  };
54
+ export const getAllFiles = (startDir, _options) => {
55
+ if (!!_options && 'depth' in _options && typeof _options.depth !== 'undefined' && _options.depth < 1) {
56
+ throw new Error('Invalid depth, must be greater than 0');
57
+ }
58
+ return _getAllFiles(startDir, { ...OPTIONS, ...(_options || {}), startDir });
59
+ };
@@ -0,0 +1,10 @@
1
+ export type Merge<T> = {
2
+ [K in keyof T]: T[K];
3
+ };
4
+ export type AddOR<T, K extends keyof T, V> = Merge<Omit<T, K> & {
5
+ [key in K]: T[K] | V;
6
+ }>;
7
+ export type Update<T, K extends keyof T, V> = Merge<Omit<T, K> & {
8
+ [key in K]: V;
9
+ }>;
10
+ export type ToRecord<T> = Record<keyof T, T[keyof T]>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export * from '../../_core/types/utilities.js';
@@ -0,0 +1 @@
1
+ export * from '../../_core/types/utilities.js';
@@ -0,0 +1 @@
1
+ export * from '../../_internal/types/utilities.js';
@@ -0,0 +1 @@
1
+ export * from '../../_internal/types/utilities.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "my-gadgetry",
3
3
  "type": "module",
4
- "version": "1.1.2",
4
+ "version": "1.2.1",
5
5
  "description": "",
6
6
  "author": "",
7
7
  "repository": {
@@ -49,12 +49,12 @@
49
49
  "@actions/github": "^6.0.0",
50
50
  "fs-extra": "^11.2.0",
51
51
  "minimatch": "^9.0.4",
52
- "zx": "^8.1.0"
52
+ "zx": "^8.1.1"
53
53
  },
54
54
  "devDependencies": {
55
- "@babel/core": "^7.24.5",
56
- "@babel/preset-env": "^7.24.5",
57
- "@babel/preset-typescript": "^7.24.1",
55
+ "@babel/core": "^7.24.6",
56
+ "@babel/preset-env": "^7.24.6",
57
+ "@babel/preset-typescript": "^7.24.6",
58
58
  "@eslint/js": "^8.57.0",
59
59
  "@types/jest": "^29.5.12",
60
60
  "@types/node": "^20.12.12",
@@ -69,15 +69,15 @@
69
69
  "eslint-plugin-unused-imports": "^3.2.0",
70
70
  "husky": "^9.0.11",
71
71
  "jest": "^29.7.0",
72
- "lint-staged": "^15.2.2",
72
+ "lint-staged": "^15.2.5",
73
73
  "npm-run-all2": "^6.2.0",
74
74
  "prettier": "^3.2.5",
75
- "ts-jest": "^29.1.2",
75
+ "ts-jest": "^29.1.3",
76
76
  "ts-node": "^10.9.2",
77
77
  "tsc-alias": "^1.8.10",
78
- "tsx": "^4.10.4",
78
+ "tsx": "^4.11.0",
79
79
  "typescript": "^5.4.5",
80
- "typescript-eslint": "^7.9.0"
80
+ "typescript-eslint": "^7.10.0"
81
81
  },
82
82
  "exports": {
83
83
  ".": "./dist/**/*.js",
@@ -88,6 +88,7 @@
88
88
  "./dev-ops/package-generator/generate-alias": "./dist/modules/dev-ops/package-generator/generate-alias.js",
89
89
  "./fs": "./dist/modules/fs.js",
90
90
  "./type-check": "./dist/modules/type-check.js",
91
+ "./types/utilities": "./dist/modules/types/utilities.js",
91
92
  "./package.json": "./package.json"
92
93
  },
93
94
  "files": [
@@ -1,8 +1,8 @@
1
1
  import { resolve, join } from 'path'
2
- import { getAllFiles } from '../fs.js'
2
+ import { getAllFiles } from '../../fs.js'
3
3
 
4
4
  describe('getAllFiles', () => {
5
- const path = resolve(__dirname, '../../..', 'fs-test')
5
+ const path = resolve(__dirname, '../../../..', 'fs-test')
6
6
  it('no exclude & include', () => {
7
7
  const exclude: string[] = []
8
8
  const include: string[] = []
@@ -15,7 +15,7 @@ describe('getAllFiles', () => {
15
15
  join(path, 'hoge/foo.ts'),
16
16
  join(path, 'hoge.ts'),
17
17
  ]
18
- expect(JSON.stringify(getAllFiles(path, [], { include, exclude }))).toBe(JSON.stringify(expects))
18
+ expect(JSON.stringify(getAllFiles(path, { include, exclude }))).toBe(JSON.stringify(expects))
19
19
  })
20
20
  describe('set exclude', () => {
21
21
  it('filename', () => {
@@ -28,7 +28,7 @@ describe('getAllFiles', () => {
28
28
  join(path, 'hoge/foo.ts'),
29
29
  join(path, 'hoge.ts'),
30
30
  ]
31
- expect(JSON.stringify(getAllFiles(path, [], { include, exclude }))).toBe(JSON.stringify(expects))
31
+ expect(JSON.stringify(getAllFiles(path, { include, exclude }))).toBe(JSON.stringify(expects))
32
32
  })
33
33
  it('dirname', () => {
34
34
  const exclude: string[] = ['**/piyo/**/*']
@@ -40,7 +40,7 @@ describe('getAllFiles', () => {
40
40
  join(path, 'hoge/foo.ts'),
41
41
  join(path, 'hoge.ts'),
42
42
  ]
43
- expect(JSON.stringify(getAllFiles(path, [], { include, exclude }))).toBe(JSON.stringify(expects))
43
+ expect(JSON.stringify(getAllFiles(path, { include, exclude }))).toBe(JSON.stringify(expects))
44
44
  })
45
45
  })
46
46
  describe('set include', () => {
@@ -48,7 +48,7 @@ describe('getAllFiles', () => {
48
48
  const exclude: string[] = []
49
49
  const include: string[] = ['**/index.ts']
50
50
  const expects = [join(path, 'foo/piyo/index.ts'), join(path, 'hoge/foo/piyo/index.ts')]
51
- expect(JSON.stringify(getAllFiles(path, [], { include, exclude }))).toBe(JSON.stringify(expects))
51
+ expect(JSON.stringify(getAllFiles(path, { include, exclude }))).toBe(JSON.stringify(expects))
52
52
  })
53
53
  it('dirname', () => {
54
54
  const exclude: string[] = []
@@ -59,7 +59,7 @@ describe('getAllFiles', () => {
59
59
  join(path, 'hoge/foo/piyo/index.ts'),
60
60
  join(path, 'hoge/foo/piyo.ts'),
61
61
  ]
62
- expect(JSON.stringify(getAllFiles(path, [], { include, exclude }))).toBe(JSON.stringify(expects))
62
+ expect(JSON.stringify(getAllFiles(path, { include, exclude }))).toBe(JSON.stringify(expects))
63
63
  })
64
64
  })
65
65
  describe('set include & exclude', () => {
@@ -67,7 +67,24 @@ describe('getAllFiles', () => {
67
67
  const exclude: string[] = ['**/p*.ts']
68
68
  const include: string[] = ['**/foo/**/*']
69
69
  const expects = [join(path, 'foo/piyo/index.ts'), join(path, 'hoge/foo/piyo/index.ts')]
70
- expect(JSON.stringify(getAllFiles(path, [], { include, exclude }))).toBe(JSON.stringify(expects))
70
+ expect(JSON.stringify(getAllFiles(path, { include, exclude }))).toBe(JSON.stringify(expects))
71
+ })
72
+ })
73
+ describe('set depth', () => {
74
+ it('1', () => {
75
+ const exclude: string[] = []
76
+ const include: string[] = []
77
+ const depth = 1
78
+ const expects = [join(path, 'foo.ts'), join(path, 'hoge.ts')]
79
+ expect(JSON.stringify(getAllFiles(path, { include, exclude, depth }))).toBe(JSON.stringify(expects))
80
+ })
81
+ it('0: toThrow', () => {
82
+ const exclude: string[] = []
83
+ const include: string[] = []
84
+ const depth = 0
85
+ expect(() => getAllFiles(join(path, 'foo'), { include, exclude, depth })).toThrow(
86
+ 'Invalid depth, must be greater than 0'
87
+ )
71
88
  })
72
89
  })
73
90
  })
@@ -0,0 +1,46 @@
1
+ import { getDepth } from '../../fs.js'
2
+
3
+ describe('getDepth', () => {
4
+ describe('shallow', () => {
5
+ it('root', () => {
6
+ expect(getDepth('hoge')).toBe(1)
7
+ })
8
+ it('/', () => {
9
+ expect(getDepth('hoge')).toBe(1)
10
+ })
11
+ it('.', () => {
12
+ expect(getDepth('./hoge')).toBe(1)
13
+ })
14
+ it('..', () => {
15
+ expect(getDepth('../hoge')).toBe(0)
16
+ })
17
+ })
18
+ describe('deep', () => {
19
+ it('root', () => {
20
+ expect(getDepth('hoge/foo')).toBe(2)
21
+ })
22
+ it('/', () => {
23
+ expect(getDepth('foo/hoge')).toBe(2)
24
+ })
25
+ it('.', () => {
26
+ expect(getDepth('./foo/hoge')).toBe(2)
27
+ })
28
+ it('..', () => {
29
+ expect(getDepth('../foo/hoge')).toBe(1)
30
+ })
31
+ })
32
+ describe('deep/filename', () => {
33
+ it('root', () => {
34
+ expect(getDepth('hoge/foo/piyo.js')).toBe(3)
35
+ })
36
+ it('/', () => {
37
+ expect(getDepth('foo/hoge/piyo.js')).toBe(3)
38
+ })
39
+ it('.', () => {
40
+ expect(getDepth('./foo/hoge/piyo.js')).toBe(3)
41
+ })
42
+ it('..', () => {
43
+ expect(getDepth('../foo/hoge/piyo.js')).toBe(2)
44
+ })
45
+ })
46
+ })
@@ -0,0 +1,13 @@
1
+ import { isShallow } from '../../fs.js'
2
+ import { resolve } from 'path'
3
+
4
+ const path = resolve(__dirname, '../../../..', 'fs-test')
5
+
6
+ describe('isShallow', () => {
7
+ it('depth: 1', () => {
8
+ expect(isShallow(path, `${path}/foo`, 1)).toBeTruthy()
9
+ })
10
+ it('same path', () => {
11
+ expect(isShallow(path, path, 0)).toBeTruthy()
12
+ })
13
+ })
package/src/_core/fs.ts CHANGED
@@ -1,32 +1,66 @@
1
1
  import { statSync, readdirSync } from 'fs'
2
+ import { relative } from 'path'
2
3
 
3
4
  import { minimatch } from 'minimatch'
4
5
 
5
6
  export interface Options {
6
- include: string[]
7
- exclude: string[]
7
+ include?: string[]
8
+ exclude?: string[]
9
+ depth?: number
10
+ startDir?: string
8
11
  }
9
12
 
10
13
  export const OPTIONS = {
11
14
  include: [],
12
15
  exclude: [],
16
+ depth: 0,
17
+ }
18
+
19
+ export interface Stacks {
20
+ files: string[]
21
+ depth: number
13
22
  }
14
23
 
15
24
  const isMatch = (path: string, patterns: string[]) => {
16
25
  return patterns.some(pattern => minimatch(path, pattern))
17
26
  }
18
27
 
19
- export const getAllFiles = (dir: string, _files: string[] = [], { include, exclude }: Options = OPTIONS) => {
28
+ export const getDepth = (path: string) => {
29
+ if (!path) {
30
+ return 0
31
+ }
32
+ let depth = 0
33
+ for (const p of path.replace(/^\.?\/(.*$)/, '$1').split('/')) {
34
+ switch (p) {
35
+ case '..':
36
+ --depth
37
+ break
38
+ default:
39
+ ++depth
40
+ break
41
+ }
42
+ }
43
+ return depth
44
+ }
45
+
46
+ export const isShallow = (from: string, to: string, depth: number) => {
47
+ return getDepth(relative(from, to)) <= depth
48
+ }
49
+
50
+ const _getAllFiles = (dir: string, options: Required<Options>, _files: string[] = []) => {
20
51
  const files = readdirSync(dir)
21
52
  for (const file of files) {
22
- const name = dir + '/' + file
23
- if (isMatch(name, exclude)) {
53
+ const name = `${dir}/${file}`
54
+ if (isMatch(name, options.exclude)) {
55
+ continue
56
+ }
57
+ if (options.depth >= 1 && !isShallow(options.startDir, name, options.depth)) {
24
58
  continue
25
59
  }
26
60
  if (statSync(name).isDirectory()) {
27
- getAllFiles(name, _files, { include, exclude })
61
+ _getAllFiles(name, options, _files)
28
62
  } else {
29
- if (include.length > 0 && !isMatch(name, include)) {
63
+ if (options.include.length > 0 && !isMatch(name, options.include)) {
30
64
  continue
31
65
  }
32
66
  _files.push(name)
@@ -34,3 +68,10 @@ export const getAllFiles = (dir: string, _files: string[] = [], { include, exclu
34
68
  }
35
69
  return _files
36
70
  }
71
+
72
+ export const getAllFiles = (startDir: string, _options?: Options) => {
73
+ if (!!_options && 'depth' in _options && typeof _options.depth !== 'undefined' && _options.depth < 1) {
74
+ throw new Error('Invalid depth, must be greater than 0')
75
+ }
76
+ return _getAllFiles(startDir, { ...OPTIONS, ...(_options || {}), startDir })
77
+ }
@@ -0,0 +1,17 @@
1
+ export type Merge<T> = {
2
+ [K in keyof T]: T[K]
3
+ }
4
+
5
+ export type AddOR<T, K extends keyof T, V> = Merge<
6
+ Omit<T, K> & {
7
+ [key in K]: T[K] | V
8
+ }
9
+ >
10
+
11
+ export type Update<T, K extends keyof T, V> = Merge<
12
+ Omit<T, K> & {
13
+ [key in K]: V
14
+ }
15
+ >
16
+
17
+ export type ToRecord<T> = Record<keyof T, T[keyof T]>
@@ -0,0 +1 @@
1
+ export * from '~core/types/utilities.js'
@@ -0,0 +1 @@
1
+ export * from '~internal/types/utilities.js'