@xrmforge/typegen 0.7.1 → 0.8.0

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.
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Package | Version | Tests | Description |
6
6
  |---------|---------|-------|-------------|
7
- | @xrmforge/typegen | 0.6.0 | 444 | Core: type generation engine, metadata client, HTTP client, helpers |
7
+ | @xrmforge/typegen | 0.8.0 | 444 | Core: type generation engine, metadata client, HTTP client, helpers |
8
8
  | @xrmforge/cli | 0.4.2 | 10 | CLI: generate, build, init commands |
9
9
  | @xrmforge/testing | 0.2.0 | 76 | Test utilities: createFormMock, fireOnChange, setupXrmMock |
10
10
  | @xrmforge/helpers | 0.1.0 | 59 | Browser-safe runtime: select(), parseLookup(), typedForm(), Xrm constants, Action executors |
@@ -1,91 +1,93 @@
1
1
  # Generated Types
2
2
 
3
- Running `xrmforge generate` produces the following TypeScript declarations:
3
+ Running `xrmforge generate` produces the following TypeScript ES modules:
4
4
 
5
- ### 3.1 Entity Interfaces (`entities/{entity}.d.ts`)
5
+ ### 3.1 Entity Interfaces (`entities/{entity}.ts`)
6
6
 
7
7
  ```typescript
8
- declare namespace XrmForge.Entities {
9
- /** Account | Konto */
10
- 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
- }
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
+ // ...
18
17
  }
19
18
  ```
20
19
 
21
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`.
22
21
 
23
- ### 3.2 Entity Fields Enums (`entities/{entity}.d.ts`)
22
+ ### 3.2 Entity Fields Enums (`fields/{entity}.ts`)
24
23
 
25
24
  ```typescript
26
- declare namespace XrmForge.Entities {
27
- const enum AccountFields {
28
- /** Account Name | Kontoname */
29
- Name = 'name',
30
- Revenue = 'revenue',
31
- // all readable attributes
32
- }
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
33
38
  }
34
39
  ```
35
40
 
36
41
  Used for Web API `$select`: `select(AccountFields.Name, AccountFields.Revenue)`.
37
42
 
38
- ### 3.3 Navigation Properties (`entities/{entity}.d.ts`)
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:
39
46
 
40
47
  ```typescript
41
- declare namespace XrmForge.Entities {
42
- const enum AccountNavigation {
43
- PrimaryContactId = 'primarycontactid',
44
- ContactCustomerAccounts = 'contact_customer_accounts',
45
- // OneToMany + ManyToMany relationships
46
- }
47
- }
48
+ import { AccountNavigationProperties } from '../generated/fields/account';
49
+ // used for $expand queries
48
50
  ```
49
51
 
50
- ### 3.4 Form Interfaces (`forms/{entity}.d.ts`)
52
+ ### 3.4 Form Interfaces (`forms/{entity}.ts`)
51
53
 
52
54
  ```typescript
53
- declare namespace XrmForge.Forms.Account {
54
- // Union type restricting valid field names
55
- type AccountMainFormFields = 'name' | 'telephone1' | 'revenue';
56
-
57
- // Mapped type: field name to Xrm attribute type
58
- type AccountMainFormAttributeMap = {
59
- name: Xrm.Attributes.StringAttribute;
60
- telephone1: Xrm.Attributes.StringAttribute;
61
- revenue: Xrm.Attributes.NumberAttribute;
62
- };
63
-
64
- // Mapped type: field name to Xrm control type
65
- type AccountMainFormControlMap = {
66
- name: Xrm.Controls.StringControl;
67
- telephone1: Xrm.Controls.StringControl;
68
- revenue: Xrm.Controls.NumberControl;
69
- };
70
-
71
- // Fields enum for autocomplete
72
- const enum AccountMainFormFieldsEnum {
73
- /** Account Name | Kontoname */
74
- AccountName = 'name',
75
- Telephone1 = 'telephone1',
76
- Revenue = 'revenue',
77
- }
78
-
79
- // Type-safe FormContext with overloaded getAttribute/getControl
80
- interface AccountMainForm extends Omit<Xrm.FormContext, 'getAttribute' | 'getControl'> {
81
- getAttribute<K extends AccountMainFormFields>(name: K): AccountMainFormAttributeMap[K];
82
- getAttribute(index: number): Xrm.Attributes.Attribute;
83
- getAttribute(): Xrm.Attributes.Attribute[];
84
-
85
- getControl<K extends AccountMainFormFields>(name: K): AccountMainFormControlMap[K];
86
- getControl(index: number): Xrm.Controls.Control;
87
- getControl(): Xrm.Controls.Control[];
88
- }
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[];
89
91
  }
90
92
  ```
91
93
 
@@ -104,30 +106,28 @@ const enum AccountMainFormSubgrids { Contacts = 'Contacts_Subgrid' }
104
106
  const enum AccountMainFormQuickViews { ContactPreview = 'ContactQuickView' }
105
107
  ```
106
108
 
107
- ### 3.6 OptionSet Enums (`optionsets/{entity}.d.ts`)
109
+ ### 3.6 OptionSet Enums (`optionsets/{entity}.ts`)
108
110
 
109
111
  ```typescript
110
- declare namespace XrmForge.OptionSets.Account {
111
- /** Account Category Code | Kontokategoriecode */
112
- const enum AccountCategoryCode {
113
- /** Preferred Customer | Bevorzugter Kunde */
114
- PreferredCustomer = 1,
115
- Standard = 2,
116
- }
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,
117
118
  }
118
119
  ```
119
120
 
120
121
  Includes Picklist, Status, State, and MultiSelectPicklist attributes. Duplicate labels are disambiguated with `_{Value}` suffix.
121
122
 
122
- ### 3.7 EntityNames Enum (`entity-names.d.ts`)
123
+ ### 3.7 EntityNames Enum (`entity-names.ts`)
123
124
 
124
125
  ```typescript
125
- declare namespace XrmForge {
126
- const enum EntityNames {
127
- Account = 'account',
128
- Contact = 'contact',
129
- // all entities in scope
130
- }
126
+ // generated/entity-names.ts
127
+ export const enum EntityNames {
128
+ Account = 'account',
129
+ Contact = 'contact',
130
+ // all entities in scope
131
131
  }
132
132
  ```
133
133
 
@@ -143,19 +143,15 @@ type AccountMainFormMockValues = {
143
143
 
144
144
  Used with `createFormMock<AccountMainForm, AccountMainFormMockValues>({ name: 'Test' })`.
145
145
 
146
- ### 3.9 Action/Function Executors (`actions/{entity|global}.d.ts` + `.ts`)
146
+ ### 3.9 Action/Function Executors (`actions/{entity|global}.ts`)
147
147
 
148
- **Declaration (.d.ts):**
149
148
  ```typescript
150
- declare namespace XrmForge.Actions {
151
- interface NormalizePhoneParams { Input: string; AllowSuspicious?: boolean; }
152
- interface NormalizePhoneResult { Normalized: string; Status: number; }
153
- }
154
- ```
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; }
155
154
 
156
- **Runtime module (.ts):**
157
- ```typescript
158
- import { createUnboundAction } from '@xrmforge/typegen';
159
155
  export const NormalizePhone = createUnboundAction<NormalizePhoneParams, NormalizePhoneResult>(
160
156
  'markant_NormalizePhone',
161
157
  { Input: { typeName: 'String', structuralProperty: 1 } }
@@ -14,7 +14,7 @@ Generates TypeScript declarations from a Dataverse environment.
14
14
  | `--token <token>` | string | varies | Pre-acquired bearer token (token auth only) |
15
15
  | `--entities <list>` | string | - | Comma-separated entity logical names |
16
16
  | `--solutions <list>` | string | - | Comma-separated solution unique names |
17
- | `--output <dir>` | string | ./typings | Output directory |
17
+ | `--output <dir>` | string | ./generated | Output directory |
18
18
  | `--label-language <n>` | string | 1033 | Primary label language (LCID) |
19
19
  | `--secondary-language <n>` | string | - | Secondary label language for JSDoc |
20
20
  | `--no-forms` | flag | - | Skip form interface generation |
@@ -55,4 +55,4 @@ Scaffolds a new D365 form scripting project.
55
55
  | `--skip-install` | flag | false | Skip npm install |
56
56
  | `--force` | flag | false | Allow non-empty directories |
57
57
 
58
- Generates 11 files: package.json, tsconfig.json, xrmforge.config.json, vitest.config.ts, .gitignore, AGENT.md, example-form.ts, example-form.test.ts, typings/.gitkeep, GitHub Actions CI, Azure DevOps Pipeline.
58
+ Generates 11 files: package.json, tsconfig.json, xrmforge.config.json, vitest.config.ts, .gitignore, AGENT.md, example-form.ts, example-form.test.ts, generated/.gitkeep, GitHub Actions CI, Azure DevOps Pipeline.
@@ -4,7 +4,7 @@
4
4
 
5
5
  ```typescript
6
6
  import { createFormMock } from '@xrmforge/testing';
7
- import type { AccountMainForm, AccountMainFormMockValues } from '../typings/forms/account';
7
+ import type { AccountMainForm, AccountMainFormMockValues } from '../generated/forms/account';
8
8
 
9
9
  const mock = createFormMock<AccountMainForm, AccountMainFormMockValues>({
10
10
  name: 'Contoso Ltd',
@@ -36,7 +36,7 @@ Forbids raw numbers (>= 2) in comparisons with `.getValue()`.
36
36
  if (attr.getValue() === 595300000) { }
37
37
 
38
38
  // Good
39
- import { StatusCode } from '../typings/optionsets/account';
39
+ import { StatusCode } from '../generated/optionsets/account';
40
40
  if (attr.getValue() === StatusCode.Active) { }
41
41
  ```
42
42
 
@@ -35,4 +35,4 @@ Five AI models were tested converting legacy D365 JavaScript (account.js + lm_he
35
35
 
36
36
  **Criteria (11, max 5 points each = 55 max):** Fields Enum usage, OptionSet Enums, FormContext typing, XrmForge helpers, module exports, tests present, test quality, error handling, code quality, bugs found, documentation.
37
37
 
38
- **Key finding:** No AI consistently used `@xrmforge/typegen/helpers` imports (select, parseLookup). This remains the biggest adoption gap.
38
+ **Key finding:** No AI consistently used `@xrmforge/helpers` imports (select, parseLookup). This remains the biggest adoption gap.
@@ -10,5 +10,5 @@ Known issues when working with `@types/xrm`:
10
10
  | setNotification | `setNotification(message)` | `setNotification(message, uniqueId)` (requires 2 args) |
11
11
  | openFile | `openFile({ fileName, ... })` | Must include `fileSize` property in FileDetails |
12
12
  | SubmitMode | `Xrm.Attributes.SubmitMode` | `Xrm.SubmitMode` |
13
- | const enum in .d.ts | `const enum` in `.d.ts` files | Use regular `enum` in `.ts` files (vitest cannot import const enums from .d.ts) |
13
+ | const enum in .d.ts | `const enum` in `.d.ts` files | Use `const enum` in `.ts` ES modules (typegen 0.8.0+ generates `.ts` files, resolving this issue) |
14
14
  | Grid.refresh() | `grid.refresh()` | `(grid as any).refresh()` (not typed in @types/xrm) |
@@ -12,6 +12,6 @@
12
12
 
13
13
  ### 16.2 Accepted Limitations
14
14
 
15
- - **const enum limitation:** Cannot be imported at runtime by test frameworks from `.d.ts` files. Workaround: use `.ts` files with regular `enum` for manual typings.
15
+ - **const enum limitation:** Resolved in typegen 0.8.0. Generated output is now `.ts` ES modules, so `const enum` works directly with vitest and other test frameworks.
16
16
  - **Grid.refresh() requires `as any`:** Not typed in @types/xrm.
17
17
  - **Single solution per entity:** If an entity appears in multiple solutions, it is only generated once.
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Package | Version | Tests | Beschreibung |
6
6
  |---------|---------|-------|--------------|
7
- | @xrmforge/typegen | 0.6.0 | 444 | Kern: Typgenerierungs-Engine, Metadaten-Client, HTTP-Client, Hilfsfunktionen |
7
+ | @xrmforge/typegen | 0.8.0 | 444 | Kern: Typgenerierungs-Engine, Metadaten-Client, HTTP-Client, Hilfsfunktionen |
8
8
  | @xrmforge/cli | 0.4.2 | 10 | CLI: generate-, build-, init-Befehle |
9
9
  | @xrmforge/testing | 0.2.0 | 76 | Test-Hilfsmittel: createFormMock, fireOnChange, setupXrmMock |
10
10
  | @xrmforge/helpers | 0.1.0 | 59 | Browsersichere Laufzeit: select(), parseLookup(), typedForm(), Xrm-Konstanten, Action-Executors |
@@ -1,91 +1,93 @@
1
1
  # 3. Generierte Typen
2
2
 
3
- Die Ausführung von `xrmforge generate` erzeugt die folgenden TypeScript-Deklarationen:
3
+ Die Ausführung von `xrmforge generate` erzeugt die folgenden TypeScript-ES-Module:
4
4
 
5
- ## 3.1 Entitäts-Interfaces (`entities/{entity}.d.ts`)
5
+ ## 3.1 Entitäts-Interfaces (`entities/{entity}.ts`)
6
6
 
7
7
  ```typescript
8
- declare namespace XrmForge.Entities {
9
- /** Account | Konto */
10
- 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
- }
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
+ // ...
18
17
  }
19
18
  ```
20
19
 
21
20
  **Typ-Zuordnung:** String/Memo/EntityName zu `string`, Integer/BigInt/Decimal/Double/Money zu `number`, Boolean zu `boolean`, DateTime/Uniqueidentifier/Lookup zu `string`, Picklist/State/Status zu `number`.
22
21
 
23
- ## 3.2 Entity Fields Enums (`entities/{entity}.d.ts`)
22
+ ## 3.2 Entity Fields Enums (`fields/{entity}.ts`)
24
23
 
25
24
  ```typescript
26
- declare namespace XrmForge.Entities {
27
- const enum AccountFields {
28
- /** Account Name | Kontoname */
29
- Name = 'name',
30
- Revenue = 'revenue',
31
- // alle lesbaren Attribute
32
- }
25
+ // generated/fields/account.ts
26
+ export const enum AccountFields {
27
+ /** Account Name | Kontoname */
28
+ Name = 'name',
29
+ Telephone1 = 'telephone1',
30
+ Revenue = 'revenue',
31
+ // alle Entitätsattribute für $select-Abfragen
32
+ }
33
+
34
+ export const enum AccountNavigationProperties {
35
+ PrimaryContact = 'primarycontactid',
36
+ ContactCustomerAccounts = 'contact_customer_accounts',
37
+ // alle Lookup-Navigations-Properties
33
38
  }
34
39
  ```
35
40
 
36
41
  Verwendet für Web API `$select`: `select(AccountFields.Name, AccountFields.Revenue)`.
37
42
 
38
- ## 3.3 Navigations-Properties (`entities/{entity}.d.ts`)
43
+ ## 3.3 Navigations-Properties (`fields/{entity}.ts`)
44
+
45
+ Navigations-Property-Enums befinden sich zusammen mit den Fields-Enums in derselben Datei (siehe 3.2 oben). Beispielverwendung:
39
46
 
40
47
  ```typescript
41
- declare namespace XrmForge.Entities {
42
- const enum AccountNavigation {
43
- PrimaryContactId = 'primarycontactid',
44
- ContactCustomerAccounts = 'contact_customer_accounts',
45
- // OneToMany- + ManyToMany-Beziehungen
46
- }
47
- }
48
+ import { AccountNavigationProperties } from '../generated/fields/account';
49
+ // verwendet für $expand-Abfragen
48
50
  ```
49
51
 
50
- ## 3.4 Formular-Interfaces (`forms/{entity}.d.ts`)
52
+ ## 3.4 Formular-Interfaces (`forms/{entity}.ts`)
51
53
 
52
54
  ```typescript
53
- declare namespace XrmForge.Forms.Account {
54
- // Union-Typ, der gültige Feldnamen einschränkt
55
- type AccountMainFormFields = 'name' | 'telephone1' | 'revenue';
56
-
57
- // Gemappter Typ: Feldname zu Xrm-Attributtyp
58
- type AccountMainFormAttributeMap = {
59
- name: Xrm.Attributes.StringAttribute;
60
- telephone1: Xrm.Attributes.StringAttribute;
61
- revenue: Xrm.Attributes.NumberAttribute;
62
- };
63
-
64
- // Gemappter Typ: Feldname zu Xrm-Steuerelementtyp
65
- type AccountMainFormControlMap = {
66
- name: Xrm.Controls.StringControl;
67
- telephone1: Xrm.Controls.StringControl;
68
- revenue: Xrm.Controls.NumberControl;
69
- };
70
-
71
- // Fields-Enum für Autovervollständigung
72
- const enum AccountMainFormFieldsEnum {
73
- /** Account Name | Kontoname */
74
- AccountName = 'name',
75
- Telephone1 = 'telephone1',
76
- Revenue = 'revenue',
77
- }
78
-
79
- // Typsicherer FormContext mit überladenen getAttribute/getControl
80
- interface AccountMainForm extends Omit<Xrm.FormContext, 'getAttribute' | 'getControl'> {
81
- getAttribute<K extends AccountMainFormFields>(name: K): AccountMainFormAttributeMap[K];
82
- getAttribute(index: number): Xrm.Attributes.Attribute;
83
- getAttribute(): Xrm.Attributes.Attribute[];
84
-
85
- getControl<K extends AccountMainFormFields>(name: K): AccountMainFormControlMap[K];
86
- getControl(index: number): Xrm.Controls.Control;
87
- getControl(): Xrm.Controls.Control[];
88
- }
55
+ // generated/forms/account.ts
56
+
57
+ // Union-Typ, der gültige Feldnamen einschränkt
58
+ export type AccountMainFormFields = 'name' | 'telephone1' | 'revenue';
59
+
60
+ // Gemappter Typ: Feldname zu Xrm-Attributtyp
61
+ export type AccountMainFormAttributeMap = {
62
+ name: Xrm.Attributes.StringAttribute;
63
+ telephone1: Xrm.Attributes.StringAttribute;
64
+ revenue: Xrm.Attributes.NumberAttribute;
65
+ };
66
+
67
+ // Gemappter Typ: Feldname zu Xrm-Steuerelementtyp
68
+ export type AccountMainFormControlMap = {
69
+ name: Xrm.Controls.StringControl;
70
+ telephone1: Xrm.Controls.StringControl;
71
+ revenue: Xrm.Controls.NumberControl;
72
+ };
73
+
74
+ // Fields-Enum für Autovervollständigung
75
+ export const enum AccountMainFormFieldsEnum {
76
+ /** Account Name | Kontoname */
77
+ AccountName = 'name',
78
+ Telephone1 = 'telephone1',
79
+ Revenue = 'revenue',
80
+ }
81
+
82
+ // Typsicherer FormContext mit überladenen 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[];
89
91
  }
90
92
  ```
91
93
 
@@ -104,30 +106,28 @@ const enum AccountMainFormSubgrids { Contacts = 'Contacts_Subgrid' }
104
106
  const enum AccountMainFormQuickViews { ContactPreview = 'ContactQuickView' }
105
107
  ```
106
108
 
107
- ## 3.6 OptionSet Enums (`optionsets/{entity}.d.ts`)
109
+ ## 3.6 OptionSet Enums (`optionsets/{entity}.ts`)
108
110
 
109
111
  ```typescript
110
- declare namespace XrmForge.OptionSets.Account {
111
- /** Account Category Code | Kontokategoriecode */
112
- const enum AccountCategoryCode {
113
- /** Preferred Customer | Bevorzugter Kunde */
114
- PreferredCustomer = 1,
115
- Standard = 2,
116
- }
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,
117
118
  }
118
119
  ```
119
120
 
120
121
  Umfasst Picklist-, Status-, State- und MultiSelectPicklist-Attribute. Doppelte Labels werden mit dem Suffix `_{Value}` disambiguiert.
121
122
 
122
- ## 3.7 EntityNames Enum (`entity-names.d.ts`)
123
+ ## 3.7 EntityNames Enum (`entity-names.ts`)
123
124
 
124
125
  ```typescript
125
- declare namespace XrmForge {
126
- const enum EntityNames {
127
- Account = 'account',
128
- Contact = 'contact',
129
- // alle Entitäten im Scope
130
- }
126
+ // generated/entity-names.ts
127
+ export const enum EntityNames {
128
+ Account = 'account',
129
+ Contact = 'contact',
130
+ // alle Entitäten im Scope
131
131
  }
132
132
  ```
133
133
 
@@ -143,19 +143,15 @@ type AccountMainFormMockValues = {
143
143
 
144
144
  Verwendet mit `createFormMock<AccountMainForm, AccountMainFormMockValues>({ name: 'Test' })`.
145
145
 
146
- ## 3.9 Action/Function Executors (`actions/{entity|global}.d.ts` + `.ts`)
146
+ ## 3.9 Action/Function Executors (`actions/{entity|global}.ts`)
147
147
 
148
- **Deklaration (.d.ts):**
149
148
  ```typescript
150
- declare namespace XrmForge.Actions {
151
- interface NormalizePhoneParams { Input: string; AllowSuspicious?: boolean; }
152
- interface NormalizePhoneResult { Normalized: string; Status: number; }
153
- }
154
- ```
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; }
155
154
 
156
- **Laufzeitmodul (.ts):**
157
- ```typescript
158
- import { createUnboundAction } from '@xrmforge/typegen';
159
155
  export const NormalizePhone = createUnboundAction<NormalizePhoneParams, NormalizePhoneResult>(
160
156
  'markant_NormalizePhone',
161
157
  { Input: { typeName: 'String', structuralProperty: 1 } }
@@ -14,7 +14,7 @@ Generiert TypeScript-Deklarationen aus einer Dataverse-Umgebung.
14
14
  | `--token <token>` | string | variiert | Vorab erworbenes Bearer-Token (nur Token-Auth) |
15
15
  | `--entities <list>` | string | - | Kommagetrennte logische Entitätsnamen |
16
16
  | `--solutions <list>` | string | - | Kommagetrennte eindeutige Lösungsnamen |
17
- | `--output <dir>` | string | ./typings | Ausgabeverzeichnis |
17
+ | `--output <dir>` | string | ./generated | Ausgabeverzeichnis |
18
18
  | `--label-language <n>` | string | 1033 | Primäre Label-Sprache (LCID) |
19
19
  | `--secondary-language <n>` | string | - | Sekundäre Label-Sprache für JSDoc |
20
20
  | `--no-forms` | flag | - | Formular-Interface-Generierung überspringen |
@@ -55,4 +55,4 @@ Erstellt ein neues D365-Formularskript-Projekt.
55
55
  | `--skip-install` | flag | false | npm install überspringen |
56
56
  | `--force` | flag | false | Nicht-leere Verzeichnisse erlauben |
57
57
 
58
- Generiert 11 Dateien: package.json, tsconfig.json, xrmforge.config.json, vitest.config.ts, .gitignore, AGENT.md, example-form.ts, example-form.test.ts, typings/.gitkeep, GitHub Actions CI, Azure DevOps Pipeline.
58
+ Generiert 11 Dateien: package.json, tsconfig.json, xrmforge.config.json, vitest.config.ts, .gitignore, AGENT.md, example-form.ts, example-form.test.ts, generated/.gitkeep, GitHub Actions CI, Azure DevOps Pipeline.
@@ -4,7 +4,7 @@
4
4
 
5
5
  ```typescript
6
6
  import { createFormMock } from '@xrmforge/testing';
7
- import type { AccountMainForm, AccountMainFormMockValues } from '../typings/forms/account';
7
+ import type { AccountMainForm, AccountMainFormMockValues } from '../generated/forms/account';
8
8
 
9
9
  const mock = createFormMock<AccountMainForm, AccountMainFormMockValues>({
10
10
  name: 'Contoso Ltd',
@@ -36,7 +36,7 @@ Verbietet rohe Zahlen (>= 2) in Vergleichen mit `.getValue()`.
36
36
  if (attr.getValue() === 595300000) { }
37
37
 
38
38
  // Richtig
39
- import { StatusCode } from '../typings/optionsets/account';
39
+ import { StatusCode } from '../generated/optionsets/account';
40
40
  if (attr.getValue() === StatusCode.Active) { }
41
41
  ```
42
42
 
@@ -35,4 +35,4 @@ Fünf KI-Modelle wurden beim Konvertieren von Legacy-D365-JavaScript (account.js
35
35
 
36
36
  **Kriterien (11, maximal 5 Punkte je = 55 max):** Fields-Enum-Nutzung, OptionSet-Enums, FormContext-Typisierung, XrmForge-Helpers, Modul-Exports, Tests vorhanden, Testqualität, Fehlerbehandlung, Codequalität, gefundene Bugs, Dokumentation.
37
37
 
38
- **Zentrale Erkenntnis:** Keine KI hat konsistent `@xrmforge/typegen/helpers`-Imports (select, parseLookup) verwendet. Dies bleibt die grösste Adoptionslücke.
38
+ **Zentrale Erkenntnis:** Keine KI hat konsistent `@xrmforge/helpers`-Imports (select, parseLookup) verwendet. Dies bleibt die grösste Adoptionslücke.
@@ -10,5 +10,5 @@ Bekannte Probleme bei der Arbeit mit `@types/xrm`:
10
10
  | setNotification | `setNotification(message)` | `setNotification(message, uniqueId)` (erfordert 2 Argumente) |
11
11
  | openFile | `openFile({ fileName, ... })` | Muss `fileSize`-Eigenschaft in FileDetails enthalten |
12
12
  | SubmitMode | `Xrm.Attributes.SubmitMode` | `Xrm.SubmitMode` |
13
- | const enum in .d.ts | `const enum` in `.d.ts`-Dateien | Reguläres `enum` in `.ts`-Dateien verwenden (vitest kann const enums aus .d.ts nicht importieren) |
13
+ | const enum in .d.ts | `const enum` in `.d.ts`-Dateien | `const enum` in `.ts`-ES-Modulen verwenden (typegen 0.8.0+ generiert `.ts`-Dateien, wodurch dieses Problem gelöst ist) |
14
14
  | Grid.refresh() | `grid.refresh()` | `(grid as any).refresh()` (nicht typisiert in @types/xrm) |
@@ -12,6 +12,6 @@
12
12
 
13
13
  ## 16.2 Akzeptierte Einschränkungen
14
14
 
15
- - **const-enum-Einschränkung:** Kann zur Laufzeit von Test-Frameworks nicht aus `.d.ts`-Dateien importiert werden. Workaround: `.ts`-Dateien mit regulärem `enum` für manuelle Typings verwenden.
15
+ - **const-enum-Einschränkung:** Gelöst in typegen 0.8.0. Generierter Output sind jetzt `.ts`-ES-Module, sodass `const enum` direkt mit vitest und anderen Test-Frameworks funktioniert.
16
16
  - **Grid.refresh() erfordert `as any`:** Nicht typisiert in @types/xrm.
17
17
  - **Eine Solution pro Entität:** Wenn eine Entität in mehreren Solutions vorkommt, wird sie nur einmal generiert.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xrmforge/typegen",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "TypeScript declaration generator for Dynamics 365 / Dataverse",
5
5
  "keywords": [
6
6
  "dynamics-365",