@xrmforge/typegen 0.8.4 → 0.8.5

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.
Files changed (43) hide show
  1. package/LICENSE +21 -21
  2. package/MIGRATION.md +194 -194
  3. package/dist/index.js +4 -4
  4. package/dist/index.js.map +1 -1
  5. package/docs/architecture/00-README.md +26 -26
  6. package/docs/architecture/01-executive-summary.md +11 -11
  7. package/docs/architecture/02-packages.md +110 -110
  8. package/docs/architecture/03-generated-types.md +172 -172
  9. package/docs/architecture/04-cli.md +58 -58
  10. package/docs/architecture/05-build.md +50 -50
  11. package/docs/architecture/06-incremental.md +42 -42
  12. package/docs/architecture/07-http-client.md +59 -59
  13. package/docs/architecture/08-authentication.md +18 -18
  14. package/docs/architecture/09-testing.md +55 -55
  15. package/docs/architecture/10-eslint-plugin.md +82 -82
  16. package/docs/architecture/11-agent-md.md +38 -38
  17. package/docs/architecture/12-xrm-pitfalls.md +14 -14
  18. package/docs/architecture/13-helpers.md +50 -50
  19. package/docs/architecture/14-showcases.md +21 -21
  20. package/docs/architecture/15-ci-cd.md +49 -49
  21. package/docs/architecture/16-technical-debt.md +17 -17
  22. package/docs/architecture/17-roadmap.md +25 -25
  23. package/docs/architecture/18-design-principles.md +22 -22
  24. package/docs/architektur/00-README.md +26 -26
  25. package/docs/architektur/01-zusammenfassung.md +11 -11
  26. package/docs/architektur/02-packages.md +110 -110
  27. package/docs/architektur/03-generierte-typen.md +172 -172
  28. package/docs/architektur/04-cli.md +58 -58
  29. package/docs/architektur/05-build.md +50 -50
  30. package/docs/architektur/06-inkrementell.md +42 -42
  31. package/docs/architektur/07-http-client.md +59 -59
  32. package/docs/architektur/08-authentifizierung.md +18 -18
  33. package/docs/architektur/09-testing.md +55 -55
  34. package/docs/architektur/10-eslint-plugin.md +82 -82
  35. package/docs/architektur/11-agent-md.md +38 -38
  36. package/docs/architektur/12-xrm-fallstricke.md +14 -14
  37. package/docs/architektur/13-helpers.md +50 -50
  38. package/docs/architektur/14-showcases.md +21 -21
  39. package/docs/architektur/15-ci-cd.md +49 -49
  40. package/docs/architektur/16-technische-schulden.md +17 -17
  41. package/docs/architektur/17-roadmap.md +25 -25
  42. package/docs/architektur/18-designprinzipien.md +22 -22
  43. package/package.json +1 -1
@@ -1,26 +1,26 @@
1
- # XrmForge Architecture
2
-
3
- > **Status:** Living document describing the current implementation state.
4
- > **Last updated:** 2026-04-04 (Session 10)
5
- > **Version:** 7 packages, 666+ tests across all packages.
6
-
7
- ## Chapters
8
-
9
- 1. [Executive Summary](01-executive-summary.md)
10
- 2. [Package Architecture](02-packages.md)
11
- 3. [Generated Types](03-generated-types.md)
12
- 4. [CLI Commands](04-cli.md)
13
- 5. [Build Architecture](05-build.md)
14
- 6. [Incremental Generation](06-incremental.md)
15
- 7. [HTTP Client](07-http-client.md)
16
- 8. [Authentication](08-authentication.md)
17
- 9. [Testing Framework](09-testing.md)
18
- 10. [ESLint Plugin](10-eslint-plugin.md)
19
- 11. [AGENT.md System](11-agent-md.md)
20
- 12. [@types/xrm Pitfalls](12-xrm-pitfalls.md)
21
- 13. [@xrmforge/helpers Package](13-helpers.md)
22
- 14. [Showcases](14-showcases.md)
23
- 15. [CI/CD](15-ci-cd.md)
24
- 16. [Technical Debt](16-technical-debt.md)
25
- 17. [Roadmap](17-roadmap.md)
26
- 18. [Design Principles](18-design-principles.md)
1
+ # XrmForge Architecture
2
+
3
+ > **Status:** Living document describing the current implementation state.
4
+ > **Last updated:** 2026-04-04 (Session 10)
5
+ > **Version:** 7 packages, 666+ tests across all packages.
6
+
7
+ ## Chapters
8
+
9
+ 1. [Executive Summary](01-executive-summary.md)
10
+ 2. [Package Architecture](02-packages.md)
11
+ 3. [Generated Types](03-generated-types.md)
12
+ 4. [CLI Commands](04-cli.md)
13
+ 5. [Build Architecture](05-build.md)
14
+ 6. [Incremental Generation](06-incremental.md)
15
+ 7. [HTTP Client](07-http-client.md)
16
+ 8. [Authentication](08-authentication.md)
17
+ 9. [Testing Framework](09-testing.md)
18
+ 10. [ESLint Plugin](10-eslint-plugin.md)
19
+ 11. [AGENT.md System](11-agent-md.md)
20
+ 12. [@types/xrm Pitfalls](12-xrm-pitfalls.md)
21
+ 13. [@xrmforge/helpers Package](13-helpers.md)
22
+ 14. [Showcases](14-showcases.md)
23
+ 15. [CI/CD](15-ci-cd.md)
24
+ 16. [Technical Debt](16-technical-debt.md)
25
+ 17. [Roadmap](17-roadmap.md)
26
+ 18. [Design Principles](18-design-principles.md)
@@ -1,11 +1,11 @@
1
- # Executive Summary
2
-
3
- XrmForge is an open-source TypeScript toolkit for type-safe Dynamics 365 / Dataverse WebResource development. It generates TypeScript declarations from live Dataverse metadata, turning runtime string errors into compile-time type errors.
4
-
5
- **Core value proposition:** Every field name, OptionSet value, tab name, entity name, and subgrid name becomes a typed constant with IDE autocomplete and compile-time validation.
6
-
7
- **Target audience:** D365 developers who write form scripts (WebResources) in JavaScript/TypeScript and want compile-time safety, zero magic strings, and modern tooling (esbuild, vitest, ESLint).
8
-
9
- **Tech stack:** TypeScript, pnpm monorepo with Turborepo, esbuild for IIFE bundles, vitest for testing, @azure/identity for authentication, fast-xml-parser for FormXml parsing.
10
-
11
- **npm organization:** [@xrmforge](https://www.npmjs.com/org/xrmforge)
1
+ # Executive Summary
2
+
3
+ XrmForge is an open-source TypeScript toolkit for type-safe Dynamics 365 / Dataverse WebResource development. It generates TypeScript declarations from live Dataverse metadata, turning runtime string errors into compile-time type errors.
4
+
5
+ **Core value proposition:** Every field name, OptionSet value, tab name, entity name, and subgrid name becomes a typed constant with IDE autocomplete and compile-time validation.
6
+
7
+ **Target audience:** D365 developers who write form scripts (WebResources) in JavaScript/TypeScript and want compile-time safety, zero magic strings, and modern tooling (esbuild, vitest, ESLint).
8
+
9
+ **Tech stack:** TypeScript, pnpm monorepo with Turborepo, esbuild for IIFE bundles, vitest for testing, @azure/identity for authentication, fast-xml-parser for FormXml parsing.
10
+
11
+ **npm organization:** [@xrmforge](https://www.npmjs.com/org/xrmforge)
@@ -1,110 +1,110 @@
1
- # Package Architecture
2
-
3
- ## Package Overview
4
-
5
- | Package | Version | Tests | Description |
6
- |---------|---------|-------|-------------|
7
- | @xrmforge/typegen | 0.8.0 | 444 | Core: type generation engine, metadata client, HTTP client, helpers |
8
- | @xrmforge/cli | 0.4.2 | 10 | CLI: generate, build, init commands |
9
- | @xrmforge/testing | 0.2.0 | 76 | Test utilities: createFormMock, fireOnChange, setupXrmMock |
10
- | @xrmforge/helpers | 0.1.0 | 59 | Browser-safe runtime: select(), parseLookup(), typedForm(), Xrm constants, Action executors |
11
- | @xrmforge/webapi | 0.1.0 | 45 | Type-safe Xrm.WebApi client with QueryBuilder |
12
- | @xrmforge/devkit | 0.4.0 | 42 | Build orchestration, scaffolding, AGENT.md generation |
13
- | @xrmforge/eslint-plugin | 0.2.0 | 32 | 5 D365-specific ESLint rules |
14
-
15
- **Total:** 708 tests across 7 packages.
16
-
17
- ## Dependency Graph
18
-
19
- ```
20
- @xrmforge/cli
21
- |-- @xrmforge/typegen (generate command)
22
- |-- @xrmforge/devkit (build + init commands)
23
- '-- commander (CLI framework)
24
-
25
- @xrmforge/typegen
26
- |-- @azure/identity (authentication)
27
- '-- fast-xml-parser (FormXml parsing)
28
-
29
- @xrmforge/devkit
30
- '-- esbuild (IIFE bundling)
31
-
32
- @xrmforge/testing (no runtime deps)
33
- @xrmforge/helpers (no runtime deps)
34
- @xrmforge/webapi (no runtime deps)
35
- @xrmforge/eslint-plugin (ESLint peer dep)
36
- ```
37
-
38
- ## Package Details
39
-
40
- ### @xrmforge/typegen
41
-
42
- The core package. Contains:
43
-
44
- - **TypeGenerationOrchestrator** - Coordinates the entire generation pipeline
45
- - **MetadataClient** - Queries Dataverse metadata (entities, forms, OptionSets, Custom APIs)
46
- - **DataverseHttpClient** - Resilient REST client with retry, rate limiting, concurrency control
47
- - **ChangeDetector** - Incremental generation via RetrieveMetadataChanges
48
- - **MetadataCache** - Filesystem-based caching with version stamps
49
- - **Generators** - Entity interfaces, form interfaces, OptionSet enums, Fields enums, EntityNames, Navigation Properties, Action/Function executors
50
- - **Helpers** - select(), parseLookup(), parseFormattedValue() (moved to @xrmforge/helpers)
51
- - **Xrm Constants** - DisplayState, FormNotificationLevel, RequiredLevel, SubmitMode, SaveMode, ClientType, ClientState (moved to @xrmforge/helpers)
52
- - **Authentication** - createCredential() factory for 4 auth methods
53
- - **Logging** - Scoped loggers with pluggable sinks (Console, JSON, Silent)
54
- - **Errors** - Structured error hierarchy with ErrorCode enum (AUTH_1xxx, API_2xxx, META_3xxx, GEN_4xxx, CONFIG_5xxx)
55
-
56
- ### @xrmforge/cli
57
-
58
- Command-line interface built with commander.js. Three commands:
59
- - `xrmforge generate` - Orchestrates TypeGenerationOrchestrator
60
- - `xrmforge build` - Delegates to devkit build()
61
- - `xrmforge init` - Delegates to devkit scaffoldProject()
62
-
63
- ### @xrmforge/testing
64
-
65
- FormContext mocking for unit tests:
66
- - `createFormMock<TForm>(values)` - Creates a complete mock from simple key-value pairs
67
- - `MockAttribute` - getValue/setValue, dirty tracking, onChange handlers, required level, submit mode
68
- - `MockControl` - visible, disabled, label, notifications
69
- - `MockUi` - Form notifications, tab/section stubs
70
- - `MockEntity` - Entity ID, name, primary attribute
71
- - `fireOnChange(fieldName)` - Triggers registered onChange handlers
72
- - `setupXrmMock(options)` / `teardownXrmMock()` - Global Xrm mock with WebApi/Navigation stubs
73
-
74
- ### @xrmforge/helpers
75
-
76
- Consolidates all browser-safe runtime code. Zero Node.js dependencies. Contains:
77
- - **Web API helpers** - select(), parseLookup(), parseFormattedValue()
78
- - **Xrm constants** - DisplayState, SubmitMode, RequiredLevel, SaveMode, ClientType, ClientState, FormNotificationLevel, OperationType
79
- - **Action/Function executors** - createBoundAction(), executeRequest(), withProgress()
80
- - **typedForm() proxy** - Proxy-based FormContext wrapper where `form.name` delegates to `getAttribute('name')`
81
-
82
- ### @xrmforge/webapi
83
-
84
- Type-safe wrapper around Xrm.WebApi:
85
- - `retrieve<T>(entityName, id, query)` - Single record
86
- - `retrieveMultiple<T>(entityName, query, options)` - With pagination (maxPages)
87
- - `create(entityName, data)` - Returns record ID
88
- - `update(entityName, id, data)` - Void
89
- - `remove(entityName, id)` - Void
90
- - `QueryBuilder` - Fluent API: `.select().filter().orderBy().top().expand().build()`
91
- - `WebApiError` - Structured errors with statusCode, errorCode, innerMessage
92
-
93
- ### @xrmforge/devkit
94
-
95
- Build orchestration and project scaffolding:
96
- - `build(config)` - Parallel esbuild IIFE builds via Promise.allSettled
97
- - `watch(config)` - esbuild watch mode with rebuild callbacks
98
- - `scaffoldProject(config)` - Generates 11 project files from templates
99
- - `validateBuildConfig(config)` / `resolveBuildConfig(config)` - Config validation
100
- - `BuildError` with codes: CONFIG_INVALID, ENTRY_NOT_FOUND, BUILD_FAILED, WATCH_ERROR
101
- - Template system: 7 text templates in `src/scaffold/templates/`, loaded via `template-loader.ts`
102
-
103
- ### @xrmforge/eslint-plugin
104
-
105
- 5 rules for D365 form scripts (ESLint v9 flat config):
106
- - `no-xrm-page` (error) - Forbids deprecated Xrm.Page API
107
- - `no-magic-optionset` (warn) - Forbids magic numbers in OptionSet comparisons
108
- - `no-sync-webapi` (error) - Forbids synchronous XMLHttpRequest
109
- - `require-error-handling` (warn) - Requires try/catch in async on* event handlers
110
- - `require-namespace` (warn) - Forbids window/globalThis assignments
1
+ # Package Architecture
2
+
3
+ ## Package Overview
4
+
5
+ | Package | Version | Tests | Description |
6
+ |---------|---------|-------|-------------|
7
+ | @xrmforge/typegen | 0.8.0 | 444 | Core: type generation engine, metadata client, HTTP client, helpers |
8
+ | @xrmforge/cli | 0.4.2 | 10 | CLI: generate, build, init commands |
9
+ | @xrmforge/testing | 0.2.0 | 76 | Test utilities: createFormMock, fireOnChange, setupXrmMock |
10
+ | @xrmforge/helpers | 0.1.0 | 59 | Browser-safe runtime: select(), parseLookup(), typedForm(), Xrm constants, Action executors |
11
+ | @xrmforge/webapi | 0.1.0 | 45 | Type-safe Xrm.WebApi client with QueryBuilder |
12
+ | @xrmforge/devkit | 0.4.0 | 42 | Build orchestration, scaffolding, AGENT.md generation |
13
+ | @xrmforge/eslint-plugin | 0.2.0 | 32 | 5 D365-specific ESLint rules |
14
+
15
+ **Total:** 708 tests across 7 packages.
16
+
17
+ ## Dependency Graph
18
+
19
+ ```
20
+ @xrmforge/cli
21
+ |-- @xrmforge/typegen (generate command)
22
+ |-- @xrmforge/devkit (build + init commands)
23
+ '-- commander (CLI framework)
24
+
25
+ @xrmforge/typegen
26
+ |-- @azure/identity (authentication)
27
+ '-- fast-xml-parser (FormXml parsing)
28
+
29
+ @xrmforge/devkit
30
+ '-- esbuild (IIFE bundling)
31
+
32
+ @xrmforge/testing (no runtime deps)
33
+ @xrmforge/helpers (no runtime deps)
34
+ @xrmforge/webapi (no runtime deps)
35
+ @xrmforge/eslint-plugin (ESLint peer dep)
36
+ ```
37
+
38
+ ## Package Details
39
+
40
+ ### @xrmforge/typegen
41
+
42
+ The core package. Contains:
43
+
44
+ - **TypeGenerationOrchestrator** - Coordinates the entire generation pipeline
45
+ - **MetadataClient** - Queries Dataverse metadata (entities, forms, OptionSets, Custom APIs)
46
+ - **DataverseHttpClient** - Resilient REST client with retry, rate limiting, concurrency control
47
+ - **ChangeDetector** - Incremental generation via RetrieveMetadataChanges
48
+ - **MetadataCache** - Filesystem-based caching with version stamps
49
+ - **Generators** - Entity interfaces, form interfaces, OptionSet enums, Fields enums, EntityNames, Navigation Properties, Action/Function executors
50
+ - **Helpers** - select(), parseLookup(), parseFormattedValue() (moved to @xrmforge/helpers)
51
+ - **Xrm Constants** - DisplayState, FormNotificationLevel, RequiredLevel, SubmitMode, SaveMode, ClientType, ClientState (moved to @xrmforge/helpers)
52
+ - **Authentication** - createCredential() factory for 4 auth methods
53
+ - **Logging** - Scoped loggers with pluggable sinks (Console, JSON, Silent)
54
+ - **Errors** - Structured error hierarchy with ErrorCode enum (AUTH_1xxx, API_2xxx, META_3xxx, GEN_4xxx, CONFIG_5xxx)
55
+
56
+ ### @xrmforge/cli
57
+
58
+ Command-line interface built with commander.js. Three commands:
59
+ - `xrmforge generate` - Orchestrates TypeGenerationOrchestrator
60
+ - `xrmforge build` - Delegates to devkit build()
61
+ - `xrmforge init` - Delegates to devkit scaffoldProject()
62
+
63
+ ### @xrmforge/testing
64
+
65
+ FormContext mocking for unit tests:
66
+ - `createFormMock<TForm>(values)` - Creates a complete mock from simple key-value pairs
67
+ - `MockAttribute` - getValue/setValue, dirty tracking, onChange handlers, required level, submit mode
68
+ - `MockControl` - visible, disabled, label, notifications
69
+ - `MockUi` - Form notifications, tab/section stubs
70
+ - `MockEntity` - Entity ID, name, primary attribute
71
+ - `fireOnChange(fieldName)` - Triggers registered onChange handlers
72
+ - `setupXrmMock(options)` / `teardownXrmMock()` - Global Xrm mock with WebApi/Navigation stubs
73
+
74
+ ### @xrmforge/helpers
75
+
76
+ Consolidates all browser-safe runtime code. Zero Node.js dependencies. Contains:
77
+ - **Web API helpers** - select(), parseLookup(), parseFormattedValue()
78
+ - **Xrm constants** - DisplayState, SubmitMode, RequiredLevel, SaveMode, ClientType, ClientState, FormNotificationLevel, OperationType
79
+ - **Action/Function executors** - createBoundAction(), executeRequest(), withProgress()
80
+ - **typedForm() proxy** - Proxy-based FormContext wrapper where `form.name` delegates to `getAttribute('name')`
81
+
82
+ ### @xrmforge/webapi
83
+
84
+ Type-safe wrapper around Xrm.WebApi:
85
+ - `retrieve<T>(entityName, id, query)` - Single record
86
+ - `retrieveMultiple<T>(entityName, query, options)` - With pagination (maxPages)
87
+ - `create(entityName, data)` - Returns record ID
88
+ - `update(entityName, id, data)` - Void
89
+ - `remove(entityName, id)` - Void
90
+ - `QueryBuilder` - Fluent API: `.select().filter().orderBy().top().expand().build()`
91
+ - `WebApiError` - Structured errors with statusCode, errorCode, innerMessage
92
+
93
+ ### @xrmforge/devkit
94
+
95
+ Build orchestration and project scaffolding:
96
+ - `build(config)` - Parallel esbuild IIFE builds via Promise.allSettled
97
+ - `watch(config)` - esbuild watch mode with rebuild callbacks
98
+ - `scaffoldProject(config)` - Generates 11 project files from templates
99
+ - `validateBuildConfig(config)` / `resolveBuildConfig(config)` - Config validation
100
+ - `BuildError` with codes: CONFIG_INVALID, ENTRY_NOT_FOUND, BUILD_FAILED, WATCH_ERROR
101
+ - Template system: 7 text templates in `src/scaffold/templates/`, loaded via `template-loader.ts`
102
+
103
+ ### @xrmforge/eslint-plugin
104
+
105
+ 5 rules for D365 form scripts (ESLint v9 flat config):
106
+ - `no-xrm-page` (error) - Forbids deprecated Xrm.Page API
107
+ - `no-magic-optionset` (warn) - Forbids magic numbers in OptionSet comparisons
108
+ - `no-sync-webapi` (error) - Forbids synchronous XMLHttpRequest
109
+ - `require-error-handling` (warn) - Requires try/catch in async on* event handlers
110
+ - `require-namespace` (warn) - Forbids window/globalThis assignments
@@ -1,172 +1,172 @@
1
- # Generated Types
2
-
3
- Running `xrmforge generate` produces the following TypeScript ES modules:
4
-
5
- ### 3.1 Entity Interfaces (`entities/{entity}.ts`)
6
-
7
- ```typescript
8
- // generated/entities/account.ts
9
- /** Account | Konto */
10
- export interface Account {
11
- /** Account Name | Kontoname */
12
- name: string | null;
13
- accountid: string | null;
14
- revenue: number | null;
15
- _parentaccountid_value: string | null; // Lookup GUID
16
- // ...
17
- }
18
- ```
19
-
20
- **Type mapping:** String/Memo/EntityName to `string`, Integer/BigInt/Decimal/Double/Money to `number`, Boolean to `boolean`, DateTime/Uniqueidentifier/Lookup to `string`, Picklist/State/Status to `number`.
21
-
22
- ### 3.2 Entity Fields Enums (`fields/{entity}.ts`)
23
-
24
- ```typescript
25
- // generated/fields/account.ts
26
- export const enum AccountFields {
27
- /** Account Name | Kontoname */
28
- Name = 'name',
29
- Telephone1 = 'telephone1',
30
- Revenue = 'revenue',
31
- // all entity attributes for $select queries
32
- }
33
-
34
- export const enum AccountNavigationProperties {
35
- PrimaryContact = 'primarycontactid',
36
- ContactCustomerAccounts = 'contact_customer_accounts',
37
- // all lookup navigation properties
38
- }
39
- ```
40
-
41
- Used for Web API `$select`: `select(AccountFields.Name, AccountFields.Revenue)`.
42
-
43
- ### 3.3 Navigation Properties (`fields/{entity}.ts`)
44
-
45
- Navigation property enums are co-located with the Fields enums in the same file (see 3.2 above). Example usage:
46
-
47
- ```typescript
48
- import { AccountNavigationProperties } from '../generated/fields/account';
49
- // used for $expand queries
50
- ```
51
-
52
- ### 3.4 Form Interfaces (`forms/{entity}.ts`)
53
-
54
- ```typescript
55
- // generated/forms/account.ts
56
-
57
- // Union type restricting valid field names
58
- export type AccountMainFormFields = 'name' | 'telephone1' | 'revenue';
59
-
60
- // Mapped type: field name to Xrm attribute type
61
- export type AccountMainFormAttributeMap = {
62
- name: Xrm.Attributes.StringAttribute;
63
- telephone1: Xrm.Attributes.StringAttribute;
64
- revenue: Xrm.Attributes.NumberAttribute;
65
- };
66
-
67
- // Mapped type: field name to Xrm control type
68
- export type AccountMainFormControlMap = {
69
- name: Xrm.Controls.StringControl;
70
- telephone1: Xrm.Controls.StringControl;
71
- revenue: Xrm.Controls.NumberControl;
72
- };
73
-
74
- // Fields enum for autocomplete
75
- export const enum AccountMainFormFieldsEnum {
76
- /** Account Name | Kontoname */
77
- AccountName = 'name',
78
- Telephone1 = 'telephone1',
79
- Revenue = 'revenue',
80
- }
81
-
82
- // Type-safe FormContext with overloaded getAttribute/getControl
83
- export interface AccountMainForm extends Omit<Xrm.FormContext, 'getAttribute' | 'getControl'> {
84
- getAttribute<K extends AccountMainFormFields>(name: K): AccountMainFormAttributeMap[K];
85
- getAttribute(index: number): Xrm.Attributes.Attribute;
86
- getAttribute(): Xrm.Attributes.Attribute[];
87
-
88
- getControl<K extends AccountMainFormFields>(name: K): AccountMainFormControlMap[K];
89
- getControl(index: number): Xrm.Controls.Control;
90
- getControl(): Xrm.Controls.Control[];
91
- }
92
- ```
93
-
94
- **Special controls** are typed based on their FormXml ClassID:
95
- - Subgrid: `Xrm.Controls.GridControl`
96
- - Editable Grid: `Xrm.Controls.GridControl`
97
- - Quick View: `Xrm.Controls.QuickFormControl`
98
- - Web Resource / iFrame: `Xrm.Controls.IframeControl`
99
-
100
- ### 3.5 Tabs/Sections/Subgrids/QuickViews Enums
101
-
102
- ```typescript
103
- const enum AccountMainFormTabs { Summary = 'SUMMARY_TAB', Details = 'DETAILS_TAB' }
104
- const enum AccountMainFormSections { General = 'GENERAL', Address = 'ADDRESS' }
105
- const enum AccountMainFormSubgrids { Contacts = 'Contacts_Subgrid' }
106
- const enum AccountMainFormQuickViews { ContactPreview = 'ContactQuickView' }
107
- ```
108
-
109
- ### 3.6 OptionSet Enums (`optionsets/{entity}.ts`)
110
-
111
- ```typescript
112
- // generated/optionsets/account.ts
113
- /** Account Category Code | Kontokategoriecode */
114
- export const enum AccountCategoryCode {
115
- /** Preferred Customer | Bevorzugter Kunde */
116
- PreferredCustomer = 1,
117
- Standard = 2,
118
- }
119
- ```
120
-
121
- Includes Picklist, Status, State, and MultiSelectPicklist attributes. Duplicate labels are disambiguated with `_{Value}` suffix.
122
-
123
- ### 3.7 EntityNames Enum (`entity-names.ts`)
124
-
125
- ```typescript
126
- // generated/entity-names.ts
127
- export const enum EntityNames {
128
- Account = 'account',
129
- Contact = 'contact',
130
- // all entities in scope
131
- }
132
- ```
133
-
134
- ### 3.8 MockValues Types (in form interfaces)
135
-
136
- ```typescript
137
- type AccountMainFormMockValues = {
138
- name?: string | null;
139
- telephone1?: string | null;
140
- revenue?: number | null;
141
- };
142
- ```
143
-
144
- Used with `createFormMock<AccountMainForm, AccountMainFormMockValues>({ name: 'Test' })`.
145
-
146
- ### 3.9 Action/Function Executors (`actions/{entity|global}.ts`)
147
-
148
- ```typescript
149
- // generated/actions/global.ts
150
- import { createUnboundAction } from '@xrmforge/helpers';
151
-
152
- export interface NormalizePhoneParams { Input: string; AllowSuspicious?: boolean; }
153
- export interface NormalizePhoneResult { Normalized: string; Status: number; }
154
-
155
- export const NormalizePhone = createUnboundAction<NormalizePhoneParams, NormalizePhoneResult>(
156
- 'markant_NormalizePhone',
157
- { Input: { typeName: 'String', structuralProperty: 1 } }
158
- );
159
- // Usage: const result = await NormalizePhone.execute({ Input: '123' });
160
- ```
161
-
162
- Factory functions: `createBoundAction`, `createUnboundAction`, `createBoundFunction`, `createUnboundFunction`. Batch execution via `executeMultiple()`, progress UI via `withProgress()`.
163
-
164
- ### 3.10 Dual-Language Labels
165
-
166
- All generated JSDoc comments support dual-language labels:
167
- ```typescript
168
- /** Account Name | Kontoname */
169
- Name = 'name',
170
- ```
171
-
172
- German umlauts are transliterated in identifiers: ae, oe, ue, ss (e.g. "Ubergeordnet" becomes `Uebergeordnet`).
1
+ # Generated Types
2
+
3
+ Running `xrmforge generate` produces the following TypeScript ES modules:
4
+
5
+ ### 3.1 Entity Interfaces (`entities/{entity}.ts`)
6
+
7
+ ```typescript
8
+ // generated/entities/account.ts
9
+ /** Account | Konto */
10
+ export interface Account {
11
+ /** Account Name | Kontoname */
12
+ name: string | null;
13
+ accountid: string | null;
14
+ revenue: number | null;
15
+ _parentaccountid_value: string | null; // Lookup GUID
16
+ // ...
17
+ }
18
+ ```
19
+
20
+ **Type mapping:** String/Memo/EntityName to `string`, Integer/BigInt/Decimal/Double/Money to `number`, Boolean to `boolean`, DateTime/Uniqueidentifier/Lookup to `string`, Picklist/State/Status to `number`.
21
+
22
+ ### 3.2 Entity Fields Enums (`fields/{entity}.ts`)
23
+
24
+ ```typescript
25
+ // generated/fields/account.ts
26
+ export const enum AccountFields {
27
+ /** Account Name | Kontoname */
28
+ Name = 'name',
29
+ Telephone1 = 'telephone1',
30
+ Revenue = 'revenue',
31
+ // all entity attributes for $select queries
32
+ }
33
+
34
+ export const enum AccountNavigationProperties {
35
+ PrimaryContact = 'primarycontactid',
36
+ ContactCustomerAccounts = 'contact_customer_accounts',
37
+ // all lookup navigation properties
38
+ }
39
+ ```
40
+
41
+ Used for Web API `$select`: `select(AccountFields.Name, AccountFields.Revenue)`.
42
+
43
+ ### 3.3 Navigation Properties (`fields/{entity}.ts`)
44
+
45
+ Navigation property enums are co-located with the Fields enums in the same file (see 3.2 above). Example usage:
46
+
47
+ ```typescript
48
+ import { AccountNavigationProperties } from '../generated/fields/account';
49
+ // used for $expand queries
50
+ ```
51
+
52
+ ### 3.4 Form Interfaces (`forms/{entity}.ts`)
53
+
54
+ ```typescript
55
+ // generated/forms/account.ts
56
+
57
+ // Union type restricting valid field names
58
+ export type AccountMainFormFields = 'name' | 'telephone1' | 'revenue';
59
+
60
+ // Mapped type: field name to Xrm attribute type
61
+ export type AccountMainFormAttributeMap = {
62
+ name: Xrm.Attributes.StringAttribute;
63
+ telephone1: Xrm.Attributes.StringAttribute;
64
+ revenue: Xrm.Attributes.NumberAttribute;
65
+ };
66
+
67
+ // Mapped type: field name to Xrm control type
68
+ export type AccountMainFormControlMap = {
69
+ name: Xrm.Controls.StringControl;
70
+ telephone1: Xrm.Controls.StringControl;
71
+ revenue: Xrm.Controls.NumberControl;
72
+ };
73
+
74
+ // Fields enum for autocomplete
75
+ export const enum AccountMainFormFieldsEnum {
76
+ /** Account Name | Kontoname */
77
+ AccountName = 'name',
78
+ Telephone1 = 'telephone1',
79
+ Revenue = 'revenue',
80
+ }
81
+
82
+ // Type-safe FormContext with overloaded getAttribute/getControl
83
+ export interface AccountMainForm extends Omit<Xrm.FormContext, 'getAttribute' | 'getControl'> {
84
+ getAttribute<K extends AccountMainFormFields>(name: K): AccountMainFormAttributeMap[K];
85
+ getAttribute(index: number): Xrm.Attributes.Attribute;
86
+ getAttribute(): Xrm.Attributes.Attribute[];
87
+
88
+ getControl<K extends AccountMainFormFields>(name: K): AccountMainFormControlMap[K];
89
+ getControl(index: number): Xrm.Controls.Control;
90
+ getControl(): Xrm.Controls.Control[];
91
+ }
92
+ ```
93
+
94
+ **Special controls** are typed based on their FormXml ClassID:
95
+ - Subgrid: `Xrm.Controls.GridControl`
96
+ - Editable Grid: `Xrm.Controls.GridControl`
97
+ - Quick View: `Xrm.Controls.QuickFormControl`
98
+ - Web Resource / iFrame: `Xrm.Controls.IframeControl`
99
+
100
+ ### 3.5 Tabs/Sections/Subgrids/QuickViews Enums
101
+
102
+ ```typescript
103
+ const enum AccountMainFormTabs { Summary = 'SUMMARY_TAB', Details = 'DETAILS_TAB' }
104
+ const enum AccountMainFormSections { General = 'GENERAL', Address = 'ADDRESS' }
105
+ const enum AccountMainFormSubgrids { Contacts = 'Contacts_Subgrid' }
106
+ const enum AccountMainFormQuickViews { ContactPreview = 'ContactQuickView' }
107
+ ```
108
+
109
+ ### 3.6 OptionSet Enums (`optionsets/{entity}.ts`)
110
+
111
+ ```typescript
112
+ // generated/optionsets/account.ts
113
+ /** Account Category Code | Kontokategoriecode */
114
+ export const enum AccountCategoryCode {
115
+ /** Preferred Customer | Bevorzugter Kunde */
116
+ PreferredCustomer = 1,
117
+ Standard = 2,
118
+ }
119
+ ```
120
+
121
+ Includes Picklist, Status, State, and MultiSelectPicklist attributes. Duplicate labels are disambiguated with `_{Value}` suffix.
122
+
123
+ ### 3.7 EntityNames Enum (`entity-names.ts`)
124
+
125
+ ```typescript
126
+ // generated/entity-names.ts
127
+ export const enum EntityNames {
128
+ Account = 'account',
129
+ Contact = 'contact',
130
+ // all entities in scope
131
+ }
132
+ ```
133
+
134
+ ### 3.8 MockValues Types (in form interfaces)
135
+
136
+ ```typescript
137
+ type AccountMainFormMockValues = {
138
+ name?: string | null;
139
+ telephone1?: string | null;
140
+ revenue?: number | null;
141
+ };
142
+ ```
143
+
144
+ Used with `createFormMock<AccountMainForm, AccountMainFormMockValues>({ name: 'Test' })`.
145
+
146
+ ### 3.9 Action/Function Executors (`actions/{entity|global}.ts`)
147
+
148
+ ```typescript
149
+ // generated/actions/global.ts
150
+ import { createUnboundAction } from '@xrmforge/helpers';
151
+
152
+ export interface NormalizePhoneParams { Input: string; AllowSuspicious?: boolean; }
153
+ export interface NormalizePhoneResult { Normalized: string; Status: number; }
154
+
155
+ export const NormalizePhone = createUnboundAction<NormalizePhoneParams, NormalizePhoneResult>(
156
+ 'markant_NormalizePhone',
157
+ { Input: { typeName: 'String', structuralProperty: 1 } }
158
+ );
159
+ // Usage: const result = await NormalizePhone.execute({ Input: '123' });
160
+ ```
161
+
162
+ Factory functions: `createBoundAction`, `createUnboundAction`, `createBoundFunction`, `createUnboundFunction`. Batch execution via `executeMultiple()`, progress UI via `withProgress()`.
163
+
164
+ ### 3.10 Dual-Language Labels
165
+
166
+ All generated JSDoc comments support dual-language labels:
167
+ ```typescript
168
+ /** Account Name | Kontoname */
169
+ Name = 'name',
170
+ ```
171
+
172
+ German umlauts are transliterated in identifiers: ae, oe, ue, ss (e.g. "Ubergeordnet" becomes `Uebergeordnet`).