@ainc/fs 0.1.22 → 0.1.24
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/cache.d.ts +16 -0
- package/dist/cache.js +24 -0
- package/dist/dict.d.ts +21 -0
- package/dist/dict.js +66 -0
- package/dist/download.js +4 -16
- package/dist/downloadFile.js +19 -13
- package/dist/gzip.d.ts +13 -0
- package/dist/gzip.js +50 -0
- package/dist/index.d.ts +37 -1
- package/dist/index.exports.json +34 -0
- package/dist/index.js +60 -3
- package/dist/isEsmModule.d.ts +18 -0
- package/dist/isEsmModule.js +63 -0
- package/dist/loadPackageDescription.d.ts +61 -0
- package/dist/loadPackageDescription.js +71 -0
- package/dist/loadTsConfig.d.ts +87 -0
- package/dist/loadTsConfig.js +219 -0
- package/dist/match.d.ts +30 -0
- package/dist/match.js +59 -0
- package/dist/promises.d.ts +69 -0
- package/dist/promises.js +103 -0
- package/dist/resolveAlias.d.ts +25 -0
- package/dist/resolveAlias.js +82 -0
- package/dist/resolveDirect.d.ts +15 -0
- package/dist/resolveDirect.js +144 -0
- package/dist/resolveExports.d.ts +19 -0
- package/dist/resolveExports.js +54 -0
- package/dist/resolveImports.d.ts +21 -0
- package/dist/resolveImports.js +114 -0
- package/dist/resolveModuleDir.d.ts +12 -0
- package/dist/resolveModuleDir.js +67 -0
- package/dist/resolveModuleId.d.ts +6 -0
- package/dist/resolveModuleId.js +32 -0
- package/dist/resolvePath.d.ts +23 -0
- package/dist/resolvePath.js +86 -0
- package/dist/resolvePaths.d.ts +13 -0
- package/dist/resolvePaths.js +42 -0
- package/dist/split.d.ts +6 -0
- package/dist/split.js +24 -0
- package/dist/sys.d.ts +60 -0
- package/dist/sys.js +260 -0
- package/esm/cache.mjs +22 -0
- package/esm/dict.mjs +63 -0
- package/esm/download.mjs +4 -16
- package/esm/downloadFile.mjs +19 -13
- package/esm/gzip.mjs +47 -0
- package/esm/index.exports.json +34 -0
- package/esm/index.mjs +29 -1
- package/esm/isEsmModule.mjs +59 -0
- package/esm/loadPackageDescription.mjs +67 -0
- package/esm/loadTsConfig.mjs +215 -0
- package/esm/match.mjs +53 -0
- package/esm/promises.mjs +96 -0
- package/esm/resolveAlias.mjs +79 -0
- package/esm/resolveDirect.mjs +142 -0
- package/esm/resolveExports.mjs +51 -0
- package/esm/resolveImports.mjs +112 -0
- package/esm/resolveModuleDir.mjs +64 -0
- package/esm/resolveModuleId.mjs +30 -0
- package/esm/resolvePath.mjs +84 -0
- package/esm/resolvePaths.mjs +40 -0
- package/esm/split.mjs +22 -0
- package/esm/sys.mjs +258 -0
- package/package.json +5 -6
package/esm/index.mjs
CHANGED
|
@@ -5,6 +5,22 @@
|
|
|
5
5
|
*****************************************
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 文件系统
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
export { sys } from './sys.mjs';
|
|
14
|
+
/**
|
|
15
|
+
*****************************************
|
|
16
|
+
* 导出工具
|
|
17
|
+
*****************************************
|
|
18
|
+
*/
|
|
19
|
+
export { unary, noop, nil, match } from './match.mjs';
|
|
20
|
+
export { split } from './split.mjs';
|
|
21
|
+
export { cache } from './cache.mjs';
|
|
22
|
+
export { retry } from './retry.mjs';
|
|
23
|
+
export { Dict } from './dict.mjs';
|
|
8
24
|
/**
|
|
9
25
|
*****************************************
|
|
10
26
|
* 导出接口
|
|
@@ -13,8 +29,8 @@
|
|
|
13
29
|
export { resolve, join, isAbsolute } from 'node:path';
|
|
14
30
|
export { relative, isRelative } from './relative.mjs';
|
|
15
31
|
export { dirname } from './dirname.mjs';
|
|
32
|
+
export { isEsmModule, isEsmFile, isEsmPackage } from './isEsmModule.mjs';
|
|
16
33
|
export { stat, isDir, isFile } from './stat.mjs';
|
|
17
|
-
export { resolveFile } from './resolveFile.mjs';
|
|
18
34
|
export { readFile } from './readFile.mjs';
|
|
19
35
|
export { writeFile } from './writeFile.mjs';
|
|
20
36
|
export { copy } from './copy.mjs';
|
|
@@ -24,3 +40,15 @@ export { md5 } from './md5.mjs';
|
|
|
24
40
|
export { json, jsonc } from './jsonc.mjs';
|
|
25
41
|
export { findUp } from './findUp.mjs';
|
|
26
42
|
export { download } from './download.mjs';
|
|
43
|
+
export { gzip, ungzip } from './gzip.mjs';
|
|
44
|
+
export { loadPackageDescription, resolvePackageDescription } from './loadPackageDescription.mjs';
|
|
45
|
+
export { loadTsConfig, loadCompilerOptions, resolveTsConfig } from './loadTsConfig.mjs';
|
|
46
|
+
export { resolveAlias, resolveDict } from './resolveAlias.mjs';
|
|
47
|
+
export { resolvePaths } from './resolvePaths.mjs';
|
|
48
|
+
export { resolvePath } from './resolvePath.mjs';
|
|
49
|
+
export { resolveFile } from './resolveFile.mjs';
|
|
50
|
+
export { resolveDirect } from './resolveDirect.mjs';
|
|
51
|
+
export { resolveImports } from './resolveImports.mjs';
|
|
52
|
+
export { resolveExports } from './resolveExports.mjs';
|
|
53
|
+
export { resolveModuleDir, resolveModuleDirs } from './resolveModuleDir.mjs';
|
|
54
|
+
export { resolveModuleId } from './resolveModuleId.mjs';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2026-03-18 20:14:00
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 加载依赖
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
import { dirname, extname } from 'node:path';
|
|
14
|
+
import { loadPackageDescription } from './loadPackageDescription.mjs';
|
|
15
|
+
/**
|
|
16
|
+
*****************************************
|
|
17
|
+
* 判断是否为 ESM 模块
|
|
18
|
+
*****************************************
|
|
19
|
+
*/
|
|
20
|
+
export function isEsmModule(filename, dir = dirname(filename)) {
|
|
21
|
+
const result = isEsmFile(filename);
|
|
22
|
+
// 文件扩展名未匹配成功时,解析文件所在包的配置
|
|
23
|
+
if (result === undefined) {
|
|
24
|
+
return isEsmPackage(dir);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
*****************************************
|
|
32
|
+
* 判断是否为 ESM 模块
|
|
33
|
+
*****************************************
|
|
34
|
+
*/
|
|
35
|
+
export function isEsmPackage(dir) {
|
|
36
|
+
const pkg = loadPackageDescription(dir);
|
|
37
|
+
if (pkg && pkg.type === 'module') {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
*****************************************
|
|
46
|
+
* 判断为 ESM 文件
|
|
47
|
+
*****************************************
|
|
48
|
+
*/
|
|
49
|
+
export function isEsmFile(filename) {
|
|
50
|
+
const ext = extname(filename);
|
|
51
|
+
// 判断 mjs 模块
|
|
52
|
+
if (['.mjs', '.mts', '.mjsx', '.mtsx'].includes(ext)) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
// 判断 cjs 模块
|
|
56
|
+
if (['.cjs', '.cts', '.cjsx', '.ctsx'].includes(ext)) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2023-12-02 11:43:57
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 加载依赖
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
import { sep } from 'node:path';
|
|
14
|
+
import { isFile } from './stat.mjs';
|
|
15
|
+
import { lookup } from './lookup.mjs';
|
|
16
|
+
import { json } from './jsonc.mjs';
|
|
17
|
+
import { readFile } from './readFile.mjs';
|
|
18
|
+
/**
|
|
19
|
+
*****************************************
|
|
20
|
+
* 加载包描述
|
|
21
|
+
*****************************************
|
|
22
|
+
*/
|
|
23
|
+
export function loadPackageDescription(from) {
|
|
24
|
+
const data = resolvePackageDescription(from);
|
|
25
|
+
// 返回配置
|
|
26
|
+
if (data) {
|
|
27
|
+
return data.config;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
*****************************************
|
|
32
|
+
* 读取包描述
|
|
33
|
+
*****************************************
|
|
34
|
+
*/
|
|
35
|
+
export function readPackageDescription(dir) {
|
|
36
|
+
const data = resolvePackageDescription(dir);
|
|
37
|
+
// 返回配置
|
|
38
|
+
if (data && data.path.startsWith(dir)) {
|
|
39
|
+
return data.config;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
*****************************************
|
|
44
|
+
* 缓存
|
|
45
|
+
*****************************************
|
|
46
|
+
*/
|
|
47
|
+
const cache = new Map();
|
|
48
|
+
const moduleDir = sep + 'node_modules';
|
|
49
|
+
/**
|
|
50
|
+
*****************************************
|
|
51
|
+
* 解析包配置
|
|
52
|
+
*****************************************
|
|
53
|
+
*/
|
|
54
|
+
export function resolvePackageDescription(from) {
|
|
55
|
+
return lookup('package.json', {
|
|
56
|
+
from,
|
|
57
|
+
cache,
|
|
58
|
+
resolve(path, dir) {
|
|
59
|
+
if (isFile(path)) {
|
|
60
|
+
return { dir, path, config: json(readFile(path)) };
|
|
61
|
+
}
|
|
62
|
+
if (dir.endsWith(moduleDir)) {
|
|
63
|
+
return { dir, path };
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2023-12-30 13:48:09
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 加载依赖
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
import { dirname, resolve, sep, isAbsolute } from 'node:path';
|
|
15
|
+
import { relative, isRelative } from './relative.mjs';
|
|
16
|
+
import { resolveFile } from './resolveFile.mjs';
|
|
17
|
+
import { isFile } from './stat.mjs';
|
|
18
|
+
import { lookup } from './lookup.mjs';
|
|
19
|
+
import { jsonc } from './jsonc.mjs';
|
|
20
|
+
import { match } from './match.mjs';
|
|
21
|
+
import { resolveModuleDirs } from './resolveModuleDir.mjs';
|
|
22
|
+
/**
|
|
23
|
+
*****************************************
|
|
24
|
+
* 加载 TS 配置
|
|
25
|
+
*****************************************
|
|
26
|
+
*/
|
|
27
|
+
export function loadTsConfig(from) {
|
|
28
|
+
const data = resolveTsConfig(from);
|
|
29
|
+
// 返回配置
|
|
30
|
+
if (data) {
|
|
31
|
+
return data.config;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
*****************************************
|
|
36
|
+
* 加载编译配置
|
|
37
|
+
*****************************************
|
|
38
|
+
*/
|
|
39
|
+
export function loadCompilerOptions(from) {
|
|
40
|
+
const data = resolveTsConfig(from);
|
|
41
|
+
// 返回配置
|
|
42
|
+
if (data && data.config) {
|
|
43
|
+
return data.config.compilerOptions;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
*****************************************
|
|
48
|
+
* 缓存内容
|
|
49
|
+
*****************************************
|
|
50
|
+
*/
|
|
51
|
+
const cache = new Map();
|
|
52
|
+
/**
|
|
53
|
+
*****************************************
|
|
54
|
+
* 解析 TS 配置
|
|
55
|
+
*****************************************
|
|
56
|
+
*/
|
|
57
|
+
export function resolveTsConfig(from) {
|
|
58
|
+
return lookup('tsconfig.json', {
|
|
59
|
+
from,
|
|
60
|
+
cache,
|
|
61
|
+
resolve(path) {
|
|
62
|
+
return isFile(path) ? loadTsConfigFile(path) : undefined;
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
*****************************************
|
|
68
|
+
* 解析 TS 配置文件
|
|
69
|
+
*****************************************
|
|
70
|
+
*/
|
|
71
|
+
function loadTsConfigFile(path) {
|
|
72
|
+
const config = parseTsConfig(path, new Set([path]), ['.json', sep + 'tsconfig.json']);
|
|
73
|
+
const dir = dirname(path);
|
|
74
|
+
// 移除继承属性
|
|
75
|
+
config.extends = undefined;
|
|
76
|
+
// 格式化 include 配置
|
|
77
|
+
if (config.include) {
|
|
78
|
+
config.include = config.include.map(path => relative(dir, path));
|
|
79
|
+
}
|
|
80
|
+
// 格式化 exclude 配置
|
|
81
|
+
if (config.exclude) {
|
|
82
|
+
config.exclude = config.exclude.map(path => relative(dir, path));
|
|
83
|
+
}
|
|
84
|
+
// 格式化 files 配置
|
|
85
|
+
if (config.files) {
|
|
86
|
+
config.files = config.files.map(path => relative(dir, path));
|
|
87
|
+
}
|
|
88
|
+
// 返回结果
|
|
89
|
+
return { path, config };
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
*****************************************
|
|
93
|
+
* 解析配置
|
|
94
|
+
*****************************************
|
|
95
|
+
*/
|
|
96
|
+
function parseTsConfig(path, tracker, extensions) {
|
|
97
|
+
const data = jsonc(readFileSync(path, 'utf8'));
|
|
98
|
+
const dir = dirname(path);
|
|
99
|
+
const config = normalizeTsConfig(data, dir);
|
|
100
|
+
// 不存在继承,直接返回
|
|
101
|
+
if (!config.extends) {
|
|
102
|
+
return config;
|
|
103
|
+
}
|
|
104
|
+
// 获取继承列表
|
|
105
|
+
const extendsList = Array.isArray(config.extends) ? config.extends : [config.extends];
|
|
106
|
+
const configs = extendsList.map(path => parseExtendsTsConfig(path, dir, tracker, extensions));
|
|
107
|
+
// 追加当前配置
|
|
108
|
+
configs.push(config);
|
|
109
|
+
// 合并配置
|
|
110
|
+
return configs.reduce(mergeTsConfig);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
*****************************************
|
|
114
|
+
* 合并配置
|
|
115
|
+
*****************************************
|
|
116
|
+
*/
|
|
117
|
+
function mergeTsConfig(target, source) {
|
|
118
|
+
const { baseUrl, paths } = source.compilerOptions || {};
|
|
119
|
+
const config = { ...target, ...source };
|
|
120
|
+
// 合并配置项
|
|
121
|
+
config.compilerOptions = { ...target.compilerOptions, ...source.compilerOptions };
|
|
122
|
+
config.watchOptions = { ...target.watchOptions, ...source.watchOptions };
|
|
123
|
+
// 更新 paths 配置
|
|
124
|
+
if (baseUrl || paths) {
|
|
125
|
+
config.compilerOptions.baseUrl = baseUrl;
|
|
126
|
+
config.compilerOptions.paths = paths;
|
|
127
|
+
}
|
|
128
|
+
// 返回配置
|
|
129
|
+
return config;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
*****************************************
|
|
133
|
+
* 解析继承配置
|
|
134
|
+
*****************************************
|
|
135
|
+
*/
|
|
136
|
+
function parseExtendsTsConfig(path, from, tracker, extensions) {
|
|
137
|
+
const extendsFile = resolveExtendsFile(path, from, extensions);
|
|
138
|
+
// 未找到文件
|
|
139
|
+
if (!extendsFile) {
|
|
140
|
+
throw new Error(`file '${path}' not found.`);
|
|
141
|
+
}
|
|
142
|
+
// 循环引用
|
|
143
|
+
if (tracker.has(extendsFile)) {
|
|
144
|
+
throw new Error(`circularity detected while resolving configuration: ${extendsFile}`);
|
|
145
|
+
}
|
|
146
|
+
// 添加引用文件
|
|
147
|
+
tracker.add(extendsFile);
|
|
148
|
+
// 解析文件
|
|
149
|
+
return parseTsConfig(extendsFile, tracker, extensions);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
*****************************************
|
|
153
|
+
* 解析继承文件地址
|
|
154
|
+
*****************************************
|
|
155
|
+
*/
|
|
156
|
+
function resolveExtendsFile(path, from, extensions) {
|
|
157
|
+
// 解析相对路径
|
|
158
|
+
if (isRelative(path)) {
|
|
159
|
+
return resolveFile(resolve(from, path), extensions);
|
|
160
|
+
}
|
|
161
|
+
// 解析绝对路径
|
|
162
|
+
if (isAbsolute(path)) {
|
|
163
|
+
return resolveFile(path, extensions);
|
|
164
|
+
}
|
|
165
|
+
// 解析模块目录
|
|
166
|
+
const moduleDirs = resolveModuleDirs(from);
|
|
167
|
+
// 模块目录
|
|
168
|
+
return match(moduleDirs, dir => resolveFile(resolve(dir, path), extensions));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
*****************************************
|
|
172
|
+
* 格式化配置
|
|
173
|
+
*****************************************
|
|
174
|
+
*/
|
|
175
|
+
function normalizeTsConfig(config, dir) {
|
|
176
|
+
const compilerOptions = config.compilerOptions;
|
|
177
|
+
const watchOptions = config.watchOptions;
|
|
178
|
+
// 格式化 include 配置
|
|
179
|
+
if (config.include) {
|
|
180
|
+
config.include = config.include.map(path => resolve(dir, path));
|
|
181
|
+
}
|
|
182
|
+
// 格式化 exclude 配置
|
|
183
|
+
if (config.exclude) {
|
|
184
|
+
config.exclude = config.exclude.map(path => resolve(dir, path));
|
|
185
|
+
}
|
|
186
|
+
// 格式化 files 配置
|
|
187
|
+
if (config.files) {
|
|
188
|
+
config.files = config.files.map(path => resolve(dir, path));
|
|
189
|
+
}
|
|
190
|
+
// 格式化 compilerOptions 配置
|
|
191
|
+
if (compilerOptions) {
|
|
192
|
+
// 格式化 baseUrl 配置
|
|
193
|
+
if (compilerOptions.baseUrl) {
|
|
194
|
+
compilerOptions.baseUrl = resolve(dir, compilerOptions.baseUrl);
|
|
195
|
+
}
|
|
196
|
+
// 格式化 outDir 配置
|
|
197
|
+
if (compilerOptions.outDir) {
|
|
198
|
+
compilerOptions.outDir = resolve(dir, compilerOptions.outDir);
|
|
199
|
+
}
|
|
200
|
+
// 格式化 rootDir 配置
|
|
201
|
+
if (compilerOptions.rootDir) {
|
|
202
|
+
compilerOptions.rootDir = resolve(dir, compilerOptions.rootDir);
|
|
203
|
+
}
|
|
204
|
+
// 格式化 rootDirs 配置
|
|
205
|
+
if (compilerOptions.rootDirs) {
|
|
206
|
+
compilerOptions.rootDirs = compilerOptions.rootDirs.map(path => resolve(dir, path));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// 格式化监听路径
|
|
210
|
+
if (watchOptions && watchOptions.excludeDirectories) {
|
|
211
|
+
watchOptions.excludeDirectories = watchOptions.excludeDirectories.map(path => resolve(dir, path));
|
|
212
|
+
}
|
|
213
|
+
// 返回配置
|
|
214
|
+
return config;
|
|
215
|
+
}
|
package/esm/match.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2026-03-18 15:12:42
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 空函数
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
export function noop() {
|
|
14
|
+
// do nothing
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
*****************************************
|
|
18
|
+
* nil 函数
|
|
19
|
+
*****************************************
|
|
20
|
+
*/
|
|
21
|
+
export function nil() {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
*****************************************
|
|
26
|
+
* false
|
|
27
|
+
*****************************************
|
|
28
|
+
*/
|
|
29
|
+
export function falsy() {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
*****************************************
|
|
34
|
+
* 一元函数
|
|
35
|
+
*****************************************
|
|
36
|
+
*/
|
|
37
|
+
export function unary(value) {
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
*****************************************
|
|
42
|
+
* 执行匹配
|
|
43
|
+
*****************************************
|
|
44
|
+
*/
|
|
45
|
+
export function match(list, handler) {
|
|
46
|
+
for (let i = 0; i < list.length; i++) {
|
|
47
|
+
const result = handler(list[i]);
|
|
48
|
+
// 查找到结果
|
|
49
|
+
if (result !== undefined) {
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
package/esm/promises.mjs
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2026-03-21 12:37:59
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
import { dirname } from 'node:path';
|
|
9
|
+
import * as fs from 'node:fs/promises';
|
|
10
|
+
/**
|
|
11
|
+
*****************************************
|
|
12
|
+
* 获取文件状态
|
|
13
|
+
*****************************************
|
|
14
|
+
*/
|
|
15
|
+
export async function stat(path, options) {
|
|
16
|
+
return fs.stat(path, options).catch(err => err.code === 'ENOENT' ? null : Promise.reject(err));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
*****************************************
|
|
20
|
+
* 删除文件
|
|
21
|
+
*****************************************
|
|
22
|
+
*/
|
|
23
|
+
export async function rm(path, options) {
|
|
24
|
+
if (await stat(path)) {
|
|
25
|
+
await fs.rm(path, { force: true, recursive: true, ...options });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
*****************************************
|
|
30
|
+
* 创建文件目录
|
|
31
|
+
*****************************************
|
|
32
|
+
*/
|
|
33
|
+
export async function mkdir(path, options) {
|
|
34
|
+
const stats = await stat(path);
|
|
35
|
+
const opts = { recursive: true, ...options };
|
|
36
|
+
// 创建目录
|
|
37
|
+
if (!stats) {
|
|
38
|
+
await fs.mkdir(path, opts);
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
else if (stats.isDirectory()) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
else if (!opts.force) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
await fs.unlink(path);
|
|
49
|
+
await fs.mkdir(path, opts);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
*****************************************
|
|
55
|
+
* pipe
|
|
56
|
+
*****************************************
|
|
57
|
+
*/
|
|
58
|
+
export async function pipe(src, dest, options) {
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
src.once('close', resolve);
|
|
61
|
+
src.once('error', reject);
|
|
62
|
+
src.pipe(dest, options);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
*****************************************
|
|
67
|
+
* 读取文件
|
|
68
|
+
*****************************************
|
|
69
|
+
*/
|
|
70
|
+
export async function readFile(path) {
|
|
71
|
+
const stats = await stat(path);
|
|
72
|
+
if (stats && !stats.isDirectory()) {
|
|
73
|
+
return fs.readFile(path, 'utf8');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
*****************************************
|
|
78
|
+
* 写入文件
|
|
79
|
+
*****************************************
|
|
80
|
+
*/
|
|
81
|
+
export async function writeFile(path, content, options) {
|
|
82
|
+
const stats = await stat(path);
|
|
83
|
+
if (stats) {
|
|
84
|
+
if (!options || !options.force) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
await rm(path);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// 写入文件内容
|
|
92
|
+
await fs.mkdir(dirname(path), { recursive: true });
|
|
93
|
+
await fs.writeFile(path, content);
|
|
94
|
+
// 返回结果
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2025-05-26 22:30:23
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 加载依赖
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
import { Dict } from './dict.mjs';
|
|
14
|
+
import { cache } from './cache.mjs';
|
|
15
|
+
import { resolveDirect } from './resolveDirect.mjs';
|
|
16
|
+
/**
|
|
17
|
+
*****************************************
|
|
18
|
+
* 缓存
|
|
19
|
+
*****************************************
|
|
20
|
+
*/
|
|
21
|
+
const cached = cache(new WeakMap());
|
|
22
|
+
/**
|
|
23
|
+
*****************************************
|
|
24
|
+
* 解析别名
|
|
25
|
+
*****************************************
|
|
26
|
+
*/
|
|
27
|
+
export function resolveAlias(alias) {
|
|
28
|
+
return cached.get(alias, resolveTarget);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
*****************************************
|
|
32
|
+
* 解析别名
|
|
33
|
+
*****************************************
|
|
34
|
+
*/
|
|
35
|
+
function resolveTarget(alias) {
|
|
36
|
+
return resolveDict(alias, resolvePath);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
*****************************************
|
|
40
|
+
* 解析匹配路径
|
|
41
|
+
*****************************************
|
|
42
|
+
*/
|
|
43
|
+
function resolvePath(key, value) {
|
|
44
|
+
const { test, resolve } = resolveDirect(key);
|
|
45
|
+
const rule = resolve(value);
|
|
46
|
+
// 返回匹配函数
|
|
47
|
+
return function match(id, handler) {
|
|
48
|
+
if (test(id)) {
|
|
49
|
+
return handler(rule(id));
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
*****************************************
|
|
55
|
+
* 解析字典
|
|
56
|
+
*****************************************
|
|
57
|
+
*/
|
|
58
|
+
export function resolveDict(data, handler) {
|
|
59
|
+
const result = new Dict();
|
|
60
|
+
// 生成元素
|
|
61
|
+
Object.keys(data)
|
|
62
|
+
.forEach(key => result.set(key, handler(key, data[key])));
|
|
63
|
+
// 排序列表
|
|
64
|
+
result.sort((a, b) => {
|
|
65
|
+
const idxA = a.indexOf('*');
|
|
66
|
+
const idxB = b.indexOf('*');
|
|
67
|
+
const baseA = idxA === -1 ? a.length : idxA;
|
|
68
|
+
const baseB = idxB === -1 ? b.length : idxB;
|
|
69
|
+
// 比较基准长度
|
|
70
|
+
if (baseA !== baseB) {
|
|
71
|
+
return baseB - baseA;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
return idxA === -1 ? -1 : idxB === -1 ? 1 : b.length - a.length;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// 返回结果
|
|
78
|
+
return result;
|
|
79
|
+
}
|