@williamthorsen/nmr 0.55.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.meta/changelog.json +124 -0
- package/.readyup/kits/default.js +667 -167
- package/.readyup/manifest.json +77 -46
- package/CHANGELOG.md +40 -0
- package/README.md +1 -14
- package/agents/guidance/rulebooks/nmr.md +1 -1
- package/bin/ensure-prepublish-hooks.js +1 -1
- package/bin/nmr-actionlint.js +1 -1
- package/bin/nmr-clean.js +1 -1
- package/bin/nmr-compile.js +1 -1
- package/bin/nmr-fmt.js +1 -1
- package/bin/nmr-report-catalog.js +1 -1
- package/bin/nmr-report-overrides.js +1 -1
- package/bin/nmr-shellcheck.js +1 -1
- package/bin/nmr-taze.js +1 -1
- package/bin/nmr-vitest.js +1 -1
- package/bin/nmr.js +1 -1
- package/dist/esm/bins.d.ts +11 -0
- package/dist/esm/bins.js +11 -0
- package/dist/esm/check-cache-entries.js +5 -5
- package/dist/esm/check-cache-gate.js +2 -1
- package/dist/esm/child-env.js +2 -1
- package/dist/esm/child-process.d.ts +2 -0
- package/dist/esm/child-process.js +3 -3
- package/dist/esm/cli-actionlint.js +2 -1
- package/dist/esm/cli-build.js +2 -1
- package/dist/esm/cli-clean.js +2 -1
- package/dist/esm/cli-ensure-prepublish-hooks.js +29 -16
- package/dist/esm/cli-fmt.js +2 -1
- package/dist/esm/cli-report-catalog.js +2 -1
- package/dist/esm/cli-report-overrides.js +2 -1
- package/dist/esm/cli-shellcheck.js +2 -1
- package/dist/esm/cli-taze.js +2 -1
- package/dist/esm/cli-vitest.js +2 -1
- package/dist/esm/cli.js +2 -1
- package/dist/esm/commands/actionlint.d.ts +3 -3
- package/dist/esm/commands/actionlint.js +5 -5
- package/dist/esm/commands/build.js +6 -6
- package/dist/esm/commands/clean.js +3 -1
- package/dist/esm/commands/compiler.js +3 -3
- package/dist/esm/commands/ensure-prepublish-hooks.d.ts +1 -1
- package/dist/esm/commands/ensure-prepublish-hooks.js +4 -5
- package/dist/esm/commands/fmt.d.ts +3 -3
- package/dist/esm/commands/fmt.js +33 -52
- package/dist/esm/commands/format-targets.js +1 -13
- package/dist/esm/commands/node-pin.js +3 -4
- package/dist/esm/commands/rewrite-specifiers.js +2 -2
- package/dist/esm/commands/run-vitest.js +5 -5
- package/dist/esm/commands/shellcheck.d.ts +3 -3
- package/dist/esm/commands/shellcheck.js +8 -11
- package/dist/esm/commands/taze.js +5 -4
- package/dist/esm/commands/tsconfig-chain.js +3 -3
- package/dist/esm/commands/workflow-tools.d.ts +12 -3
- package/dist/esm/commands/workflow-tools.js +29 -14
- package/dist/esm/config-validation.js +9 -9
- package/dist/esm/config.js +2 -3
- package/dist/esm/delegate-host.d.ts +1 -1
- package/dist/esm/delegate-host.js +5 -3
- package/dist/esm/entry-chain.js +2 -3
- package/dist/esm/fan-out.d.ts +3 -3
- package/dist/esm/fan-out.js +14 -6
- package/dist/esm/git-ignored-paths.js +3 -3
- package/dist/esm/help.d.ts +14 -15
- package/dist/esm/help.js +29 -54
- package/dist/esm/helpers/filter-selection.js +2 -2
- package/dist/esm/helpers/package-json.js +8 -9
- package/dist/esm/helpers/resolveXdgBaseDir.d.ts +5 -0
- package/dist/esm/helpers/resolveXdgBaseDir.js +12 -0
- package/dist/esm/helpers/type-guards.d.ts +0 -2
- package/dist/esm/helpers/type-guards.js +2 -4
- package/dist/esm/invocation-args.d.ts +0 -32
- package/dist/esm/invocation-args.js +23 -121
- package/dist/esm/invocation.d.ts +3 -1
- package/dist/esm/invocation.js +1 -0
- package/dist/esm/machine-lock.js +3 -4
- package/dist/esm/nmr-flags.d.ts +109 -0
- package/dist/esm/nmr-flags.js +120 -0
- package/dist/esm/output-style.d.ts +1 -1
- package/dist/esm/output-style.js +2 -1
- package/dist/esm/pass-manifest.js +2 -2
- package/dist/esm/presentation.d.ts +1 -1
- package/dist/esm/remote-host-session.d.ts +2 -0
- package/dist/esm/remote-host-session.js +1 -0
- package/dist/esm/remote-probe.js +2 -2
- package/dist/esm/remote-run.d.ts +3 -3
- package/dist/esm/remote-run.js +6 -4
- package/dist/esm/remote-session.js +4 -4
- package/dist/esm/remote-snapshot.js +8 -22
- package/dist/esm/resolver.js +3 -4
- package/dist/esm/route.d.ts +29 -0
- package/dist/esm/route.js +94 -0
- package/dist/esm/run-chain.d.ts +1 -1
- package/dist/esm/run-chain.js +4 -2
- package/dist/esm/runCli.d.ts +2 -0
- package/dist/esm/runCli.js +36 -78
- package/dist/esm/stated-outcome.js +3 -3
- package/dist/esm/steps.js +6 -30
- package/dist/esm/user-config.js +7 -14
- package/dist/esm/vitest-source-resolution.js +5 -6
- package/dist/esm/vitest-temp-isolation.d.ts +2 -0
- package/dist/esm/vitest-temp-isolation.js +44 -0
- package/dist/esm/vitest.d.ts +9 -0
- package/dist/esm/vitest.js +8 -5
- package/docs/reporting.md +3 -3
- package/docs/scripts.md +1 -1
- package/docs/utilities.md +5 -5
- package/docs/vitest.md +11 -6
- package/package.json +4 -4
package/.readyup/kits/default.js
CHANGED
|
@@ -117,17 +117,17 @@ var require_visit = __commonJS({
|
|
|
117
117
|
visit.BREAK = BREAK;
|
|
118
118
|
visit.SKIP = SKIP;
|
|
119
119
|
visit.REMOVE = REMOVE;
|
|
120
|
-
function visit_(key, node, visitor,
|
|
121
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
120
|
+
function visit_(key, node, visitor, path9) {
|
|
121
|
+
const ctrl = callVisitor(key, node, visitor, path9);
|
|
122
122
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
123
|
-
replaceNode(key,
|
|
124
|
-
return visit_(key, ctrl, visitor,
|
|
123
|
+
replaceNode(key, path9, ctrl);
|
|
124
|
+
return visit_(key, ctrl, visitor, path9);
|
|
125
125
|
}
|
|
126
126
|
if (typeof ctrl !== "symbol") {
|
|
127
127
|
if (identity.isCollection(node)) {
|
|
128
|
-
|
|
128
|
+
path9 = Object.freeze(path9.concat(node));
|
|
129
129
|
for (let i = 0; i < node.items.length; ++i) {
|
|
130
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
130
|
+
const ci = visit_(i, node.items[i], visitor, path9);
|
|
131
131
|
if (typeof ci === "number")
|
|
132
132
|
i = ci - 1;
|
|
133
133
|
else if (ci === BREAK)
|
|
@@ -138,13 +138,13 @@ var require_visit = __commonJS({
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
} else if (identity.isPair(node)) {
|
|
141
|
-
|
|
142
|
-
const ck = visit_("key", node.key, visitor,
|
|
141
|
+
path9 = Object.freeze(path9.concat(node));
|
|
142
|
+
const ck = visit_("key", node.key, visitor, path9);
|
|
143
143
|
if (ck === BREAK)
|
|
144
144
|
return BREAK;
|
|
145
145
|
else if (ck === REMOVE)
|
|
146
146
|
node.key = null;
|
|
147
|
-
const cv = visit_("value", node.value, visitor,
|
|
147
|
+
const cv = visit_("value", node.value, visitor, path9);
|
|
148
148
|
if (cv === BREAK)
|
|
149
149
|
return BREAK;
|
|
150
150
|
else if (cv === REMOVE)
|
|
@@ -165,17 +165,17 @@ var require_visit = __commonJS({
|
|
|
165
165
|
visitAsync.BREAK = BREAK;
|
|
166
166
|
visitAsync.SKIP = SKIP;
|
|
167
167
|
visitAsync.REMOVE = REMOVE;
|
|
168
|
-
async function visitAsync_(key, node, visitor,
|
|
169
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
168
|
+
async function visitAsync_(key, node, visitor, path9) {
|
|
169
|
+
const ctrl = await callVisitor(key, node, visitor, path9);
|
|
170
170
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
171
|
-
replaceNode(key,
|
|
172
|
-
return visitAsync_(key, ctrl, visitor,
|
|
171
|
+
replaceNode(key, path9, ctrl);
|
|
172
|
+
return visitAsync_(key, ctrl, visitor, path9);
|
|
173
173
|
}
|
|
174
174
|
if (typeof ctrl !== "symbol") {
|
|
175
175
|
if (identity.isCollection(node)) {
|
|
176
|
-
|
|
176
|
+
path9 = Object.freeze(path9.concat(node));
|
|
177
177
|
for (let i = 0; i < node.items.length; ++i) {
|
|
178
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
178
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path9);
|
|
179
179
|
if (typeof ci === "number")
|
|
180
180
|
i = ci - 1;
|
|
181
181
|
else if (ci === BREAK)
|
|
@@ -186,13 +186,13 @@ var require_visit = __commonJS({
|
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
} else if (identity.isPair(node)) {
|
|
189
|
-
|
|
190
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
189
|
+
path9 = Object.freeze(path9.concat(node));
|
|
190
|
+
const ck = await visitAsync_("key", node.key, visitor, path9);
|
|
191
191
|
if (ck === BREAK)
|
|
192
192
|
return BREAK;
|
|
193
193
|
else if (ck === REMOVE)
|
|
194
194
|
node.key = null;
|
|
195
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
195
|
+
const cv = await visitAsync_("value", node.value, visitor, path9);
|
|
196
196
|
if (cv === BREAK)
|
|
197
197
|
return BREAK;
|
|
198
198
|
else if (cv === REMOVE)
|
|
@@ -219,23 +219,23 @@ var require_visit = __commonJS({
|
|
|
219
219
|
}
|
|
220
220
|
return visitor;
|
|
221
221
|
}
|
|
222
|
-
function callVisitor(key, node, visitor,
|
|
222
|
+
function callVisitor(key, node, visitor, path9) {
|
|
223
223
|
if (typeof visitor === "function")
|
|
224
|
-
return visitor(key, node,
|
|
224
|
+
return visitor(key, node, path9);
|
|
225
225
|
if (identity.isMap(node))
|
|
226
|
-
return visitor.Map?.(key, node,
|
|
226
|
+
return visitor.Map?.(key, node, path9);
|
|
227
227
|
if (identity.isSeq(node))
|
|
228
|
-
return visitor.Seq?.(key, node,
|
|
228
|
+
return visitor.Seq?.(key, node, path9);
|
|
229
229
|
if (identity.isPair(node))
|
|
230
|
-
return visitor.Pair?.(key, node,
|
|
230
|
+
return visitor.Pair?.(key, node, path9);
|
|
231
231
|
if (identity.isScalar(node))
|
|
232
|
-
return visitor.Scalar?.(key, node,
|
|
232
|
+
return visitor.Scalar?.(key, node, path9);
|
|
233
233
|
if (identity.isAlias(node))
|
|
234
|
-
return visitor.Alias?.(key, node,
|
|
234
|
+
return visitor.Alias?.(key, node, path9);
|
|
235
235
|
return void 0;
|
|
236
236
|
}
|
|
237
|
-
function replaceNode(key,
|
|
238
|
-
const parent =
|
|
237
|
+
function replaceNode(key, path9, node) {
|
|
238
|
+
const parent = path9[path9.length - 1];
|
|
239
239
|
if (identity.isCollection(parent)) {
|
|
240
240
|
parent.items[key] = node;
|
|
241
241
|
} else if (identity.isPair(parent)) {
|
|
@@ -847,10 +847,10 @@ var require_Collection = __commonJS({
|
|
|
847
847
|
var createNode = require_createNode();
|
|
848
848
|
var identity = require_identity();
|
|
849
849
|
var Node = require_Node();
|
|
850
|
-
function collectionFromPath(schema,
|
|
850
|
+
function collectionFromPath(schema, path9, value) {
|
|
851
851
|
let v = value;
|
|
852
|
-
for (let i =
|
|
853
|
-
const k =
|
|
852
|
+
for (let i = path9.length - 1; i >= 0; --i) {
|
|
853
|
+
const k = path9[i];
|
|
854
854
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
855
855
|
const a = [];
|
|
856
856
|
a[k] = v;
|
|
@@ -869,7 +869,7 @@ var require_Collection = __commonJS({
|
|
|
869
869
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
870
870
|
});
|
|
871
871
|
}
|
|
872
|
-
var isEmptyPath = (
|
|
872
|
+
var isEmptyPath = (path9) => path9 == null || typeof path9 === "object" && !!path9[Symbol.iterator]().next().done;
|
|
873
873
|
var Collection = class extends Node.NodeBase {
|
|
874
874
|
constructor(type, schema) {
|
|
875
875
|
super(type);
|
|
@@ -899,11 +899,11 @@ var require_Collection = __commonJS({
|
|
|
899
899
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
900
900
|
* that already exists in the map.
|
|
901
901
|
*/
|
|
902
|
-
addIn(
|
|
903
|
-
if (isEmptyPath(
|
|
902
|
+
addIn(path9, value) {
|
|
903
|
+
if (isEmptyPath(path9))
|
|
904
904
|
this.add(value);
|
|
905
905
|
else {
|
|
906
|
-
const [key, ...rest] =
|
|
906
|
+
const [key, ...rest] = path9;
|
|
907
907
|
const node = this.get(key, true);
|
|
908
908
|
if (identity.isCollection(node))
|
|
909
909
|
node.addIn(rest, value);
|
|
@@ -917,8 +917,8 @@ var require_Collection = __commonJS({
|
|
|
917
917
|
* Removes a value from the collection.
|
|
918
918
|
* @returns `true` if the item was found and removed.
|
|
919
919
|
*/
|
|
920
|
-
deleteIn(
|
|
921
|
-
const [key, ...rest] =
|
|
920
|
+
deleteIn(path9) {
|
|
921
|
+
const [key, ...rest] = path9;
|
|
922
922
|
if (rest.length === 0)
|
|
923
923
|
return this.delete(key);
|
|
924
924
|
const node = this.get(key, true);
|
|
@@ -932,8 +932,8 @@ var require_Collection = __commonJS({
|
|
|
932
932
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
933
933
|
* `true` (collections are always returned intact).
|
|
934
934
|
*/
|
|
935
|
-
getIn(
|
|
936
|
-
const [key, ...rest] =
|
|
935
|
+
getIn(path9, keepScalar) {
|
|
936
|
+
const [key, ...rest] = path9;
|
|
937
937
|
const node = this.get(key, true);
|
|
938
938
|
if (rest.length === 0)
|
|
939
939
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -951,8 +951,8 @@ var require_Collection = __commonJS({
|
|
|
951
951
|
/**
|
|
952
952
|
* Checks if the collection includes a value with the key `key`.
|
|
953
953
|
*/
|
|
954
|
-
hasIn(
|
|
955
|
-
const [key, ...rest] =
|
|
954
|
+
hasIn(path9) {
|
|
955
|
+
const [key, ...rest] = path9;
|
|
956
956
|
if (rest.length === 0)
|
|
957
957
|
return this.has(key);
|
|
958
958
|
const node = this.get(key, true);
|
|
@@ -962,8 +962,8 @@ var require_Collection = __commonJS({
|
|
|
962
962
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
963
963
|
* boolean to add/remove the item from the set.
|
|
964
964
|
*/
|
|
965
|
-
setIn(
|
|
966
|
-
const [key, ...rest] =
|
|
965
|
+
setIn(path9, value) {
|
|
966
|
+
const [key, ...rest] = path9;
|
|
967
967
|
if (rest.length === 0) {
|
|
968
968
|
this.set(key, value);
|
|
969
969
|
} else {
|
|
@@ -3478,9 +3478,9 @@ var require_Document = __commonJS({
|
|
|
3478
3478
|
this.contents.add(value);
|
|
3479
3479
|
}
|
|
3480
3480
|
/** Adds a value to the document. */
|
|
3481
|
-
addIn(
|
|
3481
|
+
addIn(path9, value) {
|
|
3482
3482
|
if (assertCollection(this.contents))
|
|
3483
|
-
this.contents.addIn(
|
|
3483
|
+
this.contents.addIn(path9, value);
|
|
3484
3484
|
}
|
|
3485
3485
|
/**
|
|
3486
3486
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -3555,14 +3555,14 @@ var require_Document = __commonJS({
|
|
|
3555
3555
|
* Removes a value from the document.
|
|
3556
3556
|
* @returns `true` if the item was found and removed.
|
|
3557
3557
|
*/
|
|
3558
|
-
deleteIn(
|
|
3559
|
-
if (Collection.isEmptyPath(
|
|
3558
|
+
deleteIn(path9) {
|
|
3559
|
+
if (Collection.isEmptyPath(path9)) {
|
|
3560
3560
|
if (this.contents == null)
|
|
3561
3561
|
return false;
|
|
3562
3562
|
this.contents = null;
|
|
3563
3563
|
return true;
|
|
3564
3564
|
}
|
|
3565
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
3565
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path9) : false;
|
|
3566
3566
|
}
|
|
3567
3567
|
/**
|
|
3568
3568
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -3577,10 +3577,10 @@ var require_Document = __commonJS({
|
|
|
3577
3577
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
3578
3578
|
* `true` (collections are always returned intact).
|
|
3579
3579
|
*/
|
|
3580
|
-
getIn(
|
|
3581
|
-
if (Collection.isEmptyPath(
|
|
3580
|
+
getIn(path9, keepScalar) {
|
|
3581
|
+
if (Collection.isEmptyPath(path9))
|
|
3582
3582
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
3583
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
3583
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path9, keepScalar) : void 0;
|
|
3584
3584
|
}
|
|
3585
3585
|
/**
|
|
3586
3586
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -3591,10 +3591,10 @@ var require_Document = __commonJS({
|
|
|
3591
3591
|
/**
|
|
3592
3592
|
* Checks if the document includes a value at `path`.
|
|
3593
3593
|
*/
|
|
3594
|
-
hasIn(
|
|
3595
|
-
if (Collection.isEmptyPath(
|
|
3594
|
+
hasIn(path9) {
|
|
3595
|
+
if (Collection.isEmptyPath(path9))
|
|
3596
3596
|
return this.contents !== void 0;
|
|
3597
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
3597
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path9) : false;
|
|
3598
3598
|
}
|
|
3599
3599
|
/**
|
|
3600
3600
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -3611,13 +3611,13 @@ var require_Document = __commonJS({
|
|
|
3611
3611
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
3612
3612
|
* boolean to add/remove the item from the set.
|
|
3613
3613
|
*/
|
|
3614
|
-
setIn(
|
|
3615
|
-
if (Collection.isEmptyPath(
|
|
3614
|
+
setIn(path9, value) {
|
|
3615
|
+
if (Collection.isEmptyPath(path9)) {
|
|
3616
3616
|
this.contents = value;
|
|
3617
3617
|
} else if (this.contents == null) {
|
|
3618
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3618
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path9), value);
|
|
3619
3619
|
} else if (assertCollection(this.contents)) {
|
|
3620
|
-
this.contents.setIn(
|
|
3620
|
+
this.contents.setIn(path9, value);
|
|
3621
3621
|
}
|
|
3622
3622
|
}
|
|
3623
3623
|
/**
|
|
@@ -5578,9 +5578,9 @@ var require_cst_visit = __commonJS({
|
|
|
5578
5578
|
visit.BREAK = BREAK;
|
|
5579
5579
|
visit.SKIP = SKIP;
|
|
5580
5580
|
visit.REMOVE = REMOVE;
|
|
5581
|
-
visit.itemAtPath = (cst,
|
|
5581
|
+
visit.itemAtPath = (cst, path9) => {
|
|
5582
5582
|
let item = cst;
|
|
5583
|
-
for (const [field, index] of
|
|
5583
|
+
for (const [field, index] of path9) {
|
|
5584
5584
|
const tok = item?.[field];
|
|
5585
5585
|
if (tok && "items" in tok) {
|
|
5586
5586
|
item = tok.items[index];
|
|
@@ -5589,23 +5589,23 @@ var require_cst_visit = __commonJS({
|
|
|
5589
5589
|
}
|
|
5590
5590
|
return item;
|
|
5591
5591
|
};
|
|
5592
|
-
visit.parentCollection = (cst,
|
|
5593
|
-
const parent = visit.itemAtPath(cst,
|
|
5594
|
-
const field =
|
|
5592
|
+
visit.parentCollection = (cst, path9) => {
|
|
5593
|
+
const parent = visit.itemAtPath(cst, path9.slice(0, -1));
|
|
5594
|
+
const field = path9[path9.length - 1][0];
|
|
5595
5595
|
const coll = parent?.[field];
|
|
5596
5596
|
if (coll && "items" in coll)
|
|
5597
5597
|
return coll;
|
|
5598
5598
|
throw new Error("Parent collection not found");
|
|
5599
5599
|
};
|
|
5600
|
-
function _visit(
|
|
5601
|
-
let ctrl = visitor(item,
|
|
5600
|
+
function _visit(path9, item, visitor) {
|
|
5601
|
+
let ctrl = visitor(item, path9);
|
|
5602
5602
|
if (typeof ctrl === "symbol")
|
|
5603
5603
|
return ctrl;
|
|
5604
5604
|
for (const field of ["key", "value"]) {
|
|
5605
5605
|
const token = item[field];
|
|
5606
5606
|
if (token && "items" in token) {
|
|
5607
5607
|
for (let i = 0; i < token.items.length; ++i) {
|
|
5608
|
-
const ci = _visit(Object.freeze(
|
|
5608
|
+
const ci = _visit(Object.freeze(path9.concat([[field, i]])), token.items[i], visitor);
|
|
5609
5609
|
if (typeof ci === "number")
|
|
5610
5610
|
i = ci - 1;
|
|
5611
5611
|
else if (ci === BREAK)
|
|
@@ -5616,10 +5616,10 @@ var require_cst_visit = __commonJS({
|
|
|
5616
5616
|
}
|
|
5617
5617
|
}
|
|
5618
5618
|
if (typeof ctrl === "function" && field === "key")
|
|
5619
|
-
ctrl = ctrl(item,
|
|
5619
|
+
ctrl = ctrl(item, path9);
|
|
5620
5620
|
}
|
|
5621
5621
|
}
|
|
5622
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5622
|
+
return typeof ctrl === "function" ? ctrl(item, path9) : ctrl;
|
|
5623
5623
|
}
|
|
5624
5624
|
exports.visit = visit;
|
|
5625
5625
|
}
|
|
@@ -7416,11 +7416,11 @@ function discoverWorkspacesOrFailure(filter) {
|
|
|
7416
7416
|
}
|
|
7417
7417
|
}
|
|
7418
7418
|
function findFiles(patterns, cwd) {
|
|
7419
|
-
return globSync(patterns, { cwd, exclude: (
|
|
7419
|
+
return globSync(patterns, { cwd, exclude: (path9) => SCAN_EXCLUDE_DIRS.has(basename(path9)) }).map((path9) => path9.split(sep).join("/")).toSorted();
|
|
7420
7420
|
}
|
|
7421
7421
|
function formatPaths(paths) {
|
|
7422
7422
|
return `${paths.length} found:
|
|
7423
|
-
${paths.map((
|
|
7423
|
+
${paths.map((path9) => ` ${path9}`).join("\n")}`;
|
|
7424
7424
|
}
|
|
7425
7425
|
function importsSharedExport(content, exportName, moduleSpecifier) {
|
|
7426
7426
|
if (content === void 0) return false;
|
|
@@ -7518,7 +7518,7 @@ function readWrapperTarget(cwd, workspace, entry) {
|
|
|
7518
7518
|
// .readyup/lib/root-scripts.ts
|
|
7519
7519
|
import { existsSync as existsSync2, readdirSync } from "node:fs";
|
|
7520
7520
|
import { join as join2 } from "node:path";
|
|
7521
|
-
import { fileExists, isRecord as
|
|
7521
|
+
import { fileExists, isRecord as isRecord3, readFile as readFile2, readPackageJson } from "readyup/check-utils";
|
|
7522
7522
|
|
|
7523
7523
|
// src/shell-syntax.ts
|
|
7524
7524
|
var ENV_ASSIGNMENT = /^\w+=/;
|
|
@@ -7725,12 +7725,17 @@ function buildRootScripts(workspaceGlobs) {
|
|
|
7725
7725
|
};
|
|
7726
7726
|
}
|
|
7727
7727
|
|
|
7728
|
-
// ../nmr-core/dist/esm/workspace.js
|
|
7728
|
+
// ../nmr-core/dist/esm/workspace/workspace.js
|
|
7729
7729
|
import { existsSync, readFileSync } from "node:fs";
|
|
7730
7730
|
import path2 from "node:path";
|
|
7731
7731
|
var import_yaml = __toESM(require_dist(), 1);
|
|
7732
7732
|
|
|
7733
|
-
// ../nmr-core/dist/esm/
|
|
7733
|
+
// ../nmr-core/dist/esm/portable/isRecord.js
|
|
7734
|
+
function isRecord2(value) {
|
|
7735
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7736
|
+
}
|
|
7737
|
+
|
|
7738
|
+
// ../nmr-core/dist/esm/workspace/workspace-patterns.js
|
|
7734
7739
|
import { globSync as globSync2 } from "node:fs";
|
|
7735
7740
|
import path from "node:path";
|
|
7736
7741
|
var MANIFEST_FILENAME = "package.json";
|
|
@@ -7768,7 +7773,7 @@ function buildManifestPattern(pattern) {
|
|
|
7768
7773
|
return `${pattern.replace(/\/?$/, "")}/${MANIFEST_FILENAME}`;
|
|
7769
7774
|
}
|
|
7770
7775
|
|
|
7771
|
-
// ../nmr-core/dist/esm/workspace.js
|
|
7776
|
+
// ../nmr-core/dist/esm/workspace/workspace.js
|
|
7772
7777
|
var WORKSPACE_MANIFEST_FILENAME = "pnpm-workspace.yaml";
|
|
7773
7778
|
function isMonorepoRoot(dir) {
|
|
7774
7779
|
return existsSync(path2.join(dir, WORKSPACE_MANIFEST_FILENAME));
|
|
@@ -7804,7 +7809,7 @@ function diagnoseEmptyCause(monorepoRoot, patterns) {
|
|
|
7804
7809
|
return "no-package";
|
|
7805
7810
|
}
|
|
7806
7811
|
function readDeclaredPackages(parsedManifest) {
|
|
7807
|
-
if (!
|
|
7812
|
+
if (!isRecord2(parsedManifest))
|
|
7808
7813
|
return { kind: "absent" };
|
|
7809
7814
|
const packages = parsedManifest["packages"];
|
|
7810
7815
|
if (packages === void 0 || packages === null)
|
|
@@ -7815,9 +7820,6 @@ function readDeclaredPackages(parsedManifest) {
|
|
|
7815
7820
|
return { kind: "unreadable" };
|
|
7816
7821
|
return packages.length === 0 ? { kind: "absent" } : { kind: "patterns", patterns: packages };
|
|
7817
7822
|
}
|
|
7818
|
-
function isObject(value) {
|
|
7819
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7820
|
-
}
|
|
7821
7823
|
function readWorkspaceManifest(monorepoRoot) {
|
|
7822
7824
|
const workspaceManifestPath = path2.join(monorepoRoot, WORKSPACE_MANIFEST_FILENAME);
|
|
7823
7825
|
if (!existsSync(workspaceManifestPath)) {
|
|
@@ -7830,12 +7832,12 @@ function readWorkspaceManifest(monorepoRoot) {
|
|
|
7830
7832
|
}
|
|
7831
7833
|
}
|
|
7832
7834
|
|
|
7833
|
-
// ../nmr-core/dist/esm/hasErrnoCode.js
|
|
7835
|
+
// ../nmr-core/dist/esm/errors/hasErrnoCode.js
|
|
7834
7836
|
function hasErrnoCode(error, code) {
|
|
7835
7837
|
return isError(error) && "code" in error && error.code === code;
|
|
7836
7838
|
}
|
|
7837
7839
|
|
|
7838
|
-
// ../nmr-core/dist/esm/UserError.js
|
|
7840
|
+
// ../nmr-core/dist/esm/errors/UserError.js
|
|
7839
7841
|
var UserError = class extends Error {
|
|
7840
7842
|
constructor(message, options) {
|
|
7841
7843
|
super(message, options);
|
|
@@ -7843,6 +7845,32 @@ var UserError = class extends Error {
|
|
|
7843
7845
|
}
|
|
7844
7846
|
};
|
|
7845
7847
|
|
|
7848
|
+
// ../nmr-core/dist/esm/git/gitOutputLimit.js
|
|
7849
|
+
var GIT_OUTPUT_LIMIT_BYTES = 64 * 1024 * 1024;
|
|
7850
|
+
|
|
7851
|
+
// ../nmr-core/dist/esm/git/runGit.js
|
|
7852
|
+
import { spawnSync } from "node:child_process";
|
|
7853
|
+
function runGit(args, cwd, input, env) {
|
|
7854
|
+
const result = runGitForBytes(args, cwd, input === void 0 ? void 0 : Buffer.from(input, "utf8"), env);
|
|
7855
|
+
return result.ok ? { ok: true, stdout: result.stdout.toString("utf8") } : result;
|
|
7856
|
+
}
|
|
7857
|
+
function runGitForBytes(args, cwd, input, env) {
|
|
7858
|
+
const result = spawnSync("git", args, {
|
|
7859
|
+
cwd,
|
|
7860
|
+
env: { ...env ?? process.env, GIT_OPTIONAL_LOCKS: "0" },
|
|
7861
|
+
input,
|
|
7862
|
+
maxBuffer: GIT_OUTPUT_LIMIT_BYTES
|
|
7863
|
+
});
|
|
7864
|
+
if (result.error) {
|
|
7865
|
+
return { ok: false, error: result.error.message };
|
|
7866
|
+
}
|
|
7867
|
+
if (result.status !== 0) {
|
|
7868
|
+
const stderr = result.stderr.toString("utf8").trim();
|
|
7869
|
+
return { ok: false, error: stderr || `\`git ${args.join(" ")}\` failed with exit code ${result.status}.` };
|
|
7870
|
+
}
|
|
7871
|
+
return { ok: true, stdout: result.stdout };
|
|
7872
|
+
}
|
|
7873
|
+
|
|
7846
7874
|
// src/workspace.ts
|
|
7847
7875
|
var WORKSPACE_MANIFEST = "pnpm-workspace.yaml";
|
|
7848
7876
|
function getWorkspacePackageDirs(monorepoRoot) {
|
|
@@ -7944,7 +7972,7 @@ function noRedundantRootScripts() {
|
|
|
7944
7972
|
const pkg = readPackageJson();
|
|
7945
7973
|
if (!pkg) return true;
|
|
7946
7974
|
const scripts = pkg["scripts"];
|
|
7947
|
-
if (!
|
|
7975
|
+
if (!isRecord3(scripts)) return true;
|
|
7948
7976
|
const builtInNames = Object.keys(getDefaultRootScripts(process.cwd()));
|
|
7949
7977
|
const redundantNames = Object.keys(scripts).filter((name) => builtInNames.includes(name));
|
|
7950
7978
|
if (redundantNames.length === 0) return true;
|
|
@@ -7981,13 +8009,13 @@ function readRootScripts(cwd) {
|
|
|
7981
8009
|
} catch {
|
|
7982
8010
|
return {};
|
|
7983
8011
|
}
|
|
7984
|
-
if (!
|
|
8012
|
+
if (!isRecord3(parsedManifest)) return {};
|
|
7985
8013
|
const scripts = parsedManifest["scripts"];
|
|
7986
|
-
return
|
|
8014
|
+
return isRecord3(scripts) ? scripts : {};
|
|
7987
8015
|
}
|
|
7988
8016
|
|
|
7989
8017
|
// .readyup/lib/self-hosted-runner.ts
|
|
7990
|
-
import { isRecord as
|
|
8018
|
+
import { isRecord as isRecord5 } from "readyup/check-utils";
|
|
7991
8019
|
|
|
7992
8020
|
// src/config.ts
|
|
7993
8021
|
import { existsSync as existsSync3 } from "node:fs";
|
|
@@ -8044,9 +8072,10 @@ function isHookName(key) {
|
|
|
8044
8072
|
}
|
|
8045
8073
|
|
|
8046
8074
|
// src/resolver.ts
|
|
8047
|
-
import { readFileSync as
|
|
8075
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
8048
8076
|
|
|
8049
8077
|
// src/helpers/package-json.ts
|
|
8078
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
8050
8079
|
import path5 from "node:path";
|
|
8051
8080
|
|
|
8052
8081
|
// src/helpers/config-path.ts
|
|
@@ -8058,15 +8087,52 @@ function resolveConfigPath(baseDir) {
|
|
|
8058
8087
|
return path4.join(baseDir, CONFIG_DIR, CONFIG_FILENAME);
|
|
8059
8088
|
}
|
|
8060
8089
|
|
|
8061
|
-
// src/helpers/
|
|
8062
|
-
function
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8090
|
+
// src/helpers/readStringValues.ts
|
|
8091
|
+
function readStringValues(record) {
|
|
8092
|
+
const result = {};
|
|
8093
|
+
for (const [key, value] of Object.entries(record)) {
|
|
8094
|
+
if (typeof value === "string") result[key] = value;
|
|
8095
|
+
}
|
|
8096
|
+
return result;
|
|
8067
8097
|
}
|
|
8068
8098
|
|
|
8069
8099
|
// src/helpers/package-json.ts
|
|
8100
|
+
var DEPENDENCY_FIELDS = [
|
|
8101
|
+
"dependencies",
|
|
8102
|
+
"devDependencies",
|
|
8103
|
+
"optionalDependencies",
|
|
8104
|
+
"peerDependencies"
|
|
8105
|
+
];
|
|
8106
|
+
function readPackageJson2(dir) {
|
|
8107
|
+
const file = resolvePackageJsonPath(dir);
|
|
8108
|
+
const parsedManifest = parsePackageJson(readFileSync2(file, "utf8"), file);
|
|
8109
|
+
if (!isRecord2(parsedManifest)) {
|
|
8110
|
+
throw new UserError(`Invalid package.json in ${dir}: expected an object`);
|
|
8111
|
+
}
|
|
8112
|
+
const packageJson = {};
|
|
8113
|
+
if (typeof parsedManifest["name"] === "string") packageJson.name = parsedManifest["name"];
|
|
8114
|
+
if (parsedManifest["private"] === true) packageJson.private = true;
|
|
8115
|
+
if (typeof parsedManifest["version"] === "string") packageJson.version = parsedManifest["version"];
|
|
8116
|
+
if (typeof parsedManifest["packageManager"] === "string") {
|
|
8117
|
+
packageJson.packageManager = parsedManifest["packageManager"];
|
|
8118
|
+
}
|
|
8119
|
+
if (isRecord2(parsedManifest["scripts"])) {
|
|
8120
|
+
packageJson.scripts = readScriptRecord(dir, parsedManifest["scripts"]);
|
|
8121
|
+
}
|
|
8122
|
+
if (isRecord2(parsedManifest["pnpm"])) {
|
|
8123
|
+
const pnpm = parsedManifest["pnpm"];
|
|
8124
|
+
if (isRecord2(pnpm["overrides"])) {
|
|
8125
|
+
packageJson.pnpm = { overrides: pnpm["overrides"] };
|
|
8126
|
+
}
|
|
8127
|
+
}
|
|
8128
|
+
for (const field of DEPENDENCY_FIELDS) {
|
|
8129
|
+
const declaredDependencies = parsedManifest[field];
|
|
8130
|
+
if (isRecord2(declaredDependencies)) {
|
|
8131
|
+
packageJson[field] = readStringValues(declaredDependencies);
|
|
8132
|
+
}
|
|
8133
|
+
}
|
|
8134
|
+
return packageJson;
|
|
8135
|
+
}
|
|
8070
8136
|
function parsePackageJson(rawText, file) {
|
|
8071
8137
|
try {
|
|
8072
8138
|
return JSON.parse(rawText);
|
|
@@ -8096,6 +8162,370 @@ function formatMalformedScript(dir, key, value) {
|
|
|
8096
8162
|
return `${rejection} A step list belongs in \`${CONFIG_RELATIVE_PATH}\` under \`${field}\`.`;
|
|
8097
8163
|
}
|
|
8098
8164
|
|
|
8165
|
+
// ../../node_modules/.pnpm/@williamthorsen+toolbelt.cli@0.8.0/node_modules/@williamthorsen/toolbelt.cli/dist/esm/3-candidate/parseArgs.js
|
|
8166
|
+
import path6 from "node:path";
|
|
8167
|
+
import process2 from "node:process";
|
|
8168
|
+
|
|
8169
|
+
// ../../node_modules/.pnpm/@williamthorsen+toolbelt.cli@0.8.0/node_modules/@williamthorsen/toolbelt.cli/dist/esm/3-candidate/UsageError.js
|
|
8170
|
+
var UsageError = class extends Error {
|
|
8171
|
+
constructor(message, options) {
|
|
8172
|
+
super(message, options);
|
|
8173
|
+
this.name = "UsageError";
|
|
8174
|
+
}
|
|
8175
|
+
};
|
|
8176
|
+
|
|
8177
|
+
// ../../node_modules/.pnpm/@williamthorsen+toolbelt.cli@0.8.0/node_modules/@williamthorsen/toolbelt.cli/dist/esm/3-candidate/ParseError.js
|
|
8178
|
+
var ParseError = class extends UsageError {
|
|
8179
|
+
kind;
|
|
8180
|
+
token;
|
|
8181
|
+
constructor(kind, token, message, options) {
|
|
8182
|
+
super(message, options);
|
|
8183
|
+
this.name = "ParseError";
|
|
8184
|
+
this.kind = kind;
|
|
8185
|
+
this.token = token;
|
|
8186
|
+
}
|
|
8187
|
+
};
|
|
8188
|
+
|
|
8189
|
+
// ../../node_modules/.pnpm/@williamthorsen+toolbelt.cli@0.8.0/node_modules/@williamthorsen/toolbelt.cli/dist/esm/3-candidate/resolveLongName.js
|
|
8190
|
+
function resolveLongName(key, definition) {
|
|
8191
|
+
return definition.long ?? key.replaceAll(/[A-Z]/g, (capital) => `-${capital.toLowerCase()}`);
|
|
8192
|
+
}
|
|
8193
|
+
|
|
8194
|
+
// ../../node_modules/.pnpm/@williamthorsen+toolbelt.cli@0.8.0/node_modules/@williamthorsen/toolbelt.cli/dist/esm/3-candidate/tokenizeArgs.js
|
|
8195
|
+
import { parseArgs as nodeParseArgs } from "node:util";
|
|
8196
|
+
function tokenizeArgs(argv, schema, extraBooleans = []) {
|
|
8197
|
+
const nodeOptions = {};
|
|
8198
|
+
const flagsByName = /* @__PURE__ */ new Map();
|
|
8199
|
+
for (const [key, definition] of Object.entries(schema)) {
|
|
8200
|
+
const name = resolveLongName(key, definition);
|
|
8201
|
+
const type = definition.type === "boolean" ? "boolean" : "string";
|
|
8202
|
+
nodeOptions[name] = definition.short === void 0 ? { type } : { type, short: definition.short };
|
|
8203
|
+
flagsByName.set(name, { key, definition });
|
|
8204
|
+
}
|
|
8205
|
+
for (const { long, short } of extraBooleans) {
|
|
8206
|
+
nodeOptions[long] = { type: "boolean", short };
|
|
8207
|
+
}
|
|
8208
|
+
const { tokens } = nodeParseArgs({
|
|
8209
|
+
args: [...argv],
|
|
8210
|
+
options: nodeOptions,
|
|
8211
|
+
strict: false,
|
|
8212
|
+
allowPositionals: true,
|
|
8213
|
+
tokens: true
|
|
8214
|
+
});
|
|
8215
|
+
return { tokens, flagsByName };
|
|
8216
|
+
}
|
|
8217
|
+
function findFlagEntry(flagsByName, token) {
|
|
8218
|
+
const entry = flagsByName.get(token.name);
|
|
8219
|
+
if (entry === void 0 || token.rawName.startsWith("--"))
|
|
8220
|
+
return entry;
|
|
8221
|
+
return entry.definition.short === token.rawName.slice(1) ? entry : void 0;
|
|
8222
|
+
}
|
|
8223
|
+
|
|
8224
|
+
// ../../node_modules/.pnpm/@williamthorsen+toolbelt.cli@0.8.0/node_modules/@williamthorsen/toolbelt.cli/dist/esm/3-candidate/validateSpec.js
|
|
8225
|
+
var CAMEL_CASE_KEY = /^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]+)*$/;
|
|
8226
|
+
function validateSpec(spec) {
|
|
8227
|
+
validateFlags(spec.flags ?? {});
|
|
8228
|
+
validateOperands(spec.operands ?? []);
|
|
8229
|
+
}
|
|
8230
|
+
function validateFlags(flags) {
|
|
8231
|
+
const longNames = /* @__PURE__ */ new Set(["help"]);
|
|
8232
|
+
const shortNames = /* @__PURE__ */ new Set(["h"]);
|
|
8233
|
+
for (const [key, definition] of Object.entries(flags)) {
|
|
8234
|
+
if (definition.long === void 0 && !CAMEL_CASE_KEY.test(key)) {
|
|
8235
|
+
throw new Error(`Flag key '${key}' must be camelCase or declare 'long'.`);
|
|
8236
|
+
}
|
|
8237
|
+
if (definition.long !== void 0 && (definition.long === "" || definition.long.startsWith("-"))) {
|
|
8238
|
+
throw new Error(`Flag '${key}' declares a long name that is empty or starts with a dash: '${definition.long}'.`);
|
|
8239
|
+
}
|
|
8240
|
+
const longName = resolveLongName(key, definition);
|
|
8241
|
+
if (longNames.has(longName)) {
|
|
8242
|
+
throw new Error(`Flag '${key}' reuses the long name --${longName}, which is reserved or already declared.`);
|
|
8243
|
+
}
|
|
8244
|
+
longNames.add(longName);
|
|
8245
|
+
if (definition.short !== void 0) {
|
|
8246
|
+
if (definition.short.length !== 1 || definition.short === "-") {
|
|
8247
|
+
throw new Error(`Flag '${key}' must declare 'short' as one character other than a dash.`);
|
|
8248
|
+
}
|
|
8249
|
+
if (shortNames.has(definition.short)) {
|
|
8250
|
+
throw new Error(`Flag '${key}' reuses the short name -${definition.short}, which is reserved or already declared.`);
|
|
8251
|
+
}
|
|
8252
|
+
shortNames.add(definition.short);
|
|
8253
|
+
}
|
|
8254
|
+
validateFlagFields(key, definition);
|
|
8255
|
+
}
|
|
8256
|
+
}
|
|
8257
|
+
function validateFlagFields(key, definition) {
|
|
8258
|
+
if (definition.type === "boolean") {
|
|
8259
|
+
if (definition.valueHint !== void 0)
|
|
8260
|
+
throw new Error(`Boolean flag '${key}' cannot declare 'valueHint'.`);
|
|
8261
|
+
if (definition.parse !== void 0)
|
|
8262
|
+
throw new Error(`Boolean flag '${key}' cannot declare 'parse'.`);
|
|
8263
|
+
if ("default" in definition && typeof definition.default !== "boolean") {
|
|
8264
|
+
throw new Error(`Boolean flag '${key}' must declare a boolean 'default'.`);
|
|
8265
|
+
}
|
|
8266
|
+
if (definition.multiple === true)
|
|
8267
|
+
throw new Error(`Boolean flag '${key}' cannot declare 'multiple'.`);
|
|
8268
|
+
}
|
|
8269
|
+
if (definition.multiple === true && "default" in definition) {
|
|
8270
|
+
throw new Error(`Flag '${key}' declares 'multiple', which does not take a 'default'.`);
|
|
8271
|
+
}
|
|
8272
|
+
const { choices } = definition;
|
|
8273
|
+
if (choices === void 0)
|
|
8274
|
+
return;
|
|
8275
|
+
if (definition.type !== "string")
|
|
8276
|
+
throw new Error(`Flag '${key}' declares 'choices', which only a string flag takes.`);
|
|
8277
|
+
if (choices.length === 0)
|
|
8278
|
+
throw new Error(`Flag '${key}' declares empty 'choices'.`);
|
|
8279
|
+
if ("default" in definition && (typeof definition.default !== "string" || !choices.includes(definition.default))) {
|
|
8280
|
+
throw new Error(`Flag '${key}' declares a 'default' that is not one of its 'choices'.`);
|
|
8281
|
+
}
|
|
8282
|
+
}
|
|
8283
|
+
function validateOperands(operands) {
|
|
8284
|
+
const names = /* @__PURE__ */ new Set();
|
|
8285
|
+
let hasOptional = false;
|
|
8286
|
+
for (const [index, operand] of operands.entries()) {
|
|
8287
|
+
if (operand.name === "")
|
|
8288
|
+
throw new Error(`Operand ${index + 1} has an empty name.`);
|
|
8289
|
+
if (names.has(operand.name))
|
|
8290
|
+
throw new Error(`Operand name '${operand.name}' is declared twice.`);
|
|
8291
|
+
names.add(operand.name);
|
|
8292
|
+
if (operand.optional === true) {
|
|
8293
|
+
hasOptional = true;
|
|
8294
|
+
} else if (hasOptional) {
|
|
8295
|
+
throw new Error(`Required operand '${operand.name}' follows an optional one.`);
|
|
8296
|
+
}
|
|
8297
|
+
if (operand.variadic === true && index !== operands.length - 1) {
|
|
8298
|
+
throw new Error(`Variadic operand '${operand.name}' must be the last operand.`);
|
|
8299
|
+
}
|
|
8300
|
+
if (operand.choices?.length === 0)
|
|
8301
|
+
throw new Error(`Operand '${operand.name}' declares empty 'choices'.`);
|
|
8302
|
+
}
|
|
8303
|
+
}
|
|
8304
|
+
|
|
8305
|
+
// ../../node_modules/.pnpm/@williamthorsen+toolbelt.cli@0.8.0/node_modules/@williamthorsen/toolbelt.cli/dist/esm/3-candidate/parseArgs.js
|
|
8306
|
+
function parseArgs(argv, spec, options = {}) {
|
|
8307
|
+
validateSpec(spec);
|
|
8308
|
+
return parseValidatedArgs(argv, spec, options);
|
|
8309
|
+
}
|
|
8310
|
+
function parseValidatedArgs(argv, spec, options = {}) {
|
|
8311
|
+
const schema = spec.flags ?? {};
|
|
8312
|
+
const operandDefinitions = spec.operands ?? [];
|
|
8313
|
+
const baseDir = options.baseDir ?? process2.cwd();
|
|
8314
|
+
const stopAtPositional = options.stopAtPositional === true || options.stopAtUnclaimedFlag === true;
|
|
8315
|
+
const { tokens, flagsByName } = tokenizeArgs(argv, schema);
|
|
8316
|
+
const flags = {};
|
|
8317
|
+
for (const [key, definition] of Object.entries(schema)) {
|
|
8318
|
+
flags[key] = "default" in definition ? definition.default : initialValue(definition);
|
|
8319
|
+
}
|
|
8320
|
+
const positionals = [];
|
|
8321
|
+
let rest = [];
|
|
8322
|
+
let previousIndex = -1;
|
|
8323
|
+
let precedingInArgument = 0;
|
|
8324
|
+
for (const token of tokens) {
|
|
8325
|
+
if (token.kind === "option") {
|
|
8326
|
+
precedingInArgument = token.index === previousIndex ? precedingInArgument + 1 : 0;
|
|
8327
|
+
previousIndex = token.index;
|
|
8328
|
+
}
|
|
8329
|
+
if (stopAtPositional && token.kind !== "option") {
|
|
8330
|
+
rest = argv.slice(token.index);
|
|
8331
|
+
break;
|
|
8332
|
+
}
|
|
8333
|
+
if (token.kind === "option-terminator")
|
|
8334
|
+
continue;
|
|
8335
|
+
if (token.kind === "positional") {
|
|
8336
|
+
acceptPositional(token.value, positionals, operandDefinitions);
|
|
8337
|
+
continue;
|
|
8338
|
+
}
|
|
8339
|
+
const entry = findFlagEntry(flagsByName, token);
|
|
8340
|
+
if (entry === void 0) {
|
|
8341
|
+
if (options.stopAtUnclaimedFlag === true) {
|
|
8342
|
+
rest = splitAtOption(argv, token.index, precedingInArgument);
|
|
8343
|
+
break;
|
|
8344
|
+
}
|
|
8345
|
+
throw new ParseError("unknown-flag", token.rawName, `Unknown option: ${token.rawName}`);
|
|
8346
|
+
}
|
|
8347
|
+
const value = readFlagValue(token, entry.key, entry.definition, baseDir);
|
|
8348
|
+
const collected = flags[entry.key];
|
|
8349
|
+
if (entry.definition.multiple === true && Array.isArray(collected)) {
|
|
8350
|
+
collected.push(value);
|
|
8351
|
+
} else {
|
|
8352
|
+
flags[entry.key] = value;
|
|
8353
|
+
}
|
|
8354
|
+
}
|
|
8355
|
+
const operands = assignOperands(positionals, operandDefinitions);
|
|
8356
|
+
return { flags, operands, rest };
|
|
8357
|
+
}
|
|
8358
|
+
function acceptPositional(value, positionals, definitions) {
|
|
8359
|
+
const last = definitions.at(-1);
|
|
8360
|
+
const overflow = last?.variadic === true ? last : void 0;
|
|
8361
|
+
const definition = positionals.length < definitions.length ? definitions[positionals.length] : overflow;
|
|
8362
|
+
if (definition === void 0) {
|
|
8363
|
+
throw new ParseError("unexpected-positional", value, `Unexpected positional argument: ${value}`);
|
|
8364
|
+
}
|
|
8365
|
+
checkChoice(value, definition.choices, `<${definition.name}>`);
|
|
8366
|
+
positionals.push(value);
|
|
8367
|
+
}
|
|
8368
|
+
function assignOperands(positionals, definitions) {
|
|
8369
|
+
const operands = {};
|
|
8370
|
+
for (const [index, definition] of definitions.entries()) {
|
|
8371
|
+
const value = definition.variadic === true ? positionals.slice(index) : positionals[index];
|
|
8372
|
+
const isAbsent = value === void 0 || Array.isArray(value) && value.length === 0;
|
|
8373
|
+
if (isAbsent && definition.optional !== true) {
|
|
8374
|
+
const label = `<${definition.name}>`;
|
|
8375
|
+
throw new ParseError("missing-operand", label, `Missing argument: ${label}`);
|
|
8376
|
+
}
|
|
8377
|
+
operands[definition.name] = value;
|
|
8378
|
+
}
|
|
8379
|
+
return operands;
|
|
8380
|
+
}
|
|
8381
|
+
function initialValue(definition) {
|
|
8382
|
+
if (definition.multiple === true)
|
|
8383
|
+
return [];
|
|
8384
|
+
return definition.type === "boolean" ? false : void 0;
|
|
8385
|
+
}
|
|
8386
|
+
function checkChoice(value, choices, label) {
|
|
8387
|
+
if (choices === void 0 || choices.includes(value))
|
|
8388
|
+
return;
|
|
8389
|
+
throw new ParseError("invalid-choice", value, `Invalid value for ${label}: ${value}. Expected one of: ${choices.join(", ")}`);
|
|
8390
|
+
}
|
|
8391
|
+
function readFlagValue(token, key, definition, baseDir) {
|
|
8392
|
+
if (definition.type === "boolean") {
|
|
8393
|
+
if (token.value !== void 0) {
|
|
8394
|
+
throw new ParseError("unexpected-value", token.rawName, `Option does not accept a value: ${token.rawName}`);
|
|
8395
|
+
}
|
|
8396
|
+
return true;
|
|
8397
|
+
}
|
|
8398
|
+
const { value } = token;
|
|
8399
|
+
if (value === void 0 || value === "" || token.inlineValue !== true && value.startsWith("-") && value !== "-") {
|
|
8400
|
+
throw new ParseError("missing-value", token.rawName, `Missing value for option: ${token.rawName}`);
|
|
8401
|
+
}
|
|
8402
|
+
const label = `--${resolveLongName(key, definition)}`;
|
|
8403
|
+
checkChoice(value, definition.choices, label);
|
|
8404
|
+
const raw = definition.type === "path" ? path6.resolve(baseDir, value) : value;
|
|
8405
|
+
if (definition.parse === void 0)
|
|
8406
|
+
return raw;
|
|
8407
|
+
try {
|
|
8408
|
+
return definition.parse(raw);
|
|
8409
|
+
} catch (error) {
|
|
8410
|
+
const reason = describeError(error);
|
|
8411
|
+
throw new ParseError("invalid-value", value, `Invalid value for ${label}: ${value}. ${reason}`, { cause: error });
|
|
8412
|
+
}
|
|
8413
|
+
}
|
|
8414
|
+
function splitAtOption(argv, index, precedingInArgument) {
|
|
8415
|
+
const argument = argv[index];
|
|
8416
|
+
if (argument === void 0 || precedingInArgument === 0)
|
|
8417
|
+
return argv.slice(index);
|
|
8418
|
+
return [`-${argument.slice(1 + precedingInArgument)}`, ...argv.slice(index + 1)];
|
|
8419
|
+
}
|
|
8420
|
+
|
|
8421
|
+
// src/nmr-flags.ts
|
|
8422
|
+
var NMR_FLAGS = {
|
|
8423
|
+
delegate: {
|
|
8424
|
+
type: "boolean",
|
|
8425
|
+
description: "Run over SSH on the first free host that NMR_DELEGATE or the user config names"
|
|
8426
|
+
},
|
|
8427
|
+
delegateTo: {
|
|
8428
|
+
type: "string",
|
|
8429
|
+
description: "Run over SSH on the first free of <hosts>, comma-separated",
|
|
8430
|
+
valueHint: "hosts"
|
|
8431
|
+
},
|
|
8432
|
+
filter: {
|
|
8433
|
+
type: "string",
|
|
8434
|
+
description: "Run command in packages whose manifest name matches",
|
|
8435
|
+
short: "F",
|
|
8436
|
+
valueHint: "pattern"
|
|
8437
|
+
},
|
|
8438
|
+
json: { type: "boolean", description: "Report one JSON object per command, withholding command output" },
|
|
8439
|
+
log: { type: "boolean", description: "Print the recorded run instead of running (up to 256 KiB)" },
|
|
8440
|
+
noCache: { type: "boolean", description: "Run even if this tree already passed; record the result" },
|
|
8441
|
+
noDelegate: { type: "boolean", description: "Run here, whatever NMR_DELEGATE or the user config says" },
|
|
8442
|
+
noLock: { type: "boolean", description: "Run without waiting for another heavy command on this machine" },
|
|
8443
|
+
outputStyle: {
|
|
8444
|
+
type: "string",
|
|
8445
|
+
description: "Output style: auto (default), plain, or rich",
|
|
8446
|
+
valueHint: "auto|plain|rich"
|
|
8447
|
+
},
|
|
8448
|
+
quiet: { type: "boolean", description: "Suppress command output, keeping nmr's verdicts", short: "q" },
|
|
8449
|
+
recursive: { type: "boolean", description: "Run command in all packages", short: "R" },
|
|
8450
|
+
workspaceRoot: { type: "boolean", description: "Use root scripts, running at the monorepo root", short: "w" }
|
|
8451
|
+
};
|
|
8452
|
+
function readInvocationFlags(args) {
|
|
8453
|
+
const remaining = [...args];
|
|
8454
|
+
let shouldShowHelp = false;
|
|
8455
|
+
for (; ; ) {
|
|
8456
|
+
try {
|
|
8457
|
+
const parsed = parseArgs(remaining, { flags: READER_FLAGS }, { stopAtPositional: true });
|
|
8458
|
+
return { ok: true, parsedArgs: { ...toParsedArgs(parsed.flags, parsed.rest), shouldShowHelp } };
|
|
8459
|
+
} catch (error) {
|
|
8460
|
+
if (!(error instanceof ParseError)) {
|
|
8461
|
+
throw error;
|
|
8462
|
+
}
|
|
8463
|
+
if (error.kind !== "unknown-flag" || !HELP_SPELLINGS.has(error.token) || !removeHelpFlag(remaining, error.token)) {
|
|
8464
|
+
return { ok: false };
|
|
8465
|
+
}
|
|
8466
|
+
shouldShowHelp = true;
|
|
8467
|
+
}
|
|
8468
|
+
}
|
|
8469
|
+
}
|
|
8470
|
+
function toParsedArgs(flags, rest) {
|
|
8471
|
+
const [first, ...remaining] = rest;
|
|
8472
|
+
const hasCommand = first !== void 0 && first !== "--";
|
|
8473
|
+
return {
|
|
8474
|
+
...flags.delegateTo !== void 0 && { delegateHosts: flags.delegateTo },
|
|
8475
|
+
...flags.filter !== void 0 && { filter: flags.filter },
|
|
8476
|
+
isWorkspaceRoot: flags.workspaceRoot,
|
|
8477
|
+
...flags.outputStyle !== void 0 && { outputStyle: flags.outputStyle },
|
|
8478
|
+
quiet: flags.quiet,
|
|
8479
|
+
recursive: flags.recursive,
|
|
8480
|
+
shouldBypassCache: flags.noCache,
|
|
8481
|
+
shouldBypassLock: flags.noLock,
|
|
8482
|
+
shouldDelegate: flags.delegate,
|
|
8483
|
+
shouldEmitJson: flags.json,
|
|
8484
|
+
shouldPrintLog: flags.log,
|
|
8485
|
+
shouldRunLocally: flags.noDelegate,
|
|
8486
|
+
shouldShowHelp: false,
|
|
8487
|
+
shouldShowVersion: flags.version ?? false,
|
|
8488
|
+
...hasCommand && { command: first },
|
|
8489
|
+
passthrough: hasCommand ? remaining : []
|
|
8490
|
+
};
|
|
8491
|
+
}
|
|
8492
|
+
var HELP_SPELLINGS = /* @__PURE__ */ new Set(["--help", "-h"]);
|
|
8493
|
+
var READER_FLAGS = {
|
|
8494
|
+
...NMR_FLAGS,
|
|
8495
|
+
version: { type: "boolean", description: "Print the version", short: "V" }
|
|
8496
|
+
};
|
|
8497
|
+
function isBooleanCluster(arg) {
|
|
8498
|
+
if (!/^-[^-]./.test(arg)) {
|
|
8499
|
+
return false;
|
|
8500
|
+
}
|
|
8501
|
+
const booleanShorts = /* @__PURE__ */ new Set(["h", "V"]);
|
|
8502
|
+
for (const definition of Object.values(NMR_FLAGS)) {
|
|
8503
|
+
if (definition.type === "boolean" && "short" in definition) {
|
|
8504
|
+
booleanShorts.add(definition.short);
|
|
8505
|
+
}
|
|
8506
|
+
}
|
|
8507
|
+
for (const letter of arg.slice(1)) {
|
|
8508
|
+
if (!booleanShorts.has(letter)) {
|
|
8509
|
+
return false;
|
|
8510
|
+
}
|
|
8511
|
+
}
|
|
8512
|
+
return true;
|
|
8513
|
+
}
|
|
8514
|
+
function removeHelpFlag(args, token) {
|
|
8515
|
+
const index = args.indexOf(token);
|
|
8516
|
+
if (index !== -1) {
|
|
8517
|
+
args.splice(index, 1);
|
|
8518
|
+
return true;
|
|
8519
|
+
}
|
|
8520
|
+
const clusterIndex = args.findIndex((arg) => isBooleanCluster(arg) && arg.includes("h"));
|
|
8521
|
+
const cluster = args[clusterIndex];
|
|
8522
|
+
if (cluster === void 0) {
|
|
8523
|
+
return false;
|
|
8524
|
+
}
|
|
8525
|
+
args[clusterIndex] = cluster.replace("h", "");
|
|
8526
|
+
return true;
|
|
8527
|
+
}
|
|
8528
|
+
|
|
8099
8529
|
// src/steps.ts
|
|
8100
8530
|
var LAUNCHERS = /* @__PURE__ */ new Map([
|
|
8101
8531
|
["bun", /* @__PURE__ */ new Set(["x"])],
|
|
@@ -8191,39 +8621,12 @@ function readNmrTail(segment) {
|
|
|
8191
8621
|
return rest[nmrIndex] === "nmr" ? { launcher: head, launcherArgs: rest.slice(0, nmrIndex), tail: rest.slice(nmrIndex + 1) } : void 0;
|
|
8192
8622
|
}
|
|
8193
8623
|
function readNmrTarget(tokens) {
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
let index = 0;
|
|
8198
|
-
while (index < tokens.length) {
|
|
8199
|
-
const token = tokens[index] ?? "";
|
|
8200
|
-
switch (token) {
|
|
8201
|
-
// The pattern is the flag's value, and reading it as a command name would name whichever package it
|
|
8202
|
-
// selects rather than the command that every selected scope runs.
|
|
8203
|
-
case "-F":
|
|
8204
|
-
case "--filter":
|
|
8205
|
-
isDelegate = true;
|
|
8206
|
-
index += 2;
|
|
8207
|
-
break;
|
|
8208
|
-
case "-R":
|
|
8209
|
-
case "--recursive":
|
|
8210
|
-
isDelegate = true;
|
|
8211
|
-
isRecursive = true;
|
|
8212
|
-
index += 1;
|
|
8213
|
-
break;
|
|
8214
|
-
case "-w":
|
|
8215
|
-
case "--workspace-root":
|
|
8216
|
-
isWorkspaceRoot = true;
|
|
8217
|
-
index += 1;
|
|
8218
|
-
break;
|
|
8219
|
-
default:
|
|
8220
|
-
if (!token.startsWith("-")) {
|
|
8221
|
-
return { command: token, isDelegate, isRecursive, isWorkspaceRoot };
|
|
8222
|
-
}
|
|
8223
|
-
index += 1;
|
|
8224
|
-
}
|
|
8624
|
+
const reading = readInvocationFlags(tokens);
|
|
8625
|
+
if (!reading.ok || reading.parsedArgs.command === void 0) {
|
|
8626
|
+
return void 0;
|
|
8225
8627
|
}
|
|
8226
|
-
|
|
8628
|
+
const { command, filter, isWorkspaceRoot, recursive } = reading.parsedArgs;
|
|
8629
|
+
return { command, isDelegate: filter !== void 0 || recursive, isRecursive: recursive, isWorkspaceRoot };
|
|
8227
8630
|
}
|
|
8228
8631
|
|
|
8229
8632
|
// src/resolver.ts
|
|
@@ -8244,7 +8647,7 @@ function readPackageJsonScripts(packageDir) {
|
|
|
8244
8647
|
const file = resolvePackageJsonPath(packageDir);
|
|
8245
8648
|
let rawText;
|
|
8246
8649
|
try {
|
|
8247
|
-
rawText =
|
|
8650
|
+
rawText = readFileSync3(file, "utf8");
|
|
8248
8651
|
} catch (error) {
|
|
8249
8652
|
if (hasErrnoCode(error, "ENOENT")) {
|
|
8250
8653
|
return void 0;
|
|
@@ -8252,9 +8655,9 @@ function readPackageJsonScripts(packageDir) {
|
|
|
8252
8655
|
throw error;
|
|
8253
8656
|
}
|
|
8254
8657
|
const parsedManifest = parsePackageJson(rawText, file);
|
|
8255
|
-
if (!
|
|
8658
|
+
if (!isRecord2(parsedManifest)) return void 0;
|
|
8256
8659
|
const scripts = parsedManifest["scripts"];
|
|
8257
|
-
if (!
|
|
8660
|
+
if (!isRecord2(scripts)) return void 0;
|
|
8258
8661
|
return readScriptRecord(packageDir, scripts);
|
|
8259
8662
|
}
|
|
8260
8663
|
function buildWorkspaceRegistry(config) {
|
|
@@ -8330,6 +8733,11 @@ function readPackageScripts(packageDir) {
|
|
|
8330
8733
|
}
|
|
8331
8734
|
}
|
|
8332
8735
|
|
|
8736
|
+
// src/helpers/type-guards.ts
|
|
8737
|
+
function isStringRecord(value) {
|
|
8738
|
+
return isRecord2(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
8739
|
+
}
|
|
8740
|
+
|
|
8333
8741
|
// src/verbosity.ts
|
|
8334
8742
|
var COMMAND_VERBOSITIES = ["full", "quiet"];
|
|
8335
8743
|
function formatVerbosityRejection(source, value) {
|
|
@@ -8370,7 +8778,7 @@ function assertRecognizedKeys(value, recognizedKeys, configPath, prefix = "") {
|
|
|
8370
8778
|
);
|
|
8371
8779
|
}
|
|
8372
8780
|
function validateConfig(value, configPath, baseDir) {
|
|
8373
|
-
if (!
|
|
8781
|
+
if (!isRecord2(value)) {
|
|
8374
8782
|
throw new UserError(`Invalid nmr config at ${configPath}: expected an object, got ${typeof value}`);
|
|
8375
8783
|
}
|
|
8376
8784
|
assertRecognizedKeys(value, RECOGNIZED_KEYS, configPath);
|
|
@@ -8426,7 +8834,7 @@ function isOptionalBoolean(value) {
|
|
|
8426
8834
|
return value === void 0 || typeof value === "boolean";
|
|
8427
8835
|
}
|
|
8428
8836
|
function isScriptRecord(value) {
|
|
8429
|
-
if (!
|
|
8837
|
+
if (!isRecord2(value)) return false;
|
|
8430
8838
|
for (const v of Object.values(value)) {
|
|
8431
8839
|
if (typeof v === "string") continue;
|
|
8432
8840
|
if (!Array.isArray(v) || !v.every(isScriptElement)) return false;
|
|
@@ -8435,7 +8843,7 @@ function isScriptRecord(value) {
|
|
|
8435
8843
|
}
|
|
8436
8844
|
function isScriptElement(value) {
|
|
8437
8845
|
if (typeof value === "string") return true;
|
|
8438
|
-
if (!
|
|
8846
|
+
if (!isRecord2(value) || typeof value["run"] !== "string") return false;
|
|
8439
8847
|
return isOptionalBoolean(value["shouldDeclineArguments"]) && isOptionalBoolean(value["shouldRunInBackground"]);
|
|
8440
8848
|
}
|
|
8441
8849
|
function isStringArray(value) {
|
|
@@ -8446,7 +8854,7 @@ function validateBuildField(value, configPath) {
|
|
|
8446
8854
|
if (build === void 0) {
|
|
8447
8855
|
return void 0;
|
|
8448
8856
|
}
|
|
8449
|
-
if (!
|
|
8857
|
+
if (!isRecord2(build)) {
|
|
8450
8858
|
throw new UserError(`Invalid nmr config at ${configPath}: \`build\` must be an object`);
|
|
8451
8859
|
}
|
|
8452
8860
|
assertRecognizedKeys(build, RECOGNIZED_BUILD_KEYS, configPath, "build.");
|
|
@@ -8461,7 +8869,7 @@ function validateCheckCacheField(value, configPath) {
|
|
|
8461
8869
|
if (checkCache === void 0) {
|
|
8462
8870
|
return void 0;
|
|
8463
8871
|
}
|
|
8464
|
-
if (!
|
|
8872
|
+
if (!isRecord2(checkCache)) {
|
|
8465
8873
|
throw new UserError(`Invalid nmr config at ${configPath}: \`checkCache\` must be an object`);
|
|
8466
8874
|
}
|
|
8467
8875
|
assertRecognizedKeys(checkCache, RECOGNIZED_CHECK_CACHE_KEYS, configPath, "checkCache.");
|
|
@@ -8498,7 +8906,7 @@ function validateOutputField(value, configPath) {
|
|
|
8498
8906
|
if (output === void 0) {
|
|
8499
8907
|
return void 0;
|
|
8500
8908
|
}
|
|
8501
|
-
if (!
|
|
8909
|
+
if (!isRecord2(output)) {
|
|
8502
8910
|
throw new UserError(`Invalid nmr config at ${configPath}: \`output\` must be an object`);
|
|
8503
8911
|
}
|
|
8504
8912
|
assertRecognizedKeys(output, RECOGNIZED_OUTPUT_KEYS, configPath, "output.");
|
|
@@ -8527,7 +8935,7 @@ function validateSelfHostedRunnerField(value, configPath) {
|
|
|
8527
8935
|
if (selfHostedRunner === void 0) {
|
|
8528
8936
|
return void 0;
|
|
8529
8937
|
}
|
|
8530
|
-
if (!
|
|
8938
|
+
if (!isRecord2(selfHostedRunner)) {
|
|
8531
8939
|
throw new UserError(`Invalid nmr config at ${configPath}: \`selfHostedRunner\` must be an object`);
|
|
8532
8940
|
}
|
|
8533
8941
|
assertRecognizedKeys(selfHostedRunner, RECOGNIZED_SELF_HOSTED_RUNNER_KEYS, configPath, "selfHostedRunner.");
|
|
@@ -8587,7 +8995,7 @@ async function loadConfig(baseDir) {
|
|
|
8587
8995
|
return {};
|
|
8588
8996
|
}
|
|
8589
8997
|
const importedModule = await import(pathToFileURL(configPath).href);
|
|
8590
|
-
const loadedConfig =
|
|
8998
|
+
const loadedConfig = isRecord2(importedModule) ? importedModule["default"] : void 0;
|
|
8591
8999
|
return validateConfig(loadedConfig, configPath, baseDir);
|
|
8592
9000
|
}
|
|
8593
9001
|
async function loadRootConfig(monorepoRoot) {
|
|
@@ -8638,17 +9046,15 @@ function formatSelfReferenceRemedy(options) {
|
|
|
8638
9046
|
|
|
8639
9047
|
// src/tiers.ts
|
|
8640
9048
|
import { readdirSync as readdirSync2 } from "node:fs";
|
|
8641
|
-
import
|
|
9049
|
+
import path7 from "node:path";
|
|
8642
9050
|
|
|
8643
9051
|
// src/git-ignored-paths.ts
|
|
8644
|
-
import { spawnSync } from "node:child_process";
|
|
8645
9052
|
function listGitIgnoredPaths(dir) {
|
|
8646
|
-
const result =
|
|
8647
|
-
"git",
|
|
9053
|
+
const result = runGit(
|
|
8648
9054
|
["ls-files", "-z", "--others", "--ignored", "--exclude-standard", "--directory", "--no-empty-directory"],
|
|
8649
|
-
|
|
9055
|
+
dir
|
|
8650
9056
|
);
|
|
8651
|
-
if (result.
|
|
9057
|
+
if (!result.ok) return [];
|
|
8652
9058
|
return result.stdout.split("\0").filter((entry) => entry !== "").toSorted();
|
|
8653
9059
|
}
|
|
8654
9060
|
|
|
@@ -8669,7 +9075,7 @@ function findUntieredTestFiles(rootDir, options = {}) {
|
|
|
8669
9075
|
}
|
|
8670
9076
|
function hasTierInfix(filePath) {
|
|
8671
9077
|
const tiers = TIER_NAMES;
|
|
8672
|
-
return tiers.includes(
|
|
9078
|
+
return tiers.includes(path7.basename(filePath).split(".").at(-3) ?? "");
|
|
8673
9079
|
}
|
|
8674
9080
|
var TEST_COLLECTION_EXCLUDE = [".git", "coverage", "dist", "node_modules"];
|
|
8675
9081
|
var TIER_NAMES = ["unit", "tool", "localhost", "remote"];
|
|
@@ -8679,7 +9085,7 @@ function collectTestFiles(dir, relativeDir, isInTestDir, context) {
|
|
|
8679
9085
|
const relativePath = relativeDir === "" ? entry.name : `${relativeDir}/${entry.name}`;
|
|
8680
9086
|
if (entry.isDirectory()) {
|
|
8681
9087
|
if (context.pruned.has(entry.name) || context.ignoredPaths.has(`${relativePath}/`)) continue;
|
|
8682
|
-
collectTestFiles(
|
|
9088
|
+
collectTestFiles(path7.join(dir, entry.name), relativePath, isInTestDir || entry.name === TEST_DIR, context);
|
|
8683
9089
|
} else if (isInTestDir !== context.misplaced && TEST_FILE_PATTERN.test(entry.name) && !context.ignoredPaths.has(relativePath)) {
|
|
8684
9090
|
context.foundPaths.push(relativePath);
|
|
8685
9091
|
}
|
|
@@ -8701,16 +9107,16 @@ var import_yaml2 = __toESM(require_dist(), 1);
|
|
|
8701
9107
|
import { execFile } from "node:child_process";
|
|
8702
9108
|
import { existsSync as existsSync4, readdirSync as readdirSync3 } from "node:fs";
|
|
8703
9109
|
import { join as join3, posix as posix2 } from "node:path";
|
|
8704
|
-
import { isRecord as
|
|
9110
|
+
import { isRecord as isRecord4, readFile as readFile3 } from "readyup/check-utils";
|
|
8705
9111
|
var CODE_QUALITY_WORKFLOW = "williamthorsen/.github/.github/workflows/code-quality-pnpm-workflow.yaml";
|
|
8706
9112
|
var MIN_CODE_QUALITY_MAJOR = 8;
|
|
8707
9113
|
var GH_TIMEOUT_MS = 15e3;
|
|
8708
9114
|
var IMAGE_ABSENT_PROGRAM_PATTERN = /(?:^|[\s;&|(])(corepack|gh|node|npm|npx|pnpm)(?=\s|$)/gm;
|
|
8709
9115
|
var NEVER_INSTALLED_PROGRAMS = /* @__PURE__ */ new Set(["corepack", "gh"]);
|
|
8710
9116
|
function countOnlineSelfHostedRunners(response) {
|
|
8711
|
-
if (!
|
|
9117
|
+
if (!isRecord4(response) || !Array.isArray(response["runners"])) return 0;
|
|
8712
9118
|
return response["runners"].filter(
|
|
8713
|
-
(runner) =>
|
|
9119
|
+
(runner) => isRecord4(runner) && runner["status"] === "online" && Array.isArray(runner["labels"]) && runner["labels"].some((label) => isRecord4(label) && label["name"] === "self-hosted")
|
|
8714
9120
|
).length;
|
|
8715
9121
|
}
|
|
8716
9122
|
function describeGhFailure(result, context) {
|
|
@@ -8737,7 +9143,7 @@ function findCodeQualityCallerDefects(workflows) {
|
|
|
8737
9143
|
);
|
|
8738
9144
|
}
|
|
8739
9145
|
const inputs = job["with"];
|
|
8740
|
-
if (
|
|
9146
|
+
if (isRecord4(inputs) && inputs["runs-on"] !== void 0) {
|
|
8741
9147
|
defects.push(`${file} job ${jobName} passes runs-on, which overrides CI_RUNS_ON`);
|
|
8742
9148
|
}
|
|
8743
9149
|
}
|
|
@@ -8753,7 +9159,7 @@ function findImageIncompatibleSteps(workflows) {
|
|
|
8753
9159
|
if (!Array.isArray(steps)) continue;
|
|
8754
9160
|
const installed = /* @__PURE__ */ new Set();
|
|
8755
9161
|
for (const [index, step] of steps.entries()) {
|
|
8756
|
-
if (!
|
|
9162
|
+
if (!isRecord4(step)) continue;
|
|
8757
9163
|
const stepLabel = typeof step["name"] === "string" ? step["name"] : `step ${index + 1}`;
|
|
8758
9164
|
const run = step["run"];
|
|
8759
9165
|
if (typeof run === "string") {
|
|
@@ -8784,14 +9190,14 @@ async function readOrganizationValue(nameWithOwner, cwd, runGh) {
|
|
|
8784
9190
|
const result = await runGh(["api", `repos/${nameWithOwner}/actions/organization-variables`], cwd);
|
|
8785
9191
|
if (!result.ok) return void 0;
|
|
8786
9192
|
const response = parseJson(result.stdout);
|
|
8787
|
-
if (!
|
|
9193
|
+
if (!isRecord4(response) || !Array.isArray(response["variables"])) return void 0;
|
|
8788
9194
|
const variable = response["variables"].find(
|
|
8789
|
-
(entry) =>
|
|
9195
|
+
(entry) => isRecord4(entry) && entry["name"] === "CI_RUNS_ON"
|
|
8790
9196
|
);
|
|
8791
9197
|
return readVariableValue(variable);
|
|
8792
9198
|
}
|
|
8793
9199
|
function readVariableValue(variable) {
|
|
8794
|
-
return
|
|
9200
|
+
return isRecord4(variable) && typeof variable["value"] === "string" ? variable["value"] : void 0;
|
|
8795
9201
|
}
|
|
8796
9202
|
function readWorkflows(cwd) {
|
|
8797
9203
|
const dir = join3(cwd, ".github", "workflows");
|
|
@@ -8805,9 +9211,9 @@ function readWorkflows(cwd) {
|
|
|
8805
9211
|
} catch {
|
|
8806
9212
|
continue;
|
|
8807
9213
|
}
|
|
8808
|
-
if (!
|
|
9214
|
+
if (!isRecord4(document) || !isRecord4(document["jobs"])) continue;
|
|
8809
9215
|
const jobs = Object.entries(document["jobs"]).filter(
|
|
8810
|
-
(entry) =>
|
|
9216
|
+
(entry) => isRecord4(entry[1])
|
|
8811
9217
|
);
|
|
8812
9218
|
workflows.push({ file: posix2.join(".github/workflows", file), jobs });
|
|
8813
9219
|
}
|
|
@@ -8841,7 +9247,7 @@ function readInstalledPrograms(step) {
|
|
|
8841
9247
|
if (action === "actions/setup-node") return ["node"];
|
|
8842
9248
|
if (action === "pnpm/action-setup") return ["pnpm"];
|
|
8843
9249
|
if (action !== "pnpm/setup") return [];
|
|
8844
|
-
const inputs =
|
|
9250
|
+
const inputs = isRecord4(step["with"]) ? step["with"] : {};
|
|
8845
9251
|
const runtime = inputs["runtime"];
|
|
8846
9252
|
const installsNode = typeof runtime === "string" ? /^node\b/.test(runtime) : String(inputs["node-version-file"]) !== "false";
|
|
8847
9253
|
return installsNode ? ["pnpm", "node"] : ["pnpm"];
|
|
@@ -8919,7 +9325,7 @@ async function readGitHubFacts(cwd, runGh = runGhCommand) {
|
|
|
8919
9325
|
const repo = await runGh(["repo", "view", "--json", "nameWithOwner,visibility"], cwd);
|
|
8920
9326
|
if (!repo.ok) return { skip: describeGhFailure(repo, "cannot resolve this repo on GitHub") };
|
|
8921
9327
|
const repoView = parseJson(repo.stdout);
|
|
8922
|
-
if (!
|
|
9328
|
+
if (!isRecord5(repoView) || typeof repoView["nameWithOwner"] !== "string") {
|
|
8923
9329
|
return { skip: "gh repo view returned an unexpected shape" };
|
|
8924
9330
|
}
|
|
8925
9331
|
const nameWithOwner = repoView["nameWithOwner"];
|
|
@@ -9018,7 +9424,7 @@ import {
|
|
|
9018
9424
|
// .readyup/lib/catalog.ts
|
|
9019
9425
|
import { posix as posix3 } from "node:path";
|
|
9020
9426
|
var import_yaml3 = __toESM(require_dist(), 1);
|
|
9021
|
-
import { isRecord as
|
|
9427
|
+
import { isRecord as isRecord6 } from "readyup/check-utils";
|
|
9022
9428
|
var CATALOGUE_CHECKED_FIELDS = ["dependencies", "devDependencies", "optionalDependencies"];
|
|
9023
9429
|
var PROTOCOL_PATTERN = /^[a-z][a-z0-9+.-]*:/i;
|
|
9024
9430
|
function cataloguedDependenciesUseCatalog() {
|
|
@@ -9036,7 +9442,7 @@ function findLiteralCataloguedSpecifiers(workspace, names) {
|
|
|
9036
9442
|
const manifestPath = posix3.join(workspace.dir, "package.json");
|
|
9037
9443
|
return CATALOGUE_CHECKED_FIELDS.flatMap((field) => {
|
|
9038
9444
|
const declared = workspace.packageJson[field];
|
|
9039
|
-
if (!
|
|
9445
|
+
if (!isRecord6(declared)) return [];
|
|
9040
9446
|
return Object.entries(declared).flatMap(
|
|
9041
9447
|
([name, specifier]) => names.has(name) && typeof specifier === "string" && !PROTOCOL_PATTERN.test(specifier) ? { manifestPath, name, specifier } : []
|
|
9042
9448
|
);
|
|
@@ -9051,14 +9457,14 @@ function readCataloguedNames(cwd) {
|
|
|
9051
9457
|
} catch (error) {
|
|
9052
9458
|
return { ok: false, detail: `cannot parse pnpm-workspace.yaml: ${describeError(error)}` };
|
|
9053
9459
|
}
|
|
9054
|
-
if (!
|
|
9460
|
+
if (!isRecord6(workspaceManifest)) return { ok: true, names: /* @__PURE__ */ new Set() };
|
|
9055
9461
|
const namedCatalogs = workspaceManifest["catalogs"];
|
|
9056
|
-
const catalogs = [workspaceManifest["catalog"], ...
|
|
9057
|
-
return { ok: true, names: new Set(catalogs.filter(
|
|
9462
|
+
const catalogs = [workspaceManifest["catalog"], ...isRecord6(namedCatalogs) ? Object.values(namedCatalogs) : []];
|
|
9463
|
+
return { ok: true, names: new Set(catalogs.filter(isRecord6).flatMap((catalog) => Object.keys(catalog))) };
|
|
9058
9464
|
}
|
|
9059
9465
|
|
|
9060
9466
|
// .readyup/lib/manifest-fields.ts
|
|
9061
|
-
import { isRecord as
|
|
9467
|
+
import { isRecord as isRecord7 } from "readyup/check-utils";
|
|
9062
9468
|
function noPnpmFieldInPackageJson(cwd = process.cwd()) {
|
|
9063
9469
|
const declaringFiles = findFiles(["**/package.json"], cwd).flatMap((relativePath) => {
|
|
9064
9470
|
const keys = readPnpmFieldKeys(readFileIn(cwd, relativePath));
|
|
@@ -9079,7 +9485,7 @@ function declaresWorkspacesField(content) {
|
|
|
9079
9485
|
if (content === void 0) return false;
|
|
9080
9486
|
try {
|
|
9081
9487
|
const parsedManifest = JSON.parse(content);
|
|
9082
|
-
return
|
|
9488
|
+
return isRecord7(parsedManifest) && "workspaces" in parsedManifest;
|
|
9083
9489
|
} catch {
|
|
9084
9490
|
return false;
|
|
9085
9491
|
}
|
|
@@ -9092,9 +9498,9 @@ function readPnpmFieldKeys(content) {
|
|
|
9092
9498
|
} catch {
|
|
9093
9499
|
return void 0;
|
|
9094
9500
|
}
|
|
9095
|
-
if (!
|
|
9501
|
+
if (!isRecord7(parsedManifest)) return void 0;
|
|
9096
9502
|
const pnpm = parsedManifest["pnpm"];
|
|
9097
|
-
return
|
|
9503
|
+
return isRecord7(pnpm) ? Object.keys(pnpm).toSorted() : void 0;
|
|
9098
9504
|
}
|
|
9099
9505
|
|
|
9100
9506
|
// .readyup/lib/setup.ts
|
|
@@ -9205,7 +9611,7 @@ function hasSupportedStrictLintVersion() {
|
|
|
9205
9611
|
});
|
|
9206
9612
|
}
|
|
9207
9613
|
function getMinVersion() {
|
|
9208
|
-
const pickedFields = { "version": "0.
|
|
9614
|
+
const pickedFields = { "version": "1.0.0" };
|
|
9209
9615
|
if (typeof pickedFields["version"] !== "string") {
|
|
9210
9616
|
throw new TypeError("nmr/package.json: 'version' must be a string");
|
|
9211
9617
|
}
|
|
@@ -9221,7 +9627,7 @@ function toolVersionsHasNoPnpm() {
|
|
|
9221
9627
|
}
|
|
9222
9628
|
|
|
9223
9629
|
// .readyup/lib/shared-configs.ts
|
|
9224
|
-
import { isRecord as
|
|
9630
|
+
import { isRecord as isRecord8 } from "readyup/check-utils";
|
|
9225
9631
|
var SHARED_PRETTIER_MODULE = "@williamthorsen/nmr/prettier";
|
|
9226
9632
|
var INERT_PRETTIER_CONFIGS = [".prettierrc", ".prettierrc.{json,json5,yaml,yml,toml}"];
|
|
9227
9633
|
var SHARED_TAZE_MODULE = "@williamthorsen/nmr/taze";
|
|
@@ -9315,7 +9721,7 @@ function hasPrettierConfigKey(cwd) {
|
|
|
9315
9721
|
if (manifest === void 0) return false;
|
|
9316
9722
|
try {
|
|
9317
9723
|
const parsedManifest = JSON.parse(manifest);
|
|
9318
|
-
return
|
|
9724
|
+
return isRecord8(parsedManifest) && parsedManifest["prettier"] !== void 0;
|
|
9319
9725
|
} catch {
|
|
9320
9726
|
return false;
|
|
9321
9727
|
}
|
|
@@ -9404,8 +9810,8 @@ function everyViteConfigHasVitestConfig() {
|
|
|
9404
9810
|
return { ok: false, detail: formatPaths(unpairedConfigs) };
|
|
9405
9811
|
}
|
|
9406
9812
|
function noReExportOnlyVitestConfigs(cwd = process.cwd()) {
|
|
9407
|
-
const nonRootConfigs = findFiles([`**/${VITEST_CONFIG_PATTERN}`], cwd).filter((
|
|
9408
|
-
const reExports = nonRootConfigs.filter((
|
|
9813
|
+
const nonRootConfigs = findFiles([`**/${VITEST_CONFIG_PATTERN}`], cwd).filter((path9) => path9.includes("/"));
|
|
9814
|
+
const reExports = nonRootConfigs.filter((path9) => isOwnedByReExportCheck(cwd, path9));
|
|
9409
9815
|
if (reExports.length === 0) return true;
|
|
9410
9816
|
return { ok: false, detail: formatPaths(reExports) };
|
|
9411
9817
|
}
|
|
@@ -9480,14 +9886,108 @@ function isReExportOnly(content) {
|
|
|
9480
9886
|
import { existsSync as existsSync5, readdirSync as readdirSync4 } from "node:fs";
|
|
9481
9887
|
import { join as join5 } from "node:path";
|
|
9482
9888
|
import { fileExists as fileExists3, readFile as readFile5 } from "readyup/check-utils";
|
|
9889
|
+
|
|
9890
|
+
// src/commands/ensure-prepublish-hooks.ts
|
|
9891
|
+
import { readFileSync as readFileSync4, writeFileSync } from "node:fs";
|
|
9892
|
+
import path8 from "node:path";
|
|
9893
|
+
var DEFAULT_HOOK = "nmr build";
|
|
9894
|
+
function ensurePrepublishHooks(monorepoRoot, options) {
|
|
9895
|
+
const hookCommand = options.command ?? DEFAULT_HOOK;
|
|
9896
|
+
const packageDirs = getWorkspacePackageDirs(monorepoRoot);
|
|
9897
|
+
const packages = [];
|
|
9898
|
+
for (const packageDir of packageDirs) {
|
|
9899
|
+
const packageJson = readPackageJson2(packageDir);
|
|
9900
|
+
const packageName = packageJson.name ?? path8.basename(packageDir);
|
|
9901
|
+
const isPrivate = packageJson.private === true;
|
|
9902
|
+
if (isPrivate) {
|
|
9903
|
+
packages.push({
|
|
9904
|
+
packageName,
|
|
9905
|
+
packageDir,
|
|
9906
|
+
isPrivate: true,
|
|
9907
|
+
prepublishOnly: packageJson.scripts?.["prepublishOnly"],
|
|
9908
|
+
action: "ok"
|
|
9909
|
+
});
|
|
9910
|
+
continue;
|
|
9911
|
+
}
|
|
9912
|
+
const existingHook = packageJson.scripts?.["prepublishOnly"];
|
|
9913
|
+
if (existingHook) {
|
|
9914
|
+
packages.push({
|
|
9915
|
+
packageName,
|
|
9916
|
+
packageDir,
|
|
9917
|
+
isPrivate: false,
|
|
9918
|
+
prepublishOnly: existingHook,
|
|
9919
|
+
action: "ok"
|
|
9920
|
+
});
|
|
9921
|
+
continue;
|
|
9922
|
+
}
|
|
9923
|
+
if (options.shouldFix) {
|
|
9924
|
+
const action = options.isDryRun ? "would-fix" : "fixed";
|
|
9925
|
+
if (!options.isDryRun) {
|
|
9926
|
+
addPrepublishOnly(packageDir, hookCommand);
|
|
9927
|
+
}
|
|
9928
|
+
packages.push({
|
|
9929
|
+
packageName,
|
|
9930
|
+
packageDir,
|
|
9931
|
+
isPrivate: false,
|
|
9932
|
+
prepublishOnly: void 0,
|
|
9933
|
+
action
|
|
9934
|
+
});
|
|
9935
|
+
} else {
|
|
9936
|
+
packages.push({
|
|
9937
|
+
packageName,
|
|
9938
|
+
packageDir,
|
|
9939
|
+
isPrivate: false,
|
|
9940
|
+
prepublishOnly: void 0,
|
|
9941
|
+
action: "missing"
|
|
9942
|
+
});
|
|
9943
|
+
}
|
|
9944
|
+
}
|
|
9945
|
+
const hasFailures = packages.some((p) => p.action === "missing");
|
|
9946
|
+
return { packages, hasFailures };
|
|
9947
|
+
}
|
|
9948
|
+
function addPrepublishOnly(packageDir, command) {
|
|
9949
|
+
const filePath = path8.join(packageDir, "package.json");
|
|
9950
|
+
const rawText = readFileSync4(filePath, "utf8");
|
|
9951
|
+
let parsedManifest;
|
|
9952
|
+
try {
|
|
9953
|
+
parsedManifest = JSON.parse(rawText);
|
|
9954
|
+
} catch (error) {
|
|
9955
|
+
throw new UserError(`Invalid package.json in ${packageDir}: ${describeError(error)}`, { cause: error });
|
|
9956
|
+
}
|
|
9957
|
+
if (!isRecord2(parsedManifest)) {
|
|
9958
|
+
throw new UserError(`Invalid package.json in ${packageDir}: expected an object`);
|
|
9959
|
+
}
|
|
9960
|
+
const scripts = isRecord2(parsedManifest["scripts"]) ? parsedManifest["scripts"] : {};
|
|
9961
|
+
scripts["prepublishOnly"] = command;
|
|
9962
|
+
parsedManifest["scripts"] = scripts;
|
|
9963
|
+
writeFileSync(filePath, JSON.stringify(parsedManifest, null, 2) + "\n", "utf8");
|
|
9964
|
+
}
|
|
9965
|
+
|
|
9966
|
+
// .readyup/lib/workspace-build.ts
|
|
9483
9967
|
var buildReadinessChecks = [
|
|
9484
9968
|
{
|
|
9485
9969
|
name: "all workspace packages can build",
|
|
9486
9970
|
severity: "warn",
|
|
9487
9971
|
check: allWorkspacePackagesCanBuild,
|
|
9488
9972
|
fix: `Add "build": ":" to packages that don't need a build, or ensure packages that use the default nmr build have a tsconfig.json and a src/ directory`
|
|
9973
|
+
},
|
|
9974
|
+
{
|
|
9975
|
+
name: "every publishable package declares prepublishOnly",
|
|
9976
|
+
severity: "warn",
|
|
9977
|
+
check: everyPublishablePackageDeclaresPrepublishOnly,
|
|
9978
|
+
fix: 'Add "prepublishOnly": "nmr build" to the scripts of each listed package, or run ensure-prepublish-hooks --fix. A package without it publishes without its build output'
|
|
9489
9979
|
}
|
|
9490
9980
|
];
|
|
9981
|
+
function everyPublishablePackageDeclaresPrepublishOnly() {
|
|
9982
|
+
try {
|
|
9983
|
+
const { packages } = ensurePrepublishHooks(process.cwd(), { shouldFix: false, isDryRun: false });
|
|
9984
|
+
const offenders = packages.filter((packageStatus) => packageStatus.action === "missing").map((packageStatus) => packageStatus.packageName);
|
|
9985
|
+
if (offenders.length === 0) return true;
|
|
9986
|
+
return { ok: false, detail: formatPaths(offenders) };
|
|
9987
|
+
} catch (error) {
|
|
9988
|
+
return { ok: false, detail: describeError(error) };
|
|
9989
|
+
}
|
|
9990
|
+
}
|
|
9491
9991
|
function allWorkspacePackagesCanBuild() {
|
|
9492
9992
|
const packagesDir = join5(process.cwd(), "packages");
|
|
9493
9993
|
if (!existsSync5(packagesDir)) return true;
|