Merge remote-tracking branch 'origin/staging'

This commit is contained in:
Andrey Antukh 2026-06-08 09:40:28 +02:00
commit bae4d23c67
5 changed files with 73 additions and 54 deletions

View File

@ -59,6 +59,7 @@
- Clarify self-hosted OIDC configuration for containerized (by @sancfc) [#9764](https://github.com/penpot/penpot/issues/9764) (PR: [#9758](https://github.com/penpot/penpot/pull/9758))
- Update User Guide with 2.16 features (by @myfunnyandy) [#9767](https://github.com/penpot/penpot/issues/9767) (PR: [#9768](https://github.com/penpot/penpot/pull/9768))
- Improve file validation performance and fix orphan shape detection [#9790](https://github.com/penpot/penpot/issues/9790) (PR: [#9789](https://github.com/penpot/penpot/pull/9789))
- Add v2.16 release notes (What's new modal) [#9945](https://github.com/penpot/penpot/issues/9945) (PR: [#9940](https://github.com/penpot/penpot/pull/9940))
### :bug: Bugs fixed
- Add Shift+Numpad aliases for zoom shortcuts (by @RenzoMXD) [#2457](https://github.com/penpot/penpot/issues/2457) (PR: [#9063](https://github.com/penpot/penpot/pull/9063))
@ -139,6 +140,7 @@
- Fix delete invitation modal readability in light theme [#9737](https://github.com/penpot/penpot/issues/9737) (PR: [#9747](https://github.com/penpot/penpot/pull/9747))
- Fix team invitation not automatically accepted after account validation [#9776](https://github.com/penpot/penpot/issues/9776) (PR: [#9782](https://github.com/penpot/penpot/pull/9782))
- Fix design tokens vanishing from the sidebar when a token name collides with a token-group prefix from another active set (e.g. `a` in one set and `a.b` in another); the colliding token is now kept and rendered as a broken pill [Github #9584](https://github.com/penpot/penpot/issues/9584)
- Fix Plugin API addRulerGuide creating guides on page instead of board (by @girafic) [#8225](https://github.com/penpot/penpot/issues/8225) (PR: [#8632](https://github.com/penpot/penpot/pull/8632))
## 2.15.4

View File

@ -171,3 +171,20 @@
(t/is (= candidate-2 (encode-j expected)))))
(t/deftest test-boolean
(let [decode-s (sm/decoder ::sm/boolean sm/string-transformer)]
(t/is (= true (decode-s "true")))
(t/is (= true (decode-s "True")))
(t/is (= true (decode-s "TrUe")))
(t/is (= true (decode-s "TRUE")))
(t/is (= false (decode-s "false")))
(t/is (= false (decode-s "False")))
(t/is (= false (decode-s "fAlSe")))
(t/is (= false (decode-s "FALSE")))
(t/is (= true (decode-s "T")))
(t/is (= false (decode-s "F")))
(t/is (= true (decode-s "t")))
(t/is (= false (decode-s "f")))
(t/is (= true (decode-s "1")))
(t/is (= false (decode-s "0")))))

View File

@ -1,27 +0,0 @@
server {
listen 8080 default_server;
server_name _;
charset utf-8;
etag off;
gzip on;
gzip_static on;
gzip_types text/plain text/css application/javascript application/json application/vnd.api+json application/xml application/x-javascript text/xml image/svg+xml;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_vary on;
error_log /dev/stderr;
access_log /dev/stdout;
root /var/www;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}

View File

@ -302,36 +302,38 @@
{:errors [(wte/error-with-value :error.style-dictionary/invalid-token-value-typography value)]}
:else
(let [converted (js->clj value :keywordize-keys true)
add-keyed-errors (fn [typography-map k errors]
(update typography-map :errors concat (map #(assoc % :typography-key k) errors)))
;; Separate line-height to process in an extra step
without-line-height (dissoc converted :line-height)
valid-typography (reduce
(fn [acc [k v]]
(let [{:keys [errors value]} (parse-atomic-typography-value k v)]
(if (seq errors)
(add-keyed-errors acc k errors)
(assoc-in acc [:value k] (or value v)))))
{:value {}}
without-line-height)
(let [converted (js->clj value :keywordize-keys true)]
(if-not (map? converted)
{:errors [(wte/error-with-value :error.style-dictionary/invalid-token-value-typography value)]}
(let [add-keyed-errors (fn [typography-map k errors]
(update typography-map :errors concat (map #(assoc % :typography-key k) errors)))
;; Separate line-height to process in an extra step
without-line-height (dissoc converted :line-height)
valid-typography (reduce
(fn [acc [k v]]
(let [{:keys [errors value]} (parse-atomic-typography-value k v)]
(if (seq errors)
(add-keyed-errors acc k errors)
(assoc-in acc [:value k] (or value v)))))
{:value {}}
without-line-height)
;; Calculate line-height based on the resolved font-size and add it back to the map
line-height (when-let [line-height (:line-height converted)]
(-> (parse-sd-token-typography-line-height
line-height
(get-in valid-typography [:value :font-size])
(get-in valid-typography [:errors :font-size]))))
valid-typography (cond
(:errors line-height)
(add-keyed-errors valid-typography :line-height (:errors line-height))
;; Calculate line-height based on the resolved font-size and add it back to the map
line-height (when-let [line-height (:line-height converted)]
(-> (parse-sd-token-typography-line-height
line-height
(get-in valid-typography [:value :font-size])
(get-in valid-typography [:errors :font-size]))))
valid-typography (cond
(:errors line-height)
(add-keyed-errors valid-typography :line-height (:errors line-height))
line-height
(assoc-in valid-typography [:value :line-height] line-height)
line-height
(assoc-in valid-typography [:value :line-height] line-height)
:else
valid-typography)]
valid-typography))))
:else
valid-typography)]
valid-typography))))))
(defn collect-typography-errors [token]
(group-by :typography-key (:errors token)))

View File

@ -97,6 +97,31 @@
(-> errors first :error/code)))))
(done))))))))
;; Regression: a composite typography token whose value is a plain
;; array (e.g. ["Roboto"]) instead of a map must not crash with
;; "No protocol method IMap.-dissoc defined for type object".
;; It should return an invalid-token-value-typography error instead.
(t/deftest resolve-tokens-typography-array-value-test
(t/async
done
(t/testing "typography token with array value produces error instead of crashing"
(let [tokens (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :id (cthi/new-id! :core-set)
:name "core"))
(ctob/add-token (cthi/id :core-set)
(ctob/make-token {:name "typography.bad"
:value ["Roboto"]
:type :typography}))
(ctob/get-all-tokens-map))]
(-> (sd/resolve-tokens tokens)
(rx/sub!
(fn [resolved-tokens]
(t/is (contains? resolved-tokens "typography.bad"))
(t/is (nil? (get-in resolved-tokens ["typography.bad" :resolved-value])))
(t/is (= :error.style-dictionary/invalid-token-value-typography
(get-in resolved-tokens ["typography.bad" :errors 0 :error/code])))
(done))))))))
(t/deftest resolve-tokens-interactive-test
(t/async
done