fyn 3.1.5 → 3.1.6

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 (2) hide show
  1. package/dist/fyn.mjs +119 -60
  2. package/package.json +4 -4
package/dist/fyn.mjs CHANGED
@@ -27044,8 +27044,6 @@ function processDir(options, extras) {
27044
27044
  */
27045
27045
  function processFile(options, extras) {
27046
27046
  if (!options.includeDir && !options.includeSymlink && extras.stat && extras.stat.isSymbolicLink && extras.stat.isSymbolicLink()) return false;
27047
- if (options.ignoreExt.length > 0 && options.ignoreExt.indexOf(extras.ext) >= 0) return false;
27048
- if (options.filterExt.length > 0 && options.filterExt.indexOf(extras.ext) < 0) return false;
27049
27047
  const filterResult = options.filter ? options.filter(extras.file, extras.path, extras) : true;
27050
27048
  if (filterResult) {
27051
27049
  if (filterResult.skip !== true) addResult(filterResult, options, extras);
@@ -27053,6 +27051,19 @@ function processFile(options, extras) {
27053
27051
  }
27054
27052
  return false;
27055
27053
  }
27054
+ function acceptEntry(options, entry, path) {
27055
+ const isDirectory = entry.isDirectory();
27056
+ if (isDirectory && options._ignoreDirs.has(entry.name)) return false;
27057
+ if (options.prefilter && !options.prefilter(entry.name, path, entry)) return false;
27058
+ if (isDirectory) return true;
27059
+ if (options.ignoreExt.length || options.filterExt.length) {
27060
+ const ix = entry.name.lastIndexOf(".");
27061
+ const ext = ix > 0 ? entry.name.substring(ix) : "";
27062
+ if (options.ignoreExt.indexOf(ext) >= 0) return false;
27063
+ if (options.filterExt.length && options.filterExt.indexOf(ext) < 0) return false;
27064
+ }
27065
+ return true;
27066
+ }
27056
27067
  /**
27057
27068
  * get the result base on grouping enable flag
27058
27069
  *
@@ -27060,10 +27071,23 @@ function processFile(options, extras) {
27060
27071
  * @returns
27061
27072
  */
27062
27073
  function getResult(options) {
27063
- return options.grouping ? Object.assign({ files: [] }, options.result) : options.result.files || [];
27074
+ return options.grouping ? {
27075
+ files: [],
27076
+ ...options.result
27077
+ } : options.result.files || [];
27064
27078
  }
27065
27079
  const asyncReaddir = Util.promisify(fs.readdir);
27066
27080
  const asyncLStat = Util.promisify(fs.lstat);
27081
+ function releaseDirectory(options) {
27082
+ if (options._waitIndex < options._waiting.length) {
27083
+ const resume = options._waiting[options._waitIndex++];
27084
+ if (options._waitIndex === options._waiting.length) {
27085
+ options._waiting = [];
27086
+ options._waitIndex = 0;
27087
+ }
27088
+ resume();
27089
+ } else options._concurrentCount--;
27090
+ }
27067
27091
  /**
27068
27092
  * async version of dir walk
27069
27093
  *
@@ -27073,59 +27097,73 @@ const asyncLStat = Util.promisify(fs.lstat);
27073
27097
  * @returns
27074
27098
  */
27075
27099
  async function walk(path, options, level = 0) {
27100
+ let promises = [];
27101
+ let hasSlot = false;
27076
27102
  try {
27103
+ if (options.concurrency > 1) {
27104
+ if (options._concurrentCount >= options.concurrency) await new Promise((resolve) => options._waiting.push(resolve));
27105
+ else options._concurrentCount++;
27106
+ hasSlot = true;
27107
+ }
27108
+ if (options._stopped) return void 0;
27077
27109
  const dir = Path.join(options.dir, path);
27078
27110
  let files = await asyncReaddir(dir, options.readdirOpts);
27079
27111
  if (options.sortFiles) {
27080
- if (options.fullStat) files = files.sort();
27112
+ if (!options.readdirOpts) files = files.sort();
27081
27113
  else files = files.sort(direntCmp);
27082
27114
  }
27083
27115
  const dirs = [];
27084
- let stop = false;
27085
- for (let ix = 0; !stop && ix < files.length; ix++) {
27116
+ const extrasFiles = options.fullStat && options._earlyFilter && (options.filter || options.filterDir) ? files.map((entry) => entry.name) : files;
27117
+ for (let ix = 0; !options._stopped && ix < files.length; ix++) {
27086
27118
  const file = files[ix];
27119
+ if (options._earlyFilter && !acceptEntry(options, file, path)) continue;
27087
27120
  let extras;
27088
27121
  if (options.fullStat) {
27089
- const fullFile = join2(options._sep, dir, file);
27090
- extras = makeExtrasData(file, fullFile, path, await asyncLStat(fullFile), files, options);
27122
+ const name = options._earlyFilter ? file.name : file;
27123
+ const fullFile = join2(options._sep, dir, name);
27124
+ const stat = await asyncLStat(fullFile);
27125
+ if (options._stopped) break;
27126
+ extras = makeExtrasData(name, fullFile, path, stat, extrasFiles, options);
27091
27127
  } else {
27092
27128
  const fullFile = join2(options._sep, dir, file.name);
27093
27129
  extras = makeExtrasData(file.name, fullFile, path, file, files, options);
27094
27130
  }
27095
27131
  if (extras.stat.isDirectory()) dirs.push(extras);
27096
- else stop = processFile(options, extras);
27097
- }
27098
- if (!stop && dirs.length > 0) {
27099
- let promises = [];
27100
- for (let ix = 0; ix < dirs.length; ix++) {
27101
- const extras = dirs[ix];
27102
- const flags = processDir(options, extras);
27103
- if (flags.stop) break;
27104
- if (!flags.skip && level < options.maxLevel) {
27105
- const walkP = walk(extras.dirFile, options, level + 1);
27106
- if (options.concurrency > 1) {
27107
- if (options._concurrentCount < options.concurrency) {
27108
- options._concurrentCount++;
27109
- promises.push(walkP);
27110
- } else if (promises.length) {
27111
- await Promise.all(promises);
27112
- options._concurrentCount -= promises.length;
27113
- promises = [walkP];
27114
- options._concurrentCount++;
27115
- } else await walkP;
27116
- } else await walkP;
27117
- }
27118
- }
27119
- if (promises.length) {
27120
- await Promise.all(promises);
27121
- options._concurrentCount -= promises.length;
27122
- promises = [];
27132
+ else options._stopped = !!processFile(options, extras);
27133
+ }
27134
+ if (hasSlot) {
27135
+ releaseDirectory(options);
27136
+ hasSlot = false;
27137
+ }
27138
+ if (!options._stopped && dirs.length > 0) for (let ix = 0; !options._stopped && ix < dirs.length; ix++) {
27139
+ const extras = dirs[ix];
27140
+ const flags = processDir(options, extras);
27141
+ if (flags.stop) {
27142
+ options._stopped = true;
27143
+ break;
27144
+ }
27145
+ if (!flags.skip && level < options.maxLevel) {
27146
+ const walkP = walk(extras.dirFile, options, level + 1);
27147
+ if (options.concurrency > 1) {
27148
+ promises.push(walkP);
27149
+ if (promises.length >= options.concurrency) {
27150
+ await Promise.all(promises);
27151
+ promises = [];
27152
+ }
27153
+ } else await walkP;
27123
27154
  }
27124
27155
  }
27125
27156
  } catch (err) {
27126
- if (options.rethrowError) throw err;
27157
+ if (options.rethrowError) {
27158
+ if (!options._error) options._error = { cause: err };
27159
+ options._stopped = true;
27160
+ }
27161
+ } finally {
27162
+ if (hasSlot) releaseDirectory(options);
27163
+ if (promises.length) await Promise.all(promises);
27127
27164
  }
27128
- return getResult(options);
27165
+ if (level === 0 && options._error) throw options._error.cause;
27166
+ return level === 0 ? getResult(options) : void 0;
27129
27167
  }
27130
27168
  /**
27131
27169
  * make a copy of the user's options with proper defaults
@@ -27135,6 +27173,7 @@ async function walk(path, options, level = 0) {
27135
27173
  */
27136
27174
  function makeOptions(opts) {
27137
27175
  const options = typeof opts === "string" ? { cwd: opts } : opts;
27176
+ if (options.prefilter && options.fullStat === false) throw new TypeError("prefilter requires fullStat: true");
27138
27177
  const sep = options.pathSep || Path.posix.sep;
27139
27178
  let cwd = options.cwd || options.dir || process.cwd();
27140
27179
  if (!options.hasOwnProperty("pathSep") && cwd.includes("\\")) cwd = cwd.replace(/\\/g, "/");
@@ -27156,12 +27195,20 @@ function makeOptions(opts) {
27156
27195
  grouping: void 0
27157
27196
  }, options, {
27158
27197
  dir: cwd,
27159
- result: {},
27198
+ fullStat: options.fullStat === void 0 ? true : options.fullStat,
27199
+ result: Object.create(null),
27160
27200
  ignoreExt: [].concat(options.ignoreExt).map(cleanExt).filter((x) => x),
27161
27201
  filterExt: [].concat(options.filterExt).map(cleanExt).filter((x) => x),
27162
- _concurrentCount: 0
27202
+ _concurrentCount: 0,
27203
+ _waiting: [],
27204
+ _waitIndex: 0,
27205
+ _stopped: false,
27206
+ _error: void 0,
27207
+ _earlyFilter: false,
27208
+ _ignoreDirs: new Set([].concat(options.ignoreDirs || []))
27163
27209
  });
27164
- if (!opts2.fullStat) opts2.readdirOpts = { withFileTypes: true };
27210
+ opts2._earlyFilter = !!opts2.prefilter || opts2._ignoreDirs.size > 0 || opts2.ignoreExt.length > 0 || opts2.filterExt.length > 0;
27211
+ if (!opts2.fullStat || opts2._earlyFilter) opts2.readdirOpts = { withFileTypes: true };
27165
27212
  return opts2;
27166
27213
  }
27167
27214
  function filterScanDir(options = {}) {
@@ -102357,7 +102404,6 @@ function createAbortError(context) {
102357
102404
  return err;
102358
102405
  }
102359
102406
  function lastLines(text, n) {
102360
- if (!text) return [];
102361
102407
  return text.split("\n").filter(Boolean).slice(-n);
102362
102408
  }
102363
102409
  function enhanceError(err, context) {
@@ -102446,12 +102492,11 @@ var VisualExec = class {
102446
102492
  if (typeof command !== "string") command = "user command";
102447
102493
  return `Running ${command}`;
102448
102494
  }
102449
- _createOutputFileStream() {
102450
- if (typeof this._outputFile !== "string") return void 0;
102495
+ _createOutputFileStream(outputFile) {
102451
102496
  const flags = this._outputFileOptions.append ? "a" : "w";
102452
- const dir = Path$1.dirname(this._outputFile);
102497
+ const dir = Path$1.dirname(outputFile);
102453
102498
  if (!fs$2.existsSync(dir)) fs$2.mkdirSync(dir, { recursive: true });
102454
- return fs$2.createWriteStream(this._outputFile, { flags });
102499
+ return fs$2.createWriteStream(outputFile, { flags });
102455
102500
  }
102456
102501
  _writeToOutputFile(data, stream) {
102457
102502
  var _a;
@@ -102571,7 +102616,7 @@ var VisualExec = class {
102571
102616
  child.stdout.on("data", this._onStdoutData);
102572
102617
  child.stderr.on("data", this._onStderrData);
102573
102618
  this._child = child;
102574
- if (typeof this._outputFile === "string") this._outputStream = this._createOutputFileStream();
102619
+ if (typeof this._outputFile === "string") this._outputStream = this._createOutputFileStream(this._outputFile);
102575
102620
  else if (this._outputFile) this._outputStream = void 0;
102576
102621
  let timeoutId;
102577
102622
  const startTime = Date.now();
@@ -102707,6 +102752,7 @@ var VisualExec = class {
102707
102752
  child: result.child
102708
102753
  };
102709
102754
  const duration = () => Date.now() - this._startTime;
102755
+ /* v8 ignore next -- @preserve Every field is overwritten in the context below. */
102710
102756
  const baseContext = (output) => {
102711
102757
  var _a, _b, _c, _d;
102712
102758
  return {
@@ -102726,7 +102772,8 @@ var VisualExec = class {
102726
102772
  stderr: ""
102727
102773
  };
102728
102774
  const exitCode = (_c = err.code) !== null && _c !== void 0 ? _c : 1;
102729
- const signal = (_e = (_d = err.signal) !== null && _d !== void 0 ? _d : ((_a = result.child) === null || _a === void 0 ? void 0 : _a.killed) ? "SIGTERM" : null) !== null && _e !== void 0 ? _e : null;
102775
+ const signal = (_e = (_d = err.signal) !== null && _d !== void 0 ? _d : ((_a = result.child) === null || _a === void 0 ? void 0 : _a.killed) ? "SIGTERM" : null) !== null && _e !== void 0 ? _e :
102776
+ /* v8 ignore next -- @preserve The preceding fallback already returns null. */ null;
102730
102777
  const context = {
102731
102778
  ...baseContext(output),
102732
102779
  exitCode,
@@ -114834,7 +114881,7 @@ async function _internalCheck(options) {
114834
114881
  const existMeta = await readMetaFile();
114835
114882
  const shouldFetch = now - existMeta.time >= checkInterval || !existMeta.distTags;
114836
114883
  const distTags = shouldFetch ? await fetchDistTags() : existMeta.distTags;
114837
- const saveMetaFile = async (notifiedVersion = "", notifiedTime = 0) => {
114884
+ const saveMetaFile = async (notifiedVersion = "", notifiedTime) => {
114838
114885
  await promises.writeFile(metaFile, JSON.stringify({
114839
114886
  ...pkg,
114840
114887
  distTags,
@@ -115883,6 +115930,7 @@ var CliBase = class {
115883
115930
  required,
115884
115931
  name,
115885
115932
  type,
115933
+ array: xm[4] ? true : void 0,
115886
115934
  variadic,
115887
115935
  min,
115888
115936
  max
@@ -116019,9 +116067,9 @@ var Options = class {
116019
116067
  match(data) {
116020
116068
  const alias = data.name;
116021
116069
  let name;
116022
- let option = this._options[alias];
116070
+ let option = Object.hasOwn(this._options, alias) ? this._options[alias] : void 0;
116023
116071
  if (option) name = alias;
116024
- else if (this._optAlias[alias]) {
116072
+ else if (Object.hasOwn(this._optAlias, alias)) {
116025
116073
  name = this._optAlias[alias];
116026
116074
  option = this._options[name];
116027
116075
  } else return false;
@@ -116154,7 +116202,7 @@ var CommandBase = class CommandBase extends CliBase {
116154
116202
  */
116155
116203
  setCommandAliases(alias, name) {
116156
116204
  alias.forEach((a) => {
116157
- if (this.subAliases[a]) throw new Error(`Command ${name} alias ${a} already used by command ${this.subAliases[a]}`);
116205
+ if (Object.hasOwn(this.subAliases, a)) throw new Error(`Command ${name} alias ${a} already used by command ${this.subAliases[a]}`);
116158
116206
  this.subAliases[a] = name;
116159
116207
  });
116160
116208
  }
@@ -116235,10 +116283,10 @@ var CommandBase = class CommandBase extends CliBase {
116235
116283
  * ```
116236
116284
  */
116237
116285
  matchSubCommand(alias) {
116238
- let cmd = this.subCmdsBase[alias];
116286
+ let cmd = Object.hasOwn(this.subCmdsBase, alias) ? this.subCmdsBase[alias] : void 0;
116239
116287
  let name = alias;
116240
116288
  if (!cmd) {
116241
- name = this.subAliases[alias];
116289
+ name = Object.hasOwn(this.subAliases, alias) ? this.subAliases[alias] : void 0;
116242
116290
  if (name) cmd = this.subCmdsBase[name];
116243
116291
  else name = alias;
116244
116292
  }
@@ -116535,11 +116583,18 @@ var CommandNode = class extends ClapNode {
116535
116583
  if (matchOpt) {
116536
116584
  const optNode = this.optNodes[matchOpt.name];
116537
116585
  if (!optNode || !optNode.source.startsWith("cli")) {
116586
+ const camelCaseKey = camelCase(matchOpt.name);
116587
+ const aliasNode = this.optNodes[camelCaseKey];
116538
116588
  this.removeOptionNode(matchOpt.name);
116539
116589
  new ClapNodeGenerator(this).addOptionWithArgs(matchOpt.name, [].concat(data.arg), matchOpt.option, src);
116590
+ if (optNode && aliasNode === optNode) {
116591
+ this.optNodes[camelCaseKey] = this.optNodes[matchOpt.name];
116592
+ this.optCount[camelCaseKey] = this.optCount[matchOpt.name];
116593
+ }
116540
116594
  }
116541
116595
  } else if (!this.optNodes[key]) new ClapNodeGenerator(this).addOptionWithArgs(key, [].concat(data.arg), void 0, src);
116542
116596
  }
116597
+ for (let command = this; command; command = command.getParent()) command._jsonMeta = void 0;
116543
116598
  }
116544
116599
  /**
116545
116600
  * For options that has names with - in them, add it using its name converted to camelCase.
@@ -116720,6 +116775,7 @@ var ClapNodeGenerator = class ClapNodeGenerator {
116720
116775
  fallbackBuilder.parent = this;
116721
116776
  fallbackNode.addVerbatimArg(arg);
116722
116777
  fallbackBuilder.node.addArg(arg);
116778
+ if (fallbackMatched.cmd.expectArgs === fallbackNode.argsList.length) fallbackBuilder.endArgGathering();
116723
116779
  return [fallbackBuilder];
116724
116780
  }
116725
116781
  }
@@ -116921,8 +116977,8 @@ var ClapNodeGenerator = class ClapNodeGenerator {
116921
116977
  optNode.getParent();
116922
116978
  this.cmdNode;
116923
116979
  const builder = new ClapNodeGenerator(optNode, this);
116924
- const minArg = data.value ? 1 : 0;
116925
- if (!(optNode.option.args.length > minArg)) builder.complete();
116980
+ const minArg = data.value !== void 0 ? 1 : 0;
116981
+ if (!(optNode.option.expectArgs > minArg)) builder.complete();
116926
116982
  return [builder];
116927
116983
  }
116928
116984
  /**
@@ -116940,7 +116996,7 @@ var ClapNodeGenerator = class ClapNodeGenerator {
116940
116996
  };
116941
116997
  if (opt.hasArgs) for (let i = 0; i < args.length && i < node.argsList.length; i++) setArg(i, args[i], node.argsList[i]);
116942
116998
  else node.argsMap[0] = node.argsList.length > 0 ? this.convertValue(isBoolean(node.argsList[0]) ? "boolean" : isNumber(node.argsList[0]) ? "number" : "string", node.argsList[0], opt) : true;
116943
- if (opt.isVariadicArgs) {
116999
+ if (args.length > 0 && args[args.length - 1].array) {
116944
117000
  const lastIx = args.length - 1;
116945
117001
  if (node.argsList.length > lastIx) setArg(lastIx, args[lastIx], node.argsList.slice(lastIx));
116946
117002
  }
@@ -116959,7 +117015,7 @@ var ClapNodeGenerator = class ClapNodeGenerator {
116959
117015
  node.argsMap[argIx] = setValue;
116960
117016
  };
116961
117017
  for (let i = 0; i < args.length && i < node.argsList.length; i++) setArg(i, args[i], node.argsList[i]);
116962
- if (cmd.isVariadicArgs) {
117018
+ if (args.length > 0 && args[args.length - 1].array) {
116963
117019
  const lastIx = args.length - 1;
116964
117020
  if (node.argsList.length > lastIx) setArg(lastIx, args[lastIx], node.argsList.slice(lastIx));
116965
117021
  }
@@ -117105,7 +117161,7 @@ var Parser = class {
117105
117161
  * @param arg - a raw argv entry already known to start with '-'
117106
117162
  * @returns count of subsequent argv entries taken as this option's value
117107
117163
  */
117108
- _optionValueCount(arg) {
117164
+ _optionValueCount(arg, nextArg) {
117109
117165
  if (arg.startsWith("--no-")) return 0;
117110
117166
  const dashes = arg.startsWith("--") ? 2 : 1;
117111
117167
  let name = arg.substring(dashes);
@@ -117126,7 +117182,10 @@ var Parser = class {
117126
117182
  dashes,
117127
117183
  arg
117128
117184
  });
117129
- if (matched && matched.option) return matched.option.expectArgs || 0;
117185
+ if (matched && matched.option) {
117186
+ if (matched.option.expectArgs > 0 && matched.option.args[0].type === "boolean" && !isBoolean(nextArg)) return 0;
117187
+ return matched.option.expectArgs || 0;
117188
+ }
117130
117189
  }
117131
117190
  return 0;
117132
117191
  }
@@ -117146,7 +117205,7 @@ var Parser = class {
117146
117205
  hasNonOptionArgs = true;
117147
117206
  break;
117148
117207
  }
117149
- i += this._optionValueCount(arg);
117208
+ i += this._optionValueCount(arg, argv[i + 1]);
117150
117209
  if (arg === "--help" || arg === "-h" || arg === "-?" || arg === "--version" || arg === "-v" || arg === "-V") hasHelpOrVersion = true;
117151
117210
  }
117152
117211
  const hasDefaultCommand = this._nc._rootCommand?.ncConfig?.defaultCommand !== void 0;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "fyn",
3
3
  "type": "module",
4
- "version": "3.1.5",
4
+ "version": "3.1.6",
5
5
  "description": "fyn is a node.js package manager, and supports fynpo -- a zero setup monorepo tool",
6
6
  "main": "./bin/index.mjs",
7
7
  "homepage": "https://github.com/jchip/fynjs/tree/main/packages/fyn",
@@ -82,8 +82,8 @@
82
82
  "Walmart GTP.js Team and Contributors"
83
83
  ],
84
84
  "devDependencies": {
85
- "@fynjs/run": "^1.1.4",
86
- "@fynjs/ts-resolve": "^1.0.2",
85
+ "@fynjs/run": "^1.1.5",
86
+ "@fynjs/ts-resolve": "^1.0.3",
87
87
  "@types/node": "^26.4.1",
88
88
  "@vitest/coverage-v8": "^5.0.0",
89
89
  "@vitest/ui": "^5.0.0",
@@ -92,7 +92,7 @@
92
92
  "patch-package": "^8.0.0",
93
93
  "prettier": "^3.5.3",
94
94
  "rolldown": "^1.2.6",
95
- "run-verify": "^2.1.4",
95
+ "run-verify": "^2.1.5",
96
96
  "typescript": "^7.0.2",
97
97
  "vite": "^8.2.2",
98
98
  "vitest": "^5.0.0",