@xrmforge/typegen 0.7.1 → 0.8.1
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/MIGRATION.md +40 -11
- package/dist/index.d.ts +15 -27
- package/dist/index.js +222 -212
- package/dist/index.js.map +1 -1
- package/docs/architecture/02-packages.md +1 -1
- package/docs/architecture/03-generated-types.md +86 -90
- package/docs/architecture/04-cli.md +2 -2
- package/docs/architecture/09-testing.md +1 -1
- package/docs/architecture/10-eslint-plugin.md +1 -1
- package/docs/architecture/11-agent-md.md +1 -1
- package/docs/architecture/12-xrm-pitfalls.md +1 -1
- package/docs/architecture/16-technical-debt.md +1 -1
- package/docs/architektur/02-packages.md +1 -1
- package/docs/architektur/03-generierte-typen.md +86 -90
- package/docs/architektur/04-cli.md +2 -2
- package/docs/architektur/09-testing.md +1 -1
- package/docs/architektur/10-eslint-plugin.md +1 -1
- package/docs/architektur/11-agent-md.md +1 -1
- package/docs/architektur/12-xrm-fallstricke.md +1 -1
- package/docs/architektur/16-technische-schulden.md +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1295,7 +1295,7 @@ var MetadataCache = class {
|
|
|
1295
1295
|
log5.info(`Loaded metadata cache: ${data.manifest.entities.length} entities, last refreshed ${data.manifest.lastRefreshed}`);
|
|
1296
1296
|
return data;
|
|
1297
1297
|
} catch (error) {
|
|
1298
|
-
if (error.code === "ENOENT") {
|
|
1298
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
1299
1299
|
log5.info("No metadata cache found, will do full refresh");
|
|
1300
1300
|
} else {
|
|
1301
1301
|
log5.warn("Failed to read metadata cache, will do full refresh", {
|
|
@@ -1367,7 +1367,7 @@ var MetadataCache = class {
|
|
|
1367
1367
|
await fs.unlink(this.cacheFilePath);
|
|
1368
1368
|
log5.info("Metadata cache cleared");
|
|
1369
1369
|
} catch (error) {
|
|
1370
|
-
if (error.code
|
|
1370
|
+
if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
|
|
1371
1371
|
throw error;
|
|
1372
1372
|
}
|
|
1373
1373
|
}
|
|
@@ -1748,36 +1748,33 @@ function shouldIncludeInEntityInterface(attr) {
|
|
|
1748
1748
|
}
|
|
1749
1749
|
|
|
1750
1750
|
// src/generators/activity-party.ts
|
|
1751
|
-
function generateActivityPartyInterface(
|
|
1751
|
+
function generateActivityPartyInterface() {
|
|
1752
1752
|
const lines = [];
|
|
1753
|
-
lines.push(
|
|
1754
|
-
lines.push("");
|
|
1753
|
+
lines.push("/**");
|
|
1754
|
+
lines.push(" * Activity Party - Teilnehmer einer Aktivit\xE4t (E-Mail, Termin, etc.)");
|
|
1755
|
+
lines.push(" * Wird von PartyList-Feldern (to, from, cc, bcc, requiredattendees) referenziert.");
|
|
1756
|
+
lines.push(" * @see https://learn.microsoft.com/en-us/power-apps/developer/data-platform/reference/entities/activityparty");
|
|
1757
|
+
lines.push(" */");
|
|
1758
|
+
lines.push("export interface ActivityParty {");
|
|
1759
|
+
lines.push(" /** Primary key */");
|
|
1760
|
+
lines.push(" activitypartyid?: string;");
|
|
1761
|
+
lines.push(" /** Referenz auf die zugeh\xF6rige Aktivit\xE4t */");
|
|
1762
|
+
lines.push(" _activityid_value?: string;");
|
|
1763
|
+
lines.push(" /** Referenz auf den Teilnehmer (account | contact | systemuser | queue | knowledgearticle) */");
|
|
1764
|
+
lines.push(" _partyid_value?: string;");
|
|
1755
1765
|
lines.push(" /**");
|
|
1756
|
-
lines.push(" *
|
|
1757
|
-
lines.push(" *
|
|
1758
|
-
lines.push(" *
|
|
1766
|
+
lines.push(" * Rolle des Teilnehmers:");
|
|
1767
|
+
lines.push(" * 1=Sender, 2=To, 3=CC, 4=BCC, 5=Required Attendee,");
|
|
1768
|
+
lines.push(" * 6=Optional Attendee, 7=Organizer, 8=Regarding, 9=Owner,");
|
|
1769
|
+
lines.push(" * 10=Resource, 11=Customer, 12=Chat Participant, 13=Related");
|
|
1759
1770
|
lines.push(" */");
|
|
1760
|
-
lines.push("
|
|
1761
|
-
lines.push("
|
|
1762
|
-
lines.push("
|
|
1763
|
-
lines.push("
|
|
1764
|
-
lines.push("
|
|
1765
|
-
lines.push("
|
|
1766
|
-
lines.push("
|
|
1767
|
-
lines.push(" /**");
|
|
1768
|
-
lines.push(" * Rolle des Teilnehmers:");
|
|
1769
|
-
lines.push(" * 1=Sender, 2=To, 3=CC, 4=BCC, 5=Required Attendee,");
|
|
1770
|
-
lines.push(" * 6=Optional Attendee, 7=Organizer, 8=Regarding, 9=Owner,");
|
|
1771
|
-
lines.push(" * 10=Resource, 11=Customer, 12=Chat Participant, 13=Related");
|
|
1772
|
-
lines.push(" */");
|
|
1773
|
-
lines.push(" participationtypemask?: number;");
|
|
1774
|
-
lines.push(" /** E-Mail-Adresse f\xFCr die Zustellung */");
|
|
1775
|
-
lines.push(" addressused?: string;");
|
|
1776
|
-
lines.push(" /** Aufwand des Teilnehmers (bei Serviceterminen) */");
|
|
1777
|
-
lines.push(" effort?: number;");
|
|
1778
|
-
lines.push(" /** Name des Teilnehmers (wenn nicht aufgel\xF6st) */");
|
|
1779
|
-
lines.push(" unresolvedpartyname?: string;");
|
|
1780
|
-
lines.push(" }");
|
|
1771
|
+
lines.push(" participationtypemask?: number;");
|
|
1772
|
+
lines.push(" /** E-Mail-Adresse f\xFCr die Zustellung */");
|
|
1773
|
+
lines.push(" addressused?: string;");
|
|
1774
|
+
lines.push(" /** Aufwand des Teilnehmers (bei Serviceterminen) */");
|
|
1775
|
+
lines.push(" effort?: number;");
|
|
1776
|
+
lines.push(" /** Name des Teilnehmers (wenn nicht aufgel\xF6st) */");
|
|
1777
|
+
lines.push(" unresolvedpartyname?: string;");
|
|
1781
1778
|
lines.push("}");
|
|
1782
1779
|
lines.push("");
|
|
1783
1780
|
return lines.join("\n");
|
|
@@ -1824,16 +1821,18 @@ function disambiguateEnumMembers(members) {
|
|
|
1824
1821
|
// src/generators/entity-generator.ts
|
|
1825
1822
|
function generateEntityInterface(info, options = {}) {
|
|
1826
1823
|
const labelConfig = options.labelConfig || DEFAULT_LABEL_CONFIG;
|
|
1827
|
-
const namespace = options.namespace || "XrmForge.Entities";
|
|
1828
1824
|
const entityName = toPascalCase(info.entity.LogicalName);
|
|
1829
1825
|
const entityLabel = getJSDocLabel(info.entity.DisplayName, labelConfig);
|
|
1830
1826
|
const lines = [];
|
|
1831
|
-
|
|
1832
|
-
|
|
1827
|
+
const partyListAttrs = info.attributes.filter((a) => isPartyListType(a.AttributeType));
|
|
1828
|
+
if (partyListAttrs.length > 0) {
|
|
1829
|
+
lines.push("import type { ActivityParty } from './_activity-party.js';");
|
|
1830
|
+
lines.push("");
|
|
1831
|
+
}
|
|
1833
1832
|
if (entityLabel) {
|
|
1834
|
-
lines.push(
|
|
1833
|
+
lines.push(`/** ${entityLabel} */`);
|
|
1835
1834
|
}
|
|
1836
|
-
lines.push(`
|
|
1835
|
+
lines.push(`export interface ${entityName} {`);
|
|
1837
1836
|
const includedAttrs = info.attributes.filter(shouldIncludeInEntityInterface).sort((a, b) => a.LogicalName.localeCompare(b.LogicalName));
|
|
1838
1837
|
const lookupTargets = /* @__PURE__ */ new Map();
|
|
1839
1838
|
for (const la of info.lookupAttributes) {
|
|
@@ -1858,21 +1857,19 @@ function generateEntityInterface(info, options = {}) {
|
|
|
1858
1857
|
jsdocParts.push("read-only");
|
|
1859
1858
|
}
|
|
1860
1859
|
if (jsdocParts.length > 0) {
|
|
1861
|
-
lines.push(`
|
|
1860
|
+
lines.push(` /** ${jsdocParts.join(" - ")} */`);
|
|
1862
1861
|
}
|
|
1863
|
-
lines.push(`
|
|
1862
|
+
lines.push(` ${propertyName}: ${tsType} | null;`);
|
|
1864
1863
|
}
|
|
1865
|
-
const partyListAttrs = info.attributes.filter((a) => isPartyListType(a.AttributeType));
|
|
1866
1864
|
if (partyListAttrs.length > 0) {
|
|
1867
1865
|
const relationship = info.oneToManyRelationships.find(
|
|
1868
1866
|
(r) => r.ReferencingEntity === "activityparty"
|
|
1869
1867
|
);
|
|
1870
1868
|
const navPropName = relationship ? relationship.SchemaName.charAt(0).toLowerCase() + relationship.SchemaName.slice(1) : `${info.entity.LogicalName}_activity_parties`;
|
|
1871
1869
|
lines.push("");
|
|
1872
|
-
lines.push(`
|
|
1873
|
-
lines.push(`
|
|
1870
|
+
lines.push(` /** ActivityParty collection (${partyListAttrs.length} PartyList-Felder: ${partyListAttrs.map((a) => a.LogicalName).join(", ")}) */`);
|
|
1871
|
+
lines.push(` ${navPropName}: ActivityParty[] | null;`);
|
|
1874
1872
|
}
|
|
1875
|
-
lines.push(" }");
|
|
1876
1873
|
lines.push("}");
|
|
1877
1874
|
lines.push("");
|
|
1878
1875
|
return lines.join("\n");
|
|
@@ -1881,7 +1878,6 @@ function generateEntityInterface(info, options = {}) {
|
|
|
1881
1878
|
// src/generators/optionset-generator.ts
|
|
1882
1879
|
function generateOptionSetEnum(optionSet, _entityLogicalName, attributeSchemaName, options = {}) {
|
|
1883
1880
|
const labelConfig = options.labelConfig || DEFAULT_LABEL_CONFIG;
|
|
1884
|
-
const namespace = options.namespace || "XrmForge.OptionSets";
|
|
1885
1881
|
const enumName = optionSet.IsGlobal ? toPascalCase(optionSet.Name) : toPascalCase(attributeSchemaName);
|
|
1886
1882
|
const rawMembers = optionSet.Options.map((opt) => {
|
|
1887
1883
|
const label = getPrimaryLabel(opt.Label, labelConfig);
|
|
@@ -1897,24 +1893,21 @@ function generateOptionSetEnum(optionSet, _entityLogicalName, attributeSchemaNam
|
|
|
1897
1893
|
rawMembers.map((m) => ({ name: m.name, value: m.value }))
|
|
1898
1894
|
);
|
|
1899
1895
|
const lines = [];
|
|
1900
|
-
lines.push(`declare namespace ${namespace} {`);
|
|
1901
|
-
lines.push("");
|
|
1902
1896
|
const enumLabel = getJSDocLabel(optionSet.DisplayName, labelConfig);
|
|
1903
1897
|
if (enumLabel) {
|
|
1904
|
-
lines.push(
|
|
1898
|
+
lines.push(`/** ${enumLabel} (${optionSet.Name}) */`);
|
|
1905
1899
|
}
|
|
1906
|
-
lines.push(`
|
|
1900
|
+
lines.push(`export const enum ${enumName} {`);
|
|
1907
1901
|
for (let i = 0; i < disambiguated.length; i++) {
|
|
1908
1902
|
const member = disambiguated[i];
|
|
1909
1903
|
const rawMember = rawMembers[i];
|
|
1910
1904
|
if (!rawMember) continue;
|
|
1911
1905
|
const memberLabel = getJSDocLabel(rawMember.option.Label, labelConfig);
|
|
1912
1906
|
if (memberLabel) {
|
|
1913
|
-
lines.push(`
|
|
1907
|
+
lines.push(` /** ${memberLabel} */`);
|
|
1914
1908
|
}
|
|
1915
|
-
lines.push(`
|
|
1909
|
+
lines.push(` ${member.name} = ${member.value},`);
|
|
1916
1910
|
}
|
|
1917
|
-
lines.push(" }");
|
|
1918
1911
|
lines.push("}");
|
|
1919
1912
|
lines.push("");
|
|
1920
1913
|
return lines.join("\n");
|
|
@@ -1979,9 +1972,7 @@ function labelToPascalMember(label) {
|
|
|
1979
1972
|
}
|
|
1980
1973
|
function generateFormInterface(form, entityLogicalName, attributeMap, options = {}, baseNameOverride) {
|
|
1981
1974
|
const labelConfig = options.labelConfig || DEFAULT_LABEL_CONFIG;
|
|
1982
|
-
const namespacePrefix = options.namespacePrefix || "XrmForge.Forms";
|
|
1983
1975
|
const entityPascal = toPascalCase(entityLogicalName);
|
|
1984
|
-
const namespace = `${namespacePrefix}.${entityPascal}`;
|
|
1985
1976
|
const baseName = baseNameOverride || buildFormBaseName(entityPascal, toSafeFormName(form.name));
|
|
1986
1977
|
const interfaceName = `${baseName}Form`;
|
|
1987
1978
|
const fieldsTypeName = `${baseName}FormFields`;
|
|
@@ -2021,38 +2012,48 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2021
2012
|
});
|
|
2022
2013
|
}
|
|
2023
2014
|
const lines = [];
|
|
2024
|
-
lines.push(
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2015
|
+
lines.push(`/** Valid field names for the "${form.name}" form */`);
|
|
2016
|
+
if (fields.length === 0) {
|
|
2017
|
+
lines.push(`export type ${fieldsTypeName} = never;`);
|
|
2018
|
+
} else {
|
|
2019
|
+
lines.push(`export type ${fieldsTypeName} =`);
|
|
2020
|
+
for (let i = 0; i < fields.length; i++) {
|
|
2021
|
+
const separator = i === fields.length - 1 ? ";" : "";
|
|
2022
|
+
lines.push(` | "${fields[i].logicalName}"${separator}`);
|
|
2023
|
+
}
|
|
2031
2024
|
}
|
|
2032
2025
|
lines.push("");
|
|
2033
|
-
lines.push(
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2026
|
+
lines.push(`/** Attribute type map for "${form.name}" */`);
|
|
2027
|
+
if (fields.length === 0) {
|
|
2028
|
+
lines.push(`export type ${attrMapName} = Record<string, never>;`);
|
|
2029
|
+
} else {
|
|
2030
|
+
lines.push(`export type ${attrMapName} = {`);
|
|
2031
|
+
for (const field of fields) {
|
|
2032
|
+
lines.push(` ${field.logicalName}: ${field.formAttributeType};`);
|
|
2033
|
+
}
|
|
2034
|
+
lines.push("};");
|
|
2037
2035
|
}
|
|
2038
|
-
lines.push(" };");
|
|
2039
2036
|
lines.push("");
|
|
2040
|
-
lines.push(
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2037
|
+
lines.push(`/** Control type map for "${form.name}" */`);
|
|
2038
|
+
if (fields.length === 0) {
|
|
2039
|
+
lines.push(`export type ${ctrlMapName} = Record<string, never>;`);
|
|
2040
|
+
} else {
|
|
2041
|
+
lines.push(`export type ${ctrlMapName} = {`);
|
|
2042
|
+
for (const field of fields) {
|
|
2043
|
+
lines.push(` ${field.logicalName}: ${field.formControlType};`);
|
|
2044
|
+
}
|
|
2045
|
+
lines.push("};");
|
|
2044
2046
|
}
|
|
2045
|
-
lines.push(" };");
|
|
2046
2047
|
lines.push("");
|
|
2047
|
-
lines.push(
|
|
2048
|
-
lines.push(`
|
|
2048
|
+
lines.push(`/** Field constants for "${form.name}" (compile-time only, zero runtime) */`);
|
|
2049
|
+
lines.push(`export const enum ${fieldsTypeName}Enum {`);
|
|
2049
2050
|
for (const field of fields) {
|
|
2050
2051
|
if (field.label) {
|
|
2051
|
-
lines.push(`
|
|
2052
|
+
lines.push(` /** ${field.label} */`);
|
|
2052
2053
|
}
|
|
2053
|
-
lines.push(`
|
|
2054
|
+
lines.push(` ${field.enumMemberName} = '${field.logicalName}',`);
|
|
2054
2055
|
}
|
|
2055
|
-
lines.push("
|
|
2056
|
+
lines.push("}");
|
|
2056
2057
|
lines.push("");
|
|
2057
2058
|
const namedTabs = form.tabs.filter((t) => t.name);
|
|
2058
2059
|
if (namedTabs.length > 0) {
|
|
@@ -2070,16 +2071,16 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2070
2071
|
usedTabMembers.add(memberName);
|
|
2071
2072
|
tabMemberNames.push(memberName);
|
|
2072
2073
|
}
|
|
2073
|
-
lines.push(
|
|
2074
|
-
lines.push(`
|
|
2074
|
+
lines.push(`/** Tab constants for "${form.name}" (compile-time only, zero runtime) */`);
|
|
2075
|
+
lines.push(`export const enum ${tabsEnumName} {`);
|
|
2075
2076
|
for (let i = 0; i < namedTabs.length; i++) {
|
|
2076
2077
|
const tab = namedTabs[i];
|
|
2077
2078
|
if (tab.label) {
|
|
2078
|
-
lines.push(`
|
|
2079
|
+
lines.push(` /** ${tab.label} */`);
|
|
2079
2080
|
}
|
|
2080
|
-
lines.push(`
|
|
2081
|
+
lines.push(` ${tabMemberNames[i]} = '${tab.name}',`);
|
|
2081
2082
|
}
|
|
2082
|
-
lines.push("
|
|
2083
|
+
lines.push("}");
|
|
2083
2084
|
lines.push("");
|
|
2084
2085
|
for (let i = 0; i < namedTabs.length; i++) {
|
|
2085
2086
|
const tab = namedTabs[i];
|
|
@@ -2087,12 +2088,12 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2087
2088
|
if (namedSections.length === 0) continue;
|
|
2088
2089
|
const tabMemberName = tabMemberNames[i];
|
|
2089
2090
|
const sectionsEnumName = `${baseName}Form${tabMemberName}Sections`;
|
|
2090
|
-
lines.push(
|
|
2091
|
-
lines.push(`
|
|
2091
|
+
lines.push(`/** Section constants for tab "${tab.name}" (compile-time only, zero runtime) */`);
|
|
2092
|
+
lines.push(`export const enum ${sectionsEnumName} {`);
|
|
2092
2093
|
const usedSectionMembers = /* @__PURE__ */ new Set();
|
|
2093
2094
|
for (const section of namedSections) {
|
|
2094
2095
|
if (section.label) {
|
|
2095
|
-
lines.push(`
|
|
2096
|
+
lines.push(` /** ${section.label} */`);
|
|
2096
2097
|
}
|
|
2097
2098
|
let sectionMember = toSafeFormName(section.name) || toPascalCase(section.name);
|
|
2098
2099
|
const originalSectionMember = sectionMember;
|
|
@@ -2102,9 +2103,9 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2102
2103
|
sCounter++;
|
|
2103
2104
|
}
|
|
2104
2105
|
usedSectionMembers.add(sectionMember);
|
|
2105
|
-
lines.push(`
|
|
2106
|
+
lines.push(` ${sectionMember} = '${section.name}',`);
|
|
2106
2107
|
}
|
|
2107
|
-
lines.push("
|
|
2108
|
+
lines.push("}");
|
|
2108
2109
|
lines.push("");
|
|
2109
2110
|
}
|
|
2110
2111
|
}
|
|
@@ -2113,8 +2114,8 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2113
2114
|
const quickViews = specialControls.filter((sc) => sc.controlType === "quickview");
|
|
2114
2115
|
if (subgrids.length > 0) {
|
|
2115
2116
|
const subgridsEnumName = `${baseName}FormSubgrids`;
|
|
2116
|
-
lines.push(
|
|
2117
|
-
lines.push(`
|
|
2117
|
+
lines.push(`/** Subgrid constants for "${form.name}" (compile-time only, zero runtime) */`);
|
|
2118
|
+
lines.push(`export const enum ${subgridsEnumName} {`);
|
|
2118
2119
|
const usedMembers = /* @__PURE__ */ new Set();
|
|
2119
2120
|
for (const sg of subgrids) {
|
|
2120
2121
|
let member = toSafeFormName(sg.id) || toPascalCase(sg.id);
|
|
@@ -2126,16 +2127,16 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2126
2127
|
}
|
|
2127
2128
|
usedMembers.add(member);
|
|
2128
2129
|
const label = sg.targetEntityType ? `Subgrid: ${sg.targetEntityType}` : `Subgrid`;
|
|
2129
|
-
lines.push(`
|
|
2130
|
-
lines.push(`
|
|
2130
|
+
lines.push(` /** ${label} */`);
|
|
2131
|
+
lines.push(` ${member} = '${sg.id}',`);
|
|
2131
2132
|
}
|
|
2132
|
-
lines.push("
|
|
2133
|
+
lines.push("}");
|
|
2133
2134
|
lines.push("");
|
|
2134
2135
|
}
|
|
2135
2136
|
if (quickViews.length > 0) {
|
|
2136
2137
|
const qvEnumName = `${baseName}FormQuickViews`;
|
|
2137
|
-
lines.push(
|
|
2138
|
-
lines.push(`
|
|
2138
|
+
lines.push(`/** Quick View constants for "${form.name}" (compile-time only, zero runtime) */`);
|
|
2139
|
+
lines.push(`export const enum ${qvEnumName} {`);
|
|
2139
2140
|
const usedMembers = /* @__PURE__ */ new Set();
|
|
2140
2141
|
for (const qv of quickViews) {
|
|
2141
2142
|
let member = toSafeFormName(qv.id) || toPascalCase(qv.id);
|
|
@@ -2146,66 +2147,65 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2146
2147
|
counter++;
|
|
2147
2148
|
}
|
|
2148
2149
|
usedMembers.add(member);
|
|
2149
|
-
lines.push(`
|
|
2150
|
-
lines.push(`
|
|
2150
|
+
lines.push(` /** Quick View */`);
|
|
2151
|
+
lines.push(` ${member} = '${qv.id}',`);
|
|
2151
2152
|
}
|
|
2152
|
-
lines.push("
|
|
2153
|
+
lines.push("}");
|
|
2153
2154
|
lines.push("");
|
|
2154
2155
|
}
|
|
2155
|
-
lines.push(
|
|
2156
|
-
lines.push(`
|
|
2157
|
-
lines.push(`
|
|
2158
|
-
lines.push(`
|
|
2159
|
-
lines.push("
|
|
2160
|
-
lines.push("
|
|
2156
|
+
lines.push(`/** ${form.name} */`);
|
|
2157
|
+
lines.push(`export interface ${interfaceName} extends Omit<Xrm.FormContext, 'getAttribute' | 'getControl'> {`);
|
|
2158
|
+
lines.push(` /** Typisierter Feldzugriff: nur Felder die auf diesem Formular existieren */`);
|
|
2159
|
+
lines.push(` getAttribute<K extends ${fieldsTypeName}>(name: K): ${attrMapName}[K];`);
|
|
2160
|
+
lines.push(" getAttribute(index: number): Xrm.Attributes.Attribute;");
|
|
2161
|
+
lines.push(" getAttribute(): Xrm.Attributes.Attribute[];");
|
|
2161
2162
|
lines.push("");
|
|
2162
|
-
lines.push(`
|
|
2163
|
-
lines.push(`
|
|
2163
|
+
lines.push(` /** Typisierter Control-Zugriff: nur Controls die auf diesem Formular existieren */`);
|
|
2164
|
+
lines.push(` getControl<K extends ${fieldsTypeName}>(name: K): ${ctrlMapName}[K];`);
|
|
2164
2165
|
for (const sc of specialControls) {
|
|
2165
2166
|
const xrmType = specialControlToXrmType(sc.controlType);
|
|
2166
2167
|
if (xrmType) {
|
|
2167
|
-
lines.push(`
|
|
2168
|
+
lines.push(` getControl(name: "${sc.id}"): ${xrmType};`);
|
|
2168
2169
|
}
|
|
2169
2170
|
}
|
|
2170
|
-
lines.push("
|
|
2171
|
-
lines.push("
|
|
2171
|
+
lines.push(" getControl(index: number): Xrm.Controls.Control;");
|
|
2172
|
+
lines.push(" getControl(): Xrm.Controls.Control[];");
|
|
2172
2173
|
if (form.tabs.length > 0) {
|
|
2173
2174
|
lines.push("");
|
|
2174
|
-
lines.push("
|
|
2175
|
-
lines.push("
|
|
2176
|
-
lines.push("
|
|
2175
|
+
lines.push(" /** Typisierter Tab-Zugriff */");
|
|
2176
|
+
lines.push(" ui: {");
|
|
2177
|
+
lines.push(" tabs: {");
|
|
2177
2178
|
for (const tab of form.tabs) {
|
|
2178
2179
|
if (tab.name) {
|
|
2179
2180
|
const sectionNames = tab.sections.filter((s) => s.name).map((s) => s.name);
|
|
2180
2181
|
if (sectionNames.length > 0) {
|
|
2181
|
-
lines.push(`
|
|
2182
|
-
lines.push("
|
|
2182
|
+
lines.push(` get(name: "${tab.name}"): Xrm.Controls.Tab & {`);
|
|
2183
|
+
lines.push(" sections: {");
|
|
2183
2184
|
for (const sectionName of sectionNames) {
|
|
2184
|
-
lines.push(`
|
|
2185
|
+
lines.push(` get(name: "${sectionName}"): Xrm.Controls.Section;`);
|
|
2185
2186
|
}
|
|
2186
|
-
lines.push("
|
|
2187
|
-
lines.push(" };");
|
|
2187
|
+
lines.push(" get(name: string): Xrm.Controls.Section;");
|
|
2188
2188
|
lines.push(" };");
|
|
2189
|
+
lines.push(" };");
|
|
2189
2190
|
} else {
|
|
2190
|
-
lines.push(`
|
|
2191
|
+
lines.push(` get(name: "${tab.name}"): Xrm.Controls.Tab;`);
|
|
2191
2192
|
}
|
|
2192
2193
|
}
|
|
2193
2194
|
}
|
|
2194
|
-
lines.push("
|
|
2195
|
-
lines.push("
|
|
2196
|
-
lines.push("
|
|
2195
|
+
lines.push(" get(name: string): Xrm.Controls.Tab;");
|
|
2196
|
+
lines.push(" };");
|
|
2197
|
+
lines.push(" } & Xrm.Ui;");
|
|
2197
2198
|
}
|
|
2198
|
-
lines.push("
|
|
2199
|
+
lines.push("}");
|
|
2199
2200
|
const mockValuesName = `${interfaceName}MockValues`;
|
|
2200
2201
|
lines.push("");
|
|
2201
|
-
lines.push(
|
|
2202
|
-
lines.push(`
|
|
2202
|
+
lines.push(`/** Mock value types for "${form.name}" form (used with @xrmforge/testing) */`);
|
|
2203
|
+
lines.push(`export type ${mockValuesName} = {`);
|
|
2203
2204
|
for (const field of fields) {
|
|
2204
2205
|
const mockType = getFormMockValueType(field.attributeType);
|
|
2205
|
-
lines.push(`
|
|
2206
|
+
lines.push(` ${field.logicalName}?: ${mockType};`);
|
|
2206
2207
|
}
|
|
2207
|
-
lines.push("
|
|
2208
|
-
lines.push("}");
|
|
2208
|
+
lines.push("};");
|
|
2209
2209
|
lines.push("");
|
|
2210
2210
|
return lines.join("\n");
|
|
2211
2211
|
}
|
|
@@ -2256,15 +2256,12 @@ function labelToPascalMember2(label) {
|
|
|
2256
2256
|
}
|
|
2257
2257
|
function generateEntityFieldsEnum(info, options = {}) {
|
|
2258
2258
|
const labelConfig = options.labelConfig || DEFAULT_LABEL_CONFIG;
|
|
2259
|
-
const namespace = options.namespace || "XrmForge.Entities";
|
|
2260
2259
|
const entityName = toPascalCase(info.entity.LogicalName);
|
|
2261
2260
|
const enumName = `${entityName}Fields`;
|
|
2262
2261
|
const includedAttrs = info.attributes.filter(shouldIncludeInEntityInterface).sort((a, b) => a.LogicalName.localeCompare(b.LogicalName));
|
|
2263
2262
|
const lines = [];
|
|
2264
|
-
lines.push(
|
|
2265
|
-
lines.push(
|
|
2266
|
-
lines.push(` /** All fields of ${entityName} (for Web API $select queries) */`);
|
|
2267
|
-
lines.push(` const enum ${enumName} {`);
|
|
2263
|
+
lines.push(`/** All fields of ${entityName} (for Web API $select queries) */`);
|
|
2264
|
+
lines.push(`export const enum ${enumName} {`);
|
|
2268
2265
|
const usedNames = /* @__PURE__ */ new Set();
|
|
2269
2266
|
for (const attr of includedAttrs) {
|
|
2270
2267
|
const isLookup = isLookupType(attr.AttributeType);
|
|
@@ -2283,27 +2280,23 @@ function generateEntityFieldsEnum(info, options = {}) {
|
|
|
2283
2280
|
usedNames.add(memberName);
|
|
2284
2281
|
const dualLabel = getJSDocLabel(attr.DisplayName, labelConfig);
|
|
2285
2282
|
if (dualLabel) {
|
|
2286
|
-
lines.push(`
|
|
2283
|
+
lines.push(` /** ${dualLabel} */`);
|
|
2287
2284
|
}
|
|
2288
|
-
lines.push(`
|
|
2285
|
+
lines.push(` ${memberName} = '${propertyName}',`);
|
|
2289
2286
|
}
|
|
2290
|
-
lines.push(" }");
|
|
2291
2287
|
lines.push("}");
|
|
2292
2288
|
lines.push("");
|
|
2293
2289
|
return lines.join("\n");
|
|
2294
2290
|
}
|
|
2295
2291
|
function generateEntityNavigationProperties(info, options = {}) {
|
|
2296
2292
|
const labelConfig = options.labelConfig || DEFAULT_LABEL_CONFIG;
|
|
2297
|
-
const namespace = options.namespace || "XrmForge.Entities";
|
|
2298
2293
|
const entityName = toPascalCase(info.entity.LogicalName);
|
|
2299
2294
|
const enumName = `${entityName}NavigationProperties`;
|
|
2300
2295
|
const lookupAttrs = info.attributes.filter(shouldIncludeInEntityInterface).filter((a) => isLookupType(a.AttributeType)).sort((a, b) => a.LogicalName.localeCompare(b.LogicalName));
|
|
2301
2296
|
if (lookupAttrs.length === 0) return "";
|
|
2302
2297
|
const lines = [];
|
|
2303
|
-
lines.push(
|
|
2304
|
-
lines.push(
|
|
2305
|
-
lines.push(` /** Navigation properties of ${entityName} (for parseLookup and $expand) */`);
|
|
2306
|
-
lines.push(` const enum ${enumName} {`);
|
|
2298
|
+
lines.push(`/** Navigation properties of ${entityName} (for parseLookup and $expand) */`);
|
|
2299
|
+
lines.push(`export const enum ${enumName} {`);
|
|
2307
2300
|
const usedNames = /* @__PURE__ */ new Set();
|
|
2308
2301
|
for (const attr of lookupAttrs) {
|
|
2309
2302
|
const primaryLabel = getPrimaryLabel(attr.DisplayName, labelConfig);
|
|
@@ -2320,29 +2313,25 @@ function generateEntityNavigationProperties(info, options = {}) {
|
|
|
2320
2313
|
usedNames.add(memberName);
|
|
2321
2314
|
const dualLabel = getJSDocLabel(attr.DisplayName, labelConfig);
|
|
2322
2315
|
if (dualLabel) {
|
|
2323
|
-
lines.push(`
|
|
2316
|
+
lines.push(` /** ${dualLabel} */`);
|
|
2324
2317
|
}
|
|
2325
|
-
lines.push(`
|
|
2318
|
+
lines.push(` ${memberName} = '${attr.LogicalName}',`);
|
|
2326
2319
|
}
|
|
2327
|
-
lines.push(" }");
|
|
2328
2320
|
lines.push("}");
|
|
2329
2321
|
lines.push("");
|
|
2330
2322
|
return lines.join("\n");
|
|
2331
2323
|
}
|
|
2332
2324
|
|
|
2333
2325
|
// src/generators/entity-names-generator.ts
|
|
2334
|
-
function generateEntityNamesEnum(entityNames,
|
|
2335
|
-
const namespace = options.namespace ?? "XrmForge";
|
|
2326
|
+
function generateEntityNamesEnum(entityNames, _options = {}) {
|
|
2336
2327
|
const sorted = [...entityNames].sort();
|
|
2337
2328
|
const lines = [];
|
|
2338
|
-
lines.push(
|
|
2339
|
-
lines.push("
|
|
2340
|
-
lines.push(" const enum EntityNames {");
|
|
2329
|
+
lines.push("/** Entity logical names for Xrm.WebApi calls (compile-time only, zero runtime) */");
|
|
2330
|
+
lines.push("export const enum EntityNames {");
|
|
2341
2331
|
for (const name of sorted) {
|
|
2342
2332
|
const pascal = toPascalCase(name);
|
|
2343
|
-
lines.push(`
|
|
2333
|
+
lines.push(` ${pascal} = '${name}',`);
|
|
2344
2334
|
}
|
|
2345
|
-
lines.push(" }");
|
|
2346
2335
|
lines.push("}");
|
|
2347
2336
|
lines.push("");
|
|
2348
2337
|
return lines.join("\n");
|
|
@@ -2541,7 +2530,6 @@ function createBoundAction(operationName, entityLogicalName, paramMeta) {
|
|
|
2541
2530
|
}
|
|
2542
2531
|
function createUnboundAction(operationName, paramMeta) {
|
|
2543
2532
|
return {
|
|
2544
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- return type varies (Response or parsed JSON)
|
|
2545
2533
|
async execute(params) {
|
|
2546
2534
|
const req = buildUnboundRequest(
|
|
2547
2535
|
operationName,
|
|
@@ -2678,46 +2666,42 @@ function deriveActionName(uniquename) {
|
|
|
2678
2666
|
function generateParamsInterface(name, params) {
|
|
2679
2667
|
if (params.length === 0) return "";
|
|
2680
2668
|
const lines = [];
|
|
2681
|
-
lines.push(`
|
|
2669
|
+
lines.push(`export interface ${name}Params {`);
|
|
2682
2670
|
for (const param of params) {
|
|
2683
2671
|
const mapped = mapCustomApiParameterType(param.type, param.logicalentityname);
|
|
2684
2672
|
const optional = param.isoptional ? "?" : "";
|
|
2685
2673
|
if (param.description) {
|
|
2686
|
-
lines.push(`
|
|
2674
|
+
lines.push(` /** ${param.description} */`);
|
|
2687
2675
|
}
|
|
2688
|
-
lines.push(`
|
|
2676
|
+
lines.push(` ${param.uniquename}${optional}: ${mapped.tsType};`);
|
|
2689
2677
|
}
|
|
2690
|
-
lines.push("
|
|
2678
|
+
lines.push("}");
|
|
2691
2679
|
return lines.join("\n");
|
|
2692
2680
|
}
|
|
2693
2681
|
function generateResultInterface(name, props) {
|
|
2694
2682
|
if (props.length === 0) return "";
|
|
2695
2683
|
const lines = [];
|
|
2696
|
-
lines.push(`
|
|
2684
|
+
lines.push(`export interface ${name}Result {`);
|
|
2697
2685
|
for (const prop of props) {
|
|
2698
2686
|
const mapped = mapCustomApiParameterType(prop.type, prop.logicalentityname);
|
|
2699
2687
|
if (prop.description) {
|
|
2700
|
-
lines.push(`
|
|
2688
|
+
lines.push(` /** ${prop.description} */`);
|
|
2701
2689
|
}
|
|
2702
|
-
lines.push(`
|
|
2690
|
+
lines.push(` ${prop.uniquename}: ${mapped.tsType};`);
|
|
2703
2691
|
}
|
|
2704
|
-
lines.push("
|
|
2692
|
+
lines.push("}");
|
|
2705
2693
|
return lines.join("\n");
|
|
2706
2694
|
}
|
|
2707
|
-
function generateActionDeclarations(apis,
|
|
2708
|
-
const baseNamespace = isFunction ? options.functionsNamespace || "XrmForge.Functions" : options.actionsNamespace || "XrmForge.Actions";
|
|
2709
|
-
const namespace = entityName ? `${baseNamespace}.${toPascalCase(entityName)}` : baseNamespace;
|
|
2695
|
+
function generateActionDeclarations(apis, _isFunction, _entityName, _options = {}) {
|
|
2710
2696
|
const lines = [];
|
|
2711
2697
|
lines.push("// Auto-generated by @xrmforge/typegen - DO NOT EDIT");
|
|
2712
2698
|
lines.push("");
|
|
2713
|
-
lines.push(`declare namespace ${namespace} {`);
|
|
2714
2699
|
for (const apiInfo of apis) {
|
|
2715
2700
|
const name = deriveActionName(apiInfo.api.uniquename);
|
|
2716
2701
|
const hasParams = apiInfo.requestParameters.length > 0;
|
|
2717
2702
|
const hasResult = apiInfo.responseProperties.length > 0;
|
|
2718
|
-
lines.push("");
|
|
2719
2703
|
const description = apiInfo.api.description || apiInfo.api.displayname || apiInfo.api.uniquename;
|
|
2720
|
-
lines.push(
|
|
2704
|
+
lines.push(`/** ${description} (${apiInfo.api.uniquename}) */`);
|
|
2721
2705
|
if (hasParams) {
|
|
2722
2706
|
lines.push(generateParamsInterface(name, apiInfo.requestParameters));
|
|
2723
2707
|
lines.push("");
|
|
@@ -2726,29 +2710,11 @@ function generateActionDeclarations(apis, isFunction, entityName, options = {})
|
|
|
2726
2710
|
lines.push(generateResultInterface(name, apiInfo.responseProperties));
|
|
2727
2711
|
lines.push("");
|
|
2728
2712
|
}
|
|
2729
|
-
const importFrom = options.importPath || "@xrmforge/typegen";
|
|
2730
|
-
if (apiInfo.api.bindingtype === 0 /* Global */) {
|
|
2731
|
-
if (hasParams && hasResult) {
|
|
2732
|
-
lines.push(` const ${name}: import('${importFrom}').UnboundActionWithParamsExecutor<${name}Params, ${name}Result>;`);
|
|
2733
|
-
} else if (hasParams) {
|
|
2734
|
-
lines.push(` const ${name}: import('${importFrom}').UnboundActionWithParamsExecutor<${name}Params, void>;`);
|
|
2735
|
-
} else {
|
|
2736
|
-
lines.push(` const ${name}: import('${importFrom}').UnboundActionExecutor;`);
|
|
2737
|
-
}
|
|
2738
|
-
} else {
|
|
2739
|
-
if (hasParams) {
|
|
2740
|
-
lines.push(` const ${name}: import('${importFrom}').BoundActionWithParamsExecutor<${name}Params>;`);
|
|
2741
|
-
} else {
|
|
2742
|
-
lines.push(` const ${name}: import('${importFrom}').BoundActionExecutor;`);
|
|
2743
|
-
}
|
|
2744
|
-
}
|
|
2745
2713
|
}
|
|
2746
|
-
lines.push("}");
|
|
2747
|
-
lines.push("");
|
|
2748
2714
|
return lines.join("\n");
|
|
2749
2715
|
}
|
|
2750
2716
|
function generateActionModule(apis, isFunction, options = {}) {
|
|
2751
|
-
const importPath = options.importPath || "@xrmforge/
|
|
2717
|
+
const importPath = options.importPath || "@xrmforge/helpers";
|
|
2752
2718
|
const lines = [];
|
|
2753
2719
|
lines.push("// Auto-generated by @xrmforge/typegen - DO NOT EDIT");
|
|
2754
2720
|
lines.push("");
|
|
@@ -2773,8 +2739,17 @@ function generateActionModule(apis, isFunction, options = {}) {
|
|
|
2773
2739
|
for (const apiInfo of apis) {
|
|
2774
2740
|
const name = deriveActionName(apiInfo.api.uniquename);
|
|
2775
2741
|
const hasParams = apiInfo.requestParameters.length > 0;
|
|
2742
|
+
const hasResult = apiInfo.responseProperties.length > 0;
|
|
2776
2743
|
const description = apiInfo.api.description || apiInfo.api.displayname || apiInfo.api.uniquename;
|
|
2777
|
-
lines.push(`/** ${description} */`);
|
|
2744
|
+
lines.push(`/** ${description} (${apiInfo.api.uniquename}) */`);
|
|
2745
|
+
if (hasParams) {
|
|
2746
|
+
lines.push(generateParamsInterface(name, apiInfo.requestParameters));
|
|
2747
|
+
lines.push("");
|
|
2748
|
+
}
|
|
2749
|
+
if (hasResult) {
|
|
2750
|
+
lines.push(generateResultInterface(name, apiInfo.responseProperties));
|
|
2751
|
+
lines.push("");
|
|
2752
|
+
}
|
|
2778
2753
|
if (apiInfo.api.bindingtype === 0 /* Global */) {
|
|
2779
2754
|
if (isFunction) {
|
|
2780
2755
|
lines.push(`export const ${name} = createUnboundFunction('${apiInfo.api.uniquename}');`);
|
|
@@ -2860,10 +2835,10 @@ async function writeAllFiles(outputDir, files) {
|
|
|
2860
2835
|
}
|
|
2861
2836
|
async function deleteOrphanedFiles(outputDir, deletedEntityNames) {
|
|
2862
2837
|
let deleted = 0;
|
|
2863
|
-
const subdirs = ["entities", "optionsets", "forms"];
|
|
2838
|
+
const subdirs = ["entities", "optionsets", "forms", "fields"];
|
|
2864
2839
|
for (const entityName of deletedEntityNames) {
|
|
2865
2840
|
for (const subdir of subdirs) {
|
|
2866
|
-
const filePath = join2(outputDir, subdir, `${entityName}.
|
|
2841
|
+
const filePath = join2(outputDir, subdir, `${entityName}.ts`);
|
|
2867
2842
|
try {
|
|
2868
2843
|
await unlink(filePath);
|
|
2869
2844
|
deleted++;
|
|
@@ -2885,29 +2860,49 @@ var GENERATED_HEADER = `// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
2885
2860
|
function addGeneratedHeader(content) {
|
|
2886
2861
|
return GENERATED_HEADER + content;
|
|
2887
2862
|
}
|
|
2863
|
+
function toImportSpecifier(relativePath) {
|
|
2864
|
+
const withoutExt = relativePath.replace(/\.ts$/, "");
|
|
2865
|
+
return `./${withoutExt}.js`;
|
|
2866
|
+
}
|
|
2888
2867
|
function generateBarrelIndex(files) {
|
|
2889
2868
|
const lines = [GENERATED_HEADER];
|
|
2890
2869
|
const entities = files.filter((f) => f.type === "entity");
|
|
2891
2870
|
const optionsets = files.filter((f) => f.type === "optionset");
|
|
2892
2871
|
const forms = files.filter((f) => f.type === "form");
|
|
2872
|
+
const fields = files.filter((f) => f.type === "fields");
|
|
2873
|
+
const actions = files.filter((f) => f.type === "action");
|
|
2893
2874
|
if (entities.length > 0) {
|
|
2894
2875
|
lines.push("// Entity Interfaces");
|
|
2895
2876
|
for (const f of entities) {
|
|
2896
|
-
lines.push(
|
|
2877
|
+
lines.push(`export * from '${toImportSpecifier(f.relativePath)}';`);
|
|
2897
2878
|
}
|
|
2898
2879
|
lines.push("");
|
|
2899
2880
|
}
|
|
2900
2881
|
if (optionsets.length > 0) {
|
|
2901
|
-
lines.push("// OptionSet Enums");
|
|
2882
|
+
lines.push("// OptionSet Enums - import directly from individual files to avoid name conflicts:");
|
|
2902
2883
|
for (const f of optionsets) {
|
|
2903
|
-
lines.push(
|
|
2884
|
+
lines.push(`// import { ... } from '${toImportSpecifier(f.relativePath)}';`);
|
|
2904
2885
|
}
|
|
2905
2886
|
lines.push("");
|
|
2906
2887
|
}
|
|
2907
2888
|
if (forms.length > 0) {
|
|
2908
2889
|
lines.push("// Form Interfaces");
|
|
2909
2890
|
for (const f of forms) {
|
|
2910
|
-
lines.push(
|
|
2891
|
+
lines.push(`export * from '${toImportSpecifier(f.relativePath)}';`);
|
|
2892
|
+
}
|
|
2893
|
+
lines.push("");
|
|
2894
|
+
}
|
|
2895
|
+
if (fields.length > 0) {
|
|
2896
|
+
lines.push("// Entity Fields & Navigation Properties - import directly from individual files to avoid name conflicts:");
|
|
2897
|
+
for (const f of fields) {
|
|
2898
|
+
lines.push(`// import { ... } from '${toImportSpecifier(f.relativePath)}';`);
|
|
2899
|
+
}
|
|
2900
|
+
lines.push("");
|
|
2901
|
+
}
|
|
2902
|
+
if (actions.length > 0) {
|
|
2903
|
+
lines.push("// Custom API Actions & Functions");
|
|
2904
|
+
for (const f of actions) {
|
|
2905
|
+
lines.push(`export * from '${toImportSpecifier(f.relativePath)}';`);
|
|
2911
2906
|
}
|
|
2912
2907
|
lines.push("");
|
|
2913
2908
|
}
|
|
@@ -3024,6 +3019,19 @@ var TypeGenerationOrchestrator = class {
|
|
|
3024
3019
|
}
|
|
3025
3020
|
}
|
|
3026
3021
|
}
|
|
3022
|
+
if (this.config.generateEntities) {
|
|
3023
|
+
const hasPartyList = Object.values(cachedEntityInfos).some(
|
|
3024
|
+
(info) => info.attributes.some((a) => isPartyListType(a.AttributeType))
|
|
3025
|
+
);
|
|
3026
|
+
if (hasPartyList) {
|
|
3027
|
+
const activityPartyContent = generateActivityPartyInterface();
|
|
3028
|
+
allFiles.push({
|
|
3029
|
+
relativePath: "entities/_activity-party.ts",
|
|
3030
|
+
content: addGeneratedHeader(activityPartyContent),
|
|
3031
|
+
type: "entity"
|
|
3032
|
+
});
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
3027
3035
|
this.logger.info(`Generating types for ${this.config.entities.length - failedEntities.size} entities`);
|
|
3028
3036
|
for (const entityName of this.config.entities) {
|
|
3029
3037
|
if (signal?.aborted) break;
|
|
@@ -3047,11 +3055,9 @@ var TypeGenerationOrchestrator = class {
|
|
|
3047
3055
|
allFiles.push(...actionFiles);
|
|
3048
3056
|
}
|
|
3049
3057
|
if (this.config.entities.length > 0) {
|
|
3050
|
-
const entityNamesContent = generateEntityNamesEnum(this.config.entities
|
|
3051
|
-
namespace: this.config.namespacePrefix
|
|
3052
|
-
});
|
|
3058
|
+
const entityNamesContent = generateEntityNamesEnum(this.config.entities);
|
|
3053
3059
|
allFiles.push({
|
|
3054
|
-
relativePath: "entity-names.
|
|
3060
|
+
relativePath: "entity-names.ts",
|
|
3055
3061
|
content: addGeneratedHeader(entityNamesContent),
|
|
3056
3062
|
type: "entity"
|
|
3057
3063
|
});
|
|
@@ -3059,7 +3065,7 @@ var TypeGenerationOrchestrator = class {
|
|
|
3059
3065
|
if (allFiles.length > 0) {
|
|
3060
3066
|
const indexContent = generateBarrelIndex(allFiles);
|
|
3061
3067
|
const indexFile = {
|
|
3062
|
-
relativePath: "index.
|
|
3068
|
+
relativePath: "index.ts",
|
|
3063
3069
|
content: indexContent,
|
|
3064
3070
|
type: "entity"
|
|
3065
3071
|
};
|
|
@@ -3212,11 +3218,10 @@ var TypeGenerationOrchestrator = class {
|
|
|
3212
3218
|
const files = [];
|
|
3213
3219
|
if (this.config.generateEntities) {
|
|
3214
3220
|
const entityContent = generateEntityInterface(entityInfo, {
|
|
3215
|
-
labelConfig: this.config.labelConfig
|
|
3216
|
-
namespace: `${this.config.namespacePrefix}.Entities`
|
|
3221
|
+
labelConfig: this.config.labelConfig
|
|
3217
3222
|
});
|
|
3218
3223
|
files.push({
|
|
3219
|
-
relativePath: `entities/${entityName}.
|
|
3224
|
+
relativePath: `entities/${entityName}.ts`,
|
|
3220
3225
|
content: addGeneratedHeader(entityContent),
|
|
3221
3226
|
type: "entity"
|
|
3222
3227
|
});
|
|
@@ -3225,13 +3230,12 @@ var TypeGenerationOrchestrator = class {
|
|
|
3225
3230
|
const picklistAttrs = this.getPicklistAttributes(entityInfo);
|
|
3226
3231
|
if (picklistAttrs.length > 0) {
|
|
3227
3232
|
const optionSets = generateEntityOptionSets(picklistAttrs, entityName, {
|
|
3228
|
-
labelConfig: this.config.labelConfig
|
|
3229
|
-
namespace: `${this.config.namespacePrefix}.OptionSets`
|
|
3233
|
+
labelConfig: this.config.labelConfig
|
|
3230
3234
|
});
|
|
3231
3235
|
if (optionSets.length > 0) {
|
|
3232
3236
|
const combinedContent = optionSets.map((os) => os.content).join("\n");
|
|
3233
3237
|
files.push({
|
|
3234
|
-
relativePath: `optionsets/${entityName}.
|
|
3238
|
+
relativePath: `optionsets/${entityName}.ts`,
|
|
3235
3239
|
content: addGeneratedHeader(combinedContent),
|
|
3236
3240
|
type: "optionset"
|
|
3237
3241
|
});
|
|
@@ -3247,14 +3251,13 @@ var TypeGenerationOrchestrator = class {
|
|
|
3247
3251
|
entityName,
|
|
3248
3252
|
entityInfo.attributes,
|
|
3249
3253
|
{
|
|
3250
|
-
labelConfig: this.config.labelConfig
|
|
3251
|
-
namespacePrefix: `${this.config.namespacePrefix}.Forms`
|
|
3254
|
+
labelConfig: this.config.labelConfig
|
|
3252
3255
|
}
|
|
3253
3256
|
);
|
|
3254
3257
|
if (formResults.length > 0) {
|
|
3255
3258
|
const combinedContent = formResults.map((f) => f.content).join("\n");
|
|
3256
3259
|
files.push({
|
|
3257
|
-
relativePath: `forms/${entityName}.
|
|
3260
|
+
relativePath: `forms/${entityName}.ts`,
|
|
3258
3261
|
content: addGeneratedHeader(combinedContent),
|
|
3259
3262
|
type: "form"
|
|
3260
3263
|
});
|
|
@@ -3263,6 +3266,21 @@ var TypeGenerationOrchestrator = class {
|
|
|
3263
3266
|
warnings.push(`No forms found for ${entityName}`);
|
|
3264
3267
|
}
|
|
3265
3268
|
}
|
|
3269
|
+
if (this.config.generateEntities) {
|
|
3270
|
+
const fieldsEnumContent = generateEntityFieldsEnum(entityInfo, {
|
|
3271
|
+
labelConfig: this.config.labelConfig
|
|
3272
|
+
});
|
|
3273
|
+
const navPropsContent = generateEntityNavigationProperties(entityInfo, {
|
|
3274
|
+
labelConfig: this.config.labelConfig
|
|
3275
|
+
});
|
|
3276
|
+
const combinedFieldsContent = navPropsContent ? `${fieldsEnumContent}
|
|
3277
|
+
${navPropsContent}` : fieldsEnumContent;
|
|
3278
|
+
files.push({
|
|
3279
|
+
relativePath: `fields/${entityName}.ts`,
|
|
3280
|
+
content: addGeneratedHeader(combinedFieldsContent),
|
|
3281
|
+
type: "fields"
|
|
3282
|
+
});
|
|
3283
|
+
}
|
|
3266
3284
|
return { entityLogicalName: entityName, files, warnings };
|
|
3267
3285
|
}
|
|
3268
3286
|
/**
|
|
@@ -3279,20 +3297,16 @@ var TypeGenerationOrchestrator = class {
|
|
|
3279
3297
|
this.logger.info(`Filtered Custom APIs by prefix "${this.config.actionsFilter}": ${before} -> ${customApis.length}`);
|
|
3280
3298
|
}
|
|
3281
3299
|
if (customApis.length > 0) {
|
|
3282
|
-
const importPath = "@xrmforge/
|
|
3300
|
+
const importPath = "@xrmforge/helpers";
|
|
3283
3301
|
const grouped = groupCustomApis(customApis);
|
|
3284
3302
|
for (const [key, apis] of grouped.actions) {
|
|
3285
3303
|
const entityName = key === "global" ? void 0 : key;
|
|
3286
3304
|
const declarations = generateActionDeclarations(apis, false, entityName, { importPath });
|
|
3287
3305
|
const module = generateActionModule(apis, false, { importPath });
|
|
3288
|
-
files.push({
|
|
3289
|
-
relativePath: `actions/${key}.d.ts`,
|
|
3290
|
-
content: addGeneratedHeader(declarations),
|
|
3291
|
-
type: "action"
|
|
3292
|
-
});
|
|
3293
3306
|
files.push({
|
|
3294
3307
|
relativePath: `actions/${key}.ts`,
|
|
3295
|
-
content: addGeneratedHeader(
|
|
3308
|
+
content: addGeneratedHeader(`${declarations}
|
|
3309
|
+
${module}`),
|
|
3296
3310
|
type: "action"
|
|
3297
3311
|
});
|
|
3298
3312
|
}
|
|
@@ -3300,14 +3314,10 @@ var TypeGenerationOrchestrator = class {
|
|
|
3300
3314
|
const entityName = key === "global" ? void 0 : key;
|
|
3301
3315
|
const declarations = generateActionDeclarations(apis, true, entityName, { importPath });
|
|
3302
3316
|
const module = generateActionModule(apis, true, { importPath });
|
|
3303
|
-
files.push({
|
|
3304
|
-
relativePath: `functions/${key}.d.ts`,
|
|
3305
|
-
content: addGeneratedHeader(declarations),
|
|
3306
|
-
type: "action"
|
|
3307
|
-
});
|
|
3308
3317
|
files.push({
|
|
3309
3318
|
relativePath: `functions/${key}.ts`,
|
|
3310
|
-
content: addGeneratedHeader(
|
|
3319
|
+
content: addGeneratedHeader(`${declarations}
|
|
3320
|
+
${module}`),
|
|
3311
3321
|
type: "action"
|
|
3312
3322
|
});
|
|
3313
3323
|
}
|