@dbx-tools/auth 0.6.182 → 0.9.29

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.
Files changed (53) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +116 -32
  3. package/index.ts +26 -2
  4. package/lib/exports.d.ts +2 -0
  5. package/lib/exports.js +3 -0
  6. package/lib/index.d.ts +27 -0
  7. package/lib/index.js +26 -1595
  8. package/lib/src/_logging.d.ts +10 -0
  9. package/lib/src/_logging.js +38 -0
  10. package/lib/src/_profile-core.d.ts +28 -0
  11. package/lib/src/_profile-core.js +216 -0
  12. package/lib/src/_profile.d.ts +15 -0
  13. package/lib/src/_profile.js +236 -0
  14. package/lib/src/databricks-auth.d.ts +11 -0
  15. package/lib/src/databricks-auth.js +314 -0
  16. package/lib/src/databricks-cli.d.ts +28 -0
  17. package/lib/src/databricks-cli.js +239 -0
  18. package/lib/src/errors.d.ts +7 -0
  19. package/lib/src/errors.js +14 -0
  20. package/lib/src/generated/databricks-cli-assets.json +33 -0
  21. package/lib/src/http-client.d.ts +23 -0
  22. package/lib/src/http-client.js +116 -0
  23. package/lib/src/lifecycle.d.ts +26 -0
  24. package/lib/src/lifecycle.js +229 -0
  25. package/lib/src/node-storage.d.ts +20 -0
  26. package/lib/src/node-storage.js +207 -0
  27. package/lib/src/personal-access-token.d.ts +11 -0
  28. package/lib/src/personal-access-token.js +30 -0
  29. package/lib/src/service-principal.d.ts +24 -0
  30. package/lib/src/service-principal.js +69 -0
  31. package/lib/src/storage.d.ts +20 -0
  32. package/lib/src/storage.js +98 -0
  33. package/lib/src/types.d.ts +157 -0
  34. package/lib/src/types.js +67 -0
  35. package/lib/tsconfig.tsbuildinfo +1 -0
  36. package/package.json +39 -16
  37. package/src/_logging.ts +42 -0
  38. package/src/_profile-core.ts +258 -0
  39. package/src/_profile.ts +319 -0
  40. package/src/databricks-auth.ts +416 -0
  41. package/src/databricks-cli.ts +298 -0
  42. package/src/errors.ts +16 -0
  43. package/src/generated/databricks-cli-assets.json +33 -0
  44. package/src/http-client.ts +147 -0
  45. package/src/lifecycle.ts +239 -0
  46. package/src/node-storage.ts +230 -0
  47. package/src/personal-access-token.ts +34 -0
  48. package/src/service-principal.ts +96 -0
  49. package/src/storage.ts +104 -0
  50. package/src/types.ts +188 -0
  51. package/src/_bindings-ffi.ts +0 -715
  52. package/src/_bindings.ts +0 -1794
  53. package/src/bindings.ts +0 -12
@@ -0,0 +1,229 @@
1
+ import { AuthError } from "./errors.js";
2
+ import { authLogger, credentialId, failureMetadata, tokenMetadata } from "./_logging.js";
3
+ const logger = authLogger("lifecycle");
4
+ /** Provider-neutral check-lock-check authentication and persistent token lifecycle. */
5
+ export class TokenLifecycle {
6
+ key;
7
+ provider;
8
+ store;
9
+ options;
10
+ now;
11
+ constructor(key, provider, store, options, now = () => new Date()) {
12
+ this.key = key;
13
+ this.provider = provider;
14
+ this.store = store;
15
+ this.options = options;
16
+ this.now = now;
17
+ logger.debug("created authentication lifecycle", {
18
+ credential: credentialId(key),
19
+ storage: store.name(),
20
+ refreshBufferSeconds: options.refreshBufferSeconds,
21
+ lockTimeoutSeconds: options.lockTimeoutSeconds,
22
+ loginTimeoutSeconds: options.loginTimeoutSeconds,
23
+ silentProvider: provider.canAuthenticateSilently(),
24
+ });
25
+ }
26
+ storeName() {
27
+ return this.store.name();
28
+ }
29
+ async login() {
30
+ logger.debug("interactive login requested", this.context());
31
+ return this.withLock(async () => {
32
+ await this.store.prepareWrite();
33
+ const token = validateToken(await this.provider.login(this.options.loginTimeoutSeconds * 1000));
34
+ await this.store.save(this.key, token);
35
+ logger.debug("interactive login stored credential", {
36
+ ...this.context(),
37
+ token: tokenMetadata(token, this.now()),
38
+ });
39
+ return publicToken(token);
40
+ });
41
+ }
42
+ token() {
43
+ return this.loadToken(false);
44
+ }
45
+ tokenOrLogin() {
46
+ return this.loadToken(true);
47
+ }
48
+ async tokenWithLogin(login) {
49
+ logger.debug("token requested", { ...this.context(), login: login ?? "auto" });
50
+ if (login === true)
51
+ return this.login();
52
+ if (login === false)
53
+ return this.token();
54
+ return this.tokenOrLogin();
55
+ }
56
+ forceRefresh(login = true) {
57
+ logger.debug("forced refresh requested", { ...this.context(), login });
58
+ return this.refreshRejected(undefined, login);
59
+ }
60
+ refreshRejectedToken(staleAccessToken, login = true) {
61
+ logger.debug("rejected token refresh requested", { ...this.context(), login });
62
+ return this.refreshRejected(staleAccessToken, login);
63
+ }
64
+ async logout() {
65
+ logger.debug("logout requested", this.context());
66
+ await this.withLock(() => this.store.remove(this.key));
67
+ logger.debug("stored credential removed", this.context());
68
+ }
69
+ async loadToken(login) {
70
+ const existing = await this.store.load(this.key);
71
+ const reusable = Boolean(existing && this.canReuse(existing));
72
+ logger.debug("checked credential cache", {
73
+ ...this.context(),
74
+ login,
75
+ reusable,
76
+ token: tokenMetadata(existing, this.now()),
77
+ });
78
+ if (existing && reusable)
79
+ return publicToken(existing);
80
+ return this.withLock(async () => {
81
+ const current = await this.store.load(this.key);
82
+ const currentReusable = Boolean(current && this.canReuse(current));
83
+ logger.debug("rechecked credential cache after lock", {
84
+ ...this.context(),
85
+ reusable: currentReusable,
86
+ token: tokenMetadata(current, this.now()),
87
+ });
88
+ if (current && currentReusable)
89
+ return publicToken(current);
90
+ return this.renew(current, login);
91
+ });
92
+ }
93
+ async refreshRejected(staleAccessToken, login) {
94
+ return this.withLock(async () => {
95
+ const current = await this.store.load(this.key);
96
+ if (staleAccessToken &&
97
+ current?.accessToken &&
98
+ current.accessToken !== staleAccessToken &&
99
+ isValid(current, this.now())) {
100
+ logger.debug("reused replacement for rejected credential", {
101
+ ...this.context(),
102
+ token: tokenMetadata(current, this.now()),
103
+ });
104
+ return publicToken(current);
105
+ }
106
+ return this.renew(current, login);
107
+ });
108
+ }
109
+ async renew(current, login) {
110
+ let token;
111
+ if (current) {
112
+ logger.debug("refreshing stored credential", {
113
+ ...this.context(),
114
+ loginFallback: login,
115
+ token: tokenMetadata(current, this.now()),
116
+ });
117
+ try {
118
+ token = await this.provider.refresh(current);
119
+ }
120
+ catch (error) {
121
+ logger.debug("credential refresh failed", {
122
+ ...this.context(),
123
+ loginFallback: login,
124
+ error: failureMetadata(error),
125
+ });
126
+ if (!login)
127
+ throw error;
128
+ logger.debug("falling back to interactive login", this.context());
129
+ token = await this.provider.login(this.options.loginTimeoutSeconds * 1000);
130
+ }
131
+ }
132
+ else if (this.provider.canAuthenticateSilently()) {
133
+ logger.debug("attempting silent credential acquisition", {
134
+ ...this.context(),
135
+ loginFallback: login,
136
+ });
137
+ try {
138
+ token = await this.provider.authenticate(this.options.loginTimeoutSeconds * 1000);
139
+ }
140
+ catch (error) {
141
+ logger.debug("silent credential acquisition failed", {
142
+ ...this.context(),
143
+ loginFallback: login,
144
+ error: failureMetadata(error),
145
+ });
146
+ if (!login)
147
+ throw error;
148
+ logger.debug("falling back to interactive login", this.context());
149
+ token = await this.provider.login(this.options.loginTimeoutSeconds * 1000);
150
+ }
151
+ }
152
+ else if (login) {
153
+ logger.debug("provider requires interactive login", this.context());
154
+ token = await this.provider.login(this.options.loginTimeoutSeconds * 1000);
155
+ }
156
+ else {
157
+ throw new AuthError("oauth", "No stored credential is available and interactive login is disabled");
158
+ }
159
+ token = validateToken(token, current);
160
+ logger.debug("credential acquisition completed", {
161
+ ...this.context(),
162
+ token: tokenMetadata(token, this.now()),
163
+ });
164
+ await this.store.prepareWrite();
165
+ await this.store.save(this.key, token);
166
+ logger.debug("credential saved", this.context());
167
+ return publicToken(token);
168
+ }
169
+ canReuse(token) {
170
+ if (!isValid(token, this.now()))
171
+ return false;
172
+ if (!token.expiry)
173
+ return true;
174
+ return (Date.parse(token.expiry) - this.now().getTime() > this.options.refreshBufferSeconds * 1000);
175
+ }
176
+ async withLock(action) {
177
+ logger.debug("waiting for credential lock", this.context());
178
+ const lease = await this.store.acquireLock(this.key, this.options.lockTimeoutSeconds * 1000);
179
+ logger.debug("credential lock acquired", this.context());
180
+ let failure;
181
+ try {
182
+ return await action();
183
+ }
184
+ catch (error) {
185
+ failure = error;
186
+ throw error;
187
+ }
188
+ finally {
189
+ try {
190
+ await this.store.releaseLock(lease);
191
+ logger.debug("credential lock released", this.context());
192
+ }
193
+ catch (releaseError) {
194
+ logger.debug("credential lock release failed", {
195
+ ...this.context(),
196
+ error: failureMetadata(releaseError),
197
+ });
198
+ if (failure === undefined)
199
+ throw releaseError;
200
+ }
201
+ }
202
+ }
203
+ context() {
204
+ return { credential: credentialId(this.key), storage: this.store.name() };
205
+ }
206
+ }
207
+ export function publicToken(token) {
208
+ return {
209
+ accessToken: token.accessToken,
210
+ tokenType: token.tokenType,
211
+ ...(token.expiry ? { expiry: token.expiry } : {}),
212
+ scopes: [...token.scopes],
213
+ };
214
+ }
215
+ export function validateToken(token, previous) {
216
+ if (!token.accessToken.trim())
217
+ throw new AuthError("oauth", "Token response did not contain an access token");
218
+ return {
219
+ accessToken: token.accessToken,
220
+ tokenType: token.tokenType || "Bearer",
221
+ refreshToken: token.refreshToken ?? previous?.refreshToken,
222
+ expiry: token.expiry,
223
+ scopes: token.scopes.length ? [...token.scopes] : [...(previous?.scopes ?? [])],
224
+ };
225
+ }
226
+ function isValid(token, now) {
227
+ return Boolean(token.accessToken) && (!token.expiry || Date.parse(token.expiry) > now.getTime());
228
+ }
229
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlmZWN5Y2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpZmVjeWNsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHekYsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBRXZDLHVGQUF1RjtBQUN2RixNQUFNLE9BQU8sY0FBYztJQUVOO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFMbkIsWUFDbUIsR0FBVyxFQUNYLFFBQXVCLEVBQ3ZCLEtBQXNCLEVBQ3RCLE9BQW9CLEVBQ3BCLE1BQWtCLEdBQUcsRUFBRSxDQUFDLElBQUksSUFBSSxFQUFFO1FBSmxDLFFBQUcsR0FBSCxHQUFHLENBQVE7UUFDWCxhQUFRLEdBQVIsUUFBUSxDQUFlO1FBQ3ZCLFVBQUssR0FBTCxLQUFLLENBQWlCO1FBQ3RCLFlBQU8sR0FBUCxPQUFPLENBQWE7UUFDcEIsUUFBRyxHQUFILEdBQUcsQ0FBK0I7UUFFbkQsTUFBTSxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsRUFBRTtZQUMvQyxVQUFVLEVBQUUsWUFBWSxDQUFDLEdBQUcsQ0FBQztZQUM3QixPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRTtZQUNyQixvQkFBb0IsRUFBRSxPQUFPLENBQUMsb0JBQW9CO1lBQ2xELGtCQUFrQixFQUFFLE9BQU8sQ0FBQyxrQkFBa0I7WUFDOUMsbUJBQW1CLEVBQUUsT0FBTyxDQUFDLG1CQUFtQjtZQUNoRCxjQUFjLEVBQUUsUUFBUSxDQUFDLHVCQUF1QixFQUFFO1NBQ25ELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxTQUFTO1FBQ1AsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFF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RUFBRSxZQUFZO1FBQzFELE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtRQUNwQixNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLElBQUksRUFBRSxDQUFDLENBQUM7S0FDaEYsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLE9BQU8sQ0FBQyxLQUFZLEVBQUUsR0FBUztJQUN0QyxPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDbkcsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEF1dGhFcnJvciB9IGZyb20gXCIuL2Vycm9ycy50c1wiO1xuaW1wb3J0IHsgYXV0aExvZ2dlciwgY3JlZGVudGlhbElkLCBmYWlsdXJlTWV0YWRhdGEsIHRva2VuTWV0YWRhdGEgfSBmcm9tIFwiLi9fbG9nZ2luZy50c1wiO1xuaW1wb3J0IHR5cGUgeyBBY2Nlc3NUb2tlbiwgQXV0aE9wdGlvbnMsIENyZWRlbnRpYWxTdG9yZSwgVG9rZW4sIFRva2VuUHJvdmlkZXIgfSBmcm9tIFwiLi90eXBlcy50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBhdXRoTG9nZ2VyKFwibGlmZWN5Y2xlXCIpO1xuXG4vKiogUHJvdmlkZXItbmV1dHJhbCBjaGVjay1sb2NrLWNoZWNrIGF1dGhlbnRpY2F0aW9uIGFuZCBwZXJzaXN0ZW50IHRva2VuIGxpZmVjeWNsZS4gKi9cbmV4cG9ydCBjbGFzcyBUb2tlbkxpZmVjeWNsZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkga2V5OiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm92aWRlcjogVG9rZW5Qcm92aWRlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0b3JlOiBDcmVkZW50aWFsU3RvcmUsXG4gICAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBBdXRoT3B0aW9ucyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG5vdzogKCkgPT4gRGF0ZSA9ICgpID0+IG5ldyBEYXRlKCksXG4gICkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImNyZWF0ZWQgYXV0aGVudGljYXRpb24gbGlmZWN5Y2xlXCIsIHtcbiAgICAgIGNyZWRlbnRpYWw6IGNyZWRlbnRpYWxJZChrZXkpLFxuICAgICAgc3RvcmFnZTogc3RvcmUubmFtZSgpLFxuICAgICAgcmVmcmVzaEJ1ZmZlclNlY29uZHM6IG9wdGlvbnMucmVmcmVzaEJ1ZmZlclNlY29uZHMsXG4gICAgICBsb2NrVGltZW91dFNlY29uZHM6IG9wdGlvbnMubG9ja1RpbWVvdXRTZWNvbmRzLFxuICAgICAgbG9naW5UaW1lb3V0U2Vjb25kczogb3B0aW9ucy5sb2dpblRpbWVvdXRTZWNvbmRzLFxuICAgICAgc2lsZW50UHJvdmlkZXI6IHByb3ZpZGVyLmNhbkF1dGhlbnRpY2F0ZVNpbGVudGx5KCksXG4gICAgfSk7XG4gIH1cblxuICBzdG9yZU5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5zdG9yZS5uYW1lKCk7XG4gIH1cblxuICBhc3luYyBsb2dpbigpOiBQcm9taXNlPEFjY2Vzc1Rva2VuPiB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiaW50ZXJhY3RpdmUgbG9naW4gcmVxdWVzdGVkXCIsIHRoaXMuY29udGV4dCgpKTtcbiAgICByZXR1cm4gdGhpcy53aXRoTG9jayhhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLnN0b3JlLnByZXBhcmVXcml0ZSgpO1xuICAgICAgY29uc3QgdG9rZW4gPSB2YWxpZGF0ZVRva2VuKFxuICAgICAgICBhd2FpdCB0aGlzLnByb3ZpZGVyLmxvZ2luKHRoaXMub3B0aW9ucy5sb2dpblRpbWVvdXRTZWNvbmRzICogMTAwMCksXG4gICAgICApO1xuICAgICAgYXdhaXQgdGhpcy5zdG9yZS5zYXZlKHRoaXMua2V5LCB0b2tlbik7XG4gICAgICBsb2dnZXIuZGVidWcoXCJpbnRlcmFjdGl2ZSBsb2dpbiBzdG9yZWQgY3JlZGVudGlhbFwiLCB7XG4gICAgICAgIC4uLnRoaXMuY29udGV4dCgpLFxuICAgICAgICB0b2tlbjogdG9rZW5NZXRhZGF0YSh0b2tlbiwgdGhpcy5ub3coKSksXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBwdWJsaWNUb2tlbih0b2tlbik7XG4gICAgfSk7XG4gIH1cblxuICB0b2tlbigpOiBQcm9taXNlPEFjY2Vzc1Rva2VuPiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZFRva2VuKGZhbHNlKTtcbiAgfVxuXG4gIHRva2VuT3JMb2dpbigpOiBQcm9taXNlPEFjY2Vzc1Rva2VuPiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZFRva2VuKHRydWUpO1xuICB9XG5cbiAgYXN5bmMgdG9rZW5XaXRoTG9naW4obG9naW4/OiBib29sZWFuKTogUHJvbWlzZTxBY2Nlc3NUb2tlbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInRva2VuIHJlcXVlc3RlZFwiLCB7IC4uLnRoaXMuY29udGV4dCgpLCBsb2dpbjogbG9naW4gPz8gXCJhdXRvXCIgfSk7XG4gICAgaWYgKGxvZ2luID09PSB0cnVlKSByZXR1cm4gdGhpcy5sb2dpbigpO1xuICAgIGlmIChsb2dpbiA9PT0gZmFsc2UpIHJldHVybiB0aGlzLnRva2VuKCk7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5PckxvZ2luKCk7XG4gIH1cblxuICBmb3JjZVJlZnJlc2gobG9naW4gPSB0cnVlKTogUHJvbWlzZTxBY2Nlc3NUb2tlbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImZvcmNlZCByZWZyZXNoIHJlcXVlc3RlZFwiLCB7IC4uLnRoaXMuY29udGV4dCgpLCBsb2dpbiB9KTtcbiAgICByZXR1cm4gdGhpcy5yZWZyZXNoUmVqZWN0ZWQodW5kZWZpbmVkLCBsb2dpbik7XG4gIH1cblxuICByZWZyZXNoUmVqZWN0ZWRUb2tlbihzdGFsZUFjY2Vzc1Rva2VuOiBzdHJpbmcsIGxvZ2luID0gdHJ1ZSk6IFByb21pc2U8QWNjZXNzVG9rZW4+IHtcbiAgICBsb2dnZXIuZGVidWcoXCJyZWplY3RlZCB0b2tlbiByZWZyZXNoIHJlcXVlc3RlZFwiLCB7IC4uLnRoaXMuY29udGV4dCgpLCBsb2dpbiB9KTtcbiAgICByZXR1cm4gdGhpcy5yZWZyZXNoUmVqZWN0ZWQoc3RhbGVBY2Nlc3NUb2tlbiwgbG9naW4pO1xuICB9XG5cbiAgYXN5bmMgbG9nb3V0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImxvZ291dCByZXF1ZXN0ZWRcIiwgdGhpcy5jb250ZXh0KCkpO1xuICAgIGF3YWl0IHRoaXMud2l0aExvY2soKCkgPT4gdGhpcy5zdG9yZS5yZW1vdmUodGhpcy5rZXkpKTtcbiAgICBsb2dnZXIuZGVidWcoXCJzdG9yZWQgY3JlZGVudGlhbCByZW1vdmVkXCIsIHRoaXMuY29udGV4dCgpKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbG9hZFRva2VuKGxvZ2luOiBib29sZWFuKTogUHJvbWlzZTxBY2Nlc3NUb2tlbj4ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgdGhpcy5zdG9yZS5sb2FkKHRoaXMua2V5KTtcbiAgICBjb25zdCByZXVzYWJsZSA9IEJvb2xlYW4oZXhpc3RpbmcgJiYgdGhpcy5jYW5SZXVzZShleGlzdGluZykpO1xuICAgIGxvZ2dlci5kZWJ1ZyhcImNoZWNrZWQgY3JlZGVudGlhbCBjYWNoZVwiLCB7XG4gICAgICAuLi50aGlzLmNvbnRleHQoKSxcbiAgICAgIGxvZ2luLFxuICAgICAgcmV1c2FibGUsXG4gICAgICB0b2tlbjogdG9rZW5NZXRhZGF0YShleGlzdGluZywgdGhpcy5ub3coKSksXG4gICAgfSk7XG4gICAgaWYgKGV4aXN0aW5nICYmIHJldXNhYmxlKSByZXR1cm4gcHVibGljVG9rZW4oZXhpc3RpbmcpO1xuICAgIHJldHVybiB0aGlzLndpdGhMb2NrKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCB0aGlzLnN0b3JlLmxvYWQodGhpcy5rZXkpO1xuICAgICAgY29uc3QgY3VycmVudFJldXNhYmxlID0gQm9vbGVhbihjdXJyZW50ICYmIHRoaXMuY2FuUmV1c2UoY3VycmVudCkpO1xuICAgICAgbG9nZ2VyLmRlYnVnKFwicmVjaGVja2VkIGNyZWRlbnRpYWwgY2FjaGUgYWZ0ZXIgbG9ja1wiLCB7XG4gICAgICAgIC4uLnRoaXMuY29udGV4dCgpLFxuICAgICAgICByZXVzYWJsZTogY3VycmVudFJldXNhYmxlLFxuICAgICAgICB0b2tlbjogdG9rZW5NZXRhZGF0YShjdXJyZW50LCB0aGlzLm5vdygpKSxcbiAgICAgIH0pO1xuICAgICAgaWYgKGN1cnJlbnQgJiYgY3VycmVudFJldXNhYmxlKSByZXR1cm4gcHVibGljVG9rZW4oY3VycmVudCk7XG4gICAgICByZXR1cm4gdGhpcy5yZW5ldyhjdXJyZW50LCBsb2dpbik7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZnJlc2hSZWplY3RlZChcbiAgICBzdGFsZUFjY2Vzc1Rva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgbG9naW46IGJvb2xlYW4sXG4gICk6IFByb21pc2U8QWNjZXNzVG9rZW4+IHtcbiAgICByZXR1cm4gdGhpcy53aXRoTG9jayhhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgdGhpcy5zdG9yZS5sb2FkKHRoaXMua2V5KTtcbiAgICAgIGlmIChcbiAgICAgICAgc3RhbGVBY2Nlc3NUb2tlbiAmJlxuICAgICAgICBjdXJyZW50Py5hY2Nlc3NUb2tlbiAmJlxuICAgICAgICBjdXJyZW50LmFjY2Vzc1Rva2VuICE9PSBzdGFsZUFjY2Vzc1Rva2VuICYmXG4gICAgICAgIGlzVmFsaWQoY3VycmVudCwgdGhpcy5ub3coKSlcbiAgICAgICkge1xuICAgICAgICBsb2dnZXIuZGVidWcoXCJyZXVzZWQgcmVwbGFjZW1lbnQgZm9yIHJlamVjdGVkIGNyZWRlbnRpYWxcIiwge1xuICAgICAgICAgIC4uLnRoaXMuY29udGV4dCgpLFxuICAgICAgICAgIHRva2VuOiB0b2tlbk1ldGFkYXRhKGN1cnJlbnQsIHRoaXMubm93KCkpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHB1YmxpY1Rva2VuKGN1cnJlbnQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMucmVuZXcoY3VycmVudCwgbG9naW4pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZW5ldyhjdXJyZW50OiBUb2tlbiB8IHVuZGVmaW5lZCwgbG9naW46IGJvb2xlYW4pOiBQcm9taXNlPEFjY2Vzc1Rva2VuPiB7XG4gICAgbGV0IHRva2VuOiBUb2tlbjtcbiAgICBpZiAoY3VycmVudCkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwicmVmcmVzaGluZyBzdG9yZWQgY3JlZGVudGlhbFwiLCB7XG4gICAgICAgIC4uLnRoaXMuY29udGV4dCgpLFxuICAgICAgICBsb2dpbkZhbGxiYWNrOiBsb2dpbixcbiAgICAgICAgdG9rZW46IHRva2VuTWV0YWRhdGEoY3VycmVudCwgdGhpcy5ub3coKSksXG4gICAgICB9KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRva2VuID0gYXdhaXQgdGhpcy5wcm92aWRlci5yZWZyZXNoKGN1cnJlbnQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiY3JlZGVudGlhbCByZWZyZXNoIGZhaWxlZFwiLCB7XG4gICAgICAgICAgLi4udGhpcy5jb250ZXh0KCksXG4gICAgICAgICAgbG9naW5GYWxsYmFjazogbG9naW4sXG4gICAgICAgICAgZXJyb3I6IGZhaWx1cmVNZXRhZGF0YShlcnJvciksXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWxvZ2luKSB0aHJvdyBlcnJvcjtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiZmFsbGluZyBiYWNrIHRvIGludGVyYWN0aXZlIGxvZ2luXCIsIHRoaXMuY29udGV4dCgpKTtcbiAgICAgICAgdG9rZW4gPSBhd2FpdCB0aGlzLnByb3ZpZGVyLmxvZ2luKHRoaXMub3B0aW9ucy5sb2dpblRpbWVvdXRTZWNvbmRzICogMTAwMCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh0aGlzLnByb3ZpZGVyLmNhbkF1dGhlbnRpY2F0ZVNpbGVudGx5KCkpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcImF0dGVtcHRpbmcgc2lsZW50IGNyZWRlbnRpYWwgYWNxdWlzaXRpb25cIiwge1xuICAgICAgICAuLi50aGlzLmNvbnRleHQoKSxcbiAgICAgICAgbG9naW5GYWxsYmFjazogbG9naW4sXG4gICAgICB9KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRva2VuID0gYXdhaXQgdGhpcy5wcm92aWRlci5hdXRoZW50aWNhdGUodGhpcy5vcHRpb25zLmxvZ2luVGltZW91dFNlY29uZHMgKiAxMDAwKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhcInNpbGVudCBjcmVkZW50aWFsIGFjcXVpc2l0aW9uIGZhaWxlZFwiLCB7XG4gICAgICAgICAgLi4udGhpcy5jb250ZXh0KCksXG4gICAgICAgICAgbG9naW5GYWxsYmFjazogbG9naW4sXG4gICAgICAgICAgZXJyb3I6IGZhaWx1cmVNZXRhZGF0YShlcnJvciksXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWxvZ2luKSB0aHJvdyBlcnJvcjtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiZmFsbGluZyBiYWNrIHRvIGludGVyYWN0aXZlIGxvZ2luXCIsIHRoaXMuY29udGV4dCgpKTtcbiAgICAgICAgdG9rZW4gPSBhd2FpdCB0aGlzLnByb3ZpZGVyLmxvZ2luKHRoaXMub3B0aW9ucy5sb2dpblRpbWVvdXRTZWNvbmRzICogMTAwMCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChsb2dpbikge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwicHJvdmlkZXIgcmVxdWlyZXMgaW50ZXJhY3RpdmUgbG9naW5cIiwgdGhpcy5jb250ZXh0KCkpO1xuICAgICAgdG9rZW4gPSBhd2FpdCB0aGlzLnByb3ZpZGVyLmxvZ2luKHRoaXMub3B0aW9ucy5sb2dpblRpbWVvdXRTZWNvbmRzICogMTAwMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBBdXRoRXJyb3IoXG4gICAgICAgIFwib2F1dGhcIixcbiAgICAgICAgXCJObyBzdG9yZWQgY3JlZGVudGlhbCBpcyBhdmFpbGFibGUgYW5kIGludGVyYWN0aXZlIGxvZ2luIGlzIGRpc2FibGVkXCIsXG4gICAgICApO1xuICAgIH1cbiAgICB0b2tlbiA9IHZhbGlkYXRlVG9rZW4odG9rZW4sIGN1cnJlbnQpO1xuICAgIGxvZ2dlci5kZWJ1ZyhcImNyZWRlbnRpYWwgYWNxdWlzaXRpb24gY29tcGxldGVkXCIsIHtcbiAgICAgIC4uLnRoaXMuY29udGV4dCgpLFxuICAgICAgdG9rZW46IHRva2VuTWV0YWRhdGEodG9rZW4sIHRoaXMubm93KCkpLFxuICAgIH0pO1xuICAgIGF3YWl0IHRoaXMuc3RvcmUucHJlcGFyZVdyaXRlKCk7XG4gICAgYXdhaXQgdGhpcy5zdG9yZS5zYXZlKHRoaXMua2V5LCB0b2tlbik7XG4gICAgbG9nZ2VyLmRlYnVnKFwiY3JlZGVudGlhbCBzYXZlZFwiLCB0aGlzLmNvbnRleHQoKSk7XG4gICAgcmV0dXJuIHB1YmxpY1Rva2VuKHRva2VuKTtcbiAgfVxuXG4gIHByaXZhdGUgY2FuUmV1c2UodG9rZW46IFRva2VuKTogYm9vbGVhbiB7XG4gICAgaWYgKCFpc1ZhbGlkKHRva2VuLCB0aGlzLm5vdygpKSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICghdG9rZW4uZXhwaXJ5KSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gKFxuICAgICAgRGF0ZS5wYXJzZSh0b2tlbi5leHBpcnkpIC0gdGhpcy5ub3coKS5nZXRUaW1lKCkgPiB0aGlzLm9wdGlvbnMucmVmcmVzaEJ1ZmZlclNlY29uZHMgKiAxMDAwXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgd2l0aExvY2s8VD4oYWN0aW9uOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgbG9nZ2VyLmRlYnVnKFwid2FpdGluZyBmb3IgY3JlZGVudGlhbCBsb2NrXCIsIHRoaXMuY29udGV4dCgpKTtcbiAgICBjb25zdCBsZWFzZSA9IGF3YWl0IHRoaXMuc3RvcmUuYWNxdWlyZUxvY2sodGhpcy5rZXksIHRoaXMub3B0aW9ucy5sb2NrVGltZW91dFNlY29uZHMgKiAxMDAwKTtcbiAgICBsb2dnZXIuZGVidWcoXCJjcmVkZW50aWFsIGxvY2sgYWNxdWlyZWRcIiwgdGhpcy5jb250ZXh0KCkpO1xuICAgIGxldCBmYWlsdXJlOiB1bmtub3duO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgYWN0aW9uKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGZhaWx1cmUgPSBlcnJvcjtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLnN0b3JlLnJlbGVhc2VMb2NrKGxlYXNlKTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiY3JlZGVudGlhbCBsb2NrIHJlbGVhc2VkXCIsIHRoaXMuY29udGV4dCgpKTtcbiAgICAgIH0gY2F0Y2ggKHJlbGVhc2VFcnJvcikge1xuICAgICAgICBsb2dnZXIuZGVidWcoXCJjcmVkZW50aWFsIGxvY2sgcmVsZWFzZSBmYWlsZWRcIiwge1xuICAgICAgICAgIC4uLnRoaXMuY29udGV4dCgpLFxuICAgICAgICAgIGVycm9yOiBmYWlsdXJlTWV0YWRhdGEocmVsZWFzZUVycm9yKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChmYWlsdXJlID09PSB1bmRlZmluZWQpIHRocm93IHJlbGVhc2VFcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbnRleHQoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHJldHVybiB7IGNyZWRlbnRpYWw6IGNyZWRlbnRpYWxJZCh0aGlzLmtleSksIHN0b3JhZ2U6IHRoaXMuc3RvcmUubmFtZSgpIH07XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHB1YmxpY1Rva2VuKHRva2VuOiBUb2tlbik6IEFjY2Vzc1Rva2VuIHtcbiAgcmV0dXJuIHtcbiAgICBhY2Nlc3NUb2tlbjogdG9rZW4uYWNjZXNzVG9rZW4sXG4gICAgdG9rZW5UeXBlOiB0b2tlbi50b2tlblR5cGUsXG4gICAgLi4uKHRva2VuLmV4cGlyeSA/IHsgZXhwaXJ5OiB0b2tlbi5leHBpcnkgfSA6IHt9KSxcbiAgICBzY29wZXM6IFsuLi50b2tlbi5zY29wZXNdLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVUb2tlbih0b2tlbjogVG9rZW4sIHByZXZpb3VzPzogVG9rZW4pOiBUb2tlbiB7XG4gIGlmICghdG9rZW4uYWNjZXNzVG9rZW4udHJpbSgpKVxuICAgIHRocm93IG5ldyBBdXRoRXJyb3IoXCJvYXV0aFwiLCBcIlRva2VuIHJlc3BvbnNlIGRpZCBub3QgY29udGFpbiBhbiBhY2Nlc3MgdG9rZW5cIik7XG4gIHJldHVybiB7XG4gICAgYWNjZXNzVG9rZW46IHRva2VuLmFjY2Vzc1Rva2VuLFxuICAgIHRva2VuVHlwZTogdG9rZW4udG9rZW5UeXBlIHx8IFwiQmVhcmVyXCIsXG4gICAgcmVmcmVzaFRva2VuOiB0b2tlbi5yZWZyZXNoVG9rZW4gPz8gcHJldmlvdXM/LnJlZnJlc2hUb2tlbixcbiAgICBleHBpcnk6IHRva2VuLmV4cGlyeSxcbiAgICBzY29wZXM6IHRva2VuLnNjb3Blcy5sZW5ndGggPyBbLi4udG9rZW4uc2NvcGVzXSA6IFsuLi4ocHJldmlvdXM/LnNjb3BlcyA/PyBbXSldLFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc1ZhbGlkKHRva2VuOiBUb2tlbiwgbm93OiBEYXRlKTogYm9vbGVhbiB7XG4gIHJldHVybiBCb29sZWFuKHRva2VuLmFjY2Vzc1Rva2VuKSAmJiAoIXRva2VuLmV4cGlyeSB8fCBEYXRlLnBhcnNlKHRva2VuLmV4cGlyeSkgPiBub3cuZ2V0VGltZSgpKTtcbn1cbiJdfQ==
@@ -0,0 +1,20 @@
1
+ import type { CredentialStore, LockAdapter, Token } from "./types.ts";
2
+ import { FileLayout } from "./types.ts";
3
+ /** File-backed credential store preserving unrelated Databricks CLI entries. */
4
+ export declare class FileCredentialStore implements CredentialStore {
5
+ private readonly root;
6
+ private readonly layout;
7
+ private readonly locks;
8
+ constructor(root?: string, layout?: FileLayout, locks?: LockAdapter);
9
+ load(key: string): Promise<Token | undefined>;
10
+ prepareWrite(): Promise<void>;
11
+ save(key: string, token: Token): Promise<void>;
12
+ remove(key: string): Promise<void>;
13
+ acquireLock(key: string, timeoutMs: number): Promise<string>;
14
+ releaseLock(lease: string): Promise<void>;
15
+ name(): string;
16
+ private forKey;
17
+ private withCacheLock;
18
+ private readCache;
19
+ private writeCache;
20
+ }
@@ -0,0 +1,207 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { chmod, mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { basename, dirname, join } from "node:path";
5
+ import { acquireFileLock } from "@dbx-tools/core/file-lock";
6
+ import { authLogger, credentialId, tokenMetadata } from "./_logging.js";
7
+ import { AuthError } from "./errors.js";
8
+ import { FileLayout } from "./types.js";
9
+ const logger = authLogger("file-storage");
10
+ class NodeFileLocks {
11
+ lockDirectory;
12
+ leases = new Map();
13
+ constructor(lockDirectory) {
14
+ this.lockDirectory = lockDirectory;
15
+ }
16
+ async acquire(key, timeoutMs) {
17
+ logger.debug("waiting for file lock", {
18
+ credential: credentialId(key),
19
+ timeoutMs,
20
+ });
21
+ const lease = await acquireFileLock(key, { dir: this.lockDirectory, timeoutMs });
22
+ const id = randomUUID();
23
+ this.leases.set(id, lease);
24
+ logger.debug("file lock acquired", {
25
+ credential: credentialId(key),
26
+ backend: lease.backend,
27
+ });
28
+ return id;
29
+ }
30
+ async release(id) {
31
+ const lease = this.leases.get(id);
32
+ if (!lease)
33
+ return;
34
+ this.leases.delete(id);
35
+ await lease.release();
36
+ logger.debug("file lock released", { backend: lease.backend });
37
+ }
38
+ }
39
+ /** File-backed credential store preserving unrelated Databricks CLI entries. */
40
+ export class FileCredentialStore {
41
+ root;
42
+ layout;
43
+ locks;
44
+ constructor(root = join(homedir(), ".databricks"), layout = FileLayout.Single, locks) {
45
+ this.root = root;
46
+ this.layout = layout;
47
+ this.locks = locks ?? new NodeFileLocks(join(root, "locks"));
48
+ }
49
+ async load(key) {
50
+ const store = this.forKey(key);
51
+ return store.withCacheLock(async () => {
52
+ const token = deserializeToken((await store.readCache()).tokens[key]);
53
+ logger.debug("loaded file credential", {
54
+ credential: credentialId(key),
55
+ layout: this.layout,
56
+ token: tokenMetadata(token),
57
+ });
58
+ return token;
59
+ });
60
+ }
61
+ async prepareWrite() {
62
+ await ensureDirectory(this.root, 0o700);
63
+ logger.debug("prepared credential directory", { layout: this.layout });
64
+ }
65
+ async save(key, token) {
66
+ const store = this.forKey(key);
67
+ await store.withCacheLock(async () => {
68
+ const cache = await store.readCache();
69
+ cache.tokens[key] = serializeToken(token);
70
+ await store.writeCache(cache);
71
+ logger.debug("saved file credential", {
72
+ credential: credentialId(key),
73
+ layout: this.layout,
74
+ token: tokenMetadata(token),
75
+ });
76
+ });
77
+ }
78
+ async remove(key) {
79
+ const store = this.forKey(key);
80
+ await store.withCacheLock(async () => {
81
+ const cache = await store.readCache();
82
+ delete cache.tokens[key];
83
+ await store.writeCache(cache);
84
+ logger.debug("removed file credential", {
85
+ credential: credentialId(key),
86
+ layout: this.layout,
87
+ });
88
+ });
89
+ }
90
+ acquireLock(key, timeoutMs) {
91
+ return this.locks.acquire(this.layout === FileLayout.Single ? `${this.root}:refresh` : `${this.root}:${key}:refresh`, timeoutMs);
92
+ }
93
+ releaseLock(lease) {
94
+ return this.locks.release(lease);
95
+ }
96
+ name() {
97
+ return "file";
98
+ }
99
+ forKey(key) {
100
+ if (this.layout === FileLayout.Single)
101
+ return this;
102
+ const digest = createHash("sha256").update(key).digest("hex");
103
+ return new FileCredentialStore(join(this.root, digest), FileLayout.Single, this.locks);
104
+ }
105
+ async withCacheLock(action) {
106
+ await ensureDirectory(this.root, 0o700);
107
+ const lease = await this.locks.acquire(`${this.root}:cache`, 30_000);
108
+ try {
109
+ return await action();
110
+ }
111
+ finally {
112
+ await this.locks.release(lease);
113
+ }
114
+ }
115
+ async readCache() {
116
+ try {
117
+ const source = await readTextFile(join(this.root, "token-cache.json"));
118
+ const cache = source ? JSON.parse(source) : { version: 1, tokens: {} };
119
+ if (cache.version !== 1 || typeof cache.tokens !== "object" || !cache.tokens) {
120
+ throw new AuthError("storage", "Token cache must use version 1");
121
+ }
122
+ logger.debug("read token cache", {
123
+ exists: Boolean(source),
124
+ credentialCount: Object.keys(cache.tokens).length,
125
+ });
126
+ return cache;
127
+ }
128
+ catch (cause) {
129
+ if (cause instanceof AuthError)
130
+ throw cause;
131
+ throw new AuthError("storage", "Could not read Databricks token cache", { cause });
132
+ }
133
+ }
134
+ async writeCache(cache) {
135
+ try {
136
+ await atomicWriteTextFile(join(this.root, "token-cache.json"), `${JSON.stringify(cache, null, 2)}\n`, 0o600);
137
+ logger.debug("wrote token cache", { credentialCount: Object.keys(cache.tokens).length });
138
+ }
139
+ catch (cause) {
140
+ throw new AuthError("storage", "Could not write Databricks token cache", { cause });
141
+ }
142
+ }
143
+ }
144
+ async function ensureDirectory(path, mode) {
145
+ await mkdir(path, { recursive: true, mode });
146
+ await chmod(path, mode);
147
+ }
148
+ async function readTextFile(path) {
149
+ try {
150
+ return await readFile(path, "utf8");
151
+ }
152
+ catch (cause) {
153
+ if (cause.code === "ENOENT")
154
+ return undefined;
155
+ throw cause;
156
+ }
157
+ }
158
+ async function atomicWriteTextFile(path, content, mode) {
159
+ const parent = dirname(path);
160
+ await ensureDirectory(parent, 0o700);
161
+ const temporary = join(parent, `.${basename(path)}-${randomUUID()}.tmp`);
162
+ try {
163
+ await writeFile(temporary, content, { mode, flag: "wx" });
164
+ await chmod(temporary, mode);
165
+ await rename(temporary, path);
166
+ }
167
+ finally {
168
+ await unlink(temporary).catch((cause) => {
169
+ if (cause.code !== "ENOENT")
170
+ throw cause;
171
+ });
172
+ }
173
+ }
174
+ function serializeToken(token) {
175
+ return {
176
+ access_token: token.accessToken,
177
+ token_type: token.tokenType,
178
+ ...(token.refreshToken ? { refresh_token: token.refreshToken } : {}),
179
+ ...(token.expiry ? { expiry: token.expiry } : {}),
180
+ ...(token.scopes.length ? { scopes: token.scopes } : {}),
181
+ };
182
+ }
183
+ function deserializeToken(value) {
184
+ if (!value || typeof value !== "object")
185
+ return undefined;
186
+ const record = value;
187
+ const accessToken = stringValue(record.access_token ?? record.accessToken);
188
+ if (!accessToken)
189
+ return undefined;
190
+ return {
191
+ accessToken,
192
+ tokenType: stringValue(record.token_type ?? record.tokenType) ?? "Bearer",
193
+ ...(stringValue(record.refresh_token ?? record.refreshToken)
194
+ ? { refreshToken: stringValue(record.refresh_token ?? record.refreshToken) }
195
+ : {}),
196
+ ...(stringValue(record.expiry ?? record.expires_at)
197
+ ? { expiry: stringValue(record.expiry ?? record.expires_at) }
198
+ : {}),
199
+ scopes: Array.isArray(record.scopes)
200
+ ? record.scopes.filter((scope) => typeof scope === "string")
201
+ : [],
202
+ };
203
+ }
204
+ function stringValue(value) {
205
+ return typeof value === "string" && value.trim() ? value : undefined;
206
+ }
207
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9kZS1zdG9yYWdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL25vZGUtc3RvcmFnZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNyRCxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVwRCxPQUFPLEVBQUUsZUFBZSxFQUFzQixNQUFNLDJCQUEyQixDQUFDO0FBRWhGLE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRXhDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFeEMsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBTzFDLE1BQU0sYUFBYTtJQUdZO0lBRlosTUFBTSxHQUFHLElBQUksR0FBRyxFQUF5QixDQUFDO0lBRTNELFlBQTZCLGFBQXFCO1FBQXJCLGtCQUFhLEdBQWIsYUFBYSxDQUFRO0lBQUcsQ0FBQztJQUV0RCxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQVcsRUFBRSxTQUFpQjtRQUMxQyxNQUFNLENBQUMsS0FBSyxDQUFDLHVCQUF1QixFQUFFO1lBQ3BDLFVBQVUsRUFBRSxZQUFZLENBQUMsR0FBRyxDQUFDO1lBQzdCLFNBQVM7U0FDVixDQUFDLENBQUM7UUFDSCxNQUFNLEtBQUssR0FBRyxNQUFNLGVBQWUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxH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dCB7IGNyZWF0ZUhhc2gsIHJhbmRvbVVVSUQgfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcbmltcG9ydCB7IGNobW9kLCBta2RpciwgcmVhZEZpbGUsIHJlbmFtZSwgdW5saW5rLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgaG9tZWRpciB9IGZyb20gXCJub2RlOm9zXCI7XG5pbXBvcnQgeyBiYXNlbmFtZSwgZGlybmFtZSwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcblxuaW1wb3J0IHsgYWNxdWlyZUZpbGVMb2NrLCB0eXBlIEZpbGVMb2NrTGVhc2UgfSBmcm9tIFwiQGRieC10b29scy9jb3JlL2ZpbGUtbG9ja1wiO1xuXG5pbXBvcnQgeyBhdXRoTG9nZ2VyLCBjcmVkZW50aWFsSWQsIHRva2VuTWV0YWRhdGEgfSBmcm9tIFwiLi9fbG9nZ2luZy50c1wiO1xuaW1wb3J0IHsgQXV0aEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzLnRzXCI7XG5pbXBvcnQgdHlwZSB7IENyZWRlbnRpYWxTdG9yZSwgTG9ja0FkYXB0ZXIsIFRva2VuIH0gZnJvbSBcIi4vdHlwZXMudHNcIjtcbmltcG9ydCB7IEZpbGVMYXlvdXQgfSBmcm9tIFwiLi90eXBlcy50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBhdXRoTG9nZ2VyKFwiZmlsZS1zdG9yYWdlXCIpO1xuXG5pbnRlcmZhY2UgVG9rZW5DYWNoZSB7XG4gIHZlcnNpb246IG51bWJlcjtcbiAgdG9rZW5zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuY2xhc3MgTm9kZUZpbGVMb2NrcyBpbXBsZW1lbnRzIExvY2tBZGFwdGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBsZWFzZXMgPSBuZXcgTWFwPHN0cmluZywgRmlsZUxvY2tMZWFzZT4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGxvY2tEaXJlY3Rvcnk6IHN0cmluZykge31cblxuICBhc3luYyBhY3F1aXJlKGtleTogc3RyaW5nLCB0aW1lb3V0TXM6IG51bWJlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgbG9nZ2VyLmRlYnVnKFwid2FpdGluZyBmb3IgZmlsZSBsb2NrXCIsIHtcbiAgICAgIGNyZWRlbnRpYWw6IGNyZWRlbnRpYWxJZChrZXkpLFxuICAgICAgdGltZW91dE1zLFxuICAgIH0pO1xuICAgIGNvbnN0IGxlYXNlID0gYXdhaXQgYWNxdWlyZUZpbGVMb2NrKGtleSwgeyBkaXI6IHRoaXMubG9ja0RpcmVjdG9yeSwgdGltZW91dE1zIH0pO1xuICAgIGNvbnN0IGlkID0gcmFuZG9tVVVJRCgpO1xuICAgIHRoaXMubGVhc2VzLnNldChpZCwgbGVhc2UpO1xuICAgIGxvZ2dlci5kZWJ1ZyhcImZpbGUgbG9jayBhY3F1aXJlZFwiLCB7XG4gICAgICBjcmVkZW50aWFsOiBjcmVkZW50aWFsSWQoa2V5KSxcbiAgICAgIGJhY2tlbmQ6IGxlYXNlLmJhY2tlbmQsXG4gICAgfSk7XG4gICAgcmV0dXJuIGlkO1xuICB9XG5cbiAgYXN5bmMgcmVsZWFzZShpZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbGVhc2UgPSB0aGlzLmxlYXNlcy5nZXQoaWQpO1xuICAgIGlmICghbGVhc2UpIHJldHVybjtcbiAgICB0aGlzLmxlYXNlcy5kZWxldGUoaWQpO1xuICAgIGF3YWl0IGxlYXNlLnJlbGVhc2UoKTtcbiAgICBsb2dnZXIuZGVidWcoXCJmaWxlIGxvY2sgcmVsZWFzZWRcIiwgeyBiYWNrZW5kOiBsZWFzZS5iYWNrZW5kIH0pO1xuICB9XG59XG5cbi8qKiBGaWxlLWJhY2tlZCBjcmVkZW50aWFsIHN0b3JlIHByZXNlcnZpbmcgdW5yZWxhdGVkIERhdGFicmlja3MgQ0xJIGVudHJpZXMuICovXG5leHBvcnQgY2xhc3MgRmlsZUNyZWRlbnRpYWxTdG9yZSBpbXBsZW1lbnRzIENyZWRlbnRpYWxTdG9yZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9ja3M6IExvY2tBZGFwdGVyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcm9vdCA9IGpvaW4oaG9tZWRpcigpLCBcIi5kYXRhYnJpY2tzXCIpLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbGF5b3V0ID0gRmlsZUxheW91dC5TaW5nbGUsXG4gICAgbG9ja3M/OiBMb2NrQWRhcHRlcixcbiAgKSB7XG4gICAgdGhpcy5sb2NrcyA9IGxvY2tzID8/IG5ldyBOb2RlRmlsZUxvY2tzKGpvaW4ocm9vdCwgXCJsb2Nrc1wiKSk7XG4gIH1cblxuICBhc3luYyBsb2FkKGtleTogc3RyaW5nKTogUHJvbWlzZTxUb2tlbiB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHN0b3JlID0gdGhpcy5mb3JLZXkoa2V5KTtcbiAgICByZXR1cm4gc3RvcmUud2l0aENhY2hlTG9jayhhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0b2tlbiA9IGRlc2VyaWFsaXplVG9rZW4oKGF3YWl0IHN0b3JlLnJlYWRDYWNoZSgpKS50b2tlbnNba2V5XSk7XG4gICAgICBsb2dnZXIuZGVidWcoXCJsb2FkZWQgZmlsZSBjcmVkZW50aWFsXCIsIHtcbiAgICAgICAgY3JlZGVudGlhbDogY3JlZGVudGlhbElkKGtleSksXG4gICAgICAgIGxheW91dDogdGhpcy5sYXlvdXQsXG4gICAgICAgIHRva2VuOiB0b2tlbk1ldGFkYXRhKHRva2VuKSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRva2VuO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgcHJlcGFyZVdyaXRlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IGVuc3VyZURpcmVjdG9yeSh0aGlzLnJvb3QsIDBvNzAwKTtcbiAgICBsb2dnZXIuZGVidWcoXCJwcmVwYXJlZCBjcmVkZW50aWFsIGRpcmVjdG9yeVwiLCB7IGxheW91dDogdGhpcy5sYXlvdXQgfSk7XG4gIH1cblxuICBhc3luYyBzYXZlKGtleTogc3RyaW5nLCB0b2tlbjogVG9rZW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdG9yZSA9IHRoaXMuZm9yS2V5KGtleSk7XG4gICAgYXdhaXQgc3RvcmUud2l0aENhY2hlTG9jayhhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjYWNoZSA9IGF3YWl0IHN0b3JlLnJlYWRDYWNoZSgpO1xuICAgICAgY2FjaGUudG9rZW5zW2tleV0gPSBzZXJpYWxpemVUb2tlbih0b2tlbik7XG4gICAgICBhd2FpdCBzdG9yZS53cml0ZUNhY2hlKGNhY2hlKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcInNhdmVkIGZpbGUgY3JlZGVudGlhbFwiLCB7XG4gICAgICAgIGNyZWRlbnRpYWw6IGNyZWRlbnRpYWxJZChrZXkpLFxuICAgICAgICBsYXlvdXQ6IHRoaXMubGF5b3V0LFxuICAgICAgICB0b2tlbjogdG9rZW5NZXRhZGF0YSh0b2tlbiksXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHJlbW92ZShrZXk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHN0b3JlID0gdGhpcy5mb3JLZXkoa2V5KTtcbiAgICBhd2FpdCBzdG9yZS53aXRoQ2FjaGVMb2NrKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGNhY2hlID0gYXdhaXQgc3RvcmUucmVhZENhY2hlKCk7XG4gICAgICBkZWxldGUgY2FjaGUudG9rZW5zW2tleV07XG4gICAgICBhd2FpdCBzdG9yZS53cml0ZUNhY2hlKGNhY2hlKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcInJlbW92ZWQgZmlsZSBjcmVkZW50aWFsXCIsIHtcbiAgICAgICAgY3JlZGVudGlhbDogY3JlZGVudGlhbElkKGtleSksXG4gICAgICAgIGxheW91dDogdGhpcy5sYXlvdXQsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFjcXVpcmVMb2NrKGtleTogc3RyaW5nLCB0aW1lb3V0TXM6IG51bWJlcik6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMubG9ja3MuYWNxdWlyZShcbiAgICAgIHRoaXMubGF5b3V0ID09PSBGaWxlTGF5b3V0LlNpbmdsZSA/IGAke3RoaXMucm9vdH06cmVmcmVzaGAgOiBgJHt0aGlzLnJvb3R9OiR7a2V5fTpyZWZyZXNoYCxcbiAgICAgIHRpbWVvdXRNcyxcbiAgICApO1xuICB9XG5cbiAgcmVsZWFzZUxvY2sobGVhc2U6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmxvY2tzLnJlbGVhc2UobGVhc2UpO1xuICB9XG5cbiAgbmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiBcImZpbGVcIjtcbiAgfVxuXG4gIHByaXZhdGUgZm9yS2V5KGtleTogc3RyaW5nKTogRmlsZUNyZWRlbnRpYWxTdG9yZSB7XG4gICAgaWYgKHRoaXMubGF5b3V0ID09PSBGaWxlTGF5b3V0LlNpbmdsZSkgcmV0dXJuIHRoaXM7XG4gICAgY29uc3QgZGlnZXN0ID0gY3JlYXRlSGFzaChcInNoYTI1NlwiKS51cGRhdGUoa2V5KS5kaWdlc3QoXCJoZXhcIik7XG4gICAgcmV0dXJuIG5ldyBGaWxlQ3JlZGVudGlhbFN0b3JlKGpvaW4odGhpcy5yb290LCBkaWdlc3QpLCBGaWxlTGF5b3V0LlNpbmdsZSwgdGhpcy5sb2Nrcyk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdpdGhDYWNoZUxvY2s8VD4oYWN0aW9uOiAoKSA9PiBQcm9taXNlPFQ+KTogUHJvbWlzZTxUPiB7XG4gICAgYXdhaXQgZW5zdXJlRGlyZWN0b3J5KHRoaXMucm9vdCwgMG83MDApO1xuICAgIGNvbnN0IGxlYXNlID0gYXdhaXQgdGhpcy5sb2Nrcy5hY3F1aXJlKGAke3RoaXMucm9vdH06Y2FjaGVgLCAzMF8wMDApO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgYWN0aW9uKCk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IHRoaXMubG9ja3MucmVsZWFzZShsZWFzZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWFkQ2FjaGUoKTogUHJvbWlzZTxUb2tlbkNhY2hlPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IHJlYWRUZXh0RmlsZShqb2luKHRoaXMucm9vdCwgXCJ0b2tlbi1jYWNoZS5qc29uXCIpKTtcbiAgICAgIGNvbnN0IGNhY2hlID0gc291cmNlID8gKEpTT04ucGFyc2Uoc291cmNlKSBhcyBUb2tlbkNhY2hlKSA6IHsgdmVyc2lvbjogMSwgdG9rZW5zOiB7fSB9O1xuICAgICAgaWYgKGNhY2hlLnZlcnNpb24gIT09IDEgfHwgdHlwZW9mIGNhY2hlLnRva2VucyAhPT0gXCJvYmplY3RcIiB8fCAhY2FjaGUudG9rZW5zKSB7XG4gICAgICAgIHRocm93IG5ldyBBdXRoRXJyb3IoXCJzdG9yYWdlXCIsIFwiVG9rZW4gY2FjaGUgbXVzdCB1c2UgdmVyc2lvbiAxXCIpO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLmRlYnVnKFwicmVhZCB0b2tlbiBjYWNoZVwiLCB7XG4gICAgICAgIGV4aXN0czogQm9vbGVhbihzb3VyY2UpLFxuICAgICAgICBjcmVkZW50aWFsQ291bnQ6IE9iamVjdC5rZXlzKGNhY2hlLnRva2VucykubGVuZ3RoLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gY2FjaGU7XG4gICAgfSBjYXRjaCAoY2F1c2UpIHtcbiAgICAgIGlmIChjYXVzZSBpbnN0YW5jZW9mIEF1dGhFcnJvcikgdGhyb3cgY2F1c2U7XG4gICAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwic3RvcmFnZVwiLCBcIkNvdWxkIG5vdCByZWFkIERhdGFicmlja3MgdG9rZW4gY2FjaGVcIiwgeyBjYXVzZSB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHdyaXRlQ2FjaGUoY2FjaGU6IFRva2VuQ2FjaGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgYXRvbWljV3JpdGVUZXh0RmlsZShcbiAgICAgICAgam9pbih0aGlzLnJvb3QsIFwidG9rZW4tY2FjaGUuanNvblwiKSxcbiAgICAgICAgYCR7SlNPTi5zdHJpbmdpZnkoY2FjaGUsIG51bGwsIDIpfVxcbmAsXG4gICAgICAgIDBvNjAwLFxuICAgICAgKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcIndyb3RlIHRva2VuIGNhY2hlXCIsIHsgY3JlZGVudGlhbENvdW50OiBPYmplY3Qua2V5cyhjYWNoZS50b2tlbnMpLmxlbmd0aCB9KTtcbiAgICB9IGNhdGNoIChjYXVzZSkge1xuICAgICAgdGhyb3cgbmV3IEF1dGhFcnJvcihcInN0b3JhZ2VcIiwgXCJDb3VsZCBub3Qgd3JpdGUgRGF0YWJyaWNrcyB0b2tlbiBjYWNoZVwiLCB7IGNhdXNlIH0pO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBlbnN1cmVEaXJlY3RvcnkocGF0aDogc3RyaW5nLCBtb2RlOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbWtkaXIocGF0aCwgeyByZWN1cnNpdmU6IHRydWUsIG1vZGUgfSk7XG4gIGF3YWl0IGNobW9kKHBhdGgsIG1vZGUpO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZWFkVGV4dEZpbGUocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgcmVhZEZpbGUocGF0aCwgXCJ1dGY4XCIpO1xuICB9IGNhdGNoIChjYXVzZSkge1xuICAgIGlmICgoY2F1c2UgYXMgTm9kZUpTLkVycm5vRXhjZXB0aW9uKS5jb2RlID09PSBcIkVOT0VOVFwiKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHRocm93IGNhdXNlO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGF0b21pY1dyaXRlVGV4dEZpbGUocGF0aDogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcsIG1vZGU6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBwYXJlbnQgPSBkaXJuYW1lKHBhdGgpO1xuICBhd2FpdCBlbnN1cmVEaXJlY3RvcnkocGFyZW50LCAwbzcwMCk7XG4gIGNvbnN0IHRlbXBvcmFyeSA9IGpvaW4ocGFyZW50LCBgLiR7YmFzZW5hbWUocGF0aCl9LSR7cmFuZG9tVVVJRCgpfS50bXBgKTtcbiAgdHJ5IHtcbiAgICBhd2FpdCB3cml0ZUZpbGUodGVtcG9yYXJ5LCBjb250ZW50LCB7IG1vZGUsIGZsYWc6IFwid3hcIiB9KTtcbiAgICBhd2FpdCBjaG1vZCh0ZW1wb3JhcnksIG1vZGUpO1xuICAgIGF3YWl0IHJlbmFtZSh0ZW1wb3JhcnksIHBhdGgpO1xuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IHVubGluayh0ZW1wb3JhcnkpLmNhdGNoKChjYXVzZTogTm9kZUpTLkVycm5vRXhjZXB0aW9uKSA9PiB7XG4gICAgICBpZiAoY2F1c2UuY29kZSAhPT0gXCJFTk9FTlRcIikgdGhyb3cgY2F1c2U7XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplVG9rZW4odG9rZW46IFRva2VuKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4ge1xuICAgIGFjY2Vzc190b2tlbjogdG9rZW4uYWNjZXNzVG9rZW4sXG4gICAgdG9rZW5fdHlwZTogdG9rZW4udG9rZW5UeXBlLFxuICAgIC4uLih0b2tlbi5yZWZyZXNoVG9rZW4gPyB7IHJlZnJlc2hfdG9rZW46IHRva2VuLnJlZnJlc2hUb2tlbiB9IDoge30pLFxuICAgIC4uLih0b2tlbi5leHBpcnkgPyB7IGV4cGlyeTogdG9rZW4uZXhwaXJ5IH0gOiB7fSksXG4gICAgLi4uKHRva2VuLnNjb3Blcy5sZW5ndGggPyB7IHNjb3BlczogdG9rZW4uc2NvcGVzIH0gOiB7fSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIGRlc2VyaWFsaXplVG9rZW4odmFsdWU6IHVua25vd24pOiBUb2tlbiB8IHVuZGVmaW5lZCB7XG4gIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCByZWNvcmQgPSB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3QgYWNjZXNzVG9rZW4gPSBzdHJpbmdWYWx1ZShyZWNvcmQuYWNjZXNzX3Rva2VuID8/IHJlY29yZC5hY2Nlc3NUb2tlbik7XG4gIGlmICghYWNjZXNzVG9rZW4pIHJldHVybiB1bmRlZmluZWQ7XG4gIHJldHVybiB7XG4gICAgYWNjZXNzVG9rZW4sXG4gICAgdG9rZW5UeXBlOiBzdHJpbmdWYWx1ZShyZWNvcmQudG9rZW5fdHlwZSA/PyByZWNvcmQudG9rZW5UeXBlKSA/PyBcIkJlYXJlclwiLFxuICAgIC4uLihzdHJpbmdWYWx1ZShyZWNvcmQucmVmcmVzaF90b2tlbiA/PyByZWNvcmQucmVmcmVzaFRva2VuKVxuICAgICAgPyB7IHJlZnJlc2hUb2tlbjogc3RyaW5nVmFsdWUocmVjb3JkLnJlZnJlc2hfdG9rZW4gPz8gcmVjb3JkLnJlZnJlc2hUb2tlbikgfVxuICAgICAgOiB7fSksXG4gICAgLi4uKHN0cmluZ1ZhbHVlKHJlY29yZC5leHBpcnkgPz8gcmVjb3JkLmV4cGlyZXNfYXQpXG4gICAgICA/IHsgZXhwaXJ5OiBzdHJpbmdWYWx1ZShyZWNvcmQuZXhwaXJ5ID8/IHJlY29yZC5leHBpcmVzX2F0KSB9XG4gICAgICA6IHt9KSxcbiAgICBzY29wZXM6IEFycmF5LmlzQXJyYXkocmVjb3JkLnNjb3BlcylcbiAgICAgID8gcmVjb3JkLnNjb3Blcy5maWx0ZXIoKHNjb3BlKTogc2NvcGUgaXMgc3RyaW5nID0+IHR5cGVvZiBzY29wZSA9PT0gXCJzdHJpbmdcIilcbiAgICAgIDogW10sXG4gIH07XG59XG5cbmZ1bmN0aW9uIHN0cmluZ1ZhbHVlKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS50cmltKCkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cbiJdfQ==
@@ -0,0 +1,11 @@
1
+ import type { Token, TokenProvider } from "./types.ts";
2
+ /** Non-refreshing provider for a configured Databricks personal access token. */
3
+ export declare class DatabricksPersonalAccessTokenProvider implements TokenProvider {
4
+ private readonly accessToken;
5
+ constructor(accessToken: string);
6
+ authenticate(): Promise<Token>;
7
+ login(): Promise<Token>;
8
+ refresh(): Promise<Token>;
9
+ canAuthenticateSilently(): boolean;
10
+ private token;
11
+ }
@@ -0,0 +1,30 @@
1
+ import { authLogger } from "./_logging.js";
2
+ const logger = authLogger("pat");
3
+ /** Non-refreshing provider for a configured Databricks personal access token. */
4
+ export class DatabricksPersonalAccessTokenProvider {
5
+ accessToken;
6
+ constructor(accessToken) {
7
+ this.accessToken = accessToken;
8
+ }
9
+ authenticate() {
10
+ return Promise.resolve(this.token());
11
+ }
12
+ login() {
13
+ return Promise.resolve(this.token());
14
+ }
15
+ refresh() {
16
+ return Promise.resolve(this.token());
17
+ }
18
+ canAuthenticateSilently() {
19
+ return true;
20
+ }
21
+ token() {
22
+ logger.debug("using configured personal access token");
23
+ return {
24
+ accessToken: this.accessToken,
25
+ tokenType: "Bearer",
26
+ scopes: [],
27
+ };
28
+ }
29
+ }
30
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVyc29uYWwtYWNjZXNzLXRva2VuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BlcnNvbmFsLWFjY2Vzcy10b2tlbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRzNDLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUVqQyxpRkFBaUY7QUFDakYsTUFBTSxPQUFPLHFDQUFxQztJQUNuQjtJQUE3QixZQUE2QixXQUFtQjtRQUFuQixnQkFBVyxHQUFYLFdBQVcsQ0FBUTtJQUFHLENBQUM7SUFFcEQsWUFBWTtRQUNWLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsS0FBSztRQUNILE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsT0FBTztRQUNMLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQsdUJBQXVCO1FBQ3JCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVPLEtBQUs7UUFDWCxNQUFNLENBQUMsS0FBSyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDdkQsT0FBTztZQUNMLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztZQUM3QixTQUFTLEVBQUUsUUFBUTtZQUNuQixNQUFNLEVBQUUsRUFBRTtTQUNYLENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhdXRoTG9nZ2VyIH0gZnJvbSBcIi4vX2xvZ2dpbmcudHNcIjtcbmltcG9ydCB0eXBlIHsgVG9rZW4sIFRva2VuUHJvdmlkZXIgfSBmcm9tIFwiLi90eXBlcy50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBhdXRoTG9nZ2VyKFwicGF0XCIpO1xuXG4vKiogTm9uLXJlZnJlc2hpbmcgcHJvdmlkZXIgZm9yIGEgY29uZmlndXJlZCBEYXRhYnJpY2tzIHBlcnNvbmFsIGFjY2VzcyB0b2tlbi4gKi9cbmV4cG9ydCBjbGFzcyBEYXRhYnJpY2tzUGVyc29uYWxBY2Nlc3NUb2tlblByb3ZpZGVyIGltcGxlbWVudHMgVG9rZW5Qcm92aWRlciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgYWNjZXNzVG9rZW46IHN0cmluZykge31cblxuICBhdXRoZW50aWNhdGUoKTogUHJvbWlzZTxUb2tlbj4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy50b2tlbigpKTtcbiAgfVxuXG4gIGxvZ2luKCk6IFByb21pc2U8VG9rZW4+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMudG9rZW4oKSk7XG4gIH1cblxuICByZWZyZXNoKCk6IFByb21pc2U8VG9rZW4+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMudG9rZW4oKSk7XG4gIH1cblxuICBjYW5BdXRoZW50aWNhdGVTaWxlbnRseSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgdG9rZW4oKTogVG9rZW4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInVzaW5nIGNvbmZpZ3VyZWQgcGVyc29uYWwgYWNjZXNzIHRva2VuXCIpO1xuICAgIHJldHVybiB7XG4gICAgICBhY2Nlc3NUb2tlbjogdGhpcy5hY2Nlc3NUb2tlbixcbiAgICAgIHRva2VuVHlwZTogXCJCZWFyZXJcIixcbiAgICAgIHNjb3BlczogW10sXG4gICAgfTtcbiAgfVxufVxuIl19
@@ -0,0 +1,24 @@
1
+ import type { Token, TokenProvider } from "./types.ts";
2
+ /** Client-credentials inputs and transport options for Databricks OAuth. */
3
+ export interface DatabricksServicePrincipalConfig {
4
+ tokenEndpoint: string;
5
+ clientId: string;
6
+ clientSecret: string;
7
+ scopes: string[];
8
+ groupId?: string;
9
+ fetch?: typeof globalThis.fetch;
10
+ allowInsecureRequests?: boolean;
11
+ }
12
+ /** Databricks service-principal provider backed by client credentials. */
13
+ export declare class DatabricksServicePrincipalProvider implements TokenProvider {
14
+ private readonly config;
15
+ private readonly authorizationServer;
16
+ private readonly client;
17
+ private readonly requestOptions;
18
+ constructor(config: DatabricksServicePrincipalConfig);
19
+ authenticate(): Promise<Token>;
20
+ login(): Promise<Token>;
21
+ refresh(): Promise<Token>;
22
+ canAuthenticateSilently(): boolean;
23
+ private acquire;
24
+ }