UNPKG

n8n-nodes-dataverse

Version:

n8n community node for communicating to dataverse

313 lines 14.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.dataverseAuth = void 0; const axios_1 = __importDefault(require("axios")); class dataverseAuth { constructor() { this.accessToken = null; this.tokenExpiry = 0; this.scope = null; this.credentials = null; this.axiosInstance = null; this.name = 'dataverseAuth'; this.displayName = 'Dataverse Auth'; this.properties = [ { displayName: 'Authentication Method', name: 'authenticationMethod', type: 'options', options: [ { name: 'Client Credentials', value: 'clientCredentials', } ], default: 'clientCredentials', }, { displayName: 'Tenant ID', name: 'tenantId', type: 'string', default: '', description: 'The Azure Active Directory tenant ID', }, { displayName: 'Client ID', name: 'clientId', type: 'string', default: '', description: 'The application (client) ID registered in Azure AD', }, { displayName: 'Client Secret', name: 'clientSecret', type: 'string', typeOptions: { password: true }, default: '', description: 'The client secret generated for the application in Azure AD', }, { displayName: 'Scope', name: 'scope', type: 'string', default: 'https://<your-org-name>.crm4.dynamics.com', description: 'The URL of your Dataverse environment (e.g., https://<your-org-name>.crm4.dynamics.com)', }, ]; } static getCachedTables() { return dataverseAuth.cachedTables; } static setCachedTables(tables) { dataverseAuth.cachedTables = tables; } static getCachedEntityColumns(entityName) { return dataverseAuth.cachedEntityColumns[entityName]; } static setCachedEntityColumns(entityName, options) { dataverseAuth.cachedEntityColumns[entityName] = options; } updateAxiosInstance() { if (!this.scope || !this.accessToken) return; if (!this.axiosInstance) { this.axiosInstance = axios_1.default.create({ baseURL: this.scope, headers: { Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json', 'OData-MaxPageSize': '5000', }, }); } else { this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${this.accessToken}`; } } async authenticate(credentials, requestOptions) { this.credentials = credentials; const { tenantId, clientId, clientSecret, scope } = credentials; this.scope = scope; if (this.accessToken && Date.now() < this.tokenExpiry) { this.updateAxiosInstance(); requestOptions.headers = { ...requestOptions.headers, Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json', 'OData-MaxPageSize': '5000', }; return requestOptions; } const tokenResponse = await this.getToken(String(tenantId), String(clientId), String(clientSecret), String(scope)); this.accessToken = tokenResponse.access_token; const expiresIn = tokenResponse.expires_in ? parseInt(tokenResponse.expires_in, 10) : 3600; this.tokenExpiry = Date.now() + expiresIn * 1000; this.updateAxiosInstance(); requestOptions.headers = { ...requestOptions.headers, Authorization: `Bearer ${this.accessToken}`, 'Content-Type': 'application/json', 'OData-MaxPageSize': '5000', }; return requestOptions; } async getToken(tenantId, clientId, clientSecret, resourceURL) { try { const url = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`; const data = new URLSearchParams(); data.append('grant_type', 'client_credentials'); data.append('client_id', clientId); data.append('client_secret', clientSecret); data.append('scope', `${resourceURL}/.default`); const response = await axios_1.default.post(url, data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, }); return response.data; } catch (error) { throw new Error(`Error fetching token: ${error}`); } } async ensureAuthenticated() { if (!this.accessToken || Date.now() >= this.tokenExpiry) { if (!this.credentials) { throw new Error('Credentials are not available.'); } const { tenantId, clientId, clientSecret, scope } = this.credentials; const tokenResponse = await this.getToken(String(tenantId), String(clientId), String(clientSecret), String(scope)); this.accessToken = tokenResponse.access_token; const expiresIn = tokenResponse.expires_in ? parseInt(tokenResponse.expires_in, 10) : 3600; this.tokenExpiry = Date.now() + expiresIn * 1000; this.updateAxiosInstance(); } } async CreateData(entityName, payload, columnsToUpdate) { var _a, _b, _c; await this.ensureAuthenticated(); if (!this.axiosInstance) throw new Error('Axios instance not available'); debugger; let body = {}; if (payload && Object.keys(payload).length > 0) { body = { ...payload }; } if (columnsToUpdate && columnsToUpdate.columnValues && Array.isArray(columnsToUpdate.columnValues)) { for (const columnUpdate of columnsToUpdate.columnValues) { if (columnUpdate.columnName) { body[columnUpdate.columnName] = columnUpdate.columnValue; } } } const databody = JSON.stringify(body); const modifiedEntityLogicalName = this.modifyEntityLogicalName(entityName); const fullApiUrl = `/api/data/v9.2/${modifiedEntityLogicalName}`; const headers = { "OData-MaxVersion": "4.0", "Content-Type": "application/json; charset=utf-8", "Accept": "application/json", "Prefer": "odata.include-annotations=*", }; console.log(`Url : ${fullApiUrl} , Body : ${databody}`); try { const response = await this.axiosInstance.post(fullApiUrl, databody, { headers }); return response.data; } catch (error) { throw new Error(`Dataverse API error: ${(_a = error.response) === null || _a === void 0 ? void 0 : _a.status} - ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusText}. Details: ${JSON.stringify((_c = error.response) === null || _c === void 0 ? void 0 : _c.data)}`); } } async UpdateData(entityName, recordId, updateData, columnsToUpdate) { var _a, _b, _c; await this.ensureAuthenticated(); if (!this.axiosInstance) throw new Error('Axios instance not available'); let body = {}; if (updateData && Object.keys(updateData).length > 0) { body = { ...updateData }; } if (columnsToUpdate && columnsToUpdate.columnValues && Array.isArray(columnsToUpdate.columnValues)) { for (const columnUpdate of columnsToUpdate.columnValues) { if (columnUpdate.columnName) { body[columnUpdate.columnName] = columnUpdate.columnValue; } } } const databody = JSON.stringify(body); const modifiedEntityLogicalName = this.modifyEntityLogicalName(entityName); const fullApiUrl = `/api/data/v9.2/${modifiedEntityLogicalName}(${recordId})`; const headers = { "OData-MaxVersion": "4.0", "Content-Type": "application/json; charset=utf-8", "Accept": "application/json", "Prefer": "odata.include-annotations=*", }; try { const response = await this.axiosInstance.patch(fullApiUrl, databody, { headers }); return response.data; } catch (error) { throw new Error(`Dataverse API error: ${(_a = error.response) === null || _a === void 0 ? void 0 : _a.status} - ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusText}. Details: ${JSON.stringify((_c = error.response) === null || _c === void 0 ? void 0 : _c.data)}`); } } async ListEntityColumns(entityName) { var _a, _b, _c; await this.ensureAuthenticated(); if (!this.axiosInstance) throw new Error('Axios instance not available'); const apiUrl = `/api/data/v9.2/EntityDefinitions(LogicalName='${entityName}')/Attributes?$select=LogicalName,DisplayName`; try { const response = await this.axiosInstance.get(apiUrl); const columns = response.data.value.map((attribute) => { var _a, _b; return ({ logicalName: attribute.LogicalName, displayName: ((_b = (_a = attribute.DisplayName) === null || _a === void 0 ? void 0 : _a.UserLocalizedLabel) === null || _b === void 0 ? void 0 : _b.Label) || attribute.LogicalName, }); }); return { columns }; } catch (error) { throw new Error(`Dataverse API error: ${(_a = error.response) === null || _a === void 0 ? void 0 : _a.status} - ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusText}. Details: ${JSON.stringify((_c = error.response) === null || _c === void 0 ? void 0 : _c.data)}`); } } async ListTables() { var _a, _b, _c; await this.ensureAuthenticated(); if (!this.axiosInstance) throw new Error('Axios instance not available'); const apiUrl = `/api/data/v9.2/EntityDefinitions?$select=LogicalName,DisplayName`; try { const response = await this.axiosInstance.get(apiUrl); const entities = response.data.value.map((entity) => { var _a, _b; return ({ logicalName: entity.LogicalName, displayName: ((_b = (_a = entity.DisplayName) === null || _a === void 0 ? void 0 : _a.UserLocalizedLabel) === null || _b === void 0 ? void 0 : _b.Label) || entity.LogicalName, }); }); return { tables: entities }; } catch (error) { throw new Error(`Dataverse API error: ${(_a = error.response) === null || _a === void 0 ? void 0 : _a.status} - ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusText}. Details: ${JSON.stringify((_c = error.response) === null || _c === void 0 ? void 0 : _c.data)}`); } } extractEntityNameFromFetchXml(fetchXml) { const match = fetchXml.match(/<entity name=['"]([^'"]+)['"]/); return match ? match[1] : null; } modifyEntityLogicalName(entityLogicalName) { if (entityLogicalName.endsWith('y')) { return entityLogicalName.slice(0, -1) + 'ies'; } else if (entityLogicalName.endsWith('s')) { return entityLogicalName + 'es'; } else { return entityLogicalName + 's'; } } async GetData(type, entityName, query) { var _a, _b, _c; await this.ensureAuthenticated(); if (!this.axiosInstance) throw new Error('Axios instance not available'); let fullApiUrl = ''; if (type === "FETCHXML") { const entityLogicalName = this.extractEntityNameFromFetchXml(query); if (!entityLogicalName) { throw new Error("Failed to extract entity name from FetchXML."); } const modifiedEntityLogicalName = this.modifyEntityLogicalName(entityLogicalName); fullApiUrl = `/api/data/v9.2/${modifiedEntityLogicalName}?fetchXml=${encodeURIComponent(query)}`; } else if (type === "ODATA") { fullApiUrl = `/api/data/v9.2/${query}`; } else if (type === "column") { const modifiedEntityLogicalName = this.modifyEntityLogicalName(entityName); fullApiUrl = `/api/data/v9.2/${modifiedEntityLogicalName}?$select=${query}`; } try { const response = await this.axiosInstance.get(fullApiUrl, { headers: { Prefer: 'odata.include-annotations="*"' }, }); return response.data; } catch (error) { throw new Error(`Dataverse API error: ${(_a = error.response) === null || _a === void 0 ? void 0 : _a.status} - ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusText}. Details: ${JSON.stringify((_c = error.response) === null || _c === void 0 ? void 0 : _c.data)}`); } } } exports.dataverseAuth = dataverseAuth; dataverseAuth.cachedTables = null; dataverseAuth.cachedEntityColumns = {}; //# sourceMappingURL=dataverseAuth.credentials.js.map