politty 0.4.4 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/{arg-registry-BUUhZ7JR.d.ts → arg-registry-2m40k1Et.d.ts} +1 -1
  2. package/dist/{arg-registry-BUUhZ7JR.d.ts.map → arg-registry-2m40k1Et.d.ts.map} +1 -1
  3. package/dist/augment.d.ts +1 -1
  4. package/dist/completion/index.cjs +16 -168
  5. package/dist/completion/index.d.cts +2 -77
  6. package/dist/completion/index.d.ts +2 -77
  7. package/dist/completion/index.js +3 -154
  8. package/dist/{zsh-DR47Ccac.cjs → completion-Df0eZ70u.cjs} +230 -18
  9. package/dist/completion-Df0eZ70u.cjs.map +1 -0
  10. package/dist/{zsh-XbRzR8FW.js → completion-_AnQsWh9.js} +202 -8
  11. package/dist/completion-_AnQsWh9.js.map +1 -0
  12. package/dist/docs/index.cjs +274 -28
  13. package/dist/docs/index.cjs.map +1 -1
  14. package/dist/docs/index.d.cts +62 -7
  15. package/dist/docs/index.d.cts.map +1 -1
  16. package/dist/docs/index.d.ts +62 -7
  17. package/dist/docs/index.d.ts.map +1 -1
  18. package/dist/docs/index.js +269 -29
  19. package/dist/docs/index.js.map +1 -1
  20. package/dist/{value-completion-resolver-C9LTGr0O.d.ts → index-BA0GkZQx.d.cts} +83 -4
  21. package/dist/index-BA0GkZQx.d.cts.map +1 -0
  22. package/dist/{value-completion-resolver-BQgHsX7b.d.cts → index-rMDe9hp1.d.ts} +83 -4
  23. package/dist/index-rMDe9hp1.d.ts.map +1 -0
  24. package/dist/index.cjs +8 -7
  25. package/dist/index.d.cts +67 -13
  26. package/dist/index.d.cts.map +1 -1
  27. package/dist/index.d.ts +68 -14
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +4 -5
  30. package/dist/{lazy-BEDnSR0m.cjs → lazy-DHlvJiQQ.cjs} +44 -8
  31. package/dist/lazy-DHlvJiQQ.cjs.map +1 -0
  32. package/dist/{lazy-BrEg8SgI.js → lazy-DSyfzR-F.js} +38 -8
  33. package/dist/lazy-DSyfzR-F.js.map +1 -0
  34. package/dist/{runner-C4fSHJMe.cjs → runner-Cn6Oq4ZZ.cjs} +453 -26
  35. package/dist/runner-Cn6Oq4ZZ.cjs.map +1 -0
  36. package/dist/{runner-D6k4BgB4.js → runner-D4ByDT5I.js} +453 -26
  37. package/dist/runner-D4ByDT5I.js.map +1 -0
  38. package/dist/{schema-extractor-DFaAZzaY.d.cts → schema-extractor-BoWkcP9a.d.cts} +48 -2
  39. package/dist/schema-extractor-BoWkcP9a.d.cts.map +1 -0
  40. package/dist/{schema-extractor-n9288WJ6.d.ts → schema-extractor-DoDO4M_i.d.ts} +49 -3
  41. package/dist/schema-extractor-DoDO4M_i.d.ts.map +1 -0
  42. package/dist/{subcommand-router-CAzBsLSI.js → subcommand-router-CKuy6D2b.js} +2 -2
  43. package/dist/{subcommand-router-CAzBsLSI.js.map → subcommand-router-CKuy6D2b.js.map} +1 -1
  44. package/dist/{subcommand-router-ZjNjFaUL.cjs → subcommand-router-sZHhUP7b.cjs} +2 -2
  45. package/dist/{subcommand-router-ZjNjFaUL.cjs.map → subcommand-router-sZHhUP7b.cjs.map} +1 -1
  46. package/package.json +9 -9
  47. package/dist/completion/index.cjs.map +0 -1
  48. package/dist/completion/index.d.cts.map +0 -1
  49. package/dist/completion/index.d.ts.map +0 -1
  50. package/dist/completion/index.js.map +0 -1
  51. package/dist/lazy-BEDnSR0m.cjs.map +0 -1
  52. package/dist/lazy-BrEg8SgI.js.map +0 -1
  53. package/dist/runner-C4fSHJMe.cjs.map +0 -1
  54. package/dist/runner-D6k4BgB4.js.map +0 -1
  55. package/dist/schema-extractor-DFaAZzaY.d.cts.map +0 -1
  56. package/dist/schema-extractor-n9288WJ6.d.ts.map +0 -1
  57. package/dist/value-completion-resolver-BQgHsX7b.d.cts.map +0 -1
  58. package/dist/value-completion-resolver-C9LTGr0O.d.ts.map +0 -1
  59. package/dist/zsh-DR47Ccac.cjs.map +0 -1
  60. package/dist/zsh-XbRzR8FW.js.map +0 -1
@@ -1,5 +1,5 @@
1
- const require_subcommand_router = require('./subcommand-router-ZjNjFaUL.cjs');
2
- const require_lazy = require('./lazy-BEDnSR0m.cjs');
1
+ const require_subcommand_router = require('./subcommand-router-sZHhUP7b.cjs');
2
+ const require_lazy = require('./lazy-DHlvJiQQ.cjs');
3
3
  let zod = require("zod");
4
4
  let node_child_process = require("node:child_process");
5
5
 
@@ -17,6 +17,30 @@ function defineCommand(config) {
17
17
  examples: config.examples
18
18
  };
19
19
  }
20
+ /**
21
+ * Create a typed defineCommand factory with pre-bound global args type.
22
+ * This is the recommended pattern for type-safe global options.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * // global-args.ts
27
+ * type GlobalArgsType = { verbose: boolean; config?: string };
28
+ * export const defineAppCommand = createDefineCommand<GlobalArgsType>();
29
+ *
30
+ * // commands/build.ts
31
+ * export const buildCommand = defineAppCommand({
32
+ * name: "build",
33
+ * args: z.object({ output: arg(z.string().default("dist")) }),
34
+ * run: (args) => {
35
+ * args.verbose; // typed via GlobalArgsType
36
+ * args.output; // typed via local args
37
+ * },
38
+ * });
39
+ * ```
40
+ */
41
+ function createDefineCommand() {
42
+ return defineCommand;
43
+ }
20
44
 
21
45
  //#endregion
22
46
  //#region src/completion/value-completion-resolver.ts
@@ -201,14 +225,34 @@ function isSubcmdCaseLines(routeEntries) {
201
225
  return routeEntries.map((r) => ` ${r.lookupPattern}) return 0 ;;`);
202
226
  }
203
227
  /**
228
+ * Recursively merge global options into a subcommand and all its descendants.
229
+ * Avoids duplicates by checking existing option names.
230
+ */
231
+ function propagateGlobalOptions(sub, globalOptions) {
232
+ const existingNames = new Set(sub.options.map((o) => o.name));
233
+ const newOpts = globalOptions.filter((o) => !existingNames.has(o.name));
234
+ sub.options = [...sub.options, ...newOpts];
235
+ for (const child of sub.subcommands) propagateGlobalOptions(child, globalOptions);
236
+ }
237
+ /**
204
238
  * Extract completion data from a command tree
239
+ *
240
+ * @param command - The root command
241
+ * @param programName - Program name for completion scripts
242
+ * @param globalArgsSchema - Optional global args schema. When provided, global options
243
+ * are derived from this schema instead of the root command's options.
205
244
  */
206
- function extractCompletionData(command, programName) {
245
+ function extractCompletionData(command, programName, globalArgsSchema) {
207
246
  const rootSubcommand = extractSubcommand(programName, command);
247
+ let globalOptions;
248
+ if (globalArgsSchema) {
249
+ globalOptions = require_lazy.extractFields(globalArgsSchema).fields.filter((field) => !field.positional).map(fieldToOption);
250
+ propagateGlobalOptions(rootSubcommand, globalOptions);
251
+ } else globalOptions = rootSubcommand.options;
208
252
  return {
209
253
  command: rootSubcommand,
210
254
  programName,
211
- globalOptions: rootSubcommand.options
255
+ globalOptions
212
256
  };
213
257
  }
214
258
 
@@ -383,7 +427,7 @@ function generateSubHandler$2(sub, fn, path) {
383
427
  }
384
428
  function generateBashCompletion(command, options) {
385
429
  const { programName } = options;
386
- const data = extractCompletionData(command, programName);
430
+ const data = extractCompletionData(command, programName, options.globalArgsSchema);
387
431
  const fn = sanitize(programName);
388
432
  const root = data.command;
389
433
  const visibleSubs = getVisibleSubs(root.subcommands);
@@ -1200,7 +1244,7 @@ function optTakesValueCases(sub, parentPath) {
1200
1244
  }
1201
1245
  function generateFishCompletion(command, options) {
1202
1246
  const { programName } = options;
1203
- const data = extractCompletionData(command, programName);
1247
+ const data = extractCompletionData(command, programName, options.globalArgsSchema);
1204
1248
  const fn = sanitize(programName);
1205
1249
  const root = data.command;
1206
1250
  const visibleSubs = getVisibleSubs(root.subcommands);
@@ -1452,7 +1496,7 @@ function generateSubHandler(sub, fn, path) {
1452
1496
  }
1453
1497
  function generateZshCompletion(command, options) {
1454
1498
  const { programName } = options;
1455
- const data = extractCompletionData(command, programName);
1499
+ const data = extractCompletionData(command, programName, options.globalArgsSchema);
1456
1500
  const fn = sanitize(programName);
1457
1501
  const root = data.command;
1458
1502
  const visibleSubs = getVisibleSubs(root.subcommands);
@@ -1581,6 +1625,156 @@ source ~/.zshrc`
1581
1625
  };
1582
1626
  }
1583
1627
 
1628
+ //#endregion
1629
+ //#region src/completion/index.ts
1630
+ /**
1631
+ * Shell completion generation module
1632
+ *
1633
+ * Provides utilities to generate shell completion scripts for bash, zsh, and fish.
1634
+ *
1635
+ * @example
1636
+ * ```typescript
1637
+ * import { generateCompletion, createCompletionCommand } from "politty/completion";
1638
+ *
1639
+ * // Generate completion script directly
1640
+ * const result = generateCompletion(myCommand, {
1641
+ * shell: "bash",
1642
+ * programName: "mycli"
1643
+ * });
1644
+ * console.log(result.script);
1645
+ *
1646
+ * // Or add a completion subcommand to your CLI
1647
+ * const mainCommand = withCompletionCommand(
1648
+ * defineCommand({
1649
+ * name: "mycli",
1650
+ * subCommands: { ... },
1651
+ * }),
1652
+ * );
1653
+ * ```
1654
+ */
1655
+ /**
1656
+ * Generate completion script for the specified shell
1657
+ */
1658
+ function generateCompletion(command, options) {
1659
+ switch (options.shell) {
1660
+ case "bash": return generateBashCompletion(command, options);
1661
+ case "zsh": return generateZshCompletion(command, options);
1662
+ case "fish": return generateFishCompletion(command, options);
1663
+ default: throw new Error(`Unsupported shell: ${options.shell}`);
1664
+ }
1665
+ }
1666
+ /**
1667
+ * Get the list of supported shells
1668
+ */
1669
+ function getSupportedShells() {
1670
+ return [
1671
+ "bash",
1672
+ "zsh",
1673
+ "fish"
1674
+ ];
1675
+ }
1676
+ /**
1677
+ * Detect the current shell from environment
1678
+ */
1679
+ function detectShell() {
1680
+ const shellName = (process.env.SHELL || "").split("/").pop()?.toLowerCase() || "";
1681
+ if (shellName.includes("bash")) return "bash";
1682
+ if (shellName.includes("zsh")) return "zsh";
1683
+ if (shellName.includes("fish")) return "fish";
1684
+ return null;
1685
+ }
1686
+ /**
1687
+ * Schema for the completion command arguments
1688
+ */
1689
+ const completionArgsSchema = zod.z.object({
1690
+ shell: require_lazy.arg(zod.z.enum([
1691
+ "bash",
1692
+ "zsh",
1693
+ "fish"
1694
+ ]).optional().describe("Shell type (auto-detected if not specified)"), {
1695
+ positional: true,
1696
+ description: "Shell type (bash, zsh, or fish)",
1697
+ placeholder: "SHELL"
1698
+ }),
1699
+ instructions: require_lazy.arg(zod.z.boolean().default(false), {
1700
+ alias: "i",
1701
+ description: "Show installation instructions"
1702
+ })
1703
+ });
1704
+ /**
1705
+ * Create a completion subcommand for your CLI
1706
+ *
1707
+ * This creates a ready-to-use subcommand that generates completion scripts.
1708
+ *
1709
+ * @example
1710
+ * ```typescript
1711
+ * const mainCommand = defineCommand({
1712
+ * name: "mycli",
1713
+ * subCommands: {
1714
+ * completion: createCompletionCommand(mainCommand)
1715
+ * }
1716
+ * });
1717
+ * ```
1718
+ */
1719
+ function createCompletionCommand(rootCommand, programName, globalArgsSchema) {
1720
+ const resolvedProgramName = programName ?? rootCommand.name;
1721
+ if (!rootCommand.subCommands?.__complete) rootCommand.subCommands = {
1722
+ ...rootCommand.subCommands,
1723
+ __complete: createDynamicCompleteCommand(rootCommand, resolvedProgramName)
1724
+ };
1725
+ return defineCommand({
1726
+ name: "completion",
1727
+ description: "Generate shell completion script",
1728
+ args: completionArgsSchema,
1729
+ run(args) {
1730
+ const shellType = args.shell || detectShell();
1731
+ if (!shellType) {
1732
+ console.error("Could not detect shell type. Please specify one of: bash, zsh, fish");
1733
+ process.exitCode = 1;
1734
+ return;
1735
+ }
1736
+ const result = generateCompletion(rootCommand, {
1737
+ shell: shellType,
1738
+ programName: resolvedProgramName,
1739
+ includeDescriptions: true,
1740
+ ...globalArgsSchema !== void 0 && { globalArgsSchema }
1741
+ });
1742
+ if (args.instructions) console.log(result.installInstructions);
1743
+ else console.log(result.script);
1744
+ }
1745
+ });
1746
+ }
1747
+ /**
1748
+ * Wrap a command with a completion subcommand
1749
+ *
1750
+ * This avoids circular references that occur when a command references itself
1751
+ * in its subCommands (e.g., for completion generation).
1752
+ *
1753
+ * @param command - The command to wrap
1754
+ * @param options - Options including programName
1755
+ * @returns A new command with the completion subcommand added
1756
+ *
1757
+ * @example
1758
+ * ```typescript
1759
+ * const mainCommand = withCompletionCommand(
1760
+ * defineCommand({
1761
+ * name: "mycli",
1762
+ * subCommands: { ... },
1763
+ * }),
1764
+ * );
1765
+ * ```
1766
+ */
1767
+ function withCompletionCommand(command, options) {
1768
+ const { programName, globalArgsSchema } = typeof options === "string" ? { programName: options } : options ?? {};
1769
+ const wrappedCommand = { ...command };
1770
+ wrappedCommand.subCommands = {
1771
+ ...command.subCommands,
1772
+ completion: createCompletionCommand(wrappedCommand, programName, globalArgsSchema),
1773
+ __complete: createDynamicCompleteCommand(wrappedCommand, programName)
1774
+ };
1775
+ return wrappedCommand;
1776
+ }
1777
+
1584
1778
  //#endregion
1585
1779
  Object.defineProperty(exports, 'CompletionDirective', {
1586
1780
  enumerable: true,
@@ -1588,6 +1782,18 @@ Object.defineProperty(exports, 'CompletionDirective', {
1588
1782
  return CompletionDirective;
1589
1783
  }
1590
1784
  });
1785
+ Object.defineProperty(exports, 'createCompletionCommand', {
1786
+ enumerable: true,
1787
+ get: function () {
1788
+ return createCompletionCommand;
1789
+ }
1790
+ });
1791
+ Object.defineProperty(exports, 'createDefineCommand', {
1792
+ enumerable: true,
1793
+ get: function () {
1794
+ return createDefineCommand;
1795
+ }
1796
+ });
1591
1797
  Object.defineProperty(exports, 'createDynamicCompleteCommand', {
1592
1798
  enumerable: true,
1593
1799
  get: function () {
@@ -1600,6 +1806,12 @@ Object.defineProperty(exports, 'defineCommand', {
1600
1806
  return defineCommand;
1601
1807
  }
1602
1808
  });
1809
+ Object.defineProperty(exports, 'detectShell', {
1810
+ enumerable: true,
1811
+ get: function () {
1812
+ return detectShell;
1813
+ }
1814
+ });
1603
1815
  Object.defineProperty(exports, 'extractCompletionData', {
1604
1816
  enumerable: true,
1605
1817
  get: function () {
@@ -1618,28 +1830,22 @@ Object.defineProperty(exports, 'formatForShell', {
1618
1830
  return formatForShell;
1619
1831
  }
1620
1832
  });
1621
- Object.defineProperty(exports, 'generateBashCompletion', {
1622
- enumerable: true,
1623
- get: function () {
1624
- return generateBashCompletion;
1625
- }
1626
- });
1627
1833
  Object.defineProperty(exports, 'generateCandidates', {
1628
1834
  enumerable: true,
1629
1835
  get: function () {
1630
1836
  return generateCandidates;
1631
1837
  }
1632
1838
  });
1633
- Object.defineProperty(exports, 'generateFishCompletion', {
1839
+ Object.defineProperty(exports, 'generateCompletion', {
1634
1840
  enumerable: true,
1635
1841
  get: function () {
1636
- return generateFishCompletion;
1842
+ return generateCompletion;
1637
1843
  }
1638
1844
  });
1639
- Object.defineProperty(exports, 'generateZshCompletion', {
1845
+ Object.defineProperty(exports, 'getSupportedShells', {
1640
1846
  enumerable: true,
1641
1847
  get: function () {
1642
- return generateZshCompletion;
1848
+ return getSupportedShells;
1643
1849
  }
1644
1850
  });
1645
1851
  Object.defineProperty(exports, 'hasCompleteCommand', {
@@ -1660,4 +1866,10 @@ Object.defineProperty(exports, 'resolveValueCompletion', {
1660
1866
  return resolveValueCompletion;
1661
1867
  }
1662
1868
  });
1663
- //# sourceMappingURL=zsh-DR47Ccac.cjs.map
1869
+ Object.defineProperty(exports, 'withCompletionCommand', {
1870
+ enumerable: true,
1871
+ get: function () {
1872
+ return withCompletionCommand;
1873
+ }
1874
+ });
1875
+ //# sourceMappingURL=completion-Df0eZ70u.cjs.map