postman-cli-completion 1.73.0 → 1.74.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/README.md CHANGED
@@ -119,6 +119,74 @@ After installing for your shell, open a fresh terminal and check each:
119
119
  | `postman flows <TAB>` | `list`, `trigger`, `deploy`, `run`, `update`, `list-runs`, `get-run` |
120
120
  | `postman --<TAB>` | `--silent`, `--color`, `--version`, `--help` |
121
121
 
122
+ ## Check your Postman CLI version
123
+
124
+ The completions are generated for a specific Postman CLI version, so a CLI that has
125
+ drifted from that version may complete commands it does not have (or miss ones it does).
126
+ `doctor` reports both kinds of drift:
127
+
128
+ ```sh
129
+ postman-completion doctor
130
+ ```
131
+
132
+ It performs two independent checks:
133
+
134
+ 1. **Installed CLI vs. the latest published `postman-cli`** — if yours is older, it warns
135
+ and tells you how to upgrade.
136
+ 2. **Installed CLI vs. the version these completions were generated for** — if they differ,
137
+ it warns and tells you how to update the completions.
138
+
139
+ ```console
140
+ $ postman-completion doctor
141
+ Your Postman CLI is outdated: installed 1.60.0, latest 1.73.0.
142
+ Upgrade with: npm install -g postman-cli@latest
143
+ These completions were generated for Postman CLI 1.73.0, but 1.60.0 is installed.
144
+ Completions may offer commands your CLI does not have.
145
+ Update them with: npm install -g postman-cli-completion@latest
146
+ ```
147
+
148
+ Check 1 queries the npm registry. To skip it — offline, or in a hook where you do not want
149
+ a network call — use `--offline`, which still runs check 2:
150
+
151
+ ```sh
152
+ postman-completion doctor --offline
153
+ ```
154
+
155
+ `doctor` exits **1** when you should act (outdated CLI, or completions that no longer match
156
+ it) and **0** when everything is current, so it works as a shell-startup or CI check. A
157
+ missing Postman CLI is reported as a notice and exits 0. A failed registry lookup never
158
+ fails the command — it degrades to the offline check and explains itself on stderr.
159
+
160
+ ### Automatic notice on install
161
+
162
+ You do not have to remember to run `doctor`. Installing or updating this package prints a
163
+ notice if your Postman CLI does not match the version the completions were built for:
164
+
165
+ ```console
166
+ $ npm install -g postman-cli-completion
167
+
168
+ postman-cli-completion:
169
+ These completions were generated for Postman CLI 1.73.0, but 1.60.0 is installed.
170
+ Completions may offer commands your CLI does not have.
171
+ Update them with: npm install -g postman-cli-completion@latest
172
+
173
+ Silence this check with POSTMAN_COMPLETION_NO_VERSION_CHECK=1
174
+ ```
175
+
176
+ This check is deliberately conservative:
177
+
178
+ - **Never fails the install** — it exits 0 on every path, including unexpected errors.
179
+ - **Never touches the network** — the comparison is local, so installs stay fast and
180
+ offline-safe. The "is my CLI older than the latest release?" question needs the
181
+ registry, so it belongs to `doctor`.
182
+ - **Silent unless it matters** — nothing is printed when the versions match, when the
183
+ Postman CLI is not installed, in CI, for non-global installs, or when stderr is not a
184
+ terminal. Set `POSTMAN_COMPLETION_NO_VERSION_CHECK=1` to disable it entirely.
185
+
186
+ Because it runs at install time, it catches drift when you install or update this package.
187
+ If you upgrade the Postman CLI itself some time later, run `postman-completion doctor` to
188
+ check on demand.
189
+
122
190
  ## Versioning
123
191
 
124
192
  The completion scripts are auto-generated from a single source of truth (`spec/commands.json`) and tracked against the upstream Postman CLI by two GitHub Actions workflows:
@@ -130,16 +198,12 @@ So this repo follows the latest published Postman CLI version automatically —
130
198
 
131
199
  Suspicious catchup diffs (≥30 % flag drop, a known fixed command missing, semver regression) are blocked by `scripts/validate-diff.mjs` and stay open for human review instead of auto-merging.
132
200
 
133
- To check the version the committed spec was generated against:
134
-
135
- ```sh
136
- node -p "require('./spec/commands.json').postmanCliVersion"
137
- ```
138
-
139
- And your installed Postman CLI:
201
+ To compare the version the completions were built for against your installed CLI, use
202
+ [`postman-completion doctor`](#check-your-postman-cli-version). The underlying values are:
140
203
 
141
204
  ```sh
142
- postman --version
205
+ node -p "require('./spec/commands.json').postmanCliVersion" # what the completions target
206
+ postman --version # what you have installed
143
207
  ```
144
208
 
145
209
  ## License
@@ -2,6 +2,7 @@
2
2
  import { readFileSync } from "node:fs";
3
3
  import { dirname, resolve } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
+ import { checkVersions } from "../lib/version-check.mjs";
5
6
 
6
7
  // bin/ lives one level under the package root. Resolve completion files relative
7
8
  // to this module (NOT process.cwd(), which is the user's shell directory).
@@ -13,6 +14,9 @@ const FILES = {
13
14
  fish: resolve(PKG_ROOT, "completions/fish/postman.fish"),
14
15
  };
15
16
 
17
+ const SPEC_PATH = resolve(PKG_ROOT, "spec/commands.json");
18
+ const PKG_JSON_PATH = resolve(PKG_ROOT, "package.json");
19
+
16
20
  const USAGE = `postman-completion — shell completions for the Postman CLI
17
21
 
18
22
  Note: this installs the command "postman-completion"; it does NOT shadow the
@@ -22,6 +26,8 @@ Usage:
22
26
  postman-completion <zsh|bash|fish> Print the completion script to stdout
23
27
  postman-completion path <zsh|bash|fish> Print the packaged file's absolute path
24
28
  postman-completion path <shell> --dir Print the file's directory (for zsh fpath)
29
+ postman-completion doctor Check your Postman CLI version for updates
30
+ postman-completion doctor --offline Same, without querying the npm registry
25
31
  postman-completion --help Show this help
26
32
 
27
33
  Wire it into your shell:
@@ -59,7 +65,30 @@ function printPath(args) {
59
65
  process.stdout.write(`${dirOnly ? dirname(file) : file}\n`);
60
66
  }
61
67
 
62
- function main(argv) {
68
+ // Exit 0 when everything is current, 1 when the user should act (outdated CLI
69
+ // or completions that no longer match it), so `doctor` is usable in a script.
70
+ async function doctor(args) {
71
+ const offline = args.includes("--offline");
72
+ const report = await checkVersions({
73
+ specPath: SPEC_PATH,
74
+ packageJsonPath: PKG_JSON_PATH,
75
+ offline,
76
+ });
77
+
78
+ for (const line of report.lines) process.stdout.write(`${line}\n`);
79
+
80
+ // Surface *why* a comparison was skipped, but only when it hid information:
81
+ // an explicit --offline is the user's own choice and needs no explanation.
82
+ if (!offline && report.latestError) {
83
+ process.stderr.write(
84
+ `postman-completion: could not check npm for the latest version (${report.latestError})\n`,
85
+ );
86
+ }
87
+
88
+ process.exit(report.level === "warn" ? 1 : 0);
89
+ }
90
+
91
+ async function main(argv) {
63
92
  const [cmd, ...rest] = argv;
64
93
 
65
94
  if (!cmd || cmd === "--help" || cmd === "-h" || cmd === "help") {
@@ -72,6 +101,11 @@ function main(argv) {
72
101
  return;
73
102
  }
74
103
 
104
+ if (cmd === "doctor") {
105
+ await doctor(rest);
106
+ return;
107
+ }
108
+
75
109
  if (cmd in FILES) {
76
110
  emit(cmd);
77
111
  return;
@@ -80,4 +114,4 @@ function main(argv) {
80
114
  die(`unknown command: ${cmd}\n\n${USAGE}`);
81
115
  }
82
116
 
83
- main(process.argv.slice(2));
117
+ main(process.argv.slice(2)).catch((err) => die(err.message));
@@ -1,4 +1,4 @@
1
- # Bash completion for Postman CLI (postman v1.73.0)
1
+ # Bash completion for Postman CLI (postman v1.74.0)
2
2
  # Auto-generated by scripts/generate.mjs — DO NOT EDIT
3
3
  # Source: spec/commands.json
4
4
  # https://github.com/yokawasa/postman-cli-completion
@@ -969,7 +969,7 @@ _postman_flows() {
969
969
  if [[ "$cur" == -* ]]; then
970
970
  COMPREPLY=( $(compgen -W "-h --help" -- "$cur") )
971
971
  else
972
- COMPREPLY=( $(compgen -W "list trigger deploy run update list-runs get-run" -- "$cur") )
972
+ COMPREPLY=( $(compgen -W "list trigger deploy run update delete list-runs get-run" -- "$cur") )
973
973
  fi
974
974
  return 0
975
975
  fi
@@ -979,6 +979,7 @@ _postman_flows() {
979
979
  deploy) _postman_flows_deploy ;;
980
980
  run) _postman_flows_run ;;
981
981
  update) _postman_flows_update ;;
982
+ delete) _postman_flows_delete ;;
982
983
  list-runs) _postman_flows_list_runs ;;
983
984
  get-run) _postman_flows_get_run ;;
984
985
  esac
@@ -1060,6 +1061,13 @@ _postman_flows_update() {
1060
1061
  esac
1061
1062
  }
1062
1063
 
1064
+ _postman_flows_delete() {
1065
+ if [[ "$cur" == -* ]]; then
1066
+ COMPREPLY=( $(compgen -W "-y --yes --verbose --debug --json -h --help" -- "$cur") )
1067
+ return 0
1068
+ fi
1069
+ }
1070
+
1063
1071
  _postman_flows_list_runs() {
1064
1072
  if [[ "$cur" == -* ]]; then
1065
1073
  COMPREPLY=( $(compgen -W "-w --workspace -f --flow -r --range --verbose --debug --json -h --help" -- "$cur") )
@@ -1193,7 +1201,7 @@ _postman_mock() {
1193
1201
 
1194
1202
  _postman_mock_generate() {
1195
1203
  if [[ "$cur" == -* ]]; then
1196
- COMPREPLY=( $(compgen -W "-o --output -n --name --port --force -u --update -w --workspace --api-key -x --suppress-exit-code -h --help" -- "$cur") )
1204
+ COMPREPLY=( $(compgen -W "-o --output -n --name --port --stateful --force -u --update -w --workspace --api-key -x --suppress-exit-code -h --help" -- "$cur") )
1197
1205
  return 0
1198
1206
  fi
1199
1207
  case "$prev" in
@@ -1737,10 +1745,13 @@ _postman_spec() {
1737
1745
 
1738
1746
  _postman_spec_lint() {
1739
1747
  if [[ "$cur" == -* ]]; then
1740
- COMPREPLY=( $(compgen -W "-f --fail-severity --issueType -o --output --workspace-id --report-events --no-report-events -h --help" -- "$cur") )
1748
+ COMPREPLY=( $(compgen -W "-f --fail-severity --issueType -o --output --workspace-id --ruleset --report-events --no-report-events -h --help" -- "$cur") )
1741
1749
  return 0
1742
1750
  fi
1743
1751
  case "$prev" in
1752
+ --ruleset)
1753
+ _postman_filematch '!*.@(json)' "$cur"
1754
+ return 0 ;;
1744
1755
  esac
1745
1756
  }
1746
1757
 
@@ -1905,7 +1916,7 @@ _postman_spec_sync() {
1905
1916
 
1906
1917
  _postman_spec_sync_collection() {
1907
1918
  if [[ "$cur" == -* ]]; then
1908
- COMPREPLY=( $(compgen -W "--collection-id --api-key --force -h --help" -- "$cur") )
1919
+ COMPREPLY=( $(compgen -W "--collection-id --api-key --force --dry-run -h --help" -- "$cur") )
1909
1920
  return 0
1910
1921
  fi
1911
1922
  case "$prev" in
@@ -2459,7 +2470,7 @@ _postman_logout() {
2459
2470
 
2460
2471
  _postman_signup() {
2461
2472
  if [[ "$cur" == -* ]]; then
2462
- COMPREPLY=( $(compgen -W "--guest --json -h --help" -- "$cur") )
2473
+ COMPREPLY=( $(compgen -W "--guest --no-push --json -h --help" -- "$cur") )
2463
2474
  return 0
2464
2475
  fi
2465
2476
  }
@@ -1,4 +1,4 @@
1
- # Fish completion for Postman CLI (postman v1.73.0)
1
+ # Fish completion for Postman CLI (postman v1.74.0)
2
2
  # Auto-generated by scripts/generate.mjs — DO NOT EDIT
3
3
  # Source: spec/commands.json
4
4
  # https://github.com/yokawasa/postman-cli-completion
@@ -618,13 +618,14 @@ complete -c postman -n '__fish_seen_subcommand_from environment; and __fish_seen
618
618
  complete -c postman -n '__fish_seen_subcommand_from environment; and __fish_seen_subcommand_from lint' -r -k -a '(__fish_complete_suffix .json)'
619
619
 
620
620
  # ---------- flows ----------
621
- complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update list-runs get-run' -a list -d 'List all flows'
622
- complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update list-runs get-run' -a trigger -d 'Trigger a deployed flow'
623
- complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update list-runs get-run' -a deploy -d 'Deploy a flow (required to trigger it)'
624
- complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update list-runs get-run' -a run -d 'Run a single flow from a file (e.g. ./path/to/flow.json)'
625
- complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update list-runs get-run' -a update -d 'Update settings for a deployed flow'
626
- complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update list-runs get-run' -a list-runs -d 'List run history for a deployed flow'
627
- complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update list-runs get-run' -a get-run -d 'Analyze a specific flow run'
621
+ complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update delete list-runs get-run' -a list -d 'List all flows'
622
+ complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update delete list-runs get-run' -a trigger -d 'Trigger a deployed flow'
623
+ complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update delete list-runs get-run' -a deploy -d 'Deploy a flow (required to trigger it)'
624
+ complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update delete list-runs get-run' -a run -d 'Run a single flow from a file (e.g. ./path/to/flow.json)'
625
+ complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update delete list-runs get-run' -a update -d 'Update settings for a deployed flow'
626
+ complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update delete list-runs get-run' -a delete -d 'Delete a flow. A flow id deletes the cloud flow; a local flow file path deletes that file only. Prompts for confirmation unless --yes is passed.'
627
+ complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update delete list-runs get-run' -a list-runs -d 'List run history for a deployed flow'
628
+ complete -c postman -n '__postman_using_subcommand flows list trigger deploy run update delete list-runs get-run' -a get-run -d 'Analyze a specific flow run'
628
629
  complete -c postman -n '__fish_seen_subcommand_from flows' -s h -l help -d 'display help for command'
629
630
  # ---------- flows list ----------
630
631
  complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from list' -s w -l workspace -d 'Specify the workspace ID to list flows from' -x
@@ -686,6 +687,12 @@ complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subco
686
687
  complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from update' -l debug -d 'Debug output'
687
688
  complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from update' -l json -d 'JSON output'
688
689
  complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from update' -s h -l help -d 'display help for command'
690
+ # ---------- flows delete ----------
691
+ complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from delete' -s y -l yes -d 'Skip the confirmation prompt'
692
+ complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from delete' -l verbose -d 'Verbose output'
693
+ complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from delete' -l debug -d 'Debug output'
694
+ complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from delete' -l json -d 'JSON output'
695
+ complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from delete' -s h -l help -d 'display help for command'
689
696
  # ---------- flows list-runs ----------
690
697
  complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from list-runs' -s w -l workspace -d 'Specify the workspace ID' -x
691
698
  complete -c postman -n '__fish_seen_subcommand_from flows; and __fish_seen_subcommand_from list-runs' -s f -l flow -d 'Filter sessions by flow ID' -x
@@ -761,6 +768,7 @@ complete -c postman -n '__fish_seen_subcommand_from mock' -s h -l help -d 'displ
761
768
  complete -c postman -n '__fish_seen_subcommand_from mock; and __fish_seen_subcommand_from generate' -s o -l output -d 'Folder to save the mock in. Relative or absolute, e.g. ./postman/mocks/orders. Defaults to postman/mocks/<name>.' -r
762
769
  complete -c postman -n '__fish_seen_subcommand_from mock; and __fish_seen_subcommand_from generate' -s n -l name -d 'Name for the mock. Taken from the source when you provide one; required for the sample.' -x
763
770
  complete -c postman -n '__fish_seen_subcommand_from mock; and __fish_seen_subcommand_from generate' -l port -d 'Port the mock runs on (e.g. 4010) (default: 4500)' -x
771
+ complete -c postman -n '__fish_seen_subcommand_from mock; and __fish_seen_subcommand_from generate' -l stateful -d 'Generate pm.state-backed CRUD handlers (create/read/list/update/delete) instead of static example responses. Endpoints that are not CRUD-shaped stay static. Applies to collection or spec sources.'
764
772
  complete -c postman -n '__fish_seen_subcommand_from mock; and __fish_seen_subcommand_from generate' -l force -d 'Overwrite the mock\'s files if the target folder already has one'
765
773
  complete -c postman -n '__fish_seen_subcommand_from mock; and __fish_seen_subcommand_from generate' -s u -l update -d 'Update an existing mock from the source instead of creating a new one. Path to the mock, relative or absolute, e.g. ./postman/mocks/orders. Cannot be used with --output.' -r
766
774
  complete -c postman -n '__fish_seen_subcommand_from mock; and __fish_seen_subcommand_from generate' -s w -l workspace -d 'Save the mock to this Postman cloud workspace (by id) instead of your repository. Cannot be used with --output, --force, or --update.' -x
@@ -1138,6 +1146,7 @@ complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcom
1138
1146
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from lint' -l issueType -d 'Limit linting to a specific issue type. [choices: "syntax"]' -x
1139
1147
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from lint' -s o -l output -d 'Output format for the results. [choices: "json", "csv"]' -x
1140
1148
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from lint' -l workspace-id -d 'The workspace ID to use for fetching governance rulesets.' -x
1149
+ complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from lint' -l ruleset -d 'Lint against a local Spectral ruleset.' -r
1141
1150
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from lint' -l report-events -d 'Dispatch events to the API Catalog and Application Inventory ingestion pipelines (on by default)'
1142
1151
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from lint' -l no-report-events -d 'Do not dispatch events to the API Catalog and Application Inventory ingestion pipelines'
1143
1152
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from lint' -s h -l help -d 'display help for command'
@@ -1208,7 +1217,8 @@ complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcom
1208
1217
  # ---------- spec sync collection ----------
1209
1218
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from sync; and __fish_seen_subcommand_from collection' -l collection-id -d 'Collection ID to sync (required for cloud mode)' -x
1210
1219
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from sync; and __fish_seen_subcommand_from collection' -l api-key -d 'Postman API key' -r
1211
- complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from sync; and __fish_seen_subcommand_from collection' -l force -d 'Overwrite hand-written scripts that the spec would otherwise drop'
1220
+ complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from sync; and __fish_seen_subcommand_from collection' -l force -d 'Overwrite hand-written scripts, headers and descriptions that the spec would otherwise drop'
1221
+ complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from sync; and __fish_seen_subcommand_from collection' -l dry-run -d 'Report what sync would change and remove without writing anything'
1212
1222
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from sync; and __fish_seen_subcommand_from collection' -s h -l help -d 'display help for command'
1213
1223
  # ---------- spec delete ----------
1214
1224
  complete -c postman -n '__fish_seen_subcommand_from spec; and __fish_seen_subcommand_from delete' -s y -l yes -d 'Delete without asking for confirmation first'
@@ -1476,6 +1486,7 @@ complete -c postman -n '__fish_seen_subcommand_from logout' -s h -l help -d 'dis
1476
1486
 
1477
1487
  # ---------- signup ----------
1478
1488
  complete -c postman -n '__fish_seen_subcommand_from signup' -l guest -d 'Start working as an anonymous guest instead of signing up — no account or browser needed, so it works anywhere. Your work is saved to a temporary workspace you can keep later by running `postman signup`.'
1489
+ complete -c postman -n '__fish_seen_subcommand_from signup' -l no-push -d 'Do not push local work to your guest workspace before signing up. By default, work saved under postman/ is pushed first, so the workspace you keep is not empty.'
1479
1490
  complete -c postman -n '__fish_seen_subcommand_from signup' -l json -d 'Print the sign-up details as machine-readable JSON.'
1480
1491
  complete -c postman -n '__fish_seen_subcommand_from signup' -s h -l help -d 'display help for command'
1481
1492
 
@@ -1556,7 +1567,7 @@ complete -c postman -n '__fish_seen_subcommand_from feedback' -l json -d 'Print
1556
1567
  complete -c postman -n '__fish_seen_subcommand_from feedback' -s h -l help -d 'display help for command'
1557
1568
 
1558
1569
  # ---------- performance ----------
1559
- complete -c postman -n '__postman_using_subcommand performance run list get' -a run -d 'Run a performance test on a collection'
1570
+ complete -c postman -n '__postman_using_subcommand performance run list get' -a run -d 'Run a performance test on a collection (cloud collection UID or local collection path)'
1560
1571
  complete -c postman -n '__postman_using_subcommand performance run list get' -a list -d 'List past performance runs for a collection, newest first.'
1561
1572
  complete -c postman -n '__postman_using_subcommand performance run list get' -a get -d 'Get one performance run by ID.'
1562
1573
  complete -c postman -n '__fish_seen_subcommand_from performance' -s h -l help -d 'display help for command'
@@ -1,6 +1,6 @@
1
1
  #compdef postman
2
2
  compdef _postman postman
3
- # Zsh completion for Postman CLI (postman v1.73.0)
3
+ # Zsh completion for Postman CLI (postman v1.74.0)
4
4
  # Auto-generated by scripts/generate.mjs — DO NOT EDIT
5
5
  # Source: spec/commands.json
6
6
  # https://github.com/yokawasa/postman-cli-completion
@@ -1173,6 +1173,7 @@ _postman_flows() {
1173
1173
  deploy) _postman_flows_deploy ;;
1174
1174
  run) _postman_flows_run ;;
1175
1175
  update) _postman_flows_update ;;
1176
+ delete) _postman_flows_delete ;;
1176
1177
  list-runs) _postman_flows_list_runs ;;
1177
1178
  get-run) _postman_flows_get_run ;;
1178
1179
  esac
@@ -1188,6 +1189,7 @@ _postman_flows_commands() {
1188
1189
  'deploy:Deploy a flow (required to trigger it)'
1189
1190
  'run:Run a single flow from a file (e.g. ./path/to/flow.json)'
1190
1191
  'update:Update settings for a deployed flow'
1192
+ 'delete:Delete a flow. A flow id deletes the cloud flow; a local flow file path deletes that file only. Prompts for confirmation unless --yes is passed.'
1191
1193
  'list-runs:List run history for a deployed flow'
1192
1194
  'get-run:Analyze a specific flow run'
1193
1195
  )
@@ -1272,6 +1274,16 @@ _postman_flows_update() {
1272
1274
  '*:flowId:'
1273
1275
  }
1274
1276
 
1277
+ _postman_flows_delete() {
1278
+ _arguments \
1279
+ '(-y --yes)'{-y,--yes}'[Skip the confirmation prompt]' \
1280
+ '--verbose[Verbose output]' \
1281
+ '--debug[Debug output]' \
1282
+ '--json[JSON output]' \
1283
+ '(-h --help)'{-h,--help}'[display help for command]' \
1284
+ '*:flowIdOrPath:'
1285
+ }
1286
+
1275
1287
  _postman_flows_list_runs() {
1276
1288
  _arguments \
1277
1289
  '(-w --workspace)'{-w,--workspace}'[Specify the workspace ID]:workspaceId' \
@@ -1442,6 +1454,7 @@ _postman_mock_generate() {
1442
1454
  '(-o --output)'{-o,--output}'[Folder to save the mock in. Relative or absolute, e.g. ./postman/mocks/orders. Defaults to postman/mocks/<name>.]:dir:_files -g "*.json"' \
1443
1455
  '(-n --name)'{-n,--name}'[Name for the mock. Taken from the source when you provide one; required for the sample.]:name' \
1444
1456
  '--port[Port the mock runs on (e.g. 4010) (default\: 4500)]:port' \
1457
+ '--stateful[Generate pm.state-backed CRUD handlers (create/read/list/update/delete) instead of static example responses. Endpoints that are not CRUD-shaped stay static. Applies to collection or spec sources.]' \
1445
1458
  '--force[Overwrite the mock'\''s files if the target folder already has one]' \
1446
1459
  '(-u --update)'{-u,--update}'[Update an existing mock from the source instead of creating a new one. Path to the mock, relative or absolute, e.g. ./postman/mocks/orders. Cannot be used with --output.]:mockPath:_files -g "*.json"' \
1447
1460
  '(-w --workspace)'{-w,--workspace}'[Save the mock to this Postman cloud workspace (by id) instead of your repository. Cannot be used with --output, --force, or --update.]:id' \
@@ -2103,6 +2116,7 @@ _postman_spec_lint() {
2103
2116
  '--issueType[Limit linting to a specific issue type. \[choices\: "syntax"\]]:value' \
2104
2117
  '(-o --output)'{-o,--output}'[Output format for the results. \[choices\: "json", "csv"\]]:value' \
2105
2118
  '--workspace-id[The workspace ID to use for fetching governance rulesets.]:value' \
2119
+ '--ruleset[Lint against a local Spectral ruleset.]:path:_files -g "*.json"' \
2106
2120
  '--report-events[Dispatch events to the API Catalog and Application Inventory ingestion pipelines (on by default)]' \
2107
2121
  '--no-report-events[Do not dispatch events to the API Catalog and Application Inventory ingestion pipelines]' \
2108
2122
  '(-h --help)'{-h,--help}'[display help for command]' \
@@ -2273,7 +2287,8 @@ _postman_spec_sync_collection() {
2273
2287
  _arguments \
2274
2288
  '--collection-id[Collection ID to sync (required for cloud mode)]:id' \
2275
2289
  '--api-key[Postman API key]:key:_files -g "*.(pem|crt|key)"' \
2276
- '--force[Overwrite hand-written scripts that the spec would otherwise drop]' \
2290
+ '--force[Overwrite hand-written scripts, headers and descriptions that the spec would otherwise drop]' \
2291
+ '--dry-run[Report what sync would change and remove without writing anything]' \
2277
2292
  '(-h --help)'{-h,--help}'[display help for command]' \
2278
2293
  '*:spec:'
2279
2294
  }
@@ -2949,6 +2964,7 @@ _postman_logout() {
2949
2964
  _postman_signup() {
2950
2965
  _arguments \
2951
2966
  '--guest[Start working as an anonymous guest instead of signing up — no account or browser needed, so it works anywhere. Your work is saved to a temporary workspace you can keep later by running `postman signup`.]' \
2967
+ '--no-push[Do not push local work to your guest workspace before signing up. By default, work saved under postman/ is pushed first, so the workspace you keep is not empty.]' \
2952
2968
  '--json[Print the sign-up details as machine-readable JSON.]' \
2953
2969
  '(-h --help)'{-h,--help}'[display help for command]'
2954
2970
  }
@@ -3134,7 +3150,7 @@ _postman_performance() {
3134
3150
  _postman_performance_commands() {
3135
3151
  local -a sub
3136
3152
  sub=(
3137
- 'run:Run a performance test on a collection'
3153
+ 'run:Run a performance test on a collection (cloud collection UID or local collection path)'
3138
3154
  'list:List past performance runs for a collection, newest first.'
3139
3155
  'get:Get one performance run by ID.'
3140
3156
  )
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ // Postinstall version-drift notice.
3
+ //
4
+ // Runs once, right after `npm i -g postman-cli-completion`, and tells the user
5
+ // if their installed Postman CLI does not match the version these completions
6
+ // were generated for. That moment is the useful one: the user is already doing
7
+ // package management, so an "upgrade this" message is actionable.
8
+ //
9
+ // Hard rules for this file, because postinstall scripts are bad neighbours:
10
+ //
11
+ // 1. NEVER fail the install. Every path exits 0, including unexpected throws.
12
+ // 2. NEVER touch the network. A registry lookup here is exactly the kind of
13
+ // postinstall behaviour people (rightly) disable; the offline comparison
14
+ // already catches the common case. `doctor` does the online check on
15
+ // demand.
16
+ // 3. Say nothing when there is nothing to say, and stay quiet in CI and other
17
+ // non-interactive installs.
18
+ //
19
+ // The online "is my CLI older than npm latest?" check lives in `doctor`.
20
+
21
+ import { resolve, dirname } from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+ import { checkVersions } from "./version-check.mjs";
24
+
25
+ const PKG_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
26
+
27
+ /**
28
+ * Should we stay silent regardless of what the versions say?
29
+ *
30
+ * Suppressed for:
31
+ * - an explicit opt-out
32
+ * - CI (the notice is for humans; it would just be log noise)
33
+ * - a non-TTY stderr, which also covers piped/scripted installs
34
+ * - local (non-global) installs: this package is a global CLI helper, so a
35
+ * local install is usually a dependency graph artifact, not a user choice
36
+ */
37
+ export function shouldSuppress(env = process.env, isTTY = process.stderr.isTTY) {
38
+ if (env.POSTMAN_COMPLETION_NO_VERSION_CHECK === "1") return true;
39
+ if (env.CI && env.CI !== "false") return true;
40
+ if (env.npm_config_global !== "true") return true;
41
+ return !isTTY;
42
+ }
43
+
44
+ /** Wrap the drift lines in a visually distinct block so it is not lost in npm's output. */
45
+ export function formatNotice(lines) {
46
+ const body = lines.map((l) => ` ${l}`).join("\n");
47
+ return `\npostman-cli-completion:\n${body}\n\n Silence this check with POSTMAN_COMPLETION_NO_VERSION_CHECK=1\n`;
48
+ }
49
+
50
+ async function main() {
51
+ if (shouldSuppress()) return;
52
+
53
+ const report = await checkVersions({
54
+ specPath: resolve(PKG_ROOT, "spec/commands.json"),
55
+ packageJsonPath: resolve(PKG_ROOT, "package.json"),
56
+ offline: true, // rule 2: no network during install
57
+ timeoutMs: 3000, // keep the install snappy even if the CLI hangs
58
+ });
59
+
60
+ // Only speak up about real, actionable drift. A matching version, a missing
61
+ // CLI, or an undeterminable one are all silent: a fresh `npm i -g` of this
62
+ // package should not lecture someone who has not installed the CLI yet.
63
+ if (!report.drifted) return;
64
+
65
+ process.stderr.write(formatNotice(report.lines));
66
+ }
67
+
68
+ // Only run when invoked as the postinstall script, not when imported by tests.
69
+ // (Matches the isMainModule guard in scripts/generate.mjs.)
70
+ const isMainModule = import.meta.url === `file://${process.argv[1]}`;
71
+ if (isMainModule) {
72
+ // Rule 1: an install must never fail because of this notice.
73
+ try {
74
+ await main();
75
+ } catch {
76
+ // Intentionally silent — a broken notice is not worth a failed install.
77
+ }
78
+ process.exit(0);
79
+ }
@@ -0,0 +1,261 @@
1
+ // Version drift detection for the Postman CLI.
2
+ //
3
+ // Two independent comparisons, because "outdated" has two meanings here:
4
+ //
5
+ // 1. installed CLI vs. the version these completions were generated against
6
+ // (spec/commands.json.postmanCliVersion). A mismatch means completions may
7
+ // offer commands the user's CLI lacks, or miss ones it has. Offline, free.
8
+ // 2. installed CLI vs. the latest published postman-cli on npm. A mismatch
9
+ // means the user should upgrade. Requires the network.
10
+ //
11
+ // Everything that decides *what* to say is a pure function so it can be tested
12
+ // without a CLI, a network, or a filesystem.
13
+
14
+ import { execFile } from "node:child_process";
15
+ import { readFileSync } from "node:fs";
16
+
17
+ export const REGISTRY_URL = "https://registry.npmjs.org/postman-cli/latest";
18
+ export const UPGRADE_COMMAND = "npm install -g postman-cli@latest";
19
+
20
+ /**
21
+ * Parse a semver-ish string into comparable parts.
22
+ * Tolerates a leading "v", trailing prerelease/build metadata, and surrounding
23
+ * whitespace. Returns null for anything we cannot order numerically.
24
+ */
25
+ export function parseVersion(raw) {
26
+ if (typeof raw !== "string") return null;
27
+ const m = /^\s*v?(\d+)\.(\d+)\.(\d+)(?:[-+]([0-9A-Za-z.-]+))?\s*$/.exec(raw);
28
+ if (!m) return null;
29
+ return {
30
+ major: Number(m[1]),
31
+ minor: Number(m[2]),
32
+ patch: Number(m[3]),
33
+ prerelease: m[4] ?? null,
34
+ };
35
+ }
36
+
37
+ /**
38
+ * Compare two version strings. Returns -1 / 0 / 1 (a<b / a==b / a>b), or null
39
+ * if either side is unparseable — callers must treat null as "unknown", never
40
+ * as "equal", so we don't warn on garbage input.
41
+ *
42
+ * A prerelease sorts below the same x.y.z release (1.2.3-beta < 1.2.3), which
43
+ * matches semver. We deliberately do not order two different prereleases of the
44
+ * same release against each other beyond a plain string compare.
45
+ */
46
+ export function compareVersions(a, b) {
47
+ const pa = parseVersion(a);
48
+ const pb = parseVersion(b);
49
+ if (!pa || !pb) return null;
50
+
51
+ for (const part of ["major", "minor", "patch"]) {
52
+ if (pa[part] !== pb[part]) return pa[part] < pb[part] ? -1 : 1;
53
+ }
54
+ if (pa.prerelease === pb.prerelease) return 0;
55
+ if (pa.prerelease === null) return 1; // release > prerelease
56
+ if (pb.prerelease === null) return -1;
57
+ return pa.prerelease < pb.prerelease ? -1 : 1;
58
+ }
59
+
60
+ /**
61
+ * Read the installed Postman CLI version by shelling out to `postman --version`,
62
+ * which prints a bare "1.73.0".
63
+ *
64
+ * Never throws: a missing CLI, a non-zero exit, or a hang are all normal states
65
+ * for this tool (the completions package is installed independently of the CLI).
66
+ * Resolves { version, error } where exactly one side is set.
67
+ */
68
+ export function detectInstalledVersion({ command = "postman", timeoutMs = 5000 } = {}) {
69
+ return new Promise((resolvePromise) => {
70
+ execFile(command, ["--version"], { timeout: timeoutMs }, (err, stdout) => {
71
+ if (err) {
72
+ const reason =
73
+ err.code === "ENOENT"
74
+ ? `"${command}" not found on PATH`
75
+ : err.killed
76
+ ? `"${command} --version" timed out`
77
+ : `"${command} --version" failed: ${err.message.trim()}`;
78
+ resolvePromise({ version: null, error: reason });
79
+ return;
80
+ }
81
+ // Some builds print the version among other noise; take the first
82
+ // semver-looking token so we degrade gracefully rather than fail.
83
+ const match = /v?\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?/.exec(stdout ?? "");
84
+ if (!match) {
85
+ resolvePromise({
86
+ version: null,
87
+ error: `could not parse a version from "${command} --version" output`,
88
+ });
89
+ return;
90
+ }
91
+ resolvePromise({ version: match[0].replace(/^v/, ""), error: null });
92
+ });
93
+ });
94
+ }
95
+
96
+ /**
97
+ * Version of the Postman CLI that the committed spec (and therefore the shipped
98
+ * completion scripts) was generated against.
99
+ */
100
+ export function readSpecVersion(specPath) {
101
+ try {
102
+ const v = JSON.parse(readFileSync(specPath, "utf8")).postmanCliVersion;
103
+ return typeof v === "string" ? v : null;
104
+ } catch {
105
+ return null;
106
+ }
107
+ }
108
+
109
+ /**
110
+ * The CLI version these completions target.
111
+ *
112
+ * Two sources, in order:
113
+ * 1. spec/commands.json — present in a git checkout, the real source of truth.
114
+ * 2. this package's own version — release.yml runs `npm version <spec
115
+ * version>` before publishing, so an installed copy's version *is* the
116
+ * targeted Postman CLI version. This keeps the 348 kB spec out of the
117
+ * published tarball.
118
+ * In a git checkout package.json holds the placeholder
119
+ * "0.0.0-managed-by-spec". That is technically valid semver (a prerelease of
120
+ * 0.0.0), so it must be rejected explicitly — otherwise every real CLI would
121
+ * compare as "newer" and trigger a bogus drift warning.
122
+ */
123
+ export function resolveTargetVersion({ specPath, packageJsonPath }) {
124
+ const fromSpec = readSpecVersion(specPath);
125
+ if (fromSpec) return fromSpec;
126
+
127
+ try {
128
+ const v = JSON.parse(readFileSync(packageJsonPath, "utf8")).version;
129
+ const parsed = parseVersion(v);
130
+ if (!parsed) return null;
131
+ // Never trust a 0.0.0 placeholder as a real target version.
132
+ if (parsed.major === 0 && parsed.minor === 0 && parsed.patch === 0) return null;
133
+ return v;
134
+ } catch {
135
+ return null;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Ask npm for the latest published postman-cli version.
141
+ * Never throws — offline is an expected state, so failure is reported as data.
142
+ */
143
+ export async function fetchLatestVersion({
144
+ url = REGISTRY_URL,
145
+ timeoutMs = 5000,
146
+ fetchImpl = globalThis.fetch,
147
+ } = {}) {
148
+ const signal = AbortSignal.timeout(timeoutMs);
149
+ try {
150
+ const res = await fetchImpl(url, {
151
+ headers: { Accept: "application/json" },
152
+ signal,
153
+ });
154
+ if (!res.ok) return { version: null, error: `registry request failed: ${res.status}` };
155
+ const body = await res.json();
156
+ const version = typeof body?.version === "string" ? body.version : null;
157
+ return version
158
+ ? { version, error: null }
159
+ : { version: null, error: "registry response had no version field" };
160
+ } catch (err) {
161
+ const offline = err?.name === "TimeoutError" || err?.name === "AbortError";
162
+ return {
163
+ version: null,
164
+ error: offline ? "registry request timed out" : `registry request failed: ${err.message}`,
165
+ };
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Decide what to report, given the three versions. Pure.
171
+ *
172
+ * `installed` / `spec` / `latest` may each be null (unknown). Returns a report:
173
+ * { level, lines, outdated, drifted }
174
+ * where level is "ok" | "notice" | "warn" and lines are ready to print.
175
+ */
176
+ export function buildReport({ installed, spec, latest }) {
177
+ const lines = [];
178
+ let level = "ok";
179
+ const bump = (next) => {
180
+ const rank = { ok: 0, notice: 1, warn: 2 };
181
+ if (rank[next] > rank[level]) level = next;
182
+ };
183
+
184
+ if (!installed) {
185
+ return {
186
+ level: "notice",
187
+ outdated: false,
188
+ drifted: false,
189
+ lines: [
190
+ "Postman CLI not detected — install it with: npm install -g postman-cli",
191
+ "(this package only provides shell completions; it does not include the CLI)",
192
+ ],
193
+ };
194
+ }
195
+
196
+ // 1. installed vs. latest published — the upgrade suggestion.
197
+ const vsLatest = compareVersions(installed, latest);
198
+ const outdated = vsLatest === -1;
199
+ if (outdated) {
200
+ bump("warn");
201
+ lines.push(
202
+ `Your Postman CLI is outdated: installed ${installed}, latest ${latest}.`,
203
+ ` Upgrade with: ${UPGRADE_COMMAND}`,
204
+ );
205
+ } else if (vsLatest === 1) {
206
+ lines.push(`Installed Postman CLI ${installed} is newer than npm latest ${latest}.`);
207
+ } else if (vsLatest === 0) {
208
+ lines.push(`Postman CLI ${installed} is up to date.`);
209
+ }
210
+
211
+ // 2. installed vs. the spec these completions were built from — the drift
212
+ // warning. Reported separately: being on the latest CLI does not guarantee
213
+ // the completions were regenerated for it yet, and vice versa.
214
+ const vsSpec = compareVersions(installed, spec);
215
+ const drifted = vsSpec !== null && vsSpec !== 0;
216
+ if (drifted) {
217
+ bump("warn");
218
+ lines.push(
219
+ `These completions were generated for Postman CLI ${spec}, but ${installed} is installed.`,
220
+ vsSpec === -1
221
+ ? " Completions may offer commands your CLI does not have."
222
+ : " Completions may be missing commands your CLI supports.",
223
+ " Update them with: npm install -g postman-cli-completion@latest",
224
+ );
225
+ } else if (vsSpec === 0) {
226
+ lines.push(`Completions match your installed CLI (${installed}).`);
227
+ }
228
+
229
+ return { level, lines, outdated, drifted };
230
+ }
231
+
232
+ /**
233
+ * Run both comparisons and build the report.
234
+ * `offline: true` skips the registry lookup entirely (no network, no delay).
235
+ */
236
+ export async function checkVersions({
237
+ specPath,
238
+ packageJsonPath,
239
+ offline = false,
240
+ command = "postman",
241
+ timeoutMs = 5000,
242
+ fetchImpl = globalThis.fetch,
243
+ } = {}) {
244
+ const spec = resolveTargetVersion({ specPath, packageJsonPath });
245
+ const [{ version: installed, error: installError }, latestResult] = await Promise.all([
246
+ detectInstalledVersion({ command, timeoutMs }),
247
+ offline
248
+ ? Promise.resolve({ version: null, error: "skipped (offline)" })
249
+ : fetchLatestVersion({ timeoutMs, fetchImpl }),
250
+ ]);
251
+
252
+ const report = buildReport({ installed, spec, latest: latestResult.version });
253
+ return {
254
+ ...report,
255
+ installed,
256
+ spec,
257
+ latest: latestResult.version,
258
+ installError,
259
+ latestError: latestResult.error,
260
+ };
261
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postman-cli-completion",
3
- "version": "1.73.0",
3
+ "version": "1.74.0",
4
4
  "description": "Shell completions for the Postman CLI (zsh, bash, fish)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,6 +8,7 @@
8
8
  },
9
9
  "files": [
10
10
  "bin/",
11
+ "lib/",
11
12
  "completions/zsh/_postman",
12
13
  "completions/bash/postman.bash",
13
14
  "completions/fish/postman.fish",
@@ -19,6 +20,7 @@
19
20
  "generate": "node scripts/generate.mjs",
20
21
  "generate:check": "node scripts/generate.mjs --check",
21
22
  "check-version": "node scripts/check-version.mjs",
23
+ "postinstall": "node lib/postinstall.mjs",
22
24
  "test": "node --test tests/*.test.mjs",
23
25
  "prepublishOnly": "node scripts/generate.mjs --check && node --test tests/*.test.mjs"
24
26
  },