@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
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2025-05-26 22:30:23
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.resolvePaths = resolvePaths;
|
|
10
|
+
const match_1 = require("./match");
|
|
11
|
+
const cache_1 = require("./cache");
|
|
12
|
+
const resolveAlias_1 = require("./resolveAlias");
|
|
13
|
+
const resolveDirect_1 = require("./resolveDirect");
|
|
14
|
+
/**
|
|
15
|
+
*****************************************
|
|
16
|
+
* 缓存
|
|
17
|
+
*****************************************
|
|
18
|
+
*/
|
|
19
|
+
const cached = (0, cache_1.cache)(new WeakMap());
|
|
20
|
+
/**
|
|
21
|
+
*****************************************
|
|
22
|
+
* 解析别名
|
|
23
|
+
*****************************************
|
|
24
|
+
*/
|
|
25
|
+
function resolvePaths(paths) {
|
|
26
|
+
return cached.get(paths, () => (0, resolveAlias_1.resolveDict)(paths, resolvePath));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
*****************************************
|
|
30
|
+
* 解析匹配规则
|
|
31
|
+
*****************************************
|
|
32
|
+
*/
|
|
33
|
+
function resolvePath(key, paths) {
|
|
34
|
+
const { test, resolve } = (0, resolveDirect_1.resolveDirect)(key);
|
|
35
|
+
const rules = paths.map(resolve);
|
|
36
|
+
// 返回解析函数
|
|
37
|
+
return function resolve(id, handler) {
|
|
38
|
+
if (test(id)) {
|
|
39
|
+
return (0, match_1.match)(rules, direct => handler(direct(id)));
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
package/dist/split.d.ts
ADDED
package/dist/split.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2025-05-24 23:56:16
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.split = split;
|
|
10
|
+
/**
|
|
11
|
+
*****************************************
|
|
12
|
+
* 分割字符串
|
|
13
|
+
*****************************************
|
|
14
|
+
*/
|
|
15
|
+
function split(str, sep) {
|
|
16
|
+
const idx = str.indexOf(sep);
|
|
17
|
+
// 执行切割
|
|
18
|
+
if (idx === -1) {
|
|
19
|
+
return [str, undefined];
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return [str.slice(0, idx), str.slice(idx + sep.length)];
|
|
23
|
+
}
|
|
24
|
+
}
|
package/dist/sys.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { PackageDescription } from './loadPackageDescription';
|
|
2
|
+
/**
|
|
3
|
+
*****************************************
|
|
4
|
+
* 文件系统
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
export type FileSystem = typeof sys;
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 文件系统
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
export declare const sys: {
|
|
14
|
+
/** 解析基准路径 */
|
|
15
|
+
baseUrl: string | undefined;
|
|
16
|
+
/** 别名配置 */
|
|
17
|
+
alias: Record<string, string> | undefined;
|
|
18
|
+
/** 路径配置 */
|
|
19
|
+
paths: Record<string, string[]> | undefined;
|
|
20
|
+
/** 缓存 ID */
|
|
21
|
+
cacheSalt: string;
|
|
22
|
+
/** 缓存 */
|
|
23
|
+
cache: Map<string, string | null | undefined>;
|
|
24
|
+
/** 当前目录 */
|
|
25
|
+
cwd: string;
|
|
26
|
+
/** 是否解析模块 */
|
|
27
|
+
module: boolean;
|
|
28
|
+
/** 是否解析模块导出 */
|
|
29
|
+
moduleExports: boolean;
|
|
30
|
+
/** 解析 main 字段 */
|
|
31
|
+
mainFields: string[];
|
|
32
|
+
/** 解析条件 */
|
|
33
|
+
conditions: string[];
|
|
34
|
+
/** 解析扩展名 */
|
|
35
|
+
extensions: string[];
|
|
36
|
+
/** 解析路径 */
|
|
37
|
+
resolve(id: string, from: string): string | null | undefined;
|
|
38
|
+
/** 解析内部模块 */
|
|
39
|
+
resolveBuiltin(id: string): string | undefined;
|
|
40
|
+
/** 解析文件 */
|
|
41
|
+
resolveFile(id: string, from: string): string | null | undefined;
|
|
42
|
+
/** 解析文件目标 */
|
|
43
|
+
resolveTarget(path: string): string | undefined;
|
|
44
|
+
/** 解析目录 */
|
|
45
|
+
resolveDir(path: string): string | undefined;
|
|
46
|
+
/** 解析 main 文件 */
|
|
47
|
+
resolveMainFile(path: string, pkg: PackageDescription): string | undefined;
|
|
48
|
+
/** 解析 index 文件 */
|
|
49
|
+
resolveIndex(path: string): string | undefined;
|
|
50
|
+
/** 解析扩展名 */
|
|
51
|
+
resolveExtensions(path: string): string | undefined;
|
|
52
|
+
/** 解析包自身 */
|
|
53
|
+
resolveSelf(name: string, path: string, from: string): string | null | undefined;
|
|
54
|
+
/** 解析模块 */
|
|
55
|
+
resolveModule(id: string, from: string): string | null | undefined;
|
|
56
|
+
/** 解析模块导入 */
|
|
57
|
+
resolveModuleImports(id: string, from: string): string | null | undefined;
|
|
58
|
+
/** 解析模块导出 */
|
|
59
|
+
resolveModuleExports(id: string, from: string, pkg: PackageDescription): string | null | undefined;
|
|
60
|
+
};
|
package/dist/sys.js
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2025-06-29 16:06:27
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.sys = void 0;
|
|
10
|
+
/**
|
|
11
|
+
*****************************************
|
|
12
|
+
* 加载依赖
|
|
13
|
+
*****************************************
|
|
14
|
+
*/
|
|
15
|
+
const node_url_1 = require("node:url");
|
|
16
|
+
const node_path_1 = require("node:path");
|
|
17
|
+
const node_module_1 = require("node:module");
|
|
18
|
+
const relative_1 = require("./relative");
|
|
19
|
+
const stat_1 = require("./stat");
|
|
20
|
+
const loadPackageDescription_1 = require("./loadPackageDescription");
|
|
21
|
+
const resolveModuleId_1 = require("./resolveModuleId");
|
|
22
|
+
const resolveModuleDir_1 = require("./resolveModuleDir");
|
|
23
|
+
const resolveAlias_1 = require("./resolveAlias");
|
|
24
|
+
const resolvePaths_1 = require("./resolvePaths");
|
|
25
|
+
const resolveImports_1 = require("./resolveImports");
|
|
26
|
+
const resolveExports_1 = require("./resolveExports");
|
|
27
|
+
/**
|
|
28
|
+
*****************************************
|
|
29
|
+
* 全局缓存
|
|
30
|
+
*****************************************
|
|
31
|
+
*/
|
|
32
|
+
const cache = new Map();
|
|
33
|
+
/**
|
|
34
|
+
*****************************************
|
|
35
|
+
* 文件系统
|
|
36
|
+
*****************************************
|
|
37
|
+
*/
|
|
38
|
+
exports.sys = {
|
|
39
|
+
/** 解析基准路径 */
|
|
40
|
+
baseUrl: undefined,
|
|
41
|
+
/** 别名配置 */
|
|
42
|
+
alias: undefined,
|
|
43
|
+
/** 路径配置 */
|
|
44
|
+
paths: undefined,
|
|
45
|
+
/** 缓存 ID */
|
|
46
|
+
cacheSalt: '',
|
|
47
|
+
/** 缓存 */
|
|
48
|
+
cache,
|
|
49
|
+
/** 当前目录 */
|
|
50
|
+
cwd: process.cwd(),
|
|
51
|
+
/** 是否解析模块 */
|
|
52
|
+
module: true,
|
|
53
|
+
/** 是否解析模块导出 */
|
|
54
|
+
moduleExports: true,
|
|
55
|
+
/** 解析 main 字段 */
|
|
56
|
+
mainFields: ['main'],
|
|
57
|
+
/** 解析条件 */
|
|
58
|
+
conditions: ['require', 'node'],
|
|
59
|
+
/** 解析扩展名 */
|
|
60
|
+
extensions: ['.ts', '.tsx', '.js', '.json', '.jsx', '.mjs', '.cjs', '.mts', '.cts', '.node', '.wasm'],
|
|
61
|
+
/** 解析路径 */
|
|
62
|
+
resolve(id, from) {
|
|
63
|
+
const cacheId = `${from}\x00${id}`;
|
|
64
|
+
const cacheSaltId = `${cacheId}\x00${this.cacheSalt}`;
|
|
65
|
+
// 存在缓存时,直接返回
|
|
66
|
+
if (this.cache.has(cacheId)) {
|
|
67
|
+
return this.cache.get(cacheId);
|
|
68
|
+
}
|
|
69
|
+
// 存在缓存时,直接返回
|
|
70
|
+
if (this.cache.has(cacheSaltId)) {
|
|
71
|
+
return this.cache.get(cacheSaltId);
|
|
72
|
+
}
|
|
73
|
+
// 添加缓存,避免循环解析
|
|
74
|
+
this.cache.set(cacheSaltId, null);
|
|
75
|
+
// 匹配规则
|
|
76
|
+
const rules = [
|
|
77
|
+
[cacheId, this.resolveBuiltin],
|
|
78
|
+
[cacheSaltId, this.resolveModuleImports],
|
|
79
|
+
[cacheId, this.resolveFile],
|
|
80
|
+
[cacheSaltId, this.resolveModule],
|
|
81
|
+
];
|
|
82
|
+
// 解析规则
|
|
83
|
+
for (let i = 0, l = rules.length; i < l; i++) {
|
|
84
|
+
const [cacheId, handler] = rules[i];
|
|
85
|
+
const resolved = handler.call(this, id, from);
|
|
86
|
+
if (resolved !== undefined) {
|
|
87
|
+
this.cache.set(cacheId, resolved);
|
|
88
|
+
return resolved;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
/** 解析内部模块 */
|
|
93
|
+
resolveBuiltin(id) {
|
|
94
|
+
if (node_module_1.builtinModules.includes(id)) {
|
|
95
|
+
return id;
|
|
96
|
+
}
|
|
97
|
+
// 处理内置模块
|
|
98
|
+
const prefix = id.slice(0, 5);
|
|
99
|
+
if (prefix === 'node:') {
|
|
100
|
+
return id;
|
|
101
|
+
}
|
|
102
|
+
// 处理 URL 路径
|
|
103
|
+
if (prefix === 'file:') {
|
|
104
|
+
return (0, node_url_1.fileURLToPath)(id);
|
|
105
|
+
}
|
|
106
|
+
// 处理资源路径
|
|
107
|
+
if (prefix === 'data:' || prefix === 'http:' || id.startsWith('https:')) {
|
|
108
|
+
return id;
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
/** 解析文件 */
|
|
112
|
+
resolveFile(id, from) {
|
|
113
|
+
// 解析相对路径
|
|
114
|
+
if ((0, relative_1.isRelative)(id)) {
|
|
115
|
+
return this.resolveTarget((0, node_path_1.resolve)(from, id));
|
|
116
|
+
}
|
|
117
|
+
// 解析绝对路径
|
|
118
|
+
if ((0, node_path_1.isAbsolute)(id)) {
|
|
119
|
+
return this.resolveTarget(id);
|
|
120
|
+
}
|
|
121
|
+
// 解析别名
|
|
122
|
+
if (this.alias) {
|
|
123
|
+
const alias = (0, resolveAlias_1.resolveAlias)(this.alias);
|
|
124
|
+
const resolved = alias.match(resolve => resolve(id, alias => this.resolve(alias, this.cwd)));
|
|
125
|
+
if (resolved !== undefined) {
|
|
126
|
+
return resolved;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// 解析基准路径
|
|
130
|
+
if (this.baseUrl) {
|
|
131
|
+
const resolved = this.resolveTarget((0, node_path_1.resolve)(this.baseUrl, id));
|
|
132
|
+
if (resolved !== undefined) {
|
|
133
|
+
return resolved;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// 解析路径映射
|
|
137
|
+
if (this.paths) {
|
|
138
|
+
const baseUrl = this.baseUrl || this.cwd;
|
|
139
|
+
const paths = (0, resolvePaths_1.resolvePaths)(this.paths);
|
|
140
|
+
const resolved = paths.match(resolve => resolve(id, alias => this.resolve(alias, baseUrl)));
|
|
141
|
+
if (resolved !== undefined) {
|
|
142
|
+
return resolved;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
/** 解析文件目标 */
|
|
147
|
+
resolveTarget(path) {
|
|
148
|
+
const stats = (0, stat_1.stat)(path);
|
|
149
|
+
// 目标存在时,需要解析目标是目录的情况
|
|
150
|
+
if (stats) {
|
|
151
|
+
return stats.isDirectory() ? this.resolveDir(path) : path;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
return this.resolveExtensions(path);
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
/** 解析目录 */
|
|
158
|
+
resolveDir(path) {
|
|
159
|
+
const pkg = (0, loadPackageDescription_1.resolvePackageDescription)(path);
|
|
160
|
+
// 解析主入口配置
|
|
161
|
+
if (pkg && pkg.dir === path && pkg.config) {
|
|
162
|
+
return this.resolveMainFile(path, pkg.config);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
return this.resolveIndex(path);
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
/** 解析 main 文件 */
|
|
169
|
+
resolveMainFile(path, pkg) {
|
|
170
|
+
for (let i = 0, l = this.mainFields.length; i < l; i++) {
|
|
171
|
+
const main = pkg[this.mainFields[i]];
|
|
172
|
+
// 存在主入口文件配置
|
|
173
|
+
if (main) {
|
|
174
|
+
return this.resolveTarget((0, node_path_1.resolve)(path, main));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// 解析 index 文件
|
|
178
|
+
return this.resolveIndex(path);
|
|
179
|
+
},
|
|
180
|
+
/** 解析 index 文件 */
|
|
181
|
+
resolveIndex(path) {
|
|
182
|
+
return this.resolveExtensions(path + node_path_1.sep + 'index');
|
|
183
|
+
},
|
|
184
|
+
/** 解析扩展名 */
|
|
185
|
+
resolveExtensions(path) {
|
|
186
|
+
for (let i = 0, l = this.extensions.length; i < l; i++) {
|
|
187
|
+
const file = path + this.extensions[i];
|
|
188
|
+
const stats = (0, stat_1.stat)(file);
|
|
189
|
+
if (stats && stats.isFile()) {
|
|
190
|
+
return file;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
/** 解析包自身 */
|
|
195
|
+
resolveSelf(name, path, from) {
|
|
196
|
+
const pkg = (0, loadPackageDescription_1.resolvePackageDescription)(from);
|
|
197
|
+
if (!pkg || !pkg.config) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// 获取配置
|
|
201
|
+
const { dir, config } = pkg;
|
|
202
|
+
// 解析模块导出
|
|
203
|
+
if (config.name === name) {
|
|
204
|
+
return this.resolveModuleExports(path, dir, config) || null;
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
/** 解析模块 */
|
|
208
|
+
resolveModule(id, from) {
|
|
209
|
+
const [name, subpath] = (0, resolveModuleId_1.resolveModuleId)(id);
|
|
210
|
+
const path = subpath === './' ? '.' : subpath;
|
|
211
|
+
// 解析当前包本身
|
|
212
|
+
const resolved = this.resolveSelf(name, path, from);
|
|
213
|
+
if (resolved !== undefined || this.module === false) {
|
|
214
|
+
return resolved;
|
|
215
|
+
}
|
|
216
|
+
// 解析模块目录
|
|
217
|
+
const dir = (0, resolveModuleDir_1.resolveModuleDir)(name, from);
|
|
218
|
+
if (!dir) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
// 读取包描述文件
|
|
222
|
+
const pkg = (0, loadPackageDescription_1.resolvePackageDescription)(dir);
|
|
223
|
+
if (pkg && pkg.dir === dir && pkg.config) {
|
|
224
|
+
return this.resolveModuleExports(path, dir, pkg.config);
|
|
225
|
+
}
|
|
226
|
+
// 解析目标路径
|
|
227
|
+
if (path === '.') {
|
|
228
|
+
return this.resolveIndex(path);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return this.resolveTarget((0, node_path_1.resolve)(dir, path));
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
/** 解析模块导入 */
|
|
235
|
+
resolveModuleImports(id, from) {
|
|
236
|
+
const pkg = id.charAt(0) === '#' && (0, loadPackageDescription_1.resolvePackageDescription)(from);
|
|
237
|
+
if (!pkg || !pkg.config || !pkg.config.imports) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// 执行配置
|
|
241
|
+
const imports = pkg.config.imports;
|
|
242
|
+
const dir = pkg.dir;
|
|
243
|
+
// 执行解析
|
|
244
|
+
return (0, resolveImports_1.resolveImports)(id, this.conditions, imports, path => this.resolve(path, dir));
|
|
245
|
+
},
|
|
246
|
+
/** 解析模块导出 */
|
|
247
|
+
resolveModuleExports(id, from, pkg) {
|
|
248
|
+
// 处理导出配置
|
|
249
|
+
if (pkg.exports && this.moduleExports) {
|
|
250
|
+
return (0, resolveExports_1.resolveExports)(id, this.conditions, pkg.exports, path => this.resolveTarget((0, node_path_1.resolve)(from, path))) || null;
|
|
251
|
+
}
|
|
252
|
+
// 解析目标路径
|
|
253
|
+
if (id === '.') {
|
|
254
|
+
return this.resolveMainFile(from, pkg);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
return this.resolveTarget((0, node_path_1.resolve)(from, id));
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
};
|
package/esm/cache.mjs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2026-03-19 12:43:17
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
export function cache(map) {
|
|
9
|
+
const cached = map || new Map();
|
|
10
|
+
// 获取缓存
|
|
11
|
+
function get(id, handler) {
|
|
12
|
+
return cached.has(id) ? cached.get(id) : set(id, handler);
|
|
13
|
+
}
|
|
14
|
+
// 更新缓存
|
|
15
|
+
function set(id, handler) {
|
|
16
|
+
const result = handler(id);
|
|
17
|
+
cached.set(id, result);
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
// 返回结果
|
|
21
|
+
return { set, get };
|
|
22
|
+
}
|
package/esm/dict.mjs
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2025-06-11 22:56:35
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 字典对象
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
export class Dict {
|
|
14
|
+
constructor() {
|
|
15
|
+
/** 键值映射 */
|
|
16
|
+
this.data = {};
|
|
17
|
+
/** 键列表 */
|
|
18
|
+
this.keys = [];
|
|
19
|
+
}
|
|
20
|
+
/** 添加映射 */
|
|
21
|
+
set(key, value) {
|
|
22
|
+
if (!Object.prototype.hasOwnProperty.call(this.data, key)) {
|
|
23
|
+
this.keys.push(key);
|
|
24
|
+
}
|
|
25
|
+
// 更新值
|
|
26
|
+
this.data[key] = value;
|
|
27
|
+
// 返回自身
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
/** 获取值 */
|
|
31
|
+
get(key) {
|
|
32
|
+
return this.data[key];
|
|
33
|
+
}
|
|
34
|
+
/** 遍历 */
|
|
35
|
+
map(handler) {
|
|
36
|
+
const dict = new Dict();
|
|
37
|
+
// 遍历映射
|
|
38
|
+
this.keys.forEach(key => {
|
|
39
|
+
dict.set(key, handler(key, this.data[key]));
|
|
40
|
+
});
|
|
41
|
+
// 返回结果
|
|
42
|
+
return dict;
|
|
43
|
+
}
|
|
44
|
+
/** 排序 */
|
|
45
|
+
sort(handler) {
|
|
46
|
+
this.keys.sort(handler);
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
/** 匹配对象 */
|
|
50
|
+
match(handler) {
|
|
51
|
+
const keys = this.keys;
|
|
52
|
+
const data = this.data;
|
|
53
|
+
const size = keys.length;
|
|
54
|
+
// 遍历匹配
|
|
55
|
+
for (let i = 0; i < size; i++) {
|
|
56
|
+
const key = keys[i];
|
|
57
|
+
const result = handler(data[key], key);
|
|
58
|
+
if (result !== undefined) {
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
package/esm/download.mjs
CHANGED
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { tmpdir } from 'node:os';
|
|
14
14
|
import { resolve, join, dirname } from 'node:path';
|
|
15
|
-
import {
|
|
15
|
+
import { mkdir, rm, rename } from 'node:fs/promises';
|
|
16
16
|
import { createReadStream, createWriteStream } from 'node:fs';
|
|
17
17
|
import { Readable } from 'node:stream';
|
|
18
18
|
import { pipeline } from 'node:stream/promises';
|
|
19
19
|
import { retry } from './retry.mjs';
|
|
20
20
|
import { md5 } from './md5.mjs';
|
|
21
|
+
import { stat, pipe } from './promises.mjs';
|
|
21
22
|
import { Concurrency } from './concurrency.mjs';
|
|
22
23
|
/**
|
|
23
24
|
*****************************************
|
|
@@ -91,7 +92,7 @@ async function downloadFileByChunk(dest, url, init, options) {
|
|
|
91
92
|
// 创建下载目录
|
|
92
93
|
await mkdir(dir, { recursive: true });
|
|
93
94
|
// 合并文件
|
|
94
|
-
await chunkConcurrency.execute(path => pipe(path, stream));
|
|
95
|
+
await chunkConcurrency.execute(path => pipe(createReadStream(path), stream, { end: false }));
|
|
95
96
|
// 结束传输
|
|
96
97
|
stream.end();
|
|
97
98
|
// 重命名临时文件
|
|
@@ -154,26 +155,13 @@ function getDownloadURL(url) {
|
|
|
154
155
|
function getDownloadDir(url, options) {
|
|
155
156
|
return join(tmpdir(), 'downloads', generateDownloadID(getDownloadURL(url), options));
|
|
156
157
|
}
|
|
157
|
-
/**
|
|
158
|
-
*****************************************
|
|
159
|
-
* 写入文件流
|
|
160
|
-
*****************************************
|
|
161
|
-
*/
|
|
162
|
-
function pipe(src, dest) {
|
|
163
|
-
return new Promise((resolve, reject) => {
|
|
164
|
-
const stream = createReadStream(src);
|
|
165
|
-
stream.once('close', resolve);
|
|
166
|
-
stream.once('error', reject);
|
|
167
|
-
stream.pipe(dest, { end: false });
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
158
|
/**
|
|
171
159
|
*****************************************
|
|
172
160
|
* 下载文件
|
|
173
161
|
*****************************************
|
|
174
162
|
*/
|
|
175
163
|
async function downloadFile(dest, url, init, options) {
|
|
176
|
-
const stats = await stat(dest)
|
|
164
|
+
const stats = await stat(dest);
|
|
177
165
|
// 已经存在文件,不再下载
|
|
178
166
|
if (stats && stats.isFile() && !options.force) {
|
|
179
167
|
options.onProgress && options.onProgress(stats.size, stats.size);
|
package/esm/downloadFile.mjs
CHANGED
|
@@ -26,11 +26,10 @@ export async function downloadFile(dest, url) {
|
|
|
26
26
|
if (size < total) {
|
|
27
27
|
print(` -> ${((size / total) * 100).toFixed(2)}% (${format(size)}/${format(total)})`);
|
|
28
28
|
}
|
|
29
|
-
else {
|
|
30
|
-
print('[download]: done', true);
|
|
31
|
-
}
|
|
32
29
|
},
|
|
33
30
|
});
|
|
31
|
+
// 下载完成
|
|
32
|
+
print('[download]: done', true);
|
|
34
33
|
}
|
|
35
34
|
/**
|
|
36
35
|
*****************************************
|
|
@@ -52,6 +51,16 @@ function format(bytes) {
|
|
|
52
51
|
// 返回默认
|
|
53
52
|
return `${(bytes / limit).toFixed(2)} TB`;
|
|
54
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
*****************************************
|
|
56
|
+
* 上移一行并清除该行内容
|
|
57
|
+
* a. 移动光标上移一行:\x1B[1A
|
|
58
|
+
* b. 清除当前行:\x1B[2K
|
|
59
|
+
* c. 移动光标到行首:\x1B[0G
|
|
60
|
+
*****************************************
|
|
61
|
+
*/
|
|
62
|
+
const clearCurrentLine = '\x1B[0G\x1B[2K';
|
|
63
|
+
const clearPreviousLine = '\x1B[1A\x1B[2K';
|
|
55
64
|
/**
|
|
56
65
|
*****************************************
|
|
57
66
|
* 进度条
|
|
@@ -59,23 +68,20 @@ function format(bytes) {
|
|
|
59
68
|
*/
|
|
60
69
|
function stdout() {
|
|
61
70
|
let progressContent = '';
|
|
62
|
-
let progressSize = 0;
|
|
63
71
|
let progressTime = 0;
|
|
64
72
|
return function print(content, flush) {
|
|
65
73
|
const now = Date.now();
|
|
66
74
|
if ((content === progressContent || now - progressTime < 600) && !flush) {
|
|
67
75
|
return;
|
|
68
76
|
}
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
// 清除内容
|
|
78
|
+
if (progressContent) {
|
|
79
|
+
process.stdout.write(clearCurrentLine);
|
|
80
|
+
process.stdout.write(clearPreviousLine);
|
|
81
|
+
}
|
|
82
|
+
// 更新内容
|
|
71
83
|
progressContent = content;
|
|
72
84
|
progressTime = now;
|
|
73
|
-
|
|
74
|
-
if (diff > 0) {
|
|
75
|
-
process.stdout.write(`\r${content}${' '.repeat(diff)}`);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
process.stdout.write(`\r${content}`);
|
|
79
|
-
}
|
|
85
|
+
process.stdout.write(content + '\n');
|
|
80
86
|
};
|
|
81
87
|
}
|
package/esm/gzip.mjs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*****************************************
|
|
3
|
+
* Created by edonet@163.com
|
|
4
|
+
* Created on 2026-03-20 23:07:36
|
|
5
|
+
*****************************************
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
/**
|
|
9
|
+
*****************************************
|
|
10
|
+
* 加载依赖
|
|
11
|
+
*****************************************
|
|
12
|
+
*/
|
|
13
|
+
import { createReadStream, createWriteStream } from 'node:fs';
|
|
14
|
+
import { createGzip, createGunzip } from 'node:zlib';
|
|
15
|
+
import { rm } from './promises.mjs';
|
|
16
|
+
/**
|
|
17
|
+
*****************************************
|
|
18
|
+
* gzip
|
|
19
|
+
*****************************************
|
|
20
|
+
*/
|
|
21
|
+
export function gzip(src, dest, options) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const readable = createReadStream(src);
|
|
24
|
+
const gzip = createGzip(options);
|
|
25
|
+
const writable = createWriteStream(dest);
|
|
26
|
+
readable.pipe(gzip)
|
|
27
|
+
.pipe(writable)
|
|
28
|
+
.once('finish', () => resolve(dest))
|
|
29
|
+
.once('error', err => rm(dest).then(() => reject(err)));
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
*****************************************
|
|
34
|
+
* ungzip
|
|
35
|
+
*****************************************
|
|
36
|
+
*/
|
|
37
|
+
export function ungzip(src, dest, options) {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const readable = createReadStream(src);
|
|
40
|
+
const gzip = createGunzip(options);
|
|
41
|
+
const writable = createWriteStream(dest);
|
|
42
|
+
readable.pipe(gzip)
|
|
43
|
+
.pipe(writable)
|
|
44
|
+
.once('finish', () => resolve(dest))
|
|
45
|
+
.once('error', err => rm(dest).then(() => reject(err)));
|
|
46
|
+
});
|
|
47
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[
|
|
2
|
+
{"path": "./sys", "names": ["sys"]},
|
|
3
|
+
{"path": "./match", "names": ["unary", "noop", "nil", "match"]},
|
|
4
|
+
{"path": "./split", "names": ["split"]},
|
|
5
|
+
{"path": "./cache", "names": ["cache"]},
|
|
6
|
+
{"path": "./retry", "names": ["retry"]},
|
|
7
|
+
{"path": "./dict", "names": ["Dict"]},
|
|
8
|
+
{"path": "node:path", "names": ["resolve", "join", "isAbsolute"]},
|
|
9
|
+
{"path": "./relative", "names": ["relative", "isRelative"]},
|
|
10
|
+
{"path": "./dirname", "names": ["dirname"]},
|
|
11
|
+
{"path": "./isEsmModule", "names": ["isEsmModule", "isEsmFile", "isEsmPackage"]},
|
|
12
|
+
{"path": "./stat", "names": ["stat", "isDir", "isFile"]},
|
|
13
|
+
{"path": "./readFile", "names": ["readFile"]},
|
|
14
|
+
{"path": "./writeFile", "names": ["writeFile"]},
|
|
15
|
+
{"path": "./copy", "names": ["copy"]},
|
|
16
|
+
{"path": "./rm", "names": ["rm"]},
|
|
17
|
+
{"path": "./lookup", "names": ["lookup"]},
|
|
18
|
+
{"path": "./md5", "names": ["md5"]},
|
|
19
|
+
{"path": "./jsonc", "names": ["json", "jsonc"]},
|
|
20
|
+
{"path": "./findUp", "names": ["findUp"]},
|
|
21
|
+
{"path": "./download", "names": ["download"]},
|
|
22
|
+
{"path": "./gzip", "names": ["gzip", "ungzip"]},
|
|
23
|
+
{"path": "./loadPackageDescription", "names": ["loadPackageDescription", "resolvePackageDescription"]},
|
|
24
|
+
{"path": "./loadTsConfig", "names": ["loadTsConfig", "loadCompilerOptions", "resolveTsConfig"]},
|
|
25
|
+
{"path": "./resolveAlias", "names": ["resolveAlias", "resolveDict"]},
|
|
26
|
+
{"path": "./resolvePaths", "names": ["resolvePaths"]},
|
|
27
|
+
{"path": "./resolvePath", "names": ["resolvePath"]},
|
|
28
|
+
{"path": "./resolveFile", "names": ["resolveFile"]},
|
|
29
|
+
{"path": "./resolveDirect", "names": ["resolveDirect"]},
|
|
30
|
+
{"path": "./resolveImports", "names": ["resolveImports"]},
|
|
31
|
+
{"path": "./resolveExports", "names": ["resolveExports"]},
|
|
32
|
+
{"path": "./resolveModuleDir", "names": ["resolveModuleDir", "resolveModuleDirs"]},
|
|
33
|
+
{"path": "./resolveModuleId", "names": ["resolveModuleId"]}
|
|
34
|
+
]
|