@dbx-tools/auth 0.6.180 → 0.9.28

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,314 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ import * as environmentUtils from "@dbx-tools/shared-core/environment-utils";
4
+ import { authLogger, tokenMetadata } from "./_logging.js";
5
+ import { AuthError } from "./errors.js";
6
+ import { DatabricksCliProvider, resolveDatabricksCli } from "./databricks-cli.js";
7
+ import { publicToken, TokenLifecycle } from "./lifecycle.js";
8
+ import { FileCredentialStore } from "./node-storage.js";
9
+ import { DatabricksPersonalAccessTokenProvider } from "./personal-access-token.js";
10
+ import { listDatabricksProfiles, machineScopes, resolveConfigFile, resolveDatabricksProfile, } from "./_profile.js";
11
+ import { DatabricksServicePrincipalProvider } from "./service-principal.js";
12
+ import { MemoryCredentialStore } from "./storage.js";
13
+ import { AuthKind, AuthOptions, DEFAULT_ACCESS_TOKEN_HEADER, Storage, TargetKind, WORKSPACE_ID_HEADER, } from "./types.js";
14
+ const logger = authLogger("databricks");
15
+ /** Persistent Databricks auth facade over the provider-neutral lifecycle. */
16
+ class PersistentAuth {
17
+ profileValue;
18
+ storageValue;
19
+ options;
20
+ environment;
21
+ client;
22
+ requestToken;
23
+ constructor(profileValue, storageValue, options, environment, client, requestToken) {
24
+ this.profileValue = profileValue;
25
+ this.storageValue = storageValue;
26
+ this.options = options;
27
+ this.environment = environment;
28
+ this.client = client;
29
+ this.requestToken = requestToken;
30
+ }
31
+ async challenge() {
32
+ if (!this.client)
33
+ throw new AuthError("oauth", "app_obo uses the current request token and cannot start login");
34
+ logger.debug("authentication challenge requested", this.context());
35
+ await this.client.login();
36
+ logger.debug("authentication challenge completed", this.context());
37
+ }
38
+ token(login) {
39
+ logger.debug("Databricks token requested", {
40
+ ...this.context(),
41
+ login: login ?? "auto",
42
+ source: this.requestToken ? "request" : "lifecycle",
43
+ });
44
+ return this.requestToken
45
+ ? Promise.resolve(publicToken(this.requestToken))
46
+ : this.requiredClient().tokenWithLogin(login);
47
+ }
48
+ async authenticate(login) {
49
+ const token = await this.token(login);
50
+ const headers = {
51
+ [DEFAULT_ACCESS_TOKEN_HEADER]: `${token.tokenType} ${token.accessToken}`,
52
+ ...(this.profileValue.workspaceId
53
+ ? { [WORKSPACE_ID_HEADER]: this.profileValue.workspaceId }
54
+ : {}),
55
+ };
56
+ logger.debug("generated Databricks authentication headers", {
57
+ ...this.context(),
58
+ headerNames: Object.keys(headers),
59
+ token: tokenMetadata(token),
60
+ });
61
+ return headers;
62
+ }
63
+ async authorizationHeaderForUrl(requestUrl, login) {
64
+ return (await this.requestHeadersForUrl(requestUrl, login))[DEFAULT_ACCESS_TOKEN_HEADER];
65
+ }
66
+ async requestHeadersForUrl(requestUrl, login) {
67
+ const request = new URL(requestUrl);
68
+ const credentialOrigin = new URL(this.profileValue.host).origin;
69
+ if (request.origin !== credentialOrigin) {
70
+ logger.debug("skipped authentication for different origin", {
71
+ ...this.context(),
72
+ requestOrigin: request.origin,
73
+ credentialOrigin,
74
+ });
75
+ return {};
76
+ }
77
+ logger.debug("applying authentication to matching origin", {
78
+ ...this.context(),
79
+ requestOrigin: request.origin,
80
+ });
81
+ return this.authenticate(login);
82
+ }
83
+ forceRefreshToken(login = true) {
84
+ logger.debug("Databricks token force refresh requested", { ...this.context(), login });
85
+ return this.requestToken
86
+ ? Promise.resolve(publicToken(this.requestToken))
87
+ : this.requiredClient().forceRefresh(login);
88
+ }
89
+ refreshRejectedToken(staleAccessToken, login = true) {
90
+ logger.debug("Databricks rejected token refresh requested", {
91
+ ...this.context(),
92
+ login,
93
+ requestToken: Boolean(this.requestToken),
94
+ });
95
+ return this.requestToken
96
+ ? Promise.resolve(publicToken(this.requestToken))
97
+ : this.requiredClient().refreshRejectedToken(staleAccessToken, login);
98
+ }
99
+ logout() {
100
+ logger.debug("Databricks logout requested", this.context());
101
+ return this.client?.logout() ?? Promise.resolve();
102
+ }
103
+ status() {
104
+ return {
105
+ profile: this.profileValue.name,
106
+ host: this.profileValue.host,
107
+ storage: this.storageValue,
108
+ };
109
+ }
110
+ principal() {
111
+ return this.profileValue.principal;
112
+ }
113
+ workspaceId() {
114
+ return this.profileValue.workspaceId;
115
+ }
116
+ authKind() {
117
+ return this.profileValue.authKind;
118
+ }
119
+ profile(name) {
120
+ const profile = !name || name === this.profileValue.name
121
+ ? this.profileValue
122
+ : resolveDatabricksProfile({ ...this.options, profile: name }, this.environment);
123
+ return profileSummary(profile);
124
+ }
125
+ listProfiles(refresh = false) {
126
+ return listDatabricksProfiles(this.options.configFile, refresh, this.environment);
127
+ }
128
+ requiredClient() {
129
+ if (!this.client)
130
+ throw new AuthError("oauth", "Authentication lifecycle is not available");
131
+ return this.client;
132
+ }
133
+ context() {
134
+ return {
135
+ profile: this.profileValue.name,
136
+ host: this.profileValue.host,
137
+ authKind: this.profileValue.authKind,
138
+ storage: this.storageValue,
139
+ hasWorkspaceId: Boolean(this.profileValue.workspaceId),
140
+ };
141
+ }
142
+ }
143
+ /** Create a Databricks authentication client. */
144
+ export function createAuthClient(options = { preferUserToMachine: true }, storage = Storage.Auto, dependencies = {}) {
145
+ return createPersistentAuth(options, storage, dependencies);
146
+ }
147
+ /** Resolve a Databricks profile and open built-in credential storage. */
148
+ async function createPersistentAuth(options, storage, dependencies) {
149
+ const environment = dependencies.environment ?? process.env;
150
+ const profile = resolveDatabricksProfile(options, environment);
151
+ const inApp = profile.authKind === AuthKind.AppOnBehalfOf ||
152
+ profile.authKind === AuthKind.AppServicePrincipal;
153
+ const backend = storage === Storage.Auto ? Storage.Memory : storage;
154
+ logger.debug("creating persistent Databricks auth", {
155
+ profile: profile.name,
156
+ host: profile.host,
157
+ authKind: profile.authKind,
158
+ requestedStorage: storage,
159
+ resolvedStorage: backend,
160
+ inApp,
161
+ });
162
+ const store = backend === Storage.Memory
163
+ ? new MemoryCredentialStore()
164
+ : new FileCredentialStore(options.cacheDir ?? join(homedir(), ".databricks"));
165
+ return createPersistentAuthWithStorage(options, store, storage, dependencies, profile);
166
+ }
167
+ /** Resolve a Databricks profile using caller-owned generic storage. */
168
+ async function createPersistentAuthWithStorage(options, store, storage = store.name() === "memory" ? Storage.Memory : Storage.File, dependencies = {}, resolvedProfile) {
169
+ const profile = resolvedProfile ?? resolveDatabricksProfile(options, dependencies.environment ?? process.env);
170
+ if (profile.authKind === AuthKind.AppOnBehalfOf) {
171
+ logger.debug("created request-scoped App OBO authentication", {
172
+ profile: profile.name,
173
+ host: profile.host,
174
+ hasWorkspaceId: Boolean(profile.workspaceId),
175
+ });
176
+ return new PersistentAuth(profile, Storage.Memory, options, dependencies.environment ?? process.env, undefined, {
177
+ accessToken: profile.accessToken,
178
+ tokenType: "Bearer",
179
+ scopes: [...profile.scopes],
180
+ });
181
+ }
182
+ const provider = await providerFor(profile, options, dependencies);
183
+ const client = new TokenLifecycle(profile.cacheKey, provider, store, AuthOptions.create(options.auth));
184
+ const persistent = new PersistentAuth(profile, storage === Storage.Auto ? storageFromName(store.name()) : storage, options, dependencies.environment ?? process.env, client);
185
+ logger.debug("created persistent authentication lifecycle", {
186
+ profile: profile.name,
187
+ host: profile.host,
188
+ authKind: profile.authKind,
189
+ storage: persistent.status().storage,
190
+ });
191
+ return persistent;
192
+ }
193
+ async function providerFor(profile, options, dependencies) {
194
+ const environment = dependencies.environment ?? process.env;
195
+ const inApp = environmentUtils.isDatabricksAppEnv({ ...environment });
196
+ switch (profile.authKind) {
197
+ case AuthKind.UserToMachine: {
198
+ const install = !inApp || options.installCliInApp === true;
199
+ logger.debug("selected Databricks CLI provider", {
200
+ profile: profile.name,
201
+ inApp,
202
+ install,
203
+ });
204
+ return new DatabricksCliProvider(profile.name, () => dependencies.resolveCli
205
+ ? dependencies.resolveCli({ install })
206
+ : resolveDatabricksCli(environment, { install }), cliEnvironment(profile, resolveConfigFile(options.configFile, environment)));
207
+ }
208
+ case AuthKind.PersonalAccessToken:
209
+ logger.debug("selected personal access token provider", { profile: profile.name });
210
+ return new DatabricksPersonalAccessTokenProvider(profile.accessToken);
211
+ case AuthKind.MachineToMachine:
212
+ case AuthKind.AppServicePrincipal: {
213
+ logger.debug("selected service-principal provider", {
214
+ profile: profile.name,
215
+ authKind: profile.authKind,
216
+ target: profile.target,
217
+ });
218
+ const endpoints = await resolveOAuthEndpoints(profile, dependencies.fetch);
219
+ return new DatabricksServicePrincipalProvider({
220
+ tokenEndpoint: endpoints.tokenEndpoint,
221
+ clientId: profile.clientId,
222
+ clientSecret: profile.clientSecret,
223
+ scopes: machineScopes(profile.scopes),
224
+ ...(profile.groupId ? { groupId: profile.groupId } : {}),
225
+ allowInsecureRequests: isLoopbackHttp(profile.host),
226
+ fetch: dependencies.fetch,
227
+ });
228
+ }
229
+ case AuthKind.AppOnBehalfOf:
230
+ throw new AuthError("config", "App OBO tokens do not use a persistent provider");
231
+ }
232
+ }
233
+ async function resolveOAuthEndpoints(profile, fetcher = globalThis.fetch) {
234
+ const host = profile.host.replace(/\/$/, "");
235
+ if (profile.target === TargetKind.Account) {
236
+ if (!profile.accountId)
237
+ throw new AuthError("config", "Account target requires account_id");
238
+ const endpoints = {
239
+ tokenEndpoint: `${host}/oidc/accounts/${profile.accountId}/v1/token`,
240
+ };
241
+ logger.debug("resolved account OAuth endpoint", {
242
+ profile: profile.name,
243
+ tokenOrigin: new URL(endpoints.tokenEndpoint).origin,
244
+ });
245
+ return endpoints;
246
+ }
247
+ const discovery = profile.target === TargetKind.Unified
248
+ ? `${host}/oidc/accounts/${requiredAccountId(profile)}/.well-known/oauth-authorization-server`
249
+ : `${host}/oidc/.well-known/oauth-authorization-server`;
250
+ logger.debug("requesting OAuth discovery", {
251
+ profile: profile.name,
252
+ target: profile.target,
253
+ discovery,
254
+ });
255
+ const response = await fetcher(discovery, { redirect: "manual" });
256
+ logger.debug("received OAuth discovery response", {
257
+ profile: profile.name,
258
+ status: response.status,
259
+ });
260
+ if (response.status === 404)
261
+ throw new AuthError("oauth", `OAuth is not supported at ${discovery}`);
262
+ if (!response.ok)
263
+ throw new AuthError("oauth", `OAuth discovery returned HTTP ${response.status}`);
264
+ const value = (await response.json());
265
+ const tokenEndpoint = stringValue(value.token_endpoint);
266
+ if (!tokenEndpoint)
267
+ throw new AuthError("oauth", "OAuth discovery response is incomplete");
268
+ logger.debug("resolved OAuth token endpoint", {
269
+ profile: profile.name,
270
+ tokenOrigin: new URL(tokenEndpoint).origin,
271
+ });
272
+ return { tokenEndpoint };
273
+ }
274
+ function requiredAccountId(profile) {
275
+ if (!profile.accountId)
276
+ throw new AuthError("config", "Unified target requires account_id");
277
+ return profile.accountId;
278
+ }
279
+ function storageFromName(name) {
280
+ return name === "memory" ? Storage.Memory : Storage.File;
281
+ }
282
+ function profileSummary(profile) {
283
+ return {
284
+ name: profile.name,
285
+ host: profile.host,
286
+ ...(profile.accountId ? { accountId: profile.accountId } : {}),
287
+ ...(profile.workspaceId ? { workspaceId: profile.workspaceId } : {}),
288
+ target: profile.target,
289
+ authKind: profile.authKind,
290
+ };
291
+ }
292
+ function isLoopbackHttp(host) {
293
+ const url = new URL(host);
294
+ return url.protocol === "http:" && ["127.0.0.1", "localhost"].includes(url.hostname);
295
+ }
296
+ function cliEnvironment(profile, configFile) {
297
+ return {
298
+ DATABRICKS_CONFIG_FILE: configFile,
299
+ DATABRICKS_CONFIG_PROFILE: profile.name,
300
+ DATABRICKS_HOST: profile.host,
301
+ ...(profile.accountId ? { DATABRICKS_ACCOUNT_ID: profile.accountId } : {}),
302
+ ...(profile.workspaceId ? { DATABRICKS_WORKSPACE_ID: profile.workspaceId } : {}),
303
+ ...(profile.authKind === AuthKind.PersonalAccessToken
304
+ ? {
305
+ DATABRICKS_AUTH_TYPE: "pat",
306
+ DATABRICKS_TOKEN: profile.accessToken,
307
+ }
308
+ : {}),
309
+ };
310
+ }
311
+ function stringValue(value) {
312
+ return typeof value === "string" && value.trim() ? value : undefined;
313
+ }
314
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWJyaWNrcy1hdXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RhdGFicmlja3MtYXV0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFakMsT0FBTyxLQUFLLGdCQUFnQixNQUFNLDBDQUEwQyxDQUFDO0FBRTdFLE9BQU8sRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDeEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLG9CQUFvQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEYsT0FBTyxFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUscUNBQXFDLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNuRixPQUFPLEVBQ0wsc0JBQXNCLEVBQ3RCLGFBQWEsRUFDYixpQkFBaUIsRUFDakIsd0JBQXdCLEdBQ3pCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQ0FBa0MsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzVFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQ0wsUUFBUSxFQUVSLFdBQVcsRUFLWCwyQkFBMkIsRUFDM0IsT0FBTyxFQUNQLFVBQVUsRUFHVixtQkFBbUIsR0FDcEIsTUFBTSxZQUFZLENBQUM7QUFFcEIsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBU3hDLDZFQUE2RTtBQUM3RSxNQUFNLGNBQWM7SUFFQztJQUNBO0lBQ0E7SUFDQTtJQUNB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dkMsZUFBZSxFQUFFLE9BQU8sQ0FBQyxJQUFJO1FBQzdCLEdBQUcsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLHFCQUFxQixFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLHVCQUF1QixFQUFFLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2hGLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxtQkFBbUI7WUFDbkQsQ0FBQyxDQUFDO2dCQUNFLG9CQUFvQixFQUFFLEtBQUs7Z0JBQzNCLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxXQUFZO2FBQ3ZDO1lBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNSLENBQUM7QUFDSixDQUFDO0FBRUQsU0FBUyxXQUFXLENBQUMsS0FBYztJQUNqQyxPQUFPLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3ZFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBob21lZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5cbmltcG9ydCAqIGFzIGVudmlyb25tZW50VXRpbHMgZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmUvZW52aXJvbm1lbnQtdXRpbHNcIjtcblxuaW1wb3J0IHsgYXV0aExvZ2dlciwgdG9rZW5NZXRhZGF0YSB9IGZyb20gXCIuL19sb2dnaW5nLnRzXCI7XG5pbXBvcnQgeyBBdXRoRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnMudHNcIjtcbmltcG9ydCB7IERhdGFicmlja3NDbGlQcm92aWRlciwgcmVzb2x2ZURhdGFicmlja3NDbGkgfSBmcm9tIFwiLi9kYXRhYnJpY2tzLWNsaS50c1wiO1xuaW1wb3J0IHsgcHVibGljVG9rZW4sIFRva2VuTGlmZWN5Y2xlIH0gZnJvbSBcIi4vbGlmZWN5Y2xlLnRzXCI7XG5pbXBvcnQgeyBGaWxlQ3JlZGVudGlhbFN0b3JlIH0gZnJvbSBcIi4vbm9kZS1zdG9yYWdlLnRzXCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzUGVyc29uYWxBY2Nlc3NUb2tlblByb3ZpZGVyIH0gZnJvbSBcIi4vcGVyc29uYWwtYWNjZXNzLXRva2VuLnRzXCI7XG5pbXBvcnQge1xuICBsaXN0RGF0YWJyaWNrc1Byb2ZpbGVzLFxuICBtYWNoaW5lU2NvcGVzLFxuICByZXNvbHZlQ29uZmlnRmlsZSxcbiAgcmVzb2x2ZURhdGFicmlja3NQcm9maWxlLFxufSBmcm9tIFwiLi9fcHJvZmlsZS50c1wiO1xuaW1wb3J0IHsgRGF0YWJyaWNrc1NlcnZpY2VQcmluY2lwYWxQcm92aWRlciB9IGZyb20gXCIuL3NlcnZpY2UtcHJpbmNpcGFsLnRzXCI7XG5pbXBvcnQgeyBNZW1vcnlDcmVkZW50aWFsU3RvcmUgfSBmcm9tIFwiLi9zdG9yYWdlLnRzXCI7XG5pbXBvcnQge1xuICBBdXRoS2luZCxcbiAgdHlwZSBBdXRoQ2xpZW50LFxuICBBdXRoT3B0aW9ucyxcbiAgdHlwZSBDcmVkZW50aWFsU3RvcmUsXG4gIHR5cGUgRGF0YWJyaWNrc0F1dGhPcHRpb25zLFxuICB0eXBlIERhdGFicmlja3NBdXRoU3RhdHVzLFxuICB0eXBlIERhdGFicmlja3NQcm9maWxlLFxuICBERUZBVUxUX0FDQ0VTU19UT0tFTl9IRUFERVIsXG4gIFN0b3JhZ2UsXG4gIFRhcmdldEtpbmQsXG4gIHR5cGUgVG9rZW4sXG4gIHR5cGUgVG9rZW5Qcm92aWRlcixcbiAgV09SS1NQQUNFX0lEX0hFQURFUixcbn0gZnJvbSBcIi4vdHlwZXMudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gYXV0aExvZ2dlcihcImRhdGFicmlja3NcIik7XG5cbi8qKiBJbmplY3RhYmxlIGhvc3QgY2FwYWJpbGl0aWVzIGZvciBEYXRhYnJpY2tzIGF1dGhlbnRpY2F0aW9uLiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRhYnJpY2tzQXV0aERlcGVuZGVuY2llcyB7XG4gIGVudmlyb25tZW50PzogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPj47XG4gIGZldGNoPzogdHlwZW9mIGdsb2JhbFRoaXMuZmV0Y2g7XG4gIHJlc29sdmVDbGk/OiAob3B0aW9uczogeyBpbnN0YWxsOiBib29sZWFuIH0pID0+IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPjtcbn1cblxuLyoqIFBlcnNpc3RlbnQgRGF0YWJyaWNrcyBhdXRoIGZhY2FkZSBvdmVyIHRoZSBwcm92aWRlci1uZXV0cmFsIGxpZmVjeWNsZS4gKi9cbmNsYXNzIFBlcnNpc3RlbnRBdXRoIGltcGxlbWVudHMgQXV0aENsaWVudCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJvZmlsZVZhbHVlOiBEYXRhYnJpY2tzUHJvZmlsZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0b3JhZ2VWYWx1ZTogU3RvcmFnZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IERhdGFicmlja3NBdXRoT3B0aW9ucyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVudmlyb25tZW50OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+PixcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudD86IFRva2VuTGlmZWN5Y2xlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdFRva2VuPzogVG9rZW4sXG4gICkge31cblxuICBhc3luYyBjaGFsbGVuZ2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLmNsaWVudClcbiAgICAgIHRocm93IG5ldyBBdXRoRXJyb3IoXCJvYXV0aFwiLCBcImFwcF9vYm8gdXNlcyB0aGUgY3VycmVudCByZXF1ZXN0IHRva2VuIGFuZCBjYW5ub3Qgc3RhcnQgbG9naW5cIik7XG4gICAgbG9nZ2VyLmRlYnVnKFwiYXV0aGVudGljYXRpb24gY2hhbGxlbmdlIHJlcXVlc3RlZFwiLCB0aGlzLmNvbnRleHQoKSk7XG4gICAgYXdhaXQgdGhpcy5jbGllbnQubG9naW4oKTtcbiAgICBsb2dnZXIuZGVidWcoXCJhdXRoZW50aWNhdGlvbiBjaGFsbGVuZ2UgY29tcGxldGVkXCIsIHRoaXMuY29udGV4dCgpKTtcbiAgfVxuXG4gIHRva2VuKGxvZ2luPzogYm9vbGVhbikge1xuICAgIGxvZ2dlci5kZWJ1ZyhcIkRhdGFicmlja3MgdG9rZW4gcmVxdWVzdGVkXCIsIHtcbiAgICAgIC4uLnRoaXMuY29udGV4dCgpLFxuICAgICAgbG9naW46IGxvZ2luID8/IFwiYXV0b1wiLFxuICAgICAgc291cmNlOiB0aGlzLnJlcXVlc3RUb2tlbiA/IFwicmVxdWVzdFwiIDogXCJsaWZlY3ljbGVcIixcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0VG9rZW5cbiAgICAgID8gUHJvbWlzZS5yZXNvbHZlKHB1YmxpY1Rva2VuKHRoaXMucmVxdWVzdFRva2VuKSlcbiAgICAgIDogdGhpcy5yZXF1aXJlZENsaWVudCgpLnRva2VuV2l0aExvZ2luKGxvZ2luKTtcbiAgfVxuXG4gIGFzeW5jIGF1dGhlbnRpY2F0ZShsb2dpbj86IGJvb2xlYW4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+IHtcbiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IHRoaXMudG9rZW4obG9naW4pO1xuICAgIGNvbnN0IGhlYWRlcnMgPSB7XG4gICAgICBbREVGQVVMVF9BQ0NFU1NfVE9LRU5fSEVBREVSXTogYCR7dG9rZW4udG9rZW5UeXBlfSAke3Rva2VuLmFjY2Vzc1Rva2VufWAsXG4gICAgICAuLi4odGhpcy5wcm9maWxlVmFsdWUud29ya3NwYWNlSWRcbiAgICAgICAgPyB7IFtXT1JLU1BBQ0VfSURfSEVBREVSXTogdGhpcy5wcm9maWxlVmFsdWUud29ya3NwYWNlSWQgfVxuICAgICAgICA6IHt9KSxcbiAgICB9O1xuICAgIGxvZ2dlci5kZWJ1ZyhcImdlbmVyYXRlZCBEYXRhYnJpY2tzIGF1dGhlbnRpY2F0aW9uIGhlYWRlcnNcIiwge1xuICAgICAgLi4udGhpcy5jb250ZXh0KCksXG4gICAgICBoZWFkZXJOYW1lczogT2JqZWN0LmtleXMoaGVhZGVycyksXG4gICAgICB0b2tlbjogdG9rZW5NZXRhZGF0YSh0b2tlbiksXG4gICAgfSk7XG4gICAgcmV0dXJuIGhlYWRlcnM7XG4gIH1cblxuICBhc3luYyBhdXRob3JpemF0aW9uSGVhZGVyRm9yVXJsKFxuICAgIHJlcXVlc3RVcmw6IHN0cmluZyxcbiAgICBsb2dpbj86IGJvb2xlYW4sXG4gICk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLnJlcXVlc3RIZWFkZXJzRm9yVXJsKHJlcXVlc3RVcmwsIGxvZ2luKSlbREVGQVVMVF9BQ0NFU1NfVE9LRU5fSEVBREVSXTtcbiAgfVxuXG4gIGFzeW5jIHJlcXVlc3RIZWFkZXJzRm9yVXJsKHJlcXVlc3RVcmw6IHN0cmluZywgbG9naW4/OiBib29sZWFuKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBVUkwocmVxdWVzdFVybCk7XG4gICAgY29uc3QgY3JlZGVudGlhbE9yaWdpbiA9IG5ldyBVUkwodGhpcy5wcm9maWxlVmFsdWUuaG9zdCkub3JpZ2luO1xuICAgIGlmIChyZXF1ZXN0Lm9yaWdpbiAhPT0gY3JlZGVudGlhbE9yaWdpbikge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwic2tpcHBlZCBhdXRoZW50aWNhdGlvbiBmb3IgZGlmZmVyZW50IG9yaWdpblwiLCB7XG4gICAgICAgIC4uLnRoaXMuY29udGV4dCgpLFxuICAgICAgICByZXF1ZXN0T3JpZ2luOiByZXF1ZXN0Lm9yaWdpbixcbiAgICAgICAgY3JlZGVudGlhbE9yaWdpbixcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBsb2dnZXIuZGVidWcoXCJhcHBseWluZyBhdXRoZW50aWNhdGlvbiB0byBtYXRjaGluZyBvcmlnaW5cIiwge1xuICAgICAgLi4udGhpcy5jb250ZXh0KCksXG4gICAgICByZXF1ZXN0T3JpZ2luOiByZXF1ZXN0Lm9yaWdpbixcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5hdXRoZW50aWNhdGUobG9naW4pO1xuICB9XG5cbiAgZm9yY2VSZWZyZXNoVG9rZW4obG9naW4gPSB0cnVlKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiRGF0YWJyaWNrcyB0b2tlbiBmb3JjZSByZWZyZXNoIHJlcXVlc3RlZFwiLCB7IC4uLnRoaXMuY29udGV4dCgpLCBsb2dpbiB9KTtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0VG9rZW5cbiAgICAgID8gUHJvbWlzZS5yZXNvbHZlKHB1YmxpY1Rva2VuKHRoaXMucmVxdWVzdFRva2VuKSlcbiAgICAgIDogdGhpcy5yZXF1aXJlZENsaWVudCgpLmZvcmNlUmVmcmVzaChsb2dpbik7XG4gIH1cblxuICByZWZyZXNoUmVqZWN0ZWRUb2tlbihzdGFsZUFjY2Vzc1Rva2VuOiBzdHJpbmcsIGxvZ2luID0gdHJ1ZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcIkRhdGFicmlja3MgcmVqZWN0ZWQgdG9rZW4gcmVmcmVzaCByZXF1ZXN0ZWRcIiwge1xuICAgICAgLi4udGhpcy5jb250ZXh0KCksXG4gICAgICBsb2dpbixcbiAgICAgIHJlcXVlc3RUb2tlbjogQm9vbGVhbih0aGlzLnJlcXVlc3RUb2tlbiksXG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdFRva2VuXG4gICAgICA/IFByb21pc2UucmVzb2x2ZShwdWJsaWNUb2tlbih0aGlzLnJlcXVlc3RUb2tlbikpXG4gICAgICA6IHRoaXMucmVxdWlyZWRDbGllbnQoKS5yZWZyZXNoUmVqZWN0ZWRUb2tlbihzdGFsZUFjY2Vzc1Rva2VuLCBsb2dpbik7XG4gIH1cblxuICBsb2dvdXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiRGF0YWJyaWNrcyBsb2dvdXQgcmVxdWVzdGVkXCIsIHRoaXMuY29udGV4dCgpKTtcbiAgICByZXR1cm4gdGhpcy5jbGllbnQ/LmxvZ291dCgpID8/IFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgc3RhdHVzKCk6IERhdGFicmlja3NBdXRoU3RhdHVzIHtcbiAgICByZXR1cm4ge1xuICAgICAgcHJvZmlsZTogdGhpcy5wcm9maWxlVmFsdWUubmFtZSxcbiAgICAgIGhvc3Q6IHRoaXMucHJvZmlsZVZhbHVlLmhvc3QsXG4gICAgICBzdG9yYWdlOiB0aGlzLnN0b3JhZ2VWYWx1ZSxcbiAgICB9O1xuICB9XG5cbiAgcHJpbmNpcGFsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZVZhbHVlLnByaW5jaXBhbDtcbiAgfVxuXG4gIHdvcmtzcGFjZUlkKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucHJvZmlsZVZhbHVlLndvcmtzcGFjZUlkO1xuICB9XG5cbiAgYXV0aEtpbmQoKTogQXV0aEtpbmQge1xuICAgIHJldHVybiB0aGlzLnByb2ZpbGVWYWx1ZS5hdXRoS2luZDtcbiAgfVxuXG4gIHByb2ZpbGUobmFtZT86IHN0cmluZykge1xuICAgIGNvbnN0IHByb2ZpbGUgPVxuICAgICAgIW5hbWUgfHwgbmFtZSA9PT0gdGhpcy5wcm9maWxlVmFsdWUubmFtZVxuICAgICAgICA/IHRoaXMucHJvZmlsZVZhbHVlXG4gICAgICAgIDogcmVzb2x2ZURhdGFicmlja3NQcm9maWxlKHsgLi4udGhpcy5vcHRpb25zLCBwcm9maWxlOiBuYW1lIH0sIHRoaXMuZW52aXJvbm1lbnQpO1xuICAgIHJldHVybiBwcm9maWxlU3VtbWFyeShwcm9maWxlKTtcbiAgfVxuXG4gIGxpc3RQcm9maWxlcyhyZWZyZXNoID0gZmFsc2UpIHtcbiAgICByZXR1cm4gbGlzdERhdGFicmlja3NQcm9maWxlcyh0aGlzLm9wdGlvbnMuY29uZmlnRmlsZSwgcmVmcmVzaCwgdGhpcy5lbnZpcm9ubWVudCk7XG4gIH1cblxuICBwcml2YXRlIHJlcXVpcmVkQ2xpZW50KCk6IFRva2VuTGlmZWN5Y2xlIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50KSB0aHJvdyBuZXcgQXV0aEVycm9yKFwib2F1dGhcIiwgXCJBdXRoZW50aWNhdGlvbiBsaWZlY3ljbGUgaXMgbm90IGF2YWlsYWJsZVwiKTtcbiAgICByZXR1cm4gdGhpcy5jbGllbnQ7XG4gIH1cblxuICBwcml2YXRlIGNvbnRleHQoKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIHJldHVybiB7XG4gICAgICBwcm9maWxlOiB0aGlzLnByb2ZpbGVWYWx1ZS5uYW1lLFxuICAgICAgaG9zdDogdGhpcy5wcm9maWxlVmFsdWUuaG9zdCxcbiAgICAgIGF1dGhLaW5kOiB0aGlzLnByb2ZpbGVWYWx1ZS5hdXRoS2luZCxcbiAgICAgIHN0b3JhZ2U6IHRoaXMuc3RvcmFnZVZhbHVlLFxuICAgICAgaGFzV29ya3NwYWNlSWQ6IEJvb2xlYW4odGhpcy5wcm9maWxlVmFsdWUud29ya3NwYWNlSWQpLFxuICAgIH07XG4gIH1cbn1cblxuLyoqIENyZWF0ZSBhIERhdGFicmlja3MgYXV0aGVudGljYXRpb24gY2xpZW50LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1dGhDbGllbnQoXG4gIG9wdGlvbnM6IERhdGFicmlja3NBdXRoT3B0aW9ucyA9IHsgcHJlZmVyVXNlclRvTWFjaGluZTogdHJ1ZSB9LFxuICBzdG9yYWdlID0gU3RvcmFnZS5BdXRvLFxuICBkZXBlbmRlbmNpZXM6IERhdGFicmlja3NBdXRoRGVwZW5kZW5jaWVzID0ge30sXG4pOiBQcm9taXNlPEF1dGhDbGllbnQ+IHtcbiAgcmV0dXJuIGNyZWF0ZVBlcnNpc3RlbnRBdXRoKG9wdGlvbnMsIHN0b3JhZ2UsIGRlcGVuZGVuY2llcyk7XG59XG5cbi8qKiBSZXNvbHZlIGEgRGF0YWJyaWNrcyBwcm9maWxlIGFuZCBvcGVuIGJ1aWx0LWluIGNyZWRlbnRpYWwgc3RvcmFnZS4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVBlcnNpc3RlbnRBdXRoKFxuICBvcHRpb25zOiBEYXRhYnJpY2tzQXV0aE9wdGlvbnMsXG4gIHN0b3JhZ2U6IFN0b3JhZ2UsXG4gIGRlcGVuZGVuY2llczogRGF0YWJyaWNrc0F1dGhEZXBlbmRlbmNpZXMsXG4pOiBQcm9taXNlPFBlcnNpc3RlbnRBdXRoPiB7XG4gIGNvbnN0IGVudmlyb25tZW50ID0gZGVwZW5kZW5jaWVzLmVudmlyb25tZW50ID8/IHByb2Nlc3MuZW52O1xuICBjb25zdCBwcm9maWxlID0gcmVzb2x2ZURhdGFicmlja3NQcm9maWxlKG9wdGlvbnMsIGVudmlyb25tZW50KTtcbiAgY29uc3QgaW5BcHAgPVxuICAgIHByb2ZpbGUuYXV0aEtpbmQgPT09IEF1dGhLaW5kLkFwcE9uQmVoYWxmT2YgfHxcbiAgICBwcm9maWxlLmF1dGhLaW5kID09PSBBdXRoS2luZC5BcHBTZXJ2aWNlUHJpbmNpcGFsO1xuICBjb25zdCBiYWNrZW5kID0gc3RvcmFnZSA9PT0gU3RvcmFnZS5BdXRvID8gU3RvcmFnZS5NZW1vcnkgOiBzdG9yYWdlO1xuICBsb2dnZXIuZGVidWcoXCJjcmVhdGluZyBwZXJzaXN0ZW50IERhdGFicmlja3MgYXV0aFwiLCB7XG4gICAgcHJvZmlsZTogcHJvZmlsZS5uYW1lLFxuICAgIGhvc3Q6IHByb2ZpbGUuaG9zdCxcbiAgICBhdXRoS2luZDogcHJvZmlsZS5hdXRoS2luZCxcbiAgICByZXF1ZXN0ZWRTdG9yYWdlOiBzdG9yYWdlLFxuICAgIHJlc29sdmVkU3RvcmFnZTogYmFja2VuZCxcbiAgICBpbkFwcCxcbiAgfSk7XG4gIGNvbnN0IHN0b3JlID1cbiAgICBiYWNrZW5kID09PSBTdG9yYWdlLk1lbW9yeVxuICAgICAgPyBuZXcgTWVtb3J5Q3JlZGVudGlhbFN0b3JlKClcbiAgICAgIDogbmV3IEZpbGVDcmVkZW50aWFsU3RvcmUob3B0aW9ucy5jYWNoZURpciA/PyBqb2luKGhvbWVkaXIoKSwgXCIuZGF0YWJyaWNrc1wiKSk7XG4gIHJldHVybiBjcmVhdGVQZXJzaXN0ZW50QXV0aFdpdGhTdG9yYWdlKG9wdGlvbnMsIHN0b3JlLCBzdG9yYWdlLCBkZXBlbmRlbmNpZXMsIHByb2ZpbGUpO1xufVxuXG4vKiogUmVzb2x2ZSBhIERhdGFicmlja3MgcHJvZmlsZSB1c2luZyBjYWxsZXItb3duZWQgZ2VuZXJpYyBzdG9yYWdlLiAqL1xuYXN5bmMgZnVuY3Rpb24gY3JlYXRlUGVyc2lzdGVudEF1dGhXaXRoU3RvcmFnZShcbiAgb3B0aW9uczogRGF0YWJyaWNrc0F1dGhPcHRpb25zLFxuICBzdG9yZTogQ3JlZGVudGlhbFN0b3JlLFxuICBzdG9yYWdlID0gc3RvcmUubmFtZSgpID09PSBcIm1lbW9yeVwiID8gU3RvcmFnZS5NZW1vcnkgOiBTdG9yYWdlLkZpbGUsXG4gIGRlcGVuZGVuY2llczogRGF0YWJyaWNrc0F1dGhEZXBlbmRlbmNpZXMgPSB7fSxcbiAgcmVzb2x2ZWRQcm9maWxlPzogRGF0YWJyaWNrc1Byb2ZpbGUsXG4pOiBQcm9taXNlPFBlcnNpc3RlbnRBdXRoPiB7XG4gIGNvbnN0IHByb2ZpbGUgPVxuICAgIHJlc29sdmVkUHJvZmlsZSA/PyByZXNvbHZlRGF0YWJyaWNrc1Byb2ZpbGUob3B0aW9ucywgZGVwZW5kZW5jaWVzLmVudmlyb25tZW50ID8/IHByb2Nlc3MuZW52KTtcbiAgaWYgKHByb2ZpbGUuYXV0aEtpbmQgPT09IEF1dGhLaW5kLkFwcE9uQmVoYWxmT2YpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJjcmVhdGVkIHJlcXVlc3Qtc2NvcGVkIEFwcCBPQk8gYXV0aGVudGljYXRpb25cIiwge1xuICAgICAgcHJvZmlsZTogcHJvZmlsZS5uYW1lLFxuICAgICAgaG9zdDogcHJvZmlsZS5ob3N0LFxuICAgICAgaGFzV29ya3NwYWNlSWQ6IEJvb2xlYW4ocHJvZmlsZS53b3Jrc3BhY2VJZCksXG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBQZXJzaXN0ZW50QXV0aChcbiAgICAgIHByb2ZpbGUsXG4gICAgICBTdG9yYWdlLk1lbW9yeSxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBkZXBlbmRlbmNpZXMuZW52aXJvbm1lbnQgPz8gcHJvY2Vzcy5lbnYsXG4gICAgICB1bmRlZmluZWQsXG4gICAgICB7XG4gICAgICAgIGFjY2Vzc1Rva2VuOiBwcm9maWxlLmFjY2Vzc1Rva2VuISxcbiAgICAgICAgdG9rZW5UeXBlOiBcIkJlYXJlclwiLFxuICAgICAgICBzY29wZXM6IFsuLi5wcm9maWxlLnNjb3Blc10sXG4gICAgICB9LFxuICAgICk7XG4gIH1cbiAgY29uc3QgcHJvdmlkZXIgPSBhd2FpdCBwcm92aWRlckZvcihwcm9maWxlLCBvcHRpb25zLCBkZXBlbmRlbmNpZXMpO1xuICBjb25zdCBjbGllbnQgPSBuZXcgVG9rZW5MaWZlY3ljbGUoXG4gICAgcHJvZmlsZS5jYWNoZUtleSxcbiAgICBwcm92aWRlcixcbiAgICBzdG9yZSxcbiAgICBBdXRoT3B0aW9ucy5jcmVhdGUob3B0aW9ucy5hdXRoKSxcbiAgKTtcbiAgY29uc3QgcGVyc2lzdGVudCA9IG5ldyBQZXJzaXN0ZW50QXV0aChcbiAgICBwcm9maWxlLFxuICAgIHN0b3JhZ2UgPT09IFN0b3JhZ2UuQXV0byA/IHN0b3JhZ2VGcm9tTmFtZShzdG9yZS5uYW1lKCkpIDogc3RvcmFnZSxcbiAgICBvcHRpb25zLFxuICAgIGRlcGVuZGVuY2llcy5lbnZpcm9ubWVudCA/PyBwcm9jZXNzLmVudixcbiAgICBjbGllbnQsXG4gICk7XG4gIGxvZ2dlci5kZWJ1ZyhcImNyZWF0ZWQgcGVyc2lzdGVudCBhdXRoZW50aWNhdGlvbiBsaWZlY3ljbGVcIiwge1xuICAgIHByb2ZpbGU6IHByb2ZpbGUubmFtZSxcbiAgICBob3N0OiBwcm9maWxlLmhvc3QsXG4gICAgYXV0aEtpbmQ6IHByb2ZpbGUuYXV0aEtpbmQsXG4gICAgc3RvcmFnZTogcGVyc2lzdGVudC5zdGF0dXMoKS5zdG9yYWdlLFxuICB9KTtcbiAgcmV0dXJuIHBlcnNpc3RlbnQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHByb3ZpZGVyRm9yKFxuICBwcm9maWxlOiBEYXRhYnJpY2tzUHJvZmlsZSxcbiAgb3B0aW9uczogRGF0YWJyaWNrc0F1dGhPcHRpb25zLFxuICBkZXBlbmRlbmNpZXM6IERhdGFicmlja3NBdXRoRGVwZW5kZW5jaWVzLFxuKTogUHJvbWlzZTxUb2tlblByb3ZpZGVyPiB7XG4gIGNvbnN0IGVudmlyb25tZW50ID0gZGVwZW5kZW5jaWVzLmVudmlyb25tZW50ID8/IHByb2Nlc3MuZW52O1xuICBjb25zdCBpbkFwcCA9IGVudmlyb25tZW50VXRpbHMuaXNEYXRhYnJpY2tzQXBwRW52KHsgLi4uZW52aXJvbm1lbnQgfSk7XG4gIHN3aXRjaCAocHJvZmlsZS5hdXRoS2luZCkge1xuICAgIGNhc2UgQXV0aEtpbmQuVXNlclRvTWFjaGluZToge1xuICAgICAgY29uc3QgaW5zdGFsbCA9ICFpbkFwcCB8fCBvcHRpb25zLmluc3RhbGxDbGlJbkFwcCA9PT0gdHJ1ZTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcInNlbGVjdGVkIERhdGFicmlja3MgQ0xJIHByb3ZpZGVyXCIsIHtcbiAgICAgICAgcHJvZmlsZTogcHJvZmlsZS5uYW1lLFxuICAgICAgICBpbkFwcCxcbiAgICAgICAgaW5zdGFsbCxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG5ldyBEYXRhYnJpY2tzQ2xpUHJvdmlkZXIoXG4gICAgICAgIHByb2ZpbGUubmFtZSxcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBkZXBlbmRlbmNpZXMucmVzb2x2ZUNsaVxuICAgICAgICAgICAgPyBkZXBlbmRlbmNpZXMucmVzb2x2ZUNsaSh7IGluc3RhbGwgfSlcbiAgICAgICAgICAgIDogcmVzb2x2ZURhdGFicmlja3NDbGkoZW52aXJvbm1lbnQsIHsgaW5zdGFsbCB9KSxcbiAgICAgICAgY2xpRW52aXJvbm1lbnQocHJvZmlsZSwgcmVzb2x2ZUNvbmZpZ0ZpbGUob3B0aW9ucy5jb25maWdGaWxlLCBlbnZpcm9ubWVudCkpLFxuICAgICAgKTtcbiAgICB9XG4gICAgY2FzZSBBdXRoS2luZC5QZXJzb25hbEFjY2Vzc1Rva2VuOlxuICAgICAgbG9nZ2VyLmRlYnVnKFwic2VsZWN0ZWQgcGVyc29uYWwgYWNjZXNzIHRva2VuIHByb3ZpZGVyXCIsIHsgcHJvZmlsZTogcHJvZmlsZS5uYW1lIH0pO1xuICAgICAgcmV0dXJuIG5ldyBEYXRhYnJpY2tzUGVyc29uYWxBY2Nlc3NUb2tlblByb3ZpZGVyKHByb2ZpbGUuYWNjZXNzVG9rZW4hKTtcbiAgICBjYXNlIEF1dGhLaW5kLk1hY2hpbmVUb01hY2hpbmU6XG4gICAgY2FzZSBBdXRoS2luZC5BcHBTZXJ2aWNlUHJpbmNpcGFsOiB7XG4gICAgICBsb2dnZXIuZGVidWcoXCJzZWxlY3RlZCBzZXJ2aWNlLXByaW5jaXBhbCBwcm92aWRlclwiLCB7XG4gICAgICAgIHByb2ZpbGU6IHByb2ZpbGUubmFtZSxcbiAgICAgICAgYXV0aEtpbmQ6IHByb2ZpbGUuYXV0aEtpbmQsXG4gICAgICAgIHRhcmdldDogcHJvZmlsZS50YXJnZXQsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGVuZHBvaW50cyA9IGF3YWl0IHJlc29sdmVPQXV0aEVuZHBvaW50cyhwcm9maWxlLCBkZXBlbmRlbmNpZXMuZmV0Y2gpO1xuICAgICAgcmV0dXJuIG5ldyBEYXRhYnJpY2tzU2VydmljZVByaW5jaXBhbFByb3ZpZGVyKHtcbiAgICAgICAgdG9rZW5FbmRwb2ludDogZW5kcG9pbnRzLnRva2VuRW5kcG9pbnQsXG4gICAgICAgIGNsaWVudElkOiBwcm9maWxlLmNsaWVudElkLFxuICAgICAgICBjbGllbnRTZWNyZXQ6IHByb2ZpbGUuY2xpZW50U2VjcmV0ISxcbiAgICAgICAgc2NvcGVzOiBtYWNoaW5lU2NvcGVzKHByb2ZpbGUuc2NvcGVzKSxcbiAgICAgICAgLi4uKHByb2ZpbGUuZ3JvdXBJZCA/IHsgZ3JvdXBJZDogcHJvZmlsZS5ncm91cElkIH0gOiB7fSksXG4gICAgICAgIGFsbG93SW5zZWN1cmVSZXF1ZXN0czogaXNMb29wYmFja0h0dHAocHJvZmlsZS5ob3N0KSxcbiAgICAgICAgZmV0Y2g6IGRlcGVuZGVuY2llcy5mZXRjaCxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjYXNlIEF1dGhLaW5kLkFwcE9uQmVoYWxmT2Y6XG4gICAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIFwiQXBwIE9CTyB0b2tlbnMgZG8gbm90IHVzZSBhIHBlcnNpc3RlbnQgcHJvdmlkZXJcIik7XG4gIH1cbn1cblxuaW50ZXJmYWNlIEF1dGhvcml6YXRpb25TZXJ2ZXIge1xuICB0b2tlbkVuZHBvaW50OiBzdHJpbmc7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVPQXV0aEVuZHBvaW50cyhcbiAgcHJvZmlsZTogRGF0YWJyaWNrc1Byb2ZpbGUsXG4gIGZldGNoZXI6IHR5cGVvZiBnbG9iYWxUaGlzLmZldGNoID0gZ2xvYmFsVGhpcy5mZXRjaCxcbik6IFByb21pc2U8QXV0aG9yaXphdGlvblNlcnZlcj4ge1xuICBjb25zdCBob3N0ID0gcHJvZmlsZS5ob3N0LnJlcGxhY2UoL1xcLyQvLCBcIlwiKTtcbiAgaWYgKHByb2ZpbGUudGFyZ2V0ID09PSBUYXJnZXRLaW5kLkFjY291bnQpIHtcbiAgICBpZiAoIXByb2ZpbGUuYWNjb3VudElkKSB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIFwiQWNjb3VudCB0YXJnZXQgcmVxdWlyZXMgYWNjb3VudF9pZFwiKTtcbiAgICBjb25zdCBlbmRwb2ludHMgPSB7XG4gICAgICB0b2tlbkVuZHBvaW50OiBgJHtob3N0fS9vaWRjL2FjY291bnRzLyR7cHJvZmlsZS5hY2NvdW50SWR9L3YxL3Rva2VuYCxcbiAgICB9O1xuICAgIGxvZ2dlci5kZWJ1ZyhcInJlc29sdmVkIGFjY291bnQgT0F1dGggZW5kcG9pbnRcIiwge1xuICAgICAgcHJvZmlsZTogcHJvZmlsZS5uYW1lLFxuICAgICAgdG9rZW5PcmlnaW46IG5ldyBVUkwoZW5kcG9pbnRzLnRva2VuRW5kcG9pbnQpLm9yaWdpbixcbiAgICB9KTtcbiAgICByZXR1cm4gZW5kcG9pbnRzO1xuICB9XG4gIGNvbnN0IGRpc2NvdmVyeSA9XG4gICAgcHJvZmlsZS50YXJnZXQgPT09IFRhcmdldEtpbmQuVW5pZmllZFxuICAgICAgPyBgJHtob3N0fS9vaWRjL2FjY291bnRzLyR7cmVxdWlyZWRBY2NvdW50SWQocHJvZmlsZSl9Ly53ZWxsLWtub3duL29hdXRoLWF1dGhvcml6YXRpb24tc2VydmVyYFxuICAgICAgOiBgJHtob3N0fS9vaWRjLy53ZWxsLWtub3duL29hdXRoLWF1dGhvcml6YXRpb24tc2VydmVyYDtcbiAgbG9nZ2VyLmRlYnVnKFwicmVxdWVzdGluZyBPQXV0aCBkaXNjb3ZlcnlcIiwge1xuICAgIHByb2ZpbGU6IHByb2ZpbGUubmFtZSxcbiAgICB0YXJnZXQ6IHByb2ZpbGUudGFyZ2V0LFxuICAgIGRpc2NvdmVyeSxcbiAgfSk7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hlcihkaXNjb3ZlcnksIHsgcmVkaXJlY3Q6IFwibWFudWFsXCIgfSk7XG4gIGxvZ2dlci5kZWJ1ZyhcInJlY2VpdmVkIE9BdXRoIGRpc2NvdmVyeSByZXNwb25zZVwiLCB7XG4gICAgcHJvZmlsZTogcHJvZmlsZS5uYW1lLFxuICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICB9KTtcbiAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gNDA0KVxuICAgIHRocm93IG5ldyBBdXRoRXJyb3IoXCJvYXV0aFwiLCBgT0F1dGggaXMgbm90IHN1cHBvcnRlZCBhdCAke2Rpc2NvdmVyeX1gKTtcbiAgaWYgKCFyZXNwb25zZS5vaylcbiAgICB0aHJvdyBuZXcgQXV0aEVycm9yKFwib2F1dGhcIiwgYE9BdXRoIGRpc2NvdmVyeSByZXR1cm5lZCBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xuICBjb25zdCB2YWx1ZSA9IChhd2FpdCByZXNwb25zZS5qc29uKCkpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBjb25zdCB0b2tlbkVuZHBvaW50ID0gc3RyaW5nVmFsdWUodmFsdWUudG9rZW5fZW5kcG9pbnQpO1xuICBpZiAoIXRva2VuRW5kcG9pbnQpIHRocm93IG5ldyBBdXRoRXJyb3IoXCJvYXV0aFwiLCBcIk9BdXRoIGRpc2NvdmVyeSByZXNwb25zZSBpcyBpbmNvbXBsZXRlXCIpO1xuICBsb2dnZXIuZGVidWcoXCJyZXNvbHZlZCBPQXV0aCB0b2tlbiBlbmRwb2ludFwiLCB7XG4gICAgcHJvZmlsZTogcHJvZmlsZS5uYW1lLFxuICAgIHRva2VuT3JpZ2luOiBuZXcgVVJMKHRva2VuRW5kcG9pbnQpLm9yaWdpbixcbiAgfSk7XG4gIHJldHVybiB7IHRva2VuRW5kcG9pbnQgfTtcbn1cblxuZnVuY3Rpb24gcmVxdWlyZWRBY2NvdW50SWQocHJvZmlsZTogRGF0YWJyaWNrc1Byb2ZpbGUpOiBzdHJpbmcge1xuICBpZiAoIXByb2ZpbGUuYWNjb3VudElkKSB0aHJvdyBuZXcgQXV0aEVycm9yKFwiY29uZmlnXCIsIFwiVW5pZmllZCB0YXJnZXQgcmVxdWlyZXMgYWNjb3VudF9pZFwiKTtcbiAgcmV0dXJuIHByb2ZpbGUuYWNjb3VudElkO1xufVxuXG5mdW5jdGlvbiBzdG9yYWdlRnJvbU5hbWUobmFtZTogc3RyaW5nKTogU3RvcmFnZSB7XG4gIHJldHVybiBuYW1lID09PSBcIm1lbW9yeVwiID8gU3RvcmFnZS5NZW1vcnkgOiBTdG9yYWdlLkZpbGU7XG59XG5cbmZ1bmN0aW9uIHByb2ZpbGVTdW1tYXJ5KHByb2ZpbGU6IERhdGFicmlja3NQcm9maWxlKSB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogcHJvZmlsZS5uYW1lLFxuICAgIGhvc3Q6IHByb2ZpbGUuaG9zdCxcbiAgICAuLi4ocHJvZmlsZS5hY2NvdW50SWQgPyB7IGFjY291bnRJZDogcHJvZmlsZS5hY2NvdW50SWQgfSA6IHt9KSxcbiAgICAuLi4ocHJvZmlsZS53b3Jrc3BhY2VJZCA/IHsgd29ya3NwYWNlSWQ6IHByb2ZpbGUud29ya3NwYWNlSWQgfSA6IHt9KSxcbiAgICB0YXJnZXQ6IHByb2ZpbGUudGFyZ2V0LFxuICAgIGF1dGhLaW5kOiBwcm9maWxlLmF1dGhLaW5kLFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc0xvb3BiYWNrSHR0cChob3N0OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgdXJsID0gbmV3IFVSTChob3N0KTtcbiAgcmV0dXJuIHVybC5wcm90b2NvbCA9PT0gXCJodHRwOlwiICYmIFtcIjEyNy4wLjAuMVwiLCBcImxvY2FsaG9zdFwiXS5pbmNsdWRlcyh1cmwuaG9zdG5hbWUpO1xufVxuXG5mdW5jdGlvbiBjbGlFbnZpcm9ubWVudChwcm9maWxlOiBEYXRhYnJpY2tzUHJvZmlsZSwgY29uZmlnRmlsZTogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIHJldHVybiB7XG4gICAgREFUQUJSSUNLU19DT05GSUdfRklMRTogY29uZmlnRmlsZSxcbiAgICBEQVRBQlJJQ0tTX0NPTkZJR19QUk9GSUxFOiBwcm9maWxlLm5hbWUsXG4gICAgREFUQUJSSUNLU19IT1NUOiBwcm9maWxlLmhvc3QsXG4gICAgLi4uKHByb2ZpbGUuYWNjb3VudElkID8geyBEQVRBQlJJQ0tTX0FDQ09VTlRfSUQ6IHByb2ZpbGUuYWNjb3VudElkIH0gOiB7fSksXG4gICAgLi4uKHByb2ZpbGUud29ya3NwYWNlSWQgPyB7IERBVEFCUklDS1NfV09SS1NQQUNFX0lEOiBwcm9maWxlLndvcmtzcGFjZUlkIH0gOiB7fSksXG4gICAgLi4uKHByb2ZpbGUuYXV0aEtpbmQgPT09IEF1dGhLaW5kLlBlcnNvbmFsQWNjZXNzVG9rZW5cbiAgICAgID8ge1xuICAgICAgICAgIERBVEFCUklDS1NfQVVUSF9UWVBFOiBcInBhdFwiLFxuICAgICAgICAgIERBVEFCUklDS1NfVE9LRU46IHByb2ZpbGUuYWNjZXNzVG9rZW4hLFxuICAgICAgICB9XG4gICAgICA6IHt9KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gc3RyaW5nVmFsdWUodmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlLnRyaW0oKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuIl19
@@ -0,0 +1,28 @@
1
+ import type { Token, TokenProvider } from "./types.ts";
2
+ /** Deferred Databricks CLI lookup used by U2M token acquisition. */
3
+ export type DatabricksCliResolver = () => Promise<string | undefined>;
4
+ /** Controls whether CLI resolution may install the pinned managed executable. */
5
+ export interface DatabricksCliResolutionOptions {
6
+ install?: boolean;
7
+ }
8
+ /** Resolve a compatible Databricks CLI, installing the pinned build asset when needed. */
9
+ export declare function resolveDatabricksCli(environment?: Readonly<Record<string, string | undefined>>, options?: DatabricksCliResolutionOptions): Promise<string | undefined>;
10
+ /** Clear cached CLI resolution, primarily after installation or environment changes. */
11
+ export declare function resetDatabricksCliResolution(): void;
12
+ /** Run interactive Databricks CLI login for one profile. */
13
+ export declare function databricksCliLogin(profile: string, timeoutMs: number, executable?: string, environment?: Record<string, string>): Promise<void>;
14
+ /** Request one profile token from the Databricks CLI. */
15
+ export declare function databricksCliToken(profile: string, forceRefresh?: boolean, executable?: string, environment?: Record<string, string>): Promise<Token>;
16
+ /** Provider that lazily delegates U2M credentials to the Databricks CLI. */
17
+ export declare class DatabricksCliProvider implements TokenProvider {
18
+ private readonly profile;
19
+ private readonly executableOrResolver;
20
+ private readonly environment;
21
+ private resolution?;
22
+ constructor(profile: string, executableOrResolver?: string | DatabricksCliResolver, environment?: Record<string, string>);
23
+ authenticate(_timeoutMs: number): Promise<Token>;
24
+ login(timeoutMs: number): Promise<Token>;
25
+ refresh(_token: Token): Promise<Token>;
26
+ canAuthenticateSilently(): boolean;
27
+ private resolveExecutable;
28
+ }