Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@

## [0.3.3]
- Load / error messages controlled via verbosity setting
- Update internal fspath handling
- Update internal fspath handling

## [0.3.4]
- Support for updating Plugin Packages
35 changes: 22 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Bamboo is a simple, friendly, and ⚡*blazingly*⚡ fast customization manager, designed to speed up development time on the [Microsoft Power Platform](https://powerplatform.microsoft.com/en-us/). 🚀

Currently supporting [web resources](https://learn.microsoft.com/en-us/power-apps/developer/model-driven-apps/web-resources) and [custom controls](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/create-custom-controls-using-pcf), Bamboo provides a seamless experience for developers to edit and manage these solution components - all from within VS Code.
Currently supporting [web resources](https://learn.microsoft.com/en-us/power-apps/developer/model-driven-apps/web-resources), [custom controls](https://learn.microsoft.com/en-us/power-apps/developer/component-framework/create-custom-controls-using-pcf), and [plugin packages](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/build-and-package), Bamboo provides a seamless experience for developers to edit and manage these solution components - all from within VS Code.

## Features
Bamboo provides the following features inside VS Code:
Expand All @@ -12,21 +12,23 @@ Bamboo provides the following features inside VS Code:
- Add web resources to a solution automatically.
- Manage custom controls (PCF components) through the import + publish of solutions.
- List all web resources and custom controls in a given solution in a VS Code tree view.
- Update plugin packages


#### Component Tree
![Component Tree](./images/component_tree.png)

#### Commands
![Command Palette](./images/command_palette.png)
![Command Palette](./images/command_palette2.png)

## Getting Started

1. Install the extension [here](https://marketplace.visualstudio.com/publishers/root16).
2. Add a `bamboo.conf.json` at the **root** of your VS Code workspace.
- ![Example Project Strucutre](./images/project_structure.png)
- **Do not check `bamboo.conf.json` into source control.**
3. Populate the json file with the following data:
2. Add the files: `bamboo.conf.json` and `.bamboo_tokens/tokenCache.json` at the **root** of your VS Code workspace.
- A suggested structure is:
- ![Example Project Structure](./images/project_structure.png)
- **Do not check `bamboo.conf.json` or `.bamboo_tokens` into source control.**
3. Populate `bamboo.conf.json` with the following data:

```json
{
Expand Down Expand Up @@ -61,6 +63,13 @@ Bamboo provides the following features inside VS Code:
"solutionName": "ControlTwoSolution"
},
...
],
"pluginPackages": [
{
"pluginPackageName": "new_NEW.Plugins",
"relativePathOnDiskToNugetPackage": "path/to/NEW.Plugins.1.0.0.nupkg"
},
...
]
}
```
Expand All @@ -81,13 +90,14 @@ Bamboo provides the following features inside VS Code:
- `baseUrl` must *not* end with a `/`.
- The [app registration](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/walkthrough-register-app-azure-active-directory#confidential-client-app-registration) specified must have:
- Access to the specified Dataverse environment
- The appropiate Security Role necessary to:
- The appropriate Security Role necessary to:
- Upload solutions
- Publish solutions
- Upload web resources
- Publish web resources
- Upload plugin packages
- Add components to solutions
- `relativePathOnDisk` and `relativePathOnDiskToSolution` must *not* start with a `/`.
- `relativePathOnDisk`, `relativePathOnDiskToSolution` and `relativePathOnDiskToNugetPackage` must *not* start with a `/`.
- For web resources, `dataverseName` and `relativePathOnDisk` don't *need* to be similar (as shown in the example), this is just encouraged for ease of development

## Usage
Expand All @@ -97,14 +107,11 @@ Bamboo provides the following features inside VS Code:
| `bamboo.syncCurrentFile` | Sync current file. (Must be present on conf.) |
| `bamboo.syncAllFiles` | Sync all files. (Each file present in the conf.) |
| `bamboo.syncCustomControl` | Sync a Custom Control. (Opens up a choice dropdown for each control specified in the conf.) |
| `bamboo.syncPluginPackage` | Sync a Plugin Package. (Opens up a choice dropdown for each package specified in the conf.) |

- All command can be run in the command palette.


## Token Refresh + Cache
- Bamboo can use the previously cached token to speed up initial load times.
- Add the file: `<vscode-workspace>/bamboo_tokens/tokenCache.json` and then restart VS Code.

## Extension Settings

| Property | Type | Default | Description |
Expand All @@ -125,7 +132,9 @@ Bamboo provides the following features inside VS Code:
- [❌] Automatically add custom controls to solution
- [❌] Manage upload / sync from context of tree view
- [❌] Sync data from Power Apps to local files
- [❌] Plugin support
- [❌] Create a Plugin Package or Plugin Assembly
- [✅] Update / sync a *Plugin Package*
- [❌] Update / sync a *Plugin Assembly*

## License
Distributed under the MIT License. See [`LICENSE`](LICENSE) for more information.
Expand Down
Binary file removed images/command_palette.png
Binary file not shown.
Binary file added images/command_palette2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 64 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"url": "https://github.com/Root16/bamboo"
},
"description": "Enables users to create, update, and publish Web Resources and Custom Controls for Microsoft Power Platform — directly from VS Code.",
"version": "0.3.3",
"version": "0.3.4",
"icon": "resources/bamboo-green.png",
"engines": {
"vscode": "^1.73.0"
Expand Down Expand Up @@ -80,6 +80,11 @@
"light": "resources/light/refresh.svg",
"dark": "resources/dark/refresh.svg"
}
},
{
"command": "bamboo.syncPluginPackage",
"title": "Sync a Plugin Package.",
"category": "Bamboo"
}
],
"menus": {
Expand All @@ -103,11 +108,13 @@
"package": "vsce package"
},
"devDependencies": {
"@types/adm-zip": "^0.5.7",
"@types/glob": "^7.1.4",
"@types/jsonwebtoken": "^9.0.9",
"@types/mocha": "^9.0.0",
"@types/node": "14.x",
"@types/vscode": "^1.73.0",
"@types/xml2js": "^0.4.14",
"@typescript-eslint/eslint-plugin": "^4.31.1",
"@typescript-eslint/parser": "^4.31.1",
"@vscode/test-electron": "^2.4.1",
Expand All @@ -118,7 +125,9 @@
},
"dependencies": {
"@azure/msal-node": "^3.2.3",
"adm-zip": "^0.5.16",
"jsonwebtoken": "^9.0.2",
"open": "^10.1.0"
"open": "^10.1.0",
"xml2js": "^0.6.2"
}
}
6 changes: 6 additions & 0 deletions src/classes/syncer/BambooConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
credential: Credential;
webResources: WebResourceMapping[];
customControls: CustomControlMapping[];
pluginPackages: PluginPackageMapping[];
}

export enum CredentialType {
ClientSecret = 0,

Check warning on line 11 in src/classes/syncer/BambooConfig.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Enum Member name `ClientSecret` must match one of the following formats: camelCase
OAuth = 1,

Check warning on line 12 in src/classes/syncer/BambooConfig.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Enum Member name `OAuth` must match one of the following formats: camelCase
}

export interface Credential {
Expand All @@ -28,3 +29,8 @@
relativePathOnDiskToSolution: string;
solutionName: string;
}

export interface PluginPackageMapping {
pluginPackageName: string;
relativePathOnDiskToNugetPackage: string;
}
38 changes: 36 additions & 2 deletions src/classes/syncer/BambooManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as vscode from 'vscode';
import { BambooConfig, CredentialType, CustomControlMapping } from './BambooConfig';
import path from 'path';
import { BambooConfig, CredentialType, CustomControlMapping, PluginPackageMapping } from './BambooConfig';
import path, { relative } from 'path';
import { IWebResource } from '../../dataverse/IWebResource';
import { logErrorMessage, logMessage, logMessageWithProgress, logTemporaryMessage, VerboseSetting } from '../../log/message';
import { DataverseClient } from '../../dataverse/DataverseClient';
Expand All @@ -9,11 +9,11 @@
public static workspaceConfigFileName: string = 'bamboo.conf.json';
public static workspaceTokenCacheFolderName: string = '.bamboo_tokens';

private static ExceptionMessages = {

Check warning on line 12 in src/classes/syncer/BambooManager.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Class Property name `ExceptionMessages` must match one of the following formats: camelCase
UnableToAuthenticateToD365: "Unable to authenticate with the CRM instance. Please check your connection details.",

Check warning on line 13 in src/classes/syncer/BambooManager.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Object Literal Property name `UnableToAuthenticateToD365` must match one of the following formats: camelCase
CantFindBambooConfig: "Cannot find bamboo config file.",

Check warning on line 14 in src/classes/syncer/BambooManager.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Object Literal Property name `CantFindBambooConfig` must match one of the following formats: camelCase
UndefinedWorkspace: "Cannot activate Bamboo. Workspace is undefined.",

Check warning on line 15 in src/classes/syncer/BambooManager.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Object Literal Property name `UndefinedWorkspace` must match one of the following formats: camelCase
NoBambooConfig: `There is no ${BambooManager.workspaceConfigFileName} in the root of the current workspace!`,

Check warning on line 16 in src/classes/syncer/BambooManager.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Object Literal Property name `NoBambooConfig` must match one of the following formats: camelCase
};

private static instance: BambooManager;
Expand Down Expand Up @@ -104,8 +104,8 @@
const rawData = JSON.parse(jsonString);

const credentialTypeMap: Record<string, CredentialType> = {
ClientSecret: CredentialType.ClientSecret,

Check warning on line 107 in src/classes/syncer/BambooManager.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Object Literal Property name `ClientSecret` must match one of the following formats: camelCase
OAuth: CredentialType.OAuth,

Check warning on line 108 in src/classes/syncer/BambooManager.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Object Literal Property name `OAuth` must match one of the following formats: camelCase
};

return {
Expand All @@ -113,6 +113,7 @@
solutionUniqueName: rawData.solutionUniqueName,
webResources: rawData.webResources,
customControls: rawData.customControls,
pluginPackages: rawData.pluginPackages,
credential: {
...rawData.credential,
type: credentialTypeMap[rawData.credential.type] ?? CredentialType.ClientSecret,
Expand Down Expand Up @@ -142,7 +143,7 @@
}

const tokenFileFolderPath = await BambooManager.getTokenCacheFolderPath();
if (tokenFileFolderPath === null) return null;

Check warning on line 146 in src/classes/syncer/BambooManager.ts

View workflow job for this annotation

GitHub Actions / test-extension-frontend

Expected { after 'if' condition

const tokenFileFolderPathStr = tokenFileFolderPath instanceof vscode.Uri ? tokenFileFolderPath.fsPath : tokenFileFolderPath;

Expand Down Expand Up @@ -341,4 +342,37 @@
}
}

public async updatePluginPackage(
currentWorkspace: vscode.WorkspaceFolder,
pluginPackage: PluginPackageMapping
): Promise<void> {
const config = await this.getConfig();
if (!config) {
return;
}

const token = await this.getToken();
if (token === null) {
return;
}

const workspaceRoot = currentWorkspace.uri.fsPath;

const fullPath = path.join(workspaceRoot, pluginPackage.relativePathOnDiskToNugetPackage);

const normalizedPath = path.normalize(fullPath).replace(/\\/g, "/");

const [success, errorMessage] = await this.client.registerPluginPackage(
pluginPackage.pluginPackageName,
normalizedPath,
token,
);

if (success) {
logTemporaryMessage(`Synced plugin package: ${pluginPackage.pluginPackageName}.`, VerboseSetting.Low);
} else {
logErrorMessage(errorMessage!, VerboseSetting.Low);
}
}

}
Loading