more-xrm
Version:
Create more applications using the Microsoft Dynamics Xrm platform, enables querying the dynamics data model from any application.
1,009 lines (1,008 loc) • 47.8 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
System.register("Query/Query", [], function (exports_1, context_1) {
"use strict";
var QueryOperator, QueryProvider;
var __moduleName = context_1 && context_1.id;
function query(entityName, ...attributeNames) {
return new QueryProvider(entityName).select(...attributeNames);
}
exports_1("default", query);
function GetRootQuery(query) {
return (query['RootQuery'] || query).Query;
}
exports_1("GetRootQuery", GetRootQuery);
return {
setters: [],
execute: function () {
(function (QueryOperator) {
QueryOperator["Contains"] = "like";
QueryOperator["NotContains"] = "not-like";
QueryOperator["StartsWith"] = "begins-with";
QueryOperator["Equals"] = "eq";
QueryOperator["NotEquals"] = "neq";
QueryOperator["GreaterThan"] = "gt";
QueryOperator["LessThan"] = "lt";
QueryOperator["In"] = "in";
QueryOperator["NotIn"] = "not-in";
QueryOperator["OnOrBefore"] = "on-or-before";
QueryOperator["OnOrAfter"] = "on-or-after";
QueryOperator["Null"] = "null";
QueryOperator["NotNull"] = "not-null";
QueryOperator["IsCurrentUser"] = "eq-userid";
QueryOperator["IsNotCurrentUser"] = "ne-userid";
QueryOperator["IsCurrentUserTeam"] = "eq-userteams";
})(QueryOperator || (QueryOperator = {}));
exports_1("QueryOperator", QueryOperator);
QueryProvider = class QueryProvider {
constructor(EntityName) {
this.EntityName = EntityName;
this.Query = {
Alias: { EntityName },
EntityName: EntityName,
Attributes: new Set(),
OrderBy: new Set(),
Conditions: [],
Joins: []
};
}
alias(attributeName, alias) {
this.Query.Alias[attributeName] = alias;
return this;
}
path(entityPath) {
this.Query.EntityPath = entityPath;
return this;
}
select(...attributeNames) {
for (const a of this.flatten(attributeNames)) {
this.Query.Attributes.add(a);
}
if (this.RootQuery) {
const rootQuery = GetRootQuery(this);
for (const a of this.flatten(attributeNames)) {
rootQuery.Attributes.add(this.EntityName + '.' + a);
}
}
return this;
}
where(attributeName, operator, ...values) {
this.Query.Conditions.push({
AttributeName: attributeName,
Operator: operator,
Values: this.flatten(values)
});
return this;
}
whereAny(any) {
var conditions = [];
any((attributeName, operator, ...values) => {
conditions.push({
AttributeName: attributeName,
Operator: operator,
Values: this.flatten(values)
});
});
this.Query.Conditions.push(conditions);
return this;
}
orderBy(attributeName, isDescendingOrder) {
if (isDescendingOrder) {
this.Query.OrderBy.add('_' + attributeName);
}
else {
this.Query.OrderBy.add(attributeName);
}
return this;
}
join(entityName, fromAttribute, toAttribute, alias, isOuterJoin) {
var exp = new QueryProvider(entityName);
var join = exp.Query;
exp.RootQuery = this.RootQuery || this;
join.JoinAlias = alias || entityName;
join.JoinFromAttributeName = fromAttribute;
join.JoinToAttributeName = toAttribute || this.EntityName + 'id';
join.IsOuterJoin = isOuterJoin;
this.Query.Joins.push(join);
return exp;
}
flatten(values) {
return [].concat(...values);
}
};
}
};
});
System.register("Query/QueryXml", ["Query/Query"], function (exports_2, context_2) {
"use strict";
var Query_1;
var __moduleName = context_2 && context_2.id;
function GetQueryXml(query, maxRowCount = 0, format = false) {
const dataQuery = Query_1.GetRootQuery(query);
if (format) {
return formatXml(GetDataQueryXml(dataQuery, maxRowCount));
}
else {
return GetDataQueryXml(dataQuery, maxRowCount);
}
}
exports_2("default", GetQueryXml);
function GetDataQueryXml(query, maxRowCount) {
var xml = [];
xml.push('<fetch mapping="logical"');
if (maxRowCount > 0) {
xml.push(` count="${maxRowCount}"`);
}
xml.push('>');
xml.push(`<entity name="${query.EntityName}" >`);
xml.push(getQueryXml(query));
xml.push('</entity>');
xml.push('</fetch>');
return xml.join('');
}
function getQueryXml(query) {
const xml = [];
query.Attributes.forEach(attribute => {
if (query.Alias[attribute]) {
xml.push(`<attribute name="${attribute}" alias="${query.Alias[attribute]}" />`);
}
else {
xml.push(`<attribute name="${attribute}" />`);
}
});
query.OrderBy.forEach(attribute => {
if (attribute.indexOf('_') == 0) {
xml.push(`<order attribute="${attribute.slice(1)}" descending="true" />`);
}
else {
xml.push(`<order attribute="${attribute}" />`);
}
});
if (query.Conditions.length > 0) {
var hasOrCondition = false;
var filters = [];
filters.push('<filter type="and">');
for (var filter of query.Conditions) {
if (filter && filter.hasOwnProperty('length')) {
hasOrCondition = true;
var conditions = filter;
filters.push('</filter>');
filters.push('<filter type="or">');
for (var condition of conditions) {
filters.push(getConditionXml(condition));
}
filters.push('</filter>');
filters.push('<filter type="and">');
}
else {
filters.push(getConditionXml(filter));
}
}
filters.push('</filter>');
if (hasOrCondition) {
filters.unshift('<filter type="and">');
filters.push('</filter>');
}
var skipNextFilter;
for (var i = 0; i < filters.length; i++) {
if (filters[i] && filters[i + 1] && filters[i].indexOf('<filter') > -1 && filters[i + 1].indexOf('/filter>') > -1) {
skipNextFilter = true;
}
else if (!skipNextFilter) {
xml.push(filters[i]);
}
else {
skipNextFilter = false;
}
}
}
if (query.Joins) {
for (var join of query.Joins) {
xml.push(`<link-entity name="${join.EntityName}" alias="${join.JoinAlias}" from="${join.JoinFromAttributeName}" to="${join.JoinToAttributeName}" link-type="${join.IsOuterJoin ? 'outer' : 'inner'}">`);
xml.push(getQueryXml(join));
xml.push('</link-entity>');
}
}
return xml.join('\n');
}
function getConditionXml(condition) {
var xml = [];
if (condition.AttributeName.indexOf('.') > -1) {
condition.AttributeName = `${condition.AttributeName.split('.')[1]}" entityname="${condition.AttributeName.split('.')[0]}`;
}
if (condition.Values && condition.Values.length > 0) {
if (condition.Values.length > 1) {
xml.push(`<condition attribute="${condition.AttributeName}" operator="${condition.Operator}">`);
for (var value of condition.Values) {
xml.push(`<value>${encodeValue(value)}</value>`);
}
xml.push('</condition>');
}
else {
xml.push(`<condition attribute="${condition.AttributeName}" operator="${condition.Operator}" value="${encodeValue(condition.Values[0])}" />`);
}
}
else {
xml.push(`<condition attribute="${condition.AttributeName}" operator="${condition.Operator}" />`);
}
return xml.join('\n');
}
function encodeValue(value) {
if (value === 0)
return '0';
if (value === true)
return 'true';
if (value === false)
return 'false';
if (!value)
return '';
if (typeof (value.toISOString) === 'function')
return value.toISOString();
return xmlEncode(value.toString());
}
function xmlEncode(text) {
if (text && typeof (text) === 'string') {
text = text.replace(/&/g, '&');
text = text.replace(/\"/g, '"');
text = text.replace(/\'/g, ''');
text = text.replace(/</g, '<');
text = text.replace(/>/g, '>');
}
return text;
}
function formatXml(xmlString) {
var indent = "\t";
var tabs = ""; //store the current indentation
return xmlString.replace(/\s*<[^>\/]*>[^<>]*<\/[^>]*>|\s*<.+?>|\s*[^<]+/g, //pattern to match nodes (angled brackets or text)
function (m, i) {
m = m.replace(/^\s+|\s+$/g, ""); //trim the match just in case
if (i < 38 && /^<[?]xml/.test(m))
return m + "\n"; //if the match is a header, ignore it
if (/^<[/]/.test(m)) //if the match is a closing tag
{
tabs = tabs.replace(indent, ""); //remove one indent from the store
m = tabs + m; //add the tabs at the beginning of the match
}
else if (/<.*>.*<\/.*>|<.*[^>]\/>/.test(m)) //if the match contains an entire node
{
//leave the store as is or
m = m.replace(/(<[^\/>]*)><[\/][^>]*>/g, "$1 />"); //join opening with closing tags of the same node to one entire node if no content is between them
m = tabs + m; //add the tabs at the beginning of the match
}
else if (/<.*>/.test(m)) //if the match starts with an opening tag and does not contain an entire node
{
m = tabs + m; //add the tabs at the beginning of the match
tabs += indent; //and add one indent to the store
}
else //if the match contain a text node
{
m = tabs + m; // add the tabs at the beginning of the match
}
//return m+"\n";
return "\n" + m; //content has additional space(match) from header
});
}
return {
setters: [
function (Query_1_1) {
Query_1 = Query_1_1;
}
],
execute: function () {
}
};
});
System.register("Dynamics/DynamicsRequest", ["Query/Query", "Query/QueryXml", "Dynamics/Dynamics"], function (exports_3, context_3) {
"use strict";
var Query_2, QueryXml_1, Dynamics_1;
var __moduleName = context_3 && context_3.id;
function dynamicsQuery(query, maxRowCount, headers) {
const dataQuery = Query_2.GetRootQuery(query);
if (!dataQuery.EntityPath) {
throw new Error('dynamicsQuery requires a Query object with an EntityPath');
}
return dynamicsQueryUrl(`/api/data/${Dynamics_1.WebApiVersion}/${dataQuery.EntityPath}`, query, maxRowCount, headers);
}
exports_3("dynamicsQuery", dynamicsQuery);
function dynamicsQueryUrl(dynamicsEntitySetUrl, query, maxRowCount, headers) {
const querySeparator = (dynamicsEntitySetUrl.indexOf('?') > -1 ? '&' : '?');
return request(`${dynamicsEntitySetUrl}${querySeparator}fetchXml=${escape(QueryXml_1.default(query, maxRowCount))}`, 'GET', undefined, headers);
}
exports_3("dynamicsQueryUrl", dynamicsQueryUrl);
function dynamicsRequest(dynamicsEntitySetUrl, headers) {
return request(dynamicsEntitySetUrl, 'GET', undefined, headers);
}
exports_3("dynamicsRequest", dynamicsRequest);
function dynamicsSave(entitySetName, data, id, headers) {
if (id) {
return request(`/api/data/${Dynamics_1.WebApiVersion}/${entitySetName}(${trimId(id)})`, 'PATCH', data, headers);
}
else {
return request(`/api/data/${Dynamics_1.WebApiVersion}/${entitySetName}()`, 'POST', data, headers);
}
}
exports_3("dynamicsSave", dynamicsSave);
function formatDynamicsResponse(data) {
var items = [];
if (data && data.error) {
throw new Error(data.error);
}
if (data && data.value) {
data = data.value;
}
if (!Array.isArray(data)) {
return formatDynamicsResponse([data])[0];
}
if (data) {
for (var item of data) {
var row = {};
for (var key in item) {
var name = key;
if (name.indexOf('@odata') == 0) {
continue;
}
if (name.indexOf('transactioncurrencyid') > -1) {
continue;
}
if (name.indexOf('@') > -1) {
name = name.substring(0, name.indexOf('@'));
if (name.indexOf('_') == 0) {
name = name.slice(1, -6);
}
name += "_formatted";
}
else if (name.indexOf('_') == 0) {
name = name.slice(1, -6);
}
if (name.indexOf('_x002e_') > -1) {
var obj = name.substring(0, name.indexOf('_x002e_'));
name = name.substring(name.indexOf('_x002e_') + 7);
if (!row[obj]) {
row[obj] = {};
}
row[obj][name] = item[key];
}
else {
row[name] = item[key];
}
}
items.push(row);
}
}
return items;
}
exports_3("formatDynamicsResponse", formatDynamicsResponse);
function request(url, method, body, headers) {
return fetch(url, {
method: method,
headers: Object.assign({ 'Content-Type': 'application/json; charset=utf-8' }, Dynamics_1.DynamicsHeaders, headers),
body: body
})
.then(response => response.json())
.then(data => formatDynamicsResponse(data));
}
function trimId(id) {
return (id || '').replace(/{|}/g, '');
}
return {
setters: [
function (Query_2_1) {
Query_2 = Query_2_1;
},
function (QueryXml_1_1) {
QueryXml_1 = QueryXml_1_1;
},
function (Dynamics_1_1) {
Dynamics_1 = Dynamics_1_1;
}
],
execute: function () {
}
};
});
System.register("Dynamics/DynamicsBatch", ["Query/Query", "Query/QueryXml", "Dynamics/Dynamics", "Dynamics/DynamicsRequest"], function (exports_4, context_4) {
"use strict";
var Query_3, QueryXml_2, Dynamics_2, DynamicsRequest_1, Batch;
var __moduleName = context_4 && context_4.id;
function dynamicsBatch(headers) {
return new Batch(headers);
}
exports_4("dynamicsBatch", dynamicsBatch);
function dynamicsBatchRequest(...url) {
const batch = new Batch();
batch.requestAllUrls(url);
return batch.execute();
}
exports_4("dynamicsBatchRequest", dynamicsBatchRequest);
function dynamicsBatchQuery(...query) {
const batch = new Batch();
batch.requestAll(query);
return batch.execute();
}
exports_4("dynamicsBatchQuery", dynamicsBatchQuery);
return {
setters: [
function (Query_3_1) {
Query_3 = Query_3_1;
},
function (QueryXml_2_1) {
QueryXml_2 = QueryXml_2_1;
},
function (Dynamics_2_1) {
Dynamics_2 = Dynamics_2_1;
},
function (DynamicsRequest_1_1) {
DynamicsRequest_1 = DynamicsRequest_1_1;
}
],
execute: function () {
Batch = class Batch {
constructor(headers) {
this.headers = headers;
this.Changes = [];
this.RelatedChanges = [];
}
execute() {
return __awaiter(this, void 0, void 0, function* () {
const results = yield Batch.requestBatch(`/api/data/${Dynamics_2.WebApiVersion}/$batch`, this.Changes, this.headers);
if (this.RelatedChanges.length > 0) {
for (let change of this.RelatedChanges) {
let changeIndex = this.Changes.indexOf(change.relatedChange);
let relatedId = results[changeIndex];
change.entityData[`${change.relatedPropertyName}@odata.bind`] = `${change.relatedChange.entitySetName}(${Batch.trimId(relatedId)})`;
}
const related = yield Batch.requestBatch(`/api/data/${Dynamics_2.WebApiVersion}/$batch`, this.RelatedChanges, this.headers);
return results.concat(related);
}
else {
return results;
}
});
}
requestAllUrls(urls) {
this.Changes.push.apply(this.Changes, urls.map(entitySetQuery => ({ entitySetQuery })));
return this;
}
requestAll(queries) {
this.Changes.push.apply(queries.map(query => {
const dataQuery = Query_3.GetRootQuery(query);
this.request(query);
return {
entitySetName: dataQuery.EntityPath,
entitySetQuery: `fetchXml=${escape(QueryXml_2.default(query))}`
};
}));
return this;
}
request(query, maxRowCount = Dynamics_2.DefaultMaxRecords) {
const dataQuery = Query_3.GetRootQuery(query);
if (!dataQuery.EntityPath) {
throw new Error('dynamicsBatch request requires a Query object with an EntityPath');
}
this.Changes.push({
entitySetName: dataQuery.EntityPath,
entitySetQuery: `fetchXml=${escape(QueryXml_2.default(query, maxRowCount))}`
});
return this;
}
deleteEntity(entitySetName, id) {
this.Changes.push({
entitySetName: entitySetName,
entityId: id,
entityData: 'DELETE'
});
return this;
}
saveEntity(entitySetName, data, id) {
this.Changes.push({
entitySetName: entitySetName,
entityId: id,
entityData: data
});
return this;
}
createRelatedEntity(entitySetName, data, navigationPropertyName) {
let lastChange = this.Changes[this.Changes.length - 1];
if (!lastChange || lastChange.entityData == 'DELETE')
throw new Error('createRelatedEntity relies on the previous change which was not found in the batch.');
if (lastChange.entityId) {
data[`${navigationPropertyName}@odata.bind`] = `${lastChange.entitySetName}(${lastChange.entityId})`;
this.Changes.push({
entitySetName: entitySetName,
entityData: data
});
}
else {
this.RelatedChanges.push({
entitySetName: entitySetName,
entityData: data,
relatedChange: lastChange,
relatedPropertyName: navigationPropertyName
});
}
}
static requestBatch(url, requests, headers) {
const batchId = Batch.createId();
return fetch(url, {
method: 'POST',
headers: Object.assign({ 'Content-Type': `multipart/mixed;boundary=batch_${batchId}` }, Dynamics_2.DynamicsHeaders, headers),
body: Batch.formatBatchRequest(batchId, requests)
})
.then(response => Batch.formatBatchResponse(response.text()));
}
static formatBatchRequest(batchId, changes) {
let batchBody = [];
let requestBody = [];
let changeNumber = 1;
let changesetId = Batch.createId();
batchBody.push(`--batch_${batchId}`);
batchBody.push(`Content-Type: multipart/mixed;boundary=changeset_${changesetId}`);
batchBody.push('');
for (let change of changes) {
if (change.entitySetQuery) {
requestBody.push(`--batch_${batchId}`);
requestBody.push('Content-Type: application/http');
requestBody.push('Content-Transfer-Encoding:binary');
requestBody.push('');
if (change.entitySetName) {
requestBody.push(`GET ${encodeURI(`/api/data/${Dynamics_2.WebApiVersion}/${change.entitySetName}?${change.entitySetQuery}`)} HTTP/1.1`);
}
else {
requestBody.push(`GET ${encodeURI(change.entitySetQuery)} HTTP/1.1`);
}
requestBody.push('Accept: application/json');
requestBody.push('Prefer: odata.include-annotations="OData.Community.Display.V1.FormattedValue"');
requestBody.push('');
}
else {
batchBody.push(`--changeset_${changesetId}`);
batchBody.push('Content-Type: application/http');
batchBody.push('Content-Transfer-Encoding:binary');
batchBody.push(`Content-ID: ${changeNumber++}`);
batchBody.push('');
batchBody.push(`${change.entityId ? 'PATCH' : 'POST'} ${encodeURI(`/api/data/${Dynamics_2.WebApiVersion}/${change.entitySetName}(${Batch.trimId(change.entityId)})`)} HTTP/1.1`);
batchBody.push('Content-Type: application/json;type=entry');
batchBody.push('');
batchBody.push(JSON.stringify(change.entityData));
}
}
batchBody.push(`--changeset_${changesetId}--`);
batchBody.push(requestBody.join('\n'));
batchBody.push(`--batch_${batchId}--`);
return batchBody.join('\n');
}
static formatBatchResponse(responseText) {
return responseText.then(response => {
if (response) {
if (response.indexOf('"innererror"') > -1
|| response.indexOf('HTTP/1.1 500 Internal Server Error') > -1
|| response.indexOf('HTTP/1.1 400 Bad Request') > -1) {
throw new Error('Batch Request Error: ' + response);
}
else {
let data = [];
let responses = response.split('--changesetresponse');
for (let response of responses) {
let contentId = ((/Content-ID:\s?(.*)\b/g).exec(response) || []).slice(1)[0];
let entityId = ((/OData-EntityId:[^(]*\((.*)\)/g).exec(response) || []).slice(1)[0];
data[contentId - 1] = entityId;
}
let requests = response.split('--batchresponse');
for (let request of requests) {
//TODO: determine better way of identifying request responses
if (request.indexOf('OData.Community.Display.V1.FormattedValue') > -1) {
let responseIndex = request.indexOf('{');
let json = request.substring(responseIndex);
let item = JSON.parse(json);
data.push(DynamicsRequest_1.formatDynamicsResponse(item));
}
}
return data;
}
}
});
}
static createId() {
return 'id' + Math.random().toString(16).slice(2);
}
static trimId(id) {
return (id || '').replace(/{|}/g, '');
}
};
}
};
});
System.register("Dynamics/Dynamics", ["Query/Query", "Dynamics/DynamicsBatch", "Dynamics/DynamicsRequest"], function (exports_5, context_5) {
"use strict";
var Query_4, DynamicsBatch_1, DynamicsRequest_2, WebApiVersion, DefaultMaxRecords, DynamicsHeaders, DynamicsClient;
var __moduleName = context_5 && context_5.id;
function dynamics(accessToken) {
return new DynamicsClient(accessToken);
}
exports_5("default", dynamics);
return {
setters: [
function (Query_4_1) {
Query_4 = Query_4_1;
},
function (DynamicsBatch_1_1) {
DynamicsBatch_1 = DynamicsBatch_1_1;
},
function (DynamicsRequest_2_1) {
DynamicsRequest_2 = DynamicsRequest_2_1;
}
],
execute: function () {
exports_5("WebApiVersion", WebApiVersion = 'v9.1');
exports_5("DefaultMaxRecords", DefaultMaxRecords = 100);
exports_5("DynamicsHeaders", DynamicsHeaders = {
'OData-MaxVersion': '4.0',
'OData-Version': '4.0',
'Prefer': 'odata.include-annotations=OData.Community.Display.V1.FormattedValue'
});
DynamicsClient = class DynamicsClient {
constructor(accessToken) {
this.dynamicsHeaders = accessToken && {
'Authorization': 'Bearer ' + accessToken
};
}
batch() {
return DynamicsBatch_1.dynamicsBatch(this.dynamicsHeaders);
}
fetch(query, maxRowCount = DefaultMaxRecords) {
return DynamicsRequest_2.dynamicsQuery(query, maxRowCount, this.dynamicsHeaders);
}
optionset(entityName, attributeName) {
return DynamicsRequest_2.dynamicsRequest(`/api/data/${WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes(LogicalName='${attributeName}')/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=LogicalName&$expand=OptionSet($select=Options),GlobalOptionSet($select=Options)`, this.dynamicsHeaders)
.then(attribute => (attribute.OptionSet || attribute.GlobalOptionSet).Options.map((option) => ({
label: (option.Label && option.Label.UserLocalizedLabel && option.Label.UserLocalizedLabel.Label),
value: option.Value
})));
}
query(entityLogicalName, entitySetName) {
return Query_4.default(entityLogicalName).path(entitySetName);
}
save(entitySetName, data, id) {
return DynamicsRequest_2.dynamicsSave(entitySetName, data, id, this.dynamicsHeaders);
}
};
}
};
});
System.register("Dynamics/Model/EntityMetadata", [], function (exports_6, context_6) {
"use strict";
var __moduleName = context_6 && context_6.id;
return {
setters: [],
execute: function () {
}
};
});
System.register("Dynamics/Model/AttributeMetadata", [], function (exports_7, context_7) {
"use strict";
var AttributeTypeCodes;
var __moduleName = context_7 && context_7.id;
return {
setters: [],
execute: function () {
exports_7("AttributeTypeCodes", AttributeTypeCodes = [
'BigInt',
'Boolean',
'Customer',
'DateTime',
'Decimal',
'Double',
'Integer',
'Lookup',
'Memo',
'Money',
'PartyList',
'Picklist',
'State',
'Status',
'String'
]);
}
};
});
System.register("Dynamics/Model/OptionSetMetadata", [], function (exports_8, context_8) {
"use strict";
var __moduleName = context_8 && context_8.id;
return {
setters: [],
execute: function () {
}
};
});
System.register("Dynamics/DynamicsMetadata", ["Dynamics/Dynamics", "Dynamics/DynamicsBatch", "Dynamics/DynamicsRequest"], function (exports_9, context_9) {
"use strict";
var Dynamics_3, DynamicsBatch_2, DynamicsRequest_3, entityProperties, attributeProperties, ExcludedAttributeTypeFilters, ExcludedAttributeNameFilters, DynamicsMetadataClient, DynamicsMetadataMapper;
var __moduleName = context_9 && context_9.id;
function dynamicsMetadata(accessToken) {
return new DynamicsMetadataClient(accessToken);
}
exports_9("default", dynamicsMetadata);
function isLookupAttribute(attribute) {
return attribute.Type === 'Lookup' && attribute['LookupEntityName'];
}
exports_9("isLookupAttribute", isLookupAttribute);
function isOptionSetAttribute(attribute) {
return (attribute.Type === 'Picklist' || attribute.Type === 'State' || attribute.Type === 'Status') && attribute['PicklistOptions'];
}
exports_9("isOptionSetAttribute", isOptionSetAttribute);
function isLookup(attribute) {
return Array.isArray(attribute['Targets']);
}
function isOptionSet(attribute) {
return attribute['OptionSet'] && Array.isArray(attribute['OptionSet'].Options);
}
return {
setters: [
function (Dynamics_3_1) {
Dynamics_3 = Dynamics_3_1;
},
function (DynamicsBatch_2_1) {
DynamicsBatch_2 = DynamicsBatch_2_1;
},
function (DynamicsRequest_3_1) {
DynamicsRequest_3 = DynamicsRequest_3_1;
}
],
execute: function () {
entityProperties = [
"Description", "DisplayName", "EntitySetName",
"IconSmallName", "IsActivity", "IsCustomEntity",
"LogicalName", "PrimaryIdAttribute", "PrimaryNameAttribute"
];
attributeProperties = [
"AttributeType", "DisplayName", "IsCustomAttribute",
"LogicalName", "SchemaName"
];
ExcludedAttributeTypeFilters = [
'Uniqueidentifier',
'CalendarRules',
'EntityName',
'ManagedProperty',
'Owner',
'Virtual',
'Lookup',
'Picklist',
'Status',
'State'
];
ExcludedAttributeNameFilters = [
'exchangerate',
'utcconversiontimezonecode',
'timezoneruleversionnumber',
'importsequencenumber',
'organizationid',
'transactioncurrencyid',
'versionnumber',
'createdonbehalfby',
'modifiedonbehalfby',
'overriddencreatedon',
'entityimage_timestamp'
];
DynamicsMetadataClient = class DynamicsMetadataClient {
constructor(accessToken) {
this.dynamicsHeaders = accessToken && {
'Authorization': 'Bearer ' + accessToken
};
}
attributes(entityName) {
return DynamicsBatch_2.dynamicsBatch(this.dynamicsHeaders)
.requestAllUrls(this.getMetadataUrls(entityName, false))
.execute()
.then(data => this.flatten(data)
.filter((attribute) => attribute.LogicalName.indexOf('yomi') === -1 || attribute.LogicalName.indexOf('base') != attribute.LogicalName.length - 4)
.map(DynamicsMetadataMapper.MapAttribute));
}
entities() {
return DynamicsRequest_3.dynamicsRequest(`/api/data/${Dynamics_3.WebApiVersion}/EntityDefinitions?$select=EntitySetName,Description,DisplayName,LogicalName,PrimaryIdAttribute,PrimaryNameAttribute,IconSmallName,IsActivity,IsCustomEntity`, this.dynamicsHeaders)
.then(data => data
.map(entity => DynamicsMetadataMapper.MapEntity(entity)));
}
entity(entityName) {
return DynamicsRequest_3.dynamicsRequest(`/api/data/${Dynamics_3.WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')?$select=EntitySetName,Description,DisplayName,LogicalName,PrimaryIdAttribute,PrimaryNameAttribute,IconSmallName,IsActivity,IsCustomEntity`, this.dynamicsHeaders)
.then(entity => this.attributes(entityName)
.then(attributes => DynamicsMetadataMapper.MapEntity(entity, attributes)));
}
entityAttributes(...entityNames) {
return DynamicsBatch_2.dynamicsBatch(this.dynamicsHeaders)
.requestAllUrls(this.flatten(entityNames.map(e => this.getMetadataUrls(e, true))))
.execute()
.then(data => {
const entities = [];
const items = this.flatten(data);
let currentEntity;
for (const item of items) {
if (item.EntitySetName) {
currentEntity = DynamicsMetadataMapper.MapEntity(item);
entities.push(currentEntity);
}
else if (item.LogicalName.indexOf('yomi') == -1 && item.LogicalName.indexOf('base') != item.LogicalName.length - 4) {
currentEntity.Attributes.push(DynamicsMetadataMapper.MapAttribute(item));
}
}
return entities;
});
}
getMetadataUrls(entityName, includeEntity = false) {
const attributeTypeFilter = ExcludedAttributeTypeFilters.map(v => `AttributeType ne Microsoft.Dynamics.CRM.AttributeTypeCode'${v}'`).join(' and ');
const attributeNameFilter = ExcludedAttributeNameFilters.map(v => `LogicalName ne '${v}'`).join(' and ');
return [
`/api/data/${Dynamics_3.WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')?$select=${entityProperties}`,
`/api/data/${Dynamics_3.WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes?$select=${attributeProperties}&$filter=${attributeTypeFilter} and ${attributeNameFilter}`,
`/api/data/${Dynamics_3.WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes/Microsoft.Dynamics.CRM.LookupAttributeMetadata?$select=${attributeProperties},Targets`,
`/api/data/${Dynamics_3.WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes/Microsoft.Dynamics.CRM.PicklistAttributeMetadata?$select=${attributeProperties}&$expand=OptionSet($select=Options)`,
`/api/data/${Dynamics_3.WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes/Microsoft.Dynamics.CRM.StatusAttributeMetadata?$select=${attributeProperties}&$expand=OptionSet($select=Options)`,
`/api/data/${Dynamics_3.WebApiVersion}/EntityDefinitions(LogicalName='${entityName}')/Attributes/Microsoft.Dynamics.CRM.StateAttributeMetadata?$select=${attributeProperties}&$expand=OptionSet($select=Options)`
].slice(includeEntity ? 0 : 1);
}
flatten(values) {
return [].concat(...values);
}
};
DynamicsMetadataMapper = class DynamicsMetadataMapper {
static MapAttribute(attribute) {
return {
LogicalName: attribute.LogicalName,
DisplayName: (attribute.DisplayName && attribute.DisplayName.UserLocalizedLabel && attribute.DisplayName.UserLocalizedLabel.Label) || attribute.LogicalName,
Type: attribute.AttributeType,
IsCustomAttribute: attribute.IsCustomAttribute,
LookupEntityName: isLookup(attribute) && attribute.Targets[0],
LookupSchemaName: isLookup(attribute) && attribute.SchemaName,
PicklistOptions: isOptionSet(attribute) && attribute.OptionSet.Options.map((opt) => ({
Label: (opt.Label && opt.Label.UserLocalizedLabel && opt.Label.UserLocalizedLabel.Label),
Value: opt.Value
}))
};
}
static MapEntity(entity, attributes) {
return {
Description: (entity.Description && entity.Description.UserLocalizedLabel && entity.Description.UserLocalizedLabel.Label) || '',
DisplayName: (entity.DisplayName && entity.DisplayName.UserLocalizedLabel && entity.DisplayName.UserLocalizedLabel.Label) || entity.LogicalName,
EntitySetName: entity.EntitySetName,
IconSmallName: entity.IconSmallName,
IsActivity: entity.IsActivity,
IsCustomEntity: entity.IsCustomEntity,
LogicalName: entity.LogicalName,
PrimaryIdAttribute: entity.PrimaryIdAttribute,
PrimaryNameAttribute: entity.PrimaryNameAttribute,
Attributes: attributes || []
};
}
};
}
};
});
System.register("tests/dynamicsMetadataTests", ["Dynamics/DynamicsMetadata"], function (exports_10, context_10) {
"use strict";
var DynamicsMetadata_1;
var __moduleName = context_10 && context_10.id;
function dynamicsMetadataRetrieveAll() {
return __awaiter(this, void 0, void 0, function* () {
const meta = DynamicsMetadata_1.default();
const entities = yield meta.entities();
const findAccount = entities.filter(e => e.LogicalName === 'account')[0];
const accountEntity = yield meta.entity('account');
const matchingAccount = findAccount.DisplayName === accountEntity.DisplayName;
if (!matchingAccount) {
throw new Error('Account metadata was not found!');
}
const attributes = yield meta.attributes('account');
const findAccountName = attributes.filter(a => a.LogicalName === 'name')[0];
if (!findAccountName) {
throw new Error('Account name attribute was not found!');
}
});
}
exports_10("dynamicsMetadataRetrieveAll", dynamicsMetadataRetrieveAll);
return {
setters: [
function (DynamicsMetadata_1_1) {
DynamicsMetadata_1 = DynamicsMetadata_1_1;
}
],
execute: function () {
}
};
});
System.register("tests/dynamicsTests", ["Dynamics/Dynamics", "Query/Query"], function (exports_11, context_11) {
"use strict";
var Dynamics_4, Query_5;
var __moduleName = context_11 && context_11.id;
function dynamicsTestAll() {
return __awaiter(this, void 0, void 0, function* () {
const dyn = Dynamics_4.default();
/* Batch Request */
const allAccounts = yield dyn.batch()
.requestAllUrls(['/api/data/v9.1/accounts'])
.execute();
if (allAccounts.length == 0) {
throw new Error('No Accounts found!');
}
/* Create Entity */
const id = yield dyn.save('accounts', { name: 'xrmtest1' });
if (!id) {
throw new Error('Account could not be created!');
}
/* Update Entity */
const uid = yield dyn.save('accounts', { name: 'xrmtest2' }, id);
if (id !== uid) {
throw new Error('Account could not be updated!');
}
/* Fetch Query */
const xrmAccount = yield dyn.fetch(dyn.query('account', 'accounts')
.where('name', Query_5.QueryOperator.StartsWith, 'xrm')
.orderBy('name')
.select('name'))[0];
if (!xrmAccount) {
throw new Error('Account could not be found!');
}
/* Optionset Items */
const statusOptions = yield dyn.optionset('account', 'statuscode');
if (statusOptions.length == 0) {
throw new Error('Optionset items could not be found!');
}
});
}
exports_11("dynamicsTestAll", dynamicsTestAll);
return {
setters: [
function (Dynamics_4_1) {
Dynamics_4 = Dynamics_4_1;
},
function (Query_5_1) {
Query_5 = Query_5_1;
}
],
execute: function () {
}
};
});
System.register("tests/queryTests", ["Query/Query", "Query/QueryXml"], function (exports_12, context_12) {
"use strict";
var Query_6, QueryXml_3;
var __moduleName = context_12 && context_12.id;
function createQueryWithAllExpressions() {
const thisQuery = Query_6.default('account');
thisQuery
.select('accountid', 'name')
.alias('accountid', 'Id')
.orderBy('name')
.orderBy('accountid', true)
.path('accounts')
.where('name', Query_6.QueryOperator.Contains, 'abc')
.where('accountnumber', Query_6.QueryOperator.In, 1, 2, 3, 4)
.whereAny(or => {
or('name', Query_6.QueryOperator.Equals, 'a');
or('name', Query_6.QueryOperator.Equals, 'b');
or('name', Query_6.QueryOperator.Equals, 'c');
})
.join('contact', 'customerid');
const fetchXml = QueryXml_3.default(thisQuery, 999, true);
if (!fetchXml) {
throw new Error('QueryXml could not be generated!');
}
}
exports_12("createQueryWithAllExpressions", createQueryWithAllExpressions);
return {
setters: [
function (Query_6_1) {
Query_6 = Query_6_1;
},
function (QueryXml_3_1) {
QueryXml_3 = QueryXml_3_1;
}
],
execute: function () {
}
};
});