@pptb/types 1.2.4-beta.0 → 1.2.4-beta.2

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/README.md CHANGED
@@ -8,7 +8,7 @@ TypeScript type definitions for Power Platform ToolBox APIs, plus a built-in CLI
8
8
  - [Quick start](#quick-start)
9
9
  - [CLI options](#cli-options)
10
10
  - [What is validated](#what-is-validated)
11
- - [pptb.config.json (optional)](#pptbconfigjson-optional)
11
+ - [pptb.config.json (optional)](#pptbconfigjson-optional)
12
12
  - [Overview](#overview)
13
13
  - [Usage](#usage)
14
14
  - [Include all type definitions](#include-all-type-definitions)
@@ -19,22 +19,12 @@ TypeScript type definitions for Power Platform ToolBox APIs, plus a built-in CLI
19
19
  - [Terminal Operations](#terminal-operations)
20
20
  - [Events](#events)
21
21
  - [Inter-Tool Invocation](#inter-tool-invocation)
22
- - [Caller: launching another tool with prefill data](#caller-launching-another-tool-with-prefill-data)
23
- - [Caller: tag-based capability discovery](#caller-tag-based-capability-discovery)
24
- - [Callee: reading prefill data and returning a result](#callee-reading-prefill-data-and-returning-a-result)
25
- - [Declaring your invocation contract](#declaring-your-invocation-contract)
26
22
  - [Dataverse API Examples](#dataverse-api-examples)
27
23
  - [CRUD Operations](#crud-operations)
28
24
  - [FetchXML Queries](#fetchxml-queries)
29
25
  - [Metadata Operations](#metadata-operations)
30
26
  - [Execute Actions/Functions](#execute-actionsfunctions)
31
27
  - [Deploy Solutions](#deploy-solutions)
32
- - [Power Platform API Examples](#power-platform-api-examples)
33
- - [Using Power Apps API](#using-power-apps-api)
34
- - [Using Power Automate API](#using-power-automate-api)
35
- - [Using Environment Management API](#using-environment-management-api)
36
- - [Using Governance API](#using-governance-api)
37
- - [Available Categories](#available-categories)
38
28
  - [API Reference](#api-reference)
39
29
  - [ToolBox API (`window.toolboxAPI`)](#toolbox-api-windowtoolboxapi)
40
30
  - [Connections](#connections-1)
@@ -47,8 +37,6 @@ TypeScript type definitions for Power Platform ToolBox APIs, plus a built-in CLI
47
37
  - [Query Operations](#query-operations)
48
38
  - [Metadata Operations](#metadata-operations-1)
49
39
  - [Advanced Operations](#advanced-operations)
50
- - [Power Platform API (`window.powerplatformAPI`)](#power-platform-api-windowpowerplatformapi)
51
- - [Category Methods](#category-methods)
52
40
  - [Security Notes](#security-notes)
53
41
  - [Publishing the package to npm](#publishing-the-package-to-npm)
54
42
  - [License](#license)
@@ -128,14 +116,14 @@ The validator checks every field that the official review pipeline inspects:
128
116
 
129
117
  In addition to `package.json`, the validator automatically checks a `pptb.config.json` file if one is present in the same directory. This file declares tool-to-tool communication contracts and other PPTB-specific metadata.
130
118
 
131
- | Field | Required | Rules |
132
- | ----------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
133
- | `invocation.version` | ✅\*\* | Must be a valid **semantic version** string (e.g. `"1.0.0"`). Tool developers own this version and bump it when the invocation contract changes. |
134
- | `invocation.capabilities` | ❌ | Array of non-empty string tags (e.g. `["entity-picker"]`). Used by callers to discover this tool via `findToolsByCapability`. |
135
- | `invocation.prefill` | ❌ | JSON-schema-style object describing data callers can pre-populate |
136
- | `invocation.prefill.properties` | ❌ | Map of property names to `{ type?, enum?, items? }` descriptors |
137
- | `invocation.returnTopic` | ❌ | JSON-schema-style object describing the data this tool returns to its caller |
138
- | `invocation.returnTopic.properties` | ❌ | Map of property names to `{ type?, enum?, items? }` descriptors |
119
+ | Field | Required | Rules |
120
+ | --------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
121
+ | `invocation.version` | ✅\*\* | Must be a valid **semantic version** string (e.g. `"1.0.0"`). Tool developers own this version and bump it when the invocation contract changes. |
122
+ | `invocation.capabilities` | ❌ | Array of non-empty string tags (e.g. `["entity-picker"]`). Used by callers to discover this tool via `findToolsByCapability`. |
123
+ | `invocation.prefill` | ❌ | JSON-schema-style object describing data callers can pre-populate |
124
+ | `invocation.prefill.properties` | ❌ | Map of property names to `{ type?, enum?, items? }` descriptors |
125
+ | `invocation.returnTopic` | ❌ | JSON-schema-style object describing the data this tool returns to its caller |
126
+ | `invocation.returnTopic.properties` | ❌ | Map of property names to `{ type?, enum?, items? }` descriptors |
139
127
 
140
128
  > \*\* Required only when the `invocation` object is present.
141
129
 
@@ -165,11 +153,10 @@ In addition to `package.json`, the validator automatically checks a `pptb.config
165
153
 
166
154
  ## Overview
167
155
 
168
- The `@pptb/types` package provides TypeScript definitions for three main APIs:
156
+ The `@pptb/types` package provides TypeScript definitions for two main APIs:
169
157
 
170
158
  1. **ToolBox API** (`window.toolboxAPI`) - Core platform features (connections, utilities, terminals, events)
171
159
  2. **Dataverse API** (`window.dataverseAPI`) - Microsoft Dataverse Web API operations
172
- 3. **Power Platform API** (`window.powerplatformAPI`) - Power Platform Admin APIs with generic HTTP methods
173
160
 
174
161
  ## Usage
175
162
 
@@ -178,10 +165,9 @@ The `@pptb/types` package provides TypeScript definitions for three main APIs:
178
165
  ```typescript
179
166
  /// <reference types="@pptb/types" />
180
167
 
181
- // All APIs are now available
168
+ // Both APIs are now available
182
169
  const toolbox = window.toolboxAPI;
183
170
  const dataverse = window.dataverseAPI;
184
- const powerplatform = window.powerplatformAPI;
185
171
  ```
186
172
 
187
173
  ### Include specific API types
@@ -192,9 +178,6 @@ const powerplatform = window.powerplatformAPI;
192
178
 
193
179
  // Only Dataverse API types
194
180
  /// <reference types="@pptb/types/dataverseAPI" />
195
-
196
- // Only Power Platform API types
197
- /// <reference types="@pptb/types/powerplatformAPI" />
198
181
  ```
199
182
 
200
183
  ## ToolBox API Examples
@@ -316,7 +299,10 @@ Tools can launch one another and pass data between them using the `invocation` n
316
299
  ```typescript
317
300
  // Tool A – launches the entity-picker tool and waits for a selection
318
301
  // The callee automatically inherits this tool's FXS connection
319
- const result = await toolboxAPI.invocation.launchTool("@my-org/entity-picker", { entityName: "account", allowMultiSelect: false });
302
+ const result = await toolboxAPI.invocation.launchTool(
303
+ "@my-org/entity-picker",
304
+ { entityName: "account", allowMultiSelect: false },
305
+ );
320
306
 
321
307
  if (result !== null) {
322
308
  console.log("Selected record id:", (result as { selectedId: string }).selectedId);
@@ -353,7 +339,7 @@ if (ctx) {
353
339
  }
354
340
  ```
355
341
 
356
- > **Tip:** A tool that was _not_ launched by another tool receives `null` from `getLaunchContext()`.
342
+ > **Tip:** A tool that was *not* launched by another tool receives `null` from `getLaunchContext()`.
357
343
  > Use this to show a standalone UI or redirect accordingly.
358
344
 
359
345
  > **Auto-close**: after calling `returnData`, PPTB automatically closes the callee window. The callee does **not** need to close itself.
@@ -537,84 +523,9 @@ await waitForImport(result.ImportJobId);
537
523
 
538
524
  > **Note:** `deploySolution` automatically supplies `PublishWorkflows` and `OverwriteUnmanagedCustomizations` with a default value of `false` when you do not specify them, aligning with Dataverse's ImportSolution requirements.
539
525
 
540
- ## Power Platform API Examples
541
-
542
- The Power Platform API provides generic HTTP methods for all Power Platform Admin API categories:
543
-
544
- ### Using Power Apps API
545
-
546
- ```typescript
547
- // Get an admin app
548
- const app = await powerplatformAPI.PowerApps.Get("environments/{environmentId}/apps/{app}?api-version=2024-10-01");
549
-
550
- // List all apps in an environment
551
- const apps = await powerplatformAPI.PowerApps.Get("environments/{environmentId}/apps?api-version=2024-10-01");
552
-
553
- // Create a new app
554
- await powerplatformAPI.PowerApps.Post("environments/{environmentId}/apps?api-version=2024-10-01", {
555
- name: "My App",
556
- environmentId: "{environmentId}",
557
- });
558
-
559
- // Update an app
560
- await powerplatformAPI.PowerApps.Patch("environments/{environmentId}/apps/{appId}?api-version=2024-10-01", {
561
- name: "Updated App Name",
562
- });
563
-
564
- // Delete an app
565
- await powerplatformAPI.PowerApps.Delete("environments/{environmentId}/apps/{appId}?api-version=2024-10-01");
566
- ```
567
-
568
- ### Using Power Automate API
569
-
570
- ```typescript
571
- // List flows
572
- const flows = await powerplatformAPI.PowerAutomate.Get("environments/{environmentId}/flows?api-version=2024-10-01");
573
-
574
- // Get flow details
575
- const flow = await powerplatformAPI.PowerAutomate.Get("environments/{environmentId}/flows/{flowId}?api-version=2024-10-01");
576
- ```
577
-
578
- ### Using Environment Management API
579
-
580
- ```typescript
581
- // List environments
582
- const environments = await powerplatformAPI.EnvironmentManagement.Get("environments?api-version=2024-10-01");
583
-
584
- // Get environment details
585
- const env = await powerplatformAPI.EnvironmentManagement.Get("environments/{environmentId}?api-version=2024-10-01");
586
- ```
587
-
588
- ### Using Governance API
589
-
590
- ```typescript
591
- // Get governance data
592
- const data = await powerplatformAPI.Governance.Get("environments/{environmentId}/governance?api-version=2024-10-01");
593
- ```
594
-
595
- ### Available Categories
596
-
597
- The Power Platform API exposes the following categories, each with `Get`, `Post`, `Put`, `Patch`, and `Delete` methods:
598
-
599
- - **Analytics** - `https://api.powerplatform.com/analytics`
600
- - **AppManagement** - `https://api.powerplatform.com/appmanagement`
601
- - **Authorization** - `https://api.powerplatform.com/authorization`
602
- - **Connectivity** - `https://api.powerplatform.com/connectivity`
603
- - **CopilotStudio** - `https://api.powerplatform.com/copilotstudio`
604
- - **Dynamics** - `https://api.powerplatform.com/dynamics`
605
- - **EnvironmentManagement** - `https://api.powerplatform.com/environmentmanagement`
606
- - **Governance** - `https://api.powerplatform.com/governance`
607
- - **Licensing** - `https://api.powerplatform.com/licensing`
608
- - **PowerApps** - `https://api.powerplatform.com/powerapps`
609
- - **PowerAutomate** - `https://api.powerplatform.com/powerautomate`
610
- - **PowerPages** - `https://api.powerplatform.com/powerpages`
611
- - **ResourceQuery** - `https://api.powerplatform.com/resourcequery`
612
- - **UserManagement** - `https://api.powerplatform.com/usermanagement`
613
- - **WorkflowAgents** - `https://api.powerplatform.com/workflowagents`
614
-
615
526
  ## API Reference
616
527
 
617
- The Power Platform ToolBox exposes three main APIs to tools:
528
+ The Power Platform ToolBox exposes two main APIs to tools:
618
529
 
619
530
  ### ToolBox API (`window.toolboxAPI`)
620
531
 
@@ -786,50 +697,6 @@ Complete HTTP client for interacting with Microsoft Dataverse:
786
697
  - Returns import job details including progress, completion status, and error information
787
698
  - Use to track the progress of a solution deployment initiated with deploySolution
788
699
 
789
- ### Power Platform API (`window.powerplatformAPI`)
790
-
791
- Generic HTTP client for Power Platform Admin APIs covering all categories:
792
-
793
- #### Category Methods
794
-
795
- Each category (Analytics, AppManagement, Authorization, Connectivity, CopilotStudio, Dynamics, EnvironmentManagement, Governance, Licensing, PowerApps, PowerAutomate, PowerPages, ResourceQuery, UserManagement, WorkflowAgents) exposes:
796
-
797
- - **Get(path?, connectionTarget?, headers?)**: Promise<PowerPlatformResponse>
798
- - Makes a GET request to the category endpoint
799
- - Example: `powerplatformAPI.PowerApps.Get('environments/{environmentId}/apps/{app}?api-version=2024-10-01')`
800
-
801
- - **Post(path?, body?, connectionTarget?, headers?)**: Promise<PowerPlatformResponse>
802
- - Makes a POST request to the category endpoint
803
-
804
- - **Put(path?, body?, connectionTarget?, headers?)**: Promise<PowerPlatformResponse>
805
- - Makes a PUT request to the category endpoint
806
-
807
- - **Patch(path?, body?, connectionTarget?, headers?)**: Promise<PowerPlatformResponse>
808
- - Makes a PATCH request to the category endpoint
809
-
810
- - **Delete(path?, connectionTarget?, headers?, body?)**: Promise<PowerPlatformResponse>
811
- - Makes a DELETE request to the category endpoint
812
-
813
- Available categories and their base URLs:
814
-
815
- | Category | Base URL |
816
- | --------------------- | ----------------------------------------------------- |
817
- | Analytics | `https://api.powerplatform.com/analytics` |
818
- | AppManagement | `https://api.powerplatform.com/appmanagement` |
819
- | Authorization | `https://api.powerplatform.com/authorization` |
820
- | Connectivity | `https://api.powerplatform.com/connectivity` |
821
- | CopilotStudio | `https://api.powerplatform.com/copilotstudio` |
822
- | Dynamics | `https://api.powerplatform.com/dynamics` |
823
- | EnvironmentManagement | `https://api.powerplatform.com/environmentmanagement` |
824
- | Governance | `https://api.powerplatform.com/governance` |
825
- | Licensing | `https://api.powerplatform.com/licensing` |
826
- | PowerApps | `https://api.powerplatform.com/powerapps` |
827
- | PowerAutomate | `https://api.powerplatform.com/powerautomate` |
828
- | PowerPages | `https://api.powerplatform.com/powerpages` |
829
- | ResourceQuery | `https://api.powerplatform.com/resourcequery` |
830
- | UserManagement | `https://api.powerplatform.com/usermanagement` |
831
- | WorkflowAgents | `https://api.powerplatform.com/workflowagents` |
832
-
833
700
  ### Security Notes
834
701
 
835
702
  - **Access Tokens**: Tools do NOT have direct access to access tokens. All Dataverse operations are authenticated automatically by the platform.
@@ -1,244 +1,2 @@
1
1
  #!/usr/bin/env node
2
- // @ts-check
3
- "use strict";
4
-
5
- /**
6
- * pptb-validate - CLI tool for validating Power Platform ToolBox tool packages
7
- *
8
- * Usage:
9
- * pptb-validate [options] [path/to/package.json]
10
- *
11
- * Options:
12
- * --skip-url-checks Skip URL accessibility checks (faster, offline-friendly)
13
- * --json Output results as JSON
14
- * --help, -h Show help information
15
- */
16
-
17
- const fs = require("fs");
18
- const path = require("path");
19
- const { validatePackageJson, validatePPTBConfig, KNOWN_CAPABILITY_TAGS } = require("../lib/validate");
20
-
21
- // ANSI colour helpers – gracefully degrade when colours are unsupported
22
- const NO_COLOR = !process.stdout.isTTY || process.env.NO_COLOR;
23
- const c = {
24
- red: (s) => (NO_COLOR ? s : `\x1b[31m${s}\x1b[0m`),
25
- yellow: (s) => (NO_COLOR ? s : `\x1b[33m${s}\x1b[0m`),
26
- green: (s) => (NO_COLOR ? s : `\x1b[32m${s}\x1b[0m`),
27
- cyan: (s) => (NO_COLOR ? s : `\x1b[36m${s}\x1b[0m`),
28
- bold: (s) => (NO_COLOR ? s : `\x1b[1m${s}\x1b[0m`),
29
- dim: (s) => (NO_COLOR ? s : `\x1b[2m${s}\x1b[0m`),
30
- };
31
-
32
- function printHelp() {
33
- console.log(`
34
- ${c.bold("pptb-validate")} – Power Platform ToolBox tool validator
35
-
36
- ${c.bold("USAGE")}
37
- pptb-validate [options] [path/to/package.json]
38
-
39
- When no path is given the tool looks for ${c.cyan("package.json")} in the current
40
- working directory. If a ${c.cyan("pptb.config.json")} file exists in the same directory
41
- it is automatically validated as well.
42
-
43
- ${c.bold("OPTIONS")}
44
- ${c.cyan("--skip-url-checks")} Skip URL reachability checks (faster, works offline)
45
- ${c.cyan("--json")} Print results as a JSON object instead of human-readable text
46
- ${c.cyan("--help")}, ${c.cyan("-h")} Show this help message
47
-
48
- ${c.bold("ADD TO YOUR TOOL'S package.json")}
49
- ${c.dim(`"scripts": {
50
- "validate": "pptb-validate"
51
- }`)}
52
-
53
- Then run: ${c.cyan("npm run validate")}
54
-
55
- ${c.bold("EXAMPLES")}
56
- npm run validate
57
- npm run validate ./my-tool/package.json
58
- npm run validate --skip-url-checks
59
- npm run validate --json
60
- `);
61
- }
62
-
63
- async function main() {
64
- const args = process.argv.slice(2);
65
-
66
- if (args.includes("--help") || args.includes("-h")) {
67
- printHelp();
68
- process.exit(0);
69
- }
70
-
71
- const skipUrlChecks = args.includes("--skip-url-checks");
72
- const jsonOutput = args.includes("--json");
73
-
74
- // Find the package.json path from positional args (skip flags)
75
- const positional = args.filter((a) => !a.startsWith("-"));
76
- let packageJsonPath = positional[0] || path.join(process.cwd(), "package.json");
77
-
78
- // Resolve to absolute path
79
- if (!path.isAbsolute(packageJsonPath)) {
80
- packageJsonPath = path.resolve(process.cwd(), packageJsonPath);
81
- }
82
-
83
- // Derive pptb.config.json path from the same directory as package.json
84
- const toolDir = path.dirname(packageJsonPath);
85
- const pptbConfigPath = path.join(toolDir, "pptb.config.json");
86
-
87
- // --- Load package.json ---
88
- if (!fs.existsSync(packageJsonPath)) {
89
- if (jsonOutput) {
90
- console.log(JSON.stringify({ valid: false, errors: [`package.json not found at: ${packageJsonPath}`], warnings: [] }, null, 2));
91
- } else {
92
- console.error(c.red(`✖ package.json not found at: ${packageJsonPath}`));
93
- }
94
- process.exit(1);
95
- }
96
-
97
- let packageJson;
98
- try {
99
- packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
100
- } catch (err) {
101
- const message = err instanceof Error ? err.message : String(err);
102
- if (jsonOutput) {
103
- console.log(JSON.stringify({ valid: false, errors: [`Failed to parse package.json: ${message}`], warnings: [] }, null, 2));
104
- } else {
105
- console.error(c.red(`✖ Failed to parse package.json: ${message}`));
106
- }
107
- process.exit(1);
108
- }
109
-
110
- // --- Load pptb.config.json (optional) ---
111
- let pptbConfig = null;
112
- let pptbConfigParseError = null;
113
- if (fs.existsSync(pptbConfigPath)) {
114
- try {
115
- pptbConfig = JSON.parse(fs.readFileSync(pptbConfigPath, "utf8"));
116
- } catch (err) {
117
- pptbConfigParseError = err instanceof Error ? err.message : String(err);
118
- }
119
- }
120
-
121
- // --- Run validation ---
122
- if (!jsonOutput) {
123
- console.log();
124
- console.log(c.bold("Power Platform ToolBox – Tool Validator"));
125
- console.log(c.dim("─".repeat(45)));
126
- console.log(c.dim(`File: ${packageJsonPath}`));
127
- if (pptbConfig !== null) {
128
- console.log(c.dim(`Config: ${pptbConfigPath}`));
129
- }
130
- if (skipUrlChecks) {
131
- console.log(c.yellow("⚠ URL reachability checks are skipped"));
132
- }
133
- console.log();
134
- }
135
-
136
- let packageResult;
137
- try {
138
- packageResult = await validatePackageJson(packageJson, { skipUrlChecks });
139
- } catch (err) {
140
- const message = err instanceof Error ? err.message : String(err);
141
- if (jsonOutput) {
142
- console.log(JSON.stringify({ valid: false, errors: [`Unexpected validation error: ${message}`], warnings: [] }, null, 2));
143
- } else {
144
- console.error(c.red(`✖ Unexpected validation error: ${message}`));
145
- }
146
- process.exit(1);
147
- }
148
-
149
- // --- Validate pptb.config.json if present ---
150
- let configResult = null;
151
- if (pptbConfigParseError !== null) {
152
- configResult = { valid: false, errors: [`Failed to parse pptb.config.json: ${pptbConfigParseError}`], warnings: [] };
153
- } else if (pptbConfig !== null) {
154
- configResult = validatePPTBConfig(pptbConfig);
155
- }
156
-
157
- // Merge results for overall pass/fail
158
- const allErrors = [...packageResult.errors, ...(configResult ? configResult.errors : [])];
159
- const allWarnings = [...packageResult.warnings, ...(configResult ? configResult.warnings : [])];
160
- const overallValid = packageResult.valid && (configResult === null || configResult.valid);
161
-
162
- // --- Output results ---
163
- if (jsonOutput) {
164
- const output = {
165
- valid: overallValid,
166
- errors: allErrors,
167
- warnings: allWarnings,
168
- packageInfo: packageResult.packageInfo,
169
- configInfo: configResult ? configResult.packageInfo : undefined,
170
- };
171
- console.log(JSON.stringify(output, null, 2));
172
- process.exit(overallValid ? 0 : 1);
173
- }
174
-
175
- // Human-readable output – package.json section
176
- if (packageResult.errors.length > 0) {
177
- console.log(c.bold(c.red(`package.json Errors (${packageResult.errors.length})`)));
178
- packageResult.errors.forEach((e) => console.log(` ${c.red("✖")} ${e}`));
179
- console.log();
180
- }
181
-
182
- if (packageResult.warnings.length > 0) {
183
- console.log(c.bold(c.yellow(`package.json Warnings (${packageResult.warnings.length})`)));
184
- packageResult.warnings.forEach((w) => console.log(` ${c.yellow("⚠")} ${w}`));
185
- console.log();
186
- }
187
-
188
- // Human-readable output – pptb.config.json section
189
- if (configResult !== null) {
190
- if (configResult.errors.length > 0) {
191
- console.log(c.bold(c.red(`pptb.config.json Errors (${configResult.errors.length})`)));
192
- configResult.errors.forEach((e) => console.log(` ${c.red("✖")} ${e}`));
193
- console.log();
194
- }
195
-
196
- if (configResult.warnings.length > 0) {
197
- console.log(c.bold(c.yellow(`pptb.config.json Warnings (${configResult.warnings.length})`)));
198
- configResult.warnings.forEach((w) => console.log(` ${c.yellow("⚠")} ${w}`));
199
- console.log();
200
- }
201
- }
202
-
203
- if (overallValid) {
204
- const info = packageResult.packageInfo;
205
- console.log(c.green(c.bold("✔ Validation passed")));
206
- console.log();
207
- console.log(c.bold("Package summary"));
208
- console.log(c.dim("─".repeat(45)));
209
- console.log(` Name : ${info.name}`);
210
- console.log(` Version : ${info.version}`);
211
- console.log(` Display name: ${info.displayName}`);
212
- console.log(` Description : ${info.description}`);
213
- console.log(` License : ${info.license}`);
214
- console.log(` Contributors: ${info.contributors.map((contributor) => contributor.name).join(", ")}`);
215
- if (info.icon) {
216
- console.log(` Icon : ${info.icon}`);
217
- }
218
- if (info.features) {
219
- console.log(` Features : multiConnection=${info.features.multiConnection}${info.features.minAPI ? `, minAPI=${info.features.minAPI}` : ""}`);
220
- }
221
- if (configResult !== null && configResult.packageInfo && configResult.packageInfo.invocation) {
222
- const inv = configResult.packageInfo.invocation;
223
- console.log(` Invocation : version=${inv.version}`);
224
- if (Array.isArray(inv.capabilities) && inv.capabilities.length > 0) {
225
- console.log(` Capabilities: ${inv.capabilities.join(", ")}`);
226
- }
227
- }
228
- console.log();
229
- console.log(c.dim(`Known capability tags: ${KNOWN_CAPABILITY_TAGS.join(", ")}`));
230
- console.log();
231
- } else {
232
- console.log(c.red(c.bold("✖ Validation failed")));
233
- console.log();
234
- console.log(c.dim("Fix the errors listed above and re-run pptb-validate before publishing."));
235
- console.log();
236
- }
237
-
238
- process.exit(overallValid ? 0 : 1);
239
- }
240
-
241
- main().catch((err) => {
242
- console.error(c.red(`✖ Fatal error: ${err instanceof Error ? err.message : String(err)}`));
243
- process.exit(1);
244
- });
2
+ require("@pptb/validate/cli");
package/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/triple-slash-reference */
2
1
  /**
3
2
  * Power Platform ToolBox API Type Definitions
4
3
  *
@@ -17,11 +16,9 @@
17
16
 
18
17
  /// <reference path="./toolboxAPI.d.ts" />
19
18
  /// <reference path="./dataverseAPI.d.ts" />
20
- /// <reference path="./powerplatformAPI.d.ts" />
21
19
  /// <reference path="./pptbConfig.d.ts" />
22
20
 
23
21
  // Re-export all namespaces for convenience
24
22
  export * from "./dataverseAPI";
25
- export * from "./powerplatformAPI";
26
- export * from "./pptbConfig";
27
23
  export * from "./toolboxAPI";
24
+ export * from "./pptbConfig";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pptb/types",
3
- "version": "1.2.4-beta.0",
3
+ "version": "1.2.4-beta.2",
4
4
  "description": "Type definitions for Power Platform ToolBox APIs and validity checks for tool packages",
5
5
  "main": "index.d.ts",
6
6
  "types": "index.d.ts",
@@ -22,14 +22,15 @@
22
22
  "bin": {
23
23
  "pptb-validate": "./bin/pptb-validate.js"
24
24
  },
25
+ "dependencies": {
26
+ "@pptb/validate": "^0.0.1"
27
+ },
25
28
  "files": [
26
29
  "index.d.ts",
27
30
  "toolboxAPI.d.ts",
28
31
  "dataverseAPI.d.ts",
29
- "powerplatformAPI.d.ts",
30
32
  "pptbConfig.d.ts",
31
33
  "bin/",
32
- "lib/",
33
34
  "README.md"
34
35
  ],
35
36
  "scripts": {
package/lib/validate.js DELETED
@@ -1,486 +0,0 @@
1
- // @ts-check
2
- "use strict";
3
-
4
- /**
5
- * Tool validation logic for Power Platform ToolBox tools.
6
- * Mirrors the validation rules used during the official review process.
7
- */
8
-
9
- /** @typedef {{ name: string; url?: string }} Contributor */
10
- /** @typedef {{ "connect-src"?: string[]; "script-src"?: string[]; "style-src"?: string[]; "img-src"?: string[]; "font-src"?: string[]; "frame-src"?: string[]; "media-src"?: string[] }} CspExceptions */
11
- /** @typedef {{ repository?: string; website?: string; funding?: string; readmeUrl?: string }} Configurations */
12
- /** @typedef {{ multiConnection?: "required" | "optional" | "none"; minAPI?: string }} Features */
13
- /**
14
- * @typedef {{
15
- * name: string;
16
- * version: string;
17
- * displayName?: string;
18
- * description?: string;
19
- * contributors?: Contributor[];
20
- * cspExceptions?: CspExceptions;
21
- * license?: string;
22
- * icon?: string;
23
- * configurations?: Configurations;
24
- * features?: Features;
25
- * }} ToolPackageJson
26
- */
27
- /**
28
- * @typedef {{
29
- * valid: boolean;
30
- * errors: string[];
31
- * warnings: string[];
32
- * packageInfo?: object;
33
- * }} ValidationResult
34
- */
35
-
36
- /**
37
- * @typedef {{ type?: string; enum?: string[]; items?: object }} JsonSchemaProperty
38
- * @typedef {{ properties?: Record<string, JsonSchemaProperty> }} JsonSchemaObject
39
- * @typedef {{
40
- * version: string;
41
- * prefill?: JsonSchemaObject;
42
- * returnTopic?: JsonSchemaObject;
43
- * }} InvocationConfig
44
- * @typedef {{
45
- * invocation?: InvocationConfig;
46
- * }} PPTBConfig
47
- */
48
-
49
- // List of approved open source licenses
50
- const APPROVED_LICENSES = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "GPL-2.0", "GPL-3.0", "LGPL-3.0", "ISC", "AGPL-3.0-only"];
51
-
52
- // Valid multiConnection values
53
- const VALID_MULTI_CONNECTION_VALUES = ["required", "optional", "none"];
54
-
55
- // Semver regex for minAPI validation
56
- const SEMVER_REGEX = /^\d+\.\d+\.\d+(-[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?(\+[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*)?$/;
57
-
58
- /**
59
- * Built-in list of well-known capability tags.
60
- * Mirrors the entries in the Supabase `capability_tags` table.
61
- * New tags are added to Supabase first (configurable without a deploy) and are
62
- * then reflected here in the next package release so offline validation stays current.
63
- *
64
- * When a tool declares a tag that is not in this list the validator emits a warning
65
- * (not an error) so existing tools are not broken by registry updates.
66
- *
67
- * **Keep in sync with `BUILT_IN_CAPABILITY_TAGS` in
68
- * `src/main/managers/toolRegistryManager.ts`.** Because this file is a standalone
69
- * Node.js module that cannot import from the Electron/TypeScript source tree, both
70
- * lists must be updated together whenever a new tag is added.
71
- */
72
- const KNOWN_CAPABILITY_TAGS = [
73
- "fetchxml",
74
- "entity-picker",
75
- "record-selector",
76
- "solution-selector",
77
- "webresource-editor",
78
- "plugin-inspector",
79
- "pcf-control-builder",
80
- ];
81
-
82
- /**
83
- * Checks if a string is a valid URL.
84
- * @param {string} url
85
- * @returns {boolean}
86
- */
87
- function isValidUrl(url) {
88
- try {
89
- new URL(url);
90
- return true;
91
- } catch {
92
- return false;
93
- }
94
- }
95
-
96
- /**
97
- * Checks if a URL hostname is a GitHub domain.
98
- * @param {string} url
99
- * @returns {boolean}
100
- */
101
- function isGithubDomain(url) {
102
- try {
103
- const hostname = new URL(url).hostname.toLowerCase();
104
- return hostname === "github.com" || hostname.endsWith(".github.com");
105
- } catch {
106
- return false;
107
- }
108
- }
109
-
110
- /**
111
- * Validates an icon path string.
112
- * @param {string} fieldName
113
- * @param {string} iconPath
114
- * @param {string[]} errors
115
- */
116
- function validateIconPath(fieldName, iconPath, errors) {
117
- if (iconPath.startsWith("http://") || iconPath.startsWith("https://")) {
118
- errors.push(`${fieldName} cannot be an HTTP(S) URL - icons must be bundled under dist`);
119
- return;
120
- }
121
- if (iconPath.startsWith("/")) {
122
- errors.push(`${fieldName} must be a relative path (e.g., 'icon.svg' or 'icons/icon.svg')`);
123
- return;
124
- }
125
- // Reject Windows absolute paths like "C:\..." or "C:/"
126
- if (/^[a-zA-Z]:/.test(iconPath)) {
127
- errors.push(`${fieldName} must be a relative path (e.g., 'icon.svg' or 'icons/icon.svg')`);
128
- return;
129
- }
130
- // Reject backslashes — icon paths must use forward slashes
131
- if (iconPath.includes("\\")) {
132
- errors.push(`${fieldName} must use forward slashes, not backslashes (e.g., 'icons/icon.svg')`);
133
- return;
134
- }
135
- if (iconPath.includes("..")) {
136
- errors.push(`${fieldName} cannot contain '..' (path traversal not allowed)`);
137
- return;
138
- }
139
- if (!iconPath.toLowerCase().endsWith(".svg")) {
140
- errors.push(`${fieldName} must be an SVG file with .svg extension`);
141
- }
142
- }
143
-
144
- /**
145
- * Checks if a URL is accessible by making a HEAD request.
146
- * @param {string} url
147
- * @returns {Promise<boolean>}
148
- */
149
- async function isUrlAccessible(url) {
150
- try {
151
- const response = await fetch(url, { method: "HEAD", redirect: "follow" });
152
- return response.ok;
153
- } catch {
154
- return false;
155
- }
156
- }
157
-
158
- /**
159
- * Validates a tool's package.json against the official review criteria.
160
- *
161
- * @param {ToolPackageJson} packageJson - The parsed package.json object.
162
- * @param {{ skipUrlChecks?: boolean }} [options] - Validation options.
163
- * @returns {Promise<ValidationResult>}
164
- */
165
- async function validatePackageJson(packageJson, options = {}) {
166
- const { skipUrlChecks = false } = options;
167
- const errors = /** @type {string[]} */ ([]);
168
- const warnings = /** @type {string[]} */ ([]);
169
-
170
- // Required fields
171
- if (!packageJson.name || typeof packageJson.name !== "string") {
172
- errors.push("Package name is required and must be a string");
173
- }
174
-
175
- if (!packageJson.version || typeof packageJson.version !== "string") {
176
- errors.push("Package version is required and must be a string");
177
- }
178
-
179
- if (!packageJson.displayName || typeof packageJson.displayName !== "string") {
180
- errors.push("displayName is required and must be a string");
181
- }
182
-
183
- if (!packageJson.description || typeof packageJson.description !== "string") {
184
- errors.push("description is required and must be a string");
185
- }
186
-
187
- // License validation
188
- if (!packageJson.license) {
189
- errors.push("license is required");
190
- } else if (!APPROVED_LICENSES.includes(packageJson.license)) {
191
- errors.push(`License "${packageJson.license}" is not in the approved list. Approved licenses: ${APPROVED_LICENSES.join(", ")}`);
192
- }
193
-
194
- // Icon validation (optional, but must be a relative SVG path if provided)
195
- if (packageJson.icon === undefined || packageJson.icon === null) {
196
- warnings.push("icon is not set; consider adding a bundled SVG icon so your tool displays properly in the marketplace");
197
- } else if (typeof packageJson.icon !== "string") {
198
- errors.push("icon must be a string (relative path to bundled SVG under dist)");
199
- } else {
200
- validateIconPath("icon", packageJson.icon, errors);
201
- }
202
-
203
- // Contributors validation
204
- if (!packageJson.contributors || !Array.isArray(packageJson.contributors)) {
205
- errors.push("contributors is required and must be an array");
206
- } else if (packageJson.contributors.length === 0) {
207
- errors.push("At least one contributor is required");
208
- } else {
209
- packageJson.contributors.forEach((contributor, index) => {
210
- if (!contributor.name || typeof contributor.name !== "string") {
211
- errors.push(`Contributor at index ${index} must have a name`);
212
- }
213
- if (contributor.url && !isValidUrl(contributor.url)) {
214
- warnings.push(`Contributor "${contributor.name}" has an invalid URL`);
215
- }
216
- });
217
- }
218
-
219
- // Configurations validation
220
- if (!packageJson.configurations || typeof packageJson.configurations !== "object") {
221
- errors.push("configurations is required and must include repository and readmeUrl");
222
- } else {
223
- const configs = packageJson.configurations;
224
-
225
- // configurations.iconUrl is no longer supported
226
- if (/** @type {Record<string, unknown>} */ (configs).iconUrl !== undefined) {
227
- errors.push("configurations.iconUrl is no longer supported; use top-level 'icon' for bundled SVG path");
228
- }
229
-
230
- // Repository validation
231
- if (!configs.repository || typeof configs.repository !== "string") {
232
- errors.push("configurations.repository is required and must be a URL");
233
- } else if (!isValidUrl(configs.repository)) {
234
- errors.push("configurations.repository has an invalid URL format");
235
- } else if (!skipUrlChecks) {
236
- const accessible = await isUrlAccessible(configs.repository);
237
- if (!accessible) {
238
- errors.push("configurations.repository URL is not accessible");
239
- }
240
- }
241
-
242
- // Website validation (optional but recommended)
243
- if (!configs.website) {
244
- warnings.push("configurations.website is not set; consider adding a URL where users can learn more about your tool");
245
- } else if (!isValidUrl(configs.website)) {
246
- warnings.push("configurations.website has an invalid URL format");
247
- } else if (!skipUrlChecks) {
248
- const accessible = await isUrlAccessible(configs.website);
249
- if (!accessible) {
250
- warnings.push("configurations.website URL is not accessible");
251
- }
252
- }
253
-
254
- // Funding validation (optional but recommended)
255
- if (configs.funding) {
256
- if (!isValidUrl(configs.funding)) {
257
- warnings.push("configurations.funding has an invalid URL format");
258
- } else if (!skipUrlChecks) {
259
- const accessible = await isUrlAccessible(configs.funding);
260
- if (!accessible) {
261
- warnings.push("configurations.funding URL is not accessible");
262
- }
263
- }
264
- }
265
-
266
- // ReadmeUrl validation
267
- if (!configs.readmeUrl || typeof configs.readmeUrl !== "string") {
268
- errors.push("configurations.readmeUrl is required and must be a URL");
269
- } else if (!isValidUrl(configs.readmeUrl)) {
270
- errors.push("configurations.readmeUrl has an invalid URL format");
271
- } else if (isGithubDomain(configs.readmeUrl)) {
272
- errors.push("configurations.readmeUrl cannot be hosted on github.com; use raw.githubusercontent.com or another domain");
273
- } else if (!skipUrlChecks) {
274
- const accessible = await isUrlAccessible(configs.readmeUrl);
275
- if (!accessible) {
276
- errors.push("configurations.readmeUrl is not accessible");
277
- }
278
- }
279
- }
280
-
281
- // CSP Exceptions validation (optional, but validated if present)
282
- if (packageJson.cspExceptions) {
283
- const cspExceptions = packageJson.cspExceptions;
284
-
285
- if (typeof cspExceptions !== "object" || cspExceptions === null || Array.isArray(cspExceptions)) {
286
- errors.push("cspExceptions must be an object mapping CSP directives to arrays of strings");
287
- } else {
288
- const validCspDirectives = ["connect-src", "script-src", "style-src", "img-src", "font-src", "frame-src", "media-src"];
289
-
290
- const hasAnyDirectives = Object.keys(cspExceptions).length > 0;
291
- if (!hasAnyDirectives) {
292
- errors.push("cspExceptions cannot be empty. If CSP exceptions are not needed, remove the cspExceptions field");
293
- }
294
-
295
- Object.keys(cspExceptions).forEach((directive) => {
296
- if (!validCspDirectives.includes(directive)) {
297
- warnings.push(`Unknown CSP directive: ${directive}`);
298
- }
299
- const values = cspExceptions[/** @type {keyof CspExceptions} */ (directive)];
300
- if (values && !Array.isArray(values)) {
301
- errors.push(`CSP directive "${directive}" must be an array of strings`);
302
- } else if (values && values.length === 0) {
303
- errors.push(`CSP directive "${directive}" cannot be an empty array`);
304
- }
305
- });
306
- }
307
- }
308
-
309
- // Features validation (optional, but validated if present)
310
- if (packageJson.features !== undefined) {
311
- const features = packageJson.features;
312
-
313
- if (features === null || typeof features !== "object" || Array.isArray(features)) {
314
- errors.push("features must be a non-array object with optional 'multiConnection' and 'minAPI' properties");
315
- } else {
316
- const VALID_FEATURE_KEYS = ["multiConnection", "minAPI"];
317
- const featureKeys = Object.keys(features);
318
- const invalidKeys = featureKeys.filter((key) => !VALID_FEATURE_KEYS.includes(key));
319
-
320
- if (invalidKeys.length > 0) {
321
- errors.push(`features can only contain ${VALID_FEATURE_KEYS.map((k) => `'${k}'`).join(", ")} properties. Invalid properties: ${invalidKeys.join(", ")}`);
322
- }
323
-
324
- if (features.multiConnection === undefined) {
325
- errors.push("features.multiConnection is required when features object is provided");
326
- } else if (!VALID_MULTI_CONNECTION_VALUES.includes(features.multiConnection)) {
327
- errors.push(`features.multiConnection must be one of: ${VALID_MULTI_CONNECTION_VALUES.join(", ")}`);
328
- }
329
-
330
- if (features.minAPI !== undefined) {
331
- if (typeof features.minAPI !== "string" || !SEMVER_REGEX.test(features.minAPI)) {
332
- errors.push("features.minAPI must be a valid semantic version string (e.g., '1.0.0')");
333
- }
334
- }
335
- }
336
- }
337
-
338
- const valid = errors.length === 0;
339
-
340
- return {
341
- valid,
342
- errors,
343
- warnings,
344
- packageInfo: valid
345
- ? {
346
- name: packageJson.name,
347
- version: packageJson.version,
348
- displayName: packageJson.displayName,
349
- description: packageJson.description,
350
- license: packageJson.license,
351
- contributors: packageJson.contributors,
352
- cspExceptions: packageJson.cspExceptions,
353
- icon: packageJson.icon,
354
- configurations: packageJson.configurations,
355
- features: packageJson.features,
356
- }
357
- : undefined,
358
- };
359
- }
360
-
361
- module.exports = { validatePackageJson, validatePPTBConfig, isValidUrl, APPROVED_LICENSES, KNOWN_CAPABILITY_TAGS };
362
-
363
- /**
364
- * Validates a tool's pptb.config.json against the official review criteria.
365
- *
366
- * @param {PPTBConfig} config - The parsed pptb.config.json object.
367
- * @returns {ValidationResult}
368
- */
369
- function validatePPTBConfig(config) {
370
- const errors = /** @type {string[]} */ ([]);
371
- const warnings = /** @type {string[]} */ ([]);
372
-
373
- if (config === null || typeof config !== "object" || Array.isArray(config)) {
374
- errors.push("pptb.config.json must be a JSON object");
375
- return { valid: false, errors, warnings };
376
- }
377
-
378
- const VALID_ROOT_KEYS = ["invocation"];
379
- const unknownRootKeys = Object.keys(config).filter((k) => !VALID_ROOT_KEYS.includes(k));
380
- if (unknownRootKeys.length > 0) {
381
- warnings.push(`pptb.config.json contains unrecognised root keys: ${unknownRootKeys.join(", ")}`);
382
- }
383
-
384
- // Invocation section
385
- if (config.invocation !== undefined) {
386
- const inv = config.invocation;
387
-
388
- if (inv === null || typeof inv !== "object" || Array.isArray(inv)) {
389
- errors.push("invocation must be a non-array object");
390
- } else {
391
- // invocation.version – required, must be a valid semver string
392
- if (inv.version === undefined || inv.version === null) {
393
- errors.push("invocation.version is required");
394
- } else if (typeof inv.version !== "string") {
395
- errors.push("invocation.version must be a string");
396
- } else if (!SEMVER_REGEX.test(inv.version)) {
397
- errors.push(`invocation.version "${inv.version}" is not a valid semantic version string (e.g. "1.0.0")`);
398
- }
399
-
400
- // invocation.prefill – optional JSON-schema-like object
401
- if (inv.prefill !== undefined) {
402
- if (inv.prefill === null || typeof inv.prefill !== "object" || Array.isArray(inv.prefill)) {
403
- errors.push("invocation.prefill must be a non-array object");
404
- } else if (inv.prefill.properties !== undefined) {
405
- validateJsonSchemaProperties("invocation.prefill", inv.prefill.properties, errors);
406
- }
407
- }
408
-
409
- // invocation.returnTopic – optional JSON-schema-like object
410
- if (inv.returnTopic !== undefined) {
411
- if (inv.returnTopic === null || typeof inv.returnTopic !== "object" || Array.isArray(inv.returnTopic)) {
412
- errors.push("invocation.returnTopic must be a non-array object");
413
- } else if (inv.returnTopic.properties !== undefined) {
414
- validateJsonSchemaProperties("invocation.returnTopic", inv.returnTopic.properties, errors);
415
- }
416
- }
417
-
418
- // invocation.capabilities – optional array of non-empty strings
419
- if (inv.capabilities !== undefined) {
420
- if (!Array.isArray(inv.capabilities)) {
421
- errors.push("invocation.capabilities must be an array");
422
- } else {
423
- inv.capabilities.forEach((cap, idx) => {
424
- if (typeof cap !== "string" || cap.trim().length === 0) {
425
- errors.push(`invocation.capabilities[${idx}] must be a non-empty string`);
426
- } else if (!KNOWN_CAPABILITY_TAGS.includes(cap.trim())) {
427
- warnings.push(
428
- `invocation.capabilities[${idx}] "${cap}" is not a recognised capability tag. ` +
429
- `Known tags: ${KNOWN_CAPABILITY_TAGS.join(", ")}. ` +
430
- "If this is a new tag, ensure it has been added to the capability registry.",
431
- );
432
- }
433
- });
434
- }
435
- }
436
- }
437
- }
438
-
439
- const valid = errors.length === 0;
440
-
441
- return {
442
- valid,
443
- errors,
444
- warnings,
445
- packageInfo: valid
446
- ? {
447
- invocation: config.invocation,
448
- }
449
- : undefined,
450
- };
451
- }
452
-
453
- /**
454
- * Validates a JSON-schema-style `properties` map used inside invocation sections.
455
- * Only performs basic structural validation; full JSON Schema validation is not required.
456
- *
457
- * @param {string} fieldName
458
- * @param {unknown} properties
459
- * @param {string[]} errors
460
- */
461
- function validateJsonSchemaProperties(fieldName, properties, errors) {
462
- if (properties === null || typeof properties !== "object" || Array.isArray(properties)) {
463
- errors.push(`${fieldName}.properties must be a non-array object`);
464
- return;
465
- }
466
-
467
- const propsRecord = /** @type {Record<string, unknown>} */ (properties);
468
-
469
- for (const [key, value] of Object.entries(propsRecord)) {
470
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
471
- errors.push(`${fieldName}.properties.${key} must be an object`);
472
- continue;
473
- }
474
- const prop = /** @type {Record<string, unknown>} */ (value);
475
- if (prop.type !== undefined && typeof prop.type !== "string") {
476
- errors.push(`${fieldName}.properties.${key}.type must be a string`);
477
- }
478
- if (prop.enum !== undefined) {
479
- if (!Array.isArray(prop.enum)) {
480
- errors.push(`${fieldName}.properties.${key}.enum must be an array`);
481
- } else if (prop.enum.length === 0) {
482
- errors.push(`${fieldName}.properties.${key}.enum must not be empty`);
483
- }
484
- }
485
- }
486
- }
@@ -1,200 +0,0 @@
1
- /**
2
- * Power Platform ToolBox - Power Platform API Type Definitions
3
- *
4
- * Power Platform Admin APIs exposed to tools via window.powerplatformAPI
5
- * https://learn.microsoft.com/en-us/rest/api/power-platform/
6
- */
7
-
8
- declare namespace PowerPlatformAPI {
9
- /**
10
- * Power Platform API category response type
11
- */
12
- export interface PowerPlatformResponse {
13
- [key: string]: unknown;
14
- }
15
-
16
- /**
17
- * Generic HTTP method type
18
- */
19
- export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
20
-
21
- /**
22
- * Power Platform API category client interface
23
- * Provides generic HTTP methods for each API category
24
- */
25
- export interface CategoryClient {
26
- /**
27
- * Make a GET request to the category endpoint
28
- * @param path Relative path after the category base URL (e.g., "environments/{environmentId}/apps/{app}?api-version=2024-10-01")
29
- * @param connectionTarget Optional connection target for multi-connection tools ('primary' or 'secondary'). Defaults to 'primary'.
30
- * @param headers Optional custom headers
31
- */
32
- Get: (path?: string, connectionTarget?: "primary" | "secondary", headers?: Record<string, string>) => Promise<PowerPlatformResponse>;
33
-
34
- /**
35
- * Make a POST request to the category endpoint
36
- * @param path Relative path after the category base URL
37
- * @param body Optional request body
38
- * @param connectionTarget Optional connection target for multi-connection tools ('primary' or 'secondary'). Defaults to 'primary'.
39
- * @param headers Optional custom headers
40
- */
41
- Post: (path?: string, body?: unknown, connectionTarget?: "primary" | "secondary", headers?: Record<string, string>) => Promise<PowerPlatformResponse>;
42
-
43
- /**
44
- * Make a PUT request to the category endpoint
45
- * @param path Relative path after the category base URL
46
- * @param body Optional request body
47
- * @param connectionTarget Optional connection target for multi-connection tools ('primary' or 'secondary'). Defaults to 'primary'.
48
- * @param headers Optional custom headers
49
- */
50
- Put: (path?: string, body?: unknown, connectionTarget?: "primary" | "secondary", headers?: Record<string, string>) => Promise<PowerPlatformResponse>;
51
-
52
- /**
53
- * Make a PATCH request to the category endpoint
54
- * @param path Relative path after the category base URL
55
- * @param body Optional request body
56
- * @param connectionTarget Optional connection target for multi-connection tools ('primary' or 'secondary'). Defaults to 'primary'.
57
- * @param headers Optional custom headers
58
- */
59
- Patch: (path?: string, body?: unknown, connectionTarget?: "primary" | "secondary", headers?: Record<string, string>) => Promise<PowerPlatformResponse>;
60
-
61
- /**
62
- * Make a DELETE request to the category endpoint
63
- * @param path Relative path after the category base URL
64
- * @param connectionTarget Optional connection target for multi-connection tools ('primary' or 'secondary'). Defaults to 'primary'.
65
- * @param headers Optional custom headers
66
- * @param body Optional request body (for DELETE with payload)
67
- */
68
- Delete: (path?: string, connectionTarget?: "primary" | "secondary", headers?: Record<string, string>, body?: unknown) => Promise<PowerPlatformResponse>;
69
- }
70
-
71
- /**
72
- * Power Platform Analytics API
73
- * https://api.powerplatform.com/analytics
74
- */
75
- export interface Analytics extends CategoryClient {}
76
-
77
- /**
78
- * Power Platform App Management API
79
- * https://api.powerplatform.com/appmanagement
80
- */
81
- export interface AppManagement extends CategoryClient {}
82
-
83
- /**
84
- * Power Platform Authorization API
85
- * https://api.powerplatform.com/authorization
86
- */
87
- export interface Authorization extends CategoryClient {}
88
-
89
- /**
90
- * Power Platform Connectivity API
91
- * https://api.powerplatform.com/connectivity
92
- */
93
- export interface Connectivity extends CategoryClient {}
94
-
95
- /**
96
- * Power Platform Copilot Studio API
97
- * https://api.powerplatform.com/copilotstudio
98
- */
99
- export interface CopilotStudio extends CategoryClient {}
100
-
101
- /**
102
- * Power Platform Dynamics API
103
- * https://api.powerplatform.com/dynamics
104
- */
105
- export interface Dynamics extends CategoryClient {}
106
-
107
- /**
108
- * Power Platform Environment Management API
109
- * https://api.powerplatform.com/environmentmanagement
110
- */
111
- export interface EnvironmentManagement extends CategoryClient {}
112
-
113
- /**
114
- * Power Platform Governance API
115
- * https://api.powerplatform.com/governance
116
- */
117
- export interface Governance extends CategoryClient {}
118
-
119
- /**
120
- * Power Platform Licensing API
121
- * https://api.powerplatform.com/licensing
122
- */
123
- export interface Licensing extends CategoryClient {}
124
-
125
- /**
126
- * Power Platform Power Apps API
127
- * https://api.powerplatform.com/powerapps
128
- */
129
- export interface PowerApps extends CategoryClient {}
130
-
131
- /**
132
- * Power Platform Power Automate API
133
- * https://api.powerplatform.com/powerautomate
134
- */
135
- export interface PowerAutomate extends CategoryClient {}
136
-
137
- /**
138
- * Power Platform Power Pages API
139
- * https://api.powerplatform.com/powerpages
140
- */
141
- export interface PowerPages extends CategoryClient {}
142
-
143
- /**
144
- * Power Platform Resource Query API
145
- * https://api.powerplatform.com/resourcequery
146
- */
147
- export interface ResourceQuery extends CategoryClient {}
148
-
149
- /**
150
- * Power Platform User Management API
151
- * https://api.powerplatform.com/usermanagement
152
- */
153
- export interface UserManagement extends CategoryClient {}
154
-
155
- /**
156
- * Power Platform Workflow Agents API
157
- * https://api.powerplatform.com/workflowagents
158
- */
159
- export interface WorkflowAgents extends CategoryClient {}
160
-
161
- /**
162
- * Main Power Platform API interface
163
- * Each category exposes generic HTTP methods (Get, Post, Put, Patch, Delete)
164
- */
165
- export interface API {
166
- Analytics: Analytics;
167
- AppManagement: AppManagement;
168
- Authorization: Authorization;
169
- Connectivity: Connectivity;
170
- CopilotStudio: CopilotStudio;
171
- Dynamics: Dynamics;
172
- EnvironmentManagement: EnvironmentManagement;
173
- Governance: Governance;
174
- Licensing: Licensing;
175
- PowerApps: PowerApps;
176
- PowerAutomate: PowerAutomate;
177
- PowerPages: PowerPages;
178
- ResourceQuery: ResourceQuery;
179
- UserManagement: UserManagement;
180
- WorkflowAgents: WorkflowAgents;
181
- }
182
- }
183
-
184
- /**
185
- * Global window interface extension for Power Platform API
186
- */
187
- declare global {
188
- interface Window {
189
- /**
190
- * Power Platform Admin API accessible to tools
191
- * @example
192
- * // Get admin app from Power Apps
193
- * const app = await powerplatformAPI.PowerApps.Get('environments/{environmentId}/apps/{app}?api-version=2024-10-01');
194
- */
195
- powerplatformAPI: PowerPlatformAPI.API;
196
- }
197
- }
198
-
199
- export = PowerPlatformAPI;
200
- export as namespace PowerPlatformAPI;