@crustjs/extensions 0.3.0 → 0.3.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.
package/dist/index.d.ts CHANGED
@@ -109,10 +109,11 @@ declare const colorFlags: readonly [{
109
109
  * and hyperlinks keep following TTY detection, per
110
110
  * [no-color.org](https://no-color.org/).
111
111
  *
112
- * Previous values are restored after the command finishes. When overlapping
113
- * programmatic runs in one process use opposite flags, the later run wins
114
- * mid-flight (the env is process-global); the ambient values are restored
115
- * once all runs finish.
112
+ * Previous values are restored after the command finishes. Overlapping
113
+ * programmatic runs in one process may share a direction (both `--color` or
114
+ * both `--no-color`); the ambient values are restored once all runs finish.
115
+ * An overlapping run with the opposing flag throws a `CrustError` in
116
+ * `preRun`, because the env is process-global and cannot hold both values.
116
117
  */
117
118
  export declare const noColor: ExtensionFactory<[], {}, [], typeof colorFlags>;
118
119
  //#endregion
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import { CrustError, defineCommand, defineExtension, defineExtensionId } from "@
4
4
  import { buildCommandDocumentation, formatDescription, isListed, sectionsFor } from "@crustjs/core/tooling";
5
5
  import { stripVTControlCharacters } from "node:util";
6
6
  import { bold, cyan, dim, green, padEnd, stringWidth, yellow } from "@crustjs/style";
7
+ import { packageManagerFromUserAgent } from "@crustjs/utils/process";
7
8
  //#region src/completion/escape.ts
8
9
  /**
9
10
  * Per-shell quoting and validation helpers used by the completion
@@ -1467,6 +1468,7 @@ const didYouMean = defineExtension(DID_YOU_MEAN, (options = {}) => {
1467
1468
  //#region src/no-color.ts
1468
1469
  const NO_COLOR = defineExtensionId("crust:no-color");
1469
1470
  let activeRuns = 0;
1471
+ let activeFlag;
1470
1472
  let baseForceColor;
1471
1473
  let baseNoColor;
1472
1474
  const colorRuns = /* @__PURE__ */ new WeakSet();
@@ -1489,10 +1491,11 @@ const colorFlags = [{
1489
1491
  * and hyperlinks keep following TTY detection, per
1490
1492
  * [no-color.org](https://no-color.org/).
1491
1493
  *
1492
- * Previous values are restored after the command finishes. When overlapping
1493
- * programmatic runs in one process use opposite flags, the later run wins
1494
- * mid-flight (the env is process-global); the ambient values are restored
1495
- * once all runs finish.
1494
+ * Previous values are restored after the command finishes. Overlapping
1495
+ * programmatic runs in one process may share a direction (both `--color` or
1496
+ * both `--no-color`); the ambient values are restored once all runs finish.
1497
+ * An overlapping run with the opposing flag throws a `CrustError` in
1498
+ * `preRun`, because the env is process-global and cannot hold both values.
1496
1499
  */
1497
1500
  const noColor = defineExtension(NO_COLOR, () => ({
1498
1501
  flags: colorFlags,
@@ -1500,6 +1503,12 @@ const noColor = defineExtension(NO_COLOR, () => ({
1500
1503
  preRun(context) {
1501
1504
  const flagValue = context.flags.color;
1502
1505
  if (flagValue !== true && flagValue !== false) return;
1506
+ if (activeRuns > 0 && activeFlag !== flagValue) throw new CrustError("DEFINITION", "noColor: cannot start a --color run while a --no-color run is in flight (or vice versa); opposing overlapping runs share process.env", {
1507
+ subject: "extension",
1508
+ name: NO_COLOR,
1509
+ reason: "opposing-overlap"
1510
+ });
1511
+ activeFlag = flagValue;
1503
1512
  if (activeRuns === 0) {
1504
1513
  baseForceColor = process.env.FORCE_COLOR;
1505
1514
  baseNoColor = process.env.NO_COLOR;
@@ -1519,6 +1528,7 @@ const noColor = defineExtension(NO_COLOR, () => ({
1519
1528
  colorRuns.delete(context);
1520
1529
  activeRuns--;
1521
1530
  if (activeRuns === 0) {
1531
+ activeFlag = void 0;
1522
1532
  if (baseForceColor === void 0) delete process.env.FORCE_COLOR;
1523
1533
  else process.env.FORCE_COLOR = baseForceColor;
1524
1534
  if (baseNoColor === void 0) delete process.env.NO_COLOR;
@@ -1528,16 +1538,6 @@ const noColor = defineExtension(NO_COLOR, () => ({
1528
1538
  }
1529
1539
  }));
1530
1540
  //#endregion
1531
- //#region ../utils/src/process.ts
1532
- /** Parse the package manager from npm's user-agent environment value. */
1533
- function packageManagerFromUserAgent(userAgent) {
1534
- if (userAgent?.startsWith("bun")) return "bun";
1535
- if (userAgent?.startsWith("pnpm")) return "pnpm";
1536
- if (userAgent?.startsWith("yarn")) return "yarn";
1537
- if (userAgent?.startsWith("npm")) return "npm";
1538
- return null;
1539
- }
1540
- //#endregion
1541
1541
  //#region src/update-notifier.ts
1542
1542
  const UPDATE_NOTIFIER = defineExtensionId("crust:update-notifier");
1543
1543
  /** Default check interval: 24 hours. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crustjs/extensions",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Official Extensions for the Crust CLI framework",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -46,17 +46,17 @@
46
46
  "postpack": "rm -f LICENSE"
47
47
  },
48
48
  "dependencies": {
49
- "@crustjs/store": "^0.4.0",
50
- "@crustjs/style": "^0.3.2"
49
+ "@crustjs/store": "^0.4.1",
50
+ "@crustjs/style": "^0.3.3",
51
+ "@crustjs/utils": "^0.1.0"
51
52
  },
52
53
  "devDependencies": {
53
54
  "@crustjs/config": "0.0.0",
54
- "@crustjs/core": "0.3.0",
55
- "@crustjs/utils": "0.0.0",
55
+ "@crustjs/core": "0.3.2",
56
56
  "tsdown": "^0.23.0"
57
57
  },
58
58
  "peerDependencies": {
59
- "@crustjs/core": "^0.3.0",
59
+ "@crustjs/core": "^0.3.2",
60
60
  "typescript": "^7.0.0"
61
61
  },
62
62
  "peerDependenciesMeta": {