@theholocron/holocron-plugin-postman 2.0.0-alpha.20 → 2.0.0-alpha.22

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.d.mts CHANGED
@@ -1,56 +1,7 @@
1
- import { Tooling, ToolingDoctorReport } from "@theholocron/cli";
1
+ import { AuthError, ResolveTokenInput, RestClient, RestClient as RestClient$1, Tooling, ToolingDoctorReport } from "@theholocron/cli";
2
2
 
3
3
  //#region src/auth.d.ts
4
- /**
5
- * Token resolution for the Postman plugin.
6
- *
7
- * Resolution order (matches the standard 4-step precedence set by
8
- * `.notes/tech-auth-bootstrap.spec.md`):
9
- * 1. explicit `cliToken` argument (from `--token` flag)
10
- * 2. HOLOCRON_POSTMAN_API_KEY env var (preferred — explicit intent)
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
14
- */
15
- declare class AuthError extends Error {
16
- name: string;
17
- }
18
- interface ResolveTokenInput {
19
- /** From `--token` CLI flag. */
20
- cliToken?: string;
21
- /** Env vars; passed in for testability. Defaults to `process.env`. */
22
- env?: NodeJS.ProcessEnv;
23
- /** Keyring lookup fn; passed in for testability. Defaults to `getToken(provider)`. */
24
- keyring?: (provider: string) => string | null;
25
- }
26
- declare function resolveToken(input?: ResolveTokenInput): string;
27
- //#endregion
28
- //#region src/rest.d.ts
29
- /**
30
- * Thin REST wrapper around api.getpostman.com.
31
- *
32
- * Same pattern as the github / vercel / neon / clerk REST clients —
33
- * the Postman API uses `x-api-key` (not bearer) for auth, but
34
- * otherwise the shape's identical: JSON only, transport-failure
35
- * wrapping with `status: 0`.
36
- */
37
- interface RestClientOptions {
38
- token: string;
39
- fetch?: typeof fetch;
40
- baseUrl?: string;
41
- }
42
- interface RequestOptions {
43
- method?: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
44
- body?: unknown;
45
- query?: Record<string, string>;
46
- }
47
- declare class PostmanRestClient {
48
- private readonly token;
49
- private readonly fetchImpl;
50
- readonly baseUrl: string;
51
- constructor(opts: RestClientOptions);
52
- request<T>(path: string, opts?: RequestOptions): Promise<T>;
53
- }
4
+ declare const resolveToken: (input?: import("@theholocron/http-client").ResolveTokenInput) => string;
54
5
  //#endregion
55
6
  //#region src/capabilities/tooling.d.ts
56
7
  interface PostmanToolingOptions {
@@ -97,7 +48,7 @@ declare class PostmanTooling implements Tooling {
97
48
  readonly providerName = "postman";
98
49
  private readonly opts;
99
50
  private readonly repoRoot;
100
- constructor(rest: PostmanRestClient, opts: PostmanToolingOptions);
51
+ constructor(rest: RestClient, opts: PostmanToolingOptions);
101
52
  sync(): Promise<void>;
102
53
  doctor(): Promise<ToolingDoctorReport>;
103
54
  getMyself(): Promise<PostmanUser>;
@@ -172,6 +123,13 @@ declare class PostmanPlanLimitError extends Error {
172
123
  */
173
124
  declare function detectPlanLimit(body: string): string | null;
174
125
  //#endregion
126
+ //#region src/rest.d.ts
127
+ declare function createPostmanRestClient(opts: {
128
+ token: string;
129
+ baseUrl?: string;
130
+ fetch?: typeof fetch;
131
+ }): RestClient$1;
132
+ //#endregion
175
133
  //#region src/verify-token.d.ts
176
134
  /**
177
135
  * `verifyToken` — plugin-level export used by `holocron auth set` +
@@ -204,7 +162,7 @@ interface PostmanPluginOptions extends ResolveTokenInput, PostmanToolingOptions
204
162
  }
205
163
  interface PluginContext {
206
164
  options: PostmanPluginOptions;
207
- rest: PostmanRestClient;
165
+ rest: RestClient;
208
166
  }
209
167
  declare function createContext(options: PostmanPluginOptions): PluginContext;
210
168
  declare function tooling(ctx: PluginContext): Tooling;
@@ -220,4 +178,4 @@ declare function createPlugin(options: PostmanPluginOptions): {
220
178
  */
221
179
  declare const AUTH_HINT: string;
222
180
  //#endregion
223
- export { AUTH_HINT, AuthError, PluginContext, PostmanPlanLimitError, PostmanPluginOptions, PostmanRestClient, PostmanTooling, ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createContext, createPlugin, detectPlanLimit, resolveToken, tooling, verifyToken };
181
+ export { AUTH_HINT, AuthError, PluginContext, PostmanPlanLimitError, PostmanPluginOptions, PostmanTooling, type ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createContext, createPlugin, createPostmanRestClient, detectPlanLimit, resolveToken, tooling, verifyToken };
package/dist/index.mjs CHANGED
@@ -1,28 +1,13 @@
1
- import { ProviderApiError, getToken } from "@theholocron/cli";
1
+ import { AuthError, ProviderApiError, createResolveToken, createRestClient } from "@theholocron/cli";
2
2
  import { readFile } from "node:fs/promises";
3
3
  import { basename, resolve } from "node:path";
4
4
  //#region src/auth.ts
5
- /**
6
- * Token resolution for the Postman plugin.
7
- *
8
- * Resolution order (matches the standard 4-step precedence set by
9
- * `.notes/tech-auth-bootstrap.spec.md`):
10
- * 1. explicit `cliToken` argument (from `--token` flag)
11
- * 2. HOLOCRON_POSTMAN_API_KEY env var (preferred — explicit intent)
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
15
- */
16
- var AuthError = class extends Error {
17
- name = "AuthError";
18
- };
19
- function resolveToken(input = {}) {
20
- const env = input.env ?? process.env;
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>");
24
- return token;
25
- }
5
+ const resolveToken = createResolveToken({
6
+ envName: "HOLOCRON_POSTMAN_API_KEY",
7
+ vendorEnvName: "POSTMAN_API_KEY",
8
+ keyringService: "postman",
9
+ errorMessage: "no Postman API key found. Pass --token <KEY>, set HOLOCRON_POSTMAN_API_KEY / POSTMAN_API_KEY, or run: holocron auth set postman <KEY>"
10
+ });
26
11
  //#endregion
27
12
  //#region src/capabilities/tooling.ts
28
13
  /**
@@ -270,60 +255,33 @@ function detectPlanLimit(body) {
270
255
  }
271
256
  //#endregion
272
257
  //#region src/rest.ts
273
- /**
274
- * Thin REST wrapper around api.getpostman.com.
275
- *
276
- * Same pattern as the github / vercel / neon / clerk REST clients —
277
- * the Postman API uses `x-api-key` (not bearer) for auth, but
278
- * otherwise the shape's identical: JSON only, transport-failure
279
- * wrapping with `status: 0`.
280
- */
281
- var PostmanRestClient = class {
282
- token;
283
- fetchImpl;
284
- baseUrl;
285
- constructor(opts) {
286
- this.token = opts.token;
287
- this.fetchImpl = opts.fetch ?? globalThis.fetch;
288
- let url = opts.baseUrl ?? "https://api.getpostman.com";
289
- while (url.endsWith("/")) url = url.slice(0, -1);
290
- this.baseUrl = url;
291
- }
292
- async request(path, opts = {}) {
293
- const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : "/" + path}`);
294
- for (const [k, v] of Object.entries(opts.query ?? {})) url.searchParams.set(k, v);
295
- const fullUrl = url.toString();
296
- const headers = {
297
- "x-api-key": this.token,
298
- accept: "application/json"
299
- };
300
- const init = {
301
- method: opts.method ?? "GET",
302
- headers
303
- };
304
- if (opts.body !== void 0) {
305
- headers["content-type"] = "application/json";
306
- init.body = JSON.stringify(opts.body);
307
- }
308
- let res;
309
- try {
310
- res = await this.fetchImpl(fullUrl, init);
311
- } catch (err) {
312
- const detail = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
313
- throw new ProviderApiError(`Postman ${init.method} ${path} failed: ${detail}`, 0, void 0);
314
- }
315
- if (!res.ok) {
316
- const body = await res.text().catch(() => "");
317
- const limit = detectPlanLimit(body);
318
- if (limit) throw new PostmanPlanLimitError(limit, body);
319
- throw new ProviderApiError(`Postman ${init.method} ${path} → ${res.status}`, res.status, body);
258
+ function createPostmanRestClient(opts) {
259
+ const base = createRestClient({
260
+ baseUrl: opts.baseUrl ?? "https://api.getpostman.com",
261
+ token: opts.token,
262
+ tokenScheme: "apikey",
263
+ apiKeyHeader: "x-api-key",
264
+ vendor: "Postman",
265
+ fetch: opts.fetch
266
+ });
267
+ return {
268
+ baseUrl: base.baseUrl,
269
+ async request(path, reqOpts) {
270
+ let res;
271
+ try {
272
+ res = await base.request(path, reqOpts);
273
+ } catch (err) {
274
+ const details = err.details;
275
+ if (typeof details === "string") {
276
+ const limit = detectPlanLimit(details);
277
+ if (limit) throw new PostmanPlanLimitError(limit, details);
278
+ }
279
+ throw err;
280
+ }
281
+ return res;
320
282
  }
321
- if (res.status === 204) return void 0;
322
- const text = await res.text();
323
- if (!text) return void 0;
324
- return JSON.parse(text);
325
- }
326
- };
283
+ };
284
+ }
327
285
  //#endregion
328
286
  //#region src/verify-token.ts
329
287
  /**
@@ -332,10 +290,11 @@ var PostmanRestClient = class {
332
290
  * authenticated user).
333
291
  */
334
292
  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);
293
+ const rest = createPostmanRestClient({
294
+ token,
295
+ baseUrl: opts.baseUrl,
296
+ fetch: opts.fetch
297
+ });
339
298
  try {
340
299
  const res = await rest.request("/me");
341
300
  return {
@@ -353,12 +312,13 @@ async function verifyToken(token, opts = {}) {
353
312
  //#region src/index.ts
354
313
  function createContext(options) {
355
314
  if (!options.workspaceId) throw new Error("@theholocron/holocron-plugin-postman requires `workspaceId` in options");
356
- const restOpts = { token: resolveToken(options) };
357
- if (options.baseUrl !== void 0) restOpts.baseUrl = options.baseUrl;
358
- if (options.fetch !== void 0) restOpts.fetch = options.fetch;
359
315
  return {
360
316
  options,
361
- rest: new PostmanRestClient(restOpts)
317
+ rest: createPostmanRestClient({
318
+ token: resolveToken(options),
319
+ baseUrl: options.baseUrl,
320
+ fetch: options.fetch
321
+ })
362
322
  };
363
323
  }
364
324
  function tooling(ctx) {
@@ -383,4 +343,4 @@ function createPlugin(options) {
383
343
  */
384
344
  const AUTH_HINT = "generate a Postman API key at https://postman.co/settings/me/api-keys, then run: holocron auth set postman <KEY>";
385
345
  //#endregion
386
- export { AUTH_HINT, AuthError, PostmanPlanLimitError, PostmanRestClient, PostmanTooling, createContext, createPlugin, detectPlanLimit, resolveToken, tooling, verifyToken };
346
+ export { AUTH_HINT, AuthError, PostmanPlanLimitError, PostmanTooling, createContext, createPlugin, createPostmanRestClient, 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.20",
3
+ "version": "2.0.0-alpha.22",
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,13 +21,14 @@
21
21
  }
22
22
  },
23
23
  "peerDependencies": {
24
- "@theholocron/cli": "2.0.0-alpha.20"
24
+ "@theholocron/cli": "2.0.0-alpha.22"
25
25
  },
26
26
  "devDependencies": {
27
- "@theholocron/eslint-config": "^5.1.2",
28
- "@theholocron/tsconfig": "^5.1.2",
29
- "@tsconfig/node-lts": "^24.0.0",
30
- "@vitest/coverage-v8": "^3.2.6",
27
+ "@types/node": "^26",
28
+ "@theholocron/eslint-config": "^5.2.0",
29
+ "@theholocron/tsconfig": "^6.0.0",
30
+ "@theholocron/tsdown-config": "^5.1.2",
31
+ "@theholocron/vitest-config": "^5.2.0",
31
32
  "@vitest/eslint-plugin": "^1.6.23",
32
33
  "eslint": "^10.7.0",
33
34
  "eslint-plugin-n": "^18.2.2",
@@ -35,8 +36,8 @@
35
36
  "tsdown": "^0.22.3",
36
37
  "tsx": "^4.22.4",
37
38
  "typescript": "^5.9.3",
38
- "vitest": "^3.2.6",
39
- "@theholocron/cli": "2.0.0-alpha.20"
39
+ "vitest": "^4.1.10",
40
+ "@theholocron/cli": "2.0.0-alpha.22"
40
41
  },
41
42
  "publishConfig": {
42
43
  "access": "public"