@e-mc/module 0.12.8 → 0.13.0

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.
Files changed (3) hide show
  1. package/README.md +20 -13
  2. package/index.js +196 -173
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @e-mc/module
2
2
 
3
- * NodeJS 18
3
+ * NodeJS 18.20.5 LTS
4
4
  * ES2022
5
5
 
6
6
  ## General Usage
@@ -9,7 +9,7 @@
9
9
 
10
10
  ## Interface
11
11
 
12
- * [View Source](https://www.unpkg.com/@e-mc/types@0.12.7/lib/index.d.ts)
12
+ * [View Source](https://www.unpkg.com/@e-mc/types@0.13.0/lib/index.d.ts)
13
13
 
14
14
  ```typescript
15
15
  import type { LogStatus } from "./squared";
@@ -17,8 +17,8 @@ import type { LogStatus } from "./squared";
17
17
  import type { IHost } from "./index";
18
18
  import type { IAbortComponent, IPermission } from "./core";
19
19
  import type { LOG_TYPE, STATUS_TYPE, ExecCommand, LogArguments, LogComponent, LogDate, LogFailOptions, LogMessageOptions, LogOptions, LogProcessOptions, LogTime, LogType, LogValue, LoggerFormat, StatusType } from "./logger";
20
- import type { AsHashOptions, CheckSemVerOptions, CopyDirOptions, CopyDirResult, CopyFileOptions, CreateDirOptions, DeleteFileOptions, GlobDirOptions, MoveFileOptions, PackageVersionOptions, ParseFunctionOptions, PermissionOptions, ProtocolType, ReadBufferOptions, ReadFileCallback, ReadFileOptions, ReadHashOptions, ReadTextOptions, RemoveDirOptions, TempDirOptions, WriteFileOptions } from "./module";
21
- import type { Settings } from "./node";
20
+ import type { AsHashOptions, CheckSemVerOptions, CopyDirOptions, CopyDirResult, CopyFileOptions, CreateDirOptions, DeleteFileOptions, DirectoryActionType, FileActionType, GlobDirOptions, MoveFileOptions, PackageVersionOptions, ParseFunctionOptions, PermissionOptions, ProtocolType, ReadBufferOptions, ReadFileCallback, ReadFileOptions, ReadHashOptions, ReadTextOptions, RemoveDirOptions, TempDirOptions, WriteFileOptions } from "./module";
21
+ import type { ErrorCode, Settings } from "./node";
22
22
  import type { LoggerFormatSettings } from "/settings";
23
23
 
24
24
  import type { SpawnOptions } from "node:child_process";
@@ -138,26 +138,32 @@ interface IModule extends EventEmitter, IAbortComponent {
138
138
  on(event: "file:delete", listener: (src: string, options?: DeleteFileOptions) => void): this;
139
139
  on(event: "file:copy", listener: (dest: string, options?: CopyFileOptions) => void): this;
140
140
  on(event: "file:move", listener: (dest: string, options?: MoveFileOptions) => void): this;
141
+ on(event: "file:permission", listener: (src: string, type?: FileActionType) => void): this;
141
142
  on(event: "dir:create", listener: (src: string, options?: CreateDirOptions) => void): this;
142
143
  on(event: "dir:remove", listener: (src: string, options?: RemoveDirOptions) => void): this;
144
+ on(event: "dir:permission", listener: (src: string, type?: DirectoryActionType) => void): this;
143
145
  once(event: "exec", listener: (command: ExecCommand, options?: SpawnOptions) => void): this;
144
146
  once(event: "error", listener: (err: Error) => void): this;
145
- once(event: "file:read", listener: (src: string, data: Buffer | string, options?: ReadFileOptions) => void): this;
147
+ once(event: "file:read", listener: (src: string, data: Buffer | string,, options?: ReadFileOptions) => void): this;
146
148
  once(event: "file:write", listener: (src: string, options?: WriteFileOptions) => void): this;
147
149
  once(event: "file:delete", listener: (src: string, options?: DeleteFileOptions) => void): this;
148
150
  once(event: "file:copy", listener: (dest: string, options?: CopyFileOptions) => void): this;
149
151
  once(event: "file:move", listener: (dest: string, options?: MoveFileOptions) => void): this;
152
+ once(event: "file:permission", listener: (src: string, type?: FileActionType) => void): this;
150
153
  once(event: "dir:create", listener: (src: string, options?: CreateDirOptions) => void): this;
151
154
  once(event: "dir:remove", listener: (src: string, options?: RemoveDirOptions) => void): this;
155
+ once(event: "dir:permission", listener: (src: string, type?: DirectoryActionType) => void): this;
152
156
  emit(event: "exec", command: ExecCommand, options?: SpawnOptions): boolean;
153
157
  emit(event: "error", err: Error): boolean;
154
- emit(event: "file:read", src: string, data: Buffer | string, options?: ReadFileOptions): boolean;
158
+ emit(event: "file:read", src: string, data: Buffer | string,, options?: ReadFileOptions): boolean;
155
159
  emit(event: "file:write", src: string, options?: WriteFileOptions): boolean;
156
160
  emit(event: "file:delete", src: string, options?: DeleteFileOptions): boolean;
157
161
  emit(event: "file:copy", dest: string, options?: CopyFileOptions): boolean;
158
162
  emit(event: "file:move", dest: string, options?: MoveFileOptions): boolean;
163
+ emit(event: "file:permission", src: string, type?: FileActionType): boolean;
159
164
  emit(event: "dir:create", src: string, options?: CreateDirOptions): boolean;
160
165
  emit(event: "dir:remove", src: string, options?: RemoveDirOptions): boolean;
166
+ emit(event: "dir:permission", src: string, type?: DirectoryActionType): boolean;
161
167
  }
162
168
 
163
169
  interface ModuleConstructor {
@@ -193,10 +199,11 @@ interface ModuleConstructor {
193
199
  hasLogType(value: LogType): boolean;
194
200
  isURL(value: string, ...exclude: string[]): boolean;
195
201
  isFile(value: string | URL, type?: ProtocolType): boolean;
196
- isDir(value: string | URL): boolean;
202
+ isDir(value: string | URL, absolute?: boolean): boolean;
197
203
  isPath(value: string | URL, type?: "unc" | "unc-exists"): boolean;
198
204
  isPath(value: string | URL, isFile?: boolean): boolean;
199
- isErrorCode(err: unknown, ...code: string[]): boolean;
205
+ /** @deprecated @e-mc/types */
206
+ isErrorCode(err: unknown, ...code: unknown[]): err is Required<ErrorCode>;
200
207
  fromLocalPath(value: string): string;
201
208
  resolveFile(value: string): string;
202
209
  resolvePath(value: string, base: string | URL): string;
@@ -414,11 +421,11 @@ interface LoggerModule {
414
421
 
415
422
  ## References
416
423
 
417
- - https://www.unpkg.com/@e-mc/types@0.12.7/lib/core.d.ts
418
- - https://www.unpkg.com/@e-mc/types@0.12.7/lib/logger.d.ts
419
- - https://www.unpkg.com/@e-mc/types@0.12.7/lib/module.d.ts
420
- - https://www.unpkg.com/@e-mc/types@0.12.7/lib/node.d.ts
421
- - https://www.unpkg.com/@e-mc/types@0.12.7/lib/settings.d.ts
424
+ - https://www.unpkg.com/@e-mc/types@0.13.0/lib/core.d.ts
425
+ - https://www.unpkg.com/@e-mc/types@0.13.0/lib/logger.d.ts
426
+ - https://www.unpkg.com/@e-mc/types@0.13.0/lib/module.d.ts
427
+ - https://www.unpkg.com/@e-mc/types@0.13.0/lib/node.d.ts
428
+ - https://www.unpkg.com/@e-mc/types@0.13.0/lib/settings.d.ts
422
429
 
423
430
  * https://www.npmjs.com/package/@types/node
424
431
 
package/index.js CHANGED
@@ -159,7 +159,7 @@ function setPnpmVer() {
159
159
  let baseDir;
160
160
  try {
161
161
  let pathname = path.resolve("node_modules/.modules.yaml"), config;
162
- if (fs.existsSync(pathname) && (0, types_1.isPlainObject)(config = parseYaml(pathname))) {
162
+ if (fs.existsSync(pathname) && (0, types_1.isObject)(config = parseYaml(pathname))) {
163
163
  if (config.nodeLinker === 'hoisted') {
164
164
  return PNPM_VER = true;
165
165
  }
@@ -175,7 +175,7 @@ function setPnpmVer() {
175
175
  if (!fs.existsSync(pathname = path.resolve(baseDir, "lock.yaml"))) {
176
176
  baseDir = undefined;
177
177
  }
178
- else if ((0, types_1.isPlainObject)(config = parseYaml(pathname))) {
178
+ else if ((0, types_1.isObject)(config = parseYaml(pathname))) {
179
179
  for (const name in config.packages) {
180
180
  addPnpmPackage(items, name);
181
181
  }
@@ -208,7 +208,7 @@ function setYarnVer() {
208
208
  try {
209
209
  const pathname = path.resolve(".yarnrc.yml");
210
210
  let config;
211
- if (fs.existsSync(pathname) && (0, types_1.isPlainObject)(config = parseYaml(pathname)) && config.nodeLinker === 'node-modules') {
211
+ if (fs.existsSync(pathname) && (0, types_1.isObject)(config = parseYaml(pathname)) && config.nodeLinker === 'node-modules') {
212
212
  return YARN_VER = true;
213
213
  }
214
214
  }
@@ -393,14 +393,14 @@ function tryCreateDir(value) {
393
393
  }
394
394
  return false;
395
395
  }
396
- function tryRemoveDir(value, empty, recursive) {
396
+ function tryRemoveDir(srcDir, empty, recursive) {
397
397
  const temp = typeof empty === 'number';
398
398
  let options;
399
399
  if (!temp) {
400
400
  try {
401
- fs.rmSync(value, { recursive, force: true });
401
+ fs.rmSync(srcDir, { recursive, force: true });
402
402
  if (empty) {
403
- fs.mkdirSync(value);
403
+ fs.mkdirSync(srcDir);
404
404
  }
405
405
  return [];
406
406
  }
@@ -408,30 +408,11 @@ function tryRemoveDir(value, empty, recursive) {
408
408
  }
409
409
  options = { recursive };
410
410
  }
411
- value = Module.normalizePath(value, 1);
412
411
  const failed = [];
413
- const nameMap = new WeakMap();
414
- let files;
415
- if (temp) {
416
- files = [];
417
- fs.readdirSync(value).forEach(name => {
418
- try {
419
- const stat = fs.statSync(value + name);
420
- nameMap.set(stat, name);
421
- files.push(stat);
422
- }
423
- catch {
424
- failed.push(value + name);
425
- }
426
- });
427
- }
428
- else {
429
- files = fs.readdirSync(value, { withFileTypes: true });
430
- }
431
412
  const current = Date.now();
432
- for (let i = 0, length = files.length; i < length; ++i) {
433
- const file = files[i];
434
- const pathname = value + (file.name || nameMap.get(file));
413
+ let entry;
414
+ fs.readdirSync(srcDir, { withFileTypes: true }).forEach(file => {
415
+ const pathname = path.join(srcDir, file.name);
435
416
  try {
436
417
  if (file.isDirectory()) {
437
418
  if (recursive) {
@@ -443,16 +424,16 @@ function tryRemoveDir(value, empty, recursive) {
443
424
  }
444
425
  }
445
426
  }
446
- else if (!temp || file.ctimeMs + empty <= current) {
427
+ else if (!temp || (entry = fs.statSync(pathname)) && entry.ctimeMs + empty <= current) {
447
428
  fs.unlinkSync(pathname);
448
429
  }
449
430
  }
450
431
  catch {
451
432
  failed.push(pathname);
452
433
  }
453
- }
434
+ });
454
435
  if (!empty && failed.length === 0) {
455
- fs.rmdirSync(value);
436
+ fs.rmdirSync(srcDir);
456
437
  }
457
438
  return failed;
458
439
  }
@@ -598,48 +579,77 @@ function addCacheItem(map, key, data, cache = false) {
598
579
  const length = Buffer.byteLength(data);
599
580
  if (length >= MEMORY_CACHE_DISK.min_size && length <= MEMORY_CACHE_DISK.max_size) {
600
581
  key = Module.toPosix(key, true);
601
- let valid = true;
602
- if (MEMORY_CACHE_DISK.exclude) {
603
- for (const value of MEMORY_CACHE_DISK.exclude) {
604
- if (value.startsWith('!')) {
605
- if (isMatch(key, value.substring(1))) {
606
- valid = true;
607
- break;
608
- }
609
- }
610
- else if (valid && isMatch(key, value)) {
611
- valid = false;
612
- }
613
- }
582
+ if (MEMORY_CACHE_DISK.exclude && isMatch(key, MEMORY_CACHE_DISK.exclude)) {
583
+ return;
614
584
  }
615
- if (valid && (cache || !MEMORY_CACHE_DISK.include || MEMORY_CACHE_DISK.include.some(value => isMatch(key, value)))) {
585
+ if (cache || !MEMORY_CACHE_DISK.include || isMatch(key, MEMORY_CACHE_DISK.include)) {
616
586
  map.set(key, [Date.now(), data]);
617
587
  }
618
588
  }
619
589
  }
620
- function getCacheTotal() {
590
+ function getCacheSize() {
621
591
  return CACHE_READTEXT.size + CACHE_READBUFFER.size + CACHE_READCJS.size;
622
592
  }
623
- function isMatch(key, value) {
624
- return pm.isMatch(key, value, { nocase: PLATFORM_WIN32, matchBase: value.startsWith('*') && !value.includes('/') });
593
+ function createMatchNegate(values) {
594
+ if (!(0, types_1.isArray)(values)) {
595
+ return null;
596
+ }
597
+ const result = [[], []];
598
+ const base = [];
599
+ const baseAbs = [];
600
+ const relative = [];
601
+ const relativeAbs = [];
602
+ for (let value of values) {
603
+ value = Module.toPosix(value, true);
604
+ const invert = value.startsWith('!');
605
+ if (invert) {
606
+ value = value.substring(1);
607
+ }
608
+ if (value.startsWith('*') && !value.includes('/')) {
609
+ (invert ? relativeAbs : relative).push(value);
610
+ }
611
+ else {
612
+ (invert ? baseAbs : base).push(value);
613
+ }
614
+ }
615
+ if (base.length > 0) {
616
+ result[0].push(pm(base, { nocase: PLATFORM_WIN32 }));
617
+ }
618
+ if (relative.length > 0) {
619
+ result[0].push(pm(relative, { nocase: PLATFORM_WIN32, matchBase: true }));
620
+ }
621
+ if (baseAbs.length > 0) {
622
+ result[1].push(pm(baseAbs, { nocase: PLATFORM_WIN32 }));
623
+ }
624
+ if (relativeAbs.length > 0) {
625
+ result[1].push(pm(relativeAbs, { nocase: PLATFORM_WIN32, matchBase: true }));
626
+ }
627
+ return result;
628
+ }
629
+ function isMatch(value, globs) {
630
+ return !globs[1].some(match => match(value)) && globs[0].some(match => match(value));
625
631
  }
626
632
  function listDir(src, paths, depth, include, exclude, excludeDir, outFiles) {
627
633
  const srcDir = path.join(src, ...paths);
628
- fs.readdirSync(srcDir, { withFileTypes: true }).forEach(file => {
629
- if (file.isFile()) {
630
- const pathname = path.join(srcDir, file.name);
631
- const pathglob = pathname.substring(src.length);
632
- if (include(pathglob) && !exclude?.(pathglob)) {
633
- outFiles.push(pathname);
634
+ try {
635
+ fs.readdirSync(srcDir, { withFileTypes: true }).forEach(file => {
636
+ if (file.isFile()) {
637
+ const pathname = path.join(srcDir, file.name);
638
+ const pathglob = pathname.substring(src.length);
639
+ if (include(pathglob) && !exclude?.(pathglob)) {
640
+ outFiles.push(pathname);
641
+ }
634
642
  }
635
- }
636
- else if (depth > 0 && file.isDirectory()) {
637
- const subDirs = paths.concat(file.name);
638
- if (!excludeDir?.includes(subDirs.join('/') + '/')) {
639
- listDir(src, subDirs, depth - 1, include, exclude, excludeDir, outFiles);
643
+ else if (depth > 0 && file.isDirectory()) {
644
+ const subDirs = paths.concat(file.name);
645
+ if (!excludeDir?.includes(subDirs.join('/') + '/')) {
646
+ listDir(src, subDirs, depth - 1, include, exclude, excludeDir, outFiles);
647
+ }
640
648
  }
641
- }
642
- });
649
+ });
650
+ }
651
+ catch {
652
+ }
643
653
  }
644
654
  function checkFunction(value) {
645
655
  if (typeof value === 'function') {
@@ -707,7 +717,7 @@ function setCpuAndMem(instance, options) {
707
717
  }
708
718
  }
709
719
  function checkExDev(err, src, dest) {
710
- if (Module.isErrorCode(err, 'EXDEV')) {
720
+ if ((0, types_1.isErrorCode)(err, 'EXDEV')) {
711
721
  try {
712
722
  fs.copyFileSync(src, dest);
713
723
  fs.unlinkSync(src);
@@ -838,7 +848,6 @@ function isPathUNC(value) {
838
848
  value = value.toString();
839
849
  return (VALUES["node.posix.strict"] && value.includes('/') ? /^\/\/[\w.-]+\/[\w-]+\$?\/[^\n]*?[^/]$/ : /^(?:\\\\|\/\/)[\w.-]+[\\/][\w-]+\$?[\\/][^\n]*?[^\\/]$/).test(value);
840
850
  }
841
- const isErrnoException = (value) => value instanceof Error && typeof value.code === 'string';
842
851
  const isConstructor = (value) => typeof value === 'function' && !!value.prototype?.constructor.name;
843
852
  const isHost = (value) => 'username' in value && typeof value.username === 'string';
844
853
  const hasAuth = (users, username) => !!username && (users === true || Array.isArray(users) && users.includes(username));
@@ -846,7 +855,7 @@ const formatLogMessage = (type, message, unit, ident) => !ident && (type & 256)
846
855
  const hideAbort = (err) => err.name === 'AbortError' && SETTINGS.abort === false;
847
856
  const asFile = (value) => typeof value === 'string' ? PLATFORM_WIN32 ? value.trim() : value : value instanceof URL && value.protocol === 'file:' ? (0, node_url_1.fileURLToPath)(value) : '';
848
857
  const isFileURL = (value) => /^file:\/\//i.test(value);
849
- const sanitizePath = (value) => value ? path.resolve(value) : '';
858
+ const sanitizePath = (value) => value && path.resolve(value);
850
859
  const stripPath = (value) => path.normalize(value).replace(REGEXP_PATHEND, '');
851
860
  const ensureDir = (value) => value.endsWith(path.sep) ? value : value + path.sep;
852
861
  const trimDir = (value) => value.endsWith(path.sep) ? value.substring(0, value.length - 1) : value;
@@ -869,7 +878,7 @@ class Module extends EventEmitter {
869
878
  static LOG_STYLE_NOTICE = Object.freeze({ titleBgColor: 'bgGrey', titleColor: 'white' });
870
879
  static LOG_STYLE_REVERSE = Object.freeze({ titleBgColor: 'bgWhite', titleColor: 'black', messageBgColor: 'bgGrey' });
871
880
  static get VERSION() {
872
- return "0.12.8";
881
+ return "0.13.0";
873
882
  }
874
883
  static get LOG_TYPE() {
875
884
  return types_1.LOG_TYPE;
@@ -1141,8 +1150,8 @@ class Module extends EventEmitter {
1141
1150
  i = sessionIdColor || sessionIdBgColor || sessionIdBold ? formatLogColumn(i, sessionIdColor, sessionIdBgColor, sessionIdBold) : chalk.grey(i);
1142
1151
  }
1143
1152
  if ((m || unit) && SETTINGS.message !== false) {
1153
+ const formatMessage = format.message;
1144
1154
  if (!error) {
1145
- const formatMessage = format.message;
1146
1155
  if (!messageColor && !messageBgColor) {
1147
1156
  ({ color: messageColor, bgColor: messageBgColor, bold: messageBold } = formatMessage);
1148
1157
  messageBold ??= formatMessage.bold;
@@ -1192,6 +1201,7 @@ class Module extends EventEmitter {
1192
1201
  catch {
1193
1202
  m = chalk.redBright(L) + chalk.bgWhite.blackBright(m) + (R && chalk.redBright(R));
1194
1203
  }
1204
+ m = chalk.blackBright(formatMessage.braces[0]) + m;
1195
1205
  }
1196
1206
  }
1197
1207
  else {
@@ -1387,11 +1397,14 @@ class Module extends EventEmitter {
1387
1397
  else {
1388
1398
  algorithm = undefined;
1389
1399
  }
1390
- if ('digestEncoding' in options || 'digest' in options) {
1391
- encoding = options.digestEncoding || options.digest;
1392
- delete options.digest;
1400
+ if ('digestEncoding' in options) {
1401
+ encoding = options.digestEncoding;
1393
1402
  delete options.digestEncoding;
1394
1403
  }
1404
+ else if ('digest' in options) {
1405
+ encoding = options.digest;
1406
+ delete options.digest;
1407
+ }
1395
1408
  else {
1396
1409
  encoding = undefined;
1397
1410
  }
@@ -1416,7 +1429,7 @@ class Module extends EventEmitter {
1416
1429
  }
1417
1430
  }
1418
1431
  catch (err) {
1419
- if (this.isErrorCode(err, 'ENOENT', 'EACCES', 'ELOOP', 'ENAMETOOLONG', 'EINVAL')) {
1432
+ if ((0, types_1.isErrorCode)(err, 'ENOENT', 'EACCES', 'ELOOP', 'ENAMETOOLONG', 'EINVAL')) {
1420
1433
  throw err;
1421
1434
  }
1422
1435
  }
@@ -1476,8 +1489,7 @@ class Module extends EventEmitter {
1476
1489
  }
1477
1490
  static isFile(value, type) {
1478
1491
  if (!type) {
1479
- value = asFile(value);
1480
- return !!value && this.isPath(value, true);
1492
+ return this.isPath(value = asFile(value), true);
1481
1493
  }
1482
1494
  if (typeof value === 'string') {
1483
1495
  switch (type) {
@@ -1525,7 +1537,10 @@ class Module extends EventEmitter {
1525
1537
  }
1526
1538
  return false;
1527
1539
  }
1528
- static isDir(value) {
1540
+ static isDir(value, absolute) {
1541
+ if (absolute && !path.isAbsolute(value = asFile(value))) {
1542
+ return false;
1543
+ }
1529
1544
  try {
1530
1545
  return fs.statSync(value).isDirectory();
1531
1546
  }
@@ -1552,11 +1567,11 @@ class Module extends EventEmitter {
1552
1567
  }
1553
1568
  }
1554
1569
  catch (err) {
1555
- return !type && this.isErrorCode(err, 'EBUSY', 'EPERM');
1570
+ return !type && (0, types_1.isErrorCode)(err, 'EBUSY', 'EPERM');
1556
1571
  }
1557
1572
  }
1558
1573
  static isErrorCode(err, ...code) {
1559
- return isErrnoException(err) && code.includes(err.code);
1574
+ return (0, types_1.isErrorCode)(err, ...code);
1560
1575
  }
1561
1576
  static resolveFile(value) {
1562
1577
  if (isFileURL(value = value instanceof URL ? value.toString() : value)) {
@@ -1590,7 +1605,7 @@ class Module extends EventEmitter {
1590
1605
  }
1591
1606
  static joinPath(...values) {
1592
1607
  let normalize = false;
1593
- if (typeof values[values.length - 1] === 'boolean') {
1608
+ if (typeof values.at(-1) === 'boolean') {
1594
1609
  normalize = values.pop();
1595
1610
  }
1596
1611
  const paths = values.filter(item => (0, types_1.isString)(item)).map(value => this.toPosix(value, normalize));
@@ -1658,7 +1673,7 @@ class Module extends EventEmitter {
1658
1673
  }
1659
1674
  }
1660
1675
  catch (err) {
1661
- if (this.isErrorCode(err, 'EBUSY', 'EPERM')) {
1676
+ if ((0, types_1.isErrorCode)(err, 'EBUSY', 'EPERM')) {
1662
1677
  return false;
1663
1678
  }
1664
1679
  }
@@ -1696,11 +1711,11 @@ class Module extends EventEmitter {
1696
1711
  }
1697
1712
  static async copyDir(src, dest, move, recursive) {
1698
1713
  const srcOut = sanitizePath(asFile(src));
1699
- if (!(srcOut && this.isDir(srcOut))) {
1714
+ if (!this.isDir(srcOut)) {
1700
1715
  return Promise.reject(errorDirectory(asFile(src) || "Unknown"));
1701
1716
  }
1702
1717
  const destOut = sanitizePath(asFile(dest));
1703
- if (!(destOut && this.createDir(destOut))) {
1718
+ if (!this.createDir(destOut)) {
1704
1719
  return Promise.reject(errorDirectory(asFile(dest) || "Unknown"));
1705
1720
  }
1706
1721
  let symFile, symDir, ignoreFile, ignoreDir, silent, overwrite;
@@ -1712,7 +1727,7 @@ class Module extends EventEmitter {
1712
1727
  const tasks = [];
1713
1728
  const success = [];
1714
1729
  const failed = [];
1715
- const ignored = [];
1730
+ const ignored = new Set();
1716
1731
  const methodName = move ? 'rename' : 'copyFile';
1717
1732
  const srcFound = [];
1718
1733
  const symFound = [];
@@ -1726,11 +1741,6 @@ class Module extends EventEmitter {
1726
1741
  const name = file.name;
1727
1742
  const destPath = path.join(destDir, name);
1728
1743
  let srcPath = path.join(srcDir, name), isDir = false, isFile = file.isFile() ? 1 : 0;
1729
- const ignore = () => {
1730
- if (!ignored.includes(srcPath)) {
1731
- ignored.push(srcPath);
1732
- }
1733
- };
1734
1744
  if (file.isSymbolicLink()) {
1735
1745
  const previous = symFound.includes(srcPath);
1736
1746
  symFound.push(srcPath);
@@ -1739,7 +1749,7 @@ class Module extends EventEmitter {
1739
1749
  const stat = fs.statSync(realPath);
1740
1750
  if (stat.isFile()) {
1741
1751
  if (symFile === false || !(fs.existsSync(destPath) && !fs.statSync(destPath).isFile())) {
1742
- ignore();
1752
+ ignored.add(srcPath);
1743
1753
  return;
1744
1754
  }
1745
1755
  srcPath = realPath;
@@ -1747,7 +1757,7 @@ class Module extends EventEmitter {
1747
1757
  }
1748
1758
  else {
1749
1759
  if (symDir !== true || previous || !stat.isDirectory()) {
1750
- ignore();
1760
+ ignored.add(srcPath);
1751
1761
  return;
1752
1762
  }
1753
1763
  isFile = 0;
@@ -1755,24 +1765,24 @@ class Module extends EventEmitter {
1755
1765
  }
1756
1766
  }
1757
1767
  catch {
1758
- ignore();
1768
+ ignored.add(srcPath);
1759
1769
  return;
1760
1770
  }
1761
1771
  }
1762
1772
  if (isFile) {
1763
1773
  if (ignoreFile?.test(name)) {
1764
- ignore();
1774
+ ignored.add(srcPath);
1765
1775
  return;
1766
1776
  }
1767
1777
  if (overwrite === false) {
1768
1778
  try {
1769
1779
  if (fs.existsSync(destPath)) {
1770
- ignore();
1780
+ ignored.add(srcPath);
1771
1781
  return;
1772
1782
  }
1773
1783
  }
1774
1784
  catch {
1775
- ignore();
1785
+ ignored.add(srcPath);
1776
1786
  return;
1777
1787
  }
1778
1788
  }
@@ -1789,7 +1799,7 @@ class Module extends EventEmitter {
1789
1799
  }
1790
1800
  else if (depth > 0 && (isDir || file.isDirectory())) {
1791
1801
  if (ignoreDir?.test(name)) {
1792
- ignore();
1802
+ ignored.add(srcPath);
1793
1803
  return;
1794
1804
  }
1795
1805
  recurse.call(this, paths.concat(name), depth - 1);
@@ -1831,13 +1841,13 @@ class Module extends EventEmitter {
1831
1841
  }
1832
1842
  }
1833
1843
  }
1834
- resolve({ success, failed, ignored });
1844
+ resolve({ success, failed, ignored: Array.from(ignored) });
1835
1845
  });
1836
1846
  });
1837
1847
  }
1838
1848
  static async globDir(src, pattern, options) {
1839
1849
  const outDir = sanitizePath(asFile(src));
1840
- if (!(outDir && this.isDir(outDir))) {
1850
+ if (!this.isDir(outDir)) {
1841
1851
  return Promise.reject(errorDirectory(asFile(src) || "Unknown"));
1842
1852
  }
1843
1853
  const pmOpts = PLATFORM_WIN32 ? { nocase: true, posixSlashes: true, windows: true } : {};
@@ -1881,7 +1891,7 @@ class Module extends EventEmitter {
1881
1891
  return true;
1882
1892
  }
1883
1893
  catch (err) {
1884
- if (this.isErrorCode(err, 'EXDEV')) {
1894
+ if ((0, types_1.isErrorCode)(err, 'EXDEV')) {
1885
1895
  let copied = false;
1886
1896
  try {
1887
1897
  fs.copyFileSync(src, dest);
@@ -1911,7 +1921,7 @@ class Module extends EventEmitter {
1911
1921
  ({ minStreamSize = 0, encoding, signal, cache } = options);
1912
1922
  }
1913
1923
  const src = sanitizePath(asFile(value));
1914
- if (src && this.isPath(src, true)) {
1924
+ if (this.isPath(src, true)) {
1915
1925
  return new Promise(async (resolve) => {
1916
1926
  const fileSize = fs.statSync(src).size;
1917
1927
  let data;
@@ -1948,7 +1958,7 @@ class Module extends EventEmitter {
1948
1958
  ({ minStreamSize, encoding, cache } = options);
1949
1959
  }
1950
1960
  const src = sanitizePath(asFile(value));
1951
- if (src && this.isPath(src, true)) {
1961
+ if (this.isPath(src, true)) {
1952
1962
  let result;
1953
1963
  if (cache && (result = getCacheItem(CACHE_READTEXT, src))) {
1954
1964
  return (minStreamSize !== undefined ? Promise.resolve(result) : result);
@@ -1977,7 +1987,7 @@ class Module extends EventEmitter {
1977
1987
  ({ minStreamSize, cache } = options);
1978
1988
  }
1979
1989
  const src = sanitizePath(asFile(value));
1980
- if (src && this.isPath(src, true)) {
1990
+ if (this.isPath(src, true)) {
1981
1991
  let result;
1982
1992
  if (cache && (result = getCacheItem(CACHE_READBUFFER, src))) {
1983
1993
  return (minStreamSize !== undefined ? Promise.resolve(result) : result);
@@ -2000,7 +2010,7 @@ class Module extends EventEmitter {
2000
2010
  }
2001
2011
  static async resolveMime(data) {
2002
2012
  FILETYPE_ESM ||= await (0, types_1.importESM)('file-type');
2003
- return typeof data === 'string' ? FILETYPE_ESM.fileTypeFromFile(data) : data instanceof stream.Readable ? FILETYPE_ESM.fileTypeFromStream(data) : FILETYPE_ESM.fileTypeFromBuffer(data);
2013
+ return typeof data === 'string' ? FILETYPE_ESM.fileTypeFromFile(data) : stream.Readable.isReadable(data) ? FILETYPE_ESM.fileTypeFromStream(data) : FILETYPE_ESM.fileTypeFromBuffer(data);
2004
2014
  }
2005
2015
  static lookupMime(value, extension) {
2006
2016
  return (extension ? mime.extension(value) : mime.lookup(value)) || '';
@@ -2259,9 +2269,9 @@ class Module extends EventEmitter {
2259
2269
  limit = 0;
2260
2270
  }
2261
2271
  let result = 0;
2262
- if (limit === 0 || limit >= getCacheTotal()) {
2272
+ if (limit === 0 || limit >= getCacheSize()) {
2263
2273
  if (percent >= 1) {
2264
- result = getCacheTotal();
2274
+ result = getCacheSize();
2265
2275
  CACHE_READTEXT.clear();
2266
2276
  CACHE_READBUFFER.clear();
2267
2277
  CACHE_READCJS.clear();
@@ -2413,14 +2423,8 @@ class Module extends EventEmitter {
2413
2423
  if (expires !== undefined && (expires = (0, types_1.parseExpires)(expires)) > 0) {
2414
2424
  MEMORY_CACHE_DISK.expires = expires;
2415
2425
  }
2416
- MEMORY_CACHE_DISK.include = null;
2417
- MEMORY_CACHE_DISK.exclude = null;
2418
- if ((0, types_1.isArray)(include)) {
2419
- MEMORY_CACHE_DISK.include = include.map(value => this.toPosix(value, true));
2420
- }
2421
- if ((0, types_1.isArray)(exclude)) {
2422
- MEMORY_CACHE_DISK.exclude = exclude.map(value => this.toPosix(value, true));
2423
- }
2426
+ MEMORY_CACHE_DISK.include = createMatchNegate(include);
2427
+ MEMORY_CACHE_DISK.exclude = createMatchNegate(exclude);
2424
2428
  }
2425
2429
  }
2426
2430
  if (logger) {
@@ -2559,7 +2563,7 @@ class Module extends EventEmitter {
2559
2563
  case 'process': {
2560
2564
  const proc = logger.process;
2561
2565
  if (proc) {
2562
- if ((0, types_1.isObject)(proc)) {
2566
+ if ((0, types_1.isPlainObject)(proc)) {
2563
2567
  if ('cpu_bar_color' in proc) {
2564
2568
  const barColor = proc.cpu_bar_color;
2565
2569
  if (Array.isArray(barColor) && barColor.length === 3 && barColor.every(color => isBackgroundColor(color))) {
@@ -2635,13 +2639,13 @@ class Module extends EventEmitter {
2635
2639
  }
2636
2640
  write = temp.write;
2637
2641
  }
2638
- if (env && path.isAbsolute(env) && this.isDir(env)) {
2642
+ if (env && this.isDir(env, true)) {
2639
2643
  (0, types_1.setTempDir)(TEMP_DIR = stripPath(env));
2640
2644
  dir = path.relative(PROCESS_CWD, TEMP_DIR);
2641
2645
  VALUES["temp.dir"] = dir;
2642
2646
  modified = true;
2643
2647
  }
2644
- else if ((0, types_1.isString)(dir)) {
2648
+ else if (dir) {
2645
2649
  if (path.isAbsolute(dir = stripPath(dir))) {
2646
2650
  if (withinDir(dir, PROCESS_CWD)) {
2647
2651
  dir = dir.substring(ensureDir(PROCESS_CWD).length);
@@ -2761,48 +2765,54 @@ class Module extends EventEmitter {
2761
2765
  return result || path.join(...leading);
2762
2766
  }
2763
2767
  canRead(uri, options) {
2764
- let permission = this.permission, ownPermissionOnly = false;
2768
+ uri = asFile(uri);
2769
+ if (!uri) {
2770
+ return false;
2771
+ }
2772
+ let permission, ownPermissionOnly = false;
2765
2773
  if (options) {
2766
2774
  if (options.hostPermissionOnly) {
2767
- let host;
2768
- if (!(permission = (host = this.host) && host.permission)) {
2775
+ permission = this.host?.permission;
2776
+ if (!permission) {
2769
2777
  return true;
2770
2778
  }
2771
2779
  }
2772
2780
  else if (options.ownPermissionOnly) {
2773
- if (!(permission = this.#permission)) {
2781
+ permission = this.#permission;
2782
+ if (!permission) {
2774
2783
  return true;
2775
2784
  }
2776
2785
  ownPermissionOnly = true;
2777
2786
  }
2778
2787
  }
2779
- if (!(uri = asFile(uri))) {
2780
- return false;
2781
- }
2788
+ permission ??= this.permission;
2782
2789
  if (permission && (_a.isFile(uri, 'unc') ? permission.hasUNCRead(uri) || ownPermissionOnly && !permission.getUNCRead() : path.isAbsolute(uri = path.resolve(uri)) && (permission.hasDiskRead(uri) || ownPermissionOnly && !permission.getDiskRead()))) {
2783
2790
  return true;
2784
2791
  }
2785
2792
  return VALUES["permission.home_read"] && withinDir(uri, OS_HOMEDIR, true);
2786
2793
  }
2787
2794
  canWrite(uri, options) {
2788
- let permission = this.permission, ownPermissionOnly = false;
2795
+ uri = asFile(uri);
2796
+ if (!uri) {
2797
+ return false;
2798
+ }
2799
+ let permission, ownPermissionOnly = false;
2789
2800
  if (options) {
2790
2801
  if (options.hostPermissionOnly) {
2791
- let host;
2792
- if (!(permission = (host = this.host) && host.permission)) {
2802
+ permission = this.host?.permission;
2803
+ if (!permission) {
2793
2804
  return true;
2794
2805
  }
2795
2806
  }
2796
2807
  else if (options.ownPermissionOnly) {
2797
- if (!(permission = this.#permission)) {
2808
+ permission = this.#permission;
2809
+ if (!permission) {
2798
2810
  return true;
2799
2811
  }
2800
2812
  ownPermissionOnly = true;
2801
2813
  }
2802
2814
  }
2803
- if (!(uri = asFile(uri))) {
2804
- return false;
2805
- }
2815
+ permission ??= this.permission;
2806
2816
  if (permission && (_a.isFile(uri, 'unc') ? permission.hasUNCWrite(uri) || ownPermissionOnly && !permission.getUNCWrite() : path.isAbsolute(uri = path.resolve(uri)) && (permission.hasDiskWrite(uri) || ownPermissionOnly && !permission.getDiskWrite()))) {
2807
2817
  return true;
2808
2818
  }
@@ -2896,11 +2906,14 @@ class Module extends EventEmitter {
2896
2906
  this.writeFail(["Unable to read file", path.basename(asFile(src))], err, 32);
2897
2907
  }
2898
2908
  }
2899
- else if (promises) {
2900
- return Promise.reject(errorPermission(src));
2901
- }
2902
- else if ((0, types_1.isFunction)(callback)) {
2903
- callback(errorPermission(src));
2909
+ else {
2910
+ this.emit('file:permission', src, 'read');
2911
+ if (promises) {
2912
+ return Promise.reject(errorPermission(src));
2913
+ }
2914
+ if ((0, types_1.isFunction)(callback)) {
2915
+ callback(errorPermission(src));
2916
+ }
2904
2917
  }
2905
2918
  }
2906
2919
  writeFile(src, data, options = {}, callback) {
@@ -2932,12 +2945,15 @@ class Module extends EventEmitter {
2932
2945
  this.writeFail(["Unable to write file", path.basename(outSrc)], err, 32);
2933
2946
  }
2934
2947
  }
2935
- else if (promises) {
2936
- return Promise.reject(errorPermission(src));
2937
- }
2938
- else if ((0, types_1.isFunction)(callback)) {
2939
- callback(errorPermission(src));
2940
- return;
2948
+ else {
2949
+ this.emit('file:permission', src, 'write');
2950
+ if (promises) {
2951
+ return Promise.reject(errorPermission(src));
2952
+ }
2953
+ if ((0, types_1.isFunction)(callback)) {
2954
+ callback(errorPermission(src));
2955
+ return;
2956
+ }
2941
2957
  }
2942
2958
  return false;
2943
2959
  }
@@ -2965,7 +2981,7 @@ class Module extends EventEmitter {
2965
2981
  fs.unlinkSync(outSrc);
2966
2982
  }
2967
2983
  catch (err) {
2968
- if (!_a.isErrorCode(err, 'ENOENT')) {
2984
+ if (!(0, types_1.isErrorCode)(err, 'ENOENT')) {
2969
2985
  this.writeFail(["Unable to delete file", path.basename(outSrc)], err, 32);
2970
2986
  return false;
2971
2987
  }
@@ -2973,10 +2989,11 @@ class Module extends EventEmitter {
2973
2989
  this.emit('file:delete', outSrc, options);
2974
2990
  return true;
2975
2991
  }
2976
- else if (promises) {
2992
+ this.emit('file:permission', src, 'delete');
2993
+ if (promises) {
2977
2994
  return Promise.reject(errorPermission(src));
2978
2995
  }
2979
- else if ((0, types_1.isFunction)(callback)) {
2996
+ if ((0, types_1.isFunction)(callback)) {
2980
2997
  callback(errorPermission(src));
2981
2998
  return;
2982
2999
  }
@@ -3027,12 +3044,15 @@ class Module extends EventEmitter {
3027
3044
  }
3028
3045
  }
3029
3046
  }
3030
- else if (promises) {
3031
- return Promise.reject(errorPermission(src));
3032
- }
3033
- else if ((0, types_1.isFunction)(callback)) {
3034
- callback(errorPermission(!outSrc ? src : dest));
3035
- return;
3047
+ else {
3048
+ this.emit('file:permission', src, 'copy');
3049
+ if (promises) {
3050
+ return Promise.reject(errorPermission(src));
3051
+ }
3052
+ if ((0, types_1.isFunction)(callback)) {
3053
+ callback(errorPermission(!outSrc ? src : dest));
3054
+ return;
3055
+ }
3036
3056
  }
3037
3057
  return false;
3038
3058
  }
@@ -3102,6 +3122,7 @@ class Module extends EventEmitter {
3102
3122
  if (outSrc) {
3103
3123
  src = dest;
3104
3124
  }
3125
+ this.emit('file:permission', src, 'move');
3105
3126
  if (promises) {
3106
3127
  return Promise.reject(errorPermission(src));
3107
3128
  }
@@ -3168,12 +3189,15 @@ class Module extends EventEmitter {
3168
3189
  this.writeFail(["Unable to create directory", path.basename(outSrc)], err, 32);
3169
3190
  }
3170
3191
  }
3171
- else if (promises) {
3172
- return Promise.reject(errorPermission(src));
3173
- }
3174
- else if ((0, types_1.isFunction)(callback)) {
3175
- callback(errorPermission(src));
3176
- return;
3192
+ else {
3193
+ this.emit('dir:permission', src, 'create');
3194
+ if (promises) {
3195
+ return Promise.reject(errorPermission(src));
3196
+ }
3197
+ if ((0, types_1.isFunction)(callback)) {
3198
+ callback(errorPermission(src));
3199
+ return;
3200
+ }
3177
3201
  }
3178
3202
  return false;
3179
3203
  }
@@ -3184,7 +3208,7 @@ class Module extends EventEmitter {
3184
3208
  if (outSrc) {
3185
3209
  try {
3186
3210
  if (_a.isDir(outSrc)) {
3187
- const { emptyDir = false, recursive = true } = options;
3211
+ const { emptyDir = false, recursive } = options;
3188
3212
  if (promises || (0, types_1.isFunction)(callback)) {
3189
3213
  const result = new Promise((resolve, reject) => {
3190
3214
  const failed = tryRemoveDir(outSrc, emptyDir, !!recursive);
@@ -3195,12 +3219,12 @@ class Module extends EventEmitter {
3195
3219
  reject(errorAccess(failed));
3196
3220
  }
3197
3221
  })
3198
- .then(success => {
3222
+ .then(() => {
3199
3223
  this.emit('dir:remove', outSrc, options);
3200
3224
  if (callback) {
3201
3225
  callback(null);
3202
3226
  }
3203
- return success;
3227
+ return true;
3204
3228
  });
3205
3229
  if (callback) {
3206
3230
  result.catch((err) => {
@@ -3240,12 +3264,15 @@ class Module extends EventEmitter {
3240
3264
  this.writeFail(["Unable to remove directory", path.basename(outSrc)], err, 32);
3241
3265
  }
3242
3266
  }
3243
- else if (promises) {
3244
- return Promise.reject(errorPermission(src));
3245
- }
3246
- else if ((0, types_1.isFunction)(callback)) {
3247
- callback(errorPermission(src));
3248
- return;
3267
+ else {
3268
+ this.emit('dir:permission', src, 'remove');
3269
+ if (promises) {
3270
+ return Promise.reject(errorPermission(src));
3271
+ }
3272
+ if ((0, types_1.isFunction)(callback)) {
3273
+ callback(errorPermission(src));
3274
+ return;
3275
+ }
3249
3276
  }
3250
3277
  return false;
3251
3278
  }
@@ -3270,7 +3297,7 @@ class Module extends EventEmitter {
3270
3297
  }
3271
3298
  writeFail(value, message, options) {
3272
3299
  let type;
3273
- if ((0, types_1.isPlainObject)(options)) {
3300
+ if ((0, types_1.isObject)(options)) {
3274
3301
  ({ type } = options);
3275
3302
  }
3276
3303
  else {
@@ -3515,7 +3542,7 @@ class Module extends EventEmitter {
3515
3542
  options = value;
3516
3543
  value = undefined;
3517
3544
  }
3518
- if (name && isErrnoException(err) && (err.code === types_1.ERR_CODE.MODULE_NOT_FOUND || err.code === types_1.ERR_CODE.ERR_MODULE_NOT_FOUND)) {
3545
+ if (name && (0, types_1.isErrorCode)(err, types_1.ERR_CODE.MODULE_NOT_FOUND, types_1.ERR_CODE.ERR_MODULE_NOT_FOUND)) {
3519
3546
  if (typeof options === 'number') {
3520
3547
  options = undefined;
3521
3548
  }
@@ -3529,7 +3556,7 @@ class Module extends EventEmitter {
3529
3556
  return false;
3530
3557
  }
3531
3558
  checkFail(message, options) {
3532
- switch (options.code || isErrnoException(message) && message.code) {
3559
+ switch (options.code || message.code) {
3533
3560
  case types_1.ERR_CODE.MODULE_NOT_FOUND:
3534
3561
  case types_1.ERR_CODE.ERR_MODULE_NOT_FOUND:
3535
3562
  if (options.exec) {
@@ -3817,8 +3844,7 @@ class Module extends EventEmitter {
3817
3844
  options.sessionId ??= this.sessionId;
3818
3845
  let value = options.broadcastId;
3819
3846
  if (value === undefined) {
3820
- value = this.broadcastId;
3821
- if (value) {
3847
+ if (value = this.broadcastId) {
3822
3848
  options.broadcastId = this.supports('stripAnsi') ? value : { value, stripAnsi: false };
3823
3849
  }
3824
3850
  }
@@ -3853,9 +3879,7 @@ class Module extends EventEmitter {
3853
3879
  this.abortable = value.willAbort(this);
3854
3880
  value.modules.add(this);
3855
3881
  if (aborting) {
3856
- value.signal.addEventListener('abort', this.#abortEvent = () => {
3857
- this.abort(new Error("Aborted by host"));
3858
- }, { once: true });
3882
+ value.signal.addEventListener('abort', this.#abortEvent = () => this.abort(new Error("Aborted by host")), { once: true });
3859
3883
  }
3860
3884
  }
3861
3885
  }
@@ -3866,20 +3890,19 @@ class Module extends EventEmitter {
3866
3890
  this.#sessionId = value;
3867
3891
  }
3868
3892
  get sessionId() {
3869
- return this.#sessionId || (this.host ? this.host.sessionId : '');
3893
+ return this.#sessionId || this.host?.sessionId || '';
3870
3894
  }
3871
3895
  set broadcastId(value) {
3872
3896
  this.#broadcastId = value;
3873
3897
  }
3874
3898
  get broadcastId() {
3875
- return this.#broadcastId || (this.host ? this.host.broadcastId : '');
3899
+ return this.#broadcastId || this.host?.broadcastId || '';
3876
3900
  }
3877
3901
  set permission(value) {
3878
3902
  this.#permission = value;
3879
3903
  }
3880
3904
  get permission() {
3881
- let host;
3882
- return this.#permission || (host = this.host) && host.permission;
3905
+ return this.#permission || this.host?.permission || null;
3883
3906
  }
3884
3907
  get signal() {
3885
3908
  return this.#abortController.signal;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@e-mc/module",
3
- "version": "0.12.8",
3
+ "version": "0.13.0",
4
4
  "description": "Module base class for E-mc.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -19,11 +19,11 @@
19
19
  "license": "BSD-3-Clause",
20
20
  "homepage": "https://github.com/anpham6/e-mc#readme",
21
21
  "dependencies": {
22
- "@e-mc/types": "0.12.8",
22
+ "@e-mc/types": "0.13.0",
23
23
  "chalk": "4.1.2",
24
- "file-type": "^18.7.0",
24
+ "file-type": "^20.5.0",
25
25
  "js-yaml": "^4.1.0",
26
- "mime-types": "^2.1.35",
26
+ "mime-types": "^3.0.1",
27
27
  "picomatch": "^4.0.3"
28
28
  }
29
29
  }