@imfelixyeung/git-swarm 0.1.0 → 0.1.2

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 +1 -0
  2. package/dist/cli.js +1336 -181
  3. package/package.json +34 -52
package/dist/cli.js CHANGED
@@ -2456,6 +2456,76 @@ var require_picomatch2 = __commonJS(function(exports, module) {
2456
2456
  module.exports = picomatch;
2457
2457
  });
2458
2458
 
2459
+ // node_modules/picocolors/picocolors.js
2460
+ var require_picocolors = __commonJS(function(exports, module) {
2461
+ var p = process || {};
2462
+ var argv = p.argv || [];
2463
+ var env = p.env || {};
2464
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
2465
+ var formatter = (open, close, replace = open) => (input) => {
2466
+ let string = "" + input, index = string.indexOf(close, open.length);
2467
+ return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
2468
+ };
2469
+ var replaceClose = (string, close, replace, index) => {
2470
+ let result = "", cursor = 0;
2471
+ do {
2472
+ result += string.substring(cursor, index) + replace;
2473
+ cursor = index + close.length;
2474
+ index = string.indexOf(close, cursor);
2475
+ } while (~index);
2476
+ return result + string.substring(cursor);
2477
+ };
2478
+ var createColors = (enabled = isColorSupported) => {
2479
+ let f = enabled ? formatter : () => String;
2480
+ return {
2481
+ isColorSupported: enabled,
2482
+ reset: f("\x1B[0m", "\x1B[0m"),
2483
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
2484
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
2485
+ italic: f("\x1B[3m", "\x1B[23m"),
2486
+ underline: f("\x1B[4m", "\x1B[24m"),
2487
+ inverse: f("\x1B[7m", "\x1B[27m"),
2488
+ hidden: f("\x1B[8m", "\x1B[28m"),
2489
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
2490
+ black: f("\x1B[30m", "\x1B[39m"),
2491
+ red: f("\x1B[31m", "\x1B[39m"),
2492
+ green: f("\x1B[32m", "\x1B[39m"),
2493
+ yellow: f("\x1B[33m", "\x1B[39m"),
2494
+ blue: f("\x1B[34m", "\x1B[39m"),
2495
+ magenta: f("\x1B[35m", "\x1B[39m"),
2496
+ cyan: f("\x1B[36m", "\x1B[39m"),
2497
+ white: f("\x1B[37m", "\x1B[39m"),
2498
+ gray: f("\x1B[90m", "\x1B[39m"),
2499
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
2500
+ bgRed: f("\x1B[41m", "\x1B[49m"),
2501
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
2502
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
2503
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
2504
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
2505
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
2506
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
2507
+ blackBright: f("\x1B[90m", "\x1B[39m"),
2508
+ redBright: f("\x1B[91m", "\x1B[39m"),
2509
+ greenBright: f("\x1B[92m", "\x1B[39m"),
2510
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
2511
+ blueBright: f("\x1B[94m", "\x1B[39m"),
2512
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
2513
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
2514
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
2515
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
2516
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
2517
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
2518
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
2519
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
2520
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
2521
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
2522
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
2523
+ };
2524
+ };
2525
+ module.exports = createColors();
2526
+ module.exports.createColors = createColors;
2527
+ });
2528
+
2459
2529
  // node_modules/cli-table3/src/debug.js
2460
2530
  var require_debug = __commonJS(function(exports, module) {
2461
2531
  var messages = [];
@@ -4139,76 +4209,6 @@ var require_table = __commonJS(function(exports, module) {
4139
4209
  module.exports = Table;
4140
4210
  });
4141
4211
 
4142
- // node_modules/picocolors/picocolors.js
4143
- var require_picocolors = __commonJS(function(exports, module) {
4144
- var p = process || {};
4145
- var argv = p.argv || [];
4146
- var env = p.env || {};
4147
- var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
4148
- var formatter = (open, close, replace = open) => (input) => {
4149
- let string = "" + input, index = string.indexOf(close, open.length);
4150
- return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
4151
- };
4152
- var replaceClose = (string, close, replace, index) => {
4153
- let result = "", cursor = 0;
4154
- do {
4155
- result += string.substring(cursor, index) + replace;
4156
- cursor = index + close.length;
4157
- index = string.indexOf(close, cursor);
4158
- } while (~index);
4159
- return result + string.substring(cursor);
4160
- };
4161
- var createColors = (enabled = isColorSupported) => {
4162
- let f = enabled ? formatter : () => String;
4163
- return {
4164
- isColorSupported: enabled,
4165
- reset: f("\x1B[0m", "\x1B[0m"),
4166
- bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
4167
- dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
4168
- italic: f("\x1B[3m", "\x1B[23m"),
4169
- underline: f("\x1B[4m", "\x1B[24m"),
4170
- inverse: f("\x1B[7m", "\x1B[27m"),
4171
- hidden: f("\x1B[8m", "\x1B[28m"),
4172
- strikethrough: f("\x1B[9m", "\x1B[29m"),
4173
- black: f("\x1B[30m", "\x1B[39m"),
4174
- red: f("\x1B[31m", "\x1B[39m"),
4175
- green: f("\x1B[32m", "\x1B[39m"),
4176
- yellow: f("\x1B[33m", "\x1B[39m"),
4177
- blue: f("\x1B[34m", "\x1B[39m"),
4178
- magenta: f("\x1B[35m", "\x1B[39m"),
4179
- cyan: f("\x1B[36m", "\x1B[39m"),
4180
- white: f("\x1B[37m", "\x1B[39m"),
4181
- gray: f("\x1B[90m", "\x1B[39m"),
4182
- bgBlack: f("\x1B[40m", "\x1B[49m"),
4183
- bgRed: f("\x1B[41m", "\x1B[49m"),
4184
- bgGreen: f("\x1B[42m", "\x1B[49m"),
4185
- bgYellow: f("\x1B[43m", "\x1B[49m"),
4186
- bgBlue: f("\x1B[44m", "\x1B[49m"),
4187
- bgMagenta: f("\x1B[45m", "\x1B[49m"),
4188
- bgCyan: f("\x1B[46m", "\x1B[49m"),
4189
- bgWhite: f("\x1B[47m", "\x1B[49m"),
4190
- blackBright: f("\x1B[90m", "\x1B[39m"),
4191
- redBright: f("\x1B[91m", "\x1B[39m"),
4192
- greenBright: f("\x1B[92m", "\x1B[39m"),
4193
- yellowBright: f("\x1B[93m", "\x1B[39m"),
4194
- blueBright: f("\x1B[94m", "\x1B[39m"),
4195
- magentaBright: f("\x1B[95m", "\x1B[39m"),
4196
- cyanBright: f("\x1B[96m", "\x1B[39m"),
4197
- whiteBright: f("\x1B[97m", "\x1B[39m"),
4198
- bgBlackBright: f("\x1B[100m", "\x1B[49m"),
4199
- bgRedBright: f("\x1B[101m", "\x1B[49m"),
4200
- bgGreenBright: f("\x1B[102m", "\x1B[49m"),
4201
- bgYellowBright: f("\x1B[103m", "\x1B[49m"),
4202
- bgBlueBright: f("\x1B[104m", "\x1B[49m"),
4203
- bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
4204
- bgCyanBright: f("\x1B[106m", "\x1B[49m"),
4205
- bgWhiteBright: f("\x1B[107m", "\x1B[49m")
4206
- };
4207
- };
4208
- module.exports = createColors();
4209
- module.exports.createColors = createColors;
4210
- });
4211
-
4212
4212
  // node_modules/commander/lib/error.js
4213
4213
  class CommanderError extends Error {
4214
4214
  constructor(exitCode, code, message) {
@@ -6256,7 +6256,7 @@ var program = new Command;
6256
6256
  var package_default = {
6257
6257
  name: "@imfelixyeung/git-swarm",
6258
6258
  description: "Manage multiple Git repositories with ease.",
6259
- version: "0.1.0",
6259
+ version: "0.1.2",
6260
6260
  repository: {
6261
6261
  type: "git",
6262
6262
  url: "https://github.com/imfelixyeung/git-swarm"
@@ -6273,7 +6273,8 @@ var package_default = {
6273
6273
  scripts: {
6274
6274
  build: "bun build ./src/cli.ts --target=bun --outfile=dist/cli.js",
6275
6275
  dev: "bun run build --watch",
6276
- prepack: "bun run build",
6276
+ prepack: "bun run build && jq 'del(.dependencies, .devDependencies, .peerDependencies)' package.json > package.json.tmp && mv package.json.tmp package.json",
6277
+ postpack: "git checkout package.json",
6277
6278
  typecheck: "tsc --noEmit",
6278
6279
  biome: "biome check",
6279
6280
  ci: "biome ci",
@@ -6287,7 +6288,8 @@ var package_default = {
6287
6288
  "@biomejs/biome": "2.5.12",
6288
6289
  "@changesets/changelog-github": "^1.0.1",
6289
6290
  "@changesets/cli": "^3.0.2",
6290
- "@types/bun": "latest"
6291
+ "@types/bun": "latest",
6292
+ prettier: "3.9.6"
6291
6293
  },
6292
6294
  publishConfig: {
6293
6295
  access: "public",
@@ -6299,15 +6301,20 @@ var package_default = {
6299
6301
  dependencies: {
6300
6302
  "cli-table3": "^0.6.5",
6301
6303
  commander: "^15.0.0",
6304
+ "date-fns": "^4.4.0",
6302
6305
  dedent: "^1.7.2",
6303
6306
  "p-limit": "^7.3.2",
6304
6307
  picocolors: "^1.1.1",
6308
+ "pluralize-esm": "^9.0.5",
6305
6309
  "simple-git": "^3.36.0",
6306
6310
  tinyglobby: "^0.2.17",
6307
6311
  zod: "^4.5.4"
6308
6312
  }
6309
6313
  };
6310
6314
 
6315
+ // src/git/worker.ts
6316
+ import { relative as relative2 } from "path";
6317
+
6311
6318
  // node_modules/yocto-queue/index.js
6312
6319
  class Node {
6313
6320
  value;
@@ -6464,9 +6471,6 @@ function validateConcurrency(concurrency) {
6464
6471
  }
6465
6472
  }
6466
6473
 
6467
- // src/git/discover.ts
6468
- import { dirname as dirname2, relative as relative2 } from "path";
6469
-
6470
6474
  // node_modules/simple-git/dist/esm/index.js
6471
6475
  var import_file_exists = __toESM(require_dist(), 1);
6472
6476
 
@@ -10887,6 +10891,10 @@ function gitInstanceFactory(baseDir, options) {
10887
10891
  init_git_response_error();
10888
10892
  var esm_default = gitInstanceFactory;
10889
10893
 
10894
+ // src/git/discover.ts
10895
+ import { stat as stat2 } from "fs/promises";
10896
+ import { dirname as dirname2, join, resolve as resolve3 } from "path";
10897
+
10890
10898
  // node_modules/tinyglobby/dist/index.mjs
10891
10899
  import { readdir, readdirSync, realpath, realpathSync, stat, statSync } from "fs";
10892
10900
  import { isAbsolute, posix, resolve as resolve2 } from "path";
@@ -16664,6 +16672,14 @@ function object(shape, params) {
16664
16672
  };
16665
16673
  return new ZodObject(def);
16666
16674
  }
16675
+ function strictObject(shape, params) {
16676
+ return new ZodObject({
16677
+ type: "object",
16678
+ shape,
16679
+ catchall: never2(),
16680
+ ...normalizeParams(params)
16681
+ });
16682
+ }
16667
16683
  var ZodUnion = /* @__PURE__ */ $constructor("ZodUnion", (inst, def) => {
16668
16684
  $ZodUnion.init(inst, def);
16669
16685
  ZodType.init(inst, def);
@@ -16909,12 +16925,14 @@ function superRefine(fn, params) {
16909
16925
  // src/config/index.ts
16910
16926
  var CONFIG_FILE_NAME = "git-swarm.config.yaml";
16911
16927
  var defaults = {
16928
+ $schema: `https://raw.githubusercontent.com/imfelixyeung/git-swarm/v${package_default.version}/src/config/schema.json`,
16912
16929
  options: {
16913
16930
  parallel: 1,
16914
16931
  where: ""
16915
16932
  }
16916
16933
  };
16917
16934
  var configSchema = object({
16935
+ $schema: string2().nullish(),
16918
16936
  repositories: array(object({
16919
16937
  path: string2()
16920
16938
  })).nullish(),
@@ -16924,6 +16942,7 @@ var configSchema = object({
16924
16942
  }).nullish()
16925
16943
  });
16926
16944
  var defaultConfig = {
16945
+ $schema: defaults.$schema,
16927
16946
  options: {
16928
16947
  parallel: defaults.options.parallel,
16929
16948
  where: defaults.options.where
@@ -16961,6 +16980,320 @@ var config2 = {
16961
16980
  getOption
16962
16981
  };
16963
16982
 
16983
+ // src/utils/colour.ts
16984
+ var import_picocolors = __toESM(require_picocolors(), 1);
16985
+ var c3 = import_picocolors.default;
16986
+
16987
+ // src/git/discover.ts
16988
+ var failConfigRepoPath = (path, reason) => {
16989
+ console.error(`${c3.red("\u2717")} Config repository path ${reason}: "${path}"`);
16990
+ console.error(`${c3.gray("Hint:")} Run ${c3.bold("`git-swarm config refresh`")} to refresh repository paths`);
16991
+ process.exit(1);
16992
+ };
16993
+ var assertConfigRepoPath = async (root, path) => {
16994
+ const absolute = resolve3(root, path);
16995
+ const stats = await stat2(absolute).catch(() => null);
16996
+ if (stats === null || !stats.isDirectory()) {
16997
+ failConfigRepoPath(path, stats === null ? "not found" : "is not a directory");
16998
+ }
16999
+ try {
17000
+ await stat2(join(absolute, ".git"));
17001
+ } catch {
17002
+ failConfigRepoPath(path, "is not a git repository");
17003
+ }
17004
+ };
17005
+ async function* findGitRepositoryPaths(root, options) {
17006
+ if (!options.skipConfig) {
17007
+ const repos = await config2.get().then((c) => c.repositories);
17008
+ if (repos) {
17009
+ for (const repo of repos) {
17010
+ await assertConfigRepoPath(root, repo.path);
17011
+ yield repo.path;
17012
+ }
17013
+ return;
17014
+ }
17015
+ }
17016
+ const matches = await glob("**/.git", {
17017
+ cwd: root,
17018
+ dot: true,
17019
+ onlyFiles: false,
17020
+ expandDirectories: false,
17021
+ absolute: true
17022
+ });
17023
+ for (const path of matches) {
17024
+ yield dirname2(path);
17025
+ }
17026
+ }
17027
+
17028
+ // src/utils/filter-not-null.ts
17029
+ var filterNotNull = (array) => array.filter((t) => t !== null);
17030
+
17031
+ // node_modules/pluralize-esm/dist/index.js
17032
+ var pluralRules = [];
17033
+ var singularRules = [];
17034
+ var uncountables = /* @__PURE__ */ new Set;
17035
+ var irregularPlurals = /* @__PURE__ */ new Map;
17036
+ var irregularSingles = /* @__PURE__ */ new Map;
17037
+ var sanitizeRule = (rule) => typeof rule === "string" ? new RegExp("^".concat(rule, "$"), "i") : rule;
17038
+ var restoreCase = (word, token) => {
17039
+ if (typeof token !== "string")
17040
+ return word;
17041
+ if (word === token)
17042
+ return token;
17043
+ if (word === word.toLowerCase())
17044
+ return token.toLowerCase();
17045
+ if (word === word.toUpperCase())
17046
+ return token.toUpperCase();
17047
+ if (word[0] === word[0].toUpperCase()) {
17048
+ return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase();
17049
+ }
17050
+ return token.toLowerCase();
17051
+ };
17052
+ var sanitizeWord = (token, word, rules) => {
17053
+ if (!token.length || uncountables.has(token)) {
17054
+ return word;
17055
+ }
17056
+ let {
17057
+ length: len
17058
+ } = rules;
17059
+ while (len--) {
17060
+ const rule = rules[len];
17061
+ if (rule[0].test(word)) {
17062
+ return word.replace(rule[0], function() {
17063
+ for (var _len = arguments.length, args = new Array(_len), _key = 0;_key < _len; _key++) {
17064
+ args[_key] = arguments[_key];
17065
+ }
17066
+ const [match, index] = args;
17067
+ const result = rule[1].replace(/\$(\d{1,2})/g, (_, index2) => args[index2] || "");
17068
+ if (match === "") {
17069
+ return restoreCase(word[index - 1], result);
17070
+ }
17071
+ return restoreCase(match, result);
17072
+ });
17073
+ }
17074
+ }
17075
+ return word;
17076
+ };
17077
+ var compute = (word, replaceMap, keepMap, rules) => {
17078
+ const token = word.toLowerCase();
17079
+ if (keepMap.has(token)) {
17080
+ return restoreCase(word, token);
17081
+ }
17082
+ if (replaceMap.has(token)) {
17083
+ return restoreCase(word, replaceMap.get(token));
17084
+ }
17085
+ return sanitizeWord(token, word, rules);
17086
+ };
17087
+ var mapHas = (word, replaceMap, keepMap, rules) => {
17088
+ const token = word.toLowerCase();
17089
+ if (keepMap.has(token))
17090
+ return true;
17091
+ if (replaceMap.has(token))
17092
+ return false;
17093
+ return sanitizeWord(token, token, rules) === token;
17094
+ };
17095
+ var pluralize = (word, count, inclusive) => {
17096
+ const pluralized = count === 1 ? pluralize.singular(word) : pluralize.plural(word);
17097
+ if (inclusive)
17098
+ return "".concat(count, " ").concat(pluralized);
17099
+ return pluralized;
17100
+ };
17101
+ pluralize.plural = (word) => compute(word, irregularSingles, irregularPlurals, pluralRules);
17102
+ pluralize.singular = (word) => compute(word, irregularPlurals, irregularSingles, singularRules);
17103
+ pluralize.addPluralRule = (rule, replacement) => {
17104
+ pluralRules.push([sanitizeRule(rule), replacement]);
17105
+ };
17106
+ pluralize.addSingularRule = (rule, replacement) => {
17107
+ singularRules.push([sanitizeRule(rule), replacement]);
17108
+ };
17109
+ pluralize.addIrregularRule = (single, plural) => {
17110
+ const _plural = plural.toLowerCase();
17111
+ const _single = single.toLowerCase();
17112
+ irregularSingles.set(_single, _plural);
17113
+ irregularPlurals.set(_plural, _single);
17114
+ };
17115
+ pluralize.addUncountableRule = (rule) => {
17116
+ if (typeof rule === "string") {
17117
+ uncountables.add(rule.toLowerCase());
17118
+ return;
17119
+ }
17120
+ pluralize.addPluralRule(rule, "$0");
17121
+ pluralize.addSingularRule(rule, "$0");
17122
+ };
17123
+ pluralize.isPlural = (word) => mapHas(word, irregularSingles, irregularPlurals, pluralRules);
17124
+ pluralize.isSingular = (word) => mapHas(word, irregularPlurals, irregularSingles, singularRules);
17125
+ var defaultIrregulars = [
17126
+ ["I", "we"],
17127
+ ["me", "us"],
17128
+ ["he", "they"],
17129
+ ["she", "they"],
17130
+ ["them", "them"],
17131
+ ["myself", "ourselves"],
17132
+ ["yourself", "yourselves"],
17133
+ ["itself", "themselves"],
17134
+ ["herself", "themselves"],
17135
+ ["himself", "themselves"],
17136
+ ["themself", "themselves"],
17137
+ ["is", "are"],
17138
+ ["was", "were"],
17139
+ ["has", "have"],
17140
+ ["this", "these"],
17141
+ ["that", "those"],
17142
+ ["my", "our"],
17143
+ ["its", "their"],
17144
+ ["his", "their"],
17145
+ ["her", "their"],
17146
+ ["echo", "echoes"],
17147
+ ["dingo", "dingoes"],
17148
+ ["volcano", "volcanoes"],
17149
+ ["tornado", "tornadoes"],
17150
+ ["torpedo", "torpedoes"],
17151
+ ["genus", "genera"],
17152
+ ["viscus", "viscera"],
17153
+ ["stigma", "stigmata"],
17154
+ ["stoma", "stomata"],
17155
+ ["dogma", "dogmata"],
17156
+ ["lemma", "lemmata"],
17157
+ ["schema", "schemata"],
17158
+ ["anathema", "anathemata"],
17159
+ ["ox", "oxen"],
17160
+ ["axe", "axes"],
17161
+ ["die", "dice"],
17162
+ ["yes", "yeses"],
17163
+ ["foot", "feet"],
17164
+ ["eave", "eaves"],
17165
+ ["goose", "geese"],
17166
+ ["tooth", "teeth"],
17167
+ ["quiz", "quizzes"],
17168
+ ["human", "humans"],
17169
+ ["proof", "proofs"],
17170
+ ["carve", "carves"],
17171
+ ["valve", "valves"],
17172
+ ["looey", "looies"],
17173
+ ["thief", "thieves"],
17174
+ ["groove", "grooves"],
17175
+ ["pickaxe", "pickaxes"],
17176
+ ["passerby", "passersby"],
17177
+ ["canvas", "canvases"]
17178
+ ];
17179
+ var defaultPlurals = [[/s?$/i, "s"], [/[^\u0000-\u007F]$/i, "$0"], [/([^aeiou]ese)$/i, "$1"], [/(ax|test)is$/i, "$1es"], [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, "$1es"], [/(e[mn]u)s?$/i, "$1s"], [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, "$1"], [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1i"], [/(alumn|alg|vertebr)(?:a|ae)$/i, "$1ae"], [/(seraph|cherub)(?:im)?$/i, "$1im"], [/(her|at|gr)o$/i, "$1oes"], [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, "$1a"], [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, "$1a"], [/sis$/i, "ses"], [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, "$1$2ves"], [/([^aeiouy]|qu)y$/i, "$1ies"], [/([^ch][ieo][ln])ey$/i, "$1ies"], [/(x|ch|ss|sh|zz)$/i, "$1es"], [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, "$1ices"], [/\b((?:tit)?m|l)(?:ice|ouse)$/i, "$1ice"], [/(pe)(?:rson|ople)$/i, "$1ople"], [/(child)(?:ren)?$/i, "$1ren"], [/eaux$/i, "$0"], [/m[ae]n$/i, "men"], ["thou", "you"]];
17180
+ var defaultSingles = [[/s$/i, ""], [/(ss)$/i, "$1"], [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, "$1fe"], [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, "$1f"], [/ies$/i, "y"], [/(dg|ss|ois|lk|ok|wn|mb|th|ch|ec|oal|is|ck|ix|sser|ts|wb)ies$/i, "$1ie"], [/\b(l|(?:neck|cross|hog|aun)?t|coll|faer|food|gen|goon|group|hipp|junk|vegg|(?:pork)?p|charl|calor|cut)ies$/i, "$1ie"], [/\b(mon|smil)ies$/i, "$1ey"], [/\b((?:tit)?m|l)ice$/i, "$1ouse"], [/(seraph|cherub)im$/i, "$1"], [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, "$1"], [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, "$1sis"], [/(movie|twelve|abuse|e[mn]u)s$/i, "$1"], [/(test)(?:is|es)$/i, "$1is"], [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, "$1us"], [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, "$1um"], [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, "$1on"], [/(alumn|alg|vertebr)ae$/i, "$1a"], [/(cod|mur|sil|vert|ind)ices$/i, "$1ex"], [/(matr|append)ices$/i, "$1ix"], [/(pe)(rson|ople)$/i, "$1rson"], [/(child)ren$/i, "$1"], [/(eau)x?$/i, "$1"], [/men$/i, "man"]];
17181
+ var defaultUncountables = [
17182
+ "adulthood",
17183
+ "advice",
17184
+ "agenda",
17185
+ "aid",
17186
+ "aircraft",
17187
+ "alcohol",
17188
+ "ammo",
17189
+ "analytics",
17190
+ "anime",
17191
+ "athletics",
17192
+ "audio",
17193
+ "bison",
17194
+ "blood",
17195
+ "bream",
17196
+ "buffalo",
17197
+ "butter",
17198
+ "carp",
17199
+ "cash",
17200
+ "chassis",
17201
+ "chess",
17202
+ "clothing",
17203
+ "cod",
17204
+ "commerce",
17205
+ "cooperation",
17206
+ "corps",
17207
+ "debris",
17208
+ "diabetes",
17209
+ "digestion",
17210
+ "elk",
17211
+ "energy",
17212
+ "equipment",
17213
+ "excretion",
17214
+ "expertise",
17215
+ "firmware",
17216
+ "flounder",
17217
+ "fun",
17218
+ "gallows",
17219
+ "garbage",
17220
+ "graffiti",
17221
+ "hardware",
17222
+ "headquarters",
17223
+ "health",
17224
+ "herpes",
17225
+ "highjinks",
17226
+ "homework",
17227
+ "housework",
17228
+ "information",
17229
+ "jeans",
17230
+ "justice",
17231
+ "kudos",
17232
+ "labour",
17233
+ "literature",
17234
+ "machinery",
17235
+ "mackerel",
17236
+ "mail",
17237
+ "media",
17238
+ "mews",
17239
+ "moose",
17240
+ "music",
17241
+ "mud",
17242
+ "manga",
17243
+ "news",
17244
+ "only",
17245
+ "personnel",
17246
+ "pike",
17247
+ "plankton",
17248
+ "pliers",
17249
+ "police",
17250
+ "pollution",
17251
+ "premises",
17252
+ "rain",
17253
+ "research",
17254
+ "rice",
17255
+ "salmon",
17256
+ "scissors",
17257
+ "series",
17258
+ "sewage",
17259
+ "shambles",
17260
+ "shrimp",
17261
+ "software",
17262
+ "staff",
17263
+ "swine",
17264
+ "tennis",
17265
+ "traffic",
17266
+ "transportation",
17267
+ "trout",
17268
+ "tuna",
17269
+ "wealth",
17270
+ "welfare",
17271
+ "whiting",
17272
+ "wildebeest",
17273
+ "wildlife",
17274
+ "you",
17275
+ /pok[e\u00E9]mon$/i,
17276
+ /[^aeiou]ese$/i,
17277
+ /deer$/i,
17278
+ /fish$/i,
17279
+ /measles$/i,
17280
+ /o[iu]s$/i,
17281
+ /pox$/i,
17282
+ /sheep$/i
17283
+ ];
17284
+ for (const [single, plural] of defaultIrregulars) {
17285
+ pluralize.addIrregularRule(single, plural);
17286
+ }
17287
+ for (const [search, replacement] of defaultPlurals) {
17288
+ pluralize.addPluralRule(search, replacement);
17289
+ }
17290
+ for (const [search, replacement] of defaultSingles) {
17291
+ pluralize.addSingularRule(search, replacement);
17292
+ }
17293
+ for (const search of defaultUncountables) {
17294
+ pluralize.addUncountableRule(search);
17295
+ }
17296
+
16964
17297
  // src/utils/array-has-overlaps.ts
16965
17298
  var arrayHasOverlaps = (a, b) => {
16966
17299
  return !new Set(a).isDisjointFrom(new Set(b));
@@ -16968,15 +17301,17 @@ var arrayHasOverlaps = (a, b) => {
16968
17301
 
16969
17302
  // src/utils/error.ts
16970
17303
  var catchError = (error) => error instanceof Error ? error : new Error(`${error}`, { cause: error });
17304
+ var reportRepoError = (path, error) => {
17305
+ const message = (error instanceof Error ? error.message : `${error}`).trim();
17306
+ console.error(`${c3.red("\u2717")} ${path}: ${message}`);
17307
+ return null;
17308
+ };
16971
17309
 
16972
17310
  // src/utils/is-nullish.ts
16973
17311
  var isNullish = (value) => {
16974
17312
  return value === null || value === undefined;
16975
17313
  };
16976
17314
 
16977
- // src/utils/filter-not-null.ts
16978
- var filterNotNull = (array) => array.filter((t) => t !== null);
16979
-
16980
17315
  // src/git/remote.ts
16981
17316
  var KNOWN_PROVIDERS = {
16982
17317
  "github.com": "github",
@@ -17032,7 +17367,7 @@ var parseGitRemoteRefs = (refs) => {
17032
17367
  // src/git/filter.ts
17033
17368
  var oneOrMoreStringsFilterSchema = union([string2(), array(string2())]).transform((v) => Array.isArray(v) ? v : [v]).nullish();
17034
17369
  var booleanFilterSchema = _enum(["true", "false"]).transform((v) => v === "true").nullish();
17035
- var repoFiltersSchema = object({
17370
+ var repoFiltersSchema = strictObject({
17036
17371
  branch: oneOrMoreStringsFilterSchema,
17037
17372
  clean: booleanFilterSchema,
17038
17373
  "remote.ref": oneOrMoreStringsFilterSchema,
@@ -17056,29 +17391,17 @@ var parseQueryString = (query) => {
17056
17391
  }
17057
17392
  const result = repoFiltersSchema.safeParse(rawSearch);
17058
17393
  if (result.error) {
17059
- const issue = result.error.issues.map((i) => `${i.path}: ${i.message}`).join(". ");
17394
+ const issue = result.error.issues.map((i) => {
17395
+ if (i.code === "unrecognized_keys") {
17396
+ return `${pluralize("unknown filter", i.keys.length, true)}: ${i.keys.map((key) => `"${key}"`).join(", ")}`;
17397
+ }
17398
+ return `${i.path}: ${i.message}`;
17399
+ }).join(". ");
17060
17400
  throw new Error(`Invalid filter query. ${issue}`);
17061
17401
  }
17062
17402
  return result.data;
17063
17403
  };
17064
17404
  var repoMatchesFilter = async (repo, filters) => {
17065
- const status = await repo.git.status().catch(catchError);
17066
- if (status instanceof Error) {
17067
- return false;
17068
- }
17069
- const rawRemotes = await repo.git.getRemotes(true);
17070
- const remotes = parseGitRemoteRefs(rawRemotes);
17071
- if (!isNullish(filters.branch) && status.current) {
17072
- if (!arrayHasOverlaps(filters.branch, [status.current])) {
17073
- return false;
17074
- }
17075
- }
17076
- if (!isNullish(filters.clean)) {
17077
- const isClean = status.isClean();
17078
- if (filters.clean !== isClean) {
17079
- return false;
17080
- }
17081
- }
17082
17405
  const remoteStringFilters = [
17083
17406
  "ref",
17084
17407
  "provider",
@@ -17086,58 +17409,67 @@ var repoMatchesFilter = async (repo, filters) => {
17086
17409
  "host",
17087
17410
  "name"
17088
17411
  ];
17089
- for (const remoteKey of remoteStringFilters) {
17090
- const filterKey = `remote.${remoteKey}`;
17091
- if (!isNullish(filters[filterKey])) {
17092
- const needles = filters[filterKey];
17093
- const haystacks = remotes.map((r) => r[remoteKey]);
17094
- if (!arrayHasOverlaps(needles, haystacks)) {
17412
+ const needsStatus = !isNullish(filters.branch) || !isNullish(filters.clean);
17413
+ const needsRemotes = remoteStringFilters.some((key) => !isNullish(filters[`remote.${key}`]));
17414
+ if (!needsStatus && !needsRemotes) {
17415
+ return true;
17416
+ }
17417
+ if (needsStatus) {
17418
+ const status = await repo.git.status().catch(catchError);
17419
+ if (status instanceof Error) {
17420
+ return false;
17421
+ }
17422
+ if (!isNullish(filters.branch) && status.current) {
17423
+ if (!arrayHasOverlaps(filters.branch, [status.current])) {
17095
17424
  return false;
17096
17425
  }
17097
17426
  }
17098
- }
17099
- return true;
17100
- };
17101
-
17102
- // src/git/discover.ts
17103
- async function* findGitRepositoryPaths(root, options) {
17104
- if (!options.skipConfig) {
17105
- const repos = await config2.get().then((c) => c.repositories);
17106
- if (repos) {
17107
- for (const repo of repos) {
17108
- yield repo.path;
17427
+ if (!isNullish(filters.clean)) {
17428
+ const isClean = status.isClean();
17429
+ if (filters.clean !== isClean) {
17430
+ return false;
17109
17431
  }
17110
- return;
17111
17432
  }
17112
17433
  }
17113
- const matches = await glob("**/.git", {
17114
- cwd: root,
17115
- dot: true,
17116
- onlyFiles: false,
17117
- expandDirectories: false,
17118
- absolute: true
17119
- });
17120
- for (const path of matches) {
17121
- yield dirname2(path);
17122
- }
17123
- }
17124
- async function* findGitRepositories(root, filter, options = { skipConfig: false }) {
17125
- for await (const path of findGitRepositoryPaths(root, options)) {
17126
- const repo = {
17127
- path: { absolute: path, relative: relative2(root, path) || "." },
17128
- git: esm_default(path, { baseDir: path })
17129
- };
17130
- if (!await repoMatchesFilter(repo, filter)) {
17131
- continue;
17434
+ if (needsRemotes) {
17435
+ const rawRemotes = await repo.git.getRemotes(true).catch(catchError);
17436
+ if (rawRemotes instanceof Error) {
17437
+ return false;
17438
+ }
17439
+ const remotes = parseGitRemoteRefs(rawRemotes);
17440
+ for (const remoteKey of remoteStringFilters) {
17441
+ const filterKey = `remote.${remoteKey}`;
17442
+ if (!isNullish(filters[filterKey])) {
17443
+ const needles = filters[filterKey];
17444
+ const haystacks = remotes.map((r) => r[remoteKey]);
17445
+ if (!arrayHasOverlaps(needles, haystacks)) {
17446
+ return false;
17447
+ }
17448
+ }
17132
17449
  }
17133
- yield repo;
17134
17450
  }
17135
- }
17451
+ return true;
17452
+ };
17136
17453
 
17137
17454
  // src/git/worker.ts
17138
- var forEachRepo = async (root, _label, visit, options) => {
17455
+ var forEachRepo = async (root, visit, options) => {
17139
17456
  const limit = pLimit(options.parallel);
17140
- const repos = await Array.fromAsync(findGitRepositories(root, options.where));
17457
+ const paths = await Array.fromAsync(findGitRepositoryPaths(root, {
17458
+ skipConfig: options.skipConfig ?? false
17459
+ }));
17460
+ const repos = await Promise.all(paths.map((path) => limit(async () => {
17461
+ const repo = {
17462
+ path: {
17463
+ absolute: path,
17464
+ relative: relative2(root, path) || "."
17465
+ },
17466
+ git: esm_default(path, { baseDir: path })
17467
+ };
17468
+ if (!await repoMatchesFilter(repo, options.where)) {
17469
+ return null;
17470
+ }
17471
+ return repo;
17472
+ }))).then(filterNotNull);
17141
17473
  const promises = repos.map((repo) => limit(() => visit(repo)));
17142
17474
  const results = await Promise.all(promises);
17143
17475
  return results;
@@ -17181,13 +17513,18 @@ var checkoutCommand = new Command("checkout").description("Switch branches").arg
17181
17513
  const programOptions = getProgramOptions();
17182
17514
  const root = process.cwd();
17183
17515
  const table = new CliTable({ head: ["path", "result"] });
17184
- const results = await forEachRepo(root, `checking out ${branch}`, async ({ path, git }) => {
17516
+ let failed = false;
17517
+ const results = await forEachRepo(root, async ({ path, git }) => {
17185
17518
  const result = await git.checkout(branch).catch(catchError);
17186
17519
  if (result instanceof Error) {
17187
- return null;
17520
+ failed = true;
17521
+ return reportRepoError(path.relative, result);
17188
17522
  }
17189
17523
  return [path.relative, branch];
17190
17524
  }, programOptions);
17525
+ if (failed) {
17526
+ process.exitCode = 1;
17527
+ }
17191
17528
  table.push(...filterNotNull(results));
17192
17529
  console.log(table.toString());
17193
17530
  });
@@ -17315,10 +17652,6 @@ ${indent}`);
17315
17652
  return value;
17316
17653
  }
17317
17654
 
17318
- // src/utils/colour.ts
17319
- var import_picocolors = __toESM(require_picocolors(), 1);
17320
- var c3 = import_picocolors.default;
17321
-
17322
17655
  // src/program/commands/config/init/command.ts
17323
17656
  var initCommand = new Command("init").description(dedent_default`
17324
17657
  Initialises a git swarm config.
@@ -17331,9 +17664,10 @@ var initCommand = new Command("init").description(dedent_default`
17331
17664
  }
17332
17665
  const programOptions = getProgramOptions();
17333
17666
  const root = process.cwd();
17334
- const repos = await Array.fromAsync(findGitRepositories(root, programOptions.where, {
17667
+ const repos = await forEachRepo(root, async (repo) => repo, {
17668
+ ...programOptions,
17335
17669
  skipConfig: true
17336
- }));
17670
+ });
17337
17671
  repos.sort((a, b) => a.path.relative.localeCompare(b.path.relative));
17338
17672
  const configData = {
17339
17673
  ...defaultConfig,
@@ -17355,9 +17689,10 @@ var refreshCommand = new Command("refresh").description(dedent_default`
17355
17689
  const oldConfig = await config2.get();
17356
17690
  const programOptions = getProgramOptions();
17357
17691
  const root = process.cwd();
17358
- const repos = await Array.fromAsync(findGitRepositories(root, programOptions.where, {
17692
+ const repos = await forEachRepo(root, async (repo) => repo, {
17693
+ ...programOptions,
17359
17694
  skipConfig: true
17360
- }));
17695
+ });
17361
17696
  repos.sort((a, b) => a.path.relative.localeCompare(b.path.relative));
17362
17697
  const configData = {
17363
17698
  ...oldConfig,
@@ -17393,10 +17728,12 @@ var diffCommand = new Command("diff").description("Show changes across all repos
17393
17728
  const programOptions = getProgramOptions();
17394
17729
  const root = process.cwd();
17395
17730
  const diffArgs = options.cached ? ["--cached"] : [];
17396
- const results = await forEachRepo(root, "diffing repositories", async ({ path, git }) => {
17731
+ let failed = false;
17732
+ const results = await forEachRepo(root, async ({ path, git }) => {
17397
17733
  const summary = await git.diffSummary(rev ? [rev, ...diffArgs] : diffArgs).catch(catchError);
17398
17734
  if (summary instanceof Error) {
17399
- return null;
17735
+ failed = true;
17736
+ return reportRepoError(path.relative, summary);
17400
17737
  }
17401
17738
  if (summary.changed === 0) {
17402
17739
  return null;
@@ -17405,6 +17742,7 @@ var diffCommand = new Command("diff").description("Show changes across all repos
17405
17742
  }, programOptions);
17406
17743
  const diffs = filterNotNull(results);
17407
17744
  if (diffs.length === 0) {
17745
+ process.exitCode = failed ? 1 : 0;
17408
17746
  return;
17409
17747
  }
17410
17748
  const head = options.stat ? ["path", "files", "insertions", "deletions"] : ["path", "file", "changes", "insertions", "deletions"];
@@ -17460,7 +17798,7 @@ var printLines = (prefix, lines) => {
17460
17798
  var execCommand = new Command("exec").description("Run a command in every repository").option("-v, --verbose", "use compact output format").passThroughOptions().argument("<command...>", "the command and arguments to run").action(async (command, options) => {
17461
17799
  const programOptions = getProgramOptions();
17462
17800
  const root = process.cwd();
17463
- const results = await forEachRepo(root, "executing command", async ({ path }) => runCommand(path.relative, path.absolute, command), programOptions);
17801
+ const results = await forEachRepo(root, async ({ path }) => runCommand(path.relative, path.absolute, command), programOptions);
17464
17802
  if (options.verbose) {
17465
17803
  const maxWidth = Math.max(...results.map((result) => `[${result.path}]`.length));
17466
17804
  for (const result of results) {
@@ -17484,10 +17822,10 @@ var execCommand = new Command("exec").description("Run a command in every reposi
17484
17822
  // src/program/commands/fetch/command.ts
17485
17823
  var getFetchSummary = (result) => {
17486
17824
  const chunks = [
17487
- result.branches.length ? `${result.branches.length} new branch(s)` : null,
17488
- result.tags.length ? `${result.tags.length} new tag(s)` : null,
17489
- result.updated.length ? `${result.updated.length} branch(s) updated` : null,
17490
- result.deleted.length ? `${result.deleted.length} branch(s) deleted` : null
17825
+ result.branches.length ? pluralize("new branch", result.branches.length, true) : null,
17826
+ result.tags.length ? pluralize("new tag", result.tags.length, true) : null,
17827
+ result.updated.length ? `${pluralize("branch", result.updated.length, true)} updated` : null,
17828
+ result.deleted.length ? `${pluralize("branch", result.deleted.length, true)} deleted` : null
17491
17829
  ].filter(Boolean);
17492
17830
  return chunks.join(", ") || "already up-to-date";
17493
17831
  };
@@ -17495,13 +17833,18 @@ var fetchCommand = new Command("fetch").description("Download objects and refs f
17495
17833
  const programOptions = getProgramOptions();
17496
17834
  const root = process.cwd();
17497
17835
  const table = new CliTable({ head: ["path", "result"] });
17498
- const results = await forEachRepo(root, "fetching repositories", async ({ path, git }) => {
17836
+ let failed = false;
17837
+ const results = await forEachRepo(root, async ({ path, git }) => {
17499
17838
  const result = await git.fetch(options?.prune ? ["--prune"] : []).catch(catchError);
17500
17839
  if (result instanceof Error) {
17501
- return null;
17840
+ failed = true;
17841
+ return reportRepoError(path.relative, result);
17502
17842
  }
17503
17843
  return [path.relative, getFetchSummary(result)];
17504
17844
  }, programOptions);
17845
+ if (failed) {
17846
+ process.exitCode = 1;
17847
+ }
17505
17848
  table.push(...filterNotNull(results));
17506
17849
  console.log(table.toString());
17507
17850
  });
@@ -17525,10 +17868,10 @@ var findBranchCommand = new Command("find-branch").description("Search repositor
17525
17868
  const table = new CliTable({
17526
17869
  head: ["path", "result"]
17527
17870
  });
17528
- const results = await forEachRepo(root, "searching repositories", async ({ path, git }) => {
17871
+ const results = await forEachRepo(root, async ({ path, git }) => {
17529
17872
  const result = await git.branch().catch(catchError);
17530
17873
  if (result instanceof Error) {
17531
- return null;
17874
+ return reportRepoError(path.relative, result);
17532
17875
  }
17533
17876
  const found = getBranchSummary(branch, result.all);
17534
17877
  if (found) {
@@ -17537,7 +17880,7 @@ var findBranchCommand = new Command("find-branch").description("Search repositor
17537
17880
  return null;
17538
17881
  }, programOptions);
17539
17882
  const matches = filterNotNull(results);
17540
- console.log(`${c3.gray("branch")} ${c3.bold(branch)} ${c3.gray(`found in ${matches.length} repo(s):`)}`);
17883
+ console.log(`${c3.gray("branch")} ${c3.bold(branch)} ${c3.gray(`found in ${pluralize("repo", matches.length, true)}:`)}`);
17541
17884
  if (matches.length === 0) {
17542
17885
  return;
17543
17886
  }
@@ -17549,10 +17892,10 @@ var findBranchCommand = new Command("find-branch").description("Search repositor
17549
17892
  var grepCommand = new Command("grep").description("Search for a pattern across all repositories").passThroughOptions().argument("<pattern>", "the search pattern").argument("[options...]", "git-grep search options", []).action(async (pattern, grepOptions) => {
17550
17893
  const programOptions = getProgramOptions();
17551
17894
  const root = process.cwd();
17552
- const results = await forEachRepo(root, `searching for "${pattern}"`, async ({ path, git }) => {
17895
+ const results = await forEachRepo(root, async ({ path, git }) => {
17553
17896
  const result = await git.grep(pattern, grepOptions).catch(catchError);
17554
17897
  if (result instanceof Error) {
17555
- return null;
17898
+ return reportRepoError(path.relative, result);
17556
17899
  }
17557
17900
  const lines = [];
17558
17901
  for (const [file, matches] of Object.entries(result.results)) {
@@ -17592,8 +17935,793 @@ var listCommand = new Command("list").description("List repositories discovered
17592
17935
  const table = new CliTable({
17593
17936
  head: ["path"]
17594
17937
  });
17595
- for await (const { path } of findGitRepositories(root, programOptions.where)) {
17596
- table.push([path.relative]);
17938
+ const repos = await forEachRepo(root, async ({ path }) => path.relative, programOptions);
17939
+ for (const relative of repos) {
17940
+ table.push([relative]);
17941
+ }
17942
+ console.log(table.toString());
17943
+ });
17944
+
17945
+ // node_modules/date-fns/constants.js
17946
+ var daysInYear = 365.2425;
17947
+ var maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1000;
17948
+ var minTime = -maxTime;
17949
+ var minutesInMonth = 43200;
17950
+ var minutesInDay = 1440;
17951
+ var secondsInHour = 3600;
17952
+ var secondsInDay = secondsInHour * 24;
17953
+ var secondsInWeek = secondsInDay * 7;
17954
+ var secondsInYear = secondsInDay * daysInYear;
17955
+ var secondsInMonth = secondsInYear / 12;
17956
+ var secondsInQuarter = secondsInMonth * 3;
17957
+ var constructFromSymbol = Symbol.for("constructDateFrom");
17958
+
17959
+ // node_modules/date-fns/constructFrom.js
17960
+ function constructFrom(date, value) {
17961
+ if (typeof date === "function")
17962
+ return date(value);
17963
+ if (date && typeof date === "object" && constructFromSymbol in date)
17964
+ return date[constructFromSymbol](value);
17965
+ if (date instanceof Date)
17966
+ return new date.constructor(value);
17967
+ return new Date(value);
17968
+ }
17969
+
17970
+ // node_modules/date-fns/toDate.js
17971
+ function toDate(argument, context) {
17972
+ return constructFrom(context || argument, argument);
17973
+ }
17974
+
17975
+ // node_modules/date-fns/_lib/defaultOptions.js
17976
+ var defaultOptions3 = {};
17977
+ function getDefaultOptions() {
17978
+ return defaultOptions3;
17979
+ }
17980
+
17981
+ // node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js
17982
+ function getTimezoneOffsetInMilliseconds(date) {
17983
+ const _date = toDate(date);
17984
+ const utcDate = new Date(Date.UTC(_date.getFullYear(), _date.getMonth(), _date.getDate(), _date.getHours(), _date.getMinutes(), _date.getSeconds(), _date.getMilliseconds()));
17985
+ utcDate.setUTCFullYear(_date.getFullYear());
17986
+ return +date - +utcDate;
17987
+ }
17988
+
17989
+ // node_modules/date-fns/_lib/normalizeDates.js
17990
+ function normalizeDates(context, ...dates) {
17991
+ const normalize = constructFrom.bind(null, context || dates.find((date) => typeof date === "object"));
17992
+ return dates.map(normalize);
17993
+ }
17994
+
17995
+ // node_modules/date-fns/compareAsc.js
17996
+ function compareAsc(dateLeft, dateRight) {
17997
+ const diff = +toDate(dateLeft) - +toDate(dateRight);
17998
+ if (diff < 0)
17999
+ return -1;
18000
+ else if (diff > 0)
18001
+ return 1;
18002
+ return diff;
18003
+ }
18004
+
18005
+ // node_modules/date-fns/constructNow.js
18006
+ function constructNow(date) {
18007
+ return constructFrom(date, Date.now());
18008
+ }
18009
+
18010
+ // node_modules/date-fns/differenceInCalendarMonths.js
18011
+ function differenceInCalendarMonths(laterDate, earlierDate, options) {
18012
+ const [laterDate_, earlierDate_] = normalizeDates(options?.in, laterDate, earlierDate);
18013
+ const yearsDiff = laterDate_.getFullYear() - earlierDate_.getFullYear();
18014
+ const monthsDiff = laterDate_.getMonth() - earlierDate_.getMonth();
18015
+ return yearsDiff * 12 + monthsDiff;
18016
+ }
18017
+
18018
+ // node_modules/date-fns/_lib/getRoundingMethod.js
18019
+ function getRoundingMethod(method) {
18020
+ return (number) => {
18021
+ const round = method ? Math[method] : Math.trunc;
18022
+ const result = round(number);
18023
+ return result === 0 ? 0 : result;
18024
+ };
18025
+ }
18026
+
18027
+ // node_modules/date-fns/differenceInMilliseconds.js
18028
+ function differenceInMilliseconds(laterDate, earlierDate) {
18029
+ return +toDate(laterDate) - +toDate(earlierDate);
18030
+ }
18031
+
18032
+ // node_modules/date-fns/endOfDay.js
18033
+ function endOfDay(date, options) {
18034
+ const _date = toDate(date, options?.in);
18035
+ _date.setHours(23, 59, 59, 999);
18036
+ return _date;
18037
+ }
18038
+
18039
+ // node_modules/date-fns/endOfMonth.js
18040
+ function endOfMonth(date, options) {
18041
+ const _date = toDate(date, options?.in);
18042
+ const month = _date.getMonth();
18043
+ _date.setFullYear(_date.getFullYear(), month + 1, 0);
18044
+ _date.setHours(23, 59, 59, 999);
18045
+ return _date;
18046
+ }
18047
+
18048
+ // node_modules/date-fns/isLastDayOfMonth.js
18049
+ function isLastDayOfMonth(date, options) {
18050
+ const _date = toDate(date, options?.in);
18051
+ return +endOfDay(_date, options) === +endOfMonth(_date, options);
18052
+ }
18053
+
18054
+ // node_modules/date-fns/differenceInMonths.js
18055
+ function differenceInMonths(laterDate, earlierDate, options) {
18056
+ const [laterDate_, workingLaterDate, earlierDate_] = normalizeDates(options?.in, laterDate, laterDate, earlierDate);
18057
+ const sign = compareAsc(workingLaterDate, earlierDate_);
18058
+ const difference = Math.abs(differenceInCalendarMonths(workingLaterDate, earlierDate_));
18059
+ if (difference < 1)
18060
+ return 0;
18061
+ if (workingLaterDate.getMonth() === 1 && workingLaterDate.getDate() > 27)
18062
+ workingLaterDate.setDate(30);
18063
+ workingLaterDate.setMonth(workingLaterDate.getMonth() - sign * difference);
18064
+ let isLastMonthNotFull = compareAsc(workingLaterDate, earlierDate_) === -sign;
18065
+ if (isLastDayOfMonth(laterDate_) && difference === 1 && compareAsc(laterDate_, earlierDate_) === 1) {
18066
+ isLastMonthNotFull = false;
18067
+ }
18068
+ const result = sign * (difference - +isLastMonthNotFull);
18069
+ return result === 0 ? 0 : result;
18070
+ }
18071
+
18072
+ // node_modules/date-fns/differenceInSeconds.js
18073
+ function differenceInSeconds(laterDate, earlierDate, options) {
18074
+ const diff = differenceInMilliseconds(laterDate, earlierDate) / 1000;
18075
+ return getRoundingMethod(options?.roundingMethod)(diff);
18076
+ }
18077
+
18078
+ // node_modules/date-fns/locale/en-US/_lib/formatDistance.js
18079
+ var formatDistanceLocale = {
18080
+ lessThanXSeconds: {
18081
+ one: "less than a second",
18082
+ other: "less than {{count}} seconds"
18083
+ },
18084
+ xSeconds: {
18085
+ one: "1 second",
18086
+ other: "{{count}} seconds"
18087
+ },
18088
+ halfAMinute: "half a minute",
18089
+ lessThanXMinutes: {
18090
+ one: "less than a minute",
18091
+ other: "less than {{count}} minutes"
18092
+ },
18093
+ xMinutes: {
18094
+ one: "1 minute",
18095
+ other: "{{count}} minutes"
18096
+ },
18097
+ aboutXHours: {
18098
+ one: "about 1 hour",
18099
+ other: "about {{count}} hours"
18100
+ },
18101
+ xHours: {
18102
+ one: "1 hour",
18103
+ other: "{{count}} hours"
18104
+ },
18105
+ xDays: {
18106
+ one: "1 day",
18107
+ other: "{{count}} days"
18108
+ },
18109
+ aboutXWeeks: {
18110
+ one: "about 1 week",
18111
+ other: "about {{count}} weeks"
18112
+ },
18113
+ xWeeks: {
18114
+ one: "1 week",
18115
+ other: "{{count}} weeks"
18116
+ },
18117
+ aboutXMonths: {
18118
+ one: "about 1 month",
18119
+ other: "about {{count}} months"
18120
+ },
18121
+ xMonths: {
18122
+ one: "1 month",
18123
+ other: "{{count}} months"
18124
+ },
18125
+ aboutXYears: {
18126
+ one: "about 1 year",
18127
+ other: "about {{count}} years"
18128
+ },
18129
+ xYears: {
18130
+ one: "1 year",
18131
+ other: "{{count}} years"
18132
+ },
18133
+ overXYears: {
18134
+ one: "over 1 year",
18135
+ other: "over {{count}} years"
18136
+ },
18137
+ almostXYears: {
18138
+ one: "almost 1 year",
18139
+ other: "almost {{count}} years"
18140
+ }
18141
+ };
18142
+ var formatDistance = (token, count, options) => {
18143
+ let result;
18144
+ const tokenValue = formatDistanceLocale[token];
18145
+ if (typeof tokenValue === "string") {
18146
+ result = tokenValue;
18147
+ } else if (count === 1) {
18148
+ result = tokenValue.one;
18149
+ } else {
18150
+ result = tokenValue.other.replace("{{count}}", count.toString());
18151
+ }
18152
+ if (options?.addSuffix) {
18153
+ if (options.comparison && options.comparison > 0) {
18154
+ return "in " + result;
18155
+ } else {
18156
+ return result + " ago";
18157
+ }
18158
+ }
18159
+ return result;
18160
+ };
18161
+
18162
+ // node_modules/date-fns/locale/_lib/buildFormatLongFn.js
18163
+ function buildFormatLongFn(args) {
18164
+ return (options = {}) => {
18165
+ const width = options.width ? String(options.width) : args.defaultWidth;
18166
+ const format = args.formats[width] || args.formats[args.defaultWidth];
18167
+ return format;
18168
+ };
18169
+ }
18170
+
18171
+ // node_modules/date-fns/locale/en-US/_lib/formatLong.js
18172
+ var dateFormats = {
18173
+ full: "EEEE, MMMM do, y",
18174
+ long: "MMMM do, y",
18175
+ medium: "MMM d, y",
18176
+ short: "MM/dd/yyyy"
18177
+ };
18178
+ var timeFormats = {
18179
+ full: "h:mm:ss a zzzz",
18180
+ long: "h:mm:ss a z",
18181
+ medium: "h:mm:ss a",
18182
+ short: "h:mm a"
18183
+ };
18184
+ var dateTimeFormats = {
18185
+ full: "{{date}} 'at' {{time}}",
18186
+ long: "{{date}} 'at' {{time}}",
18187
+ medium: "{{date}}, {{time}}",
18188
+ short: "{{date}}, {{time}}"
18189
+ };
18190
+ var formatLong = {
18191
+ date: buildFormatLongFn({
18192
+ formats: dateFormats,
18193
+ defaultWidth: "full"
18194
+ }),
18195
+ time: buildFormatLongFn({
18196
+ formats: timeFormats,
18197
+ defaultWidth: "full"
18198
+ }),
18199
+ dateTime: buildFormatLongFn({
18200
+ formats: dateTimeFormats,
18201
+ defaultWidth: "full"
18202
+ })
18203
+ };
18204
+
18205
+ // node_modules/date-fns/locale/en-US/_lib/formatRelative.js
18206
+ var formatRelativeLocale = {
18207
+ lastWeek: "'last' eeee 'at' p",
18208
+ yesterday: "'yesterday at' p",
18209
+ today: "'today at' p",
18210
+ tomorrow: "'tomorrow at' p",
18211
+ nextWeek: "eeee 'at' p",
18212
+ other: "P"
18213
+ };
18214
+ var formatRelative = (token, _date, _baseDate, _options) => formatRelativeLocale[token];
18215
+
18216
+ // node_modules/date-fns/locale/_lib/buildLocalizeFn.js
18217
+ function buildLocalizeFn(args) {
18218
+ return (value, options) => {
18219
+ const context = options?.context ? String(options.context) : "standalone";
18220
+ let valuesArray;
18221
+ if (context === "formatting" && args.formattingValues) {
18222
+ const defaultWidth = args.defaultFormattingWidth || args.defaultWidth;
18223
+ const width = options?.width ? String(options.width) : defaultWidth;
18224
+ valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth];
18225
+ } else {
18226
+ const defaultWidth = args.defaultWidth;
18227
+ const width = options?.width ? String(options.width) : args.defaultWidth;
18228
+ valuesArray = args.values[width] || args.values[defaultWidth];
18229
+ }
18230
+ const index = args.argumentCallback ? args.argumentCallback(value) : value;
18231
+ return valuesArray[index];
18232
+ };
18233
+ }
18234
+
18235
+ // node_modules/date-fns/locale/en-US/_lib/localize.js
18236
+ var eraValues = {
18237
+ narrow: ["B", "A"],
18238
+ abbreviated: ["BC", "AD"],
18239
+ wide: ["Before Christ", "Anno Domini"]
18240
+ };
18241
+ var quarterValues = {
18242
+ narrow: ["1", "2", "3", "4"],
18243
+ abbreviated: ["Q1", "Q2", "Q3", "Q4"],
18244
+ wide: ["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"]
18245
+ };
18246
+ var monthValues = {
18247
+ narrow: ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"],
18248
+ abbreviated: [
18249
+ "Jan",
18250
+ "Feb",
18251
+ "Mar",
18252
+ "Apr",
18253
+ "May",
18254
+ "Jun",
18255
+ "Jul",
18256
+ "Aug",
18257
+ "Sep",
18258
+ "Oct",
18259
+ "Nov",
18260
+ "Dec"
18261
+ ],
18262
+ wide: [
18263
+ "January",
18264
+ "February",
18265
+ "March",
18266
+ "April",
18267
+ "May",
18268
+ "June",
18269
+ "July",
18270
+ "August",
18271
+ "September",
18272
+ "October",
18273
+ "November",
18274
+ "December"
18275
+ ]
18276
+ };
18277
+ var dayValues = {
18278
+ narrow: ["S", "M", "T", "W", "T", "F", "S"],
18279
+ short: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
18280
+ abbreviated: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
18281
+ wide: [
18282
+ "Sunday",
18283
+ "Monday",
18284
+ "Tuesday",
18285
+ "Wednesday",
18286
+ "Thursday",
18287
+ "Friday",
18288
+ "Saturday"
18289
+ ]
18290
+ };
18291
+ var dayPeriodValues = {
18292
+ narrow: {
18293
+ am: "a",
18294
+ pm: "p",
18295
+ midnight: "mi",
18296
+ noon: "n",
18297
+ morning: "morning",
18298
+ afternoon: "afternoon",
18299
+ evening: "evening",
18300
+ night: "night"
18301
+ },
18302
+ abbreviated: {
18303
+ am: "AM",
18304
+ pm: "PM",
18305
+ midnight: "midnight",
18306
+ noon: "noon",
18307
+ morning: "morning",
18308
+ afternoon: "afternoon",
18309
+ evening: "evening",
18310
+ night: "night"
18311
+ },
18312
+ wide: {
18313
+ am: "a.m.",
18314
+ pm: "p.m.",
18315
+ midnight: "midnight",
18316
+ noon: "noon",
18317
+ morning: "morning",
18318
+ afternoon: "afternoon",
18319
+ evening: "evening",
18320
+ night: "night"
18321
+ }
18322
+ };
18323
+ var formattingDayPeriodValues = {
18324
+ narrow: {
18325
+ am: "a",
18326
+ pm: "p",
18327
+ midnight: "mi",
18328
+ noon: "n",
18329
+ morning: "in the morning",
18330
+ afternoon: "in the afternoon",
18331
+ evening: "in the evening",
18332
+ night: "at night"
18333
+ },
18334
+ abbreviated: {
18335
+ am: "AM",
18336
+ pm: "PM",
18337
+ midnight: "midnight",
18338
+ noon: "noon",
18339
+ morning: "in the morning",
18340
+ afternoon: "in the afternoon",
18341
+ evening: "in the evening",
18342
+ night: "at night"
18343
+ },
18344
+ wide: {
18345
+ am: "a.m.",
18346
+ pm: "p.m.",
18347
+ midnight: "midnight",
18348
+ noon: "noon",
18349
+ morning: "in the morning",
18350
+ afternoon: "in the afternoon",
18351
+ evening: "in the evening",
18352
+ night: "at night"
18353
+ }
18354
+ };
18355
+ var ordinalNumber = (dirtyNumber, _options) => {
18356
+ const number = Number(dirtyNumber);
18357
+ const rem100 = number % 100;
18358
+ if (rem100 > 20 || rem100 < 10) {
18359
+ switch (rem100 % 10) {
18360
+ case 1:
18361
+ return number + "st";
18362
+ case 2:
18363
+ return number + "nd";
18364
+ case 3:
18365
+ return number + "rd";
18366
+ }
18367
+ }
18368
+ return number + "th";
18369
+ };
18370
+ var localize = {
18371
+ ordinalNumber,
18372
+ era: buildLocalizeFn({
18373
+ values: eraValues,
18374
+ defaultWidth: "wide"
18375
+ }),
18376
+ quarter: buildLocalizeFn({
18377
+ values: quarterValues,
18378
+ defaultWidth: "wide",
18379
+ argumentCallback: (quarter) => quarter - 1
18380
+ }),
18381
+ month: buildLocalizeFn({
18382
+ values: monthValues,
18383
+ defaultWidth: "wide"
18384
+ }),
18385
+ day: buildLocalizeFn({
18386
+ values: dayValues,
18387
+ defaultWidth: "wide"
18388
+ }),
18389
+ dayPeriod: buildLocalizeFn({
18390
+ values: dayPeriodValues,
18391
+ defaultWidth: "wide",
18392
+ formattingValues: formattingDayPeriodValues,
18393
+ defaultFormattingWidth: "wide"
18394
+ })
18395
+ };
18396
+
18397
+ // node_modules/date-fns/locale/_lib/buildMatchFn.js
18398
+ function buildMatchFn(args) {
18399
+ return (string, options = {}) => {
18400
+ const width = options.width;
18401
+ const matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth];
18402
+ const matchResult = string.match(matchPattern);
18403
+ if (!matchResult) {
18404
+ return null;
18405
+ }
18406
+ const matchedString = matchResult[0];
18407
+ const parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth];
18408
+ const key = Array.isArray(parsePatterns) ? findIndex(parsePatterns, (pattern) => pattern.test(matchedString)) : findKey(parsePatterns, (pattern) => pattern.test(matchedString));
18409
+ let value;
18410
+ value = args.valueCallback ? args.valueCallback(key) : key;
18411
+ value = options.valueCallback ? options.valueCallback(value) : value;
18412
+ const rest = string.slice(matchedString.length);
18413
+ return { value, rest };
18414
+ };
18415
+ }
18416
+ function findKey(object, predicate) {
18417
+ for (const key in object) {
18418
+ if (Object.prototype.hasOwnProperty.call(object, key) && predicate(object[key])) {
18419
+ return key;
18420
+ }
18421
+ }
18422
+ return;
18423
+ }
18424
+ function findIndex(array, predicate) {
18425
+ for (let key = 0;key < array.length; key++) {
18426
+ if (predicate(array[key])) {
18427
+ return key;
18428
+ }
18429
+ }
18430
+ return;
18431
+ }
18432
+
18433
+ // node_modules/date-fns/locale/_lib/buildMatchPatternFn.js
18434
+ function buildMatchPatternFn(args) {
18435
+ return (string, options = {}) => {
18436
+ const matchResult = string.match(args.matchPattern);
18437
+ if (!matchResult)
18438
+ return null;
18439
+ const matchedString = matchResult[0];
18440
+ const parseResult = string.match(args.parsePattern);
18441
+ if (!parseResult)
18442
+ return null;
18443
+ let value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0];
18444
+ value = options.valueCallback ? options.valueCallback(value) : value;
18445
+ const rest = string.slice(matchedString.length);
18446
+ return { value, rest };
18447
+ };
18448
+ }
18449
+
18450
+ // node_modules/date-fns/locale/en-US/_lib/match.js
18451
+ var matchOrdinalNumberPattern = /^(\d+)(th|st|nd|rd)?/i;
18452
+ var parseOrdinalNumberPattern = /\d+/i;
18453
+ var matchEraPatterns = {
18454
+ narrow: /^(b|a)/i,
18455
+ abbreviated: /^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,
18456
+ wide: /^(before christ|before common era|anno domini|common era)/i
18457
+ };
18458
+ var parseEraPatterns = {
18459
+ any: [/^b/i, /^(a|c)/i]
18460
+ };
18461
+ var matchQuarterPatterns = {
18462
+ narrow: /^[1234]/i,
18463
+ abbreviated: /^q[1234]/i,
18464
+ wide: /^[1234](th|st|nd|rd)? quarter/i
18465
+ };
18466
+ var parseQuarterPatterns = {
18467
+ any: [/1/i, /2/i, /3/i, /4/i]
18468
+ };
18469
+ var matchMonthPatterns = {
18470
+ narrow: /^[jfmasond]/i,
18471
+ abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,
18472
+ wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i
18473
+ };
18474
+ var parseMonthPatterns = {
18475
+ narrow: [
18476
+ /^j/i,
18477
+ /^f/i,
18478
+ /^m/i,
18479
+ /^a/i,
18480
+ /^m/i,
18481
+ /^j/i,
18482
+ /^j/i,
18483
+ /^a/i,
18484
+ /^s/i,
18485
+ /^o/i,
18486
+ /^n/i,
18487
+ /^d/i
18488
+ ],
18489
+ any: [
18490
+ /^ja/i,
18491
+ /^f/i,
18492
+ /^mar/i,
18493
+ /^ap/i,
18494
+ /^may/i,
18495
+ /^jun/i,
18496
+ /^jul/i,
18497
+ /^au/i,
18498
+ /^s/i,
18499
+ /^o/i,
18500
+ /^n/i,
18501
+ /^d/i
18502
+ ]
18503
+ };
18504
+ var matchDayPatterns = {
18505
+ narrow: /^[smtwf]/i,
18506
+ short: /^(su|mo|tu|we|th|fr|sa)/i,
18507
+ abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,
18508
+ wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i
18509
+ };
18510
+ var parseDayPatterns = {
18511
+ narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],
18512
+ any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i]
18513
+ };
18514
+ var matchDayPeriodPatterns = {
18515
+ narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,
18516
+ any: /^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i
18517
+ };
18518
+ var parseDayPeriodPatterns = {
18519
+ any: {
18520
+ am: /^a/i,
18521
+ pm: /^p/i,
18522
+ midnight: /^mi/i,
18523
+ noon: /^no/i,
18524
+ morning: /morning/i,
18525
+ afternoon: /afternoon/i,
18526
+ evening: /evening/i,
18527
+ night: /night/i
18528
+ }
18529
+ };
18530
+ var match = {
18531
+ ordinalNumber: buildMatchPatternFn({
18532
+ matchPattern: matchOrdinalNumberPattern,
18533
+ parsePattern: parseOrdinalNumberPattern,
18534
+ valueCallback: (value) => parseInt(value, 10)
18535
+ }),
18536
+ era: buildMatchFn({
18537
+ matchPatterns: matchEraPatterns,
18538
+ defaultMatchWidth: "wide",
18539
+ parsePatterns: parseEraPatterns,
18540
+ defaultParseWidth: "any"
18541
+ }),
18542
+ quarter: buildMatchFn({
18543
+ matchPatterns: matchQuarterPatterns,
18544
+ defaultMatchWidth: "wide",
18545
+ parsePatterns: parseQuarterPatterns,
18546
+ defaultParseWidth: "any",
18547
+ valueCallback: (index) => index + 1
18548
+ }),
18549
+ month: buildMatchFn({
18550
+ matchPatterns: matchMonthPatterns,
18551
+ defaultMatchWidth: "wide",
18552
+ parsePatterns: parseMonthPatterns,
18553
+ defaultParseWidth: "any"
18554
+ }),
18555
+ day: buildMatchFn({
18556
+ matchPatterns: matchDayPatterns,
18557
+ defaultMatchWidth: "wide",
18558
+ parsePatterns: parseDayPatterns,
18559
+ defaultParseWidth: "any"
18560
+ }),
18561
+ dayPeriod: buildMatchFn({
18562
+ matchPatterns: matchDayPeriodPatterns,
18563
+ defaultMatchWidth: "any",
18564
+ parsePatterns: parseDayPeriodPatterns,
18565
+ defaultParseWidth: "any"
18566
+ })
18567
+ };
18568
+
18569
+ // node_modules/date-fns/locale/en-US.js
18570
+ var enUS = {
18571
+ code: "en-US",
18572
+ formatDistance,
18573
+ formatLong,
18574
+ formatRelative,
18575
+ localize,
18576
+ match,
18577
+ options: {
18578
+ weekStartsOn: 0,
18579
+ firstWeekContainsDate: 1
18580
+ }
18581
+ };
18582
+ // node_modules/date-fns/formatDistance.js
18583
+ function formatDistance2(laterDate, earlierDate, options) {
18584
+ const defaultOptions = getDefaultOptions();
18585
+ const locale = options?.locale ?? defaultOptions.locale ?? enUS;
18586
+ const minutesInAlmostTwoDays = 2520;
18587
+ const comparison = compareAsc(laterDate, earlierDate);
18588
+ if (isNaN(comparison))
18589
+ throw new RangeError("Invalid time value");
18590
+ const localizeOptions = Object.assign({}, options, {
18591
+ addSuffix: options?.addSuffix,
18592
+ comparison
18593
+ });
18594
+ const [laterDate_, earlierDate_] = normalizeDates(options?.in, ...comparison > 0 ? [earlierDate, laterDate] : [laterDate, earlierDate]);
18595
+ const seconds = differenceInSeconds(earlierDate_, laterDate_);
18596
+ const offsetInSeconds = (getTimezoneOffsetInMilliseconds(earlierDate_) - getTimezoneOffsetInMilliseconds(laterDate_)) / 1000;
18597
+ const minutes = Math.round((seconds - offsetInSeconds) / 60);
18598
+ let months;
18599
+ if (minutes < 2) {
18600
+ if (options?.includeSeconds) {
18601
+ if (seconds < 5) {
18602
+ return locale.formatDistance("lessThanXSeconds", 5, localizeOptions);
18603
+ } else if (seconds < 10) {
18604
+ return locale.formatDistance("lessThanXSeconds", 10, localizeOptions);
18605
+ } else if (seconds < 20) {
18606
+ return locale.formatDistance("lessThanXSeconds", 20, localizeOptions);
18607
+ } else if (seconds < 40) {
18608
+ return locale.formatDistance("halfAMinute", 0, localizeOptions);
18609
+ } else if (seconds < 60) {
18610
+ return locale.formatDistance("lessThanXMinutes", 1, localizeOptions);
18611
+ } else {
18612
+ return locale.formatDistance("xMinutes", 1, localizeOptions);
18613
+ }
18614
+ } else {
18615
+ if (minutes === 0) {
18616
+ return locale.formatDistance("lessThanXMinutes", 1, localizeOptions);
18617
+ } else {
18618
+ return locale.formatDistance("xMinutes", minutes, localizeOptions);
18619
+ }
18620
+ }
18621
+ } else if (minutes < 45) {
18622
+ return locale.formatDistance("xMinutes", minutes, localizeOptions);
18623
+ } else if (minutes < 90) {
18624
+ return locale.formatDistance("aboutXHours", 1, localizeOptions);
18625
+ } else if (minutes < minutesInDay) {
18626
+ const hours = Math.round(minutes / 60);
18627
+ return locale.formatDistance("aboutXHours", hours, localizeOptions);
18628
+ } else if (minutes < minutesInAlmostTwoDays) {
18629
+ return locale.formatDistance("xDays", 1, localizeOptions);
18630
+ } else if (minutes < minutesInMonth) {
18631
+ const days = Math.round(minutes / minutesInDay);
18632
+ return locale.formatDistance("xDays", days, localizeOptions);
18633
+ } else if (minutes < minutesInMonth * 2) {
18634
+ months = Math.round(minutes / minutesInMonth);
18635
+ return locale.formatDistance("aboutXMonths", months, localizeOptions);
18636
+ }
18637
+ months = differenceInMonths(earlierDate_, laterDate_);
18638
+ if (months < 12) {
18639
+ const nearestMonth = Math.round(minutes / minutesInMonth);
18640
+ return locale.formatDistance("xMonths", nearestMonth, localizeOptions);
18641
+ } else {
18642
+ const monthsSinceStartOfYear = months % 12;
18643
+ const years = Math.trunc(months / 12);
18644
+ if (monthsSinceStartOfYear < 3) {
18645
+ return locale.formatDistance("aboutXYears", years, localizeOptions);
18646
+ } else if (monthsSinceStartOfYear < 9) {
18647
+ return locale.formatDistance("overXYears", years, localizeOptions);
18648
+ } else {
18649
+ return locale.formatDistance("almostXYears", years + 1, localizeOptions);
18650
+ }
18651
+ }
18652
+ }
18653
+
18654
+ // node_modules/date-fns/formatDistanceToNow.js
18655
+ function formatDistanceToNow(date, options) {
18656
+ return formatDistance2(date, constructNow(date), options);
18657
+ }
18658
+
18659
+ // src/program/commands/log/command.ts
18660
+ var logCommand = new Command("log").description("Show commit logs across all repositories").argument("[rev]", "the revision or revision range to log").option("--after <date>", "show commits more recent than a specific date").option("--before <date>", "show commits older than a specific date").option("--exact-date", "show the exact commit date instead of a relative time").option("--author", "show the author of each commit").action(async (rev, options) => {
18661
+ const programOptions = getProgramOptions();
18662
+ const root = process.cwd();
18663
+ const logArgs = [
18664
+ ...rev ? [rev] : [],
18665
+ ...options.after ? [`--after=${options.after}`] : [],
18666
+ ...options.before ? [`--before=${options.before}`] : []
18667
+ ];
18668
+ const log = await forEachRepo(root, async ({ path, git }) => {
18669
+ const result = await git.log(["--stat=4096", ...logArgs]).catch(catchError);
18670
+ if (result instanceof Error) {
18671
+ return reportRepoError(path.relative, result);
18672
+ }
18673
+ if (result.all.length === 0) {
18674
+ return null;
18675
+ }
18676
+ return { path: path.relative, log: result };
18677
+ }, programOptions);
18678
+ const logs = filterNotNull(log);
18679
+ if (logs.length === 0) {
18680
+ return;
18681
+ }
18682
+ const rows = [];
18683
+ for (const { path, log } of logs) {
18684
+ for (const entry of log.all) {
18685
+ rows.push({
18686
+ path,
18687
+ hash: entry.hash.slice(0, 7),
18688
+ message: entry.message,
18689
+ date: options.exactDate ? entry.date : formatDistanceToNow(new Date(entry.date), {
18690
+ addSuffix: true
18691
+ }),
18692
+ time: new Date(entry.date).getTime(),
18693
+ author: entry.author_name,
18694
+ files: entry.diff?.changed ?? 0,
18695
+ insertions: entry.diff?.insertions ?? 0,
18696
+ deletions: entry.diff?.deletions ?? 0
18697
+ });
18698
+ }
18699
+ }
18700
+ rows.sort((a, b) => b.time - a.time);
18701
+ const head = [
18702
+ "path",
18703
+ "hash",
18704
+ "date",
18705
+ ...options.author ? ["author"] : [],
18706
+ "message",
18707
+ "files",
18708
+ "insertions",
18709
+ "deletions"
18710
+ ];
18711
+ const table = new CliTable({
18712
+ head
18713
+ });
18714
+ for (const row of rows) {
18715
+ table.push([
18716
+ row.path,
18717
+ row.hash,
18718
+ c3.gray(row.date),
18719
+ ...options.author ? [row.author] : [],
18720
+ row.message,
18721
+ String(row.files),
18722
+ c3.green(`+${row.insertions}`),
18723
+ c3.red(`-${row.deletions}`)
18724
+ ]);
17597
18725
  }
17598
18726
  console.log(table.toString());
17599
18727
  });
@@ -17605,7 +18733,7 @@ var getPullSummary = (result) => {
17605
18733
  }
17606
18734
  const { insertions, deletions } = result.summary;
17607
18735
  const chunks = [
17608
- `${result.files.length} file(s) changed`,
18736
+ `${pluralize("file", result.files.length, true)} changed`,
17609
18737
  insertions ? `+${insertions}` : null,
17610
18738
  deletions ? `-${deletions}` : null
17611
18739
  ];
@@ -17615,13 +18743,18 @@ var pullCommand = new Command("pull").description("Fetch from and integrate with
17615
18743
  const programOptions = getProgramOptions();
17616
18744
  const root = process.cwd();
17617
18745
  const table = new CliTable({ head: ["path", "result"] });
17618
- const results = await forEachRepo(root, "pulling repositories", async ({ path, git }) => {
18746
+ let failed = false;
18747
+ const results = await forEachRepo(root, async ({ path, git }) => {
17619
18748
  const result = await git.pull(remote ?? undefined, branch ?? undefined).catch(catchError);
17620
18749
  if (result instanceof Error) {
17621
- return null;
18750
+ failed = true;
18751
+ return reportRepoError(path.relative, result);
17622
18752
  }
17623
18753
  return [path.relative, getPullSummary(result)];
17624
18754
  }, programOptions);
18755
+ if (failed) {
18756
+ process.exitCode = 1;
18757
+ }
17625
18758
  table.push(...filterNotNull(results));
17626
18759
  console.log(table.toString());
17627
18760
  });
@@ -17677,10 +18810,10 @@ var remoteCommand = new Command("remote").description("List remotes for each rep
17677
18810
  "name"
17678
18811
  ]
17679
18812
  });
17680
- const results = await forEachRepo(root, "listing remotes", async ({ path, git }) => {
18813
+ const results = await forEachRepo(root, async ({ path, git }) => {
17681
18814
  const remotes = await git.getRemotes(true).catch(catchError);
17682
18815
  if (remotes instanceof Error) {
17683
- return null;
18816
+ return reportRepoError(path.relative, remotes);
17684
18817
  }
17685
18818
  const parsed = parseGitRemoteRefs(remotes);
17686
18819
  if (parsed.length === 0) {
@@ -17708,7 +18841,7 @@ var getStatusSummary = (status) => {
17708
18841
  return c3.green("clean");
17709
18842
  }
17710
18843
  if (status.not_added.length) {
17711
- return c3.red(`${status.not_added.length} untracked item(s)`);
18844
+ return c3.red(pluralize("untracked item", status.not_added.length, true));
17712
18845
  }
17713
18846
  return c3.gray("unknown");
17714
18847
  };
@@ -17718,11 +18851,10 @@ var statusCommand = new Command("status").description("Show the working tree sta
17718
18851
  const table = new CliTable({
17719
18852
  head: ["path", "branch", "tracking", "status"]
17720
18853
  });
17721
- const results = await forEachRepo(root, "checking repositories", async ({ path, git }) => {
18854
+ const results = await forEachRepo(root, async ({ path, git }) => {
17722
18855
  const status = await git.status().catch(catchError);
17723
18856
  if (status instanceof Error) {
17724
- if (false) {}
17725
- return null;
18857
+ return reportRepoError(path.relative, status);
17726
18858
  }
17727
18859
  return [
17728
18860
  path.relative,
@@ -17736,23 +18868,46 @@ var statusCommand = new Command("status").description("Show the working tree sta
17736
18868
  });
17737
18869
 
17738
18870
  // src/program/options/parallel.ts
17739
- var defaultValue = await config2.getOption("parallel");
17740
- var parallelOption = new Option("--parallel <count>", "run git in parallel").default(defaultValue, defaultValue === 1 ? "sequential" : defaultValue.toString()).argParser((value) => Number(value));
18871
+ var toParallel = (value) => {
18872
+ const parallel = Number(value);
18873
+ if (!Number.isInteger(parallel) || parallel < 0) {
18874
+ throw new InvalidArgumentError("expected a non-negative integer (0 = unlimited, 1 = sequential)");
18875
+ }
18876
+ if (parallel === 0) {
18877
+ return Infinity;
18878
+ }
18879
+ return parallel;
18880
+ };
18881
+ var valueDescription = (value) => {
18882
+ switch (true) {
18883
+ case value === 0:
18884
+ return "unlimited";
18885
+ case value === 1:
18886
+ return "sequential";
18887
+ default:
18888
+ return value.toLocaleString();
18889
+ }
18890
+ };
18891
+ var defaultValue = toParallel(await config2.getOption("parallel"));
18892
+ var parallelOption = new Option("--parallel <count>", "run git in parallel, 0 = unlimited").default(defaultValue, valueDescription(defaultValue)).argParser(toParallel);
17741
18893
 
17742
18894
  // src/program/options/where.ts
17743
18895
  var defaultWhere = await config2.getOption("where");
17744
18896
  var whereOption = new Option("--where <query>", "filter repos by a query string").default(parseQueryString(defaultWhere), defaultWhere || "all repos").argParser((value) => {
17745
- const parsed = parseQueryString(value);
17746
- if (parsed instanceof Error) {
17747
- throw new InvalidArgumentError(parsed.message);
18897
+ try {
18898
+ return parseQueryString(value);
18899
+ } catch (error) {
18900
+ if (error instanceof Error) {
18901
+ throw new InvalidArgumentError(error.message);
18902
+ }
18903
+ throw error;
17748
18904
  }
17749
- return parsed;
17750
18905
  });
17751
18906
 
17752
18907
  // src/program/index.ts
17753
18908
  var program2 = new Command;
17754
18909
  var getProgramOptions = () => program2.opts();
17755
- program2.name("git-swarm").description(package_default.description).version(package_default.version).enablePositionalOptions().addOption(parallelOption).addOption(whereOption).addCommand(checkoutCommand).addCommand(configCommand).addCommand(diffCommand).addCommand(execCommand).addCommand(fetchCommand).addCommand(findBranchCommand).addCommand(grepCommand).addCommand(listCommand).addCommand(pullCommand).addCommand(remoteCommand).addCommand(statusCommand);
18910
+ program2.name("git-swarm").description(package_default.description).version(package_default.version).enablePositionalOptions().addOption(parallelOption).addOption(whereOption).addCommand(checkoutCommand).addCommand(configCommand).addCommand(diffCommand).addCommand(execCommand).addCommand(fetchCommand).addCommand(findBranchCommand).addCommand(grepCommand).addCommand(listCommand).addCommand(logCommand).addCommand(pullCommand).addCommand(remoteCommand).addCommand(statusCommand);
17756
18911
 
17757
18912
  // src/cli.ts
17758
18913
  program2.parse();