@zapier/zapier-sdk 0.102.4 → 0.103.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.
- package/CHANGELOG.md +6 -0
- package/dist/{chunk-6TIBB6TI.mjs → chunk-JJHKZ4XK.mjs} +536 -129
- package/dist/{chunk-WVRZG6I6.cjs → chunk-RHL6GGME.cjs} +536 -129
- package/dist/experimental.cjs +355 -355
- package/dist/experimental.d.mts +3 -2
- package/dist/experimental.d.ts +3 -2
- package/dist/experimental.mjs +2 -2
- package/dist/{index-CfJjkJU-.d.mts → index-DT4MnaD0.d.mts} +8 -0
- package/dist/{index-CfJjkJU-.d.ts → index-DT4MnaD0.d.ts} +8 -0
- package/dist/index.cjs +277 -277
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -2032,8 +2032,528 @@ function parseDeprecationDate(value) {
|
|
|
2032
2032
|
return Number(match[1]) * 1e3;
|
|
2033
2033
|
}
|
|
2034
2034
|
|
|
2035
|
+
// src/api/routing/config.ts
|
|
2036
|
+
var pathConfig = {
|
|
2037
|
+
// e.g. /relay -> https://sdkapi.zapier.com/api/v0/sdk/relay/...
|
|
2038
|
+
"/relay": {
|
|
2039
|
+
authHeader: "X-Relay-Authorization",
|
|
2040
|
+
pathPrefix: "/api/v0/sdk/relay",
|
|
2041
|
+
omitDeprecationMessaging: true
|
|
2042
|
+
},
|
|
2043
|
+
// The concrete gateway form of the relay route. Callers that pass the
|
|
2044
|
+
// already-prefixed path reach the same third-party upstreams, so it must
|
|
2045
|
+
// classify as relay too; without this entry it would match nothing and
|
|
2046
|
+
// sniff deprecation headers off a relay response.
|
|
2047
|
+
"/api/v0/sdk/relay": {
|
|
2048
|
+
override: { enabled: false },
|
|
2049
|
+
omitDeprecationMessaging: true
|
|
2050
|
+
},
|
|
2051
|
+
// Concrete sdkapi routes that do not live behind /api/v0/sdk/<service>.
|
|
2052
|
+
"/api/v0": {},
|
|
2053
|
+
// e.g. /zapier -> https://sdkapi.zapier.com/api/v0/sdk/zapier/...
|
|
2054
|
+
"/zapier": {
|
|
2055
|
+
authHeader: "Authorization",
|
|
2056
|
+
pathPrefix: "/api/v0/sdk/zapier"
|
|
2057
|
+
},
|
|
2058
|
+
// e.g. /tables -> https://sdkapi.zapier.com/api/v0/sdk/tables/...
|
|
2059
|
+
"/tables": {
|
|
2060
|
+
authHeader: "Authorization",
|
|
2061
|
+
pathPrefix: "/api/v0/sdk/tables"
|
|
2062
|
+
},
|
|
2063
|
+
// e.g. /trigger-inbox -> https://sdkapi.zapier.com/api/v0/sdk/trigger-inbox/...
|
|
2064
|
+
"/trigger-inbox": {
|
|
2065
|
+
authHeader: "Authorization",
|
|
2066
|
+
pathPrefix: "/api/v0/sdk/trigger-inbox"
|
|
2067
|
+
},
|
|
2068
|
+
// e.g. /sdkdurableapi -> https://sdkapi.zapier.com/api/v0/sdk/sdkdurableapi/...
|
|
2069
|
+
// sdkapi proxies to the sdkdurableapi backend.
|
|
2070
|
+
"/sdkdurableapi": {
|
|
2071
|
+
authHeader: "Authorization",
|
|
2072
|
+
pathPrefix: "/api/v0/sdk/sdkdurableapi"
|
|
2073
|
+
},
|
|
2074
|
+
// e.g. /durableworkflowzaps -> https://sdkapi.zapier.com/api/v0/sdk/durableworkflowzaps/...
|
|
2075
|
+
// sdkapi proxies to the durableworkflowzaps backend.
|
|
2076
|
+
"/durableworkflowzaps": {
|
|
2077
|
+
authHeader: "Authorization",
|
|
2078
|
+
pathPrefix: "/api/v0/sdk/durableworkflowzaps"
|
|
2079
|
+
},
|
|
2080
|
+
// e.g. /code-substrate-runner -> https://sdkapi.zapier.com/api/v0/sdk/code-substrate-runner/...
|
|
2081
|
+
// sdkapi proxies to the code-substrate-runner backend.
|
|
2082
|
+
"/code-substrate-runner": {
|
|
2083
|
+
authHeader: "Authorization",
|
|
2084
|
+
pathPrefix: "/api/v0/sdk/code-substrate-runner"
|
|
2085
|
+
},
|
|
2086
|
+
// e.g. /code-substrate-workflows -> https://sdkapi.zapier.com/api/v0/sdk/code-substrate-workflows/...
|
|
2087
|
+
// sdkapi proxies to the code-substrate-workflows backend.
|
|
2088
|
+
"/code-substrate-workflows": {
|
|
2089
|
+
authHeader: "Authorization",
|
|
2090
|
+
pathPrefix: "/api/v0/sdk/code-substrate-workflows"
|
|
2091
|
+
},
|
|
2092
|
+
// e.g. /code-substrate-analyzer/validations ->
|
|
2093
|
+
// https://api.zapier.com/code-substrate-analyzer/v0/validations
|
|
2094
|
+
"/code-substrate-analyzer": {
|
|
2095
|
+
authHeader: "Authorization",
|
|
2096
|
+
pathPrefix: "/code-substrate-analyzer/v0",
|
|
2097
|
+
subdomain: "api",
|
|
2098
|
+
override: { pathPrefixMode: "preserve" }
|
|
2099
|
+
},
|
|
2100
|
+
// e.g. /forms/v0/forms -> https://api.zapier.com/forms/v0/forms
|
|
2101
|
+
// The Forms API is registered on the Public API Gateway and has no sdkapi
|
|
2102
|
+
// proxy route, so it goes straight to the gateway. Its governance metadata
|
|
2103
|
+
// rewrites /forms/v0/... to the backend's /api/forms/v0/..., which is why no
|
|
2104
|
+
// pathPrefix is applied here.
|
|
2105
|
+
"/forms": {
|
|
2106
|
+
authHeader: "Authorization",
|
|
2107
|
+
subdomain: "api"
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
|
|
2111
|
+
// src/api/routing/default.ts
|
|
2112
|
+
function resolveDefaultRoute({
|
|
2113
|
+
path,
|
|
2114
|
+
baseUrl
|
|
2115
|
+
}) {
|
|
2116
|
+
const matchingPathEntries = findPathConfigEntries({ path });
|
|
2117
|
+
const routingMatch = matchingPathEntries[0];
|
|
2118
|
+
let finalPath = path;
|
|
2119
|
+
if (routingMatch?.config.pathPrefix) {
|
|
2120
|
+
const pathWithoutPrefix = path.slice(routingMatch.configPath.length) || "/";
|
|
2121
|
+
finalPath = `${routingMatch.config.pathPrefix}${pathWithoutPrefix}`;
|
|
2122
|
+
}
|
|
2123
|
+
const zapierBaseUrl = getZapierBaseUrl(baseUrl);
|
|
2124
|
+
if (zapierBaseUrl === baseUrl.replace(/\/$/, "")) {
|
|
2125
|
+
const originalBaseUrl = new URL(baseUrl);
|
|
2126
|
+
const subdomain = routingMatch?.config.subdomain ?? "sdkapi";
|
|
2127
|
+
const finalBaseUrl = `https://${subdomain}.${originalBaseUrl.hostname}`;
|
|
2128
|
+
return buildRouteResult({
|
|
2129
|
+
url: new URL(finalPath, finalBaseUrl),
|
|
2130
|
+
matchingPathEntries,
|
|
2131
|
+
routingMatch
|
|
2132
|
+
});
|
|
2133
|
+
}
|
|
2134
|
+
const parsedBaseUrl = new URL(baseUrl);
|
|
2135
|
+
const basePath = parsedBaseUrl.pathname.replace(/\/$/, "");
|
|
2136
|
+
return buildRouteResult({
|
|
2137
|
+
url: new URL(basePath + finalPath, parsedBaseUrl.origin),
|
|
2138
|
+
matchingPathEntries,
|
|
2139
|
+
routingMatch
|
|
2140
|
+
});
|
|
2141
|
+
}
|
|
2142
|
+
function buildRouteResult({
|
|
2143
|
+
url,
|
|
2144
|
+
matchingPathEntries,
|
|
2145
|
+
routingMatch
|
|
2146
|
+
}) {
|
|
2147
|
+
const resolvedPathEntries = findPathConfigEntries({
|
|
2148
|
+
path: url.pathname,
|
|
2149
|
+
matchResolvedGatewayPath: true
|
|
2150
|
+
});
|
|
2151
|
+
const deprecationPathMatches = [
|
|
2152
|
+
...matchingPathEntries,
|
|
2153
|
+
...resolvedPathEntries
|
|
2154
|
+
];
|
|
2155
|
+
const canSendDeprecationMessaging = deprecationPathMatches.length > 0 && deprecationPathMatches.every(
|
|
2156
|
+
({ config }) => config.omitDeprecationMessaging !== true
|
|
2157
|
+
);
|
|
2158
|
+
return {
|
|
2159
|
+
url,
|
|
2160
|
+
pathConfig: routingMatch?.config,
|
|
2161
|
+
canSendDeprecationMessaging
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
2164
|
+
function findPathConfigEntries({
|
|
2165
|
+
path,
|
|
2166
|
+
matchResolvedGatewayPath = false
|
|
2167
|
+
}) {
|
|
2168
|
+
const pathSegments = path.split("/").filter(Boolean);
|
|
2169
|
+
return Object.entries(pathConfig).filter(([configPath, config]) => {
|
|
2170
|
+
if (!matchResolvedGatewayPath) {
|
|
2171
|
+
return path === configPath || path.startsWith(`${configPath}/`);
|
|
2172
|
+
}
|
|
2173
|
+
const prefixSegments = (config.pathPrefix ?? configPath).split("/").filter(Boolean);
|
|
2174
|
+
return pathSegments.some(
|
|
2175
|
+
(_, startIndex) => prefixSegments.every(
|
|
2176
|
+
(segment, offset) => pathSegments[startIndex + offset] === segment
|
|
2177
|
+
)
|
|
2178
|
+
);
|
|
2179
|
+
}).map(([configPath, config]) => ({ configPath, config }));
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
// src/api/routing/overrides.ts
|
|
2183
|
+
var ROUTE_ORIGIN_ENV_PREFIX = "ZAPIER_ROUTE_ORIGIN_";
|
|
2184
|
+
function createRoutingConfig({
|
|
2185
|
+
pathConfig: pathConfig2
|
|
2186
|
+
}) {
|
|
2187
|
+
const routeByEnvName = new Map(
|
|
2188
|
+
Object.entries(pathConfig2).filter(([, routeConfig]) => isRouteOverrideEnabled({ routeConfig })).map(([route]) => [encodeRouteOriginEnvName({ route }), route])
|
|
2189
|
+
);
|
|
2190
|
+
return { pathConfig: pathConfig2, routeByEnvName };
|
|
2191
|
+
}
|
|
2192
|
+
function encodeRouteOriginEnvName({ route }) {
|
|
2193
|
+
return `${ROUTE_ORIGIN_ENV_PREFIX}${route.slice(1).split("/").map((segment) => segment.replace(/-/g, "_").toUpperCase()).join("__")}`;
|
|
2194
|
+
}
|
|
2195
|
+
function createRouteOverrideEntry({
|
|
2196
|
+
route,
|
|
2197
|
+
source,
|
|
2198
|
+
sourceReference,
|
|
2199
|
+
origin
|
|
2200
|
+
}) {
|
|
2201
|
+
return {
|
|
2202
|
+
route,
|
|
2203
|
+
source,
|
|
2204
|
+
sourceReference,
|
|
2205
|
+
origin: parseRouteOverrideOrigin({
|
|
2206
|
+
origin,
|
|
2207
|
+
sourceLabel: describeRouteOverrideSource({ source, sourceReference })
|
|
2208
|
+
})
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
function describeRouteOverrideSource({
|
|
2212
|
+
source,
|
|
2213
|
+
sourceReference
|
|
2214
|
+
}) {
|
|
2215
|
+
return source === "environment-variable" ? `environment variable ${sourceReference}` : `routeOverrides[${JSON.stringify(sourceReference)}]`;
|
|
2216
|
+
}
|
|
2217
|
+
function readOptionRouteOverrideEntries({
|
|
2218
|
+
routeOverrides,
|
|
2219
|
+
routingConfig: routingConfig2
|
|
2220
|
+
}) {
|
|
2221
|
+
const entries = [];
|
|
2222
|
+
if (!routeOverrides) {
|
|
2223
|
+
return entries;
|
|
2224
|
+
}
|
|
2225
|
+
for (const [route, origin] of Object.entries(routeOverrides)) {
|
|
2226
|
+
assertSupportedRouteOverride({ route, routingConfig: routingConfig2 });
|
|
2227
|
+
entries.push(
|
|
2228
|
+
createRouteOverrideEntry({
|
|
2229
|
+
route,
|
|
2230
|
+
source: "sdk-option",
|
|
2231
|
+
sourceReference: route,
|
|
2232
|
+
origin
|
|
2233
|
+
})
|
|
2234
|
+
);
|
|
2235
|
+
}
|
|
2236
|
+
return entries;
|
|
2237
|
+
}
|
|
2238
|
+
function buildRouteOverrideMap({
|
|
2239
|
+
environmentEntries,
|
|
2240
|
+
optionEntries
|
|
2241
|
+
}) {
|
|
2242
|
+
const routeOverrideMap = /* @__PURE__ */ new Map();
|
|
2243
|
+
for (const entry of environmentEntries) {
|
|
2244
|
+
routeOverrideMap.set(entry.route, entry);
|
|
2245
|
+
}
|
|
2246
|
+
for (const entry of optionEntries) {
|
|
2247
|
+
routeOverrideMap.set(entry.route, entry);
|
|
2248
|
+
}
|
|
2249
|
+
return routeOverrideMap;
|
|
2250
|
+
}
|
|
2251
|
+
function collectRouteOverrideSources({
|
|
2252
|
+
routingOptions,
|
|
2253
|
+
environment,
|
|
2254
|
+
routingConfig: routingConfig2
|
|
2255
|
+
}) {
|
|
2256
|
+
try {
|
|
2257
|
+
const optionEntries = routingOptions?.routeOverrideEntries ?? [];
|
|
2258
|
+
const environmentEntries = readEnvironmentRouteOverrideEntries({
|
|
2259
|
+
environment,
|
|
2260
|
+
routingConfig: routingConfig2
|
|
2261
|
+
});
|
|
2262
|
+
if (optionEntries.length === 0 && environmentEntries.length === 0) {
|
|
2263
|
+
return void 0;
|
|
2264
|
+
}
|
|
2265
|
+
return { optionEntries, environmentEntries };
|
|
2266
|
+
} catch (error) {
|
|
2267
|
+
if (isZapierError(error) && error.code === "ZAPIER_CONFIGURATION_ERROR") {
|
|
2268
|
+
throw error;
|
|
2269
|
+
}
|
|
2270
|
+
return void 0;
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
function findRouteOverrideMatch({
|
|
2274
|
+
path,
|
|
2275
|
+
routeOverrideMap,
|
|
2276
|
+
routingConfig: routingConfig2
|
|
2277
|
+
}) {
|
|
2278
|
+
let bestMatch;
|
|
2279
|
+
const { pathname } = splitPathReference({ path });
|
|
2280
|
+
for (const override of routeOverrideMap.values()) {
|
|
2281
|
+
const { route } = override;
|
|
2282
|
+
for (const candidate of getRouteCandidates({
|
|
2283
|
+
route,
|
|
2284
|
+
override,
|
|
2285
|
+
routingConfig: routingConfig2
|
|
2286
|
+
})) {
|
|
2287
|
+
if (!pathnameMatchesPrefix({
|
|
2288
|
+
pathname,
|
|
2289
|
+
prefix: candidate.matchedPrefix
|
|
2290
|
+
})) {
|
|
2291
|
+
continue;
|
|
2292
|
+
}
|
|
2293
|
+
if (!bestMatch || compareRouteOverrideMatches(candidate, bestMatch) < 0) {
|
|
2294
|
+
bestMatch = candidate;
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
}
|
|
2298
|
+
return bestMatch;
|
|
2299
|
+
}
|
|
2300
|
+
function resolveOverrideRoute({
|
|
2301
|
+
overrideMatch,
|
|
2302
|
+
path
|
|
2303
|
+
}) {
|
|
2304
|
+
const { matchedPrefix, routeConfig, override } = overrideMatch;
|
|
2305
|
+
const directPath = deriveDirectPath({ path, matchedPrefix, routeConfig });
|
|
2306
|
+
return {
|
|
2307
|
+
url: buildRouteOverrideUrl({ origin: override.origin, path: directPath }),
|
|
2308
|
+
pathConfig: routeConfig,
|
|
2309
|
+
canSendDeprecationMessaging: false
|
|
2310
|
+
};
|
|
2311
|
+
}
|
|
2312
|
+
function deriveDirectPath({
|
|
2313
|
+
path,
|
|
2314
|
+
matchedPrefix,
|
|
2315
|
+
routeConfig
|
|
2316
|
+
}) {
|
|
2317
|
+
const { pathPrefix } = routeConfig;
|
|
2318
|
+
if (!pathPrefix) {
|
|
2319
|
+
return path;
|
|
2320
|
+
}
|
|
2321
|
+
const remainingPath = path.slice(matchedPrefix.length) || "/";
|
|
2322
|
+
const override = routeConfig.override;
|
|
2323
|
+
const pathPrefixMode = override?.enabled === false ? "strip" : override?.pathPrefixMode ?? "strip";
|
|
2324
|
+
return pathPrefixMode === "preserve" ? `${pathPrefix}${remainingPath}` : remainingPath;
|
|
2325
|
+
}
|
|
2326
|
+
function readEnvironmentRouteOverrideEntries({
|
|
2327
|
+
environment,
|
|
2328
|
+
routingConfig: routingConfig2
|
|
2329
|
+
}) {
|
|
2330
|
+
const entries = [];
|
|
2331
|
+
if (!environment) {
|
|
2332
|
+
return entries;
|
|
2333
|
+
}
|
|
2334
|
+
for (const [envName, route] of routingConfig2.routeByEnvName) {
|
|
2335
|
+
let value;
|
|
2336
|
+
try {
|
|
2337
|
+
if (!Object.prototype.hasOwnProperty.call(environment, envName)) {
|
|
2338
|
+
continue;
|
|
2339
|
+
}
|
|
2340
|
+
value = environment[envName];
|
|
2341
|
+
} catch {
|
|
2342
|
+
continue;
|
|
2343
|
+
}
|
|
2344
|
+
if (isUnsetEnvironmentValue(value)) {
|
|
2345
|
+
continue;
|
|
2346
|
+
}
|
|
2347
|
+
entries.push(
|
|
2348
|
+
createRouteOverrideEntry({
|
|
2349
|
+
route,
|
|
2350
|
+
source: "environment-variable",
|
|
2351
|
+
sourceReference: envName,
|
|
2352
|
+
origin: value
|
|
2353
|
+
})
|
|
2354
|
+
);
|
|
2355
|
+
}
|
|
2356
|
+
return entries;
|
|
2357
|
+
}
|
|
2358
|
+
function isUnsetEnvironmentValue(value) {
|
|
2359
|
+
if (value === void 0 || value === null) {
|
|
2360
|
+
return true;
|
|
2361
|
+
}
|
|
2362
|
+
return typeof value === "string" && value.trim() === "";
|
|
2363
|
+
}
|
|
2364
|
+
function assertSupportedRouteOverride({
|
|
2365
|
+
route,
|
|
2366
|
+
routingConfig: routingConfig2
|
|
2367
|
+
}) {
|
|
2368
|
+
if (!Object.prototype.hasOwnProperty.call(routingConfig2.pathConfig, route)) {
|
|
2369
|
+
throw new ZapierConfigurationError(
|
|
2370
|
+
`Route override is not supported for ${route}`,
|
|
2371
|
+
{ configType: "routeOverrides" }
|
|
2372
|
+
);
|
|
2373
|
+
}
|
|
2374
|
+
const routeConfig = routingConfig2.pathConfig[route];
|
|
2375
|
+
if (!isRouteOverrideEnabled({ routeConfig })) {
|
|
2376
|
+
throw new ZapierConfigurationError(
|
|
2377
|
+
`Route override is disabled for ${route}`,
|
|
2378
|
+
{ configType: "routeOverrides" }
|
|
2379
|
+
);
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
function parseRouteOverrideOrigin({
|
|
2383
|
+
origin,
|
|
2384
|
+
sourceLabel
|
|
2385
|
+
}) {
|
|
2386
|
+
if (typeof origin !== "string") {
|
|
2387
|
+
throw new ZapierConfigurationError(
|
|
2388
|
+
`Invalid route override origin for ${sourceLabel}`,
|
|
2389
|
+
{ configType: "routeOverrides" }
|
|
2390
|
+
);
|
|
2391
|
+
}
|
|
2392
|
+
let url;
|
|
2393
|
+
try {
|
|
2394
|
+
url = new URL(origin);
|
|
2395
|
+
} catch {
|
|
2396
|
+
throw new ZapierConfigurationError(
|
|
2397
|
+
`Invalid route override origin for ${sourceLabel}`,
|
|
2398
|
+
{ configType: "routeOverrides" }
|
|
2399
|
+
);
|
|
2400
|
+
}
|
|
2401
|
+
const includesOnlyOrigin = url.username === "" && url.password === "" && url.pathname === "/" && url.search === "" && url.hash === "";
|
|
2402
|
+
if (!includesOnlyOrigin) {
|
|
2403
|
+
throw new ZapierConfigurationError(
|
|
2404
|
+
`Invalid route override origin for ${sourceLabel}`,
|
|
2405
|
+
{ configType: "routeOverrides" }
|
|
2406
|
+
);
|
|
2407
|
+
}
|
|
2408
|
+
if (url.protocol === "https:") {
|
|
2409
|
+
return url.origin;
|
|
2410
|
+
}
|
|
2411
|
+
if (url.protocol === "http:" && isLoopbackHost(url.hostname)) {
|
|
2412
|
+
return url.origin;
|
|
2413
|
+
}
|
|
2414
|
+
throw new ZapierConfigurationError(
|
|
2415
|
+
`Invalid route override origin for ${sourceLabel}: expected https, or http on a loopback host`,
|
|
2416
|
+
{ configType: "routeOverrides" }
|
|
2417
|
+
);
|
|
2418
|
+
}
|
|
2419
|
+
function isLoopbackHost(hostname) {
|
|
2420
|
+
return hostname === "localhost" || hostname === "[::1]" || // pii:allow
|
|
2421
|
+
// RFC 6761 reserves .localhost names for loopback.
|
|
2422
|
+
hostname.endsWith(".localhost") || /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname);
|
|
2423
|
+
}
|
|
2424
|
+
function compareRouteOverrideMatches(a, b) {
|
|
2425
|
+
return b.matchedPrefix.length - a.matchedPrefix.length || Number(b.isExactRouteSpelling) - Number(a.isExactRouteSpelling);
|
|
2426
|
+
}
|
|
2427
|
+
function getRouteCandidates({
|
|
2428
|
+
route,
|
|
2429
|
+
override,
|
|
2430
|
+
routingConfig: routingConfig2
|
|
2431
|
+
}) {
|
|
2432
|
+
const routeConfig = routingConfig2.pathConfig[route];
|
|
2433
|
+
if (!routeConfig || !isRouteOverrideEnabled({ routeConfig })) {
|
|
2434
|
+
return [];
|
|
2435
|
+
}
|
|
2436
|
+
const candidates = [
|
|
2437
|
+
{
|
|
2438
|
+
route,
|
|
2439
|
+
matchedPrefix: route,
|
|
2440
|
+
isExactRouteSpelling: true,
|
|
2441
|
+
routeConfig,
|
|
2442
|
+
override
|
|
2443
|
+
}
|
|
2444
|
+
];
|
|
2445
|
+
if (routeConfig.pathPrefix && routeConfig.pathPrefix !== route) {
|
|
2446
|
+
candidates.push({
|
|
2447
|
+
route,
|
|
2448
|
+
matchedPrefix: routeConfig.pathPrefix,
|
|
2449
|
+
isExactRouteSpelling: false,
|
|
2450
|
+
routeConfig,
|
|
2451
|
+
override
|
|
2452
|
+
});
|
|
2453
|
+
}
|
|
2454
|
+
return candidates;
|
|
2455
|
+
}
|
|
2456
|
+
function buildRouteOverrideUrl({
|
|
2457
|
+
origin,
|
|
2458
|
+
path
|
|
2459
|
+
}) {
|
|
2460
|
+
const url = new URL(origin);
|
|
2461
|
+
const { pathname, search, hash } = splitPathReference({ path });
|
|
2462
|
+
url.pathname = pathname;
|
|
2463
|
+
url.search = search;
|
|
2464
|
+
url.hash = hash;
|
|
2465
|
+
return url;
|
|
2466
|
+
}
|
|
2467
|
+
function splitPathReference({ path }) {
|
|
2468
|
+
const hashStart = path.indexOf("#");
|
|
2469
|
+
const pathWithoutHash = hashStart === -1 ? path : path.slice(0, hashStart);
|
|
2470
|
+
const searchStart = pathWithoutHash.indexOf("?");
|
|
2471
|
+
return {
|
|
2472
|
+
pathname: searchStart === -1 ? pathWithoutHash : pathWithoutHash.slice(0, searchStart),
|
|
2473
|
+
search: searchStart === -1 ? "" : pathWithoutHash.slice(searchStart),
|
|
2474
|
+
hash: hashStart === -1 ? "" : path.slice(hashStart)
|
|
2475
|
+
};
|
|
2476
|
+
}
|
|
2477
|
+
function pathnameMatchesPrefix({
|
|
2478
|
+
pathname,
|
|
2479
|
+
prefix
|
|
2480
|
+
}) {
|
|
2481
|
+
return pathname === prefix || pathname.startsWith(`${prefix}/`);
|
|
2482
|
+
}
|
|
2483
|
+
function isRouteOverrideEnabled({
|
|
2484
|
+
routeConfig
|
|
2485
|
+
}) {
|
|
2486
|
+
return routeConfig.override?.enabled !== false;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
// src/api/routing/index.ts
|
|
2490
|
+
var routingConfig = createRoutingConfig({ pathConfig });
|
|
2491
|
+
function parseRoutingOptions({
|
|
2492
|
+
options
|
|
2493
|
+
}) {
|
|
2494
|
+
try {
|
|
2495
|
+
return {
|
|
2496
|
+
routeOverrideEntries: readOptionRouteOverrideEntries({
|
|
2497
|
+
routeOverrides: options.routeOverrides,
|
|
2498
|
+
routingConfig
|
|
2499
|
+
})
|
|
2500
|
+
};
|
|
2501
|
+
} catch (error) {
|
|
2502
|
+
if (isZapierError(error) && error.code === "ZAPIER_CONFIGURATION_ERROR") {
|
|
2503
|
+
throw error;
|
|
2504
|
+
}
|
|
2505
|
+
throw new ZapierConfigurationError("Failed to read SDK routing options", {
|
|
2506
|
+
configType: "routeOverrides",
|
|
2507
|
+
cause: error
|
|
2508
|
+
});
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
function resolveRoute({
|
|
2512
|
+
path,
|
|
2513
|
+
baseUrl,
|
|
2514
|
+
routingOptions = { routeOverrideEntries: [] },
|
|
2515
|
+
environment,
|
|
2516
|
+
debugLog
|
|
2517
|
+
}) {
|
|
2518
|
+
const overrideSources = collectRouteOverrideSources({
|
|
2519
|
+
routingOptions,
|
|
2520
|
+
environment,
|
|
2521
|
+
routingConfig
|
|
2522
|
+
});
|
|
2523
|
+
if (!overrideSources) {
|
|
2524
|
+
return resolveDefaultRoute({ path, baseUrl });
|
|
2525
|
+
}
|
|
2526
|
+
const routeOverrideMap = buildRouteOverrideMap(overrideSources);
|
|
2527
|
+
const overrideMatch = findRouteOverrideMatch({
|
|
2528
|
+
path,
|
|
2529
|
+
routeOverrideMap,
|
|
2530
|
+
routingConfig
|
|
2531
|
+
});
|
|
2532
|
+
if (overrideMatch) {
|
|
2533
|
+
const resolved = resolveOverrideRoute({ overrideMatch, path });
|
|
2534
|
+
logRouteOverride({ path, resolved, overrideMatch, debugLog });
|
|
2535
|
+
return resolved;
|
|
2536
|
+
}
|
|
2537
|
+
return resolveDefaultRoute({ path, baseUrl });
|
|
2538
|
+
}
|
|
2539
|
+
function logRouteOverride({
|
|
2540
|
+
path,
|
|
2541
|
+
resolved,
|
|
2542
|
+
overrideMatch,
|
|
2543
|
+
debugLog
|
|
2544
|
+
}) {
|
|
2545
|
+
if (!debugLog) {
|
|
2546
|
+
return;
|
|
2547
|
+
}
|
|
2548
|
+
const { route, override } = overrideMatch;
|
|
2549
|
+
const source = describeRouteOverrideSource(override);
|
|
2550
|
+
debugLog(
|
|
2551
|
+
`Route override: ${path} -> ${resolved.url.toString()} (route ${route} via ${source})`
|
|
2552
|
+
);
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2035
2555
|
// src/sdk-version.ts
|
|
2036
|
-
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.
|
|
2556
|
+
var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.103.0" : void 0) || "unknown";
|
|
2037
2557
|
|
|
2038
2558
|
// src/utils/open-url.ts
|
|
2039
2559
|
var nodePrefix = "node:";
|
|
@@ -2157,23 +2677,6 @@ function validateSdkPath(path) {
|
|
|
2157
2677
|
);
|
|
2158
2678
|
}
|
|
2159
2679
|
}
|
|
2160
|
-
function findPathConfigEntries({
|
|
2161
|
-
path,
|
|
2162
|
-
matchResolvedGatewayPath = false
|
|
2163
|
-
}) {
|
|
2164
|
-
const pathSegments = path.split("/").filter(Boolean);
|
|
2165
|
-
return Object.entries(pathConfig).filter(([configPath, config]) => {
|
|
2166
|
-
if (!matchResolvedGatewayPath) {
|
|
2167
|
-
return path === configPath || path.startsWith(`${configPath}/`);
|
|
2168
|
-
}
|
|
2169
|
-
const prefixSegments = (config.pathPrefix ?? configPath).split("/").filter(Boolean);
|
|
2170
|
-
return pathSegments.some(
|
|
2171
|
-
(_, startIndex) => prefixSegments.every(
|
|
2172
|
-
(segment, offset) => pathSegments[startIndex + offset] === segment
|
|
2173
|
-
)
|
|
2174
|
-
);
|
|
2175
|
-
}).map(([configPath, config]) => ({ configPath, config }));
|
|
2176
|
-
}
|
|
2177
2680
|
function parseRateLimitHeaders(response) {
|
|
2178
2681
|
const info = {};
|
|
2179
2682
|
const retryAfter = response.headers.get("retry-after");
|
|
@@ -2215,78 +2718,6 @@ function parseRateLimitHeaders(response) {
|
|
|
2215
2718
|
}
|
|
2216
2719
|
return info;
|
|
2217
2720
|
}
|
|
2218
|
-
var pathConfig = {
|
|
2219
|
-
// e.g. /relay -> https://sdkapi.zapier.com/api/v0/sdk/relay/...
|
|
2220
|
-
"/relay": {
|
|
2221
|
-
authHeader: "X-Relay-Authorization",
|
|
2222
|
-
pathPrefix: "/api/v0/sdk/relay",
|
|
2223
|
-
omitDeprecationMessaging: true
|
|
2224
|
-
},
|
|
2225
|
-
// The concrete gateway form of the relay route. Callers that pass the
|
|
2226
|
-
// already-prefixed path reach the same third-party upstreams, so it must
|
|
2227
|
-
// classify as relay too; without this entry it would match nothing and
|
|
2228
|
-
// sniff deprecation headers off a relay response.
|
|
2229
|
-
"/api/v0/sdk/relay": {
|
|
2230
|
-
omitDeprecationMessaging: true
|
|
2231
|
-
},
|
|
2232
|
-
// Concrete sdkapi routes that do not live behind /api/v0/sdk/<service>.
|
|
2233
|
-
"/api/v0": {},
|
|
2234
|
-
// e.g. /zapier -> https://sdkapi.zapier.com/api/v0/sdk/zapier/...
|
|
2235
|
-
"/zapier": {
|
|
2236
|
-
authHeader: "Authorization",
|
|
2237
|
-
pathPrefix: "/api/v0/sdk/zapier"
|
|
2238
|
-
},
|
|
2239
|
-
// e.g. /tables -> https://sdkapi.zapier.com/api/v0/sdk/tables/...
|
|
2240
|
-
"/tables": {
|
|
2241
|
-
authHeader: "Authorization",
|
|
2242
|
-
pathPrefix: "/api/v0/sdk/tables"
|
|
2243
|
-
},
|
|
2244
|
-
// e.g. /trigger-inbox -> https://sdkapi.zapier.com/api/v0/sdk/trigger-inbox/...
|
|
2245
|
-
"/trigger-inbox": {
|
|
2246
|
-
authHeader: "Authorization",
|
|
2247
|
-
pathPrefix: "/api/v0/sdk/trigger-inbox"
|
|
2248
|
-
},
|
|
2249
|
-
// e.g. /sdkdurableapi -> https://sdkapi.zapier.com/api/v0/sdk/sdkdurableapi/...
|
|
2250
|
-
// sdkapi proxies to the sdkdurableapi backend.
|
|
2251
|
-
"/sdkdurableapi": {
|
|
2252
|
-
authHeader: "Authorization",
|
|
2253
|
-
pathPrefix: "/api/v0/sdk/sdkdurableapi"
|
|
2254
|
-
},
|
|
2255
|
-
// e.g. /durableworkflowzaps -> https://sdkapi.zapier.com/api/v0/sdk/durableworkflowzaps/...
|
|
2256
|
-
// sdkapi proxies to the durableworkflowzaps backend.
|
|
2257
|
-
"/durableworkflowzaps": {
|
|
2258
|
-
authHeader: "Authorization",
|
|
2259
|
-
pathPrefix: "/api/v0/sdk/durableworkflowzaps"
|
|
2260
|
-
},
|
|
2261
|
-
// e.g. /code-substrate-runner -> https://sdkapi.zapier.com/api/v0/sdk/code-substrate-runner/...
|
|
2262
|
-
// sdkapi proxies to the code-substrate-runner backend.
|
|
2263
|
-
"/code-substrate-runner": {
|
|
2264
|
-
authHeader: "Authorization",
|
|
2265
|
-
pathPrefix: "/api/v0/sdk/code-substrate-runner"
|
|
2266
|
-
},
|
|
2267
|
-
// e.g. /code-substrate-workflows -> https://sdkapi.zapier.com/api/v0/sdk/code-substrate-workflows/...
|
|
2268
|
-
// sdkapi proxies to the code-substrate-workflows backend.
|
|
2269
|
-
"/code-substrate-workflows": {
|
|
2270
|
-
authHeader: "Authorization",
|
|
2271
|
-
pathPrefix: "/api/v0/sdk/code-substrate-workflows"
|
|
2272
|
-
},
|
|
2273
|
-
// e.g. /code-substrate-analyzer/validations ->
|
|
2274
|
-
// https://api.zapier.com/code-substrate-analyzer/v0/validations
|
|
2275
|
-
"/code-substrate-analyzer": {
|
|
2276
|
-
authHeader: "Authorization",
|
|
2277
|
-
pathPrefix: "/code-substrate-analyzer/v0",
|
|
2278
|
-
subdomain: "api"
|
|
2279
|
-
},
|
|
2280
|
-
// e.g. /forms/v0/forms -> https://api.zapier.com/forms/v0/forms
|
|
2281
|
-
// The Forms API is registered on the Public API Gateway and has no sdkapi
|
|
2282
|
-
// proxy route, so it goes straight to the gateway. Its governance metadata
|
|
2283
|
-
// rewrites /forms/v0/... to the backend's /api/forms/v0/..., which is why no
|
|
2284
|
-
// pathPrefix is applied here.
|
|
2285
|
-
"/forms": {
|
|
2286
|
-
authHeader: "Authorization",
|
|
2287
|
-
subdomain: "api"
|
|
2288
|
-
}
|
|
2289
|
-
};
|
|
2290
2721
|
var ZapierApiClient = class {
|
|
2291
2722
|
constructor(options) {
|
|
2292
2723
|
this.options = options;
|
|
@@ -2831,43 +3262,13 @@ var ZapierApiClient = class {
|
|
|
2831
3262
|
}
|
|
2832
3263
|
// Apply any special routing logic for configured paths.
|
|
2833
3264
|
applyPathConfiguration(path) {
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
const deprecationPathMatches = [
|
|
2842
|
-
...matchingPathEntries,
|
|
2843
|
-
...resolvedPathEntries
|
|
2844
|
-
];
|
|
2845
|
-
const canSendDeprecationMessaging = deprecationPathMatches.length > 0 && deprecationPathMatches.every(
|
|
2846
|
-
({ config }) => config.omitDeprecationMessaging !== true
|
|
2847
|
-
);
|
|
2848
|
-
return {
|
|
2849
|
-
url: url2,
|
|
2850
|
-
pathConfig: routingMatch?.config,
|
|
2851
|
-
canSendDeprecationMessaging
|
|
2852
|
-
};
|
|
2853
|
-
};
|
|
2854
|
-
let finalPath = path;
|
|
2855
|
-
if (routingMatch?.config.pathPrefix) {
|
|
2856
|
-
const pathWithoutPrefix = path.slice(routingMatch.configPath.length) || "/";
|
|
2857
|
-
finalPath = `${routingMatch.config.pathPrefix}${pathWithoutPrefix}`;
|
|
2858
|
-
}
|
|
2859
|
-
const zapierBaseUrl = getZapierBaseUrl(this.options.baseUrl);
|
|
2860
|
-
if (zapierBaseUrl === this.options.baseUrl.replace(/\/$/, "")) {
|
|
2861
|
-
const originalBaseUrl = new URL(this.options.baseUrl);
|
|
2862
|
-
const subdomain = routingMatch?.config.subdomain ?? "sdkapi";
|
|
2863
|
-
const finalBaseUrl = `https://${subdomain}.${originalBaseUrl.hostname}`;
|
|
2864
|
-
const url2 = new URL(finalPath, finalBaseUrl);
|
|
2865
|
-
return buildResult(url2);
|
|
2866
|
-
}
|
|
2867
|
-
const baseUrl = new URL(this.options.baseUrl);
|
|
2868
|
-
const basePath = baseUrl.pathname.replace(/\/$/, "");
|
|
2869
|
-
const url = new URL(basePath + finalPath, baseUrl.origin);
|
|
2870
|
-
return buildResult(url);
|
|
3265
|
+
return resolveRoute({
|
|
3266
|
+
path,
|
|
3267
|
+
baseUrl: this.options.baseUrl,
|
|
3268
|
+
routingOptions: this.options.routingOptions,
|
|
3269
|
+
environment: globalThis.process?.env,
|
|
3270
|
+
debugLog: this.options.debugLog
|
|
3271
|
+
});
|
|
2871
3272
|
}
|
|
2872
3273
|
// Helper to build full URLs and return routing info
|
|
2873
3274
|
buildUrl(path, searchParams) {
|
|
@@ -3396,6 +3797,7 @@ var ZapierApiClient = class {
|
|
|
3396
3797
|
};
|
|
3397
3798
|
var createZapierApi = (options) => {
|
|
3398
3799
|
const { debug = false, fetch: originalFetch = globalThis.fetch } = options;
|
|
3800
|
+
const routingOptions = parseRoutingOptions({ options });
|
|
3399
3801
|
const debugLog = createDebugLogger(debug);
|
|
3400
3802
|
const debugFetch = createDebugFetch({ originalFetch, debugLog });
|
|
3401
3803
|
return new ZapierApiClient({
|
|
@@ -3406,7 +3808,9 @@ var createZapierApi = (options) => {
|
|
|
3406
3808
|
fetch: debugFetch,
|
|
3407
3809
|
// Built from the caller's own `fetch`, not `debugFetch`: the pipeline wraps
|
|
3408
3810
|
// for debug itself, and passing the wrapped one would log twice.
|
|
3409
|
-
sendHttpRequest: options.sendHttpRequest ?? createZapierSendHttpRequest({ fetch: options.fetch, debug })
|
|
3811
|
+
sendHttpRequest: options.sendHttpRequest ?? createZapierSendHttpRequest({ fetch: options.fetch, debug }),
|
|
3812
|
+
debugLog,
|
|
3813
|
+
routingOptions
|
|
3410
3814
|
});
|
|
3411
3815
|
};
|
|
3412
3816
|
|
|
@@ -3495,7 +3899,8 @@ var apiPlugin = kitcore.defineProperty({
|
|
|
3495
3899
|
maxApprovalRetries,
|
|
3496
3900
|
approvalMode,
|
|
3497
3901
|
openAutoModeApprovalsInBrowser,
|
|
3498
|
-
callerPackage
|
|
3902
|
+
callerPackage,
|
|
3903
|
+
routeOverrides
|
|
3499
3904
|
} = imports.sdkOptions ?? {};
|
|
3500
3905
|
return createZapierApi({
|
|
3501
3906
|
baseUrl,
|
|
@@ -3512,6 +3917,7 @@ var apiPlugin = kitcore.defineProperty({
|
|
|
3512
3917
|
approvalMode,
|
|
3513
3918
|
openAutoModeApprovalsInBrowser,
|
|
3514
3919
|
callerPackage,
|
|
3920
|
+
routeOverrides,
|
|
3515
3921
|
// Inject the graph-composed transport so host `dispatchHttpRequest` wraps
|
|
3516
3922
|
// apply.
|
|
3517
3923
|
sendHttpRequest: imports.sendHttpRequest
|
|
@@ -11906,6 +12312,7 @@ var BaseSdkOptionsSchema = zod.z.object({
|
|
|
11906
12312
|
),
|
|
11907
12313
|
debug: zod.z.boolean().optional().describe("Enable debug logging."),
|
|
11908
12314
|
baseUrl: zod.z.string().optional().describe("Base URL for Zapier API endpoints.").meta({ valueHint: "url" }),
|
|
12315
|
+
routeOverrides: zod.z.record(zod.z.string(), zod.z.string()).optional().describe("Maps SDK route prefixes to direct origins.").meta({ internal: true }),
|
|
11909
12316
|
trackingBaseUrl: zod.z.string().optional().describe("Base URL for Zapier tracking endpoints.").meta({ valueHint: "url" }),
|
|
11910
12317
|
/**
|
|
11911
12318
|
* Maximum number of retries for rate-limited requests (429 responses).
|