@postman/postman-plugin 0.3.0 → 0.4.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.
Files changed (46) hide show
  1. package/README.md +32 -8
  2. package/dist/hosts/antigravity.js +47 -0
  3. package/dist/hosts/copilot.js +60 -0
  4. package/dist/hosts/index.js +3 -1
  5. package/mcp.pi.json +2 -2
  6. package/package.json +1 -1
  7. package/skills/ai-readiness/SKILL.md +40 -44
  8. package/skills/api-discovery/SKILL.md +64 -145
  9. package/skills/api-discovery/reference/orbit.md +17 -5
  10. package/skills/api-documentation/SKILL.md +41 -46
  11. package/skills/api-engineer/SKILL.md +78 -23
  12. package/skills/api-mocking/SKILL.md +117 -163
  13. package/skills/api-monitoring/SKILL.md +52 -129
  14. package/skills/api-simulation/SKILL.md +130 -178
  15. package/skills/api-simulation/reference/sim_yaml_schema.md +41 -103
  16. package/skills/api-testing/SKILL.md +48 -95
  17. package/skills/bootstrap/SKILL.md +123 -224
  18. package/skills/ci-integration/SKILL.md +53 -113
  19. package/skills/collection-schema-v3/SKILL.md +43 -204
  20. package/skills/collection-schema-v3/reference/http.md +150 -0
  21. package/skills/datasets/SKILL.md +89 -315
  22. package/skills/datasets/reference/spreadsheets.md +25 -0
  23. package/skills/flows/SKILL.md +57 -206
  24. package/skills/flows/reference/flow_cli_flags.md +3 -2
  25. package/skills/performance-testing/SKILL.md +46 -62
  26. package/skills/performance-testing/references/jmeter-import/README.md +113 -0
  27. package/skills/performance-testing/references/jmeter-import/import-report.md +52 -0
  28. package/skills/performance-testing/references/jmeter-import/mapping-table.md +97 -0
  29. package/skills/performance-testing/references/jmeter-import/postman-perf-capabilities.md +56 -0
  30. package/skills/performance-testing/references/jmeter-import/script-translation.md +98 -0
  31. package/skills/performance-testing/references/jmeter-import/scripts/groovy_to_js.py +83 -0
  32. package/skills/performance-testing/references/jmeter-import/scripts/jmx_to_postman.py +1433 -0
  33. package/skills/postman-mcp-server/SKILL.md +53 -59
  34. package/skills/postman-mcp-server/references/docs.md +0 -1
  35. package/skills/postman-mcp-server/references/learn.md +10 -9
  36. package/skills/postman-mcp-server/references/mock.md +0 -1
  37. package/skills/postman-mcp-server/references/search.md +0 -1
  38. package/skills/postman-mcp-server/references/security.md +0 -1
  39. package/skills/postman-mcp-server/references/setup.md +0 -1
  40. package/skills/postman-mcp-server/references/sync.md +0 -1
  41. package/skills/postman-mcp-server/references/test.md +0 -1
  42. package/skills/variables/SKILL.md +44 -87
  43. package/skills/webhook-testing/SKILL.md +103 -0
  44. package/skills/webhook-testing/reference/forwarding.md +10 -0
  45. package/skills/webhook-testing/reference/outbound_webhooks.md +25 -0
  46. package/skills/webhook-testing/reference/webhook_scripts.md +163 -0
@@ -0,0 +1,163 @@
1
+ # Webhook scripts
2
+
3
+ Recipes for the `onEvent` script that `postman webhook scripts set` uploads.
4
+ Each delivery runs the script in a fresh Postman sandbox, with the incoming
5
+ request in `pm.request`. `pm.test` results appear in
6
+ `postman webhook requests describe <webhookId> <requestId>`, and the
7
+ `console.log` output appears with `--verbose`.
8
+
9
+ ```bash
10
+ postman webhook scripts set <webhookId> ./webhooks/github-on-event.js --event onEvent
11
+ ```
12
+
13
+ ## Contents
14
+
15
+ - [How webhook scripts behave](#how-webhook-scripts-behave)
16
+ - [What a script can use](#what-a-script-can-use)
17
+ - [Asserting on the payload](#asserting-on-the-payload)
18
+ - [Signature checks](#signature-checks): GitHub, Stripe, Slack, any HMAC
19
+
20
+ ## How webhook scripts behave
21
+
22
+ - **`onEvent`** runs when a request arrives, before Postman forwards or
23
+ responds. Use it to validate the payload, verify the signature, or modify
24
+ the request. **`onResponse`** runs after Postman has responded to the
25
+ sender. Use it for logging and follow-up work from your local responder
26
+ or the configured forwarding endpoint.
27
+ - **The file in the repo is the only copy you can read.** The CLI has
28
+ `scripts set` but no command that reads a script back, and a second `set`
29
+ replaces the first. Commit the script beside the handler it guards, and set
30
+ it again after you edit it. The file can be JavaScript or TypeScript.
31
+ - **No state carries over between deliveries.** A script can't remember which
32
+ event ids it has already seen, so test duplicate handling in the handler, by
33
+ replaying a request twice.
34
+ - **Secrets come from the linked environment.** Read a signing secret with
35
+ `pm.environment.get` and never write it into the file. An environment is
36
+ linked to a webhook in its settings in the Postman app. See the `variables`
37
+ skill for where a secret belongs.
38
+ - **Results are per delivery.** The console output that `--verbose` shows is
39
+ capped at 25 KB per event.
40
+ - **A script is a test, not your handler's guard.** Postman doesn't document
41
+ that a failing `pm.test` stops the request from being routed. Your handler
42
+ verifies signatures itself, whatever the script reports.
43
+
44
+ ## What a script can use
45
+
46
+ | Available | Not available |
47
+ | --- | --- |
48
+ | `pm.request.headers.get(name)`, `pm.request.body.raw` | `pm.globals`, `pm.collectionVariables`, `pm.iterationData` |
49
+ | `pm.test`, `pm.expect` | `pm.execution.setNextRequest`, `pm.visualizer` |
50
+ | `pm.environment.get`, from the environment linked to the webhook | State that lasts beyond one delivery |
51
+ | `require("crypto-js")` and other packages, from the Package Library, npm or JSR | |
52
+ | `pm.execution.runRequest`, to run a saved collection request | |
53
+
54
+ Parse and hash `pm.request.body.raw`. Postman keeps the body exactly as the
55
+ sender sent it, and every signature scheme below is computed over those exact
56
+ bytes. A body that was parsed and serialized again fails the check even when
57
+ the JSON is the same.
58
+
59
+ ## Asserting on the payload
60
+
61
+ Write down the contract the handler depends on. A test fails on the first
62
+ delivery that breaks it, instead of when the handler happens to crash.
63
+
64
+ ```javascript
65
+ // Just a reference based on expected payload, it can be of a different data type as well.
66
+ const event = JSON.parse(pm.request.body.raw);
67
+
68
+ pm.test("is a JSON event with an id and a type", function () {
69
+ pm.expect(event).to.have.property("id").that.is.a("string");
70
+ pm.expect(event).to.have.property("type").that.is.a("string");
71
+ });
72
+
73
+ pm.test("is an event this handler subscribes to", function () {
74
+ pm.expect(["payment_intent.succeeded", "payment_intent.payment_failed"])
75
+ .to.include(event.type);
76
+ });
77
+ ```
78
+
79
+ ## Signature checks
80
+
81
+ Postman also has signature-verification presets for Stripe, GitHub and Slack
82
+ in the Postman app. Use a script when you want the check in a file that can be
83
+ reviewed, or when the provider has no preset. Read the secret from the linked
84
+ environment. A secret pasted into the script ends up in the repo and in the
85
+ webhook's configuration.
86
+
87
+ ### GitHub
88
+
89
+ `X-Hub-Signature-256` is `sha256=` followed by the hex HMAC-SHA256 of the raw
90
+ body. There's no timestamp, so a replayed delivery still verifies.
91
+
92
+ ```javascript
93
+ const CryptoJS = require("crypto-js");
94
+
95
+ const secret = pm.environment.get("github_webhook_secret");
96
+ const expected = "sha256=" +
97
+ CryptoJS.HmacSHA256(pm.request.body.raw, secret).toString(CryptoJS.enc.Hex);
98
+
99
+ pm.test("GitHub signature matches the body", function () {
100
+ pm.expect(pm.request.headers.get("X-Hub-Signature-256")).to.equal(expected);
101
+ });
102
+ ```
103
+
104
+ ### Stripe
105
+
106
+ `Stripe-Signature` is `t=<unix seconds>,v1=<hex>[,v1=<hex>…]`. Stripe signs
107
+ `<t>.<raw body>` with the endpoint's whole `whsec_…` secret, prefix included.
108
+ More than one `v1` appears while a secret is being rolled, and any one of them
109
+ can match.
110
+
111
+ ```javascript
112
+ const CryptoJS = require("crypto-js");
113
+
114
+ const secret = pm.environment.get("stripe_webhook_secret");
115
+ const fields = pm.request.headers.get("Stripe-Signature").split(",");
116
+ const t = fields.find(f => f.startsWith("t=")).slice(2);
117
+ const signatures = fields.filter(f => f.startsWith("v1=")).map(f => f.slice(3));
118
+ const expected = CryptoJS.HmacSHA256(t + "." + pm.request.body.raw, secret)
119
+ .toString(CryptoJS.enc.Hex);
120
+
121
+ pm.test("Stripe signature matches the body", function () {
122
+ pm.expect(signatures).to.include(expected);
123
+ });
124
+
125
+ pm.test("Stripe timestamp is within five minutes", function () {
126
+ pm.expect(Math.abs(Date.now() / 1000 - Number(t))).to.be.below(300);
127
+ });
128
+ ```
129
+
130
+ The timestamp test fails on a replay of anything older than five minutes. That
131
+ failure is expected and doesn't mean the replay is broken.
132
+
133
+ ### Slack
134
+
135
+ Slack signs `v0:<X-Slack-Request-Timestamp>:<raw body>` with the app's signing
136
+ secret and sends `X-Slack-Signature: v0=<hex>`.
137
+
138
+ ```javascript
139
+ const CryptoJS = require("crypto-js");
140
+
141
+ const secret = pm.environment.get("slack_signing_secret");
142
+ const ts = pm.request.headers.get("X-Slack-Request-Timestamp");
143
+ const expected = "v0=" +
144
+ CryptoJS.HmacSHA256("v0:" + ts + ":" + pm.request.body.raw, secret)
145
+ .toString(CryptoJS.enc.Hex);
146
+
147
+ pm.test("Slack signature matches the body", function () {
148
+ pm.expect(pm.request.headers.get("X-Slack-Signature")).to.equal(expected);
149
+ });
150
+
151
+ pm.test("Slack timestamp is within five minutes", function () {
152
+ pm.expect(Math.abs(Date.now() / 1000 - Number(ts))).to.be.below(300);
153
+ });
154
+ ```
155
+
156
+ ### Any other HMAC scheme, including your own API's
157
+
158
+ Start from the provider's documentation, or your own if you're checking the
159
+ webhooks your API sends. Find out three things: which header carries the
160
+ signature and any prefix it uses, exactly which bytes are signed (the body
161
+ alone, or a timestamp or id joined to it), and whether the result is hex or
162
+ base64. A mismatch is nearly always one of those three. Use
163
+ `CryptoJS.enc.Base64` in place of `CryptoJS.enc.Hex` for a base64 signature.