@xrmforge/typegen 0.11.1 → 0.12.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/LICENSE +21 -21
- package/dist/index.d.ts +74 -77
- package/dist/index.js +32 -15
- package/dist/index.js.map +1 -1
- package/docs/architecture/13-helpers.md +1 -1
- package/docs/architektur/13-helpers.md +1 -1
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 XrmForge Contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 XrmForge Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
CHANGED
|
@@ -489,6 +489,10 @@ interface SystemFormMetadata {
|
|
|
489
489
|
formxml: string;
|
|
490
490
|
description: string | null;
|
|
491
491
|
isdefault: boolean;
|
|
492
|
+
/** Form type (systemform_type): 2 = Main, 7 = Quick Create, ... */
|
|
493
|
+
type: number;
|
|
494
|
+
/** Activation state (systemform_formactivationstate): 0 = Inactive, 1 = Active */
|
|
495
|
+
formactivationstate: number;
|
|
492
496
|
}
|
|
493
497
|
/** Parsed data-bound control from FormXml (bound to an attribute) */
|
|
494
498
|
interface FormControl {
|
|
@@ -541,6 +545,8 @@ interface ParsedForm {
|
|
|
541
545
|
name: string;
|
|
542
546
|
formId: string;
|
|
543
547
|
isDefault: boolean;
|
|
548
|
+
/** Form type (systemform_type): 2 = Main, 7 = Quick Create */
|
|
549
|
+
type: number;
|
|
544
550
|
tabs: FormTab[];
|
|
545
551
|
/** All data-bound controls across all tabs/sections (flattened) */
|
|
546
552
|
allControls: FormControl[];
|
|
@@ -712,10 +718,14 @@ declare class MetadataClient {
|
|
|
712
718
|
*/
|
|
713
719
|
getStateAttributes(logicalName: string): Promise<StateAttributeMetadata[]>;
|
|
714
720
|
/**
|
|
715
|
-
* Get and parse
|
|
716
|
-
*
|
|
721
|
+
* Get and parse the form types relevant for type generation (Main type=2 and
|
|
722
|
+
* Quick Create type=7), restricted to ACTIVE forms (formactivationstate=1).
|
|
723
|
+
* Inactive forms are leftovers that no app surfaces, so they get no interface -
|
|
724
|
+
* this applies to both Main and Quick Create forms.
|
|
725
|
+
*
|
|
726
|
+
* Returns parsed form structures with tabs, sections, controls, and the form type.
|
|
717
727
|
*/
|
|
718
|
-
|
|
728
|
+
getForms(logicalName: string): Promise<ParsedForm[]>;
|
|
719
729
|
/**
|
|
720
730
|
* Get a global OptionSet by its exact name.
|
|
721
731
|
*/
|
|
@@ -1199,17 +1209,15 @@ declare function disambiguateEnumMembers(members: Array<{
|
|
|
1199
1209
|
/**
|
|
1200
1210
|
* @xrmforge/typegen - Entity Interface Generator
|
|
1201
1211
|
*
|
|
1202
|
-
* Generates
|
|
1212
|
+
* Generates Dataverse entity interfaces as a flat ES module (.ts file).
|
|
1203
1213
|
* These interfaces represent the data types returned by the Web API.
|
|
1204
1214
|
*
|
|
1205
|
-
* Output pattern:
|
|
1215
|
+
* Output pattern (flat ES module, one file per entity):
|
|
1206
1216
|
* ```typescript
|
|
1207
|
-
*
|
|
1208
|
-
*
|
|
1209
|
-
*
|
|
1210
|
-
*
|
|
1211
|
-
* // ...
|
|
1212
|
-
* }
|
|
1217
|
+
* export interface Account {
|
|
1218
|
+
* accountid: string;
|
|
1219
|
+
* name: string | null;
|
|
1220
|
+
* // ...
|
|
1213
1221
|
* }
|
|
1214
1222
|
* ```
|
|
1215
1223
|
*/
|
|
@@ -1224,7 +1232,7 @@ interface EntityGeneratorOptions {
|
|
|
1224
1232
|
*
|
|
1225
1233
|
* @param info - Complete entity metadata (from MetadataClient.getEntityTypeInfo)
|
|
1226
1234
|
* @param options - Generator options
|
|
1227
|
-
* @returns TypeScript
|
|
1235
|
+
* @returns TypeScript source string (flat ES module)
|
|
1228
1236
|
*/
|
|
1229
1237
|
declare function generateEntityInterface(info: EntityTypeInfo, options?: EntityGeneratorOptions): string;
|
|
1230
1238
|
|
|
@@ -1235,13 +1243,11 @@ declare function generateEntityInterface(info: EntityTypeInfo, options?: EntityG
|
|
|
1235
1243
|
* Uses const enum because D365 form scripts have no module system at runtime,
|
|
1236
1244
|
* so enum values must be inlined at compile time.
|
|
1237
1245
|
*
|
|
1238
|
-
* Output pattern:
|
|
1246
|
+
* Output pattern (flat ES module, all OptionSets of an entity in one file):
|
|
1239
1247
|
* ```typescript
|
|
1240
|
-
*
|
|
1241
|
-
*
|
|
1242
|
-
*
|
|
1243
|
-
* Standard = 2,
|
|
1244
|
-
* }
|
|
1248
|
+
* export const enum AccountCategoryCode {
|
|
1249
|
+
* PreferredCustomer = 1,
|
|
1250
|
+
* Standard = 2,
|
|
1245
1251
|
* }
|
|
1246
1252
|
* ```
|
|
1247
1253
|
*/
|
|
@@ -1291,38 +1297,37 @@ declare function generateEntityOptionSets(picklistAttributes: Array<{
|
|
|
1291
1297
|
* 4. Fields const enum: provides autocomplete with dual-language labels
|
|
1292
1298
|
* 5. NO fallback getAttribute(name: string): unknown fields are compile errors
|
|
1293
1299
|
*
|
|
1294
|
-
* Output pattern:
|
|
1300
|
+
* Output pattern (flat ES module, one file per entity, all forms combined):
|
|
1295
1301
|
* ```typescript
|
|
1296
|
-
*
|
|
1297
|
-
*
|
|
1298
|
-
*
|
|
1299
|
-
*
|
|
1300
|
-
*
|
|
1301
|
-
*
|
|
1302
|
-
*
|
|
1303
|
-
*
|
|
1304
|
-
*
|
|
1305
|
-
*
|
|
1306
|
-
*
|
|
1307
|
-
*
|
|
1308
|
-
*
|
|
1309
|
-
*
|
|
1310
|
-
*
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
*
|
|
1316
|
-
*
|
|
1317
|
-
*
|
|
1318
|
-
*
|
|
1319
|
-
*
|
|
1320
|
-
*
|
|
1321
|
-
*
|
|
1322
|
-
*
|
|
1323
|
-
* getControl(): Xrm.Controls.Control[];
|
|
1324
|
-
* }
|
|
1302
|
+
* export type AccountMainFormFields = "name" | "telephone1" | "revenue";
|
|
1303
|
+
*
|
|
1304
|
+
* export type AccountMainFormAttributeMap = {
|
|
1305
|
+
* name: Xrm.Attributes.StringAttribute;
|
|
1306
|
+
* telephone1: Xrm.Attributes.StringAttribute;
|
|
1307
|
+
* revenue: Xrm.Attributes.NumberAttribute;
|
|
1308
|
+
* };
|
|
1309
|
+
*
|
|
1310
|
+
* export type AccountMainFormControlMap = {
|
|
1311
|
+
* name: Xrm.Controls.StringControl;
|
|
1312
|
+
* telephone1: Xrm.Controls.StringControl;
|
|
1313
|
+
* revenue: Xrm.Controls.NumberControl;
|
|
1314
|
+
* };
|
|
1315
|
+
*
|
|
1316
|
+
* export const enum AccountMainFormFieldsEnum {
|
|
1317
|
+
* Name = 'name',
|
|
1318
|
+
* Telephone1 = 'telephone1',
|
|
1319
|
+
* Revenue = 'revenue',
|
|
1320
|
+
* }
|
|
1321
|
+
*
|
|
1322
|
+
* export interface AccountMainForm extends Omit<Xrm.FormContext, 'getAttribute' | 'getControl'> {
|
|
1323
|
+
* getAttribute<K extends AccountMainFormFields>(name: K): AccountMainFormAttributeMap[K];
|
|
1324
|
+
* getAttribute(index: number): Xrm.Attributes.Attribute;
|
|
1325
|
+
* getAttribute(): Xrm.Attributes.Attribute[];
|
|
1326
|
+
* getControl<K extends AccountMainFormFields>(name: K): AccountMainFormControlMap[K];
|
|
1327
|
+
* getControl(index: number): Xrm.Controls.Control;
|
|
1328
|
+
* getControl(): Xrm.Controls.Control[];
|
|
1325
1329
|
* }
|
|
1330
|
+
* // plus ...FormTabs/...Sections/...FormSubgrids enums, ...FormTypeInfo, ...FormMockValues
|
|
1326
1331
|
* ```
|
|
1327
1332
|
*/
|
|
1328
1333
|
|
|
@@ -1364,15 +1369,13 @@ declare function generateEntityForms(forms: ParsedForm[], entityLogicalName: str
|
|
|
1364
1369
|
* Generates a const enum with ALL entity fields for use with Xrm.WebApi.
|
|
1365
1370
|
* Unlike form-specific Fields enums, this contains every readable attribute.
|
|
1366
1371
|
*
|
|
1367
|
-
* Output pattern:
|
|
1372
|
+
* Output pattern (flat ES module):
|
|
1368
1373
|
* ```typescript
|
|
1369
|
-
*
|
|
1370
|
-
*
|
|
1371
|
-
*
|
|
1372
|
-
*
|
|
1373
|
-
*
|
|
1374
|
-
* Telephone1 = 'telephone1',
|
|
1375
|
-
* }
|
|
1374
|
+
* export const enum AccountFields {
|
|
1375
|
+
* /** Account Name | Firmenname *\/
|
|
1376
|
+
* Name = 'name',
|
|
1377
|
+
* /** Main Phone | Haupttelefon *\/
|
|
1378
|
+
* Telephone1 = 'telephone1',
|
|
1376
1379
|
* }
|
|
1377
1380
|
* ```
|
|
1378
1381
|
*/
|
|
@@ -1422,14 +1425,12 @@ declare function generateEntityNavigationProperties(info: EntityTypeInfo, option
|
|
|
1422
1425
|
* Generates a single const enum with all entity logical names.
|
|
1423
1426
|
* Eliminates raw strings in Xrm.WebApi calls.
|
|
1424
1427
|
*
|
|
1425
|
-
* Output pattern:
|
|
1428
|
+
* Output pattern (flat ES module):
|
|
1426
1429
|
* ```typescript
|
|
1427
|
-
*
|
|
1428
|
-
*
|
|
1429
|
-
*
|
|
1430
|
-
*
|
|
1431
|
-
* Lead = 'lead',
|
|
1432
|
-
* }
|
|
1430
|
+
* export const enum EntityNames {
|
|
1431
|
+
* Account = 'account',
|
|
1432
|
+
* Contact = 'contact',
|
|
1433
|
+
* Lead = 'lead',
|
|
1433
1434
|
* }
|
|
1434
1435
|
* ```
|
|
1435
1436
|
*/
|
|
@@ -1447,24 +1448,20 @@ declare function generateEntityNamesEnum(entityNames: string[], _options?: Entit
|
|
|
1447
1448
|
/**
|
|
1448
1449
|
* @xrmforge/typegen - Action/Function Generator
|
|
1449
1450
|
*
|
|
1450
|
-
* Generates
|
|
1451
|
-
*
|
|
1452
|
-
* - .ts: Runtime modules that import factory functions from @xrmforge/helpers
|
|
1451
|
+
* Generates a flat ES module (.ts) per Custom API group: exported Param/Result
|
|
1452
|
+
* interfaces plus runtime executors that import factory functions from @xrmforge/helpers.
|
|
1453
1453
|
*
|
|
1454
1454
|
* Input: CustomApiTypeInfo[] (from fixture JSON or live Dataverse query)
|
|
1455
1455
|
* Output: Grouped by entity (bound) or "global" (unbound)
|
|
1456
1456
|
*
|
|
1457
|
-
* @example Generated output for markant_NormalizePhone (unbound action):
|
|
1457
|
+
* @example Generated output for markant_NormalizePhone (unbound action) in actions/global.ts:
|
|
1458
1458
|
* ```typescript
|
|
1459
|
-
* // global.d.ts
|
|
1460
|
-
* declare namespace XrmForge.Actions {
|
|
1461
|
-
* interface NormalizePhoneParams { Input: string; AllowSuspicious?: boolean; }
|
|
1462
|
-
* interface NormalizePhoneResult { Normalized: string; Status: number; Message: string; }
|
|
1463
|
-
* }
|
|
1464
|
-
*
|
|
1465
|
-
* // global.ts
|
|
1466
1459
|
* import { createUnboundAction } from '@xrmforge/helpers';
|
|
1467
|
-
*
|
|
1460
|
+
*
|
|
1461
|
+
* export type NormalizePhoneParams = { Input: string; AllowSuspicious?: boolean; };
|
|
1462
|
+
* export type NormalizePhoneResult = { Normalized: string; Status: number; Message: string; };
|
|
1463
|
+
* export const NormalizePhone =
|
|
1464
|
+
* createUnboundAction<NormalizePhoneParams, NormalizePhoneResult>('markant_NormalizePhone', { ... });
|
|
1468
1465
|
* ```
|
|
1469
1466
|
*/
|
|
1470
1467
|
|
|
@@ -1485,7 +1482,7 @@ interface ActionGeneratorOptions {
|
|
|
1485
1482
|
declare function generateActionDeclarations(apis: CustomApiTypeInfo[], _isFunction: boolean, _entityName?: string, _options?: ActionGeneratorOptions): string;
|
|
1486
1483
|
/**
|
|
1487
1484
|
* Generate a single .ts file with both interfaces and runtime executors for a group of Custom APIs.
|
|
1488
|
-
*
|
|
1485
|
+
* Emits the Param/Result interfaces and the runtime executors together in one .ts file.
|
|
1489
1486
|
*
|
|
1490
1487
|
* @param apis - Custom APIs to generate
|
|
1491
1488
|
* @param isFunction - true for functions, false for actions
|
|
@@ -1517,7 +1514,7 @@ interface GenerateConfig {
|
|
|
1517
1514
|
entities: string[];
|
|
1518
1515
|
/** Solution unique names to discover entities automatically (merged with entities, deduplicated) */
|
|
1519
1516
|
solutionNames?: string[];
|
|
1520
|
-
/** Output directory for generated .
|
|
1517
|
+
/** Output directory for generated .ts files */
|
|
1521
1518
|
outputDir: string;
|
|
1522
1519
|
/** Label language configuration */
|
|
1523
1520
|
labelConfig: LabelConfig;
|
package/dist/index.js
CHANGED
|
@@ -774,6 +774,7 @@ function parseForm(form, parser = defaultXmlParser) {
|
|
|
774
774
|
name: form.name,
|
|
775
775
|
formId: form.formid,
|
|
776
776
|
isDefault: form.isdefault,
|
|
777
|
+
type: form.type,
|
|
777
778
|
tabs,
|
|
778
779
|
allControls,
|
|
779
780
|
allSpecialControls
|
|
@@ -918,13 +919,15 @@ function extractParameter(controlElement, paramName) {
|
|
|
918
919
|
// src/metadata/client.ts
|
|
919
920
|
var log4 = createLogger("metadata");
|
|
920
921
|
var FORM_TYPE_MAIN = 2;
|
|
922
|
+
var FORM_TYPE_QUICK_CREATE = 7;
|
|
923
|
+
var FORM_ACTIVATION_ACTIVE = 1;
|
|
921
924
|
var COMPONENT_TYPE_ENTITY = 1;
|
|
922
925
|
function byUniqueName(a, b) {
|
|
923
926
|
return a.uniquename < b.uniquename ? -1 : a.uniquename > b.uniquename ? 1 : 0;
|
|
924
927
|
}
|
|
925
928
|
var ENTITY_SELECT = "LogicalName,SchemaName,EntitySetName,DisplayName,PrimaryIdAttribute,PrimaryNameAttribute,OwnershipType,IsCustomEntity,LogicalCollectionName,MetadataId";
|
|
926
929
|
var ATTRIBUTE_SELECT = "LogicalName,SchemaName,AttributeType,AttributeTypeName,DisplayName,IsPrimaryId,IsPrimaryName,RequiredLevel,IsValidForRead,IsValidForCreate,IsValidForUpdate,MetadataId";
|
|
927
|
-
var FORM_SELECT = "name,formid,formxml,description,isdefault";
|
|
930
|
+
var FORM_SELECT = "name,formid,formxml,description,isdefault,type,formactivationstate";
|
|
928
931
|
var MetadataClient = class {
|
|
929
932
|
http;
|
|
930
933
|
constructor(httpClient) {
|
|
@@ -1001,16 +1004,22 @@ var MetadataClient = class {
|
|
|
1001
1004
|
}
|
|
1002
1005
|
// ─── Form Metadata ────────────────────────────────────────────────────
|
|
1003
1006
|
/**
|
|
1004
|
-
* Get and parse
|
|
1005
|
-
*
|
|
1007
|
+
* Get and parse the form types relevant for type generation (Main type=2 and
|
|
1008
|
+
* Quick Create type=7), restricted to ACTIVE forms (formactivationstate=1).
|
|
1009
|
+
* Inactive forms are leftovers that no app surfaces, so they get no interface -
|
|
1010
|
+
* this applies to both Main and Quick Create forms.
|
|
1011
|
+
*
|
|
1012
|
+
* Returns parsed form structures with tabs, sections, controls, and the form type.
|
|
1006
1013
|
*/
|
|
1007
|
-
async
|
|
1014
|
+
async getForms(logicalName) {
|
|
1008
1015
|
const safeName = DataverseHttpClient.sanitizeIdentifier(logicalName);
|
|
1009
|
-
log4.info(`Fetching Main forms for: ${safeName}`);
|
|
1016
|
+
log4.info(`Fetching active Main + Quick Create forms for: ${safeName}`);
|
|
1010
1017
|
const forms = await this.http.getAll(
|
|
1011
|
-
`/systemforms?$filter=objecttypecode eq '${safeName}' and type eq ${FORM_TYPE_MAIN}&$select=${FORM_SELECT}`
|
|
1018
|
+
`/systemforms?$filter=objecttypecode eq '${safeName}' and (type eq ${FORM_TYPE_MAIN} or type eq ${FORM_TYPE_QUICK_CREATE}) and formactivationstate eq ${FORM_ACTIVATION_ACTIVE}&$select=${FORM_SELECT}`
|
|
1012
1019
|
);
|
|
1013
|
-
|
|
1020
|
+
const mainCount = forms.filter((f) => f.type === FORM_TYPE_MAIN).length;
|
|
1021
|
+
const qcCount = forms.filter((f) => f.type === FORM_TYPE_QUICK_CREATE).length;
|
|
1022
|
+
log4.info(`Found ${mainCount} Main + ${qcCount} Quick Create active form(s) for "${safeName}"`);
|
|
1014
1023
|
return forms.map((form) => {
|
|
1015
1024
|
try {
|
|
1016
1025
|
return parseForm(form);
|
|
@@ -1024,6 +1033,7 @@ var MetadataClient = class {
|
|
|
1024
1033
|
name: form.name,
|
|
1025
1034
|
formId: form.formid,
|
|
1026
1035
|
isDefault: form.isdefault,
|
|
1036
|
+
type: form.type,
|
|
1027
1037
|
tabs: [],
|
|
1028
1038
|
allControls: [],
|
|
1029
1039
|
allSpecialControls: []
|
|
@@ -1152,7 +1162,7 @@ var MetadataClient = class {
|
|
|
1152
1162
|
this.getLookupAttributes(safeName),
|
|
1153
1163
|
this.getStatusAttributes(safeName),
|
|
1154
1164
|
this.getStateAttributes(safeName),
|
|
1155
|
-
this.
|
|
1165
|
+
this.getForms(safeName),
|
|
1156
1166
|
this.getRelationships(safeName)
|
|
1157
1167
|
]);
|
|
1158
1168
|
const result = {
|
|
@@ -1936,7 +1946,14 @@ function generateEntityOptionSets(picklistAttributes, entityLogicalName, options
|
|
|
1936
1946
|
return results;
|
|
1937
1947
|
}
|
|
1938
1948
|
|
|
1949
|
+
// src/generators/string-escape.ts
|
|
1950
|
+
function singleQuoted(value) {
|
|
1951
|
+
const escaped = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\r/g, "\\r").replace(/\n/g, "\\n");
|
|
1952
|
+
return `'${escaped}'`;
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1939
1955
|
// src/generators/form-generator.ts
|
|
1956
|
+
var FORM_TYPE_QUICK_CREATE2 = 7;
|
|
1940
1957
|
function specialControlToXrmType(controlType) {
|
|
1941
1958
|
switch (controlType) {
|
|
1942
1959
|
case "subgrid":
|
|
@@ -2065,7 +2082,7 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2065
2082
|
if (field.label) {
|
|
2066
2083
|
lines.push(` /** ${field.label} */`);
|
|
2067
2084
|
}
|
|
2068
|
-
lines.push(` ${field.enumMemberName} =
|
|
2085
|
+
lines.push(` ${field.enumMemberName} = ${singleQuoted(field.logicalName)},`);
|
|
2069
2086
|
}
|
|
2070
2087
|
lines.push("}");
|
|
2071
2088
|
lines.push("");
|
|
@@ -2092,7 +2109,7 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2092
2109
|
if (tab.label) {
|
|
2093
2110
|
lines.push(` /** ${tab.label} */`);
|
|
2094
2111
|
}
|
|
2095
|
-
lines.push(` ${tabMemberNames[i]} =
|
|
2112
|
+
lines.push(` ${tabMemberNames[i]} = ${singleQuoted(tab.name)},`);
|
|
2096
2113
|
}
|
|
2097
2114
|
lines.push("}");
|
|
2098
2115
|
lines.push("");
|
|
@@ -2117,7 +2134,7 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2117
2134
|
sCounter++;
|
|
2118
2135
|
}
|
|
2119
2136
|
usedSectionMembers.add(sectionMember);
|
|
2120
|
-
lines.push(` ${sectionMember} =
|
|
2137
|
+
lines.push(` ${sectionMember} = ${singleQuoted(section.name)},`);
|
|
2121
2138
|
}
|
|
2122
2139
|
lines.push("}");
|
|
2123
2140
|
lines.push("");
|
|
@@ -2142,7 +2159,7 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2142
2159
|
usedMembers.add(member);
|
|
2143
2160
|
const label = sg.targetEntityType ? `Subgrid: ${sg.targetEntityType}` : `Subgrid`;
|
|
2144
2161
|
lines.push(` /** ${label} */`);
|
|
2145
|
-
lines.push(` ${member} =
|
|
2162
|
+
lines.push(` ${member} = ${singleQuoted(sg.id)},`);
|
|
2146
2163
|
}
|
|
2147
2164
|
lines.push("}");
|
|
2148
2165
|
lines.push("");
|
|
@@ -2162,7 +2179,7 @@ function generateFormInterface(form, entityLogicalName, attributeMap, options =
|
|
|
2162
2179
|
}
|
|
2163
2180
|
usedMembers.add(member);
|
|
2164
2181
|
lines.push(` /** Quick View */`);
|
|
2165
|
-
lines.push(` ${member} =
|
|
2182
|
+
lines.push(` ${member} = ${singleQuoted(qv.id)},`);
|
|
2166
2183
|
}
|
|
2167
2184
|
lines.push("}");
|
|
2168
2185
|
lines.push("");
|
|
@@ -2239,8 +2256,8 @@ function generateEntityForms(forms, entityLogicalName, attributes, options = {})
|
|
|
2239
2256
|
const entityPascal = toPascalCase(entityLogicalName);
|
|
2240
2257
|
const validForms = forms.filter((f) => f.allControls.length > 0);
|
|
2241
2258
|
const baseNames = validForms.map((form) => {
|
|
2242
|
-
const
|
|
2243
|
-
return
|
|
2259
|
+
const base = buildFormBaseName(entityPascal, toSafeFormName(form.name));
|
|
2260
|
+
return form.type === FORM_TYPE_QUICK_CREATE2 ? `${base}QuickCreate` : base;
|
|
2244
2261
|
});
|
|
2245
2262
|
const baseNameCounts = /* @__PURE__ */ new Map();
|
|
2246
2263
|
for (const name of baseNames) {
|