@theholocron/holocron-plugin-postman 2.0.0-alpha.0 → 2.0.0-alpha.5
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 +43 -31
- package/dist/index.d.mts +34 -3
- package/dist/index.mjs +42 -6
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
Postman plugin for [Holocron](../cli). Implements the **multi-cardinality**
|
|
4
4
|
`tooling` capability against [Postman's REST API](https://learning.postman.com/docs/developer/postman-api/).
|
|
5
5
|
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pnpm add -D @theholocron/holocron-plugin-postman@alpha
|
|
10
|
+
```
|
|
11
|
+
|
|
6
12
|
## Why REST, not the CLI
|
|
7
13
|
|
|
8
14
|
Postman ships a CLI (`postman`, the newer + more capable successor to
|
|
@@ -19,24 +25,27 @@ Token resolution order:
|
|
|
19
25
|
2. `HOLOCRON_POSTMAN_API_KEY` env var
|
|
20
26
|
3. `POSTMAN_API_KEY` env var (Postman's own standard)
|
|
21
27
|
|
|
22
|
-
Generate the key at https://web.postman.co/settings/me/api-keys
|
|
28
|
+
Generate the key at <https://web.postman.co/settings/me/api-keys>.
|
|
23
29
|
|
|
24
30
|
## Config
|
|
25
31
|
|
|
26
32
|
```jsonc
|
|
27
33
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
"providers": {
|
|
35
|
+
"tooling": [
|
|
36
|
+
[
|
|
37
|
+
"postman",
|
|
38
|
+
{
|
|
39
|
+
"workspaceId": "00000000-0000-0000-0000-000000000000",
|
|
40
|
+
"specFile": "apps/api/openapi.json",
|
|
41
|
+
"specName": "Rando API",
|
|
42
|
+
"collectionName": "Rando API",
|
|
43
|
+
"envFiles": ["apps/api/postman-env-staging.json"],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
"storybook",
|
|
47
|
+
],
|
|
48
|
+
},
|
|
40
49
|
}
|
|
41
50
|
```
|
|
42
51
|
|
|
@@ -48,27 +57,30 @@ Generate the key at https://web.postman.co/settings/me/api-keys.
|
|
|
48
57
|
|
|
49
58
|
## What's implemented
|
|
50
59
|
|
|
51
|
-
| Method
|
|
52
|
-
|
|
|
53
|
-
| **Tooling interface**
|
|
54
|
-
| `sync()`
|
|
55
|
-
| `doctor()`
|
|
56
|
-
| **Postman-specific methods** (on `PostmanTooling`, not on the `Tooling` interface) |
|
|
57
|
-
| `getMyself`
|
|
58
|
-
| `listWorkspaces`
|
|
59
|
-
| `findCollectionByName`
|
|
60
|
-
| `deleteCollection`
|
|
61
|
-
| `importOpenApi`
|
|
62
|
-
| `findEnvironmentByName`
|
|
63
|
-
| `createEnvironment`
|
|
64
|
-
| `updateEnvironment`
|
|
65
|
-
| `findSpecByName`
|
|
66
|
-
| `createSpec`
|
|
67
|
-
| `upsertSpecFile`
|
|
60
|
+
| Method | What it does |
|
|
61
|
+
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
62
|
+
| **Tooling interface** | |
|
|
63
|
+
| `sync()` | Reads `specFile`, upserts the Spec Hub spec, delete-then-imports the collection, find-or-creates each env in `envFiles`. |
|
|
64
|
+
| `doctor()` | Probes `/me` + `/workspaces`; returns `{ ok, message }`. |
|
|
65
|
+
| **Postman-specific methods** (on `PostmanTooling`, not on the `Tooling` interface) | |
|
|
66
|
+
| `getMyself` | `GET /me` — authed user identity. |
|
|
67
|
+
| `listWorkspaces` | `GET /workspaces`. |
|
|
68
|
+
| `findCollectionByName` | `GET /collections?workspace=…` + name filter. |
|
|
69
|
+
| `deleteCollection` | `DELETE /collections/{uid}`. |
|
|
70
|
+
| `importOpenApi` | `POST /import/openapi?workspace=…` with the spec stringified into `{ type: "string", input }`. |
|
|
71
|
+
| `findEnvironmentByName` | `GET /environments?workspace=…` + name filter. |
|
|
72
|
+
| `createEnvironment` | `POST /environments?workspace=…`. |
|
|
73
|
+
| `updateEnvironment` | `PUT /environments/{uid}`. |
|
|
74
|
+
| `findSpecByName` | `GET /specs?workspaceId=…` + name filter. |
|
|
75
|
+
| `createSpec` | `POST /specs?workspaceId=…` (flat body — name/type are NOT wrapped under `spec`). |
|
|
76
|
+
| `upsertSpecFile` | `PATCH /specs/{id}/files/{path}` (PUT returns 404 here). |
|
|
68
77
|
|
|
69
78
|
## Status
|
|
70
79
|
|
|
71
|
-
|
|
80
|
+
**`v2.0.0-alpha.0`** — published on npm under the `alpha` dist-tag.
|
|
81
|
+
[Release notes](https://github.com/theholocron/holocron/releases/tag/v2.0.0-alpha.0).
|
|
82
|
+
APIs may still shift before stable v2.0.0.
|
|
83
|
+
|
|
72
84
|
`PostmanPlanLimitError` is thrown when Postman responds with
|
|
73
85
|
`limitReachedError` (e.g., Free-tier "0 APIs" cap) — callers can
|
|
74
86
|
discriminate to render "upgrade required" instead of a raw API dump.
|
package/dist/index.d.mts
CHANGED
|
@@ -4,10 +4,13 @@ import { Tooling, ToolingDoctorReport } from "@theholocron/cli";
|
|
|
4
4
|
/**
|
|
5
5
|
* Token resolution for the Postman plugin.
|
|
6
6
|
*
|
|
7
|
-
* Resolution order
|
|
7
|
+
* Resolution order (matches the standard 4-step precedence set by
|
|
8
|
+
* `.notes/tech-auth-bootstrap.spec.md`):
|
|
8
9
|
* 1. explicit `cliToken` argument (from `--token` flag)
|
|
9
10
|
* 2. HOLOCRON_POSTMAN_API_KEY env var (preferred — explicit intent)
|
|
10
11
|
* 3. POSTMAN_API_KEY env var (Postman's own default)
|
|
12
|
+
* 4. keyring (com.theholocron.cli / "postman")
|
|
13
|
+
* 5. AuthError naming all four options + the bootstrap hint
|
|
11
14
|
*/
|
|
12
15
|
declare class AuthError extends Error {
|
|
13
16
|
name: string;
|
|
@@ -17,6 +20,8 @@ interface ResolveTokenInput {
|
|
|
17
20
|
cliToken?: string;
|
|
18
21
|
/** Env vars; passed in for testability. Defaults to `process.env`. */
|
|
19
22
|
env?: NodeJS.ProcessEnv;
|
|
23
|
+
/** Keyring lookup fn; passed in for testability. Defaults to `getToken(provider)`. */
|
|
24
|
+
keyring?: (provider: string) => string | null;
|
|
20
25
|
}
|
|
21
26
|
declare function resolveToken(input?: ResolveTokenInput): string;
|
|
22
27
|
//#endregion
|
|
@@ -35,7 +40,7 @@ interface RestClientOptions {
|
|
|
35
40
|
baseUrl?: string;
|
|
36
41
|
}
|
|
37
42
|
interface RequestOptions {
|
|
38
|
-
method?:
|
|
43
|
+
method?: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
|
|
39
44
|
body?: unknown;
|
|
40
45
|
query?: Record<string, string>;
|
|
41
46
|
}
|
|
@@ -167,6 +172,27 @@ declare class PostmanPlanLimitError extends Error {
|
|
|
167
172
|
*/
|
|
168
173
|
declare function detectPlanLimit(body: string): string | null;
|
|
169
174
|
//#endregion
|
|
175
|
+
//#region src/verify-token.d.ts
|
|
176
|
+
/**
|
|
177
|
+
* `verifyToken` — plugin-level export used by `holocron auth set` +
|
|
178
|
+
* `holocron auth check`. Hits Postman's `/me` endpoint (returns the
|
|
179
|
+
* authenticated user).
|
|
180
|
+
*/
|
|
181
|
+
interface VerifyTokenSuccess {
|
|
182
|
+
ok: true;
|
|
183
|
+
subject: string;
|
|
184
|
+
}
|
|
185
|
+
interface VerifyTokenFailure {
|
|
186
|
+
ok: false;
|
|
187
|
+
message: string;
|
|
188
|
+
}
|
|
189
|
+
type VerifyTokenResult = VerifyTokenSuccess | VerifyTokenFailure;
|
|
190
|
+
interface VerifyTokenOptions {
|
|
191
|
+
baseUrl?: string;
|
|
192
|
+
fetch?: typeof fetch;
|
|
193
|
+
}
|
|
194
|
+
declare function verifyToken(token: string, opts?: VerifyTokenOptions): Promise<VerifyTokenResult>;
|
|
195
|
+
//#endregion
|
|
170
196
|
//#region src/index.d.ts
|
|
171
197
|
interface PostmanPluginOptions extends ResolveTokenInput, PostmanToolingOptions {
|
|
172
198
|
/** Working repo root. Used to resolve relative paths in specFile/envFiles. Defaults to process.cwd(). */
|
|
@@ -188,5 +214,10 @@ declare function createPlugin(options: PostmanPluginOptions): {
|
|
|
188
214
|
tooling: () => Tooling;
|
|
189
215
|
};
|
|
190
216
|
};
|
|
217
|
+
/**
|
|
218
|
+
* One-line hint printed by `holocron auth set postman` when no
|
|
219
|
+
* token is supplied or the supplied token is rejected.
|
|
220
|
+
*/
|
|
221
|
+
declare const AUTH_HINT: string;
|
|
191
222
|
//#endregion
|
|
192
|
-
export { AuthError, PluginContext, PostmanPlanLimitError, PostmanPluginOptions, PostmanRestClient, PostmanTooling, ResolveTokenInput, createContext, createPlugin, detectPlanLimit, resolveToken, tooling };
|
|
223
|
+
export { AUTH_HINT, AuthError, PluginContext, PostmanPlanLimitError, PostmanPluginOptions, PostmanRestClient, PostmanTooling, ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createContext, createPlugin, detectPlanLimit, resolveToken, tooling, verifyToken };
|
package/dist/index.mjs
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
|
+
import { ProviderApiError, getToken } from "@theholocron/cli";
|
|
1
2
|
import { readFile } from "node:fs/promises";
|
|
2
3
|
import { basename, resolve } from "node:path";
|
|
3
|
-
import { ProviderApiError } from "@theholocron/cli";
|
|
4
4
|
//#region src/auth.ts
|
|
5
5
|
/**
|
|
6
6
|
* Token resolution for the Postman plugin.
|
|
7
7
|
*
|
|
8
|
-
* Resolution order
|
|
8
|
+
* Resolution order (matches the standard 4-step precedence set by
|
|
9
|
+
* `.notes/tech-auth-bootstrap.spec.md`):
|
|
9
10
|
* 1. explicit `cliToken` argument (from `--token` flag)
|
|
10
11
|
* 2. HOLOCRON_POSTMAN_API_KEY env var (preferred — explicit intent)
|
|
11
12
|
* 3. POSTMAN_API_KEY env var (Postman's own default)
|
|
13
|
+
* 4. keyring (com.theholocron.cli / "postman")
|
|
14
|
+
* 5. AuthError naming all four options + the bootstrap hint
|
|
12
15
|
*/
|
|
13
16
|
var AuthError = class extends Error {
|
|
14
17
|
name = "AuthError";
|
|
15
18
|
};
|
|
16
19
|
function resolveToken(input = {}) {
|
|
17
20
|
const env = input.env ?? process.env;
|
|
18
|
-
const
|
|
19
|
-
|
|
21
|
+
const keyring = input.keyring ?? getToken;
|
|
22
|
+
const token = input.cliToken || env["HOLOCRON_POSTMAN_API_KEY"] || env["POSTMAN_API_KEY"] || keyring("postman");
|
|
23
|
+
if (!token) throw new AuthError("no Postman API key found. Pass --token <KEY>, set HOLOCRON_POSTMAN_API_KEY / POSTMAN_API_KEY, or run: holocron auth set postman <KEY>");
|
|
20
24
|
return token;
|
|
21
25
|
}
|
|
22
26
|
//#endregion
|
|
@@ -281,7 +285,9 @@ var PostmanRestClient = class {
|
|
|
281
285
|
constructor(opts) {
|
|
282
286
|
this.token = opts.token;
|
|
283
287
|
this.fetchImpl = opts.fetch ?? globalThis.fetch;
|
|
284
|
-
|
|
288
|
+
let url = opts.baseUrl ?? "https://api.getpostman.com";
|
|
289
|
+
while (url.endsWith("/")) url = url.slice(0, -1);
|
|
290
|
+
this.baseUrl = url;
|
|
285
291
|
}
|
|
286
292
|
async request(path, opts = {}) {
|
|
287
293
|
const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : "/" + path}`);
|
|
@@ -319,6 +325,31 @@ var PostmanRestClient = class {
|
|
|
319
325
|
}
|
|
320
326
|
};
|
|
321
327
|
//#endregion
|
|
328
|
+
//#region src/verify-token.ts
|
|
329
|
+
/**
|
|
330
|
+
* `verifyToken` — plugin-level export used by `holocron auth set` +
|
|
331
|
+
* `holocron auth check`. Hits Postman's `/me` endpoint (returns the
|
|
332
|
+
* authenticated user).
|
|
333
|
+
*/
|
|
334
|
+
async function verifyToken(token, opts = {}) {
|
|
335
|
+
const restOpts = { token };
|
|
336
|
+
if (opts.baseUrl !== void 0) restOpts.baseUrl = opts.baseUrl;
|
|
337
|
+
if (opts.fetch !== void 0) restOpts.fetch = opts.fetch;
|
|
338
|
+
const rest = new PostmanRestClient(restOpts);
|
|
339
|
+
try {
|
|
340
|
+
const res = await rest.request("/me");
|
|
341
|
+
return {
|
|
342
|
+
ok: true,
|
|
343
|
+
subject: `user @ ${res?.user?.email ?? res?.user?.username ?? res?.user?.fullName ?? String(res?.user?.id ?? "unknown")}`
|
|
344
|
+
};
|
|
345
|
+
} catch (err) {
|
|
346
|
+
return {
|
|
347
|
+
ok: false,
|
|
348
|
+
message: err instanceof Error ? err.message : String(err)
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
//#endregion
|
|
322
353
|
//#region src/index.ts
|
|
323
354
|
function createContext(options) {
|
|
324
355
|
if (!options.workspaceId) throw new Error("@theholocron/holocron-plugin-postman requires `workspaceId` in options");
|
|
@@ -346,5 +377,10 @@ function createPlugin(options) {
|
|
|
346
377
|
capabilities: { tooling: () => tooling(ctx) }
|
|
347
378
|
};
|
|
348
379
|
}
|
|
380
|
+
/**
|
|
381
|
+
* One-line hint printed by `holocron auth set postman` when no
|
|
382
|
+
* token is supplied or the supplied token is rejected.
|
|
383
|
+
*/
|
|
384
|
+
const AUTH_HINT = "generate a Postman API key at https://postman.co/settings/me/api-keys, then run: holocron auth set postman <KEY>";
|
|
349
385
|
//#endregion
|
|
350
|
-
export { AuthError, PostmanPlanLimitError, PostmanRestClient, PostmanTooling, createContext, createPlugin, detectPlanLimit, resolveToken, tooling };
|
|
386
|
+
export { AUTH_HINT, AuthError, PostmanPlanLimitError, PostmanRestClient, PostmanTooling, createContext, createPlugin, detectPlanLimit, resolveToken, tooling, verifyToken };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-postman",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.5",
|
|
4
4
|
"description": "Holocron plugin for Postman. Implements the tooling capability against Postman's REST API — workspace + collection + spec + environment sync.",
|
|
5
5
|
"homepage": "https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-postman#readme",
|
|
6
6
|
"bugs": "https://github.com/theholocron/holocron/issues",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"@theholocron/cli": "2.0.0-alpha.
|
|
24
|
+
"@theholocron/cli": "2.0.0-alpha.5"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@theholocron/tsconfig": "^4.1.0",
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"typescript": "^5.9.3",
|
|
33
33
|
"vitest": "^3.2.6",
|
|
34
34
|
"tsdown": "^0.22.3",
|
|
35
|
-
"
|
|
35
|
+
"tsx": "^4.22.4",
|
|
36
|
+
"@theholocron/cli": "2.0.0-alpha.5"
|
|
36
37
|
},
|
|
37
38
|
"publishConfig": {
|
|
38
39
|
"access": "public"
|
|
@@ -47,7 +48,8 @@
|
|
|
47
48
|
"typecheck": "tsc --noEmit",
|
|
48
49
|
"test": "vitest run",
|
|
49
50
|
"test:watch": "vitest",
|
|
50
|
-
"test:coverage": "vitest run --coverage"
|
|
51
|
+
"test:coverage": "vitest run --coverage",
|
|
52
|
+
"validate": "tsx scripts/validate.mjs"
|
|
51
53
|
},
|
|
52
54
|
"types": "./dist/index.d.mts"
|
|
53
55
|
}
|