dataverse-msal-client
v0.2.0
Published
Authenticated DynamicsWebApi client factory (MSAL client credentials) and @odata.bind helpers for Microsoft Dataverse / Dynamics 365.
Downloads
288
Maintainers
Readme
dataverse-msal-client
Authenticated DynamicsWebApi client factory and @odata.bind URL helpers for Microsoft Dataverse / Dynamics 365.
Authenticates with Microsoft Entra ID using the client-credentials flow (service principal) via @azure/msal-node — suitable for unattended scripts, scheduled jobs, and integration tools.
Installation
pnpm add dataverse-msal-client @azure/msal-node dynamics-web-api@azure/msal-node and dynamics-web-api are peer dependencies — install them alongside.
Usage
import { createClient } from "dataverse-msal-client";
const dynamics = createClient({
serverUrl: process.env.SERVER_URL!, // e.g. https://contoso.crm.dynamics.com
tenantId: process.env.DYNAMICS_TENANT_ID!, // Entra tenant GUID
clientId: process.env.DYNAMICS_CLIENT_ID!,
clientSecret: process.env.DYNAMICS_CLIENT_SECRET!
});
const accounts = await dynamics.retrieveAll({
collection: "accounts",
select: ["accountid", "name"]
});createClient returns a fully-configured DynamicsWebApi instance. Token acquisition and refresh are handled automatically. If MSAL fails to acquire a token, createClient's onTokenRefresh callback throws with a clear error instead of silently returning null.
Options
| Option | Type | Description |
| ----------------- | ------------------- | ------------------------------------------------------------------ |
| serverUrl | string | Dataverse environment URL. |
| tenantId | string | Microsoft Entra ID tenant GUID. |
| clientId | string | App registration (client) ID. |
| clientSecret | string | App registration client secret. |
| apiVersion | string (optional) | Web API version. Defaults to "9.2". |
| webApiOverrides | Partial<Config> | Escape hatch: passed through to the DynamicsWebApi constructor. |
@odata.bind helpers
Pairs naturally with the *Bind interfaces generated by dataverse-types-gen:
import { bindRef, bindKey } from "dataverse-msal-client";
import type { ContactBind } from "./dataverse-gen";
await dynamics.update({
collection: "contacts",
key: contactId,
data: {
[bindKey("parentcustomerid_account")]: bindRef("accounts", accountId)
} satisfies ContactBind
});bindRef(entitySet, id)validates the GUID and returns"/<entitySet>(<id>)".bindKey(navProperty)returns a template-literal-typed key like"[email protected]".
License
MIT
