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