@kitschpatrol/shared-config 5.6.0 → 5.7.1

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/bin/cli.js +173 -91
  2. package/package.json +15 -14
  3. package/readme.md +47 -47
package/bin/cli.js CHANGED
@@ -11084,7 +11084,7 @@ var Yargs = YargsFactory(esm_default);
11084
11084
  var yargs_default = Yargs;
11085
11085
 
11086
11086
  // ../../package.json
11087
- var version = "5.6.0";
11087
+ var version = "5.7.1";
11088
11088
 
11089
11089
  // ../../src/execa-utilities.ts
11090
11090
  function isErrorExecaError(error) {
@@ -11975,7 +11975,7 @@ var commandDefinition = {
11975
11975
  description: "Kitschpatrol's CSpell shared configuration tools. (Automated fixes are handled by ESLint.)",
11976
11976
  logColor: "cyan",
11977
11977
  logPrefix: "[CSpell]",
11978
- name: "kpi-cspell",
11978
+ name: "ksc-cspell",
11979
11979
  order: 6
11980
11980
  };
11981
11981
 
@@ -12045,7 +12045,7 @@ var commandDefinition2 = {
12045
12045
  description: "Kitschpatrol's ESLint shared configuration tools.",
12046
12046
  logColor: "magenta",
12047
12047
  logPrefix: `[ESLint]`,
12048
- name: "kpi-eslint",
12048
+ name: "ksc-eslint",
12049
12049
  order: 4
12050
12050
  };
12051
12051
 
@@ -12068,17 +12068,17 @@ var sharedKnipConfig = {
12068
12068
  "prettier.config.{js,mjs,cjs,ts,mts,cts}",
12069
12069
  "stylelint.config.{js,mjs,cjs,ts,mts,cts}"
12070
12070
  ],
12071
- // Allow calling of individual kpi binaries...
12071
+ // Allow calling of individual ksc binaries...
12072
12072
  ignoreBinaries: [
12073
- "kpi-repo",
12074
- "kpi-mdat",
12075
- "kpi-typescript",
12076
- "kpi-eslint",
12077
- "kpi-stylelint",
12078
- "kpi-cspell",
12079
- "kpi-knip",
12080
- "kpi-remark",
12081
- "kpi-prettier",
12073
+ "ksc-repo",
12074
+ "ksc-mdat",
12075
+ "ksc-typescript",
12076
+ "ksc-eslint",
12077
+ "ksc-stylelint",
12078
+ "ksc-cspell",
12079
+ "ksc-knip",
12080
+ "ksc-remark",
12081
+ "ksc-prettier",
12082
12082
  // 1Password CLI, typically a global install...
12083
12083
  "op",
12084
12084
  // GitHub CLI, typically a global install...
@@ -12128,8 +12128,8 @@ function getKnipPackageJsonObject() {
12128
12128
  var commandDefinition3 = {
12129
12129
  commands: {
12130
12130
  // In practice, Knip's auto-fix behavior is too dangerous for most projects.
12131
- // Since kpi doesn't currently have per-tool configuration options, we'll
12132
- // just disable `kpi-knip fix` for now.
12131
+ // Since ksc doesn't currently have per-tool configuration options, we'll
12132
+ // just disable `ksc-knip fix` for now.
12133
12133
  //
12134
12134
  // fix: {
12135
12135
  // commands: [
@@ -12181,7 +12181,7 @@ var commandDefinition3 = {
12181
12181
  description: "Kitschpatrol's Knip shared configuration tools.",
12182
12182
  logColor: "cyan",
12183
12183
  logPrefix: "[Knip]",
12184
- name: "kpi-knip",
12184
+ name: "ksc-knip",
12185
12185
  order: 7
12186
12186
  };
12187
12187
 
@@ -12262,7 +12262,7 @@ var commandDefinition4 = {
12262
12262
  description: "Kitschpatrol's Mdat shared configuration tools.",
12263
12263
  logColor: "green",
12264
12264
  logPrefix: "[Mdat Config]",
12265
- name: "kpi-mdat",
12265
+ name: "ksc-mdat",
12266
12266
  order: 2
12267
12267
  };
12268
12268
 
@@ -12326,7 +12326,7 @@ var commandDefinition5 = {
12326
12326
  description: "Kitschpatrol's Prettier shared configuration tools.",
12327
12327
  logColor: "blue",
12328
12328
  logPrefix: "[Prettier]",
12329
- name: "kpi-prettier",
12329
+ name: "ksc-prettier",
12330
12330
  order: 9
12331
12331
  };
12332
12332
 
@@ -12352,18 +12352,19 @@ var commandDefinition6 = {
12352
12352
  description: "Kitschpatrol's Remark and Remark Lint shared configuration tools. (Actual linting and fixing is managed through @kitschpatrol/eslint-config.)",
12353
12353
  logColor: "blue",
12354
12354
  logPrefix: "[remarklint]",
12355
- name: "kpi-remark",
12355
+ name: "ksc-remark",
12356
12356
  order: 8
12357
12357
  };
12358
12358
 
12359
- // ../../node_modules/.pnpm/globby@14.1.0/node_modules/globby/index.js
12359
+ // ../../node_modules/.pnpm/globby@15.0.0/node_modules/globby/index.js
12360
12360
  import process5 from "node:process";
12361
12361
  import fs6 from "node:fs";
12362
12362
  import nodePath from "node:path";
12363
+ import { Readable } from "node:stream";
12363
12364
 
12364
- // ../../node_modules/.pnpm/@sindresorhus+merge-streams@2.3.0/node_modules/@sindresorhus/merge-streams/index.js
12365
+ // ../../node_modules/.pnpm/@sindresorhus+merge-streams@4.0.0/node_modules/@sindresorhus/merge-streams/index.js
12365
12366
  import { on, once } from "node:events";
12366
- import { PassThrough as PassThroughStream } from "node:stream";
12367
+ import { PassThrough as PassThroughStream, getDefaultHighWaterMark } from "node:stream";
12367
12368
  import { finished } from "node:stream/promises";
12368
12369
  function mergeStreams(streams) {
12369
12370
  if (!Array.isArray(streams)) {
@@ -12382,14 +12383,11 @@ function mergeStreams(streams) {
12382
12383
  for (const stream of streams) {
12383
12384
  passThroughStream.add(stream);
12384
12385
  }
12385
- if (streams.length === 0) {
12386
- endStream(passThroughStream);
12387
- }
12388
12386
  return passThroughStream;
12389
12387
  }
12390
12388
  var getHighWaterMark = (streams, objectMode) => {
12391
12389
  if (streams.length === 0) {
12392
- return 16384;
12390
+ return getDefaultHighWaterMark(objectMode);
12393
12391
  }
12394
12392
  const highWaterMarks = streams.filter(({ readableObjectMode }) => readableObjectMode === objectMode).map(({ readableHighWaterMark }) => readableHighWaterMark);
12395
12393
  return Math.max(...highWaterMarks);
@@ -12399,39 +12397,49 @@ var MergedStream = class extends PassThroughStream {
12399
12397
  #ended = /* @__PURE__ */ new Set([]);
12400
12398
  #aborted = /* @__PURE__ */ new Set([]);
12401
12399
  #onFinished;
12400
+ #unpipeEvent = Symbol("unpipe");
12401
+ #streamPromises = /* @__PURE__ */ new WeakMap();
12402
12402
  add(stream) {
12403
12403
  validateStream(stream);
12404
12404
  if (this.#streams.has(stream)) {
12405
12405
  return;
12406
12406
  }
12407
12407
  this.#streams.add(stream);
12408
- this.#onFinished ??= onMergedStreamFinished(this, this.#streams);
12409
- endWhenStreamsDone({
12408
+ this.#onFinished ??= onMergedStreamFinished(this, this.#streams, this.#unpipeEvent);
12409
+ const streamPromise = endWhenStreamsDone({
12410
12410
  passThroughStream: this,
12411
12411
  stream,
12412
12412
  streams: this.#streams,
12413
12413
  ended: this.#ended,
12414
12414
  aborted: this.#aborted,
12415
- onFinished: this.#onFinished
12415
+ onFinished: this.#onFinished,
12416
+ unpipeEvent: this.#unpipeEvent
12416
12417
  });
12418
+ this.#streamPromises.set(stream, streamPromise);
12417
12419
  stream.pipe(this, { end: false });
12418
12420
  }
12419
- remove(stream) {
12421
+ async remove(stream) {
12420
12422
  validateStream(stream);
12421
12423
  if (!this.#streams.has(stream)) {
12422
12424
  return false;
12423
12425
  }
12426
+ const streamPromise = this.#streamPromises.get(stream);
12427
+ if (streamPromise === void 0) {
12428
+ return false;
12429
+ }
12430
+ this.#streamPromises.delete(stream);
12424
12431
  stream.unpipe(this);
12432
+ await streamPromise;
12425
12433
  return true;
12426
12434
  }
12427
12435
  };
12428
- var onMergedStreamFinished = async (passThroughStream, streams) => {
12436
+ var onMergedStreamFinished = async (passThroughStream, streams, unpipeEvent) => {
12429
12437
  updateMaxListeners(passThroughStream, PASSTHROUGH_LISTENERS_COUNT);
12430
12438
  const controller = new AbortController();
12431
12439
  try {
12432
12440
  await Promise.race([
12433
12441
  onMergedStreamEnd(passThroughStream, controller),
12434
- onInputStreamsUnpipe(passThroughStream, streams, controller)
12442
+ onInputStreamsUnpipe(passThroughStream, streams, unpipeEvent, controller)
12435
12443
  ]);
12436
12444
  } finally {
12437
12445
  controller.abort();
@@ -12439,9 +12447,14 @@ var onMergedStreamFinished = async (passThroughStream, streams) => {
12439
12447
  }
12440
12448
  };
12441
12449
  var onMergedStreamEnd = async (passThroughStream, { signal }) => {
12442
- await finished(passThroughStream, { signal, cleanup: true });
12450
+ try {
12451
+ await finished(passThroughStream, { signal, cleanup: true });
12452
+ } catch (error) {
12453
+ errorOrAbortStream(passThroughStream, error);
12454
+ throw error;
12455
+ }
12443
12456
  };
12444
- var onInputStreamsUnpipe = async (passThroughStream, streams, { signal }) => {
12457
+ var onInputStreamsUnpipe = async (passThroughStream, streams, unpipeEvent, { signal }) => {
12445
12458
  for await (const [unpipedStream] of on(passThroughStream, "unpipe", { signal })) {
12446
12459
  if (streams.has(unpipedStream)) {
12447
12460
  unpipedStream.emit(unpipeEvent);
@@ -12453,20 +12466,34 @@ var validateStream = (stream) => {
12453
12466
  throw new TypeError(`Expected a readable stream, got: \`${typeof stream}\`.`);
12454
12467
  }
12455
12468
  };
12456
- var endWhenStreamsDone = async ({ passThroughStream, stream, streams, ended, aborted, onFinished }) => {
12469
+ var endWhenStreamsDone = async ({ passThroughStream, stream, streams, ended, aborted, onFinished, unpipeEvent }) => {
12457
12470
  updateMaxListeners(passThroughStream, PASSTHROUGH_LISTENERS_PER_STREAM);
12458
12471
  const controller = new AbortController();
12459
12472
  try {
12460
12473
  await Promise.race([
12461
- afterMergedStreamFinished(onFinished, stream),
12462
- onInputStreamEnd({ passThroughStream, stream, streams, ended, aborted, controller }),
12463
- onInputStreamUnpipe({ stream, streams, ended, aborted, controller })
12474
+ afterMergedStreamFinished(onFinished, stream, controller),
12475
+ onInputStreamEnd({
12476
+ passThroughStream,
12477
+ stream,
12478
+ streams,
12479
+ ended,
12480
+ aborted,
12481
+ controller
12482
+ }),
12483
+ onInputStreamUnpipe({
12484
+ stream,
12485
+ streams,
12486
+ ended,
12487
+ aborted,
12488
+ unpipeEvent,
12489
+ controller
12490
+ })
12464
12491
  ]);
12465
12492
  } finally {
12466
12493
  controller.abort();
12467
12494
  updateMaxListeners(passThroughStream, -PASSTHROUGH_LISTENERS_PER_STREAM);
12468
12495
  }
12469
- if (streams.size === ended.size + aborted.size) {
12496
+ if (streams.size > 0 && streams.size === ended.size + aborted.size) {
12470
12497
  if (ended.size === 0 && aborted.size > 0) {
12471
12498
  abortStream(passThroughStream);
12472
12499
  } else {
@@ -12474,22 +12501,26 @@ var endWhenStreamsDone = async ({ passThroughStream, stream, streams, ended, abo
12474
12501
  }
12475
12502
  }
12476
12503
  };
12477
- var isAbortError = (error) => error?.code === "ERR_STREAM_PREMATURE_CLOSE";
12478
- var afterMergedStreamFinished = async (onFinished, stream) => {
12504
+ var afterMergedStreamFinished = async (onFinished, stream, { signal }) => {
12479
12505
  try {
12480
12506
  await onFinished;
12481
- abortStream(stream);
12482
- } catch (error) {
12483
- if (isAbortError(error)) {
12507
+ if (!signal.aborted) {
12484
12508
  abortStream(stream);
12485
- } else {
12486
- errorStream(stream, error);
12509
+ }
12510
+ } catch (error) {
12511
+ if (!signal.aborted) {
12512
+ errorOrAbortStream(stream, error);
12487
12513
  }
12488
12514
  }
12489
12515
  };
12490
12516
  var onInputStreamEnd = async ({ passThroughStream, stream, streams, ended, aborted, controller: { signal } }) => {
12491
12517
  try {
12492
- await finished(stream, { signal, cleanup: true, readable: true, writable: false });
12518
+ await finished(stream, {
12519
+ signal,
12520
+ cleanup: true,
12521
+ readable: true,
12522
+ writable: false
12523
+ });
12493
12524
  if (streams.has(stream)) {
12494
12525
  ended.add(stream);
12495
12526
  }
@@ -12504,18 +12535,28 @@ var onInputStreamEnd = async ({ passThroughStream, stream, streams, ended, abort
12504
12535
  }
12505
12536
  }
12506
12537
  };
12507
- var onInputStreamUnpipe = async ({ stream, streams, ended, aborted, controller: { signal } }) => {
12538
+ var onInputStreamUnpipe = async ({ stream, streams, ended, aborted, unpipeEvent, controller: { signal } }) => {
12508
12539
  await once(stream, unpipeEvent, { signal });
12540
+ if (!stream.readable) {
12541
+ return once(signal, "abort", { signal });
12542
+ }
12509
12543
  streams.delete(stream);
12510
12544
  ended.delete(stream);
12511
12545
  aborted.delete(stream);
12512
12546
  };
12513
- var unpipeEvent = Symbol("unpipe");
12514
12547
  var endStream = (stream) => {
12515
12548
  if (stream.writable) {
12516
12549
  stream.end();
12517
12550
  }
12518
12551
  };
12552
+ var errorOrAbortStream = (stream, error) => {
12553
+ if (isAbortError(error)) {
12554
+ abortStream(stream);
12555
+ } else {
12556
+ errorStream(stream, error);
12557
+ }
12558
+ };
12559
+ var isAbortError = (error) => error?.code === "ERR_STREAM_PREMATURE_CLOSE";
12519
12560
  var abortStream = (stream) => {
12520
12561
  if (stream.readable || stream.writable) {
12521
12562
  stream.destroy();
@@ -12538,7 +12579,7 @@ var updateMaxListeners = (passThroughStream, increment2) => {
12538
12579
  var PASSTHROUGH_LISTENERS_COUNT = 2;
12539
12580
  var PASSTHROUGH_LISTENERS_PER_STREAM = 1;
12540
12581
 
12541
- // ../../node_modules/.pnpm/globby@14.1.0/node_modules/globby/index.js
12582
+ // ../../node_modules/.pnpm/globby@15.0.0/node_modules/globby/index.js
12542
12583
  var import_fast_glob2 = __toESM(require_out4(), 1);
12543
12584
 
12544
12585
  // ../../node_modules/.pnpm/path-type@6.0.0/node_modules/path-type/index.js
@@ -12588,7 +12629,7 @@ function toPath2(urlOrPath) {
12588
12629
  }
12589
12630
  var TEN_MEGABYTES_IN_BYTES = 10 * 1024 * 1024;
12590
12631
 
12591
- // ../../node_modules/.pnpm/globby@14.1.0/node_modules/globby/ignore.js
12632
+ // ../../node_modules/.pnpm/globby@15.0.0/node_modules/globby/ignore.js
12592
12633
  var import_fast_glob = __toESM(require_out4(), 1);
12593
12634
  var import_ignore = __toESM(require_ignore(), 1);
12594
12635
  import process4 from "node:process";
@@ -12605,10 +12646,10 @@ function slash(path10) {
12605
12646
  return path10.replace(/\\/g, "/");
12606
12647
  }
12607
12648
 
12608
- // ../../node_modules/.pnpm/globby@14.1.0/node_modules/globby/utilities.js
12649
+ // ../../node_modules/.pnpm/globby@15.0.0/node_modules/globby/utilities.js
12609
12650
  var isNegativePattern = (pattern) => pattern[0] === "!";
12610
12651
 
12611
- // ../../node_modules/.pnpm/globby@14.1.0/node_modules/globby/ignore.js
12652
+ // ../../node_modules/.pnpm/globby@15.0.0/node_modules/globby/ignore.js
12612
12653
  var defaultIgnoredDirectories = [
12613
12654
  "**/node_modules",
12614
12655
  "**/flow-typed",
@@ -12620,7 +12661,24 @@ var ignoreFilesGlobOptions = {
12620
12661
  dot: true
12621
12662
  };
12622
12663
  var GITIGNORE_FILES_PATTERN = "**/.gitignore";
12623
- var applyBaseToPattern = (pattern, base) => isNegativePattern(pattern) ? "!" + path7.posix.join(base, pattern.slice(1)) : path7.posix.join(base, pattern);
12664
+ var applyBaseToPattern = (pattern, base) => {
12665
+ if (!base) {
12666
+ return pattern;
12667
+ }
12668
+ const isNegative = isNegativePattern(pattern);
12669
+ const cleanPattern = isNegative ? pattern.slice(1) : pattern;
12670
+ const slashIndex = cleanPattern.indexOf("/");
12671
+ const hasNonTrailingSlash = slashIndex !== -1 && slashIndex !== cleanPattern.length - 1;
12672
+ let result;
12673
+ if (!hasNonTrailingSlash) {
12674
+ result = path7.posix.join(base, "**", cleanPattern);
12675
+ } else if (cleanPattern.startsWith("/")) {
12676
+ result = path7.posix.join(base, cleanPattern.slice(1));
12677
+ } else {
12678
+ result = path7.posix.join(base, cleanPattern);
12679
+ }
12680
+ return isNegative ? "!" + result : result;
12681
+ };
12624
12682
  var parseIgnoreFile = (file, cwd) => {
12625
12683
  const base = slash(path7.relative(cwd, path7.dirname(file.filePath)));
12626
12684
  return file.content.split(/\r?\n/).filter((line) => line && !line.startsWith("#")).map((pattern) => applyBaseToPattern(pattern, base));
@@ -12633,6 +12691,12 @@ var toRelativePath = (fileOrDirectory, cwd) => {
12633
12691
  }
12634
12692
  throw new Error(`Path ${fileOrDirectory} is not in cwd ${cwd}`);
12635
12693
  }
12694
+ if (fileOrDirectory.startsWith("./")) {
12695
+ return fileOrDirectory.slice(2);
12696
+ }
12697
+ if (fileOrDirectory.startsWith("../")) {
12698
+ return void 0;
12699
+ }
12636
12700
  return fileOrDirectory;
12637
12701
  };
12638
12702
  var getIsIgnoredPredicate = (files, cwd) => {
@@ -12641,6 +12705,9 @@ var getIsIgnoredPredicate = (files, cwd) => {
12641
12705
  return (fileOrDirectory) => {
12642
12706
  fileOrDirectory = toPath2(fileOrDirectory);
12643
12707
  fileOrDirectory = toRelativePath(fileOrDirectory, cwd);
12708
+ if (fileOrDirectory === void 0) {
12709
+ return false;
12710
+ }
12644
12711
  return fileOrDirectory ? ignores.ignores(slash(fileOrDirectory)) : false;
12645
12712
  };
12646
12713
  };
@@ -12659,12 +12726,10 @@ var isIgnoredByIgnoreFiles = async (patterns, options) => {
12659
12726
  ignore,
12660
12727
  ...ignoreFilesGlobOptions
12661
12728
  });
12662
- const files = await Promise.all(
12663
- paths.map(async (filePath) => ({
12664
- filePath,
12665
- content: await fsPromises3.readFile(filePath, "utf8")
12666
- }))
12667
- );
12729
+ const files = await Promise.all(paths.map(async (filePath) => ({
12730
+ filePath,
12731
+ content: await fsPromises3.readFile(filePath, "utf8")
12732
+ })));
12668
12733
  return getIsIgnoredPredicate(files, cwd);
12669
12734
  };
12670
12735
  var isIgnoredByIgnoreFilesSync = (patterns, options) => {
@@ -12683,7 +12748,7 @@ var isIgnoredByIgnoreFilesSync = (patterns, options) => {
12683
12748
  return getIsIgnoredPredicate(files, cwd);
12684
12749
  };
12685
12750
 
12686
- // ../../node_modules/.pnpm/globby@14.1.0/node_modules/globby/index.js
12751
+ // ../../node_modules/.pnpm/globby@15.0.0/node_modules/globby/index.js
12687
12752
  var assertPatternsInput = (patterns) => {
12688
12753
  if (patterns.some((pattern) => typeof pattern !== "string")) {
12689
12754
  throw new TypeError("Patterns must be a string or an array of strings");
@@ -12693,6 +12758,16 @@ var normalizePathForDirectoryGlob = (filePath, cwd) => {
12693
12758
  const path10 = isNegativePattern(filePath) ? filePath.slice(1) : filePath;
12694
12759
  return nodePath.isAbsolute(path10) ? path10 : nodePath.join(cwd, path10);
12695
12760
  };
12761
+ var shouldExpandGlobstarDirectory = (pattern) => {
12762
+ const match = pattern?.match(/\*\*\/([^/]+)$/);
12763
+ if (!match) {
12764
+ return false;
12765
+ }
12766
+ const dirname3 = match[1];
12767
+ const hasWildcards = /[*?[\]{}]/.test(dirname3);
12768
+ const hasExtension = nodePath.extname(dirname3) && !dirname3.startsWith(".");
12769
+ return !hasWildcards && !hasExtension;
12770
+ };
12696
12771
  var getDirectoryGlob = ({ directoryPath, files, extensions }) => {
12697
12772
  const extensionGlob = extensions?.length > 0 ? `.${extensions.length > 1 ? `{${extensions.join(",")}}` : extensions[0]}` : "";
12698
12773
  return files ? files.map((file) => nodePath.posix.join(directoryPath, `**/${nodePath.extname(file) ? file : `${file}${extensionGlob}`}`)) : [nodePath.posix.join(directoryPath, `**${extensionGlob ? `/*${extensionGlob}` : ""}`)];
@@ -12702,16 +12777,28 @@ var directoryToGlob = async (directoryPaths, {
12702
12777
  files,
12703
12778
  extensions
12704
12779
  } = {}) => {
12705
- const globs = await Promise.all(
12706
- directoryPaths.map(async (directoryPath) => await isDirectory(normalizePathForDirectoryGlob(directoryPath, cwd)) ? getDirectoryGlob({ directoryPath, files, extensions }) : directoryPath)
12707
- );
12780
+ const globs = await Promise.all(directoryPaths.map(async (directoryPath) => {
12781
+ const checkPattern = isNegativePattern(directoryPath) ? directoryPath.slice(1) : directoryPath;
12782
+ if (shouldExpandGlobstarDirectory(checkPattern)) {
12783
+ return getDirectoryGlob({ directoryPath, files, extensions });
12784
+ }
12785
+ const pathToCheck = normalizePathForDirectoryGlob(directoryPath, cwd);
12786
+ return await isDirectory(pathToCheck) ? getDirectoryGlob({ directoryPath, files, extensions }) : directoryPath;
12787
+ }));
12708
12788
  return globs.flat();
12709
12789
  };
12710
12790
  var directoryToGlobSync = (directoryPaths, {
12711
12791
  cwd = process5.cwd(),
12712
12792
  files,
12713
12793
  extensions
12714
- } = {}) => directoryPaths.flatMap((directoryPath) => isDirectorySync(normalizePathForDirectoryGlob(directoryPath, cwd)) ? getDirectoryGlob({ directoryPath, files, extensions }) : directoryPath);
12794
+ } = {}) => directoryPaths.flatMap((directoryPath) => {
12795
+ const checkPattern = isNegativePattern(directoryPath) ? directoryPath.slice(1) : directoryPath;
12796
+ if (shouldExpandGlobstarDirectory(checkPattern)) {
12797
+ return getDirectoryGlob({ directoryPath, files, extensions });
12798
+ }
12799
+ const pathToCheck = normalizePathForDirectoryGlob(directoryPath, cwd);
12800
+ return isDirectorySync(pathToCheck) ? getDirectoryGlob({ directoryPath, files, extensions }) : directoryPath;
12801
+ });
12715
12802
  var toPatternsArray = (patterns) => {
12716
12803
  patterns = [...new Set([patterns].flat())];
12717
12804
  assertPatternsInput(patterns);
@@ -12753,15 +12840,11 @@ var getIgnoreFilesPatterns = (options) => {
12753
12840
  };
12754
12841
  var getFilter = async (options) => {
12755
12842
  const ignoreFilesPatterns = getIgnoreFilesPatterns(options);
12756
- return createFilterFunction(
12757
- ignoreFilesPatterns.length > 0 && await isIgnoredByIgnoreFiles(ignoreFilesPatterns, options)
12758
- );
12843
+ return createFilterFunction(ignoreFilesPatterns.length > 0 && await isIgnoredByIgnoreFiles(ignoreFilesPatterns, options));
12759
12844
  };
12760
12845
  var getFilterSync = (options) => {
12761
12846
  const ignoreFilesPatterns = getIgnoreFilesPatterns(options);
12762
- return createFilterFunction(
12763
- ignoreFilesPatterns.length > 0 && isIgnoredByIgnoreFilesSync(ignoreFilesPatterns, options)
12764
- );
12847
+ return createFilterFunction(ignoreFilesPatterns.length > 0 && isIgnoredByIgnoreFilesSync(ignoreFilesPatterns, options));
12765
12848
  };
12766
12849
  var createFilterFunction = (isIgnored) => {
12767
12850
  const seen = /* @__PURE__ */ new Set();
@@ -12814,19 +12897,17 @@ var generateTasks = async (patterns, options) => {
12814
12897
  return globTasks;
12815
12898
  }
12816
12899
  const directoryToGlobOptions = normalizeExpandDirectoriesOption(expandDirectories, cwd);
12817
- return Promise.all(
12818
- globTasks.map(async (task) => {
12819
- let { patterns: patterns2, options: options2 } = task;
12820
- [
12821
- patterns2,
12822
- options2.ignore
12823
- ] = await Promise.all([
12824
- directoryToGlob(patterns2, directoryToGlobOptions),
12825
- directoryToGlob(options2.ignore, { cwd })
12826
- ]);
12827
- return { patterns: patterns2, options: options2 };
12828
- })
12829
- );
12900
+ return Promise.all(globTasks.map(async (task) => {
12901
+ let { patterns: patterns2, options: options2 } = task;
12902
+ [
12903
+ patterns2,
12904
+ options2.ignore
12905
+ ] = await Promise.all([
12906
+ directoryToGlob(patterns2, directoryToGlobOptions),
12907
+ directoryToGlob(options2.ignore, { cwd })
12908
+ ]);
12909
+ return { patterns: patterns2, options: options2 };
12910
+ }));
12830
12911
  };
12831
12912
  var generateTasksSync = (patterns, options) => {
12832
12913
  const globTasks = convertNegativePatterns(patterns, options);
@@ -12863,12 +12944,13 @@ var globbyStream = normalizeArgumentsSync((patterns, options) => {
12863
12944
  const tasks = generateTasksSync(patterns, options);
12864
12945
  const filter = getFilterSync(options);
12865
12946
  const streams = tasks.map((task) => import_fast_glob2.default.stream(task.patterns, task.options));
12947
+ if (streams.length === 0) {
12948
+ return Readable.from([]);
12949
+ }
12866
12950
  const stream = mergeStreams(streams).filter((fastGlobResult) => filter(fastGlobResult));
12867
12951
  return stream;
12868
12952
  });
12869
- var isDynamicPattern = normalizeArgumentsSync(
12870
- (patterns, options) => patterns.some((pattern) => import_fast_glob2.default.isDynamicPattern(pattern, options))
12871
- );
12953
+ var isDynamicPattern = normalizeArgumentsSync((patterns, options) => patterns.some((pattern) => import_fast_glob2.default.isDynamicPattern(pattern, options)));
12872
12954
  var generateGlobTasks = normalizeArguments(generateTasks);
12873
12955
  var generateGlobTasksSync = normalizeArgumentsSync(generateTasksSync);
12874
12956
  var { convertPathToPattern } = import_fast_glob2.default;
@@ -12977,7 +13059,7 @@ var commandDefinition7 = {
12977
13059
  description: "Kitschpatrol's repository-related shared configuration tools.",
12978
13060
  logColor: "gray",
12979
13061
  logPrefix: "[Repo Config]",
12980
- name: "kpi-repo",
13062
+ name: "ksc-repo",
12981
13063
  order: 1
12982
13064
  };
12983
13065
 
@@ -13080,7 +13162,7 @@ var commandDefinition8 = {
13080
13162
  description: "Kitschpatrol's Stylelint shared configuration tools.",
13081
13163
  logColor: "greenBright",
13082
13164
  logPrefix: "[Stylelint]",
13083
- name: "kpi-stylelint",
13165
+ name: "ksc-stylelint",
13084
13166
  order: 5
13085
13167
  };
13086
13168
 
@@ -13145,7 +13227,7 @@ var commandDefinition9 = {
13145
13227
  description: "Kitschpatrol's TypeScript shared configuration tools.",
13146
13228
  logColor: "blueBright",
13147
13229
  logPrefix: "[TypeScript Config]",
13148
- name: "kpi-typescript",
13230
+ name: "ksc-typescript",
13149
13231
  order: 3
13150
13232
  };
13151
13233
 
@@ -13209,7 +13291,7 @@ var commandDefinition10 = {
13209
13291
  description: "Run aggregated @kitschpatrol/shared-config commands.",
13210
13292
  logColor: "yellow",
13211
13293
  logPrefix: "\u{1F52C}",
13212
- name: "kpi",
13294
+ name: "ksc",
13213
13295
  order: 0,
13214
13296
  showSummary: true,
13215
13297
  verbose: true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitschpatrol/shared-config",
3
- "version": "5.6.0",
3
+ "version": "5.7.1",
4
4
  "description": "A collection of shared configurations, linters, and formatting tools for TypeScript projects. All managed as a single dependency, and invoked via a single CLI command.",
5
5
  "keywords": [
6
6
  "shared-config",
@@ -13,7 +13,7 @@
13
13
  "cspell",
14
14
  "mdat",
15
15
  "cli",
16
- "kpi"
16
+ "ksc"
17
17
  ],
18
18
  "homepage": "https://github.com/kitschpatrol/shared-config",
19
19
  "bugs": "https://github.com/kitschpatrol/shared-config/issues",
@@ -30,7 +30,8 @@
30
30
  },
31
31
  "type": "module",
32
32
  "bin": {
33
- "kpi": "bin/cli.js"
33
+ "kpi": "bin/cli.js",
34
+ "ksc": "bin/cli.js"
34
35
  },
35
36
  "files": [
36
37
  "bin/*"
@@ -41,20 +42,20 @@
41
42
  "cosmiconfig-typescript-loader": "^6.1.0",
42
43
  "execa": "^9.6.0",
43
44
  "find-workspaces": "^0.3.1",
44
- "fs-extra": "^11.3.1",
45
+ "fs-extra": "^11.3.2",
45
46
  "prettier": "^3.6.2",
46
- "@kitschpatrol/mdat-config": "5.6.0",
47
- "@kitschpatrol/cspell-config": "5.6.0",
48
- "@kitschpatrol/eslint-config": "5.6.0",
49
- "@kitschpatrol/prettier-config": "5.6.0",
50
- "@kitschpatrol/knip-config": "5.6.0",
51
- "@kitschpatrol/repo-config": "5.6.0",
52
- "@kitschpatrol/remark-config": "5.6.0",
53
- "@kitschpatrol/stylelint-config": "5.6.0",
54
- "@kitschpatrol/typescript-config": "5.6.0"
47
+ "@kitschpatrol/cspell-config": "5.7.1",
48
+ "@kitschpatrol/knip-config": "5.7.1",
49
+ "@kitschpatrol/eslint-config": "5.7.1",
50
+ "@kitschpatrol/remark-config": "5.7.1",
51
+ "@kitschpatrol/mdat-config": "5.7.1",
52
+ "@kitschpatrol/repo-config": "5.7.1",
53
+ "@kitschpatrol/prettier-config": "5.7.1",
54
+ "@kitschpatrol/stylelint-config": "5.7.1",
55
+ "@kitschpatrol/typescript-config": "5.7.1"
55
56
  },
56
57
  "devDependencies": {
57
- "globby": "^14.1.0",
58
+ "globby": "^15.0.0",
58
59
  "picocolors": "^1.1.1"
59
60
  },
60
61
  "engines": {
package/readme.md CHANGED
@@ -35,15 +35,15 @@
35
35
 
36
36
  ## Overview
37
37
 
38
- This project attempts to consolidate most of the configuration and tooling shared by my open-source and internal TypeScript / Node based projects into a single dependency with a single CLI meta-command to lint and fix issues.
38
+ This project consolidates most of the configuration and tooling shared by my open-source and internal TypeScript-based projects into a single dependency with a single CLI meta-command to lint and fix issues.
39
39
 
40
- By installing `@kitschpatrol/shared-config` and then running `kpi`, you can run a half-dozen pre-configured code quality and linting tools in one shot. This spares you from cluttering your project's `devDependencies` with packages tangential to the task at hand.
40
+ By installing `@kitschpatrol/shared-config` and then running `ksc`, you can run a half-dozen pre-configured code quality and linting tools in one shot. This spares you from cluttering your project's `devDependencies` with packages tangential to the task at hand.
41
41
 
42
- If you don't plan to customize tool configurations, `@kitschpatrol/shared-config init` exposes an option to store references to each tool's shared configuration in your `package.json` instead of in files in your project root (at least where permitted by the tool). This can save a bit of file clutter in your project's root directory, at the expense of the immediate discoverability of the tools.
42
+ If you don't plan to customize tool configurations, `ksc init` exposes an option to store references to each tool's shared configuration in your `package.json` instead of in files in your project root (at least where permitted by the tool). This can save a bit of file clutter in your project's root directory, at the expense of the immediate discoverability of the tools.
43
43
 
44
44
  In addition, each tool exports a typed configuration factory function to simplify specifying and extending the default configuration.
45
45
 
46
- The command name `kpi` might stand for "Kitschpatrol Project Inspector", or the more McKinseyan "Key Performance Indicators".
46
+ The command name `ksc` is just an initialism for "Kitschpatrol Shared Configuration".
47
47
 
48
48
  ### Tools
49
49
 
@@ -67,51 +67,51 @@ This particular readme is for the [`@kitschpatrol/shared-config`](https://www.np
67
67
 
68
68
  #### Primary package
69
69
 
70
- - [`@kitschpatrol/shared-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/shared-config/readme.md) (`kpi` command)
70
+ - [`@kitschpatrol/shared-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/shared-config/readme.md) (`ksc` command)
71
71
 
72
72
  #### Sub-packages
73
73
 
74
- - [`@kitschpatrol/cspell-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/cspell-config/readme.md) (`kpi-cspell` command)
75
- - [`@kitschpatrol/eslint-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/eslint-config/readme.md) (`kpi-eslint` command)
76
- - [`@kitschpatrol/knip-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/knip-config/readme.md) (`kpi-knip` command)
77
- - [`@kitschpatrol/mdat-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/mdat-config/readme.md) (`kpi-mdat` command)
78
- - [`@kitschpatrol/prettier-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/prettier-config/readme.md) (`kpi-prettier` command)
79
- - [`@kitschpatrol/remark-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/remark-config/readme.md) (`kpi-remark` command)
80
- - [`@kitschpatrol/repo-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/repo-config/readme.md) (`kpi-repo` command)
81
- - [`@kitschpatrol/stylelint-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/stylelint-config/readme.md) (`kpi-stylelint` command)
82
- - [`@kitschpatrol/typescript-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/typescript-config/readme.md) (`kpi-typescript` command)
74
+ - [`@kitschpatrol/cspell-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/cspell-config/readme.md) (`ksc-cspell` command)
75
+ - [`@kitschpatrol/eslint-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/eslint-config/readme.md) (`ksc-eslint` command)
76
+ - [`@kitschpatrol/knip-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/knip-config/readme.md) (`ksc-knip` command)
77
+ - [`@kitschpatrol/mdat-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/mdat-config/readme.md) (`ksc-mdat` command)
78
+ - [`@kitschpatrol/prettier-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/prettier-config/readme.md) (`ksc-prettier` command)
79
+ - [`@kitschpatrol/remark-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/remark-config/readme.md) (`ksc-remark` command)
80
+ - [`@kitschpatrol/repo-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/repo-config/readme.md) (`ksc-repo` command)
81
+ - [`@kitschpatrol/stylelint-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/stylelint-config/readme.md) (`ksc-stylelint` command)
82
+ - [`@kitschpatrol/typescript-config`](https://github.com/kitschpatrol/shared-config/blob/main/packages/typescript-config/readme.md) (`ksc-typescript` command)
83
83
 
84
84
  > [!IMPORTANT]
85
85
  >
86
86
  > Any of these packages may be installed and run on their own via CLI if desired. However, in general, the idea is to use `@kitschpatrol/shared-config` to easily run them all simultaneously over a repo with a single command with options to either check or (where possible) fix problems, with output aggregated into a single report.
87
87
 
88
- Running `kpi <command>` calls the same command across the entire collection of sub-packages.
88
+ Running `ksc <command>` calls the same command across the entire collection of sub-packages.
89
89
 
90
90
  So assuming you've installed `@kitschpatrol/shared-config`...
91
91
 
92
92
  Running:
93
93
 
94
94
  ```sh
95
- kpi init
95
+ ksc init
96
96
  ```
97
97
 
98
98
  Is the same as running:
99
99
 
100
100
  ```sh
101
- kpi-repo init
102
- kpi-mdat init
103
- kpi-typescript init
104
- kpi-eslint init
105
- kpi-stylelint init
106
- kpi-cspell init
107
- kpi-knip init
108
- kpi-remark init
109
- kpi-prettier init
101
+ ksc-repo init
102
+ ksc-mdat init
103
+ ksc-typescript init
104
+ ksc-eslint init
105
+ ksc-stylelint init
106
+ ksc-cspell init
107
+ ksc-knip init
108
+ ksc-remark init
109
+ ksc-prettier init
110
110
  ```
111
111
 
112
112
  _(Sub-commands are always executed in the above order.)_
113
113
 
114
- The top-level `kpi` command also takes care of some nuances in terms of _which_ sub-packages implement _which_ commands, and which subcommands take arguments.
114
+ The top-level `ksc` command also takes care of some nuances in terms of _which_ sub-packages implement _which_ commands, and which subcommands take arguments.
115
115
 
116
116
  ## Getting started
117
117
 
@@ -126,19 +126,19 @@ The top-level `kpi` command also takes care of some nuances in terms of _which_
126
126
  Bootstrap a new project and open in VS Code:
127
127
 
128
128
  ```sh
129
- git init && pnpm init && pnpm pkg set type="module" && pnpm dlx @kitschpatrol/repo-config init && pnpm add -D @kitschpatrol/shared-config && pnpm kpi init && pnpm i && code .
129
+ git init && pnpm init && pnpm pkg set type="module" && pnpm dlx @kitschpatrol/repo-config init && pnpm add -D @kitschpatrol/shared-config && pnpm ksc init && pnpm i && code .
130
130
  ```
131
131
 
132
- Note that `kpi init` takes an optional `--location package` flag will put as much configuration in your `package.json` as possible instead of creating discrete config files in your project root for each tool. Putting config in `package.json` can save some clutter, but can make it clunkier to extend or customize configurations.
132
+ Note that `ksc init` takes an optional `--location package` flag will put as much configuration in your `package.json` as possible instead of creating discrete config files in your project root for each tool. Putting config in `package.json` can save some clutter, but can make it clunkier to extend or customize configurations.
133
133
 
134
- At any point, you can call `kpi init` again with the `--location package` or `--location file` flag to reinitialize your configuration files in one place or the other and restore the default configurations.
134
+ At any point, you can call `ksc init` again with the `--location package` or `--location file` flag to reinitialize your configuration files in one place or the other and restore the default configurations.
135
135
 
136
136
  #### Quick add to an existing project:
137
137
 
138
138
  This might overwrite certain config files, so commit first:
139
139
 
140
140
  ```sh
141
- pnpm dlx @kitschpatrol/repo-config init && pnpm i && pnpm add -D @kitschpatrol/shared-config && pnpm kpi init
141
+ pnpm dlx @kitschpatrol/repo-config init && pnpm i && pnpm add -D @kitschpatrol/shared-config && pnpm ksc init
142
142
  ```
143
143
 
144
144
  #### Step-by-step:
@@ -158,13 +158,13 @@ pnpm dlx @kitschpatrol/repo-config init && pnpm i && pnpm add -D @kitschpatrol/s
158
158
  3. Add default config files for all the tools to your project root:
159
159
 
160
160
  ```sh
161
- pnpm kpi init
161
+ pnpm ksc init
162
162
  ```
163
163
 
164
164
  Or, if you don't plan to customize tool configurations, you might want to put as much config as possible under tool-specific keys in 'package.json':
165
165
 
166
166
  ```sh
167
- pnpm kpi init --location package
167
+ pnpm ksc init --location package
168
168
  ```
169
169
 
170
170
  4. Add helper scripts to your `package.json`:
@@ -174,8 +174,8 @@ pnpm dlx @kitschpatrol/repo-config init && pnpm i && pnpm add -D @kitschpatrol/s
174
174
  ```json
175
175
  {
176
176
  "scripts": {
177
- "fix": "kpi fix",
178
- "lint": "kpi lint"
177
+ "fix": "ksc fix",
178
+ "lint": "ksc lint"
179
179
  }
180
180
  }
181
181
  ```
@@ -208,18 +208,18 @@ pnpm run fix
208
208
 
209
209
  ### CLI
210
210
 
211
- <!-- cli-help cliCommand: 'kpi' -->
211
+ <!-- cli-help cliCommand: 'ksc' -->
212
212
 
213
- #### Command: `kpi`
213
+ #### Command: `ksc`
214
214
 
215
215
  Run aggregated @kitschpatrol/shared-config commands.
216
216
 
217
- This section lists top-level commands for `kpi`.
217
+ This section lists top-level commands for `ksc`.
218
218
 
219
219
  Usage:
220
220
 
221
221
  ```txt
222
- kpi <command>
222
+ ksc <command>
223
223
  ```
224
224
 
225
225
  | Command | Argument | Description |
@@ -236,14 +236,14 @@ kpi <command>
236
236
 
237
237
  _See the sections below for more information on each subcommand._
238
238
 
239
- #### Subcommand: `kpi init`
239
+ #### Subcommand: `ksc init`
240
240
 
241
241
  Initialize configuration files for the entire suite of @kitschpatrol/shared-config tools. Will use option flags where possible if provided, but some of the invoked tools will ignore them.
242
242
 
243
243
  Usage:
244
244
 
245
245
  ```txt
246
- kpi init
246
+ ksc init
247
247
  ```
248
248
 
249
249
  | Option | Description | Type | Default |
@@ -252,14 +252,14 @@ kpi init
252
252
  | `--help`<br>`-h` | Show help | `boolean` | |
253
253
  | `--version`<br>`-v` | Show version number | `boolean` | |
254
254
 
255
- #### Subcommand: `kpi lint`
255
+ #### Subcommand: `ksc lint`
256
256
 
257
257
  Lint your project with multiple tools in one go. Will use file arguments / globs where possible if provided, but some of the invoked tools only operate at the package-scope.
258
258
 
259
259
  Usage:
260
260
 
261
261
  ```txt
262
- kpi lint [files..]
262
+ ksc lint [files..]
263
263
  ```
264
264
 
265
265
  | Positional Argument | Description | Type | Default |
@@ -271,14 +271,14 @@ kpi lint [files..]
271
271
  | `--help`<br>`-h` | Show help | `boolean` |
272
272
  | `--version`<br>`-v` | Show version number | `boolean` |
273
273
 
274
- #### Subcommand: `kpi fix`
274
+ #### Subcommand: `ksc fix`
275
275
 
276
276
  Fix your project with multiple tools in one go. Will use file arguments / globs where possible if provided, but some of the invoked tools only operate at the package-scope.
277
277
 
278
278
  Usage:
279
279
 
280
280
  ```txt
281
- kpi fix [files..]
281
+ ksc fix [files..]
282
282
  ```
283
283
 
284
284
  | Positional Argument | Description | Type | Default |
@@ -290,14 +290,14 @@ kpi fix [files..]
290
290
  | `--help`<br>`-h` | Show help | `boolean` |
291
291
  | `--version`<br>`-v` | Show version number | `boolean` |
292
292
 
293
- #### Subcommand: `kpi print-config`
293
+ #### Subcommand: `ksc print-config`
294
294
 
295
295
  Print aggregated tool configuration data. Will use file arguments / globs where possible if provided, but some of the invoked tools only operate at the package-scope.
296
296
 
297
297
  Usage:
298
298
 
299
299
  ```txt
300
- kpi print-config [file]
300
+ ksc print-config [file]
301
301
  ```
302
302
 
303
303
  | Positional Argument | Description | Type |
@@ -311,7 +311,7 @@ kpi print-config [file]
311
311
 
312
312
  <!-- /cli-help -->
313
313
 
314
- Recall that the `@kitschpatrol/shared-config` package aggregates integration and invocation of the other tool-specific packages in this monorepo. Running a cli command on `kpi` effectively runs the same command against all the tool-specific packages.
314
+ Recall that the `@kitschpatrol/shared-config` package aggregates integration and invocation of the other tool-specific packages in this monorepo. Running a cli command on `ksc` effectively runs the same command against all the tool-specific packages.
315
315
 
316
316
  ## Implementation notes
317
317