politty 0.4.8 → 0.4.10
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/completion-BADAzqT9.cjs.map +1 -1
- package/dist/completion-Dj7ytbLu.js.map +1 -1
- package/dist/docs/index.cjs +63 -5
- package/dist/docs/index.cjs.map +1 -1
- package/dist/docs/index.d.cts +1 -1
- package/dist/docs/index.d.cts.map +1 -1
- package/dist/docs/index.d.ts +1 -1
- package/dist/docs/index.d.ts.map +1 -1
- package/dist/docs/index.js +63 -5
- package/dist/docs/index.js.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.d.cts +97 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +97 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{runner-BQcd2UEj.js → runner-BnBUkTvG.js} +112 -11
- package/dist/runner-BnBUkTvG.js.map +1 -0
- package/dist/{runner-nKNXknDl.cjs → runner-DXmgHXNR.cjs} +134 -9
- package/dist/runner-DXmgHXNR.cjs.map +1 -0
- package/package.json +3 -3
- package/dist/runner-BQcd2UEj.js.map +0 -1
- package/dist/runner-nKNXknDl.cjs.map +0 -1
|
@@ -5,6 +5,42 @@ let node_util = require("node:util");
|
|
|
5
5
|
let string_width = require("string-width");
|
|
6
6
|
string_width = require_subcommand_router.__toESM(string_width);
|
|
7
7
|
|
|
8
|
+
//#region src/core/case-proxy.ts
|
|
9
|
+
/**
|
|
10
|
+
* Wrap an args object with a Proxy that allows dual-case access.
|
|
11
|
+
*
|
|
12
|
+
* Given `{ "my-option": "value" }`, both `obj["my-option"]` and `obj.myOption`
|
|
13
|
+
* will return `"value"`.
|
|
14
|
+
*
|
|
15
|
+
* - `Object.keys()`, `JSON.stringify()`, and spread return only the original keys.
|
|
16
|
+
* - The `in` operator detects both case variants.
|
|
17
|
+
*/
|
|
18
|
+
function createDualCaseProxy(obj) {
|
|
19
|
+
return new Proxy(obj, {
|
|
20
|
+
get(target, prop, receiver) {
|
|
21
|
+
if (typeof prop === "string") {
|
|
22
|
+
if (prop in target) return Reflect.get(target, prop, receiver);
|
|
23
|
+
const camel = require_lazy.toCamelCase(prop);
|
|
24
|
+
if (camel !== prop && camel in target) return Reflect.get(target, camel, receiver);
|
|
25
|
+
const kebab = require_lazy.toKebabCase(prop);
|
|
26
|
+
if (kebab !== prop && kebab in target) return Reflect.get(target, kebab, receiver);
|
|
27
|
+
}
|
|
28
|
+
return Reflect.get(target, prop, receiver);
|
|
29
|
+
},
|
|
30
|
+
has(target, prop) {
|
|
31
|
+
if (typeof prop === "string") {
|
|
32
|
+
if (prop in target) return true;
|
|
33
|
+
const camel = require_lazy.toCamelCase(prop);
|
|
34
|
+
if (camel !== prop && camel in target) return true;
|
|
35
|
+
const kebab = require_lazy.toKebabCase(prop);
|
|
36
|
+
if (kebab !== prop && kebab in target) return true;
|
|
37
|
+
}
|
|
38
|
+
return Reflect.has(target, prop);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
8
44
|
//#region src/executor/command-runner.ts
|
|
9
45
|
/**
|
|
10
46
|
* Execute a command lifecycle: setup → run → cleanup
|
|
@@ -906,6 +942,15 @@ var DuplicateAliasError = class extends Error {
|
|
|
906
942
|
this.name = "DuplicateAliasError";
|
|
907
943
|
}
|
|
908
944
|
};
|
|
945
|
+
/**
|
|
946
|
+
* Error thrown when fields are case variants of each other (e.g. "my-option" and "myOption")
|
|
947
|
+
*/
|
|
948
|
+
var CaseVariantCollisionError = class extends Error {
|
|
949
|
+
constructor(message) {
|
|
950
|
+
super(message);
|
|
951
|
+
this.name = "CaseVariantCollisionError";
|
|
952
|
+
}
|
|
953
|
+
};
|
|
909
954
|
|
|
910
955
|
//#endregion
|
|
911
956
|
//#region src/validator/command-validator.ts
|
|
@@ -927,6 +972,25 @@ function checkDuplicateFields(extracted, commandPath) {
|
|
|
927
972
|
return errors;
|
|
928
973
|
}
|
|
929
974
|
/**
|
|
975
|
+
* Check for case-variant collisions (e.g. "my-option" and "myOption" defined simultaneously)
|
|
976
|
+
*/
|
|
977
|
+
function checkCaseVariantCollisions(extracted, commandPath) {
|
|
978
|
+
const errors = [];
|
|
979
|
+
const canonicalMap = /* @__PURE__ */ new Map();
|
|
980
|
+
for (const field of extracted.fields) {
|
|
981
|
+
const camel = require_lazy.toCamelCase(field.name);
|
|
982
|
+
const existing = canonicalMap.get(camel);
|
|
983
|
+
if (existing && existing !== field.name) errors.push({
|
|
984
|
+
commandPath,
|
|
985
|
+
type: "case_variant_collision",
|
|
986
|
+
message: `Fields "${existing}" and "${field.name}" are case variants of each other and would collide.`,
|
|
987
|
+
field: field.name
|
|
988
|
+
});
|
|
989
|
+
canonicalMap.set(camel, field.name);
|
|
990
|
+
}
|
|
991
|
+
return errors;
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
930
994
|
* Check for duplicate aliases and alias-field name conflicts
|
|
931
995
|
*/
|
|
932
996
|
function checkDuplicateAliases(extracted, commandPath) {
|
|
@@ -1063,11 +1127,42 @@ function validateReservedAliases(extracted, _hasSubCommands) {
|
|
|
1063
1127
|
}
|
|
1064
1128
|
}
|
|
1065
1129
|
/**
|
|
1130
|
+
* Validate that no case-variant collisions exist
|
|
1131
|
+
*
|
|
1132
|
+
* @param extracted - Extracted fields from schema
|
|
1133
|
+
* @throws {CaseVariantCollisionError} If case-variant collisions are found
|
|
1134
|
+
*/
|
|
1135
|
+
function validateCaseVariantCollisions(extracted) {
|
|
1136
|
+
const errors = checkCaseVariantCollisions(extracted, []);
|
|
1137
|
+
if (errors.length > 0) {
|
|
1138
|
+
const err = errors[0];
|
|
1139
|
+
throw new CaseVariantCollisionError(err.message);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Validate that no case-variant collisions exist between two schemas
|
|
1144
|
+
* (e.g., global args and command args).
|
|
1145
|
+
*
|
|
1146
|
+
* @param extractedA - Extracted fields from first schema (e.g., global args)
|
|
1147
|
+
* @param extractedB - Extracted fields from second schema (e.g., command args)
|
|
1148
|
+
* @throws {CaseVariantCollisionError} If cross-schema case-variant collisions are found
|
|
1149
|
+
*/
|
|
1150
|
+
function validateCrossSchemaCollisions(extractedA, extractedB) {
|
|
1151
|
+
const canonicalMap = /* @__PURE__ */ new Map();
|
|
1152
|
+
for (const field of extractedA.fields) canonicalMap.set(require_lazy.toCamelCase(field.name), field.name);
|
|
1153
|
+
for (const field of extractedB.fields) {
|
|
1154
|
+
const camel = require_lazy.toCamelCase(field.name);
|
|
1155
|
+
const existing = canonicalMap.get(camel);
|
|
1156
|
+
if (existing && existing !== field.name) throw new CaseVariantCollisionError(`Global field "${existing}" and command field "${field.name}" are case variants of each other and would collide.`);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
/**
|
|
1066
1160
|
* Collect validation errors for a single command's schema (non-throwing)
|
|
1067
1161
|
*/
|
|
1068
1162
|
function collectSchemaErrors(extracted, _hasSubCommands, commandPath) {
|
|
1069
1163
|
return [
|
|
1070
1164
|
...checkDuplicateFields(extracted, commandPath),
|
|
1165
|
+
...checkCaseVariantCollisions(extracted, commandPath),
|
|
1071
1166
|
...checkDuplicateAliases(extracted, commandPath),
|
|
1072
1167
|
...checkPositionalConfig(extracted, commandPath),
|
|
1073
1168
|
...checkReservedAliases(extracted, commandPath)
|
|
@@ -1499,9 +1594,11 @@ function parseArgs(argv, command, options = {}) {
|
|
|
1499
1594
|
extracted = require_lazy.extractFields(command.args);
|
|
1500
1595
|
if (!options.skipValidation) {
|
|
1501
1596
|
validateDuplicateFields(extracted);
|
|
1597
|
+
validateCaseVariantCollisions(extracted);
|
|
1502
1598
|
validateDuplicateAliases(extracted);
|
|
1503
1599
|
validatePositionalConfig(extracted);
|
|
1504
1600
|
validateReservedAliases(extracted, hasSubCommands);
|
|
1601
|
+
if (options.globalExtracted) validateCrossSchemaCollisions(options.globalExtracted, extracted);
|
|
1505
1602
|
}
|
|
1506
1603
|
}
|
|
1507
1604
|
const hasUserDefinedH = extracted?.fields.some((f) => f.alias === "H" && f.overrideBuiltinAlias === true) ?? false;
|
|
@@ -2086,9 +2183,10 @@ async function runCommandInternal(command, argv, options = {}) {
|
|
|
2086
2183
|
validatedGlobalArgs = globalValidation.data;
|
|
2087
2184
|
}
|
|
2088
2185
|
if (!command.args) {
|
|
2089
|
-
|
|
2186
|
+
const proxiedGlobalArgs = createDualCaseProxy(validatedGlobalArgs);
|
|
2187
|
+
if (options._globalExtracted) await runEffects(proxiedGlobalArgs, options._globalExtracted, proxiedGlobalArgs);
|
|
2090
2188
|
collector?.stop();
|
|
2091
|
-
return await executeLifecycle(command,
|
|
2189
|
+
return await executeLifecycle(command, proxiedGlobalArgs, {
|
|
2092
2190
|
handleSignals: options.handleSignals,
|
|
2093
2191
|
captureLogs: options.captureLogs,
|
|
2094
2192
|
existingLogs: getCurrentLogs(),
|
|
@@ -2106,12 +2204,14 @@ async function runCommandInternal(command, argv, options = {}) {
|
|
|
2106
2204
|
logs: getCurrentLogs()
|
|
2107
2205
|
};
|
|
2108
2206
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2207
|
+
const proxiedCommandArgs = createDualCaseProxy(validationResult.data);
|
|
2208
|
+
const proxiedGlobalArgs = createDualCaseProxy(validatedGlobalArgs);
|
|
2209
|
+
if (options._globalExtracted) await runEffects(proxiedGlobalArgs, options._globalExtracted, proxiedGlobalArgs);
|
|
2210
|
+
if (parseResult.extractedFields) await runEffects(proxiedCommandArgs, parseResult.extractedFields, proxiedGlobalArgs);
|
|
2211
|
+
const mergedArgs = createDualCaseProxy({
|
|
2212
|
+
...proxiedGlobalArgs,
|
|
2213
|
+
...proxiedCommandArgs
|
|
2214
|
+
});
|
|
2115
2215
|
collector?.stop();
|
|
2116
2216
|
return await executeLifecycle(command, mergedArgs, {
|
|
2117
2217
|
handleSignals: options.handleSignals,
|
|
@@ -2141,6 +2241,7 @@ function extractAndValidateGlobal(options) {
|
|
|
2141
2241
|
const extracted = require_lazy.extractFields(options.globalArgs);
|
|
2142
2242
|
if (!options.skipValidation) {
|
|
2143
2243
|
validateDuplicateFields(extracted);
|
|
2244
|
+
validateCaseVariantCollisions(extracted);
|
|
2144
2245
|
validateDuplicateAliases(extracted);
|
|
2145
2246
|
validateReservedAliases(extracted, true);
|
|
2146
2247
|
const positionalNames = extracted.fields.filter((f) => f.positional).map((f) => f.name);
|
|
@@ -2150,6 +2251,12 @@ function extractAndValidateGlobal(options) {
|
|
|
2150
2251
|
}
|
|
2151
2252
|
|
|
2152
2253
|
//#endregion
|
|
2254
|
+
Object.defineProperty(exports, 'CaseVariantCollisionError', {
|
|
2255
|
+
enumerable: true,
|
|
2256
|
+
get: function () {
|
|
2257
|
+
return CaseVariantCollisionError;
|
|
2258
|
+
}
|
|
2259
|
+
});
|
|
2153
2260
|
Object.defineProperty(exports, 'DuplicateAliasError', {
|
|
2154
2261
|
enumerable: true,
|
|
2155
2262
|
get: function () {
|
|
@@ -2174,6 +2281,12 @@ Object.defineProperty(exports, 'ReservedAliasError', {
|
|
|
2174
2281
|
return ReservedAliasError;
|
|
2175
2282
|
}
|
|
2176
2283
|
});
|
|
2284
|
+
Object.defineProperty(exports, 'createDualCaseProxy', {
|
|
2285
|
+
enumerable: true,
|
|
2286
|
+
get: function () {
|
|
2287
|
+
return createDualCaseProxy;
|
|
2288
|
+
}
|
|
2289
|
+
});
|
|
2177
2290
|
Object.defineProperty(exports, 'formatCommandValidationErrors', {
|
|
2178
2291
|
enumerable: true,
|
|
2179
2292
|
get: function () {
|
|
@@ -2258,12 +2371,24 @@ Object.defineProperty(exports, 'symbols', {
|
|
|
2258
2371
|
return symbols;
|
|
2259
2372
|
}
|
|
2260
2373
|
});
|
|
2374
|
+
Object.defineProperty(exports, 'validateCaseVariantCollisions', {
|
|
2375
|
+
enumerable: true,
|
|
2376
|
+
get: function () {
|
|
2377
|
+
return validateCaseVariantCollisions;
|
|
2378
|
+
}
|
|
2379
|
+
});
|
|
2261
2380
|
Object.defineProperty(exports, 'validateCommand', {
|
|
2262
2381
|
enumerable: true,
|
|
2263
2382
|
get: function () {
|
|
2264
2383
|
return validateCommand;
|
|
2265
2384
|
}
|
|
2266
2385
|
});
|
|
2386
|
+
Object.defineProperty(exports, 'validateCrossSchemaCollisions', {
|
|
2387
|
+
enumerable: true,
|
|
2388
|
+
get: function () {
|
|
2389
|
+
return validateCrossSchemaCollisions;
|
|
2390
|
+
}
|
|
2391
|
+
});
|
|
2267
2392
|
Object.defineProperty(exports, 'validateDuplicateAliases', {
|
|
2268
2393
|
enumerable: true,
|
|
2269
2394
|
get: function () {
|
|
@@ -2288,4 +2413,4 @@ Object.defineProperty(exports, 'validateReservedAliases', {
|
|
|
2288
2413
|
return validateReservedAliases;
|
|
2289
2414
|
}
|
|
2290
2415
|
});
|
|
2291
|
-
//# sourceMappingURL=runner-
|
|
2416
|
+
//# sourceMappingURL=runner-DXmgHXNR.cjs.map
|