@composio/client 2.0.0-rc.16 → 2.0.0-rc.18
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/README.md +146 -32
- package/dist/{api-key-revocation-CvGpd3Rw.mjs → api-key-revocation-JkA4sOGH.mjs} +1 -1
- package/dist/{auth-C0IYTv5D.mjs → auth-B_K-wdMm.mjs} +1 -1
- package/dist/{auth-configs-COmbnKYx.mjs → auth-configs-RAgN782Z.mjs} +1 -1
- package/dist/{clanker-hE4FKPjg.mjs → clanker-Pgyyh95r.mjs} +1 -1
- package/dist/{cli-CuFaxvp4.mjs → cli-Ca5bRiEN.mjs} +4 -5
- package/dist/{connected-accounts-BmbcAhdS.mjs → connected-accounts-D6NTwvbi.mjs} +1 -1
- package/dist/{consumer-BaJgJBXQ.mjs → consumer-BP4OyJS0.mjs} +6 -7
- package/dist/{custom-DIJbIQGR.mjs → custom-BBr7KbCv.mjs} +1 -1
- package/dist/{custom-DbEv7dUC.mjs → custom-DA3ABHnI.mjs} +1 -1
- package/dist/effect.d.mts +70 -26
- package/dist/effect.mjs +216 -141
- package/dist/{error-D9cG225M.mjs → error-Bw7_G2NZ.mjs} +1 -1
- package/dist/{files-Cw6ulQZy.mjs → files-CeBs4ZE1.mjs} +1 -1
- package/dist/{files-RPz_Fvnz.mjs → files-DLRmNLRD.mjs} +1 -1
- package/dist/{generate-DZXuXtYM.mjs → generate-16uLPwUU.mjs} +1 -1
- package/dist/{generated-deprecated-inputs-B6o8D8ub.mjs → generated-deprecated-inputs-zx6ml908.mjs} +2 -2
- package/dist/{generated-operations-DrhN6W_k.mjs → generated-operations-DKgGT6Dg.mjs} +572 -211
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +134 -100
- package/dist/{keyring-CmnkWH5K.mjs → keyring-Q8GSieAv.mjs} +1 -1
- package/dist/{link-C0KzTJBI.mjs → link-D4dY_eaN.mjs} +1 -1
- package/dist/{logs-Bj5MAt8z.mjs → logs-Dc63Ju74.mjs} +3 -3
- package/dist/{manage-DDFmGWNH.mjs → manage-ByF6b3OD.mjs} +1 -1
- package/dist/{mcp-DXmBAF09.mjs → mcp-Cw7-Mtkm.mjs} +3 -3
- package/dist/{org-D4J-n07N.mjs → org-RRUxKfRw.mjs} +6 -6
- package/dist/{owner-CfjgcAcM.mjs → owner-GZX-sp-h.mjs} +1 -1
- package/dist/{pagination-rules-uMUdPq_7.mjs → pagination-rules-CMnBwktJ.mjs} +1 -1
- package/dist/pagination.mjs +1 -1
- package/dist/{project-Dw9JLelr.mjs → project-BsKmk9T7.mjs} +1 -1
- package/dist/{project-CnOrdnOM.mjs → project-C1uq7bV_.mjs} +1 -1
- package/dist/{project-7LL6W_tc.mjs → project-C_YZ-eLI.mjs} +4 -7
- package/dist/{project-CLrBv6tJ.mjs → project-Cj9ULE0a.mjs} +1 -1
- package/dist/{realtime-DQ_gT0q7.mjs → realtime-W-lJ0Vcs.mjs} +1 -1
- package/dist/resources/api-key-revocation.d.mts +1 -1
- package/dist/resources/api-key-revocation.mjs +1 -1
- package/dist/resources/auth/auth.d.mts +1 -1
- package/dist/resources/auth/auth.mjs +1 -1
- package/dist/resources/auth/index.d.mts +1 -1
- package/dist/resources/auth/index.mjs +2 -2
- package/dist/resources/auth/session.d.mts +1 -1
- package/dist/resources/auth/session.mjs +1 -1
- package/dist/resources/auth-configs.d.mts +1 -1
- package/dist/resources/auth-configs.mjs +1 -1
- package/dist/resources/auth.d.mts +1 -1
- package/dist/resources/auth.mjs +2 -2
- package/dist/resources/cli/cli.d.mts +1 -1
- package/dist/resources/cli/cli.mjs +1 -1
- package/dist/resources/cli/index.d.mts +1 -1
- package/dist/resources/cli/index.mjs +2 -2
- package/dist/resources/cli/realtime.d.mts +1 -1
- package/dist/resources/cli/realtime.mjs +1 -1
- package/dist/resources/cli.d.mts +1 -1
- package/dist/resources/cli.mjs +2 -2
- package/dist/resources/connected-accounts.d.mts +1 -1
- package/dist/resources/connected-accounts.mjs +1 -1
- package/dist/resources/custom.d.mts +1 -1
- package/dist/resources/custom.mjs +1 -1
- package/dist/resources/files.d.mts +1 -1
- package/dist/resources/files.mjs +1 -1
- package/dist/resources/index.d.mts +1 -1
- package/dist/resources/index.mjs +13 -13
- package/dist/resources/keyring.d.mts +1 -1
- package/dist/resources/keyring.mjs +1 -1
- package/dist/resources/link.d.mts +1 -1
- package/dist/resources/link.mjs +1 -1
- package/dist/resources/logs/index.d.mts +1 -1
- package/dist/resources/logs/index.mjs +3 -3
- package/dist/resources/logs/logs.d.mts +1 -1
- package/dist/resources/logs/logs.mjs +1 -1
- package/dist/resources/logs/tools.d.mts +1 -1
- package/dist/resources/logs/tools.mjs +1 -1
- package/dist/resources/logs/triggers.d.mts +1 -1
- package/dist/resources/logs/triggers.mjs +1 -1
- package/dist/resources/logs.d.mts +1 -1
- package/dist/resources/logs.mjs +3 -3
- package/dist/resources/mcp/custom.d.mts +1 -1
- package/dist/resources/mcp/custom.mjs +1 -1
- package/dist/resources/mcp/generate.d.mts +1 -1
- package/dist/resources/mcp/generate.mjs +1 -1
- package/dist/resources/mcp/index.d.mts +1 -1
- package/dist/resources/mcp/index.mjs +3 -3
- package/dist/resources/mcp/mcp.d.mts +1 -1
- package/dist/resources/mcp/mcp.mjs +1 -1
- package/dist/resources/mcp.d.mts +1 -1
- package/dist/resources/mcp.mjs +3 -3
- package/dist/resources/org/clanker.d.mts +1 -1
- package/dist/resources/org/clanker.mjs +1 -1
- package/dist/resources/org/consumer/consumer.d.mts +1 -1
- package/dist/resources/org/consumer/consumer.mjs +1 -1
- package/dist/resources/org/consumer/index.d.mts +1 -1
- package/dist/resources/org/consumer/index.mjs +2 -2
- package/dist/resources/org/consumer/project.d.mts +1 -1
- package/dist/resources/org/consumer/project.mjs +1 -1
- package/dist/resources/org/consumer.d.mts +1 -1
- package/dist/resources/org/consumer.mjs +2 -2
- package/dist/resources/org/index.d.mts +1 -1
- package/dist/resources/org/index.mjs +6 -6
- package/dist/resources/org/org.d.mts +1 -1
- package/dist/resources/org/org.mjs +1 -1
- package/dist/resources/org/owner/index.d.mts +1 -1
- package/dist/resources/org/owner/index.mjs +2 -2
- package/dist/resources/org/owner/owner.d.mts +1 -1
- package/dist/resources/org/owner/owner.mjs +1 -1
- package/dist/resources/org/owner/project.d.mts +1 -1
- package/dist/resources/org/owner/project.mjs +1 -1
- package/dist/resources/org/owner.d.mts +1 -1
- package/dist/resources/org/owner.mjs +2 -2
- package/dist/resources/org/project.d.mts +1 -1
- package/dist/resources/org/project.mjs +1 -1
- package/dist/resources/org/usage.d.mts +1 -1
- package/dist/resources/org/usage.mjs +1 -1
- package/dist/resources/org.d.mts +1 -1
- package/dist/resources/org.mjs +6 -6
- package/dist/resources/project/index.d.mts +1 -1
- package/dist/resources/project/index.mjs +1 -1
- package/dist/resources/project/project.d.mts +1 -1
- package/dist/resources/project/project.mjs +1 -1
- package/dist/resources/project/usage.d.mts +1 -1
- package/dist/resources/project/usage.mjs +1 -1
- package/dist/resources/project.d.mts +1 -1
- package/dist/resources/project.mjs +1 -1
- package/dist/resources/session-configs.d.mts +1 -1
- package/dist/resources/session-configs.mjs +1 -1
- package/dist/resources/tool-router/index.d.mts +1 -1
- package/dist/resources/tool-router/index.mjs +2 -2
- package/dist/resources/tool-router/session/files.d.mts +1 -1
- package/dist/resources/tool-router/session/files.mjs +1 -1
- package/dist/resources/tool-router/session/index.d.mts +1 -1
- package/dist/resources/tool-router/session/index.mjs +2 -2
- package/dist/resources/tool-router/session/session.d.mts +1 -1
- package/dist/resources/tool-router/session/session.mjs +1 -1
- package/dist/resources/tool-router/session.d.mts +1 -1
- package/dist/resources/tool-router/session.mjs +2 -2
- package/dist/resources/tool-router/tool-router.d.mts +1 -1
- package/dist/resources/tool-router/tool-router.mjs +1 -1
- package/dist/resources/tool-router.d.mts +1 -1
- package/dist/resources/tool-router.mjs +2 -2
- package/dist/resources/toolkits.d.mts +1 -1
- package/dist/resources/toolkits.mjs +1 -1
- package/dist/resources/tools.d.mts +1 -1
- package/dist/resources/tools.mjs +1 -1
- package/dist/resources/trigger-instances/index.d.mts +1 -1
- package/dist/resources/trigger-instances/index.mjs +2 -2
- package/dist/resources/trigger-instances/manage.d.mts +1 -1
- package/dist/resources/trigger-instances/manage.mjs +1 -1
- package/dist/resources/trigger-instances/trigger-instances.d.mts +1 -1
- package/dist/resources/trigger-instances/trigger-instances.mjs +1 -1
- package/dist/resources/trigger-instances.d.mts +1 -1
- package/dist/resources/trigger-instances.mjs +2 -2
- package/dist/resources/triggers-types.d.mts +1 -1
- package/dist/resources/triggers-types.mjs +1 -1
- package/dist/resources/webhook-endpoints.d.mts +1 -1
- package/dist/resources/webhook-endpoints.mjs +1 -1
- package/dist/resources/webhook-subscriptions.d.mts +1 -1
- package/dist/resources/webhook-subscriptions.mjs +1 -1
- package/dist/{session-CtO_BX-m.mjs → session-BT5NJfbm.mjs} +1 -1
- package/dist/{session-Bmbv2Y2h.mjs → session-BmXeclWC.mjs} +2 -2
- package/dist/{session-configs-C_A0gUf5.d.mts → session-configs-x3OA4CSe.d.mts} +205 -97
- package/dist/{tool-router-BICZScC1.mjs → tool-router-DYPUf-fN.mjs} +1 -1
- package/dist/{toolkits-Cj8oNvQi.mjs → toolkits-DZOZDm-4.mjs} +1 -1
- package/dist/{tools-C-2Nsm32.mjs → tools-BDCRk80t.mjs} +1 -1
- package/dist/{tools-BiyVpJSA.mjs → tools-C0GjPEpP.mjs} +1 -1
- package/dist/{trigger-instances-0GIUz_qu.mjs → trigger-instances-J5frdgzO.mjs} +2 -2
- package/dist/{triggers-DWnL3gjv.mjs → triggers-CnvE7y0L.mjs} +1 -1
- package/dist/{triggers-types-BkigxzlE.mjs → triggers-types-DLVCtuwC.mjs} +1 -1
- package/dist/{usage-RRYqkjLH.mjs → usage-DPxuivP6.mjs} +1 -1
- package/dist/{usage-D9XlIZBX.mjs → usage-DjQg9WIV.mjs} +1 -1
- package/dist/version-DEAhxVwC.d.mts +4 -0
- package/dist/{webhook-endpoints-x3UiV7uH.mjs → webhook-endpoints-BrSjXOf0.mjs} +1 -1
- package/dist/{webhook-subscriptions-_7MTwe1s.mjs → webhook-subscriptions-HT1acmwH.mjs} +1 -1
- package/package.json +2 -2
- package/dist/version-BkHUhokz.d.mts +0 -4
|
@@ -1,74 +1,5 @@
|
|
|
1
|
-
import { i as APIUserAbortError, n as APIConnectionTimeoutError, s as ComposioError, t as APIConnectionError } from "./error-
|
|
1
|
+
import { i as APIUserAbortError, n as APIConnectionTimeoutError, s as ComposioError, t as APIConnectionError } from "./error-Bw7_G2NZ.mjs";
|
|
2
2
|
|
|
3
|
-
//#region src/compat/headers.ts
|
|
4
|
-
const hasEntries = (value) => typeof value === "object" && value !== null && "append" in value && typeof value.append === "function" && "delete" in value && typeof value.delete === "function" && "entries" in value && typeof value.entries === "function" && "get" in value && typeof value.get === "function";
|
|
5
|
-
const isHeaders = (value) => value instanceof Headers || hasEntries(value);
|
|
6
|
-
const isNullableHeadersLike = (headers) => {
|
|
7
|
-
if (!("values" in headers) || !isHeaders(headers.values) || !("nulls" in headers)) return false;
|
|
8
|
-
const nulls = headers.nulls;
|
|
9
|
-
return typeof nulls === "object" && nulls !== null && Symbol.iterator in nulls;
|
|
10
|
-
};
|
|
11
|
-
/**
|
|
12
|
-
* Iterates every supported input while preserving explicit deletions. Plain
|
|
13
|
-
* objects replace an older value for a key; tuple inputs append duplicate
|
|
14
|
-
* values, matching the published client.
|
|
15
|
-
*/
|
|
16
|
-
function* iterateHeaders(headers) {
|
|
17
|
-
if (!headers) return;
|
|
18
|
-
if (isNullableHeadersLike(headers)) {
|
|
19
|
-
yield* headers.values.entries();
|
|
20
|
-
for (const name of headers.nulls) yield [name, null];
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const shouldReplace = !isHeaders(headers) && !Array.isArray(headers);
|
|
24
|
-
const entries = isHeaders(headers) ? headers.entries() : Array.isArray(headers) ? headers : Object.entries(headers);
|
|
25
|
-
for (const entry of entries) {
|
|
26
|
-
const name = entry[0];
|
|
27
|
-
if (typeof name !== "string") throw new TypeError("expected header name to be a string");
|
|
28
|
-
const rawValue = entry[1];
|
|
29
|
-
const values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
30
|
-
let replaced = false;
|
|
31
|
-
for (const value of values) {
|
|
32
|
-
if (value === void 0) continue;
|
|
33
|
-
if (shouldReplace && !replaced) {
|
|
34
|
-
replaced = true;
|
|
35
|
-
yield [name, null];
|
|
36
|
-
}
|
|
37
|
-
yield [name, value];
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
/** Merge sources while retaining names explicitly deleted by the last source. */
|
|
42
|
-
const mergeHeaders = (sources) => {
|
|
43
|
-
const values = new Headers();
|
|
44
|
-
const nulls = /* @__PURE__ */ new Set();
|
|
45
|
-
for (const source of sources) {
|
|
46
|
-
if (!source) continue;
|
|
47
|
-
const seen = /* @__PURE__ */ new Set();
|
|
48
|
-
for (const [name, value] of iterateHeaders(source)) {
|
|
49
|
-
const lowerName = name.toLowerCase();
|
|
50
|
-
if (!seen.has(lowerName)) {
|
|
51
|
-
values.delete(name);
|
|
52
|
-
seen.add(lowerName);
|
|
53
|
-
}
|
|
54
|
-
if (value === null) {
|
|
55
|
-
values.delete(name);
|
|
56
|
-
nulls.add(lowerName);
|
|
57
|
-
} else {
|
|
58
|
-
values.append(name, value);
|
|
59
|
-
nulls.delete(lowerName);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
values,
|
|
65
|
-
nulls
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
/** Merge sources into the native header collection sent to fetch. */
|
|
69
|
-
const buildHeaders = (sources) => mergeHeaders(sources).values;
|
|
70
|
-
|
|
71
|
-
//#endregion
|
|
72
3
|
//#region src/compat/credentials.ts
|
|
73
4
|
/**
|
|
74
5
|
* The credential transport boundary.
|
|
@@ -90,8 +21,8 @@ const buildHeaders = (sources) => mergeHeaders(sources).values;
|
|
|
90
21
|
* caller opts into with `allowInsecureHTTP` or
|
|
91
22
|
* `COMPOSIO_ALLOW_INSECURE_HTTP=1`.
|
|
92
23
|
* Enforced by {@link assertCredentialTransport} at construction and again
|
|
93
|
-
* by {@link credentialForRequest} at dispatch, because `
|
|
94
|
-
*
|
|
24
|
+
* by {@link credentialForRequest} at dispatch, because `baseURL` is a
|
|
25
|
+
* public mutable field on the client.
|
|
95
26
|
* 2. **The credential is attached only to requests whose origin matches the
|
|
96
27
|
* configured API origin.** {@link credentialForRequest} returns `null`
|
|
97
28
|
* off-origin, and the header is simply not sent.
|
|
@@ -154,22 +85,10 @@ const SCHEME_HEADERS = {
|
|
|
154
85
|
};
|
|
155
86
|
/** The scheme a request authenticates with when its operation names none. */
|
|
156
87
|
const DEFAULT_SCHEME = "ApiKeyAuth";
|
|
157
|
-
const valueFor = (scheme, credentials) => scheme === "ApiKeyAuth" ? credentials.apiKey : scheme === "UserApiKeyAuth" ? credentials.userApiKey : credentials.orgApiKey;
|
|
158
|
-
/**
|
|
159
|
-
* Whether anything beyond the project key is configured — the condition that
|
|
160
|
-
* makes per-operation selection able to change an outcome at all.
|
|
161
|
-
*
|
|
162
|
-
* Load-bearing rather than an optimization. With only `apiKey` set, every
|
|
163
|
-
* branch of {@link selectScheme} lands on `ApiKeyAuth`: it wins wherever it is
|
|
164
|
-
* an accepted alternative, and where it is not, the alternative is unconfigured
|
|
165
|
-
* and the fallback is `ApiKeyAuth` again. So the client that every existing
|
|
166
|
-
* caller constructs never consults the operation table, and "an `apiKey`-only
|
|
167
|
-
* client emits byte-identical requests on all 104 operations" is a property of
|
|
168
|
-
* the code shape rather than a claim tests have to keep re-establishing.
|
|
169
|
-
*/
|
|
170
|
-
const hasAlternateCredential = (credentials) => credentials.userApiKey !== null || credentials.orgApiKey !== null;
|
|
171
88
|
/**
|
|
172
|
-
* Which credential a request declaring `schemes` should carry
|
|
89
|
+
* Which credential a request declaring `schemes` should carry, for a client in
|
|
90
|
+
* `auto` mode holding the schemes `held` answers `true` for. A fixed mode never
|
|
91
|
+
* asks: it always sends its own.
|
|
173
92
|
*
|
|
174
93
|
* **Exactly one, always** — and the API says so itself. Measured against
|
|
175
94
|
* production on 2026-08-06, `GET /toolkits` answers 200 for `x-api-key` alone
|
|
@@ -187,37 +106,38 @@ const hasAlternateCredential = (credentials) => credentials.userApiKey !== null
|
|
|
187
106
|
* model available, and the choice has to be made per request rather than
|
|
188
107
|
* accumulated.
|
|
189
108
|
*
|
|
190
|
-
* The precedence
|
|
109
|
+
* The precedence is the one every release before `rc.18` applied:
|
|
191
110
|
*
|
|
192
|
-
* 1. **`ApiKeyAuth` wins wherever the operation accepts it** and
|
|
193
|
-
*
|
|
111
|
+
* 1. **`ApiKeyAuth` wins wherever the operation accepts it** and a project key
|
|
112
|
+
* is held.
|
|
194
113
|
* 2. Otherwise the first scheme the operation names that this client both
|
|
195
|
-
* recognizes *and* holds a credential for. That is what makes the
|
|
114
|
+
* recognizes *and* holds a credential for. That is what makes the
|
|
196
115
|
* `UserApiKeyAuth`-only and `OrgApiKeyAuth`-only operations reachable.
|
|
197
116
|
* 3. Otherwise `ApiKeyAuth`, which is what this client did before any of this
|
|
198
117
|
* existed. A `UserApiKeyAuth`-only operation called by a client with no user
|
|
199
|
-
* key still sends `x-api-key` and still fails the same way
|
|
200
|
-
* keeps `cli.realtime.auth` and `cli.realtime.credentials` pinned against
|
|
201
|
-
* the Stainless oracle in `test/unit/differential-wire.test.ts`.
|
|
118
|
+
* key still sends `x-api-key` and still fails the same way.
|
|
202
119
|
*
|
|
203
120
|
* Rule 3 is also where a scheme name this client does not know lands. Three of
|
|
204
121
|
* them exist: `security` references `no_auth` (3 operations) and
|
|
205
122
|
* `workbench_access_key` (1) and `components.securitySchemes` declares neither.
|
|
206
|
-
* Those four operations receive `x-api-key
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* must not "fix" that.
|
|
123
|
+
* Those four operations receive `x-api-key`, so resolving an unknown name to
|
|
124
|
+
* "no credential" would be a wire change made on the strength of a spec defect.
|
|
125
|
+
* A later generator pass must not "fix" that.
|
|
210
126
|
*/
|
|
211
|
-
const selectScheme = (schemes,
|
|
127
|
+
const selectScheme = (schemes, held) => {
|
|
212
128
|
if (schemes === void 0 || schemes.length === 0) return DEFAULT_SCHEME;
|
|
213
|
-
if (schemes.includes(DEFAULT_SCHEME) &&
|
|
129
|
+
if (schemes.includes(DEFAULT_SCHEME) && held(DEFAULT_SCHEME)) return DEFAULT_SCHEME;
|
|
214
130
|
for (const scheme of schemes) {
|
|
215
131
|
if (!Object.hasOwn(SCHEME_HEADERS, scheme)) continue;
|
|
216
132
|
const known = scheme;
|
|
217
|
-
if (
|
|
133
|
+
if (held(known)) return known;
|
|
218
134
|
}
|
|
219
135
|
return DEFAULT_SCHEME;
|
|
220
136
|
};
|
|
137
|
+
/** The header `scheme` is sent as. */
|
|
138
|
+
const schemeHeader = (scheme) => SCHEME_HEADERS[scheme];
|
|
139
|
+
/** The scheme a credential header name belongs to, or `undefined` for any other name. */
|
|
140
|
+
const schemeOfHeader = (name) => Object.keys(SCHEME_HEADERS).find((scheme) => SCHEME_HEADERS[scheme] === name);
|
|
221
141
|
/**
|
|
222
142
|
* What counts as loopback, pinned rather than assumed. `localhost` is not the
|
|
223
143
|
* whole set:
|
|
@@ -272,8 +192,6 @@ const resolveHTTPURL = (target, base) => {
|
|
|
272
192
|
const isCredentialSafeOrigin = (url, allowedHTTPOrigin = null) => url.protocol === "https:" || url.protocol === "http:" && (isLoopbackHostname(url.hostname) || allowedHTTPOrigin !== null && url.origin === allowedHTTPOrigin);
|
|
273
193
|
const LOOPBACK_DESCRIPTION = "localhost, *.localhost, 127.0.0.0/8, [::1]";
|
|
274
194
|
const insecureOriginMessage = (baseURL) => `Refusing to send a Composio API credential to ${baseURL}: a credentialed API origin must use HTTPS. By default, plain http:// is permitted only for loopback development endpoints (${LOOPBACK_DESCRIPTION}). Pass an https:// baseURL, use environment: 'local', set allowInsecureHTTP: true (or COMPOSIO_ALLOW_INSECURE_HTTP=1) for the configured development origin, or construct the client without credentials.`;
|
|
275
|
-
/** Whether the client holds anything at all that rule 1 has to protect. */
|
|
276
|
-
const anyCredential = (credentials) => credentials.apiKey !== null || hasAlternateCredential(credentials);
|
|
277
195
|
/**
|
|
278
196
|
* Rule 1 at construction time: a client that holds a credential must be
|
|
279
197
|
* pointed at an origin that can carry one. Knowable before any request is
|
|
@@ -282,13 +200,9 @@ const anyCredential = (credentials) => credentials.apiKey !== null || hasAlterna
|
|
|
282
200
|
* A `baseURL` that is not an absolute http(s) URL fails the same way — a
|
|
283
201
|
* credential cannot be sent over a scheme this client does not speak, and the
|
|
284
202
|
* alternative is a `TypeError` from `new URL()` one layer down.
|
|
285
|
-
*
|
|
286
|
-
* Every configured credential counts, not just `apiKey`: which one a given
|
|
287
|
-
* request carries is decided per operation, so a client holding *any* of them
|
|
288
|
-
* is a client that can put one on the wire.
|
|
289
203
|
*/
|
|
290
|
-
const assertCredentialTransport = (baseURL,
|
|
291
|
-
if (!
|
|
204
|
+
const assertCredentialTransport = (baseURL, credentialed, allowedHTTPOrigin = null) => {
|
|
205
|
+
if (!credentialed) return;
|
|
292
206
|
const url = parseHTTPURL(baseURL);
|
|
293
207
|
if (url === null || !isCredentialSafeOrigin(url, allowedHTTPOrigin)) throw new ComposioError(insecureOriginMessage(baseURL));
|
|
294
208
|
};
|
|
@@ -296,7 +210,7 @@ const assertCredentialTransport = (baseURL, credentials, allowedHTTPOrigin = nul
|
|
|
296
210
|
* The credential this request may carry, or `null` for none.
|
|
297
211
|
*
|
|
298
212
|
* Rules 1 and 2 at dispatch time. Both re-checks are load-bearing rather than
|
|
299
|
-
* belt-and-braces: `
|
|
213
|
+
* belt-and-braces: `baseURL` is a public mutable field, so the
|
|
300
214
|
* construction-time check can be invalidated by an assignment, and the request
|
|
301
215
|
* URL is *not* guaranteed to sit on the configured origin. `buildURL`
|
|
302
216
|
* concatenates `baseURL + path` and the escape hatch (`client.get(path)`)
|
|
@@ -310,18 +224,14 @@ const assertCredentialTransport = (baseURL, credentials, allowedHTTPOrigin = nul
|
|
|
310
224
|
* with credentials, so that one dies at the transport instead. httpx has no
|
|
311
225
|
* such objection, which is why the Python port checks the same thing.)
|
|
312
226
|
*/
|
|
313
|
-
const credentialForRequest = (baseURL,
|
|
314
|
-
|
|
315
|
-
if (value === null) return null;
|
|
227
|
+
const credentialForRequest = (baseURL, credential, requestURL, allowedHTTPOrigin = null) => {
|
|
228
|
+
if (credential === null) return null;
|
|
316
229
|
const base = parseHTTPURL(baseURL);
|
|
317
230
|
const target = parseHTTPURL(requestURL);
|
|
318
231
|
if (base === null || target === null) return null;
|
|
319
232
|
if (base.origin !== target.origin) return null;
|
|
320
233
|
if (!isCredentialSafeOrigin(target, allowedHTTPOrigin)) throw new ComposioError(insecureOriginMessage(baseURL));
|
|
321
|
-
return
|
|
322
|
-
name: SCHEME_HEADERS[scheme],
|
|
323
|
-
value
|
|
324
|
-
};
|
|
234
|
+
return credential;
|
|
325
235
|
};
|
|
326
236
|
/**
|
|
327
237
|
* Whether two absolute http(s) URLs share an origin, by the same test
|
|
@@ -333,34 +243,6 @@ const sameOrigin = (a, b) => {
|
|
|
333
243
|
return origin !== void 0 && origin === parseHTTPURL(b)?.origin;
|
|
334
244
|
};
|
|
335
245
|
/**
|
|
336
|
-
* The credential headers a *caller* can place that are not the one this client
|
|
337
|
-
* attaches — `x-api-key` is excluded because a caller setting it is overriding
|
|
338
|
-
* the client's own value in the same slot, which is pinned Stainless behaviour,
|
|
339
|
-
* not a second credential.
|
|
340
|
-
*/
|
|
341
|
-
const FOREIGN_CREDENTIAL_HEADERS = ["x-user-api-key", "x-org-api-key"];
|
|
342
|
-
/**
|
|
343
|
-
* Whether the caller has placed a credential of their own, in which case the
|
|
344
|
-
* client must not add one beside it.
|
|
345
|
-
*
|
|
346
|
-
* Not a courtesy: this API answers a request carrying two credential headers
|
|
347
|
-
* with `401 HTTP_Unauthorized`, so attaching `x-api-key` next to a caller's
|
|
348
|
-
* `x-user-api-key` does not weaken the call, it *breaks* it. Three released
|
|
349
|
-
* methods make that reachable without any `defaultHeaders` at all —
|
|
350
|
-
* `cli.createCodactFailure`, `org.consumer.project.resolve` and
|
|
351
|
-
* `org.consumer.listConnectedToolkits` declare `x-user-api-key` as a `required`
|
|
352
|
-
* header parameter, which the generator folds into their params object. Calling
|
|
353
|
-
* them the way their signature asks for returned 401 until this rule existed.
|
|
354
|
-
*
|
|
355
|
-
* Header merging is replayed rather than approximated, because a later source
|
|
356
|
-
* may carry `null` to delete what an earlier one set (`buildHeaders`).
|
|
357
|
-
*/
|
|
358
|
-
const callerPlacedCredential = (sources) => {
|
|
359
|
-
if (!sources.some(Boolean)) return false;
|
|
360
|
-
const headers = buildHeaders(sources);
|
|
361
|
-
return FOREIGN_CREDENTIAL_HEADERS.some((name) => headers.has(name));
|
|
362
|
-
};
|
|
363
|
-
/**
|
|
364
246
|
* Header names that carry a credential and must not survive an origin change.
|
|
365
247
|
*
|
|
366
248
|
* The first three are what `fetch` itself would have stripped had it been
|
|
@@ -433,6 +315,211 @@ const withdrawCredentials = (headers) => {
|
|
|
433
315
|
*/
|
|
434
316
|
const carriesCredentials = (headers) => CREDENTIAL_HEADERS.some((name) => headers.has(name));
|
|
435
317
|
|
|
318
|
+
//#endregion
|
|
319
|
+
//#region src/compat/auth.ts
|
|
320
|
+
/**
|
|
321
|
+
* Who a client authenticates as (`Auth`) and which organization or project it
|
|
322
|
+
* addresses (`Scope`).
|
|
323
|
+
*
|
|
324
|
+
* A request carries zero or one Composio credential. A fixed mode sends that
|
|
325
|
+
* credential class on every request to the API origin and never consults the
|
|
326
|
+
* operation table; `auto` picks one configured credential from the operation's
|
|
327
|
+
* declared schemes, which is how `rc.17` and earlier chose. `none` sends no
|
|
328
|
+
* credential, and leaves the credential header names to the caller.
|
|
329
|
+
*/
|
|
330
|
+
const NONE = Object.freeze({ mode: "none" });
|
|
331
|
+
/** The constructors, typed for one entry's credential. Every entry's behave the same. */
|
|
332
|
+
const authConstructors = () => Object.freeze({
|
|
333
|
+
none: () => NONE,
|
|
334
|
+
project: (credential) => Object.freeze({
|
|
335
|
+
mode: "project",
|
|
336
|
+
credential
|
|
337
|
+
}),
|
|
338
|
+
user: (credential) => Object.freeze({
|
|
339
|
+
mode: "user",
|
|
340
|
+
credential
|
|
341
|
+
}),
|
|
342
|
+
organization: (credential) => Object.freeze({
|
|
343
|
+
mode: "organization",
|
|
344
|
+
credential
|
|
345
|
+
}),
|
|
346
|
+
auto: (credentials) => Object.freeze({
|
|
347
|
+
mode: "auto",
|
|
348
|
+
credentials: Object.freeze({ ...credentials })
|
|
349
|
+
})
|
|
350
|
+
});
|
|
351
|
+
/** The constructors of {@link Auth}: `Auth.project(key)`, `Auth.user(key)`, `Auth.organization(key)`, `Auth.auto({ ... })`, `Auth.none()`. */
|
|
352
|
+
const Auth = authConstructors();
|
|
353
|
+
/**
|
|
354
|
+
* The rule `fromEnv` and the Effect `layerConfig` share: one credential given
|
|
355
|
+
* is that fixed mode, several is `auto` over them, none is `none`. Generic over
|
|
356
|
+
* what a credential is, so the Effect entry keeps its `Redacted` values.
|
|
357
|
+
*/
|
|
358
|
+
const authFromCredentials = (credentials) => {
|
|
359
|
+
const given = [
|
|
360
|
+
"project",
|
|
361
|
+
"user",
|
|
362
|
+
"organization"
|
|
363
|
+
].filter((key) => credentials[key] !== void 0);
|
|
364
|
+
if (given.length === 0) return NONE;
|
|
365
|
+
if (given.length > 1) return authConstructors().auto(Object.fromEntries(given.map((key) => [key, credentials[key]])));
|
|
366
|
+
const [only] = given;
|
|
367
|
+
return authConstructors()[only](credentials[only]);
|
|
368
|
+
};
|
|
369
|
+
const MODE_SCHEME = {
|
|
370
|
+
project: "ApiKeyAuth",
|
|
371
|
+
user: "UserApiKeyAuth",
|
|
372
|
+
organization: "OrgApiKeyAuth"
|
|
373
|
+
};
|
|
374
|
+
/** The scheme each credential class authenticates with, keyed by mode. */
|
|
375
|
+
const schemeOfMode = (mode) => MODE_SCHEME[mode];
|
|
376
|
+
const MIGRATION = "Pass `auth`: `Auth.project(key)`, `Auth.user(key)`, `Auth.organization(key)`, `Auth.auto({ project, user, organization })` or `Auth.none()`.";
|
|
377
|
+
/** The credential options `rc.18` removed, each with the `auth` that replaces it. */
|
|
378
|
+
const REMOVED_OPTIONS = {
|
|
379
|
+
apiKey: "Auth.project(key)",
|
|
380
|
+
userApiKey: "Auth.user(key)",
|
|
381
|
+
orgApiKey: "Auth.organization(key)"
|
|
382
|
+
};
|
|
383
|
+
/**
|
|
384
|
+
* Refuses a removed credential option, which TypeScript already rejects, for
|
|
385
|
+
* a caller it did not reach.
|
|
386
|
+
*/
|
|
387
|
+
const assertNoRemovedCredentialOptions = (options) => {
|
|
388
|
+
for (const [option, replacement] of Object.entries(REMOVED_OPTIONS)) if (Object.hasOwn(options, option)) throw new ComposioError(`The \`${option}\` option was removed in 2.0.0-rc.18. Pass \`auth: ${replacement}\` instead, or \`Auth.auto({ ... })\` for per-operation selection.`);
|
|
389
|
+
};
|
|
390
|
+
/**
|
|
391
|
+
* Validates `auth` and lays it out by scheme. `isCredential` decides what a
|
|
392
|
+
* credential may be on the calling entry; `checkKey` validates a key that is
|
|
393
|
+
* already known, so a bad literal fails here rather than on the first request.
|
|
394
|
+
*/
|
|
395
|
+
const resolveAuth = (auth, isCredential, checkKey) => {
|
|
396
|
+
if (typeof auth !== "object" || auth === null || !("mode" in auth)) throw new ComposioError(`\`auth\` is required. ${MIGRATION}`);
|
|
397
|
+
const value = auth;
|
|
398
|
+
const held = (credential, option) => {
|
|
399
|
+
if (!isCredential(credential)) throw new ComposioError(`\`${option}\` must be a key or a function that returns one.`);
|
|
400
|
+
checkKey(credential, option);
|
|
401
|
+
return credential;
|
|
402
|
+
};
|
|
403
|
+
switch (value.mode) {
|
|
404
|
+
case "none": return {
|
|
405
|
+
mode: "none",
|
|
406
|
+
credentials: {}
|
|
407
|
+
};
|
|
408
|
+
case "project":
|
|
409
|
+
case "user":
|
|
410
|
+
case "organization": return {
|
|
411
|
+
mode: value.mode,
|
|
412
|
+
credentials: { [MODE_SCHEME[value.mode]]: held(value.credential, "auth.credential") }
|
|
413
|
+
};
|
|
414
|
+
case "auto": {
|
|
415
|
+
const given = value.credentials;
|
|
416
|
+
if (typeof given !== "object" || given === null) throw new ComposioError("`Auth.auto` needs at least one of `project`, `user` and `organization`.");
|
|
417
|
+
const credentials = {};
|
|
418
|
+
for (const [key, scheme] of Object.entries(MODE_SCHEME)) {
|
|
419
|
+
const credential = given[key];
|
|
420
|
+
if (credential !== void 0) credentials[scheme] = held(credential, `auth.credentials.${key}`);
|
|
421
|
+
}
|
|
422
|
+
if (Object.keys(credentials).length === 0) throw new ComposioError("`Auth.auto` needs at least one of `project`, `user` and `organization`.");
|
|
423
|
+
return {
|
|
424
|
+
mode: "auto",
|
|
425
|
+
credentials
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
default: throw new ComposioError(`\`auth.mode\` must be 'none', 'project', 'user', 'organization' or 'auto'. ${MIGRATION}`);
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
/** Whether the platform's `Headers` takes `value` under `name`. Its refusal quotes the value, so it stays here. */
|
|
432
|
+
const isSendable = (name, value) => {
|
|
433
|
+
try {
|
|
434
|
+
new globalThis.Headers().set(name, value);
|
|
435
|
+
return true;
|
|
436
|
+
} catch {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
/**
|
|
441
|
+
* Whether `key` can be sent as `scheme`'s header: a string with a
|
|
442
|
+
* non-whitespace character that the platform's `Headers` accepts. It is sent
|
|
443
|
+
* as given.
|
|
444
|
+
*/
|
|
445
|
+
const isUsableKey = (scheme, key) => typeof key === "string" && /\S/.test(key) && isSendable(SCHEME_HEADERS[scheme], key);
|
|
446
|
+
/** The error for a key that cannot be sent. It names where the key came from and never the key. */
|
|
447
|
+
const unusableKeyError = (source) => new ComposioError(`${source} is not a usable key: it must be a string with a non-whitespace character and no line break, NUL or character outside Latin-1.`);
|
|
448
|
+
const SCOPE_ID = /^\S(?:.*\S)?$/s;
|
|
449
|
+
/** Validates `scope` (an id must be non-empty with no surrounding whitespace) and returns the headers it sends. */
|
|
450
|
+
const resolveScope = (scope) => {
|
|
451
|
+
if (scope === void 0) return void 0;
|
|
452
|
+
if (typeof scope !== "object" || scope === null) throw new ComposioError("`scope` must be an object with an `organizationId`, a `projectId`, or both.");
|
|
453
|
+
const { organizationId, projectId } = scope;
|
|
454
|
+
if (organizationId === void 0 && projectId === void 0) throw new ComposioError("`scope` must name an `organizationId`, a `projectId`, or both.");
|
|
455
|
+
const headers = {};
|
|
456
|
+
for (const [field, header, value] of [[
|
|
457
|
+
"organizationId",
|
|
458
|
+
"x-org-id",
|
|
459
|
+
organizationId
|
|
460
|
+
], [
|
|
461
|
+
"projectId",
|
|
462
|
+
"x-project-id",
|
|
463
|
+
projectId
|
|
464
|
+
]]) {
|
|
465
|
+
if (value === void 0) continue;
|
|
466
|
+
if (typeof value !== "string" || !SCOPE_ID.test(value) || !isSendable(header, value)) throw new ComposioError(`\`scope.${field}\` must be a non-empty string with no surrounding whitespace.`);
|
|
467
|
+
headers[header] = value;
|
|
468
|
+
}
|
|
469
|
+
return headers;
|
|
470
|
+
};
|
|
471
|
+
/** The header names `auth` owns while it is not `none`. */
|
|
472
|
+
const CREDENTIAL_HEADER_NAMES = Object.values(SCHEME_HEADERS);
|
|
473
|
+
/** The header names `scope` owns while it is set. */
|
|
474
|
+
const SCOPE_HEADER_NAMES = ["x-org-id", "x-project-id"];
|
|
475
|
+
/**
|
|
476
|
+
* Fails a generated call whose operation requires an owned header parameter it
|
|
477
|
+
* did not supply. It does not fall back to the configured `auth` or `scope`:
|
|
478
|
+
* the operation asked for a value of its own.
|
|
479
|
+
*/
|
|
480
|
+
const assertRequiredOperationHeaders = (operation, supplied) => {
|
|
481
|
+
for (const name of operation?.requiredHeaders ?? []) if (supplied?.[name] == null) throw new ComposioError(`\`${operation?.chain.join(".")}\` requires the \`${name}\` parameter.`);
|
|
482
|
+
};
|
|
483
|
+
const chooseCredential = (auth, operation, supplied) => {
|
|
484
|
+
for (const [name, value] of Object.entries(supplied ?? {})) {
|
|
485
|
+
const scheme = schemeOfHeader(name);
|
|
486
|
+
if (scheme === void 0 || value == null) continue;
|
|
487
|
+
if (!isUsableKey(scheme, value)) throw unusableKeyError(`The \`${name}\` parameter`);
|
|
488
|
+
return {
|
|
489
|
+
kind: "operation",
|
|
490
|
+
scheme,
|
|
491
|
+
key: value
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
if (auth.mode === "none") return null;
|
|
495
|
+
const scheme = auth.mode === "auto" ? selectScheme(operation?.schemes, (candidate) => auth.credentials[candidate] !== void 0) : schemeOfMode(auth.mode);
|
|
496
|
+
const credential = auth.credentials[scheme];
|
|
497
|
+
return credential === void 0 ? null : {
|
|
498
|
+
kind: "configured",
|
|
499
|
+
scheme,
|
|
500
|
+
credential
|
|
501
|
+
};
|
|
502
|
+
};
|
|
503
|
+
/**
|
|
504
|
+
* The routing headers one call sends: the configured scope, with any operation
|
|
505
|
+
* scope id the call supplied in its place. Where both name the same id they
|
|
506
|
+
* must agree; a call that disagrees with its own client fails before dispatch.
|
|
507
|
+
*/
|
|
508
|
+
const scopeForCall = (configured, supplied) => {
|
|
509
|
+
let merged = configured;
|
|
510
|
+
for (const name of SCOPE_HEADER_NAMES) {
|
|
511
|
+
const value = supplied?.[name];
|
|
512
|
+
if (value == null) continue;
|
|
513
|
+
const current = configured?.[name];
|
|
514
|
+
if (current !== void 0 && current !== value) throw new ComposioError(`The \`${name}\` parameter disagrees with the client's \`scope\`. Derive a client with \`withOptions({ scope })\` to address another one.`);
|
|
515
|
+
merged = {
|
|
516
|
+
...merged,
|
|
517
|
+
[name]: value
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
return merged;
|
|
521
|
+
};
|
|
522
|
+
|
|
436
523
|
//#endregion
|
|
437
524
|
//#region src/compat/deprecation.ts
|
|
438
525
|
/**
|
|
@@ -903,45 +990,266 @@ const inspectDeprecatedInputs = ({ operation, query, body, headers, table, seen,
|
|
|
903
990
|
}
|
|
904
991
|
};
|
|
905
992
|
|
|
993
|
+
//#endregion
|
|
994
|
+
//#region src/compat/headers.ts
|
|
995
|
+
const hasEntries = (value) => typeof value === "object" && value !== null && "append" in value && typeof value.append === "function" && "delete" in value && typeof value.delete === "function" && "entries" in value && typeof value.entries === "function" && "get" in value && typeof value.get === "function";
|
|
996
|
+
const isHeaders = (value) => value instanceof Headers || hasEntries(value);
|
|
997
|
+
const isNullableHeadersLike = (headers) => {
|
|
998
|
+
if (!("values" in headers) || !isHeaders(headers.values) || !("nulls" in headers)) return false;
|
|
999
|
+
const nulls = headers.nulls;
|
|
1000
|
+
return typeof nulls === "object" && nulls !== null && Symbol.iterator in nulls;
|
|
1001
|
+
};
|
|
1002
|
+
/**
|
|
1003
|
+
* Iterates every supported input while preserving explicit deletions. Plain
|
|
1004
|
+
* objects replace an older value for a key; tuple inputs append duplicate
|
|
1005
|
+
* values, matching the published client.
|
|
1006
|
+
*/
|
|
1007
|
+
function* iterateHeaders(headers) {
|
|
1008
|
+
if (!headers) return;
|
|
1009
|
+
if (isNullableHeadersLike(headers)) {
|
|
1010
|
+
yield* headers.values.entries();
|
|
1011
|
+
for (const name of headers.nulls) yield [name, null];
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
const shouldReplace = !isHeaders(headers) && !Array.isArray(headers);
|
|
1015
|
+
const entries = isHeaders(headers) ? headers.entries() : Array.isArray(headers) ? headers : Object.entries(headers);
|
|
1016
|
+
for (const entry of entries) {
|
|
1017
|
+
const name = entry[0];
|
|
1018
|
+
if (typeof name !== "string") throw new TypeError("expected header name to be a string");
|
|
1019
|
+
const rawValue = entry[1];
|
|
1020
|
+
const values = Array.isArray(rawValue) ? rawValue : [rawValue];
|
|
1021
|
+
let replaced = false;
|
|
1022
|
+
for (const value of values) {
|
|
1023
|
+
if (value === void 0) continue;
|
|
1024
|
+
if (shouldReplace && !replaced) {
|
|
1025
|
+
replaced = true;
|
|
1026
|
+
yield [name, null];
|
|
1027
|
+
}
|
|
1028
|
+
yield [name, value];
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
/** Merge sources while retaining names explicitly deleted by the last source. */
|
|
1033
|
+
const mergeHeaders = (sources) => {
|
|
1034
|
+
const values = new Headers();
|
|
1035
|
+
const nulls = /* @__PURE__ */ new Set();
|
|
1036
|
+
for (const source of sources) {
|
|
1037
|
+
if (!source) continue;
|
|
1038
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1039
|
+
for (const [name, value] of iterateHeaders(source)) {
|
|
1040
|
+
const lowerName = name.toLowerCase();
|
|
1041
|
+
if (!seen.has(lowerName)) {
|
|
1042
|
+
values.delete(name);
|
|
1043
|
+
seen.add(lowerName);
|
|
1044
|
+
}
|
|
1045
|
+
if (value === null) {
|
|
1046
|
+
values.delete(name);
|
|
1047
|
+
nulls.add(lowerName);
|
|
1048
|
+
} else {
|
|
1049
|
+
values.append(name, value);
|
|
1050
|
+
nulls.delete(lowerName);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
return {
|
|
1055
|
+
values,
|
|
1056
|
+
nulls
|
|
1057
|
+
};
|
|
1058
|
+
};
|
|
1059
|
+
/** Merge sources into the native header collection sent to fetch. */
|
|
1060
|
+
const buildHeaders = (sources) => mergeHeaders(sources).values;
|
|
1061
|
+
/** Every header name a source mentions, lowercased, a `null` deletion included. */
|
|
1062
|
+
function* headerNames(headers) {
|
|
1063
|
+
for (const [name] of iterateHeaders(headers)) yield name.toLowerCase();
|
|
1064
|
+
}
|
|
1065
|
+
|
|
906
1066
|
//#endregion
|
|
907
1067
|
//#region src/version.ts
|
|
908
|
-
const VERSION = "2.0.0-rc.
|
|
1068
|
+
const VERSION = "2.0.0-rc.18";
|
|
909
1069
|
|
|
910
1070
|
//#endregion
|
|
911
|
-
//#region src/compat/
|
|
1071
|
+
//#region src/compat/identity.ts
|
|
1072
|
+
/**
|
|
1073
|
+
* The runtime keys `std-env` detects, in its order, each with the label this
|
|
1074
|
+
* client sends as `x-client-runtime`. Ported from std-env 4.3.0
|
|
1075
|
+
* (https://github.com/unjs/std-env, MIT) rather than imported: std-env reads
|
|
1076
|
+
* `process.env` when it is imported, which throws under Deno without
|
|
1077
|
+
* `--allow-env`, and this needs only the runtime check.
|
|
1078
|
+
*
|
|
1079
|
+
* The labels are the ones released clients already send and the platform
|
|
1080
|
+
* already normalizes (`nodejs`, `cloudflare`, `vercel_edge`, ...), so a
|
|
1081
|
+
* dashboard groups old and new traffic together. Edge runtimes come before
|
|
1082
|
+
* Node because `nodejs_compat` and edge polyfills expose `process.versions.node`.
|
|
1083
|
+
*/
|
|
1084
|
+
const RUNTIMES = [
|
|
1085
|
+
[
|
|
1086
|
+
"netlify",
|
|
1087
|
+
"netlify",
|
|
1088
|
+
(g) => "Netlify" in g
|
|
1089
|
+
],
|
|
1090
|
+
[
|
|
1091
|
+
"edge-light",
|
|
1092
|
+
"vercel_edge",
|
|
1093
|
+
(g) => "EdgeRuntime" in g
|
|
1094
|
+
],
|
|
1095
|
+
[
|
|
1096
|
+
"workerd",
|
|
1097
|
+
"cloudflare",
|
|
1098
|
+
(g) => g.navigator?.userAgent === "Cloudflare-Workers"
|
|
1099
|
+
],
|
|
1100
|
+
[
|
|
1101
|
+
"fastly",
|
|
1102
|
+
"fastly",
|
|
1103
|
+
(g) => "fastly" in g
|
|
1104
|
+
],
|
|
1105
|
+
[
|
|
1106
|
+
"deno",
|
|
1107
|
+
"deno",
|
|
1108
|
+
(g) => "Deno" in g
|
|
1109
|
+
],
|
|
1110
|
+
[
|
|
1111
|
+
"bun",
|
|
1112
|
+
"bun",
|
|
1113
|
+
(g) => "Bun" in g
|
|
1114
|
+
],
|
|
1115
|
+
[
|
|
1116
|
+
"node",
|
|
1117
|
+
"nodejs",
|
|
1118
|
+
(g) => Boolean(g.process?.versions?.node)
|
|
1119
|
+
]
|
|
1120
|
+
];
|
|
912
1121
|
/**
|
|
913
|
-
* The runtime label and version
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
* version is never sent as theirs.
|
|
1122
|
+
* The runtime label and its version. The version is `process.versions[key]`,
|
|
1123
|
+
* which Node, Bun and Deno each set for themselves; an edge runtime reports
|
|
1124
|
+
* none, so a polyfilled Node version is never sent as its own.
|
|
917
1125
|
*/
|
|
918
1126
|
const detectRuntime = () => {
|
|
919
1127
|
const g = globalThis;
|
|
920
|
-
|
|
921
|
-
if (g.Deno !== void 0) return ["deno", g.Deno.version?.deno];
|
|
922
|
-
if (g.navigator?.userAgent === "Cloudflare-Workers" || g.caches !== void 0 && g.WebSocketPair !== void 0) return ["cloudflare", void 0];
|
|
923
|
-
if (g.EdgeRuntime !== void 0) return ["vercel_edge", void 0];
|
|
924
|
-
if (typeof process !== "undefined" && process.versions?.node) return ["nodejs", process.versions.node];
|
|
925
|
-
if (typeof g.ServiceWorkerGlobalScope === "function" && globalThis instanceof g.ServiceWorkerGlobalScope) return ["service_worker", void 0];
|
|
926
|
-
if (g.WorkerGlobalScope !== void 0 && typeof g.importScripts === "function") return ["web_worker", void 0];
|
|
927
|
-
if (g.navigator?.product === "ReactNative") return ["react_native", void 0];
|
|
928
|
-
if (g.window !== void 0 && g.document !== void 0) return ["browser", void 0];
|
|
1128
|
+
for (const [key, label, detect] of RUNTIMES) if (detect(g)) return [label, g.process?.versions?.[key]];
|
|
929
1129
|
return ["unknown", void 0];
|
|
930
1130
|
};
|
|
931
|
-
/**
|
|
932
|
-
const
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1131
|
+
/** The library sending the request. Never caller-settable, with or without an identity. */
|
|
1132
|
+
const PACKAGE_HEADERS = [
|
|
1133
|
+
"x-client-library",
|
|
1134
|
+
"x-client-library-version",
|
|
1135
|
+
"x-client-language"
|
|
1136
|
+
];
|
|
1137
|
+
/**
|
|
1138
|
+
* The calling product and its runtime. Reserved once a client has an
|
|
1139
|
+
* `identity`; without one they default to the package and stay
|
|
1140
|
+
* caller-settable, which is how a wrapper identified itself before `identity`.
|
|
1141
|
+
*/
|
|
1142
|
+
const PRODUCT_HEADERS = [
|
|
1143
|
+
"x-client-provenance",
|
|
1144
|
+
"x-client-version",
|
|
1145
|
+
"x-sdk-version",
|
|
1146
|
+
"x-source",
|
|
1147
|
+
"x-framework",
|
|
1148
|
+
"x-runtime",
|
|
1149
|
+
"x-client-runtime",
|
|
1150
|
+
"x-runtime-version"
|
|
1151
|
+
];
|
|
1152
|
+
const PACKAGE_RESERVED = new Set(PACKAGE_HEADERS);
|
|
1153
|
+
const IDENTITY_RESERVED = /* @__PURE__ */ new Set([...PACKAGE_HEADERS, ...PRODUCT_HEADERS]);
|
|
1154
|
+
/** Printable ASCII with no leading or trailing whitespace: what every runtime's `Headers` sends unchanged. */
|
|
1155
|
+
const HEADER_SAFE = /^[\x21-\x7e](?:[\x20-\x7e]*[\x21-\x7e])?$/;
|
|
1156
|
+
const IDENTITY_FIELDS = [
|
|
1157
|
+
"product",
|
|
1158
|
+
"version",
|
|
1159
|
+
"source",
|
|
1160
|
+
"framework",
|
|
1161
|
+
"runtime"
|
|
1162
|
+
];
|
|
1163
|
+
const REQUIRED_FIELDS = /* @__PURE__ */ new Set(["product", "version"]);
|
|
1164
|
+
const validateIdentity = (identity) => {
|
|
1165
|
+
if (typeof identity !== "object" || identity === null) throw new ComposioError("`identity` must be an object with a `product` and a `version`.");
|
|
1166
|
+
const fields = identity;
|
|
1167
|
+
for (const field of IDENTITY_FIELDS) {
|
|
1168
|
+
const value = fields[field];
|
|
1169
|
+
if (value === void 0 && !REQUIRED_FIELDS.has(field)) continue;
|
|
1170
|
+
if (typeof value !== "string" || !HEADER_SAFE.test(value)) throw new ComposioError(`\`identity.${field}\` must be a non-empty string of printable ASCII with no leading or trailing whitespace.`);
|
|
1171
|
+
}
|
|
1172
|
+
return identity;
|
|
1173
|
+
};
|
|
1174
|
+
/**
|
|
1175
|
+
* Validates `identity` and resolves the headers it owns, once per client.
|
|
1176
|
+
*
|
|
1177
|
+
* Without an identity the client reports itself, as it always has. With one,
|
|
1178
|
+
* the product fields replace the package's; the runtime the package detected
|
|
1179
|
+
* stays in `x-client-runtime` and `x-runtime-version` either way, since
|
|
1180
|
+
* `identity.runtime` is the legacy `x-runtime` label and the platform does not
|
|
1181
|
+
* read the two as aliases.
|
|
1182
|
+
*/
|
|
1183
|
+
const resolveIdentity = (identity) => {
|
|
1184
|
+
const [runtime, runtimeVersion] = detectRuntime();
|
|
1185
|
+
const library = {
|
|
937
1186
|
"x-client-library": "@composio/client",
|
|
938
1187
|
"x-client-library-version": VERSION,
|
|
939
1188
|
"x-client-language": "typescript",
|
|
940
|
-
"x-client-runtime": runtime
|
|
941
|
-
"x-runtime": runtime
|
|
1189
|
+
"x-client-runtime": runtime
|
|
942
1190
|
};
|
|
943
|
-
if (
|
|
944
|
-
|
|
1191
|
+
if (identity === void 0) {
|
|
1192
|
+
const headers = {
|
|
1193
|
+
"x-client-provenance": "@composio/client",
|
|
1194
|
+
"x-client-version": VERSION,
|
|
1195
|
+
...library,
|
|
1196
|
+
"x-runtime": runtime
|
|
1197
|
+
};
|
|
1198
|
+
if (runtimeVersion) headers["x-runtime-version"] = runtimeVersion;
|
|
1199
|
+
return {
|
|
1200
|
+
headers,
|
|
1201
|
+
reserved: PACKAGE_RESERVED
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
const valid = validateIdentity(identity);
|
|
1205
|
+
const headers = {
|
|
1206
|
+
"x-client-provenance": valid.product,
|
|
1207
|
+
"x-client-version": valid.version,
|
|
1208
|
+
...library,
|
|
1209
|
+
"x-runtime": valid.runtime ?? runtime
|
|
1210
|
+
};
|
|
1211
|
+
if (runtimeVersion) headers["x-runtime-version"] = runtimeVersion;
|
|
1212
|
+
headers["x-sdk-version"] = valid.version;
|
|
1213
|
+
if (valid.source !== void 0) headers["x-source"] = valid.source;
|
|
1214
|
+
if (valid.framework !== void 0) headers["x-framework"] = valid.framework;
|
|
1215
|
+
return {
|
|
1216
|
+
headers,
|
|
1217
|
+
reserved: IDENTITY_RESERVED
|
|
1218
|
+
};
|
|
1219
|
+
};
|
|
1220
|
+
/**
|
|
1221
|
+
* The reserved names, as a function of what is configured. The identity names
|
|
1222
|
+
* are rc.17's. The credential names are reserved while `auth` is not `none`,
|
|
1223
|
+
* and the routing ids while a `scope` is set; with neither configured they are
|
|
1224
|
+
* ordinary headers, which is how a client is used as a transport for schemes
|
|
1225
|
+
* it does not model.
|
|
1226
|
+
*/
|
|
1227
|
+
const reservedHeaders = (identity, configured) => {
|
|
1228
|
+
const reserved = /* @__PURE__ */ new Map();
|
|
1229
|
+
for (const name of identity.reserved) reserved.set(name, PACKAGE_RESERVED.has(name) ? "client" : "identity");
|
|
1230
|
+
if (configured.auth) for (const name of CREDENTIAL_HEADER_NAMES) reserved.set(name, "auth");
|
|
1231
|
+
if (configured.scope) for (const name of SCOPE_HEADER_NAMES) reserved.set(name, "scope");
|
|
1232
|
+
return reserved;
|
|
1233
|
+
};
|
|
1234
|
+
const REMEDY = {
|
|
1235
|
+
client: " Pass `identity` to describe the calling product.",
|
|
1236
|
+
identity: "",
|
|
1237
|
+
auth: " Configure the credential through `auth`; derive a client with `withOptions({ auth })` for another one.",
|
|
1238
|
+
scope: " Configure the organization and project through `scope`; derive a client with `withOptions({ scope })` for another one."
|
|
1239
|
+
};
|
|
1240
|
+
/**
|
|
1241
|
+
* Refuses a generic header source that names a reserved header, whether it
|
|
1242
|
+
* sets one or deletes one with `null`. Constructor validation runs it over
|
|
1243
|
+
* `defaultHeaders`; request validation over a call's `headers`, before any
|
|
1244
|
+
* network work.
|
|
1245
|
+
*/
|
|
1246
|
+
const assertNoReservedHeaders = (headers, reserved, option) => {
|
|
1247
|
+
if (!headers) return;
|
|
1248
|
+
for (const name of headerNames(headers)) {
|
|
1249
|
+
const owner = reserved.get(name);
|
|
1250
|
+
if (owner === void 0) continue;
|
|
1251
|
+
throw new ComposioError(`The \`${name}\` header is set by ${owner === "client" ? "the client" : `\`${owner}\``} and cannot be passed in \`${option}\`.${REMEDY[owner]}`);
|
|
1252
|
+
}
|
|
945
1253
|
};
|
|
946
1254
|
|
|
947
1255
|
//#endregion
|
|
@@ -1011,19 +1319,31 @@ const createFetchTransport = (options = {}) => {
|
|
|
1011
1319
|
*/
|
|
1012
1320
|
const OPERATION = Symbol("composio.operation");
|
|
1013
1321
|
/**
|
|
1014
|
-
*
|
|
1322
|
+
* Beside the descriptor, the owned header parameters the call supplied
|
|
1323
|
+
* (`x-user-api-key`, `x-org-id`): the generated method takes them out of the
|
|
1324
|
+
* generic header bag and hands them over here, so the kernel can let an
|
|
1325
|
+
* operation credential replace `auth` and hold an operation scope id to the
|
|
1326
|
+
* configured `scope`. A raw call has no way to set it.
|
|
1327
|
+
*/
|
|
1328
|
+
const OPERATION_HEADERS = Symbol("composio.operationHeaders");
|
|
1329
|
+
/**
|
|
1330
|
+
* Attach a generated call's operation, and the owned header parameters it
|
|
1331
|
+
* supplied, to the options bag it dispatches with.
|
|
1015
1332
|
*
|
|
1016
1333
|
* Called with the freshly built literal — never with the caller's own object —
|
|
1017
1334
|
* and *after* the caller's options have been spread into it, so a caller
|
|
1018
1335
|
* cannot pre-empt the descriptor: the write happens last, and the key it
|
|
1019
1336
|
* writes to is not one a caller can name.
|
|
1020
1337
|
*/
|
|
1021
|
-
const withOperation = (operation, options) => {
|
|
1338
|
+
const withOperation = (operation, options, headers) => {
|
|
1022
1339
|
options[OPERATION] = operation;
|
|
1340
|
+
if (headers !== void 0) options[OPERATION_HEADERS] = headers;
|
|
1023
1341
|
return options;
|
|
1024
1342
|
};
|
|
1025
1343
|
/** The operation a generated call recorded, or `undefined` for a raw one. */
|
|
1026
1344
|
const readOperation = (options) => options[OPERATION];
|
|
1345
|
+
/** The owned header parameters a generated call supplied, or `undefined`. */
|
|
1346
|
+
const readOperationHeaders = (options) => options[OPERATION_HEADERS];
|
|
1027
1347
|
/** A request label safe to print: dynamic path values and URL secrets are excluded. */
|
|
1028
1348
|
const printableURL = (url, operation) => `${new URL(url).origin}${operation?.path ?? "/<custom>"}`;
|
|
1029
1349
|
const emitLog = (config, level, message, metadata) => {
|
|
@@ -1286,24 +1606,27 @@ const kernelInternals = { sleep };
|
|
|
1286
1606
|
* The headers for one hop, built fresh from the URL that hop is going to.
|
|
1287
1607
|
*
|
|
1288
1608
|
* This is where rule 3 mostly stops needing machinery of its own: the
|
|
1289
|
-
* credential is re-
|
|
1290
|
-
* along from the last one, so a hop that leaves the configured API
|
|
1291
|
-
* simply does not get a key. `withdrawn` covers what that cannot — the
|
|
1609
|
+
* credential is re-checked per hop against the *request* URL rather than
|
|
1610
|
+
* carried along from the last one, so a hop that leaves the configured API
|
|
1611
|
+
* origin simply does not get a key. `withdrawn` covers what that cannot — the
|
|
1292
1612
|
* caller's own credential headers, which are legitimate on the URL the caller
|
|
1293
1613
|
* chose and are dropped once the *server* has chosen one.
|
|
1294
1614
|
*
|
|
1295
|
-
* The client's identity headers follow the same per-hop rule: they
|
|
1296
|
-
* this client to its own API, so a hop off the configured origin (a
|
|
1297
|
-
* storage URL, a redirect target) goes without them.
|
|
1615
|
+
* The client's identity and scope headers follow the same per-hop rule: they
|
|
1616
|
+
* describe this client to its own API, so a hop off the configured origin (a
|
|
1617
|
+
* presigned storage URL, a redirect target) goes without them.
|
|
1298
1618
|
*/
|
|
1299
|
-
const buildRequestHeaders = (config, options, requestURL, bodyHeaders, withdrawn,
|
|
1300
|
-
const credential = withdrawn
|
|
1301
|
-
const
|
|
1619
|
+
const buildRequestHeaders = (config, options, requestURL, bodyHeaders, withdrawn, call) => {
|
|
1620
|
+
const credential = withdrawn ? null : credentialForRequest(config.baseURL, call.credential, requestURL, config.allowedHTTPOrigin);
|
|
1621
|
+
const own = sameOrigin(config.baseURL, requestURL);
|
|
1622
|
+
const identity = own ? config.identity.headers : void 0;
|
|
1623
|
+
const scope = own ? call.scope : void 0;
|
|
1302
1624
|
if (!withdrawn && bodyHeaders === void 0 && !config.defaultHeaders && !options.headers && options.idempotencyKey === void 0) {
|
|
1303
1625
|
const direct = new Headers({
|
|
1304
1626
|
...identity,
|
|
1305
1627
|
accept: "application/json",
|
|
1306
|
-
"user-agent": config.userAgent
|
|
1628
|
+
"user-agent": config.userAgent,
|
|
1629
|
+
...scope
|
|
1307
1630
|
});
|
|
1308
1631
|
if (credential !== null) direct.set(credential.name, credential.value);
|
|
1309
1632
|
return direct;
|
|
@@ -1316,6 +1639,7 @@ const buildRequestHeaders = (config, options, requestURL, bodyHeaders, withdrawn
|
|
|
1316
1639
|
"user-agent": config.userAgent
|
|
1317
1640
|
},
|
|
1318
1641
|
credential === null ? void 0 : { [credential.name]: credential.value },
|
|
1642
|
+
scope,
|
|
1319
1643
|
config.defaultHeaders,
|
|
1320
1644
|
bodyHeaders,
|
|
1321
1645
|
options.headers
|
|
@@ -1323,28 +1647,55 @@ const buildRequestHeaders = (config, options, requestURL, bodyHeaders, withdrawn
|
|
|
1323
1647
|
if (withdrawn) withdrawCredentials(headers);
|
|
1324
1648
|
return headers;
|
|
1325
1649
|
};
|
|
1650
|
+
/** The error for a provider that failed; the provider's own error is its `cause`. */
|
|
1651
|
+
const providerFailed = (cause) => {
|
|
1652
|
+
const error = new ComposioError("The `auth` credential provider failed.");
|
|
1653
|
+
Object.defineProperty(error, "cause", {
|
|
1654
|
+
value: cause,
|
|
1655
|
+
configurable: true,
|
|
1656
|
+
writable: true
|
|
1657
|
+
});
|
|
1658
|
+
return error;
|
|
1659
|
+
};
|
|
1326
1660
|
/**
|
|
1327
|
-
* The credential
|
|
1328
|
-
*
|
|
1661
|
+
* The credential one logical call carries, its provider asked at most once,
|
|
1662
|
+
* and before any network work.
|
|
1329
1663
|
*
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
1332
|
-
*
|
|
1333
|
-
*
|
|
1334
|
-
*
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1664
|
+
* A configured credential is asked for only when the call starts on the API
|
|
1665
|
+
* origin: a call that starts anywhere else never carries it (rule 2), and a
|
|
1666
|
+
* redirect back onto the origin arrives after the chain has left it, so the
|
|
1667
|
+
* withdrawal holds. An operation credential is the call's own and is returned
|
|
1668
|
+
* as given; the origin rules still decide, per hop, whether it is sent.
|
|
1669
|
+
*/
|
|
1670
|
+
const resolveCallCredential = (config, operation, supplied, requestURL) => {
|
|
1671
|
+
const choice = chooseCredential(config.auth, operation, supplied);
|
|
1672
|
+
if (choice === null) return null;
|
|
1673
|
+
const name = schemeHeader(choice.scheme);
|
|
1674
|
+
if (choice.kind === "operation") return {
|
|
1675
|
+
name,
|
|
1676
|
+
value: choice.key
|
|
1677
|
+
};
|
|
1678
|
+
if (!sameOrigin(config.baseURL, requestURL)) return null;
|
|
1679
|
+
if (typeof choice.credential === "string") return {
|
|
1680
|
+
name,
|
|
1681
|
+
value: choice.credential
|
|
1682
|
+
};
|
|
1683
|
+
const usable = (key) => {
|
|
1684
|
+
if (!isUsableKey(choice.scheme, key)) throw unusableKeyError("The key the `auth` credential provider returned");
|
|
1685
|
+
return {
|
|
1686
|
+
name,
|
|
1687
|
+
value: key
|
|
1688
|
+
};
|
|
1689
|
+
};
|
|
1690
|
+
let key;
|
|
1691
|
+
try {
|
|
1692
|
+
key = choice.credential();
|
|
1693
|
+
} catch (cause) {
|
|
1694
|
+
throw providerFailed(cause);
|
|
1695
|
+
}
|
|
1696
|
+
return typeof key === "string" ? usable(key) : Promise.resolve(key).then(usable, (cause) => {
|
|
1697
|
+
throw providerFailed(cause);
|
|
1698
|
+
});
|
|
1348
1699
|
};
|
|
1349
1700
|
/**
|
|
1350
1701
|
* One attempt: the request, plus however many redirects it takes to land on a
|
|
@@ -1362,15 +1713,14 @@ const schemeForRequest = (config, operation) => {
|
|
|
1362
1713
|
* rewrite), and the query, which is left to the `Location` URL because the
|
|
1363
1714
|
* server picked it.
|
|
1364
1715
|
*/
|
|
1365
|
-
const dispatchWithRedirects = async (config, options, initialURL, initialBody, initialBodyHeaders, signal,
|
|
1716
|
+
const dispatchWithRedirects = async (config, options, initialURL, initialBody, initialBodyHeaders, signal, call) => {
|
|
1366
1717
|
let url = initialURL;
|
|
1367
1718
|
let method = options.method.toUpperCase();
|
|
1368
1719
|
let body = initialBody;
|
|
1369
1720
|
let bodyHeaders = initialBodyHeaders;
|
|
1370
1721
|
let withdrawn = false;
|
|
1371
|
-
const callerPlaced = callerPlacedCredential([config.defaultHeaders, options.headers]);
|
|
1372
1722
|
for (let hop = 0;; hop++) {
|
|
1373
|
-
const headers = buildRequestHeaders(config, options, url, bodyHeaders, withdrawn,
|
|
1723
|
+
const headers = buildRequestHeaders(config, options, url, bodyHeaders, withdrawn, call);
|
|
1374
1724
|
const delegated = hop === 0 && !carriesCredentials(headers);
|
|
1375
1725
|
const init = {
|
|
1376
1726
|
method,
|
|
@@ -1415,6 +1765,7 @@ const dispatchWithRedirects = async (config, options, initialURL, initialBody, i
|
|
|
1415
1765
|
* which is what `deprecation.ts` resolves relative `Link` targets against.
|
|
1416
1766
|
*/
|
|
1417
1767
|
async function makeRequest(config, options) {
|
|
1768
|
+
assertNoReservedHeaders(options.headers, config.reserved, "headers");
|
|
1418
1769
|
if (options.timeout !== void 0) validatePositiveInteger("timeout", options.timeout);
|
|
1419
1770
|
const maxRetries = options.maxRetries ?? config.maxRetries;
|
|
1420
1771
|
validatePositiveInteger("maxRetries", maxRetries);
|
|
@@ -1430,7 +1781,14 @@ async function makeRequest(config, options) {
|
|
|
1430
1781
|
url: printableURL(url, operation),
|
|
1431
1782
|
maxAttempts: maxRetries + 1
|
|
1432
1783
|
};
|
|
1433
|
-
const
|
|
1784
|
+
const supplied = readOperationHeaders(options);
|
|
1785
|
+
assertRequiredOperationHeaders(threaded ?? null, supplied);
|
|
1786
|
+
const scope = scopeForCall(config.scope, supplied);
|
|
1787
|
+
const resolving = resolveCallCredential(config, operation, supplied, url);
|
|
1788
|
+
const call = {
|
|
1789
|
+
scope,
|
|
1790
|
+
credential: resolving instanceof Promise ? await resolving : resolving
|
|
1791
|
+
};
|
|
1434
1792
|
if (config.onRequest !== void 0 && (threaded === void 0 || threaded.hasDeprecatedInputs === true)) config.onRequest(operation, query, options.body, buildHeaders([config.defaultHeaders, options.headers]));
|
|
1435
1793
|
for (let numRetries = 0;; numRetries++) {
|
|
1436
1794
|
if (userSignal?.aborted) throw new APIUserAbortError();
|
|
@@ -1448,7 +1806,7 @@ async function makeRequest(config, options) {
|
|
|
1448
1806
|
const timer = setTimeout(abort, timeout);
|
|
1449
1807
|
let result;
|
|
1450
1808
|
try {
|
|
1451
|
-
result = await dispatchWithRedirects(config, options, url, body, bodyHeaders, controller.signal,
|
|
1809
|
+
result = await dispatchWithRedirects(config, options, url, body, bodyHeaders, controller.signal, call);
|
|
1452
1810
|
} catch (cause) {
|
|
1453
1811
|
if (cause instanceof ComposioError) {
|
|
1454
1812
|
if (attemptLog !== void 0) emitLog(config, "info", "Request failed", {
|
|
@@ -1708,7 +2066,8 @@ const GENERATED_OPERATIONS = [
|
|
|
1708
2066
|
"consumer",
|
|
1709
2067
|
"listConnectedToolkits"
|
|
1710
2068
|
],
|
|
1711
|
-
schemes: ["UserApiKeyAuth"]
|
|
2069
|
+
schemes: ["UserApiKeyAuth"],
|
|
2070
|
+
requiredHeaders: ["x-user-api-key", "x-org-id"]
|
|
1712
2071
|
},
|
|
1713
2072
|
{
|
|
1714
2073
|
method: "get",
|
|
@@ -1973,7 +2332,8 @@ const GENERATED_OPERATIONS = [
|
|
|
1973
2332
|
method: "post",
|
|
1974
2333
|
path: "/api/v3.1/cli/codact_failures",
|
|
1975
2334
|
chain: ["cli", "createCodactFailure"],
|
|
1976
|
-
schemes: ["UserApiKeyAuth"]
|
|
2335
|
+
schemes: ["UserApiKeyAuth"],
|
|
2336
|
+
requiredHeaders: ["x-user-api-key"]
|
|
1977
2337
|
},
|
|
1978
2338
|
{
|
|
1979
2339
|
method: "post",
|
|
@@ -2105,7 +2465,8 @@ const GENERATED_OPERATIONS = [
|
|
|
2105
2465
|
"project",
|
|
2106
2466
|
"resolve"
|
|
2107
2467
|
],
|
|
2108
|
-
schemes: ["UserApiKeyAuth"]
|
|
2468
|
+
schemes: ["UserApiKeyAuth"],
|
|
2469
|
+
requiredHeaders: ["x-user-api-key", "x-org-id"]
|
|
2109
2470
|
},
|
|
2110
2471
|
{
|
|
2111
2472
|
method: "post",
|
|
@@ -2345,4 +2706,4 @@ const generatedOperation = (chainKey) => {
|
|
|
2345
2706
|
};
|
|
2346
2707
|
|
|
2347
2708
|
//#endregion
|
|
2348
|
-
export {
|
|
2709
|
+
export { Auth as A, unusableKeyError as B, resolveIdentity as C, inspectDeprecatedInputs as D, mergeHeaders as E, chooseCredential as F, resolveHTTPURL as G, assertCredentialTransport as H, isUsableKey as I, sameOrigin as K, resolveAuth as L, assertRequiredOperationHeaders as M, authConstructors as N, inspectDeprecation as O, authFromCredentials as P, resolveScope as R, reservedHeaders as S, buildHeaders as T, carriesCredentials as U, SCHEME_HEADERS as V, parseHTTPURL as W, shouldRetryResponse as _, TOO_MANY_REDIRECTS as a, createFetchTransport as b, buildURL as c, path as d, printableURL as f, safeJSON as g, rewriteForRedirect as h, REDIRECT_STATUSES as i, assertNoRemovedCredentialOptions as j, matchOperation as k, castToError as l, retryDelayMillis as m, generatedOperation as n, buildBody as o, readOperation as p, schemeHeader as q, OPAQUE_REDIRECT as r, buildRequestHeaders as s, GENERATED_OPERATIONS as t, makeRequest as u, validatePositiveInteger as v, VERSION as w, assertNoReservedHeaders as x, withOperation as y, scopeForCall as z };
|