@xrmforge/typegen 0.1.0 → 0.3.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 +622 -2
- package/dist/index.js +815 -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,587 @@ 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/entity-names-generator.ts
|
|
2173
|
+
function generateEntityNamesEnum(entityNames, options = {}) {
|
|
2174
|
+
const namespace = options.namespace ?? "XrmForge";
|
|
2175
|
+
const sorted = [...entityNames].sort();
|
|
2176
|
+
const lines = [];
|
|
2177
|
+
lines.push(`declare namespace ${namespace} {`);
|
|
2178
|
+
lines.push(" /** Entity logical names for Xrm.WebApi calls (compile-time only, zero runtime) */");
|
|
2179
|
+
lines.push(" const enum EntityNames {");
|
|
2180
|
+
for (const name of sorted) {
|
|
2181
|
+
const pascal = toPascalCase(name);
|
|
2182
|
+
lines.push(` ${pascal} = '${name}',`);
|
|
2183
|
+
}
|
|
2184
|
+
lines.push(" }");
|
|
2185
|
+
lines.push("}");
|
|
2186
|
+
lines.push("");
|
|
2187
|
+
return lines.join("\n");
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
// src/generators/webapi-helpers.ts
|
|
2191
|
+
function select(...fields) {
|
|
2192
|
+
if (fields.length === 0) return "";
|
|
2193
|
+
return `?$select=${fields.join(",")}`;
|
|
2194
|
+
}
|
|
2195
|
+
function parseLookup(response, navigationProperty) {
|
|
2196
|
+
const key = `_${navigationProperty}_value`;
|
|
2197
|
+
const id = response[key];
|
|
2198
|
+
if (!id) return null;
|
|
2199
|
+
return {
|
|
2200
|
+
id,
|
|
2201
|
+
name: response[`${key}@OData.Community.Display.V1.FormattedValue`] ?? "",
|
|
2202
|
+
entityType: response[`${key}@Microsoft.Dynamics.CRM.lookuplogicalname`] ?? ""
|
|
2203
|
+
};
|
|
2204
|
+
}
|
|
2205
|
+
function parseLookups(response, navigationProperties) {
|
|
2206
|
+
const result = {};
|
|
2207
|
+
for (const prop of navigationProperties) {
|
|
2208
|
+
result[prop] = parseLookup(response, prop);
|
|
2209
|
+
}
|
|
2210
|
+
return result;
|
|
2211
|
+
}
|
|
2212
|
+
function parseFormattedValue(response, fieldName) {
|
|
2213
|
+
return response[`${fieldName}@OData.Community.Display.V1.FormattedValue`] ?? null;
|
|
2214
|
+
}
|
|
2215
|
+
function selectExpand(fields, expand) {
|
|
2216
|
+
const parts = [];
|
|
2217
|
+
if (fields.length > 0) parts.push(`$select=${fields.join(",")}`);
|
|
2218
|
+
if (expand) parts.push(`$expand=${expand}`);
|
|
2219
|
+
return parts.length > 0 ? `?${parts.join("&")}` : "";
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
// src/generators/xrm-constants.ts
|
|
2223
|
+
var DisplayState = /* @__PURE__ */ ((DisplayState2) => {
|
|
2224
|
+
DisplayState2["Expanded"] = "expanded";
|
|
2225
|
+
DisplayState2["Collapsed"] = "collapsed";
|
|
2226
|
+
return DisplayState2;
|
|
2227
|
+
})(DisplayState || {});
|
|
2228
|
+
var FormNotificationLevel = /* @__PURE__ */ ((FormNotificationLevel2) => {
|
|
2229
|
+
FormNotificationLevel2["Error"] = "ERROR";
|
|
2230
|
+
FormNotificationLevel2["Warning"] = "WARNING";
|
|
2231
|
+
FormNotificationLevel2["Info"] = "INFO";
|
|
2232
|
+
return FormNotificationLevel2;
|
|
2233
|
+
})(FormNotificationLevel || {});
|
|
2234
|
+
var RequiredLevel = /* @__PURE__ */ ((RequiredLevel2) => {
|
|
2235
|
+
RequiredLevel2["None"] = "none";
|
|
2236
|
+
RequiredLevel2["Required"] = "required";
|
|
2237
|
+
RequiredLevel2["Recommended"] = "recommended";
|
|
2238
|
+
return RequiredLevel2;
|
|
2239
|
+
})(RequiredLevel || {});
|
|
2240
|
+
var SubmitMode = /* @__PURE__ */ ((SubmitMode2) => {
|
|
2241
|
+
SubmitMode2["Always"] = "always";
|
|
2242
|
+
SubmitMode2["Never"] = "never";
|
|
2243
|
+
SubmitMode2["Dirty"] = "dirty";
|
|
2244
|
+
return SubmitMode2;
|
|
2245
|
+
})(SubmitMode || {});
|
|
2246
|
+
var SaveMode = /* @__PURE__ */ ((SaveMode2) => {
|
|
2247
|
+
SaveMode2[SaveMode2["Save"] = 1] = "Save";
|
|
2248
|
+
SaveMode2[SaveMode2["SaveAndClose"] = 2] = "SaveAndClose";
|
|
2249
|
+
SaveMode2[SaveMode2["Deactivate"] = 5] = "Deactivate";
|
|
2250
|
+
SaveMode2[SaveMode2["Reactivate"] = 6] = "Reactivate";
|
|
2251
|
+
SaveMode2[SaveMode2["Send"] = 7] = "Send";
|
|
2252
|
+
SaveMode2[SaveMode2["Disqualify"] = 15] = "Disqualify";
|
|
2253
|
+
SaveMode2[SaveMode2["Qualify"] = 16] = "Qualify";
|
|
2254
|
+
SaveMode2[SaveMode2["Assign"] = 47] = "Assign";
|
|
2255
|
+
SaveMode2[SaveMode2["SaveAsCompleted"] = 58] = "SaveAsCompleted";
|
|
2256
|
+
SaveMode2[SaveMode2["SaveAndNew"] = 59] = "SaveAndNew";
|
|
2257
|
+
SaveMode2[SaveMode2["AutoSave"] = 70] = "AutoSave";
|
|
2258
|
+
return SaveMode2;
|
|
2259
|
+
})(SaveMode || {});
|
|
2260
|
+
var ClientType = /* @__PURE__ */ ((ClientType2) => {
|
|
2261
|
+
ClientType2["Web"] = "Web";
|
|
2262
|
+
ClientType2["Outlook"] = "Outlook";
|
|
2263
|
+
ClientType2["Mobile"] = "Mobile";
|
|
2264
|
+
return ClientType2;
|
|
2265
|
+
})(ClientType || {});
|
|
2266
|
+
var ClientState = /* @__PURE__ */ ((ClientState2) => {
|
|
2267
|
+
ClientState2["Online"] = "Online";
|
|
2268
|
+
ClientState2["Offline"] = "Offline";
|
|
2269
|
+
return ClientState2;
|
|
2270
|
+
})(ClientState || {});
|
|
2271
|
+
var OperationType = /* @__PURE__ */ ((OperationType2) => {
|
|
2272
|
+
OperationType2[OperationType2["Action"] = 0] = "Action";
|
|
2273
|
+
OperationType2[OperationType2["Function"] = 1] = "Function";
|
|
2274
|
+
OperationType2[OperationType2["CRUD"] = 2] = "CRUD";
|
|
2275
|
+
return OperationType2;
|
|
2276
|
+
})(OperationType || {});
|
|
2277
|
+
var StructuralProperty = /* @__PURE__ */ ((StructuralProperty2) => {
|
|
2278
|
+
StructuralProperty2[StructuralProperty2["Unknown"] = 0] = "Unknown";
|
|
2279
|
+
StructuralProperty2[StructuralProperty2["PrimitiveType"] = 1] = "PrimitiveType";
|
|
2280
|
+
StructuralProperty2[StructuralProperty2["ComplexType"] = 2] = "ComplexType";
|
|
2281
|
+
StructuralProperty2[StructuralProperty2["EnumerationType"] = 3] = "EnumerationType";
|
|
2282
|
+
StructuralProperty2[StructuralProperty2["Collection"] = 4] = "Collection";
|
|
2283
|
+
StructuralProperty2[StructuralProperty2["EntityType"] = 5] = "EntityType";
|
|
2284
|
+
return StructuralProperty2;
|
|
2285
|
+
})(StructuralProperty || {});
|
|
2286
|
+
var BindingType = /* @__PURE__ */ ((BindingType2) => {
|
|
2287
|
+
BindingType2[BindingType2["Global"] = 0] = "Global";
|
|
2288
|
+
BindingType2[BindingType2["Entity"] = 1] = "Entity";
|
|
2289
|
+
BindingType2[BindingType2["EntityCollection"] = 2] = "EntityCollection";
|
|
2290
|
+
return BindingType2;
|
|
2291
|
+
})(BindingType || {});
|
|
2292
|
+
|
|
2293
|
+
// src/generators/action-runtime.ts
|
|
2294
|
+
function executeRequest(request) {
|
|
2295
|
+
return Xrm.WebApi.online.execute(request);
|
|
2296
|
+
}
|
|
2297
|
+
function executeMultiple(requests) {
|
|
2298
|
+
return Xrm.WebApi.online.executeMultiple(requests);
|
|
2299
|
+
}
|
|
2300
|
+
function cleanRecordId(id) {
|
|
2301
|
+
return id.replace(/[{}]/g, "");
|
|
2302
|
+
}
|
|
2303
|
+
function buildBoundRequest(operationName, entityLogicalName, operationType, recordId, paramMeta, params) {
|
|
2304
|
+
const parameterTypes = {
|
|
2305
|
+
entity: {
|
|
2306
|
+
typeName: `mscrm.${entityLogicalName}`,
|
|
2307
|
+
structuralProperty: 5 /* EntityType */
|
|
2308
|
+
}
|
|
2309
|
+
};
|
|
2310
|
+
if (paramMeta) {
|
|
2311
|
+
for (const [key, meta] of Object.entries(paramMeta)) {
|
|
2312
|
+
parameterTypes[key] = meta;
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
const request = {
|
|
2316
|
+
getMetadata: () => ({
|
|
2317
|
+
boundParameter: "entity",
|
|
2318
|
+
parameterTypes,
|
|
2319
|
+
operationName,
|
|
2320
|
+
operationType
|
|
2321
|
+
}),
|
|
2322
|
+
entity: {
|
|
2323
|
+
id: cleanRecordId(recordId),
|
|
2324
|
+
entityType: entityLogicalName
|
|
2325
|
+
}
|
|
2326
|
+
};
|
|
2327
|
+
if (params) {
|
|
2328
|
+
for (const [key, value] of Object.entries(params)) {
|
|
2329
|
+
request[key] = value;
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
return request;
|
|
2333
|
+
}
|
|
2334
|
+
function buildUnboundRequest(operationName, operationType, paramMeta, params) {
|
|
2335
|
+
const parameterTypes = {};
|
|
2336
|
+
if (paramMeta) {
|
|
2337
|
+
for (const [key, meta] of Object.entries(paramMeta)) {
|
|
2338
|
+
parameterTypes[key] = meta;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
const request = {
|
|
2342
|
+
getMetadata: () => ({
|
|
2343
|
+
boundParameter: null,
|
|
2344
|
+
parameterTypes,
|
|
2345
|
+
operationName,
|
|
2346
|
+
operationType
|
|
2347
|
+
})
|
|
2348
|
+
};
|
|
2349
|
+
if (params) {
|
|
2350
|
+
for (const [key, value] of Object.entries(params)) {
|
|
2351
|
+
request[key] = value;
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
return request;
|
|
2355
|
+
}
|
|
2356
|
+
function createBoundAction(operationName, entityLogicalName, paramMeta) {
|
|
2357
|
+
return {
|
|
2358
|
+
execute(recordId, params) {
|
|
2359
|
+
const req = buildBoundRequest(
|
|
2360
|
+
operationName,
|
|
2361
|
+
entityLogicalName,
|
|
2362
|
+
0 /* Action */,
|
|
2363
|
+
recordId,
|
|
2364
|
+
paramMeta,
|
|
2365
|
+
params
|
|
2366
|
+
);
|
|
2367
|
+
return executeRequest(req);
|
|
2368
|
+
},
|
|
2369
|
+
request(recordId, params) {
|
|
2370
|
+
return buildBoundRequest(
|
|
2371
|
+
operationName,
|
|
2372
|
+
entityLogicalName,
|
|
2373
|
+
0 /* Action */,
|
|
2374
|
+
recordId,
|
|
2375
|
+
paramMeta,
|
|
2376
|
+
params
|
|
2377
|
+
);
|
|
2378
|
+
}
|
|
2379
|
+
};
|
|
2380
|
+
}
|
|
2381
|
+
function createUnboundAction(operationName, paramMeta) {
|
|
2382
|
+
return {
|
|
2383
|
+
async execute(params) {
|
|
2384
|
+
const req = buildUnboundRequest(
|
|
2385
|
+
operationName,
|
|
2386
|
+
0 /* Action */,
|
|
2387
|
+
paramMeta,
|
|
2388
|
+
params
|
|
2389
|
+
);
|
|
2390
|
+
const response = await executeRequest(req);
|
|
2391
|
+
if (!response.ok) {
|
|
2392
|
+
const errorText = await response.text();
|
|
2393
|
+
throw new Error(errorText);
|
|
2394
|
+
}
|
|
2395
|
+
if (response.status !== 204) {
|
|
2396
|
+
return response.json();
|
|
2397
|
+
}
|
|
2398
|
+
return response;
|
|
2399
|
+
},
|
|
2400
|
+
request(params) {
|
|
2401
|
+
return buildUnboundRequest(
|
|
2402
|
+
operationName,
|
|
2403
|
+
0 /* Action */,
|
|
2404
|
+
paramMeta,
|
|
2405
|
+
params
|
|
2406
|
+
);
|
|
2407
|
+
}
|
|
2408
|
+
};
|
|
2409
|
+
}
|
|
2410
|
+
function createUnboundFunction(operationName) {
|
|
2411
|
+
return {
|
|
2412
|
+
async execute() {
|
|
2413
|
+
const req = buildUnboundRequest(operationName, 1 /* Function */);
|
|
2414
|
+
const response = await executeRequest(req);
|
|
2415
|
+
if (!response.ok) {
|
|
2416
|
+
const errorText = await response.text();
|
|
2417
|
+
throw new Error(errorText);
|
|
2418
|
+
}
|
|
2419
|
+
return response.json();
|
|
2420
|
+
},
|
|
2421
|
+
request() {
|
|
2422
|
+
return buildUnboundRequest(operationName, 1 /* Function */);
|
|
2423
|
+
}
|
|
2424
|
+
};
|
|
2425
|
+
}
|
|
2426
|
+
function createBoundFunction(operationName, entityLogicalName) {
|
|
2427
|
+
return {
|
|
2428
|
+
async execute(recordId) {
|
|
2429
|
+
const req = buildBoundRequest(
|
|
2430
|
+
operationName,
|
|
2431
|
+
entityLogicalName,
|
|
2432
|
+
1 /* Function */,
|
|
2433
|
+
recordId
|
|
2434
|
+
);
|
|
2435
|
+
const response = await executeRequest(req);
|
|
2436
|
+
if (!response.ok) {
|
|
2437
|
+
const errorText = await response.text();
|
|
2438
|
+
throw new Error(errorText);
|
|
2439
|
+
}
|
|
2440
|
+
return response.json();
|
|
2441
|
+
},
|
|
2442
|
+
request(recordId) {
|
|
2443
|
+
return buildBoundRequest(
|
|
2444
|
+
operationName,
|
|
2445
|
+
entityLogicalName,
|
|
2446
|
+
1 /* Function */,
|
|
2447
|
+
recordId
|
|
2448
|
+
);
|
|
2449
|
+
}
|
|
2450
|
+
};
|
|
2451
|
+
}
|
|
2452
|
+
async function withProgress(message, operation) {
|
|
2453
|
+
Xrm.Utility.showProgressIndicator(message);
|
|
2454
|
+
try {
|
|
2455
|
+
return await operation();
|
|
2456
|
+
} catch (error) {
|
|
2457
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
2458
|
+
Xrm.Navigation.openErrorDialog({ message: msg });
|
|
2459
|
+
throw error;
|
|
2460
|
+
} finally {
|
|
2461
|
+
Xrm.Utility.closeProgressIndicator();
|
|
2462
|
+
}
|
|
2463
|
+
}
|
|
2464
|
+
|
|
2465
|
+
// src/metadata/custom-api-types.ts
|
|
2466
|
+
function mapCustomApiParameterType(type, entityName) {
|
|
2467
|
+
switch (type) {
|
|
2468
|
+
case 0 /* Boolean */:
|
|
2469
|
+
return { tsType: "boolean", typeName: "Edm.Boolean", structuralProperty: 1 };
|
|
2470
|
+
case 1 /* DateTime */:
|
|
2471
|
+
return { tsType: "string", typeName: "Edm.DateTimeOffset", structuralProperty: 1 };
|
|
2472
|
+
case 2 /* Decimal */:
|
|
2473
|
+
return { tsType: "number", typeName: "Edm.Decimal", structuralProperty: 1 };
|
|
2474
|
+
case 3 /* Entity */:
|
|
2475
|
+
return {
|
|
2476
|
+
tsType: "Record<string, unknown>",
|
|
2477
|
+
typeName: `mscrm.${entityName || "crmbaseentity"}`,
|
|
2478
|
+
structuralProperty: 5
|
|
2479
|
+
};
|
|
2480
|
+
case 4 /* EntityCollection */:
|
|
2481
|
+
return {
|
|
2482
|
+
tsType: "Array<Record<string, unknown>>",
|
|
2483
|
+
typeName: "Collection(mscrm.crmbaseentity)",
|
|
2484
|
+
structuralProperty: 4
|
|
2485
|
+
};
|
|
2486
|
+
case 5 /* EntityReference */:
|
|
2487
|
+
return {
|
|
2488
|
+
tsType: "{ id: string; entityType: string; name?: string }",
|
|
2489
|
+
typeName: `mscrm.${entityName || "crmbaseentity"}`,
|
|
2490
|
+
structuralProperty: 5
|
|
2491
|
+
};
|
|
2492
|
+
case 6 /* Float */:
|
|
2493
|
+
return { tsType: "number", typeName: "Edm.Double", structuralProperty: 1 };
|
|
2494
|
+
case 7 /* Integer */:
|
|
2495
|
+
return { tsType: "number", typeName: "Edm.Int32", structuralProperty: 1 };
|
|
2496
|
+
case 8 /* Money */:
|
|
2497
|
+
return { tsType: "number", typeName: "Edm.Decimal", structuralProperty: 1 };
|
|
2498
|
+
case 9 /* Picklist */:
|
|
2499
|
+
return { tsType: "number", typeName: "Edm.Int32", structuralProperty: 1 };
|
|
2500
|
+
case 10 /* String */:
|
|
2501
|
+
return { tsType: "string", typeName: "Edm.String", structuralProperty: 1 };
|
|
2502
|
+
case 11 /* StringArray */:
|
|
2503
|
+
return { tsType: "string[]", typeName: "Collection(Edm.String)", structuralProperty: 4 };
|
|
2504
|
+
case 12 /* Guid */:
|
|
2505
|
+
return { tsType: "string", typeName: "Edm.Guid", structuralProperty: 1 };
|
|
2506
|
+
default:
|
|
2507
|
+
return { tsType: "unknown", typeName: "Edm.String", structuralProperty: 0 };
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
// src/generators/action-generator.ts
|
|
2512
|
+
function deriveActionName(uniquename) {
|
|
2513
|
+
const withoutPrefix = uniquename.includes("_") ? uniquename.substring(uniquename.indexOf("_") + 1) : uniquename;
|
|
2514
|
+
return toPascalCase(withoutPrefix);
|
|
2515
|
+
}
|
|
2516
|
+
function generateParamsInterface(name, params) {
|
|
2517
|
+
if (params.length === 0) return "";
|
|
2518
|
+
const lines = [];
|
|
2519
|
+
lines.push(` interface ${name}Params {`);
|
|
2520
|
+
for (const param of params) {
|
|
2521
|
+
const mapped = mapCustomApiParameterType(param.type, param.logicalentityname);
|
|
2522
|
+
const optional = param.isoptional ? "?" : "";
|
|
2523
|
+
if (param.description) {
|
|
2524
|
+
lines.push(` /** ${param.description} */`);
|
|
2525
|
+
}
|
|
2526
|
+
lines.push(` ${param.uniquename}${optional}: ${mapped.tsType};`);
|
|
2527
|
+
}
|
|
2528
|
+
lines.push(" }");
|
|
2529
|
+
return lines.join("\n");
|
|
2530
|
+
}
|
|
2531
|
+
function generateResultInterface(name, props) {
|
|
2532
|
+
if (props.length === 0) return "";
|
|
2533
|
+
const lines = [];
|
|
2534
|
+
lines.push(` interface ${name}Result {`);
|
|
2535
|
+
for (const prop of props) {
|
|
2536
|
+
const mapped = mapCustomApiParameterType(prop.type, prop.logicalentityname);
|
|
2537
|
+
if (prop.description) {
|
|
2538
|
+
lines.push(` /** ${prop.description} */`);
|
|
2539
|
+
}
|
|
2540
|
+
lines.push(` ${prop.uniquename}: ${mapped.tsType};`);
|
|
2541
|
+
}
|
|
2542
|
+
lines.push(" }");
|
|
2543
|
+
return lines.join("\n");
|
|
2544
|
+
}
|
|
2545
|
+
function generateActionDeclarations(apis, isFunction, entityName, options = {}) {
|
|
2546
|
+
const baseNamespace = isFunction ? options.functionsNamespace || "XrmForge.Functions" : options.actionsNamespace || "XrmForge.Actions";
|
|
2547
|
+
const namespace = entityName ? `${baseNamespace}.${toPascalCase(entityName)}` : baseNamespace;
|
|
2548
|
+
const lines = [];
|
|
2549
|
+
lines.push("// Auto-generated by @xrmforge/typegen - DO NOT EDIT");
|
|
2550
|
+
lines.push("");
|
|
2551
|
+
lines.push(`declare namespace ${namespace} {`);
|
|
2552
|
+
for (const apiInfo of apis) {
|
|
2553
|
+
const name = deriveActionName(apiInfo.api.uniquename);
|
|
2554
|
+
const hasParams = apiInfo.requestParameters.length > 0;
|
|
2555
|
+
const hasResult = apiInfo.responseProperties.length > 0;
|
|
2556
|
+
lines.push("");
|
|
2557
|
+
const description = apiInfo.api.description || apiInfo.api.displayname || apiInfo.api.uniquename;
|
|
2558
|
+
lines.push(` /** ${description} (${apiInfo.api.uniquename}) */`);
|
|
2559
|
+
if (hasParams) {
|
|
2560
|
+
lines.push(generateParamsInterface(name, apiInfo.requestParameters));
|
|
2561
|
+
lines.push("");
|
|
2562
|
+
}
|
|
2563
|
+
if (hasResult) {
|
|
2564
|
+
lines.push(generateResultInterface(name, apiInfo.responseProperties));
|
|
2565
|
+
lines.push("");
|
|
2566
|
+
}
|
|
2567
|
+
const importFrom = options.importPath || "@xrmforge/typegen";
|
|
2568
|
+
if (apiInfo.api.bindingtype === 0 /* Global */) {
|
|
2569
|
+
if (hasParams && hasResult) {
|
|
2570
|
+
lines.push(` const ${name}: import('${importFrom}').UnboundActionWithParamsExecutor<${name}Params, ${name}Result>;`);
|
|
2571
|
+
} else if (hasParams) {
|
|
2572
|
+
lines.push(` const ${name}: import('${importFrom}').UnboundActionWithParamsExecutor<${name}Params, void>;`);
|
|
2573
|
+
} else {
|
|
2574
|
+
lines.push(` const ${name}: import('${importFrom}').UnboundActionExecutor;`);
|
|
2575
|
+
}
|
|
2576
|
+
} else {
|
|
2577
|
+
if (hasParams) {
|
|
2578
|
+
lines.push(` const ${name}: import('${importFrom}').BoundActionWithParamsExecutor<${name}Params>;`);
|
|
2579
|
+
} else {
|
|
2580
|
+
lines.push(` const ${name}: import('${importFrom}').BoundActionExecutor;`);
|
|
2581
|
+
}
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
lines.push("}");
|
|
2585
|
+
lines.push("");
|
|
2586
|
+
return lines.join("\n");
|
|
2587
|
+
}
|
|
2588
|
+
function generateActionModule(apis, isFunction, options = {}) {
|
|
2589
|
+
const importPath = options.importPath || "@xrmforge/typegen";
|
|
2590
|
+
const lines = [];
|
|
2591
|
+
lines.push("// Auto-generated by @xrmforge/typegen - DO NOT EDIT");
|
|
2592
|
+
lines.push("");
|
|
2593
|
+
const imports = /* @__PURE__ */ new Set();
|
|
2594
|
+
for (const apiInfo of apis) {
|
|
2595
|
+
if (apiInfo.api.bindingtype === 0 /* Global */) {
|
|
2596
|
+
if (isFunction) {
|
|
2597
|
+
imports.add("createUnboundFunction");
|
|
2598
|
+
} else {
|
|
2599
|
+
imports.add("createUnboundAction");
|
|
2600
|
+
}
|
|
2601
|
+
} else {
|
|
2602
|
+
if (isFunction) {
|
|
2603
|
+
imports.add("createBoundFunction");
|
|
2604
|
+
} else {
|
|
2605
|
+
imports.add("createBoundAction");
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
}
|
|
2609
|
+
lines.push(`import { ${[...imports].sort().join(", ")} } from '${importPath}';`);
|
|
2610
|
+
lines.push("");
|
|
2611
|
+
for (const apiInfo of apis) {
|
|
2612
|
+
const name = deriveActionName(apiInfo.api.uniquename);
|
|
2613
|
+
const hasParams = apiInfo.requestParameters.length > 0;
|
|
2614
|
+
const description = apiInfo.api.description || apiInfo.api.displayname || apiInfo.api.uniquename;
|
|
2615
|
+
lines.push(`/** ${description} */`);
|
|
2616
|
+
if (apiInfo.api.bindingtype === 0 /* Global */) {
|
|
2617
|
+
if (isFunction) {
|
|
2618
|
+
lines.push(`export const ${name} = createUnboundFunction('${apiInfo.api.uniquename}');`);
|
|
2619
|
+
} else if (hasParams) {
|
|
2620
|
+
const paramMeta = generateParameterMetaMap(apiInfo.requestParameters);
|
|
2621
|
+
lines.push(`export const ${name} = createUnboundAction('${apiInfo.api.uniquename}', ${paramMeta});`);
|
|
2622
|
+
} else {
|
|
2623
|
+
lines.push(`export const ${name} = createUnboundAction('${apiInfo.api.uniquename}');`);
|
|
2624
|
+
}
|
|
2625
|
+
} else {
|
|
2626
|
+
const entity = apiInfo.api.boundentitylogicalname;
|
|
2627
|
+
if (isFunction) {
|
|
2628
|
+
lines.push(`export const ${name} = createBoundFunction('${apiInfo.api.uniquename}', '${entity}');`);
|
|
2629
|
+
} else if (hasParams) {
|
|
2630
|
+
const paramMeta = generateParameterMetaMap(apiInfo.requestParameters);
|
|
2631
|
+
lines.push(`export const ${name} = createBoundAction('${apiInfo.api.uniquename}', '${entity}', ${paramMeta});`);
|
|
2632
|
+
} else {
|
|
2633
|
+
lines.push(`export const ${name} = createBoundAction('${apiInfo.api.uniquename}', '${entity}');`);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
lines.push("");
|
|
2637
|
+
}
|
|
2638
|
+
return lines.join("\n");
|
|
2639
|
+
}
|
|
2640
|
+
function generateParameterMetaMap(params) {
|
|
2641
|
+
const entries = [];
|
|
2642
|
+
for (const param of params) {
|
|
2643
|
+
const mapped = mapCustomApiParameterType(param.type, param.logicalentityname);
|
|
2644
|
+
entries.push(
|
|
2645
|
+
` ${param.uniquename}: { typeName: '${mapped.typeName}', structuralProperty: ${mapped.structuralProperty} }`
|
|
2646
|
+
);
|
|
2647
|
+
}
|
|
2648
|
+
return `{
|
|
2649
|
+
${entries.join(",\n")},
|
|
2650
|
+
}`;
|
|
2651
|
+
}
|
|
2652
|
+
function groupCustomApis(apis) {
|
|
2653
|
+
const actions = /* @__PURE__ */ new Map();
|
|
2654
|
+
const functions = /* @__PURE__ */ new Map();
|
|
2655
|
+
for (const api of apis) {
|
|
2656
|
+
const target = api.api.isfunction ? functions : actions;
|
|
2657
|
+
const key = api.api.bindingtype === 0 /* Global */ ? "global" : api.api.boundentitylogicalname || "global";
|
|
2658
|
+
if (!target.has(key)) {
|
|
2659
|
+
target.set(key, []);
|
|
2660
|
+
}
|
|
2661
|
+
target.get(key).push(api);
|
|
2662
|
+
}
|
|
2663
|
+
return { actions, functions };
|
|
2664
|
+
}
|
|
2665
|
+
|
|
1942
2666
|
// src/orchestrator/file-writer.ts
|
|
1943
2667
|
import { mkdir, writeFile, readFile } from "fs/promises";
|
|
1944
2668
|
import { join as join2, dirname } from "path";
|
|
@@ -2032,6 +2756,8 @@ var TypeGenerationOrchestrator = class {
|
|
|
2032
2756
|
generateEntities: config.generateEntities ?? true,
|
|
2033
2757
|
generateForms: config.generateForms ?? true,
|
|
2034
2758
|
generateOptionSets: config.generateOptionSets ?? true,
|
|
2759
|
+
generateActions: config.generateActions ?? false,
|
|
2760
|
+
actionsFilter: config.actionsFilter ?? "",
|
|
2035
2761
|
useCache: config.useCache ?? false,
|
|
2036
2762
|
cacheDir: config.cacheDir ?? ".xrmforge/cache",
|
|
2037
2763
|
namespacePrefix: config.namespacePrefix ?? "XrmForge"
|
|
@@ -2106,6 +2832,63 @@ var TypeGenerationOrchestrator = class {
|
|
|
2106
2832
|
});
|
|
2107
2833
|
}
|
|
2108
2834
|
}
|
|
2835
|
+
if (this.config.generateActions && !signal?.aborted) {
|
|
2836
|
+
this.logger.info("Fetching Custom APIs...");
|
|
2837
|
+
let customApis = await metadataClient.getCustomApis();
|
|
2838
|
+
if (this.config.actionsFilter) {
|
|
2839
|
+
const prefix = this.config.actionsFilter.toLowerCase();
|
|
2840
|
+
const before = customApis.length;
|
|
2841
|
+
customApis = customApis.filter((api) => api.api.uniquename.toLowerCase().startsWith(prefix));
|
|
2842
|
+
this.logger.info(`Filtered Custom APIs by prefix "${this.config.actionsFilter}": ${before} -> ${customApis.length}`);
|
|
2843
|
+
}
|
|
2844
|
+
if (customApis.length > 0) {
|
|
2845
|
+
const importPath = "@xrmforge/typegen";
|
|
2846
|
+
const grouped = groupCustomApis(customApis);
|
|
2847
|
+
for (const [key, apis] of grouped.actions) {
|
|
2848
|
+
const entityName = key === "global" ? void 0 : key;
|
|
2849
|
+
const declarations = generateActionDeclarations(apis, false, entityName, { importPath });
|
|
2850
|
+
const module = generateActionModule(apis, false, { importPath });
|
|
2851
|
+
allFiles.push({
|
|
2852
|
+
relativePath: `actions/${key}.d.ts`,
|
|
2853
|
+
content: addGeneratedHeader(declarations),
|
|
2854
|
+
type: "action"
|
|
2855
|
+
});
|
|
2856
|
+
allFiles.push({
|
|
2857
|
+
relativePath: `actions/${key}.ts`,
|
|
2858
|
+
content: addGeneratedHeader(module),
|
|
2859
|
+
type: "action"
|
|
2860
|
+
});
|
|
2861
|
+
}
|
|
2862
|
+
for (const [key, apis] of grouped.functions) {
|
|
2863
|
+
const entityName = key === "global" ? void 0 : key;
|
|
2864
|
+
const declarations = generateActionDeclarations(apis, true, entityName, { importPath });
|
|
2865
|
+
const module = generateActionModule(apis, true, { importPath });
|
|
2866
|
+
allFiles.push({
|
|
2867
|
+
relativePath: `functions/${key}.d.ts`,
|
|
2868
|
+
content: addGeneratedHeader(declarations),
|
|
2869
|
+
type: "action"
|
|
2870
|
+
});
|
|
2871
|
+
allFiles.push({
|
|
2872
|
+
relativePath: `functions/${key}.ts`,
|
|
2873
|
+
content: addGeneratedHeader(module),
|
|
2874
|
+
type: "action"
|
|
2875
|
+
});
|
|
2876
|
+
}
|
|
2877
|
+
this.logger.info(`Generated ${grouped.actions.size} action groups, ${grouped.functions.size} function groups`);
|
|
2878
|
+
} else {
|
|
2879
|
+
this.logger.info("No Custom APIs found");
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
if (this.config.entities.length > 0) {
|
|
2883
|
+
const entityNamesContent = generateEntityNamesEnum(this.config.entities, {
|
|
2884
|
+
namespace: this.config.namespacePrefix
|
|
2885
|
+
});
|
|
2886
|
+
allFiles.push({
|
|
2887
|
+
relativePath: "entity-names.d.ts",
|
|
2888
|
+
content: addGeneratedHeader(entityNamesContent),
|
|
2889
|
+
type: "entity"
|
|
2890
|
+
});
|
|
2891
|
+
}
|
|
2109
2892
|
if (allFiles.length > 0) {
|
|
2110
2893
|
const indexContent = generateBarrelIndex(allFiles);
|
|
2111
2894
|
const indexFile = {
|
|
@@ -2232,12 +3015,17 @@ var TypeGenerationOrchestrator = class {
|
|
|
2232
3015
|
export {
|
|
2233
3016
|
ApiRequestError,
|
|
2234
3017
|
AuthenticationError,
|
|
3018
|
+
BindingType,
|
|
3019
|
+
ClientState,
|
|
3020
|
+
ClientType,
|
|
2235
3021
|
ConfigError,
|
|
2236
3022
|
ConsoleLogSink,
|
|
2237
3023
|
DEFAULT_LABEL_CONFIG,
|
|
2238
3024
|
DataverseHttpClient,
|
|
3025
|
+
DisplayState,
|
|
2239
3026
|
ErrorCode,
|
|
2240
3027
|
FastXmlParser,
|
|
3028
|
+
FormNotificationLevel,
|
|
2241
3029
|
GenerationError,
|
|
2242
3030
|
JsonLogSink,
|
|
2243
3031
|
LogLevel,
|
|
@@ -2245,18 +3033,35 @@ export {
|
|
|
2245
3033
|
MetadataCache,
|
|
2246
3034
|
MetadataClient,
|
|
2247
3035
|
MetadataError,
|
|
3036
|
+
OperationType,
|
|
3037
|
+
RequiredLevel,
|
|
3038
|
+
SaveMode,
|
|
2248
3039
|
SilentLogSink,
|
|
3040
|
+
StructuralProperty,
|
|
3041
|
+
SubmitMode,
|
|
2249
3042
|
TypeGenerationOrchestrator,
|
|
2250
3043
|
XrmForgeError,
|
|
2251
3044
|
configureLogging,
|
|
3045
|
+
createBoundAction,
|
|
3046
|
+
createBoundFunction,
|
|
2252
3047
|
createCredential,
|
|
2253
3048
|
createLogger,
|
|
3049
|
+
createUnboundAction,
|
|
3050
|
+
createUnboundFunction,
|
|
2254
3051
|
defaultXmlParser,
|
|
2255
3052
|
disambiguateEnumMembers,
|
|
3053
|
+
executeMultiple,
|
|
3054
|
+
executeRequest,
|
|
2256
3055
|
extractControlFields,
|
|
2257
3056
|
getJSDocLabel as formatDualLabel,
|
|
3057
|
+
generateActionDeclarations,
|
|
3058
|
+
generateActionModule,
|
|
3059
|
+
generateActivityPartyInterface,
|
|
3060
|
+
generateEntityFieldsEnum,
|
|
2258
3061
|
generateEntityForms,
|
|
2259
3062
|
generateEntityInterface,
|
|
3063
|
+
generateEntityNamesEnum,
|
|
3064
|
+
generateEntityNavigationProperties,
|
|
2260
3065
|
generateEntityOptionSets,
|
|
2261
3066
|
generateEnumMembers,
|
|
2262
3067
|
generateFormInterface,
|
|
@@ -2264,18 +3069,27 @@ export {
|
|
|
2264
3069
|
getEntityPropertyType,
|
|
2265
3070
|
getFormAttributeType,
|
|
2266
3071
|
getFormControlType,
|
|
3072
|
+
getFormMockValueType,
|
|
2267
3073
|
getJSDocLabel,
|
|
2268
3074
|
getLabelLanguagesParam,
|
|
2269
3075
|
getPrimaryLabel,
|
|
2270
3076
|
getSecondaryLabel,
|
|
3077
|
+
groupCustomApis,
|
|
2271
3078
|
isLookupType,
|
|
3079
|
+
isPartyListType,
|
|
2272
3080
|
isRateLimitError,
|
|
2273
3081
|
isXrmForgeError,
|
|
2274
3082
|
labelToIdentifier,
|
|
2275
3083
|
parseForm,
|
|
3084
|
+
parseFormattedValue,
|
|
3085
|
+
parseLookup,
|
|
3086
|
+
parseLookups,
|
|
3087
|
+
select,
|
|
3088
|
+
selectExpand,
|
|
2276
3089
|
shouldIncludeInEntityInterface,
|
|
2277
3090
|
toLookupValueProperty,
|
|
2278
3091
|
toPascalCase,
|
|
2279
|
-
toSafeIdentifier
|
|
3092
|
+
toSafeIdentifier,
|
|
3093
|
+
withProgress
|
|
2280
3094
|
};
|
|
2281
3095
|
//# sourceMappingURL=index.js.map
|