From 88355a229157791e538203a57da4ab77a7b1bfe6 Mon Sep 17 00:00:00 2001 From: MarioCadenas Date: Fri, 9 Oct 2026 17:40:46 +0200 Subject: [PATCH] feat(shared): add a modular UC functions client to the workspace client Add buildFunctionsClient (@databricks/sdk-uc-functions 0.51.0) and a lazy `functions` accessor on the facade, so the CLI can probe a UC function by full name with getFunction instead of a raw request(). No callers migrated. Co-authored-by: Isaac Signed-off-by: MarioCadenas --- knip.json | 1 + packages/appkit/package.json | 1 + .../src/testing/mock-workspace-client.ts | 1 + packages/shared/package.json | 1 + .../shared/src/workspace-client/client.ts | 11 ++++++ .../shared/src/workspace-client/modular.ts | 17 ++++++++++ .../workspace-client/tests/modular.test.ts | 34 +++++++++++++++++++ packages/shared/src/workspace-client/types.ts | 4 +++ pnpm-lock.yaml | 19 +++++++++++ 9 files changed, 89 insertions(+) diff --git a/knip.json b/knip.json index 02c3b30ac..7097761d3 100644 --- a/knip.json +++ b/knip.json @@ -15,6 +15,7 @@ "@databricks/sdk-experimental", "@databricks/sdk-files", "@databricks/sdk-genie", + "@databricks/sdk-uc-functions", "@databricks/sdk-jobs", "@databricks/sdk-postgres", "@databricks/sdk-modelserving", diff --git a/packages/appkit/package.json b/packages/appkit/package.json index a724e5eb5..902993f70 100644 --- a/packages/appkit/package.json +++ b/packages/appkit/package.json @@ -76,6 +76,7 @@ "@databricks/sdk-experimental": "0.17.0", "@databricks/sdk-files": "0.52.0", "@databricks/sdk-genie": "0.54.0", + "@databricks/sdk-uc-functions": "0.51.0", "@databricks/sdk-jobs": "0.57.0", "@databricks/sdk-modelserving": "0.53.0", "@databricks/sdk-uc-tables": "0.52.0", diff --git a/packages/appkit/src/testing/mock-workspace-client.ts b/packages/appkit/src/testing/mock-workspace-client.ts index d6a921920..182907e15 100644 --- a/packages/appkit/src/testing/mock-workspace-client.ts +++ b/packages/appkit/src/testing/mock-workspace-client.ts @@ -73,6 +73,7 @@ const FACADE_SERVICES = [ "tables", "postgres", "volumes", + "functions", "statementExecution", "modelServing", "servingEndpoints", diff --git a/packages/shared/package.json b/packages/shared/package.json index 2e965936f..da07ee9c9 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -53,6 +53,7 @@ "@databricks/sdk-experimental": "0.17.0", "@databricks/sdk-files": "0.52.0", "@databricks/sdk-genie": "0.54.0", + "@databricks/sdk-uc-functions": "0.51.0", "@databricks/sdk-jobs": "0.57.0", "@databricks/sdk-modelserving": "0.53.0", "@databricks/sdk-uc-tables": "0.52.0", diff --git a/packages/shared/src/workspace-client/client.ts b/packages/shared/src/workspace-client/client.ts index dd55d02b4..d2ace29c2 100644 --- a/packages/shared/src/workspace-client/client.ts +++ b/packages/shared/src/workspace-client/client.ts @@ -18,7 +18,9 @@ import { buildWarehousesClient, buildWorkspaceAuth, type ScimClient, + buildFunctionsClient, buildGenieClient, + type FunctionsClient, type GenieClient, buildJobsClient, type JobsClient, @@ -56,6 +58,7 @@ export class AppKitWorkspaceClient implements WorkspaceClient { #tables?: TablesClient; #postgres?: PostgresClient; #volumes?: VolumesClient; + #functions?: FunctionsClient; constructor(opts: WorkspaceClientOptions) { this.#opts = opts; @@ -117,6 +120,14 @@ export class AppKitWorkspaceClient implements WorkspaceClient { return this.#postgres; } + // Migrated to the modular SDK — built lazily, independent of the legacy client. + get functions(): FunctionsClient { + if (!this.#functions) { + this.#functions = buildFunctionsClient(this.#opts); + } + return this.#functions; + } + // Migrated to the modular SDK — built lazily, independent of the legacy client. get volumes(): VolumesClient { if (!this.#volumes) { diff --git a/packages/shared/src/workspace-client/modular.ts b/packages/shared/src/workspace-client/modular.ts index 995039ea7..e01318fcc 100644 --- a/packages/shared/src/workspace-client/modular.ts +++ b/packages/shared/src/workspace-client/modular.ts @@ -60,6 +60,7 @@ import type { ClientOptions } from "@databricks/sdk-options/client"; import type { PostgresClient } from "@databricks/sdk-postgres/v1"; import { ScimClient } from "@databricks/sdk-scim/v1"; import { StatementExecutionClient } from "@databricks/sdk-statementexecution/v1"; +import type { FunctionsClient } from "@databricks/sdk-uc-functions/v1"; import type { TablesClient } from "@databricks/sdk-uc-tables/v1"; import type { VolumesClient } from "@databricks/sdk-uc-volumes/v1"; import type { VectorSearchClient } from "@databricks/sdk-vectorsearch/v1"; @@ -649,6 +650,17 @@ export function buildVolumesClient( ); } +/** Build a modular Unity Catalog Functions client from wrapper options. */ +export function buildFunctionsClient( + opts: WorkspaceClientOptions, +): FunctionsClient { + return lazyClient( + () => + import("@databricks/sdk-uc-functions/v1").then((m) => m.FunctionsClient), + mapToClientOptions(opts), + ); +} + /** * Build a modular Lakebase Postgres (autoscaling: projects, branches, * endpoints) client from wrapper options. Distinct from the provisioned @@ -675,6 +687,7 @@ export type { ModelServingClient } from "@databricks/sdk-modelserving/v1"; export type { PostgresClient } from "@databricks/sdk-postgres/v1"; export type { ScimClient } from "@databricks/sdk-scim/v1"; export type { StatementExecutionClient } from "@databricks/sdk-statementexecution/v1"; +export type { FunctionsClient } from "@databricks/sdk-uc-functions/v1"; export type { TablesClient } from "@databricks/sdk-uc-tables/v1"; export type { VolumesClient } from "@databricks/sdk-uc-volumes/v1"; export type { VectorSearchClient } from "@databricks/sdk-vectorsearch/v1"; @@ -704,6 +717,10 @@ export type { GenieGetMessageQueryResultResponse, GenieMessage, } from "@databricks/sdk-genie/v1"; +export type { + FunctionInfo, + GetFunctionRequest, +} from "@databricks/sdk-uc-functions/v1"; export type { BaseRun, CancelRunRequest, diff --git a/packages/shared/src/workspace-client/tests/modular.test.ts b/packages/shared/src/workspace-client/tests/modular.test.ts index b54ca0a8c..b83bf24e1 100644 --- a/packages/shared/src/workspace-client/tests/modular.test.ts +++ b/packages/shared/src/workspace-client/tests/modular.test.ts @@ -67,6 +67,12 @@ vi.mock("@databricks/sdk-uc-volumes/v1", () => ({ return { opts, getVolume: async () => ({}) }; }), })); +vi.mock("@databricks/sdk-uc-functions/v1", () => ({ + FunctionsClient: vi.fn().mockImplementation((opts) => { + ctorOpts.push(opts); + return { opts, getFunction: async () => ({}) }; + }), +})); vi.mock("@databricks/sdk-postgres/v1", () => ({ PostgresClient: vi.fn().mockImplementation((opts) => { ctorOpts.push(opts); @@ -136,6 +142,7 @@ vi.mock("node:child_process", () => ({ import { ApiError } from "../errors"; import { + buildFunctionsClient, buildGenieClient, buildModelServingClient, buildVolumesClient, @@ -423,6 +430,33 @@ describe("modular mapToClientOptions (via buildWarehousesClient)", () => { expect(m2mOpts).toEqual([]); }); + test("functions maps host + SP M2M credentials onto the client", async () => { + process.env.DATABRICKS_CLIENT_ID = "sp-client-id"; + process.env.DATABRICKS_CLIENT_SECRET = "sp-secret"; + await buildFunctionsClient({ + host: "my-ws.cloud.databricks.com", + } as never).getFunction({} as never); + expect(ctorOpts[0].host).toBe("https://my-ws.cloud.databricks.com"); + expect(ctorOpts[0].credentials).toMatchObject({ + name: expect.any(Function), + }); + expect(m2mOpts).toHaveLength(1); + }); + + test("functions (asUser) uses the OBO token as PAT", async () => { + process.env.DATABRICKS_CLIENT_ID = "sp-client-id"; + process.env.DATABRICKS_CLIENT_SECRET = "sp-secret"; + await buildFunctionsClient({ + token: "user-token", + host: "https://x", + } as never).getFunction({} as never); + expect(ctorOpts[0].credentials).toMatchObject({ + kind: "pat", + token: "user-token", + }); + expect(m2mOpts).toEqual([]); + }); + test("postgres normalizes the host and passes SP M2M credentials", async () => { process.env.DATABRICKS_HOST = "envhost.cloud.databricks.com"; process.env.DATABRICKS_CLIENT_ID = "sp-client-id"; diff --git a/packages/shared/src/workspace-client/types.ts b/packages/shared/src/workspace-client/types.ts index 66dc9fbf1..8904cee2b 100644 --- a/packages/shared/src/workspace-client/types.ts +++ b/packages/shared/src/workspace-client/types.ts @@ -25,6 +25,7 @@ import type { FilesClient, TablesClient, VolumesClient, + FunctionsClient, VectorSearchClient, PostgresClient, } from "./modular"; @@ -73,6 +74,9 @@ export interface WorkspaceClient extends WorkspaceAuth { /** Unity Catalog Volumes (modular SDK). */ readonly volumes: VolumesClient; + /** Unity Catalog Functions (modular SDK). */ + readonly functions: FunctionsClient; + /** Statement Execution (modular SDK). */ readonly statementExecution: StatementExecutionClient; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f1fa623cd..5719dcd05 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -314,6 +314,9 @@ importers: '@databricks/sdk-statementexecution': specifier: 0.52.0 version: 0.52.0(patch_hash=9377a46b883b548d47116662bf73b159a4da51ec28b9ff1896a7e4a7841c240c) + '@databricks/sdk-uc-functions': + specifier: 0.51.0 + version: 0.51.0 '@databricks/sdk-uc-tables': specifier: 0.52.0 version: 0.52.0 @@ -674,6 +677,9 @@ importers: '@databricks/sdk-statementexecution': specifier: 0.52.0 version: 0.52.0(patch_hash=9377a46b883b548d47116662bf73b159a4da51ec28b9ff1896a7e4a7841c240c) + '@databricks/sdk-uc-functions': + specifier: 0.51.0 + version: 0.51.0 '@databricks/sdk-uc-tables': specifier: 0.52.0 version: 0.52.0 @@ -2099,6 +2105,10 @@ packages: resolution: {integrity: sha512-ymDGDW67PJ/0VujM89mUrE6mbbrabsKJP5LvPv8ZbgzPR0bm0DwXMcQzvS0XUt0UGITjV2gqbx5jQwP3ijtOmg==} engines: {node: '>=22.0.0'} + '@databricks/sdk-uc-functions@0.51.0': + resolution: {integrity: sha512-L5Qq3lB8OIiEOW4h8s9EJQ82VeBFiPnA0F5S2Fhqpd8L8bpx3rjG/e88ZYDtDg3bg4xunOdMQS1VWRxSF9IMxA==} + engines: {node: '>=22.0.0'} + '@databricks/sdk-uc-tables@0.52.0': resolution: {integrity: sha512-Dlqu3+O1krk6ogBX/uJGUDn1xMdt0gVMvrpmf16XkPelmgzwrbdWWtU2LU/zlcCBrb3XvhPPUpxVVHmyNS8Pjg==} engines: {node: '>=22.0.0'} @@ -14479,6 +14489,15 @@ snapshots: json-bigint: 1.0.0 zod: 4.3.6 + '@databricks/sdk-uc-functions@0.51.0': + dependencies: + '@databricks/sdk-auth': 0.51.0 + '@databricks/sdk-core': 0.51.0 + '@databricks/sdk-options': 0.51.0 + '@js-temporal/polyfill': 0.5.1 + json-bigint: 1.0.0 + zod: 4.3.6 + '@databricks/sdk-uc-tables@0.52.0': dependencies: '@databricks/sdk-auth': 0.51.0