* ✨ Adds static dispatch safe stubs in tests
* 🐛 Fix shapesColors metadata key to match ColorShapeInfo
* 🐛 Fix CommentThread.remove rejecting the owner's own threads
* 🐛 Fix page.removeCommentThread throwing on a spurious Promise
* ✨ Implement ShapeBase.swapComponent in the plugin API
* ✨ Expose File.revn in the plugin API
* 🐛 Fix FileVersion.createdAt calling Luxon method on a js/Date
* 🐛 Fix plugin font/typography application to text and ranges
* 🐛 Default plugin overlay interaction position for non-manual types
* 🐛 Fix plugin interaction setters passing an id-only shape
* 🐛 Fix grid addColumnAtIndex rejecting valid track types
* 🐛 Expose libraryId on library color/typography/component proxies
* ✨ Implement LibraryTypography.setFont in the plugin API
* 🐛 Fix typography.applyToTextRange reading unexposed range bounds
* 🐛 Fix utils.geometry.center argument mismatch
* 🐛 Fix localStorage.removeItem calling getItem
* 🐛 Fix shape backgroundBlur proxy key casing
* 🐛 Report boolean shape type as 'boolean' in the plugin API
* 🐛 Return the resulting paths from plugin flatten
* 🐛 Make plugin z-order methods act on the target shape
* 🐛 Make is-variant-container? return a boolean
* ✨ Implement Group.isMask in the plugin API
* 🐛 Return a shape proxy from TextRange.shape
* 🐛 Return the duplicated set from TokenSet.duplicate
* 🐛 Fix theme addSet/removeSet reading set name with a keyword
* 🐛 Accept string fontFamilies token value in the plugin API
* 🐛 Fix combineAsVariants ignoring the passed component ids
* 🐛 Fix board removeRulerGuide ignoring its argument
* 🐛 Fix board guides setter schema and parser
* 🐛 Avoid 0-byte allocation when syncing empty grid tracks
* 🐛 Validate grid track indices in the plugin API
* 🐛 Return null for empty input in group() and centerShapes()
* 🐛 Return TokenTypographyValue[] from a typography token's resolvedValue
* 🐛 Return TokenShadowValue[] from a shadow token's resolvedValue
* 🐛 Return string[] from a fontFamilies token's resolvedValue
* 🐛 Clear mutually-exclusive reps when setting LibraryColor gradient/image
* 🐛 Add readonly tags to types, deprecate Image type
* 📚 Update plugins changelog
`library.connectLibrary()` declared its permission check **outside** the
`js/Promise.` wrapper, so when a plugin without `library:write` permission
called `await library.connectLibrary(id)` the method did not return a
`Promise` at all:
- With the default `throwValidationErrors` flag off → `u/not-valid`
logs to console and returns `nil`. `await nil` resolves to `nil`, so
the plugin sees a "successful" result and crashes later when it tries
to use methods on what it thinks is a `LibraryProxy`.
- With `throwValidationErrors` on → `u/not-valid` throws synchronously,
so the caller gets a thrown exception instead of a rejected promise —
inconsistent with every other `library:*` / `content:*` method which
always returns a Promise that rejects via `reject-not-valid`.
Additionally, the in-Promise `(not (string? library-id))` branch used
`(reject nil)` — the plugin got a rejected Promise but with no error
message.
Move the permission check inside the Promise constructor and replace
both validation errors with `u/reject-not-valid`, matching the pattern
used by the sibling methods `restore`, `remove`, `pin`, `saveVersion`,
`findVersions` in `frontend/src/app/plugins/file.cljs` and every other
promise-returning plugin method. No new imports.
Also add a CHANGES.md entry under the 2.17.0 Unreleased bugs-fixed section.
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
* ♻️ Split history workspace.cljs to workspace/pages.cljs - rename file to target-name
* ♻️ Split history workspace.cljs to workspace/pages.cljs - rename source-file to git-split-temp
* ♻️ Split history workspace.cljs to workspace/pages.cljs - restore name of source-file
* ♻️ Cleanup after adding new ns, add exports
* ♻️ Move set-plugin-data to main.data.plugins
* 🐛 Possible bugfix, cherry-picked from commit 8f7c63d6e2c (conflict during refactor)
---------
Co-authored-by: Eva Marco <eva.marco@kaleidos.net>