Compare commits

...

26 Commits

Author SHA1 Message Date
Andrey Antukh
f65292a13c 📎 Mark as skip two text editor v2 tests (flaky) 2026-01-29 10:43:29 +01:00
Andrey Antukh
94722fdec2 Ensure .hidePopover fn exist before call 2026-01-29 10:43:29 +01:00
Andrey Antukh
28509e0418 Ensure .stopPropagation fn exists before calling
Also for .stopImmediatePropagation and .preventDefault on
the event instances.
2026-01-29 10:43:29 +01:00
Eva Marco
9569fa2bcb 🐛 Fix error when creating a token with an invalid name (#8216) 2026-01-29 10:41:52 +01:00
Eva Marco
852b31c3a0 🐛 Fix allow spaces on token description (#8234) 2026-01-29 10:40:32 +01:00
Andrés Moya
84b3f5d7c6 🐛 Fix import of shadow tokens 2026-01-29 10:25:22 +01:00
David Barragán Merino
cc81e56d82 🔧 Fix CORS error 2026-01-28 13:40:26 +01:00
Andrey Antukh
a9e2fc8d94 Backport linter fixes and config from develop 2026-01-28 12:58:54 +01:00
David Barragán Merino
18aca16f98 🔧 Fix file name 2026-01-27 21:12:32 +01:00
David Barragán Merino
c6465e27e3 📚 Fix links related to penpot plugins 2026-01-27 21:12:32 +01:00
David Barragán Merino
1834a18263 🔧 Deploy plugin styles documentation 2026-01-27 21:12:32 +01:00
David Barragán Merino
d220d07875 🔧 Add custom domain 2026-01-27 21:12:32 +01:00
Eva Marco
9ca76c745f 🐛 Fix app freeze on token name change (#8214) 2026-01-27 17:31:50 +01:00
Andrey Antukh
3112b240a0 📎 Add missing entry on changelog 2026-01-27 09:28:41 +01:00
Andrey Antukh
56fd66b91a 🐛 Fix several issues related to path edition (#8187)
*  Improve save-path-content event consistency

Mainly removing possible race conditions from the event
implementation.

*  Ensure path content snapshot on start-path-edit event

*  Reuse already available shape-id on split-segments
2026-01-27 09:27:42 +01:00
David Barragán Merino
1ce0b60e3d 🔧 Run all the jobs if the workflow is launched manually 2026-01-26 17:13:54 +01:00
David Barragán Merino
ef80901400 🔧 Enable secret inheritance 2026-01-26 14:00:55 +01:00
David Barragán Merino
5306bed548 🔧 Define deploy plugin packages workflows 2026-01-26 13:47:57 +01:00
David Barragán Merino
92a319ddd1 🔧 Rename wrangle to wrangler 2026-01-26 13:47:57 +01:00
David Barragán Merino
68a6d4c9a8 🔧 Add deploy plugin packages workflow placeholder and wrangle config files 2026-01-26 13:47:57 +01:00
Andrey Antukh
f07495ae95 🐛 Fix incorrect handling of numeric values layout padding and gap
Fixes https://github.com/penpot/penpot/issues/8113
2026-01-26 11:01:25 +01:00
Andrey Antukh
23d5fc7408 🐛 Prevent exception on open-new-window when no window is returned
Fixes https://github.com/penpot/penpot/issues/7787
2026-01-26 11:01:25 +01:00
Andrey Antukh
8632b18eec 🐛 Avoid json decoder liner limit exception by chunking
Happens only when we send large binary data serialized with transit
(mainly used for upload fonts data).
2026-01-26 11:01:25 +01:00
Andrey Antukh
33e650242c Add slugify to the filename on assets exportation
Fixes https://github.com/penpot/penpot/issues/8017
2026-01-26 11:01:25 +01:00
Andrey Antukh
e03ad25118 🔧 Backport CI workflow from develop 2026-01-26 10:18:24 +01:00
David Barragán Merino
5d7e6afd76 🔧 Fix a typo in an interpolation 2026-01-23 19:52:20 +01:00
57 changed files with 720 additions and 114 deletions

View File

@@ -45,6 +45,15 @@
:potok/reify-type
{:level :error}
:redundant-primitive-coercion
{:level :off}
:unused-excluded-var
{:level :off}
:unresolved-excluded-var
{:level :off}
:missing-protocol-method
{:level :off}

View File

@@ -33,7 +33,7 @@ jobs:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK }}
MATTERMOST_CHANNEL: bot-alerts-cicd
TEXT: |
🐳 *[PENPOT] Docker image available: {{ github.ref_name }}*
🐳 *[PENPOT] Docker image available: ${{ github.ref_name }}*
🔗 Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
@infra

View File

@@ -7,11 +7,11 @@ on:
- staging
- main
paths:
- "plugins/libs/plugin-types/index.d.ts"
- "plugins/libs/plugin-types/REAME.md"
- "plugins/tools/typedoc.css"
- "plugins/CHANGELOG.md"
- "plugins/wrangle-penpot-plugins-api-doc.toml"
- 'plugins/libs/plugin-types/index.d.ts'
- 'plugins/libs/plugin-types/REAME.md'
- 'plugins/tools/typedoc.css'
- 'plugins/CHANGELOG.md'
- 'plugins/wrangler-penpot-plugins-api-doc.toml'
workflow_dispatch:
inputs:
gh_ref:
@@ -86,16 +86,40 @@ jobs:
run: |
REF="${{ steps.vars.outputs.gh_ref }}"
case "$REF" in
main) echo "WORKER_NAME=penpot-plugins-api-doc-pro" >> $GITHUB_ENV ;;
staging) echo "WORKER_NAME=penpot-plugins-api-doc-pre" >> $GITHUB_ENV ;;
develop) echo "WORKER_NAME=penpot-plugins-api-doc-hourly" >> $GITHUB_ENV ;;
main)
echo "WORKER_NAME=penpot-plugins-api-doc-pro" >> $GITHUB_ENV
echo "WORKER_URI=doc.plugins.penpot.app" >> $GITHUB_ENV ;;
staging)
echo "WORKER_NAME=penpot-plugins-api-doc-pre" >> $GITHUB_ENV
echo "WORKER_URI=doc.plugins.penpot.dev" >> $GITHUB_ENV ;;
develop)
echo "WORKER_NAME=penpot-plugins-api-doc-hourly" >> $GITHUB_ENV
echo "WORKER_URI=doc.plugins.hourly.penpot.dev" >> $GITHUB_ENV ;;
*) echo "Unsupported branch ${REF}" && exit 1 ;;
esac
- name: Set the custom url
working-directory: plugins
shell: bash
run: |
sed -i "s/WORKER_URI/${{ env.WORKER_URI }}/g" wrangler-penpot-plugins-api-doc.toml
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v3
with:
workingDirectory: plugins
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --config wrangle-penpot-plugins-api-doc.toml --name ${{ env.WORKER_NAME }}
command: deploy --config wrangler-penpot-plugins-api-doc.toml --name ${{ env.WORKER_NAME }}
- name: Notify Mattermost
if: failure()
uses: mattermost/action-mattermost-notify@master
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK }}
MATTERMOST_CHANNEL: bot-alerts-cicd
TEXT: |
❌ 🧩📚 *[PENPOT PLUGINS] Error deploying API documentation.*
📄 Triggered from ref: `${{ inputs.gh_ref }}`
🔗 Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
@infra

View File

@@ -0,0 +1,127 @@
name: Plugins/package deployer
on:
# Deploy package from manual action
workflow_dispatch:
inputs:
gh_ref:
description: 'Name of the branch'
type: choice
required: true
default: 'develop'
options:
- develop
- staging
- main
plugin_name:
description: 'Pluging name (like plugins/apps/<plugin_name>-plugin)'
type: string
required: true
workflow_call:
inputs:
gh_ref:
description: 'Name of the branch'
type: string
required: true
default: 'develop'
plugin_name:
description: 'Publig name (from plugins/apps/<plugin_name>-plugin)'
type: string
required: true
permissions:
contents: read
jobs:
deploy:
runs-on: penpot-runner-01
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ inputs.gh_ref }}
# START: Setup Node and PNPM enabling cache
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
- name: Enable PNPM
working-directory: ./plugins
shell: bash
run: |
corepack enable;
corepack install;
- name: Get pnpm store path
id: pnpm-store
working-directory: ./plugins
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-store.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('plugins/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
# END: Setup Node and PNPM enabling cache
- name: Install deps
working-directory: ./plugins
shell: bash
run: |
pnpm install --no-frozen-lockfile;
pnpm add -D -w wrangler@latest;
- name: "Build package for ${{ inputs.plugin_name }}-plugin"
working-directory: plugins
shell: bash
run: npx nx build ${{ inputs.plugin_name }}-plugin
- name: Select Worker name
run: |
REF="${{ inputs.gh_ref }}"
case "$REF" in
main)
echo "WORKER_NAME=${{ inputs.plugin_name }}-plugin-pro" >> $GITHUB_ENV
echo "WORKER_URI=${{ inputs.plugin_name }}.plugins.penpot.app" >> $GITHUB_ENV ;;
staging)
echo "WORKER_NAME=${{ inputs.plugin_name }}-plugin-pre" >> $GITHUB_ENV
echo "WORKER_URI=${{ inputs.plugin_name }}.plugins.penpot.dev" >> $GITHUB_ENV ;;
develop)
echo "WORKER_NAME=${{ inputs.plugin_name }}-plugin-hourly" >> $GITHUB_ENV
echo "WORKER_URI=${{ inputs.plugin_name }}.plugins.hourly.penpot.dev" >> $GITHUB_ENV ;;
*) echo "Unsupported branch ${REF}" && exit 1 ;;
esac
- name: Set the custom url
working-directory: plugins
shell: bash
run: |
sed -i "s/WORKER_URI/${{ env.WORKER_URI }}/g" apps/${{ inputs.plugin_name }}-plugin/wrangler.toml
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v3
with:
workingDirectory: plugins
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --config apps/${{ inputs.plugin_name }}-plugin/wrangler.toml --name ${{ env.WORKER_NAME }}
- name: Notify Mattermost
if: failure()
uses: mattermost/action-mattermost-notify@master
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK }}
MATTERMOST_CHANNEL: bot-alerts-cicd
TEXT: |
❌ 🧩📦 *[PENPOT PLUGINS] Error deploying ${{ env.WORKER_NAME }}.*
📄 Triggered from ref: `${{ inputs.gh_ref }}`
Plugin name: `${{ inputs.plugin_name }}-plugin`
Cloudflare worker name: `${{ env.WORKER_NAME }}`
🔗 Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
@infra

View File

@@ -0,0 +1,143 @@
name: Plugins/packages deployer
on:
push:
branches:
- develop
- staging
- main
paths:
- 'plugins/apps/*-plugin/**'
- 'libs/plugins-styles/**'
workflow_dispatch:
inputs:
gh_ref:
description: 'Name of the branch'
type: choice
required: true
default: 'develop'
options:
- develop
- staging
- main
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
colors_to_tokens: ${{ steps.filter.outputs.colors_to_tokens }}
create_palette: ${{ steps.filter.outputs.create_palette }}
lorem_ipsum: ${{ steps.filter.outputs.lorem_ipsum }}
rename_layers: ${{ steps.filter.outputs.rename_layers }}
contrast: ${{ steps.filter.outputs.contrast }}
icons: ${{ steps.filter.outputs.icons }}
poc_state: ${{ steps.filter.outputs.poc_state }}
table: ${{ steps.filter.outputs.table }}
# [For new plugins]
# Add more outputs here
steps:
- uses: actions/checkout@v4
- id: filter
uses: dorny/paths-filter@v3
with:
filters: |
colors_to_tokens:
- 'plugins/apps/colors-to-tokens-plugin/**'
- 'libs/plugins-styles/**'
contrast:
- 'plugins/apps/contrast-plugin/**'
- 'libs/plugins-styles/**'
create_palette:
- 'plugins/apps/create-palette-plugin/**'
- 'libs/plugins-styles/**'
icons:
- 'plugins/apps/icons-plugin/**'
- 'libs/plugins-styles/**'
lorem_ipsum:
- 'plugins/apps/lorem-ipsum-plugin/**'
- 'libs/plugins-styles/**'
rename_layers:
- 'plugins/apps/rename-layers-plugin/**'
- 'libs/plugins-styles/**'
table:
- 'plugins/apps/table-plugin/**'
- 'libs/plugins-styles/**'
# [For new plugins]
# Add more plugin filters here
# another_plugin:
# - 'plugins/apps/another-plugin/**'
# - 'libs/plugins-styles/**'
colors-to-tokens-plugin:
needs: detect-changes
if: github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.colors_to_tokens == 'true'
uses: ./.github/workflows/plugins-deploy-package.yml
secrets: inherit
with:
gh_ref: "${{ inputs.gh_ref || github.ref_name }}"
plugin_name: colors-to-tokens
contrast-plugin:
needs: detect-changes
if: github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.contrast == 'true'
uses: ./.github/workflows/plugins-deploy-package.yml
secrets: inherit
with:
gh_ref: "${{ inputs.gh_ref || github.ref_name }}"
plugin_name: contrast
create-palette-plugin:
needs: detect-changes
if: github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.create_palette == 'true'
uses: ./.github/workflows/plugins-deploy-package.yml
secrets: inherit
with:
gh_ref: "${{ inputs.gh_ref || github.ref_name }}"
plugin_name: create-palette
icons-plugin:
needs: detect-changes
if: github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.icons == 'true'
uses: ./.github/workflows/plugins-deploy-package.yml
secrets: inherit
with:
gh_ref: "${{ inputs.gh_ref || github.ref_name }}"
plugin_name: icons
lorem-ipsum-plugin:
needs: detect-changes
if: github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.lorem_ipsum == 'true'
uses: ./.github/workflows/plugins-deploy-package.yml
secrets: inherit
with:
gh_ref: "${{ inputs.gh_ref || github.ref_name }}"
plugin_name: lorem-ipsum
rename-layers-plugin:
needs: detect-changes
if: github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.rename_layers == 'true'
uses: ./.github/workflows/plugins-deploy-package.yml
secrets: inherit
with:
gh_ref: "${{ inputs.gh_ref || github.ref_name }}"
plugin_name: rename-layers
table-plugin:
needs: detect-changes
if: github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.table == 'true'
uses: ./.github/workflows/plugins-deploy-package.yml
secrets: inherit
with:
gh_ref: "${{ inputs.gh_ref || github.ref_name }}"
plugin_name: table
# [For new plugins]
# Add more jobs for other plugins below, following the same pattern
# another-plugin:
# needs: detect-changes
# if: github.event_name == 'workflow_dispatch' || needs.detect-changes.outputs.another_plugin == 'true'
# uses: ./.github/workflows/plugins-deploy-package.yml
# secrets: inherit
# with:
# gh_ref: "${{ inputs.gh_ref || github.ref_name }}"
# plugin_name: another

View File

@@ -0,0 +1,123 @@
name: Plugins/styles-doc deployer
on:
push:
branches:
- develop
- staging
- main
paths:
- 'plugins/apps/example-styles/**'
- 'plugins/libs/plugins-styles/**'
- 'plugins/wrangler-penpot-plugins-styles-doc.toml'
workflow_dispatch:
inputs:
gh_ref:
description: 'Name of the branch'
type: choice
required: true
default: 'develop'
options:
- develop
- staging
- main
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Extract some useful variables
id: vars
run: |
echo "gh_ref=${{ inputs.gh_ref || github.ref_name }}" >> $GITHUB_OUTPUT
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ steps.vars.outputs.gh_ref }}
# START: Setup Node and PNPM enabling cache
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
- name: Enable PNPM
working-directory: ./plugins
shell: bash
run: |
corepack enable;
corepack install;
- name: Get pnpm store path
id: pnpm-store
working-directory: ./plugins
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-store.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('plugins/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
# END: Setup Node and PNPM enabling cache
- name: Install deps
working-directory: ./plugins
shell: bash
run: |
pnpm install --no-frozen-lockfile;
pnpm add -D -w wrangler@latest;
- name: Build styles
working-directory: plugins
shell: bash
run: npx nx run example-styles:build
- name: Select Worker name
run: |
REF="${{ steps.vars.outputs.gh_ref }}"
case "$REF" in
main)
echo "WORKER_NAME=penpot-plugins-styles-doc-pro" >> $GITHUB_ENV
echo "WORKER_URI=styles-doc.plugins.penpot.app" >> $GITHUB_ENV ;;
staging)
echo "WORKER_NAME=penpot-plugins-styles-doc-pre" >> $GITHUB_ENV
echo "WORKER_URI=styles-doc.plugins.penpot.dev" >> $GITHUB_ENV ;;
develop)
echo "WORKER_NAME=penpot-plugins-styles-doc-hourly" >> $GITHUB_ENV
echo "WORKER_URI=styles-doc.plugins.hourly.penpot.dev" >> $GITHUB_ENV ;;
*) echo "Unsupported branch ${REF}" && exit 1 ;;
esac
- name: Set the custom url
working-directory: plugins
shell: bash
run: |
sed -i "s/WORKER_URI/${{ env.WORKER_URI }}/g" wrangler-penpot-plugins-styles-doc.toml
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v3
with:
workingDirectory: plugins
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy --config wrangler-penpot-plugins-styles-doc.toml --name ${{ env.WORKER_NAME }}
- name: Notify Mattermost
if: failure()
uses: mattermost/action-mattermost-notify@master
with:
MATTERMOST_WEBHOOK_URL: ${{ secrets.MATTERMOST_WEBHOOK }}
MATTERMOST_CHANNEL: bot-alerts-cicd
TEXT: |
❌ 🧩💅 *[PENPOT PLUGINS] Error deploying Styles documentation.*
📄 Triggered from ref: `${{ inputs.gh_ref }}`
🔗 Run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
@infra

View File

@@ -21,7 +21,7 @@ concurrency:
jobs:
lint:
name: "Linter"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
steps:
@@ -34,7 +34,7 @@ jobs:
test-common:
name: "Common Tests"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
steps:
@@ -53,7 +53,8 @@ jobs:
test-plugins:
name: Plugins Runtime Linter & Tests
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
steps:
- uses: actions/checkout@v4
@@ -98,7 +99,7 @@ jobs:
test-frontend:
name: "Frontend Tests"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
steps:
@@ -119,7 +120,7 @@ jobs:
test-render-wasm:
name: "Render WASM Tests"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
steps:
@@ -143,7 +144,7 @@ jobs:
test-backend:
name: "Backend Tests"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
services:
@@ -182,7 +183,7 @@ jobs:
test-library:
name: "Library Tests"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
steps:
@@ -196,7 +197,7 @@ jobs:
build-integration:
name: "Build Integration Bundle"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
steps:
@@ -217,7 +218,7 @@ jobs:
test-integration-1:
name: "Integration Tests 1/4"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
needs: build-integration
@@ -247,7 +248,7 @@ jobs:
test-integration-2:
name: "Integration Tests 2/4"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
needs: build-integration
@@ -277,7 +278,7 @@ jobs:
test-integration-3:
name: "Integration Tests 3/4"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
needs: build-integration
@@ -307,7 +308,7 @@ jobs:
test-integration-4:
name: "Integration Tests 4/4"
runs-on: ubuntu-24.04
runs-on: penpot-runner-02
container: penpotapp/devenv:latest
needs: build-integration

View File

@@ -32,6 +32,15 @@
- Fix unhandled exception tokens creation dialog [Github #8110](https://github.com/penpot/penpot/issues/8110)
- Fix allow negative spread values on shadow token creation [Taiga #13167](https://tree.taiga.io/project/penpot/issue/13167)
- Fix spanish translations on import export token modal [Taiga #13171](https://tree.taiga.io/project/penpot/issue/13171)
- Remove whitespaces from asset export filename [Github #8133](https://github.com/penpot/penpot/pull/8133)
- Fix exception on uploading large fonts [Github #8135](https://github.com/penpot/penpot/pull/8135)
- Fix unhandled exception on open-new-window helper [Github #7787](https://github.com/penpot/penpot/issues/7787)
- Fix incorrect handling of input values on layout gap and padding inputs [Github #8113](https://github.com/penpot/penpot/issues/8113)
- Fix several race conditions on path editor [Github #8187](https://github.com/penpot/penpot/pull/8187)
- Fix app freeze when introducing an error on a very long token name [Taiga #13214](https://tree.taiga.io/project/penpot/issue/13214)
- Fix import a file with shadow tokens [Taiga #13229](https://tree.taiga.io/project/penpot/issue/13229)
- Fix allow spaces on token description [Taiga #13184](https://tree.taiga.io/project/penpot/issue/13184)
- Fix error when creating a token with an invalid name [Taiga #13219](https://tree.taiga.io/project/penpot/issue/13219)
## 2.12.1

View File

@@ -873,11 +873,8 @@
(import-storage-objects cfg)
(let [files (get manifest :files)
result (reduce (fn [result {:keys [id] :as file}]
result (reduce (fn [result file]
(let [name' (get file :name)
name' (if (map? name)
(get name id)
name')
file (assoc file :name name')]
(conj result (import-file cfg file))))
[]

View File

@@ -27,7 +27,17 @@
[app.rpc.helpers :as rph]
[app.rpc.quotes :as quotes]
[app.storage :as sto]
[app.util.services :as sv]))
[app.storage.tmp :as tmp]
[app.util.services :as sv]
[datoteka.io :as io])
(:import
java.io.InputStream
java.io.OutputStream
java.io.SequenceInputStream
java.util.Collections))
(set! *warn-on-reflection* true)
(def valid-weight #{100 200 300 400 500 600 700 800 900 950})
(def valid-style #{"normal" "italic"})
@@ -105,7 +115,7 @@
(defn create-font-variant
[{:keys [::sto/storage ::db/conn]} {:keys [data] :as params}]
(letfn [(generate-missing! [data]
(letfn [(generate-missing [data]
(let [data (media/run {:cmd :generate-fonts :input data})]
(when (and (not (contains? data "font/otf"))
(not (contains? data "font/ttf"))
@@ -116,8 +126,26 @@
:hint "invalid font upload, unable to generate missing font assets"))
data))
(process-chunks [chunks]
(let [tmp (tmp/tempfile :prefix "penpot.tempfont." :suffix "")
streams (map io/input-stream chunks)
streams (Collections/enumeration streams)]
(with-open [^OutputStream output (io/output-stream tmp)
^InputStream input (SequenceInputStream. streams)]
(io/copy input output))
tmp))
(join-chunks [data]
(reduce-kv (fn [data mtype content]
(if (vector? content)
(assoc data mtype (process-chunks content))
data))
data
data))
(prepare-font [data mtype]
(when-let [resource (get data mtype)]
(let [hash (sto/calculate-hash resource)
content (-> (sto/content resource)
(sto/wrap-with-hash hash))]
@@ -156,7 +184,8 @@
:otf-file-id (:id otf)
:ttf-file-id (:id ttf)}))]
(let [data (generate-missing! data)
(let [data (join-chunks data)
data (generate-missing data)
assets (persist-fonts-files! data)
result (insert-font-variant! assets)]
(vary-meta result assoc ::audit/replace-props (update params :data (comp vec keys))))))

View File

@@ -97,9 +97,12 @@
(def token-types
(into #{} (keys token-type->dtcg-token-type)))
(def token-name-validation-regex
#"^[a-zA-Z0-9_-][a-zA-Z0-9$_-]*(\.[a-zA-Z0-9$_-]+)*$")
(def token-name-ref
[:re {:title "TokenNameRef" :gen/gen sg/text}
#"^(?!\$)([a-zA-Z0-9-$_]+\.?)*(?<!\.)$"])
token-name-validation-regex])
(def ^:private schema:color
[:map

View File

@@ -1462,11 +1462,12 @@ Will return a value that matches this schema:
(def ^:private schema:dtcg-node
[:schema {:registry
{::simple-value
[:or :string :int :double]
[:or :string :int :double ::sm/boolean]
::value
[:or
[:ref ::simple-value]
[:vector ::simple-value]
[:vector [:map-of :string ::simple-value]]
[:map-of :string [:or
[:ref ::simple-value]
[:vector ::simple-value]]]]}}

View File

@@ -6,4 +6,4 @@ desc: Create, deploy, and use the Penpot plugin API with our comprehensive docum
# Penpot plugins API
We've got all the documentation you need for the API right <a target="_blank" href="https://penpot-plugins-api-doc.pages.dev/">here</a>.
We've got all the documentation you need for the API right <a target="_blank" href="https://doc.plugins.penpot.app/">here</a>.

View File

@@ -9,13 +9,13 @@ desc: See the Penpot plugin API changelog for version 1.0! Find breaking changes
### <g-emoji class="g-emoji" alias="boom" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f680.png"><img class="emoji" alt="boom" height="20" width="20" src="https://github.githubassets.com/images/icons/emoji/unicode/1f680.png"></g-emoji> Epics and highlights</code>
- This marks the release of version 1.0, and from this point forward, well do our best to avoid making any more breaking changes (or make deprecations backward compatible).
- Weve redone the documentation. You can check the API here:
[https://penpot-plugins-api-doc.pages.dev/](https://penpot-plugins-api-doc.pages.dev/)
[https://doc.plugins.penpot.app/](https://doc.plugins.penpot.app/)
- New samples repository with lots of samples to use the API:
[https://github.com/penpot/penpot-plugins-samples](https://github.com/penpot/penpot-plugins-samples)
### <g-emoji class="g-emoji" alias="boom" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f4a5.png"><img class="emoji" alt="boom" height="20" width="20" src="https://github.githubassets.com/images/icons/emoji/unicode/1f4a5.png"></g-emoji> Breaking changes & Deprecations
- Changed types names to remove the Penpot prefix. So for example: <code class="language-js">PenpotShape</code> becomes <code class="language-js">Shape</code>; <code class="language-js">PenpotFile</code> becomes <code class="language-js">File</code>, and so on. Check the [API documentation](https://penpot-plugins-api-doc.pages.dev/) for more details.
- Changed types names to remove the Penpot prefix. So for example: <code class="language-js">PenpotShape</code> becomes <code class="language-js">Shape</code>; <code class="language-js">PenpotFile</code> becomes <code class="language-js">File</code>, and so on. Check the [API documentation](https://doc.plugins.penpot.app/) for more details.
- Changes on the <code class="language-js">penpot.on</code> and <code class="language-js">penpot.off</code> methods.
Previously you had to send the original callback to the off method in order to remove an event listener. Now, <code class="language-js">penpot.on</code> will return an *id* that you can pass to the <code class="language-js">penpot.off</code> method in order to remove the listener.

View File

@@ -49,7 +49,7 @@ There are two libraries that can help you with your plugin's development. They a
### Plugin styles
<code class="language-js">@penpot/plugin-styles</code> contains styles to help build the UI for Penpot plugins. To check the styles go to <a target="_blank" href="https://penpot-plugins-styles.pages.dev/">Plugin styles</a>.
<code class="language-js">@penpot/plugin-styles</code> contains styles to help build the UI for Penpot plugins. To check the styles go to <a target="_blank" href="https://styles-doc.plugins.penpot.app/">Plugin styles</a>.
```bash
npm install @penpot/plugin-styles
@@ -139,7 +139,7 @@ parent.postMessage(responseMessage, targetOrigin);
By using these message-based events, any data retrieved through the Penpot API can be communicated to and from your plugin interface seamlessly.
For more detailed information, refer to the [Penpot Plugins API Documentation](https://penpot-plugins-api-doc.pages.dev/).
For more detailed information, refer to the [Penpot Plugins API Documentation](https://doc.plugins.penpot.app/).
## 2.5. Step 5. Build the plugin file

View File

@@ -86,7 +86,7 @@ penpot.library.local.createTypography();
Penpot has dark and light modes, and you can easily add this to your plugin so your interface adapts to both themes. When you add theme support, your plugin will automatically sync with Penpot's interface settings, so the user experience is consistent no matter which mode is selected. This makes your plugin look better and also ensures it stays in line with Penpot's overall design.
Just a heads-up: if you use the <a target="_blank" href="https://penpot-plugins-styles.pages.dev/">plugin-styles library</a>, many elements will automatically adapt to dark or light mode without any extra effort from you. However, if you need to customize specific elements, be sure to use the selectors provided in the <code class="language-bash">styles.css</code> of the example.
Just a heads-up: if you use the <a target="_blank" href="https://styles-doc.plugins.penpot.app/">plugin-styles library</a>, many elements will automatically adapt to dark or light mode without any extra effort from you. However, if you need to customize specific elements, be sure to use the selectors provided in the <code class="language-bash">styles.css</code> of the example.
<a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/theme">Theme example</a>

View File

@@ -40,7 +40,7 @@ The plugin <a target="_blank" href="https://www.npmjs.com/package/@penpot/plugin
### Is the API ready to use the prototyping features?
Absolutely! You can definitely create flows and interactions in the same elements as in the interface, like frames, shapes, and groups. Just check out the API documentation for the methods: createFlow, addInteraction, or removeInteraction. And if you need more help, you can always check out the <a target="_blank" href="https://penpot-plugins-api-doc.pages.dev/interfaces/PenpotFlow">PenpotFlow</a> or <a target="_blank" href="https://penpot-plugins-api-doc.pages.dev/interfaces/PenpotInteraction">PenpotInteraction</a> interfaces.
Absolutely! You can definitely create flows and interactions in the same elements as in the interface, like frames, shapes, and groups. Just check out the API documentation for the methods: createFlow, addInteraction, or removeInteraction. And if you need more help, you can always check out the <a target="_blank" href="https://doc.plugins.penpot.app/interfaces/Flow">Flow</a> or <a target="_blank" href="https://doc.plugins.penpot.app/interfaces/Interaction">Interaction</a> interfaces.
### Are there any security or quality criteria I should be aware of?
@@ -48,7 +48,8 @@ There are no set requirements. However, we can recommend the use of <a target="_
### Is it necessary to create plugins with a UI?
No, its completely optional, in fact, we have an example of a plugin without UI. Try the plugin using this url to install it: <code class="language-js">https:\/\/create-palette-penpot-plugin.pages.dev/assets/manifest.json</code> or check the code <a target="_blank" href="https://github.com/penpot/penpot-plugins/tree/main/apps/create-palette-plugin">here</a>
No, its completely optional, in fact, we have an example of a plugin without UI. Try the plugin using this url to install it: <code class="language-js">https:\/\/create-palette.plugins.penpot.app/assets/manifest.json</code> or check the code <a target="_blank" href="https://github.com/penpot/penpot/tree/main/plugins/apps/create-palette-plugin">here</a>
### Can I create components?
@@ -58,7 +59,7 @@ Yes, it is possible to create components using:
createComponent(shapes: Shape[]): LibraryComponent;
```
Take a look at the Penpot Library methods in the <a target="_blank" href="https://penpot-plugins-api-doc.pages.dev/interfaces/Library">API documentation</a> or this <a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/components-library">simple example</a>.
Take a look at the Penpot Library methods in the <a target="_blank" href="https://doc.plugins.penpot.app/interfaces/Library">API documentation</a> or this <a target="_blank" href="https://github.com/penpot/penpot-plugins-samples/tree/main/components-library">simple example</a>.
### Is there a place where I can share my plugin?

View File

@@ -69,12 +69,13 @@ You need to provide the plugin's manifest URL for the installation. If there are
| Name | URL |
| ------------- | ------------------------------------------------------------------- |
| Lorem Ipsum | https://lorem-ipsum-penpot-plugin.pages.dev/assets/manifest.json |
| Contrast | https://contrast-penpot-plugin.pages.dev/assets/manifest.json |
| Feather icons | https://icons-penpot-plugin.pages.dev/assets/manifest.json |
| Tables | https://table-penpot-plugin.pages.dev/assets/manifest.json |
| Color palette | https://create-palette-penpot-plugin.pages.dev/assets/manifest.json |
| Rename layers | https://rename-layers-penpot-plugin.pages.dev/assets/manifest.json |
| Color palette | https://create-palette.plugins.penpot.app/assets/manifest.json |
| Contrast | https://contrast.plugins.penpot.app/assets/manifest.json |
| Feather icons | https://icons.plugins.penpot.app/assets/manifest.json |
| Lorem ipsum | https://lorem-ipsum.plugins.penpot.app/assets/manifest.json |
| Rename layers | https://rename-layers.plugins.penpot.app/assets/manifest.json |
| Tables | https://table.plugins.penpot.app/assets/manifest.json |
## 1.4. Plugin's basics

View File

@@ -36,7 +36,7 @@
{:path path
:mtype (mime/get type)
:name name
:filename (str/concat name (mime/get-extension type))
:filename (str/concat (str/slug name) (mime/get-extension type))
:id task-id}))
(defn create-zip

View File

@@ -110,7 +110,7 @@ test("Update an already created text shape by prepending text", async ({
await workspace.textEditor.stopEditing();
});
test("Update an already created text shape by inserting text in between", async ({
test.skip("Update an already created text shape by inserting text in between", async ({
page,
}) => {
const workspace = new WorkspacePage(page, {
@@ -151,7 +151,7 @@ test("Update a new text shape appending text by pasting text", async ({
await workspace.textEditor.stopEditing();
});
test("Update a new text shape prepending text by pasting text", async ({
test.skip("Update a new text shape prepending text by pasting text", async ({
page,
context,
}) => {

View File

@@ -24,6 +24,20 @@
[cuerdas.core :as str]
[potok.v2.core :as ptk]))
(def ^:const default-chunk-size
(* 1024 1024 4)) ;; 4MiB
(defn- chunk-array
[data chunk-size]
(let [total-size (alength data)]
(loop [offset 0
chunks []]
(if (< offset total-size)
(let [end (min (+ offset chunk-size) total-size)
chunk (.subarray ^js data offset end)]
(recur end (conj chunks chunk)))
chunks))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; General purpose events & IMPL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -116,9 +130,9 @@
(not= hhea-descender win-descent)
(and f-selection (or
(not= hhea-ascender os2-ascent)
(not= hhea-descender os2-descent))))]
{:content {:data (js/Uint8Array. data)
(not= hhea-descender os2-descent))))
data (js/Uint8Array. data)]
{:content {:data (chunk-array data default-chunk-size)
:name name
:type type}
:font-family (or family "")

View File

@@ -70,20 +70,22 @@
(= (-> content last :command) :move-to))
(into [] (take (dec (count content)) content))
content)]
(-> state
(st/set-content content))))
(st/set-content state content)))
ptk/WatchEvent
(watch [it state _]
(let [page-id (:current-page-id state)
objects (dsh/lookup-page-objects state page-id)
id (dm/get-in state [:workspace-local :edition])
old-content (dm/get-in state [:workspace-local :edit-path id :old-content])
shape (st/get-path state)]
local (get state :workspace-local)
id (get local :edition)
objects (dsh/lookup-page-objects state page-id)]
(if (and (some? old-content) (some? (:id shape)))
(let [changes (generate-path-changes it objects page-id shape old-content (:content shape))]
(rx/of (dch/commit-changes changes)))
(rx/empty)))))))
;; NOTE: we proceed only if the shape is present on the
;; objects, if shape is a ephimeral drawing shape, we should
;; do nothing
(when-let [shape (get objects id)]
(when-let [old-content (dm/get-in local [:edit-path id :old-content])]
(let [new-content (get shape :content)
changes (generate-path-changes it objects page-id shape old-content new-content)]
(rx/of (dch/commit-changes changes))))))))))

View File

@@ -8,7 +8,6 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.files.helpers :as cfh]
[app.common.geom.point :as gpt]
[app.common.types.path :as path]
[app.common.types.path.helpers :as path.helpers]
@@ -289,34 +288,34 @@
(declare stop-path-edit)
(defn start-path-edit
[id]
(ptk/reify ::start-path-edit
ptk/UpdateEvent
(update [_ state]
(let [objects (dsh/lookup-page-objects state)
edit-path (dm/get-in state [:workspace-local :edit-path id])
content (st/get-path state :content)
state (cond-> state
(cfh/path-shape? objects id)
(st/set-content (path/close-subpaths content)))]
shape (get objects id)]
(cond-> state
(or (not edit-path)
(= :draw (:edit-mode edit-path)))
(assoc-in [:workspace-local :edit-path id] {:edit-mode :move
:selected #{}
:snap-toggled false})
(and (some? edit-path)
(= :move (:edit-mode edit-path)))
(assoc-in [:workspace-local :edit-path id :edit-mode] :draw))))
(-> state
(st/set-content (path/close-subpaths (:content shape)))
(update-in [:workspace-local :edit-path id]
(fn [state]
(let [state (if state
(if (= :move (:edit-mode state))
(assoc state :edit-mode :draw)
state)
{:edit-mode :move
:selected #{}
:snap-toggled false})]
(assoc state :old-content (:content shape))))))))
ptk/WatchEvent
(watch [_ _ stream]
(let [stopper (->> stream
(rx/filter #(let [type (ptk/type %)]
(= type ::dwe/clear-edition-mode)
(= type ::start-path-edit))))]
(let [stopper (rx/filter #(let [type (ptk/type %)]
(= type ::dwe/clear-edition-mode)
(= type ::start-path-edit))
stream)]
(rx/concat
(rx/of (undo/start-path-undo))
(->> stream
@@ -325,7 +324,8 @@
(rx/map #(stop-path-edit id))
(rx/take-until stopper)))))))
(defn stop-path-edit [id]
(defn stop-path-edit
[id]
(ptk/reify ::stop-path-edit
ptk/UpdateEvent
(update [_ state]
@@ -335,13 +335,12 @@
(watch [_ _ _]
(rx/of (ptk/data-event :layout/update {:ids [id]})))))
(defn split-segments
[{:keys [from-p to-p t]}]
(defn- split-segments
[id {:keys [from-p to-p t]}]
(ptk/reify ::split-segments
ptk/UpdateEvent
(update [_ state]
(let [id (st/get-path-id state)
content (st/get-path state :content)]
(let [content (st/get-path state :content)]
(-> state
(assoc-in [:workspace-local :edit-path id :old-content] content)
(st/set-content (-> content
@@ -353,10 +352,10 @@
(rx/of (changes/save-path-content {:preserve-move-to true})))))
(defn create-node-at-position
[event]
[params]
(ptk/reify ::create-node-at-position
ptk/WatchEvent
(watch [_ state _]
(let [id (st/get-path-id state)]
(rx/of (dwsh/update-shapes [id] path/convert-to-path)
(split-segments event))))))
(split-segments id params))))))

View File

@@ -36,10 +36,12 @@
(defn- hide-popover
[node]
(dom/unset-css-property! node "block-size")
(dom/unset-css-property! node "inset-block-start")
(dom/unset-css-property! node "inset-inline-start")
(.hidePopover ^js node))
(when (and (some? node)
(fn? (.-hidePopover node)))
(dom/unset-css-property! node "block-size")
(dom/unset-css-property! node "inset-block-start")
(dom/unset-css-property! node "inset-inline-start")
(.hidePopover ^js node)))
(defn- calculate-placement-bounding-rect
"Given a placement, calcultates the bounding rect for it taking in

View File

@@ -16,7 +16,7 @@
(def context (mf/create-context nil))
(mf/defc form-input*
[{:keys [name] :rest props}]
[{:keys [name trim] :rest props}]
(let [form (mf/use-ctx context)
input-name name
@@ -33,7 +33,7 @@
(mf/deps input-name)
(fn [event]
(let [value (-> event dom/get-target dom/get-input-value)]
(fm/on-input-change form input-name value true))))
(fm/on-input-change form input-name value trim))))
props
(mf/spread-props props {:on-change on-change

View File

@@ -375,7 +375,7 @@
(mf/use-fn
(mf/deps on-change ids)
(fn [value attr event]
(if (or (string? value) (int? value))
(if (or (string? value) (number? value))
(on-change :simple attr value event)
(do
(let [resolved-value (:resolved-value (first value))
@@ -489,7 +489,7 @@
(mf/use-fn
(mf/deps on-change ids)
(fn [value attr event]
(if (or (string? value) (int? value))
(if (or (string? value) (number? value))
(on-change :multiple attr value event)
(do
(let [resolved-value (:resolved-value (first value))]
@@ -724,7 +724,7 @@
(mf/use-fn
(mf/deps on-change wrap-type ids)
(fn [value event attr]
(if (or (string? value) (int? value))
(if (or (string? value) (number? value))
(on-change (= "nowrap" wrap-type) attr value event)
(do
(let [resolved-value (:resolved-value (first value))]

View File

@@ -11,6 +11,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.types.color :as cl]
[app.common.types.token :as cto]
[app.common.types.tokens-lib :as ctob]
[app.main.data.style-dictionary :as sd]
[app.main.data.tinycolor :as tinycolor]
@@ -51,12 +52,15 @@
;; Both variants provide identical color-picker and text-input behavior, but
;; differ in how they persist the value within the forms nested structure.
(defn- resolve-value
[tokens prev-token token-name value]
(let [token
(let [valid-token-name?
(and (string? token-name)
(re-matches cto/token-name-validation-regex token-name))
token
{:value value
:name (if (str/blank? token-name)
:name (if (or (not valid-token-name?) (str/blank? token-name))
"__PENPOT__TOKEN__NAME__PLACEHOLDER__"
token-name)}

View File

@@ -50,9 +50,13 @@
(defn- resolve-value
[tokens prev-token token-name value]
(let [token
(let [valid-token-name?
(and (string? token-name)
(re-matches cto/token-name-validation-regex token-name))
token
{:value (cto/split-font-family value)
:name (if (str/blank? token-name)
:name (if (or (not valid-token-name?) (str/blank? token-name))
"__PENPOT__TOKEN__NAME__PLACEHOLDER__"
token-name)}

View File

@@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.files.tokens :as cft]
[app.common.types.token :as cto]
[app.common.types.tokens-lib :as ctob]
[app.main.data.style-dictionary :as sd]
[app.main.data.workspace.tokens.format :as dwtf]
@@ -140,9 +141,13 @@
(defn- resolve-value
[tokens prev-token token-name value]
(let [token
(let [valid-token-name?
(and (string? token-name)
(re-matches cto/token-name-validation-regex token-name))
token
{:value value
:name (if (str/blank? token-name)
:name (if (or (not valid-token-name?) (str/blank? token-name))
"__PENPOT__TOKEN__NAME__PLACEHOLDER__"
token-name)}
tokens

View File

@@ -230,6 +230,7 @@
:placeholder (tr "workspace.tokens.enter-token-name" token-title)
:max-length max-input-length
:variant "comfortable"
:trim true
:auto-focus true}]
(when (and warning-name-change? (= action "edit"))

View File

@@ -106,17 +106,20 @@
(defn stop-propagation
[^js event]
(when event
(when (and (some? event)
(fn? (.-stopPropagation event)))
(.stopPropagation event)))
(defn stop-immediate-propagation
[^js event]
(when event
(when (and (some? event)
(fn? (.-stopImmediatePropagation event)))
(.stopImmediatePropagation event)))
(defn prevent-default
[^js event]
(when event
(when (and (some? event)
(fn? (.-preventDefault event)))
(.preventDefault event)))
(defn get-target
@@ -802,9 +805,10 @@
([uri name]
(open-new-window uri name "noopener,noreferrer"))
([uri name features]
(let [new-window (.open js/window (str uri) name features)]
(when-let [new-window (.open js/window (str uri) name features)]
(when (not= name "_blank")
(.reload (.-location new-window))))))
(when-let [location (.-location new-window)]
(.reload location))))))
(defn browser-back
[]

View File

@@ -7,15 +7,16 @@
(ns app.util.keyboard
(:require
[app.config :as cfg]
[app.util.dom :as dom]
[cuerdas.core :as str]))
(defrecord KeyboardEvent [type key shift ctrl alt meta mod editing native-event]
Object
(preventDefault [_]
(.preventDefault native-event))
(dom/prevent-default native-event))
(stopPropagation [_]
(.stopPropagation native-event)))
(dom/stop-propagation native-event)))
(defn keyboard-event?
[o]

View File

@@ -7,7 +7,7 @@ different parts of the platform, please refer to `docs/` directory.
## Reporting Bugs
We are using [GitHub Issues](https://github.com/penpot/penpot-plugins/issues)
We are using [GitHub Issues](https://github.com/penpot/penpot/issues)
for our public bugs. We keep a close eye on this and try to make it
clear when we have an internal fix in progress. Before filing a new
task, try to make sure your problem doesn't already exist.

View File

@@ -16,6 +16,7 @@
"polyfills": ["zone.js"],
"tsConfig": "apps/colors-to-tokens-plugin/tsconfig.app.json",
"assets": [
"apps/colors-to-tokens-plugin/src/_headers",
"apps/colors-to-tokens-plugin/src/favicon.ico",
"apps/colors-to-tokens-plugin/src/assets"
],

View File

@@ -0,0 +1,4 @@
/*
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

View File

@@ -0,0 +1,8 @@
name = "color-to-tokens-plugin"
compatibility_date = "2025-01-01"
assets = { directory = "../../dist/apps/colors-to-tokens-plugin/browser" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true

View File

@@ -16,6 +16,7 @@
"polyfills": ["zone.js"],
"tsConfig": "apps/contrast-plugin/tsconfig.app.json",
"assets": [
"apps/contrast-plugin/src/_headers",
"apps/contrast-plugin/src/favicon.ico",
"apps/contrast-plugin/src/assets"
],

View File

@@ -0,0 +1,4 @@
/*
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

View File

@@ -0,0 +1,8 @@
name = "contrast-plugin"
compatibility_date = "2025-01-01"
assets = { directory = "../../dist/apps/contrast-plugin/browser" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true

View File

@@ -0,0 +1,4 @@
/*
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

View File

@@ -0,0 +1,8 @@
name = "create-palette-plugin"
compatibility_date = "2025-01-01"
assets = { directory = "../../dist/apps/create-palette-plugin" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true

View File

@@ -16,6 +16,7 @@
"polyfills": ["zone.js"],
"tsConfig": "apps/icons-plugin/tsconfig.app.json",
"assets": [
"apps/icons-plugin/src/_headers",
"apps/icons-plugin/src/favicon.ico",
"apps/icons-plugin/src/assets"
],

View File

@@ -0,0 +1,4 @@
/*
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

View File

@@ -0,0 +1,8 @@
name = "icons-plugin"
compatibility_date = "2025-01-01"
assets = { directory = "../../dist/apps/icons-plugin/browser" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true

View File

@@ -16,6 +16,7 @@
"polyfills": ["zone.js"],
"tsConfig": "apps/lorem-ipsum-plugin/tsconfig.app.json",
"assets": [
"apps/lorem-ipsum-plugin/src/_headers",
"apps/lorem-ipsum-plugin/src/favicon.ico",
"apps/lorem-ipsum-plugin/src/assets"
],

View File

@@ -0,0 +1,4 @@
/*
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

View File

@@ -0,0 +1,8 @@
name = "lorem-ipsum-plugin"
compatibility_date = "2025-01-01"
assets = { directory = "../../dist/apps/lorem-ipsum-plugin/browser" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true

View File

@@ -16,6 +16,7 @@
"polyfills": ["zone.js"],
"tsConfig": "apps/rename-layers-plugin/tsconfig.app.json",
"assets": [
"apps/rename-layers-plugin/src/_headers",
"apps/rename-layers-plugin/src/favicon.ico",
"apps/rename-layers-plugin/src/assets"
],

View File

@@ -0,0 +1,4 @@
/*
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

View File

@@ -0,0 +1,8 @@
name = "rename-layers-plugin"
compatibility_date = "2025-01-01"
assets = { directory = "../../dist/apps/rename-layers-plugin/browser" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true

View File

@@ -16,6 +16,7 @@
"polyfills": ["zone.js"],
"tsConfig": "apps/table-plugin/tsconfig.app.json",
"assets": [
"apps/table-plugin/src/_headers",
"apps/table-plugin/src/favicon.ico",
"apps/table-plugin/src/assets"
],

View File

@@ -0,0 +1,4 @@
/*
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type

View File

@@ -0,0 +1,8 @@
name = "table-plugin"
compatibility_date = "2025-01-01"
assets = { directory = "../../dist/apps/table-plugin/browser" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true

View File

@@ -19,7 +19,7 @@ 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.
Take a look at the [Penpot plugins API](https://doc.plugins.penpot.app/) to see what's new.
#### Styles

View File

@@ -20,7 +20,7 @@ Import the CSS file into your project:
For detailed examples and to see how to use the styles and components, visit the documentation at:
[Penpot Plugin Styles Documentation](https://penpot-plugins-styles.pages.dev)
[Penpot Plugin Styles Documentation](https://styles-doc.plugins.penpot.app)
#### Icons

View File

@@ -2,3 +2,7 @@ name = "penpot-plugins-api-doc"
compatibility_date = "2025-01-01"
assets = { directory = "dist/doc" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true

View File

@@ -0,0 +1,8 @@
name = "penpot-plugins-style-doc"
compatibility_date = "2025-01-01"
assets = { directory = "dist/apps/example-styles" }
[[routes]]
pattern = "WORKER_URI"
custom_domain = true