@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 CHANGED
@@ -2,6 +2,32 @@
2
2
 
3
3
  How to convert legacy Dynamics 365 JavaScript to type-safe TypeScript with XrmForge.
4
4
 
5
+ ## Breaking Changes in v0.8.0 (ES Module Output)
6
+
7
+ ### What changed
8
+ - Generated files are now `.ts` modules with `export` statements instead of `.d.ts` files with `declare namespace`
9
+ - Default output directory changed from `./typings` to `./generated`
10
+ - Entity Fields enums are now generated in a separate `fields/` directory
11
+ - Action declarations and runtime code are now in a single `.ts` file per group
12
+ - The barrel index uses `export * from` instead of `/// <reference path />`
13
+
14
+ ### Migration steps
15
+ 1. Update your `xrmforge generate` command: replace `--output ./typings` with `--output ./generated` (or omit for the new default)
16
+ 2. Replace namespace access with imports:
17
+ ```typescript
18
+ // Before (v0.7.x):
19
+ type AccountForm = XrmForge.Forms.Account.AccountMainForm;
20
+
21
+ // After (v0.8.0):
22
+ import type { AccountMainForm } from './generated/forms/account.js';
23
+ ```
24
+ 3. Update your tsconfig.json: replace `"typings/**/*.d.ts"` in `include` with `"generated/**/*.ts"`
25
+ 4. Entity Fields enums are now available:
26
+ ```typescript
27
+ import { AccountFields } from './generated/fields/account.js';
28
+ const result = await Xrm.WebApi.retrieveRecord('account', id, `?$select=${AccountFields.Name},${AccountFields.Telephone1}`);
29
+ ```
30
+
5
31
  ## Breaking Changes in v0.7.0
6
32
 
7
33
  - The `@xrmforge/typegen/helpers` subpath export has been removed.
@@ -30,14 +56,15 @@ npx xrmforge generate \
30
56
  --tenant-id YOUR-TENANT-ID \
31
57
  --client-id YOUR-CLIENT-ID \
32
58
  --entities account,contact,opportunity \
33
- --output ./typings
59
+ --output ./generated
34
60
  ```
35
61
 
36
62
  This generates:
37
- - `typings/entities/*.d.ts` - Entity interfaces with typed attributes
38
- - `typings/forms/*.d.ts` - Form interfaces with Fields enum, Tabs enum, Subgrid enum
39
- - `typings/optionsets/*.d.ts` - OptionSet const enums with labels
40
- - `typings/entity-names.d.ts` - EntityNames const enum
63
+ - `generated/entities/*.ts` - Entity interfaces with typed attributes
64
+ - `generated/forms/*.ts` - Form interfaces with Fields enum, Tabs enum, Subgrid enum
65
+ - `generated/optionsets/*.ts` - OptionSet const enums with labels
66
+ - `generated/fields/*.ts` - Entity Fields enums for type-safe $select queries
67
+ - `generated/entity-names.ts` - EntityNames const enum
41
68
 
42
69
  ## Step 3: Convert Form Scripts
43
70
 
@@ -62,17 +89,19 @@ LM.Account = {
62
89
 
63
90
  ```typescript
64
91
  // account-form.ts - typed, safe, autocomplete everywhere
65
- import { AccountMainFormFieldsEnum as Fields } from '../../typings/forms/account';
92
+ import { AccountMainFormFieldsEnum as Fields } from '../../generated/forms/account.js';
93
+ import type { AccountMainForm } from '../../generated/forms/account.js';
94
+ import { StatusCode } from '../../generated/optionsets/account.js';
66
95
 
67
96
  export function onLoad(executionContext: Xrm.Events.EventContext): void {
68
- const form = executionContext.getFormContext() as XrmForge.Forms.Account.AccountMainForm;
97
+ const form = executionContext.getFormContext() as AccountMainForm;
69
98
 
70
99
  // Fields enum: compile error on typos, autocomplete in IDE
71
100
  const name = form.getAttribute(Fields.AccountName); // StringAttribute, not generic
72
101
  const status = form.getAttribute(Fields.StatusCode); // OptionSetAttribute
73
102
 
74
103
  // OptionSet enum: no magic numbers
75
- if (status.getValue() === XrmForge.OptionSets.Account.StatusCode.Active) {
104
+ if (status.getValue() === StatusCode.Active) {
76
105
  form.getControl(Fields.Revenue).setVisible(true);
77
106
  }
78
107
  }
@@ -114,7 +143,7 @@ Xrm.WebApi.retrieveMultipleRecords("account",
114
143
 
115
144
  // After: use Fields enum for $select
116
145
  import { select } from '@xrmforge/helpers';
117
- import { AccountFields } from '../../typings/entities/account';
146
+ import { AccountFields } from '../../generated/fields/account.js';
118
147
  Xrm.WebApi.retrieveMultipleRecords("account",
119
148
  `?$select=${select(AccountFields.Name, AccountFields.Revenue)}&$filter=statecode eq 0`);
120
149
  ```
@@ -126,7 +155,7 @@ Xrm.WebApi.retrieveMultipleRecords("account",
126
155
 
127
156
  // After: @xrmforge/testing
128
157
  import { createFormMock, fireOnChange } from '@xrmforge/testing';
129
- import type { AccountMainForm, AccountMainFormMockValues } from '../../typings/forms/account';
158
+ import type { AccountMainForm, AccountMainFormMockValues } from '../../generated/forms/account.js';
130
159
 
131
160
  const mock = createFormMock<AccountMainForm, AccountMainFormMockValues>({
132
161
  name: 'Contoso Ltd',
@@ -152,7 +181,7 @@ Search your code for patterns like:
152
181
  - `setValue("statuscode", 1)`
153
182
  - Raw OptionSet values in if/switch statements
154
183
 
155
- Replace with generated const enums from `typings/optionsets/`.
184
+ Replace with generated const enums from `generated/optionsets/`.
156
185
 
157
186
  ## Checklist
158
187
 
package/dist/index.d.ts CHANGED
@@ -1145,10 +1145,9 @@ declare function shouldIncludeInEntityInterface(attr: AttributeMetadata): boolea
1145
1145
  * Generate the ActivityParty base interface declaration.
1146
1146
  * This is a fixed structure (system entity, never customized).
1147
1147
  *
1148
- * @param namespace - Namespace for the interface (default: "XrmForge.Entities")
1149
1148
  * @returns TypeScript declaration string
1150
1149
  */
1151
- declare function generateActivityPartyInterface(namespace?: string): string;
1150
+ declare function generateActivityPartyInterface(): string;
1152
1151
 
1153
1152
  /**
1154
1153
  * @xrmforge/typegen - Generator-specific Label Utilities
@@ -1215,8 +1214,6 @@ declare function disambiguateEnumMembers(members: Array<{
1215
1214
  interface EntityGeneratorOptions {
1216
1215
  /** Label configuration for dual-language JSDoc comments */
1217
1216
  labelConfig?: LabelConfig;
1218
- /** Namespace for generated types (default: "XrmForge.Entities") */
1219
- namespace?: string;
1220
1217
  }
1221
1218
  /**
1222
1219
  * Generate a TypeScript declaration for an entity interface.
@@ -1249,8 +1246,6 @@ declare function generateEntityInterface(info: EntityTypeInfo, options?: EntityG
1249
1246
  interface OptionSetGeneratorOptions {
1250
1247
  /** Label configuration for dual-language JSDoc comments */
1251
1248
  labelConfig?: LabelConfig;
1252
- /** Namespace for generated types (default: "XrmForge.OptionSets") */
1253
- namespace?: string;
1254
1249
  }
1255
1250
  /**
1256
1251
  * Generate a TypeScript const enum declaration from an OptionSet.
@@ -1331,8 +1326,6 @@ declare function generateEntityOptionSets(picklistAttributes: Array<{
1331
1326
  interface FormGeneratorOptions {
1332
1327
  /** Label configuration for dual-language JSDoc comments */
1333
1328
  labelConfig?: LabelConfig;
1334
- /** Namespace prefix for generated types (default: "XrmForge.Forms") */
1335
- namespacePrefix?: string;
1336
1329
  /** Form types to include (default: [2] = Main only) */
1337
1330
  formTypes?: number[];
1338
1331
  }
@@ -1384,8 +1377,6 @@ declare function generateEntityForms(forms: ParsedForm[], entityLogicalName: str
1384
1377
  interface EntityFieldsGeneratorOptions {
1385
1378
  /** Label configuration for dual-language JSDoc comments */
1386
1379
  labelConfig?: LabelConfig;
1387
- /** Namespace for generated enums (default: "XrmForge.Entities") */
1388
- namespace?: string;
1389
1380
  }
1390
1381
  /**
1391
1382
  * Generate a const enum with all entity fields for Web API usage.
@@ -1439,8 +1430,6 @@ declare function generateEntityNavigationProperties(info: EntityTypeInfo, option
1439
1430
  * ```
1440
1431
  */
1441
1432
  interface EntityNamesGeneratorOptions {
1442
- /** Namespace (default: "XrmForge") */
1443
- namespace?: string;
1444
1433
  }
1445
1434
  /**
1446
1435
  * Generate a const enum mapping entity PascalCase names to logical names.
@@ -1449,7 +1438,7 @@ interface EntityNamesGeneratorOptions {
1449
1438
  * @param options - Generator options
1450
1439
  * @returns TypeScript declaration string
1451
1440
  */
1452
- declare function generateEntityNamesEnum(entityNames: string[], options?: EntityNamesGeneratorOptions): string;
1441
+ declare function generateEntityNamesEnum(entityNames: string[], _options?: EntityNamesGeneratorOptions): string;
1453
1442
 
1454
1443
  /**
1455
1444
  * @xrmforge/typegen - Web API Helper Functions
@@ -1810,23 +1799,22 @@ declare function withProgress<T>(message: string, operation: () => Promise<T>):
1810
1799
 
1811
1800
  /** Options for action/function generation */
1812
1801
  interface ActionGeneratorOptions {
1813
- /** Import path for @xrmforge/typegen (default: "@xrmforge/typegen") */
1802
+ /** Import path for @xrmforge/helpers (default: "@xrmforge/helpers") */
1814
1803
  importPath?: string;
1815
- /** Namespace for generated types (default: "XrmForge.Actions" / "XrmForge.Functions") */
1816
- actionsNamespace?: string;
1817
- functionsNamespace?: string;
1818
1804
  }
1819
1805
  /**
1820
- * Generate .d.ts content for a group of Custom APIs.
1806
+ * Generate declarations (interfaces only) for a group of Custom APIs.
1807
+ * Output is flat ES module style with `export interface`.
1821
1808
  *
1822
1809
  * @param apis - Custom APIs to generate (all in the same group: same entity or all global)
1823
- * @param isFunction - true for functions namespace, false for actions
1824
- * @param entityName - Entity name for bound APIs, undefined for global
1825
- * @param options - Generator options
1810
+ * @param isFunction - true for functions, false for actions
1811
+ * @param _entityName - Entity name for bound APIs, undefined for global (reserved for future use)
1812
+ * @param _options - Generator options (reserved for future use)
1826
1813
  */
1827
- declare function generateActionDeclarations(apis: CustomApiTypeInfo[], isFunction: boolean, entityName?: string, options?: ActionGeneratorOptions): string;
1814
+ declare function generateActionDeclarations(apis: CustomApiTypeInfo[], _isFunction: boolean, _entityName?: string, _options?: ActionGeneratorOptions): string;
1828
1815
  /**
1829
- * Generate .ts content with runtime executors for a group of Custom APIs.
1816
+ * Generate a single .ts file with both interfaces and runtime executors for a group of Custom APIs.
1817
+ * Combines what was previously split into .d.ts (interfaces) and .ts (executors).
1830
1818
  *
1831
1819
  * @param apis - Custom APIs to generate
1832
1820
  * @param isFunction - true for functions, false for actions
@@ -1905,7 +1893,7 @@ interface GeneratedFile {
1905
1893
  /** File content */
1906
1894
  content: string;
1907
1895
  /** Type of generated content */
1908
- type: 'entity' | 'optionset' | 'form' | 'action';
1896
+ type: 'entity' | 'optionset' | 'form' | 'action' | 'fields';
1909
1897
  }
1910
1898
  /** Statistics about cache usage during generation */
1911
1899
  interface CacheStats {
@@ -1939,8 +1927,8 @@ interface GenerationResult {
1939
1927
  *
1940
1928
  * Coordinates the full type generation pipeline:
1941
1929
  * 1. Fetch metadata for requested entities (via MetadataClient)
1942
- * 2. Generate entity interfaces, OptionSet enums, form interfaces
1943
- * 3. Write .d.ts files to disk
1930
+ * 2. Generate entity interfaces, OptionSet enums, form interfaces, fields enums
1931
+ * 3. Write .ts files to disk
1944
1932
  *
1945
1933
  * This is the main entry point that ties all components together.
1946
1934
  */
@@ -1953,7 +1941,7 @@ interface GenerationResult {
1953
1941
  * const orchestrator = new TypeGenerationOrchestrator(credential, {
1954
1942
  * environmentUrl: 'https://myorg.crm4.dynamics.com',
1955
1943
  * entities: ['account', 'contact'],
1956
- * outputDir: './typings',
1944
+ * outputDir: './generated',
1957
1945
  * labelConfig: { primaryLanguage: 1033, secondaryLanguage: 1031 },
1958
1946
  * });
1959
1947
  * const result = await orchestrator.generate();