dynamics-web-api
Version:
DynamicsWebApi is a Microsoft Dataverse Web API helper library
1,266 lines (1,245 loc) • 139 kB
JavaScript
/*! dynamics-web-api v2.3.2 (c) 2025 Aleksandr Rogov. License: MIT */
"use strict";
var _dynamicsWebApiExports = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __typeError = (msg) => {
throw TypeError(msg);
};
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
// src/helpers/Crypto.ts
function getCrypto() {
return true ? window.crypto : null.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";
}
function escapeSearchSpecialCharacters(value) {
return value.replace(SEARCH_SPECIAL_CHARACTERS_REGEX, "\\$&");
}
function extractPreferCallbackUrl(value) {
const match = PREFER_CALLBACK_URL_REGEX.exec(value);
return match ? match[1] : null;
}
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, SEARCH_SPECIAL_CHARACTERS_REGEX, PREFER_CALLBACK_URL_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})$/;
SEARCH_SPECIAL_CHARACTERS_REGEX = /[+\-&|!(){}[\]^"~*?:\\\/]/g;
PREFER_CALLBACK_URL_REGEX = /^odata\.callback;\s*url=["']?(.+?)["']?$/;
}
});
// 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()];
}
function buildFunctionParameters(parameters) {
return parameters ? processParameters(parameters) : { key: "()" };
}
function getFetchXmlPagingCookie(pageCookies = "", currentPageNumber = 1) {
pageCookies = decodeURIComponent(decodeURIComponent(pageCookies));
const result = parsePagingCookie(pageCookies);
return {
cookie: result?.sanitizedCookie || "",
page: result?.page || currentPageNumber,
nextPage: result?.page ? result.page + 1 : currentPageNumber + 1
};
}
function isNull(value) {
return typeof value === "undefined" || value == null;
}
function generateUUID() {
return getCrypto().randomUUID();
}
function getXrmContext() {
if (typeof GetGlobalContext !== "undefined") {
return GetGlobalContext();
} else {
if (typeof Xrm !== "undefined") {
if (!isNull(Xrm.Utility) && !isNull(Xrm.Utility.getGlobalContext)) {
return Xrm.Utility.getGlobalContext();
} else if (!isNull(Xrm.Page) && !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."
);
}
function getClientUrl() {
const context = getXrmContext();
let clientUrl = context.getClientUrl();
if (clientUrl.match(/\/$/)) {
clientUrl = clientUrl.substring(0, clientUrl.length - 1);
}
return clientUrl;
}
function isRunningWithinPortals() {
return true ? !!window.shell : false;
}
function isObject(obj) {
return typeof obj === "object" && !!obj && !Array.isArray(obj) && Object.prototype.toString.call(obj) !== "[object Date]";
}
function copyObject(src, excludeProps) {
let target = {};
for (let prop in src) {
if (src.hasOwnProperty(prop) && !excludeProps?.includes(prop)) {
if (isObject(src[prop])) {
target[prop] = copyObject(src[prop]);
} else if (Array.isArray(src[prop])) {
target[prop] = src[prop].slice();
} else {
target[prop] = src[prop];
}
}
}
return target;
}
function copyRequest(src, excludeProps = []) {
if (!excludeProps.includes("signal")) excludeProps.push("signal");
const result = copyObject(src, excludeProps);
result.signal = src.signal;
return result;
}
function setFileChunk(request, fileBuffer, chunkSize, offset) {
offset = offset || 0;
const count2 = offset + chunkSize > fileBuffer.length ? fileBuffer.length % chunkSize : chunkSize;
let content;
if (true) {
content = new Uint8Array(count2);
for (let i = 0; i < count2; i++) {
content[i] = fileBuffer[offset + i];
}
} else {
content = fileBuffer.slice(offset, offset + count2);
}
request.data = content;
request.contentRange = "bytes " + offset + "-" + (offset + count2 - 1) + "/" + fileBuffer.length;
}
function convertToFileBuffer(binaryString) {
if (false) 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;
}
var downloadChunkSize;
var init_Utility = __esm({
"src/utils/Utility.ts"() {
"use strict";
init_Crypto();
init_Regex();
downloadChunkSize = 4194304;
}
});
// 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?.length ? textReg[0] : void 0;
}
function handlePlainContent(batchResponse, parseParams, requestNumber) {
const plainContent = getPlainContent(batchResponse);
return handlePlainResponse(plainContent);
}
function handleEmptyContent(batchResponse, parseParams, requestNumber) {
if (parseParams?.[requestNumber]?.valueIfEmpty !== void 0) {
return parseParams[requestNumber].valueIfEmpty;
} else {
const entityUrl = ODATA_ENTITYID_REGEX.exec(batchResponse);
return extractUuidFromUrl(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 = getFetchXmlPagingCookie(object["@" + DWA.Prefer.Annotations.FetchXmlPagingCookie], parseParams.pageNumber);
}
}
return object;
}
function base64ToString(base64) {
return true ? window.atob(base64) : Buffer.from(base64, "base64").toString("binary");
}
function parseFileResponse(response, responseHeaders, parseParams) {
let data = response;
if (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?.startsWith("application/json") == true;
}
function handleBatchResponse(response, parseParams) {
const batch = parseBatchResponse(response, parseParams);
return 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) {
if (parseParams?.[0]?.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"]);
}
if (responseHeaders["x-ms-dyn-backgroundoperationid"]) {
result.backgroundOperationId = responseHeaders["x-ms-dyn-backgroundoperationid"];
}
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/helpers/parseResponseHeaders.ts
function parseResponseHeaders(headerStr) {
const headers = {};
if (!headerStr) {
return headers;
}
const headerPairs = headerStr.split("\r\n");
for (let i = 0, ilen = headerPairs.length; i < ilen; i++) {
const headerPair = headerPairs[i];
const index = headerPair.indexOf(": ");
if (index > 0) {
headers[headerPair.substring(0, index)] = headerPair.substring(index + 2);
}
}
return headers;
}
var init_parseResponseHeaders = __esm({
"src/client/helpers/parseResponseHeaders.ts"() {
"use strict";
}
});
// src/client/xhr.ts
var xhr_exports = {};
__export(xhr_exports, {
XhrWrapper: () => XhrWrapper,
executeRequest: () => executeRequest
});
function executeRequest(options) {
return new Promise((resolve, reject) => {
_executeRequest(options, resolve, reject);
});
}
function _executeRequest(options, successCallback, errorCallback) {
const data = options.data;
const headers = options.headers;
const responseParams = options.responseParams;
const signal = options.abortSignal;
if (signal?.aborted) {
errorCallback(
ErrorHelper.handleHttpError({
name: "AbortError",
code: 20,
message: "The user aborted a request."
})
);
return;
}
let request = new XMLHttpRequest();
request.open(options.method, options.uri, options.isAsync || false);
for (let key in headers) {
request.setRequestHeader(key, headers[key]);
}
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (signal) signal.removeEventListener("abort", abort);
if (!request || request.status === 0) return;
if (request.status >= 200 && request.status < 300 || request.status === 304) {
const responseHeaders = parseResponseHeaders(request.getAllResponseHeaders());
const responseData = parseResponse(request.responseText, responseHeaders, responseParams[options.requestId]);
const response = {
data: responseData,
headers: responseHeaders,
status: request.status
};
request = null;
successCallback(response);
} else {
let error;
let headers2;
try {
headers2 = parseResponseHeaders(request.getAllResponseHeaders());
const errorParsed = parseResponse(request.responseText, headers2, responseParams[options.requestId]);
if (Array.isArray(errorParsed)) {
errorCallback(errorParsed);
return;
}
error = errorParsed.error;
} catch (e) {
if (request.response.length > 0) {
error = { message: request.response };
} else {
error = { message: "Unexpected Error" };
}
}
const errorParameters = {
status: request.status,
statusText: request.statusText,
headers: headers2
};
request = null;
errorCallback(ErrorHelper.handleHttpError(error, errorParameters));
}
}
};
if (options.timeout) {
request.timeout = options.timeout;
}
request.onerror = function() {
const headers2 = parseResponseHeaders(request.getAllResponseHeaders());
errorCallback(
ErrorHelper.handleHttpError({
status: request.status,
statusText: request.statusText,
message: request.responseText || "Network Error",
headers: headers2
})
);
request = null;
};
request.ontimeout = function() {
const headers2 = parseResponseHeaders(request.getAllResponseHeaders());
errorCallback(
ErrorHelper.handleHttpError({
name: "TimeoutError",
status: request.status,
statusText: request.statusText,
message: request.responseText || "Request Timed Out",
headers: headers2
})
);
request = null;
};
request.onabort = function() {
if (!request) return;
const headers2 = parseResponseHeaders(request.getAllResponseHeaders());
errorCallback(
ErrorHelper.handleHttpError({
status: request.status,
statusText: request.statusText,
message: "Request aborted",
headers: headers2
})
);
request = null;
};
const abort = () => {
if (!request) return;
const headers2 = parseResponseHeaders(request.getAllResponseHeaders());
errorCallback(
ErrorHelper.handleHttpError({
name: "AbortError",
code: 20,
status: request.status,
statusText: request.statusText,
message: "The user aborted a request.",
headers: headers2
})
);
request.abort();
request = null;
};
if (signal) {
signal.addEventListener("abort", abort);
}
data ? request.send(data) : request.send();
if (XhrWrapper.afterSendEvent) XhrWrapper.afterSendEvent();
}
var XhrWrapper;
var init_xhr = __esm({
"src/client/xhr.ts"() {
"use strict";
init_ErrorHelper();
init_parseResponse();
init_parseResponseHeaders();
XhrWrapper = class {
};
}
});
// src/dynamics-web-api.ts
var dynamics_web_api_exports = {};
__export(dynamics_web_api_exports, {
DynamicsWebApi: () => DynamicsWebApi
});
// src/utils/Config.ts
init_Utility();
init_ErrorHelper();
// src/requests/constants.ts
var LIBRARY_NAME = "DynamicsWebApi";
// src/utils/Config.ts
var FUNCTION_NAME = `${LIBRARY_NAME}.setConfig`;
var apiConfigs = ["dataApi", "searchApi", "serviceApi"];
var getApiUrl = (serverUrl, apiConfig) => {
if (isRunningWithinPortals()) {
return new URL("_api", window.location.origin).toString() + "/";
} else {
if (!serverUrl) serverUrl = getClientUrl();
let url = "api";
if (apiConfig.path) {
url += `/${apiConfig.path}`;
}
if (apiConfig.version) {
url += `/v${apiConfig.version}`;
}
return new URL(url, serverUrl).toString() + "/";
}
};
var mergeSearchApiOptions = (internalApiConfig, options) => {
if (!options) return;
if (options.escapeSpecialCharacters != null) {
ErrorHelper.boolParameterCheck(options.escapeSpecialCharacters, FUNCTION_NAME, `config.searchApi.options.escapeSpecialCharacters`);
internalApiConfig.escapeSpecialCharacters = options.escapeSpecialCharacters;
}
if (options.enableResponseCompatibility != null) {
ErrorHelper.boolParameterCheck(options.enableResponseCompatibility, FUNCTION_NAME, `config.searchApi.options.enableResponseCompatibility`);
internalApiConfig.enableSearchApiResponseCompatibility = options.enableResponseCompatibility;
}
};
var mergeApiConfig = (internalConfig, apiType, config) => {
const internalApiConfig = internalConfig[apiType];
const apiConfig = config?.[apiType];
if (apiConfig?.version) {
ErrorHelper.stringParameterCheck(apiConfig.version, FUNCTION_NAME, `config.${apiType}.version`);
internalApiConfig.version = apiConfig.version;
}
if (apiConfig?.path) {
ErrorHelper.stringParameterCheck(apiConfig.path, FUNCTION_NAME, `config.${apiType}.path`);
internalApiConfig.path = apiConfig.path;
}
if (apiType === "searchApi") {
mergeSearchApiOptions(internalApiConfig, apiConfig?.options);
}
internalApiConfig.url = getApiUrl(internalConfig.serverUrl, internalApiConfig);
};
function mergeConfig(internalConfig, config) {
if (config?.serverUrl) {
ErrorHelper.stringParameterCheck(config.serverUrl, FUNCTION_NAME, "config.serverUrl");
internalConfig.serverUrl = config.serverUrl;
}
apiConfigs.forEach((apiType) => {
mergeApiConfig(internalConfig, apiType, config);
});
if (config?.impersonate) {
internalConfig.impersonate = ErrorHelper.guidParameterCheck(config.impersonate, FUNCTION_NAME, "config.impersonate");
}
if (config?.impersonateAAD) {
internalConfig.impersonateAAD = ErrorHelper.guidParameterCheck(config.impersonateAAD, FUNCTION_NAME, "config.impersonateAAD");
}
if (config?.onTokenRefresh) {
ErrorHelper.callbackParameterCheck(config.onTokenRefresh, FUNCTION_NAME, "config.onTokenRefresh");
internalConfig.onTokenRefresh = config.onTokenRefresh;
}
if (config?.includeAnnotations) {
ErrorHelper.stringParameterCheck(config.includeAnnotations, FUNCTION_NAME, "config.includeAnnotations");
internalConfig.includeAnnotations = config.includeAnnotations;
}
if (config?.timeout) {
ErrorHelper.numberParameterCheck(config.timeout, FUNCTION_NAME, "config.timeout");
internalConfig.timeout = config.timeout;
}
if (config?.maxPageSize) {
ErrorHelper.numberParameterCheck(config.maxPageSize, FUNCTION_NAME, "config.maxPageSize");
internalConfig.maxPageSize = config.maxPageSize;
}
if (config?.returnRepresentation != null) {
ErrorHelper.boolParameterCheck(config.returnRepresentation, FUNCTION_NAME, "config.returnRepresentation");
internalConfig.returnRepresentation = config.returnRepresentation;
}
if (config?.useEntityNames != null) {
ErrorHelper.boolParameterCheck(config.useEntityNames, FUNCTION_NAME, "config.useEntityNames");
internalConfig.useEntityNames = config.useEntityNames;
}
if (config?.headers) {
internalConfig.headers = config.headers;
}
if (false) {
ErrorHelper.parameterCheck(config.proxy, FUNCTION_NAME, "config.proxy");
if (config.proxy.url) {
ErrorHelper.stringParameterCheck(config.proxy.url, FUNCTION_NAME, "config.proxy.url");
if (config.proxy.auth) {
ErrorHelper.parameterCheck(config.proxy.auth, FUNCTION_NAME, "config.proxy.auth");
ErrorHelper.stringParameterCheck(config.proxy.auth.username, FUNCTION_NAME, "config.proxy.auth.username");
ErrorHelper.stringParameterCheck(config.proxy.auth.password, FUNCTION_NAME, "config.proxy.auth.password");
}
}
internalConfig.proxy = config.proxy;
}
}
function defaultConfig() {
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: ""
},
serviceApi: {
url: ""
}
};
}
// src/client/RequestClient.ts
init_Utility();
// src/client/helpers/entityNameMapper.ts
init_Utility();
var entityNames = null;
var setEntityNames = (newEntityNames) => {
entityNames = newEntityNames;
};
var findCollectionName = (entityName) => {
if (isNull(entityNames)) return null;
const collectionName = entityNames[entityName];
if (!collectionName) {
for (const key in entityNames) {
if (entityNames[key] === entityName) {
return entityName;
}
}
}
return collectionName;
};
// src/client/helpers/executeRequest.ts
async function executeRequest2(options) {
return true ? (init_xhr(), __toCommonJS(xhr_exports)).executeRequest(options) : null.executeRequest(options);
}
// src/client/RequestClient.ts
init_ErrorHelper();
// src/client/request/composers/url.ts
init_ErrorHelper();
init_Regex();
init_Utility();
var composeUrl = (request, config, url = "", joinSymbol = "&") => {
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 (request.select?.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 (request.tag) {
ErrorHelper.stringParameterCheck(request.tag, `DynamicsWebApi.${request.functionName}`, "request.tag");
queryArray.push("tag=" + encodeURIComponent(request.tag));
}
if (request.queryParams?.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 (request.fetchXml) {
ErrorHelper.stringParameterCheck(request.fetchXml, `DynamicsWebApi.${request.functionName}`, "request.fetchXml");
queryArray.push("fetchXml=" + encodeURIComponent(request.fetchXml));
}
if (!isNull(request.inChangeSet)) {
ErrorHelper.boolParameterCheck(request.inChangeSet, `DynamicsWebApi.${request.functionName}`, "request.inChangeSet");
}
if (request.isBatch && isNull(request.inChangeSet)) request.inChangeSet = true;
if (request.timeout) {
ErrorHelper.numberParameterCheck(request.timeout, `DynamicsWebApi.${request.functionName}`, "request.timeout");
}
if (request.expand?.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})`;
}
expandQueryArray.push(property + expandConverted);
}
if (expandQueryArray.length) {
queryArray.push("$expand=" + expandQueryArray.join(","));
}
}
}
}
if (!queryArray.length) {
return url;
}
if (joinSymbol === "&") {
url += "?";
}
return url + queryArray.join(joinSymbol);
};
// src/client/request/composers/headers.ts
init_ErrorHelper();
// src/client/request/composers/preferHeader.ts
init_ErrorHelper();
init_Regex();
var composePreferHeader = (request, config) => {
const functionName = `DynamicsWebApi.${request.functionName}`;
const options = {
respondAsync: request.respondAsync,
backgroundOperationCallbackUrl: request.backgroundOperationCallbackUrl ?? config?.backgroundOperationCallbackUrl,
returnRepresentation: request.returnRepresentation ?? config?.returnRepresentation,
includeAnnotations: request.includeAnnotations ?? config?.includeAnnotations,
maxPageSize: request.maxPageSize ?? config?.maxPageSize,
trackChanges: request.trackChanges,
continueOnError: request.continueOnError
};
const prefer = /* @__PURE__ */ new Set();
if (request.prefer?.length) {
ErrorHelper.stringOrArrayParameterCheck(request.prefer, functionName, "request.prefer");
const preferArray = typeof request.prefer === "string" ? request.prefer.split(",") : request.prefer;
for (const item of preferArray) {
const trimmedItem = item.trim();
if (trimmedItem.includes("respond-async")) {
options.respondAsync = true;
} else if (trimmedItem.startsWith("odata.callback")) {
options.backgroundOperationCallbackUrl = extractPreferCallbackUrl(trimmedItem);
} else if (trimmedItem === "return=representation") {
options.returnRepresentation = true;
} else if (trimmedItem.includes("odata.include-annotations=")) {
options.includeAnnotations = removeDoubleQuotes(trimmedItem.replace("odata.include-annotations=", ""));
} else if (trimmedItem.startsWith("odata.maxpagesize=")) {
options.maxPageSize = Number(removeDoubleQuotes(trimmedItem.replace("odata.maxpagesize=", ""))) || 0;
} else if (trimmedItem.includes("odata.track-changes")) {
options.trackChanges = true;
} else if (trimmedItem.includes("odata.continue-on-error")) {
options.continueOnError = true;
} else {
prefer.add(trimmedItem);
}
}
}
for (const key in options) {
const optionFactory = preferOptionsFactory[key];
if (optionFactory && options[key]) {
optionFactory.validator?.(options[key], functionName, `request.${key}`);
if (optionFactory.condition(options[key], options)) {
prefer.add(optionFactory.formatter(options[key], options));
}
}
}
return Array.from(prefer).join(",");
};
var preferOptionsFactory = {
respondAsync: {
validator: ErrorHelper.boolParameterCheck,
condition: (value) => !!value,
formatter: () => "respond-async"
},
backgroundOperationCallbackUrl: {
validator: ErrorHelper.stringParameterCheck,
condition: (value, options) => value && options.respondAsync,
formatter: (url) => `odata.callback;url="${url}"`
},
returnRepresentation: {
validator: ErrorHelper.boolParameterCheck,
condition: (value) => !!value,
formatter: () => "return=representation"
},
includeAnnotations: {
validator: ErrorHelper.stringParameterCheck,
condition: (value) => !!value,
formatter: (annotations) => `odata.include-annotations="${annotations}"`
},
maxPageSize: {
validator: (value, functionName) => value > 0 ? Err