35 Commits

Author SHA1 Message Date
BitCompass
fbb1f9e634
🐛 Fix plugin API error message for nested malli validation paths (#9486)
When a plugin call fails malli validation, the frontend renders one
"plugins.validation.message" line per error via
`app.plugins.utils/error-messages`, which reduces the explain via
`csm/interpret-schema-problem` and then destructures each entry as
`[field {:keys [message]}]` for translation.

That works only when the underlying malli error path has a single
element. `interpret-schema-problem` calls `(assoc-in acc field ...)`
where `field` can be a multi-element vector (e.g. `[:sets 0 :name]`).
For single-element paths the resulting map is flat
(`{:group {:message "..."}}`); for multi-element paths it is nested
(`{:sets {0 {:name {:message "..."}}}}`). The destructure assumes the
flat shape, so for a nested error the consumer reads:

    field   -> :sets
    message -> nil (the nested entry has no :message at the top level)

and the produced i18n line resolves to `Field sets is invalid: ` --
or, when several errors are merged together at the same outer key,
to the user-facing `Field message is invalid` that the bug report
calls out, because `:message` then becomes the field name of the
deepest nested entry.

The original consumer carried a `#_(mapcat (comp seq val))` FIXME
that hinted at the missing flattening but did not implement one,
because the data shape produced by `interpret-schema-problem` is
not uniform.

Fix
---

Add a private `flatten-error-map` helper inside `app.plugins.utils`
that walks the error map produced by `interpret-schema-problem` and
yields `[path message]` pairs where `path` is the dot-joined field
path. Keywords use `(name k)`, strings pass through, anything else
(such as numeric indices from vector positions in the malli path)
is coerced via `str`. The recursion descends until it hits a leaf
that carries `:message`, which matches what
`interpret-schema-problem` produces in every branch.

The producer side (`csm/interpret-schema-problem` in
`common/src/app/common/schema/messages.cljc`) is left alone: it
already has another consumer (`collect-schema-errors` + the
form-validators pipeline) that depends on the keyed-by-field-path
shape, so normalising it at the source would require auditing every
validator. Flattening at the plugin consumer is the narrowest fix.

The FIXME comment is removed because the new helper supersedes it.

Tests
-----

`frontend-tests.plugins.utils-test` (new file, registered in
`runner.cljs`) covers:

- flat single-segment paths (`{:group {:message "..."}}`)
- nested multi-segment paths
  (`{:sets {0 {:name {:message "..."}}}}`) -- the case from #9417
- mixed single- and multi-segment paths at the same explain
- mixed key types (keyword / string / numeric index)
- empty explain (no validation errors)

Closes #9417

Signed-off-by: bitcompass <devwiz.sh@gmail.com>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-05-14 12:43:57 +02:00
Andrés Moya
61cd757355
🐛 Detect duplicated token names in the whole library (#9034)
* 🐛 Detect duplicated token names in the whole library

* 🔧 Review comments

* 🐛 Prevent and repair token themes with inexistent sets

* 🔧 Convert tokens lib migration into file migration
2026-05-08 08:26:15 +02:00
Dominik Jain
07ad152ae5 🐛 Fix .component() returning outermost component for nested instances
The shape API method .component() used locate-component which walks
to the outermost instance root via get-instance-root. For nested
component instances (e.g. a button inside a card), this incorrectly
returned the outer component (the card) instead of the nearest one
(the button).

Added locate-head-component in utils.cljs which uses get-head-shape
to find the nearest component head, and updated the :component
property in shape.cljs to use it.

Fixes #9183
2026-05-04 16:13:25 +02:00
Alonso Torres
6ce2aadfae
Improve message from schema errors in plugins (#8865) 2026-04-08 16:14:51 +02:00
alonso.torres
a1a469449e Add throwValidationErrors flag for plugins 2026-03-19 15:37:08 +01:00
Alonso Torres
321b53e936
Add improvements on variants plugins (#8482) 2026-03-09 10:24:16 +01:00
Andrés Moya
813c804d45 🔧 Enhance schema validation of token application 2026-02-16 15:16:14 +01:00
Andrés Moya
5b5f22a8c6
🎉 Add tokens to Penpot Plugins API (#7756)
* 🎉 Add tokens to plugins API documentation

And add poc plugin example

* 📚 Document better the tokens value in plugins API

* 🔧 Refactor token validation schemas

* 🔧 Use automatic validation in token proxies

* 🔧 Use schemas to validate token creation

* 🔧 Use multi schema for token value

* 🔧 Use schema in token api methods

* 🐛 Fix review comments

---------

Co-authored-by: Andrey Antukh <niwi@niwi.nz>
2026-02-09 14:18:31 +01:00
Andrés Moya
3cc54fd988
🎉 Add design tokens to plugins API (#7602)
Co-authored-by: alonso.torres <alonso.torres@kaleidos.net>
2025-11-14 11:14:56 +01:00
Marina López
179a5654e7 🐛 Fix get current user for plugins api 2025-05-27 10:50:01 +02:00
Andrey Antukh
85746e7cb2 ♻️ Refactor state locality
The main purpose of this refactor is reduce
a custom state from different pages and unify
them under common access patterns
2025-01-16 15:31:18 +01:00
Andrey Antukh
e5894ceea1 ♻️ Rename workspace-libraries to libraries on state and refs 2024-12-10 14:45:56 +01:00
alonso.torres
eccc4226c7 Migrate proxies to new format 2024-11-27 08:32:07 +01:00
alonso.torres
4de43b32e8 Add versions support in plugins 2024-11-14 12:02:15 +01:00
alonso.torres
6c0dce580d 🐛 Fix problem with promises in plugins 2024-11-04 17:12:45 +01:00
alonso.torres
2b2a84da64 🐛 Fix problem with frame guides 2024-09-18 12:15:12 +02:00
Andrey Antukh
4ad4057878 ♻️ Refactor page options data structure 2024-09-18 12:15:12 +02:00
alonso.torres
dd0c5b7806 Add support to guides for plugins 2024-09-13 11:30:59 +02:00
alonso.torres
2d25df33ce Add write methods to prototype API 2024-07-23 16:55:32 +02:00
alonso.torres
ac58a5b8fa Improved transformation from and to JS for plugins 2024-07-02 10:41:06 +02:00
alonso.torres
f86156b619 Plugins support for code generation 2024-06-24 15:26:21 +02:00
alonso.torres
7fd223893b Expose component properties in components 2024-06-21 09:29:09 +02:00
alonso.torres
2da5dcb619 Add text ranges support in plugins 2024-06-21 09:29:09 +02:00
alonso.torres
3e2ccbc85f Add infor for users 2024-06-04 16:44:24 +02:00
alonso.torres
3209511557 Add support for colors and typographies 2024-06-04 16:44:24 +02:00
alonso.torres
007ab3d909 Add library edition mode for plugins 2024-05-29 12:54:49 +02:00
alonso.torres
032e551dc1 🐛 Fix problem with shadows 2024-05-28 13:44:39 +02:00
alonso.torres
85ae3ff6f8 🐛 Fix problem with hot reload 2024-05-22 17:30:19 +02:00
alonso.torres
3ca5b13e27 New apis for plugins 2024-05-21 15:24:28 +02:00
alonso.torres
d6de1fdbdf ♻️ Refactor plugins proxies internal data 2024-05-21 15:24:28 +02:00
alonso.torres
fde0bcfd3e Add grid layout options to context 2024-05-03 13:44:31 +02:00
alonso.torres
9243ba937d Add to plugins clone and remove 2024-05-03 11:36:59 +02:00
alonso.torres
21d38a058b Add to plugin api: upload media, group and ungroup 2024-05-03 11:36:59 +02:00
alonso.torres
0ffd82299f Refactor to the context api 2024-04-19 01:29:13 +02:00
alonso.torres
127b481c38 Refactor of the plugins context 2024-04-19 01:29:13 +02:00