@zapier/zapier-sdk 0.45.2 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +7 -1
- package/dist/api/schemas.d.ts +5 -5
- package/dist/api/types.d.ts +6 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/auth.d.ts +27 -6
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +130 -92
- package/dist/cache.d.ts +50 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +47 -0
- package/dist/index.cjs +107 -55
- package/dist/index.d.mts +105 -35
- package/dist/index.mjs +107 -56
- package/dist/plugins/getAction/schemas.d.ts +4 -4
- package/dist/plugins/getInputFieldsSchema/schemas.d.ts +4 -4
- package/dist/plugins/listActions/schemas.d.ts +4 -4
- package/dist/plugins/listInputFieldChoices/schemas.d.ts +4 -4
- package/dist/plugins/listInputFields/schemas.d.ts +4 -4
- package/dist/plugins/runAction/schemas.d.ts +4 -4
- package/dist/plugins/tables/createTableFields/schemas.d.ts +21 -21
- package/dist/plugins/tables/listTableFields/schemas.d.ts +12 -12
- package/dist/plugins/tables/listTableRecords/schemas.d.ts +6 -6
- package/dist/schemas/Action.d.ts +1 -1
- package/dist/types/credentials.d.ts +2 -1
- package/dist/types/credentials.d.ts.map +1 -1
- package/dist/types/credentials.js +2 -1
- package/dist/types/properties.d.ts +1 -1
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/sdk.d.ts.map +1 -1
- package/dist/types/sdk.js +1 -0
- package/package.json +2 -4
package/CHANGELOG.md
CHANGED
package/dist/api/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAGjB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,gBAAgB,EAGjB,MAAM,SAAS,CAAC;AAuhCjB,eAAO,MAAM,eAAe,GAAI,SAAS,gBAAgB,KAAG,SAW3D,CAAC"}
|
package/dist/api/client.js
CHANGED
|
@@ -331,6 +331,7 @@ class ZapierApiClient {
|
|
|
331
331
|
baseUrl: this.options.baseUrl,
|
|
332
332
|
requiredScopes: options?.requiredScopes,
|
|
333
333
|
debug: this.options.debug,
|
|
334
|
+
cache: this.options.cache,
|
|
334
335
|
});
|
|
335
336
|
}
|
|
336
337
|
// Helper to handle responses
|
|
@@ -373,12 +374,17 @@ class ZapierApiClient {
|
|
|
373
374
|
if (wasMissingAuthToken) {
|
|
374
375
|
throw new ZapierAuthenticationError(`Authentication required (HTTP ${response.status}). Please provide credentials in options or set ZAPIER_CREDENTIALS environment variable.`, errorOptions);
|
|
375
376
|
}
|
|
376
|
-
// On 401, invalidate cached token so next request
|
|
377
|
+
// On 401, invalidate the cached token so the next request fires
|
|
378
|
+
// a fresh exchange. Passing baseUrl + cache explicitly so the
|
|
379
|
+
// invalidation targets the same cache key the token was stored
|
|
380
|
+
// under (both are part of the key identity).
|
|
377
381
|
if (response.status === 401) {
|
|
378
382
|
await invalidateCredentialsToken({
|
|
379
383
|
credentials: this.options.credentials,
|
|
380
384
|
token: this.options.token,
|
|
385
|
+
baseUrl: this.options.baseUrl,
|
|
381
386
|
requiredScopes,
|
|
387
|
+
cache: this.options.cache,
|
|
382
388
|
});
|
|
383
389
|
}
|
|
384
390
|
throw new ZapierAuthenticationError(message, errorOptions);
|
package/dist/api/schemas.d.ts
CHANGED
|
@@ -43,8 +43,8 @@ export declare const NeedSchema: z.ZodObject<{
|
|
|
43
43
|
string: "string";
|
|
44
44
|
boolean: "boolean";
|
|
45
45
|
file: "file";
|
|
46
|
-
integer: "integer";
|
|
47
46
|
filter: "filter";
|
|
47
|
+
integer: "integer";
|
|
48
48
|
text: "text";
|
|
49
49
|
datetime: "datetime";
|
|
50
50
|
decimal: "decimal";
|
|
@@ -65,11 +65,11 @@ export declare const ActionPermissionsSchema: z.ZodObject<{
|
|
|
65
65
|
export declare const ActionSchema: z.ZodObject<{
|
|
66
66
|
id: z.ZodOptional<z.ZodString>;
|
|
67
67
|
type: z.ZodEnum<{
|
|
68
|
-
search: "search";
|
|
69
68
|
filter: "filter";
|
|
70
69
|
read: "read";
|
|
71
70
|
read_bulk: "read_bulk";
|
|
72
71
|
run: "run";
|
|
72
|
+
search: "search";
|
|
73
73
|
search_and_write: "search_and_write";
|
|
74
74
|
search_or_write: "search_or_write";
|
|
75
75
|
write: "write";
|
|
@@ -288,8 +288,8 @@ export declare const NeedsResponseSchema: z.ZodObject<{
|
|
|
288
288
|
string: "string";
|
|
289
289
|
boolean: "boolean";
|
|
290
290
|
file: "file";
|
|
291
|
-
integer: "integer";
|
|
292
291
|
filter: "filter";
|
|
292
|
+
integer: "integer";
|
|
293
293
|
text: "text";
|
|
294
294
|
datetime: "datetime";
|
|
295
295
|
decimal: "decimal";
|
|
@@ -313,11 +313,11 @@ export declare const ImplementationSchema: z.ZodObject<{
|
|
|
313
313
|
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
314
314
|
id: z.ZodOptional<z.ZodString>;
|
|
315
315
|
type: z.ZodEnum<{
|
|
316
|
-
search: "search";
|
|
317
316
|
filter: "filter";
|
|
318
317
|
read: "read";
|
|
319
318
|
read_bulk: "read_bulk";
|
|
320
319
|
run: "run";
|
|
320
|
+
search: "search";
|
|
321
321
|
search_and_write: "search_and_write";
|
|
322
322
|
search_or_write: "search_or_write";
|
|
323
323
|
write: "write";
|
|
@@ -355,11 +355,11 @@ export declare const ImplementationsResponseSchema: z.ZodObject<{
|
|
|
355
355
|
actions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
356
356
|
id: z.ZodOptional<z.ZodString>;
|
|
357
357
|
type: z.ZodEnum<{
|
|
358
|
-
search: "search";
|
|
359
358
|
filter: "filter";
|
|
360
359
|
read: "read";
|
|
361
360
|
read_bulk: "read_bulk";
|
|
362
361
|
run: "run";
|
|
362
|
+
search: "search";
|
|
363
363
|
search_and_write: "search_and_write";
|
|
364
364
|
search_or_write: "search_or_write";
|
|
365
365
|
write: "write";
|
package/dist/api/types.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ import type { ImplementationMetaSchema, ImplementationsMetaResponseSchema } from
|
|
|
13
13
|
import type { SdkEvent } from "../types/events";
|
|
14
14
|
import type { Credentials } from "../types/credentials";
|
|
15
15
|
import type { RequestContext } from "@zapier/policy-context";
|
|
16
|
+
import type { ZapierCache } from "../cache";
|
|
16
17
|
import type { z } from "zod";
|
|
17
18
|
import type { NeedChoicesSchema, NeedSchema, ActionLinksSchema, ActionPermissionsSchema, ActionSchema, ChoiceSchema, FieldSchema, ActionExecutionResultSchema, ActionFieldChoiceSchema, ActionFieldSchema, UserProfileSchema, AppSchema, NeedsRequestSchema, NeedsResponseSchema, ImplementationSchema, ImplementationsResponseSchema, ServiceSchema, ServicesResponseSchema, NeedChoicesRequestSchema, NeedChoicesResponseSchema, NeedChoicesResponseMetaSchema, NeedChoicesResponseLinksSchema } from "./schemas";
|
|
18
19
|
export interface ApiClientOptions {
|
|
@@ -71,6 +72,11 @@ export interface ApiClientOptions {
|
|
|
71
72
|
name: string;
|
|
72
73
|
version: string;
|
|
73
74
|
};
|
|
75
|
+
/**
|
|
76
|
+
* Pluggable key-value cache used to cache access tokens across
|
|
77
|
+
* invocations. See ZapierCache in ../cache.ts.
|
|
78
|
+
*/
|
|
79
|
+
cache?: ZapierCache;
|
|
74
80
|
}
|
|
75
81
|
export interface ApiClient {
|
|
76
82
|
get: <T = unknown>(path: string, options?: RequestOptions) => Promise<T>;
|
package/dist/api/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,yBAAyB,EAC1B,MAAM,gDAAgD,CAAC;AACxD,OAAO,KAAK,EACV,wBAAwB,EACxB,iCAAiC,EAClC,MAAM,oDAAoD,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,2BAA2B,EAC3B,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,SAAS,EACT,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,6BAA6B,EAC7B,aAAa,EACb,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,6BAA6B,EAC7B,8BAA8B,EAC/B,MAAM,WAAW,CAAC;AAMnB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;OAEG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.d.ts
CHANGED
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
* and handles different credential types appropriately.
|
|
7
7
|
*
|
|
8
8
|
* CLI-specific functionality like login/logout is handled by the
|
|
9
|
-
* @zapier/zapier-sdk-cli
|
|
9
|
+
* @zapier/zapier-sdk-cli package (imported via its `./login` subpath).
|
|
10
10
|
*/
|
|
11
11
|
import type { EventCallback } from "./types/events";
|
|
12
12
|
import type { Credentials } from "./types/credentials";
|
|
13
|
+
import { type ZapierCache } from "./cache";
|
|
14
|
+
export type { ZapierCache, ZapierCacheEntry, ZapierCacheSetOptions, } from "./cache";
|
|
15
|
+
export { createMemoryCache } from "./cache";
|
|
13
16
|
export type { SdkEvent, AuthEvent, ApiEvent, LoadingEvent, EventCallback, } from "./types/events";
|
|
14
17
|
export type { Credentials, ResolvedCredentials, CredentialsObject, ClientCredentialsObject, PkceCredentialsObject, } from "./types/credentials";
|
|
15
18
|
export { isClientCredentials, isPkceCredentials, isCredentialsObject, isCredentialsFunction, } from "./types/credentials";
|
|
@@ -31,16 +34,32 @@ export interface ResolveAuthTokenOptions {
|
|
|
31
34
|
requiredScopes?: string[];
|
|
32
35
|
/** Enable debug logging for auth operations. */
|
|
33
36
|
debug?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Pluggable key-value cache used to cache access tokens across
|
|
39
|
+
* process boundaries. When omitted, the SDK tries to load a default
|
|
40
|
+
* adapter from the cli-login package (file system + keychain) and
|
|
41
|
+
* falls back to in-memory cache if none is available.
|
|
42
|
+
*/
|
|
43
|
+
cache?: ZapierCache;
|
|
34
44
|
}
|
|
35
45
|
/**
|
|
36
|
-
* Clear
|
|
46
|
+
* Clear in-process caches. Useful for testing or to force the next
|
|
47
|
+
* resolve to re-import the default cache adapter. Does not touch
|
|
48
|
+
* persistent cache — use `invalidateCachedToken` for that.
|
|
37
49
|
*/
|
|
38
50
|
export declare function clearTokenCache(): void;
|
|
39
51
|
/**
|
|
40
|
-
* Invalidate
|
|
41
|
-
* Called
|
|
52
|
+
* Invalidate the cached token for a given client_credentials identity.
|
|
53
|
+
* Called on 401 so the next request re-exchanges. Clears both the
|
|
54
|
+
* in-process pending-exchange map and the persistent layer via the
|
|
55
|
+
* resolved cache adapter.
|
|
42
56
|
*/
|
|
43
|
-
export declare function invalidateCachedToken(
|
|
57
|
+
export declare function invalidateCachedToken(options: {
|
|
58
|
+
clientId: string;
|
|
59
|
+
scopes: string[];
|
|
60
|
+
baseUrl: string;
|
|
61
|
+
cache?: ZapierCache;
|
|
62
|
+
}): Promise<void>;
|
|
44
63
|
/**
|
|
45
64
|
* Options for getTokenFromCliLogin.
|
|
46
65
|
*/
|
|
@@ -55,7 +74,7 @@ interface CliLoginOptions {
|
|
|
55
74
|
};
|
|
56
75
|
debug?: boolean;
|
|
57
76
|
}
|
|
58
|
-
type CliLoginModule = typeof import("@zapier/zapier-sdk-cli
|
|
77
|
+
type CliLoginModule = typeof import("@zapier/zapier-sdk-cli/login");
|
|
59
78
|
/**
|
|
60
79
|
* Inject an already-loaded CLI login module so the SDK skips its dynamic import.
|
|
61
80
|
* This guarantees CLI and SDK share the same module instance in the same process.
|
|
@@ -97,6 +116,8 @@ export declare function resolveAuthToken(options?: ResolveAuthTokenOptions): Pro
|
|
|
97
116
|
export declare function invalidateCredentialsToken(options: {
|
|
98
117
|
credentials?: Credentials;
|
|
99
118
|
token?: string;
|
|
119
|
+
baseUrl?: string;
|
|
100
120
|
requiredScopes?: string[];
|
|
121
|
+
cache?: ZapierCache;
|
|
101
122
|
}): Promise<void>;
|
|
102
123
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/auth.js
CHANGED
|
@@ -6,80 +6,100 @@
|
|
|
6
6
|
* and handles different credential types appropriately.
|
|
7
7
|
*
|
|
8
8
|
* CLI-specific functionality like login/logout is handled by the
|
|
9
|
-
* @zapier/zapier-sdk-cli
|
|
9
|
+
* @zapier/zapier-sdk-cli package (imported via its `./login` subpath).
|
|
10
10
|
*/
|
|
11
11
|
import { isClientCredentials, isPkceCredentials } from "./types/credentials";
|
|
12
12
|
import { resolveCredentials, getClientIdFromCredentials } from "./credentials";
|
|
13
|
-
import {
|
|
13
|
+
import { createMemoryCache } from "./cache";
|
|
14
|
+
const DEFAULT_AUTH_BASE_URL = "https://zapier.com";
|
|
15
|
+
export { createMemoryCache } from "./cache";
|
|
14
16
|
export { isClientCredentials, isPkceCredentials, isCredentialsObject, isCredentialsFunction, } from "./types/credentials";
|
|
15
17
|
/**
|
|
16
|
-
* In-
|
|
17
|
-
*
|
|
18
|
+
* In-flight token exchange promises to prevent duplicate exchanges
|
|
19
|
+
* inside the same process. When an exchange is in progress, subsequent
|
|
20
|
+
* calls await the same promise. Cache backends are responsible for
|
|
21
|
+
* cross-process dedup via their optional `withLock` method.
|
|
18
22
|
*/
|
|
19
|
-
const
|
|
23
|
+
const pendingExchanges = new Map();
|
|
20
24
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* Keyed by clientId + sorted scopes.
|
|
25
|
+
* The resolved default cache adapter. Cached at module scope so
|
|
26
|
+
* repeated calls to `resolveAuthToken` reuse the same provider.
|
|
24
27
|
*/
|
|
25
|
-
|
|
28
|
+
let cachedDefaultCache;
|
|
26
29
|
/**
|
|
27
|
-
* Build
|
|
30
|
+
* Build the cache key for a client_credentials identity. baseUrl is
|
|
31
|
+
* part of the key so the same clientId+scopes against different auth
|
|
32
|
+
* hosts (prod vs staging) never alias.
|
|
28
33
|
*/
|
|
29
|
-
function buildCacheKey(
|
|
30
|
-
const sortedScopes = [...scopes].sort().join(",");
|
|
31
|
-
return
|
|
34
|
+
function buildCacheKey(options) {
|
|
35
|
+
const sortedScopes = [...options.scopes].sort().join(",");
|
|
36
|
+
return `zapier-sdk/client-credentials/${options.clientId}:${sortedScopes}:${options.baseUrl}`;
|
|
32
37
|
}
|
|
33
38
|
/**
|
|
34
|
-
* Clear
|
|
39
|
+
* Clear in-process caches. Useful for testing or to force the next
|
|
40
|
+
* resolve to re-import the default cache adapter. Does not touch
|
|
41
|
+
* persistent cache — use `invalidateCachedToken` for that.
|
|
35
42
|
*/
|
|
36
43
|
export function clearTokenCache() {
|
|
37
|
-
tokenCache.clear();
|
|
38
44
|
pendingExchanges.clear();
|
|
39
45
|
cachedCliLogin = undefined;
|
|
46
|
+
cachedDefaultCache = undefined;
|
|
40
47
|
}
|
|
41
|
-
const
|
|
48
|
+
const TOKEN_EXPIRATION_BUFFER_MS = 5 * 60 * 1000;
|
|
42
49
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
50
|
+
* Decide which cache adapter to use for this call. Priority:
|
|
51
|
+
* 1. explicit `options.cache`
|
|
52
|
+
* 2. CLI's default cache provider (if installed)
|
|
53
|
+
* 3. in-memory fallback
|
|
45
54
|
*/
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (
|
|
50
|
-
return
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
|
|
55
|
+
async function resolveCache(options) {
|
|
56
|
+
if (options.cache)
|
|
57
|
+
return options.cache;
|
|
58
|
+
if (cachedDefaultCache !== undefined)
|
|
59
|
+
return cachedDefaultCache;
|
|
60
|
+
const cliLogin = await getCliLogin();
|
|
61
|
+
if (cliLogin?.createCache) {
|
|
62
|
+
try {
|
|
63
|
+
const cache = cliLogin.createCache();
|
|
64
|
+
cachedDefaultCache = cache;
|
|
65
|
+
return cache;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Fall through to in-memory if the CLI provider can't be constructed.
|
|
69
|
+
}
|
|
54
70
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return
|
|
71
|
+
const fallback = createMemoryCache();
|
|
72
|
+
cachedDefaultCache = fallback;
|
|
73
|
+
return fallback;
|
|
58
74
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const cacheKey = buildCacheKey(clientId, scopes);
|
|
64
|
-
tokenCache.set(cacheKey, {
|
|
65
|
-
accessToken,
|
|
66
|
-
expiresAt: Date.now() + expiresIn * 1000,
|
|
67
|
-
});
|
|
75
|
+
function entryIsValid(entry) {
|
|
76
|
+
if (entry.expiresAt === undefined)
|
|
77
|
+
return true;
|
|
78
|
+
return entry.expiresAt > Date.now() + TOKEN_EXPIRATION_BUFFER_MS;
|
|
68
79
|
}
|
|
69
80
|
/**
|
|
70
|
-
* Invalidate
|
|
71
|
-
* Called
|
|
81
|
+
* Invalidate the cached token for a given client_credentials identity.
|
|
82
|
+
* Called on 401 so the next request re-exchanges. Clears both the
|
|
83
|
+
* in-process pending-exchange map and the persistent layer via the
|
|
84
|
+
* resolved cache adapter.
|
|
72
85
|
*/
|
|
73
|
-
export function invalidateCachedToken(
|
|
74
|
-
const cacheKey = buildCacheKey(
|
|
75
|
-
tokenCache.delete(cacheKey);
|
|
86
|
+
export async function invalidateCachedToken(options) {
|
|
87
|
+
const cacheKey = buildCacheKey(options);
|
|
76
88
|
pendingExchanges.delete(cacheKey);
|
|
89
|
+
const cache = await resolveCache({ cache: options.cache });
|
|
90
|
+
try {
|
|
91
|
+
await cache.delete(cacheKey);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Best-effort: the caller is about to surface a 401 to its own
|
|
95
|
+
// caller; a failed invalidation shouldn't add noise on top of that.
|
|
96
|
+
}
|
|
77
97
|
}
|
|
78
98
|
/**
|
|
79
99
|
* Get the token endpoint URL for client credentials exchange.
|
|
80
100
|
*/
|
|
81
101
|
function getTokenEndpointUrl(baseUrl) {
|
|
82
|
-
const base = baseUrl ||
|
|
102
|
+
const base = baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
83
103
|
return `${base}/oauth/token/`;
|
|
84
104
|
}
|
|
85
105
|
/**
|
|
@@ -109,9 +129,6 @@ function mergeScopes(credentialsScope, requiredScopes) {
|
|
|
109
129
|
}
|
|
110
130
|
return [...scopeSet].sort();
|
|
111
131
|
}
|
|
112
|
-
/**
|
|
113
|
-
* Exchange client credentials for an access token.
|
|
114
|
-
*/
|
|
115
132
|
async function exchangeClientCredentials(options) {
|
|
116
133
|
const { clientId, clientSecret, baseUrl, scope, requiredScopes, onEvent } = options;
|
|
117
134
|
const fetchFn = options.fetch || globalThis.fetch;
|
|
@@ -157,9 +174,6 @@ async function exchangeClientCredentials(options) {
|
|
|
157
174
|
if (!data.access_token) {
|
|
158
175
|
throw new Error("Client credentials response missing access_token");
|
|
159
176
|
}
|
|
160
|
-
// Cache the token with the scopes used
|
|
161
|
-
const expiresIn = data.expires_in || 3600; // Default to 1 hour
|
|
162
|
-
cacheToken(clientId, mergedScopes, data.access_token, expiresIn);
|
|
163
177
|
onEvent?.({
|
|
164
178
|
type: "auth_success",
|
|
165
179
|
payload: {
|
|
@@ -168,18 +182,17 @@ async function exchangeClientCredentials(options) {
|
|
|
168
182
|
},
|
|
169
183
|
timestamp: Date.now(),
|
|
170
184
|
});
|
|
171
|
-
return
|
|
185
|
+
return {
|
|
186
|
+
accessToken: data.access_token,
|
|
187
|
+
expiresIn: data.expires_in || 3600,
|
|
188
|
+
};
|
|
172
189
|
}
|
|
173
190
|
let cachedCliLogin;
|
|
174
191
|
/**
|
|
175
|
-
* Dynamically imports
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
* users who install the lightweight login package directly).
|
|
180
|
-
*
|
|
181
|
-
* Returns the module if found, or `undefined` if neither package is available.
|
|
182
|
-
* The result is cached after the first attempt.
|
|
192
|
+
* Dynamically imports the CLI's login/cache entrypoint with caching.
|
|
193
|
+
* Returns the module if the CLI package is installed in the consumer's
|
|
194
|
+
* environment, or `undefined` if not (e.g. in a browser or minimal
|
|
195
|
+
* server deployment). The result is cached after the first attempt.
|
|
183
196
|
*/
|
|
184
197
|
async function getCliLogin() {
|
|
185
198
|
if (cachedCliLogin !== undefined) {
|
|
@@ -193,17 +206,7 @@ async function getCliLogin() {
|
|
|
193
206
|
}
|
|
194
207
|
}
|
|
195
208
|
catch {
|
|
196
|
-
// Not available
|
|
197
|
-
}
|
|
198
|
-
try {
|
|
199
|
-
const mod = await import("@zapier/zapier-sdk-cli-login");
|
|
200
|
-
if (typeof mod.getToken === "function") {
|
|
201
|
-
cachedCliLogin = mod;
|
|
202
|
-
return cachedCliLogin;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
catch {
|
|
206
|
-
// Not available
|
|
209
|
+
// Not available (no CLI installed in this environment).
|
|
207
210
|
}
|
|
208
211
|
cachedCliLogin = false;
|
|
209
212
|
return undefined;
|
|
@@ -277,33 +280,62 @@ async function resolveAuthTokenFromCredentials(credentials, options) {
|
|
|
277
280
|
if (typeof credentials === "string") {
|
|
278
281
|
return credentials;
|
|
279
282
|
}
|
|
280
|
-
// Client credentials: exchange
|
|
283
|
+
// Client credentials: exchange + cache through a pluggable cache
|
|
284
|
+
// adapter. Resolution order:
|
|
285
|
+
// 1. in-process pending exchange (dedup concurrent same-process calls)
|
|
286
|
+
// 2. cache.get (hits keychain + config under the filesystem adapter,
|
|
287
|
+
// RAM under the in-memory adapter, whatever the user adapter does)
|
|
288
|
+
// 3. cache.withLock (if available) -> re-read, exchange, persist
|
|
289
|
+
// (so N parallel processes collapse to 1 network exchange)
|
|
290
|
+
// 4. plain exchange + persist when no lock is available
|
|
281
291
|
if (isClientCredentials(credentials)) {
|
|
282
292
|
const { clientId } = credentials;
|
|
283
|
-
// Compute merged scopes for cache lookup
|
|
284
293
|
const mergedScopes = mergeScopes(credentials.scope, options.requiredScopes);
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
294
|
+
const resolvedBaseUrl = credentials.baseUrl || options.baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
295
|
+
const cacheKey = buildCacheKey({
|
|
296
|
+
clientId,
|
|
297
|
+
scopes: mergedScopes,
|
|
298
|
+
baseUrl: resolvedBaseUrl,
|
|
299
|
+
});
|
|
300
|
+
const cache = await resolveCache(options);
|
|
301
|
+
// Fast-path read
|
|
302
|
+
const cached = await cache.get(cacheKey);
|
|
303
|
+
if (cached && entryIsValid(cached)) {
|
|
304
|
+
return cached.value;
|
|
290
305
|
}
|
|
291
|
-
//
|
|
306
|
+
// In-process dedup
|
|
292
307
|
const pending = pendingExchanges.get(cacheKey);
|
|
293
|
-
if (pending)
|
|
308
|
+
if (pending)
|
|
294
309
|
return pending;
|
|
295
|
-
|
|
296
|
-
//
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
310
|
+
// Serialize exchange + persist inside the lock (when the adapter
|
|
311
|
+
// supports cross-process locking). The second acquirer re-reads the
|
|
312
|
+
// cache under the lock and uses the first's token instead of firing
|
|
313
|
+
// another exchange.
|
|
314
|
+
const runLocked = async () => {
|
|
315
|
+
const recheck = await cache.get(cacheKey);
|
|
316
|
+
if (recheck && entryIsValid(recheck))
|
|
317
|
+
return recheck.value;
|
|
318
|
+
const { accessToken, expiresIn } = await exchangeClientCredentials({
|
|
319
|
+
clientId: credentials.clientId,
|
|
320
|
+
clientSecret: credentials.clientSecret,
|
|
321
|
+
baseUrl: credentials.baseUrl || options.baseUrl,
|
|
322
|
+
scope: credentials.scope,
|
|
323
|
+
requiredScopes: options.requiredScopes,
|
|
324
|
+
fetch: options.fetch,
|
|
325
|
+
onEvent: options.onEvent,
|
|
326
|
+
});
|
|
327
|
+
try {
|
|
328
|
+
await cache.set(cacheKey, accessToken, {
|
|
329
|
+
secret: true,
|
|
330
|
+
ttl: expiresIn,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
// Best-effort persistence: next process will re-exchange.
|
|
335
|
+
}
|
|
336
|
+
return accessToken;
|
|
337
|
+
};
|
|
338
|
+
const exchangePromise = (cache.withLock ? cache.withLock(cacheKey, runLocked) : runLocked()).finally(() => {
|
|
307
339
|
pendingExchanges.delete(cacheKey);
|
|
308
340
|
});
|
|
309
341
|
pendingExchanges.set(cacheKey, exchangePromise);
|
|
@@ -340,6 +372,12 @@ export async function invalidateCredentialsToken(options) {
|
|
|
340
372
|
const clientId = getClientIdFromCredentials(resolved);
|
|
341
373
|
if (clientId && isClientCredentials(resolved)) {
|
|
342
374
|
const scopes = mergeScopes(resolved.scope, options.requiredScopes);
|
|
343
|
-
|
|
375
|
+
const baseUrl = resolved.baseUrl || options.baseUrl || DEFAULT_AUTH_BASE_URL;
|
|
376
|
+
await invalidateCachedToken({
|
|
377
|
+
clientId,
|
|
378
|
+
scopes,
|
|
379
|
+
baseUrl,
|
|
380
|
+
cache: options.cache,
|
|
381
|
+
});
|
|
344
382
|
}
|
|
345
383
|
}
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort cache for the SDK.
|
|
3
|
+
*
|
|
4
|
+
* The SDK uses this to avoid re-fetching values it can recreate, primarily
|
|
5
|
+
* client_credentials access tokens. Cache entries may disappear at any time:
|
|
6
|
+
* a miss is normal and callers must be able to rebuild the value.
|
|
7
|
+
*
|
|
8
|
+
* The default cache is in-memory. When the CLI package is installed, the SDK
|
|
9
|
+
* can opportunistically use its filesystem + keychain cache. Browser and
|
|
10
|
+
* minimal server deployments fall back to memory unless a caller injects a
|
|
11
|
+
* Redis, database, or environment-specific cache.
|
|
12
|
+
*
|
|
13
|
+
* Secrets: adapters receive a `secret: true` flag on `set` and decide
|
|
14
|
+
* what to do with it (keychain for the filesystem adapter; ignored for
|
|
15
|
+
* the in-memory adapter; user adapters can throw, plaintext, encrypt —
|
|
16
|
+
* their call). The value returned by `get` is always the plain secret.
|
|
17
|
+
*/
|
|
18
|
+
export interface ZapierCacheEntry {
|
|
19
|
+
value: string;
|
|
20
|
+
/** Millisecond epoch. Undefined means "no expiration recorded." */
|
|
21
|
+
expiresAt?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ZapierCacheSetOptions {
|
|
24
|
+
/**
|
|
25
|
+
* Hint that this value is sensitive. Adapters may use a more secure
|
|
26
|
+
* backend (e.g. the OS keychain for the filesystem adapter); adapters
|
|
27
|
+
* without a secure backend may throw, warn, or accept — their call.
|
|
28
|
+
*/
|
|
29
|
+
secret?: boolean;
|
|
30
|
+
/** Time-to-live in seconds from now. */
|
|
31
|
+
ttl?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface ZapierCache {
|
|
34
|
+
get(key: string): Promise<ZapierCacheEntry | undefined>;
|
|
35
|
+
set(key: string, value: string, options?: ZapierCacheSetOptions): Promise<void>;
|
|
36
|
+
delete(key: string): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Optional mutex for caches that can coordinate beyond one JavaScript
|
|
39
|
+
* process. The SDK re-checks the cache inside the lock before rebuilding.
|
|
40
|
+
*/
|
|
41
|
+
withLock?<T>(key: string, fn: () => Promise<T>): Promise<T>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Simplest possible adapter: a Map. No persistence, no locking (single
|
|
45
|
+
* process only), no differentiation between secrets and non-secrets.
|
|
46
|
+
* This is the default when cli-login isn't installed and no custom
|
|
47
|
+
* cache is provided.
|
|
48
|
+
*/
|
|
49
|
+
export declare function createMemoryCache(): ZapierCache;
|
|
50
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IACxD,GAAG,CACD,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC7D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAsB/C"}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Best-effort cache for the SDK.
|
|
3
|
+
*
|
|
4
|
+
* The SDK uses this to avoid re-fetching values it can recreate, primarily
|
|
5
|
+
* client_credentials access tokens. Cache entries may disappear at any time:
|
|
6
|
+
* a miss is normal and callers must be able to rebuild the value.
|
|
7
|
+
*
|
|
8
|
+
* The default cache is in-memory. When the CLI package is installed, the SDK
|
|
9
|
+
* can opportunistically use its filesystem + keychain cache. Browser and
|
|
10
|
+
* minimal server deployments fall back to memory unless a caller injects a
|
|
11
|
+
* Redis, database, or environment-specific cache.
|
|
12
|
+
*
|
|
13
|
+
* Secrets: adapters receive a `secret: true` flag on `set` and decide
|
|
14
|
+
* what to do with it (keychain for the filesystem adapter; ignored for
|
|
15
|
+
* the in-memory adapter; user adapters can throw, plaintext, encrypt —
|
|
16
|
+
* their call). The value returned by `get` is always the plain secret.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Simplest possible adapter: a Map. No persistence, no locking (single
|
|
20
|
+
* process only), no differentiation between secrets and non-secrets.
|
|
21
|
+
* This is the default when cli-login isn't installed and no custom
|
|
22
|
+
* cache is provided.
|
|
23
|
+
*/
|
|
24
|
+
export function createMemoryCache() {
|
|
25
|
+
const store = new Map();
|
|
26
|
+
return {
|
|
27
|
+
async get(key) {
|
|
28
|
+
const entry = store.get(key);
|
|
29
|
+
if (!entry)
|
|
30
|
+
return undefined;
|
|
31
|
+
if (entry.expiresAt !== undefined && entry.expiresAt <= Date.now()) {
|
|
32
|
+
store.delete(key);
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return { value: entry.value, expiresAt: entry.expiresAt };
|
|
36
|
+
},
|
|
37
|
+
async set(key, value, options) {
|
|
38
|
+
const expiresAt = options?.ttl
|
|
39
|
+
? Date.now() + options.ttl * 1000
|
|
40
|
+
: undefined;
|
|
41
|
+
store.set(key, { value, expiresAt });
|
|
42
|
+
},
|
|
43
|
+
async delete(key) {
|
|
44
|
+
store.delete(key);
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|