zinkee 0.1.11 → 0.1.12

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.js CHANGED
@@ -732,6 +732,197 @@ var commandRegistry = {
732
732
  }
733
733
  };
734
734
 
735
+ // src/utils/argv-rewrite.ts
736
+ var HOISTABLE_GLOBAL_FLAGS = {
737
+ "--profile": "value",
738
+ "--base-url": "value",
739
+ "--api-key": "value",
740
+ "--read-only": "boolean",
741
+ "--json": "boolean"
742
+ };
743
+ function isHoistableFlag(flagName) {
744
+ return Object.hasOwn(HOISTABLE_GLOBAL_FLAGS, flagName);
745
+ }
746
+ function getCommandPath(command) {
747
+ const parts = [];
748
+ let cursor = command;
749
+ while (cursor && cursor.parent) {
750
+ parts.unshift(cursor.name());
751
+ cursor = cursor.parent;
752
+ }
753
+ return parts.join(" ");
754
+ }
755
+ function buildOptionMetadata(program) {
756
+ const valueFlags = /* @__PURE__ */ new Set();
757
+ const booleanFlags = /* @__PURE__ */ new Set();
758
+ const localOptionsByCommand = /* @__PURE__ */ new Map();
759
+ function visit(command, isRoot) {
760
+ const localFlags = /* @__PURE__ */ new Set();
761
+ for (const option of command.options) {
762
+ if (!option.long) continue;
763
+ if (option.required || option.optional) {
764
+ valueFlags.add(option.long);
765
+ } else {
766
+ booleanFlags.add(option.long);
767
+ }
768
+ if (!isRoot) {
769
+ localFlags.add(option.long);
770
+ }
771
+ }
772
+ if (!isRoot) {
773
+ localOptionsByCommand.set(getCommandPath(command), localFlags);
774
+ }
775
+ for (const sub of command.commands) {
776
+ visit(sub, false);
777
+ }
778
+ }
779
+ visit(program, true);
780
+ return { valueFlags, booleanFlags, localOptionsByCommand };
781
+ }
782
+ function createDefaultOptionMetadata() {
783
+ return {
784
+ valueFlags: /* @__PURE__ */ new Set([
785
+ "--profile",
786
+ "--base-url",
787
+ "--api-key",
788
+ "--install-completion",
789
+ "--show-completion"
790
+ ]),
791
+ booleanFlags: /* @__PURE__ */ new Set([
792
+ "--read-only",
793
+ "--json",
794
+ "--example",
795
+ "--help"
796
+ ]),
797
+ localOptionsByCommand: /* @__PURE__ */ new Map()
798
+ };
799
+ }
800
+ function isFlagToken(token) {
801
+ return token.length > 1 && token.startsWith("-");
802
+ }
803
+ function splitFlagToken(token) {
804
+ if (token.startsWith("--") && token.includes("=")) {
805
+ const eqIdx = token.indexOf("=");
806
+ return {
807
+ flagName: token.slice(0, eqIdx),
808
+ inlineValue: token.slice(eqIdx + 1)
809
+ };
810
+ }
811
+ return { flagName: token, inlineValue: void 0 };
812
+ }
813
+ function flagConsumesValue(flagName, optionMeta) {
814
+ if (optionMeta.valueFlags.has(flagName)) {
815
+ return true;
816
+ }
817
+ if (optionMeta.booleanFlags.has(flagName)) {
818
+ return false;
819
+ }
820
+ return true;
821
+ }
822
+ function collectOperandTokens(userArgs, optionMeta, options = {}) {
823
+ const operands = [];
824
+ let i = 0;
825
+ while (i < userArgs.length) {
826
+ const token = userArgs[i];
827
+ if (token === "--") {
828
+ break;
829
+ }
830
+ if (isFlagToken(token)) {
831
+ const { flagName, inlineValue } = splitFlagToken(token);
832
+ if (options.skipFlag !== void 0 && flagName === options.skipFlag) {
833
+ i += 1;
834
+ continue;
835
+ }
836
+ if (inlineValue !== void 0) {
837
+ i += 1;
838
+ continue;
839
+ }
840
+ const consumes = flagConsumesValue(flagName, optionMeta);
841
+ const next = userArgs[i + 1];
842
+ if (consumes && next !== void 0 && !isFlagToken(next)) {
843
+ i += 2;
844
+ } else {
845
+ i += 1;
846
+ }
847
+ continue;
848
+ }
849
+ operands.push({ index: i, token });
850
+ i += 1;
851
+ }
852
+ return operands;
853
+ }
854
+ function findCommandPath(operands, registry) {
855
+ if (operands.length === 0) return null;
856
+ const commandsByLength = Object.keys(registry).sort(
857
+ (left, right) => right.split(" ").length - left.split(" ").length
858
+ );
859
+ for (let start = 0; start < operands.length; start += 1) {
860
+ for (const commandName of commandsByLength) {
861
+ const parts = commandName.split(" ");
862
+ if (start + parts.length > operands.length) continue;
863
+ let matches = true;
864
+ for (let j = 0; j < parts.length; j += 1) {
865
+ if (operands[start + j].token !== parts[j]) {
866
+ matches = false;
867
+ break;
868
+ }
869
+ }
870
+ if (matches) {
871
+ return {
872
+ commandName,
873
+ firstArgvIndex: operands[start].index,
874
+ lastArgvIndex: operands[start + parts.length - 1].index
875
+ };
876
+ }
877
+ }
878
+ }
879
+ return null;
880
+ }
881
+ function hoistGlobalOptions(argv, optionMeta, registry) {
882
+ if (argv.length < 3) return [...argv];
883
+ const userArgs = argv.slice(2);
884
+ const operands = collectOperandTokens(userArgs, optionMeta);
885
+ const cmdPath = findCommandPath(operands, registry);
886
+ if (!cmdPath) return [...argv];
887
+ const localOptions = optionMeta.localOptionsByCommand.get(cmdPath.commandName) ?? /* @__PURE__ */ new Set();
888
+ const hoisted = [];
889
+ const remaining = [];
890
+ let i = 0;
891
+ while (i < userArgs.length) {
892
+ const token = userArgs[i];
893
+ if (token === "--") {
894
+ remaining.push(...userArgs.slice(i));
895
+ break;
896
+ }
897
+ if (!isFlagToken(token)) {
898
+ remaining.push(token);
899
+ i += 1;
900
+ continue;
901
+ }
902
+ const { flagName, inlineValue } = splitFlagToken(token);
903
+ if (!isHoistableFlag(flagName)) {
904
+ remaining.push(token);
905
+ i += 1;
906
+ continue;
907
+ }
908
+ const isAfterCommandPath = i > cmdPath.lastArgvIndex;
909
+ const collidesWithLocal = localOptions.has(flagName);
910
+ const target = isAfterCommandPath && collidesWithLocal ? remaining : hoisted;
911
+ target.push(token);
912
+ const spec = HOISTABLE_GLOBAL_FLAGS[flagName];
913
+ if (spec === "value" && inlineValue === void 0) {
914
+ const next = userArgs[i + 1];
915
+ if (next !== void 0 && !isFlagToken(next)) {
916
+ target.push(next);
917
+ i += 2;
918
+ continue;
919
+ }
920
+ }
921
+ i += 1;
922
+ }
923
+ return [argv[0], argv[1], ...hoisted, ...remaining];
924
+ }
925
+
735
926
  // src/client.ts
736
927
  var ApiClientError = class extends Error {
737
928
  name = "ApiClientError";
@@ -6392,26 +6583,6 @@ async function getResolvedCommandExamples(commandName, filters = {}, options = {
6392
6583
  function getStdout(stdout) {
6393
6584
  return stdout ?? process.stdout;
6394
6585
  }
6395
- function resolveExampleCommand(tokens) {
6396
- const commands = Object.keys(commandRegistry).sort(
6397
- (left, right) => right.split(" ").length - left.split(" ").length
6398
- );
6399
- for (const commandName of commands) {
6400
- const commandTokens2 = commandName.split(" ");
6401
- const matches = commandTokens2.every((token, index) => tokens[index] === token);
6402
- if (matches) {
6403
- return {
6404
- commandName,
6405
- remainingTokens: tokens.slice(commandTokens2.length)
6406
- };
6407
- }
6408
- }
6409
- const commandTokens = tokens.filter((token) => !token.startsWith("-"));
6410
- return {
6411
- commandName: commandTokens.join(" "),
6412
- remainingTokens: []
6413
- };
6414
- }
6415
6586
  function extractExampleFilters(tokens) {
6416
6587
  const filters = {};
6417
6588
  for (let index = 0; index < tokens.length; index += 1) {
@@ -6451,18 +6622,19 @@ function extractExampleOverrides(tokens) {
6451
6622
  }
6452
6623
  return overrides;
6453
6624
  }
6454
- function extractExampleRequest(argv) {
6455
- const exampleIndex = argv.indexOf("--example");
6456
- if (exampleIndex === -1) {
6625
+ function extractExampleRequest(argv, optionMeta = createDefaultOptionMetadata()) {
6626
+ if (!argv.includes("--example")) {
6457
6627
  return null;
6458
6628
  }
6459
- const requestTokens = argv.slice(exampleIndex + 1);
6460
- const { commandName, remainingTokens } = resolveExampleCommand(requestTokens);
6461
- if (commandName.length === 0) {
6629
+ const userArgs = argv.slice(2);
6630
+ const operands = collectOperandTokens(userArgs, optionMeta, { skipFlag: "--example" });
6631
+ const cmdPath = findCommandPath(operands, commandRegistry);
6632
+ if (!cmdPath) {
6462
6633
  throw new CliError("invalid_cli_usage", 'Provide a command after "--example".');
6463
6634
  }
6635
+ const remainingTokens = userArgs.slice(cmdPath.lastArgvIndex + 1);
6464
6636
  return {
6465
- commandName,
6637
+ commandName: cmdPath.commandName,
6466
6638
  filters: extractExampleFilters(remainingTokens),
6467
6639
  overrides: extractExampleOverrides(argv),
6468
6640
  json: argv.includes("--json")
@@ -11541,7 +11713,9 @@ async function runCli(argv) {
11541
11713
  process.exitCode = exitCode;
11542
11714
  return;
11543
11715
  }
11544
- const exampleRequest = extractExampleRequest(argv);
11716
+ const program = buildProgram();
11717
+ const optionMeta = buildOptionMetadata(program);
11718
+ const exampleRequest = extractExampleRequest(argv, optionMeta);
11545
11719
  if (exampleRequest) {
11546
11720
  await showExamples(
11547
11721
  exampleRequest.commandName,
@@ -11555,7 +11729,8 @@ async function runCli(argv) {
11555
11729
  );
11556
11730
  throw new ExampleDisplayed();
11557
11731
  }
11558
- await buildProgram().parseAsync(argv);
11732
+ const rewrittenArgv = hoistGlobalOptions(argv, optionMeta, commandRegistry);
11733
+ await program.parseAsync(rewrittenArgv);
11559
11734
  } catch (error) {
11560
11735
  if (error instanceof ExampleDisplayed) {
11561
11736
  process.exitCode = 0;