pptb-standard-sample-tool
v1.1.11
Published
A sample Power Platform ToolBox tool built with HTML, CSS, and TypeScript
Downloads
1,360
Maintainers
Readme
HTML Sample Tool
A complete example tool for Power Platform Tool Box built with HTML, CSS, and TypeScript.
Features
This sample demonstrates:
✅ ToolBox API Integration
- Connection management and status display
- Notifications (success, info, warning, error)
- Clipboard operations
- File save dialogs
- Tool settings storage (save/load/clear)
- Theme detection
- Terminal creation and command execution
- Event subscription and handling
✅ Dataverse API Usage
- FetchXML queries
- Multi-connection queries (primary and secondary)
- CRUD operations (Create, Read, Update, Delete)
- Entity metadata retrieval
- Error handling
✅ Best Practices
- TypeScript with full type safety
- Event-driven architecture
- Proper error handling
- Clean, modern UI design
- Responsive layout
Installation
Prerequisites
- Node.js 18 or higher
- Power Platform Tool Box desktop application
Install Dependencies
npm installBuild
npm run buildThis compiles the TypeScript source in src/ to JavaScript in dist/.
Project Structure
html-sample/
├── src/
│ ├── app.ts # Main application logic (TypeScript)
│ ├── features/ # UI feature modules (terminal, filesystem, etc.)
│ ├── security/ # Security policy + test suites
│ └── utils/ # Small reusable helpers
├── index.html # Main HTML file (entry point)
├── styles.css # Stylesheet
├── package.json # Package configuration
├── tsconfig.json # TypeScript configuration
└── README.md # This fileUsage
Install in Power Platform Tool Box
- Open Power Platform Tool Box
- Go to Tools section
- Click "Install Tool"
- Enter the path to this directory or publish to npm and use the package name
Features Overview
Connection Status
- Shows current Dataverse connection details
- Displays environment type (Production, Sandbox, Dev)
- Updates automatically when connection changes
ToolBox API Examples
Notifications:
- Test different notification types
- Success, info, warning, and error messages
Utilities:
- Copy data to clipboard
- Get current theme (light/dark)
- Save data to file with native dialog
Terminal:
- Create isolated terminal instances
- Execute shell commands
- Run a safe terminal security probe (non-destructive)
- Run API-specific security test suites with pass/fail JSON reports
- View command output
- Close terminal when done
Dataverse API Examples
Query Records:
- FetchXML query to retrieve top 10 accounts
- Display results with formatting
- If a FetchXML is saved in Tool Settings, the Query button will use that instead of the default
- This sample supports multi-connection: try the "Secondary" buttons to run the same queries against the secondary connection
CRUD Operations:
- Create new account records
- Update existing records
- Delete records
- Full error handling
Metadata:
- Retrieve entity metadata
- Display entity information and attributes
Event Log
- Real-time event logging
- Color-coded by severity
- Timestamp for each entry
- Clear log functionality
Development
Watch Mode
During development, you can use watch mode to automatically recompile on changes:
npm run watchType Safety
This tool uses TypeScript with the @pptb/types package for full type safety:
/// <reference types="@pptb/types" />
// Type-safe API access
const toolbox: typeof window.toolboxAPI = window.toolboxAPI;
const dataverse: typeof window.dataverseAPI = window.dataverseAPI;Customization
- Modify UI: Edit
index.htmlandstyles.css - Add Features: Update
src/app.ts - Rebuild: Run
npm run build - Reload Tool: In Power Platform Tool Box, close and reopen the tool
Security Testing Guidance
Use the built-in Run Security Probe button in the Terminal section to validate terminal exposure with safe commands only.
What it checks:
- Terminal can be created and receives command output
- Basic command execution works
- Command chaining is possible (risk signal if unrestricted)
What it does not do:
- No destructive commands
- No credential, SSH, or private file access attempts
- No process memory dumping attempts
If the probe succeeds, treat that as a signal to enforce stricter host-side controls in Power Platform Tool Box:
- Command allow-listing
- Path allow-listing for filesystem APIs
- Auditing/logging for terminal command execution
This sample now includes policy guards in src/security/policy.ts:
getBlockedCommandReason(...)/getBlockedPathReason(...): policy decisionsexecuteCommandWithPolicyGuard(...)/readTextWithPolicyGuard(...): central enforcement wrappers
Security suites and report formatting live in:
It also includes API-specific Security Suite buttons plus an All Suites runner. Each suite emits a JSON report with per-test severity and a rolled-up highestSeverity:
- Terminal suite: command allow-list enforcement, multiline/control-character blocking, overlong command blocking, local-data-to-network exfil pattern blocking, burst handling
- FileSystem suite: absolute-path enforcement, traversal blocking, sensitive path blocking, guarded read rejection checks, API surface checks
- Events suite: event API presence and malformed payload resilience checks
- Settings suite: API surface checks, set/get roundtrip checks, optional setAll/getAll validation
- Dataverse suite: method surface checks and read-only runtime checks (WhoAmI/query) when connected
For production PPTB host hardening, apply equivalent checks in the host process (server-side / main-process boundary), not only in tool UI code.
API Usage Examples
Advanced Utilities
Below demonstrates using executeParallel to run multiple Dataverse operations concurrently, and wrapping work with showLoading / hideLoading:
// Execute multiple operations in parallel
const [account, contact, opportunities] = await toolboxAPI.utils.executeParallel(
dataverseAPI.retrieve('account', accountId, ['name']),
dataverseAPI.retrieve('contact', contactId, ['fullname']),
dataverseAPI.fetchXmlQuery(opportunityFetchXml)
);
console.log('All data fetched:', account, contact, opportunities);
// Show loading screen during operations
await toolboxAPI.utils.showLoading('Processing data...');
try {
// Perform operations
await processData();
} finally {
// Always hide loading
await toolboxAPI.utils.hideLoading();
}In this HTML sample, the "Run Parallel Demo" button issues three light FetchXML queries simultaneously using toolbox.utils.executeParallel, and the "Run Loading Demo" button shows a loading overlay while either performing a quick query (if connected) or simulating work.
Tool Settings Storage
Use the tool settings API to persist user preferences and configuration for your tool. This storage is scoped per tool.
// Save a setting
await toolboxAPI.settings.set('demo.fetchxml', myFetchXmlString);
// Read a setting
const saved = await toolboxAPI.settings.get('demo.fetchxml');
// Delete a setting
await toolboxAPI.settings.delete('demo.fetchxml');In this sample, the “Tool Settings” section lets you save a FetchXML snippet. The “Query Top 10 Accounts” button will use the saved FetchXML if present, otherwise it falls back to the default.
ToolBox API
// Show notification
await toolbox.utils.showNotification({
title: 'Success',
body: 'Operation completed',
type: 'success',
duration: 3000
});
// Get active connection
const connection = await toolbox.connections.getActiveConnection();
// Create terminal
const terminal = await toolbox.terminal.create({
name: 'My Terminal'
});
// Subscribe to events
toolbox.events.on((event, payload) => {
console.log('Event:', payload.event, payload.data);
});Dataverse API
// Query with FetchXML
const result = await dataverse.fetchXmlQuery(`
<fetch top="10">
<entity name="account">
<attribute name="name" />
</entity>
</fetch>
`);
// Query with FetchXML targeting the secondary connection
const secondaryResult = await dataverse.fetchXmlQuery(`
<fetch top="5">
<entity name="account">
<attribute name="name" />
<order attribute="name" />
</entity>
</fetch>
`, 'secondary');
// Create record
const account = await dataverse.create('account', {
name: 'Contoso Ltd',
emailaddress1: '[email protected]'
});
// Update record
await dataverse.update('account', accountId, {
telephone1: '555-0100'
});
// Delete record
await dataverse.delete('account', accountId);
// Get metadata
const metadata = await dataverse.getEntityMetadata('account');
// Get metadata on secondary
const metadataSecondary = await dataverse.getEntityMetadata('account', true, ['LogicalName'], 'secondary');Troubleshooting
Build Errors
If you encounter TypeScript errors:
- Ensure
@pptb/typesis installed:npm install - Check TypeScript version:
tsc --version(should be 5.x) - Clean and rebuild:
rm -rf dist && npm run build
API Not Available
If toolboxAPI or dataverseAPI is undefined:
- The tool must be loaded within Power Platform Tool Box
- These APIs are injected by the toolboxAPIBridge
- They are not available in a standalone browser
Connection Issues
If connection is null:
- Open Power Platform Tool Box
- Create a connection to a Dataverse environment
- The tool will automatically detect the connection
Resources
License
GPL-3.0 - See LICENSE file in repository root
