my-gadgetry 1.1.2 → 1.2.5
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/dist/_core/fs.d.ts +12 -3
- package/dist/_core/fs.js +36 -5
- package/dist/_core/types/utilities.d.ts +10 -0
- package/dist/_core/types/utilities.js +1 -0
- package/dist/_internal/types/utilities.d.ts +1 -0
- package/dist/_internal/types/utilities.js +1 -0
- package/dist/modules/types/utilities.d.ts +1 -0
- package/dist/modules/types/utilities.js +1 -0
- package/package.json +11 -10
- package/src/_core/__tests__/{fs.spec.ts → fs/get-all-files.spec.ts} +25 -8
- package/src/_core/__tests__/fs/get-depth.spec.ts +46 -0
- package/src/_core/__tests__/fs/is-shallow.spec.ts +13 -0
- package/src/_core/fs.ts +48 -7
- package/src/_core/types/utilities.ts +17 -0
- package/src/_internal/types/utilities.ts +1 -0
- package/src/modules/types/utilities.ts +1 -0
package/dist/_core/fs.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
export interface Options {
|
|
2
|
-
include
|
|
3
|
-
exclude
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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.
|
|
4
|
+
"version": "1.2.5",
|
|
5
5
|
"description": "",
|
|
6
6
|
"author": "",
|
|
7
7
|
"repository": {
|
|
@@ -49,15 +49,15 @@
|
|
|
49
49
|
"@actions/github": "^6.0.0",
|
|
50
50
|
"fs-extra": "^11.2.0",
|
|
51
51
|
"minimatch": "^9.0.4",
|
|
52
|
-
"zx": "^8.1.
|
|
52
|
+
"zx": "^8.1.2"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
|
-
"@babel/core": "^7.24.
|
|
56
|
-
"@babel/preset-env": "^7.24.
|
|
57
|
-
"@babel/preset-typescript": "^7.24.
|
|
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
|
-
"@types/node": "^20.12.
|
|
60
|
+
"@types/node": "^20.12.13",
|
|
61
61
|
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
|
62
62
|
"@typescript-eslint/parser": "^7.9.0",
|
|
63
63
|
"babel-jest": "^29.7.0",
|
|
@@ -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.
|
|
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.
|
|
75
|
+
"ts-jest": "^29.1.4",
|
|
76
76
|
"ts-node": "^10.9.2",
|
|
77
77
|
"tsc-alias": "^1.8.10",
|
|
78
|
-
"tsx": "^4.
|
|
78
|
+
"tsx": "^4.11.0",
|
|
79
79
|
"typescript": "^5.4.5",
|
|
80
|
-
"typescript-eslint": "^7.
|
|
80
|
+
"typescript-eslint": "^7.11.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 '
|
|
2
|
+
import { getAllFiles } from '../../fs.js'
|
|
3
3
|
|
|
4
4
|
describe('getAllFiles', () => {
|
|
5
|
-
const path = resolve(__dirname, '
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
7
|
-
exclude
|
|
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
|
|
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
|
|
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
|
-
|
|
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'
|