UNPKG

dynamics-web-api

Version:

DynamicsWebApi is a Microsoft Dataverse Web API helper library

1,230 lines (1,215 loc) 113 kB
/*! dynamics-web-api v2.2.1 (c) 2025 Aleksandr Rogov. License: MIT */ "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __esm = (fn, res) => function __init() { return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/helpers/crypto/node.ts var node_exports = {}; __export(node_exports, { getCrypto: () => getCrypto }); function getCrypto() { return import_node_crypto.default; } var import_node_crypto; var init_node = __esm({ "src/helpers/crypto/node.ts"() { "use strict"; import_node_crypto = __toESM(require("crypto")); } }); // src/helpers/Crypto.ts function getCrypto2() { return false ? global.window.crypto : (init_node(), __toCommonJS(node_exports)).getCrypto(); } var init_Crypto = __esm({ "src/helpers/Crypto.ts"() { "use strict"; } }); // src/helpers/Regex.ts function isUuid(value) { const match = UUID_REGEX.exec(value); return !!match; } function extractUuid(value) { const match = EXTRACT_UUID_REGEX.exec(value); return match ? match[1] : null; } function extractUuidFromUrl(url) { if (!url) return null; const match = EXTRACT_UUID_FROM_URL_REGEX.exec(url); return match ? match[1] : null; } function removeCurlyBracketsFromUuid(value) { return value.replace(REMOVE_BRACKETS_FROM_UUID_REGEX, (_match, p1) => p1); } function safelyRemoveCurlyBracketsFromUrl(url) { const parts = url.split(QUOTATION_MARK_REGEX); return parts.map((part, index) => { if (index % 2 === 0) { return removeCurlyBracketsFromUuid(part); } return part; }).join(""); } function convertToReferenceObject(responseData) { const result = ENTITY_UUID_REGEX.exec(responseData["@odata.id"]); return { id: result[2], collection: result[1], oDataContext: responseData["@odata.context"] }; } function parsePagingCookie(pagingCookie) { const info = PAGING_COOKIE_REGEX.exec(pagingCookie); if (!info) return null; const page = parseInt(info[2], 10); const sanitizedCookie = sanitizeCookie(info[1]); return { page, sanitizedCookie }; } function sanitizeCookie(cookie) { const characterMap = { "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" // Use numeric reference for single quote to avoid confusion }; return cookie.replace(SPECIAL_CHARACTER_REGEX, (char) => characterMap[char]); } function removeLeadingSlash(value) { return value.replace(LEADING_SLASH_REGEX, ""); } function escapeUnicodeSymbols(value) { return value.replace(UNICODE_SYMBOLS_REGEX, (chr) => `\\u${("0000" + chr.charCodeAt(0).toString(16)).slice(-4)}`); } function removeDoubleQuotes(value) { return value.replace(DOUBLE_QUOTE_REGEX, ""); } function getUpdateMethod(collection) { return SPECIAL_COLLECTION_FOR_UPDATE_REGEX.test(collection ?? "") ? "PUT" : "PATCH"; } var UUID, UUID_REGEX, EXTRACT_UUID_REGEX, EXTRACT_UUID_FROM_URL_REGEX, REMOVE_BRACKETS_FROM_UUID_REGEX, ENTITY_UUID_REGEX, QUOTATION_MARK_REGEX, PAGING_COOKIE_REGEX, SPECIAL_CHARACTER_REGEX, LEADING_SLASH_REGEX, UNICODE_SYMBOLS_REGEX, DOUBLE_QUOTE_REGEX, BATCH_RESPONSE_HEADERS_REGEX, HTTP_STATUS_REGEX, CONTENT_TYPE_PLAIN_REGEX, ODATA_ENTITYID_REGEX, TEXT_REGEX, LINE_ENDING_REGEX, SEARCH_FOR_ENTITY_NAME_REGEX, SPECIAL_COLLECTION_FOR_UPDATE_REGEX, FETCH_XML_TOP_REGEX, FETCH_XML_PAGE_REGEX, FETCH_XML_REPLACE_REGEX, DATE_FORMAT_REGEX; var init_Regex = __esm({ "src/helpers/Regex.ts"() { "use strict"; UUID = "[0-9a-fA-F]{8}[-]?([0-9a-fA-F]{4}[-]?){3}[0-9a-fA-F]{12}"; UUID_REGEX = new RegExp(UUID, "i"); EXTRACT_UUID_REGEX = new RegExp("^{?(" + UUID + ")}?$", "i"); EXTRACT_UUID_FROM_URL_REGEX = new RegExp("(" + UUID + ")\\)$", "i"); REMOVE_BRACKETS_FROM_UUID_REGEX = new RegExp(`{(${UUID})}`, "g"); ENTITY_UUID_REGEX = new RegExp(`\\/(\\w+)\\((${UUID})`, "i"); QUOTATION_MARK_REGEX = /(["'].*?["'])/; PAGING_COOKIE_REGEX = /pagingcookie="(<cookie page="(\d+)".+<\/cookie>)/; SPECIAL_CHARACTER_REGEX = /[<>"']/g; LEADING_SLASH_REGEX = /^\//; UNICODE_SYMBOLS_REGEX = /[\u007F-\uFFFF]/g; DOUBLE_QUOTE_REGEX = /"/g; BATCH_RESPONSE_HEADERS_REGEX = /^([^()<>@,;:\\"\/[\]?={} \t]+)\s?:\s?(.*)/; HTTP_STATUS_REGEX = /HTTP\/?\s*[\d.]*\s+(\d{3})\s+([\w\s]*)$/m; CONTENT_TYPE_PLAIN_REGEX = /Content-Type: text\/plain/i; ODATA_ENTITYID_REGEX = /OData-EntityId.+/i; TEXT_REGEX = /\w+$/g; LINE_ENDING_REGEX = /\r?\n/; SEARCH_FOR_ENTITY_NAME_REGEX = /(\w+)(\([\d\w-]+\))$/; SPECIAL_COLLECTION_FOR_UPDATE_REGEX = /EntityDefinitions|RelationshipDefinitions|GlobalOptionSetDefinitions/; FETCH_XML_TOP_REGEX = /^<fetch.+top=/; FETCH_XML_PAGE_REGEX = /^<fetch.+page=/; FETCH_XML_REPLACE_REGEX = /^(<fetch)/; DATE_FORMAT_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:Z|[-+]\d{2}:\d{2})$/; } }); // src/utils/Utility.ts function formatParameterValue(value) { if (value == null) return ""; if (typeof value === "string" && !value.startsWith("Microsoft.Dynamics.CRM") && !isUuid(value)) { return `'${value}'`; } else if (typeof value === "object") { return JSON.stringify(value); } return value.toString(); } function processParameters(parameters) { const parameterNames = Object.keys(parameters); const functionParams = []; const urlQuery = []; parameterNames.forEach((parameterName, index) => { let value = parameters[parameterName]; if (value == null) return; value = formatParameterValue(value); const paramIndex = index + 1; functionParams.push(`${parameterName}=@p${paramIndex}`); urlQuery.push(`@p${paramIndex}=${extractUuid(value) || value}`); }); return { key: `(${functionParams.join(",")})`, queryParams: urlQuery }; } function hasHeader(headers, name) { return headers.hasOwnProperty(name) || headers.hasOwnProperty(name.toLowerCase()); } function getHeader(headers, name) { if (headers[name]) return headers[name]; return headers[name.toLowerCase()]; } var downloadChunkSize, _Utility, Utility; var init_Utility = __esm({ "src/utils/Utility.ts"() { "use strict"; init_Crypto(); init_Regex(); downloadChunkSize = 4194304; _Utility = class _Utility { /** * Builds parametes for a funciton. Returns '()' (if no parameters) or '([params])?[query]' * * @param {Object} [parameters] - Function's input parameters. Example: { param1: "test", param2: 3 }. * @returns {string} */ static buildFunctionParameters(parameters) { return parameters ? processParameters(parameters) : { key: "()" }; } /** * Parses a paging cookie returned in response * * @param {string} pageCookies - Page cookies returned in @Microsoft.Dynamics.CRM.fetchxmlpagingcookie. * @param {number} currentPageNumber - A current page number. Fix empty paging-cookie for complex fetch xmls. * @returns {{cookie: "", number: 0, next: 1}} */ static getFetchXmlPagingCookie(pageCookies = "", currentPageNumber = 1) { pageCookies = decodeURIComponent(decodeURIComponent(pageCookies)); const result = parsePagingCookie(pageCookies); return { cookie: (result == null ? void 0 : result.sanitizedCookie) || "", page: (result == null ? void 0 : result.page) || currentPageNumber, nextPage: (result == null ? void 0 : result.page) ? result.page + 1 : currentPageNumber + 1 }; } /** * Checks whether the value is JS Null. * @param {Object} value * @returns {boolean} */ static isNull(value) { return typeof value === "undefined" || value == null; } /** Generates UUID */ static generateUUID() { return getCrypto2().randomUUID(); } static getXrmContext() { if (typeof GetGlobalContext !== "undefined") { return GetGlobalContext(); } else { if (typeof Xrm !== "undefined") { if (!_Utility.isNull(Xrm.Utility) && !_Utility.isNull(Xrm.Utility.getGlobalContext)) { return Xrm.Utility.getGlobalContext(); } else if (!_Utility.isNull(Xrm.Page) && !_Utility.isNull(Xrm.Page.context)) { return Xrm.Page.context; } } } throw new Error( "Xrm Context is not available. In most cases, it can be resolved by adding a reference to a ClientGlobalContext.js.aspx. Please refer to MSDN documentation for more details." ); } // static getXrmUtility(): any { // return typeof Xrm !== "undefined" ? Xrm.Utility : null; // } static getClientUrl() { const context = _Utility.getXrmContext(); let clientUrl = context.getClientUrl(); if (clientUrl.match(/\/$/)) { clientUrl = clientUrl.substring(0, clientUrl.length - 1); } return clientUrl; } /** * Checks whether the app is currently running in a Dynamics Portals Environment. * * In that case we switch to the Web API for Dynamics Portals. * @returns {boolean} */ static isRunningWithinPortals() { return false ? !!global.window.shell : false; } static isObject(obj) { return typeof obj === "object" && !!obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== "[object Date]"; } static copyObject(src, excludeProps) { let target = {}; for (let prop in src) { if (src.hasOwnProperty(prop) && !(excludeProps == null ? void 0 : excludeProps.includes(prop))) { if (_Utility.isObject(src[prop])) { target[prop] = _Utility.copyObject(src[prop]); } else if (Array.isArray(src[prop])) { target[prop] = src[prop].slice(); } else { target[prop] = src[prop]; } } } return target; } static copyRequest(src, excludeProps = []) { if (!excludeProps.includes("signal")) excludeProps.push("signal"); const result = _Utility.copyObject(src, excludeProps); result.signal = src.signal; return result; } static setFileChunk(request, fileBuffer, chunkSize, offset) { offset = offset || 0; const count = offset + chunkSize > fileBuffer.length ? fileBuffer.length % chunkSize : chunkSize; let content; if (false) { content = new Uint8Array(count); for (let i = 0; i < count; i++) { content[i] = fileBuffer[offset + i]; } } else { content = fileBuffer.slice(offset, offset + count); } request.data = content; request.contentRange = "bytes " + offset + "-" + (offset + count - 1) + "/" + fileBuffer.length; } static convertToFileBuffer(binaryString) { if (true) return Buffer.from(binaryString, "binary"); const bytes = new Uint8Array(binaryString.length); for (var i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes; } }; // static isNodeEnv = isNodeEnv; _Utility.downloadChunkSize = downloadChunkSize; Utility = _Utility; } }); // src/helpers/ErrorHelper.ts function throwParameterError(functionName, parameterName, type) { throw new Error( type ? `${functionName} requires a ${parameterName} parameter to be of type ${type}.` : `${functionName} requires a ${parameterName} parameter.` ); } var ErrorHelper; var init_ErrorHelper = __esm({ "src/helpers/ErrorHelper.ts"() { "use strict"; init_Regex(); ErrorHelper = class _ErrorHelper { static handleErrorResponse(req) { throw new Error(`Error: ${req.status}: ${req.message}`); } static parameterCheck(parameter, functionName, parameterName, type) { if (typeof parameter === "undefined" || parameter === null || parameter === "") { throwParameterError(functionName, parameterName, type); } } static stringParameterCheck(parameter, functionName, parameterName) { if (typeof parameter !== "string") { throwParameterError(functionName, parameterName, "String"); } } static maxLengthStringParameterCheck(parameter, functionName, parameterName, maxLength) { if (!parameter) return; if (parameter.length > maxLength) { throw new Error(`${parameterName} has a ${maxLength} character limit.`); } } static arrayParameterCheck(parameter, functionName, parameterName) { if (parameter.constructor !== Array) { throwParameterError(functionName, parameterName, "Array"); } } static stringOrArrayParameterCheck(parameter, functionName, parameterName) { if (parameter.constructor !== Array && typeof parameter !== "string") { throwParameterError(functionName, parameterName, "String or Array"); } } static numberParameterCheck(parameter, functionName, parameterName) { if (typeof parameter != "number") { if (typeof parameter === "string" && parameter) { if (!isNaN(parseInt(parameter))) { return; } } throwParameterError(functionName, parameterName, "Number"); } } static batchIsEmpty() { return [ new Error( "Payload of the batch operation is empty. Please make that you have other operations in between startBatch() and executeBatch() to successfuly build a batch payload." ) ]; } static handleHttpError(parsedError, parameters) { const error = new Error(); Object.keys(parsedError).forEach((k) => { error[k] = parsedError[k]; }); if (parameters) { Object.keys(parameters).forEach((k) => { error[k] = parameters[k]; }); } return error; } static boolParameterCheck(parameter, functionName, parameterName) { if (typeof parameter != "boolean") { throwParameterError(functionName, parameterName, "Boolean"); } } /** * Private function used to check whether required parameter is a valid GUID * @param parameter The GUID parameter to check * @param functionName * @param parameterName * @returns */ static guidParameterCheck(parameter, functionName, parameterName) { const match = extractUuid(parameter); if (!match) throwParameterError(functionName, parameterName, "GUID String"); return match; } static keyParameterCheck(parameter, functionName, parameterName) { try { _ErrorHelper.stringParameterCheck(parameter, functionName, parameterName); const match = extractUuid(parameter); if (match) return match; const alternateKeys = parameter.split(","); if (alternateKeys.length) { for (let i = 0; i < alternateKeys.length; i++) { alternateKeys[i] = alternateKeys[i].trim().replace(/"/g, "'"); /^[\w\d\_]+\=(.+)$/i.exec(alternateKeys[i])[0]; } } return alternateKeys.join(","); } catch (error) { throwParameterError(functionName, parameterName, "String representing GUID or Alternate Key"); } } static callbackParameterCheck(callbackParameter, functionName, parameterName) { if (typeof callbackParameter != "function") { throwParameterError(functionName, parameterName, "Function"); } } static throwBatchIncompatible(functionName, isBatch) { if (isBatch) { isBatch = false; throw new Error(functionName + " cannot be used in a BATCH request."); } } static throwBatchNotStarted(isBatch) { if (!isBatch) { throw new Error( "Batch operation has not been started. Please call a DynamicsWebApi.startBatch() function prior to calling DynamicsWebApi.executeBatch() to perform a batch request correctly." ); } } }; } }); // src/dwa.ts var _a, _b, _DWA, DWA; var init_dwa = __esm({ "src/dwa.ts"() { "use strict"; _DWA = class _DWA { }; _DWA.Prefer = (_b = class { static get(annotation) { return `${_DWA.Prefer.IncludeAnnotations}="${annotation}"`; } }, _b.ReturnRepresentation = "return=representation", _b.Annotations = (_a = class { }, _a.AssociatedNavigationProperty = "Microsoft.Dynamics.CRM.associatednavigationproperty", _a.LookupLogicalName = "Microsoft.Dynamics.CRM.lookuplogicalname", _a.All = "*", _a.FormattedValue = "OData.Community.Display.V1.FormattedValue", _a.FetchXmlPagingCookie = "Microsoft.Dynamics.CRM.fetchxmlpagingcookie", _a), _b.IncludeAnnotations = "odata.include-annotations", _b); DWA = _DWA; } }); // src/client/helpers/dateReviver.ts function dateReviver(key, value) { if (typeof value === "string") { const a = DATE_FORMAT_REGEX.exec(value); if (a) { return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])); } } return value; } var init_dateReviver = __esm({ "src/client/helpers/dateReviver.ts"() { "use strict"; init_Regex(); } }); // src/client/helpers/parseBatchResponse.ts function parseBatchHeaders(text) { const ctx = { position: 0 }; const headers = {}; let parts; let line; let pos; do { pos = ctx.position; line = readLine(text, ctx); if (!line) break; parts = BATCH_RESPONSE_HEADERS_REGEX.exec(line); if (parts !== null) { headers[parts[1].toLowerCase()] = parts[2]; } else { ctx.position = pos; } } while (line && parts); return headers; } function readLine(text, ctx) { return readTo(text, ctx, LINE_ENDING_REGEX); } function readTo(text, ctx, searchRegTerm) { const start = ctx.position || 0; const slicedText = text.slice(start); const match = searchRegTerm.exec(slicedText); if (!match) { return null; } const end = start + match.index; ctx.position = end + match[0].length; return text.substring(start, end); } function getHttpStatus(response) { const parts = HTTP_STATUS_REGEX.exec(response); return { httpStatusString: parts[0], httpStatus: parseInt(parts[1]), httpStatusMessage: parts[2].trim() }; } function getPlainContent(response) { HTTP_STATUS_REGEX.lastIndex = 0; const textReg = TEXT_REGEX.exec(response.trim()); return (textReg == null ? void 0 : textReg.length) ? textReg[0] : void 0; } function handlePlainContent(batchResponse, parseParams, requestNumber) { const plainContent = getPlainContent(batchResponse); return handlePlainResponse(plainContent); } function handleEmptyContent(batchResponse, parseParams, requestNumber) { var _a2; if (((_a2 = parseParams == null ? void 0 : parseParams[requestNumber]) == null ? void 0 : _a2.valueIfEmpty) !== void 0) { return parseParams[requestNumber].valueIfEmpty; } else { const entityUrl = ODATA_ENTITYID_REGEX.exec(batchResponse); return extractUuidFromUrl(entityUrl == null ? void 0 : entityUrl[0]) ?? void 0; } } function processBatchPart(batchResponse, parseParams, requestNumber) { const { httpStatusString, httpStatus, httpStatusMessage } = getHttpStatus(batchResponse); const responseData = batchResponse.substring(batchResponse.indexOf("{"), batchResponse.lastIndexOf("}") + 1); if (!responseData) { if (CONTENT_TYPE_PLAIN_REGEX.test(batchResponse)) { return handlePlainContent(batchResponse, parseParams, requestNumber); } return handleEmptyContent(batchResponse, parseParams, requestNumber); } const parsedResponse = handleJsonResponse(responseData, parseParams, requestNumber); if (httpStatus < 400) { return parsedResponse; } const responseHeaders = parseBatchHeaders( batchResponse.substring(batchResponse.indexOf(httpStatusString) + httpStatusString.length + 1, batchResponse.indexOf("{")) ); return ErrorHelper.handleHttpError(parsedResponse, { status: httpStatus, statusText: httpStatusMessage, statusMessage: httpStatusMessage, headers: responseHeaders }); } function parseBatchResponse(response, parseParams, requestNumber = 0) { const delimiter = response.substring(0, response.search(LINE_ENDING_REGEX)); const batchResponseParts = response.split(delimiter); batchResponseParts.shift(); batchResponseParts.pop(); let result = []; for (let part of batchResponseParts) { if (part.indexOf("--changesetresponse_") === -1) { result.push(processBatchPart(part, parseParams, requestNumber++)); continue; } part = part.trim(); const batchToProcess = part.substring(part.search(LINE_ENDING_REGEX) + 1).trim(); result = result.concat(parseBatchResponse(batchToProcess, parseParams, requestNumber++)); } return result; } var init_parseBatchResponse = __esm({ "src/client/helpers/parseBatchResponse.ts"() { "use strict"; init_ErrorHelper(); init_Regex(); init_parseResponse(); } }); // src/client/helpers/parseResponse.ts function getFormattedKeyValue(keyName, value) { let newKey = null; if (keyName.indexOf("@") !== -1) { const format = keyName.split("@"); switch (format[1]) { case "odata.context": newKey = "oDataContext"; break; case "odata.count": newKey = "oDataCount"; value = value != null ? parseInt(value) : 0; break; case "odata.nextLink": newKey = "oDataNextLink"; break; case "odata.deltaLink": newKey = "oDataDeltaLink"; break; case DWA.Prefer.Annotations.FormattedValue: newKey = format[0] + "_Formatted"; break; case DWA.Prefer.Annotations.AssociatedNavigationProperty: newKey = format[0] + "_NavigationProperty"; break; case DWA.Prefer.Annotations.LookupLogicalName: newKey = format[0] + "_LogicalName"; break; } } return [newKey, value]; } function parseData(object, parseParams) { if (parseParams) { if (parseParams.isRef && object["@odata.id"] != null) { return convertToReferenceObject(object); } if (parseParams.toCount) { return getFormattedKeyValue("@odata.count", object["@odata.count"])[1] || 0; } } for (const currentKey in object) { if (object[currentKey] != null) { if (Array.isArray(object[currentKey])) { for (var j = 0; j < object[currentKey].length; j++) { object[currentKey][j] = parseData(object[currentKey][j]); } } else if (typeof object[currentKey] === "object") { parseData(object[currentKey]); } } let formattedKeyValue = getFormattedKeyValue(currentKey, object[currentKey]); if (formattedKeyValue[0]) { object[formattedKeyValue[0]] = formattedKeyValue[1]; } if (currentKey.indexOf("_x002e_") !== -1) { const aliasKeys = currentKey.split("_x002e_"); if (!object.hasOwnProperty(aliasKeys[0])) { object[aliasKeys[0]] = { _dwaType: "alias" }; } else if (typeof object[aliasKeys[0]] !== "object" || typeof object[aliasKeys[0]] === "object" && !object[aliasKeys[0]].hasOwnProperty("_dwaType")) { throw new Error("The alias name of the linked entity must be unique!"); } object[aliasKeys[0]][aliasKeys[1]] = object[currentKey]; formattedKeyValue = getFormattedKeyValue(aliasKeys[1], object[currentKey]); if (formattedKeyValue[0]) { object[aliasKeys[0]][formattedKeyValue[0]] = formattedKeyValue[1]; } } } if (parseParams) { if (parseParams.hasOwnProperty("pageNumber") && object["@" + DWA.Prefer.Annotations.FetchXmlPagingCookie] != null) { object.PagingInfo = Utility.getFetchXmlPagingCookie(object["@" + DWA.Prefer.Annotations.FetchXmlPagingCookie], parseParams.pageNumber); } } return object; } function base64ToString(base64) { return false ? global.window.atob(base64) : Buffer.from(base64, "base64").toString("binary"); } function parseFileResponse(response, responseHeaders, parseParams) { let data = response; if (parseParams == null ? void 0 : parseParams.hasOwnProperty("parse")) { data = JSON.parse(data).value; data = base64ToString(data); } const parseResult = { value: data }; if (responseHeaders["x-ms-file-name"]) parseResult.fileName = responseHeaders["x-ms-file-name"]; if (responseHeaders["x-ms-file-size"]) parseResult.fileSize = parseInt(responseHeaders["x-ms-file-size"]); const location = getHeader(responseHeaders, "Location"); if (location) parseResult.location = location; return parseResult; } function isBatchResponse(response) { return response.indexOf("--batchresponse_") > -1; } function isFileResponse(responseHeaders) { return hasHeader(responseHeaders, "Content-Disposition"); } function isJsonResponse(responseHeaders) { const contentType = getHeader(responseHeaders, "Content-Type"); return (contentType == null ? void 0 : contentType.startsWith("application/json")) == true; } function handleBatchResponse(response, parseParams) { const batch = parseBatchResponse(response, parseParams); return (parseParams == null ? void 0 : parseParams[0].convertedToBatch) ? batch[0] : batch; } function handleFileResponse(response, responseHeaders, parseParams) { return parseFileResponse(response, responseHeaders, parseParams[0]); } function handleJsonResponse(response, parseParams, requestNumber = 0) { return parseData(JSON.parse(response, dateReviver), parseParams[requestNumber]); } function handlePlainResponse(response) { const numberResponse = Number(response); return isFinite(numberResponse) ? numberResponse : response; } function handleEmptyResponse(responseHeaders, parseParams) { var _a2; if (((_a2 = parseParams == null ? void 0 : parseParams[0]) == null ? void 0 : _a2.valueIfEmpty) !== void 0) { return parseParams[0].valueIfEmpty; } const entityUrl = getHeader(responseHeaders, "OData-EntityId"); if (entityUrl) { return extractUuidFromUrl(entityUrl) ?? void 0; } const location = getHeader(responseHeaders, "Location"); if (location) { const result = { location }; if (responseHeaders["x-ms-chunk-size"]) { result.chunkSize = parseInt(responseHeaders["x-ms-chunk-size"]); } return result; } } function parseResponse(response, responseHeaders, parseParams) { if (!response.length) { return handleEmptyResponse(responseHeaders, parseParams); } if (isBatchResponse(response)) { return handleBatchResponse(response, parseParams); } if (isFileResponse(responseHeaders)) { return handleFileResponse(response, responseHeaders, parseParams); } if (isJsonResponse(responseHeaders)) { return handleJsonResponse(response, parseParams); } return handlePlainResponse(response); } var init_parseResponse = __esm({ "src/client/helpers/parseResponse.ts"() { "use strict"; init_dwa(); init_Utility(); init_dateReviver(); init_Regex(); init_parseBatchResponse(); } }); // src/client/http.ts var http_exports = {}; __export(http_exports, { executeRequest: () => executeRequest }); function executeRequest(options) { return new Promise((resolve, reject) => { _executeRequest(options, resolve, reject); }); } function _executeRequest(options, successCallback, errorCallback) { var _a2; const data = options.data; const headers = options.headers; const responseParams = options.responseParams; const signal = options.abortSignal; const httpHeaders = {}; if (data) { httpHeaders["Content-Type"] = headers["Content-Type"]; httpHeaders["Content-Length"] = data.length; delete headers["Content-Type"]; } for (let key in headers) { httpHeaders[key] = headers[key]; } const parsedUrl = new URL(options.uri); const protocol = ((_a2 = parsedUrl.protocol) == null ? void 0 : _a2.slice(0, -1)) || "https"; const protocolInterface = protocol === "http" ? http : https; const internalOptions = { hostname: parsedUrl.hostname, port: parsedUrl.port, path: parsedUrl.pathname + parsedUrl.search, method: options.method, timeout: options.timeout || 0, headers: httpHeaders, signal }; if (!options.proxy && process.env[`${protocol}_proxy`]) { options.proxy = { url: process.env[`${protocol}_proxy`] }; } internalOptions.agent = getAgent(options, protocol); if (options.proxy) { const hostHeader = new URL(options.proxy.url).host; if (hostHeader) httpHeaders.host = hostHeader; } const request = protocolInterface.request(internalOptions, function(res) { let rawData = ""; res.setEncoding("utf8"); res.on("data", function(chunk) { rawData += chunk; }); res.on("end", function() { switch (res.statusCode) { case 200: // Success with content returned in response body. case 201: // Success with content returned in response body. case 204: // Success with no content returned in response body. case 206: //Success with partial content case 304: { let responseData = parseResponse(rawData, res.headers, responseParams[options.requestId]); let response = { data: responseData, headers: res.headers, status: res.statusCode }; successCallback(response); break; } default: let crmError; try { var errorParsed = parseResponse(rawData, res.headers, responseParams[options.requestId]); if (Array.isArray(errorParsed)) { errorCallback(errorParsed); break; } crmError = errorParsed.hasOwnProperty("error") && errorParsed.error ? errorParsed.error : { message: errorParsed.Message }; } catch (e) { if (rawData.length > 0) { crmError = { message: rawData }; } else { crmError = { message: "Unexpected Error" }; } } errorCallback( ErrorHelper.handleHttpError(crmError, { status: res.statusCode, statusText: "", statusMessage: res.statusMessage, headers: res.headers }) ); break; } }); }); if (internalOptions.timeout) { request.setTimeout(internalOptions.timeout, function() { request.destroy(); }); } request.on("error", function(error) { errorCallback(error); }); if (data) { request.write(data); } request.end(); } var http, https, import_http_proxy_agent, import_https_proxy_agent, agents, getAgent; var init_http = __esm({ "src/client/http.ts"() { "use strict"; http = __toESM(require("http")); https = __toESM(require("https")); import_http_proxy_agent = __toESM(require("http-proxy-agent")); import_https_proxy_agent = __toESM(require("https-proxy-agent")); init_ErrorHelper(); init_parseResponse(); agents = {}; getAgent = (options, protocol) => { const isHttp = protocol === "http"; const proxy = options.proxy; const agentName = proxy ? proxy.url : protocol; if (!agents[agentName]) { if (proxy) { const parsedProxyUrl = new URL(proxy.url); const proxyAgent = isHttp ? import_http_proxy_agent.default.HttpProxyAgent : import_https_proxy_agent.default.HttpsProxyAgent; const proxyOptions = { host: parsedProxyUrl.hostname, port: parsedProxyUrl.port, protocol: parsedProxyUrl.protocol }; if (proxy.auth) proxyOptions.auth = proxy.auth.username + ":" + proxy.auth.password; else if (parsedProxyUrl.username && parsedProxyUrl.password) proxyOptions.auth = `${parsedProxyUrl.username}:${parsedProxyUrl.password}`; agents[agentName] = new proxyAgent(proxyOptions); } else { const protocolInterface = isHttp ? http : https; agents[agentName] = new protocolInterface.Agent({ keepAlive: true, maxSockets: Infinity }); } } return agents[agentName]; }; } }); // src/dynamics-web-api.ts var dynamics_web_api_exports = {}; __export(dynamics_web_api_exports, { DynamicsWebApi: () => DynamicsWebApi }); module.exports = __toCommonJS(dynamics_web_api_exports); // src/utils/Config.ts init_Utility(); init_ErrorHelper(); var getApiUrl = (serverUrl, apiConfig) => { if (Utility.isRunningWithinPortals()) { return new URL("_api", global.window.location.origin).toString() + "/"; } else { if (!serverUrl) serverUrl = Utility.getClientUrl(); return new URL(`api/${apiConfig.path}/v${apiConfig.version}`, serverUrl).toString() + "/"; } }; var mergeApiConfigs = (apiConfig, apiType, internalConfig) => { const internalApiConfig = internalConfig[apiType]; if (apiConfig == null ? void 0 : apiConfig.version) { ErrorHelper.stringParameterCheck(apiConfig.version, "DynamicsWebApi.setConfig", `config.${apiType}.version`); internalApiConfig.version = apiConfig.version; } if (apiConfig == null ? void 0 : apiConfig.path) { ErrorHelper.stringParameterCheck(apiConfig.path, "DynamicsWebApi.setConfig", `config.${apiType}.path`); internalApiConfig.path = apiConfig.path; } internalApiConfig.url = getApiUrl(internalConfig.serverUrl, internalApiConfig); }; var ConfigurationUtility = class { static merge(internalConfig, config) { if (config == null ? void 0 : config.serverUrl) { ErrorHelper.stringParameterCheck(config.serverUrl, "DynamicsWebApi.setConfig", "config.serverUrl"); internalConfig.serverUrl = config.serverUrl; } mergeApiConfigs(config == null ? void 0 : config.dataApi, "dataApi", internalConfig); mergeApiConfigs(config == null ? void 0 : config.searchApi, "searchApi", internalConfig); if (config == null ? void 0 : config.impersonate) { internalConfig.impersonate = ErrorHelper.guidParameterCheck(config.impersonate, "DynamicsWebApi.setConfig", "config.impersonate"); } if (config == null ? void 0 : config.impersonateAAD) { internalConfig.impersonateAAD = ErrorHelper.guidParameterCheck(config.impersonateAAD, "DynamicsWebApi.setConfig", "config.impersonateAAD"); } if (config == null ? void 0 : config.onTokenRefresh) { ErrorHelper.callbackParameterCheck(config.onTokenRefresh, "DynamicsWebApi.setConfig", "config.onTokenRefresh"); internalConfig.onTokenRefresh = config.onTokenRefresh; } if (config == null ? void 0 : config.includeAnnotations) { ErrorHelper.stringParameterCheck(config.includeAnnotations, "DynamicsWebApi.setConfig", "config.includeAnnotations"); internalConfig.includeAnnotations = config.includeAnnotations; } if (config == null ? void 0 : config.timeout) { ErrorHelper.numberParameterCheck(config.timeout, "DynamicsWebApi.setConfig", "config.timeout"); internalConfig.timeout = config.timeout; } if (config == null ? void 0 : config.maxPageSize) { ErrorHelper.numberParameterCheck(config.maxPageSize, "DynamicsWebApi.setConfig", "config.maxPageSize"); internalConfig.maxPageSize = config.maxPageSize; } if (config == null ? void 0 : config.returnRepresentation) { ErrorHelper.boolParameterCheck(config.returnRepresentation, "DynamicsWebApi.setConfig", "config.returnRepresentation"); internalConfig.returnRepresentation = config.returnRepresentation; } if (config == null ? void 0 : config.useEntityNames) { ErrorHelper.boolParameterCheck(config.useEntityNames, "DynamicsWebApi.setConfig", "config.useEntityNames"); internalConfig.useEntityNames = config.useEntityNames; } if (config == null ? void 0 : config.headers) { internalConfig.headers = config.headers; } if (config == null ? void 0 : config.proxy) { ErrorHelper.parameterCheck(config.proxy, "DynamicsWebApi.setConfig", "config.proxy"); if (config.proxy.url) { ErrorHelper.stringParameterCheck(config.proxy.url, "DynamicsWebApi.setConfig", "config.proxy.url"); if (config.proxy.auth) { ErrorHelper.parameterCheck(config.proxy.auth, "DynamicsWebApi.setConfig", "config.proxy.auth"); ErrorHelper.stringParameterCheck(config.proxy.auth.username, "DynamicsWebApi.setConfig", "config.proxy.auth.username"); ErrorHelper.stringParameterCheck(config.proxy.auth.password, "DynamicsWebApi.setConfig", "config.proxy.auth.password"); } } internalConfig.proxy = config.proxy; } } static default() { return { serverUrl: null, impersonate: null, impersonateAAD: null, onTokenRefresh: null, includeAnnotations: null, maxPageSize: null, returnRepresentation: null, proxy: null, dataApi: { path: "data", version: "9.2", url: "" }, searchApi: { path: "search", version: "1.0", url: "" } }; } }; ConfigurationUtility.mergeApiConfigs = mergeApiConfigs; // src/dynamics-web-api.ts init_Utility(); init_ErrorHelper(); // src/client/RequestClient.ts init_Utility(); // src/utils/Request.ts init_Utility(); init_ErrorHelper(); init_Regex(); var entityNames = null; var setEntityNames = (newEntityNames) => { entityNames = newEntityNames; }; var compose = (request, config) => { request.path = request.path || ""; request.functionName = request.functionName || ""; if (!request.url) { if (!request._isUnboundRequest && !request.contentId && !request.collection) { ErrorHelper.parameterCheck(request.collection, `DynamicsWebApi.${request.functionName}`, "request.collection"); } if (request.collection != null) { ErrorHelper.stringParameterCheck(request.collection, `DynamicsWebApi.${request.functionName}`, "request.collection"); request.path = request.collection; if (request.key) { request.key = ErrorHelper.keyParameterCheck(request.key, `DynamicsWebApi.${request.functionName}`, "request.key"); request.path += `(${request.key})`; } } if (request.contentId) { ErrorHelper.stringParameterCheck(request.contentId, `DynamicsWebApi.${request.functionName}`, "request.contentId"); if (request.contentId.startsWith("$")) { request.path = request.path ? `${request.contentId}/${request.path}` : request.contentId; } } if (request.addPath) { if (request.path) { request.path += "/"; } request.path += request.addPath; } request.path = composeUrl(request, config, request.path); if (request.fetchXml) { ErrorHelper.stringParameterCheck(request.fetchXml, `DynamicsWebApi.${request.functionName}`, "request.fetchXml"); let join = request.path.indexOf("?") === -1 ? "?" : "&"; request.path += `${join}fetchXml=${encodeURIComponent(request.fetchXml)}`; } } else { ErrorHelper.stringParameterCheck(request.url, `DynamicsWebApi.${request.functionName}`, "request.url"); request.path = request.url.replace(config.dataApi.url, ""); } if (request.hasOwnProperty("async") && request.async != null) { ErrorHelper.boolParameterCheck(request.async, `DynamicsWebApi.${request.functionName}`, "request.async"); } else { request.async = true; } request.headers = composeHeaders(request, config); return request; }; var composeUrl = (request, config, url = "", joinSymbol = "&") => { var _a2, _b2, _c; const queryArray = []; if (request) { if (request.navigationProperty) { ErrorHelper.stringParameterCheck(request.navigationProperty, `DynamicsWebApi.${request.functionName}`, "request.navigationProperty"); url += "/" + request.navigationProperty; if (request.navigationPropertyKey) { let navigationKey = ErrorHelper.keyParameterCheck( request.navigationPropertyKey, `DynamicsWebApi.${request.functionName}`, "request.navigationPropertyKey" ); url += "(" + navigationKey + ")"; } if (request.navigationProperty === "Attributes") { if (request.metadataAttributeType) { ErrorHelper.stringParameterCheck(request.metadataAttributeType, `DynamicsWebApi.${request.functionName}`, "request.metadataAttributeType"); url += "/" + request.metadataAttributeType; } } } if ((_a2 = request.select) == null ? void 0 : _a2.length) { ErrorHelper.arrayParameterCheck(request.select, `DynamicsWebApi.${request.functionName}`, "request.select"); if (request.functionName == "retrieve" && request.select.length == 1 && request.select[0].endsWith("/$ref")) { url += "/" + request.select[0]; } else { if (request.select[0].startsWith("/") && request.functionName == "retrieve") { if (request.navigationProperty == null) { url += request.select.shift(); } else { request.select.shift(); } } if (request.select.length) { queryArray.push("$select=" + request.select.join(",")); } } } if (request.filter) { ErrorHelper.stringParameterCheck(request.filter, `DynamicsWebApi.${request.functionName}`, "request.filter"); const filterResult = safelyRemoveCurlyBracketsFromUrl(request.filter); queryArray.push("$filter=" + encodeURIComponent(filterResult)); } if (request.fieldName) { ErrorHelper.stringParameterCheck(request.fieldName, `DynamicsWebApi.${request.functionName}`, "request.fieldName"); if (!request.property) request.property = request.fieldName; delete request.fieldName; } if (request.property) { ErrorHelper.stringParameterCheck(request.property, `DynamicsWebApi.${request.functionName}`, "request.property"); url += "/" + request.property; } if (request.savedQuery) { queryArray.push("savedQuery=" + ErrorHelper.guidParameterCheck(request.savedQuery, `DynamicsWebApi.${request.functionName}`, "request.savedQuery")); } if (request.userQuery) { queryArray.push("userQuery=" + ErrorHelper.guidParameterCheck(request.userQuery, `DynamicsWebApi.${request.functionName}`, "request.userQuery")); } if (request.apply) { ErrorHelper.stringParameterCheck(request.apply, `DynamicsWebApi.${request.functionName}`, "request.apply"); queryArray.push("$apply=" + request.apply); } if (request.count) { ErrorHelper.boolParameterCheck(request.count, `DynamicsWebApi.${request.functionName}`, "request.count"); queryArray.push("$count=" + request.count); } if (request.top && request.top > 0) { ErrorHelper.numberParameterCheck(request.top, `DynamicsWebApi.${request.functionName}`, "request.top"); queryArray.push("$top=" + request.top); } if (request.orderBy != null && request.orderBy.length) { ErrorHelper.arrayParameterCheck(request.orderBy, `DynamicsWebApi.${request.functionName}`, "request.orderBy"); queryArray.push("$orderby=" + request.orderBy.join(",")); } if (request.partitionId) { ErrorHelper.stringParameterCheck(request.partitionId, `DynamicsWebApi.${request.functionName}`, "request.partitionId"); queryArray.push("partitionid='" + request.partitionId + "'"); } if (request.downloadSize) { ErrorHelper.stringParameterCheck(request.downloadSize, `DynamicsWebApi.${request.functionName}`, "request.downloadSize"); queryArray.push("size=" + request.downloadSize); } if ((_b2 = request.queryParams) == null ? void 0 : _b2.length) { ErrorHelper.arrayParameterCheck(request.queryParams, `DynamicsWebApi.${request.functionName}`, "request.queryParams"); queryArray.push(request.queryParams.join("&")); } if (request.fileName) { ErrorHelper.stringParameterCheck(request.fileName, `DynamicsWebApi.${request.functionName}`, "request.fileName"); queryArray.push("x-ms-file-name=" + request.fileName); } if (request.data) { ErrorHelper.parameterCheck(request.data, `DynamicsWebApi.${request.functionName}`, "request.data"); } if (request.isBatch) { ErrorHelper.boolParameterCheck(request.isBatch, `DynamicsWebApi.${request.functionName}`, "request.isBatch"); } if (!Utility.isNull(request.inChangeSet)) { ErrorHelper.boolParameterCheck(request.inChangeSet, `DynamicsWebApi.${request.functionName}`, "request.inChangeSet"); } if (request.isBatch && Utility.isNull(request.inChangeSet)) request.inChangeSet = true; if (request.timeout) { ErrorHelper.numberParameterCheck(request.timeout, `DynamicsWebApi.${request.functionName}`, "request.timeout"); } if ((_c = request.expand) == null ? void 0 : _c.length) { ErrorHelper.stringOrArrayParameterCheck(request.expand, `DynamicsWebApi.${request.functionName}`, "request.expand"); if (typeof request.expand === "string") { queryArray.push("$expand=" + request.expand); } else { const expandQueryArray = []; for (const { property, ...expand } of request.expand) { if (!property) continue; const expandRequest = { functionName: `${request.functionName} $expand`, ...expand }; let expandConverted = composeUrl(expandRequest, config, "", ";"); if (expandConverted) { expandConverted = `(${expandConverted.slice(1)})`; } expandQueryArray.push(property + expandConverted); } if (expandQueryArray.length) { queryArray.push("$expand=" + expandQueryArray.join(",")); } } } } return !queryArray.length ? url : url + "?" + queryArray.join(joinSymbol); }; var composeHeaders = (request, config) => { const headers = { ...config.headers, ...request.userHeaders }; const prefer = composePreferHeader(request, config); if (prefer.length) { headers["Prefer"] = prefer; } if (request.collection === "$metadata") { headers["Accept"] = "application/xml"; } if (request.transferMode) { headers["x-ms-transfer-mode"] = request.transferMode; } if (request.ifmatch != null && request.ifnonematch != null) { throw new Error( `DynamicsWebApi.${request.functionName}. Either one of request.ifmatch or request.ifnonematch parameters should be used in a call, not both.` ); } if (request.ifmatch) { ErrorHelper.stringParameterCheck(request.ifmatch, `DynamicsWebApi.${request.functionName}`, "request.ifmatch"); headers["If-Match"] = request.ifmatch; } if (request.ifnonematch) { ErrorHelper.stringParameterCheck(request.ifnonematch, `DynamicsWebApi.${request.functionName}`, "request.ifnonematch"); headers["If-None-Match"] = request.ifnonematch; } if (request.impersonate) { ErrorHelper.stringParameterCheck(request.impersonate, `DynamicsWebApi.${request.functionName}`, "request.impersonate"); headers["MSCRMCallerID"] = ErrorHelper.guidParameterCheck(request.impersonate, `DynamicsWebApi.${request.functionName}`, "request.impersonate"); } if (request.impersonateAAD) { ErrorHelper.stringParameterCheck(request.impersonateAAD, `DynamicsWebApi.${request.functionName}`, "request.impersonateAAD"); headers["CallerObjectId"] = ErrorHelper.gu