@dbx-tools/auth 0.9.51 → 0.9.58

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.
@@ -5,7 +5,7 @@ export interface ListProfilesOptions {
5
5
  configFile?: string;
6
6
  refresh?: boolean;
7
7
  }
8
- /** Resolve one selected profile without exposing credentials. */
9
- export declare function resolveProfile(options?: DatabricksAuthOptions): DatabricksProfileSummary;
8
+ /** Resolve one configured profile without exposing credentials, or `null` when none exists. */
9
+ export declare function resolveProfile(options?: DatabricksAuthOptions): DatabricksProfileSummary | null;
10
10
  /** List configured profiles without exposing credentials. */
11
11
  export declare function listProfiles(options?: ListProfilesOptions): DatabricksProfileSummary[];
@@ -1,7 +1,26 @@
1
+ import { AuthError } from "./_errors.js";
1
2
  import { listDatabricksProfiles, resolveDatabricksProfile } from "./_profile-config.js";
2
- /** Resolve one selected profile without exposing credentials. */
3
+ /** Resolve one configured profile without exposing credentials, or `null` when none exists. */
3
4
  export function resolveProfile(options = {}) {
4
- return toProfileSummary(resolveDatabricksProfile(options));
5
+ const configured = listDatabricksProfiles(options.configFile);
6
+ if (configured.length === 0)
7
+ return null;
8
+ const environment = options.configFile
9
+ ? { DATABRICKS_CONFIG_FILE: options.configFile }
10
+ : process.env;
11
+ try {
12
+ const resolved = resolveDatabricksProfile(options, environment);
13
+ if (!resolved.selectedProfile ||
14
+ !configured.some(({ name }) => name === resolved.selectedProfile)) {
15
+ return null;
16
+ }
17
+ return toProfileSummary(resolved);
18
+ }
19
+ catch (error) {
20
+ if (error instanceof AuthError && error.kind === "config")
21
+ return null;
22
+ throw error;
23
+ }
5
24
  }
6
25
  /** List configured profiles without exposing credentials. */
7
26
  export function listProfiles(options = {}) {
@@ -18,4 +37,4 @@ function toProfileSummary(profile) {
18
37
  principal: profile.principal,
19
38
  };
20
39
  }
21
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcm9maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBVXhGLGlFQUFpRTtBQUNqRSxNQUFNLFVBQVUsY0FBYyxDQUFDLFVBQWlDLEVBQUU7SUFDaEUsT0FBTyxnQkFBZ0IsQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQzdELENBQUM7QUFFRCw2REFBNkQ7QUFDN0QsTUFBTSxVQUFVLFlBQVksQ0FBQyxVQUErQixFQUFFO0lBQzVELE9BQU8sc0JBQXNCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDckUsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsT0FBMEI7SUFDbEQsT0FBTztRQUNMLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtRQUNsQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlELEdBQUcsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNwRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07UUFDdEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1FBQzFCLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUztLQUM3QixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRGF0YWJyaWNrc1Byb2ZpbGVTdW1tYXJ5IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWF1dGgvcHJvZmlsZVwiO1xuXG5pbXBvcnQgeyBsaXN0RGF0YWJyaWNrc1Byb2ZpbGVzLCByZXNvbHZlRGF0YWJyaWNrc1Byb2ZpbGUgfSBmcm9tIFwiLi9fcHJvZmlsZS1jb25maWcudHNcIjtcbmltcG9ydCB0eXBlIHsgRGF0YWJyaWNrc1Byb2ZpbGUgfSBmcm9tIFwiLi9fdHlwZXMudHNcIjtcbmltcG9ydCB0eXBlIHsgRGF0YWJyaWNrc0F1dGhPcHRpb25zIH0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5cbi8qKiBQcm9maWxlLWxpc3RpbmcgY29udHJvbHMuICovXG5leHBvcnQgaW50ZXJmYWNlIExpc3RQcm9maWxlc09wdGlvbnMge1xuICBjb25maWdGaWxlPzogc3RyaW5nO1xuICByZWZyZXNoPzogYm9vbGVhbjtcbn1cblxuLyoqIFJlc29sdmUgb25lIHNlbGVjdGVkIHByb2ZpbGUgd2l0aG91dCBleHBvc2luZyBjcmVkZW50aWFscy4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlUHJvZmlsZShvcHRpb25zOiBEYXRhYnJpY2tzQXV0aE9wdGlvbnMgPSB7fSk6IERhdGFicmlja3NQcm9maWxlU3VtbWFyeSB7XG4gIHJldHVybiB0b1Byb2ZpbGVTdW1tYXJ5KHJlc29sdmVEYXRhYnJpY2tzUHJvZmlsZShvcHRpb25zKSk7XG59XG5cbi8qKiBMaXN0IGNvbmZpZ3VyZWQgcHJvZmlsZXMgd2l0aG91dCBleHBvc2luZyBjcmVkZW50aWFscy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsaXN0UHJvZmlsZXMob3B0aW9uczogTGlzdFByb2ZpbGVzT3B0aW9ucyA9IHt9KTogRGF0YWJyaWNrc1Byb2ZpbGVTdW1tYXJ5W10ge1xuICByZXR1cm4gbGlzdERhdGFicmlja3NQcm9maWxlcyhvcHRpb25zLmNvbmZpZ0ZpbGUsIG9wdGlvbnMucmVmcmVzaCk7XG59XG5cbmZ1bmN0aW9uIHRvUHJvZmlsZVN1bW1hcnkocHJvZmlsZTogRGF0YWJyaWNrc1Byb2ZpbGUpOiBEYXRhYnJpY2tzUHJvZmlsZVN1bW1hcnkge1xuICByZXR1cm4ge1xuICAgIG5hbWU6IHByb2ZpbGUubmFtZSxcbiAgICBob3N0OiBwcm9maWxlLmhvc3QsXG4gICAgLi4uKHByb2ZpbGUuYWNjb3VudElkID8geyBhY2NvdW50SWQ6IHByb2ZpbGUuYWNjb3VudElkIH0gOiB7fSksXG4gICAgLi4uKHByb2ZpbGUud29ya3NwYWNlSWQgPyB7IHdvcmtzcGFjZUlkOiBwcm9maWxlLndvcmtzcGFjZUlkIH0gOiB7fSksXG4gICAgdGFyZ2V0OiBwcm9maWxlLnRhcmdldCxcbiAgICBhdXRoVHlwZTogcHJvZmlsZS5hdXRoVHlwZSxcbiAgICBwcmluY2lwYWw6IHByb2ZpbGUucHJpbmNpcGFsLFxuICB9O1xufVxuIl19
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcm9maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLHdCQUF3QixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFVeEYsK0ZBQStGO0FBQy9GLE1BQU0sVUFBVSxjQUFjLENBQzVCLFVBQWlDLEVBQUU7SUFFbkMsTUFBTSxVQUFVLEdBQUcsc0JBQXNCLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlELElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDekMsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLFVBQVU7UUFDcEMsQ0FBQyxDQUFDLEVBQUUsc0JBQXNCLEVBQUUsT0FBTyxDQUFDLFVBQVUsRUFBRTtRQUNoRCxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQztJQUNoQixJQUFJLENBQUM7UUFDSCxNQUFNLFFBQVEsR0FBRyx3QkFBd0IsQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDaEUsSUFDRSxDQUFDLFFBQVEsQ0FBQyxlQUFlO1lBQ3pCLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUMsZUFBZSxDQUFDLEVBQ2pFLENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxPQUFPLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsSUFBSSxLQUFLLFlBQVksU0FBUyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssUUFBUTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3ZFLE1BQU0sS0FBSyxDQUFDO0lBQ2QsQ0FBQztBQUNILENBQUM7QUFFRCw2REFBNkQ7QUFDN0QsTUFBTSxVQUFVLFlBQVksQ0FBQyxVQUErQixFQUFFO0lBQzVELE9BQU8sc0JBQXNCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDckUsQ0FBQztBQUVELFNBQVMsZ0JBQWdCLENBQUMsT0FBMEI7SUFDbEQsT0FBTztRQUNMLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSTtRQUNsQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsR0FBRyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlELEdBQUcsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNwRSxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07UUFDdEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1FBQzFCLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUztLQUM3QixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgRGF0YWJyaWNrc1Byb2ZpbGVTdW1tYXJ5IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWF1dGgvcHJvZmlsZVwiO1xuXG5pbXBvcnQgeyBBdXRoRXJyb3IgfSBmcm9tIFwiLi9fZXJyb3JzLnRzXCI7XG5pbXBvcnQgeyBsaXN0RGF0YWJyaWNrc1Byb2ZpbGVzLCByZXNvbHZlRGF0YWJyaWNrc1Byb2ZpbGUgfSBmcm9tIFwiLi9fcHJvZmlsZS1jb25maWcudHNcIjtcbmltcG9ydCB0eXBlIHsgRGF0YWJyaWNrc1Byb2ZpbGUgfSBmcm9tIFwiLi9fdHlwZXMudHNcIjtcbmltcG9ydCB0eXBlIHsgRGF0YWJyaWNrc0F1dGhPcHRpb25zIH0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5cbi8qKiBQcm9maWxlLWxpc3RpbmcgY29udHJvbHMuICovXG5leHBvcnQgaW50ZXJmYWNlIExpc3RQcm9maWxlc09wdGlvbnMge1xuICBjb25maWdGaWxlPzogc3RyaW5nO1xuICByZWZyZXNoPzogYm9vbGVhbjtcbn1cblxuLyoqIFJlc29sdmUgb25lIGNvbmZpZ3VyZWQgcHJvZmlsZSB3aXRob3V0IGV4cG9zaW5nIGNyZWRlbnRpYWxzLCBvciBgbnVsbGAgd2hlbiBub25lIGV4aXN0cy4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlUHJvZmlsZShcbiAgb3B0aW9uczogRGF0YWJyaWNrc0F1dGhPcHRpb25zID0ge30sXG4pOiBEYXRhYnJpY2tzUHJvZmlsZVN1bW1hcnkgfCBudWxsIHtcbiAgY29uc3QgY29uZmlndXJlZCA9IGxpc3REYXRhYnJpY2tzUHJvZmlsZXMob3B0aW9ucy5jb25maWdGaWxlKTtcbiAgaWYgKGNvbmZpZ3VyZWQubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgZW52aXJvbm1lbnQgPSBvcHRpb25zLmNvbmZpZ0ZpbGVcbiAgICA/IHsgREFUQUJSSUNLU19DT05GSUdfRklMRTogb3B0aW9ucy5jb25maWdGaWxlIH1cbiAgICA6IHByb2Nlc3MuZW52O1xuICB0cnkge1xuICAgIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZURhdGFicmlja3NQcm9maWxlKG9wdGlvbnMsIGVudmlyb25tZW50KTtcbiAgICBpZiAoXG4gICAgICAhcmVzb2x2ZWQuc2VsZWN0ZWRQcm9maWxlIHx8XG4gICAgICAhY29uZmlndXJlZC5zb21lKCh7IG5hbWUgfSkgPT4gbmFtZSA9PT0gcmVzb2x2ZWQuc2VsZWN0ZWRQcm9maWxlKVxuICAgICkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiB0b1Byb2ZpbGVTdW1tYXJ5KHJlc29sdmVkKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBBdXRoRXJyb3IgJiYgZXJyb3Iua2luZCA9PT0gXCJjb25maWdcIikgcmV0dXJuIG51bGw7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuLyoqIExpc3QgY29uZmlndXJlZCBwcm9maWxlcyB3aXRob3V0IGV4cG9zaW5nIGNyZWRlbnRpYWxzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RQcm9maWxlcyhvcHRpb25zOiBMaXN0UHJvZmlsZXNPcHRpb25zID0ge30pOiBEYXRhYnJpY2tzUHJvZmlsZVN1bW1hcnlbXSB7XG4gIHJldHVybiBsaXN0RGF0YWJyaWNrc1Byb2ZpbGVzKG9wdGlvbnMuY29uZmlnRmlsZSwgb3B0aW9ucy5yZWZyZXNoKTtcbn1cblxuZnVuY3Rpb24gdG9Qcm9maWxlU3VtbWFyeShwcm9maWxlOiBEYXRhYnJpY2tzUHJvZmlsZSk6IERhdGFicmlja3NQcm9maWxlU3VtbWFyeSB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogcHJvZmlsZS5uYW1lLFxuICAgIGhvc3Q6IHByb2ZpbGUuaG9zdCxcbiAgICAuLi4ocHJvZmlsZS5hY2NvdW50SWQgPyB7IGFjY291bnRJZDogcHJvZmlsZS5hY2NvdW50SWQgfSA6IHt9KSxcbiAgICAuLi4ocHJvZmlsZS53b3Jrc3BhY2VJZCA/IHsgd29ya3NwYWNlSWQ6IHByb2ZpbGUud29ya3NwYWNlSWQgfSA6IHt9KSxcbiAgICB0YXJnZXQ6IHByb2ZpbGUudGFyZ2V0LFxuICAgIGF1dGhUeXBlOiBwcm9maWxlLmF1dGhUeXBlLFxuICAgIHByaW5jaXBhbDogcHJvZmlsZS5wcmluY2lwYWwsXG4gIH07XG59XG4iXX0=
@@ -0,0 +1,21 @@
1
+ import type { AuthClient } from "./client.ts";
2
+ import { type DatabricksAuthOptions } from "./config.ts";
3
+ /** Python runtime authentication operations backed by one SDK WorkspaceClient. */
4
+ export interface DatabricksRuntimeAuthClient {
5
+ /** Resolved Databricks workspace URL. */
6
+ readonly host: string;
7
+ /** Resolved workspace identifier when the Python SDK provides one. */
8
+ readonly workspaceId?: string;
9
+ /** Resolved caller identifier when the Python SDK provides one. */
10
+ readonly principal?: string;
11
+ /** Return the Python SDK's directly configured token, when present. */
12
+ token(): Promise<string | undefined>;
13
+ /** Return fresh authentication headers from the Python SDK. */
14
+ authenticate(): Promise<Record<string, string>>;
15
+ }
16
+ /**
17
+ * Return auth installed by the shared Python Node runtime, when available.
18
+ */
19
+ export declare function _databricksRuntimeAuthClient(): Promise<DatabricksRuntimeAuthClient | undefined>;
20
+ /** Create an auth facade over a Python runtime WorkspaceClient. */
21
+ export declare function createDatabricksRuntimeAuthClient(runtime: DatabricksRuntimeAuthClient, options: DatabricksAuthOptions): AuthClient;
@@ -0,0 +1,139 @@
1
+ import { RUNTIME_AUTH_TYPE } from "@dbx-tools/shared-auth/client";
2
+ import { TargetKind } from "@dbx-tools/shared-auth/config";
3
+ import { getAccessTokenPayload, getAccessTokenScopes } from "@dbx-tools/shared-core/token";
4
+ import { AuthError } from "./_errors.js";
5
+ import { TokenLifecycle } from "./_lifecycle.js";
6
+ import { normalizeHost } from "./_profile-config.js";
7
+ import { MemoryCredentialStore } from "./_storage.js";
8
+ import { AUTH_DEFAULTS, DEFAULT_ACCESS_TOKEN_HEADER, WORKSPACE_ID_HEADER, } from "./config.js";
9
+ const MINIMUM_RUNTIME_TOKEN_TTL_MS = 60_000;
10
+ const RUNTIME_PRINCIPAL = "runtime";
11
+ /**
12
+ * Return auth installed by the shared Python Node runtime, when available.
13
+ */
14
+ export async function _databricksRuntimeAuthClient() {
15
+ const runtime = globalThis[Symbol.for("@dbx-tools/node-runtime/runtime")];
16
+ return runtime?.databricksRuntimeAuthClient?.();
17
+ }
18
+ /** Create an auth facade over a Python runtime WorkspaceClient. */
19
+ export function createDatabricksRuntimeAuthClient(runtime, options) {
20
+ const lifecycleOptions = {
21
+ ...AUTH_DEFAULTS,
22
+ ...options.auth,
23
+ };
24
+ const provider = new DatabricksRuntimeTokenProvider(runtime, lifecycleOptions.refreshBufferMs);
25
+ const lifecycle = new TokenLifecycle(runtimeCacheKey(runtime), provider, new MemoryCredentialStore(), lifecycleOptions);
26
+ return new DefaultDatabricksRuntimeAuthClient(runtime, provider, lifecycle);
27
+ }
28
+ function runtimeCacheKey(runtime) {
29
+ return [
30
+ RUNTIME_AUTH_TYPE,
31
+ normalizeHost(runtime.host, RUNTIME_PRINCIPAL),
32
+ runtime.workspaceId ?? "",
33
+ runtime.principal ?? "",
34
+ ].join(":");
35
+ }
36
+ function normalizedHeaders(headers) {
37
+ return Object.fromEntries(Object.entries(headers).map(([name, value]) => [name.toLowerCase(), value]));
38
+ }
39
+ function runtimeToken(headers, refreshBufferMs, configuredToken) {
40
+ const authorization = headers[DEFAULT_ACCESS_TOKEN_HEADER];
41
+ const match = authorization?.trim().match(/^(\S+)\s+(.+)$/);
42
+ const accessToken = match?.[2]?.trim() || configuredToken?.trim();
43
+ if (!accessToken) {
44
+ throw new AuthError("oauth", "Databricks Python runtime authentication did not provide an access token");
45
+ }
46
+ const payload = getAccessTokenPayload(accessToken);
47
+ const jwtExpiry = typeof payload.exp === "number" && Number.isFinite(payload.exp)
48
+ ? new Date(payload.exp * 1000).toISOString()
49
+ : undefined;
50
+ // Opaque runtime credentials still need a bounded Node cache. Reacquire them
51
+ // from the Python SDK after one refresh-buffer interval.
52
+ const expiry = jwtExpiry ??
53
+ new Date(Date.now() + Math.max(refreshBufferMs * 2, MINIMUM_RUNTIME_TOKEN_TTL_MS)).toISOString();
54
+ return {
55
+ accessToken,
56
+ tokenType: match?.[1] || "Bearer",
57
+ ...(expiry ? { expiry } : {}),
58
+ scopes: [...getAccessTokenScopes(accessToken)],
59
+ };
60
+ }
61
+ class DatabricksRuntimeTokenProvider {
62
+ runtime;
63
+ refreshBufferMs;
64
+ #accessToken;
65
+ #headers;
66
+ constructor(runtime, refreshBufferMs) {
67
+ this.runtime = runtime;
68
+ this.refreshBufferMs = refreshBufferMs;
69
+ }
70
+ authenticate() {
71
+ return this.acquire();
72
+ }
73
+ login() {
74
+ return this.acquire();
75
+ }
76
+ refresh() {
77
+ return this.acquire();
78
+ }
79
+ canAuthenticateSilently() {
80
+ return true;
81
+ }
82
+ headers(token) {
83
+ if (this.#accessToken === token.accessToken && this.#headers) {
84
+ return { ...this.#headers };
85
+ }
86
+ return {
87
+ [DEFAULT_ACCESS_TOKEN_HEADER]: `${token.tokenType} ${token.accessToken}`,
88
+ };
89
+ }
90
+ clear() {
91
+ this.#accessToken = undefined;
92
+ this.#headers = undefined;
93
+ }
94
+ async acquire() {
95
+ const headers = normalizedHeaders(await this.runtime.authenticate());
96
+ const token = runtimeToken(headers, this.refreshBufferMs, await this.runtime.token());
97
+ this.#accessToken = token.accessToken;
98
+ this.#headers = {
99
+ ...headers,
100
+ [DEFAULT_ACCESS_TOKEN_HEADER]: `${token.tokenType} ${token.accessToken}`,
101
+ };
102
+ return token;
103
+ }
104
+ }
105
+ class DefaultDatabricksRuntimeAuthClient {
106
+ provider;
107
+ lifecycle;
108
+ profile = undefined;
109
+ host;
110
+ accountId = undefined;
111
+ workspaceId;
112
+ target = TargetKind.Workspace;
113
+ authType = RUNTIME_AUTH_TYPE;
114
+ principal;
115
+ constructor(runtime, provider, lifecycle) {
116
+ this.provider = provider;
117
+ this.lifecycle = lifecycle;
118
+ this.host = normalizeHost(runtime.host, RUNTIME_PRINCIPAL);
119
+ this.workspaceId = runtime.workspaceId;
120
+ this.principal = runtime.principal || RUNTIME_PRINCIPAL;
121
+ }
122
+ token(options = {}) {
123
+ return options.refresh
124
+ ? this.lifecycle.forceRefresh(options.login ?? true)
125
+ : this.lifecycle.tokenWithLogin(options.login);
126
+ }
127
+ async headers(options = {}) {
128
+ const headers = this.provider.headers(await this.token(options));
129
+ if (this.workspaceId && headers[WORKSPACE_ID_HEADER] === undefined) {
130
+ headers[WORKSPACE_ID_HEADER] = this.workspaceId;
131
+ }
132
+ return headers;
133
+ }
134
+ async logout() {
135
+ await this.lifecycle.logout();
136
+ this.provider.clear();
137
+ }
138
+ }
139
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS1hdXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUtYXV0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLHFCQUFxQixFQUFFLG9CQUFvQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFFM0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUd0RCxPQUFPLEVBQ0wsYUFBYSxFQUViLDJCQUEyQixFQUMzQixtQkFBbUIsR0FDcEIsTUFBTSxhQUFhLENBQUM7QUFFckIsTUFBTSw0QkFBNEIsR0FBRyxNQUFNLENBQUM7QUFDNUMsTUFBTSxpQkFBaUIsR0FBRyxTQUFTLENBQUM7QUFvQnBDOztHQUVHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSw0QkFBNEI7SUFHaEQsTUFBTSxPQUFPLEdBQ1gsVUFHRCxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsaUNBQWlDLENBQUMsQ0FBQyxDQUFDO0lBQ2pELE9BQU8sT0FBTyxFQUFFLDJCQUEyQixFQUFFLEVBQUUsQ0FBQztBQUNsRCxDQUFDO0FBRUQsbUVBQW1FO0FBQ25FLE1BQU0sVUFBVSxpQ0FBaUMsQ0FDL0MsT0FBb0MsRUFDcEMsT0FBOEI7SUFFOUIsTUFBTSxnQkFBZ0IsR0FBRztRQUN2QixHQUFHLGFBQWE7UUFDaEIsR0FBRyxPQUFPLENBQUMsSUFBSTtLQUNoQixDQUFDO0lBQ0YsTUFBTSxRQUFRLEdBQUcsSUFBSSw4QkFB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QUksSUFBSSxDQUFDLFdBQVcsSUFBSSxPQUFPLENBQUMsbUJBQW1CLENBQUMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNuRSxPQUFPLENBQUMsbUJBQW1CLENBQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ2xELENBQUM7UUFDRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU07UUFDVixNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDOUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSVU5USU1FX0FVVEhfVFlQRSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1hdXRoL2NsaWVudFwiO1xuaW1wb3J0IHsgVGFyZ2V0S2luZCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1hdXRoL2NvbmZpZ1wiO1xuaW1wb3J0IHsgZ2V0QWNjZXNzVG9rZW5QYXlsb2FkLCBnZXRBY2Nlc3NUb2tlblNjb3BlcyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlL3Rva2VuXCI7XG5cbmltcG9ydCB7IEF1dGhFcnJvciB9IGZyb20gXCIuL19lcnJvcnMudHNcIjtcbmltcG9ydCB7IFRva2VuTGlmZWN5Y2xlIH0gZnJvbSBcIi4vX2xpZmVjeWNsZS50c1wiO1xuaW1wb3J0IHsgbm9ybWFsaXplSG9zdCB9IGZyb20gXCIuL19wcm9maWxlLWNvbmZpZy50c1wiO1xuaW1wb3J0IHsgTWVtb3J5Q3JlZGVudGlhbFN0b3JlIH0gZnJvbSBcIi4vX3N0b3JhZ2UudHNcIjtcbmltcG9ydCB0eXBlIHsgVG9rZW4sIFRva2VuUHJvdmlkZXIgfSBmcm9tIFwiLi9fdHlwZXMudHNcIjtcbmltcG9ydCB0eXBlIHsgQWNjZXNzVG9rZW4sIEF1dGhDbGllbnQsIFRva2VuT3B0aW9ucyB9IGZyb20gXCIuL2NsaWVudC50c1wiO1xuaW1wb3J0IHtcbiAgQVVUSF9ERUZBVUxUUyxcbiAgdHlwZSBEYXRhYnJpY2tzQXV0aE9wdGlvbnMsXG4gIERFRkFVTFRfQUNDRVNTX1RPS0VOX0hFQURFUixcbiAgV09SS1NQQUNFX0lEX0hFQURFUixcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5cbmNvbnN0IE1JTklNVU1fUlVOVElNRV9UT0tFTl9UVExfTVMgPSA2MF8wMDA7XG5jb25zdCBSVU5USU1FX1BSSU5DSVBBTCA9IFwicnVudGltZVwiO1xuXG4vKiogUHl0aG9uIHJ1bnRpbWUgYXV0aGVudGljYXRpb24gb3BlcmF0aW9ucyBiYWNrZWQgYnkgb25lIFNESyBXb3Jrc3BhY2VDbGllbnQuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFicmlja3NSdW50aW1lQXV0aENsaWVudCB7XG4gIC8qKiBSZXNvbHZlZCBEYXRhYnJpY2tzIHdvcmtzcGFjZSBVUkwuICovXG4gIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcbiAgLyoqIFJlc29sdmVkIHdvcmtzcGFjZSBpZGVudGlmaWVyIHdoZW4gdGhlIFB5dGhvbiBTREsgcHJvdmlkZXMgb25lLiAqL1xuICByZWFkb25seSB3b3Jrc3BhY2VJZD86IHN0cmluZztcbiAgLyoqIFJlc29sdmVkIGNhbGxlciBpZGVudGlmaWVyIHdoZW4gdGhlIFB5dGhvbiBTREsgcHJvdmlkZXMgb25lLiAqL1xuICByZWFkb25seSBwcmluY2lwYWw/OiBzdHJpbmc7XG4gIC8qKiBSZXR1cm4gdGhlIFB5dGhvbiBTREsncyBkaXJlY3RseSBjb25maWd1cmVkIHRva2VuLCB3aGVuIHByZXNlbnQuICovXG4gIHRva2VuKCk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPjtcbiAgLyoqIFJldHVybiBmcmVzaCBhdXRoZW50aWNhdGlvbiBoZWFkZXJzIGZyb20gdGhlIFB5dGhvbiBTREsuICovXG4gIGF1dGhlbnRpY2F0ZSgpOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+O1xufVxuXG5pbnRlcmZhY2UgUHl0aG9uTm9kZVJ1bnRpbWUge1xuICBkYXRhYnJpY2tzUnVudGltZUF1dGhDbGllbnQ/KCk6IFByb21pc2U8RGF0YWJyaWNrc1J1bnRpbWVBdXRoQ2xpZW50IHwgdW5kZWZpbmVkPjtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYXV0aCBpbnN0YWxsZWQgYnkgdGhlIHNoYXJlZCBQeXRob24gTm9kZSBydW50aW1lLCB3aGVuIGF2YWlsYWJsZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIF9kYXRhYnJpY2tzUnVudGltZUF1dGhDbGllbnQoKTogUHJvbWlzZTxcbiAgRGF0YWJyaWNrc1J1bnRpbWVBdXRoQ2xpZW50IHwgdW5kZWZpbmVkXG4+IHtcbiAgY29uc3QgcnVudGltZSA9IChcbiAgICBnbG9iYWxUaGlzIGFzIHR5cGVvZiBnbG9iYWxUaGlzICYge1xuICAgICAgW2tleTogc3ltYm9sXTogUHl0aG9uTm9kZVJ1bnRpbWUgfCB1bmRlZmluZWQ7XG4gICAgfVxuICApW1N5bWJvbC5mb3IoXCJAZGJ4LXRvb2xzL25vZGUtcnVudGltZS9ydW50aW1lXCIpXTtcbiAgcmV0dXJuIHJ1bnRpbWU/LmRhdGFicmlja3NSdW50aW1lQXV0aENsaWVudD8uKCk7XG59XG5cbi8qKiBDcmVhdGUgYW4gYXV0aCBmYWNhZGUgb3ZlciBhIFB5dGhvbiBydW50aW1lIFdvcmtzcGFjZUNsaWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEYXRhYnJpY2tzUnVudGltZUF1dGhDbGllbnQoXG4gIHJ1bnRpbWU6IERhdGFicmlja3NSdW50aW1lQXV0aENsaWVudCxcbiAgb3B0aW9uczogRGF0YWJyaWNrc0F1dGhPcHRpb25zLFxuKTogQXV0aENsaWVudCB7XG4gIGNvbnN0IGxpZmVjeWNsZU9wdGlvbnMgPSB7XG4gICAgLi4uQVVUSF9ERUZBVUxUUyxcbiAgICAuLi5vcHRpb25zLmF1dGgsXG4gIH07XG4gIGNvbnN0IHByb3ZpZGVyID0gbmV3IERhdGFicmlja3NSdW50aW1lVG9rZW5Qcm92aWRlcihydW50aW1lLCBsaWZlY3ljbGVPcHRpb25zLnJlZnJlc2hCdWZmZXJNcyk7XG4gIGNvbnN0IGxpZmVjeWNsZSA9IG5ldyBUb2tlbkxpZmVjeWNsZShcbiAgICBydW50aW1lQ2FjaGVLZXkocnVudGltZSksXG4gICAgcHJvdmlkZXIsXG4gICAgbmV3IE1lbW9yeUNyZWRlbnRpYWxTdG9yZSgpLFxuICAgIGxpZmVjeWNsZU9wdGlvbnMsXG4gICk7XG4gIHJldHVybiBuZXcgRGVmYXVsdERhdGFicmlja3NSdW50aW1lQXV0aENsaWVudChydW50aW1lLCBwcm92aWRlciwgbGlmZWN5Y2xlKTtcbn1cblxuZnVuY3Rpb24gcnVudGltZUNhY2hlS2V5KHJ1bnRpbWU6IERhdGFicmlja3NSdW50aW1lQXV0aENsaWVudCk6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgUlVOVElNRV9BVVRIX1RZUEUsXG4gICAgbm9ybWFsaXplSG9zdChydW50aW1lLmhvc3QsIFJVTlRJTUVfUFJJTkNJUEFMKSxcbiAgICBydW50aW1lLndvcmtzcGFjZUlkID8/IFwiXCIsXG4gICAgcnVudGltZS5wcmluY2lwYWwgPz8gXCJcIixcbiAgXS5qb2luKFwiOlwiKTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplZEhlYWRlcnMoaGVhZGVyczogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICBPYmplY3QuZW50cmllcyhoZWFkZXJzKS5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+IFtuYW1lLnRvTG93ZXJDYXNlKCksIHZhbHVlXSksXG4gICk7XG59XG5cbmZ1bmN0aW9uIHJ1bnRpbWVUb2tlbihcbiAgaGVhZGVyczogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4sXG4gIHJlZnJlc2hCdWZmZXJNczogbnVtYmVyLFxuICBjb25maWd1cmVkVG9rZW4/OiBzdHJpbmcsXG4pOiBUb2tlbiB7XG4gIGNvbnN0IGF1dGhvcml6YXRpb24gPSBoZWFkZXJzW0RFRkFVTFRfQUNDRVNTX1RPS0VOX0hFQURFUl07XG4gIGNvbnN0IG1hdGNoID0gYXV0aG9yaXphdGlvbj8udHJpbSgpLm1hdGNoKC9eKFxcUyspXFxzKyguKykkLyk7XG4gIGNvbnN0IGFjY2Vzc1Rva2VuID0gbWF0Y2g/LlsyXT8udHJpbSgpIHx8IGNvbmZpZ3VyZWRUb2tlbj8udHJpbSgpO1xuICBpZiAoIWFjY2Vzc1Rva2VuKSB7XG4gICAgdGhyb3cgbmV3IEF1dGhFcnJvcihcbiAgICAgIFwib2F1dGhcIixcbiAgICAgIFwiRGF0YWJyaWNrcyBQeXRob24gcnVudGltZSBhdXRoZW50aWNhdGlvbiBkaWQgbm90IHByb3ZpZGUgYW4gYWNjZXNzIHRva2VuXCIsXG4gICAgKTtcbiAgfVxuICBjb25zdCBwYXlsb2FkID0gZ2V0QWNjZXNzVG9rZW5QYXlsb2FkKGFjY2Vzc1Rva2VuKTtcbiAgY29uc3Qgand0RXhwaXJ5ID1cbiAgICB0eXBlb2YgcGF5bG9hZC5leHAgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHBheWxvYWQuZXhwKVxuICAgICAgPyBuZXcgRGF0ZShwYXlsb2FkLmV4cCAqIDEwMDApLnRvSVNPU3RyaW5nKClcbiAgICAgIDogdW5kZWZpbmVkO1xuICAvLyBPcGFxdWUgcnVudGltZSBjcmVkZW50aWFscyBzdGlsbCBuZWVkIGEgYm91bmRlZCBOb2RlIGNhY2hlLiBSZWFjcXVpcmUgdGhlbVxuICAvLyBmcm9tIHRoZSBQeXRob24gU0RLIGFmdGVyIG9uZSByZWZyZXNoLWJ1ZmZlciBpbnRlcnZhbC5cbiAgY29uc3QgZXhwaXJ5ID1cbiAgICBqd3RFeHBpcnkgPz9cbiAgICBuZXcgRGF0ZShcbiAgICAgIERhdGUubm93KCkgKyBNYXRoLm1heChyZWZyZXNoQnVmZmVyTXMgKiAyLCBNSU5JTVVNX1JVTlRJTUVfVE9LRU5fVFRMX01TKSxcbiAgICApLnRvSVNPU3RyaW5nKCk7XG4gIHJldHVybiB7XG4gICAgYWNjZXNzVG9rZW4sXG4gICAgdG9rZW5UeXBlOiBtYXRjaD8uWzFdIHx8IFwiQmVhcmVyXCIsXG4gICAgLi4uKGV4cGlyeSA/IHsgZXhwaXJ5IH0gOiB7fSksXG4gICAgc2NvcGVzOiBbLi4uZ2V0QWNjZXNzVG9rZW5TY29wZXMoYWNjZXNzVG9rZW4pXSxcbiAgfTtcbn1cblxuY2xhc3MgRGF0YWJyaWNrc1J1bnRpbWVUb2tlblByb3ZpZGVyIGltcGxlbWVudHMgVG9rZW5Qcm92aWRlciB7XG4gICNhY2Nlc3NUb2tlbj86IHN0cmluZztcbiAgI2hlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcnVudGltZTogRGF0YWJyaWNrc1J1bnRpbWVBdXRoQ2xpZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVmcmVzaEJ1ZmZlck1zOiBudW1iZXIsXG4gICkge31cblxuICBhdXRoZW50aWNhdGUoKTogUHJvbWlzZTxUb2tlbj4ge1xuICAgIHJldHVybiB0aGlzLmFjcXVpcmUoKTtcbiAgfVxuXG4gIGxvZ2luKCk6IFByb21pc2U8VG9rZW4+IHtcbiAgICByZXR1cm4gdGhpcy5hY3F1aXJlKCk7XG4gIH1cblxuICByZWZyZXNoKCk6IFByb21pc2U8VG9rZW4+IHtcbiAgICByZXR1cm4gdGhpcy5hY3F1aXJlKCk7XG4gIH1cblxuICBjYW5BdXRoZW50aWNhdGVTaWxlbnRseSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGhlYWRlcnModG9rZW46IEFjY2Vzc1Rva2VuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgaWYgKHRoaXMuI2FjY2Vzc1Rva2VuID09PSB0b2tlbi5hY2Nlc3NUb2tlbiAmJiB0aGlzLiNoZWFkZXJzKSB7XG4gICAgICByZXR1cm4geyAuLi50aGlzLiNoZWFkZXJzIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBbREVGQVVMVF9BQ0NFU1NfVE9LRU5fSEVBREVSXTogYCR7dG9rZW4udG9rZW5UeXBlfSAke3Rva2VuLmFjY2Vzc1Rva2VufWAsXG4gICAgfTtcbiAgfVxuXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuI2FjY2Vzc1Rva2VuID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuI2hlYWRlcnMgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGFjcXVpcmUoKTogUHJvbWlzZTxUb2tlbj4ge1xuICAgIGNvbnN0IGhlYWRlcnMgPSBub3JtYWxpemVkSGVhZGVycyhhd2FpdCB0aGlzLnJ1bnRpbWUuYXV0aGVudGljYXRlKCkpO1xuICAgIGNvbnN0IHRva2VuID0gcnVudGltZVRva2VuKGhlYWRlcnMsIHRoaXMucmVmcmVzaEJ1ZmZlck1zLCBhd2FpdCB0aGlzLnJ1bnRpbWUudG9rZW4oKSk7XG4gICAgdGhpcy4jYWNjZXNzVG9rZW4gPSB0b2tlbi5hY2Nlc3NUb2tlbjtcbiAgICB0aGlzLiNoZWFkZXJzID0ge1xuICAgICAgLi4uaGVhZGVycyxcbiAgICAgIFtERUZBVUxUX0FDQ0VTU19UT0tFTl9IRUFERVJdOiBgJHt0b2tlbi50b2tlblR5cGV9ICR7dG9rZW4uYWNjZXNzVG9rZW59YCxcbiAgICB9O1xuICAgIHJldHVybiB0b2tlbjtcbiAgfVxufVxuXG5jbGFzcyBEZWZhdWx0RGF0YWJyaWNrc1J1bnRpbWVBdXRoQ2xpZW50IGltcGxlbWVudHMgQXV0aENsaWVudCB7XG4gIHJlYWRvbmx5IHByb2ZpbGUgPSB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IGhvc3Q6IHN0cmluZztcbiAgcmVhZG9ubHkgYWNjb3VudElkID0gdW5kZWZpbmVkO1xuICByZWFkb25seSB3b3Jrc3BhY2VJZD86IHN0cmluZztcbiAgcmVhZG9ubHkgdGFyZ2V0ID0gVGFyZ2V0S2luZC5Xb3Jrc3BhY2U7XG4gIHJlYWRvbmx5IGF1dGhUeXBlID0gUlVOVElNRV9BVVRIX1RZUEU7XG4gIHJlYWRvbmx5IHByaW5jaXBhbDogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJ1bnRpbWU6IERhdGFicmlja3NSdW50aW1lQXV0aENsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHByb3ZpZGVyOiBEYXRhYnJpY2tzUnVudGltZVRva2VuUHJvdmlkZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBsaWZlY3ljbGU6IFRva2VuTGlmZWN5Y2xlLFxuICApIHtcbiAgICB0aGlzLmhvc3QgPSBub3JtYWxpemVIb3N0KHJ1bnRpbWUuaG9zdCwgUlVOVElNRV9QUklOQ0lQQUwpO1xuICAgIHRoaXMud29ya3NwYWNlSWQgPSBydW50aW1lLndvcmtzcGFjZUlkO1xuICAgIHRoaXMucHJpbmNpcGFsID0gcnVudGltZS5wcmluY2lwYWwgfHwgUlVOVElNRV9QUklOQ0lQQUw7XG4gIH1cblxuICB0b2tlbihvcHRpb25zOiBUb2tlbk9wdGlvbnMgPSB7fSk6IFByb21pc2U8QWNjZXNzVG9rZW4+IHtcbiAgICByZXR1cm4gb3B0aW9ucy5yZWZyZXNoXG4gICAgICA/IHRoaXMubGlmZWN5Y2xlLmZvcmNlUmVmcmVzaChvcHRpb25zLmxvZ2luID8/IHRydWUpXG4gICAgICA6IHRoaXMubGlmZWN5Y2xlLnRva2VuV2l0aExvZ2luKG9wdGlvbnMubG9naW4pO1xuICB9XG5cbiAgYXN5bmMgaGVhZGVycyhvcHRpb25zOiBUb2tlbk9wdGlvbnMgPSB7fSk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4ge1xuICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLnByb3ZpZGVyLmhlYWRlcnMoYXdhaXQgdGhpcy50b2tlbihvcHRpb25zKSk7XG4gICAgaWYgKHRoaXMud29ya3NwYWNlSWQgJiYgaGVhZGVyc1tXT1JLU1BBQ0VfSURfSEVBREVSXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBoZWFkZXJzW1dPUktTUEFDRV9JRF9IRUFERVJdID0gdGhpcy53b3Jrc3BhY2VJZDtcbiAgICB9XG4gICAgcmV0dXJuIGhlYWRlcnM7XG4gIH1cblxuICBhc3luYyBsb2dvdXQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5saWZlY3ljbGUubG9nb3V0KCk7XG4gICAgdGhpcy5wcm92aWRlci5jbGVhcigpO1xuICB9XG59XG4iXX0=
@@ -1 +1 @@
1
- {"root":["../src/_databricks-cli.ts","../src/_errors.ts","../src/_lifecycle.ts","../src/_logging.ts","../src/_personal-access-token.ts","../src/_profile-config.ts","../src/_service-principal.ts","../src/_storage.ts","../src/_types.ts","../src/bindings.ts","../src/client.ts","../src/config.ts","../src/profile.ts","../index.ts"],"version":"5.9.3"}
1
+ {"root":["../src/_databricks-cli.ts","../src/_errors.ts","../src/_lifecycle.ts","../src/_logging.ts","../src/_personal-access-token.ts","../src/_profile-config.ts","../src/_service-principal.ts","../src/_storage.ts","../src/_types.ts","../src/bindings.ts","../src/client.ts","../src/config.ts","../src/profile.ts","../src/runtime-auth.ts","../index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -24,9 +24,9 @@
24
24
  "typescript": "^5.9.3"
25
25
  },
26
26
  "dependencies": {
27
- "@dbx-tools/core": "^0.9.51",
28
- "@dbx-tools/shared-auth": "^0.9.51",
29
- "@dbx-tools/shared-core": "^0.9.51",
27
+ "@dbx-tools/core": "^0.9.58",
28
+ "@dbx-tools/shared-auth": "^0.9.58",
29
+ "@dbx-tools/shared-core": "^0.9.58",
30
30
  "ini": "^6.0.0",
31
31
  "oauth4webapi": "^3.8.8",
32
32
  "zod": "4.3.6"
@@ -58,10 +58,14 @@
58
58
  "types": "./lib/src/profile.d.ts",
59
59
  "default": "./lib/src/profile.js"
60
60
  },
61
+ "./runtime-auth": {
62
+ "types": "./lib/src/runtime-auth.d.ts",
63
+ "default": "./lib/src/runtime-auth.js"
64
+ },
61
65
  "./package.json": "./package.json"
62
66
  }
63
67
  },
64
- "version": "0.9.51",
68
+ "version": "0.9.58",
65
69
  "types": "./lib/index.d.ts",
66
70
  "dbxToolsConfig": {
67
71
  "tags": [
@@ -90,6 +94,10 @@
90
94
  "types": "./lib/src/profile.d.ts",
91
95
  "default": "./lib/src/profile.js"
92
96
  },
97
+ "./runtime-auth": {
98
+ "types": "./lib/src/runtime-auth.d.ts",
99
+ "default": "./lib/src/runtime-auth.js"
100
+ },
93
101
  "./package.json": "./package.json"
94
102
  },
95
103
  "files": [
@@ -106,14 +106,29 @@ export function parseDatabricksConfig(source: string): IniConfig {
106
106
  if (!name.trim() || !object.isRecord(value)) {
107
107
  throw new AuthError("config", "Databricks configuration values must belong to a profile");
108
108
  }
109
- const section = new Map<string, string>();
110
- for (const [key, entry] of Object.entries(value)) {
111
- if (entry === undefined || entry === null) continue;
109
+ _appendConfigSections(config, [name.trim()], value);
110
+ }
111
+ return config;
112
+ }
113
+
114
+ function _appendConfigSections(
115
+ config: IniConfig,
116
+ path: readonly string[],
117
+ value: Record<string, unknown>,
118
+ ): void {
119
+ const section = new Map<string, string>();
120
+ let nested = false;
121
+ for (const [key, entry] of Object.entries(value)) {
122
+ if (object.isRecord(entry)) {
123
+ nested = true;
124
+ _appendConfigSections(config, [...path, key], entry);
125
+ } else if (entry !== undefined && entry !== null) {
112
126
  section.set(key.trim().toLowerCase(), String(entry).trim());
113
127
  }
114
- config.set(name.trim(), section);
115
128
  }
116
- return config;
129
+ if (section.size || !nested) {
130
+ config.set(path.join("."), section);
131
+ }
117
132
  }
118
133
 
119
134
  export function loadRawProfile(config: IniConfig | undefined, name: string): RawProfile {
@@ -366,19 +381,26 @@ export function resolveDatabricksProfile(
366
381
  environment: Environment = process.env,
367
382
  ): DatabricksProfile {
368
383
  const inApp = environmentUtils.isDatabricksAppEnv({ ...environment });
369
- const environmentProfile = stringUtils.trimToUndefined(environment.DATABRICKS_CONFIG_PROFILE);
370
- const explicitProfile = Boolean(
371
- stringUtils.trimToUndefined(options.profile) ?? environmentProfile,
384
+ const configPath = resolveConfigFile(options.configFile, environment);
385
+ const config = loadConfig(options.configFile, false, environment);
386
+ const optionProfile = stringUtils.trimToUndefined(options.profile);
387
+ const configuredEnvironmentProfile = stringUtils.trimToUndefined(
388
+ environment.DATABRICKS_CONFIG_PROFILE,
372
389
  );
373
- const requestToken = requestOboToken(options.requestHeaders, options.accessTokenHeader);
374
- const explicitAuthType =
375
- options.authType ??
376
- (!inApp && !explicitProfile ? parseAuthType(environment.DATABRICKS_AUTH_TYPE) : undefined);
390
+ const environmentProfile =
391
+ configuredEnvironmentProfile && config?.has(configuredEnvironmentProfile)
392
+ ? configuredEnvironmentProfile
393
+ : undefined;
377
394
  const appServicePrincipal = [
378
395
  environment.DATABRICKS_HOST,
379
396
  environment.DATABRICKS_CLIENT_ID,
380
397
  environment.DATABRICKS_CLIENT_SECRET,
381
398
  ].every((value) => Boolean(stringUtils.trimToUndefined(value)));
399
+ const explicitProfile = Boolean(optionProfile ?? environmentProfile);
400
+ const requestToken = requestOboToken(options.requestHeaders, options.accessTokenHeader);
401
+ const explicitAuthType =
402
+ options.authType ??
403
+ (!inApp && !explicitProfile ? parseAuthType(environment.DATABRICKS_AUTH_TYPE) : undefined);
382
404
  const selectedAuthType =
383
405
  !inApp || explicitProfile || explicitAuthType
384
406
  ? explicitAuthType
@@ -391,9 +413,7 @@ export function resolveDatabricksProfile(
391
413
  selectedAuthType === AuthType.AppOnBehalfOf ||
392
414
  selectedAuthType === AuthType.AppServicePrincipal;
393
415
  const ignoreAmbientCredentials = explicitProfile && !appAuth;
394
- const configPath = resolveConfigFile(options.configFile, environment);
395
- const config = loadConfig(options.configFile, false, environment);
396
- const requestedName = stringUtils.trimToUndefined(options.profile) ?? environmentProfile;
416
+ const requestedName = optionProfile ?? environmentProfile;
397
417
  const profileName = resolveProfileName(
398
418
  requestedName,
399
419
  explicitProfile,
@@ -410,12 +430,13 @@ export function resolveDatabricksProfile(
410
430
  ].some((value) => Boolean(stringUtils.trimToUndefined(value)));
411
431
  const selectedProfile =
412
432
  explicitProfile || (!ambientCredentials && config?.has(profileName)) ? profileName : undefined;
413
- const configured = loadRawProfile(config, profileName);
433
+ const configured = selectedProfile ? loadRawProfile(config, profileName) : {};
434
+ const credentialName = selectedProfile ?? "ambient";
414
435
  const ambient = (name: keyof NodeJS.ProcessEnv): string | undefined =>
415
436
  ignoreAmbientCredentials ? undefined : stringUtils.trimToUndefined(environment[name]);
416
437
  const host = normalizeHost(
417
438
  options.host ?? ambient("DATABRICKS_HOST") ?? configured.host,
418
- profileName,
439
+ credentialName,
419
440
  );
420
441
  const accountId =
421
442
  stringUtils.trimToUndefined(options.accountId) ??
@@ -448,7 +469,7 @@ export function resolveDatabricksProfile(
448
469
  authType === AuthType.DatabricksCli
449
470
  ? (clientIdValue ?? DEFAULT_CLIENT_ID)
450
471
  : authType === AuthType.OAuthM2M || authType === AuthType.AppServicePrincipal
451
- ? (clientIdValue ?? missing(profileName, "client_id"))
472
+ ? (clientIdValue ?? missing(credentialName, "client_id"))
452
473
  : (clientIdValue ?? "");
453
474
  const scopes = options.scopes?.length
454
475
  ? stringUtils.parseList(options.scopes)
@@ -461,9 +482,9 @@ export function resolveDatabricksProfile(
461
482
  const principal =
462
483
  authType === AuthType.OAuthM2M || authType === AuthType.AppServicePrincipal
463
484
  ? clientId
464
- : profileName;
485
+ : credentialName;
465
486
  const cacheKey = credentialCacheKey({
466
- name: profileName,
487
+ name: credentialName,
467
488
  host,
468
489
  accountId,
469
490
  workspaceId,
@@ -474,7 +495,7 @@ export function resolveDatabricksProfile(
474
495
  accessToken,
475
496
  });
476
497
  logger.debug("resolved Databricks profile", {
477
- profile: profileName,
498
+ profile: credentialName,
478
499
  host,
479
500
  authType,
480
501
  target,
@@ -488,7 +509,7 @@ export function resolveDatabricksProfile(
488
509
  configPath,
489
510
  });
490
511
  return {
491
- name: profileName,
512
+ name: credentialName,
492
513
  ...(selectedProfile ? { selectedProfile } : {}),
493
514
  host,
494
515
  ...(accountId ? { accountId } : {}),
package/src/client.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  DEFAULT_ACCESS_TOKEN_HEADER,
16
16
  WORKSPACE_ID_HEADER,
17
17
  } from "./config.ts";
18
+ import { _databricksRuntimeAuthClient, createDatabricksRuntimeAuthClient } from "./runtime-auth.ts";
18
19
 
19
20
  const logger = authLogger("databricks");
20
21
 
@@ -126,6 +127,16 @@ export async function createAuthClient(
126
127
  options: DatabricksAuthOptions = {},
127
128
  dependencies: DatabricksAuthDependencies = {},
128
129
  ): Promise<AuthClient> {
130
+ if (usesDefaultCredentialSource(options)) {
131
+ const runtime = await _databricksRuntimeAuthClient();
132
+ if (runtime) {
133
+ logger.debug("selected Databricks Python runtime authentication", {
134
+ host: runtime.host,
135
+ hasWorkspaceId: Boolean(runtime.workspaceId),
136
+ });
137
+ return createDatabricksRuntimeAuthClient(runtime, options);
138
+ }
139
+ }
129
140
  return createResolvedAuth(options, dependencies);
130
141
  }
131
142
 
@@ -289,3 +300,7 @@ function cliEnvironment(profile: DatabricksProfile, configFile: string): Record<
289
300
  function stringValue(value: unknown): string | undefined {
290
301
  return typeof value === "string" && value.trim() ? value : undefined;
291
302
  }
303
+
304
+ function usesDefaultCredentialSource(options: DatabricksAuthOptions): boolean {
305
+ return Object.values(options).every((value) => value === undefined);
306
+ }
package/src/profile.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { DatabricksProfileSummary } from "@dbx-tools/shared-auth/profile";
2
2
 
3
+ import { AuthError } from "./_errors.ts";
3
4
  import { listDatabricksProfiles, resolveDatabricksProfile } from "./_profile-config.ts";
4
5
  import type { DatabricksProfile } from "./_types.ts";
5
6
  import type { DatabricksAuthOptions } from "./config.ts";
@@ -10,9 +11,28 @@ export interface ListProfilesOptions {
10
11
  refresh?: boolean;
11
12
  }
12
13
 
13
- /** Resolve one selected profile without exposing credentials. */
14
- export function resolveProfile(options: DatabricksAuthOptions = {}): DatabricksProfileSummary {
15
- return toProfileSummary(resolveDatabricksProfile(options));
14
+ /** Resolve one configured profile without exposing credentials, or `null` when none exists. */
15
+ export function resolveProfile(
16
+ options: DatabricksAuthOptions = {},
17
+ ): DatabricksProfileSummary | null {
18
+ const configured = listDatabricksProfiles(options.configFile);
19
+ if (configured.length === 0) return null;
20
+ const environment = options.configFile
21
+ ? { DATABRICKS_CONFIG_FILE: options.configFile }
22
+ : process.env;
23
+ try {
24
+ const resolved = resolveDatabricksProfile(options, environment);
25
+ if (
26
+ !resolved.selectedProfile ||
27
+ !configured.some(({ name }) => name === resolved.selectedProfile)
28
+ ) {
29
+ return null;
30
+ }
31
+ return toProfileSummary(resolved);
32
+ } catch (error) {
33
+ if (error instanceof AuthError && error.kind === "config") return null;
34
+ throw error;
35
+ }
16
36
  }
17
37
 
18
38
  /** List configured profiles without exposing credentials. */