@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/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 !== "ENOENT") {
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(namespace = "XrmForge.Entities") {
1751
+ function generateActivityPartyInterface() {
1752
1752
  const lines = [];
1753
- lines.push(`declare namespace ${namespace} {`);
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(" * Activity Party - Teilnehmer einer Aktivit\xE4t (E-Mail, Termin, etc.)");
1757
- lines.push(" * Wird von PartyList-Feldern (to, from, cc, bcc, requiredattendees) referenziert.");
1758
- lines.push(" * @see https://learn.microsoft.com/en-us/power-apps/developer/data-platform/reference/entities/activityparty");
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(" interface ActivityParty {");
1761
- lines.push(" /** Primary key */");
1762
- lines.push(" activitypartyid?: string;");
1763
- lines.push(" /** Referenz auf die zugeh\xF6rige Aktivit\xE4t */");
1764
- lines.push(" _activityid_value?: string;");
1765
- lines.push(" /** Referenz auf den Teilnehmer (account | contact | systemuser | queue | knowledgearticle) */");
1766
- lines.push(" _partyid_value?: string;");
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
- lines.push(`declare namespace ${namespace} {`);
1832
- lines.push("");
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(` /** ${entityLabel} */`);
1833
+ lines.push(`/** ${entityLabel} */`);
1835
1834
  }
1836
- lines.push(` interface ${entityName} {`);
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(` /** ${jsdocParts.join(" - ")} */`);
1860
+ lines.push(` /** ${jsdocParts.join(" - ")} */`);
1862
1861
  }
1863
- lines.push(` ${propertyName}: ${tsType} | null;`);
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(` /** ActivityParty collection (${partyListAttrs.length} PartyList-Felder: ${partyListAttrs.map((a) => a.LogicalName).join(", ")}) */`);
1873
- lines.push(` ${navPropName}: ActivityParty[] | null;`);
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(` /** ${enumLabel} (${optionSet.Name}) */`);
1898
+ lines.push(`/** ${enumLabel} (${optionSet.Name}) */`);
1905
1899
  }
1906
- lines.push(` const enum ${enumName} {`);
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(` /** ${memberLabel} */`);
1907
+ lines.push(` /** ${memberLabel} */`);
1914
1908
  }
1915
- lines.push(` ${member.name} = ${member.value},`);
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(`declare namespace ${namespace} {`);
2025
- lines.push("");
2026
- lines.push(` /** Valid field names for the "${form.name}" form */`);
2027
- lines.push(` type ${fieldsTypeName} =`);
2028
- for (let i = 0; i < fields.length; i++) {
2029
- const separator = i === fields.length - 1 ? ";" : "";
2030
- lines.push(` | "${fields[i].logicalName}"${separator}`);
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(` /** Attribute type map for "${form.name}" */`);
2034
- lines.push(` type ${attrMapName} = {`);
2035
- for (const field of fields) {
2036
- lines.push(` ${field.logicalName}: ${field.formAttributeType};`);
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(` /** Control type map for "${form.name}" */`);
2041
- lines.push(` type ${ctrlMapName} = {`);
2042
- for (const field of fields) {
2043
- lines.push(` ${field.logicalName}: ${field.formControlType};`);
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(` /** Field constants for "${form.name}" (compile-time only, zero runtime) */`);
2048
- lines.push(` const enum ${fieldsTypeName}Enum {`);
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(` /** ${field.label} */`);
2052
+ lines.push(` /** ${field.label} */`);
2052
2053
  }
2053
- lines.push(` ${field.enumMemberName} = '${field.logicalName}',`);
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(` /** Tab constants for "${form.name}" (compile-time only, zero runtime) */`);
2074
- lines.push(` const enum ${tabsEnumName} {`);
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(` /** ${tab.label} */`);
2079
+ lines.push(` /** ${tab.label} */`);
2079
2080
  }
2080
- lines.push(` ${tabMemberNames[i]} = '${tab.name}',`);
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(` /** Section constants for tab "${tab.name}" (compile-time only, zero runtime) */`);
2091
- lines.push(` const enum ${sectionsEnumName} {`);
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(` /** ${section.label} */`);
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(` ${sectionMember} = '${section.name}',`);
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(` /** Subgrid constants for "${form.name}" (compile-time only, zero runtime) */`);
2117
- lines.push(` const enum ${subgridsEnumName} {`);
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(` /** ${label} */`);
2130
- lines.push(` ${member} = '${sg.id}',`);
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(` /** Quick View constants for "${form.name}" (compile-time only, zero runtime) */`);
2138
- lines.push(` const enum ${qvEnumName} {`);
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(` /** Quick View */`);
2150
- lines.push(` ${member} = '${qv.id}',`);
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(` /** ${form.name} */`);
2156
- lines.push(` interface ${interfaceName} extends Omit<Xrm.FormContext, 'getAttribute' | 'getControl'> {`);
2157
- lines.push(` /** Typisierter Feldzugriff: nur Felder die auf diesem Formular existieren */`);
2158
- lines.push(` getAttribute<K extends ${fieldsTypeName}>(name: K): ${attrMapName}[K];`);
2159
- lines.push(" getAttribute(index: number): Xrm.Attributes.Attribute;");
2160
- lines.push(" getAttribute(): Xrm.Attributes.Attribute[];");
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(` /** Typisierter Control-Zugriff: nur Controls die auf diesem Formular existieren */`);
2163
- lines.push(` getControl<K extends ${fieldsTypeName}>(name: K): ${ctrlMapName}[K];`);
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(` getControl(name: "${sc.id}"): ${xrmType};`);
2168
+ lines.push(` getControl(name: "${sc.id}"): ${xrmType};`);
2168
2169
  }
2169
2170
  }
2170
- lines.push(" getControl(index: number): Xrm.Controls.Control;");
2171
- lines.push(" getControl(): Xrm.Controls.Control[];");
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(" /** Typisierter Tab-Zugriff */");
2175
- lines.push(" ui: {");
2176
- lines.push(" tabs: {");
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(` get(name: "${tab.name}"): Xrm.Controls.Tab & {`);
2182
- lines.push(" sections: {");
2182
+ lines.push(` get(name: "${tab.name}"): Xrm.Controls.Tab & {`);
2183
+ lines.push(" sections: {");
2183
2184
  for (const sectionName of sectionNames) {
2184
- lines.push(` get(name: "${sectionName}"): Xrm.Controls.Section;`);
2185
+ lines.push(` get(name: "${sectionName}"): Xrm.Controls.Section;`);
2185
2186
  }
2186
- lines.push(" get(name: string): Xrm.Controls.Section;");
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(` get(name: "${tab.name}"): Xrm.Controls.Tab;`);
2191
+ lines.push(` get(name: "${tab.name}"): Xrm.Controls.Tab;`);
2191
2192
  }
2192
2193
  }
2193
2194
  }
2194
- lines.push(" get(name: string): Xrm.Controls.Tab;");
2195
- lines.push(" };");
2196
- lines.push(" } & Xrm.Ui;");
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(` /** Mock value types for "${form.name}" form (used with @xrmforge/testing) */`);
2202
- lines.push(` type ${mockValuesName} = {`);
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(` ${field.logicalName}?: ${mockType};`);
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(`declare namespace ${namespace} {`);
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(` /** ${dualLabel} */`);
2283
+ lines.push(` /** ${dualLabel} */`);
2287
2284
  }
2288
- lines.push(` ${memberName} = '${propertyName}',`);
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(`declare namespace ${namespace} {`);
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(` /** ${dualLabel} */`);
2316
+ lines.push(` /** ${dualLabel} */`);
2324
2317
  }
2325
- lines.push(` ${memberName} = '${attr.LogicalName}',`);
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, options = {}) {
2335
- const namespace = options.namespace ?? "XrmForge";
2326
+ function generateEntityNamesEnum(entityNames, _options = {}) {
2336
2327
  const sorted = [...entityNames].sort();
2337
2328
  const lines = [];
2338
- lines.push(`declare namespace ${namespace} {`);
2339
- lines.push(" /** Entity logical names for Xrm.WebApi calls (compile-time only, zero runtime) */");
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(` ${pascal} = '${name}',`);
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(` interface ${name}Params {`);
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(` /** ${param.description} */`);
2674
+ lines.push(` /** ${param.description} */`);
2687
2675
  }
2688
- lines.push(` ${param.uniquename}${optional}: ${mapped.tsType};`);
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(` interface ${name}Result {`);
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(` /** ${prop.description} */`);
2688
+ lines.push(` /** ${prop.description} */`);
2701
2689
  }
2702
- lines.push(` ${prop.uniquename}: ${mapped.tsType};`);
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, isFunction, entityName, options = {}) {
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(` /** ${description} (${apiInfo.api.uniquename}) */`);
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/typegen";
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}.d.ts`);
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(`/// <reference path="${f.relativePath}" />`);
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(`/// <reference path="${f.relativePath}" />`);
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(`/// <reference path="${f.relativePath}" />`);
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.d.ts",
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.d.ts",
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}.d.ts`,
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}.d.ts`,
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}.d.ts`,
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/typegen";
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(module),
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(module),
3319
+ content: addGeneratedHeader(`${declarations}
3320
+ ${module}`),
3311
3321
  type: "action"
3312
3322
  });
3313
3323
  }