@khester/dataverse-codegen 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/tsup/assets/cjs_shims.js","../../api-client/src/index.ts","../../api-client/src/fetch-client.ts","../../api-client/src/xrm-client.ts","../../api-client/src/mock-client.ts","../../api-client/src/factory.ts","../src/index.ts","../src/metadata/adapter.ts","../src/metadata/fetch.ts","../src/metadata/typedCast.ts","../src/metadata/http.ts","../src/validate.ts","../src/io/write.ts","../src/connection.ts","../../dev-tools/src/auth/envLoader.ts","../../dev-tools/src/auth/getToken.ts","../../dev-tools/src/proxy/viteProxy.ts","../../dev-tools/src/proxy/craProxy.ts","../src/metadata/links.ts","../src/design/parse.ts"],"sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","/**\n * @dynamics-ui-kit/api-client\n * Unified Dataverse/Dynamics 365 API client.\n */\n\n// Client interface\nexport type { IDataverseClient } from './interfaces';\n\n// Client implementations\nexport { FetchClient } from './fetch-client';\nexport { XrmClient } from './xrm-client';\nexport { MockClient } from './mock-client';\nexport type { MockDataConfig } from './mock-client';\n\n// Factory\nexport { createClient, getEnvironmentInfo } from './factory';\n\n// Types\nexport type {\n ODataResponse,\n BatchDeleteResult,\n BatchUpdateRecord,\n BatchUpdateResult,\n BatchCreateResult,\n ViewUpdateData,\n ViewCreateData,\n ClientOptions,\n EnvironmentInfo,\n Logger,\n EntityMetadata,\n AttributeMetadata,\n ViewMetadata,\n DisplayNameInfo,\n // Relationship types\n RelationshipType,\n OneToManyRelationshipMetadata,\n ManyToOneRelationshipMetadata,\n RelationshipMetadata,\n NormalizedRelationship,\n // Global option set types\n GlobalOptionSetMetadata,\n GlobalOptionSetOption,\n} from './types';\n","/**\n * @dynamics-ui-kit/api-client\n * Bearer token client for local development with real Dynamics data.\n */\n\nimport type { IDataverseClient } from './interfaces';\n\n/** A single OData collection page. */\ninterface ODataPage<T> {\n value?: T[];\n '@odata.nextLink'?: string;\n}\nimport type {\n BatchDeleteResult,\n BatchUpdateRecord,\n BatchUpdateResult,\n BatchCreateResult,\n ViewUpdateData,\n ViewCreateData,\n EntityMetadata,\n AttributeMetadata,\n ViewMetadata,\n Logger,\n RelationshipMetadata,\n OneToManyRelationshipMetadata,\n ManyToOneRelationshipMetadata,\n GlobalOptionSetMetadata,\n} from './types';\n\n/**\n * Dataverse client using fetch with Bearer token authentication.\n * Used for local development against real Dynamics 365 data.\n */\nexport class FetchClient implements IDataverseClient {\n private baseUrl: string;\n private token: string;\n private log: Logger;\n\n constructor(baseUrl: string, token: string, logger?: Logger) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n this.token = token;\n this.log = logger ?? console;\n }\n\n /** Update the token (e.g., after refresh) */\n setToken(token: string): void {\n this.token = token;\n }\n\n private getHeaders(): HeadersInit {\n return {\n 'Authorization': `Bearer ${this.token}`,\n 'Content-Type': 'application/json; charset=utf-8',\n 'Accept': 'application/json',\n 'OData-MaxVersion': '4.0',\n 'OData-Version': '4.0',\n 'Prefer': 'odata.include-annotations=\"*\"',\n };\n }\n\n private buildUrl(path: string, id?: string, options?: string): string {\n let url = `${this.baseUrl}/api/data/v9.2/${path}`;\n if (id) {\n url += `(${id.replace(/[{}]/g, '')})`;\n }\n if (options) {\n url += options.startsWith('?') ? options : `?${options}`;\n }\n return url;\n }\n\n private async handleResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}: ${response.statusText}`;\n try {\n const errorBody = await response.json();\n if (errorBody.error?.message) {\n errorMessage = errorBody.error.message;\n } else if (errorBody.Message) {\n errorMessage = errorBody.Message;\n }\n } catch {\n // Response wasn't JSON\n }\n\n if (response.status === 401) {\n errorMessage += ' (Token may be expired)';\n } else if (response.status === 403) {\n errorMessage += ' (Insufficient permissions)';\n } else if (response.status === 404) {\n errorMessage += ' (Entity or record not found)';\n }\n\n throw new Error(errorMessage);\n }\n\n if (response.status === 204) {\n return {} as T;\n }\n\n return response.json();\n }\n\n /**\n * GET a collection endpoint, following `@odata.nextLink` so wide results\n * (e.g. an entity with hundreds of attributes, or large metadata sets) are\n * not silently truncated at the server page cap.\n */\n private async fetchAllPages<T>(url: string): Promise<T[]> {\n const out: T[] = [];\n let next: string | undefined = url;\n while (next) {\n const response: Response = await fetch(next, { method: 'GET', headers: this.getHeaders() });\n const page = await this.handleResponse<ODataPage<T>>(response);\n if (page.value) out.push(...page.value);\n next = page['@odata.nextLink'];\n }\n return out;\n }\n\n private extractIdFromResponse(response: Response, _entitySetName: string): string | null {\n const entityIdHeader = response.headers.get('OData-EntityId');\n if (entityIdHeader) {\n const match = entityIdHeader.match(/\\(([0-9a-f-]+)\\)/i);\n if (match) return match[1];\n }\n return null;\n }\n\n // CRUD Operations\n\n async retrieve<T = Record<string, unknown>>(entitySetName: string, id: string, options?: string): Promise<T> {\n const url = this.buildUrl(entitySetName, id, options);\n this.log.log(`[FetchClient] GET ${url}`);\n const response = await fetch(url, { method: 'GET', headers: this.getHeaders() });\n return this.handleResponse<T>(response);\n }\n\n async retrieveMultiple<T = Record<string, unknown>>(entitySetName: string, options?: string): Promise<{ value: T[] }> {\n const url = this.buildUrl(entitySetName, undefined, options);\n this.log.log(`[FetchClient] GET ${url}`);\n const response = await fetch(url, { method: 'GET', headers: this.getHeaders() });\n return this.handleResponse<{ value: T[] }>(response);\n }\n\n async create(entitySetName: string, data: Record<string, unknown>): Promise<{ id: string }> {\n const url = this.buildUrl(entitySetName);\n this.log.log(`[FetchClient] POST ${url}`);\n const response = await fetch(url, {\n method: 'POST',\n headers: { ...this.getHeaders(), 'Prefer': 'return=representation' },\n body: JSON.stringify(data),\n });\n\n if (!response.ok) {\n return this.handleResponse(response);\n }\n\n const id = this.extractIdFromResponse(response, entitySetName);\n if (id) return { id };\n\n try {\n const body = await response.json();\n const primaryKey = entitySetName.slice(0, -1) + 'id';\n const recordId = body[primaryKey] || body.id;\n if (recordId) return { id: recordId };\n } catch { /* empty */ }\n\n throw new Error('Could not determine created record ID');\n }\n\n async update(entitySetName: string, id: string, data: Record<string, unknown>): Promise<void> {\n const url = this.buildUrl(entitySetName, id);\n this.log.log(`[FetchClient] PATCH ${url}`);\n const response = await fetch(url, {\n method: 'PATCH',\n headers: this.getHeaders(),\n body: JSON.stringify(data),\n });\n await this.handleResponse<void>(response);\n }\n\n async delete(entitySetName: string, id: string): Promise<void> {\n const url = this.buildUrl(entitySetName, id);\n this.log.log(`[FetchClient] DELETE ${url}`);\n const response = await fetch(url, { method: 'DELETE', headers: this.getHeaders() });\n await this.handleResponse<void>(response);\n }\n\n // Batch Operations\n\n async batchDelete(entitySetName: string, ids: string[]): Promise<BatchDeleteResult> {\n const succeeded: string[] = [];\n const failed: Array<{ id: string; error: string }> = [];\n for (const id of ids) {\n try {\n await this.delete(entitySetName, id);\n succeeded.push(id);\n } catch (err) {\n failed.push({ id, error: err instanceof Error ? err.message : 'Delete failed' });\n }\n }\n return { succeeded, failed };\n }\n\n async batchUpdate(entitySetName: string, records: BatchUpdateRecord[]): Promise<BatchUpdateResult> {\n const succeeded: string[] = [];\n const failed: Array<{ id: string; error: string }> = [];\n for (const record of records) {\n try {\n await this.update(entitySetName, record.id, record.data);\n succeeded.push(record.id);\n } catch (err) {\n failed.push({ id: record.id, error: err instanceof Error ? err.message : 'Update failed' });\n }\n }\n return { succeeded, failed };\n }\n\n async batchCreate(entitySetName: string, records: Array<Record<string, unknown>>): Promise<BatchCreateResult> {\n const succeeded: Array<{ id: string; data: Record<string, unknown> }> = [];\n const failed: Array<{ rowNumber: number; error: string }> = [];\n for (let i = 0; i < records.length; i++) {\n try {\n const result = await this.create(entitySetName, records[i]);\n succeeded.push({ id: result.id, data: records[i] });\n } catch (err) {\n failed.push({ rowNumber: i + 1, error: err instanceof Error ? err.message : 'Create failed' });\n }\n }\n return { succeeded, failed };\n }\n\n // Metadata Operations\n\n async getEntityDefinitions(filter?: string): Promise<EntityMetadata[]> {\n const selectFields = [\n 'LogicalName', 'EntitySetName', 'SchemaName', 'DisplayName', 'DisplayCollectionName',\n 'PrimaryIdAttribute', 'PrimaryNameAttribute', 'IsCustomEntity', 'IsActivity',\n 'IsValidForAdvancedFind', 'ObjectTypeCode',\n ].join(',');\n\n let options = `?$select=${selectFields}`;\n if (filter) {\n options += `&$filter=${encodeURIComponent(filter)}`;\n }\n\n const url = `${this.baseUrl}/api/data/v9.2/EntityDefinitions${options}`;\n this.log.log(`[FetchClient] GET ${url}`);\n return this.fetchAllPages<EntityMetadata>(url);\n }\n\n async getAttributeMetadata(entityLogicalName: string, filter?: string): Promise<AttributeMetadata[]> {\n const selectFields = [\n 'LogicalName', 'SchemaName', 'DisplayName', 'Description', 'AttributeType',\n 'AttributeTypeName', 'RequiredLevel', 'IsValidForRead', 'IsValidForCreate',\n 'IsValidForUpdate', 'IsPrimaryId', 'IsPrimaryName',\n ].join(',');\n\n const defaultFilter = 'IsValidForRead eq true';\n const combinedFilter = filter ? `${defaultFilter} and ${filter}` : defaultFilter;\n\n const url = `${this.baseUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/Attributes?$select=${selectFields}&$filter=${encodeURIComponent(combinedFilter)}`;\n this.log.log(`[FetchClient] GET ${url}`);\n const baseAttributes = await this.fetchAllPages<AttributeMetadata>(url);\n\n // Fetch additional metadata for picklist, multi-select, and lookup attributes\n const attributesWithExtras = await Promise.all(\n baseAttributes.map(async (attr) => {\n if (\n attr.AttributeType === 'Picklist' ||\n attr.AttributeType === 'State' ||\n attr.AttributeType === 'Status' ||\n attr.AttributeType === 'MultiSelectPicklist'\n ) {\n try {\n const castType =\n attr.AttributeType === 'State' ? 'StateAttributeMetadata' :\n attr.AttributeType === 'Status' ? 'StatusAttributeMetadata' :\n attr.AttributeType === 'MultiSelectPicklist' ? 'MultiSelectPicklistAttributeMetadata' :\n 'PicklistAttributeMetadata';\n const optionSetUrl = `${this.baseUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/Attributes(LogicalName='${attr.LogicalName}')/Microsoft.Dynamics.CRM.${castType}?$select=LogicalName&$expand=OptionSet`;\n const optionResponse = await fetch(optionSetUrl, { method: 'GET', headers: this.getHeaders() });\n if (optionResponse.ok) {\n const optionResult = await optionResponse.json();\n return { ...attr, OptionSet: optionResult.OptionSet };\n }\n } catch (err) {\n this.log.warn(`[FetchClient] Could not fetch options for ${attr.LogicalName}:`, err);\n }\n }\n if (attr.AttributeType === 'Lookup') {\n try {\n const lookupUrl = `${this.baseUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/Attributes(LogicalName='${attr.LogicalName}')/Microsoft.Dynamics.CRM.LookupAttributeMetadata?$select=LogicalName,Targets`;\n const lookupResponse = await fetch(lookupUrl, { method: 'GET', headers: this.getHeaders() });\n if (lookupResponse.ok) {\n const lookupResult = await lookupResponse.json();\n return { ...attr, Targets: lookupResult.Targets };\n }\n } catch (err) {\n this.log.warn(`[FetchClient] Could not fetch targets for ${attr.LogicalName}:`, err);\n }\n }\n return attr;\n })\n );\n\n return attributesWithExtras;\n }\n\n async getRelationshipMetadata(entityLogicalName: string): Promise<RelationshipMetadata[]> {\n const selectFields = [\n 'MetadataId', 'SchemaName', 'RelationshipType',\n 'ReferencedEntity', 'ReferencedAttribute',\n 'ReferencingEntity', 'ReferencingAttribute',\n 'IsCustomRelationship',\n 'ReferencingEntityNavigationPropertyName', 'ReferencedEntityNavigationPropertyName',\n ].join(',');\n\n // Fetch OneToMany and ManyToOne relationships in parallel\n const [oneToManyResponse, manyToOneResponse] = await Promise.all([\n fetch(\n `${this.baseUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/OneToManyRelationships?$select=${selectFields}`,\n { method: 'GET', headers: this.getHeaders() }\n ),\n fetch(\n `${this.baseUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/ManyToOneRelationships?$select=${selectFields}`,\n { method: 'GET', headers: this.getHeaders() }\n ),\n ]);\n\n const oneToMany = await this.handleResponse<{ value: OneToManyRelationshipMetadata[] }>(oneToManyResponse);\n const manyToOne = await this.handleResponse<{ value: ManyToOneRelationshipMetadata[] }>(manyToOneResponse);\n\n this.log.log(`[FetchClient] Loaded ${oneToMany.value.length} OneToMany and ${manyToOne.value.length} ManyToOne relationships for ${entityLogicalName}`);\n\n return [...oneToMany.value, ...manyToOne.value];\n }\n\n // View Operations\n\n async getViews(entityLogicalName: string): Promise<ViewMetadata[]> {\n const selectFields = 'savedqueryid,name,fetchxml,layoutxml,isdefault,returnedtypecode,description';\n const userQuerySelectFields = 'userqueryid,name,fetchxml,layoutxml,returnedtypecode,description';\n\n const [systemViewsResponse, personalViewsResponse] = await Promise.all([\n fetch(\n `${this.baseUrl}/api/data/v9.2/savedqueries?$select=${selectFields}&$filter=returnedtypecode eq '${entityLogicalName}' and querytype eq 0 and statecode eq 0`,\n { method: 'GET', headers: this.getHeaders() }\n ),\n fetch(\n `${this.baseUrl}/api/data/v9.2/userqueries?$select=${userQuerySelectFields}&$filter=returnedtypecode eq '${entityLogicalName}' and statecode eq 0`,\n { method: 'GET', headers: this.getHeaders() }\n ),\n ]);\n\n const systemViews = await this.handleResponse<{ value: Array<{\n savedqueryid: string; name: string; fetchxml: string; layoutxml?: string;\n isdefault?: boolean; returnedtypecode: string; description?: string;\n }> }>(systemViewsResponse);\n\n const personalViews = await this.handleResponse<{ value: Array<{\n userqueryid: string; name: string; fetchxml: string; layoutxml?: string;\n returnedtypecode: string; description?: string;\n }> }>(personalViewsResponse);\n\n const views: ViewMetadata[] = [\n ...systemViews.value.map(v => ({\n id: v.savedqueryid, name: v.name, fetchxml: v.fetchxml, layoutxml: v.layoutxml,\n isDefault: v.isdefault || false, isPersonal: false,\n returnedtypecode: v.returnedtypecode, description: v.description,\n })),\n ...personalViews.value.map(v => ({\n id: v.userqueryid, name: v.name, fetchxml: v.fetchxml, layoutxml: v.layoutxml,\n isDefault: false, isPersonal: true,\n returnedtypecode: v.returnedtypecode, description: v.description,\n })),\n ];\n\n views.sort((a, b) => {\n if (a.isDefault && !b.isDefault) return -1;\n if (!a.isDefault && b.isDefault) return 1;\n return a.name.localeCompare(b.name);\n });\n\n return views;\n }\n\n async updateView(isPersonal: boolean, viewId: string, data: ViewUpdateData): Promise<void> {\n const entitySet = isPersonal ? 'userqueries' : 'savedqueries';\n const url = this.buildUrl(entitySet, viewId);\n this.log.log(`[FetchClient] PATCH ${url}`);\n const response = await fetch(url, { method: 'PATCH', headers: this.getHeaders(), body: JSON.stringify(data) });\n await this.handleResponse<void>(response);\n }\n\n async createView(entityLogicalName: string, data: ViewCreateData): Promise<{ id: string }> {\n const url = this.buildUrl('userqueries');\n const payload = {\n name: data.name, returnedtypecode: entityLogicalName,\n fetchxml: data.fetchxml, layoutxml: data.layoutxml,\n querytype: 0, statecode: 0,\n ...(data.description && { description: data.description }),\n };\n this.log.log(`[FetchClient] POST ${url}`);\n const response = await fetch(url, {\n method: 'POST',\n headers: { ...this.getHeaders(), 'Prefer': 'return=representation' },\n body: JSON.stringify(payload),\n });\n if (!response.ok) return this.handleResponse(response);\n const id = this.extractIdFromResponse(response, 'userqueries');\n if (id) return { id };\n try {\n const body = await response.json();\n if (body.userqueryid || body.id) return { id: body.userqueryid || body.id };\n } catch { /* empty */ }\n throw new Error('Could not determine created view ID');\n }\n\n async deleteView(isPersonal: boolean, viewId: string): Promise<void> {\n const entitySet = isPersonal ? 'userqueries' : 'savedqueries';\n await this.delete(entitySet, viewId);\n }\n\n async publishEntity(entityLogicalName: string): Promise<void> {\n const url = `${this.baseUrl}/api/data/v9.2/PublishXml`;\n const parameterXml = `<importexportxml><entities><entity>${entityLogicalName}</entity></entities></importexportxml>`;\n this.log.log(`[FetchClient] POST ${url} - Publishing ${entityLogicalName}`);\n const response = await fetch(url, {\n method: 'POST', headers: this.getHeaders(),\n body: JSON.stringify({ ParameterXml: parameterXml }),\n });\n await this.handleResponse<void>(response);\n }\n\n // Global Option Set Operations\n\n async getGlobalOptionSets(): Promise<GlobalOptionSetMetadata[]> {\n const url = `${this.baseUrl}/api/data/v9.2/GlobalOptionSetDefinitions`;\n this.log.log(`[FetchClient] GET ${url}`);\n const all = await this.fetchAllPages<GlobalOptionSetMetadata>(url);\n\n // Filter to only Picklist type global option sets\n return all.filter(os => os.OptionSetType === 'Picklist' && os.IsGlobal);\n }\n}\n","/**\n * @dynamics-ui-kit/api-client\n * Production client using Xrm.WebApi inside Dynamics 365.\n */\n\nimport type { IDataverseClient } from './interfaces';\nimport type {\n BatchDeleteResult,\n BatchUpdateRecord,\n BatchUpdateResult,\n BatchCreateResult,\n ViewUpdateData,\n ViewCreateData,\n EntityMetadata,\n AttributeMetadata,\n ViewMetadata,\n Logger,\n RelationshipMetadata,\n OneToManyRelationshipMetadata,\n ManyToOneRelationshipMetadata,\n GlobalOptionSetMetadata,\n} from './types';\n\n/**\n * Dataverse client using Xrm.WebApi for production Dynamics 365 environment.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype XrmGlobal = any;\n\nexport class XrmClient implements IDataverseClient {\n private xrm: XrmGlobal;\n private log: Logger;\n\n constructor(xrm: XrmGlobal, logger?: Logger) {\n this.xrm = xrm;\n this.log = logger ?? console;\n }\n\n private getClientUrl(): string {\n return this.xrm.Utility.getGlobalContext().getClientUrl();\n }\n\n // CRUD Operations\n\n async retrieve<T = Record<string, unknown>>(entitySetName: string, id: string, options?: string): Promise<T> {\n const cleanId = id.replace(/[{}]/g, '');\n const result = await this.xrm.WebApi.retrieveRecord(entitySetName, cleanId, options);\n return result as T;\n }\n\n async retrieveMultiple<T = Record<string, unknown>>(entitySetName: string, options?: string): Promise<{ value: T[] }> {\n const result = await this.xrm.WebApi.retrieveMultipleRecords(entitySetName, options);\n return { value: result.entities as T[] };\n }\n\n async create(entitySetName: string, data: Record<string, unknown>): Promise<{ id: string }> {\n const result = await this.xrm.WebApi.createRecord(entitySetName, data);\n return { id: result.id };\n }\n\n async update(entitySetName: string, id: string, data: Record<string, unknown>): Promise<void> {\n await this.xrm.WebApi.updateRecord(entitySetName, id.replace(/[{}]/g, ''), data);\n }\n\n async delete(entitySetName: string, id: string): Promise<void> {\n await this.xrm.WebApi.deleteRecord(entitySetName, id.replace(/[{}]/g, ''));\n }\n\n // Batch Operations\n\n async batchDelete(entitySetName: string, ids: string[]): Promise<BatchDeleteResult> {\n const succeeded: string[] = [];\n const failed: Array<{ id: string; error: string }> = [];\n for (const id of ids) {\n try {\n await this.delete(entitySetName, id);\n succeeded.push(id);\n } catch (err) {\n failed.push({ id, error: err instanceof Error ? err.message : 'Delete failed' });\n }\n }\n return { succeeded, failed };\n }\n\n async batchUpdate(entitySetName: string, records: BatchUpdateRecord[]): Promise<BatchUpdateResult> {\n const succeeded: string[] = [];\n const failed: Array<{ id: string; error: string }> = [];\n for (const record of records) {\n try {\n await this.update(entitySetName, record.id, record.data);\n succeeded.push(record.id);\n } catch (err) {\n failed.push({ id: record.id, error: err instanceof Error ? err.message : 'Update failed' });\n }\n }\n return { succeeded, failed };\n }\n\n async batchCreate(entitySetName: string, records: Array<Record<string, unknown>>): Promise<BatchCreateResult> {\n const succeeded: Array<{ id: string; data: Record<string, unknown> }> = [];\n const failed: Array<{ rowNumber: number; error: string }> = [];\n for (let i = 0; i < records.length; i++) {\n try {\n const result = await this.create(entitySetName, records[i]);\n succeeded.push({ id: result.id, data: records[i] });\n } catch (err) {\n failed.push({ rowNumber: i + 1, error: err instanceof Error ? err.message : 'Create failed' });\n }\n }\n return { succeeded, failed };\n }\n\n // Metadata Operations\n\n async getEntityDefinitions(filter?: string): Promise<EntityMetadata[]> {\n const selectFields = [\n 'LogicalName', 'EntitySetName', 'SchemaName', 'DisplayName', 'DisplayCollectionName',\n 'PrimaryIdAttribute', 'PrimaryNameAttribute', 'IsCustomEntity', 'IsActivity',\n 'IsValidForAdvancedFind', 'ObjectTypeCode',\n ].join(',');\n\n let options = `?$select=${selectFields}`;\n if (filter) options += `&$filter=${filter}`;\n\n const result = await this.xrm.WebApi.retrieveMultipleRecords('EntityDefinitions', options);\n return result.entities as EntityMetadata[];\n }\n\n async getAttributeMetadata(entityLogicalName: string, filter?: string): Promise<AttributeMetadata[]> {\n const selectFields = [\n 'LogicalName', 'SchemaName', 'DisplayName', 'Description', 'AttributeType',\n 'AttributeTypeName', 'RequiredLevel', 'IsValidForRead', 'IsValidForCreate',\n 'IsValidForUpdate', 'IsPrimaryId', 'IsPrimaryName',\n ].join(',');\n\n const defaultFilter = 'IsValidForRead eq true';\n const combinedFilter = filter ? `${defaultFilter} and ${filter}` : defaultFilter;\n const clientUrl = this.getClientUrl();\n const url = `${clientUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/Attributes?$select=${selectFields}&$filter=${combinedFilter}`;\n\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' },\n });\n\n if (!response.ok) throw new Error(`Failed to fetch attribute metadata: ${response.statusText}`);\n const result = await response.json();\n const attributes = result.value as AttributeMetadata[];\n\n const attributesWithExtras = await Promise.all(\n attributes.map(async (attr) => {\n if (attr.AttributeType === 'Picklist' || attr.AttributeType === 'State' || attr.AttributeType === 'Status') {\n try {\n const castType = attr.AttributeType === 'State' ? 'StateAttributeMetadata' :\n attr.AttributeType === 'Status' ? 'StatusAttributeMetadata' : 'PicklistAttributeMetadata';\n const optionSetUrl = `${clientUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/Attributes(LogicalName='${attr.LogicalName}')/Microsoft.Dynamics.CRM.${castType}?$select=LogicalName&$expand=OptionSet`;\n const optionResponse = await fetch(optionSetUrl, {\n method: 'GET',\n headers: { 'Accept': 'application/json', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' },\n });\n if (optionResponse.ok) {\n const optionResult = await optionResponse.json();\n return { ...attr, OptionSet: optionResult.OptionSet };\n }\n } catch (err) {\n this.log.warn(`Could not fetch options for ${attr.LogicalName}:`, err);\n }\n }\n if (attr.AttributeType === 'Lookup') {\n try {\n const lookupUrl = `${clientUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/Attributes(LogicalName='${attr.LogicalName}')/Microsoft.Dynamics.CRM.LookupAttributeMetadata?$select=LogicalName,Targets`;\n const lookupResponse = await fetch(lookupUrl, {\n method: 'GET',\n headers: { 'Accept': 'application/json', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' },\n });\n if (lookupResponse.ok) {\n const lookupResult = await lookupResponse.json();\n return { ...attr, Targets: lookupResult.Targets };\n }\n } catch (err) {\n this.log.warn(`Could not fetch targets for ${attr.LogicalName}:`, err);\n }\n }\n return attr;\n })\n );\n\n return attributesWithExtras;\n }\n\n async getRelationshipMetadata(entityLogicalName: string): Promise<RelationshipMetadata[]> {\n const clientUrl = this.getClientUrl();\n const selectFields = [\n 'MetadataId', 'SchemaName', 'RelationshipType',\n 'ReferencedEntity', 'ReferencedAttribute',\n 'ReferencingEntity', 'ReferencingAttribute',\n 'IsCustomRelationship',\n 'ReferencingEntityNavigationPropertyName', 'ReferencedEntityNavigationPropertyName',\n ].join(',');\n\n // Fetch OneToMany and ManyToOne relationships in parallel\n const [oneToManyResponse, manyToOneResponse] = await Promise.all([\n fetch(\n `${clientUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/OneToManyRelationships?$select=${selectFields}`,\n { method: 'GET', headers: { 'Accept': 'application/json', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' } }\n ),\n fetch(\n `${clientUrl}/api/data/v9.2/EntityDefinitions(LogicalName='${entityLogicalName}')/ManyToOneRelationships?$select=${selectFields}`,\n { method: 'GET', headers: { 'Accept': 'application/json', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' } }\n ),\n ]);\n\n if (!oneToManyResponse.ok) throw new Error(`Failed to fetch OneToMany relationships: ${oneToManyResponse.statusText}`);\n if (!manyToOneResponse.ok) throw new Error(`Failed to fetch ManyToOne relationships: ${manyToOneResponse.statusText}`);\n\n const oneToMany = await oneToManyResponse.json() as { value: OneToManyRelationshipMetadata[] };\n const manyToOne = await manyToOneResponse.json() as { value: ManyToOneRelationshipMetadata[] };\n\n this.log.log(`[XrmClient] Loaded ${oneToMany.value.length} OneToMany and ${manyToOne.value.length} ManyToOne relationships for ${entityLogicalName}`);\n\n return [...oneToMany.value, ...manyToOne.value];\n }\n\n // View Operations\n\n async getViews(entityLogicalName: string): Promise<ViewMetadata[]> {\n const clientUrl = this.getClientUrl();\n const selectFields = 'savedqueryid,name,fetchxml,layoutxml,isdefault,returnedtypecode,description';\n const userQuerySelectFields = 'userqueryid,name,fetchxml,layoutxml,returnedtypecode,description';\n\n const [systemViewsResponse, personalViewsResponse] = await Promise.all([\n fetch(\n `${clientUrl}/api/data/v9.2/savedqueries?$select=${selectFields}&$filter=returnedtypecode eq '${entityLogicalName}' and querytype eq 0 and statecode eq 0`,\n { method: 'GET', headers: { 'Accept': 'application/json', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' } }\n ),\n fetch(\n `${clientUrl}/api/data/v9.2/userqueries?$select=${userQuerySelectFields}&$filter=returnedtypecode eq '${entityLogicalName}' and statecode eq 0`,\n { method: 'GET', headers: { 'Accept': 'application/json', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' } }\n ),\n ]);\n\n if (!systemViewsResponse.ok) throw new Error(`Failed to fetch system views: ${systemViewsResponse.statusText}`);\n if (!personalViewsResponse.ok) throw new Error(`Failed to fetch personal views: ${personalViewsResponse.statusText}`);\n\n const systemViews = await systemViewsResponse.json() as { value: Array<{\n savedqueryid: string; name: string; fetchxml: string; layoutxml?: string;\n isdefault?: boolean; returnedtypecode: string; description?: string;\n }> };\n\n const personalViews = await personalViewsResponse.json() as { value: Array<{\n userqueryid: string; name: string; fetchxml: string; layoutxml?: string;\n returnedtypecode: string; description?: string;\n }> };\n\n const views: ViewMetadata[] = [\n ...systemViews.value.map(v => ({\n id: v.savedqueryid, name: v.name, fetchxml: v.fetchxml, layoutxml: v.layoutxml,\n isDefault: v.isdefault || false, isPersonal: false,\n returnedtypecode: v.returnedtypecode, description: v.description,\n })),\n ...personalViews.value.map(v => ({\n id: v.userqueryid, name: v.name, fetchxml: v.fetchxml, layoutxml: v.layoutxml,\n isDefault: false, isPersonal: true,\n returnedtypecode: v.returnedtypecode, description: v.description,\n })),\n ];\n\n views.sort((a, b) => {\n if (a.isDefault && !b.isDefault) return -1;\n if (!a.isDefault && b.isDefault) return 1;\n return a.name.localeCompare(b.name);\n });\n\n return views;\n }\n\n async updateView(isPersonal: boolean, viewId: string, data: ViewUpdateData): Promise<void> {\n const entityName = isPersonal ? 'userquery' : 'savedquery';\n await this.xrm.WebApi.updateRecord(entityName, viewId.replace(/[{}]/g, ''), data);\n }\n\n async createView(entityLogicalName: string, data: ViewCreateData): Promise<{ id: string }> {\n const payload = {\n name: data.name, returnedtypecode: entityLogicalName,\n fetchxml: data.fetchxml, layoutxml: data.layoutxml,\n querytype: 0, statecode: 0,\n ...(data.description && { description: data.description }),\n };\n const result = await this.xrm.WebApi.createRecord('userquery', payload);\n return { id: result.id };\n }\n\n async deleteView(isPersonal: boolean, viewId: string): Promise<void> {\n const entityName = isPersonal ? 'userquery' : 'savedquery';\n await this.xrm.WebApi.deleteRecord(entityName, viewId.replace(/[{}]/g, ''));\n }\n\n async publishEntity(entityLogicalName: string): Promise<void> {\n const clientUrl = this.getClientUrl();\n const url = `${clientUrl}/api/data/v9.2/PublishXml`;\n const parameterXml = `<importexportxml><entities><entity>${entityLogicalName}</entity></entities></importexportxml>`;\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Accept': 'application/json', 'Content-Type': 'application/json; charset=utf-8', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' },\n body: JSON.stringify({ ParameterXml: parameterXml }),\n });\n if (!response.ok) throw new Error(`Failed to publish entity: ${response.statusText}`);\n }\n\n // Global Option Set Operations\n\n async getGlobalOptionSets(): Promise<GlobalOptionSetMetadata[]> {\n const clientUrl = this.getClientUrl();\n const url = `${clientUrl}/api/data/v9.2/GlobalOptionSetDefinitions`;\n const response = await fetch(url, {\n method: 'GET',\n headers: { 'Accept': 'application/json', 'OData-MaxVersion': '4.0', 'OData-Version': '4.0' },\n });\n if (!response.ok) throw new Error(`Failed to fetch global option sets: ${response.statusText}`);\n const result = await response.json() as { value: GlobalOptionSetMetadata[] };\n return result.value.filter(os => os.OptionSetType === 'Picklist' && os.IsGlobal);\n }\n}\n","/**\n * @dynamics-ui-kit/api-client\n * Mock client for offline development and testing.\n */\n\nimport type { IDataverseClient } from './interfaces';\nimport type {\n BatchDeleteResult,\n BatchUpdateRecord,\n BatchUpdateResult,\n BatchCreateResult,\n ViewUpdateData,\n ViewCreateData,\n EntityMetadata,\n AttributeMetadata,\n ViewMetadata,\n Logger,\n RelationshipMetadata,\n GlobalOptionSetMetadata,\n} from './types';\n\nfunction generateId(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport interface MockDataConfig {\n /** Initial records keyed by entity set name */\n records?: Record<string, Record<string, unknown>[]>;\n /** Entity definitions */\n entityDefinitions?: EntityMetadata[];\n /** Attribute metadata keyed by entity logical name */\n attributeMetadata?: Record<string, AttributeMetadata[]>;\n /** Views keyed by entity logical name */\n views?: Record<string, ViewMetadata[]>;\n /** Relationship metadata keyed by entity logical name */\n relationshipMetadata?: Record<string, RelationshipMetadata[]>;\n /** Global option sets */\n globalOptionSets?: GlobalOptionSetMetadata[];\n /** Simulated network delay in ms */\n delayMs?: number;\n}\n\n/**\n * Mock Dataverse client for offline development and testing.\n * Accepts configurable mock data.\n */\nexport class MockClient implements IDataverseClient {\n private dataStore: Record<string, Record<string, unknown>[]>;\n private entityDefs: EntityMetadata[];\n private attrMeta: Record<string, AttributeMetadata[]>;\n private viewStore: Record<string, ViewMetadata[]>;\n private relMeta: Record<string, RelationshipMetadata[]>;\n private globalOptionSets: GlobalOptionSetMetadata[];\n private delayMs: number;\n private log: Logger;\n\n constructor(config?: MockDataConfig, logger?: Logger) {\n this.dataStore = config?.records ?? {};\n this.entityDefs = config?.entityDefinitions ?? [];\n this.attrMeta = config?.attributeMetadata ?? {};\n this.viewStore = config?.views ?? {};\n this.relMeta = config?.relationshipMetadata ?? {};\n this.globalOptionSets = config?.globalOptionSets ?? [];\n this.delayMs = config?.delayMs ?? 0;\n this.log = logger ?? console;\n }\n\n private async delay(): Promise<void> {\n if (this.delayMs > 0) {\n return new Promise(resolve => setTimeout(resolve, this.delayMs));\n }\n }\n\n // CRUD Operations\n\n async retrieve<T = Record<string, unknown>>(entitySetName: string, id: string): Promise<T> {\n await this.delay();\n const records = this.dataStore[entitySetName] ?? [];\n const pkField = entitySetName.slice(0, -1) + 'id';\n const record = records.find(r => r[pkField] === id || r.id === id);\n if (!record) throw new Error(`Record ${id} not found in ${entitySetName}`);\n return record as T;\n }\n\n async retrieveMultiple<T = Record<string, unknown>>(entitySetName: string): Promise<{ value: T[] }> {\n await this.delay();\n return { value: (this.dataStore[entitySetName] ?? []) as T[] };\n }\n\n async create(entitySetName: string, data: Record<string, unknown>): Promise<{ id: string }> {\n await this.delay();\n const id = generateId();\n const pkField = entitySetName.slice(0, -1) + 'id';\n const record = { ...data, [pkField]: id };\n if (!this.dataStore[entitySetName]) this.dataStore[entitySetName] = [];\n this.dataStore[entitySetName].push(record);\n return { id };\n }\n\n async update(entitySetName: string, id: string, data: Record<string, unknown>): Promise<void> {\n await this.delay();\n const records = this.dataStore[entitySetName] ?? [];\n const pkField = entitySetName.slice(0, -1) + 'id';\n const index = records.findIndex(r => r[pkField] === id || r.id === id);\n if (index === -1) throw new Error(`Record ${id} not found in ${entitySetName}`);\n this.dataStore[entitySetName][index] = { ...records[index], ...data };\n }\n\n async delete(entitySetName: string, id: string): Promise<void> {\n await this.delay();\n const records = this.dataStore[entitySetName] ?? [];\n const pkField = entitySetName.slice(0, -1) + 'id';\n const index = records.findIndex(r => r[pkField] === id || r.id === id);\n if (index === -1) throw new Error(`Record ${id} not found in ${entitySetName}`);\n this.dataStore[entitySetName].splice(index, 1);\n }\n\n // Batch Operations\n\n async batchDelete(entitySetName: string, ids: string[]): Promise<BatchDeleteResult> {\n const succeeded: string[] = [];\n const failed: Array<{ id: string; error: string }> = [];\n for (const id of ids) {\n try { await this.delete(entitySetName, id); succeeded.push(id); }\n catch (err) { failed.push({ id, error: err instanceof Error ? err.message : 'Delete failed' }); }\n }\n return { succeeded, failed };\n }\n\n async batchUpdate(entitySetName: string, records: BatchUpdateRecord[]): Promise<BatchUpdateResult> {\n const succeeded: string[] = [];\n const failed: Array<{ id: string; error: string }> = [];\n for (const record of records) {\n try { await this.update(entitySetName, record.id, record.data); succeeded.push(record.id); }\n catch (err) { failed.push({ id: record.id, error: err instanceof Error ? err.message : 'Update failed' }); }\n }\n return { succeeded, failed };\n }\n\n async batchCreate(entitySetName: string, records: Array<Record<string, unknown>>): Promise<BatchCreateResult> {\n const succeeded: Array<{ id: string; data: Record<string, unknown> }> = [];\n const failed: Array<{ rowNumber: number; error: string }> = [];\n for (let i = 0; i < records.length; i++) {\n try {\n const result = await this.create(entitySetName, records[i]);\n succeeded.push({ id: result.id, data: records[i] });\n } catch (err) {\n failed.push({ rowNumber: i + 1, error: err instanceof Error ? err.message : 'Create failed' });\n }\n }\n return { succeeded, failed };\n }\n\n // Metadata Operations\n\n async getEntityDefinitions(_filter?: string): Promise<EntityMetadata[]> {\n await this.delay();\n return this.entityDefs;\n }\n\n async getAttributeMetadata(entityLogicalName: string): Promise<AttributeMetadata[]> {\n await this.delay();\n return this.attrMeta[entityLogicalName] ?? [];\n }\n\n async getRelationshipMetadata(entityLogicalName: string): Promise<RelationshipMetadata[]> {\n await this.delay();\n return this.relMeta[entityLogicalName] ?? [];\n }\n\n // View Operations\n\n async getViews(entityLogicalName: string): Promise<ViewMetadata[]> {\n await this.delay();\n return this.viewStore[entityLogicalName] ?? [];\n }\n\n async updateView(_isPersonal: boolean, viewId: string, data: ViewUpdateData): Promise<void> {\n await this.delay();\n for (const entity of Object.keys(this.viewStore)) {\n const views = this.viewStore[entity];\n const idx = views.findIndex(v => v.id === viewId);\n if (idx !== -1) {\n this.viewStore[entity][idx] = { ...views[idx], ...data };\n return;\n }\n }\n throw new Error(`View ${viewId} not found`);\n }\n\n async createView(entityLogicalName: string, data: ViewCreateData): Promise<{ id: string }> {\n await this.delay();\n const id = generateId();\n const view: ViewMetadata = {\n id, name: data.name, fetchxml: data.fetchxml, layoutxml: data.layoutxml,\n isDefault: false, isPersonal: true, returnedtypecode: entityLogicalName,\n description: data.description,\n };\n if (!this.viewStore[entityLogicalName]) this.viewStore[entityLogicalName] = [];\n this.viewStore[entityLogicalName].push(view);\n return { id };\n }\n\n async deleteView(_isPersonal: boolean, viewId: string): Promise<void> {\n await this.delay();\n for (const entity of Object.keys(this.viewStore)) {\n const views = this.viewStore[entity];\n const idx = views.findIndex(v => v.id === viewId);\n if (idx !== -1) {\n this.viewStore[entity].splice(idx, 1);\n return;\n }\n }\n throw new Error(`View ${viewId} not found`);\n }\n\n async publishEntity(): Promise<void> {\n await this.delay();\n this.log.log('[MockClient] publishEntity called (no-op in mock mode)');\n }\n\n // Global Option Set Operations\n\n async getGlobalOptionSets(): Promise<GlobalOptionSetMetadata[]> {\n await this.delay();\n return this.globalOptionSets;\n }\n}\n","/**\n * @dynamics-ui-kit/api-client\n * Factory for auto-detecting environment and creating the appropriate client.\n */\n\nimport type { IDataverseClient } from './interfaces';\nimport type { ClientOptions, EnvironmentInfo } from './types';\nimport { FetchClient } from './fetch-client';\nimport { XrmClient } from './xrm-client';\nimport { MockClient } from './mock-client';\nimport type { MockDataConfig } from './mock-client';\n\n/**\n * Create a Dataverse client based on the current environment.\n *\n * Detection priority:\n * 1. Explicit options (baseUrl + token → FetchClient, xrm → XrmClient)\n * 2. Window globals (__DYNAMICS_URL + __DYNAMICS_TOKEN → FetchClient)\n * 3. Xrm global present → XrmClient\n * 4. Fallback → MockClient\n */\nexport function createClient(options?: ClientOptions & { mockData?: MockDataConfig }): IDataverseClient {\n const logger = options?.logger;\n\n // Explicit FetchClient\n if (options?.baseUrl && options?.token) {\n return new FetchClient(options.baseUrl, options.token, logger);\n }\n\n // Explicit XrmClient\n if (options?.xrm) {\n return new XrmClient(options.xrm, logger);\n }\n\n // Auto-detect: check window globals\n if (typeof window !== 'undefined') {\n const win = window as { __DYNAMICS_URL?: string; __DYNAMICS_TOKEN?: string };\n if (win.__DYNAMICS_URL && win.__DYNAMICS_TOKEN) {\n return new FetchClient(win.__DYNAMICS_URL, win.__DYNAMICS_TOKEN, logger);\n }\n }\n\n // Auto-detect: check for Xrm global\n if (typeof globalThis !== 'undefined' && typeof (globalThis as Record<string, unknown>).Xrm !== 'undefined') {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return new XrmClient((globalThis as Record<string, unknown>).Xrm as any, logger);\n }\n\n // Fallback to mock\n return new MockClient(options?.mockData, logger);\n}\n\n/**\n * Get information about the current environment.\n */\nexport function getEnvironmentInfo(): EnvironmentInfo {\n const hostname = typeof window !== 'undefined' ? window.location?.hostname ?? 'unknown' : 'node';\n const hasXrm = typeof globalThis !== 'undefined' && typeof (globalThis as Record<string, unknown>).Xrm !== 'undefined';\n const win = typeof window !== 'undefined' ? window as { __DYNAMICS_URL?: string; __DYNAMICS_TOKEN?: string } : {};\n const hasToken = !!(win.__DYNAMICS_URL && win.__DYNAMICS_TOKEN);\n\n let type: EnvironmentInfo['type'] = 'mock';\n if (hasToken) type = 'fetch';\n else if (hasXrm) type = 'xrm';\n\n return { type, hostname, baseUrl: win.__DYNAMICS_URL, hasToken, hasXrm };\n}\n","/**\n * @khester/dataverse-codegen\n *\n * Library entry. The CLI (`dvgen`) is the primary surface, but the metadata\n * core is exported for programmatic use and testing.\n */\n\nexport { toEntityMetadataInput, toAttributeMetadataInput } from './metadata/adapter';\nexport { fetchEntityMetadata, type FetchEntityMetadataOptions } from './metadata/fetch';\nexport { metadataGet, metadataGetAll, type MetadataHttp } from './metadata/http';\nexport {\n augmentScalarDetail,\n mergeScalarDetail,\n type MetadataGetter,\n} from './metadata/typedCast';\nexport { safeWrite, type SafeWriteOptions, type WriteResult } from './io/write';\nexport { resolveConnection, type ConnectionOptions, type ResolvedConnection } from './connection';\nexport { deriveParentLookupLinks, type RetrieveLink } from './metadata/links';\nexport {\n parseDesignFile,\n collectEntities,\n FORM_DESIGN_KIND,\n type FormDesignFile,\n type EntityRef,\n type CollectResult,\n} from './design/parse';\n","/**\n * Adapter: raw Dataverse metadata (from @dynamics-ui-kit/api-client) →\n * the `EntityMetadataInput` shape consumed by @dynamics-ui-kit/entity-gen.\n *\n * The two shapes are intentionally field-compatible (both PascalCase\n * Dataverse-style), so this is largely a structural passthrough. It exists\n * as an explicit seam so the codegen tools never depend on the api-client's\n * concrete types and so we can validate/normalize in one place.\n */\n\nimport type { EntityMetadata, AttributeMetadata } from '@dynamics-ui-kit/api-client';\nimport type { EntityMetadataInput, AttributeMetadataInput } from '@dynamics-ui-kit/entity-gen';\n\nexport function toAttributeMetadataInput(attr: AttributeMetadata): AttributeMetadataInput {\n return {\n LogicalName: attr.LogicalName,\n SchemaName: attr.SchemaName,\n DisplayName: attr.DisplayName,\n AttributeType: attr.AttributeType,\n RequiredLevel: attr.RequiredLevel,\n IsValidForRead: attr.IsValidForRead,\n IsValidForCreate: attr.IsValidForCreate,\n IsValidForUpdate: attr.IsValidForUpdate,\n IsPrimaryId: attr.IsPrimaryId,\n IsPrimaryName: attr.IsPrimaryName,\n MaxLength: attr.MaxLength,\n Precision: attr.Precision,\n MinValue: attr.MinValue,\n MaxValue: attr.MaxValue,\n Format: attr.Format,\n FormatName: attr.FormatName,\n OptionSet: attr.OptionSet,\n GlobalOptionSet: attr.GlobalOptionSet,\n DateTimeBehavior: attr.DateTimeBehavior,\n Targets: attr.Targets,\n };\n}\n\nexport function toEntityMetadataInput(\n entity: EntityMetadata,\n attributes: AttributeMetadata[],\n): EntityMetadataInput {\n if (!entity?.LogicalName) {\n throw new Error('toEntityMetadataInput: entity.LogicalName is required.');\n }\n if (!entity.EntitySetName) {\n throw new Error(`toEntityMetadataInput: ${entity.LogicalName} is missing EntitySetName.`);\n }\n if (!entity.PrimaryIdAttribute) {\n throw new Error(`toEntityMetadataInput: ${entity.LogicalName} is missing PrimaryIdAttribute.`);\n }\n // Some entities (e.g. many-to-many intersects) legitimately have no primary\n // name. entity-gen requires the field, so fall back to the primary id —\n // the generated PrimaryName constant then mirrors PrimaryKey, which is\n // harmless and keeps the output compiling.\n const primaryName = entity.PrimaryNameAttribute || entity.PrimaryIdAttribute;\n\n return {\n LogicalName: entity.LogicalName,\n EntitySetName: entity.EntitySetName,\n SchemaName: entity.SchemaName,\n DisplayName: entity.DisplayName,\n DisplayCollectionName: entity.DisplayCollectionName,\n PrimaryIdAttribute: entity.PrimaryIdAttribute,\n PrimaryNameAttribute: primaryName,\n IsCustomEntity: entity.IsCustomEntity,\n Attributes: attributes.map(toAttributeMetadataInput),\n };\n}\n","/**\n * fetchEntityMetadata — compose a complete `EntityMetadataInput` for one\n * entity from a live org, fixing the gap entity-gen's own CLI has (it calls\n * a non-existent `client.getEntityMetadata`).\n *\n * = getEntityDefinitions(LogicalName eq '<e>')[0] + getAttributeMetadata('<e>')\n * → toEntityMetadataInput()\n * → (optional) typed-cast scalar augmentation (MaxLength/Precision/...)\n */\n\nimport type { IDataverseClient } from '@dynamics-ui-kit/api-client';\nimport type { EntityMetadataInput } from '@dynamics-ui-kit/entity-gen';\nimport { toEntityMetadataInput } from './adapter';\nimport { augmentScalarDetail } from './typedCast';\nimport type { MetadataHttp } from './http';\nimport { assertValidEntityName } from '../validate';\n\nexport interface FetchEntityMetadataOptions {\n /**\n * Optional extra OData filter ANDed onto the attribute query. The api-client\n * always restricts to readable attributes (`IsValidForRead eq true`), so\n * generated constants/models cover the readable attribute surface.\n */\n attributeFilter?: string;\n /**\n * When provided, fetch type-specific scalar detail (MaxLength, Precision,\n * Min/MaxValue, Format, DateTimeBehavior) via typed-cast queries and merge\n * it in. Best-effort — failures are logged and skipped.\n */\n augment?: MetadataHttp;\n}\n\nexport async function fetchEntityMetadata(\n client: IDataverseClient,\n logicalName: string,\n options: FetchEntityMetadataOptions = {},\n): Promise<EntityMetadataInput> {\n assertValidEntityName(logicalName);\n const defs = await client.getEntityDefinitions(`LogicalName eq '${logicalName}'`);\n const entity = defs[0];\n if (!entity) {\n throw new Error(\n `Entity '${logicalName}' was not found in this org (no EntityDefinitions match). ` +\n 'Check the logical name (singular, lowercase) and that your token targets the right org.',\n );\n }\n const attributes = await client.getAttributeMetadata(logicalName, options.attributeFilter);\n const input = toEntityMetadataInput(entity, attributes);\n\n if (options.augment) {\n try {\n await augmentScalarDetail(options.augment, logicalName, input.Attributes);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(\n `[dvgen] scalar detail augmentation skipped for ${logicalName}: ${e instanceof Error ? e.message : String(e)}`,\n );\n }\n }\n\n return input;\n}\n","/**\n * Typed-cast attribute augmentation.\n *\n * The api-client's `getAttributeMetadata` returns the base attribute shape;\n * scalar detail (MaxLength, Precision, Min/MaxValue, Format, DateTimeBehavior)\n * lives on type-specific subtypes and is only returned via a typed cast on the\n * EntityDefinitions Attributes navigation, e.g.:\n *\n * EntityDefinitions(LogicalName='x')/Attributes/Microsoft.Dynamics.CRM.StringAttributeMetadata\n * ?$select=LogicalName,MaxLength,Format\n *\n * This fills those fields in so generated constants carry full JSDoc detail.\n * Best-effort: a failed cast query is skipped (codegen still succeeds, just\n * with thinner comments for that type).\n */\n\nimport type { AttributeMetadataInput } from '@dynamics-ui-kit/entity-gen';\nimport { metadataGetAll, type MetadataHttp } from './http';\n\ninterface ScalarDetail {\n LogicalName: string;\n MaxLength?: number;\n MinValue?: number;\n MaxValue?: number;\n Precision?: number;\n Format?: string;\n DateTimeBehavior?: { Value: string };\n}\n\ninterface CastSpec {\n /** Dataverse AttributeType values this cast covers. */\n types: string[];\n /** The *AttributeMetadata subtype name. */\n cast: string;\n /** Fields to $select (always includes LogicalName). */\n select: string[];\n}\n\nconst SPECS: CastSpec[] = [\n { types: ['String'], cast: 'StringAttributeMetadata', select: ['MaxLength', 'Format'] },\n { types: ['Memo'], cast: 'MemoAttributeMetadata', select: ['MaxLength', 'Format'] },\n { types: ['Integer'], cast: 'IntegerAttributeMetadata', select: ['MinValue', 'MaxValue', 'Format'] },\n { types: ['BigInt'], cast: 'BigIntAttributeMetadata', select: ['MinValue', 'MaxValue'] },\n { types: ['Decimal'], cast: 'DecimalAttributeMetadata', select: ['MinValue', 'MaxValue', 'Precision'] },\n { types: ['Double'], cast: 'DoubleAttributeMetadata', select: ['MinValue', 'MaxValue', 'Precision'] },\n { types: ['Money'], cast: 'MoneyAttributeMetadata', select: ['MinValue', 'MaxValue', 'Precision'] },\n { types: ['DateTime'], cast: 'DateTimeAttributeMetadata', select: ['Format', 'DateTimeBehavior'] },\n];\n\nexport type MetadataGetter = (http: MetadataHttp, path: string) => Promise<{ value: ScalarDetail[] }>;\n\n/**\n * Merge fetched scalar detail into the attribute list (in place). Only fills\n * fields that are currently unset, so an explicit value from the base fetch\n * always wins. Pure — exported for testing.\n */\nexport function mergeScalarDetail(\n attrs: AttributeMetadataInput[],\n details: ScalarDetail[],\n): void {\n const byName = new Map(details.map((d) => [d.LogicalName, d]));\n for (const a of attrs) {\n const d = byName.get(a.LogicalName);\n if (!d) continue;\n if (d.MaxLength != null && a.MaxLength == null) a.MaxLength = d.MaxLength;\n if (d.MinValue != null && a.MinValue == null) a.MinValue = d.MinValue;\n if (d.MaxValue != null && a.MaxValue == null) a.MaxValue = d.MaxValue;\n if (d.Precision != null && a.Precision == null) a.Precision = d.Precision;\n if (d.Format != null && a.Format == null) a.Format = d.Format;\n if (d.DateTimeBehavior != null && a.DateTimeBehavior == null) a.DateTimeBehavior = d.DateTimeBehavior;\n }\n}\n\nexport async function augmentScalarDetail(\n http: MetadataHttp,\n logicalName: string,\n attrs: AttributeMetadataInput[],\n get: MetadataGetter = async (h, p) => ({ value: await metadataGetAll<ScalarDetail>(h, p) }),\n): Promise<void> {\n const presentTypes = new Set(attrs.map((a) => a.AttributeType));\n for (const spec of SPECS) {\n if (!spec.types.some((t) => presentTypes.has(t))) continue;\n const select = ['LogicalName', ...spec.select].join(',');\n const path =\n `EntityDefinitions(LogicalName='${logicalName}')/Attributes/` +\n `Microsoft.Dynamics.CRM.${spec.cast}?$select=${select}`;\n try {\n const resp = await get(http, path);\n mergeScalarDetail(attrs, resp.value ?? []);\n } catch {\n // Best-effort: skip this type's detail, keep generating.\n }\n }\n}\n","/**\n * Minimal Dataverse metadata HTTP helper for the codegen tools.\n *\n * Used for typed-cast attribute queries the api-client doesn't expose\n * (scalar detail like MaxLength/Precision). Honors 429/503 throttling with\n * `Retry-After` backoff, and follows `@odata.nextLink` (metadataGetAll) so\n * wide results aren't truncated. Uses the global `fetch` (Node 18+).\n */\n\nexport interface MetadataHttp {\n /** Org base URL, e.g. https://org.crm.dynamics.com */\n baseUrl: string;\n token: string;\n /** Web API version. Default 9.2. */\n apiVersion?: string;\n}\n\n/** A single OData collection page. */\ninterface ODataPage<T> {\n value?: T[];\n '@odata.nextLink'?: string;\n}\n\nconst sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\n\nfunction buildUrl(http: MetadataHttp, relativePath: string): string {\n const version = http.apiVersion ?? '9.2';\n const base = http.baseUrl.replace(/\\/+$/, '');\n return `${base}/api/data/v${version}/${relativePath}`;\n}\n\n/** GET an absolute URL with 429/503 Retry-After backoff. */\nasync function getWithRetry<T>(http: MetadataHttp, url: string, maxRetries: number): Promise<T> {\n for (let attempt = 0; ; attempt += 1) {\n const res = await fetch(url, {\n headers: {\n Authorization: `Bearer ${http.token}`,\n Accept: 'application/json',\n 'OData-MaxVersion': '4.0',\n 'OData-Version': '4.0',\n },\n });\n\n if (res.status === 429 || res.status === 503) {\n if (attempt >= maxRetries) {\n throw new Error(`Dataverse throttled (${res.status}) after ${attempt} retries: ${url}`);\n }\n const headerWait = Number(res.headers.get('Retry-After'));\n const waitSec = Number.isFinite(headerWait) && headerWait > 0 ? headerWait : Math.min(2 ** attempt, 30);\n await sleep(waitSec * 1000);\n continue;\n }\n\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n throw new Error(\n `Dataverse metadata GET ${res.status} ${res.statusText}: ${url}\\n${body.slice(0, 300)}`,\n );\n }\n\n return (await res.json()) as T;\n }\n}\n\n/** GET a single metadata resource (relative path), with retry/backoff. */\nexport async function metadataGet<T = unknown>(\n http: MetadataHttp,\n relativePath: string,\n maxRetries = 4,\n): Promise<T> {\n return getWithRetry<T>(http, buildUrl(http, relativePath), maxRetries);\n}\n\n/**\n * GET a metadata collection (relative path), following `@odata.nextLink` and\n * concatenating every page's `value`. Use for queries that can exceed the\n * server page cap (e.g. typed-cast attribute lists on very wide entities).\n */\nexport async function metadataGetAll<T = unknown>(\n http: MetadataHttp,\n relativePath: string,\n maxRetries = 4,\n): Promise<T[]> {\n const out: T[] = [];\n let url: string | undefined = buildUrl(http, relativePath);\n while (url) {\n const page: ODataPage<T> = await getWithRetry<ODataPage<T>>(http, url, maxRetries);\n if (page.value) out.push(...page.value);\n url = page['@odata.nextLink'];\n }\n return out;\n}\n","/**\n * Dataverse logical-name allowlist.\n *\n * The same rule Dataverse itself enforces (lowercase letter, then\n * [a-z0-9_]). Applied to the user-supplied `--entity` value at every\n * metadata-access boundary so it cannot inject into the OData `$filter`\n * / resource-path queries it is interpolated into (e.g.\n * `LogicalName eq '<name>'` and `EntityDefinitions(LogicalName='<name>')`).\n */\nconst LOGICAL_NAME_PATTERN = /^[a-z][a-z0-9_]*$/;\n\nexport function assertValidEntityName(name: string): string {\n if (!name || !LOGICAL_NAME_PATTERN.test(name)) {\n throw new Error(\n `Invalid entity logical name ${JSON.stringify(name)} — expected a lowercase letter ` +\n 'followed by [a-z0-9_] (Dataverse logical-name rule).',\n );\n }\n return name;\n}\n","/**\n * Non-destructive file writing — the foundational safety guarantee.\n *\n * Client `src/models/*` etc. are frequently hand-customized. Commands MUST\n * NOT clobber existing files silently. `safeWrite`:\n * - refuses to overwrite an existing file unless `force`\n * - supports `dryRun` (report only) and `diff` (print a unified-ish diff)\n * - creates parent dirs as needed\n */\n\nimport { mkdirSync, readFileSync, writeFileSync, existsSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nexport type WriteResult = 'created' | 'overwritten' | 'skipped-exists' | 'unchanged' | 'dry-run';\n\nexport interface SafeWriteOptions {\n force?: boolean;\n dryRun?: boolean;\n diff?: boolean;\n}\n\nexport function safeWrite(path: string, content: string, opts: SafeWriteOptions = {}): WriteResult {\n const exists = existsSync(path);\n const current = exists ? readFileSync(path, 'utf8') : undefined;\n\n if (exists && current === content) return 'unchanged';\n\n if (opts.diff && exists) printDiff(path, current ?? '', content);\n\n if (opts.dryRun) return 'dry-run';\n\n if (exists && !opts.force) {\n return 'skipped-exists';\n }\n\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, content, 'utf8');\n return exists ? 'overwritten' : 'created';\n}\n\n/** Minimal line-level diff (added/removed) — enough to eyeball changes in a terminal. */\nfunction printDiff(path: string, before: string, after: string): void {\n const a = before.split('\\n');\n const b = after.split('\\n');\n // eslint-disable-next-line no-console\n console.log(`\\n--- ${path} (existing)\\n+++ ${path} (generated)`);\n const max = Math.max(a.length, b.length);\n for (let i = 0; i < max; i += 1) {\n if (a[i] === b[i]) continue;\n if (a[i] !== undefined) console.log(`- ${a[i]}`); // eslint-disable-line no-console\n if (b[i] !== undefined) console.log(`+ ${b[i]}`); // eslint-disable-line no-console\n }\n}\n","/**\n * Connection resolution — build an IDataverseClient from CLI flags / env,\n * tolerant of the env-var prefixes client projects actually use\n * (VITE_/REACT_APP_/bare DYNAMICS_), with Azure CLI as the token fallback.\n *\n * Token precedence: --token > env (.env / process.env) > Azure CLI (az).\n * Use --token (or env) for cross-tenant client orgs where you don't have\n * `az login` to the client's tenant.\n */\n\nimport { createClient, type IDataverseClient } from '@dynamics-ui-kit/api-client';\nimport { loadEnv, getToken } from '@dynamics-ui-kit/dev-tools';\n\nexport interface ConnectionOptions {\n url?: string;\n token?: string;\n envFile?: string;\n}\n\nexport interface ResolvedConnection {\n client: IDataverseClient;\n url: string;\n /** The resolved bearer token — used for typed-cast metadata HTTP the client doesn't expose. */\n token: string;\n tokenSource: 'flag' | 'env' | 'azure-cli';\n}\n\nexport function resolveConnection(opts: ConnectionOptions): ResolvedConnection {\n const env = loadEnv({ path: opts.envFile, fallbackToProcessEnv: true });\n\n const url = opts.url ?? env.url;\n if (!url) {\n throw new Error(\n 'No Dataverse URL found. Pass --url <url>, or set one of ' +\n 'VITE_DYNAMICS_URL / REACT_APP_DYNAMICS_URL / DYNAMICS_URL (optionally via --env-file).',\n );\n }\n\n let token = opts.token;\n let tokenSource: ResolvedConnection['tokenSource'] = 'flag';\n if (!token) {\n // Token from the .env file (loadEnv exposes parsed pairs in `values`) or\n // process.env — tolerant of the VITE_/REACT_APP_/bare DYNAMICS_ prefixes.\n token =\n env.values.DYNAMICS_TOKEN ??\n env.values.VITE_DYNAMICS_TOKEN ??\n env.values.REACT_APP_DYNAMICS_TOKEN ??\n process.env.DYNAMICS_TOKEN ??\n process.env.VITE_DYNAMICS_TOKEN ??\n process.env.REACT_APP_DYNAMICS_TOKEN;\n if (token) tokenSource = 'env';\n }\n if (!token) {\n token = getToken({ resource: url }).token;\n tokenSource = 'azure-cli';\n }\n\n const client = createClient({ baseUrl: url, token });\n return { client, url, token, tokenSource };\n}\n","import { readFileSync, existsSync } from 'node:fs';\n\n/**\n * URL env var names in priority order. The first matching key in the .env file\n * (or process.env when no file is provided) wins. Matches the auto-detection\n * behavior of msft/04-dynamics/scripts/get-token.sh.\n */\nexport const URL_ENV_KEYS = [\n 'VITE_DYNAMICS_URL',\n 'REACT_APP_DYNAMICS_URL',\n 'DYNAMICS_URL',\n] as const;\n\nexport type UrlEnvKey = (typeof URL_ENV_KEYS)[number];\n\nexport interface LoadEnvResult {\n /** The matched URL, or undefined if no key matched. */\n url: string | undefined;\n /** The key that matched (priority winner), or undefined if no match. */\n matchedKey: UrlEnvKey | undefined;\n /** Parsed key/value pairs from the file (empty if no file was read). */\n values: Record<string, string>;\n}\n\nexport interface LoadEnvOptions {\n /** Path to a .env file. If omitted, reads from process.env only. */\n path?: string;\n /**\n * Also consider process.env if the file is missing the key. When `path` is\n * not provided, this defaults to true; when `path` IS provided, it defaults\n * to false so file contents are authoritative.\n */\n fallbackToProcessEnv?: boolean;\n}\n\n/** Parse a .env file body. Handles both \\n and \\r\\n line endings, and a leading UTF-8 BOM. */\nexport function parseEnvFile(content: string): Record<string, string> {\n const result: Record<string, string> = {};\n // Strip a UTF-8 BOM (U+FEFF) if present — otherwise the first key would\n // carry it as an invisible prefix and lookups for VITE_DYNAMICS_URL would miss.\n if (content.charCodeAt(0) === 0xfeff) {\n content = content.slice(1);\n }\n const lines = content.split(/\\r?\\n/);\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eq = trimmed.indexOf('=');\n if (eq === -1) continue;\n const key = trimmed.slice(0, eq).trim();\n let value = trimmed.slice(eq + 1).trim();\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n result[key] = value;\n }\n return result;\n}\n\nexport function loadEnv(options: LoadEnvOptions = {}): LoadEnvResult {\n let values: Record<string, string> = {};\n\n if (options.path) {\n if (!existsSync(options.path)) {\n throw new Error(`Env file not found: ${options.path}`);\n }\n const content = readFileSync(options.path, 'utf-8');\n values = parseEnvFile(content);\n }\n\n const fallback = options.fallbackToProcessEnv ?? !options.path;\n\n const lookup = (key: string): string | undefined => {\n if (key in values && values[key] !== '') return values[key];\n if (fallback) {\n const v = process.env[key];\n if (v !== undefined && v !== '') return v;\n }\n return undefined;\n };\n\n for (const key of URL_ENV_KEYS) {\n const v = lookup(key);\n if (v !== undefined) {\n return { url: v, matchedKey: key, values };\n }\n }\n\n return { url: undefined, matchedKey: undefined, values };\n}\n","import { execFileSync } from 'node:child_process';\n\nexport interface TokenResult {\n token: string;\n expiresOn: Date;\n}\n\nexport interface GetTokenOptions {\n /** Dynamics URL — used as the OAuth resource. Required. */\n resource: string;\n /** Optional: explicit Azure CLI binary path. Defaults to `az` on PATH. */\n azCommand?: string;\n /**\n * Optional execFileSync replacement, primarily for tests. Should accept the\n * same shape as Node's execFileSync and return the stdout string.\n */\n exec?: (\n file: string,\n args: ReadonlyArray<string>,\n ) => string;\n}\n\ninterface AzCliTokenResponse {\n accessToken: string;\n expiresOn: string;\n}\n\nexport class AzCliError extends Error {\n public readonly cause?: unknown;\n constructor(message: string, cause?: unknown) {\n super(message);\n this.name = 'AzCliError';\n if (cause !== undefined) this.cause = cause;\n }\n}\n\n/**\n * Acquire a Dataverse bearer token via Azure CLI.\n *\n * Requires the user to have run `az login`. The resource MUST be the\n * Dataverse environment URL (e.g. https://myorg.crm.dynamics.com).\n */\nexport function getToken(options: GetTokenOptions): TokenResult {\n const { resource } = options;\n if (!resource) {\n throw new Error('getToken: resource is required (Dataverse URL)');\n }\n const az = options.azCommand ?? 'az';\n const args = [\n 'account',\n 'get-access-token',\n '--resource',\n resource,\n '--output',\n 'json',\n ];\n\n let stdout: string;\n try {\n if (options.exec) {\n stdout = options.exec(az, args);\n } else {\n stdout = execFileSync(az, args, {\n encoding: 'utf-8',\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n }\n } catch (err) {\n const errObj = err as { stderr?: Buffer | string; code?: string; message?: string };\n const stderr =\n typeof errObj.stderr === 'string'\n ? errObj.stderr\n : errObj.stderr?.toString('utf-8') ?? errObj.message ?? '';\n\n if (errObj.code === 'ENOENT') {\n throw new AzCliError(\n 'Azure CLI (`az`) is not installed or not on PATH. Install: https://learn.microsoft.com/cli/azure/install-azure-cli',\n err,\n );\n }\n if (/please run.*az login/i.test(stderr) || /not logged in/i.test(stderr)) {\n throw new AzCliError(\n 'Azure CLI is not authenticated. Run `az login` and retry.',\n err,\n );\n }\n throw new AzCliError(\n `Failed to acquire token via Azure CLI: ${stderr.trim() || 'unknown error'}`,\n err,\n );\n }\n\n let parsed: AzCliTokenResponse;\n try {\n parsed = JSON.parse(stdout) as AzCliTokenResponse;\n } catch (err) {\n throw new AzCliError(`Could not parse Azure CLI JSON output: ${stdout}`, err);\n }\n if (!parsed.accessToken) {\n throw new AzCliError(`Azure CLI returned no accessToken: ${stdout}`);\n }\n const expiresOn = new Date(parsed.expiresOn);\n if (Number.isNaN(expiresOn.getTime())) {\n throw new AzCliError(`Azure CLI returned unparseable expiresOn: ${parsed.expiresOn}`);\n }\n return { token: parsed.accessToken, expiresOn };\n}\n","export interface ViteProxyOptions {\n /** Dataverse base URL (no trailing slash). */\n target: string;\n /** Path prefix to proxy. Defaults to /api/data. */\n prefix?: string;\n /** Forward Authorization header. Defaults to true. */\n changeOrigin?: boolean;\n /** Secure: validate certs. Defaults to true. */\n secure?: boolean;\n}\n\nexport interface ViteProxyEntry {\n target: string;\n changeOrigin: boolean;\n secure: boolean;\n}\n\nexport type ViteProxyConfig = Record<string, ViteProxyEntry>;\n\n/**\n * Build a Vite `server.proxy` config object for Dataverse Web API requests.\n *\n * Usage:\n * import { defineConfig } from 'vite';\n * import { viteProxy } from '@dynamics-ui-kit/dev-tools';\n * export default defineConfig({\n * server: { proxy: viteProxy({ target: process.env.VITE_DYNAMICS_URL! }) },\n * });\n */\nexport function viteProxy(options: ViteProxyOptions): ViteProxyConfig {\n if (!options.target) {\n throw new Error('viteProxy: target is required (Dataverse URL)');\n }\n const target = options.target.replace(/\\/$/, '');\n const prefix = options.prefix ?? '/api/data';\n return {\n [prefix]: {\n target,\n changeOrigin: options.changeOrigin ?? true,\n secure: options.secure ?? true,\n },\n };\n}\n","export interface CraProxyOptions {\n /** Dataverse base URL (no trailing slash). */\n target: string;\n /** Path prefix to proxy. Defaults to /api/data. */\n prefix?: string;\n /** Whether the generated module uses CommonJS (default) or ESM. */\n module?: 'cjs' | 'esm';\n}\n\n/**\n * Generate a CRA `setupProxy.js` file as a string.\n *\n * Drop the returned content into `src/setupProxy.js` of a Create React App\n * project. CRA picks it up at dev-server startup.\n */\nexport function craProxy(options: CraProxyOptions): string {\n if (!options.target) {\n throw new Error('craProxy: target is required (Dataverse URL)');\n }\n const target = options.target.replace(/\\/$/, '');\n const prefix = options.prefix ?? '/api/data';\n const moduleFormat = options.module ?? 'cjs';\n\n const importLine =\n moduleFormat === 'esm'\n ? \"import { createProxyMiddleware } from 'http-proxy-middleware';\"\n : \"const { createProxyMiddleware } = require('http-proxy-middleware');\";\n\n const exportLine =\n moduleFormat === 'esm'\n ? 'export default function (app) {'\n : 'module.exports = function (app) {';\n\n // JSON.stringify guarantees the generated source is a valid JS string\n // literal even if `target` or `prefix` somehow contain `'`, `\"`, `\\`, or\n // a newline. Without this, a malicious .env value could inject code into\n // the user's generated setupProxy.js.\n return [\n '// Generated by @dynamics-ui-kit/dev-tools',\n importLine,\n '',\n exportLine,\n ` app.use(`,\n ` ${JSON.stringify(prefix)},`,\n ` createProxyMiddleware({`,\n ` target: ${JSON.stringify(target)},`,\n ` changeOrigin: true,`,\n ` secure: true,`,\n ` }),`,\n ` );`,\n `};`,\n '',\n ].join('\\n');\n}\n","/**\n * Parent-lookup (many-to-one) <link-entity> derivation for model retrieve\n * scaffolds. Shared by the `models` and `design` commands.\n */\nimport type { IDataverseClient } from '@dynamics-ui-kit/api-client';\nimport type { EntityMetadataInput } from '@dynamics-ui-kit/entity-gen';\n\nexport interface RetrieveLink {\n entity: string;\n from: string;\n to: string;\n alias: string;\n}\n\n/**\n * Derive parent-lookup joins from relationship metadata to pre-fill a model's\n * `retrieveWithRelated()` scaffold. Parent lookups are relationships where THIS\n * entity is the referencing (many) side — Dataverse reports both navigations as\n * `OneToManyRelationship`, so we identify by `ReferencingEntity`, not type.\n *\n * Best-effort: returns `[]` (with a console warning) when relationships can't\n * be fetched, so callers still emit a TODO scaffold.\n */\nexport async function deriveParentLookupLinks(\n client: IDataverseClient,\n entity: EntityMetadataInput,\n): Promise<RetrieveLink[]> {\n try {\n const lookupAttrs = new Set(\n entity.Attributes.filter((a) =>\n ['Lookup', 'Customer', 'Owner'].includes(a.AttributeType),\n ).map((a) => a.LogicalName),\n );\n const rels = await client.getRelationshipMetadata(entity.LogicalName);\n const seenAliases = new Set<string>();\n return rels\n .filter(\n (r) =>\n r.ReferencingEntity === entity.LogicalName &&\n lookupAttrs.has(r.ReferencingAttribute),\n )\n .map((r) => {\n let alias = r.ReferencingEntityNavigationPropertyName || r.ReferencedEntity;\n let n = 2;\n while (seenAliases.has(alias)) alias = `${r.ReferencedEntity}${n++}`;\n seenAliases.add(alias);\n return {\n entity: r.ReferencedEntity,\n from: r.ReferencedAttribute,\n to: r.ReferencingAttribute,\n alias,\n };\n });\n } catch (e) {\n // eslint-disable-next-line no-console\n console.warn(\n ` ⚠ could not fetch relationships for ${entity.LogicalName}: ${e instanceof Error ? e.message : String(e)} (emitting TODO scaffold)`,\n );\n return [];\n }\n}\n","/**\n * Reader for the `*.design.json` contract exported by the design-only form\n * designer (`@dynamics-ui-kit/form-designer`). The `design` command uses this\n * to discover which Dataverse entities a set of forms targets, then scaffolds\n * the data layer for each.\n *\n * Parses untrusted JSON, so the shapes here are deliberately loose + defensive\n * rather than importing form-runtime's full `FormDefinition`.\n */\nimport { assertValidEntityName } from '../validate';\n\n/** Discriminator the form designer writes into every exported design file. */\nexport const FORM_DESIGN_KIND = 'dynamics-ui-kit.form-design';\n\ninterface DesignControl {\n type?: string;\n name?: string;\n properties?: { entityName?: unknown } & Record<string, unknown>;\n dataBinding?: { attributeLogicalName?: unknown; lookupTargets?: unknown };\n}\ninterface DesignCell {\n control?: DesignControl | null;\n}\ninterface DesignRow {\n cells?: DesignCell[];\n}\ninterface DesignSection {\n rows?: DesignRow[];\n}\ninterface DesignTab {\n sections?: DesignSection[];\n}\ninterface DesignForm {\n name?: string;\n type?: string;\n settings?: { dataSources?: Array<{ entityName?: unknown }> };\n sections?: DesignSection[];\n tabs?: DesignTab[];\n}\n\nexport interface FormDesignFile {\n kind?: string;\n schemaVersion?: number;\n name?: string;\n forms?: DesignForm[];\n}\n\n/** A Dataverse entity discovered in the design, with where it came from. */\nexport interface EntityRef {\n logicalName: string;\n /** Human-readable provenance, for reporting (e.g. `form \"Contact\" (target)`). */\n sources: string[];\n}\n\nexport interface CollectResult {\n entities: EntityRef[];\n /** Entity-name candidates rejected by the logical-name allowlist. */\n skipped: { name: string; reason: string }[];\n}\n\n/**\n * Parse + validate an exported design file. Throws on invalid JSON, an\n * unexpected `kind`, or a missing `forms` array.\n */\nexport function parseDesignFile(raw: string): FormDesignFile {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (e) {\n throw new Error(`Design file is not valid JSON: ${e instanceof Error ? e.message : String(e)}`);\n }\n if (!parsed || typeof parsed !== 'object') {\n throw new Error('Design file must be a JSON object.');\n }\n const file = parsed as FormDesignFile;\n if (file.kind && file.kind !== FORM_DESIGN_KIND) {\n throw new Error(\n `Unexpected design kind ${JSON.stringify(file.kind)} (expected ${JSON.stringify(FORM_DESIGN_KIND)}). ` +\n 'Is this a *.design.json exported from the form designer?',\n );\n }\n if (!Array.isArray(file.forms)) {\n throw new Error('Design file has no `forms` array — nothing to scan.');\n }\n return file;\n}\n\n/**\n * Walk every form and collect the Dataverse entities it references:\n * - each form's target entity (`settings.dataSources[0].entityName`),\n * - subgrid controls' `properties.entityName`,\n * - lookup controls' `dataBinding.lookupTargets`.\n *\n * Names are normalized to lowercase and validated against the Dataverse\n * logical-name rule; invalid candidates are reported in `skipped`, never\n * generated (they'd otherwise inject into metadata OData queries).\n */\nexport function collectEntities(design: FormDesignFile): CollectResult {\n const found = new Map<string, Set<string>>();\n const skipped: { name: string; reason: string }[] = [];\n\n const add = (raw: unknown, source: string): void => {\n if (typeof raw !== 'string') return;\n const name = raw.trim().toLowerCase();\n if (!name) return;\n try {\n assertValidEntityName(name);\n } catch {\n if (!skipped.some((s) => s.name === name)) {\n skipped.push({ name, reason: 'not a valid Dataverse logical name' });\n }\n return;\n }\n if (!found.has(name)) found.set(name, new Set());\n found.get(name)!.add(source);\n };\n\n const walkSections = (sections: DesignSection[] | undefined, formName: string): void => {\n for (const section of sections ?? []) {\n for (const row of section.rows ?? []) {\n for (const cell of row.cells ?? []) {\n const c = cell?.control;\n if (!c) continue;\n if (c.type === 'subgrid') {\n add(c.properties?.entityName, `subgrid in \"${formName}\"`);\n }\n if (c.type === 'lookup' && Array.isArray(c.dataBinding?.lookupTargets)) {\n for (const t of c.dataBinding!.lookupTargets as unknown[]) {\n add(t, `lookup in \"${formName}\"`);\n }\n }\n }\n }\n }\n };\n\n for (const form of design.forms ?? []) {\n const formName = form.name ?? '(unnamed form)';\n add(form.settings?.dataSources?.[0]?.entityName, `form \"${formName}\" (target)`);\n walkSections(form.sections, formName);\n for (const tab of form.tabs ?? []) walkSections(tab.sections, formName);\n }\n\n const entities: EntityRef[] = [...found.entries()]\n .map(([logicalName, sources]) => ({ logicalName, sources: [...sources] }))\n .sort((a, b) => a.logicalName.localeCompare(b.logicalName));\n\n return { entities, skipped };\n}\n"],"mappings":"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","names":["__export","createClient","module","__toCommonJS"]}
@@ -0,0 +1,241 @@
1
+ import { AttributeMetadata, EntityMetadata, IDataverseClient } from '@dynamics-ui-kit/api-client';
2
+ import { AttributeMetadataInput, EntityMetadataInput } from '@dynamics-ui-kit/entity-gen';
3
+
4
+ /**
5
+ * Adapter: raw Dataverse metadata (from @dynamics-ui-kit/api-client) →
6
+ * the `EntityMetadataInput` shape consumed by @dynamics-ui-kit/entity-gen.
7
+ *
8
+ * The two shapes are intentionally field-compatible (both PascalCase
9
+ * Dataverse-style), so this is largely a structural passthrough. It exists
10
+ * as an explicit seam so the codegen tools never depend on the api-client's
11
+ * concrete types and so we can validate/normalize in one place.
12
+ */
13
+
14
+ declare function toAttributeMetadataInput(attr: AttributeMetadata): AttributeMetadataInput;
15
+ declare function toEntityMetadataInput(entity: EntityMetadata, attributes: AttributeMetadata[]): EntityMetadataInput;
16
+
17
+ /**
18
+ * Minimal Dataverse metadata HTTP helper for the codegen tools.
19
+ *
20
+ * Used for typed-cast attribute queries the api-client doesn't expose
21
+ * (scalar detail like MaxLength/Precision). Honors 429/503 throttling with
22
+ * `Retry-After` backoff, and follows `@odata.nextLink` (metadataGetAll) so
23
+ * wide results aren't truncated. Uses the global `fetch` (Node 18+).
24
+ */
25
+ interface MetadataHttp {
26
+ /** Org base URL, e.g. https://org.crm.dynamics.com */
27
+ baseUrl: string;
28
+ token: string;
29
+ /** Web API version. Default 9.2. */
30
+ apiVersion?: string;
31
+ }
32
+ /** GET a single metadata resource (relative path), with retry/backoff. */
33
+ declare function metadataGet<T = unknown>(http: MetadataHttp, relativePath: string, maxRetries?: number): Promise<T>;
34
+ /**
35
+ * GET a metadata collection (relative path), following `@odata.nextLink` and
36
+ * concatenating every page's `value`. Use for queries that can exceed the
37
+ * server page cap (e.g. typed-cast attribute lists on very wide entities).
38
+ */
39
+ declare function metadataGetAll<T = unknown>(http: MetadataHttp, relativePath: string, maxRetries?: number): Promise<T[]>;
40
+
41
+ /**
42
+ * fetchEntityMetadata — compose a complete `EntityMetadataInput` for one
43
+ * entity from a live org, fixing the gap entity-gen's own CLI has (it calls
44
+ * a non-existent `client.getEntityMetadata`).
45
+ *
46
+ * = getEntityDefinitions(LogicalName eq '<e>')[0] + getAttributeMetadata('<e>')
47
+ * → toEntityMetadataInput()
48
+ * → (optional) typed-cast scalar augmentation (MaxLength/Precision/...)
49
+ */
50
+
51
+ interface FetchEntityMetadataOptions {
52
+ /**
53
+ * Optional extra OData filter ANDed onto the attribute query. The api-client
54
+ * always restricts to readable attributes (`IsValidForRead eq true`), so
55
+ * generated constants/models cover the readable attribute surface.
56
+ */
57
+ attributeFilter?: string;
58
+ /**
59
+ * When provided, fetch type-specific scalar detail (MaxLength, Precision,
60
+ * Min/MaxValue, Format, DateTimeBehavior) via typed-cast queries and merge
61
+ * it in. Best-effort — failures are logged and skipped.
62
+ */
63
+ augment?: MetadataHttp;
64
+ }
65
+ declare function fetchEntityMetadata(client: IDataverseClient, logicalName: string, options?: FetchEntityMetadataOptions): Promise<EntityMetadataInput>;
66
+
67
+ /**
68
+ * Typed-cast attribute augmentation.
69
+ *
70
+ * The api-client's `getAttributeMetadata` returns the base attribute shape;
71
+ * scalar detail (MaxLength, Precision, Min/MaxValue, Format, DateTimeBehavior)
72
+ * lives on type-specific subtypes and is only returned via a typed cast on the
73
+ * EntityDefinitions Attributes navigation, e.g.:
74
+ *
75
+ * EntityDefinitions(LogicalName='x')/Attributes/Microsoft.Dynamics.CRM.StringAttributeMetadata
76
+ * ?$select=LogicalName,MaxLength,Format
77
+ *
78
+ * This fills those fields in so generated constants carry full JSDoc detail.
79
+ * Best-effort: a failed cast query is skipped (codegen still succeeds, just
80
+ * with thinner comments for that type).
81
+ */
82
+
83
+ interface ScalarDetail {
84
+ LogicalName: string;
85
+ MaxLength?: number;
86
+ MinValue?: number;
87
+ MaxValue?: number;
88
+ Precision?: number;
89
+ Format?: string;
90
+ DateTimeBehavior?: {
91
+ Value: string;
92
+ };
93
+ }
94
+ type MetadataGetter = (http: MetadataHttp, path: string) => Promise<{
95
+ value: ScalarDetail[];
96
+ }>;
97
+ /**
98
+ * Merge fetched scalar detail into the attribute list (in place). Only fills
99
+ * fields that are currently unset, so an explicit value from the base fetch
100
+ * always wins. Pure — exported for testing.
101
+ */
102
+ declare function mergeScalarDetail(attrs: AttributeMetadataInput[], details: ScalarDetail[]): void;
103
+ declare function augmentScalarDetail(http: MetadataHttp, logicalName: string, attrs: AttributeMetadataInput[], get?: MetadataGetter): Promise<void>;
104
+
105
+ /**
106
+ * Non-destructive file writing — the foundational safety guarantee.
107
+ *
108
+ * Client `src/models/*` etc. are frequently hand-customized. Commands MUST
109
+ * NOT clobber existing files silently. `safeWrite`:
110
+ * - refuses to overwrite an existing file unless `force`
111
+ * - supports `dryRun` (report only) and `diff` (print a unified-ish diff)
112
+ * - creates parent dirs as needed
113
+ */
114
+ type WriteResult = 'created' | 'overwritten' | 'skipped-exists' | 'unchanged' | 'dry-run';
115
+ interface SafeWriteOptions {
116
+ force?: boolean;
117
+ dryRun?: boolean;
118
+ diff?: boolean;
119
+ }
120
+ declare function safeWrite(path: string, content: string, opts?: SafeWriteOptions): WriteResult;
121
+
122
+ /**
123
+ * Connection resolution — build an IDataverseClient from CLI flags / env,
124
+ * tolerant of the env-var prefixes client projects actually use
125
+ * (VITE_/REACT_APP_/bare DYNAMICS_), with Azure CLI as the token fallback.
126
+ *
127
+ * Token precedence: --token > env (.env / process.env) > Azure CLI (az).
128
+ * Use --token (or env) for cross-tenant client orgs where you don't have
129
+ * `az login` to the client's tenant.
130
+ */
131
+
132
+ interface ConnectionOptions {
133
+ url?: string;
134
+ token?: string;
135
+ envFile?: string;
136
+ }
137
+ interface ResolvedConnection {
138
+ client: IDataverseClient;
139
+ url: string;
140
+ /** The resolved bearer token — used for typed-cast metadata HTTP the client doesn't expose. */
141
+ token: string;
142
+ tokenSource: 'flag' | 'env' | 'azure-cli';
143
+ }
144
+ declare function resolveConnection(opts: ConnectionOptions): ResolvedConnection;
145
+
146
+ /**
147
+ * Parent-lookup (many-to-one) <link-entity> derivation for model retrieve
148
+ * scaffolds. Shared by the `models` and `design` commands.
149
+ */
150
+
151
+ interface RetrieveLink {
152
+ entity: string;
153
+ from: string;
154
+ to: string;
155
+ alias: string;
156
+ }
157
+ /**
158
+ * Derive parent-lookup joins from relationship metadata to pre-fill a model's
159
+ * `retrieveWithRelated()` scaffold. Parent lookups are relationships where THIS
160
+ * entity is the referencing (many) side — Dataverse reports both navigations as
161
+ * `OneToManyRelationship`, so we identify by `ReferencingEntity`, not type.
162
+ *
163
+ * Best-effort: returns `[]` (with a console warning) when relationships can't
164
+ * be fetched, so callers still emit a TODO scaffold.
165
+ */
166
+ declare function deriveParentLookupLinks(client: IDataverseClient, entity: EntityMetadataInput): Promise<RetrieveLink[]>;
167
+
168
+ /** Discriminator the form designer writes into every exported design file. */
169
+ declare const FORM_DESIGN_KIND = "dynamics-ui-kit.form-design";
170
+ interface DesignControl {
171
+ type?: string;
172
+ name?: string;
173
+ properties?: {
174
+ entityName?: unknown;
175
+ } & Record<string, unknown>;
176
+ dataBinding?: {
177
+ attributeLogicalName?: unknown;
178
+ lookupTargets?: unknown;
179
+ };
180
+ }
181
+ interface DesignCell {
182
+ control?: DesignControl | null;
183
+ }
184
+ interface DesignRow {
185
+ cells?: DesignCell[];
186
+ }
187
+ interface DesignSection {
188
+ rows?: DesignRow[];
189
+ }
190
+ interface DesignTab {
191
+ sections?: DesignSection[];
192
+ }
193
+ interface DesignForm {
194
+ name?: string;
195
+ type?: string;
196
+ settings?: {
197
+ dataSources?: Array<{
198
+ entityName?: unknown;
199
+ }>;
200
+ };
201
+ sections?: DesignSection[];
202
+ tabs?: DesignTab[];
203
+ }
204
+ interface FormDesignFile {
205
+ kind?: string;
206
+ schemaVersion?: number;
207
+ name?: string;
208
+ forms?: DesignForm[];
209
+ }
210
+ /** A Dataverse entity discovered in the design, with where it came from. */
211
+ interface EntityRef {
212
+ logicalName: string;
213
+ /** Human-readable provenance, for reporting (e.g. `form "Contact" (target)`). */
214
+ sources: string[];
215
+ }
216
+ interface CollectResult {
217
+ entities: EntityRef[];
218
+ /** Entity-name candidates rejected by the logical-name allowlist. */
219
+ skipped: {
220
+ name: string;
221
+ reason: string;
222
+ }[];
223
+ }
224
+ /**
225
+ * Parse + validate an exported design file. Throws on invalid JSON, an
226
+ * unexpected `kind`, or a missing `forms` array.
227
+ */
228
+ declare function parseDesignFile(raw: string): FormDesignFile;
229
+ /**
230
+ * Walk every form and collect the Dataverse entities it references:
231
+ * - each form's target entity (`settings.dataSources[0].entityName`),
232
+ * - subgrid controls' `properties.entityName`,
233
+ * - lookup controls' `dataBinding.lookupTargets`.
234
+ *
235
+ * Names are normalized to lowercase and validated against the Dataverse
236
+ * logical-name rule; invalid candidates are reported in `skipped`, never
237
+ * generated (they'd otherwise inject into metadata OData queries).
238
+ */
239
+ declare function collectEntities(design: FormDesignFile): CollectResult;
240
+
241
+ export { type CollectResult, type ConnectionOptions, type EntityRef, FORM_DESIGN_KIND, type FetchEntityMetadataOptions, type FormDesignFile, type MetadataGetter, type MetadataHttp, type ResolvedConnection, type RetrieveLink, type SafeWriteOptions, type WriteResult, augmentScalarDetail, collectEntities, deriveParentLookupLinks, fetchEntityMetadata, mergeScalarDetail, metadataGet, metadataGetAll, parseDesignFile, resolveConnection, safeWrite, toAttributeMetadataInput, toEntityMetadataInput };