@zapier/zapier-sdk 0.23.2 → 0.25.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 (52) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +29 -56
  3. package/dist/api/polling.d.ts +7 -0
  4. package/dist/api/polling.d.ts.map +1 -1
  5. package/dist/api/polling.js +21 -19
  6. package/dist/api/polling.test.js +43 -1
  7. package/dist/constants.d.ts +4 -0
  8. package/dist/constants.d.ts.map +1 -1
  9. package/dist/constants.js +4 -0
  10. package/dist/index.cjs +162 -128
  11. package/dist/index.d.mts +59 -31
  12. package/dist/index.mjs +161 -129
  13. package/dist/plugins/apps/index.d.ts.map +1 -1
  14. package/dist/plugins/apps/index.js +2 -1
  15. package/dist/plugins/apps/schemas.d.ts +1 -0
  16. package/dist/plugins/apps/schemas.d.ts.map +1 -1
  17. package/dist/plugins/apps/schemas.js +2 -1
  18. package/dist/plugins/fetch/index.d.ts +13 -5
  19. package/dist/plugins/fetch/index.d.ts.map +1 -1
  20. package/dist/plugins/fetch/index.js +85 -33
  21. package/dist/plugins/fetch/index.test.d.ts +2 -0
  22. package/dist/plugins/fetch/index.test.d.ts.map +1 -0
  23. package/dist/plugins/fetch/index.test.js +296 -0
  24. package/dist/plugins/fetch/schemas.d.ts.map +1 -1
  25. package/dist/plugins/fetch/schemas.js +10 -5
  26. package/dist/plugins/registry/index.d.ts.map +1 -1
  27. package/dist/plugins/registry/index.js +1 -0
  28. package/dist/plugins/request/index.d.ts +8 -7
  29. package/dist/plugins/request/index.d.ts.map +1 -1
  30. package/dist/plugins/request/index.js +15 -55
  31. package/dist/plugins/request/index.test.js +106 -2
  32. package/dist/plugins/request/schemas.d.ts +0 -2
  33. package/dist/plugins/request/schemas.d.ts.map +1 -1
  34. package/dist/plugins/request/schemas.js +0 -3
  35. package/dist/plugins/runAction/index.d.ts.map +1 -1
  36. package/dist/plugins/runAction/index.js +5 -3
  37. package/dist/plugins/runAction/index.test.js +16 -0
  38. package/dist/plugins/runAction/schemas.d.ts +1 -0
  39. package/dist/plugins/runAction/schemas.d.ts.map +1 -1
  40. package/dist/plugins/runAction/schemas.js +2 -1
  41. package/dist/schemas/Action.d.ts +1 -1
  42. package/dist/sdk.d.ts +8 -7
  43. package/dist/sdk.d.ts.map +1 -1
  44. package/dist/sdk.js +2 -2
  45. package/dist/types/plugin.d.ts +6 -0
  46. package/dist/types/plugin.d.ts.map +1 -1
  47. package/dist/types/properties.d.ts +2 -0
  48. package/dist/types/properties.d.ts.map +1 -1
  49. package/dist/types/properties.js +6 -1
  50. package/dist/types/sdk.d.ts +6 -0
  51. package/dist/types/sdk.d.ts.map +1 -1
  52. package/package.json +1 -1
@@ -1,54 +1,106 @@
1
1
  import { FetchUrlSchema, FetchInitSchema } from "./schemas";
2
+ import { coerceToNumericId } from "../../utils/id-utils";
2
3
  /**
3
- * Direct plugin function - takes options + sdk + context in one object
4
+ * Transforms full URLs into Relay format: /relay/{domain}/{path}
4
5
  */
5
- export const fetchPlugin = ({ sdk, context }) => {
6
- // Return flat structure - fetch goes directly to SDK
6
+ function transformUrlToRelayPath(url) {
7
+ const targetUrl = new URL(url);
8
+ return `/relay/${targetUrl.host}${targetUrl.pathname}${targetUrl.search}${targetUrl.hash}`;
9
+ }
10
+ /**
11
+ * Normalizes various header formats into a plain Record<string, string>.
12
+ */
13
+ function normalizeHeaders(optionsHeaders) {
14
+ const headers = {};
15
+ if (!optionsHeaders) {
16
+ return headers;
17
+ }
18
+ const headerEntries = optionsHeaders instanceof Headers
19
+ ? Array.from(optionsHeaders.entries())
20
+ : Array.isArray(optionsHeaders)
21
+ ? optionsHeaders
22
+ : Object.entries(optionsHeaders);
23
+ for (const [key, value] of headerEntries) {
24
+ headers[key] = value;
25
+ }
26
+ return headers;
27
+ }
28
+ /**
29
+ * Fetch plugin — the primary way to make authenticated HTTP requests through Zapier's Relay service.
30
+ * Mirrors the native fetch(url, init?) signature with additional Zapier-specific options.
31
+ */
32
+ export const fetchPlugin = ({ context }) => {
7
33
  return {
8
34
  fetch: async function fetch(url, init) {
35
+ const { api } = context;
9
36
  const startTime = Date.now();
37
+ const isNested = init?._telemetry?.isNested === true;
10
38
  try {
11
- const { authenticationId, callbackUrl, authenticationTemplate, ...fetchInit } = init || {};
12
- const result = await sdk.request({
13
- url: url.toString(),
14
- method: fetchInit.method,
39
+ const { authenticationId, callbackUrl, authenticationTemplate, _telemetry, ...fetchInit } = init || {};
40
+ const relayPath = transformUrlToRelayPath(url);
41
+ const headers = normalizeHeaders(fetchInit.headers);
42
+ // Auto-set Content-Type for JSON bodies if not already specified
43
+ const hasContentType = Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
44
+ if (fetchInit.body && !hasContentType) {
45
+ const bodyStr = typeof fetchInit.body === "string"
46
+ ? fetchInit.body
47
+ : JSON.stringify(fetchInit.body);
48
+ const trimmed = bodyStr.trimStart();
49
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
50
+ headers["Content-Type"] = "application/json; charset=utf-8";
51
+ }
52
+ }
53
+ if (authenticationId) {
54
+ headers["X-Relay-Authentication-Id"] = coerceToNumericId("authenticationId", authenticationId).toString();
55
+ }
56
+ if (callbackUrl) {
57
+ headers["X-Relay-Callback-Url"] = callbackUrl;
58
+ }
59
+ if (authenticationTemplate) {
60
+ headers["X-Authentication-Template"] = authenticationTemplate;
61
+ }
62
+ const result = await api.fetch(relayPath, {
63
+ method: fetchInit.method ?? "GET",
15
64
  body: fetchInit.body,
16
- headers: fetchInit.headers,
17
- authenticationId,
18
- callbackUrl,
19
- authenticationTemplate,
20
- _telemetry: { isNested: true },
21
- });
22
- // Emit success telemetry
23
- context.eventEmission.emitMethodCalled({
24
- method_name: "fetch",
25
- execution_duration_ms: Date.now() - startTime,
26
- success_flag: true,
27
- error_message: null,
28
- error_type: null,
29
- argument_count: init ? 2 : 1,
30
- is_paginated: false,
65
+ headers,
66
+ authRequired: true,
31
67
  });
68
+ if (!isNested) {
69
+ context.eventEmission.emitMethodCalled({
70
+ method_name: "fetch",
71
+ execution_duration_ms: Date.now() - startTime,
72
+ success_flag: true,
73
+ error_message: null,
74
+ error_type: null,
75
+ argument_count: init ? 2 : 1,
76
+ is_paginated: false,
77
+ });
78
+ }
32
79
  return result;
33
80
  }
34
81
  catch (error) {
35
- // Emit failure telemetry
36
- context.eventEmission.emitMethodCalled({
37
- method_name: "fetch",
38
- execution_duration_ms: Date.now() - startTime,
39
- success_flag: false,
40
- error_message: error instanceof Error ? error.message : String(error),
41
- error_type: error instanceof Error ? error.constructor.name : "Unknown",
42
- argument_count: init ? 2 : 1,
43
- is_paginated: false,
44
- });
82
+ if (!isNested) {
83
+ context.eventEmission.emitMethodCalled({
84
+ method_name: "fetch",
85
+ execution_duration_ms: Date.now() - startTime,
86
+ success_flag: false,
87
+ error_message: error instanceof Error ? error.message : String(error),
88
+ error_type: error instanceof Error ? error.constructor.name : "Unknown",
89
+ argument_count: init ? 2 : 1,
90
+ is_paginated: false,
91
+ });
92
+ }
45
93
  throw error;
46
94
  }
47
95
  },
48
96
  context: {
49
97
  meta: {
50
98
  fetch: {
51
- packages: ["sdk"],
99
+ description: "Make authenticated HTTP requests to any API through Zapier's Relay service. " +
100
+ "Pass an authenticationId to automatically inject the user's stored credentials " +
101
+ "(OAuth tokens, API keys, etc.) into the outgoing request. " +
102
+ "Mirrors the native fetch(url, init?) signature with additional Zapier-specific options.",
103
+ packages: ["sdk", "cli", "mcp"],
52
104
  categories: ["http"],
53
105
  returnType: "Response",
54
106
  inputParameters: [
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/plugins/fetch/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,296 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { fetchPlugin } from "./index";
3
+ import { createSdk } from "../../sdk";
4
+ import { eventEmissionPlugin } from "../eventEmission";
5
+ describe("fetch plugin", () => {
6
+ let mockApiClient;
7
+ let mockFetch;
8
+ beforeEach(() => {
9
+ vi.clearAllMocks();
10
+ mockFetch = vi.fn().mockResolvedValue(new Response('{"success": true}', {
11
+ status: 200,
12
+ headers: { "Content-Type": "application/json" },
13
+ }));
14
+ mockApiClient = {
15
+ fetch: mockFetch,
16
+ };
17
+ });
18
+ const apiPlugin = () => ({
19
+ context: {
20
+ api: mockApiClient,
21
+ },
22
+ });
23
+ function createTestSdk() {
24
+ return createSdk()
25
+ .addPlugin(() => ({
26
+ context: {
27
+ options: {},
28
+ },
29
+ }))
30
+ .addPlugin(apiPlugin)
31
+ .addPlugin(eventEmissionPlugin)
32
+ .addPlugin(fetchPlugin);
33
+ }
34
+ describe("URL transformation", () => {
35
+ it("should transform full URLs to relay path format", async () => {
36
+ const sdk = createTestSdk();
37
+ await sdk.fetch("https://api.github.com/user");
38
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.github.com/user", expect.any(Object));
39
+ });
40
+ it("should preserve query parameters and fragments", async () => {
41
+ const sdk = createTestSdk();
42
+ await sdk.fetch("https://api.example.com/search?q=test&limit=10#section");
43
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/search?q=test&limit=10#section", expect.any(Object));
44
+ });
45
+ it("should handle URLs with ports", async () => {
46
+ const sdk = createTestSdk();
47
+ await sdk.fetch("https://api.example.com:8443/data");
48
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com:8443/data", expect.any(Object));
49
+ });
50
+ it("should handle URL objects", async () => {
51
+ const sdk = createTestSdk();
52
+ await sdk.fetch(new URL("https://api.example.com/data"));
53
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", expect.any(Object));
54
+ });
55
+ });
56
+ describe("headers handling", () => {
57
+ it("should pass through regular headers", async () => {
58
+ const sdk = createTestSdk();
59
+ const headers = {
60
+ "Content-Type": "application/json",
61
+ "X-Custom-Header": "test-value",
62
+ };
63
+ await sdk.fetch("https://api.example.com/data", {
64
+ method: "POST",
65
+ headers,
66
+ });
67
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
68
+ method: "POST",
69
+ body: undefined,
70
+ headers: {
71
+ "Content-Type": "application/json",
72
+ "X-Custom-Header": "test-value",
73
+ },
74
+ authRequired: true,
75
+ });
76
+ });
77
+ it("should add relay-specific headers when provided", async () => {
78
+ const sdk = createTestSdk();
79
+ await sdk.fetch("https://api.example.com/data", {
80
+ method: "POST",
81
+ authenticationId: 123,
82
+ callbackUrl: "https://webhook.example.com/callback",
83
+ authenticationTemplate: '{"token": "{{auth.token}}"}',
84
+ });
85
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
86
+ method: "POST",
87
+ body: undefined,
88
+ headers: {
89
+ "X-Relay-Authentication-Id": "123",
90
+ "X-Relay-Callback-Url": "https://webhook.example.com/callback",
91
+ "X-Authentication-Template": '{"token": "{{auth.token}}"}',
92
+ },
93
+ authRequired: true,
94
+ });
95
+ });
96
+ it("should handle Headers object", async () => {
97
+ const sdk = createTestSdk();
98
+ const headers = new Headers();
99
+ headers.set("Content-Type", "application/json");
100
+ headers.set("Authorization", "Bearer token");
101
+ await sdk.fetch("https://api.example.com/data", { headers });
102
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
103
+ method: "GET",
104
+ body: undefined,
105
+ headers: {
106
+ "content-type": "application/json",
107
+ authorization: "Bearer token",
108
+ },
109
+ authRequired: true,
110
+ });
111
+ });
112
+ it("should handle headers as array of tuples", async () => {
113
+ const sdk = createTestSdk();
114
+ const headers = [
115
+ ["Content-Type", "application/json"],
116
+ ["X-Api-Key", "secret"],
117
+ ];
118
+ await sdk.fetch("https://api.example.com/data", { headers });
119
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
120
+ method: "GET",
121
+ body: undefined,
122
+ headers: {
123
+ "Content-Type": "application/json",
124
+ "X-Api-Key": "secret",
125
+ },
126
+ authRequired: true,
127
+ });
128
+ });
129
+ });
130
+ describe("HTTP methods", () => {
131
+ const methods = [
132
+ "GET",
133
+ "POST",
134
+ "PUT",
135
+ "DELETE",
136
+ "PATCH",
137
+ "HEAD",
138
+ "OPTIONS",
139
+ ];
140
+ methods.forEach((method) => {
141
+ it(`should support ${method} method`, async () => {
142
+ const sdk = createTestSdk();
143
+ await sdk.fetch("https://api.example.com/data", { method });
144
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
145
+ method,
146
+ body: undefined,
147
+ headers: {},
148
+ authRequired: true,
149
+ });
150
+ });
151
+ });
152
+ it("should default to GET method", async () => {
153
+ const sdk = createTestSdk();
154
+ await sdk.fetch("https://api.example.com/data");
155
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
156
+ method: "GET",
157
+ body: undefined,
158
+ headers: {},
159
+ authRequired: true,
160
+ });
161
+ });
162
+ });
163
+ describe("request body", () => {
164
+ it("should pass through request body", async () => {
165
+ const sdk = createTestSdk();
166
+ const body = '{"name": "test", "value": 42}';
167
+ await sdk.fetch("https://api.example.com/data", {
168
+ method: "POST",
169
+ body,
170
+ });
171
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
172
+ method: "POST",
173
+ body,
174
+ headers: {
175
+ "Content-Type": "application/json; charset=utf-8",
176
+ },
177
+ authRequired: true,
178
+ });
179
+ });
180
+ it("should auto-set Content-Type for JSON object bodies", async () => {
181
+ const sdk = createTestSdk();
182
+ const body = '{"key": "value"}';
183
+ await sdk.fetch("https://api.example.com/data", {
184
+ method: "POST",
185
+ body,
186
+ });
187
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
188
+ method: "POST",
189
+ body,
190
+ headers: {
191
+ "Content-Type": "application/json; charset=utf-8",
192
+ },
193
+ authRequired: true,
194
+ });
195
+ });
196
+ it("should auto-set Content-Type for JSON array bodies", async () => {
197
+ const sdk = createTestSdk();
198
+ const body = '[{"id": 1}, {"id": 2}]';
199
+ await sdk.fetch("https://api.example.com/data", {
200
+ method: "POST",
201
+ body,
202
+ });
203
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
204
+ method: "POST",
205
+ body,
206
+ headers: {
207
+ "Content-Type": "application/json; charset=utf-8",
208
+ },
209
+ authRequired: true,
210
+ });
211
+ });
212
+ it("should not override explicit Content-Type header", async () => {
213
+ const sdk = createTestSdk();
214
+ const body = '{"key": "value"}';
215
+ await sdk.fetch("https://api.example.com/data", {
216
+ method: "POST",
217
+ body,
218
+ headers: {
219
+ "Content-Type": "text/plain",
220
+ },
221
+ });
222
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
223
+ method: "POST",
224
+ body,
225
+ headers: {
226
+ "Content-Type": "text/plain",
227
+ },
228
+ authRequired: true,
229
+ });
230
+ });
231
+ it("should not set Content-Type for non-JSON bodies", async () => {
232
+ const sdk = createTestSdk();
233
+ const body = "plain text body";
234
+ await sdk.fetch("https://api.example.com/data", {
235
+ method: "POST",
236
+ body,
237
+ });
238
+ expect(mockFetch).toHaveBeenCalledWith("/relay/api.example.com/data", {
239
+ method: "POST",
240
+ body,
241
+ headers: {},
242
+ authRequired: true,
243
+ });
244
+ });
245
+ });
246
+ describe("authentication", () => {
247
+ it("should set authRequired to true in API call options", async () => {
248
+ const sdk = createTestSdk();
249
+ await sdk.fetch("https://api.example.com/data");
250
+ expect(mockFetch).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
251
+ authRequired: true,
252
+ }));
253
+ });
254
+ });
255
+ describe("response handling", () => {
256
+ it("should return the response from api.fetch", async () => {
257
+ const mockResponse = new Response('{"result": "success"}', {
258
+ status: 200,
259
+ statusText: "OK",
260
+ headers: { "Content-Type": "application/json" },
261
+ });
262
+ mockFetch.mockResolvedValue(mockResponse);
263
+ const sdk = createTestSdk();
264
+ const response = await sdk.fetch("https://api.example.com/data");
265
+ expect(response).toBe(mockResponse);
266
+ expect(response.status).toBe(200);
267
+ });
268
+ it("should handle API errors", async () => {
269
+ const error = new Error("Network error");
270
+ mockFetch.mockRejectedValue(error);
271
+ const sdk = createTestSdk();
272
+ await expect(sdk.fetch("https://api.example.com/data")).rejects.toThrow("Network error");
273
+ });
274
+ });
275
+ describe("context and metadata", () => {
276
+ it("should provide context with meta information", () => {
277
+ const sdk = createTestSdk();
278
+ const context = sdk.getContext();
279
+ expect(context.meta.fetch).toBeDefined();
280
+ expect(context.meta.fetch.inputParameters).toBeDefined();
281
+ expect(context.meta.fetch.inputParameters).toHaveLength(2);
282
+ });
283
+ it("should include cli and mcp in packages", () => {
284
+ const sdk = createTestSdk();
285
+ const context = sdk.getContext();
286
+ expect(context.meta.fetch.packages).toContain("cli");
287
+ expect(context.meta.fetch.packages).toContain("mcp");
288
+ expect(context.meta.fetch.packages).toContain("sdk");
289
+ });
290
+ it("should be in the http category", () => {
291
+ const sdk = createTestSdk();
292
+ const context = sdk.getContext();
293
+ expect(context.meta.fetch.categories).toContain("http");
294
+ });
295
+ });
296
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/fetch/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,cAAc,2DAEI,CAAC;AAEhC,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;kBA0ByB,CAAC"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/fetch/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,cAAc,2DAIxB,CAAC;AAEJ,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;kBAmCzB,CAAC"}
@@ -3,20 +3,25 @@ import { AuthenticationIdPropertySchema } from "../../types/properties";
3
3
  // Schemas for fetch function parameters
4
4
  export const FetchUrlSchema = z
5
5
  .union([z.string(), z.instanceof(URL)])
6
- .describe("The URL to fetch");
6
+ .describe("The full URL of the API endpoint to call (proxied through Zapier's Relay service)");
7
7
  export const FetchInitSchema = z
8
8
  .object({
9
9
  method: z
10
10
  .enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"])
11
- .optional(),
12
- headers: z.record(z.string(), z.string()).optional(),
11
+ .optional()
12
+ .describe("HTTP method for the request (defaults to GET)"),
13
+ headers: z
14
+ .record(z.string(), z.string())
15
+ .optional()
16
+ .describe("HTTP headers to include in the request"),
13
17
  body: z
14
18
  .union([
15
19
  z.string(),
16
20
  z.instanceof(FormData),
17
21
  z.instanceof(URLSearchParams),
18
22
  ])
19
- .optional(),
23
+ .optional()
24
+ .describe("Request body — JSON strings are auto-detected and Content-Type is set accordingly"),
20
25
  authenticationId: AuthenticationIdPropertySchema.optional(),
21
26
  callbackUrl: z
22
27
  .string()
@@ -28,4 +33,4 @@ export const FetchInitSchema = z
28
33
  .describe("Optional JSON string authentication template to bypass Notary lookup"),
29
34
  })
30
35
  .optional()
31
- .describe("Fetch options including authentication");
36
+ .describe("Request options including method, headers, body, and authentication");
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,WAAW,6BAA6B;CAAG;AAEjD,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK;QAC/C,SAAS,EAAE,qBAAqB,EAAE,CAAC;QACnC,UAAU,EAAE;YACV,GAAG,EAAE,MAAM,CAAC;YACZ,KAAK,EAAE,MAAM,CAAC;YACd,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,EAAE,CAAC;SACrB,EAAE,CAAC;KACL,CAAC;CACH;AAGD,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,EAAE,EAAE,wBAAwB;AAC5B,EAAE,EAAE,sBAAsB;AAC1B,sBAAsB,CAiJvB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,WAAW,6BAA6B;CAAG;AAEjD,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK;QAC/C,SAAS,EAAE,qBAAqB,EAAE,CAAC;QACnC,UAAU,EAAE;YACV,GAAG,EAAE,MAAM,CAAC;YACZ,KAAK,EAAE,MAAM,CAAC;YACd,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,EAAE,CAAC;SACrB,EAAE,CAAC;KACL,CAAC;CACH;AAGD,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,EAAE,EAAE,wBAAwB;AAC5B,EAAE,EAAE,sBAAsB;AAC1B,sBAAsB,CAkJvB,CAAC"}
@@ -47,6 +47,7 @@ export const registryPlugin = ({ sdk, context }) => {
47
47
  const meta = context.meta[key];
48
48
  return {
49
49
  name: key,
50
+ description: meta.description,
50
51
  type: meta.type,
51
52
  itemType: meta.itemType,
52
53
  returnType: meta.returnType,
@@ -1,7 +1,7 @@
1
- import type { Plugin } from "../../types/plugin";
2
- import type { ApiClient } from "../../api";
1
+ import type { Plugin, GetSdkType } from "../../types/plugin";
3
2
  import { RelayRequestSchema, type RelayRequestOptions } from "./schemas";
4
3
  import type { EventEmissionContext } from "../eventEmission";
4
+ import type { FetchPluginProvides } from "../fetch";
5
5
  export interface RequestPluginProvides {
6
6
  request: (options: RelayRequestOptions) => Promise<Response>;
7
7
  context: {
@@ -12,10 +12,11 @@ export interface RequestPluginProvides {
12
12
  };
13
13
  };
14
14
  }
15
- export declare const requestPlugin: Plugin<{}, // no SDK dependencies
16
- // no SDK dependencies
17
- {
18
- api: ApiClient;
19
- } & EventEmissionContext, // requires api in context
15
+ /**
16
+ * @deprecated Use `sdk.fetch(url, init?)` instead. This plugin now delegates to the fetch plugin
17
+ * and is kept only for backward compatibility. It is hidden from the CLI/MCP registries.
18
+ */
19
+ export declare const requestPlugin: Plugin<GetSdkType<FetchPluginProvides>, // requires fetch in SDK
20
+ EventEmissionContext, // requires eventEmission context for telemetry
20
21
  RequestPluginProvides>;
21
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/request/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAoB7D,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7D,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,OAAO,EAAE;gBACP,WAAW,EAAE,OAAO,kBAAkB,CAAC;aACxC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAChC,EAAE,EAAE,sBAAsB;AAC1B,AADI,sBAAsB;AAC1B;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,GAAG,oBAAoB,EAAE,0BAA0B;AACrE,qBAAqB,CA4FtB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/request/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7D,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,OAAO,EAAE;gBACP,WAAW,EAAE,OAAO,kBAAkB,CAAC;aACxC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAChC,UAAU,CAAC,mBAAmB,CAAC,EAAE,wBAAwB;AACzD,oBAAoB,EAAE,+CAA+C;AACrE,qBAAqB,CAgDtB,CAAC"}
@@ -1,64 +1,23 @@
1
1
  import { RelayRequestSchema } from "./schemas";
2
2
  import { createFunction } from "../../utils/function-utils";
3
3
  import { createTelemetryCallback } from "../../utils/telemetry-utils";
4
- import { coerceToNumericId } from "../../utils/id-utils";
4
+ import { logDeprecation } from "../../utils/logging";
5
5
  /**
6
- * Transforms full URLs into Relay format: /relay/{domain}/{path}
7
- *
8
- * @param url - The full URL to transform (e.g., "https://api.github.com/user")
9
- * @returns The relay path format (e.g., "/relay/api.github.com/user")
6
+ * @deprecated Use `sdk.fetch(url, init?)` instead. This plugin now delegates to the fetch plugin
7
+ * and is kept only for backward compatibility. It is hidden from the CLI/MCP registries.
10
8
  */
11
- function transformUrlToRelayPath(url) {
12
- const targetUrl = new URL(url);
13
- // Build the Relay path: /relay/{host}{pathname}{search}{hash}
14
- // Use host instead of hostname to include port if present
15
- const relayPath = `/relay/${targetUrl.host}${targetUrl.pathname}${targetUrl.search}${targetUrl.hash}`;
16
- return relayPath;
17
- }
18
- export const requestPlugin = ({ context }) => {
9
+ export const requestPlugin = ({ sdk, context }) => {
19
10
  async function request(options) {
20
- const { api } = context;
21
- const { url, method = "GET", body, headers: optionsHeaders, authenticationId, callbackUrl, authenticationTemplate, } = options;
22
- // Transform full URL to relay path format
23
- const relayPath = transformUrlToRelayPath(url);
24
- // Build headers for the request
25
- const headers = {};
26
- // Copy existing headers
27
- if (optionsHeaders) {
28
- const headerEntries = optionsHeaders instanceof Headers
29
- ? Array.from(optionsHeaders.entries())
30
- : Array.isArray(optionsHeaders)
31
- ? optionsHeaders
32
- : Object.entries(optionsHeaders);
33
- for (const [key, value] of headerEntries) {
34
- headers[key] = value;
35
- }
36
- }
37
- // Auto-set Content-Type for JSON bodies if not already specified
38
- const hasContentType = Object.keys(headers).some((k) => k.toLowerCase() === "content-type");
39
- if (body && !hasContentType) {
40
- const bodyStr = typeof body === "string" ? body : JSON.stringify(body);
41
- const trimmed = bodyStr.trimStart();
42
- if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
43
- headers["Content-Type"] = "application/json; charset=utf-8";
44
- }
45
- }
46
- // Add Relay-specific headers
47
- if (authenticationId) {
48
- headers["X-Relay-Authentication-Id"] = coerceToNumericId("authenticationId", authenticationId).toString();
49
- }
50
- if (callbackUrl) {
51
- headers["X-Relay-Callback-Url"] = callbackUrl;
52
- }
53
- if (authenticationTemplate) {
54
- headers["X-Authentication-Template"] = authenticationTemplate;
55
- }
56
- // Use the API client's fetch method directly - let it handle auth automatically
57
- return await api.fetch(relayPath, {
11
+ logDeprecation("request() is deprecated. Use fetch() instead.");
12
+ const { url, method, body, headers, authenticationId, callbackUrl, authenticationTemplate, } = options;
13
+ return sdk.fetch(url, {
58
14
  method,
59
- body,
60
- headers,
61
- authRequired: true,
15
+ body: body,
16
+ headers: headers,
17
+ authenticationId,
18
+ callbackUrl,
19
+ authenticationTemplate,
20
+ _telemetry: { isNested: true },
62
21
  });
63
22
  }
64
23
  const requestDefinition = createFunction(request, RelayRequestSchema, createTelemetryCallback(context.eventEmission.emitMethodCalled, request.name));
@@ -67,7 +26,8 @@ export const requestPlugin = ({ context }) => {
67
26
  context: {
68
27
  meta: {
69
28
  request: {
70
- categories: ["http"],
29
+ packages: ["cli", "mcp"],
30
+ categories: ["http", "deprecated"],
71
31
  returnType: "Response",
72
32
  inputSchema: RelayRequestSchema,
73
33
  },