@zapier/zapier-sdk 0.107.1 → 0.107.2
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/CHANGELOG.md +6 -0
- package/dist/{chunk-MRDFD4MP.mjs → chunk-HYFM3H36.mjs} +200 -23
- package/dist/{chunk-PFNHJW2F.cjs → chunk-Y7CGEGII.cjs} +200 -23
- package/dist/experimental.cjs +369 -369
- package/dist/experimental.mjs +2 -2
- package/dist/index.cjs +279 -279
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1308,6 +1308,16 @@ function emitOnce(onEvent, event) {
|
|
|
1308
1308
|
var { logDeprecation, resetDeprecationWarnings } = createDeprecationLogger("zapier-sdk");
|
|
1309
1309
|
|
|
1310
1310
|
// src/utils/url-utils.ts
|
|
1311
|
+
function withSearchParams({
|
|
1312
|
+
url,
|
|
1313
|
+
searchParams
|
|
1314
|
+
}) {
|
|
1315
|
+
const result = new URL(url);
|
|
1316
|
+
for (const [key, value] of Object.entries(searchParams ?? {})) {
|
|
1317
|
+
result.searchParams.set(key, value);
|
|
1318
|
+
}
|
|
1319
|
+
return result.toString();
|
|
1320
|
+
}
|
|
1311
1321
|
function getZapierBaseUrl(baseUrl) {
|
|
1312
1322
|
if (!baseUrl) {
|
|
1313
1323
|
return void 0;
|
|
@@ -2152,6 +2162,88 @@ function parseDeprecationDate(value) {
|
|
|
2152
2162
|
if (!match) return void 0;
|
|
2153
2163
|
return Number(match[1]) * 1e3;
|
|
2154
2164
|
}
|
|
2165
|
+
var RELAY_ERROR_HEADER = "x-relay-error";
|
|
2166
|
+
var RELAY_TIMEOUT_HEADER = "x-relay-extended-timeout";
|
|
2167
|
+
var SDK_CORRELATION_HEADER = "zapier-correlation-id";
|
|
2168
|
+
var SDK_MAX_TIME_HEADER = "x-zapier-sdk-max-time";
|
|
2169
|
+
var RELAY_NATIVE_TIMEOUT_SECONDS = 30;
|
|
2170
|
+
var RELAY_TIMEOUT_TIERS = [
|
|
2171
|
+
{ seconds: 60, headerValue: "1m" },
|
|
2172
|
+
{ seconds: 180, headerValue: "3m" },
|
|
2173
|
+
{ seconds: 300, headerValue: "5m" },
|
|
2174
|
+
{ seconds: 600, headerValue: "10m" }
|
|
2175
|
+
];
|
|
2176
|
+
function transformRelayRequestHeaders({
|
|
2177
|
+
headers,
|
|
2178
|
+
debugLog
|
|
2179
|
+
}) {
|
|
2180
|
+
applyTimeoutTierPolicy({ headers, debugLog });
|
|
2181
|
+
applyCorrelationIdPolicy({ headers });
|
|
2182
|
+
return headers;
|
|
2183
|
+
}
|
|
2184
|
+
function applyCorrelationIdPolicy({ headers }) {
|
|
2185
|
+
const correlationId = headers.get(SDK_CORRELATION_HEADER);
|
|
2186
|
+
if (correlationId !== null && !isValidRelayCorrelationId(correlationId)) {
|
|
2187
|
+
headers.delete(SDK_CORRELATION_HEADER);
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
function applyTimeoutTierPolicy({
|
|
2191
|
+
headers,
|
|
2192
|
+
debugLog
|
|
2193
|
+
}) {
|
|
2194
|
+
const sdkMaxTimeSeconds = headers.get(SDK_MAX_TIME_HEADER);
|
|
2195
|
+
headers.delete(SDK_MAX_TIME_HEADER);
|
|
2196
|
+
if (headers.has(RELAY_TIMEOUT_HEADER) || sdkMaxTimeSeconds === null) {
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
const seconds = parsePositiveInteger(sdkMaxTimeSeconds);
|
|
2200
|
+
if (seconds === void 0 || seconds <= RELAY_NATIVE_TIMEOUT_SECONDS) {
|
|
2201
|
+
return;
|
|
2202
|
+
}
|
|
2203
|
+
const match = RELAY_TIMEOUT_TIERS.find(
|
|
2204
|
+
(candidate) => candidate.seconds >= seconds
|
|
2205
|
+
);
|
|
2206
|
+
const tier = match ?? RELAY_TIMEOUT_TIERS[RELAY_TIMEOUT_TIERS.length - 1];
|
|
2207
|
+
if (!match) {
|
|
2208
|
+
debugLog?.(
|
|
2209
|
+
`Relay timeout of ${seconds}s exceeds the largest tier; capping to ${tier.headerValue}`
|
|
2210
|
+
);
|
|
2211
|
+
}
|
|
2212
|
+
headers.set(RELAY_TIMEOUT_HEADER, tier.headerValue);
|
|
2213
|
+
}
|
|
2214
|
+
function transformRelayResponseHeaders({
|
|
2215
|
+
headers
|
|
2216
|
+
}) {
|
|
2217
|
+
const relayError = headers.get(RELAY_ERROR_HEADER);
|
|
2218
|
+
if (!relayError?.startsWith("Authentication Template Failure")) {
|
|
2219
|
+
return headers;
|
|
2220
|
+
}
|
|
2221
|
+
const templateMatch = relayError.match(
|
|
2222
|
+
/Unable to find template for ([^@]+)@/
|
|
2223
|
+
);
|
|
2224
|
+
if (!templateMatch?.[1]) {
|
|
2225
|
+
return headers;
|
|
2226
|
+
}
|
|
2227
|
+
const appName = templateMatch[1].replace(/CLIAPI$/, "").replace(/([a-z])([A-Z])/g, "$1 $2").trim();
|
|
2228
|
+
if (!appName) {
|
|
2229
|
+
return headers;
|
|
2230
|
+
}
|
|
2231
|
+
headers.set(
|
|
2232
|
+
RELAY_ERROR_HEADER,
|
|
2233
|
+
`${appName} does not support direct HTTP requests. Use zapier.apps.{appKey} or zapier.runAction() to use Actions built for this app.`
|
|
2234
|
+
);
|
|
2235
|
+
return headers;
|
|
2236
|
+
}
|
|
2237
|
+
var RelayCorrelationIdSchema = z.uuid();
|
|
2238
|
+
function isValidRelayCorrelationId(value) {
|
|
2239
|
+
return RelayCorrelationIdSchema.safeParse(value).success;
|
|
2240
|
+
}
|
|
2241
|
+
function parsePositiveInteger(value) {
|
|
2242
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
2243
|
+
return void 0;
|
|
2244
|
+
}
|
|
2245
|
+
return Number(value);
|
|
2246
|
+
}
|
|
2155
2247
|
|
|
2156
2248
|
// src/api/routing/config.ts
|
|
2157
2249
|
var pathConfig = {
|
|
@@ -2159,7 +2251,11 @@ var pathConfig = {
|
|
|
2159
2251
|
"/relay": {
|
|
2160
2252
|
authHeader: "X-Relay-Authorization",
|
|
2161
2253
|
pathPrefix: "/api/v0/sdk/relay",
|
|
2162
|
-
omitDeprecationMessaging: true
|
|
2254
|
+
omitDeprecationMessaging: true,
|
|
2255
|
+
override: {
|
|
2256
|
+
transformRequestHeaders: transformRelayRequestHeaders,
|
|
2257
|
+
transformResponseHeaders: transformRelayResponseHeaders
|
|
2258
|
+
}
|
|
2163
2259
|
},
|
|
2164
2260
|
// The concrete gateway form of the relay route. Callers that pass the
|
|
2165
2261
|
// already-prefixed path reach the same third-party upstreams, so it must
|
|
@@ -2434,10 +2530,13 @@ function resolveOverrideRoute({
|
|
|
2434
2530
|
}) {
|
|
2435
2531
|
const { matchedPrefix, routeConfig, override } = overrideMatch;
|
|
2436
2532
|
const directPath = deriveDirectPath({ path, matchedPrefix, routeConfig });
|
|
2533
|
+
const overrideConfig = routeConfig.override?.enabled === false ? void 0 : routeConfig.override;
|
|
2437
2534
|
return {
|
|
2438
2535
|
url: buildRouteOverrideUrl({ origin: override.origin, path: directPath }),
|
|
2439
2536
|
pathConfig: routeConfig,
|
|
2440
|
-
canSendDeprecationMessaging: false
|
|
2537
|
+
canSendDeprecationMessaging: false,
|
|
2538
|
+
...overrideConfig?.transformRequestHeaders ? { transformRequestHeaders: overrideConfig.transformRequestHeaders } : {},
|
|
2539
|
+
...overrideConfig?.transformResponseHeaders ? { transformResponseHeaders: overrideConfig.transformResponseHeaders } : {}
|
|
2441
2540
|
};
|
|
2442
2541
|
}
|
|
2443
2542
|
function deriveDirectPath({
|
|
@@ -2617,6 +2716,89 @@ function isRouteOverrideEnabled({
|
|
|
2617
2716
|
return routeConfig.override?.enabled !== false;
|
|
2618
2717
|
}
|
|
2619
2718
|
|
|
2719
|
+
// src/api/routing/headers/request.ts
|
|
2720
|
+
function applyRequestHeaderTransform({
|
|
2721
|
+
headers,
|
|
2722
|
+
resolvedRoute,
|
|
2723
|
+
debugLog
|
|
2724
|
+
}) {
|
|
2725
|
+
return resolvedRoute?.transformRequestHeaders?.({ headers, debugLog }) ?? headers;
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
// src/api/routing/headers/response.ts
|
|
2729
|
+
var NULL_BODY_RESPONSE_STATUSES = /* @__PURE__ */ new Set([204, 205, 304]);
|
|
2730
|
+
function applyResponseHeaderTransform({
|
|
2731
|
+
response,
|
|
2732
|
+
resolvedRoute
|
|
2733
|
+
}) {
|
|
2734
|
+
const transformHeaders = resolvedRoute?.transformResponseHeaders;
|
|
2735
|
+
if (!transformHeaders) {
|
|
2736
|
+
return response;
|
|
2737
|
+
}
|
|
2738
|
+
if (!Number.isInteger(response.status) || response.status < 200 || response.status > 599 || response.bodyUsed || response.body?.locked) {
|
|
2739
|
+
return response;
|
|
2740
|
+
}
|
|
2741
|
+
const originalHeaders = response.headers;
|
|
2742
|
+
if (!originalHeaders) {
|
|
2743
|
+
return response;
|
|
2744
|
+
}
|
|
2745
|
+
const transformedHeaders = transformHeaders({
|
|
2746
|
+
headers: new Headers(originalHeaders)
|
|
2747
|
+
});
|
|
2748
|
+
if (areHeadersEqual({ first: originalHeaders, second: transformedHeaders })) {
|
|
2749
|
+
return response;
|
|
2750
|
+
}
|
|
2751
|
+
const transformedResponse = new Response(
|
|
2752
|
+
NULL_BODY_RESPONSE_STATUSES.has(response.status) ? null : response.body,
|
|
2753
|
+
{
|
|
2754
|
+
status: response.status,
|
|
2755
|
+
statusText: response.statusText,
|
|
2756
|
+
headers: transformedHeaders
|
|
2757
|
+
}
|
|
2758
|
+
);
|
|
2759
|
+
return preserveResponseMetadata({
|
|
2760
|
+
response: transformedResponse,
|
|
2761
|
+
source: response
|
|
2762
|
+
});
|
|
2763
|
+
}
|
|
2764
|
+
function preserveResponseMetadata({
|
|
2765
|
+
response,
|
|
2766
|
+
source
|
|
2767
|
+
}) {
|
|
2768
|
+
const nativeClone = response.clone;
|
|
2769
|
+
Object.defineProperties(response, {
|
|
2770
|
+
clone: {
|
|
2771
|
+
configurable: true,
|
|
2772
|
+
writable: true,
|
|
2773
|
+
value: function clone() {
|
|
2774
|
+
const clonedResponse = nativeClone.call(this);
|
|
2775
|
+
return this === response ? preserveResponseMetadata({ response: clonedResponse, source }) : clonedResponse;
|
|
2776
|
+
}
|
|
2777
|
+
},
|
|
2778
|
+
...sourceMetadataDescriptors(source)
|
|
2779
|
+
});
|
|
2780
|
+
return response;
|
|
2781
|
+
}
|
|
2782
|
+
function sourceMetadataDescriptors(source) {
|
|
2783
|
+
const descriptors = {};
|
|
2784
|
+
for (const key of ["redirected", "type", "url"]) {
|
|
2785
|
+
if (source[key] !== void 0) {
|
|
2786
|
+
descriptors[key] = { configurable: true, value: source[key] };
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
return descriptors;
|
|
2790
|
+
}
|
|
2791
|
+
function areHeadersEqual({
|
|
2792
|
+
first,
|
|
2793
|
+
second
|
|
2794
|
+
}) {
|
|
2795
|
+
const firstEntries = [...first.entries()];
|
|
2796
|
+
const secondEntries = [...second.entries()];
|
|
2797
|
+
return firstEntries.length === secondEntries.length && firstEntries.every(
|
|
2798
|
+
([key, value], index) => secondEntries[index]?.[0] === key && secondEntries[index]?.[1] === value
|
|
2799
|
+
);
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2620
2802
|
// src/api/routing/index.ts
|
|
2621
2803
|
var routingConfig = createRoutingConfig({ pathConfig });
|
|
2622
2804
|
function parseRoutingOptions({
|
|
@@ -2684,7 +2866,7 @@ function logRouteOverride({
|
|
|
2684
2866
|
}
|
|
2685
2867
|
|
|
2686
2868
|
// src/sdk-version.ts
|
|
2687
|
-
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.107.
|
|
2869
|
+
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.107.2" : void 0) || "unknown";
|
|
2688
2870
|
|
|
2689
2871
|
// src/utils/open-url.ts
|
|
2690
2872
|
var nodePrefix = "node:";
|
|
@@ -2824,14 +3006,14 @@ var ZapierApiClient = class {
|
|
|
2824
3006
|
* auth/retry pipeline instead of reaching for `this.options.fetch`
|
|
2825
3007
|
* directly and drifting.
|
|
2826
3008
|
*/
|
|
2827
|
-
this.rawFetchUrl = async (url, init,
|
|
3009
|
+
this.rawFetchUrl = async (url, init, resolvedRoute) => {
|
|
2828
3010
|
const { [CORRELATION_CALL_ID]: callId, ...fetchInit } = init ?? {};
|
|
2829
3011
|
if (fetchInit.body && (isPlainObject(fetchInit.body) || Array.isArray(fetchInit.body))) {
|
|
2830
3012
|
fetchInit.body = JSON.stringify(fetchInit.body);
|
|
2831
3013
|
}
|
|
2832
3014
|
const builtHeaders = await this.buildHeaders(
|
|
2833
3015
|
fetchInit,
|
|
2834
|
-
|
|
3016
|
+
resolvedRoute?.pathConfig
|
|
2835
3017
|
);
|
|
2836
3018
|
const inputHeaders = new Headers(fetchInit.headers ?? {});
|
|
2837
3019
|
const mergedHeaders = new Headers();
|
|
@@ -2842,6 +3024,11 @@ var ZapierApiClient = class {
|
|
|
2842
3024
|
mergedHeaders.set(key, value);
|
|
2843
3025
|
});
|
|
2844
3026
|
this.applyTelemetryHeaders({ headers: mergedHeaders, callId });
|
|
3027
|
+
const outboundHeaders = applyRequestHeaderTransform({
|
|
3028
|
+
headers: mergedHeaders,
|
|
3029
|
+
resolvedRoute,
|
|
3030
|
+
debugLog: this.options.debugLog
|
|
3031
|
+
});
|
|
2845
3032
|
const {
|
|
2846
3033
|
authRequired: _authRequired,
|
|
2847
3034
|
requiredScopes: _requiredScopes,
|
|
@@ -2854,11 +3041,11 @@ var ZapierApiClient = class {
|
|
|
2854
3041
|
const request = {
|
|
2855
3042
|
...wireInit,
|
|
2856
3043
|
url,
|
|
2857
|
-
headers: Object.fromEntries(
|
|
3044
|
+
headers: Object.fromEntries(outboundHeaders)
|
|
2858
3045
|
};
|
|
2859
3046
|
const response = await this.options.sendHttpRequest(request);
|
|
2860
3047
|
if (response.status !== 429) {
|
|
2861
|
-
return response;
|
|
3048
|
+
return applyResponseHeaderTransform({ response, resolvedRoute });
|
|
2862
3049
|
}
|
|
2863
3050
|
throw new ZapierRateLimitError(
|
|
2864
3051
|
await this.readRateLimitErrorMessage(response),
|
|
@@ -2928,10 +3115,10 @@ var ZapierApiClient = class {
|
|
|
2928
3115
|
*/
|
|
2929
3116
|
this.rawFetch = async (path, init) => {
|
|
2930
3117
|
validateSdkPath(path);
|
|
2931
|
-
const { url,
|
|
3118
|
+
const { url, resolvedRoute } = this.buildUrl(path, init?.searchParams);
|
|
2932
3119
|
return this.withSemaphore(
|
|
2933
3120
|
{ url, method: init?.method ?? "GET", signal: init?.signal },
|
|
2934
|
-
() => this.rawFetchUrl(url, init,
|
|
3121
|
+
() => this.rawFetchUrl(url, init, resolvedRoute)
|
|
2935
3122
|
);
|
|
2936
3123
|
};
|
|
2937
3124
|
this.runApprovalFetchLoop = async ({
|
|
@@ -3341,22 +3528,12 @@ var ZapierApiClient = class {
|
|
|
3341
3528
|
debugLog: this.options.debugLog
|
|
3342
3529
|
});
|
|
3343
3530
|
}
|
|
3344
|
-
// Helper to build full URLs and return routing info
|
|
3345
3531
|
buildUrl(path, searchParams) {
|
|
3346
|
-
const
|
|
3347
|
-
url,
|
|
3348
|
-
pathConfig: config,
|
|
3349
|
-
canSendDeprecationMessaging
|
|
3350
|
-
} = this.applyPathConfiguration(path);
|
|
3351
|
-
if (searchParams) {
|
|
3352
|
-
Object.entries(searchParams).forEach(([key, value]) => {
|
|
3353
|
-
url.searchParams.set(key, value);
|
|
3354
|
-
});
|
|
3355
|
-
}
|
|
3532
|
+
const resolvedRoute = this.applyPathConfiguration(path);
|
|
3356
3533
|
return {
|
|
3357
|
-
url: url.
|
|
3358
|
-
|
|
3359
|
-
canSendDeprecationMessaging
|
|
3534
|
+
url: withSearchParams({ url: resolvedRoute.url, searchParams }),
|
|
3535
|
+
resolvedRoute,
|
|
3536
|
+
canSendDeprecationMessaging: resolvedRoute.canSendDeprecationMessaging
|
|
3360
3537
|
};
|
|
3361
3538
|
}
|
|
3362
3539
|
// Helper to build headers
|
|
@@ -1309,6 +1309,16 @@ function emitOnce(onEvent, event) {
|
|
|
1309
1309
|
var { logDeprecation, resetDeprecationWarnings } = kitcore.createDeprecationLogger("zapier-sdk");
|
|
1310
1310
|
|
|
1311
1311
|
// src/utils/url-utils.ts
|
|
1312
|
+
function withSearchParams({
|
|
1313
|
+
url,
|
|
1314
|
+
searchParams
|
|
1315
|
+
}) {
|
|
1316
|
+
const result = new URL(url);
|
|
1317
|
+
for (const [key, value] of Object.entries(searchParams ?? {})) {
|
|
1318
|
+
result.searchParams.set(key, value);
|
|
1319
|
+
}
|
|
1320
|
+
return result.toString();
|
|
1321
|
+
}
|
|
1312
1322
|
function getZapierBaseUrl(baseUrl) {
|
|
1313
1323
|
if (!baseUrl) {
|
|
1314
1324
|
return void 0;
|
|
@@ -2153,6 +2163,88 @@ function parseDeprecationDate(value) {
|
|
|
2153
2163
|
if (!match) return void 0;
|
|
2154
2164
|
return Number(match[1]) * 1e3;
|
|
2155
2165
|
}
|
|
2166
|
+
var RELAY_ERROR_HEADER = "x-relay-error";
|
|
2167
|
+
var RELAY_TIMEOUT_HEADER = "x-relay-extended-timeout";
|
|
2168
|
+
var SDK_CORRELATION_HEADER = "zapier-correlation-id";
|
|
2169
|
+
var SDK_MAX_TIME_HEADER = "x-zapier-sdk-max-time";
|
|
2170
|
+
var RELAY_NATIVE_TIMEOUT_SECONDS = 30;
|
|
2171
|
+
var RELAY_TIMEOUT_TIERS = [
|
|
2172
|
+
{ seconds: 60, headerValue: "1m" },
|
|
2173
|
+
{ seconds: 180, headerValue: "3m" },
|
|
2174
|
+
{ seconds: 300, headerValue: "5m" },
|
|
2175
|
+
{ seconds: 600, headerValue: "10m" }
|
|
2176
|
+
];
|
|
2177
|
+
function transformRelayRequestHeaders({
|
|
2178
|
+
headers,
|
|
2179
|
+
debugLog
|
|
2180
|
+
}) {
|
|
2181
|
+
applyTimeoutTierPolicy({ headers, debugLog });
|
|
2182
|
+
applyCorrelationIdPolicy({ headers });
|
|
2183
|
+
return headers;
|
|
2184
|
+
}
|
|
2185
|
+
function applyCorrelationIdPolicy({ headers }) {
|
|
2186
|
+
const correlationId = headers.get(SDK_CORRELATION_HEADER);
|
|
2187
|
+
if (correlationId !== null && !isValidRelayCorrelationId(correlationId)) {
|
|
2188
|
+
headers.delete(SDK_CORRELATION_HEADER);
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
function applyTimeoutTierPolicy({
|
|
2192
|
+
headers,
|
|
2193
|
+
debugLog
|
|
2194
|
+
}) {
|
|
2195
|
+
const sdkMaxTimeSeconds = headers.get(SDK_MAX_TIME_HEADER);
|
|
2196
|
+
headers.delete(SDK_MAX_TIME_HEADER);
|
|
2197
|
+
if (headers.has(RELAY_TIMEOUT_HEADER) || sdkMaxTimeSeconds === null) {
|
|
2198
|
+
return;
|
|
2199
|
+
}
|
|
2200
|
+
const seconds = parsePositiveInteger(sdkMaxTimeSeconds);
|
|
2201
|
+
if (seconds === void 0 || seconds <= RELAY_NATIVE_TIMEOUT_SECONDS) {
|
|
2202
|
+
return;
|
|
2203
|
+
}
|
|
2204
|
+
const match = RELAY_TIMEOUT_TIERS.find(
|
|
2205
|
+
(candidate) => candidate.seconds >= seconds
|
|
2206
|
+
);
|
|
2207
|
+
const tier = match ?? RELAY_TIMEOUT_TIERS[RELAY_TIMEOUT_TIERS.length - 1];
|
|
2208
|
+
if (!match) {
|
|
2209
|
+
debugLog?.(
|
|
2210
|
+
`Relay timeout of ${seconds}s exceeds the largest tier; capping to ${tier.headerValue}`
|
|
2211
|
+
);
|
|
2212
|
+
}
|
|
2213
|
+
headers.set(RELAY_TIMEOUT_HEADER, tier.headerValue);
|
|
2214
|
+
}
|
|
2215
|
+
function transformRelayResponseHeaders({
|
|
2216
|
+
headers
|
|
2217
|
+
}) {
|
|
2218
|
+
const relayError = headers.get(RELAY_ERROR_HEADER);
|
|
2219
|
+
if (!relayError?.startsWith("Authentication Template Failure")) {
|
|
2220
|
+
return headers;
|
|
2221
|
+
}
|
|
2222
|
+
const templateMatch = relayError.match(
|
|
2223
|
+
/Unable to find template for ([^@]+)@/
|
|
2224
|
+
);
|
|
2225
|
+
if (!templateMatch?.[1]) {
|
|
2226
|
+
return headers;
|
|
2227
|
+
}
|
|
2228
|
+
const appName = templateMatch[1].replace(/CLIAPI$/, "").replace(/([a-z])([A-Z])/g, "$1 $2").trim();
|
|
2229
|
+
if (!appName) {
|
|
2230
|
+
return headers;
|
|
2231
|
+
}
|
|
2232
|
+
headers.set(
|
|
2233
|
+
RELAY_ERROR_HEADER,
|
|
2234
|
+
`${appName} does not support direct HTTP requests. Use zapier.apps.{appKey} or zapier.runAction() to use Actions built for this app.`
|
|
2235
|
+
);
|
|
2236
|
+
return headers;
|
|
2237
|
+
}
|
|
2238
|
+
var RelayCorrelationIdSchema = zod.z.uuid();
|
|
2239
|
+
function isValidRelayCorrelationId(value) {
|
|
2240
|
+
return RelayCorrelationIdSchema.safeParse(value).success;
|
|
2241
|
+
}
|
|
2242
|
+
function parsePositiveInteger(value) {
|
|
2243
|
+
if (!/^[1-9]\d*$/.test(value)) {
|
|
2244
|
+
return void 0;
|
|
2245
|
+
}
|
|
2246
|
+
return Number(value);
|
|
2247
|
+
}
|
|
2156
2248
|
|
|
2157
2249
|
// src/api/routing/config.ts
|
|
2158
2250
|
var pathConfig = {
|
|
@@ -2160,7 +2252,11 @@ var pathConfig = {
|
|
|
2160
2252
|
"/relay": {
|
|
2161
2253
|
authHeader: "X-Relay-Authorization",
|
|
2162
2254
|
pathPrefix: "/api/v0/sdk/relay",
|
|
2163
|
-
omitDeprecationMessaging: true
|
|
2255
|
+
omitDeprecationMessaging: true,
|
|
2256
|
+
override: {
|
|
2257
|
+
transformRequestHeaders: transformRelayRequestHeaders,
|
|
2258
|
+
transformResponseHeaders: transformRelayResponseHeaders
|
|
2259
|
+
}
|
|
2164
2260
|
},
|
|
2165
2261
|
// The concrete gateway form of the relay route. Callers that pass the
|
|
2166
2262
|
// already-prefixed path reach the same third-party upstreams, so it must
|
|
@@ -2435,10 +2531,13 @@ function resolveOverrideRoute({
|
|
|
2435
2531
|
}) {
|
|
2436
2532
|
const { matchedPrefix, routeConfig, override } = overrideMatch;
|
|
2437
2533
|
const directPath = deriveDirectPath({ path, matchedPrefix, routeConfig });
|
|
2534
|
+
const overrideConfig = routeConfig.override?.enabled === false ? void 0 : routeConfig.override;
|
|
2438
2535
|
return {
|
|
2439
2536
|
url: buildRouteOverrideUrl({ origin: override.origin, path: directPath }),
|
|
2440
2537
|
pathConfig: routeConfig,
|
|
2441
|
-
canSendDeprecationMessaging: false
|
|
2538
|
+
canSendDeprecationMessaging: false,
|
|
2539
|
+
...overrideConfig?.transformRequestHeaders ? { transformRequestHeaders: overrideConfig.transformRequestHeaders } : {},
|
|
2540
|
+
...overrideConfig?.transformResponseHeaders ? { transformResponseHeaders: overrideConfig.transformResponseHeaders } : {}
|
|
2442
2541
|
};
|
|
2443
2542
|
}
|
|
2444
2543
|
function deriveDirectPath({
|
|
@@ -2618,6 +2717,89 @@ function isRouteOverrideEnabled({
|
|
|
2618
2717
|
return routeConfig.override?.enabled !== false;
|
|
2619
2718
|
}
|
|
2620
2719
|
|
|
2720
|
+
// src/api/routing/headers/request.ts
|
|
2721
|
+
function applyRequestHeaderTransform({
|
|
2722
|
+
headers,
|
|
2723
|
+
resolvedRoute,
|
|
2724
|
+
debugLog
|
|
2725
|
+
}) {
|
|
2726
|
+
return resolvedRoute?.transformRequestHeaders?.({ headers, debugLog }) ?? headers;
|
|
2727
|
+
}
|
|
2728
|
+
|
|
2729
|
+
// src/api/routing/headers/response.ts
|
|
2730
|
+
var NULL_BODY_RESPONSE_STATUSES = /* @__PURE__ */ new Set([204, 205, 304]);
|
|
2731
|
+
function applyResponseHeaderTransform({
|
|
2732
|
+
response,
|
|
2733
|
+
resolvedRoute
|
|
2734
|
+
}) {
|
|
2735
|
+
const transformHeaders = resolvedRoute?.transformResponseHeaders;
|
|
2736
|
+
if (!transformHeaders) {
|
|
2737
|
+
return response;
|
|
2738
|
+
}
|
|
2739
|
+
if (!Number.isInteger(response.status) || response.status < 200 || response.status > 599 || response.bodyUsed || response.body?.locked) {
|
|
2740
|
+
return response;
|
|
2741
|
+
}
|
|
2742
|
+
const originalHeaders = response.headers;
|
|
2743
|
+
if (!originalHeaders) {
|
|
2744
|
+
return response;
|
|
2745
|
+
}
|
|
2746
|
+
const transformedHeaders = transformHeaders({
|
|
2747
|
+
headers: new Headers(originalHeaders)
|
|
2748
|
+
});
|
|
2749
|
+
if (areHeadersEqual({ first: originalHeaders, second: transformedHeaders })) {
|
|
2750
|
+
return response;
|
|
2751
|
+
}
|
|
2752
|
+
const transformedResponse = new Response(
|
|
2753
|
+
NULL_BODY_RESPONSE_STATUSES.has(response.status) ? null : response.body,
|
|
2754
|
+
{
|
|
2755
|
+
status: response.status,
|
|
2756
|
+
statusText: response.statusText,
|
|
2757
|
+
headers: transformedHeaders
|
|
2758
|
+
}
|
|
2759
|
+
);
|
|
2760
|
+
return preserveResponseMetadata({
|
|
2761
|
+
response: transformedResponse,
|
|
2762
|
+
source: response
|
|
2763
|
+
});
|
|
2764
|
+
}
|
|
2765
|
+
function preserveResponseMetadata({
|
|
2766
|
+
response,
|
|
2767
|
+
source
|
|
2768
|
+
}) {
|
|
2769
|
+
const nativeClone = response.clone;
|
|
2770
|
+
Object.defineProperties(response, {
|
|
2771
|
+
clone: {
|
|
2772
|
+
configurable: true,
|
|
2773
|
+
writable: true,
|
|
2774
|
+
value: function clone() {
|
|
2775
|
+
const clonedResponse = nativeClone.call(this);
|
|
2776
|
+
return this === response ? preserveResponseMetadata({ response: clonedResponse, source }) : clonedResponse;
|
|
2777
|
+
}
|
|
2778
|
+
},
|
|
2779
|
+
...sourceMetadataDescriptors(source)
|
|
2780
|
+
});
|
|
2781
|
+
return response;
|
|
2782
|
+
}
|
|
2783
|
+
function sourceMetadataDescriptors(source) {
|
|
2784
|
+
const descriptors = {};
|
|
2785
|
+
for (const key of ["redirected", "type", "url"]) {
|
|
2786
|
+
if (source[key] !== void 0) {
|
|
2787
|
+
descriptors[key] = { configurable: true, value: source[key] };
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
return descriptors;
|
|
2791
|
+
}
|
|
2792
|
+
function areHeadersEqual({
|
|
2793
|
+
first,
|
|
2794
|
+
second
|
|
2795
|
+
}) {
|
|
2796
|
+
const firstEntries = [...first.entries()];
|
|
2797
|
+
const secondEntries = [...second.entries()];
|
|
2798
|
+
return firstEntries.length === secondEntries.length && firstEntries.every(
|
|
2799
|
+
([key, value], index) => secondEntries[index]?.[0] === key && secondEntries[index]?.[1] === value
|
|
2800
|
+
);
|
|
2801
|
+
}
|
|
2802
|
+
|
|
2621
2803
|
// src/api/routing/index.ts
|
|
2622
2804
|
var routingConfig = createRoutingConfig({ pathConfig });
|
|
2623
2805
|
function parseRoutingOptions({
|
|
@@ -2685,7 +2867,7 @@ function logRouteOverride({
|
|
|
2685
2867
|
}
|
|
2686
2868
|
|
|
2687
2869
|
// src/sdk-version.ts
|
|
2688
|
-
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.107.
|
|
2870
|
+
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.107.2" : void 0) || "unknown";
|
|
2689
2871
|
|
|
2690
2872
|
// src/utils/open-url.ts
|
|
2691
2873
|
var nodePrefix = "node:";
|
|
@@ -2825,14 +3007,14 @@ var ZapierApiClient = class {
|
|
|
2825
3007
|
* auth/retry pipeline instead of reaching for `this.options.fetch`
|
|
2826
3008
|
* directly and drifting.
|
|
2827
3009
|
*/
|
|
2828
|
-
this.rawFetchUrl = async (url, init,
|
|
3010
|
+
this.rawFetchUrl = async (url, init, resolvedRoute) => {
|
|
2829
3011
|
const { [CORRELATION_CALL_ID]: callId, ...fetchInit } = init ?? {};
|
|
2830
3012
|
if (fetchInit.body && (isPlainObject(fetchInit.body) || Array.isArray(fetchInit.body))) {
|
|
2831
3013
|
fetchInit.body = JSON.stringify(fetchInit.body);
|
|
2832
3014
|
}
|
|
2833
3015
|
const builtHeaders = await this.buildHeaders(
|
|
2834
3016
|
fetchInit,
|
|
2835
|
-
|
|
3017
|
+
resolvedRoute?.pathConfig
|
|
2836
3018
|
);
|
|
2837
3019
|
const inputHeaders = new Headers(fetchInit.headers ?? {});
|
|
2838
3020
|
const mergedHeaders = new Headers();
|
|
@@ -2843,6 +3025,11 @@ var ZapierApiClient = class {
|
|
|
2843
3025
|
mergedHeaders.set(key, value);
|
|
2844
3026
|
});
|
|
2845
3027
|
this.applyTelemetryHeaders({ headers: mergedHeaders, callId });
|
|
3028
|
+
const outboundHeaders = applyRequestHeaderTransform({
|
|
3029
|
+
headers: mergedHeaders,
|
|
3030
|
+
resolvedRoute,
|
|
3031
|
+
debugLog: this.options.debugLog
|
|
3032
|
+
});
|
|
2846
3033
|
const {
|
|
2847
3034
|
authRequired: _authRequired,
|
|
2848
3035
|
requiredScopes: _requiredScopes,
|
|
@@ -2855,11 +3042,11 @@ var ZapierApiClient = class {
|
|
|
2855
3042
|
const request = {
|
|
2856
3043
|
...wireInit,
|
|
2857
3044
|
url,
|
|
2858
|
-
headers: Object.fromEntries(
|
|
3045
|
+
headers: Object.fromEntries(outboundHeaders)
|
|
2859
3046
|
};
|
|
2860
3047
|
const response = await this.options.sendHttpRequest(request);
|
|
2861
3048
|
if (response.status !== 429) {
|
|
2862
|
-
return response;
|
|
3049
|
+
return applyResponseHeaderTransform({ response, resolvedRoute });
|
|
2863
3050
|
}
|
|
2864
3051
|
throw new ZapierRateLimitError(
|
|
2865
3052
|
await this.readRateLimitErrorMessage(response),
|
|
@@ -2929,10 +3116,10 @@ var ZapierApiClient = class {
|
|
|
2929
3116
|
*/
|
|
2930
3117
|
this.rawFetch = async (path, init) => {
|
|
2931
3118
|
validateSdkPath(path);
|
|
2932
|
-
const { url,
|
|
3119
|
+
const { url, resolvedRoute } = this.buildUrl(path, init?.searchParams);
|
|
2933
3120
|
return this.withSemaphore(
|
|
2934
3121
|
{ url, method: init?.method ?? "GET", signal: init?.signal },
|
|
2935
|
-
() => this.rawFetchUrl(url, init,
|
|
3122
|
+
() => this.rawFetchUrl(url, init, resolvedRoute)
|
|
2936
3123
|
);
|
|
2937
3124
|
};
|
|
2938
3125
|
this.runApprovalFetchLoop = async ({
|
|
@@ -3342,22 +3529,12 @@ var ZapierApiClient = class {
|
|
|
3342
3529
|
debugLog: this.options.debugLog
|
|
3343
3530
|
});
|
|
3344
3531
|
}
|
|
3345
|
-
// Helper to build full URLs and return routing info
|
|
3346
3532
|
buildUrl(path, searchParams) {
|
|
3347
|
-
const
|
|
3348
|
-
url,
|
|
3349
|
-
pathConfig: config,
|
|
3350
|
-
canSendDeprecationMessaging
|
|
3351
|
-
} = this.applyPathConfiguration(path);
|
|
3352
|
-
if (searchParams) {
|
|
3353
|
-
Object.entries(searchParams).forEach(([key, value]) => {
|
|
3354
|
-
url.searchParams.set(key, value);
|
|
3355
|
-
});
|
|
3356
|
-
}
|
|
3533
|
+
const resolvedRoute = this.applyPathConfiguration(path);
|
|
3357
3534
|
return {
|
|
3358
|
-
url: url.
|
|
3359
|
-
|
|
3360
|
-
canSendDeprecationMessaging
|
|
3535
|
+
url: withSearchParams({ url: resolvedRoute.url, searchParams }),
|
|
3536
|
+
resolvedRoute,
|
|
3537
|
+
canSendDeprecationMessaging: resolvedRoute.canSendDeprecationMessaging
|
|
3361
3538
|
};
|
|
3362
3539
|
}
|
|
3363
3540
|
// Helper to build headers
|