dynamics-web-api
Version:
DynamicsWebApi is a Microsoft Dataverse Web API helper library
1,230 lines (1,215 loc) • 113 kB
JavaScript
/*! 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 = {
"<": "<",
">": ">",
'"': """,
"'": "'"
// 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