@xrmforge/devkit 0.7.33 → 0.7.34
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/templates/AGENT.md +46 -0
- package/package.json +1 -1
package/dist/templates/AGENT.md
CHANGED
|
@@ -308,6 +308,24 @@ for (const c of expandedMany<Contact>(account, 'contact_customer_accounts')) { c
|
|
|
308
308
|
const c = account['primarycontactid'] as { fullname?: string };
|
|
309
309
|
```
|
|
310
310
|
|
|
311
|
+
**Polymorphic lookups (`customerid`, `ownerid`, `regardingobjectid`) need a target-qualified
|
|
312
|
+
`$expand` name, not the blank `XxxNavigationProperties` value.** A polymorphic lookup can resolve to
|
|
313
|
+
several entity types, so Dataverse exposes one single-valued navigation property PER target, named
|
|
314
|
+
`<lookup>_<targetentity>` (e.g. `customerid_account`, `customerid_contact`). The generated
|
|
315
|
+
`XxxNavigationProperties` enum carries only the blank logical name (`customerid`) - correct for
|
|
316
|
+
`parseLookup`, `@odata.bind` and `$unsafe`, but NOT a valid `$expand` path for a polymorphic lookup.
|
|
317
|
+
Name the target-qualified property directly and read it back with that same key (the blank value
|
|
318
|
+
stays correct for `parseLookup` on the parent record):
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// customerid (account | contact): expand the concrete target, not AccountNav.CustomerId
|
|
322
|
+
const order = await Xrm.WebApi.retrieveRecord(EntityNames.SalesOrder, id,
|
|
323
|
+
selectExpand([SalesOrderFields.Name], `customerid_account($select=${AccountFields.Name})`));
|
|
324
|
+
const customer = expanded<Account>(order, 'customerid_account'); // target-qualified key
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
(Single-target lookups like `primarycontactid` keep using the blank `XxxNavigationProperties` value.)
|
|
328
|
+
|
|
311
329
|
### 6b. Web API response typing with generated Entity interfaces
|
|
312
330
|
|
|
313
331
|
Always type Web API responses with generated Entity interfaces. Never access properties with `as string` casts.
|
|
@@ -866,6 +884,34 @@ npx xrmforge build # IIFE bundles for D365
|
|
|
866
884
|
npx xrmforge build --watch # Watch mode (~10ms rebuilds)
|
|
867
885
|
```
|
|
868
886
|
|
|
887
|
+
## HTML WebResources (standalone HTML pages)
|
|
888
|
+
|
|
889
|
+
An HTML WebResource (a standalone page in a form IFrame or the sitemap, not a form
|
|
890
|
+
script) follows the same TypeScript-first split as a form script:
|
|
891
|
+
|
|
892
|
+
- **TypeScript module** (`src/<name>.ts`): all logic, built as its own esbuild IIFE
|
|
893
|
+
entry with its own `globalName` (e.g. `Contoso.ShowImages`) - exactly like a form-script entry.
|
|
894
|
+
- **HTML shell** (`src/<name>.html`): markup only, plus a `<script src="...">` to the
|
|
895
|
+
built JS and a small call to the exported init function (`Contoso.ShowImages.init()`). No
|
|
896
|
+
inline code, no jQuery. esbuild does NOT build the `.html` (static asset); deploy it as its
|
|
897
|
+
own WebResource next to the built JS, which it references via `<script src>`.
|
|
898
|
+
- **Xrm access:** an embedded HTML WebResource reaches the form API via `window.parent.Xrm`
|
|
899
|
+
(it gets no `executionContext` parameter, unlike a form script). The form script may also
|
|
900
|
+
inject the context actively (export a `setClientApiContext(...)` the form script calls on open).
|
|
901
|
+
|
|
902
|
+
`xrmforge.config.json` entry - same shape as any other module:
|
|
903
|
+
|
|
904
|
+
```json
|
|
905
|
+
"showimages": { "input": "./src/showimages.ts", "namespace": "Contoso.ShowImages", "out": "ShowImages.js" }
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
All the MANDATORY rules above still apply to the `.ts` logic (typedForm where a form context
|
|
909
|
+
is available, EntityNames/Fields enums, `select`/`parseLookup`, generated Entity interfaces, no
|
|
910
|
+
raw OData strings). **Modernize legacy HTML WebResources instead of porting 1:1:** `Xrm.WebApi`
|
|
911
|
+
instead of the old `OrganizationData.svc`/2011 endpoints, `fetch` instead of jQuery `$.ajax`,
|
|
912
|
+
`Xrm`/`formContext` instead of `Xrm.Page`, generated enums instead of raw OData strings, no
|
|
913
|
+
`document.all`.
|
|
914
|
+
|
|
869
915
|
## Drift Check (generated/ vs. live environment)
|
|
870
916
|
|
|
871
917
|
`generated/` is a snapshot of the Dataverse environment. When the environment
|