@theholocron/postman-client 1.32.0 → 1.33.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.
@@ -0,0 +1,123 @@
1
+ import "@theholocron/http-client";
2
+ import { ErrorSink, Logger } from "@theholocron/observability/core";
3
+ //#region ../../../../../src/utils.d.ts
4
+ interface PostmanClientOptions {
5
+ /** Postman API key. */
6
+ token: string;
7
+ /** Override base URL for testing. Defaults to https://api.getpostman.com. */
8
+ baseUrl?: string;
9
+ /** Override fetch for testing. Defaults to globalThis.fetch. */
10
+ fetch?: typeof fetch;
11
+ /** Structured logger for request/response diagnostics. Defaults to a no-op. */
12
+ logger?: Logger;
13
+ /** Reports transport failures and unexpected 5xx. Defaults to a no-op. */
14
+ errors?: ErrorSink;
15
+ }
16
+ //#endregion
17
+ //#region ../../../../../src/collections/collections.d.ts
18
+ interface PostmanCollection {
19
+ id: string;
20
+ uid: string;
21
+ name: string;
22
+ }
23
+ interface PostmanCollectionsResponse {
24
+ collections: PostmanCollection[];
25
+ }
26
+ //#endregion
27
+ //#region ../../../../../src/environments/environments.d.ts
28
+ interface PostmanEnvironment {
29
+ id: string;
30
+ uid: string;
31
+ name: string;
32
+ }
33
+ interface PostmanEnvironmentsResponse {
34
+ environments: PostmanEnvironment[];
35
+ }
36
+ interface PostmanEnvironmentResponse {
37
+ environment: PostmanEnvironment;
38
+ }
39
+ //#endregion
40
+ //#region ../../../../../src/import/import.d.ts
41
+ interface PostmanImportOpenApiResponse {
42
+ collections: PostmanCollection[];
43
+ }
44
+ //#endregion
45
+ //#region ../../../../../src/me/me.d.ts
46
+ interface PostmanUser {
47
+ id?: number | string;
48
+ username?: string;
49
+ email?: string;
50
+ fullName?: string;
51
+ }
52
+ interface PostmanMeResponse {
53
+ user?: PostmanUser;
54
+ }
55
+ //#endregion
56
+ //#region ../../../../../src/specs/specs.d.ts
57
+ interface PostmanSpec {
58
+ id: string;
59
+ name: string;
60
+ type: string;
61
+ }
62
+ interface PostmanSpecsResponse {
63
+ specs: PostmanSpec[];
64
+ }
65
+ interface PostmanCreateSpecInput {
66
+ name: string;
67
+ fileContent: string;
68
+ type?: string;
69
+ filePath?: string;
70
+ }
71
+ //#endregion
72
+ //#region ../../../../../src/workspaces/workspaces.d.ts
73
+ interface PostmanWorkspace {
74
+ id: string;
75
+ name: string;
76
+ type: string;
77
+ }
78
+ interface PostmanWorkspacesResponse {
79
+ workspaces: PostmanWorkspace[];
80
+ }
81
+ //#endregion
82
+ //#region ../../../../../src/errors.d.ts
83
+ /**
84
+ * Thrown when Postman returns a `limitReachedError` (e.g., a Free-tier
85
+ * account hitting the "0 APIs" cap).
86
+ */
87
+ declare class PostmanPlanLimitError extends Error {
88
+ readonly limitMessage: string;
89
+ readonly body: string;
90
+ name: string;
91
+ constructor(limitMessage: string, body: string);
92
+ }
93
+ declare function detectPlanLimit(body: string): string | null;
94
+ //#endregion
95
+ //#region ../../../../../src/index.d.ts
96
+ declare function createPostmanClient(opts: PostmanClientOptions): {
97
+ collections: {
98
+ list: (workspaceId: string) => Promise<PostmanCollectionsResponse>;
99
+ delete: (uid: string) => Promise<void>;
100
+ };
101
+ environments: {
102
+ list: (workspaceId: string) => Promise<PostmanEnvironmentsResponse>;
103
+ create: (workspaceId: string, environment: unknown) => Promise<PostmanEnvironmentResponse>;
104
+ update: (uid: string, environment: unknown) => Promise<PostmanEnvironmentResponse>;
105
+ };
106
+ import: {
107
+ openapi: (workspaceId: string, spec: unknown) => Promise<PostmanImportOpenApiResponse>;
108
+ };
109
+ me: {
110
+ get: () => Promise<PostmanMeResponse>;
111
+ };
112
+ specs: {
113
+ list: (workspaceId: string) => Promise<PostmanSpecsResponse>;
114
+ create: (workspaceId: string, input: PostmanCreateSpecInput) => Promise<PostmanSpec>;
115
+ updateFile: (specId: string, filePath: string, content: string) => Promise<void>;
116
+ };
117
+ workspaces: {
118
+ list: () => Promise<PostmanWorkspacesResponse>;
119
+ };
120
+ };
121
+ type PostmanClient = ReturnType<typeof createPostmanClient>;
122
+ //#endregion
123
+ export { PostmanClient, type PostmanClientOptions, type PostmanCollection, type PostmanCollectionsResponse, type PostmanCreateSpecInput, type PostmanEnvironment, type PostmanEnvironmentResponse, type PostmanEnvironmentsResponse, type PostmanImportOpenApiResponse, type PostmanMeResponse, PostmanPlanLimitError, type PostmanSpec, type PostmanSpecsResponse, type PostmanUser, type PostmanWorkspace, type PostmanWorkspacesResponse, createPostmanClient, detectPlanLimit };
package/dist/index.mjs ADDED
@@ -0,0 +1,136 @@
1
+ import { createRestClient } from "@theholocron/http-client";
2
+ //#region ../../../../../src/collections/collections.ts
3
+ function collections(rest) {
4
+ return {
5
+ list: (workspaceId) => rest.request("/collections", { query: { workspace: workspaceId } }),
6
+ delete: (uid) => rest.request(`/collections/${encodeURIComponent(uid)}`, { method: "DELETE" })
7
+ };
8
+ }
9
+ //#endregion
10
+ //#region ../../../../../src/environments/environments.ts
11
+ function environments(rest) {
12
+ return {
13
+ list: (workspaceId) => rest.request("/environments", { query: { workspace: workspaceId } }),
14
+ create: (workspaceId, environment) => rest.request("/environments", {
15
+ method: "POST",
16
+ query: { workspace: workspaceId },
17
+ body: { environment }
18
+ }),
19
+ update: (uid, environment) => rest.request(`/environments/${encodeURIComponent(uid)}`, {
20
+ method: "PUT",
21
+ body: { environment }
22
+ })
23
+ };
24
+ }
25
+ //#endregion
26
+ //#region ../../../../../src/import/import.ts
27
+ function importApi(rest) {
28
+ return { openapi: (workspaceId, spec) => rest.request("/import/openapi", {
29
+ method: "POST",
30
+ query: { workspace: workspaceId },
31
+ body: {
32
+ type: "string",
33
+ input: typeof spec === "string" ? spec : JSON.stringify(spec)
34
+ }
35
+ }) };
36
+ }
37
+ //#endregion
38
+ //#region ../../../../../src/me/me.ts
39
+ function me(rest) {
40
+ return { get: () => rest.request("/me") };
41
+ }
42
+ //#endregion
43
+ //#region ../../../../../src/specs/specs.ts
44
+ function specs(rest) {
45
+ return {
46
+ list: (workspaceId) => rest.request("/specs", { query: { workspaceId } }),
47
+ create: (workspaceId, input) => rest.request("/specs", {
48
+ method: "POST",
49
+ query: { workspaceId },
50
+ body: {
51
+ name: input.name,
52
+ type: input.type ?? "OPENAPI:3.0",
53
+ files: [{
54
+ path: input.filePath ?? "index.json",
55
+ content: input.fileContent
56
+ }]
57
+ }
58
+ }),
59
+ updateFile: (specId, filePath, content) => rest.request(`/specs/${encodeURIComponent(specId)}/files/${encodeURIComponent(filePath)}`, {
60
+ method: "PATCH",
61
+ body: { content }
62
+ })
63
+ };
64
+ }
65
+ //#endregion
66
+ //#region ../../../../../src/errors.ts
67
+ /**
68
+ * Thrown when Postman returns a `limitReachedError` (e.g., a Free-tier
69
+ * account hitting the "0 APIs" cap).
70
+ */
71
+ var PostmanPlanLimitError = class extends Error {
72
+ limitMessage;
73
+ body;
74
+ name = "PostmanPlanLimitError";
75
+ constructor(limitMessage, body) {
76
+ super(limitMessage);
77
+ this.limitMessage = limitMessage;
78
+ this.body = body;
79
+ }
80
+ };
81
+ function detectPlanLimit(body) {
82
+ try {
83
+ const parsed = JSON.parse(body);
84
+ if (parsed.error?.name === "limitReachedError" && parsed.error.message) return parsed.error.message;
85
+ } catch {}
86
+ return null;
87
+ }
88
+ //#endregion
89
+ //#region ../../../../../src/utils.ts
90
+ function createPostmanRestClient(opts) {
91
+ const base = createRestClient({
92
+ baseUrl: opts.baseUrl ?? "https://api.getpostman.com",
93
+ token: opts.token,
94
+ tokenScheme: "apikey",
95
+ apiKeyHeader: "x-api-key",
96
+ vendor: "Postman",
97
+ fetch: opts.fetch,
98
+ logger: opts.logger,
99
+ errors: opts.errors
100
+ });
101
+ return {
102
+ baseUrl: base.baseUrl,
103
+ async request(path, reqOpts) {
104
+ try {
105
+ return await base.request(path, reqOpts);
106
+ } catch (err) {
107
+ const details = err.details;
108
+ if (typeof details === "string") {
109
+ const limit = detectPlanLimit(details);
110
+ if (limit) throw new PostmanPlanLimitError(limit, details);
111
+ }
112
+ throw err;
113
+ }
114
+ }
115
+ };
116
+ }
117
+ //#endregion
118
+ //#region ../../../../../src/workspaces/workspaces.ts
119
+ function workspaces(rest) {
120
+ return { list: () => rest.request("/workspaces") };
121
+ }
122
+ //#endregion
123
+ //#region ../../../../../src/index.ts
124
+ function createPostmanClient(opts) {
125
+ const rest = createPostmanRestClient(opts);
126
+ return {
127
+ collections: collections(rest),
128
+ environments: environments(rest),
129
+ import: importApi(rest),
130
+ me: me(rest),
131
+ specs: specs(rest),
132
+ workspaces: workspaces(rest)
133
+ };
134
+ }
135
+ //#endregion
136
+ export { PostmanPlanLimitError, createPostmanClient, detectPlanLimit };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/postman-client",
3
- "version": "1.32.0",
3
+ "version": "1.33.0",
4
4
  "description": "A TypeScript client for the Postman API",
5
5
  "keywords": [
6
6
  "postman",
@@ -32,13 +32,13 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "@theholocron/observability": "^0.3.0",
35
- "@theholocron/http-client": "^1.32.0"
35
+ "@theholocron/http-client": "^1.33.0"
36
36
  },
37
37
  "devDependencies": {
38
38
  "@theholocron/cli": "5.0.0-alpha.79",
39
39
  "@theholocron/eslint-config": "^8.4.3",
40
40
  "@theholocron/tsconfig": "^8.2.0",
41
- "@theholocron/tsdown-config": "^8.5.2",
41
+ "@theholocron/tsdown-config": "^8.6.1",
42
42
  "@theholocron/vitest-config": "^8.2.0",
43
43
  "@types/node": "^26.4.1",
44
44
  "@vitest/coverage-v8": "^5.0.0",