@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.
@@ -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.102.4" : void 0) || "unknown";
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
- const matchingPathEntries = findPathConfigEntries({ path });
2835
- const routingMatch = matchingPathEntries[0];
2836
- const buildResult = (url2) => {
2837
- const resolvedPathEntries = findPathConfigEntries({
2838
- path: url2.pathname,
2839
- matchResolvedGatewayPath: true
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).