mirror of
https://github.com/penpot/penpot.git
synced 2026-02-12 14:42:56 +00:00
🎉 Import penpot-plugins repository
As commit 819a549e4928d2b1fa98e52bee82d59aec0f70d8
This commit is contained in:
23
plugins/docs/api-docs.md
Normal file
23
plugins/docs/api-docs.md
Normal file
@@ -0,0 +1,23 @@
|
||||
### Plugins API Documentation
|
||||
|
||||
This document shows you how to create API documentation.
|
||||
|
||||
#### On your local
|
||||
|
||||
If you want to see what the document will look like (the HTML that's generated), you can run the following command:
|
||||
|
||||
```shell
|
||||
npm run create:api-docs
|
||||
```
|
||||
|
||||
Once you've done that, you'll find the result in `./dist/apps/api-doc`
|
||||
|
||||
#### Deploy the API Documentation
|
||||
|
||||
Just move to the `stable` branch in this repository and rebase it with the latest changes from the `main` branch. This will trigger the deployment at Cloudfare if the `/libs/plugin-types/index.d.ts` or the `/tools/typedoc.css` files have been updated.
|
||||
|
||||
Take a look at the [Penpot plugins API](https://penpot-plugins-api-doc.pages.dev/) to see what's new.
|
||||
|
||||
#### Styles
|
||||
|
||||
If you want to make some style changes you can do it in `/tools/typedoc.css`.
|
||||
153
plugins/docs/create-angular-plugin.md
Normal file
153
plugins/docs/create-angular-plugin.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Creating a Plugin
|
||||
|
||||
This guide walks you through the steps to create an Angular plugin for our platform. You'll start by setting up the basic structure, configuring necessary files, and then running a local server to preview your plugin.
|
||||
|
||||
If you prefer to create the plugin without a specific framework there's also [Creating a Plugin](./create-plugin.md).
|
||||
|
||||
Keep in mind that this guide is for creating a plugin **inside `penpot-plugins` monorepo**. If you want to create a plugin outside our environment you can check the [Penpot Plugin Starter Template](https://github.com/penpot/penpot-plugin-starter-template) or the documentation at [Create a Plugin](https://help.penpot.app/plugins/create-a-plugin/).
|
||||
|
||||
Let's dive in.
|
||||
|
||||
### Step 1: Initialize the Plugin
|
||||
|
||||
First, you need to create the scaffolding for your plugin. Use the following command, replacing `example-plugin` with the name of your plugin:
|
||||
|
||||
```sh
|
||||
npx nx g @nx/angular:app example-plugin --directory=apps/example-plugin --bundler=esbuild
|
||||
```
|
||||
|
||||
### Step 2: Configure the Manifest
|
||||
|
||||
Next, create a `manifest.json` file inside the `/src/assets` directory. This file is crucial as it defines key properties of your plugin, including permissions and the entry point script.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Example plugin",
|
||||
"host": "http://localhost:4200",
|
||||
"code": "/assets/plugin.js",
|
||||
"icon": "/assets/icon.png",
|
||||
"permissions": [
|
||||
"content:write",
|
||||
"library:write",
|
||||
"user:read",
|
||||
"comment:read",
|
||||
"allow:downloads"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Update Project Configuration
|
||||
|
||||
Now, add the plugin tag.
|
||||
|
||||
```typescript
|
||||
"tags": ["type:plugin"],
|
||||
```
|
||||
|
||||
Also, update `targets.build` with the following code to allow the use of Penpot styles and build the plugin code.
|
||||
|
||||
```json
|
||||
"options": {
|
||||
"styles": [
|
||||
"libs/plugins-styles/src/lib/styles.css",
|
||||
"apps/example-plugin/src/styles.css"
|
||||
],
|
||||
"optimization": {
|
||||
"scripts": true,
|
||||
"styles": true,
|
||||
"fonts": false
|
||||
}
|
||||
},
|
||||
"dependsOn": ["buildPlugin"]
|
||||
```
|
||||
|
||||
Add the default port to the `serve.configurations.development` task:
|
||||
|
||||
```json
|
||||
"development": {
|
||||
// ...
|
||||
"port": 4302,
|
||||
}
|
||||
```
|
||||
|
||||
For choosing the port go check the Sample Plugins table at the [README](../README.md) so your plugin doesn't use a duplicate port. We're using the range 4300-4399.
|
||||
|
||||
### Step 4: Modify TypeScript Configuration
|
||||
|
||||
Create ``tsconfig.plugin.json` next to the `tsconfig.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"types": []
|
||||
},
|
||||
"files": ["src/plugin.ts"],
|
||||
"include": ["../../libs/plugin-types/index.d.ts"]
|
||||
}
|
||||
```
|
||||
|
||||
Add the reference to the main tsconfig.json:
|
||||
|
||||
```json
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.plugin.json"
|
||||
}
|
||||
],
|
||||
```
|
||||
|
||||
### Step 5: Add TS parser to eslint
|
||||
|
||||
Add these options to the end of the `eslint.config.js` file to allow linting with type information:
|
||||
|
||||
```js
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: './tsconfig.*?.json',
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
### Strep 6: Hello world plugin code
|
||||
|
||||
Create the file `apps/example-plugin/src/plugin.ts` with the following code:
|
||||
|
||||
```ts
|
||||
console.log('Hello Plugin');
|
||||
```
|
||||
|
||||
### Step 7: Run the plugin
|
||||
|
||||
Run this command:
|
||||
|
||||
```sh
|
||||
npx nx run example-plugin:init
|
||||
```
|
||||
|
||||
This will run two tasks: `serve`, the usual Angular server, and `buildPlugin`, which will compile the `plugin.ts` file.
|
||||
|
||||
### Step 8: Load the Plugin in Penpot
|
||||
|
||||
To load your plugin into Penpot you can use the shortcut `Ctrl + Alt + P` to directly open the Plugin manager modal. There you need to provide the plugin's manifest URL (example: `http://plugin.example/manifest.json`) for the installation. If there's no issues the plugin will be installed and then you would be able to open it whenever you like.
|
||||
|
||||
You can also open the Plugin manager modal via:
|
||||
|
||||
- Menu
|
||||
|
||||

|
||||
|
||||
### Step 9: Build plugin
|
||||
|
||||
```
|
||||
npx nx run example-plugin:build
|
||||
```
|
||||
|
||||
### Learn More About Plugin Development
|
||||
|
||||
For more detailed information on plugin development, check out our guides:
|
||||
|
||||
- [Plugin Usage Documentation](,/plugin-usage.md)
|
||||
18
plugins/docs/create-api.md
Normal file
18
plugins/docs/create-api.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# Create API
|
||||
|
||||
Add your API in `libs/plugins-runtime/src/lib/api/index.ts`.
|
||||
|
||||
Try to use `zod` to validate the input an output, for example:
|
||||
|
||||
```ts
|
||||
{
|
||||
sum: z.function()
|
||||
.args(z.number(), z.number())
|
||||
.returns(z.number())
|
||||
.implement((callback, time) => {
|
||||
setTimeout(callback, time);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Update `/libs/plugins-runtime/src/lib/api/index.d.ts`.
|
||||
108
plugins/docs/create-plugin.md
Normal file
108
plugins/docs/create-plugin.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Creating a Plugin
|
||||
|
||||
This guide walks you through the steps to create a plugin for our platform. You'll start by setting up the basic structure, configuring necessary files, and then running a local server to preview your plugin.
|
||||
|
||||
If you prefer to create the plugin with angular, there's also a [Creating a Plugin (angular)](./create-angular-plugin.md).
|
||||
|
||||
Keep in mind that this guide is for creating a plugin **inside `penpot-plugins` monorepo**. If you want to create a plugin outside our environment you can check the [Penpot Plugin Starter Template](https://github.com/penpot/penpot-plugin-starter-template) or the documentation at [Create a Plugin](https://help.penpot.app/plugins/create-a-plugin/).
|
||||
|
||||
Let's dive in.
|
||||
|
||||
### Step 1: Initialize the Plugin
|
||||
|
||||
First, you need to create the scaffolding for your plugin. Use the following command, replacing `example-plugin` with the name of your plugin:
|
||||
|
||||
```sh
|
||||
npx nx g @nx/web:application example-plugin --directory=apps/example-plugin
|
||||
```
|
||||
|
||||
### Step 2: Migrate eslint to ESM
|
||||
|
||||
Replace `module.exports = [` with `export default [` and const `baseConfig = require('../../eslint.base.config.js');` with `import baseConfig from '../../eslint.config.js';`.
|
||||
|
||||
### Step 3: Configure the Manifest
|
||||
|
||||
Next, create a `manifest.json` file inside the `/public` directory. This file is crucial as it defines key properties of your plugin, including permissions and the entry point script.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Example Plugin",
|
||||
"host": "http://localhost:4201",
|
||||
"code": "/plugin.js",
|
||||
"icon": "/icon.png",
|
||||
"permissions": [
|
||||
"content:write",
|
||||
"library:write",
|
||||
"user:read",
|
||||
"comment:read",
|
||||
"allow:downloads"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Update Vite Configuration
|
||||
|
||||
Now, add the following configuration to your `vite.config.ts` to specify the entry points for the build process:
|
||||
|
||||
```typescript
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
plugin: 'src/plugin.ts',
|
||||
index: './index.html',
|
||||
},
|
||||
output: {
|
||||
entryFileNames: '[name].js',
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Modify TypeScript Configuration
|
||||
|
||||
Update your `tsconfig.app.json` to include the necessary TypeScript files for your plugin:
|
||||
|
||||
```json
|
||||
{
|
||||
"include": ["src/**/*.ts", "../../libs/plugin-types/index.d.ts"]
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Run a Static Server
|
||||
|
||||
To preview your plugin, start a static server by running:
|
||||
|
||||
```sh
|
||||
npx nx run example-plugin:build --watch & npx nx run example-plugin:preview
|
||||
```
|
||||
|
||||
### Step 7: Add TS parser to eslint
|
||||
|
||||
Add these options to the end of the `eslint.config.js` file to allow linting with type information:
|
||||
|
||||
```js
|
||||
{
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: './tsconfig.*?.json',
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
### Step 8: Load the Plugin in Penpot
|
||||
|
||||
To load your plugin into Penpot you can use the shortcut `Ctrl + Alt + P` to directly open the Plugin manager modal. There you need to provide the plugin's manifest URL (example: `http://plugin.example/manifest.json`) for the installation. If there's no issues the plugin will be installed and then you would be able to open it whenever you like.
|
||||
|
||||
You can also open the Plugin manager modal via:
|
||||
|
||||
- Menu
|
||||
|
||||

|
||||
|
||||
### Learn More About Plugin Development
|
||||
|
||||
For more detailed information on plugin development, check out our guides:
|
||||
|
||||
- [Create API Documentation](./create-api.md)
|
||||
BIN
plugins/docs/images/plugin-menu.png
Normal file
BIN
plugins/docs/images/plugin-menu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
84
plugins/docs/publish-package.md
Normal file
84
plugins/docs/publish-package.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Publishing Packages
|
||||
|
||||
## Introduction
|
||||
|
||||
This guide details the process of publishing `plugin-types`, `plugins-styles` and `plugins-runtime` packages, which are essential for plugin development. Below is a walkthrough for publishing these packages and managing releases.
|
||||
|
||||
## Publishing Libraries
|
||||
|
||||
Publishing packages enables the distribution of types and styles libraries. Currently, all packages share the same version, meaning some releases might not contain updates but will still increment the version. Follow the steps below for the automated publishing processes.
|
||||
|
||||
### Previewing a Release
|
||||
|
||||
To generate a preview of the release to check if everything is as expected, run the following command:
|
||||
|
||||
```shell
|
||||
git checkout main
|
||||
npm run release
|
||||
```
|
||||
|
||||
### Generating a Real Release
|
||||
|
||||
To create an actual release, disable the dry-run option:
|
||||
|
||||
```shell
|
||||
npm run release -- --dry-run false
|
||||
```
|
||||
|
||||
This command will:
|
||||
|
||||
- Update the `CHANGELOG.md`
|
||||
- Update the library's `package.json` version
|
||||
- Generate a commit
|
||||
- Create a new git tag
|
||||
- Publish to NPM with the `latest` tag
|
||||
|
||||
Ensure everything is correct before proceeding with the git push. Once verified, execute the following commands:
|
||||
|
||||
```shell
|
||||
git push
|
||||
git push origin vX.X.X
|
||||
```
|
||||
|
||||
Replace `vX.X.X` with the new version number.
|
||||
|
||||
> 📘 To update the documentation site, you must also update the `stable` branch:
|
||||
|
||||
```shell
|
||||
git checkout stable
|
||||
git merge main
|
||||
git push origin stable
|
||||
```
|
||||
|
||||
For detailed information, refer to the [Nx Release Documentation](https://nx.dev/recipes/nx-release/get-started-with-nx-release).
|
||||
|
||||
### Creating a Preview Version
|
||||
|
||||
To generate a preview version and avoid publishing it as the latest release, use:
|
||||
|
||||
```shell
|
||||
npm run release -- --dry-run false --latest false --preid next
|
||||
```
|
||||
|
||||
For example, if the current version is `0.8.0` and you select the `prepatch` option as a version specifier, it will generate the version `0.8.1-next.0` and publish it with the next tag on npm.
|
||||
|
||||
### Help
|
||||
|
||||
To see more options, run:
|
||||
|
||||
```shell
|
||||
npm run release -- --help
|
||||
```
|
||||
|
||||
## Important Reminders
|
||||
|
||||
- Ensure to update the [penpot](https://github.com/penpot/penpot/blob/develop/frontend/package.json) and [penpot-plugin-starter-template](https://github.com/penpot/penpot-plugin-starter-template) with every release to provide developers with the latest configuration and features.
|
||||
|
||||
- Update the API documentations following [this documentation](api-docs.md).
|
||||
|
||||
## Relevant Files and Scripts
|
||||
|
||||
- **CSS Build Script**: `./tools/scripts/build-css.mjs`
|
||||
- **Types Build Script**: `./tools/scripts/build-types.mjs`
|
||||
- **Release Script**: `./tools/scripts/publish.ts`
|
||||
- **Publish config**: `./nx.json`
|
||||
82
plugins/docs/test-e2e.md
Normal file
82
plugins/docs/test-e2e.md
Normal file
@@ -0,0 +1,82 @@
|
||||
## End-to-End (E2E) Testing Guide
|
||||
|
||||
### Setting Up
|
||||
|
||||
1. **Configure Environment Variables**
|
||||
|
||||
Create and populate the `.env` file with a valid user mail & password:
|
||||
|
||||
```env
|
||||
E2E_LOGIN_EMAIL="test@penpot.app"
|
||||
E2E_LOGIN_PASSWORD="123123123"
|
||||
E2E_SCREENSHOTS= "true"
|
||||
```
|
||||
|
||||
2. **Run E2E Tests**
|
||||
|
||||
Use the following command to execute the E2E tests:
|
||||
|
||||
```bash
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
### Writing Tests
|
||||
|
||||
1. **Adding Tests**
|
||||
|
||||
Place your test files in the `/apps/e2e/src/**/*.spec.ts` directory. Below is an example of a test file:
|
||||
|
||||
```ts
|
||||
import testingPlugin from './plugins/create-board-text-rect';
|
||||
import { Agent } from './utils/agent';
|
||||
|
||||
describe('Plugins', () => {
|
||||
it('create board - text - rectangle', async () => {
|
||||
const agent = await Agent();
|
||||
const result = await agent.runCode(testingPlugin.toString());
|
||||
|
||||
expect(result).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
**Explanation**:
|
||||
|
||||
- `Agent` opens a browser, logs into Penpot, and creates a file.
|
||||
- `runCode` executes the plugin code and returns the file state after execution.
|
||||
|
||||
2. **Using `runCode` Method**
|
||||
|
||||
The `runCode` method takes the plugin code as a string:
|
||||
|
||||
```ts
|
||||
const result = await agent.runCode(testingPlugin.toString());
|
||||
```
|
||||
|
||||
It can also accept an options object:
|
||||
|
||||
```ts
|
||||
const result = await agent.runCode(testingPlugin.toString(), {
|
||||
autoFinish: false, // default: true
|
||||
screenshot: 'test-name', // default: ''
|
||||
});
|
||||
|
||||
// Finish will close the browser & delete the file
|
||||
agent.finish();
|
||||
```
|
||||
|
||||
3. **Snapshot Testing**
|
||||
|
||||
The `toMatchSnapshot` method stores the result and throws an error if the content does not match the previous result:
|
||||
|
||||
```ts
|
||||
expect(result).toMatchSnapshot();
|
||||
```
|
||||
|
||||
Snapshots are stored in the `apps/e2e/src/__snapshots__/*.spec.ts.snap` directory.
|
||||
|
||||
If you need to refresh all the snapshopts run the test with the update option:
|
||||
|
||||
```bash
|
||||
npm run test:e2e -- --update
|
||||
```
|
||||
Reference in New Issue
Block a user