@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/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 ./
|
|
59
|
+
--output ./generated
|
|
34
60
|
```
|
|
35
61
|
|
|
36
62
|
This generates:
|
|
37
|
-
- `
|
|
38
|
-
- `
|
|
39
|
-
- `
|
|
40
|
-
- `
|
|
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 '../../
|
|
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
|
|
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() ===
|
|
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 '../../
|
|
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 '../../
|
|
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 `
|
|
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(
|
|
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[],
|
|
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/
|
|
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
|
|
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
|
|
1824
|
-
* @param
|
|
1825
|
-
* @param
|
|
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[],
|
|
1814
|
+
declare function generateActionDeclarations(apis: CustomApiTypeInfo[], _isFunction: boolean, _entityName?: string, _options?: ActionGeneratorOptions): string;
|
|
1828
1815
|
/**
|
|
1829
|
-
* Generate .ts
|
|
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 .
|
|
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: './
|
|
1944
|
+
* outputDir: './generated',
|
|
1957
1945
|
* labelConfig: { primaryLanguage: 1033, secondaryLanguage: 1031 },
|
|
1958
1946
|
* });
|
|
1959
1947
|
* const result = await orchestrator.generate();
|