@mohsinonxrm/pptb-fetchxml-studio 1.0.6 → 1.2.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/README.md +135 -47
  3. package/SECURITY.md +13 -0
  4. package/dist/assets/abap-CRCWOmpq.js +1 -0
  5. package/dist/assets/apex-DnsZk_dE.js +1 -0
  6. package/dist/assets/azcli-1IWB1ccx.js +1 -0
  7. package/dist/assets/bat-DPkNLes8.js +1 -0
  8. package/dist/assets/bicep-Corcdgou.js +2 -0
  9. package/dist/assets/cameligo-CGrWLZr3.js +1 -0
  10. package/dist/assets/clojure-D9WOWImG.js +1 -0
  11. package/dist/assets/codicon-B_Z2XQ3P.ttf +0 -0
  12. package/dist/assets/coffee-B7EJu28W.js +1 -0
  13. package/dist/assets/cpp-SEyurbux.js +1 -0
  14. package/dist/assets/csharp-BoL64M5l.js +1 -0
  15. package/dist/assets/csp-C46ZqvIl.js +1 -0
  16. package/dist/assets/css-DQU6DXDx.js +3 -0
  17. package/dist/assets/cssMode-lrJE5Iiz.js +4 -0
  18. package/dist/assets/cypher-D84EuPTj.js +1 -0
  19. package/dist/assets/dart-D8lhlL1r.js +1 -0
  20. package/dist/assets/dockerfile-DLk6rpji.js +1 -0
  21. package/dist/assets/ecl-BO6FnfXk.js +1 -0
  22. package/dist/assets/elixir-BRjLKONM.js +1 -0
  23. package/dist/assets/flow9-Cac8vKd7.js +1 -0
  24. package/dist/assets/freemarker2-DwmPKpl4.js +3 -0
  25. package/dist/assets/fsharp-fd1GTHhf.js +1 -0
  26. package/dist/assets/go-O9LJTZXk.js +1 -0
  27. package/dist/assets/graphql-LQdxqEYJ.js +1 -0
  28. package/dist/assets/handlebars-Cf8Yk1XH.js +1 -0
  29. package/dist/assets/hcl-DxDQ3s82.js +1 -0
  30. package/dist/assets/html-B8r17viV.js +1 -0
  31. package/dist/assets/htmlMode-Deu2Cnyl.js +4 -0
  32. package/dist/assets/index-OtIaIY5K.js +98 -0
  33. package/dist/assets/ini-BvajGCUy.js +1 -0
  34. package/dist/assets/java-SYsfObOQ.js +1 -0
  35. package/dist/assets/javascript-21fivyfm.js +1 -0
  36. package/dist/assets/jsonMode-C6fJmDrp.js +10 -0
  37. package/dist/assets/julia-DQXNmw_w.js +1 -0
  38. package/dist/assets/kotlin-qQ0MG-9I.js +1 -0
  39. package/dist/assets/less-GGFNNJHn.js +2 -0
  40. package/dist/assets/lexon-Canl7DCW.js +1 -0
  41. package/dist/assets/liquid-CBhIUaM_.js +1 -0
  42. package/dist/assets/lua-D28Ae8-K.js +1 -0
  43. package/dist/assets/m3-DPitgjJI.js +1 -0
  44. package/dist/assets/markdown-B811l8j2.js +1 -0
  45. package/dist/assets/mdx-DKh1a8vs.js +1 -0
  46. package/dist/assets/mips-CdjsipkG.js +1 -0
  47. package/dist/assets/monaco-editor-BhPcksyq.css +1 -0
  48. package/dist/assets/monaco-editor-CSKh0Kpy.js +901 -0
  49. package/dist/assets/msdax-CYqgjx_P.js +1 -0
  50. package/dist/assets/mysql-BHd6q0vd.js +1 -0
  51. package/dist/assets/objective-c-B1aVtJYH.js +1 -0
  52. package/dist/assets/pascal-BhNW15KB.js +1 -0
  53. package/dist/assets/pascaligo-5jv8CcQD.js +1 -0
  54. package/dist/assets/perl-DlYyT36c.js +1 -0
  55. package/dist/assets/pgsql-Dy0bjov7.js +1 -0
  56. package/dist/assets/php-120yhfDK.js +1 -0
  57. package/dist/assets/pla-CjnFlu4u.js +1 -0
  58. package/dist/assets/postiats-CQpG440k.js +1 -0
  59. package/dist/assets/powerquery-DdJtto1Z.js +1 -0
  60. package/dist/assets/powershell-Bu_VLpJB.js +1 -0
  61. package/dist/assets/protobuf-IBS6jZEB.js +2 -0
  62. package/dist/assets/pug-kFxLfcjb.js +1 -0
  63. package/dist/assets/python-C1DvjtTK.js +1 -0
  64. package/dist/assets/qsharp-q7JyzKFN.js +1 -0
  65. package/dist/assets/r-BIFz-_sK.js +1 -0
  66. package/dist/assets/razor-CxbdKBwV.js +1 -0
  67. package/dist/assets/redis-CHOsPHWR.js +1 -0
  68. package/dist/assets/redshift-CBifECDb.js +1 -0
  69. package/dist/assets/restructuredtext-CghPJEOS.js +1 -0
  70. package/dist/assets/ruby-CYWGW-b1.js +1 -0
  71. package/dist/assets/rust-DMDD0SHb.js +1 -0
  72. package/dist/assets/sb-BYAiYHFx.js +1 -0
  73. package/dist/assets/scala-Bqvq8jcR.js +1 -0
  74. package/dist/assets/scheme-Dhb-2j9p.js +1 -0
  75. package/dist/assets/scss-CTwUZ5N7.js +3 -0
  76. package/dist/assets/shell-CsDZo4DB.js +1 -0
  77. package/dist/assets/solidity-CME5AdoB.js +1 -0
  78. package/dist/assets/sophia-RYC1BQQz.js +1 -0
  79. package/dist/assets/sparql-KEyrF7De.js +1 -0
  80. package/dist/assets/sql-BdTr02Mf.js +1 -0
  81. package/dist/assets/st-C7iG7M4S.js +1 -0
  82. package/dist/assets/swift-D7IUmUK8.js +1 -0
  83. package/dist/assets/systemverilog-DgMryOEJ.js +1 -0
  84. package/dist/assets/tcl-PloMZuKG.js +1 -0
  85. package/dist/assets/tsMode-CoKGlBK3.js +11 -0
  86. package/dist/assets/twig-BfRIq3la.js +1 -0
  87. package/dist/assets/typescript-DE4VX4Fi.js +1 -0
  88. package/dist/assets/typespec-CzxlYoT_.js +1 -0
  89. package/dist/assets/vb-BwAE3J76.js +1 -0
  90. package/dist/assets/wgsl-B_1kOXbF.js +298 -0
  91. package/dist/assets/xml-D5FP6KmI.js +1 -0
  92. package/dist/assets/yaml-_F_B7Ufj.js +1 -0
  93. package/dist/index.html +3 -1
  94. package/icons/icon-insider.svg +16 -0
  95. package/icons/icon.svg +12 -0
  96. package/npm-shrinkwrap.json +12 -9
  97. package/package.json +15 -15
  98. package/dist/assets/index-G6ugoEtW.js +0 -98
package/CHANGELOG.md ADDED
@@ -0,0 +1,294 @@
1
+ # Changelog
2
+
3
+ All notable changes to FetchXML Studio will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.2.2-beta.1] - 2026-05-25
9
+
10
+ ### ✨ Added
11
+
12
+ #### Tool-to-Tool (T2T) Invocation — Caller
13
+
14
+ FetchXML Studio can now send the active query to any other PPTB tool that accepts a FetchXML prefill payload. Requires **PPTB host ≥ 1.2.2**.
15
+
16
+ - **Send to Tool button** — A new "Send to Tool" button appears in the toolbar (alongside Save View) whenever the PPTB host exposes the `toolboxAPI.invocation` API. Three interaction modes depending on how many target tools are configured:
17
+ - *No tools configured* — Button is disabled with a tooltip pointing to Settings → Tool Integration.
18
+ - *One tool configured* — Single button; click launches the tool directly.
19
+ - *Multiple tools configured* — Dropdown menu listing all configured tools; click an item to launch.
20
+ - **Settings → Tool Integration section** — New section in the Settings drawer to manage the list of target tool npm package IDs (e.g. `@linked365/pptb-bulk-data-studio`). Supports add (text input + Enter/Add button) and remove (× button per item). The list is persisted via `toolboxAPI.settings` alongside other display preferences.
21
+ - **Active connection forwarding** — The caller automatically retrieves the currently active Dataverse connection and forwards its ID as `primaryConnectionId` when launching the target tool, so the callee opens against the same environment.
22
+ - **`pptb.config.json`** — Added PPTB callee contract file at the repository root. Declares the prefill schema this tool accepts when *receiving* a T2T invocation from another tool (see [Callee Contract](#-callee-contract-pptbconfigjson) in the README). `viewRef` is modelled as a Dataverse EntityReference: required fields `id` (UUID string) and `entityLogicalName` (enum: `"savedquery"` | `"userquery"`).
23
+
24
+ ### 🏗️ Technical
25
+
26
+ - `src/features/fetchxml/api/invocation.ts` — New module. Defines a local `InvocationAPI` interface (mirrors the PPTB host API not yet in `@pptb/types`) and exposes `isT2TSupported()` and `sendFetchXmlToTool(targetToolId, { fetchXml, entityLogicalName })`.
27
+ - `src/features/fetchxml/ui/Toolbar/SendToToolButton.tsx` — New toolbar component. Handles the disabled / single / multi-tool rendering variants; calls `sendFetchXmlToTool`; surfaces errors via `toolboxAPI.utils.showNotification`.
28
+ - `src/features/fetchxml/model/displaySettings.ts` — Added `targetTools: string[]` (default `[]`) to `DisplaySettings` interface and `defaultDisplaySettings`.
29
+ - `src/features/fetchxml/ui/Settings/SettingsDrawer.tsx` — Added Tool Integration section with add/remove UI. Added `Input`, `Field`, `Add20Regular`, `Dismiss16Regular`, `PlugConnected20Regular` to imports.
30
+ - `src/features/fetchxml/ui/RightPane/PreviewTabs.tsx` — Added `sendToToolButton?: ReactNode` prop; rendered unconditionally (all tabs) next to `saveViewButton`.
31
+ - `src/app/AppShell.tsx` — Imports `SendToToolButton` + `isT2TSupported`; passes `sendToToolButton` prop to `PreviewTabs` gated on `isT2TSupported()`.
32
+ - `package.json` — `features.minAPI` bumped from `1.2.0` → `1.2.2` to reflect the new PPTB host requirement. `scheduler` added to `devDependencies` (required peer dep of `@fluentui/react-context-selector` that was missing from the install tree).
33
+
34
+ #### Packaging fixes (resolves #33)
35
+
36
+ - **`icon` path corrected** — `"icon"` field in `package.json` was missing the `icons/` directory prefix (`"icon-insider.svg"` → `"icons/icon-insider.svg"`). Icon was not resolvable by PPTB at install time.
37
+ - **`files` array expanded** — Added `"icons"`, `"index.html"`, `"LICENSE"`, `"README.md"`, `"CHANGELOG.md"`, `"SECURITY.md"` alongside the existing `"dist"` and `"npm-shrinkwrap.json"` entries. Previously the `icons/` folder (referenced by the `"icon"` field) and all root-level docs were absent from the published package.
38
+ - **Production source maps disabled** — Added `sourcemap: false` to `vite.config.ts` `build` options. Monaco worker source maps were silently adding ~17 MB to the package; disabling them brings the published size down to ~3–4 MB.
39
+
40
+ ---
41
+
42
+ ## [1.2.1] - 2026-04-07
43
+
44
+ ### ✨ Added
45
+
46
+ - **Copy button in editor mode** — The FetchXML editor toolbar now includes a Copy button when in editor mode, making it consistent with the read-only toolbar. Previously Copy was only available when the editor was not in edit mode.
47
+
48
+ ### 🔧 Fixed
49
+
50
+ - **Results grid column overlap** — Column widths are now estimated dynamically from header text (capped at 400 px) so adjacent columns no longer overlap on first render. All cells use `TableCellLayout truncate` for clean overflow.
51
+ - **Results grid header/row misalignment** — Removed a stray CSS class from `DataGridBody` that was causing header and row widths to drift out of sync when the grid had overflowing content.
52
+ - **Alias validation in property editors** — Typing an invalid alias character (space, hyphen, special character) in `AttributeEditor` or `LinkEntityEditor` now sanitizes the value in real time: invalid characters are stripped, and a leading digit is prefixed with `_`.
53
+ - **Alias validation in parser** — When parsing FetchXML (both *Parse to Tree* and *Execute*), invalid aliases are now automatically sanitized. A parse warning describes the correction (e.g. *"Alias 'this is id' had invalid characters and was corrected to 'thisisid'."*) instead of silently forwarding the invalid alias to Dataverse where it would cause an API error.
54
+ - **Execute blocked when alias warnings are present** — Clicking Execute in editor mode now validates the XML completely before sending it to Dataverse. If parse warnings exist (e.g. an invalid alias that wasn't auto-corrected via *Parse to Tree*), execution is blocked and the warning is surfaced in a message bar above the editor with a hint to use *Parse to Tree* to auto-correct. Previously the bad alias was silently sent to Dataverse and the error appeared in the Results tab.
55
+ - **Editor state preserved across tab switches** — Switching from the FetchXML tab to Results or LayoutXML and back no longer resets editor mode or discards the edited XML. The editor component is now always mounted (hidden via `display: none` when not active) so Monaco state — editor mode toggle, cursor position, edit buffer — is fully preserved.
56
+ - **Validate contradictory messages** — *Validate* no longer shows both a "Valid" success message and warnings simultaneously. When warnings are present, validate now shows each warning plus an "Action required" notice and stops — the "Valid" success message is only shown when there are zero warnings.
57
+ - **Parse to Tree corrections shown as informational** — Auto-corrected alias warnings from *Parse to Tree* are now shown with `intent="info"` (blue) rather than `intent="warning"` (yellow), correctly communicating that the tool has already resolved the problem.
58
+ - **Execute API errors surfaced** — Dataverse API errors that occur during query execution are now captured and displayed in a message bar in the Results tab. Previously they were only visible in the browser console.
59
+
60
+ ### 🏗️ Technical
61
+
62
+ - Added `src/features/fetchxml/model/aliasUtils.ts` — `isValidAlias()` and `sanitizeAlias()` shared utilities enforcing the Dataverse alias constraint (`[A-Za-z_][A-Za-z0-9_]*`).
63
+ - `fetchxmlParser.ts` — `parseAttribute` and `parseLinkEntity` now import `sanitizeAlias`; invalid aliases are corrected in place and described in the parse warning rather than propagated as-is.
64
+ - `PreviewTabs.tsx` — `FetchXmlEditor` is always mounted; `handleExecute` blocks on parse warnings; navigating back to the FetchXML tab clears any stale editor validation error banner.
65
+ - `AppShell.tsx` — `handleExecute` accepts an optional `xmlOverride` (used when editor mode is active); `executeError` state threads Dataverse API errors back to the `PreviewTabs` message bar.
66
+
67
+ ---
68
+
69
+ ## [1.2.0] - 2026-04-03
70
+
71
+ ### ✨ Added
72
+
73
+ #### Query Scope Settings
74
+ - **Entity Scope Mode** — New setting (persisted across sessions) to control which entities appear in the entity dropdown:
75
+ - **Publisher + Solution** — Select a publisher, then narrow to specific solutions; only entities belonging to those solutions are shown
76
+ - **Solution Only** — Skip the publisher step and pick solutions directly
77
+ - **All Entities** — Show every entity in the environment (no solution filter)
78
+ - **Advanced Find Only toggle** — When enabled (default), entities and attributes are limited to those marked `IsValidForAdvancedFind = true`, matching the classic Advanced Find behavior. Disabling shows all entities and attributes — including system and developer-only tables — useful for building admin or integration queries. The filter is applied locally so toggling is instant with no additional API call.
79
+ - Scope mode and Advanced Find preference are persisted individually via `toolboxAPI.settings` and survive across sessions.
80
+
81
+ #### Monaco Editor — Local Bundling
82
+ - Monaco is now fully bundled in `dist/` instead of being fetched from a CDN at runtime.
83
+ - Eliminates CSP errors and ensures line numbers, syntax highlighting, and all editor features work correctly in the PPTB host environment without network access to external CDNs.
84
+
85
+ ### 🔧 Fixed
86
+
87
+ - **Internal solutions in Solution-only mode** — Solutions from `isreadonly = true` publishers (Microsoft, system publishers) are now excluded from the solution picker, consistent with what Publisher + Solution mode shows. Previously some Microsoft-owned visible solutions appeared in the list.
88
+ - **Parse-to-tree no longer resets the entity** — Pasting FetchXML into the editor and clicking "Parse to Tree" no longer wipes the selected entity. The validation that auto-clears the entity selection now only fires when there is an active solution filter in place (i.e. specific solutions have been selected) and the entity has dropped out of scope — not when the entity was set programmatically via the XML editor.
89
+ - **Entity list cache race condition** — `loadAllEntities` no longer accepts an `advancedFindOnly` parameter. It always fetches all entities from the server (no `$filter=IsValidForAdvancedFind eq true`). The Advanced Find filter is now applied locally in the EntitySelector `memo`. This eliminates a bug where an earlier `advancedFindOnly=true` load could poison the cache and cause subsequent `advancedFindOnly=false` calls to silently return the wrong (filtered) set.
90
+ - **Privilege check console noise** — `checkPrivilegeByName` errors for privileges that don't exist in the environment (e.g. `prvDeleteGitorganization` for system tables) are now logged as `console.warn` instead of `console.error`. The UI behavior is unchanged.
91
+ - **CSP exception** — Removed the invalid `*.crm*.dynamics.com` wildcard from `cspExceptions` (browsers reject multi-depth subdomain wildcards). The only `connect-src` exception kept is `https://*.dynamics.com`.
92
+
93
+ ### 🏗️ Technical
94
+
95
+ - `useAccessMode` preloads only the AF-valid entity metadata cache (`allEntityMetadataCache`) on startup — used by publisher-solution and solution-only modes. The all-entities cache is populated lazily the first time "All Entities" scope mode is used.
96
+ - `loadAllEntities` / `useLazyMetadata.loadEntities` signatures simplified (no `advancedFindOnly` param — always fetches everything).
97
+ - `vite.config.ts` — `manualChunks` splits Monaco into its own chunk (`monaco-editor-*.js`, ~3.7 MB; `monaco-editor-*.css`, ~145 kB).
98
+ - TypeScript strict compile: **zero errors** (`tsc -b --noEmit`).
99
+
100
+ ---
101
+
102
+ ## [1.1.0] - 2026-03-23
103
+
104
+ ### ⬆️ Upgraded
105
+
106
+ - **`@pptb/types` 1.0.7 → 1.2.0** — now the authoritative source for all PPTB host API types (`window.dataverseAPI`, `window.toolboxAPI`). Added to `tsconfig.app.json` `types` array so global augmentations apply project-wide without per-file triple-slash references.
107
+ - **`features.minAPI`** set to `"1.2.0"` in `package.json` to enforce the correct PPTB host version at install time.
108
+
109
+ ### ✨ Added
110
+
111
+ #### Native File Save Dialog
112
+ - Both export paths (local ExcelJS export and Dataverse `ExportToExcel` action) now use `window.toolboxAPI.fileSystem.saveFile` when running inside the PPTB desktop host, presenting a native OS save-file dialog instead of a forced browser blob download.
113
+ - Graceful fallback to browser blob/anchor download when running in standalone or dev context (i.e. when `window.toolboxAPI` is not available).
114
+
115
+ #### Connection Environment Awareness
116
+ - `PptbContext` now exposes `environment?: "Dev" | "Test" | "UAT" | "Production"` sourced from the active `DataverseConnection`.
117
+ - Subscribes to `connection:updated`, `connection:created`, and `connection:deleted` PPTB events to keep the field in sync dynamically.
118
+
119
+ #### Package Manifest Hardening
120
+ - Added top-level `"icon"` field pointing to `icons/icon.svg` (replacing deprecated `configurations.iconUrl`).
121
+ - `"features"` block added: `{ "multiConnection": "none", "minAPI": "1.2.0" }`.
122
+ - `cspExceptions` migrated from plain-string arrays to the required object format with `domain` + `exceptionReason` fields (+ `optional: true` on style-src).
123
+ - Added `"validate": "pptb-validate"` npm script for pre-publish manifest validation.
124
+ - Added `"finalize-package": "npm run build && npm shrinkwrap"` convenience script.
125
+
126
+ ### ♻️ Refactored
127
+
128
+ #### `pptbClient.ts`
129
+ - Removed the entire hand-written `declare global { interface Window { dataverseAPI?: { ... } } }` block (~60 lines). The `window.dataverseAPI` global is now typed entirely by `@pptb/types`.
130
+ - Added local `DataverseFetchXmlResponse` interface to capture OData response annotations beyond what `@pptb/types` `FetchXmlResult` declares (`@Microsoft.Dynamics.CRM.totalrecordcount`, `morerecords`, `pagingcookie`, `totalrecordcountlimitexceeded`). These are OData wire annotations returned directly by Dataverse — not fabricated by PPTB — so the cast is safe at runtime.
131
+ - `downloadBase64File()` changed from `void` to `async Promise<void>`; uses `fileSystem.saveFile` when available.
132
+
133
+ #### `usePptbContext.ts`
134
+ - Removed the entire hand-written `declare global { interface Window { toolboxAPI?: { ... } } }` block. The `window.toolboxAPI` global is now typed entirely by `@pptb/types`.
135
+ - `PptbContext` interface: removed legacy `organizationId?: string` (not present in `DataverseConnection` v1.2.0 types); replaced with `environment?: "Dev" | "Test" | "UAT" | "Production"`.
136
+
137
+ #### `excelExport.ts`
138
+ - `downloadExcelFile()` changed from `void` to `async Promise<void>`; uses `fileSystem.saveFile` when available.
139
+
140
+ #### `AppShell.tsx`
141
+ - Both download call sites updated with `await` to match the new async signatures.
142
+
143
+ ### 🔧 Technical
144
+
145
+ - TypeScript strict compile: **zero errors** (`tsc -b --noEmit`).
146
+ - `pptb-validate`: **✔ Validation passed**.
147
+
148
+ ---
149
+
150
+ ## [1.0.6] - 2026-01-14
151
+
152
+ ### ✨ Added
153
+
154
+ #### Select Attributes Dialog (#12)
155
+ - **Bulk Attribute Selection**: New "Select Attributes" modal dialog for efficient multi-attribute selection
156
+ - Accessible from entity and link-entity context menus in the tree view
157
+ - Works on root entity, link-entities, and nested link-entities at any level
158
+ - **Smart Selection Grid**: DataGrid showing all available entity attributes
159
+ - Three sortable columns: Logical Name, Display Name, and Data Type
160
+ - Pre-selects currently selected attributes with checkboxes
161
+ - Multi-select support for bulk add/remove operations
162
+ - **Search & Filter**: Integrated SearchBox for quick attribute filtering
163
+ - Filters across all columns (logical name, display name, data type)
164
+ - Real-time filtering as you type
165
+ - **Fixed Headers**: Column headers remain visible while scrolling through attributes
166
+ - **Confirmation Required**: Changes only applied when user clicks Apply button
167
+ - Cancel button discards changes without affecting the tree
168
+ - **Smart Updates**: Intelligently adds new attributes and removes deselected ones
169
+ - Preserves existing attributes that remain selected
170
+ - Maintains attribute order and properties
171
+ - **Performance**: Leverages metadata cache for fast attribute loading
172
+ - Falls back to API loading if attributes not cached
173
+ - Shows only attributes valid for Advanced Find
174
+
175
+ ### 🔧 Technical
176
+
177
+ - Added `SelectAttributesDialog` component with FluentUI DataGrid
178
+ - New `UPDATE_ATTRIBUTES` action in builderStore for bulk attribute operations
179
+ - Enhanced TreeView with dialog state management and attribute loading
180
+ - Integrated with existing metadata caching system
181
+
182
+ ## [1.0.0] - 2024-12-15
183
+
184
+ ### 🎉 Initial Release
185
+
186
+ FetchXML Studio v1.0.0 - A powerful FetchXML query builder for Power Platform ToolBox.
187
+
188
+ ### ✨ Features
189
+
190
+ #### Query Builder
191
+ - Tree-based visual query builder with hierarchical FetchXML structure
192
+ - Full entity, attribute, filter, order, and link-entity support
193
+ - Context-aware properties panel for each node type
194
+ - Nested filter groups with AND/OR logic
195
+ - Support for all FetchXML operators (60+ operators)
196
+ - Aggregate queries with groupby and distinct
197
+ - Query hints for performance optimization
198
+
199
+ #### Relationships & Joins
200
+ - Relationship picker with 1:N, N:1, N:N categorization
201
+ - Inner and outer join support
202
+ - Filter link-entity for any/all/not any/not all scenarios
203
+ - Value-of conditions for cross-entity comparisons
204
+ - Entity name conditions for outer join filtering
205
+
206
+ #### Results Grid
207
+ - Virtualized DataGrid for large datasets (react-window)
208
+ - Rich cell rendering for lookups, option sets, dates, currency
209
+ - Multi-column sorting (click + Shift+click)
210
+ - Row selection (single and multi-select)
211
+ - Resizable and reorderable columns
212
+ - Formatted values with raw value toggle
213
+
214
+ #### FetchXML Editor
215
+ - Monaco editor with XML syntax highlighting
216
+ - Bi-directional editing (visual ↔ XML)
217
+ - Parse FetchXML to visual builder
218
+ - Copy to clipboard
219
+ - LayoutXML preview tab
220
+
221
+ #### Views
222
+ - Load system and personal views
223
+ - Optimized view execution via SavedQuery/UserQuery APIs
224
+ - Save queries as personal views
225
+ - Update existing views
226
+ - Solution-aware save (add to solution)
227
+
228
+ #### Data Operations
229
+ - Export to Excel with native data types
230
+ - Delete selected records
231
+ - Bulk delete jobs (async)
232
+ - Run on-demand workflows on selection
233
+ - Batch progress tracking with ETA
234
+
235
+ #### User Experience
236
+ - Dark/Light theme support (follows PPTB theme)
237
+ - Lazy metadata loading
238
+ - Intelligent caching (per-session)
239
+ - Resizable split panes
240
+ - Keyboard shortcuts (Ctrl+Enter to execute)
241
+
242
+ #### Security
243
+ - Privilege-aware operations
244
+ - Export/Delete privilege checks
245
+ - Bulk delete privilege validation
246
+ - Workflow execution privilege checks
247
+
248
+ ### 🏗️ Technical
249
+
250
+ - Built with React 19 and TypeScript 5.9
251
+ - Fluent UI v9 components
252
+ - Monaco Editor integration
253
+ - ExcelJS for native Excel export
254
+ - Vite build tooling
255
+ - Power Platform ToolBox integration via @pptb/types
256
+
257
+ ### 📚 Documentation
258
+
259
+ - Comprehensive README with feature overview
260
+ - Debug logging system documentation
261
+ - Project structure guide
262
+ - Contributing guidelines
263
+
264
+ ---
265
+
266
+ ## Development History
267
+
268
+ ### Pre-release commits (dev branch)
269
+
270
+ - `feat: Beta release enhancements - Settings, Export, and UX improvements`
271
+ - `feat(preview): add LayoutXML tab to preview pane`
272
+ - `feat(commands): add record action commands - delete, bulk delete, workflow`
273
+ - `feat(columns): Add/Edit Columns panels with related entity support`
274
+ - `feat(export): add Export to Excel with status feedback and privilege check`
275
+ - `feat(paging): fix paging with cookies and page size support`
276
+ - `feat(grid): multi-entity metadata & column display name fixes`
277
+ - `feat(builder): Sprint 1 - Foundation & Layout improvements`
278
+ - `feat(save): implement Save View functionality`
279
+ - `feat(sort): Add multi-column sort with FetchXML integration`
280
+ - `feat(results): Add Column from Results Grid`
281
+ - `feat(views): Load view LayoutXML for column configuration`
282
+ - `feat(layout): Add column resize and reorder`
283
+ - `feat(layout): Add LayoutXML foundation`
284
+ - `feat(filter): Add filter link-entity support for any/not any/all scenarios`
285
+ - `feat(condition): Add valueof cross-entity comparison`
286
+ - `feat(condition): Add valueof same-row column comparison`
287
+ - `feat(condition): Add entityname support for outer join filtering`
288
+ - `feat(views): Add Load View picker and optimized view execution`
289
+ - `feat(parser): Add FetchXML parser with Monaco editor dialog`
290
+ - `feat: Implement Phases 1-4 - DataGrid UI polish`
291
+ - `feat: add filter consistency, cascading validation, and global metadata caching`
292
+ - `feat(entity-selector): implement advanced filtering with publisher/solution multiselect`
293
+ - `feat(ui): add resizable panes with visual grip indicators and command bar`
294
+ - `Initial commit - setup main branch`
package/README.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # FetchXML Studio for Power Platform ToolBox
2
2
 
3
- A powerful, modern FetchXML query builder and data explorer for [Power Platform ToolBox](https://github.com/PowerPlatformToolBox/desktop-app). Inspired by the XrmToolBox FetchXML Builder, reimagined with React 19, Fluent UI v9, and seamless Dataverse integration.
3
+ A powerful, modern FetchXML query builder and data explorer for [Power Platform ToolBox](https://github.com/PowerPlatformToolBox/desktop-app). Inspired by the XrmToolBox FetchXML Builder, reimagined with React 18, Fluent UI v9, and seamless Dataverse integration.
4
4
 
5
- ![Version](https://img.shields.io/badge/version-1.0.6-blue)
5
+ ![Version](https://img.shields.io/badge/version-1.2.2--beta.1-orange)
6
6
  ![React](https://img.shields.io/badge/React-18-61DAFB?logo=react)
7
7
  ![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178C6?logo=typescript)
8
8
  ![Fluent UI](https://img.shields.io/badge/Fluent%20UI-v9-0078D4?logo=microsoft)
9
+ ![PPTB Types](https://img.shields.io/badge/%40pptb%2Ftypes-1.2.2--beta.1-orange)
9
10
 
10
11
  ## ✨ Features
11
12
 
@@ -25,9 +26,10 @@ A powerful, modern FetchXML query builder and data explorer for [Power Platform
25
26
  - **Formatted values** — Display OData formatted values or raw values (configurable)
26
27
 
27
28
  ### 📝 FetchXML Editor
28
- - **Monaco editor** — Full-featured XML editor with syntax highlighting and line numbers
29
+ - **Monaco editor** — Full-featured XML editor with XML syntax highlighting and line numbers
29
30
  - **Bi-directional editing** — Edit XML directly and parse back to the visual builder
30
- - **Copy to clipboard** — One-click copy of generated FetchXML
31
+ - **Copy to clipboard** — One-click copy of generated FetchXML, available in both read-only and editor modes
32
+ - **Alias validation** — Invalid alias characters are sanitized in real time in the property editors; the parser auto-corrects aliases on Parse to Tree with a clear description of each correction
31
33
  - **LayoutXML preview** — See the column layout configuration
32
34
 
33
35
  ### 📥 Load & Save Views
@@ -37,29 +39,48 @@ A powerful, modern FetchXML query builder and data explorer for [Power Platform
37
39
  - **Solution-aware** — Add views to solutions during save
38
40
 
39
41
  ### 📤 Export & Data Operations
40
- - **Export to Excel** — Native Excel export with proper data types (numbers, dates, currencies)
41
- - **Formatted value options** — Export formatted, raw, or both value types
42
- - **Record deletion** — Delete selected records with confirmation
43
- - **Bulk delete jobs** — Submit async bulk delete operations to Dataverse
44
- - **Run workflows** — Execute on-demand workflows on selected records
42
+ - **Local Excel export** — Native `.xlsx` generation via ExcelJS with proper data types (numbers, dates, currencies, booleans)
43
+ - **Dataverse Excel export** — Server-side export via the `ExportToExcel` action (requires a saved view)
44
+ - **Native save dialog** — When running inside PPTB, both export paths use `fileSystem.saveFile` for a native OS save-file dialog; falls back to browser blob download in standalone/dev mode
45
+ - **Formatted value options** — Export formatted values, raw values, or both side-by-side columns
46
+ - **Record deletion** — Delete selected records with confirmation dialog
47
+ - **Bulk delete jobs** — Submit async `BulkDelete` jobs to Dataverse with job-tracking URL
48
+ - **Batch delete** — Parallel per-record delete for small sets (up to 100 records) with progress and ETA
49
+ - **Run workflows** — Execute on-demand workflows on selected records with batch execution and progress tracking
50
+
51
+ ### 📋 Bulk Attribute Selection
52
+ - **Select Attributes dialog** — Multi-select attributes from a searchable DataGrid; accessible from entity and link-entity context menus
53
+ - **Smart updates** — Adds new selections and removes deselected attributes while preserving existing order and properties
54
+ - **Search & filter** — Real-time filtering across logical name, display name, and data type columns
45
55
 
46
56
  ### 🎨 User Experience
47
57
  - **Dark/Light themes** — Follows Power Platform ToolBox theme with Fluent UI tokens
48
58
  - **Lazy metadata loading** — Loads only what's needed, when it's needed
49
- - **Intelligent caching** — In-memory cache prevents duplicate API calls
50
- - **Resizable panes** — Adjust the layout to your preference
51
- - **Keyboard shortcuts** — Execute queries, copy XML, and more
52
-
53
- ### 🔒 Privilege-Aware
54
- - **Security checks** — Validates user privileges before operations
55
- - **Export privilege check** — Only shows export option if user has access
56
- - **Delete privilege check** — Validates delete permissions per entity
59
+ - **Intelligent caching** — In-memory cache prevents duplicate API calls per session
60
+ - **Resizable panes** — Adjust split-pane layout to your preference
61
+ - **Keyboard shortcuts** — `Ctrl+Enter` to execute query, copy XML to clipboard
62
+ - **Display settings** — Toggle logical names vs display names in column headers; choose formatted, raw, or both value modes in the grid and exports
63
+ - **Query scope settings** — Control which entities appear in the entity picker: *Publisher + Solution* (full filter), *Solution Only*, or *All Entities* (no filter). Persisted across sessions.
64
+ - **Advanced Find Only toggle** — When on (default), limits entities and attributes to those marked `IsValidForAdvancedFind = true`. Disable to access all entities including system and developer tables. Filter is applied locally — toggling is instant with no additional API call.
65
+
66
+ ### � Tool-to-Tool (T2T) Integration
67
+ - **Send to Tool button** — Launch any other PPTB tool directly from FetchXML Studio, pre-loading it with the current FetchXML query and active Dataverse connection. Appears automatically when running on PPTB host ≥ 1.2.2.
68
+ - **Multi-tool picker** — Configure one or more target tools in Settings → Tool Integration. When multiple tools are configured, the button shows a dropdown menu.
69
+ - **Active connection forwarding** — The active Dataverse connection is forwarded automatically so the target tool opens against the same environment.
70
+ - **Inbound prefill** — FetchXML Studio also accepts incoming T2T invocations from other tools (see [Callee Contract](#-callee-contract-pptbconfigjson) below).
71
+
72
+ ### �🔒 Privilege-Aware
73
+ - **Export privilege check** — Only shows Dataverse export option if user has access
74
+ - **Delete privilege check** — Validates entity-specific delete permissions before enabling delete actions
75
+ - **Bulk delete privilege check** — Validates `prvBulkDelete` before surfacing bulk delete
76
+ - **Workflow privilege check** — Validates `prvReadWorkflow` + `prvWorkflowExecution` before showing workflow picker
77
+ - **View save privilege check** — Validates `prvWriteQuery` / `prvWriteCustomization` / `prvPublishCustomization` / `prvWriteUserQuery` before save operations
57
78
 
58
79
  ## 🖼️ Interface Overview
59
80
 
60
81
  ```
61
82
  ┌─────────────────────────────────────────────────────────────────────────┐
62
- │ [Entity Selector ▼] [Load View ▼] [Save View] [⚙ Settings]│
83
+ │ [Entity Selector ▼] [Load View ▼] [Save View] [Send to Tool ▼] [⚙] │
63
84
  ├──────────────────────┬──────────────────────────────────────────────────┤
64
85
  │ │ [FetchXML] [LayoutXML] [Results] [▶ Execute]│
65
86
  │ Query Tree ├──────────────────────────────────────────────────┤
@@ -114,6 +135,12 @@ npm run build
114
135
 
115
136
  # Preview production build
116
137
  npm run preview
138
+
139
+ # Validate package manifest against PPTB registry rules
140
+ npm run validate
141
+
142
+ # Finalize for publishing (build + shrinkwrap)
143
+ npm run finalize-package
117
144
  ```
118
145
 
119
146
  ### Debug Logging
@@ -138,48 +165,59 @@ disableAllDebug();
138
165
 
139
166
  ## 📦 Tech Stack
140
167
 
141
- | Technology | Purpose |
142
- |------------|---------|
143
- | **React 19** | UI framework with latest features (transitions, actions) |
144
- | **TypeScript 5.9** | Type-safe development |
145
- | **Vite** | Fast build tooling and HMR |
146
- | **Fluent UI v9** | Microsoft's design system (Tree, DataGrid, Tabs, etc.) |
147
- | **Monaco Editor** | VS Code's editor for XML editing |
148
- | **react-window** | Virtualized list rendering for large datasets |
149
- | **exceljs** | Native Excel file generation |
150
- | **@pptb/types** | Power Platform ToolBox API types |
168
+ | Technology | Version | Purpose |
169
+ |------------|---------|--------|
170
+ | **React** | 18.3 | UI framework |
171
+ | **TypeScript** | 5.9 | Type-safe development |
172
+ | **Vite** | 7 | Build tooling and HMR |
173
+ | **Fluent UI v9** | 9.72 | Microsoft design system (Tree, DataGrid, Tabs, Drawer, etc.) |
174
+ | **Monaco Editor** | 0.54 | VS Code XML editor for FetchXML authoring |
175
+ | **react-window** | 2 | Virtualized list rendering for large datasets |
176
+ | **ExcelJS** | 4.4 | Native `.xlsx` generation with typed cells |
177
+ | **@pptb/types** | 1.2.2-beta.1 | Power Platform ToolBox host API types (`window.dataverseAPI`, `window.toolboxAPI`) |
151
178
 
152
179
  ## 📁 Project Structure
153
180
 
154
181
  ```
155
182
  src/
156
183
  ├── app/
157
- │ └── AppShell.tsx # Main layout with split panes
184
+ │ └── AppShell.tsx # Main layout with resizable split panes
158
185
  ├── features/fetchxml/
159
186
  │ ├── api/
160
- │ │ ├── pptbClient.ts # Dataverse API wrapper
161
- │ │ ├── dataverseMetadata.ts # Metadata fetching
162
- │ │ ├── excelExport.ts # Excel export logic
163
- │ │ └── formattedValues.ts # OData formatted value handling
187
+ │ │ ├── pptbClient.ts # window.dataverseAPI wrapper (all Dataverse ops)
188
+ │ │ ├── dataverseMetadata.ts # Lazy metadata loading with cache + dedup
189
+ │ │ ├── excelExport.ts # Local ExcelJS export with native types
190
+ │ │ ├── formattedValues.ts # OData @FormattedValue annotation helpers
191
+ │ │ └── invocation.ts # T2T caller API (isT2TSupported, sendFetchXmlToTool)
164
192
  │ ├── model/
165
- │ │ ├── nodes.ts # TypeScript node definitions
166
- │ │ ├── fetchxml.ts # FetchXML generation
167
- │ │ ├── fetchxmlParser.ts # FetchXML parsing
193
+ │ │ ├── nodes.ts # FetchXML node TypeScript definitions
194
+ │ │ ├── fetchxml.ts # FetchXML XML generation
195
+ │ │ ├── fetchxmlParser.ts # FetchXML XML → node tree parser
196
+ │ │ ├── fetchxmlIntellisense.ts # Intellisense / autocomplete helpers
168
197
  │ │ ├── layoutxml.ts # LayoutXML generation
169
- │ │ └── operators.ts # Operator definitions by type
198
+ │ │ ├── operators.ts # Operator definitions by attribute type
199
+ │ │ ├── displaySettings.ts # Display settings types and defaults
200
+ │ │ └── treeUtils.ts # Tree traversal utilities
170
201
  │ ├── state/
171
- │ │ ├── builderStore.tsx # React context state management
172
- │ │ └── cache.ts # Metadata caching
202
+ │ │ ├── builderStore.tsx # React context + reducer state management
203
+ │ │ └── cache.ts # Per-session in-memory metadata cache
173
204
  │ └── ui/
174
- │ ├── LeftPane/ # Tree view and properties
175
- │ ├── RightPane/ # Tabs, editor, grid
176
- │ ├── Toolbar/ # Entity selector, view picker
177
- │ ├── Dialogs/ # Delete, bulk delete, workflow
178
- │ └── Settings/ # Display preferences
205
+ │ ├── LeftPane/ # Tree view + context-aware properties panel
206
+ │ │ └── PropertiesPanel/
207
+ │ │ └── editors/ # Node-specific property editors
208
+ │ ├── RightPane/ # Monaco editor, LayoutXML viewer, results grid
209
+ │ ├── Toolbar/ # Entity selector, load view picker, save button,
210
+ │ │ # send-to-tool button
211
+ │ ├── Dialogs/ # Save view, select attributes, delete, bulk
212
+ │ │ # delete, workflow picker, solution picker
213
+ │ └── Settings/ # Settings drawer (display preferences)
179
214
  └── shared/
180
- ├── components/ # Reusable pickers
181
- ├── hooks/ # Custom React hooks
182
- └── utils/ # Debug utilities
215
+ ├── components/ # Reusable value pickers (option set, boolean,
216
+ │ # date, numeric, multi-value, relationship, etc.)
217
+ ├── contexts/ # ThemeContext
218
+ ├── hooks/ # usePptbContext, useLazyMetadata, useAccessMode,
219
+ │ # usePublisherFilter, useSolutionFilter
220
+ └── utils/ # Debug logging utilities
183
221
  ```
184
222
 
185
223
  ## 🔧 FetchXML Features Support
@@ -207,6 +245,56 @@ src/
207
245
  | Filter link-entity (any/all) | ✅ |
208
246
  | Query hints | ✅ |
209
247
 
248
+ ## 🔗 Callee Contract (`pptb.config.json`)
249
+
250
+ FetchXML Studio declares a PPTB [Inter-Tool Invocation](https://github.com/PowerPlatformToolBox/desktop-app) callee contract in `pptb.config.json` at the repository root. Any other PPTB tool can launch FetchXML Studio and pre-populate it by passing a prefill payload that matches the following schema:
251
+
252
+ ```json
253
+ {
254
+ "fetchXml": "<fetch><entity name=\"account\">...</entity></fetch>",
255
+ "entityLogicalName": "account"
256
+ }
257
+ ```
258
+
259
+ | Field | Type | Required | Description |
260
+ |---|---|---|---|
261
+ | `fetchXml` | `string` | Recommended | Full serialized FetchXML query string |
262
+ | `entityLogicalName` | `string` | Recommended | Root entity logical name (e.g. `"account"`) |
263
+ | `viewRef` | `object` | Optional | EntityReference to an existing view. Use instead of `fetchXml` + `entityLogicalName` when launching from a view context. |
264
+ | `viewRef.id` | `string` (uuid) | Required if viewRef | GUID of the view record |
265
+ | `viewRef.entityLogicalName` | `"savedquery"` \| `"userquery"` | Required if viewRef | Dataverse entity logical name — `savedquery` = system/public view, `userquery` = personal view |
266
+
267
+ All fields are optional in the schema; at runtime FetchXML Studio expects either `viewRef` **or** both `fetchXml` + `entityLogicalName` to be present.
268
+
269
+ > **Note:** Callee-side behavior (consuming an inbound prefill on launch) is planned for a future release. The contract file and schema are declared now so other tools can reference them.
270
+
271
+ ### Sending a query from another PPTB tool
272
+
273
+ To launch FetchXML Studio from your own PPTB tool with a pre-loaded query:
274
+
275
+ ```typescript
276
+ await window.toolboxAPI.invocation.launchTool(
277
+ "@mohsinonxrm/pptb-fetchxml-studio",
278
+ {
279
+ fetchXml: "<fetch><entity name=\"account\"><attribute name=\"name\"/></entity></fetch>",
280
+ entityLogicalName: "account",
281
+ },
282
+ { primaryConnectionId: connection?.id ?? null },
283
+ );
284
+ ```
285
+
286
+ ### Configuring outbound targets (Send to Tool)
287
+
288
+ To send FetchXML Studio queries *to* another tool:
289
+
290
+ 1. Open **Settings** (⚙ icon in the toolbar)
291
+ 2. Scroll to **Tool Integration**
292
+ 3. Enter the target tool's npm package ID (e.g. `@linked365/pptb-bulk-data-studio`) and click **Add**
293
+
294
+ The "Send to Tool" button will appear in the toolbar. Multiple tools show a dropdown picker.
295
+
296
+ ---
297
+
210
298
  ## 🤝 Contributing
211
299
 
212
300
  Contributions are welcome! Please feel free to submit a Pull Request.
package/SECURITY.md ADDED
@@ -0,0 +1,13 @@
1
+ # Security Policy
2
+
3
+ ## Reporting a Vulnerability
4
+
5
+ Please do **not** open a public issue.
6
+ Use GitHub Security Advisories: <https://github.com/mohsinonxrm/pptb-mxrm-fetchxml-studio/security/advisories/new>
7
+
8
+ ## Scope
9
+
10
+ - Authentication flows
11
+ - Token handling
12
+ - Dataverse request logging
13
+ - Dependency vulnerabilities
@@ -0,0 +1 @@
1
+ var e={comments:{lineComment:"*"},brackets:[["[","]"],["(",")"]]},t={defaultToken:"invalid",ignoreCase:!0,tokenPostfix:".abap",keywords:["abap-source","abbreviated","abstract","accept","accepting","according","activation","actual","add","add-corresponding","adjacent","after","alias","aliases","align","all","allocate","alpha","analysis","analyzer","and","append","appendage","appending","application","archive","area","arithmetic","as","ascending","aspect","assert","assign","assigned","assigning","association","asynchronous","at","attributes","authority","authority-check","avg","back","background","backup","backward","badi","base","before","begin","between","big","binary","bintohex","bit","black","blank","blanks","blob","block","blocks","blue","bound","boundaries","bounds","boxed","break-point","buffer","by","bypassing","byte","byte-order","call","calling","case","cast","casting","catch","center","centered","chain","chain-input","chain-request","change","changing","channels","character","char-to-hex","check","checkbox","ci_","circular","class","class-coding","class-data","class-events","class-methods","class-pool","cleanup","clear","client","clob","clock","close","coalesce","code","coding","col_background","col_group","col_heading","col_key","col_negative","col_normal","col_positive","col_total","collect","color","column","columns","comment","comments","commit","common","communication","comparing","component","components","compression","compute","concat","concat_with_space","concatenate","cond","condense","condition","connect","connection","constants","context","contexts","continue","control","controls","conv","conversion","convert","copies","copy","corresponding","country","cover","cpi","create","creating","critical","currency","currency_conversion","current","cursor","cursor-selection","customer","customer-function","dangerous","data","database","datainfo","dataset","date","dats_add_days","dats_add_months","dats_days_between","dats_is_valid","daylight","dd/mm/yy","dd/mm/yyyy","ddmmyy","deallocate","decimal_shift","decimals","declarations","deep","default","deferred","define","defining","definition","delete","deleting","demand","department","descending","describe","destination","detail","dialog","directory","disconnect","display","display-mode","distinct","divide","divide-corresponding","division","do","dummy","duplicate","duplicates","duration","during","dynamic","dynpro","edit","editor-call","else","elseif","empty","enabled","enabling","encoding","end","endat","endcase","endcatch","endchain","endclass","enddo","endenhancement","end-enhancement-section","endexec","endform","endfunction","endian","endif","ending","endinterface","end-lines","endloop","endmethod","endmodule","end-of-definition","end-of-editing","end-of-file","end-of-page","end-of-selection","endon","endprovide","endselect","end-test-injection","end-test-seam","endtry","endwhile","endwith","engineering","enhancement","enhancement-point","enhancements","enhancement-section","entries","entry","enum","environment","equiv","errormessage","errors","escaping","event","events","exact","except","exception","exceptions","exception-table","exclude","excluding","exec","execute","exists","exit","exit-command","expand","expanding","expiration","explicit","exponent","export","exporting","extend","extended","extension","extract","fail","fetch","field","field-groups","fields","field-symbol","field-symbols","file","filter","filters","filter-table","final","find","first","first-line","fixed-point","fkeq","fkge","flush","font","for","form","format","forward","found","frame","frames","free","friends","from","function","functionality","function-pool","further","gaps","generate","get","giving","gkeq","gkge","global","grant","green","group","groups","handle","handler","harmless","hashed","having","hdb","header","headers","heading","head-lines","help-id","help-request","hextobin","hide","high","hint","hold","hotspot","icon","id","identification","identifier","ids","if","ignore","ignoring","immediately","implementation","implementations","implemented","implicit","import","importing","in","inactive","incl","include","includes","including","increment","index","index-line","infotypes","inheriting","init","initial","initialization","inner","inout","input","insert","instance","instances","instr","intensified","interface","interface-pool","interfaces","internal","intervals","into","inverse","inverted-date","is","iso","job","join","keep","keeping","kernel","key","keys","keywords","kind","language","last","late","layout","leading","leave","left","left-justified","leftplus","leftspace","legacy","length","let","level","levels","like","line","lines","line-count","linefeed","line-selection","line-size","list","listbox","list-processing","little","llang","load","load-of-program","lob","local","locale","locator","logfile","logical","log-point","long","loop","low","lower","lpad","lpi","ltrim","mail","main","major-id","mapping","margin","mark","mask","match","matchcode","max","maximum","medium","members","memory","mesh","message","message-id","messages","messaging","method","methods","min","minimum","minor-id","mm/dd/yy","mm/dd/yyyy","mmddyy","mode","modif","modifier","modify","module","move","move-corresponding","multiply","multiply-corresponding","name","nametab","native","nested","nesting","new","new-line","new-page","new-section","next","no","no-display","no-extension","no-gap","no-gaps","no-grouping","no-heading","no-scrolling","no-sign","no-title","no-topofpage","no-zero","node","nodes","non-unicode","non-unique","not","null","number","object","objects","obligatory","occurrence","occurrences","occurs","of","off","offset","ole","on","only","open","option","optional","options","or","order","other","others","out","outer","output","output-length","overflow","overlay","pack","package","pad","padding","page","pages","parameter","parameters","parameter-table","part","partially","pattern","percentage","perform","performing","person","pf1","pf10","pf11","pf12","pf13","pf14","pf15","pf2","pf3","pf4","pf5","pf6","pf7","pf8","pf9","pf-status","pink","places","pool","pos_high","pos_low","position","pragmas","precompiled","preferred","preserving","primary","print","print-control","priority","private","procedure","process","program","property","protected","provide","public","push","pushbutton","put","queue-only","quickinfo","radiobutton","raise","raising","range","ranges","read","reader","read-only","receive","received","receiver","receiving","red","redefinition","reduce","reduced","ref","reference","refresh","regex","reject","remote","renaming","replace","replacement","replacing","report","request","requested","reserve","reset","resolution","respecting","responsible","result","results","resumable","resume","retry","return","returncode","returning","returns","right","right-justified","rightplus","rightspace","risk","rmc_communication_failure","rmc_invalid_status","rmc_system_failure","role","rollback","rows","rpad","rtrim","run","sap","sap-spool","saving","scale_preserving","scale_preserving_scientific","scan","scientific","scientific_with_leading_zero","scroll","scroll-boundary","scrolling","search","secondary","seconds","section","select","selection","selections","selection-screen","selection-set","selection-sets","selection-table","select-options","send","separate","separated","set","shared","shift","short","shortdump-id","sign_as_postfix","single","size","skip","skipping","smart","some","sort","sortable","sorted","source","specified","split","spool","spots","sql","sqlscript","stable","stamp","standard","starting","start-of-editing","start-of-selection","state","statement","statements","static","statics","statusinfo","step-loop","stop","structure","structures","style","subkey","submatches","submit","subroutine","subscreen","subtract","subtract-corresponding","suffix","sum","summary","summing","supplied","supply","suppress","switch","switchstates","symbol","syncpoints","syntax","syntax-check","syntax-trace","system-call","system-exceptions","system-exit","tab","tabbed","table","tables","tableview","tabstrip","target","task","tasks","test","testing","test-injection","test-seam","text","textpool","then","throw","time","times","timestamp","timezone","tims_is_valid","title","titlebar","title-lines","to","tokenization","tokens","top-lines","top-of-page","trace-file","trace-table","trailing","transaction","transfer","transformation","translate","transporting","trmac","truncate","truncation","try","tstmp_add_seconds","tstmp_current_utctimestamp","tstmp_is_valid","tstmp_seconds_between","type","type-pool","type-pools","types","uline","unassign","under","unicode","union","unique","unit_conversion","unix","unpack","until","unwind","up","update","upper","user","user-command","using","utf-8","valid","value","value-request","values","vary","varying","verification-message","version","via","view","visible","wait","warning","when","whenever","where","while","width","window","windows","with","with-heading","without","with-title","word","work","write","writer","xml","xsd","yellow","yes","yymmdd","zero","zone","abap_system_timezone","abap_user_timezone","access","action","adabas","adjust_numbers","allow_precision_loss","allowed","amdp","applicationuser","as_geo_json","as400","associations","balance","behavior","breakup","bulk","cds","cds_client","check_before_save","child","clients","corr","corr_spearman","cross","cycles","datn_add_days","datn_add_months","datn_days_between","dats_from_datn","dats_tims_to_tstmp","dats_to_datn","db2","db6","ddl","dense_rank","depth","deterministic","discarding","entities","entity","error","failed","finalize","first_value","fltp_to_dec","following","fractional","full","graph","grouping","hierarchy","hierarchy_ancestors","hierarchy_ancestors_aggregate","hierarchy_descendants","hierarchy_descendants_aggregate","hierarchy_siblings","incremental","indicators","lag","last_value","lead","leaves","like_regexpr","link","locale_sap","lock","locks","many","mapped","matched","measures","median","mssqlnt","multiple","nodetype","ntile","nulls","occurrences_regexpr","one","operations","oracle","orphans","over","parent","parents","partition","pcre","period","pfcg_mapping","preceding","privileged","product","projection","rank","redirected","replace_regexpr","reported","response","responses","root","row","row_number","sap_system_date","save","schema","session","sets","shortdump","siblings","spantree","start","stddev","string_agg","subtotal","sybase","tims_from_timn","tims_to_timn","to_blob","to_clob","total","trace-entry","tstmp_to_dats","tstmp_to_dst","tstmp_to_tims","tstmpl_from_utcl","tstmpl_to_utcl","unbounded","utcl_add_seconds","utcl_current","utcl_seconds_between","uuid","var","verbatim"],builtinFunctions:["abs","acos","asin","atan","bit-set","boolc","boolx","ceil","char_off","charlen","cmax","cmin","concat_lines_of","contains","contains_any_not_of","contains_any_of","cos","cosh","count","count_any_not_of","count_any_of","dbmaxlen","distance","escape","exp","find_any_not_of","find_any_of","find_end","floor","frac","from_mixed","ipow","line_exists","line_index","log","log10","matches","nmax","nmin","numofchar","repeat","rescale","reverse","round","segment","shift_left","shift_right","sign","sin","sinh","sqrt","strlen","substring","substring_after","substring_before","substring_from","substring_to","tan","tanh","to_lower","to_mixed","to_upper","trunc","utclong_add","utclong_current","utclong_diff","xsdbool","xstrlen"],typeKeywords:["b","c","d","decfloat16","decfloat34","f","i","int8","n","p","s","string","t","utclong","x","xstring","any","clike","csequence","decfloat","numeric","simple","xsequence","accp","char","clnt","cuky","curr","datn","dats","d16d","d16n","d16r","d34d","d34n","d34r","dec","df16_dec","df16_raw","df34_dec","df34_raw","fltp","geom_ewkb","int1","int2","int4","lang","lchr","lraw","numc","quan","raw","rawstring","sstring","timn","tims","unit","utcl","df16_scl","df34_scl","prec","varc","abap_bool","abap_false","abap_true","abap_undefined","me","screen","space","super","sy","syst","table_line","*sys*"],builtinMethods:["class_constructor","constructor"],derivedTypes:["%CID","%CID_REF","%CONTROL","%DATA","%ELEMENT","%FAIL","%KEY","%MSG","%PARAM","%PID","%PID_ASSOC","%PID_PARENT","%_HINTS"],cdsLanguage:["@AbapAnnotation","@AbapCatalog","@AccessControl","@API","@ClientDependent","@ClientHandling","@CompatibilityContract","@DataAging","@EndUserText","@Environment","@LanguageDependency","@MappingRole","@Metadata","@MetadataExtension","@ObjectModel","@Scope","@Semantics","$EXTENSION","$SELF"],selectors:["->","->*","=>","~","~*"],operators:[" +"," -","/","*","**","div","mod","=","#","@","+=","-=","*=","/=","**=","&&=","?=","&","&&","bit-and","bit-not","bit-or","bit-xor","m","o","z","<"," >","<=",">=","<>","><","=<","=>","bt","byte-ca","byte-cn","byte-co","byte-cs","byte-na","byte-ns","ca","cn","co","cp","cs","eq","ge","gt","le","lt","na","nb","ne","np","ns","*/","*:","--","/*","//"],symbols:/[=><!~?&+\-*\/\^%#@]+/,tokenizer:{root:[[/[a-z_\/$%@]([\w\/$%]|-(?!>))*/,{cases:{"@typeKeywords":"type","@keywords":"keyword","@cdsLanguage":"annotation","@derivedTypes":"type","@builtinFunctions":"type","@builtinMethods":"type","@operators":"key","@default":"identifier"}}],[/<[\w]+>/,"identifier"],[/##[\w|_]+/,"comment"],{include:"@whitespace"},[/[:,.]/,"delimiter"],[/[{}()\[\]]/,"@brackets"],[/@symbols/,{cases:{"@selectors":"tag","@operators":"key","@default":""}}],[/'/,{token:"string",bracket:"@open",next:"@stringquote"}],[/`/,{token:"string",bracket:"@open",next:"@stringping"}],[/\|/,{token:"string",bracket:"@open",next:"@stringtemplate"}],[/\d+/,"number"]],stringtemplate:[[/[^\\\|]+/,"string"],[/\\\|/,"string"],[/\|/,{token:"string",bracket:"@close",next:"@pop"}]],stringping:[[/[^\\`]+/,"string"],[/`/,{token:"string",bracket:"@close",next:"@pop"}]],stringquote:[[/[^\\']+/,"string"],[/'/,{token:"string",bracket:"@close",next:"@pop"}]],whitespace:[[/[ \t\r\n]+/,""],[/^\*.*$/,"comment"],[/\".*$/,"comment"]]}};export{e as conf,t as language};