mirror of
https://github.com/penpot/penpot-plugins.git
synced 2025-01-06 14:50:21 -05:00
feat: load plugin
This commit is contained in:
parent
f68faaaa2c
commit
ee96862ed5
50 changed files with 962 additions and 816 deletions
3
apps/example-plugin/.babelrc
Normal file
3
apps/example-plugin/.babelrc
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"presets": ["@nx/js/babel"]
|
||||
}
|
18
apps/example-plugin/.eslintrc.json
Normal file
18
apps/example-plugin/.eslintrc.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
8
apps/example-plugin/.swcrc
Normal file
8
apps/example-plugin/.swcrc
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"jsc": {
|
||||
"parser": {
|
||||
"syntax": "typescript"
|
||||
},
|
||||
"target": "es2016"
|
||||
}
|
||||
}
|
16
apps/example-plugin/index.html
Normal file
16
apps/example-plugin/index.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>ExamplePlugin</title>
|
||||
<base href="/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/src/styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
8
apps/example-plugin/project.json
Normal file
8
apps/example-plugin/project.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"name": "example-plugin",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"projectType": "application",
|
||||
"sourceRoot": "apps/example-plugin/src",
|
||||
"tags": [],
|
||||
"targets": {}
|
||||
}
|
BIN
apps/example-plugin/public/favicon.ico
Normal file
BIN
apps/example-plugin/public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
4
apps/example-plugin/public/manifest.json
Normal file
4
apps/example-plugin/public/manifest.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "Example plugin",
|
||||
"code": "http://localhost:4201/plugin.js"
|
||||
}
|
65
apps/example-plugin/src/app/app.element.css
Normal file
65
apps/example-plugin/src/app/app.element.css
Normal file
|
@ -0,0 +1,65 @@
|
|||
html {
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
|
||||
'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
|
||||
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
line-height: 1.5;
|
||||
tab-size: 4;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
body {
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
p,
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
box-sizing: border-box;
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: currentColor;
|
||||
}
|
||||
h1,
|
||||
h2 {
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
pre {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
||||
'Liberation Mono', 'Courier New', monospace;
|
||||
}
|
||||
svg {
|
||||
display: block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
svg {
|
||||
shape-rendering: auto;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.5rem;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
21
apps/example-plugin/src/app/app.element.spec.ts
Normal file
21
apps/example-plugin/src/app/app.element.spec.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { AppElement } from './app.element';
|
||||
|
||||
describe('AppElement', () => {
|
||||
let app: AppElement;
|
||||
|
||||
beforeEach(() => {
|
||||
app = new AppElement();
|
||||
});
|
||||
|
||||
it('should create successfully', () => {
|
||||
expect(app).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should have a greeting', () => {
|
||||
app.connectedCallback();
|
||||
|
||||
expect(app.querySelector('h1').innerHTML).toContain(
|
||||
'Welcome example-plugin'
|
||||
);
|
||||
});
|
||||
});
|
57
apps/example-plugin/src/app/app.element.ts
Normal file
57
apps/example-plugin/src/app/app.element.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import './app.element.css';
|
||||
|
||||
export class AppElement extends HTMLElement {
|
||||
public static observedAttributes = [];
|
||||
|
||||
connectedCallback() {
|
||||
window.addEventListener('message', function (event) {
|
||||
if (event.data.type === 'pingpong') {
|
||||
console.log('iframe', event.data.content);
|
||||
} else if (event.data.type === 'page') {
|
||||
console.log('iframe', event.data);
|
||||
const projectName = document.getElementById('project-name');
|
||||
|
||||
if (projectName) {
|
||||
projectName.innerText = event.data.content;
|
||||
}
|
||||
} else if (event.data.type === 'init') {
|
||||
const projectName = document.getElementById('project-name');
|
||||
|
||||
if (projectName) {
|
||||
projectName.innerText = event.data.content.name;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.innerHTML = `
|
||||
<div class="wrapper">
|
||||
<h1>Test area</h1>
|
||||
|
||||
<p>Current project name: <span id="project-name">Unknown</span></p>
|
||||
|
||||
<p>
|
||||
<button type="button" class="act-ping-pong">Ping Pong message</button>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<button type="button" class="act-close-plugin">Close plugin</button>
|
||||
</p>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const pingPongAction = this.querySelector<HTMLElement>('.act-ping-pong');
|
||||
|
||||
pingPongAction?.addEventListener('click', () => {
|
||||
parent.postMessage({ content: 'ping' }, '*');
|
||||
});
|
||||
|
||||
const closeAction = this.querySelector<HTMLElement>('.act-close-plugin');
|
||||
|
||||
closeAction?.addEventListener('click', () => {
|
||||
parent.postMessage({ content: 'close' }, '*');
|
||||
});
|
||||
|
||||
parent.postMessage({ content: 'ready' }, '*');
|
||||
}
|
||||
}
|
||||
customElements.define('app-root', AppElement);
|
0
apps/example-plugin/src/assets/.gitkeep
Normal file
0
apps/example-plugin/src/assets/.gitkeep
Normal file
1
apps/example-plugin/src/main.ts
Normal file
1
apps/example-plugin/src/main.ts
Normal file
|
@ -0,0 +1 @@
|
|||
import './app/app.element';
|
36
apps/example-plugin/src/plugin.ts
Normal file
36
apps/example-plugin/src/plugin.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* eslint-disable */
|
||||
|
||||
export declare global {
|
||||
declare namespace globalThis {
|
||||
export const penpot = {
|
||||
ui: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
penpot.log('Hello from plugin');
|
||||
|
||||
penpot.ui.open('Plugin name', 'http://localhost:4201', {
|
||||
width: 500,
|
||||
height: 600,
|
||||
});
|
||||
|
||||
penpot.ui.onMessage((message) => {
|
||||
if (message.content === 'ping') {
|
||||
penpot.log('ping received');
|
||||
penpot.ui.sendMessage({ type: 'pingpong', content: 'pong' });
|
||||
} else if (message.content === 'close') {
|
||||
penpot.closePlugin();
|
||||
} else if (message.content === 'ready') {
|
||||
penpot.ui.sendMessage({
|
||||
type: 'init',
|
||||
content: {
|
||||
name: penpot.getPageState().name,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
penpot.on('pagechange', (page) => {
|
||||
penpot.ui.sendMessage({ type: 'page', content: page.name });
|
||||
});
|
1
apps/example-plugin/src/styles.css
Normal file
1
apps/example-plugin/src/styles.css
Normal file
|
@ -0,0 +1 @@
|
|||
/* You can add global styles to this file, and also import other style files */
|
9
apps/example-plugin/tsconfig.app.json
Normal file
9
apps/example-plugin/tsconfig.app.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"],
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
30
apps/example-plugin/tsconfig.json
Normal file
30
apps/example-plugin/tsconfig.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"compilerOptions": {
|
||||
"target": "ESNext",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ESNext",
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"moduleResolution": "Node",
|
||||
"strict": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"noEmit": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"skipLibCheck": true,
|
||||
"types": ["vite/client"]
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
26
apps/example-plugin/tsconfig.spec.json
Normal file
26
apps/example-plugin/tsconfig.spec.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
"vitest/importMeta",
|
||||
"vite/client",
|
||||
"node",
|
||||
"vitest"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"vitest.config.ts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.d.ts"
|
||||
]
|
||||
}
|
58
apps/example-plugin/vite.config.ts
Normal file
58
apps/example-plugin/vite.config.ts
Normal file
|
@ -0,0 +1,58 @@
|
|||
/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
|
||||
|
||||
export default defineConfig({
|
||||
root: __dirname,
|
||||
cacheDir: '../../node_modules/.vite/apps/example-plugin',
|
||||
|
||||
server: {
|
||||
port: 4200,
|
||||
host: 'localhost',
|
||||
},
|
||||
|
||||
preview: {
|
||||
port: 4300,
|
||||
host: 'localhost',
|
||||
},
|
||||
|
||||
plugins: [nxViteTsPaths()],
|
||||
|
||||
// Uncomment this if you are using workers.
|
||||
// worker: {
|
||||
// plugins: [ nxViteTsPaths() ],
|
||||
// },
|
||||
|
||||
build: {
|
||||
outDir: '../../dist/apps/example-plugin',
|
||||
reportCompressedSize: true,
|
||||
commonjsOptions: {
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
rollupOptions: {
|
||||
input: {
|
||||
plugin: 'src/plugin.ts',
|
||||
index: './index.html',
|
||||
},
|
||||
output: {
|
||||
entryFileNames: '[name].js',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
test: {
|
||||
globals: true,
|
||||
cache: {
|
||||
dir: '../../node_modules/.vitest',
|
||||
},
|
||||
environment: 'jsdom',
|
||||
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
|
||||
reporters: ['default'],
|
||||
coverage: {
|
||||
reportsDirectory: '../../coverage/apps/example-plugin',
|
||||
provider: 'v8',
|
||||
},
|
||||
},
|
||||
});
|
14
docs/create-api.md
Normal file
14
docs/create-api.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
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);
|
||||
});
|
||||
}
|
||||
```
|
35
docs/create-plugin.md
Normal file
35
docs/create-plugin.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
npx nx g @nx/web:application example-plugin --directory=apps/example-plugin
|
||||
|
||||
Create a manifes.json in /public
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Example plugin",
|
||||
"url": "http://localhost:4201",
|
||||
"code": "http://localhost:4201/plugin.js"
|
||||
}
|
||||
```
|
||||
|
||||
Add to the example vite.config.ts
|
||||
|
||||
```json
|
||||
build: {
|
||||
rollupOptions: {
|
||||
input: {
|
||||
plugin: 'src/plugin.ts',
|
||||
index: './index.html',
|
||||
},
|
||||
output: {
|
||||
entryFileNames: '[name].js',
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Run static server `npx nx run example-plugin:serve-static --port 4201`
|
||||
|
||||
Go to penpot and load the plugin.
|
||||
|
||||
```ts
|
||||
ɵloadPlugin({ manifest: 'http://localhost:4201/manifest.json' });
|
||||
```
|
72
docs/index.mustache
Normal file
72
docs/index.mustache
Normal file
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge" />
|
||||
<title>Penpot - Design Freedom for Teams</title>
|
||||
|
||||
<meta name="description" content="The open-source solution for design and prototyping.">
|
||||
<meta property="og:locale" content="en_US">
|
||||
<meta property="og:title" content="Penpot | Design Freedom for Teams">
|
||||
<meta property="og:description" content="The open-source solution for design and prototyping">
|
||||
<meta property="og:image" content="https://penpot.app/images/workspace-ui.jpg">
|
||||
<meta name="twitter:title" content="Penpot | Design Freedom for Teams">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:description" content="The open-source solution for design and prototyping">
|
||||
<meta name="twitter:image" content="https://penpot.app/images/workspace-ui.jpg">
|
||||
<meta name="twitter:site" content="@penpotapp">
|
||||
<meta name="twitter:creator" content="@penpotapp">
|
||||
<meta name="theme-color" content="#FFFFFF" media="(prefers-color-scheme: light)">
|
||||
<link id="theme" href="css/main.css?ts={{& ts}}" rel="stylesheet" type="text/css" />
|
||||
{{#isDebug}}
|
||||
<link href="css/debug.css?ts={{& ts}}" rel="stylesheet" type="text/css" />
|
||||
{{/isDebug}}
|
||||
|
||||
<link rel="icon" href="images/favicon.png" />
|
||||
<script type="importmap">
|
||||
{"imports": {"plugins-runtime": "http://localhost:4200/index.mjs"}}
|
||||
</script>
|
||||
|
||||
<script type="module" src="http://localhost:4200/index.mjs"></script>
|
||||
|
||||
<script>
|
||||
window.penpotTranslations = JSON.parse({{& translations}});
|
||||
window.penpotThemes = {{& themes}};
|
||||
window.penpotVersion = "%version%";
|
||||
window.penpotBuildDate = "%buildDate%";
|
||||
</script>
|
||||
|
||||
{{# manifest}}
|
||||
<script>window.penpotWorkerURI="{{& worker}}"</script>
|
||||
<script defer src="{{& config}}"></script>
|
||||
<script defer src="{{& polyfills}}"></script>
|
||||
{{/manifest}}
|
||||
|
||||
</head>
|
||||
<body>
|
||||
{{>../public/images/sprites/symbol/icons.svg}}
|
||||
{{>../public/images/sprites/symbol/cursors.svg}}
|
||||
<div id="app"></div>
|
||||
<section id="modal"></section>
|
||||
{{# manifest}}
|
||||
|
||||
<script defer src="{{& shared}}"></script>
|
||||
<script defer src="{{& main}}"></script>
|
||||
|
||||
<penpot-plugins />
|
||||
{{/manifest}}
|
||||
|
||||
|
||||
<script type="importmap">
|
||||
{"imports": {"plugins-runtime": "http://localhost:4200/index.mjs"}}
|
||||
</script>
|
||||
|
||||
<script type="module">
|
||||
import * as runtime from "plugins-runtime";
|
||||
|
||||
// console.log(globalThis.app.plugins);
|
||||
runtime.initialize(globalThis.app.plugins);
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
52
docs/plugin-usage.md
Normal file
52
docs/plugin-usage.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
Open UI:
|
||||
|
||||
```ts
|
||||
penpot.ui.open('Plugin name', 'http://localhost:4201', {
|
||||
width: 500,
|
||||
height: 600,
|
||||
});
|
||||
```
|
||||
|
||||
### Messages
|
||||
|
||||
Receive message from iframe:
|
||||
|
||||
```ts
|
||||
penpot.ui.onMessage((message) => {
|
||||
penpot.log('Received message:', message);
|
||||
});
|
||||
```
|
||||
|
||||
Send message from iframe:
|
||||
|
||||
```ts
|
||||
parent.postMessage({ content: 'text' }, '*');
|
||||
```
|
||||
|
||||
Send message from plugin
|
||||
|
||||
```ts
|
||||
penpot.ui.sendMessage({ type: 'hello' });
|
||||
```
|
||||
|
||||
Send message from plugin:
|
||||
|
||||
```ts
|
||||
window.addEventListener('message', function (event) {
|
||||
console.log('Message received from plugin: ', event.data);
|
||||
});
|
||||
```
|
||||
|
||||
### Events
|
||||
|
||||
Current events `pagechange` and `filechange`.
|
||||
|
||||
```ts
|
||||
const event = (page) => {
|
||||
penpot.log(page.name);
|
||||
};
|
||||
|
||||
penpot.on('pagechange', event);
|
||||
|
||||
penpot.off('pagechange', event);
|
||||
```
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": ["../.eslintrc.json"],
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
11
libs/plugins-runtime/README.md
Normal file
11
libs/plugins-runtime/README.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# plugins-runtime
|
||||
|
||||
Go to to the [this branch](https://github.com/penpot/penpot/tree/niwinz-poc-plugins) in the Penpot local code.
|
||||
|
||||
Copy `penpot-plugins/docs/index.mustache` to `penpot/frontend/resources/templates/index.mustache`.
|
||||
|
||||
Run the penpot runtime with `npm start`.
|
||||
|
||||
Now you can go to penpot and see the `log` of this file `plugins-runtime/src/index.ts`.
|
||||
|
||||
See [this docs about how to install plugins](../docs/create-plugin.md).
|
|
@ -1,7 +1,10 @@
|
|||
{
|
||||
"name": "plugins-runtime",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"ses": "^1.1.0",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"module": "./index.mjs",
|
||||
"typings": "./index.d.ts"
|
||||
}
|
34
libs/plugins-runtime/src/index.ts
Normal file
34
libs/plugins-runtime/src/index.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import 'ses';
|
||||
import './lib/plugin-modal';
|
||||
|
||||
import { ɵloadPlugin } from './lib/load-plugin';
|
||||
import { setFileState, setPageState } from './lib/api';
|
||||
|
||||
repairIntrinsics({
|
||||
evalTaming: 'unsafeEval',
|
||||
});
|
||||
|
||||
globalThis.ɵloadPlugin = ɵloadPlugin;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function initialize(api: any) {
|
||||
console.log('plugin context');
|
||||
|
||||
globalThis.ɵloadPlugin = ɵloadPlugin;
|
||||
|
||||
console.log(api);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
api.addListener('plugin-page', 'page', (page: any) => {
|
||||
console.log('Page Changed:', page);
|
||||
|
||||
setPageState(page);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
api.addListener('plugin-file', 'file', (file: any) => {
|
||||
console.log('File Changed:', file);
|
||||
|
||||
setFileState(file);
|
||||
});
|
||||
}
|
114
libs/plugins-runtime/src/lib/api/index.ts
Normal file
114
libs/plugins-runtime/src/lib/api/index.ts
Normal file
|
@ -0,0 +1,114 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import { OpenUIOptions } from '../models/open-ui-options.model';
|
||||
import openUIApi from './openUI.api';
|
||||
import z from 'zod';
|
||||
|
||||
type Callback<T> = (message: T) => void;
|
||||
|
||||
const validEvents = ['pagechange', 'filechange'] as const;
|
||||
|
||||
let uiMessagesCallbacks: Callback<any>[] = [];
|
||||
|
||||
let modal: HTMLElement | null = null;
|
||||
|
||||
let pageState = {} as any;
|
||||
let fileState = {} as any;
|
||||
|
||||
const eventListeners: Map<string, Callback<unknown>[]> = new Map();
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
for (const callback of uiMessagesCallbacks) {
|
||||
callback(event.data);
|
||||
}
|
||||
});
|
||||
|
||||
export function triggerEvent<T>(type: string, message: T) {
|
||||
const listeners = eventListeners.get(type) || [];
|
||||
listeners.forEach((listener) => listener(message));
|
||||
}
|
||||
|
||||
export function setPageState(page: unknown) {
|
||||
pageState = page;
|
||||
|
||||
triggerEvent('pagechange', page);
|
||||
}
|
||||
|
||||
export function setFileState(file: unknown) {
|
||||
fileState = file;
|
||||
|
||||
triggerEvent('filechange', file);
|
||||
}
|
||||
|
||||
export function createApi() {
|
||||
const closePlugin = () => {
|
||||
if (modal) {
|
||||
modal.remove();
|
||||
}
|
||||
|
||||
uiMessagesCallbacks = [];
|
||||
modal = null;
|
||||
};
|
||||
|
||||
const penpot = {
|
||||
ui: {
|
||||
open: (name: string, url: string, options: OpenUIOptions) => {
|
||||
modal = openUIApi(name, url, options);
|
||||
|
||||
modal.addEventListener('close', closePlugin, {
|
||||
once: true,
|
||||
});
|
||||
},
|
||||
sendMessage: (message: unknown) => {
|
||||
const event = new CustomEvent('message', {
|
||||
detail: message,
|
||||
});
|
||||
|
||||
modal?.dispatchEvent(event);
|
||||
},
|
||||
onMessage: z
|
||||
.function()
|
||||
.args(z.function())
|
||||
.implement((callback) => {
|
||||
uiMessagesCallbacks.push(callback);
|
||||
}),
|
||||
},
|
||||
log: console.log,
|
||||
setTimeout: z
|
||||
.function()
|
||||
.args(z.function(), z.number())
|
||||
.implement((callback, time) => {
|
||||
setTimeout(callback, time);
|
||||
}),
|
||||
closePlugin,
|
||||
on: (type: string, fn: Callback<unknown>) => {
|
||||
// z.function alter fn, so can't use it here
|
||||
z.enum(validEvents).parse(type);
|
||||
z.function().parse(fn);
|
||||
|
||||
const listeners = eventListeners.get(type) || [];
|
||||
|
||||
listeners.push(fn);
|
||||
eventListeners.set(type, listeners);
|
||||
},
|
||||
off: (type: string, fn: () => void) => {
|
||||
z.enum(validEvents).parse(type);
|
||||
z.function().parse(fn);
|
||||
|
||||
const listeners = eventListeners.get(type) || [];
|
||||
|
||||
eventListeners.set(
|
||||
type,
|
||||
listeners.filter((listener) => listener !== fn)
|
||||
);
|
||||
},
|
||||
getFileState: () => {
|
||||
return fileState;
|
||||
},
|
||||
getPageState: () => {
|
||||
return pageState;
|
||||
},
|
||||
};
|
||||
|
||||
return penpot;
|
||||
}
|
10
libs/plugins-runtime/src/lib/api/openUI.api.ts
Normal file
10
libs/plugins-runtime/src/lib/api/openUI.api.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import z from 'zod';
|
||||
import { openUISchema } from '../models/open-ui-options.schema';
|
||||
import { createModal } from '../create-modal';
|
||||
|
||||
export default z
|
||||
.function()
|
||||
.args(z.string(), z.string(), openUISchema)
|
||||
.implement((title, url, options) => {
|
||||
return createModal(title, url, options);
|
||||
});
|
14
libs/plugins-runtime/src/lib/create-modal.ts
Normal file
14
libs/plugins-runtime/src/lib/create-modal.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { OpenUIOptions } from './models/open-ui-options.model';
|
||||
|
||||
export function createModal(name: string, url: string, options: OpenUIOptions) {
|
||||
const modal = document.createElement('plugin-modal');
|
||||
|
||||
modal.setAttribute('title', name);
|
||||
modal.setAttribute('iframe-src', url);
|
||||
modal.setAttribute('width', String(options.width || 300));
|
||||
modal.setAttribute('height', String(options.height || 400));
|
||||
|
||||
document.body.appendChild(modal);
|
||||
|
||||
return modal;
|
||||
}
|
5
libs/plugins-runtime/src/lib/global.d.ts
vendored
Normal file
5
libs/plugins-runtime/src/lib/global.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
export declare global {
|
||||
declare namespace globalThis {
|
||||
function ɵloadPlugin(cofig: PluginConfig): void;
|
||||
}
|
||||
}
|
31
libs/plugins-runtime/src/lib/load-plugin.ts
Normal file
31
libs/plugins-runtime/src/lib/load-plugin.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { PluginConfig } from './models/plugin-config.model';
|
||||
import { createApi } from './api';
|
||||
import { parseManifest } from './parse-manifest';
|
||||
|
||||
let isLockedDown = false;
|
||||
let lastApi: ReturnType<typeof createApi> | undefined;
|
||||
|
||||
export const ɵloadPlugin = async function (config: PluginConfig) {
|
||||
const { code } = await parseManifest(config);
|
||||
|
||||
try {
|
||||
if (!isLockedDown) {
|
||||
isLockedDown = true;
|
||||
hardenIntrinsics();
|
||||
}
|
||||
|
||||
if (lastApi) {
|
||||
lastApi.closePlugin();
|
||||
}
|
||||
|
||||
lastApi = createApi();
|
||||
|
||||
const c = new Compartment({
|
||||
penpot: harden(lastApi),
|
||||
});
|
||||
|
||||
c.evaluate(code);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
4
libs/plugins-runtime/src/lib/models/manifest.model.ts
Normal file
4
libs/plugins-runtime/src/lib/models/manifest.model.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import z from 'zod';
|
||||
import { manifestSchema } from './manifest.schema';
|
||||
|
||||
export type Manifest = z.infer<typeof manifestSchema>;
|
6
libs/plugins-runtime/src/lib/models/manifest.schema.ts
Normal file
6
libs/plugins-runtime/src/lib/models/manifest.schema.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
export const manifestSchema = z.object({
|
||||
name: z.string(),
|
||||
code: z.string().url(),
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
import z from 'zod';
|
||||
import { openUISchema } from './open-ui-options.schema';
|
||||
|
||||
export type OpenUIOptions = z.infer<typeof openUISchema>;
|
|
@ -0,0 +1,6 @@
|
|||
import { z } from 'zod';
|
||||
|
||||
export const openUISchema = z.object({
|
||||
width: z.number().positive(),
|
||||
height: z.number().positive(),
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
export interface PluginConfig {
|
||||
manifest: string;
|
||||
}
|
35
libs/plugins-runtime/src/lib/parse-manifest.ts
Normal file
35
libs/plugins-runtime/src/lib/parse-manifest.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import { Manifest } from './models/manifest.model';
|
||||
import { manifestSchema } from './models/manifest.schema';
|
||||
import { PluginConfig } from './models/plugin-config.model';
|
||||
|
||||
function loadManifest(url: string): Promise<Manifest> {
|
||||
return fetch(url)
|
||||
.then((response) => response.json())
|
||||
.then((manifest: Manifest) => {
|
||||
const parseResult = manifestSchema.safeParse(manifest);
|
||||
|
||||
if (!parseResult.success) {
|
||||
throw new Error('Invalid plugin manifest');
|
||||
}
|
||||
|
||||
return manifest;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
function loadCode(url: string): Promise<string> {
|
||||
return fetch(url).then((response) => response.text());
|
||||
}
|
||||
|
||||
export async function parseManifest(config: PluginConfig) {
|
||||
const manifest = await loadManifest(config.manifest);
|
||||
const code = await loadCode(manifest.code);
|
||||
|
||||
return {
|
||||
manifest,
|
||||
code,
|
||||
};
|
||||
}
|
105
libs/plugins-runtime/src/lib/plugin-modal.ts
Normal file
105
libs/plugins-runtime/src/lib/plugin-modal.ts
Normal file
|
@ -0,0 +1,105 @@
|
|||
export class PluginModalElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
const title = this.getAttribute('title');
|
||||
const iframeSrc = this.getAttribute('iframe-src');
|
||||
const width = Number(this.getAttribute('width') || '300');
|
||||
const height = Number(this.getAttribute('height') || '400');
|
||||
|
||||
if (!title || !iframeSrc) {
|
||||
throw new Error('title and iframe-src attributes are required');
|
||||
}
|
||||
|
||||
if (!this.shadowRoot) {
|
||||
throw new Error('Error creating shadow root');
|
||||
}
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.classList.add('header');
|
||||
|
||||
const h1 = document.createElement('h1');
|
||||
h1.textContent = title;
|
||||
|
||||
header.appendChild(h1);
|
||||
|
||||
const closeButton = document.createElement('button');
|
||||
closeButton.setAttribute('type', 'button');
|
||||
closeButton.textContent = '❌';
|
||||
closeButton.addEventListener('click', () => {
|
||||
if (!this.shadowRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.shadowRoot.dispatchEvent(
|
||||
new CustomEvent('close', {
|
||||
composed: true,
|
||||
bubbles: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
header.appendChild(closeButton);
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = iframeSrc;
|
||||
|
||||
this.addEventListener('message', (e: Event) => {
|
||||
if (!iframe.contentWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
iframe.contentWindow.postMessage((e as CustomEvent).detail, '*');
|
||||
});
|
||||
|
||||
this.shadowRoot.appendChild(header);
|
||||
this.shadowRoot.appendChild(iframe);
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
inset-block-end: 10px;
|
||||
inset-inline-start: 10px;
|
||||
z-index: 1000;
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
inline-size: ${width}px;
|
||||
block-size: ${height}px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
button {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: blue;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: none;
|
||||
inline-size: 100%;
|
||||
block-size: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
this.shadowRoot.appendChild(style);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('plugin-modal', PluginModalElement);
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
14
nx.json
14
nx.json
|
@ -1,4 +1,9 @@
|
|||
{
|
||||
"pluginsConfig": {
|
||||
"@nx/js": {
|
||||
"analyzeSourceFiles": true
|
||||
}
|
||||
},
|
||||
"extends": "nx/presets/npm.json",
|
||||
"$schema": "./node_modules/nx/schemas/nx-schema.json",
|
||||
"targetDefaults": {
|
||||
|
@ -26,9 +31,12 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"pluginsConfig": {
|
||||
"@nx/js": {
|
||||
"analyzeSourceFiles": true
|
||||
"generators": {
|
||||
"@nx/web:application": {
|
||||
"style": "css",
|
||||
"linter": "eslint",
|
||||
"unitTestRunner": "vitest",
|
||||
"e2eTestRunner": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
788
package-lock.json
generated
788
package-lock.json
generated
|
@ -12,7 +12,9 @@
|
|||
"packages/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
"ses": "^1.1.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^18.6.0",
|
||||
|
@ -2411,261 +2413,10 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
|
||||
"integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
|
||||
"integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
|
||||
"integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
|
||||
"integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
|
||||
"integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
|
||||
"integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
|
||||
"integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
|
||||
"integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
|
||||
"integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
"node_modules/@endo/env-options": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@endo/env-options/-/env-options-1.1.1.tgz",
|
||||
"integrity": "sha512-uCwlJ8Vkndx/VBBo36BdYHdxSoQPy7ZZpwyJNfv86Rh4B1IZfqzCRPf0u0mPgJdzOr7lShQey60SuYwoMSZ9Xg=="
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.19.12",
|
||||
|
@ -2683,102 +2434,6 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
|
||||
"integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
|
||||
"integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
|
||||
"integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
|
@ -3348,102 +3003,6 @@
|
|||
"@nx/eslint": "18.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-darwin-arm64": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-18.0.2.tgz",
|
||||
"integrity": "sha512-zFW5GDrH3GRdm5FePCYuCAEWvJ/G7iiB3jgP0zvLTRe06BQ4Z3bKCQu1v0B/mA7kR+cCY0ZtgHE+9UhK+lWarw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-darwin-x64": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-18.0.2.tgz",
|
||||
"integrity": "sha512-Iihl8MK7NiDxn6pyhe/sctEv5J2MOK2bLJH3hBgJXbq8h278jAXqM5zLxVO49Kya65K7idAu1g5nvrRtafUIXg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-freebsd-x64": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.0.2.tgz",
|
||||
"integrity": "sha512-D6pFFLRZs5f99oF3nHWMHhEYBVDB7x0kaDuR+96FfQlZXPU2SSQ+fzV1TREeQPhfHf9owgcduiE4utrOgJBTOQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-linux-arm-gnueabihf": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.0.2.tgz",
|
||||
"integrity": "sha512-TCEKHBByEqIjiMNGOWS3maPpqQq1syUKOfp4fLJyE9A+NEK0th/6s65RWtzQR/GBUsi5r5y5g/pt+XFup+DrMA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-linux-arm64-gnu": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.0.2.tgz",
|
||||
"integrity": "sha512-oYWeWtLmtM2LmsTStc6P4xUSJvpZxHZCoHIAFw1Rw7LQRbTyky19XR87F2mbEJbhSPMymeeLDR6SN0JSplODLg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-linux-arm64-musl": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.0.2.tgz",
|
||||
"integrity": "sha512-9I27P5IilvICsLJxmh79OG6Y21uFKaqDAKCDlc608cyAH48Rq9xVM24DEQD0cITbfOjMRBBO2rMl7XX3b81w9Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-linux-x64-gnu": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-18.0.2.tgz",
|
||||
|
@ -3476,38 +3035,6 @@
|
|||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-win32-arm64-msvc": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.0.2.tgz",
|
||||
"integrity": "sha512-pLc0SC/bEh8TC5H//pD+vHYUNCdYLWsMB9xAdey6V2qmKPrrDuWTs69qh0zCW4S1Jm8C9XK1av5mWIp2Fj8KnA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/nx-win32-x64-msvc": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.0.2.tgz",
|
||||
"integrity": "sha512-alWijWoroV65IRLdAQhFpINS9SRYSncWVT7CYe1iWwjiT16Un2i4NDoselpADuAsYC+Rgd+4h5Y+XzwtsQ55gg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@nx/vite": {
|
||||
"version": "18.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@nx/vite/-/vite-18.0.2.tgz",
|
||||
|
@ -3597,110 +3124,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz",
|
||||
"integrity": "sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz",
|
||||
"integrity": "sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz",
|
||||
"integrity": "sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz",
|
||||
"integrity": "sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz",
|
||||
"integrity": "sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz",
|
||||
"integrity": "sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz",
|
||||
"integrity": "sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz",
|
||||
"integrity": "sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz",
|
||||
|
@ -3727,45 +3150,6 @@
|
|||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz",
|
||||
"integrity": "sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz",
|
||||
"integrity": "sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.9.6",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz",
|
||||
"integrity": "sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rushstack/node-core-library": {
|
||||
"version": "3.64.2",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.64.2.tgz",
|
||||
|
@ -3987,86 +3371,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-arm64": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.107.tgz",
|
||||
"integrity": "sha512-47tD/5vSXWxPd0j/ZllyQUg4bqalbQTsmqSw0J4dDdS82MWqCAwUErUrAZPRjBkjNQ6Kmrf5rpCWaGTtPw+ngw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-x64": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.107.tgz",
|
||||
"integrity": "sha512-hwiLJ2ulNkBGAh1m1eTfeY1417OAYbRGcb/iGsJ+LuVLvKAhU/itzsl535CvcwAlt2LayeCFfcI8gdeOLeZa9A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.107.tgz",
|
||||
"integrity": "sha512-I2wzcC0KXqh0OwymCmYwNRgZ9nxX7DWnOOStJXV3pS0uB83TXAkmqd7wvMBuIl9qu4Hfomi9aDM7IlEEn9tumQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-gnu": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.107.tgz",
|
||||
"integrity": "sha512-HWgnn7JORYlOYnGsdunpSF8A+BCZKPLzLtEUA27/M/ZuANcMZabKL9Zurt7XQXq888uJFAt98Gy+59PU90aHKg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-musl": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.107.tgz",
|
||||
"integrity": "sha512-vfPF74cWfAm8hyhS8yvYI94ucMHIo8xIYU+oFOW9uvDlGQRgnUf/6DEVbLyt/3yfX5723Ln57U8uiMALbX5Pyw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-gnu": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.107.tgz",
|
||||
|
@ -4099,54 +3403,6 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-arm64-msvc": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.107.tgz",
|
||||
"integrity": "sha512-J3P14Ngy/1qtapzbguEH41kY109t6DFxfbK4Ntz9dOWNuVY3o9/RTB841ctnJk0ZHEG+BjfCJjsD2n8H5HcaOA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-ia32-msvc": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.107.tgz",
|
||||
"integrity": "sha512-ZBUtgyjTHlz8TPJh7kfwwwFma+ktr6OccB1oXC8fMSopD0AxVnQasgun3l3099wIsAB9eEsJDQ/3lDkOLs1gBA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-x64-msvc": {
|
||||
"version": "1.3.107",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.107.tgz",
|
||||
"integrity": "sha512-Eyzo2XRqWOxqhE1gk9h7LWmUf4Bp4Xn2Ttb0ayAXFp6YSTxQIThXcT9kipXZqcpxcmDwoq8iWbbf2P8XL743EA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/counter": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.2.tgz",
|
||||
|
@ -6677,20 +5933,6 @@
|
|||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
|
@ -9386,6 +8628,14 @@
|
|||
"randombytes": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ses": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ses/-/ses-1.2.0.tgz",
|
||||
"integrity": "sha512-+klZ2zjFPbHAkf9owGeih+ZB1lqUqvVoCeL5IpNXmIZPhI5rGE1tR729EZmfBzmPh8j+CrsLr/+cTZUmHGFr9g==",
|
||||
"dependencies": {
|
||||
"@endo/env-options": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz",
|
||||
|
@ -10972,6 +10222,14 @@
|
|||
"optionalDependencies": {
|
||||
"commander": "^9.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "3.22.4",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz",
|
||||
"integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "npx nx run plugins-runtime:serve-static",
|
||||
"start": "npx nx run plugins-runtime:serve-static --port 4200",
|
||||
"start:example": "npx nx run example-plugin:serve-static --port 4201",
|
||||
"build": "npx nx build plugins-runtime --emptyOutDir=true",
|
||||
"lint": "nx run-many --all --target=lint --parallel",
|
||||
"lint:affected": "npx nx affected --target=lint",
|
||||
|
@ -42,7 +43,8 @@
|
|||
"packages/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
"ses": "^1.1.0",
|
||||
"tslib": "^2.3.0",
|
||||
"zod": "^3.22.4"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
# plugins-runtime
|
||||
|
||||
Go to to the [this branch](https://github.com/penpot/penpot/tree/niwinz-poc-plugins) in the Penpot local code.
|
||||
|
||||
Open `penpot/frontend/resources/templates/index.mustache` and replace the below:
|
||||
|
||||
```html
|
||||
<script type="importmap">
|
||||
{ "imports": { "plugins-runtime": "/js/plugins-runtime.mjs" } }
|
||||
</script>
|
||||
```
|
||||
|
||||
New code:
|
||||
|
||||
```
|
||||
<script type="importmap">
|
||||
{"imports": {"plugins-runtime": "http://localhost:4200/index.mjs"}}
|
||||
</script>
|
||||
```
|
||||
|
||||
Run the penpot runtime with `npm start`.
|
||||
|
||||
Now you can go to penpot and see the `log` of this file `plugins-runtime/src/index.ts`.
|
|
@ -1,13 +0,0 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export function initialize(api: any) {
|
||||
console.log('plugin context');
|
||||
console.log(api);
|
||||
|
||||
api.addListener('plugin-page', 'page', (page: any) => {
|
||||
console.log('Page Changed:', page);
|
||||
});
|
||||
|
||||
api.addListener('plugin file', 'file', (file: any) => {
|
||||
console.log('File Changed:', file);
|
||||
});
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
export class PenpotRuntimeElement extends HTMLElement {
|
||||
// connectedCallback() {}
|
||||
}
|
||||
|
||||
customElements.define('plugins-runtime', PenpotRuntimeElement);
|
|
@ -15,7 +15,7 @@
|
|||
"skipDefaultLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"plugins-runtime": ["plugins-runtime/src/index.ts"],
|
||||
"plugins-runtime": ["libs/plugins-runtime/src/index.ts"],
|
||||
"plugins-styles": ["plugins-styles/src/index.ts"]
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in a new issue