@edirect/dynamics 11.0.50 → 11.0.52

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.
package/dist/README.md CHANGED
@@ -1,68 +1,137 @@
1
1
  # @edirect/dynamics
2
2
 
3
- Dynamics integration module for Edirect applications. Provides services and utilities to interact with Microsoft Dynamics APIs, including authentication, data posting, and configuration.
3
+ Microsoft Dynamics 365 integration module for eDirect NestJS applications. Handles OAuth2 token acquisition (password grant and client credentials), automatic token refresh, and provides `get`, `post`, and `patch` methods for Dynamics API calls.
4
4
 
5
5
  ## Features
6
6
 
7
- - Handles OAuth2 authentication with Dynamics
8
- - Provides service for posting and retrieving data
9
- - Integrates with NestJS and Edirect config modules
7
+ - OAuth2 `password` grant and `client_credentials` grant support
8
+ - Automatic token caching and refresh (falls back to full re-auth on refresh failure)
9
+ - `get`, `post`, `patch` HTTP methods with automatic Bearer token injection
10
+ - `DYNAMICS_ENABLED` flag to safely disable all Dynamics calls without removing code
11
+ - NestJS module — integrates with `@edirect/config`
10
12
 
11
13
  ## Installation
12
14
 
13
- ```bash
15
+ ```sh
16
+ pnpm add @edirect/dynamics
17
+ # or
14
18
  npm install @edirect/dynamics
15
19
  ```
16
20
 
17
- ## Usage
21
+ ## Setup
18
22
 
19
- Add the following environment variables to your .env file:
23
+ ### 1. Set environment variables
20
24
 
21
25
  ```env
22
- DYNAMICS_TOKEN_URL="https://login.windows.net/YOUR_TENANT/oauth2/token"
23
- DYNAMICS_CLIENT_ID="YOUR_CLIENT_ID"
24
- DYNAMICS_USER_NAME="YOUR_USER_NAME"
25
- DYNAMICS_PASSWORD="YOUR_DYNAMICS_PASSWORD"
26
- DYNAMICS_RESOURCE="YOUR_RESOURCE_URL"
27
- DYNAMICS_ENABLED="true/false"
26
+ DYNAMICS_TOKEN_URL=https://login.windows.net/YOUR_TENANT_ID/oauth2/token
27
+ DYNAMICS_CLIENT_ID=your-client-id
28
+ DYNAMICS_CLIENT_SECRET=your-client-secret # required for client_credentials grant
29
+ DYNAMICS_USER_NAME=service@yourorg.onmicrosoft.com # required for password grant
30
+ DYNAMICS_PASSWORD=your-dynamics-password # required for password grant
31
+ DYNAMICS_RESOURCE=https://yourorg.crm.dynamics.com
32
+ DYNAMICS_ENABLED=true
28
33
  ```
29
34
 
30
- Import and register the module in your app:
35
+ ### 2. Register `DynamicsModule` in your AppModule
31
36
 
32
- ```typescript
37
+ ```ts
33
38
  import { Module } from '@nestjs/common';
34
39
  import { DynamicsModule } from '@edirect/dynamics';
35
40
 
36
41
  @Module({
37
42
  imports: [DynamicsModule],
38
- ...
39
43
  })
40
44
  export class AppModule {}
41
45
  ```
42
46
 
43
- Use the service in your controllers:
47
+ ### 3. Inject and use `DynamicsService`
44
48
 
45
- ```typescript
46
- import { Controller } from '@nestjs/common';
49
+ ```ts
50
+ import { Injectable } from '@nestjs/common';
47
51
  import { DynamicsService } from '@edirect/dynamics';
48
52
 
49
- @Controller('cats')
50
- export class CatsController {
51
- constructor(private readonly dynamicsService: DynamicsService) {}
53
+ @Injectable()
54
+ export class PolicySyncService {
55
+ constructor(private readonly dynamics: DynamicsService) {}
52
56
 
53
- postSomethingToDynamics(): Promise<any> {
54
- return this.dynamicsService.post('YOUR_URL', {
55
- YOUR_ATTRIBUTE: 'YOUR_VALUE',
56
- });
57
+ // POST using password grant (default)
58
+ async createContact(data: object): Promise<object | null> {
59
+ return this.dynamics.post(
60
+ 'https://yourorg.crm.dynamics.com/api/data/v9.2/contacts',
61
+ data,
62
+ );
63
+ }
64
+
65
+ // PATCH using password grant
66
+ async updateContact(id: string, data: object): Promise<object | null> {
67
+ return this.dynamics.patch(
68
+ `https://yourorg.crm.dynamics.com/api/data/v9.2/contacts(${id})`,
69
+ data,
70
+ );
71
+ }
72
+
73
+ // GET using client_credentials grant
74
+ async getAccounts(): Promise<object | null> {
75
+ return this.dynamics.get(
76
+ 'https://yourorg.crm.dynamics.com/api/data/v9.2/accounts',
77
+ {},
78
+ 'client_credentials',
79
+ );
57
80
  }
58
81
  }
59
82
  ```
60
83
 
84
+ ## API
85
+
86
+ ### `DynamicsService`
87
+
88
+ #### `get(url, options?, grantType?): Promise<object | null>`
89
+
90
+ Performs a GET request to the Dynamics API. Returns `null` if `DYNAMICS_ENABLED` is `false`.
91
+
92
+ | Parameter | Type | Default | Description |
93
+ | ----------- | ------------------------------------ | ------------ | -------------------------------- |
94
+ | `url` | `string` | — | Full Dynamics API endpoint URL |
95
+ | `options` | `AxiosRequestConfig` | — | Additional Axios request options |
96
+ | `grantType` | `'password' \| 'client_credentials'` | `'password'` | OAuth2 grant type to use |
97
+
98
+ #### `post(url, data, options?, grantType?): Promise<object | null>`
99
+
100
+ Performs a POST request. Returns `null` if `DYNAMICS_ENABLED` is `false`.
101
+
102
+ #### `patch(url, data, options?, grantType?): Promise<object | null>`
103
+
104
+ Performs a PATCH request. Returns `null` if `DYNAMICS_ENABLED` is `false`.
105
+
106
+ #### `getAccessToken(): Promise<ITokenSet>`
107
+
108
+ Acquires a token using the `password` grant. Automatically refreshes if expired.
109
+
110
+ #### `getAccessTokenByClientCredentials(): Promise<ITokenSet>`
111
+
112
+ Acquires a token using `client_credentials` grant.
113
+
114
+ #### `getRefreshToken(): Promise<ITokenSet>`
115
+
116
+ Refreshes the current token. Falls back to `getAccessToken()` on failure.
117
+
61
118
  ## Environment Variables
62
119
 
63
- - `DYNAMICS_TOKEN_URL`: OAuth2 token endpoint for Dynamics
64
- - `DYNAMICS_CLIENT_ID`: Client ID for authentication
65
- - `DYNAMICS_USER_NAME`: Username for Dynamics
66
- - `DYNAMICS_PASSWORD`: Password for Dynamics
67
- - `DYNAMICS_RESOURCE`: Resource URL for Dynamics API
68
- - `DYNAMICS_ENABLED`: Enable/disable Dynamics integration
120
+ | Variable | Description | Required For |
121
+ | ------------------------ | ----------------------------------------------------------------- | -------------------- |
122
+ | `DYNAMICS_TOKEN_URL` | Azure AD OAuth2 token endpoint | All grant types |
123
+ | `DYNAMICS_CLIENT_ID` | Application client ID | All grant types |
124
+ | `DYNAMICS_CLIENT_SECRET` | Client secret | `client_credentials` |
125
+ | `DYNAMICS_USER_NAME` | Service account username | `password` |
126
+ | `DYNAMICS_PASSWORD` | Service account password | `password` |
127
+ | `DYNAMICS_RESOURCE` | Dynamics CRM resource URL | All grant types |
128
+ | `DYNAMICS_ENABLED` | Set to `'true'` to enable; any other value disables all API calls | All |
129
+
130
+ ## Token Flow
131
+
132
+ ```
133
+ 1. First call → acquire token (password or client_credentials)
134
+ 2. Subsequent calls → if token not expired, use refresh_token grant
135
+ 3. If refresh fails → fall back to full re-authentication
136
+ 4. Token is cached in memory (service singleton)
137
+ ```
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edirect/dynamics",
3
- "version": "11.0.46",
3
+ "version": "11.0.52",
4
4
  "main": "./dist/src/index.js",
5
5
  "types": "./dist/src/index.d.ts",
6
6
  "exports": {
@@ -16,18 +16,18 @@
16
16
  "dist"
17
17
  ],
18
18
  "dependencies": {
19
- "@edirect/config": "^11.0.46",
19
+ "@edirect/config": "^11.0.52",
20
20
  "@nestjs/axios": "^4.0.1",
21
- "@nestjs/common": "^11.1.12",
22
- "axios": "^1.13.3",
21
+ "@nestjs/common": "^11.1.17",
22
+ "axios": "^1.13.6",
23
23
  "lodash": "^4.17.23",
24
24
  "tslib": "^2.8.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/express": "^5.0.6",
28
28
  "@types/jest": "30.0.0",
29
- "@types/lodash": "4.17.23",
30
- "@types/node": "^25.0.10"
29
+ "@types/lodash": "4.17.24",
30
+ "@types/node": "^25.4.0"
31
31
  },
32
32
  "type": "commonjs"
33
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edirect/dynamics",
3
- "version": "11.0.50",
3
+ "version": "11.0.52",
4
4
  "packageScope": "@edirect",
5
5
  "main": "./dist/src/index.js",
6
6
  "types": "./dist/src/index.d.ts",
@@ -18,11 +18,11 @@
18
18
  ],
19
19
  "dependencies": {
20
20
  "@nestjs/axios": "^4.0.1",
21
- "@nestjs/common": "^11.1.16",
21
+ "@nestjs/common": "^11.1.17",
22
22
  "axios": "^1.13.6",
23
23
  "lodash": "^4.17.23",
24
24
  "tslib": "^2.8.1",
25
- "@edirect/config": "11.0.50"
25
+ "@edirect/config": "11.0.52"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/express": "^5.0.6",