@xrmforge/typegen 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +590 -2
- package/dist/index.js +779 -1
- package/dist/index.js.map +1 -1
- package/package.json +64 -63
package/dist/index.js
CHANGED
|
@@ -1155,6 +1155,73 @@ var MetadataClient = class {
|
|
|
1155
1155
|
log4.info(`Fetching type info for ${logicalNames.length} entities`);
|
|
1156
1156
|
return Promise.all(logicalNames.map((name) => this.getEntityTypeInfo(name)));
|
|
1157
1157
|
}
|
|
1158
|
+
// ─── Custom API Metadata ───────────────────────────────────────────────
|
|
1159
|
+
/**
|
|
1160
|
+
* Fetch all Custom APIs with their request parameters and response properties.
|
|
1161
|
+
*
|
|
1162
|
+
* Queries the customapi, customapirequestparameter, and customapiresponseproperty
|
|
1163
|
+
* tables and joins them into CustomApiTypeInfo objects.
|
|
1164
|
+
*
|
|
1165
|
+
* @param solutionFilter - Optional: filter by solution unique name
|
|
1166
|
+
* @returns Array of complete Custom API definitions
|
|
1167
|
+
*/
|
|
1168
|
+
async getCustomApis(solutionFilter) {
|
|
1169
|
+
log4.info("Fetching Custom APIs...");
|
|
1170
|
+
let apiUrl = "/customapis?$select=uniquename,bindingtype,isfunction,boundentitylogicalname,displayname,description";
|
|
1171
|
+
if (solutionFilter) {
|
|
1172
|
+
const safeSolution = DataverseHttpClient.sanitizeIdentifier(solutionFilter);
|
|
1173
|
+
apiUrl += `&$filter=solutionid/uniquename eq '${safeSolution}'`;
|
|
1174
|
+
}
|
|
1175
|
+
const apis = await this.http.get(apiUrl);
|
|
1176
|
+
log4.info(`Found ${apis.value.length} Custom APIs`);
|
|
1177
|
+
if (apis.value.length === 0) return [];
|
|
1178
|
+
const params = await this.http.get(
|
|
1179
|
+
"/customapirequestparameters?$select=uniquename,type,isoptional,logicalentityname,description,_customapiid_value"
|
|
1180
|
+
);
|
|
1181
|
+
const props = await this.http.get(
|
|
1182
|
+
"/customapiresponseproperties?$select=uniquename,type,logicalentityname,description,_customapiid_value"
|
|
1183
|
+
);
|
|
1184
|
+
const paramsByApi = /* @__PURE__ */ new Map();
|
|
1185
|
+
for (const p of params.value) {
|
|
1186
|
+
const apiId = p._customapiid_value;
|
|
1187
|
+
if (!paramsByApi.has(apiId)) paramsByApi.set(apiId, []);
|
|
1188
|
+
paramsByApi.get(apiId).push({
|
|
1189
|
+
uniquename: p.uniquename,
|
|
1190
|
+
type: p.type,
|
|
1191
|
+
isoptional: p.isoptional,
|
|
1192
|
+
logicalentityname: p.logicalentityname,
|
|
1193
|
+
description: p.description
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
const propsByApi = /* @__PURE__ */ new Map();
|
|
1197
|
+
for (const p of props.value) {
|
|
1198
|
+
const apiId = p._customapiid_value;
|
|
1199
|
+
if (!propsByApi.has(apiId)) propsByApi.set(apiId, []);
|
|
1200
|
+
propsByApi.get(apiId).push({
|
|
1201
|
+
uniquename: p.uniquename,
|
|
1202
|
+
type: p.type,
|
|
1203
|
+
logicalentityname: p.logicalentityname,
|
|
1204
|
+
description: p.description
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
const result = [];
|
|
1208
|
+
for (const api of apis.value) {
|
|
1209
|
+
result.push({
|
|
1210
|
+
api: {
|
|
1211
|
+
uniquename: api.uniquename,
|
|
1212
|
+
bindingtype: api.bindingtype,
|
|
1213
|
+
isfunction: api.isfunction,
|
|
1214
|
+
boundentitylogicalname: api.boundentitylogicalname,
|
|
1215
|
+
displayname: api.displayname,
|
|
1216
|
+
description: api.description
|
|
1217
|
+
},
|
|
1218
|
+
requestParameters: paramsByApi.get(api.customapiid) ?? [],
|
|
1219
|
+
responseProperties: propsByApi.get(api.customapiid) ?? []
|
|
1220
|
+
});
|
|
1221
|
+
}
|
|
1222
|
+
log4.info(`Loaded ${result.length} Custom APIs with parameters and response properties`);
|
|
1223
|
+
return result;
|
|
1224
|
+
}
|
|
1158
1225
|
// ─── Internal Helpers ──────────────────────────────────────────────────
|
|
1159
1226
|
async getRelationships(logicalName) {
|
|
1160
1227
|
const [oneToMany, manyToMany] = await Promise.all([
|
|
@@ -1487,6 +1554,37 @@ var FORM_CONTROL_TYPE_MAP = {
|
|
|
1487
1554
|
Owner: "Xrm.Controls.LookupControl",
|
|
1488
1555
|
PartyList: "Xrm.Controls.LookupControl"
|
|
1489
1556
|
};
|
|
1557
|
+
function getFormMockValueType(attributeType) {
|
|
1558
|
+
const mapping = FORM_MOCK_VALUE_TYPE_MAP[attributeType];
|
|
1559
|
+
if (mapping) return mapping;
|
|
1560
|
+
return "unknown";
|
|
1561
|
+
}
|
|
1562
|
+
var FORM_MOCK_VALUE_TYPE_MAP = {
|
|
1563
|
+
// String types
|
|
1564
|
+
String: "string | null",
|
|
1565
|
+
Memo: "string | null",
|
|
1566
|
+
EntityName: "string | null",
|
|
1567
|
+
// Numeric types
|
|
1568
|
+
Integer: "number | null",
|
|
1569
|
+
BigInt: "number | null",
|
|
1570
|
+
Decimal: "number | null",
|
|
1571
|
+
Double: "number | null",
|
|
1572
|
+
Money: "number | null",
|
|
1573
|
+
// Boolean
|
|
1574
|
+
Boolean: "boolean | null",
|
|
1575
|
+
// OptionSet types (numeric values at runtime)
|
|
1576
|
+
Picklist: "number | null",
|
|
1577
|
+
State: "number | null",
|
|
1578
|
+
Status: "number | null",
|
|
1579
|
+
MultiSelectPicklist: "number[] | null",
|
|
1580
|
+
// Date/Time
|
|
1581
|
+
DateTime: "Date | null",
|
|
1582
|
+
// Lookup types
|
|
1583
|
+
Lookup: "Xrm.LookupValue[] | null",
|
|
1584
|
+
Customer: "Xrm.LookupValue[] | null",
|
|
1585
|
+
Owner: "Xrm.LookupValue[] | null",
|
|
1586
|
+
PartyList: "Xrm.LookupValue[] | null"
|
|
1587
|
+
};
|
|
1490
1588
|
function toSafeIdentifier(logicalName) {
|
|
1491
1589
|
if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(logicalName)) {
|
|
1492
1590
|
return logicalName;
|
|
@@ -1531,6 +1629,42 @@ function shouldIncludeInEntityInterface(attr) {
|
|
|
1531
1629
|
return true;
|
|
1532
1630
|
}
|
|
1533
1631
|
|
|
1632
|
+
// src/generators/activity-party.ts
|
|
1633
|
+
function generateActivityPartyInterface(namespace = "XrmForge.Entities") {
|
|
1634
|
+
const lines = [];
|
|
1635
|
+
lines.push(`declare namespace ${namespace} {`);
|
|
1636
|
+
lines.push("");
|
|
1637
|
+
lines.push(" /**");
|
|
1638
|
+
lines.push(" * Activity Party - Teilnehmer einer Aktivit\xE4t (E-Mail, Termin, etc.)");
|
|
1639
|
+
lines.push(" * Wird von PartyList-Feldern (to, from, cc, bcc, requiredattendees) referenziert.");
|
|
1640
|
+
lines.push(" * @see https://learn.microsoft.com/en-us/power-apps/developer/data-platform/reference/entities/activityparty");
|
|
1641
|
+
lines.push(" */");
|
|
1642
|
+
lines.push(" interface ActivityParty {");
|
|
1643
|
+
lines.push(" /** Primary key */");
|
|
1644
|
+
lines.push(" activitypartyid?: string;");
|
|
1645
|
+
lines.push(" /** Referenz auf die zugeh\xF6rige Aktivit\xE4t */");
|
|
1646
|
+
lines.push(" _activityid_value?: string;");
|
|
1647
|
+
lines.push(" /** Referenz auf den Teilnehmer (account | contact | systemuser | queue | knowledgearticle) */");
|
|
1648
|
+
lines.push(" _partyid_value?: string;");
|
|
1649
|
+
lines.push(" /**");
|
|
1650
|
+
lines.push(" * Rolle des Teilnehmers:");
|
|
1651
|
+
lines.push(" * 1=Sender, 2=To, 3=CC, 4=BCC, 5=Required Attendee,");
|
|
1652
|
+
lines.push(" * 6=Optional Attendee, 7=Organizer, 8=Regarding, 9=Owner,");
|
|
1653
|
+
lines.push(" * 10=Resource, 11=Customer, 12=Chat Participant, 13=Related");
|
|
1654
|
+
lines.push(" */");
|
|
1655
|
+
lines.push(" participationtypemask?: number;");
|
|
1656
|
+
lines.push(" /** E-Mail-Adresse f\xFCr die Zustellung */");
|
|
1657
|
+
lines.push(" addressused?: string;");
|
|
1658
|
+
lines.push(" /** Aufwand des Teilnehmers (bei Serviceterminen) */");
|
|
1659
|
+
lines.push(" effort?: number;");
|
|
1660
|
+
lines.push(" /** Name des Teilnehmers (wenn nicht aufgel\xF6st) */");
|
|
1661
|
+
lines.push(" unresolvedpartyname?: string;");
|
|
1662
|
+
lines.push(" }");
|
|
1663
|
+
lines.push("}");
|
|
1664
|
+
lines.push("");
|
|
1665
|
+
return lines.join("\n");
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1534
1668
|
// src/generators/label-utils.ts
|
|
1535
1669
|
function getSecondaryLabel(label, config) {
|
|
1536
1670
|
if (!config.secondaryLanguage) return void 0;
|
|
@@ -1901,6 +2035,15 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
1901
2035
|
lines.push(" } & Xrm.Ui;");
|
|
1902
2036
|
}
|
|
1903
2037
|
lines.push(" }");
|
|
2038
|
+
const mockValuesName = `${interfaceName}MockValues`;
|
|
2039
|
+
lines.push("");
|
|
2040
|
+
lines.push(` /** Mock value types for "${form.name}" form (used with @xrmforge/testing) */`);
|
|
2041
|
+
lines.push(` type ${mockValuesName} = {`);
|
|
2042
|
+
for (const field of fields) {
|
|
2043
|
+
const mockType = getFormMockValueType(field.attributeType);
|
|
2044
|
+
lines.push(` ${field.logicalName}?: ${mockType};`);
|
|
2045
|
+
}
|
|
2046
|
+
lines.push(" };");
|
|
1904
2047
|
lines.push("}");
|
|
1905
2048
|
lines.push("");
|
|
1906
2049
|
return lines.join("\n");
|
|
@@ -1939,6 +2082,569 @@ function generateEntityForms(forms, entityLogicalName, attributes, options = {})
|
|
|
1939
2082
|
return results;
|
|
1940
2083
|
}
|
|
1941
2084
|
|
|
2085
|
+
// src/generators/entity-fields-generator.ts
|
|
2086
|
+
function labelToPascalMember2(label) {
|
|
2087
|
+
if (!label) return "";
|
|
2088
|
+
const transliterated = transliterateUmlauts(label);
|
|
2089
|
+
const cleaned = transliterated.replace(/[^a-zA-Z0-9\s_]/g, "");
|
|
2090
|
+
const parts = cleaned.split(/[\s_]+/).filter((p) => p.length > 0);
|
|
2091
|
+
if (parts.length === 0) return "";
|
|
2092
|
+
const pascal = parts.map((p) => p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()).join("");
|
|
2093
|
+
if (/^\d/.test(pascal)) return `_${pascal}`;
|
|
2094
|
+
return pascal;
|
|
2095
|
+
}
|
|
2096
|
+
function generateEntityFieldsEnum(info, options = {}) {
|
|
2097
|
+
const labelConfig = options.labelConfig || DEFAULT_LABEL_CONFIG;
|
|
2098
|
+
const namespace = options.namespace || "XrmForge.Entities";
|
|
2099
|
+
const entityName = toPascalCase(info.entity.LogicalName);
|
|
2100
|
+
const enumName = `${entityName}Fields`;
|
|
2101
|
+
const includedAttrs = info.attributes.filter(shouldIncludeInEntityInterface).sort((a, b) => a.LogicalName.localeCompare(b.LogicalName));
|
|
2102
|
+
const lines = [];
|
|
2103
|
+
lines.push(`declare namespace ${namespace} {`);
|
|
2104
|
+
lines.push("");
|
|
2105
|
+
lines.push(` /** All fields of ${entityName} (for Web API $select queries) */`);
|
|
2106
|
+
lines.push(` const enum ${enumName} {`);
|
|
2107
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
2108
|
+
for (const attr of includedAttrs) {
|
|
2109
|
+
const isLookup = isLookupType(attr.AttributeType);
|
|
2110
|
+
const propertyName = isLookup ? toLookupValueProperty(attr.LogicalName) : attr.LogicalName;
|
|
2111
|
+
const primaryLabel = getPrimaryLabel(attr.DisplayName, labelConfig);
|
|
2112
|
+
let memberName = labelToPascalMember2(primaryLabel);
|
|
2113
|
+
if (!memberName) {
|
|
2114
|
+
memberName = toPascalCase(attr.LogicalName);
|
|
2115
|
+
}
|
|
2116
|
+
const originalName = memberName;
|
|
2117
|
+
let counter = 2;
|
|
2118
|
+
while (usedNames.has(memberName)) {
|
|
2119
|
+
memberName = `${originalName}${counter}`;
|
|
2120
|
+
counter++;
|
|
2121
|
+
}
|
|
2122
|
+
usedNames.add(memberName);
|
|
2123
|
+
const dualLabel = getJSDocLabel(attr.DisplayName, labelConfig);
|
|
2124
|
+
if (dualLabel) {
|
|
2125
|
+
lines.push(` /** ${dualLabel} */`);
|
|
2126
|
+
}
|
|
2127
|
+
lines.push(` ${memberName} = '${propertyName}',`);
|
|
2128
|
+
}
|
|
2129
|
+
lines.push(" }");
|
|
2130
|
+
lines.push("}");
|
|
2131
|
+
lines.push("");
|
|
2132
|
+
return lines.join("\n");
|
|
2133
|
+
}
|
|
2134
|
+
function generateEntityNavigationProperties(info, options = {}) {
|
|
2135
|
+
const labelConfig = options.labelConfig || DEFAULT_LABEL_CONFIG;
|
|
2136
|
+
const namespace = options.namespace || "XrmForge.Entities";
|
|
2137
|
+
const entityName = toPascalCase(info.entity.LogicalName);
|
|
2138
|
+
const enumName = `${entityName}NavigationProperties`;
|
|
2139
|
+
const lookupAttrs = info.attributes.filter(shouldIncludeInEntityInterface).filter((a) => isLookupType(a.AttributeType)).sort((a, b) => a.LogicalName.localeCompare(b.LogicalName));
|
|
2140
|
+
if (lookupAttrs.length === 0) return "";
|
|
2141
|
+
const lines = [];
|
|
2142
|
+
lines.push(`declare namespace ${namespace} {`);
|
|
2143
|
+
lines.push("");
|
|
2144
|
+
lines.push(` /** Navigation properties of ${entityName} (for parseLookup and $expand) */`);
|
|
2145
|
+
lines.push(` const enum ${enumName} {`);
|
|
2146
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
2147
|
+
for (const attr of lookupAttrs) {
|
|
2148
|
+
const primaryLabel = getPrimaryLabel(attr.DisplayName, labelConfig);
|
|
2149
|
+
let memberName = labelToPascalMember2(primaryLabel);
|
|
2150
|
+
if (!memberName) {
|
|
2151
|
+
memberName = toPascalCase(attr.LogicalName);
|
|
2152
|
+
}
|
|
2153
|
+
const originalName = memberName;
|
|
2154
|
+
let counter = 2;
|
|
2155
|
+
while (usedNames.has(memberName)) {
|
|
2156
|
+
memberName = `${originalName}${counter}`;
|
|
2157
|
+
counter++;
|
|
2158
|
+
}
|
|
2159
|
+
usedNames.add(memberName);
|
|
2160
|
+
const dualLabel = getJSDocLabel(attr.DisplayName, labelConfig);
|
|
2161
|
+
if (dualLabel) {
|
|
2162
|
+
lines.push(` /** ${dualLabel} */`);
|
|
2163
|
+
}
|
|
2164
|
+
lines.push(` ${memberName} = '${attr.LogicalName}',`);
|
|
2165
|
+
}
|
|
2166
|
+
lines.push(" }");
|
|
2167
|
+
lines.push("}");
|
|
2168
|
+
lines.push("");
|
|
2169
|
+
return lines.join("\n");
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
// src/generators/webapi-helpers.ts
|
|
2173
|
+
function select(...fields) {
|
|
2174
|
+
if (fields.length === 0) return "";
|
|
2175
|
+
return `?$select=${fields.join(",")}`;
|
|
2176
|
+
}
|
|
2177
|
+
function parseLookup(response, navigationProperty) {
|
|
2178
|
+
const key = `_${navigationProperty}_value`;
|
|
2179
|
+
const id = response[key];
|
|
2180
|
+
if (!id) return null;
|
|
2181
|
+
return {
|
|
2182
|
+
id,
|
|
2183
|
+
name: response[`${key}@OData.Community.Display.V1.FormattedValue`] ?? "",
|
|
2184
|
+
entityType: response[`${key}@Microsoft.Dynamics.CRM.lookuplogicalname`] ?? ""
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
function parseLookups(response, navigationProperties) {
|
|
2188
|
+
const result = {};
|
|
2189
|
+
for (const prop of navigationProperties) {
|
|
2190
|
+
result[prop] = parseLookup(response, prop);
|
|
2191
|
+
}
|
|
2192
|
+
return result;
|
|
2193
|
+
}
|
|
2194
|
+
function parseFormattedValue(response, fieldName) {
|
|
2195
|
+
return response[`${fieldName}@OData.Community.Display.V1.FormattedValue`] ?? null;
|
|
2196
|
+
}
|
|
2197
|
+
function selectExpand(fields, expand) {
|
|
2198
|
+
const parts = [];
|
|
2199
|
+
if (fields.length > 0) parts.push(`$select=${fields.join(",")}`);
|
|
2200
|
+
if (expand) parts.push(`$expand=${expand}`);
|
|
2201
|
+
return parts.length > 0 ? `?${parts.join("&")}` : "";
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
// src/generators/xrm-constants.ts
|
|
2205
|
+
var DisplayState = /* @__PURE__ */ ((DisplayState2) => {
|
|
2206
|
+
DisplayState2["Expanded"] = "expanded";
|
|
2207
|
+
DisplayState2["Collapsed"] = "collapsed";
|
|
2208
|
+
return DisplayState2;
|
|
2209
|
+
})(DisplayState || {});
|
|
2210
|
+
var FormNotificationLevel = /* @__PURE__ */ ((FormNotificationLevel2) => {
|
|
2211
|
+
FormNotificationLevel2["Error"] = "ERROR";
|
|
2212
|
+
FormNotificationLevel2["Warning"] = "WARNING";
|
|
2213
|
+
FormNotificationLevel2["Info"] = "INFO";
|
|
2214
|
+
return FormNotificationLevel2;
|
|
2215
|
+
})(FormNotificationLevel || {});
|
|
2216
|
+
var RequiredLevel = /* @__PURE__ */ ((RequiredLevel2) => {
|
|
2217
|
+
RequiredLevel2["None"] = "none";
|
|
2218
|
+
RequiredLevel2["Required"] = "required";
|
|
2219
|
+
RequiredLevel2["Recommended"] = "recommended";
|
|
2220
|
+
return RequiredLevel2;
|
|
2221
|
+
})(RequiredLevel || {});
|
|
2222
|
+
var SubmitMode = /* @__PURE__ */ ((SubmitMode2) => {
|
|
2223
|
+
SubmitMode2["Always"] = "always";
|
|
2224
|
+
SubmitMode2["Never"] = "never";
|
|
2225
|
+
SubmitMode2["Dirty"] = "dirty";
|
|
2226
|
+
return SubmitMode2;
|
|
2227
|
+
})(SubmitMode || {});
|
|
2228
|
+
var SaveMode = /* @__PURE__ */ ((SaveMode2) => {
|
|
2229
|
+
SaveMode2[SaveMode2["Save"] = 1] = "Save";
|
|
2230
|
+
SaveMode2[SaveMode2["SaveAndClose"] = 2] = "SaveAndClose";
|
|
2231
|
+
SaveMode2[SaveMode2["Deactivate"] = 5] = "Deactivate";
|
|
2232
|
+
SaveMode2[SaveMode2["Reactivate"] = 6] = "Reactivate";
|
|
2233
|
+
SaveMode2[SaveMode2["Send"] = 7] = "Send";
|
|
2234
|
+
SaveMode2[SaveMode2["Disqualify"] = 15] = "Disqualify";
|
|
2235
|
+
SaveMode2[SaveMode2["Qualify"] = 16] = "Qualify";
|
|
2236
|
+
SaveMode2[SaveMode2["Assign"] = 47] = "Assign";
|
|
2237
|
+
SaveMode2[SaveMode2["SaveAsCompleted"] = 58] = "SaveAsCompleted";
|
|
2238
|
+
SaveMode2[SaveMode2["SaveAndNew"] = 59] = "SaveAndNew";
|
|
2239
|
+
SaveMode2[SaveMode2["AutoSave"] = 70] = "AutoSave";
|
|
2240
|
+
return SaveMode2;
|
|
2241
|
+
})(SaveMode || {});
|
|
2242
|
+
var ClientType = /* @__PURE__ */ ((ClientType2) => {
|
|
2243
|
+
ClientType2["Web"] = "Web";
|
|
2244
|
+
ClientType2["Outlook"] = "Outlook";
|
|
2245
|
+
ClientType2["Mobile"] = "Mobile";
|
|
2246
|
+
return ClientType2;
|
|
2247
|
+
})(ClientType || {});
|
|
2248
|
+
var ClientState = /* @__PURE__ */ ((ClientState2) => {
|
|
2249
|
+
ClientState2["Online"] = "Online";
|
|
2250
|
+
ClientState2["Offline"] = "Offline";
|
|
2251
|
+
return ClientState2;
|
|
2252
|
+
})(ClientState || {});
|
|
2253
|
+
var OperationType = /* @__PURE__ */ ((OperationType2) => {
|
|
2254
|
+
OperationType2[OperationType2["Action"] = 0] = "Action";
|
|
2255
|
+
OperationType2[OperationType2["Function"] = 1] = "Function";
|
|
2256
|
+
OperationType2[OperationType2["CRUD"] = 2] = "CRUD";
|
|
2257
|
+
return OperationType2;
|
|
2258
|
+
})(OperationType || {});
|
|
2259
|
+
var StructuralProperty = /* @__PURE__ */ ((StructuralProperty2) => {
|
|
2260
|
+
StructuralProperty2[StructuralProperty2["Unknown"] = 0] = "Unknown";
|
|
2261
|
+
StructuralProperty2[StructuralProperty2["PrimitiveType"] = 1] = "PrimitiveType";
|
|
2262
|
+
StructuralProperty2[StructuralProperty2["ComplexType"] = 2] = "ComplexType";
|
|
2263
|
+
StructuralProperty2[StructuralProperty2["EnumerationType"] = 3] = "EnumerationType";
|
|
2264
|
+
StructuralProperty2[StructuralProperty2["Collection"] = 4] = "Collection";
|
|
2265
|
+
StructuralProperty2[StructuralProperty2["EntityType"] = 5] = "EntityType";
|
|
2266
|
+
return StructuralProperty2;
|
|
2267
|
+
})(StructuralProperty || {});
|
|
2268
|
+
var BindingType = /* @__PURE__ */ ((BindingType2) => {
|
|
2269
|
+
BindingType2[BindingType2["Global"] = 0] = "Global";
|
|
2270
|
+
BindingType2[BindingType2["Entity"] = 1] = "Entity";
|
|
2271
|
+
BindingType2[BindingType2["EntityCollection"] = 2] = "EntityCollection";
|
|
2272
|
+
return BindingType2;
|
|
2273
|
+
})(BindingType || {});
|
|
2274
|
+
|
|
2275
|
+
// src/generators/action-runtime.ts
|
|
2276
|
+
function executeRequest(request) {
|
|
2277
|
+
return Xrm.WebApi.online.execute(request);
|
|
2278
|
+
}
|
|
2279
|
+
function executeMultiple(requests) {
|
|
2280
|
+
return Xrm.WebApi.online.executeMultiple(requests);
|
|
2281
|
+
}
|
|
2282
|
+
function cleanRecordId(id) {
|
|
2283
|
+
return id.replace(/[{}]/g, "");
|
|
2284
|
+
}
|
|
2285
|
+
function buildBoundRequest(operationName, entityLogicalName, operationType, recordId, paramMeta, params) {
|
|
2286
|
+
const parameterTypes = {
|
|
2287
|
+
entity: {
|
|
2288
|
+
typeName: `mscrm.${entityLogicalName}`,
|
|
2289
|
+
structuralProperty: 5 /* EntityType */
|
|
2290
|
+
}
|
|
2291
|
+
};
|
|
2292
|
+
if (paramMeta) {
|
|
2293
|
+
for (const [key, meta] of Object.entries(paramMeta)) {
|
|
2294
|
+
parameterTypes[key] = meta;
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2297
|
+
const request = {
|
|
2298
|
+
getMetadata: () => ({
|
|
2299
|
+
boundParameter: "entity",
|
|
2300
|
+
parameterTypes,
|
|
2301
|
+
operationName,
|
|
2302
|
+
operationType
|
|
2303
|
+
}),
|
|
2304
|
+
entity: {
|
|
2305
|
+
id: cleanRecordId(recordId),
|
|
2306
|
+
entityType: entityLogicalName
|
|
2307
|
+
}
|
|
2308
|
+
};
|
|
2309
|
+
if (params) {
|
|
2310
|
+
for (const [key, value] of Object.entries(params)) {
|
|
2311
|
+
request[key] = value;
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
return request;
|
|
2315
|
+
}
|
|
2316
|
+
function buildUnboundRequest(operationName, operationType, paramMeta, params) {
|
|
2317
|
+
const parameterTypes = {};
|
|
2318
|
+
if (paramMeta) {
|
|
2319
|
+
for (const [key, meta] of Object.entries(paramMeta)) {
|
|
2320
|
+
parameterTypes[key] = meta;
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
const request = {
|
|
2324
|
+
getMetadata: () => ({
|
|
2325
|
+
boundParameter: null,
|
|
2326
|
+
parameterTypes,
|
|
2327
|
+
operationName,
|
|
2328
|
+
operationType
|
|
2329
|
+
})
|
|
2330
|
+
};
|
|
2331
|
+
if (params) {
|
|
2332
|
+
for (const [key, value] of Object.entries(params)) {
|
|
2333
|
+
request[key] = value;
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
return request;
|
|
2337
|
+
}
|
|
2338
|
+
function createBoundAction(operationName, entityLogicalName, paramMeta) {
|
|
2339
|
+
return {
|
|
2340
|
+
execute(recordId, params) {
|
|
2341
|
+
const req = buildBoundRequest(
|
|
2342
|
+
operationName,
|
|
2343
|
+
entityLogicalName,
|
|
2344
|
+
0 /* Action */,
|
|
2345
|
+
recordId,
|
|
2346
|
+
paramMeta,
|
|
2347
|
+
params
|
|
2348
|
+
);
|
|
2349
|
+
return executeRequest(req);
|
|
2350
|
+
},
|
|
2351
|
+
request(recordId, params) {
|
|
2352
|
+
return buildBoundRequest(
|
|
2353
|
+
operationName,
|
|
2354
|
+
entityLogicalName,
|
|
2355
|
+
0 /* Action */,
|
|
2356
|
+
recordId,
|
|
2357
|
+
paramMeta,
|
|
2358
|
+
params
|
|
2359
|
+
);
|
|
2360
|
+
}
|
|
2361
|
+
};
|
|
2362
|
+
}
|
|
2363
|
+
function createUnboundAction(operationName, paramMeta) {
|
|
2364
|
+
return {
|
|
2365
|
+
async execute(params) {
|
|
2366
|
+
const req = buildUnboundRequest(
|
|
2367
|
+
operationName,
|
|
2368
|
+
0 /* Action */,
|
|
2369
|
+
paramMeta,
|
|
2370
|
+
params
|
|
2371
|
+
);
|
|
2372
|
+
const response = await executeRequest(req);
|
|
2373
|
+
if (!response.ok) {
|
|
2374
|
+
const errorText = await response.text();
|
|
2375
|
+
throw new Error(errorText);
|
|
2376
|
+
}
|
|
2377
|
+
if (response.status !== 204) {
|
|
2378
|
+
return response.json();
|
|
2379
|
+
}
|
|
2380
|
+
return response;
|
|
2381
|
+
},
|
|
2382
|
+
request(params) {
|
|
2383
|
+
return buildUnboundRequest(
|
|
2384
|
+
operationName,
|
|
2385
|
+
0 /* Action */,
|
|
2386
|
+
paramMeta,
|
|
2387
|
+
params
|
|
2388
|
+
);
|
|
2389
|
+
}
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
function createUnboundFunction(operationName) {
|
|
2393
|
+
return {
|
|
2394
|
+
async execute() {
|
|
2395
|
+
const req = buildUnboundRequest(operationName, 1 /* Function */);
|
|
2396
|
+
const response = await executeRequest(req);
|
|
2397
|
+
if (!response.ok) {
|
|
2398
|
+
const errorText = await response.text();
|
|
2399
|
+
throw new Error(errorText);
|
|
2400
|
+
}
|
|
2401
|
+
return response.json();
|
|
2402
|
+
},
|
|
2403
|
+
request() {
|
|
2404
|
+
return buildUnboundRequest(operationName, 1 /* Function */);
|
|
2405
|
+
}
|
|
2406
|
+
};
|
|
2407
|
+
}
|
|
2408
|
+
function createBoundFunction(operationName, entityLogicalName) {
|
|
2409
|
+
return {
|
|
2410
|
+
async execute(recordId) {
|
|
2411
|
+
const req = buildBoundRequest(
|
|
2412
|
+
operationName,
|
|
2413
|
+
entityLogicalName,
|
|
2414
|
+
1 /* Function */,
|
|
2415
|
+
recordId
|
|
2416
|
+
);
|
|
2417
|
+
const response = await executeRequest(req);
|
|
2418
|
+
if (!response.ok) {
|
|
2419
|
+
const errorText = await response.text();
|
|
2420
|
+
throw new Error(errorText);
|
|
2421
|
+
}
|
|
2422
|
+
return response.json();
|
|
2423
|
+
},
|
|
2424
|
+
request(recordId) {
|
|
2425
|
+
return buildBoundRequest(
|
|
2426
|
+
operationName,
|
|
2427
|
+
entityLogicalName,
|
|
2428
|
+
1 /* Function */,
|
|
2429
|
+
recordId
|
|
2430
|
+
);
|
|
2431
|
+
}
|
|
2432
|
+
};
|
|
2433
|
+
}
|
|
2434
|
+
async function withProgress(message, operation) {
|
|
2435
|
+
Xrm.Utility.showProgressIndicator(message);
|
|
2436
|
+
try {
|
|
2437
|
+
return await operation();
|
|
2438
|
+
} catch (error) {
|
|
2439
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
2440
|
+
Xrm.Navigation.openErrorDialog({ message: msg });
|
|
2441
|
+
throw error;
|
|
2442
|
+
} finally {
|
|
2443
|
+
Xrm.Utility.closeProgressIndicator();
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
// src/metadata/custom-api-types.ts
|
|
2448
|
+
function mapCustomApiParameterType(type, entityName) {
|
|
2449
|
+
switch (type) {
|
|
2450
|
+
case 0 /* Boolean */:
|
|
2451
|
+
return { tsType: "boolean", typeName: "Edm.Boolean", structuralProperty: 1 };
|
|
2452
|
+
case 1 /* DateTime */:
|
|
2453
|
+
return { tsType: "string", typeName: "Edm.DateTimeOffset", structuralProperty: 1 };
|
|
2454
|
+
case 2 /* Decimal */:
|
|
2455
|
+
return { tsType: "number", typeName: "Edm.Decimal", structuralProperty: 1 };
|
|
2456
|
+
case 3 /* Entity */:
|
|
2457
|
+
return {
|
|
2458
|
+
tsType: "Record<string, unknown>",
|
|
2459
|
+
typeName: `mscrm.${entityName || "crmbaseentity"}`,
|
|
2460
|
+
structuralProperty: 5
|
|
2461
|
+
};
|
|
2462
|
+
case 4 /* EntityCollection */:
|
|
2463
|
+
return {
|
|
2464
|
+
tsType: "Array<Record<string, unknown>>",
|
|
2465
|
+
typeName: "Collection(mscrm.crmbaseentity)",
|
|
2466
|
+
structuralProperty: 4
|
|
2467
|
+
};
|
|
2468
|
+
case 5 /* EntityReference */:
|
|
2469
|
+
return {
|
|
2470
|
+
tsType: "{ id: string; entityType: string; name?: string }",
|
|
2471
|
+
typeName: `mscrm.${entityName || "crmbaseentity"}`,
|
|
2472
|
+
structuralProperty: 5
|
|
2473
|
+
};
|
|
2474
|
+
case 6 /* Float */:
|
|
2475
|
+
return { tsType: "number", typeName: "Edm.Double", structuralProperty: 1 };
|
|
2476
|
+
case 7 /* Integer */:
|
|
2477
|
+
return { tsType: "number", typeName: "Edm.Int32", structuralProperty: 1 };
|
|
2478
|
+
case 8 /* Money */:
|
|
2479
|
+
return { tsType: "number", typeName: "Edm.Decimal", structuralProperty: 1 };
|
|
2480
|
+
case 9 /* Picklist */:
|
|
2481
|
+
return { tsType: "number", typeName: "Edm.Int32", structuralProperty: 1 };
|
|
2482
|
+
case 10 /* String */:
|
|
2483
|
+
return { tsType: "string", typeName: "Edm.String", structuralProperty: 1 };
|
|
2484
|
+
case 11 /* StringArray */:
|
|
2485
|
+
return { tsType: "string[]", typeName: "Collection(Edm.String)", structuralProperty: 4 };
|
|
2486
|
+
case 12 /* Guid */:
|
|
2487
|
+
return { tsType: "string", typeName: "Edm.Guid", structuralProperty: 1 };
|
|
2488
|
+
default:
|
|
2489
|
+
return { tsType: "unknown", typeName: "Edm.String", structuralProperty: 0 };
|
|
2490
|
+
}
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2493
|
+
// src/generators/action-generator.ts
|
|
2494
|
+
function deriveActionName(uniquename) {
|
|
2495
|
+
const withoutPrefix = uniquename.includes("_") ? uniquename.substring(uniquename.indexOf("_") + 1) : uniquename;
|
|
2496
|
+
return toPascalCase(withoutPrefix);
|
|
2497
|
+
}
|
|
2498
|
+
function generateParamsInterface(name, params) {
|
|
2499
|
+
if (params.length === 0) return "";
|
|
2500
|
+
const lines = [];
|
|
2501
|
+
lines.push(` interface ${name}Params {`);
|
|
2502
|
+
for (const param of params) {
|
|
2503
|
+
const mapped = mapCustomApiParameterType(param.type, param.logicalentityname);
|
|
2504
|
+
const optional = param.isoptional ? "?" : "";
|
|
2505
|
+
if (param.description) {
|
|
2506
|
+
lines.push(` /** ${param.description} */`);
|
|
2507
|
+
}
|
|
2508
|
+
lines.push(` ${param.uniquename}${optional}: ${mapped.tsType};`);
|
|
2509
|
+
}
|
|
2510
|
+
lines.push(" }");
|
|
2511
|
+
return lines.join("\n");
|
|
2512
|
+
}
|
|
2513
|
+
function generateResultInterface(name, props) {
|
|
2514
|
+
if (props.length === 0) return "";
|
|
2515
|
+
const lines = [];
|
|
2516
|
+
lines.push(` interface ${name}Result {`);
|
|
2517
|
+
for (const prop of props) {
|
|
2518
|
+
const mapped = mapCustomApiParameterType(prop.type, prop.logicalentityname);
|
|
2519
|
+
if (prop.description) {
|
|
2520
|
+
lines.push(` /** ${prop.description} */`);
|
|
2521
|
+
}
|
|
2522
|
+
lines.push(` ${prop.uniquename}: ${mapped.tsType};`);
|
|
2523
|
+
}
|
|
2524
|
+
lines.push(" }");
|
|
2525
|
+
return lines.join("\n");
|
|
2526
|
+
}
|
|
2527
|
+
function generateActionDeclarations(apis, isFunction, entityName, options = {}) {
|
|
2528
|
+
const baseNamespace = isFunction ? options.functionsNamespace || "XrmForge.Functions" : options.actionsNamespace || "XrmForge.Actions";
|
|
2529
|
+
const namespace = entityName ? `${baseNamespace}.${toPascalCase(entityName)}` : baseNamespace;
|
|
2530
|
+
const lines = [];
|
|
2531
|
+
lines.push("// Auto-generated by @xrmforge/typegen - DO NOT EDIT");
|
|
2532
|
+
lines.push("");
|
|
2533
|
+
lines.push(`declare namespace ${namespace} {`);
|
|
2534
|
+
for (const apiInfo of apis) {
|
|
2535
|
+
const name = deriveActionName(apiInfo.api.uniquename);
|
|
2536
|
+
const hasParams = apiInfo.requestParameters.length > 0;
|
|
2537
|
+
const hasResult = apiInfo.responseProperties.length > 0;
|
|
2538
|
+
lines.push("");
|
|
2539
|
+
const description = apiInfo.api.description || apiInfo.api.displayname || apiInfo.api.uniquename;
|
|
2540
|
+
lines.push(` /** ${description} (${apiInfo.api.uniquename}) */`);
|
|
2541
|
+
if (hasParams) {
|
|
2542
|
+
lines.push(generateParamsInterface(name, apiInfo.requestParameters));
|
|
2543
|
+
lines.push("");
|
|
2544
|
+
}
|
|
2545
|
+
if (hasResult) {
|
|
2546
|
+
lines.push(generateResultInterface(name, apiInfo.responseProperties));
|
|
2547
|
+
lines.push("");
|
|
2548
|
+
}
|
|
2549
|
+
const importFrom = options.importPath || "@xrmforge/typegen";
|
|
2550
|
+
if (apiInfo.api.bindingtype === 0 /* Global */) {
|
|
2551
|
+
if (hasParams && hasResult) {
|
|
2552
|
+
lines.push(` const ${name}: import('${importFrom}').UnboundActionWithParamsExecutor<${name}Params, ${name}Result>;`);
|
|
2553
|
+
} else if (hasParams) {
|
|
2554
|
+
lines.push(` const ${name}: import('${importFrom}').UnboundActionWithParamsExecutor<${name}Params, void>;`);
|
|
2555
|
+
} else {
|
|
2556
|
+
lines.push(` const ${name}: import('${importFrom}').UnboundActionExecutor;`);
|
|
2557
|
+
}
|
|
2558
|
+
} else {
|
|
2559
|
+
if (hasParams) {
|
|
2560
|
+
lines.push(` const ${name}: import('${importFrom}').BoundActionWithParamsExecutor<${name}Params>;`);
|
|
2561
|
+
} else {
|
|
2562
|
+
lines.push(` const ${name}: import('${importFrom}').BoundActionExecutor;`);
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
lines.push("}");
|
|
2567
|
+
lines.push("");
|
|
2568
|
+
return lines.join("\n");
|
|
2569
|
+
}
|
|
2570
|
+
function generateActionModule(apis, isFunction, options = {}) {
|
|
2571
|
+
const importPath = options.importPath || "@xrmforge/typegen";
|
|
2572
|
+
const lines = [];
|
|
2573
|
+
lines.push("// Auto-generated by @xrmforge/typegen - DO NOT EDIT");
|
|
2574
|
+
lines.push("");
|
|
2575
|
+
const imports = /* @__PURE__ */ new Set();
|
|
2576
|
+
for (const apiInfo of apis) {
|
|
2577
|
+
if (apiInfo.api.bindingtype === 0 /* Global */) {
|
|
2578
|
+
if (isFunction) {
|
|
2579
|
+
imports.add("createUnboundFunction");
|
|
2580
|
+
} else {
|
|
2581
|
+
imports.add("createUnboundAction");
|
|
2582
|
+
}
|
|
2583
|
+
} else {
|
|
2584
|
+
if (isFunction) {
|
|
2585
|
+
imports.add("createBoundFunction");
|
|
2586
|
+
} else {
|
|
2587
|
+
imports.add("createBoundAction");
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
lines.push(`import { ${[...imports].sort().join(", ")} } from '${importPath}';`);
|
|
2592
|
+
lines.push("");
|
|
2593
|
+
for (const apiInfo of apis) {
|
|
2594
|
+
const name = deriveActionName(apiInfo.api.uniquename);
|
|
2595
|
+
const hasParams = apiInfo.requestParameters.length > 0;
|
|
2596
|
+
const description = apiInfo.api.description || apiInfo.api.displayname || apiInfo.api.uniquename;
|
|
2597
|
+
lines.push(`/** ${description} */`);
|
|
2598
|
+
if (apiInfo.api.bindingtype === 0 /* Global */) {
|
|
2599
|
+
if (isFunction) {
|
|
2600
|
+
lines.push(`export const ${name} = createUnboundFunction('${apiInfo.api.uniquename}');`);
|
|
2601
|
+
} else if (hasParams) {
|
|
2602
|
+
const paramMeta = generateParameterMetaMap(apiInfo.requestParameters);
|
|
2603
|
+
lines.push(`export const ${name} = createUnboundAction('${apiInfo.api.uniquename}', ${paramMeta});`);
|
|
2604
|
+
} else {
|
|
2605
|
+
lines.push(`export const ${name} = createUnboundAction('${apiInfo.api.uniquename}');`);
|
|
2606
|
+
}
|
|
2607
|
+
} else {
|
|
2608
|
+
const entity = apiInfo.api.boundentitylogicalname;
|
|
2609
|
+
if (isFunction) {
|
|
2610
|
+
lines.push(`export const ${name} = createBoundFunction('${apiInfo.api.uniquename}', '${entity}');`);
|
|
2611
|
+
} else if (hasParams) {
|
|
2612
|
+
const paramMeta = generateParameterMetaMap(apiInfo.requestParameters);
|
|
2613
|
+
lines.push(`export const ${name} = createBoundAction('${apiInfo.api.uniquename}', '${entity}', ${paramMeta});`);
|
|
2614
|
+
} else {
|
|
2615
|
+
lines.push(`export const ${name} = createBoundAction('${apiInfo.api.uniquename}', '${entity}');`);
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2618
|
+
lines.push("");
|
|
2619
|
+
}
|
|
2620
|
+
return lines.join("\n");
|
|
2621
|
+
}
|
|
2622
|
+
function generateParameterMetaMap(params) {
|
|
2623
|
+
const entries = [];
|
|
2624
|
+
for (const param of params) {
|
|
2625
|
+
const mapped = mapCustomApiParameterType(param.type, param.logicalentityname);
|
|
2626
|
+
entries.push(
|
|
2627
|
+
` ${param.uniquename}: { typeName: '${mapped.typeName}', structuralProperty: ${mapped.structuralProperty} }`
|
|
2628
|
+
);
|
|
2629
|
+
}
|
|
2630
|
+
return `{
|
|
2631
|
+
${entries.join(",\n")},
|
|
2632
|
+
}`;
|
|
2633
|
+
}
|
|
2634
|
+
function groupCustomApis(apis) {
|
|
2635
|
+
const actions = /* @__PURE__ */ new Map();
|
|
2636
|
+
const functions = /* @__PURE__ */ new Map();
|
|
2637
|
+
for (const api of apis) {
|
|
2638
|
+
const target = api.api.isfunction ? functions : actions;
|
|
2639
|
+
const key = api.api.bindingtype === 0 /* Global */ ? "global" : api.api.boundentitylogicalname || "global";
|
|
2640
|
+
if (!target.has(key)) {
|
|
2641
|
+
target.set(key, []);
|
|
2642
|
+
}
|
|
2643
|
+
target.get(key).push(api);
|
|
2644
|
+
}
|
|
2645
|
+
return { actions, functions };
|
|
2646
|
+
}
|
|
2647
|
+
|
|
1942
2648
|
// src/orchestrator/file-writer.ts
|
|
1943
2649
|
import { mkdir, writeFile, readFile } from "fs/promises";
|
|
1944
2650
|
import { join as join2, dirname } from "path";
|
|
@@ -2032,6 +2738,7 @@ var TypeGenerationOrchestrator = class {
|
|
|
2032
2738
|
generateEntities: config.generateEntities ?? true,
|
|
2033
2739
|
generateForms: config.generateForms ?? true,
|
|
2034
2740
|
generateOptionSets: config.generateOptionSets ?? true,
|
|
2741
|
+
generateActions: config.generateActions ?? false,
|
|
2035
2742
|
useCache: config.useCache ?? false,
|
|
2036
2743
|
cacheDir: config.cacheDir ?? ".xrmforge/cache",
|
|
2037
2744
|
namespacePrefix: config.namespacePrefix ?? "XrmForge"
|
|
@@ -2106,6 +2813,47 @@ var TypeGenerationOrchestrator = class {
|
|
|
2106
2813
|
});
|
|
2107
2814
|
}
|
|
2108
2815
|
}
|
|
2816
|
+
if (this.config.generateActions && !signal?.aborted) {
|
|
2817
|
+
this.logger.info("Fetching Custom APIs...");
|
|
2818
|
+
const customApis = await metadataClient.getCustomApis();
|
|
2819
|
+
if (customApis.length > 0) {
|
|
2820
|
+
const importPath = "@xrmforge/typegen";
|
|
2821
|
+
const grouped = groupCustomApis(customApis);
|
|
2822
|
+
for (const [key, apis] of grouped.actions) {
|
|
2823
|
+
const entityName = key === "global" ? void 0 : key;
|
|
2824
|
+
const declarations = generateActionDeclarations(apis, false, entityName, { importPath });
|
|
2825
|
+
const module = generateActionModule(apis, false, { importPath });
|
|
2826
|
+
allFiles.push({
|
|
2827
|
+
relativePath: `actions/${key}.d.ts`,
|
|
2828
|
+
content: addGeneratedHeader(declarations),
|
|
2829
|
+
type: "action"
|
|
2830
|
+
});
|
|
2831
|
+
allFiles.push({
|
|
2832
|
+
relativePath: `actions/${key}.ts`,
|
|
2833
|
+
content: addGeneratedHeader(module),
|
|
2834
|
+
type: "action"
|
|
2835
|
+
});
|
|
2836
|
+
}
|
|
2837
|
+
for (const [key, apis] of grouped.functions) {
|
|
2838
|
+
const entityName = key === "global" ? void 0 : key;
|
|
2839
|
+
const declarations = generateActionDeclarations(apis, true, entityName, { importPath });
|
|
2840
|
+
const module = generateActionModule(apis, true, { importPath });
|
|
2841
|
+
allFiles.push({
|
|
2842
|
+
relativePath: `functions/${key}.d.ts`,
|
|
2843
|
+
content: addGeneratedHeader(declarations),
|
|
2844
|
+
type: "action"
|
|
2845
|
+
});
|
|
2846
|
+
allFiles.push({
|
|
2847
|
+
relativePath: `functions/${key}.ts`,
|
|
2848
|
+
content: addGeneratedHeader(module),
|
|
2849
|
+
type: "action"
|
|
2850
|
+
});
|
|
2851
|
+
}
|
|
2852
|
+
this.logger.info(`Generated ${grouped.actions.size} action groups, ${grouped.functions.size} function groups`);
|
|
2853
|
+
} else {
|
|
2854
|
+
this.logger.info("No Custom APIs found");
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2109
2857
|
if (allFiles.length > 0) {
|
|
2110
2858
|
const indexContent = generateBarrelIndex(allFiles);
|
|
2111
2859
|
const indexFile = {
|
|
@@ -2232,12 +2980,17 @@ var TypeGenerationOrchestrator = class {
|
|
|
2232
2980
|
export {
|
|
2233
2981
|
ApiRequestError,
|
|
2234
2982
|
AuthenticationError,
|
|
2983
|
+
BindingType,
|
|
2984
|
+
ClientState,
|
|
2985
|
+
ClientType,
|
|
2235
2986
|
ConfigError,
|
|
2236
2987
|
ConsoleLogSink,
|
|
2237
2988
|
DEFAULT_LABEL_CONFIG,
|
|
2238
2989
|
DataverseHttpClient,
|
|
2990
|
+
DisplayState,
|
|
2239
2991
|
ErrorCode,
|
|
2240
2992
|
FastXmlParser,
|
|
2993
|
+
FormNotificationLevel,
|
|
2241
2994
|
GenerationError,
|
|
2242
2995
|
JsonLogSink,
|
|
2243
2996
|
LogLevel,
|
|
@@ -2245,18 +2998,34 @@ export {
|
|
|
2245
2998
|
MetadataCache,
|
|
2246
2999
|
MetadataClient,
|
|
2247
3000
|
MetadataError,
|
|
3001
|
+
OperationType,
|
|
3002
|
+
RequiredLevel,
|
|
3003
|
+
SaveMode,
|
|
2248
3004
|
SilentLogSink,
|
|
3005
|
+
StructuralProperty,
|
|
3006
|
+
SubmitMode,
|
|
2249
3007
|
TypeGenerationOrchestrator,
|
|
2250
3008
|
XrmForgeError,
|
|
2251
3009
|
configureLogging,
|
|
3010
|
+
createBoundAction,
|
|
3011
|
+
createBoundFunction,
|
|
2252
3012
|
createCredential,
|
|
2253
3013
|
createLogger,
|
|
3014
|
+
createUnboundAction,
|
|
3015
|
+
createUnboundFunction,
|
|
2254
3016
|
defaultXmlParser,
|
|
2255
3017
|
disambiguateEnumMembers,
|
|
3018
|
+
executeMultiple,
|
|
3019
|
+
executeRequest,
|
|
2256
3020
|
extractControlFields,
|
|
2257
3021
|
getJSDocLabel as formatDualLabel,
|
|
3022
|
+
generateActionDeclarations,
|
|
3023
|
+
generateActionModule,
|
|
3024
|
+
generateActivityPartyInterface,
|
|
3025
|
+
generateEntityFieldsEnum,
|
|
2258
3026
|
generateEntityForms,
|
|
2259
3027
|
generateEntityInterface,
|
|
3028
|
+
generateEntityNavigationProperties,
|
|
2260
3029
|
generateEntityOptionSets,
|
|
2261
3030
|
generateEnumMembers,
|
|
2262
3031
|
generateFormInterface,
|
|
@@ -2264,18 +3033,27 @@ export {
|
|
|
2264
3033
|
getEntityPropertyType,
|
|
2265
3034
|
getFormAttributeType,
|
|
2266
3035
|
getFormControlType,
|
|
3036
|
+
getFormMockValueType,
|
|
2267
3037
|
getJSDocLabel,
|
|
2268
3038
|
getLabelLanguagesParam,
|
|
2269
3039
|
getPrimaryLabel,
|
|
2270
3040
|
getSecondaryLabel,
|
|
3041
|
+
groupCustomApis,
|
|
2271
3042
|
isLookupType,
|
|
3043
|
+
isPartyListType,
|
|
2272
3044
|
isRateLimitError,
|
|
2273
3045
|
isXrmForgeError,
|
|
2274
3046
|
labelToIdentifier,
|
|
2275
3047
|
parseForm,
|
|
3048
|
+
parseFormattedValue,
|
|
3049
|
+
parseLookup,
|
|
3050
|
+
parseLookups,
|
|
3051
|
+
select,
|
|
3052
|
+
selectExpand,
|
|
2276
3053
|
shouldIncludeInEntityInterface,
|
|
2277
3054
|
toLookupValueProperty,
|
|
2278
3055
|
toPascalCase,
|
|
2279
|
-
toSafeIdentifier
|
|
3056
|
+
toSafeIdentifier,
|
|
3057
|
+
withProgress
|
|
2280
3058
|
};
|
|
2281
3059
|
//# sourceMappingURL=index.js.map
|