@xrmforge/typegen 0.1.0 → 0.2.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.
package/dist/index.d.ts CHANGED
@@ -574,6 +574,92 @@ interface EntityTypeInfo {
574
574
  manyToManyRelationships: ManyToManyRelationshipMetadata[];
575
575
  }
576
576
 
577
+ /**
578
+ * @xrmforge/typegen - Custom API Metadata Types
579
+ *
580
+ * TypeScript interfaces for Dataverse Custom API definitions.
581
+ * These types model the JSON structures from the customapi,
582
+ * customapirequestparameter, and customapiresponseproperty tables.
583
+ *
584
+ * Used by the action-generator to produce typed Action/Function executors.
585
+ */
586
+ /**
587
+ * Custom API parameter type (picklist values from customapirequestparameter.type).
588
+ *
589
+ * Maps to TypeScript types and OData metadata for getMetadata().
590
+ */
591
+ declare const enum CustomApiParameterType {
592
+ Boolean = 0,
593
+ DateTime = 1,
594
+ Decimal = 2,
595
+ Entity = 3,
596
+ EntityCollection = 4,
597
+ EntityReference = 5,
598
+ Float = 6,
599
+ Integer = 7,
600
+ Money = 8,
601
+ Picklist = 9,
602
+ String = 10,
603
+ StringArray = 11,
604
+ Guid = 12
605
+ }
606
+ /**
607
+ * Custom API binding type (picklist values from customapi.bindingtype).
608
+ */
609
+ declare const enum CustomApiBindingType {
610
+ /** Nicht an eine Entity gebunden (global aufrufbar) */
611
+ Global = 0,
612
+ /** An einen einzelnen Entity-Datensatz gebunden */
613
+ Entity = 1,
614
+ /** An eine Entity-Collection gebunden */
615
+ EntityCollection = 2
616
+ }
617
+ /** Custom API definition (from the customapi table) */
618
+ interface CustomApiMetadata {
619
+ /** Unique message name (e.g. "markant_NormalizePhone") */
620
+ uniquename: string;
621
+ /** 0=Global, 1=Entity, 2=EntityCollection */
622
+ bindingtype: CustomApiBindingType;
623
+ /** true = Function (GET), false = Action (POST) */
624
+ isfunction: boolean;
625
+ /** Bound entity logical name (null for unbound) */
626
+ boundentitylogicalname: string | null;
627
+ /** Display name for documentation */
628
+ displayname?: string;
629
+ /** Description for JSDoc */
630
+ description?: string;
631
+ }
632
+ /** Custom API request parameter (from the customapirequestparameter table) */
633
+ interface CustomApiRequestParameter {
634
+ /** Parameter name (e.g. "Input", "TargetId") */
635
+ uniquename: string;
636
+ /** Parameter type (0-12, see CustomApiParameterType) */
637
+ type: CustomApiParameterType;
638
+ /** Whether the parameter is optional */
639
+ isoptional: boolean;
640
+ /** Entity logical name (for Entity/EntityReference types) */
641
+ logicalentityname?: string | null;
642
+ /** Description for JSDoc */
643
+ description?: string;
644
+ }
645
+ /** Custom API response property (from the customapiresponseproperty table) */
646
+ interface CustomApiResponseProperty {
647
+ /** Property name (e.g. "Normalized", "IsValid") */
648
+ uniquename: string;
649
+ /** Property type (0-12, see CustomApiParameterType) */
650
+ type: CustomApiParameterType;
651
+ /** Entity logical name (for Entity/EntityReference types) */
652
+ logicalentityname?: string | null;
653
+ /** Description for JSDoc */
654
+ description?: string;
655
+ }
656
+ /** Complete Custom API definition with parameters and response */
657
+ interface CustomApiTypeInfo {
658
+ api: CustomApiMetadata;
659
+ requestParameters: CustomApiRequestParameter[];
660
+ responseProperties: CustomApiResponseProperty[];
661
+ }
662
+
577
663
  /**
578
664
  * @xrmforge/typegen - Metadata Client
579
665
  *
@@ -668,6 +754,16 @@ declare class MetadataClient {
668
754
  * Respects the HTTP client's concurrency limit automatically.
669
755
  */
670
756
  getMultipleEntityTypeInfos(logicalNames: string[]): Promise<EntityTypeInfo[]>;
757
+ /**
758
+ * Fetch all Custom APIs with their request parameters and response properties.
759
+ *
760
+ * Queries the customapi, customapirequestparameter, and customapiresponseproperty
761
+ * tables and joins them into CustomApiTypeInfo objects.
762
+ *
763
+ * @param solutionFilter - Optional: filter by solution unique name
764
+ * @returns Array of complete Custom API definitions
765
+ */
766
+ getCustomApis(solutionFilter?: string): Promise<CustomApiTypeInfo[]>;
671
767
  private getRelationships;
672
768
  }
673
769
 
@@ -913,6 +1009,14 @@ declare function getFormAttributeType(attributeType: string): string;
913
1009
  * @returns Fully qualified Xrm control type string
914
1010
  */
915
1011
  declare function getFormControlType(attributeType: string): string;
1012
+ /**
1013
+ * Map Dataverse AttributeType to JavaScript value type for mock objects.
1014
+ * Used by the form generator to create MockValues types for @xrmforge/testing.
1015
+ *
1016
+ * @param attributeType - The AttributeType from Dataverse metadata
1017
+ * @returns TypeScript value type string (e.g. "string | null", "number | null")
1018
+ */
1019
+ declare function getFormMockValueType(attributeType: string): string;
916
1020
  /**
917
1021
  * Convert a Dataverse LogicalName to a safe TypeScript identifier.
918
1022
  * Validates that the result is a valid identifier.
@@ -945,6 +1049,12 @@ declare function toLookupValueProperty(logicalName: string): string;
945
1049
  * not a single _fieldname_value property in the Web API.
946
1050
  */
947
1051
  declare function isLookupType(attributeType: string): boolean;
1052
+ /**
1053
+ * Determine if an attribute is a PartyList (ActivityParty collection).
1054
+ * PartyList fields (to, from, cc, bcc, requiredattendees, optionalattendees)
1055
+ * are navigation properties in the Web API, not flat lookup properties.
1056
+ */
1057
+ declare function isPartyListType(attributeType: string): boolean;
948
1058
  /**
949
1059
  * Determine if an attribute should be included in entity interfaces.
950
1060
  * Excludes virtual/calculated fields that are not readable via Web API.
@@ -958,6 +1068,29 @@ declare function isLookupType(attributeType: string): boolean;
958
1068
  */
959
1069
  declare function shouldIncludeInEntityInterface(attr: AttributeMetadata): boolean;
960
1070
 
1071
+ /**
1072
+ * @xrmforge/typegen - ActivityParty Base Interface
1073
+ *
1074
+ * ActivityParty is a Dataverse system entity that represents participants
1075
+ * in activities (email, appointment, phonecall, fax, etc.).
1076
+ *
1077
+ * PartyList fields (to, from, cc, bcc, requiredattendees, optionalattendees)
1078
+ * are collection-valued navigation properties that return ActivityParty arrays.
1079
+ *
1080
+ * This interface is generated once and referenced by all Activity entities
1081
+ * that have PartyList fields.
1082
+ *
1083
+ * @see https://learn.microsoft.com/en-us/power-apps/developer/data-platform/reference/entities/activityparty
1084
+ */
1085
+ /**
1086
+ * Generate the ActivityParty base interface declaration.
1087
+ * This is a fixed structure (system entity, never customized).
1088
+ *
1089
+ * @param namespace - Namespace for the interface (default: "XrmForge.Entities")
1090
+ * @returns TypeScript declaration string
1091
+ */
1092
+ declare function generateActivityPartyInterface(namespace?: string): string;
1093
+
961
1094
  /**
962
1095
  * @xrmforge/typegen - Generator-specific Label Utilities
963
1096
  *
@@ -1169,6 +1302,459 @@ declare function generateEntityForms(forms: ParsedForm[], entityLogicalName: str
1169
1302
  content: string;
1170
1303
  }>;
1171
1304
 
1305
+ /**
1306
+ * @xrmforge/typegen - Entity Fields Enum Generator
1307
+ *
1308
+ * Generates a const enum with ALL entity fields for use with Xrm.WebApi.
1309
+ * Unlike form-specific Fields enums, this contains every readable attribute.
1310
+ *
1311
+ * Output pattern:
1312
+ * ```typescript
1313
+ * declare namespace XrmForge.Entities {
1314
+ * const enum AccountFields {
1315
+ * /** Account Name | Firmenname *\/
1316
+ * Name = 'name',
1317
+ * /** Main Phone | Haupttelefon *\/
1318
+ * Telephone1 = 'telephone1',
1319
+ * }
1320
+ * }
1321
+ * ```
1322
+ */
1323
+
1324
+ /** Options for entity fields enum generation */
1325
+ interface EntityFieldsGeneratorOptions {
1326
+ /** Label configuration for dual-language JSDoc comments */
1327
+ labelConfig?: LabelConfig;
1328
+ /** Namespace for generated enums (default: "XrmForge.Entities") */
1329
+ namespace?: string;
1330
+ }
1331
+ /**
1332
+ * Generate a const enum with all entity fields for Web API usage.
1333
+ * Includes ALL readable fields (not form-specific).
1334
+ *
1335
+ * @param info - Complete entity metadata
1336
+ * @param options - Generator options
1337
+ * @returns TypeScript declaration string
1338
+ */
1339
+ declare function generateEntityFieldsEnum(info: EntityTypeInfo, options?: EntityFieldsGeneratorOptions): string;
1340
+ /**
1341
+ * Generate a const enum with navigation property names for all lookup fields.
1342
+ * Used with parseLookup() and $expand queries.
1343
+ *
1344
+ * Unlike EntityFields (which uses _fieldname_value format), this enum
1345
+ * contains the plain LogicalName (= navigation property name for non-polymorphic lookups).
1346
+ *
1347
+ * @param info - Complete entity metadata
1348
+ * @param options - Generator options
1349
+ * @returns TypeScript declaration string
1350
+ *
1351
+ * @example
1352
+ * ```typescript
1353
+ * // Generated:
1354
+ * const enum AccountNavigationProperties {
1355
+ * Country = 'markant_address1_countryid',
1356
+ * PrimaryContact = 'primarycontactid',
1357
+ * }
1358
+ *
1359
+ * // Usage:
1360
+ * parseLookup(response, AccountNav.Country);
1361
+ * ```
1362
+ */
1363
+ declare function generateEntityNavigationProperties(info: EntityTypeInfo, options?: EntityFieldsGeneratorOptions): string;
1364
+
1365
+ /**
1366
+ * @xrmforge/typegen - Web API Helper Functions
1367
+ *
1368
+ * Lightweight utility functions for building OData query strings
1369
+ * with type-safe field names from generated Fields enums.
1370
+ *
1371
+ * Zero runtime overhead when used with const enums (values are inlined).
1372
+ *
1373
+ * @example
1374
+ * ```typescript
1375
+ * import { select } from '@xrmforge/typegen';
1376
+ *
1377
+ * Xrm.WebApi.retrieveRecord(ref.entityType, ref.id, select(
1378
+ * AccountFields.Name,
1379
+ * AccountFields.WebsiteUrl,
1380
+ * AccountFields.Address1Line1,
1381
+ * ));
1382
+ * ```
1383
+ */
1384
+ /**
1385
+ * Build an OData $select query string from field names.
1386
+ *
1387
+ * @param fields - Field names (use generated Fields enum for type safety)
1388
+ * @returns OData query string (e.g. "?$select=name,websiteurl,address1_line1")
1389
+ */
1390
+ declare function select(...fields: string[]): string;
1391
+ /**
1392
+ * Parse a lookup field from a Dataverse Web API response into a LookupValue.
1393
+ *
1394
+ * Dataverse returns lookups as `_fieldname_value` with OData annotations:
1395
+ * - `_fieldname_value` (GUID)
1396
+ * - `_fieldname_value@OData.Community.Display.V1.FormattedValue` (display name)
1397
+ * - `_fieldname_value@Microsoft.Dynamics.CRM.lookuplogicalname` (entity type)
1398
+ *
1399
+ * This function extracts all three into an `Xrm.LookupValue` object.
1400
+ *
1401
+ * @param response - The raw Web API response object
1402
+ * @param navigationProperty - Navigation property name (use NavigationProperties enum for type safety)
1403
+ * @returns Xrm.LookupValue or null if the lookup is empty
1404
+ *
1405
+ * @example
1406
+ * ```typescript
1407
+ * // Mit NavigationProperties-Enum (empfohlen, keine Raw-Strings):
1408
+ * parseLookup(result, AccountNav.Country);
1409
+ *
1410
+ * // Oder mit Navigation Property Name direkt:
1411
+ * parseLookup(result, 'markant_address1_countryid');
1412
+ * ```
1413
+ */
1414
+ declare function parseLookup(response: Record<string, unknown>, navigationProperty: string): {
1415
+ id: string;
1416
+ name: string;
1417
+ entityType: string;
1418
+ } | null;
1419
+ /**
1420
+ * Parse multiple lookup fields from a Dataverse Web API response at once.
1421
+ *
1422
+ * @param response - The raw Web API response object
1423
+ * @param navigationProperties - Navigation property names to parse
1424
+ * @returns Map of navigation property name to LookupValue (null entries omitted)
1425
+ *
1426
+ * @example
1427
+ * ```typescript
1428
+ * const lookups = parseLookups(result, ['markant_address1_countryid', 'parentaccountid']);
1429
+ * formContext.getAttribute(Fields.Country).setValue(
1430
+ * lookups.markant_address1_countryid ? [lookups.markant_address1_countryid] : null
1431
+ * );
1432
+ * ```
1433
+ */
1434
+ declare function parseLookups(response: Record<string, unknown>, navigationProperties: string[]): Record<string, {
1435
+ id: string;
1436
+ name: string;
1437
+ entityType: string;
1438
+ } | null>;
1439
+ /**
1440
+ * Get the formatted (display) value of any field from a Web API response.
1441
+ *
1442
+ * Works for OptionSets, Lookups, DateTimes, Money, and other formatted fields.
1443
+ *
1444
+ * @param response - The raw Web API response object
1445
+ * @param fieldName - The field logical name (e.g. "statecode", "createdon")
1446
+ * @returns The formatted string value, or null if not available
1447
+ *
1448
+ * @example
1449
+ * ```typescript
1450
+ * const status = parseFormattedValue(result, 'statecode');
1451
+ * // "Active" (statt 0)
1452
+ * ```
1453
+ */
1454
+ declare function parseFormattedValue(response: Record<string, unknown>, fieldName: string): string | null;
1455
+ /**
1456
+ * Build an OData $select and $expand query string.
1457
+ *
1458
+ * @param fields - Field names to select
1459
+ * @param expand - Navigation property to expand (optional)
1460
+ * @returns OData query string
1461
+ *
1462
+ * @example
1463
+ * ```typescript
1464
+ * Xrm.WebApi.retrieveRecord("account", id, selectExpand(
1465
+ * [AccountFields.Name, AccountFields.WebsiteUrl],
1466
+ * "primarycontactid($select=fullname,emailaddress1)"
1467
+ * ));
1468
+ * ```
1469
+ */
1470
+ declare function selectExpand(fields: string[], expand: string): string;
1471
+
1472
+ /**
1473
+ * @xrmforge/typegen - Xrm API Constants
1474
+ *
1475
+ * Const enums for all common Xrm string/number constants.
1476
+ * Eliminates raw strings in D365 form scripts.
1477
+ *
1478
+ * @types/xrm defines these as string literal types for compile-time checking,
1479
+ * but does NOT provide runtime constants (XrmEnum is not available at runtime).
1480
+ * These const enums are erased at compile time (zero runtime overhead).
1481
+ *
1482
+ * @example
1483
+ * ```typescript
1484
+ * // Statt Raw-String:
1485
+ * if (tab.getDisplayState() === 'expanded') { ... }
1486
+ *
1487
+ * // Mit XrmForge-Konstante:
1488
+ * if (tab.getDisplayState() === XrmConstants.DisplayState.Expanded) { ... }
1489
+ * ```
1490
+ */
1491
+ /** Tab/Section display state */
1492
+ declare const enum DisplayState {
1493
+ Expanded = "expanded",
1494
+ Collapsed = "collapsed"
1495
+ }
1496
+ /** Form notification level (formContext.ui.setFormNotification) */
1497
+ declare const enum FormNotificationLevel {
1498
+ Error = "ERROR",
1499
+ Warning = "WARNING",
1500
+ Info = "INFO"
1501
+ }
1502
+ /** Attribute required level (attribute.setRequiredLevel) */
1503
+ declare const enum RequiredLevel {
1504
+ None = "none",
1505
+ Required = "required",
1506
+ Recommended = "recommended"
1507
+ }
1508
+ /** Attribute submit mode (attribute.setSubmitMode) */
1509
+ declare const enum SubmitMode {
1510
+ Always = "always",
1511
+ Never = "never",
1512
+ Dirty = "dirty"
1513
+ }
1514
+ /** Save mode (eventArgs.getSaveMode()) */
1515
+ declare const enum SaveMode {
1516
+ Save = 1,
1517
+ SaveAndClose = 2,
1518
+ Deactivate = 5,
1519
+ Reactivate = 6,
1520
+ Send = 7,
1521
+ Disqualify = 15,
1522
+ Qualify = 16,
1523
+ Assign = 47,
1524
+ SaveAsCompleted = 58,
1525
+ SaveAndNew = 59,
1526
+ AutoSave = 70
1527
+ }
1528
+ /** Client type (Xrm.Utility.getGlobalContext().client.getClient()) */
1529
+ declare const enum ClientType {
1530
+ Web = "Web",
1531
+ Outlook = "Outlook",
1532
+ Mobile = "Mobile"
1533
+ }
1534
+ /** Client state (Xrm.Utility.getGlobalContext().client.getClientState()) */
1535
+ declare const enum ClientState {
1536
+ Online = "Online",
1537
+ Offline = "Offline"
1538
+ }
1539
+ /** Operation type for Xrm.WebApi.execute getMetadata().operationType */
1540
+ declare const enum OperationType {
1541
+ /** Custom Action or OOB Action (POST) */
1542
+ Action = 0,
1543
+ /** Custom Function or OOB Function (GET) */
1544
+ Function = 1,
1545
+ /** CRUD operation (Create, Retrieve, Update, Delete) */
1546
+ CRUD = 2
1547
+ }
1548
+ /** Structural property for getMetadata().parameterTypes[].structuralProperty */
1549
+ declare const enum StructuralProperty {
1550
+ Unknown = 0,
1551
+ PrimitiveType = 1,
1552
+ ComplexType = 2,
1553
+ EnumerationType = 3,
1554
+ Collection = 4,
1555
+ EntityType = 5
1556
+ }
1557
+ /** Binding type for Custom API definitions */
1558
+ declare const enum BindingType {
1559
+ /** Nicht an eine Entity gebunden (global aufrufbar) */
1560
+ Global = 0,
1561
+ /** An einen einzelnen Entity-Datensatz gebunden */
1562
+ Entity = 1,
1563
+ /** An eine Entity-Collection gebunden */
1564
+ EntityCollection = 2
1565
+ }
1566
+
1567
+ /**
1568
+ * @xrmforge/typegen - Action/Function Runtime Helpers
1569
+ *
1570
+ * Factory functions for type-safe Custom API execution.
1571
+ * These are imported by generated action/function modules.
1572
+ *
1573
+ * Design:
1574
+ * - `createBoundAction` / `createUnboundAction`: Produce executor objects
1575
+ * with `.execute()` (calls Xrm.WebApi) and `.request()` (for executeMultiple)
1576
+ * - `executeRequest`: Central execute wrapper (single place for the `as any` cast)
1577
+ * - `withProgress`: Convenience wrapper with progress indicator + error dialog
1578
+ *
1579
+ * @example
1580
+ * ```typescript
1581
+ * // Generated code (in generated/actions/quote.ts):
1582
+ * export const WinQuote = createBoundAction('markant_winquote', 'quote');
1583
+ *
1584
+ * // Developer code (in quote-form.ts):
1585
+ * import { WinQuote } from '../generated/actions/quote';
1586
+ * const response = await WinQuote.execute(recordId);
1587
+ * ```
1588
+ */
1589
+ /** Parameter metadata for getMetadata().parameterTypes */
1590
+ interface ParameterMeta {
1591
+ typeName: string;
1592
+ structuralProperty: number;
1593
+ }
1594
+ /** Map of parameter names to their OData metadata */
1595
+ type ParameterMetaMap = Record<string, ParameterMeta>;
1596
+ /** Executor for a bound action without additional parameters */
1597
+ interface BoundActionExecutor {
1598
+ execute(recordId: string): Promise<Response>;
1599
+ request(recordId: string): Record<string, unknown>;
1600
+ }
1601
+ /** Executor for a bound action with typed parameters */
1602
+ interface BoundActionWithParamsExecutor<TParams> {
1603
+ execute(recordId: string, params: TParams): Promise<Response>;
1604
+ request(recordId: string, params: TParams): Record<string, unknown>;
1605
+ }
1606
+ /** Executor for an unbound action without parameters */
1607
+ interface UnboundActionExecutor {
1608
+ execute(): Promise<Response>;
1609
+ request(): Record<string, unknown>;
1610
+ }
1611
+ /** Executor for an unbound action with typed parameters and optional typed response */
1612
+ interface UnboundActionWithParamsExecutor<TParams, TResult = void> {
1613
+ execute(params: TParams): Promise<TResult extends void ? Response : TResult>;
1614
+ request(params: TParams): Record<string, unknown>;
1615
+ }
1616
+ /** Executor for an unbound function with typed response */
1617
+ interface UnboundFunctionExecutor<TResult> {
1618
+ execute(): Promise<TResult>;
1619
+ request(): Record<string, unknown>;
1620
+ }
1621
+ /** Executor for a bound function with typed response */
1622
+ interface BoundFunctionExecutor<TResult> {
1623
+ execute(recordId: string): Promise<TResult>;
1624
+ request(recordId: string): Record<string, unknown>;
1625
+ }
1626
+ /**
1627
+ * Execute a single request via Xrm.WebApi.online.execute().
1628
+ *
1629
+ * This is the ONLY place in the entire framework where the `as any` cast happens.
1630
+ * All generated executors call this function internally.
1631
+ */
1632
+ declare function executeRequest(request: Record<string, unknown>): Promise<Response>;
1633
+ /**
1634
+ * Execute multiple requests via Xrm.WebApi.online.executeMultiple().
1635
+ *
1636
+ * @param requests - Array of request objects (from `.request()` factories).
1637
+ * Wrap a subset in an inner array for transactional changeset execution.
1638
+ */
1639
+ declare function executeMultiple(requests: Array<Record<string, unknown> | Array<Record<string, unknown>>>): Promise<Response[]>;
1640
+ /**
1641
+ * Create an executor for a bound action (entity-bound).
1642
+ *
1643
+ * @param operationName - Custom API unique name (e.g. "markant_winquote")
1644
+ * @param entityLogicalName - Entity logical name (e.g. "quote")
1645
+ */
1646
+ declare function createBoundAction(operationName: string, entityLogicalName: string): BoundActionExecutor;
1647
+ /**
1648
+ * Create an executor for a bound action with typed parameters.
1649
+ *
1650
+ * @param operationName - Custom API unique name
1651
+ * @param entityLogicalName - Entity logical name
1652
+ * @param paramMeta - Parameter metadata map (parameter name to OData type info)
1653
+ */
1654
+ declare function createBoundAction<TParams extends Record<string, unknown>>(operationName: string, entityLogicalName: string, paramMeta: ParameterMetaMap): BoundActionWithParamsExecutor<TParams>;
1655
+ /**
1656
+ * Create an executor for an unbound (global) action without parameters.
1657
+ *
1658
+ * @param operationName - Custom API unique name
1659
+ */
1660
+ declare function createUnboundAction(operationName: string): UnboundActionExecutor;
1661
+ /**
1662
+ * Create an executor for an unbound action with typed parameters and response.
1663
+ *
1664
+ * @param operationName - Custom API unique name
1665
+ * @param paramMeta - Parameter metadata map
1666
+ */
1667
+ declare function createUnboundAction<TParams extends Record<string, unknown>, TResult = void>(operationName: string, paramMeta: ParameterMetaMap): UnboundActionWithParamsExecutor<TParams, TResult>;
1668
+ /**
1669
+ * Create an executor for an unbound (global) function with typed response.
1670
+ *
1671
+ * @param operationName - Function name (e.g. "WhoAmI")
1672
+ */
1673
+ declare function createUnboundFunction<TResult>(operationName: string): UnboundFunctionExecutor<TResult>;
1674
+ /**
1675
+ * Create an executor for a bound function with typed response.
1676
+ *
1677
+ * @param operationName - Function name
1678
+ * @param entityLogicalName - Entity logical name
1679
+ */
1680
+ declare function createBoundFunction<TResult>(operationName: string, entityLogicalName: string): BoundFunctionExecutor<TResult>;
1681
+ /**
1682
+ * Execute an async operation with Xrm progress indicator.
1683
+ *
1684
+ * Shows a progress spinner before the operation, closes it after,
1685
+ * and shows an error dialog on failure.
1686
+ *
1687
+ * @param message - Progress indicator message (e.g. "Angebot wird gewonnen...")
1688
+ * @param operation - Async function to execute
1689
+ * @returns The result of the operation
1690
+ *
1691
+ * @example
1692
+ * ```typescript
1693
+ * await withProgress('Angebot wird gewonnen...', () => WinQuote.execute(recordId));
1694
+ * ```
1695
+ */
1696
+ declare function withProgress<T>(message: string, operation: () => Promise<T>): Promise<T>;
1697
+
1698
+ /**
1699
+ * @xrmforge/typegen - Action/Function Generator
1700
+ *
1701
+ * Generates TypeScript files for type-safe Custom API execution:
1702
+ * - .d.ts: Parameter/Response interfaces and executor types
1703
+ * - .ts: Runtime modules that import factory functions from @xrmforge/typegen
1704
+ *
1705
+ * Input: CustomApiTypeInfo[] (from fixture JSON or live Dataverse query)
1706
+ * Output: Grouped by entity (bound) or "global" (unbound)
1707
+ *
1708
+ * @example Generated output for markant_NormalizePhone (unbound action):
1709
+ * ```typescript
1710
+ * // global.d.ts
1711
+ * declare namespace XrmForge.Actions {
1712
+ * interface NormalizePhoneParams { Input: string; AllowSuspicious?: boolean; }
1713
+ * interface NormalizePhoneResult { Normalized: string; Status: number; Message: string; }
1714
+ * }
1715
+ *
1716
+ * // global.ts
1717
+ * import { createUnboundAction } from '@xrmforge/typegen';
1718
+ * export const NormalizePhone = createUnboundAction<...>('markant_NormalizePhone', { ... });
1719
+ * ```
1720
+ */
1721
+
1722
+ /** Options for action/function generation */
1723
+ interface ActionGeneratorOptions {
1724
+ /** Import path for @xrmforge/typegen (default: "@xrmforge/typegen") */
1725
+ importPath?: string;
1726
+ /** Namespace for generated types (default: "XrmForge.Actions" / "XrmForge.Functions") */
1727
+ actionsNamespace?: string;
1728
+ functionsNamespace?: string;
1729
+ }
1730
+ /**
1731
+ * Generate .d.ts content for a group of Custom APIs.
1732
+ *
1733
+ * @param apis - Custom APIs to generate (all in the same group: same entity or all global)
1734
+ * @param isFunction - true for functions namespace, false for actions
1735
+ * @param entityName - Entity name for bound APIs, undefined for global
1736
+ * @param options - Generator options
1737
+ */
1738
+ declare function generateActionDeclarations(apis: CustomApiTypeInfo[], isFunction: boolean, entityName?: string, options?: ActionGeneratorOptions): string;
1739
+ /**
1740
+ * Generate .ts content with runtime executors for a group of Custom APIs.
1741
+ *
1742
+ * @param apis - Custom APIs to generate
1743
+ * @param isFunction - true for functions, false for actions
1744
+ * @param options - Generator options
1745
+ */
1746
+ declare function generateActionModule(apis: CustomApiTypeInfo[], isFunction: boolean, options?: ActionGeneratorOptions): string;
1747
+ /** Group result: key is entity logical name or "global" for unbound */
1748
+ interface GroupedCustomApis {
1749
+ actions: Map<string, CustomApiTypeInfo[]>;
1750
+ functions: Map<string, CustomApiTypeInfo[]>;
1751
+ }
1752
+ /**
1753
+ * Group Custom APIs by entity (bound) or "global" (unbound),
1754
+ * and separate actions from functions.
1755
+ */
1756
+ declare function groupCustomApis(apis: CustomApiTypeInfo[]): GroupedCustomApis;
1757
+
1172
1758
  /**
1173
1759
  * @xrmforge/typegen - Orchestrator Types
1174
1760
  *
@@ -1193,6 +1779,8 @@ interface GenerateConfig {
1193
1779
  generateForms?: boolean;
1194
1780
  /** Whether to generate OptionSet enums (default: true) */
1195
1781
  generateOptionSets?: boolean;
1782
+ /** Whether to generate Custom API Action/Function executors (default: false) */
1783
+ generateActions?: boolean;
1196
1784
  /**
1197
1785
  * Whether to use metadata cache for faster re-generation.
1198
1786
  * @alpha Not yet implemented. Setting this to true will throw a ConfigError.
@@ -1226,7 +1814,7 @@ interface GeneratedFile {
1226
1814
  /** File content */
1227
1815
  content: string;
1228
1816
  /** Type of generated content */
1229
- type: 'entity' | 'optionset' | 'form';
1817
+ type: 'entity' | 'optionset' | 'form' | 'action';
1230
1818
  }
1231
1819
  /** Overall result of the generation process */
1232
1820
  interface GenerationResult {
@@ -1292,4 +1880,4 @@ declare class TypeGenerationOrchestrator {
1292
1880
  private getPicklistAttributes;
1293
1881
  }
1294
1882
 
1295
- export { ApiRequestError, type AttributeMetadata, type AuthConfig, type AuthMethod, AuthenticationError, type ClientCredentialsAuth, ConfigError, ConsoleLogSink, DEFAULT_LABEL_CONFIG, DataverseHttpClient, type DateTimeAttributeMetadata, type DecimalAttributeMetadata, type DeviceCodeAuth, type EntityGenerationResult, type EntityGeneratorOptions, type EntityMetadata, type EntityTypeInfo, ErrorCode, FastXmlParser, type FormControl, type FormGeneratorOptions, type FormSection, type FormTab, type GenerateConfig, type GeneratedFile, GenerationError, type GenerationResult, type HttpClientOptions, type IntegerAttributeMetadata, type InteractiveAuth, JsonLogSink, type Label, type LabelConfig, type LocalizedLabel, type LogEntry, LogLevel, type LogSink, Logger, type LookupAttributeMetadata, type ManyToManyRelationshipMetadata, MetadataCache, MetadataClient, MetadataError, type MoneyAttributeMetadata, type OneToManyRelationshipMetadata, type OptionMetadata, type OptionSetGeneratorOptions, type OptionSetMetadata, type ParsedForm, type PicklistAttributeMetadata, SilentLogSink, type SolutionComponent, type StateAttributeMetadata, type StatusAttributeMetadata, type StringAttributeMetadata, type SystemFormMetadata, TypeGenerationOrchestrator, type XmlElement, type XmlParser, XrmForgeError, configureLogging, createCredential, createLogger, defaultXmlParser, disambiguateEnumMembers, extractControlFields, getJSDocLabel as formatDualLabel, generateEntityForms, generateEntityInterface, generateEntityOptionSets, generateEnumMembers, generateFormInterface, generateOptionSetEnum, getEntityPropertyType, getFormAttributeType, getFormControlType, getJSDocLabel, getLabelLanguagesParam, getPrimaryLabel, getSecondaryLabel, isLookupType, isRateLimitError, isXrmForgeError, labelToIdentifier, parseForm, shouldIncludeInEntityInterface, toLookupValueProperty, toPascalCase, toSafeIdentifier };
1883
+ export { type ActionGeneratorOptions, ApiRequestError, type AttributeMetadata, type AuthConfig, type AuthMethod, AuthenticationError, BindingType, type BoundActionExecutor, type BoundActionWithParamsExecutor, type BoundFunctionExecutor, type ClientCredentialsAuth, ClientState, ClientType, ConfigError, ConsoleLogSink, type CustomApiTypeInfo, DEFAULT_LABEL_CONFIG, DataverseHttpClient, type DateTimeAttributeMetadata, type DecimalAttributeMetadata, type DeviceCodeAuth, DisplayState, type EntityFieldsGeneratorOptions, type EntityGenerationResult, type EntityGeneratorOptions, type EntityMetadata, type EntityTypeInfo, ErrorCode, FastXmlParser, type FormControl, type FormGeneratorOptions, FormNotificationLevel, type FormSection, type FormTab, type GenerateConfig, type GeneratedFile, GenerationError, type GenerationResult, type GroupedCustomApis, type HttpClientOptions, type IntegerAttributeMetadata, type InteractiveAuth, JsonLogSink, type Label, type LabelConfig, type LocalizedLabel, type LogEntry, LogLevel, type LogSink, Logger, type LookupAttributeMetadata, type ManyToManyRelationshipMetadata, MetadataCache, MetadataClient, MetadataError, type MoneyAttributeMetadata, type OneToManyRelationshipMetadata, OperationType, type OptionMetadata, type OptionSetGeneratorOptions, type OptionSetMetadata, type ParameterMeta, type ParameterMetaMap, type ParsedForm, type PicklistAttributeMetadata, RequiredLevel, SaveMode, SilentLogSink, type SolutionComponent, type StateAttributeMetadata, type StatusAttributeMetadata, type StringAttributeMetadata, StructuralProperty, SubmitMode, type SystemFormMetadata, TypeGenerationOrchestrator, type UnboundActionExecutor, type UnboundActionWithParamsExecutor, type UnboundFunctionExecutor, type XmlElement, type XmlParser, XrmForgeError, configureLogging, createBoundAction, createBoundFunction, createCredential, createLogger, createUnboundAction, createUnboundFunction, defaultXmlParser, disambiguateEnumMembers, executeMultiple, executeRequest, extractControlFields, getJSDocLabel as formatDualLabel, generateActionDeclarations, generateActionModule, generateActivityPartyInterface, generateEntityFieldsEnum, generateEntityForms, generateEntityInterface, generateEntityNavigationProperties, generateEntityOptionSets, generateEnumMembers, generateFormInterface, generateOptionSetEnum, getEntityPropertyType, getFormAttributeType, getFormControlType, getFormMockValueType, getJSDocLabel, getLabelLanguagesParam, getPrimaryLabel, getSecondaryLabel, groupCustomApis, isLookupType, isPartyListType, isRateLimitError, isXrmForgeError, labelToIdentifier, parseForm, parseFormattedValue, parseLookup, parseLookups, select, selectExpand, shouldIncludeInEntityInterface, toLookupValueProperty, toPascalCase, toSafeIdentifier, withProgress };