From 3cc91e8ba218f3ee068429a38a83a10f8c3f7c32 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 28 Oct 2026 18:44:36 +0100 Subject: [PATCH 01/14] :recycle: Take the command limits before the root ones in the RPC limiter (#12686) * :recycle: Take the command limits before the root ones in the RPC limiter The RPC concurrency limiter took the root limiters (the ones every request passes through) before the ones a command declares, so a request waiting for the limits of its own command held the root permits of its profile while it waited: a profile with a pile-up of heavy requests saw its other requests queue behind them and be rejected with 429. That order was forced by two commands that entered the limiter from inside their handler: a command that declares no limits of its own can only take them deeper than the root ones, so two paths of one profile could take the same limiters in opposite order and park for good. The commands declare their limits in their metadata now and their handlers call the work directly, so no command enters the limiter from inside its handler and every path takes the limiters in the same order. The root limiters are appended to the sequence first, so the limits a command declares end up outermost and are taken first: a request waiting for them does not hold the root permits of its profile. The photo of a team keeps its limits, because it declares them now that the helper does not. A call from inside a handler can only reenter the limits that thread already holds, and it is refused when it asks for a new one, because that would take it after the root ones and invert the order against the other paths. The key of a limit is resolved the same way in every path, so both paths point at the same limiter and the reentrancy check sees it. Every entry of the shipped climit.edn declares a queue, so the number of requests waiting for the same limit is bounded instead of piling up until the timeout. The production file lives outside the repository and has to be mirrored to pick them up. The tests cover the acquisition order of a command with and without limits of its own, the order of the limits as a whole (a ring of any size fails, not only a pair in opposite order), the nested call that asks for a limit the thread does not hold, and the queues and timeouts of the shipped configuration. The import of a binfile declares its request as multipart in its test, the way the commands that take an upload map do. AI-assisted-by: minimax-m3.1-flash AI-assisted-by: deepseek-v4.1-flash * :wrench: Keep the commands' limits and the shipped config in sync `profile-plugin-ops` guarded only an UPDATE on the caller's own profile row, which the row lock already serializes, so its global cap could only reject a burst of different profiles toggling plugins. Both commands declare the by-profile limit alone now, and the example config drops the entry. A declared id without an entry does not limit anything: `wrap` logs a warning and runs the handler with no limiter at all, which is how a command ends up unbounded in production. A test fails now when a command declares an id the config does not list, and the header of the example says the production file mirrors the shape and lists every declared id, not the values. AI-assisted-by: deepseek-v4.1-flash * :books: Record that background work is not waited for with a sleep A long command moved to the background reports its own completion, so polling it with a sleep inside a foreground command only blocks the session and the notification arrives anyway. The rule says to keep working on something else, or to end the response and wait for it. AI-assisted-by: minimax-m3.1-flash --- .serena/memories/backend/subtleties.md | 7 +- .serena/memories/critical-info.md | 1 + backend/resources/climit.edn | 38 ++- backend/src/app/rpc/climit.clj | 174 ++++------ backend/src/app/rpc/commands/media.clj | 13 +- backend/src/app/rpc/commands/plugins.clj | 6 +- backend/src/app/rpc/commands/profile.clj | 15 +- backend/src/app/rpc/commands/teams.clj | 3 + backend/test/backend_tests/climit_test.clj | 307 +++++++----------- backend/test/backend_tests/helpers.clj | 10 +- .../test/backend_tests/rpc_binfile_test.clj | 16 +- .../test/backend_tests/rpc_climit_test.clj | 134 +++++++- 12 files changed, 379 insertions(+), 345 deletions(-) diff --git a/.serena/memories/backend/subtleties.md b/.serena/memories/backend/subtleties.md index e778f31f8e..1b4fa4ddec 100644 --- a/.serena/memories/backend/subtleties.md +++ b/.serena/memories/backend/subtleties.md @@ -17,9 +17,10 @@ - The waiting counters are a field of the `ConcurrencyLimiter` component (a `ConcurrentHashMap` of name to `AtomicLong`), so they start at zero, die with the component, and the sampler that closes over that map republishes only its own names every 15 s; the sampler stops with the component in `halt-key!`. `impl-invoke` pairs one decrement with one increment through a per-call flag: the flag turns a second call into a no-op and the `finally` guarantees that there is one. The increment sits inside the `try` and the decrement lives only in the acquired callback and the `finally`, so a handler that throws, a rejection and a throwable from the publishing path all leave the count where it was and the thread without the limiter marked as held (a leftover mark would skip that limiter for that key for ever). Concurrent `inc`/`dec` publications of two threads can land out of order and the value can read low for a moment; the republish corrects it. - The `app.rpc.climit` log lines carry `queue`, `queue-max`, `permits`, `elapsed`, `code` and `reason`, and their `id` carries the key (`name/`). That is the only place where the profile behind a queue is visible: a pile-up is chased there, on demand, not in the metrics. The `queue` of the line is the calls inside the limiter minus its permits, so it reads 0 for a lone caller that times out: that line goes out at TRACE instead of WARN, and the rejection count has to come from the metric. - Nothing in the limiter path has a timeout unless the config sets one, and `psm/acquire` then calls `Semaphore.acquire`, which parks the calling thread forever. A parked thread still counts as in-system for every outer limiter of its chain, so the outermost one (the method's own by-profile limiter) stops granting permits and answers 429 to everything. A limiter without `:queue` gets an unlimited queue and therefore never rejects: its pile-up is silent, with no 429 and no log line except the WARN `enqueued`/`acquired` lines of the keyed id. -- Deadlock shape between a command's own limits and the root ones (fixed): a command declaring its own limits held `process-image/by-profile` before `root/by-profile`, while a command with no limits of its own takes the roots first and then re-enters with the same keyed limits from inside its handler (`create-file-media-object-from-url`, `upload-photo`) and waits for them holding a root permit. Two calls of one profile then held the same two limiters inverted and parked for good: 69 threads at 0 CPU, an audit limiter with 0 acquisitions in 24h and 100% 429s, on an instance that never served a 204. -- `climit/wrap` now appends the root limiters after the command's own, so `root/global`/`root/by-profile` end up outermost and every path meets them first; the nested `climit/invoke!` chains carry only the command's own limits and run inside them, which puts both paths in the same order. `impl-invoke` also keeps, per thread, the set of limiters that thread is inside of and runs the handler inline when a call asks for one it already holds, instead of queueing behind itself. That check relies on `pbh/invoke!` running the handler on the calling thread; the mark is removed in a `finally`. Commands declare the by-profile limit before the global one, which makes it the outermost of the pair: keep that declaration order, the reverse one would put two paths back in inverted order. The two nested call sites (`create-file-media-object-from-url`, `upload-photo`) still share `process-image` with the enclosing call instead of getting a limiter of their own, so the comment there about keeping the download out of that limit no longer holds. -- The shipped `backend/resources/climit.edn` sets a timeout on every limiter, 60s for operations that can be slow and 30s otherwise, with a test that fails when an entry ships without one, and `init-key` logs a WARN for every entry without a timeout. The production file lives outside the repository: mirror it there, and remember that a parked thread only goes away with a restart or a deploy. +- Deadlock shape between a command's own limits and the root ones (fixed): a command declaring its own limits held `process-image/by-profile` before `root/by-profile`, while a command with no limits of its own takes the roots first and then re-enters with the same keyed limits from inside its handler (`create-file-media-object-from-url`, `upload-photo`) and waits for them holding a root permit. Two calls of one profile then held the same two limiters inverted and parked for good: 69 threads at 0 CPU, an audit limiter with 0 acquisitions in 24h and 100% 429s, on an instance that never served a 204. Both commands declare their limits now, so the shape cannot happen any more: the root limits are taken last and every path takes the limiters in the same order. +- `climit/wrap` takes the command's own limits before the root ones: the root limiters are appended to the sequence first and the last element of the sequence is the outermost one, so `root/global`/`root/by-profile` end up innermost. A request waiting for its own limits no longer holds the root permits of its profile, which is what kept a pile-up of heavy requests from blocking the other commands of that profile. Every acquisition goes through that wrapper, so every path takes the limiters in the same order: there is no way to enter the limiter from inside a handler, and a command that calls another command internally would take the limiters twice (the second call waits for a permit the first one holds and answers 429 when the timeout runs out). The key of a limit is a function of the params (a keyword is looked up in them, a function is applied to them, any other value is the key itself). Commands declare the by-profile limit before the global one, which makes it the outermost of the pair, and a test fails when the relation between all the limits the commands declare cannot be sorted: two commands that take the same limits in opposite order, or a ring of three, leave the paths of one profile holding them in opposite order. +- The two commands that used to enter climit from inside their handler declare their limits now, so the whole command runs inside them: the download of an external image takes a `process-image` permit, and that limit has one permit per profile, so a slow download holds the image processing of that profile for as long as it takes. It takes the global permit of that limit too (8 permits, queue 20), so eight slow downloads of eight different profiles leave the image processing of every profile waiting. The copy of the body has no timeout (the 30 s of the request covers the connection and the headers), so a server that stops sending keeps the permits until the operating system gives up. The storage write of the profile photo runs inside its limit too. +- The shipped `backend/resources/climit.edn` sets a timeout and a queue on every limiter, 60s for operations that can be slow and 30s otherwise, with a test that fails when an entry ships without one, and `init-key` logs a WARN for every entry without a timeout. The queue matters because the root limits no longer bound the waiters: a command takes its own limits first, so a pile-up waits in the queue of that limit. The file and the declarations have to list the same ids: a `::climit/id` without an entry makes `wrap` log `no config found for specified queue` and run the handler with no limiter at all, and a test fails when a command declares an id the file does not list. Only key a limit by profile when the work contends on something shared (`update-file`, images, fonts, thumbnails, the profile row): a global cap on a cheap command adds a rejection path nobody needs, which is why `profile-plugin-ops` and `submit-audit-events` declare only `by-profile`. The production file lives outside the repository: mirror it there, and remember that a parked thread only goes away with a restart or a deploy. ## DB helpers diff --git a/.serena/memories/critical-info.md b/.serena/memories/critical-info.md index d66a46eb84..00eb2cab6f 100644 --- a/.serena/memories/critical-info.md +++ b/.serena/memories/critical-info.md @@ -25,6 +25,7 @@ You are working on the GitHub project `penpot/penpot`, a monorepo. - Align `let` binding values: when a `let` form has multiple bindings spanning several lines, align the value forms to the same column with spaces. - If you introduce delimiter errors (mismatched parens/brackets) in Clojure/CLJS files, fix them with `scripts/paren-repair` BEFORE running lint/format checks. See `mem:scripts/paren-repair` for usage. - Never run anything that destroys data without explicit permission, including `drop-devenv`, `docker compose down -v`, `docker volume rm ...`. The user's real work lives in the volumes of the shared infra. +- **Never wait for background work with a sleep.** A long command moved to the background reports its own completion: do not poll it with `sleep 150` (or any other wait) inside a foreground command, and do not re-read its output file to check whether it finished. Keep working on something else, or end the response and wait for the notification. # Project modules diff --git a/backend/resources/climit.edn b/backend/resources/climit.edn index 9b585edabc..1a5c8f1ecc 100644 --- a/backend/resources/climit.edn +++ b/backend/resources/climit.edn @@ -6,66 +6,68 @@ ;; 60s for operations that can be slow (file updates, images, fonts, thumbnails, ;; snapshots, imports) and 30s for the rest. ;; Note: a queue bounds how many waiters pile up, a timeout bounds how long one -;; waiter waits. Every entry sets a timeout; the by-profile ones also set a -;; queue, which is where a pile-up hurts. +;; waiter waits. Every entry sets a timeout and a queue: a command takes the +;; limits it declares before the root ones, so the queue of a limit is where +;; its own pile-up waits. The root limits bound what runs at the same time, +;; not what waits for it. +;; The production file lives outside this repository: mirror the shape there, +;; not these numbers. It has to list every id a command declares: an id without +;; an entry runs with no limiter at all. {:update-file/global - {:permits 20 :timeout 60000} + {:permits 20 :queue 50 :timeout 60000} :update-file/by-profile {:permits 1 :queue 5 :timeout 60000} :process-font/global - {:permits 4 :timeout 60000} + {:permits 4 :queue 10 :timeout 60000} :process-font/by-profile - {:permits 1 :timeout 60000} + {:permits 1 :queue 5 :timeout 60000} :process-image/global - {:permits 8 :timeout 60000} + {:permits 8 :queue 20 :timeout 60000} :process-image/by-profile - {:permits 1 :timeout 60000} + {:permits 1 :queue 5 :timeout 60000} :auth/global - {:permits 8 :timeout 30000} + {:permits 8 :queue 20 :timeout 30000} :root/global - {:permits 40 :timeout 30000} + {:permits 40 :queue 100 :timeout 30000} :root/by-profile {:permits 10 :queue 30 :timeout 30000} :file-thumbnail-ops/global - {:permits 20 :timeout 60000} + {:permits 20 :queue 50 :timeout 60000} :file-thumbnail-ops/by-profile - {:permits 2 :timeout 60000} + {:permits 2 :queue 10 :timeout 60000} :submit-audit-events/by-profile {:permits 1 :queue 3 :timeout 30000} :restore-file-snapshot/global - {:permits 3 :timeout 60000} + {:permits 3 :queue 5 :timeout 60000} :restore-file-snapshot/by-profile {:permits 1 :queue 2 :timeout 60000} :create-file-snapshot/global - {:permits 3 :timeout 60000} + {:permits 3 :queue 5 :timeout 60000} :create-file-snapshot/by-profile {:permits 1 :queue 2 :timeout 60000} :send-user-feedback/global - {:permits 4 :timeout 30000} + {:permits 4 :queue 10 :timeout 30000} :send-user-feedback/by-profile {:permits 1 :queue 3 :timeout 30000} :import-binfile/global - {:permits 4 :timeout 60000} + {:permits 4 :queue 10 :timeout 60000} :import-binfile/by-profile {:permits 1 :queue 2 :timeout 60000} - :profile-plugin-ops/global - {:permits 4 :timeout 30000} - :profile-plugin-ops/by-profile {:permits 1 :queue 2 :timeout 30000}} diff --git a/backend/src/app/rpc/climit.clj b/backend/src/app/rpc/climit.clj index 82fe9ff234..3f7330238e 100644 --- a/backend/src/app/rpc/climit.clj +++ b/backend/src/app/rpc/climit.clj @@ -5,7 +5,16 @@ ;; Copyright (c) KALEIDOS SUBSIDIARY SL (ns app.rpc.climit - "Concurrencly limiter for RPC." + "Concurrencly limiter for RPC. + + A command declares its limits in its `::climit/id` metadata and takes them + before the root ones, so a request waiting for its own limits does not hold + the root permits of its profile. + + Every acquisition goes through this wrapper, so every path takes the + limiters in the same order. A command that calls another command from + inside its handler would take them twice: the second call waits for a + permit the first one holds, and answers 429 when the timeout runs out." (:refer-clojure :exclude [run!]) (:require [app.common.exceptions :as ex] @@ -221,16 +230,6 @@ (def ^:private idseq (AtomicLong. 0)) -(def ^:private ^ThreadLocal held-limiters - ;; Limiters a thread is inside of, identified by the limiter instance, which - ;; already encodes the limit id and its key: the cache is per id+key pair. - ;; `pbh/invoke!` runs the handler on the calling thread, so a handler that - ;; enters climit again for a limit it holds finds it here. Without this a - ;; thread parks forever behind a permit it holds itself. - (ThreadLocal/withInitial - (reify java.util.function.Supplier - (get [_] (java.util.HashSet.))))) - (defn- impl-invoke [metrics counters cache config handler] (let [limit-id (::id config) @@ -249,69 +248,57 @@ :permits (or (:permits config) (:concurrency config) 1) :queue-max (or (:queue config) (:queue-size config))} limiter (cache/get cache limit-id (partial create-limiter config)) - held ^java.util.Set (.get ^ThreadLocal held-limiters)] + tpoint (ct/tpoint) + req-id (.incrementAndGet ^AtomicLong idseq) + waiting (volatile! true) + stop-waiting (fn [] + ;; Exactly one decrement per increment: the flag + ;; makes a second call a no-op and the `finally` + ;; guarantees that there is one. + (when @waiting + (vreset! waiting false) + (waiting-dec metrics counters limit-name)))] - (if (.contains held limiter) - ;; The calling thread already holds this limiter for this key: run the - ;; handler inline instead of queueing behind itself. - (do - (l/trc :hint "reentrant invocation" :id limit-id :label limit-label) - (handler)) + (try + ;; The increment lives inside the `try`, so a throwable from the + ;; publishing path unwinds through the `finally`: the count comes back + ;; down instead of staying up for good. + (waiting-inc metrics counters limit-name) - (let [tpoint (ct/tpoint) - req-id (.incrementAndGet ^AtomicLong idseq) - waiting (volatile! true) - stop-waiting (fn [] - ;; Exactly one decrement per increment: the flag - ;; makes a second call a no-op and the `finally` - ;; guarantees that there is one. - (when @waiting - (vreset! waiting false) - (waiting-dec metrics counters limit-name)))] + (let [stats (pbh/get-stats limiter)] + (log limit "enqueued" req-id stats nil nil nil)) - (.add held limiter) + (pbh/invoke! limiter (fn [] + (stop-waiting) + (let [elapsed (tpoint) + stats (pbh/get-stats limiter)] + (measure metrics mlabels elapsed) + (log limit "acquired" req-id stats elapsed nil nil) + (handler)))) - (try - ;; The increment lives inside the `try`, so a throwable from the - ;; publishing path unwinds through the `finally`: the thread drops the - ;; mark and the count comes back down instead of staying up for good. - (waiting-inc metrics counters limit-name) - - (let [stats (pbh/get-stats limiter)] - (log limit "enqueued" req-id stats nil nil nil)) - - (pbh/invoke! limiter (fn [] - (stop-waiting) - (let [elapsed (tpoint) - stats (pbh/get-stats limiter)] - (measure metrics mlabels elapsed) - (log limit "acquired" req-id stats elapsed nil nil) - (handler)))) - - (catch ExceptionInfo cause - (let [{:keys [type code] :as data} (ex-data cause)] - (if (= :bulkhead-error type) - (let [elapsed (tpoint) - stats (pbh/get-stats limiter) - reason (if (some? (:timeout data)) "timeout" "queue-full")] - (mtx/run! metrics - :id :rpc-climit-rejected - :inc 1 - :labels (into-array String [limit-name reason])) - (log limit "rejected" req-id stats elapsed code reason) - (ex/raise :type :concurrency-limit - :code code - :hint "concurrency limit reached" - :cause cause)) - (throw cause)))) - - (finally - (.remove held limiter) - (stop-waiting) + (catch ExceptionInfo cause + (let [{:keys [type code] :as data} (ex-data cause)] + (if (= :bulkhead-error type) (let [elapsed (tpoint) - stats (pbh/get-stats limiter)] + stats (pbh/get-stats limiter) + reason (if (some? (:timeout data)) "timeout" "queue-full")] + (mtx/run! metrics + :id :rpc-climit-rejected + :inc 1 + :labels (into-array String [limit-name reason])) + (log limit "rejected" req-id stats elapsed code reason) + (ex/raise :type :concurrency-limit + :code code + :hint "concurrency limit reached" + :cause cause)) + (throw cause)))) - (log limit "finished" req-id stats elapsed nil nil)))))))) + (finally + (stop-waiting) + (let [elapsed (tpoint) + stats (pbh/get-stats limiter)] + + (log limit "finished" req-id stats elapsed nil nil)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MIDDLEWARE @@ -340,6 +327,16 @@ :else (throw (IllegalArgumentException. "unable to normalize limit"))))) +(defn- resolve-limit-key + "The key of a limit, resolved the same way in every path: a keyword is + looked up in the params, a function is applied to them, any other value is + the key itself." + [key params] + (cond + (keyword? key) (get params key) + (fn? key) (key params) + :else key)) + (defn wrap [cfg handler {label ::sv/name :as mdata}] (if-let [climit (::rpc/climit cfg)] @@ -363,7 +360,7 @@ (fn [cfg params] (let [config (-> config - (assoc ::key (key-fn params)) + (assoc ::key (resolve-limit-key key-fn params)) (assoc ::label label) ;; NOTE: only used for debugging output (assoc ::params params))] @@ -373,40 +370,11 @@ (l/wrn :hint "no config found for specified queue" :id (id->str limit-id)) handler))) handler - ;; The root limiters go last so they end up outermost: every path - ;; meets them before the command's own limits. The nested - ;; `climit/invoke!` chains carry only the command's own limits and - ;; run inside those of the enclosing call, so this puts both paths - ;; in the same order. With the opposite order two calls of the same - ;; profile hold the same limiters inverted and park for good. - (concat (get-limits mdata) global-limits)) + ;; The root limiters go first so they end up innermost: a command + ;; takes the limits it declares before the root ones. Every path + ;; meets the limiters in the same order, because every acquisition + ;; goes through this wrapper. + (concat global-limits (get-limits mdata))) handler)) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; PUBLIC API -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defn- build-exec-chain - [{:keys [::label ::rpc/climit] :as cfg} f] - (reduce (fn [handler [limit-id limit-key]] - (if-let [config (get-config climit limit-id)] - (let [config (-> config - (assoc ::key limit-key) - (assoc ::label label))] - (fn [cfg params] - (let [config (assoc config ::params params)] - (invoke climit config (partial handler cfg params))))) - (do - (l/wrn :hint "config not found" :label label :id limit-id) - f))) - f - (get-limits cfg))) - -(defn invoke! - "Run a function in context of climit." - [{:keys [::rpc/climit] :as cfg} f params] - (let [f (if climit - (build-exec-chain cfg f) - f)] - (f cfg params))) diff --git a/backend/src/app/rpc/commands/media.clj b/backend/src/app/rpc/commands/media.clj index c5a78df076..3ba28923b0 100644 --- a/backend/src/app/rpc/commands/media.clj +++ b/backend/src/app/rpc/commands/media.clj @@ -239,6 +239,8 @@ (sv/defmethod ::create-file-media-object-from-url {::doc/added "1.17" ::doc/changes [["2.19" "The optional :id param is rejected with a params-validation error; the server always generates the identifier"]] + ::climit/id [[:process-image/by-profile ::rpc/profile-id] + [:process-image/global]] ::sm/params schema:create-file-media-object-from-url} [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}] (files/check-edition-permissions! pool profile-id file-id) @@ -262,16 +264,7 @@ (assoc :from-url? true) (assoc :content content) (assoc :name (d/nilv name "unknown")))] - - ;; NOTE: we use the climit here in a dynamic invocation because we - ;; don't want saturate the process-image limit with IO (download - ;; of external image) - - (-> cfg - (assoc ::climit/id [[:process-image/by-profile (:profile-id params)] - [:process-image/global]]) - (assoc ::climit/label "create-file-media-object-from-url") - (climit/invoke! #(db/run! %1 create-file-media-object %2) params)))) + (db/run! cfg create-file-media-object params))) ;; --- Clone File Media object (Upload and create from url) diff --git a/backend/src/app/rpc/commands/plugins.clj b/backend/src/app/rpc/commands/plugins.clj index 8f01b3b521..882ab5e597 100644 --- a/backend/src/app/rpc/commands/plugins.clj +++ b/backend/src/app/rpc/commands/plugins.clj @@ -34,8 +34,7 @@ (sv/defmethod ::add-profile-plugin {::doc/added "2.18" - ::climit/id [[:profile-plugin-ops/by-profile ::rpc/profile-id] - [:profile-plugin-ops/global]] + ::climit/id [[:profile-plugin-ops/by-profile ::rpc/profile-id]] ::sm/params schema:add-profile-plugin ::sm/result ctp/schema:registry-entry ::db/transaction true} @@ -69,8 +68,7 @@ (sv/defmethod ::remove-profile-plugin {::doc/added "2.18" - ::climit/id [[:profile-plugin-ops/by-profile ::rpc/profile-id] - [:profile-plugin-ops/global]] + ::climit/id [[:profile-plugin-ops/by-profile ::rpc/profile-id]] ::sm/params schema:remove-profile-plugin ::sm/result :nil ::db/transaction true} diff --git a/backend/src/app/rpc/commands/profile.clj b/backend/src/app/rpc/commands/profile.clj index c0cdf56971..339509b1ed 100644 --- a/backend/src/app/rpc/commands/profile.clj +++ b/backend/src/app/rpc/commands/profile.clj @@ -306,6 +306,8 @@ (sv/defmethod ::update-profile-photo {:doc/added "1.1" + ::climit/id [[:process-image/by-profile ::rpc/profile-id] + [:process-image/global]] ::sm/params schema:update-profile-photo ::rpc/multipart-only-params [:file] ::sm/result :nil} @@ -355,13 +357,12 @@ :content-type (:mtype thumb)})) (defn upload-photo - [{:keys [::sto/storage] :as cfg} {:keys [file] :as params}] - (let [params (-> cfg - (assoc ::climit/id [[:process-image/by-profile (:profile-id params)] - [:process-image/global]]) - (assoc ::climit/label "upload-photo") - (climit/invoke! generate-thumbnail file))] - (sto/put-object! storage params))) + "Generate the thumbnail of a photo and store it. + + The caller declares the `process-image` limits: this helper runs inside + them, so a command that calls it has to take them." + [{:keys [::sto/storage] :as cfg} {:keys [file]}] + (sto/put-object! storage (generate-thumbnail cfg file))) ;; --- MUTATION: Delete Photo diff --git a/backend/src/app/rpc/commands/teams.clj b/backend/src/app/rpc/commands/teams.clj index f8b85ac0eb..3b1785830a 100644 --- a/backend/src/app/rpc/commands/teams.clj +++ b/backend/src/app/rpc/commands/teams.clj @@ -26,6 +26,7 @@ [app.msgbus :as mbus] [app.nitrate :as nitrate] [app.rpc :as-alias rpc] + [app.rpc.climit :as-alias climit] [app.rpc.commands.profile :as profile] [app.rpc.doc :as-alias doc] [app.rpc.helpers :as rph] @@ -1084,6 +1085,8 @@ (sv/defmethod ::update-team-photo {::doc/added "1.17" + ::climit/id [[:process-image/by-profile ::rpc/profile-id] + [:process-image/global]] ::sm/params schema:update-team-photo ::rpc/multipart-only-params [:file]} [cfg {:keys [::rpc/profile-id file] :as params}] diff --git a/backend/test/backend_tests/climit_test.clj b/backend/test/backend_tests/climit_test.clj index b5cef6bda3..76aff9252a 100644 --- a/backend/test/backend_tests/climit_test.clj +++ b/backend/test/backend_tests/climit_test.clj @@ -38,20 +38,16 @@ (mapcat :labels) (vec))) -(defn- saw-call? - "Wait until a metrics call mentions `label`." - [label timeout] - (let [deadline (+ (System/currentTimeMillis) timeout)] - (loop [] - (cond - (some (fn [call] (some #{label} (:labels call))) @calls) - true - - (> (System/currentTimeMillis) deadline) - false - - :else - (do (Thread/sleep 10) (recur)))))) +(defn- invoke! + "Run `f` under the limits the cfg declares, the way a command does: the key + of each limit comes from the params, and the root limiters come after the + ones the cfg declares." + [cfg f params] + (let [wrapped (climit/wrap cfg + f + {::sv/name "test-command" + ::climit/id (::climit/id cfg)})] + (wrapped cfg params))) (defn- failed-type "Run `f` and return its value, or the type of the error it raised." @@ -101,11 +97,10 @@ ;; ACQUISITION ORDER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(t/deftest acquires-root-limits-before-the-command-own-limits - ;; A command declaring its own limits must meet the root limiters first. - ;; The nested `climit/invoke!` calls take only the command's own limits and - ;; run inside the root ones, so any other order lets two calls of the same - ;; profile hold the same limiters in opposite order and park for good. +(t/deftest acquires-the-command-own-limits-before-the-root-limits + ;; A command declaring its own limits must meet them before the root + ;; limiters. No command enters climit from inside its handler any more, so + ;; every path takes the limiters in the same order. (record-metrics (fn [] (th/with-climit [climit test-config] @@ -113,124 +108,57 @@ wrapped (climit/wrap {::rpc/climit climit} (fn [_ _] :ok) mdata) result (wrapped {::rpc/climit climit} {::rpc/profile-id (uuid/next)})] (t/is (= :ok result)) - (t/is (= ["root/by-profile" - "root/global" - "process-image/by-profile" - "process-image/global"] + (t/is (= ["process-image/by-profile" + "process-image/global" + "root/by-profile" + "root/global"] (acquired-in-order)))))))) -(t/deftest nested-limits-do-not-deadlock-with-the-command-own-limits - ;; Two paths over one profile: a command declaring its own limits (like - ;; `upload-file-media-object`) and a command that takes the root limiters and - ;; then asks for the same limits from inside its handler (like - ;; `create-file-media-object-from-url`). Each path holds what the other one - ;; waits for the moment the order differs, and nothing releases. +(t/deftest the-key-of-a-limit-comes-from-the-params + ;; The key of a limit is a function of the params: a keyword is looked up in + ;; them, and that is what tells one profile from another. Two calls with the + ;; same key share the limiter, and two calls with a different key do not. + (th/with-climit [climit {:test-key/by-profile {:permits 1 :timeout 2000}}] + (let [pid (uuid/next) + limits [[:test-key/by-profile ::rpc/profile-id]] + cfg {::rpc/climit climit + ::climit/id limits} + gate (promise) + entered (promise) + wrapped (climit/wrap cfg + (fn [_ params] + ;; only the call of the first profile waits + (when (= pid (::rpc/profile-id params)) + (deliver entered true) + @gate) + :ok) + {::sv/name "test-command" ::climit/id limits}) + holder (future (wrapped cfg {::rpc/profile-id pid}))] + + ;; The call of the same profile waits for the permit this thread holds. + (t/is (true? (deref entered 5000 false))) + (t/is (= :timeout (deref (future (wrapped cfg {::rpc/profile-id pid})) 300 :timeout))) + + ;; The call of another profile takes the permit of its own key. + (t/is (= :ok (deref (future (wrapped cfg {::rpc/profile-id (uuid/next)})) 5000 :timeout))) + + (deliver gate true) + (t/is (= :ok (deref holder 5000 :timeout)))))) + +(t/deftest a-command-without-limits-takes-the-root-limits + ;; A command that declares no limits of its own still takes the root ones, + ;; and in the same order as the ones of a command that declares them. (record-metrics (fn [] (th/with-climit [climit test-config] - (let [pid (uuid/next) - gate (promise) - entered (promise) + (let [mdata {::sv/name "test-command"} + wrapped (climit/wrap {::rpc/climit climit} (fn [_ _] :ok) mdata) + result (wrapped {::rpc/climit climit} {::rpc/profile-id (uuid/next)})] + (t/is (= :ok result)) + (t/is (= ["root/by-profile" + "root/global"] + (acquired-in-order)))))))) - handler-b (fn [cfg params] - (deliver entered true) - @gate - (-> cfg - (assoc ::climit/id [[:process-image/by-profile pid] - [:process-image/global]]) - (assoc ::climit/label "path-b") - (climit/invoke! (fn [_ _] :nested-ok) params))) - - wrapped-a (climit/wrap {::rpc/climit climit} - (fn [_ _] :ok) - {::sv/name "path-a" ::climit/id image-limits}) - - wrapped-b (climit/wrap {::rpc/climit climit} - handler-b - {::sv/name "path-b"})] - - ;; Path B takes the root limiters and waits inside its handler. - (let [fb (future (failed-type #(wrapped-b {::rpc/climit climit} - {::rpc/profile-id pid})))] - (t/is (true? (deref entered 5000 false))) - - ;; Path A, started now, takes its own limiters and then waits for the - ;; root ones, which B holds. The recorded metrics are how the test - ;; knows A got that far instead of guessing with a sleep. - (reset! calls []) - (let [fa (future (failed-type #(wrapped-a {::rpc/climit climit} - {::rpc/profile-id pid})))] - (t/is (true? (saw-call? "root/by-profile" 5000))) - - ;; Let B ask for the limits A holds: if the order differs, each path - ;; now waits for a permit the other one holds. - (deliver gate true) - - (t/is (= :ok (deref fa 15000 :timeout))) - (t/is (= :nested-ok (deref fb 15000 :timeout)))))))))) - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; REENTRANCY -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(t/deftest reentrant-invoke-does-not-consume-a-second-permit - ;; A handler entering climit for a limit it already holds must not queue - ;; behind itself: it runs inline and takes no second permit. Another thread - ;; asking for the same limiter still waits, so the limit stays in place. - (th/with-climit [climit {:process-image/by-profile - {:permits 1 :timeout 2000}}] - (let [pid (uuid/next) - cfg {::rpc/climit climit - ::climit/id [[:process-image/by-profile pid]]} - inner (promise) - other (promise) - handler (fn [cfg params] - (deliver inner - (failed-type #(climit/invoke! cfg (fn [_ _] :inner-ok) params))) - (deliver other (future (climit/invoke! cfg (fn [_ _] :other-ok) params))) - (t/is (= :waiting (deref @other 300 :waiting))) - :outer-ok) - - outcome (failed-type #(climit/invoke! cfg handler {}))] - - ;; With no reentrancy handling the inner call waits for the permit this very - ;; thread holds and ends failing by timeout. - (t/is (= :inner-ok (deref inner 5000 :timeout))) - (t/is (= :outer-ok outcome)) - - ;; once the outer call releases, the other thread gets its permit - (t/is (= :other-ok (deref @other 5000 :timeout)))))) - -(t/deftest reentrant-tracking-is-cleaned-up-when-the-handler-fails - ;; If the mark is not removed, the thread keeps believing it holds the - ;; limiter and every later call of that key would skip the limit. - (th/with-climit [climit {:process-image/by-profile - {:permits 1 :timeout 1000}}] - (let [pid (uuid/next) - cfg {::rpc/climit climit - ::climit/id [[:process-image/by-profile pid]]} - holding (promise) - gate (promise)] - - ;; The failing call runs on this thread, so this thread is the one that - ;; must forget it held the limiter. - (t/is (thrown? clojure.lang.ExceptionInfo - (climit/invoke! cfg (fn [_ _] (throw (ex-info "boom" {}))) {}))) - - ;; another thread takes the only permit - (let [fb (future (climit/invoke! cfg (fn [_ _] - (deliver holding true) - @gate - :held) - {}))] - (t/is (true? (deref holding 5000 false))) - - ;; this thread must wait for it, not skip the limiter - (t/is (= :concurrency-limit - (failed-type #(climit/invoke! cfg (fn [_ _] :inner-ok) {})))) - - (deliver gate true) - (t/is (= :held (deref fb 5000 :timeout))))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SHIPPED CONFIG @@ -239,14 +167,19 @@ (t/deftest example-config-bounds-every-wait ;; A limiter without `:timeout` parks the calling thread forever, which is ;; how a limit nobody releases turns into lost worker threads and days of - ;; silent 429s. Every entry of the shipped config must carry one. + ;; silent 429s. Every entry of the shipped config must carry one. A limiter + ;; without `:queue` lets its waiters pile up without bound, and a command + ;; takes its own limits before the root ones, so the queue of a limit is + ;; where its own pile-up waits. (let [path (io/resource "climit.edn")] (t/is (some? path)) (let [data (edn/read-string (slurp path))] (t/is (seq data)) (doseq [[id config] data] (t/is (int? (:timeout config)) - (str id " must declare a timeout")))))) + (str id " must declare a timeout")) + (t/is (int? (:queue config)) + (str id " must declare a queue")))))) (t/deftest warns-when-a-limiter-has-no-timeout ;; The config that production loads lives outside the repository and is @@ -321,17 +254,17 @@ (let [name (limiter-name :test-waiting/by-profile) entered (promise) gate (promise) - holder (future (climit/invoke! (limiter-cfg climit :test-waiting/by-profile "a") - (fn [_ _] (deliver entered true) @gate :held) - {}))] + holder (future (invoke! (limiter-cfg climit :test-waiting/by-profile "a") + (fn [_ _] (deliver entered true) @gate :held) + {}))] (t/is (true? (deref entered 5000 false))) ;; the holder is running, not waiting (reset! calls []) - (let [waiter (future (climit/invoke! (limiter-cfg climit :test-waiting/by-profile "a") - (fn [_ _] :waited) - {}))] + (let [waiter (future (invoke! (limiter-cfg climit :test-waiting/by-profile "a") + (fn [_ _] :waited) + {}))] (t/is (true? (wait-until #(= 1 (waiting-last name)) 5000))) (t/is (= 1 (waiting-count climit name))) @@ -350,30 +283,30 @@ (fn [] (th/with-climit [climit {:test-waiting-keys/by-profile {:permits 1 :timeout 3000}}] (let [name (limiter-name :test-waiting-keys/by-profile) - gates {:a (promise) :b (promise)} + gates {"a" (promise) "b" (promise)} holders (into {} (map (fn [k] (let [entered (promise)] [k {:entered entered - :future (future (climit/invoke! (limiter-cfg climit :test-waiting-keys/by-profile k) - (fn [_ _] - (deliver entered true) - @(gates k) - :held) - {}))}]))) - [:a :b])] + :future (future (invoke! (limiter-cfg climit :test-waiting-keys/by-profile k) + (fn [_ _] + (deliver entered true) + @(gates k) + :held) + {}))}]))) + ["a" "b"])] - (doseq [k [:a :b]] + (doseq [k ["a" "b"]] (t/is (true? (deref (:entered (holders k)) 5000 false)))) ;; one call per key, waiting behind its own holder (let [waiters (into {} (map (fn [k] - [k (future (climit/invoke! (limiter-cfg climit :test-waiting-keys/by-profile k) - (fn [_ _] :waited) - {}))])) - [:a :b])] + [k (future (invoke! (limiter-cfg climit :test-waiting-keys/by-profile k) + (fn [_ _] :waited) + {}))])) + ["a" "b"])] (t/is (true? (wait-until #(= 2 (waiting-count climit name)) 5000))) ;; the increment that reaches 2 always publishes 2, whichever waiter @@ -381,9 +314,9 @@ ;; contract, the value is. (t/is (some #(= 2 %) (waiting-value-of name))) - (doseq [k [:a :b]] (deliver (gates k) true)) + (doseq [k ["a" "b"]] (deliver (gates k) true)) - (doseq [k [:a :b]] + (doseq [k ["a" "b"]] (t/is (= :waited (deref (waiters k) 5000 :timeout))) (t/is (= :held (deref (:future (holders k)) 5000 :timeout)))) @@ -413,17 +346,17 @@ cfg (limiter-cfg climit :test-rejected/by-profile "a") entered (promise) gate (promise) - holder (future (climit/invoke! cfg - (fn [_ _] (deliver entered true) @gate :held) - {}))] + holder (future (invoke! cfg + (fn [_ _] (deliver entered true) @gate :held) + {}))] (t/is (true? (deref entered 5000 false))) (reset! calls []) ;; the queue holds one waiter, so the next call is rejected right away - (let [queued (future (failed-type #(climit/invoke! cfg (fn [_ _] :queued) {})))] + (let [queued (future (failed-type #(invoke! cfg (fn [_ _] :queued) {})))] (t/is (true? (wait-until #(= 1 (waiting-last name)) 5000))) - (t/is (= :concurrency-limit (failed-type #(climit/invoke! cfg (fn [_ _] :extra) {})))) + (t/is (= :concurrency-limit (failed-type #(invoke! cfg (fn [_ _] :extra) {})))) (t/is (= [[name "queue-full"]] (rejections))) (deliver gate true) @@ -436,13 +369,13 @@ cfg (limiter-cfg climit :test-timeout/by-profile "a") entered (promise) gate (promise) - holder (future (climit/invoke! cfg - (fn [_ _] (deliver entered true) @gate :held) - {}))] + holder (future (invoke! cfg + (fn [_ _] (deliver entered true) @gate :held) + {}))] (t/is (true? (deref entered 5000 false))) (reset! calls []) - (t/is (= :concurrency-limit (failed-type #(climit/invoke! cfg (fn [_ _] :late) {})))) + (t/is (= :concurrency-limit (failed-type #(invoke! cfg (fn [_ _] :late) {})))) (t/is (= [[name "timeout"]] (rejections))) (deliver gate true) @@ -458,14 +391,14 @@ cfg (limiter-cfg climit :test-rejected-baseline/by-profile "a") entered (promise) gate (promise) - holder (future (climit/invoke! cfg - (fn [_ _] (deliver entered true) @gate :held) - {}))] + holder (future (invoke! cfg + (fn [_ _] (deliver entered true) @gate :held) + {}))] (t/is (true? (deref entered 5000 false))) (reset! calls []) - (t/is (= :concurrency-limit (failed-type #(climit/invoke! cfg (fn [_ _] :extra) {})))) + (t/is (= :concurrency-limit (failed-type #(invoke! cfg (fn [_ _] :extra) {})))) (t/is (= 0 (waiting-count climit name))) (t/is (true? (wait-until #(= 0 (waiting-last name)) 5000))) @@ -482,7 +415,7 @@ (reset! calls []) (t/is (thrown? clojure.lang.ExceptionInfo - (climit/invoke! cfg (fn [_ _] (throw (ex-info "boom" {}))) {}))) + (invoke! cfg (fn [_ _] (throw (ex-info "boom" {}))) {}))) (t/is (= 0 (waiting-count climit name))) (t/is (true? (wait-until #(= 0 (waiting-last name)) 5000)))))))) @@ -510,7 +443,7 @@ (reset! calls []) (with-redefs [mtx/run! (failing-first-waiting-publish calls)] (t/is (thrown? clojure.lang.ExceptionInfo - (climit/invoke! cfg (fn [_ _] :never) {})))) + (invoke! cfg (fn [_ _] :never) {})))) ;; the count came back down instead of staying up for good (t/is (= 0 (waiting-count climit name))) @@ -520,11 +453,11 @@ ;; run inline instead of waiting for the permit another thread holds. (let [entered (promise) gate (promise) - holder (future (climit/invoke! cfg - (fn [_ _] (deliver entered true) @gate :held) - {}))] + holder (future (invoke! cfg + (fn [_ _] (deliver entered true) @gate :held) + {}))] (t/is (true? (deref entered 5000 false))) - (t/is (= :concurrency-limit (failed-type #(climit/invoke! cfg (fn [_ _] :inline) {})))) + (t/is (= :concurrency-limit (failed-type #(invoke! cfg (fn [_ _] :inline) {})))) (deliver gate true) (t/is (= :held (deref holder 5000 :timeout))))))) @@ -549,13 +482,13 @@ (let [cfg (limiter-cfg climit :test-registry/by-profile "a") entered (promise) gate (promise) - holder (future (climit/invoke! cfg - (fn [_ _] (deliver entered true) @gate :held) - {}))] + holder (future (invoke! cfg + (fn [_ _] (deliver entered true) @gate :held) + {}))] (t/is (true? (deref entered 5000 false))) - (let [waiter (future (climit/invoke! cfg (fn [_ _] :waited) {}))] + (let [waiter (future (invoke! cfg (fn [_ _] :waited) {}))] (t/is (true? (wait-until #(= 1.0 (gauge-value metrics name)) 5000))) (deliver gate true) (t/is (= :waited (deref waiter 5000 :timeout))) @@ -592,20 +525,20 @@ cfg (limiter-cfg climit :test-log/by-profile "a") entered (promise) gate (promise) - holder (future (climit/invoke! cfg - (fn [_ _] (deliver entered true) @gate :held) - {}))] + holder (future (invoke! cfg + (fn [_ _] (deliver entered true) @gate :held) + {}))] (t/is (true? (deref entered 5000 false))) (reset! calls []) - (let [q1 (future (climit/invoke! cfg (fn [_ _] :q1) {})) - q2 (future (climit/invoke! cfg (fn [_ _] :q2) {}))] + (let [q1 (future (invoke! cfg (fn [_ _] :q1) {})) + q2 (future (invoke! cfg (fn [_ _] :q2) {}))] ;; the two of them fill the queue, so the next one is rejected (t/is (true? (wait-until #(= 2 (waiting-count climit name)) 5000))) (t/is (some #(= 2 %) (waiting-value-of name))) - (t/is (= :concurrency-limit (failed-type #(climit/invoke! cfg (fn [_ _] :x) {})))) + (t/is (= :concurrency-limit (failed-type #(invoke! cfg (fn [_ _] :x) {})))) (let [props (::l/props (rejected-record records "queue-full"))] (t/is (= 1 (get props :permits))) @@ -630,14 +563,14 @@ gate (promise) capture (fn [_ action _req-id _stats _elapsed code reason] (swap! lines conj [action code reason])) - holder (future (climit/invoke! cfg - (fn [_ _] (deliver entered true) @gate :held) - {}))] + holder (future (invoke! cfg + (fn [_ _] (deliver entered true) @gate :held) + {}))] (t/is (true? (deref entered 5000 false))) (with-redefs [climit/log capture] - (t/is (= :concurrency-limit (failed-type #(climit/invoke! cfg (fn [_ _] :late) {})))) + (t/is (= :concurrency-limit (failed-type #(invoke! cfg (fn [_ _] :late) {})))) (t/is (= [["rejected" :capacity-limit-reached "timeout"]] (filterv #(= "rejected" (first %)) @lines)))) diff --git a/backend/test/backend_tests/helpers.clj b/backend/test/backend_tests/helpers.clj index 8aa3b684fc..58b36244ea 100644 --- a/backend/test/backend_tests/helpers.clj +++ b/backend/test/backend_tests/helpers.clj @@ -577,13 +577,19 @@ (defn init-climit "Build a concurrency limiter component from an inline config map. The optional second argument is the metrics instance to publish to (a - `metrics-stub` by default, where every `run!` is a no-op)." + `metrics-stub` by default, where every `run!` is a no-op). + + The root limiters are added with permits that no test reaches: every + request goes through them, and a test that does not list them would log a + warning per request." ([config] (init-climit config (metrics-stub))) ([config metrics] (let [file (doto (java.io.File/createTempFile "climit" ".edn") (.deleteOnExit))] - (spit file (pr-str config)) + (spit file (pr-str (merge {:root/global {:permits 1000 :timeout 3000} + :root/by-profile {:permits 1000 :timeout 3000}} + config))) (ig/init-key ::rpc/climit {::climit/enabled true ::climit/config (.getAbsolutePath file) diff --git a/backend/test/backend_tests/rpc_binfile_test.clj b/backend/test/backend_tests/rpc_binfile_test.clj index e684d5b7e0..f15a261040 100644 --- a/backend/test/backend_tests/rpc_binfile_test.clj +++ b/backend/test/backend_tests/rpc_binfile_test.clj @@ -175,14 +175,14 @@ (defn- import-file [profile path] - (let [out (th/command! {::th/type :import-binfile - ::rpc/profile-id (:id profile) - :project-id (:default-project-id profile) - :name "imported" - :file {:filename "imported.penpot" - :size (fs/size path) - :path path - :mtype "application/zip"}})] + (let [out (th/multipart-command! {::th/type :import-binfile + ::rpc/profile-id (:id profile) + :project-id (:default-project-id profile) + :name "imported" + :file {:filename "imported.penpot" + :size (fs/size path) + :path path + :mtype "application/zip"}})] (t/is (nil? (:error out))) (th/consume-sse (:result out)))) diff --git a/backend/test/backend_tests/rpc_climit_test.clj b/backend/test/backend_tests/rpc_climit_test.clj index b5b8e853d8..aa058f03d2 100644 --- a/backend/test/backend_tests/rpc_climit_test.clj +++ b/backend/test/backend_tests/rpc_climit_test.clj @@ -6,13 +6,22 @@ (ns backend-tests.rpc-climit-test (:require + [app.rpc :as-alias rpc] [app.rpc.climit :as-alias climit] [app.util.services :as-alias sv] [backend-tests.helpers :as th] + [clojure.edn :as edn] + [clojure.java.io :as io] [clojure.test :as t])) (t/use-fixtures :once th/state-init) +(defn- command-limits + "The `::climit/id` declaration of the RPC command named `name`." + [name] + (let [[mdata _] (get (:app.rpc/methods th/*system*) (keyword name))] + (::climit/id mdata))) + (defn- method-limit-declarations "The `::climit/id` declarations of every RPC command, as the running system wraps them." @@ -24,11 +33,87 @@ (when-let [limits (::climit/id mdata)] [mdata limits]))))) +(defn- declared-ids + "The limit ids a command declares, in the order it declares them." + [limits] + (cond + (keyword? limits) + [limits] + + (vector? (first limits)) + (mapv first limits) + + :else + [(first limits)])) + +(defn- limit-order-edges + "The pairs of limit ids the commands declare, as edges: the first one of the + pair is taken before the second one." + [declarations] + (reduce (fn [edges [mdata limits]] + (let [ids (declared-ids limits) + size (count ids)] + (into edges + (for [i (range size) + j (range (inc i) size)] + [(nth ids i) (nth ids j)])))) + #{} + declarations)) + +(defn- limit-order-cycle + "The limit ids whose relative order the commands disagree about: the ones + left when the relation cannot be sorted. + + Two commands that take the same limiters in opposite order leave two paths + of one profile holding them in opposite order, and the threads park for + good. A ring of three does the same, so the relation is checked as a whole + and not pair by pair." + [edges] + (let [nodes (into #{} (mapcat identity) edges) + outgoing (reduce (fn [acc [a b]] (update acc a (fnil conj #{}) b)) {} edges) + indegree (reduce (fn [acc [_ b]] (update acc b (fnil inc 0))) {} edges)] + (loop [pending nodes + degrees indegree] + (let [ready (filterv #(zero? (get degrees % 0)) pending)] + (if (empty? ready) + (seq pending) + (recur (apply disj pending ready) + (reduce (fn [degrees node] + (reduce (fn [degrees next] + (update degrees next (fnil dec 0))) + degrees + (get outgoing node))) + degrees + ready))))))) + +(t/deftest the-media-object-from-url-command-declares-its-own-limits + ;; The command used to enter climit from inside its handler, which forced + ;; every path to take the root limiters before the command ones. It declares + ;; its limits now, so there is a single place where they are read. + (t/is (= [[:process-image/by-profile ::rpc/profile-id] + [:process-image/global]] + (command-limits "create-file-media-object-from-url")))) + +(t/deftest the-update-profile-photo-command-declares-its-own-limits + ;; The command used to enter climit from inside its handler, which forced + ;; every path to take the root limiters before the command ones. It declares + ;; its limits now, so there is a single place where they are read. + (t/is (= [[:process-image/by-profile ::rpc/profile-id] + [:process-image/global]] + (command-limits "update-profile-photo")))) + +(t/deftest the-update-team-photo-command-declares-its-own-limits + ;; The command generates the thumbnail of a team through `upload-photo`, + ;; which used to enter climit on its own. It declares the limits now, so the + ;; image processing of a team is bounded like the one of a profile. + (t/is (= [[:process-image/by-profile ::rpc/profile-id] + [:process-image/global]] + (command-limits "update-team-photo")))) + (t/deftest commands-declare-the-by-profile-limit-before-the-global-one ;; `climit/get-limits` reverses a declared vector of pairs, so the first one - ;; declared is acquired first, and the nested `climit/invoke!` chains read the - ;; same declaration. A pair declared global first puts a command back in the - ;; inverted order that parked two paths of one profile for good. + ;; declared is acquired first. A pair declared global first puts a command + ;; back in the inverted order that parked two paths of one profile for good. (let [declarations (method-limit-declarations)] ;; the system wraps every command, so a short list means the scan went stale @@ -49,3 +134,46 @@ (t/is (< idx gidx) (str where " must declare " id " before " (keyword (namespace id) "global"))))))))) + +(t/deftest every-command-takes-the-shared-limits-in-the-same-order + ;; Two commands that share a limit and take it in opposite order can hold + ;; the same limiters in opposite order and park for good. The order is free + ;; now that no command enters climit from inside its handler, so this test + ;; is what keeps the commands consistent with each other. + (let [declarations (method-limit-declarations) + edges (limit-order-edges declarations) + cycle (limit-order-cycle edges)] + + ;; the system wraps every command, so a short list means the scan went stale + (t/is (<= 10 (count declarations))) + (t/is (seq edges)) + (t/is (nil? cycle) + (str "the commands take these limits in different orders: " + (pr-str cycle))))) + +(t/deftest a-ring-of-three-limits-is-a-cycle + ;; A ring of three limits does the same as a pair in opposite order: three + ;; paths hold the three limiters and wait for each other. The relation is + ;; checked as a whole for that reason, and not pair by pair. + (t/is (= #{:a :b :c} + (set (limit-order-cycle #{[:a :b] [:b :c] [:c :a]})))) + (t/is (nil? (limit-order-cycle #{[:a :b] [:b :c]})))) + +(t/deftest every-declared-limit-has-an-entry-in-the-shipped-config + ;; `climit/wrap` logs a warning and runs the handler with no limiter at all + ;; when the config has no entry for a declared id, so the command runs on + ;; every thread that asks for it. The production file is maintained by hand + ;; outside the repository and mirrors this one, so a command declaring a limit + ;; the file does not list is the shape of an unbounded command in production. + (let [path (io/resource "climit.edn") + config (edn/read-string (slurp path)) + declared (into #{} + (mapcat (fn [[_ limits]] (declared-ids limits))) + (method-limit-declarations))] + + ;; the system wraps every command, so an empty set means the scan went stale + (t/is (seq declared)) + + (doseq [id declared] + (t/is (some? (get config id)) + (str id " is declared by a command but has no entry in climit.edn"))))) From a3fe43c1ecd1631e97bf930ef21f7e2bca423372 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Thu, 29 Oct 2026 09:02:45 +0100 Subject: [PATCH 02/14] :bug: Report raw fetch failures as connectivity errors (#12624) * :bug: Report raw fetch failures as connectivity errors A fetch that fails outside app.util.http (zip.js, plugins, schema loads) rejects with a bare TypeError such as "Failed to fetch". It reached the global handlers and was reported as an unhandled crash, with no stack and no URL. The global handlers now wrap the browser's network TypeErrors as :network (or :offline when the browser says so), so they get the connection toast and a compact handled report. Response body reads in app.util.http also wrap a TypeError as :network with the request uri, as fetch itself already did. Relates to #12581 AI-assisted-by: claude-opus-5-5 * :bug: Treat only network TypeErrors on body read as connectivity errors process-response-type turned every TypeError from a body read into a :network error, so a bug such as "body stream already read" showed a connection toast. It now uses network-failure?, which moves to app.util.http so that both the http client and the global error handlers share it. Add Firefox's "Error in body stream" message. Tests now check :offline and :network separately by setting navigator.onLine, and read-error builds on async/->promise. AI-assisted-by: claude-opus-5-5 --- frontend/src/app/main/errors.cljs | 18 +++++ frontend/src/app/util/http.cljs | 34 ++++++++- frontend/test/frontend_tests/errors_test.cljs | 31 ++++++++ frontend/test/frontend_tests/runner.cljs | 2 + .../test/frontend_tests/util_http_test.cljs | 75 +++++++++++++++++++ 5 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 frontend/test/frontend_tests/util_http_test.cljs diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 54401c94af..5125730363 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -22,6 +22,7 @@ [app.main.worker] [app.util.dom :as dom] [app.util.globals :as g] + [app.util.http :as http] [app.util.i18n :refer [tr]] [app.util.timers :as ts] [app.util.webapi :as wapi] @@ -1123,6 +1124,15 @@ (and (= (.-name ^js cause) "NotFoundError") (str/includes? message "removeChild"))))) +(defn network-failure->error + "Wrap a raw network TypeError as a connectivity error, so it is reported + as an environment failure instead of an application crash." + [cause] + (ex-info (ex-message cause) + {:type (if (false? (.-onLine ^js g/navigator)) :offline :network) + :hint "unable to perform fetch operation"} + cause)) + (defn- from-plugin? "Check if the error is marked as originating from plugin code. The plugin runtime tracks plugin errors in a WeakMap, which works even @@ -1149,6 +1159,10 @@ (is-ignorable-exception? cause) nil + ;; Raw fetch failures: connectivity, not a crash + (http/network-failure? cause) + (on-error (network-failure->error cause)) + ;; All other errors: show exception page :else @@ -1176,6 +1190,10 @@ (is-ignorable-exception? cause) nil + ;; Raw fetch failures: connectivity, not a crash + (http/network-failure? cause) + (on-error (network-failure->error cause)) + ;; All other errors: show exception page :else (let [data (ex-data cause) diff --git a/frontend/src/app/util/http.cljs b/frontend/src/app/util/http.cljs index 62a8b1cac7..97638f7231 100644 --- a/frontend/src/app/util/http.cljs +++ b/frontend/src/app/util/http.cljs @@ -146,6 +146,26 @@ :body (.-body ^js response) ::response response}) +;; Messages of the TypeError a failed `fetch` rejects with, or a failed +;; read of its response body. +(def ^:private network-failure-messages + #{"Failed to fetch" ; Chrome + "NetworkError when attempting to fetch resource." ; Firefox + "Load failed" ; Safari + "network error" ; Chrome, body read + "Error in body stream"}) ; Firefox, body read + +(defn network-failure? + "True when the error is the browser's TypeError for a request that never + got an answer. Other TypeErrors, such as reading a body twice, are bugs + and do not match." + [cause] + (and (= (.-name ^js cause) "TypeError") + (let [message (ex-message cause)] + (or (contains? network-failure-messages message) + ;; Newer Chrome versions append the host in parentheses + (str/starts-with? message "Failed to fetch ("))))) + (defn process-response-type [response-type response] (let [native-response (::response response) @@ -156,7 +176,19 @@ :blob (.blob ^js native-response))] (->> (rx/from body) (rx/map (fn [body] - (assoc response :body body)))))) + (assoc response :body body))) + ;; The connection can drop while the body streams in, after + ;; `fetch` already resolved; the browser then rejects the read + ;; with a bare TypeError. Other errors, such as parse failures + ;; (SyntaxError), pass as is. + (rx/catch (fn [cause] + (if (network-failure? cause) + (rx/throw (ex-info (ex-message cause) + {:type :network + :hint "unable to read response body" + :uri (:uri response)} + cause)) + (rx/throw cause))))))) (defn send! [{:keys [response-type] :or {response-type :text} :as params}] diff --git a/frontend/test/frontend_tests/errors_test.cljs b/frontend/test/frontend_tests/errors_test.cljs index c373926680..baa5da1f96 100644 --- a/frontend/test/frontend_tests/errors_test.cljs +++ b/frontend/test/frontend_tests/errors_test.cljs @@ -7,6 +7,7 @@ (ns frontend-tests.errors-test (:require [app.main.errors :as errors] + [app.util.globals :as g] [cljs.test :as t :include-macros true])) (defn- make-error @@ -148,3 +149,33 @@ ;; V8 gives native rejections such as a failed fetch no frames at all. (let [cause (make-error "TypeError" "Failed to fetch" :stack "TypeError: Failed to fetch")] (t/is (false? (errors/is-ignorable-exception? cause)))))) + +;; --------------------------------------------------------------------------- +;; network-failure->error tests +;; --------------------------------------------------------------------------- + +(defn- with-online + "Call `f` while `navigator.onLine` reads `online?`." + [online? f] + (js/Object.defineProperty g/navigator "onLine" + #js {:value online? :configurable true}) + (try + (f) + (finally + (js-delete g/navigator "onLine")))) + +(t/deftest test-network-failure-becomes-environment-error + (t/testing "A raw fetch failure is wrapped as an environment error" + (let [cause (make-error "TypeError" "Failed to fetch") + error (errors/network-failure->error cause)] + (t/is (true? (errors/environment-error? error))) + (t/is (= "Failed to fetch" (ex-message error))) + (t/is (identical? cause (ex-cause error)))))) + +(t/deftest test-network-failure-type-follows-connection + (let [cause (make-error "TypeError" "Failed to fetch") + type #(:type (ex-data (errors/network-failure->error cause)))] + (t/testing "Offline browsers report :offline" + (t/is (= :offline (with-online false type)))) + (t/testing "Online browsers report :network" + (t/is (= :network (with-online true type)))))) diff --git a/frontend/test/frontend_tests/runner.cljs b/frontend/test/frontend_tests/runner.cljs index c7e2d547fa..c96f1e4983 100644 --- a/frontend/test/frontend_tests/runner.cljs +++ b/frontend/test/frontend_tests/runner.cljs @@ -132,6 +132,7 @@ [frontend-tests.ui.stroke-menu-test] [frontend-tests.ui.workspace-libraries-test] [frontend-tests.util-clipboard-test] + [frontend-tests.util-http-test] [frontend-tests.util-object-test] [frontend-tests.util-queue-test] [frontend-tests.util-range-tree-test] @@ -283,6 +284,7 @@ 'frontend-tests.ui.stroke-menu-test 'frontend-tests.ui.workspace-libraries-test 'frontend-tests.util-clipboard-test + 'frontend-tests.util-http-test 'frontend-tests.util-object-test 'frontend-tests.util-queue-test 'frontend-tests.util-range-tree-test diff --git a/frontend/test/frontend_tests/util_http_test.cljs b/frontend/test/frontend_tests/util_http_test.cljs new file mode 100644 index 0000000000..e686d4d3a9 --- /dev/null +++ b/frontend/test/frontend_tests/util_http_test.cljs @@ -0,0 +1,75 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS SUBSIDIARY SL + +(ns frontend-tests.util-http-test + (:require + [app.util.http :as http] + [cljs.test :as t :include-macros true] + [frontend-tests.helpers.async :as async])) + +(def ^:private uri "https://example.com/assets/file.json") + +(defn- failing-response + "A response map whose native body read rejects with `cause`." + [cause] + {:status 200 + :uri uri + :headers {} + ::http/response #js {:text (fn [] (js/Promise.reject cause))}}) + +(defn- ^:async read-error + "Read the body of `response` as text and resolve with the error raised." + [response] + (try + (await (async/->promise (http/process-response-type :text response))) + nil + (catch :default cause + cause))) + +(t/deftest ^:async body-read-network-failure-is-a-network-error + (let [cause (js/TypeError. "network error") + error (await (read-error (failing-response cause))) + data (ex-data error)] + (t/is (= :network (:type data))) + (t/is (= uri (:uri data))) + (t/is (identical? cause (ex-cause error))))) + +(t/deftest ^:async body-parse-failure-passes-unchanged + (let [cause (js/SyntaxError. "Unexpected token < in JSON") + error (await (read-error (failing-response cause)))] + (t/is (identical? cause error)))) + +(t/deftest ^:async body-read-programming-error-passes-unchanged + (let [cause (js/TypeError. "body stream already read") + error (await (read-error (failing-response cause)))] + (t/is (identical? cause error)))) + +;; --------------------------------------------------------------------------- +;; network-failure? tests +;; --------------------------------------------------------------------------- + +(defn- make-error + [error-name message] + (let [err (js/Error. message)] + (set! (.-name err) error-name) + err)) + +(t/deftest test-network-failure-browser-messages + (t/testing "The TypeError each browser gives a failed fetch is a network failure" + (doseq [message ["Failed to fetch" + "Failed to fetch (design.penpot.app)" + "NetworkError when attempting to fetch resource." + "Load failed" + "network error" + "Error in body stream"]] + (t/is (true? (http/network-failure? (make-error "TypeError" message))) + message)))) + +(t/deftest test-network-failure-needs-type-error + (t/testing "Other errors with the same message are not network failures" + (t/is (false? (http/network-failure? (make-error "Error" "Failed to fetch"))))) + (t/testing "Other TypeErrors are not network failures" + (t/is (false? (http/network-failure? (make-error "TypeError" "x is not a function")))))) From 1962860f041d73e379b362db82bdf5218df729b4 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Thu, 29 Oct 2026 09:02:55 +0100 Subject: [PATCH 03/14] :bug: Reduce thumbnail re-renders and report throttled update loops (#12610) * :bug: Stop thumbnail subscribers re-rendering on every store change A thumbnail loaded from the server keeps a media id as :uri, and workspace-thumbnail-by-id resolves it into a new map on each read. The ref compared values with identical?, so every root frame, every component in the assets panel and the interactions layer re-rendered on every store change, mouse moves included. Compare by value instead. This does not loop by itself, but it adds work to every commit and brings other update loops closer to React's limit. Relates to #12580 AI-assisted-by: claude-opus-5-5 * :sparkles: Report update loops throttled by the update scheduler When the scheduler throttles an update loop, it only logs a console warning, so a loop that no longer crashes leaves no trace. Send an error report too, with the events in flight and the last events, at most once per report window. Relates to #12580 AI-assisted-by: claude-opus-5-5 * :bug: Report throttled update loops as unhandled exceptions The throttled update loop report used the handled-exception event, which only lands in the audit log: error reports and alerts read unhandled-exception and exception-page. A throttled loop is an application defect (its cause has :type :internal), and the point of the report is to find those loops, so it is now an unhandled exception. AI-assisted-by: claude-opus-5-5 --- frontend/src/app/main/errors.cljs | 27 ++++++++++++++----- frontend/src/app/main/refs.cljs | 5 +++- .../test/frontend_tests/main/refs_test.cljs | 21 +++++++++++++++ .../test/frontend_tests/main_errors_test.cljs | 27 ++++++++++++++++++- 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 5125730363..666a4d846b 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -440,16 +440,31 @@ (defn on-update-loop "Handler for the rumext update scheduler trips: logs the throttled - update loop with the events being processed, at most once per - `report-window-ms`. Runs inside store watchers and effect bodies, so it - never throws." - [_] + update loop and reports it as an unhandled exception with the events + being processed, at most once per `report-window-ms`. Runs inside store + watchers and effect bodies, so it never throws." + [{:keys [rounds]}] (try (let [now (inst-ms (ct/now))] (when (>= (- now @update-loop-warned-at) report-window-ms) (vreset! update-loop-warned-at now) - (.warn js/console "[update-scheduler] update loop throttled; in-flight events:" - (into-array (map ptk/repr-event (ptk/in-flight-events st/state)))))) + (let [events (ptk/in-flight-events st/state) + cause (ex-info "update loop throttled" + {:type :internal + :code :update-loop-throttled + :rounds rounds})] + (.warn js/console "[update-scheduler] update loop throttled; in-flight events:" + (into-array (map ptk/repr-event events))) + (when (seq events) + (.set in-flight-by-cause cause (in-flight-lines events))) + ;; Report outside the loop that tripped the scheduler, as an + ;; unhandled exception: a throttled loop is an application defect, + ;; so it must reach the error reports and alerts, not only audit. + (ts/schedule + #(submit-report :event-name "unhandled-exception" + :hint (ex-message cause) + :report (fn [] (generate-report cause)) + :cause cause))))) (catch :default _ nil))) diff --git a/frontend/src/app/main/refs.cljs b/frontend/src/app/main/refs.cljs index 84f6bd72f2..bb7fc0392a 100644 --- a/frontend/src/app/main/refs.cljs +++ b/frontend/src/app/main/refs.cljs @@ -609,6 +609,8 @@ (defn workspace-thumbnail-by-id [object-id] + ;; Resolving a media id builds a new map on each read; compare by + ;; value so subscribers do not re-render on every store change. (l/derived (fn [state] (when-let [entry (dm/get-in state [:thumbnails object-id])] @@ -616,7 +618,8 @@ (and (:uri entry) (not (resolved-uri? (:uri entry)))) (update :uri cf/resolve-media)))) - st/state)) + st/state + =)) (def workspace-text-modifier (l/derived :workspace-text-modifier st/state)) diff --git a/frontend/test/frontend_tests/main/refs_test.cljs b/frontend/test/frontend_tests/main/refs_test.cljs index 99c9f57657..581ff949d2 100644 --- a/frontend/test/frontend_tests/main/refs_test.cljs +++ b/frontend/test/frontend_tests/main/refs_test.cljs @@ -8,6 +8,7 @@ (:require [app.common.uuid :as uuid] [app.main.refs :as refs] + [app.main.store :as st] [cljs.test :as t :include-macros true])) (def ^:private resolved-uri? @#'refs/resolved-uri?) @@ -28,3 +29,23 @@ (t/is (false? (resolved-uri? (uuid/next)))) (t/is (false? (resolved-uri? nil))) (t/is (false? (resolved-uri? 42)))) + +(t/deftest thumbnail-ref-ignores-unrelated-state-changes + ;; A thumbnail loaded from the server keeps a media id as :uri, and + ;; the ref resolves it to a new map on each read. Subscribers (root + ;; frames, assets) must not re-render on every unrelated store change. + (let [object-id (str (uuid/next)) + ref (refs/workspace-thumbnail-by-id object-id) + calls (atom 0)] + (swap! st/state assoc-in [:thumbnails object-id] {:uri (uuid/next) :rendered-at nil}) + (add-watch ref ::probe (fn [_ _ _ _] (swap! calls inc))) + (try + (swap! st/state assoc ::probe (uuid/next)) + (t/is (zero? @calls) "unrelated change does not notify") + (swap! st/state assoc-in [:thumbnails object-id :uri] (uuid/next)) + (t/is (= 1 @calls) "a new thumbnail uri notifies") + (finally + (remove-watch ref ::probe) + (swap! st/state #(-> % + (dissoc ::probe) + (update :thumbnails dissoc object-id))))))) diff --git a/frontend/test/frontend_tests/main_errors_test.cljs b/frontend/test/frontend_tests/main_errors_test.cljs index 5954eab457..32898be282 100644 --- a/frontend/test/frontend_tests/main_errors_test.cljs +++ b/frontend/test/frontend_tests/main_errors_test.cljs @@ -14,7 +14,8 @@ - events in flight – the full report lists the events the store was processing when it caught the exception; a failing stream pipeline lists the emitters of the value, not its own event - - on-update-loop – never throws into the scheduler's caller + - on-update-loop – never throws into the scheduler's caller; + reports the throttled loop as unhandled, with the events in flight - flash schedules async report and toast – neither the report nor ntf/show is emitted synchronously - organization SSO recovery – expired SSO sessions go back to the provider @@ -554,6 +555,30 @@ {ptk/in-flight-events (fn [_] (throw (js/Error. "in-flight read failure")))} (t/is (nil? (errors/on-update-loop {:rounds 26})))))) +(t/deftest ^:async update-loop-is-reported-with-the-events-in-flight + (errors/reset-report-governor!) + (vreset! @#'errors/update-loop-warned-at 0) + (let [events (atom []) + loop-ev (ptk/reify ::test-update-loop-source)] + (await + (mock/with-mocks* + {st/emit! (mock/stub (fn [& emitted] (swap! events into emitted))) + ptk/in-flight-events (fn [_] [loop-ev]) + st/format-last-events (mock/stub (fn [& _] "(stub last events)")) + rt/get-current-href (constantly "https://penpot.example.com/#/workspace") + tm/schedule (mock/stub (fn [f] (f)))} + (errors/on-update-loop {:rounds 26}) + ;; A second trip within the window is not reported again + (errors/on-update-loop {:rounds 26}) + (t/is (= 1 (count @events))) + (let [props (deref (first @events))] + ;; An unhandled report: it reaches the error reports and alerts, + ;; not only the audit log. + (t/is (= "unhandled-exception" (::ev/name props))) + (t/is (= "update loop throttled" (:hint props))) + (t/is (str/includes? (in-flight-section (:report props)) + "test-update-loop-source"))))))) + ;; --------------------------------------------------------------------------- ;; Expired organization SSO session ;; From 705ea42622cdd14b287e3dc07327e8263771c279 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Thu, 29 Oct 2026 09:04:05 +0100 Subject: [PATCH 04/14] :bug: Keep the default cursor in the token dropdown of numeric inputs (#12680) A numeric input that can be scrubbed sets the ew-resize cursor on its wrapper, and the token dropdown renders inside that wrapper, so the whole list inherited the scrub cursor. Give the options dropdown the default cursor, so it never takes the cursor of the control that opens it. AI-assisted-by: claude-opus-5-5 --- .../playwright/ui/specs/tokens/apply.spec.js | 30 +++++++++++++++++++ .../ds/controls/shared/options_dropdown.scss | 4 +++ 2 files changed, 34 insertions(+) diff --git a/frontend/playwright/ui/specs/tokens/apply.spec.js b/frontend/playwright/ui/specs/tokens/apply.spec.js index a0e91b7c60..e13a377ae7 100644 --- a/frontend/playwright/ui/specs/tokens/apply.spec.js +++ b/frontend/playwright/ui/specs/tokens/apply.spec.js @@ -259,6 +259,36 @@ test.describe("Tokens: Apply token", () => { await expect(opacityLowPill).toBeVisible(); }); + test("Token dropdown of a scrubbable numeric input shows the default cursor", async ({ + page, + }) => { + const { workspacePage } = await setupTokensFileRender(page); + + await page.getByRole("tab", { name: "Layers" }).click(); + await workspacePage.layers.getByTestId("layer-row").nth(1).click(); + + const layerMenuSection = page.getByRole("region", { + name: "Layer menu section", + }); + const opacityWrapper = layerMenuSection + .getByTestId("numeric-input-wrapper") + .first(); + await expect(opacityWrapper).toHaveCSS("cursor", "ew-resize"); + + await layerMenuSection + .getByRole("button", { name: "Open token list" }) + .click(); + + // The scrub cursor belongs to the input, not to the dropdown it opens. + const tokenList = layerMenuSection.getByRole("listbox"); + await expect(tokenList).toBeVisible(); + await expect(tokenList).toHaveCSS("cursor", "default"); + await expect(tokenList.getByRole("option").first()).toHaveCSS( + "cursor", + "default", + ); + }); + test("User applies typography token to a text shape", async ({ page }) => { const { workspacePage, tokensSidebar, tokenContextMenuForToken } = await setupTypographyTokensFileRender(page); diff --git a/frontend/src/app/main/ui/ds/controls/shared/options_dropdown.scss b/frontend/src/app/main/ui/ds/controls/shared/options_dropdown.scss index c961b9e06c..6480e6cd79 100644 --- a/frontend/src/app/main/ui/ds/controls/shared/options_dropdown.scss +++ b/frontend/src/app/main/ui/ds/controls/shared/options_dropdown.scss @@ -29,6 +29,10 @@ z-index: var(--z-index-dropdown); box-shadow: 0 0 $sz-12 0 var(--color-shadow-dark); + // Do not inherit the cursor of the control that opens it (e.g. the + // scrub cursor of the numeric input). + cursor: default; + &:focus { outline: none; } From a6c225d5102b11cfe65557ecab72633708240951 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Thu, 29 Oct 2026 09:28:53 +0100 Subject: [PATCH 05/14] :bug: Move the CSS @charset to the start of the bundled stylesheet (#12678) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sass adds @charset "UTF-8" to every module with non-ASCII characters, and concatSass joined the modules as they came, so main.css carried it in the middle of the file. Browsers only honor @charset as the first rule, and the server sends text/css with no charset. When the browser did not take the page encoding for the stylesheet, it read main.css as Latin-1 and CSS content such as the bullet of the library element counts showed as "•". Drop every @charset while joining the modules and put one at the start. Closes #12677 AI-assisted-by: claude-opus-5-5 --- frontend/scripts/_helpers.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/frontend/scripts/_helpers.js b/frontend/scripts/_helpers.js index 60c59e8f6d..9a6bf14ec8 100644 --- a/frontend/scripts/_helpers.js +++ b/frontend/scripts/_helpers.js @@ -165,9 +165,22 @@ export async function compileSassAll(worker) { export function concatSass(data) { const output = []; + const charset = '@charset "UTF-8";'; + let hasCharset = false; + // Sass adds @charset to each file with non-ASCII characters. Browsers + // only honor it as the first rule of the stylesheet, so move it there. for (let path of data.items) { - output.push(data.index[path]); + let css = data.index[path]; + if (css.includes(charset)) { + hasCharset = true; + css = css.replaceAll(charset + "\n", "").replaceAll(charset, ""); + } + output.push(css); + } + + if (hasCharset) { + output.unshift(charset); } return output.join("\n"); From 9dc222c6427007be66e7ce24ec30ab6e470a7675 Mon Sep 17 00:00:00 2001 From: Pablo Alba Date: Thu, 29 Oct 2026 10:13:33 +0100 Subject: [PATCH 06/14] :bug: Fix bad characters allowed on variants properties (#12688) --- .../app/common/logic/variant_properties.cljc | 123 ++++++------ common/src/app/common/types/variant.cljc | 31 ++- .../common_tests/logic/variants_test.cljc | 176 +++++++++++++++++- common/test/common_tests/variant_test.cljc | 42 +++++ .../sidebar/options/menus/component.cljs | 10 +- frontend/src/app/plugins/library.cljs | 14 +- .../frontend_tests/plugins/library_test.cljs | 42 +++++ 7 files changed, 368 insertions(+), 70 deletions(-) diff --git a/common/src/app/common/logic/variant_properties.cljc b/common/src/app/common/logic/variant_properties.cljc index fe87fa3e5e..81dc28399d 100644 --- a/common/src/app/common/logic/variant_properties.cljc +++ b/common/src/app/common/logic/variant_properties.cljc @@ -16,22 +16,24 @@ (defn generate-update-property-name [changes variant-id pos new-name] - (let [data (pcb/get-library-data changes) - objects (pcb/get-objects changes) - related-components (cfv/find-variant-components data objects variant-id) + (if-let [new-name (ctv/prepare-property-name new-name)] + (let [data (pcb/get-library-data changes) + objects (pcb/get-objects changes) + related-components (cfv/find-variant-components data objects variant-id) - props (-> related-components last :variant-properties) - prop-names (mapv :name props) - prop-names (concat (subvec prop-names 0 pos) (subvec prop-names (inc pos))) - new-name (ctv/update-number-in-repeated-item prop-names new-name)] - (reduce (fn [changes component] - (pcb/update-component - changes (:id component) - (fn [component] - (d/update-in-when component [:variant-properties pos] #(assoc % :name new-name))) - {:apply-changes-local-library? true})) - changes - related-components))) + props (-> related-components last :variant-properties) + prop-names (mapv :name props) + prop-names (concat (subvec prop-names 0 pos) (subvec prop-names (inc pos))) + new-name (ctv/update-number-in-repeated-item prop-names new-name)] + (reduce (fn [changes component] + (pcb/update-component + changes (:id component) + (fn [component] + (d/update-in-when component [:variant-properties pos] #(assoc % :name new-name))) + {:apply-changes-local-library? true})) + changes + related-components)) + changes)) (defn generate-remove-property @@ -57,16 +59,18 @@ (defn generate-update-property-value [changes component-id pos value] - (let [data (pcb/get-library-data changes) - component (ctcl/get-component data component-id true) - main-id (:main-instance-id component) - name (-> (:variant-properties component) - (update pos assoc :value value) - ctv/properties-to-name)] - (-> changes - (pcb/update-component component-id #(assoc-in % [:variant-properties pos :value] value) - {:apply-changes-local-library? true}) - (pcb/update-shapes [main-id] #(assoc % :variant-name name))))) + (if-let [value (ctv/prepare-property-value value)] + (let [data (pcb/get-library-data changes) + component (ctcl/get-component data component-id true) + main-id (:main-instance-id component) + name (-> (:variant-properties component) + (update pos assoc :value value) + ctv/properties-to-name)] + (-> changes + (pcb/update-component component-id #(assoc-in % [:variant-properties pos :value] value) + {:apply-changes-local-library? true}) + (pcb/update-shapes [main-id] #(assoc % :variant-name name)))) + changes)) (defn generate-set-variant-error @@ -108,40 +112,45 @@ props (-> related-components last :variant-properties) next-prop-num (ctv/next-property-number props) - property-name (or property-name (str ctv/property-prefix next-prop-num)) + property-name (if (some? property-name) + (ctv/prepare-property-name property-name) + (str ctv/property-prefix next-prop-num))] + (if (nil? property-name) + changes + (let [prop-names (mapv :name props) + property-name (ctv/update-number-in-repeated-item prop-names property-name) + property-value (not-empty + (when property-value + (ctv/prepare-property-value property-value))) + mdata (if editing? {:editing? true} nil) - prop-names (mapv :name props) - property-name (ctv/update-number-in-repeated-item prop-names property-name) + [_ changes] + (reduce (fn [[num changes] component] + (let [main-id (:main-instance-id component) - mdata (if editing? {:editing? true} nil) + update-props #(-> (d/nilv % []) + (conj (with-meta {:name property-name + :value (cond fill-values? (str ctv/value-prefix num) + property-value property-value + :else "")} + mdata))) - [_ changes] - (reduce (fn [[num changes] component] - (let [main-id (:main-instance-id component) - - update-props #(-> (d/nilv % []) - (conj (with-meta {:name property-name - :value (cond fill-values? (str ctv/value-prefix num) - property-value property-value - :else "")} - mdata))) - - update-name #(cond fill-values? (if (str/empty? %) - (str ctv/value-prefix num) - (str % ", " ctv/value-prefix num)) - property-value (if (str/empty? %) - property-value - (str % ", " property-value)) - :else %)] - [(inc num) - (-> changes - (pcb/update-component (:id component) - #(update % :variant-properties update-props) - {:apply-changes-local-library? true}) - (pcb/update-shapes [main-id] #(update % :variant-name update-name)))])) - [1 changes] - related-components)] - changes)) + update-name #(cond fill-values? (if (str/empty? %) + (str ctv/value-prefix num) + (str % ", " ctv/value-prefix num)) + property-value (if (str/empty? %) + property-value + (str % ", " property-value)) + :else %)] + [(inc num) + (-> changes + (pcb/update-component (:id component) + #(update % :variant-properties update-props) + {:apply-changes-local-library? true}) + (pcb/update-shapes [main-id] #(update % :variant-name update-name)))])) + [1 changes] + related-components)] + changes)))) (defn- generate-make-shape-no-variant [changes shape] @@ -175,7 +184,7 @@ props (ctv/add-new-props props (repeat new-props ""))] (if add-name? - (ctv/add-new-prop props (:name component)) + (ctv/add-new-prop props (or (ctv/sanitize-property-text (:name component)) "")) props))) (defn- create-new-properties-from-non-variant diff --git a/common/src/app/common/types/variant.cljc b/common/src/app/common/types/variant.cljc index 660fec5304..f91075a170 100644 --- a/common/src/app/common/types/variant.cljc +++ b/common/src/app/common/types/variant.cljc @@ -55,19 +55,47 @@ [value] (some-> value str/trim)) +(def ^:private forbidden-property-chars-re #"[,=]") + +(defn sanitize-property-text + "Remove `,` and `=` from property name/value text, then trim. + Non-strings (including nil) return nil — never call str/replace on them." + [value] + (when (string? value) + (-> value + (str/replace forbidden-property-chars-re "") + normalize-property-text))) + (defn valid-property-name? [value] (let [value (normalize-property-text value)] (and (string? value) (not (str/blank? value)) + (nil? (re-find forbidden-property-chars-re value)) (<= (count value) property-max-length)))) (defn valid-property-value? [value] (let [value (normalize-property-text value)] (and (string? value) + (nil? (re-find forbidden-property-chars-re value)) (<= (count value) property-max-length)))) +(defn prepare-property-name + "Sanitize then validate a property name. Returns the cleaned string or nil." + [value] + (let [value (sanitize-property-text value)] + (when (valid-property-name? value) + value))) + +(defn prepare-property-value + "Sanitize then validate a property value. nil becomes \"\". + Other non-strings yield nil. Empty string remains valid." + [value] + (let [value (sanitize-property-text (if (nil? value) "" value))] + (when (valid-property-value? value) + value))) + (defn can-remove-property? [properties] (> (count properties) 1)) @@ -112,7 +140,8 @@ ([path properties] (path-to-properties path properties 0)) ([path properties min-props] - (let [cpath (cpn/split-path path) + (let [cpath (->> (cpn/split-path path) + (mapv #(or (sanitize-property-text %) ""))) total-props (max (count cpath) min-props) assigned (mapv #(assoc % :value (nth cpath %2 "")) properties (range)) ;; Add empty strings to the end of cpath to reach the minimum number of properties diff --git a/common/test/common_tests/logic/variants_test.cljc b/common/test/common_tests/logic/variants_test.cljc index c4cfc1b95a..d4a4696336 100644 --- a/common/test/common_tests/logic/variants_test.cljc +++ b/common/test/common_tests/logic/variants_test.cljc @@ -16,7 +16,9 @@ [app.common.test-helpers.ids-map :as thi] [app.common.test-helpers.shapes :as ths] [app.common.test-helpers.variants :as thv] - [clojure.test :as t])) + [app.common.types.variant :as ctv] + [clojure.test :as t] + [cuerdas.core :as str])) (t/use-fixtures :each thi/test-fixture) @@ -234,6 +236,178 @@ (t/is (= (-> comp01' :variant-properties first :value) "NewValue1")) (t/is (= (-> comp02' :variant-properties first :value) "NewValue2")))) +(t/deftest test-update-property-value-sanitizes + (let [file (-> (thf/sample-file :file1) + (thv/add-variant :v01 :c01 :m01 :c02 :m02)) + page (thf/current-page file) + comp01 (thc/get-component file :c01) + before (-> comp01 :variant-properties first :value) + + changes (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-update-property-value (:id comp01) 0 "a=b,")) + + file' (thf/apply-changes file changes) + comp01' (thc/get-component file' :c01) + main' (ths/get-shape file' :m01) + + noop (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-update-property-value (:id comp01) 0 42)) + file-noop (thf/apply-changes file noop) + comp-noop (thc/get-component file-noop :c01) + + cleared (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-update-property-value (:id comp01) 0 "=,=")) + file-cleared (thf/apply-changes file cleared) + comp-cleared (thc/get-component file-cleared :c01) + main-cleared (ths/get-shape file-cleared :m01) + + nilled (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-update-property-value (:id comp01) 0 nil)) + file-nilled (thf/apply-changes file nilled) + comp-nilled (thc/get-component file-nilled :c01)] + + (t/is (= "ab" (-> comp01' :variant-properties first :value))) + (t/is (= "ab" (:variant-name main'))) + (t/is (= before (-> comp-noop :variant-properties first :value))) + (t/is (= "" (-> comp-cleared :variant-properties first :value))) + (t/is (not (str/includes? (str (:variant-name main-cleared)) "="))) + (t/is (= "" (-> comp-nilled :variant-properties first :value))))) + +(t/deftest test-update-property-name-sanitizes-and-noops + (let [file (-> (thf/sample-file :file1) + (thv/add-variant-two-properties :v01 :c01 :m01 :c02 :m02)) + v-id (-> (ths/get-shape file :v01) :id) + page (thf/current-page file) + before (-> (thc/get-component file :c01) :variant-properties first :name) + + changes (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-update-property-name v-id 0 "Size=Big")) + + file' (thf/apply-changes file changes) + + noop (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-update-property-name v-id 0 "=,=")) + file-noop (thf/apply-changes file noop)] + + (t/is (= "SizeBig" (-> (thc/get-component file' :c01) :variant-properties first :name))) + (t/is (= before (-> (thc/get-component file-noop :c01) :variant-properties first :name))))) + +(t/deftest test-add-new-property-sanitizes + (let [file (-> (thf/sample-file :file1) + (thv/add-variant :v01 :c01 :m01 :c02 :m02)) + v-id (-> (ths/get-shape file :v01) :id) + page (thf/current-page file) + before-count (-> (thc/get-component file :c01) :variant-properties count) + + changes (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-add-new-property v-id {:property-name "Size=Big" + :property-value "a=b,"})) + + file' (thf/apply-changes file changes) + comp01' (thc/get-component file' :c01) + + noop (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-add-new-property v-id {:property-name "=,="})) + file-noop (thf/apply-changes file noop)] + + (t/is (= "SizeBig" (-> comp01' :variant-properties last :name))) + (t/is (= "ab" (-> comp01' :variant-properties last :value))) + (t/is (= before-count + (-> (thc/get-component file-noop :c01) :variant-properties count))))) + +(t/deftest test-add-new-property-blank-value-does-not-trail-separator + (let [file (-> (thf/sample-file :file1) + (thv/add-variant :v01 :c01 :m01 :c02 :m02)) + v-id (-> (ths/get-shape file :v01) :id) + page (thf/current-page file) + main (ths/get-shape file :m01) + before (:variant-name main) + changes (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-add-new-property v-id {:property-name "Size" + :property-value "=,="})) + file' (thf/apply-changes file changes) + comp01' (thc/get-component file' :c01) + main' (ths/get-shape file' :m01)] + + (t/is (= before (:variant-name main'))) + (t/is (not (str/ends-with? (str (:variant-name main')) ", "))) + (t/is (= "" (-> comp01' :variant-properties last :value))) + (t/is (= "Size" (-> comp01' :variant-properties last :name))))) + +(t/deftest test-update-property-value-from-formula-strips-equal-in-value + ;; Option A / M2: formula parse may leave `=` inside a value; write path strips it. + (let [file (-> (thf/sample-file :file1) + (thv/add-variant :v01 :c01 :m01 :c02 :m02)) + page (thf/current-page file) + comp01 (thc/get-component file :c01) + parsed (ctv/properties-formula->map "border=yes color=yes") + value (-> parsed first :value) + changes (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-update-property-value (:id comp01) 0 value)) + file' (thf/apply-changes file changes) + comp01' (thc/get-component file' :c01) + main' (ths/get-shape file' :m01)] + + (t/is (= "yes color=yes" value)) + (t/is (= "yes coloryes" (-> comp01' :variant-properties first :value))) + (t/is (= "yes coloryes" (:variant-name main'))) + (t/is (not= "yes color=yes" (-> comp01' :variant-properties first :value))))) + +(t/deftest test-make-shapes-variant-sanitizes-component-name-as-value + ;; create-new-properties-from-variant adds (:name component) as a value when + ;; moving a variant into a differently named container. Production always + ;; pairs generate-make-shapes-variant with change-parent. + (let [file (-> (thf/sample-file :file1) + (thv/add-variant :v01 :c01 :m01 :c02 :m02) + (thv/add-variant :v02 :c03 :m03 :c04 :m04) + (thc/update-component :c03 {:name "Big=red"})) + page (thf/current-page file) + container (ths/get-shape file :v01) + shape (ths/get-shape file :m03) + changes (-> (pcb/empty-changes nil) + (pcb/with-page-id (:id page)) + (pcb/with-library-data (:data file)) + (pcb/with-objects (:objects page)) + (clvp/generate-make-shapes-variant [shape] container) + (pcb/change-parent (:id container) [shape] 0)) + file' (thf/apply-changes file changes) + values (->> (thc/get-component file' :c03) + :variant-properties + (map :value) + set)] + + (t/is (contains? values "Bigred")))) + (t/deftest test-duplicate-variant-container (let [;; ==== Setup diff --git a/common/test/common_tests/variant_test.cljc b/common/test/common_tests/variant_test.cljc index d0a7099dc7..0dea2aa947 100644 --- a/common/test/common_tests/variant_test.cljc +++ b/common/test/common_tests/variant_test.cljc @@ -171,3 +171,45 @@ (t/is (= (ctv/find-boolean-pair ["false" "true"]) {"true" true "false" false})) (t/is (= (ctv/find-boolean-pair ["off" "on" "other"]) nil)) (t/is (= (ctv/find-boolean-pair ["hello" "bye"]) nil)))) + + +(t/deftest sanitize-and-prepare-property-text + (t/testing "sanitize-property-text" + (t/is (= (ctv/sanitize-property-text "a=b") "ab")) + (t/is (= (ctv/sanitize-property-text "a,b") "ab")) + (t/is (= (ctv/sanitize-property-text " Big, red ") "Big red")) + (t/is (= (ctv/sanitize-property-text " a=b, ") "ab")) + (t/is (= (ctv/sanitize-property-text ",=") "")) + (t/is (nil? (ctv/sanitize-property-text nil))) + (t/is (nil? (ctv/sanitize-property-text 42)))) + + (t/testing "valid-property-name? rejects forbidden chars" + (t/is (true? (ctv/valid-property-name? "ok"))) + (t/is (false? (ctv/valid-property-name? "a=b"))) + (t/is (false? (ctv/valid-property-name? "a,b"))) + (t/is (false? (ctv/valid-property-name? "")))) + + (t/testing "valid-property-value? rejects forbidden chars" + (t/is (true? (ctv/valid-property-value? "ok"))) + (t/is (true? (ctv/valid-property-value? ""))) + (t/is (false? (ctv/valid-property-value? "a=b"))) + (t/is (false? (ctv/valid-property-value? "a,b")))) + + (t/testing "prepare-property-name" + (t/is (= (ctv/prepare-property-name "Size=Big") "SizeBig")) + (t/is (nil? (ctv/prepare-property-name "=,="))) + (t/is (= (ctv/prepare-property-name " ok ") "ok")) + (t/is (nil? (ctv/prepare-property-name 42)))) + + (t/testing "prepare-property-value" + (t/is (= (ctv/prepare-property-value "a=b,") "ab")) + (t/is (= (ctv/prepare-property-value "=,=") "")) + (t/is (= (ctv/prepare-property-value nil) "")) + (t/is (nil? (ctv/prepare-property-value 42))))) + + +(t/deftest path-to-properties-sanitizes-values + (let [props [{:name "Property 1" :value ""}] + result (ctv/path-to-properties "Button / Big, red" props)] + (t/is (= "Button" (-> result first :value))) + (t/is (= "Big red" (-> result second :value))))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs index 8d46f46a3f..6600b370ab 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/component.cljs @@ -389,7 +389,7 @@ (mf/use-fn (mf/deps component-ids) (fn [pos value] - (let [value (ctv/normalize-property-text (d/nilv value ""))] + (when-let [value (ctv/prepare-property-value value)] (doseq [id component-ids] (st/emit! (ev/event {::ev/name "variant-edit-property-value" ::ev/origin "workspace:combo-design-tab"}) @@ -400,11 +400,11 @@ (mf/use-fn (mf/deps variant-id) (fn [event] - (let [value (ctv/normalize-property-text (dom/get-target-val event)) + (let [value (ctv/prepare-property-name (dom/get-target-val event)) pos (-> (dom/get-current-target event) (dom/get-data "position") int)] - (when (ctv/valid-property-name? value) + (when value (st/emit! (dwv/update-property-name variant-id pos value {:trigger "workspace:design-tab-variant"})))))) @@ -1230,11 +1230,11 @@ (mf/use-fn (mf/deps variant-id) (fn [event] - (let [value (ctv/normalize-property-text (dom/get-target-val event)) + (let [value (ctv/prepare-property-name (dom/get-target-val event)) pos (-> (dom/get-current-target event) (dom/get-data "position") int)] - (when (ctv/valid-property-name? value) + (when value (st/emit! (dwv/update-property-name variant-id pos value {:trigger "workspace:design-tab-component"})))))) diff --git a/frontend/src/app/plugins/library.cljs b/frontend/src/app/plugins/library.cljs index aff38a654d..c22edd3910 100644 --- a/frontend/src/app/plugins/library.cljs +++ b/frontend/src/app/plugins/library.cljs @@ -779,12 +779,13 @@ :renameProperty (fn [pos name] - (let [nprops (->> (get-variant-components file-id id) first :variant-properties count)] + (let [nprops (->> (get-variant-components file-id id) first :variant-properties count) + prepared (ctv/prepare-property-name name)] (cond (or (not (nat-int? pos)) (>= pos nprops)) (u/not-valid plugin-id :pos pos) - (not (ctv/valid-property-name? name)) + (nil? prepared) (u/not-valid plugin-id :name name) (not (r/check-permission plugin-id "library:write")) @@ -792,7 +793,7 @@ :else (st/emit! - (dwv/update-property-name id pos (ctv/normalize-property-text name) + (dwv/update-property-name id pos prepared {:trigger "plugin:rename-property"}))))))) (set! shape/variant-proxy variant-proxy) @@ -1090,12 +1091,13 @@ :setVariantProperty (fn [pos value] - (let [nprops (-> (u/locate-library-component file-id id) :variant-properties count)] + (let [nprops (-> (u/locate-library-component file-id id) :variant-properties count) + prepared (ctv/prepare-property-value value)] (cond (or (not (nat-int? pos)) (>= pos nprops)) (u/not-valid plugin-id :pos (str pos)) - (not (ctv/valid-property-value? value)) + (nil? prepared) (u/not-valid plugin-id :value value) (not (r/check-permission plugin-id "library:write")) @@ -1104,7 +1106,7 @@ :else (st/emit! (se/event plugin-id "variant-edit-property-value") - (dwv/update-property-value id pos (ctv/normalize-property-text value)))))))) + (dwv/update-property-value id pos prepared))))))) (defn library-proxy? [p] (obj/type-of? p "LibraryProxy")) diff --git a/frontend/test/frontend_tests/plugins/library_test.cljs b/frontend/test/frontend_tests/plugins/library_test.cljs index 839c25e7a7..4ee8ec0357 100644 --- a/frontend/test/frontend_tests/plugins/library_test.cljs +++ b/frontend/test/frontend_tests/plugins/library_test.cljs @@ -388,6 +388,48 @@ (t/is (= [plugin-id :setVariantProperty "Plugin doesn't have 'library:write' permission"] (first @errors))))))) +(t/deftest variant-rename-property-sanitizes-name + (let [plugin-id "test-plugin" + file-id (uuid/next) + id (uuid/next) + renamed (atom nil) + errors (atom [])] + (with-redefs [r/check-permission (constantly true) + u/not-valid (mock/stub (fn [pid prop msg] (swap! errors conj [pid prop msg]))) + library/get-variant-components (constantly [{:variant-properties [{:name "color" :value "red"}]}]) + dwv/update-property-name (fn [vid pos name opts] + (reset! renamed {:id vid :pos pos :name name :opts opts}) + ::rename-event) + st/emit! mock/noop] + (let [proxy (library/variant-proxy plugin-id file-id id)] + (.renameProperty proxy 0 "a=b") + (t/is (empty? @errors)) + (t/is (= "ab" (:name @renamed))) + (.renameProperty proxy 0 "=,=") + (t/is (= 1 (count @errors))) + (t/is (= :name (second (first @errors)))))))) + +(t/deftest component-set-variant-property-sanitizes-value + (let [plugin-id "test-plugin" + file-id (uuid/next) + id (uuid/next) + updated (atom nil) + errors (atom [])] + (with-redefs [r/check-permission (constantly true) + u/not-valid (mock/stub (fn [pid prop msg] (swap! errors conj [pid prop msg]))) + u/locate-library-component (constantly {:id id :variant-properties [{:name "color"}]}) + dwv/update-property-value (fn [cid pos value] + (reset! updated {:id cid :pos pos :value value}) + ::value-event) + st/emit! mock/noop] + (let [proxy (library/lib-component-proxy plugin-id file-id id)] + (.setVariantProperty proxy 0 "a=b") + (t/is (empty? @errors)) + (t/is (= "ab" (:value @updated))) + (.setVariantProperty proxy 0 "=,=") + (t/is (empty? @errors)) + (t/is (= "" (:value @updated))))))) + ;; --------------------------------------------------------------------------- ;; connectLibrary ;; --------------------------------------------------------------------------- From 755bb175cdb47adac78633437a112af367cb8d98 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Thu, 29 Oct 2026 13:23:36 +0100 Subject: [PATCH 07/14] :bug: Remove wrong flag (#12698) --- common/src/app/common/flags.cljc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/common/src/app/common/flags.cljc b/common/src/app/common/flags.cljc index a3f3cf44be..164d8c78a9 100644 --- a/common/src/app/common/flags.cljc +++ b/common/src/app/common/flags.cljc @@ -235,8 +235,7 @@ :enable-stroke-per-side :enable-token-combobox :enable-custom-shortcuts - :enable-token-lib-sync - :enable-link-unfurl]) + :enable-token-lib-sync]) (defn parse [& flags] From 76d403cfdbc8c30b988bec2900b85187a22464ad Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 29 Oct 2026 13:34:32 +0100 Subject: [PATCH 08/14] :arrow_up: Update npm dependencies on mcp and exporter --- exporter/package.json | 8 +- exporter/pnpm-lock.yaml | 201 ++++---- mcp/package.json | 4 +- mcp/packages/plugin/package.json | 2 +- mcp/packages/server/package.json | 22 +- mcp/pnpm-lock.yaml | 787 ++++++++++++++++--------------- 6 files changed, 509 insertions(+), 515 deletions(-) diff --git a/exporter/package.json b/exporter/package.json index d04dafe2a5..db033dbf2f 100644 --- a/exporter/package.json +++ b/exporter/package.json @@ -13,7 +13,7 @@ "dependencies": { "@penpot/svgo": "penpot/svgo#3.3.0", "archiver": "8.0.0", - "cookies": "^0.9.1", + "cookies": "^0.9.2", "date-fns": "^4.4.0", "generic-pool": "^3.9.0", "inflation": "^2.1.0", @@ -21,12 +21,12 @@ "playwright": "1.62.1", "raw-body": "^4.0.0", "source-map-support": "^0.5.21", - "undici": "^8.10.0", + "undici": "^8.12.3", "xml-js": "^1.6.11", - "xregexp": "^5.1.2" + "xregexp": "^5.1.3" }, "devDependencies": { - "ws": "^8.21.3" + "ws": "^8.22.0" }, "scripts": { "clear:shadow-cache": "rm -rf .shadow-cljs && rm -rf target", diff --git a/exporter/pnpm-lock.yaml b/exporter/pnpm-lock.yaml index e30ff1e950..ec66e081a4 100644 --- a/exporter/pnpm-lock.yaml +++ b/exporter/pnpm-lock.yaml @@ -179,8 +179,8 @@ importers: specifier: 8.0.0 version: 8.0.0 cookies: - specifier: ^0.9.1 - version: 0.9.1 + specifier: ^0.9.2 + version: 0.9.2 date-fns: specifier: ^4.4.0 version: 4.4.0 @@ -203,23 +203,23 @@ importers: specifier: ^0.5.21 version: 0.5.21 undici: - specifier: ^8.10.0 - version: 8.10.0 + specifier: ^8.12.3 + version: 8.12.3 xml-js: specifier: ^1.6.11 version: 1.6.11 xregexp: - specifier: ^5.1.2 - version: 5.1.2 + specifier: ^5.1.3 + version: 5.1.3 devDependencies: ws: - specifier: ^8.21.3 - version: 8.21.3 + specifier: ^8.22.0 + version: 8.22.0 packages: - '@babel/runtime-corejs3@7.29.7': - resolution: {integrity: sha512-ppj9ouYku+RX0ljtgZd+KMO5mkM2bCqg8H2PYAFWnLsHEIKIdRojqbJ2i3eVHrisuxy7nOFCmngTDdWtUCdXUQ==} + '@babel/runtime-corejs3@7.29.10': + resolution: {integrity: sha512-R4FKrg4Vy0hB7PfAxf9LOorEPd5/36SCIXPXAvjlQaQmPvtrjwoDXV15jsSm2ecsqBW1Iewwb7mEnG83xIEApg==} engines: {node: '>=6.9.0'} '@ioredis/commands@2.0.0': @@ -240,8 +240,8 @@ packages: async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - b4a@1.8.1: - resolution: {integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==} + b4a@1.9.0: + resolution: {integrity: sha512-dpfcF9fDNR6++cthXR67iyhgqWy9CBouAvIWhIntzBG6cvK/cnIPiZQjBwi/ZqjjBEDGfoNDtmB0kTjroOJ3pQ==} peerDependencies: react-native-b4a: '*' peerDependenciesMeta: @@ -252,32 +252,28 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - bare-events@2.9.1: - resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==} + bare-events@2.9.2: + resolution: {integrity: sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA==} peerDependencies: bare-abort-controller: '*' peerDependenciesMeta: bare-abort-controller: optional: true - bare-fs@4.7.2: - resolution: {integrity: sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==} - engines: {bare: '>=1.16.0'} + bare-fs@4.8.4: + resolution: {integrity: sha512-MPC2eyrpbk3A873sK4y6rk+Iv4o2enxTjHZ8zH3HO0mjrpm5XjnguY2XmfidIsDV6vnjpbMBKUAJpV0ISD2SsQ==} + engines: {bare: '>=1.28.0'} peerDependencies: bare-buffer: '*' peerDependenciesMeta: bare-buffer: optional: true - bare-os@3.9.1: - resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==} - engines: {bare: '>=1.14.0'} + bare-path@3.1.2: + resolution: {integrity: sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw==} - bare-path@3.0.1: - resolution: {integrity: sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==} - - bare-stream@2.13.1: - resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} + bare-stream@2.13.4: + resolution: {integrity: sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA==} peerDependencies: bare-abort-controller: '*' bare-buffer: '*' @@ -290,8 +286,8 @@ packages: bare-events: optional: true - bare-url@2.4.5: - resolution: {integrity: sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==} + bare-url@2.5.5: + resolution: {integrity: sha512-iM9qJCruvpt2rPaLsrumVDru9pogI7PHziHIa9kTNRFt8C8HuSa+kI9kFezK+NvHEFnnz71rKGZ1EAilq/3V/Q==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -300,8 +296,8 @@ packages: resolution: {integrity: sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA==} engines: {node: '>=20.19.0'} - brace-expansion@5.0.9: - resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} engines: {node: 20 || >=22} buffer-crc32@1.0.0: @@ -326,12 +322,12 @@ packages: resolution: {integrity: sha512-g0S8KAD8qf4+V//pr3BfB1aBnARLXNz2Gx+jmHU0LEriUuoQUOPOulVquHKTJ8+EAIIO7fhseNDr9wK5Q9FKBQ==} engines: {node: '>=18'} - cookies@0.9.1: - resolution: {integrity: sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==} + cookies@0.9.2: + resolution: {integrity: sha512-8BIbcC6tPZMv2/PD4PrB3CtKks7LmAWhA7FRZK/6/b/WJ2RUz00KCga7gq50S4/RhZ22kxefRFGgsuts0v3eoA==} engines: {node: '>= 0.8'} - core-js-pure@3.49.0: - resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} + core-js-pure@3.51.0: + resolution: {integrity: sha512-NE4SFDJ+qzQeqHG2vVSNwopzS6zZNPYJ5kinIqs+OofTqGzOmICgT89E/yvS9XY7rwb3eU1utWXTJ9nVFqv74A==} core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -401,8 +397,8 @@ packages: resolution: {integrity: sha512-qI4JLRKnSzqFqr7hAlS5xQDusBCjKSEG4t4+7aNrIQMHBcsC2TGEhuyABJdYkgSewL57PNLYEiibY2iPKhKpaA==} engines: {node: '>=20.19.0'} - entities@8.0.0: - resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} + entities@8.1.0: + resolution: {integrity: sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==} engines: {node: '>=20.19.0'} event-target-shim@5.0.1: @@ -470,8 +466,8 @@ packages: mdn-data@2.27.1: resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} ms@2.1.3: @@ -509,8 +505,8 @@ packages: readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + readable-stream@4.8.0: + resolution: {integrity: sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} readdir-glob@3.0.0: @@ -527,15 +523,15 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - sax@1.6.0: - resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + sax@1.6.1: + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} engines: {node: '>=11.0.0'} setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} engines: {node: '>=0.10.0'} source-map-support@0.5.21: @@ -552,8 +548,8 @@ packages: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} - streamx@2.27.0: - resolution: {integrity: sha512-WZ189TKnHoAokYHvwzaAQMpd55cgUmFIcJFzBSgGcb886jau5DL+XdDhTWV4ps3FLvk+OORp0dLRTPsLZ21CSA==} + streamx@2.28.1: + resolution: {integrity: sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==} string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -561,8 +557,8 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - tar-stream@3.2.0: - resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} + tar-stream@3.2.2: + resolution: {integrity: sha512-+8NeqHRjQWH9nYlwo2gamAMImZCVzI4UoEgDpWorBt9OEfppiZn+uSkskzQKPWIZyji/C8fpWO7u69G0DX0tbg==} teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} @@ -578,15 +574,15 @@ packages: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} - undici@8.10.0: - resolution: {integrity: sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==} + undici@8.12.3: + resolution: {integrity: sha512-+fdndUTwBP86cVjihTp21hZHo7d6oj1c/47XPA3lL8mM0XHs+C4EkcjmgRsFnFk2f/UONGDy9ItBItmXsLOQHw==} engines: {node: '>=22.19.0'} util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - ws@8.21.3: - resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + ws@8.22.0: + resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -601,8 +597,8 @@ packages: resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} hasBin: true - xregexp@5.1.2: - resolution: {integrity: sha512-6hGgEMCGhqCTFEJbqmWrNIPqfpdirdGWkqshu7fFZddmTSfgv5Sn9D2SaKloR79s5VUiUlpwzg3CM3G6D3VIlw==} + xregexp@5.1.3: + resolution: {integrity: sha512-7uOg8BVk9kt6HnkeBdyW3VEq7KXzs4un/Efge4AN1FsAMzM6fYexggbWWkQcfHExQpQEoNkWXnr4wSWpqtx49Q==} zip-stream@7.0.5: resolution: {integrity: sha512-dSvYKdvLsAHCDqPOhIwk/q5CvuWtTB3Dgpoe0uVEFjTzIOAmsQpprX25InCvrvJsirEbu1OHyy67n/kAj1Sw/w==} @@ -610,9 +606,9 @@ packages: snapshots: - '@babel/runtime-corejs3@7.29.7': + '@babel/runtime-corejs3@7.29.10': dependencies: - core-js-pure: 3.49.0 + core-js-pure: 3.51.0 '@ioredis/commands@2.0.0': {} @@ -622,7 +618,7 @@ snapshots: css-tree: 3.2.1 csso: 5.0.5 lodash: 4.18.1 - sax: 1.6.0 + sax: 1.6.1 abort-controller@3.0.0: dependencies: @@ -635,9 +631,9 @@ snapshots: is-stream: 4.0.1 lazystream: 1.0.1 normalize-path: 3.0.0 - readable-stream: 4.7.0 + readable-stream: 4.8.0 readdir-glob: 3.0.0 - tar-stream: 3.2.0 + tar-stream: 3.2.2 zip-stream: 7.0.5 transitivePeerDependencies: - bare-abort-controller @@ -646,47 +642,44 @@ snapshots: async@3.2.6: {} - b4a@1.8.1: {} + b4a@1.9.0: {} balanced-match@4.0.4: {} - bare-events@2.9.1: {} + bare-events@2.9.2: {} - bare-fs@4.7.2: + bare-fs@4.8.4: dependencies: - bare-events: 2.9.1 - bare-path: 3.0.1 - bare-stream: 2.13.1(bare-events@2.9.1) - bare-url: 2.4.5 + bare-events: 2.9.2 + bare-path: 3.1.2 + bare-stream: 2.13.4(bare-events@2.9.2) + bare-url: 2.5.5 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - bare-os@3.9.1: {} + bare-path@3.1.2: {} - bare-path@3.0.1: + bare-stream@2.13.4(bare-events@2.9.2): dependencies: - bare-os: 3.9.1 - - bare-stream@2.13.1(bare-events@2.9.1): - dependencies: - streamx: 2.27.0 + b4a: 1.9.0 + streamx: 2.28.1 teex: 1.0.1 optionalDependencies: - bare-events: 2.9.1 + bare-events: 2.9.2 transitivePeerDependencies: - react-native-b4a - bare-url@2.4.5: + bare-url@2.5.5: dependencies: - bare-path: 3.0.1 + bare-path: 3.1.2 base64-js@1.5.1: {} boolbase@2.0.0: {} - brace-expansion@5.0.9: + brace-expansion@5.0.12: dependencies: balanced-match: 4.0.4 @@ -709,14 +702,14 @@ snapshots: crc32-stream: 7.0.1 is-stream: 4.0.1 normalize-path: 3.0.0 - readable-stream: 4.7.0 + readable-stream: 4.8.0 - cookies@0.9.1: + cookies@0.9.2: dependencies: depd: 2.0.0 keygrip: 1.1.0 - core-js-pure@3.49.0: {} + core-js-pure@3.51.0: {} core-util-is@1.0.3: {} @@ -725,7 +718,7 @@ snapshots: crc32-stream@7.0.1: dependencies: crc-32: 1.2.2 - readable-stream: 4.7.0 + readable-stream: 4.8.0 css-select@7.0.0: dependencies: @@ -738,12 +731,12 @@ snapshots: css-tree@2.2.1: dependencies: mdn-data: 2.0.28 - source-map-js: 1.2.1 + source-map-js: 1.2.2 css-tree@3.2.1: dependencies: mdn-data: 2.27.1 - source-map-js: 1.2.1 + source-map-js: 1.2.2 css-what@8.0.0: {} @@ -765,7 +758,7 @@ snapshots: dependencies: domelementtype: 3.0.0 domhandler: 6.0.1 - entities: 8.0.0 + entities: 8.1.0 domelementtype@3.0.0: {} @@ -779,13 +772,13 @@ snapshots: domelementtype: 3.0.0 domhandler: 6.0.1 - entities@8.0.0: {} + entities@8.1.0: {} event-target-shim@5.0.1: {} events-universal@1.0.1: dependencies: - bare-events: 2.9.1 + bare-events: 2.9.2 transitivePeerDependencies: - bare-abort-controller @@ -841,9 +834,9 @@ snapshots: mdn-data@2.27.1: {} - minimatch@10.2.5: + minimatch@10.2.6: dependencies: - brace-expansion: 5.0.9 + brace-expansion: 5.0.12 ms@2.1.3: {} @@ -880,7 +873,7 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 - readable-stream@4.7.0: + readable-stream@4.8.0: dependencies: abort-controller: 3.0.0 buffer: 6.0.3 @@ -890,7 +883,7 @@ snapshots: readdir-glob@3.0.0: dependencies: - minimatch: 10.2.5 + minimatch: 10.2.6 redis-errors@1.2.0: {} @@ -898,11 +891,11 @@ snapshots: safe-buffer@5.2.1: {} - sax@1.6.0: {} + sax@1.6.1: {} setprototypeof@1.2.0: {} - source-map-js@1.2.1: {} + source-map-js@1.2.2: {} source-map-support@0.5.21: dependencies: @@ -915,7 +908,7 @@ snapshots: statuses@2.0.2: {} - streamx@2.27.0: + streamx@2.28.1: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -932,12 +925,12 @@ snapshots: dependencies: safe-buffer: 5.2.1 - tar-stream@3.2.0: + tar-stream@3.2.2: dependencies: - b4a: 1.8.1 - bare-fs: 4.7.2 + b4a: 1.9.0 + bare-fs: 4.8.4 fast-fifo: 1.3.2 - streamx: 2.27.0 + streamx: 2.28.1 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -945,14 +938,14 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.27.0 + streamx: 2.28.1 transitivePeerDependencies: - bare-abort-controller - react-native-b4a text-decoder@1.2.7: dependencies: - b4a: 1.8.1 + b4a: 1.9.0 transitivePeerDependencies: - react-native-b4a @@ -960,22 +953,22 @@ snapshots: tsscmp@1.0.6: {} - undici@8.10.0: {} + undici@8.12.3: {} util-deprecate@1.0.2: {} - ws@8.21.3: {} + ws@8.22.0: {} xml-js@1.6.11: dependencies: - sax: 1.6.0 + sax: 1.6.1 - xregexp@5.1.2: + xregexp@5.1.3: dependencies: - '@babel/runtime-corejs3': 7.29.7 + '@babel/runtime-corejs3': 7.29.10 zip-stream@7.0.5: dependencies: compress-commons: 7.0.1 normalize-path: 3.0.0 - readable-stream: 4.7.0 + readable-stream: 4.8.0 diff --git a/mcp/package.json b/mcp/package.json index 58eedd05f6..2b89cf1abc 100644 --- a/mcp/package.json +++ b/mcp/package.json @@ -25,7 +25,7 @@ }, "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", "devDependencies": { - "concurrently": "^10.0.5", - "prettier": "^3.9.6" + "concurrently": "^10.0.6", + "prettier": "^3.9.10" } } diff --git a/mcp/packages/plugin/package.json b/mcp/packages/plugin/package.json index 33b37f2442..6155889516 100644 --- a/mcp/packages/plugin/package.json +++ b/mcp/packages/plugin/package.json @@ -19,7 +19,7 @@ "devDependencies": { "cross-env": "^10.1.0", "typescript": "^6.0.3", - "vite": "^8.2.0", + "vite": "^8.3.5", "vite-live-preview": "^0.4.0" } } diff --git a/mcp/packages/server/package.json b/mcp/packages/server/package.json index c30679f6f6..4fb0e12d41 100644 --- a/mcp/packages/server/package.json +++ b/mcp/packages/server/package.json @@ -26,31 +26,31 @@ "license": "MIT", "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", "dependencies": { - "@modelcontextprotocol/sdk": "^1.29.0", + "@modelcontextprotocol/sdk": "^1.32.2", "class-transformer": "^0.5.1", "class-validator": "^0.15.1", - "express": "^5.2.1", + "express": "^5.3.0", "ioredis": "^6.0.0", - "js-yaml": "^5.2.3", + "js-yaml": "^5.5.0", "nrepl-client": "^0.3.0", - "pino": "^10.3.1", + "pino": "^10.4.0", "pino-loki": "^3.0.0", - "pino-pretty": "^13.1.3", + "pino-pretty": "^13.2.0", "reflect-metadata": "^0.2.2", - "sharp": "^0.35.3", - "ws": "^8.21.1", - "zod": "^4.4.3" + "sharp": "^0.35.5", + "ws": "^8.22.0", + "zod": "^4.6.7" }, "devDependencies": { "@penpot/mcp-common": "workspace:../common", "@types/express": "^5.0.6", "@types/js-yaml": "^4.0.9", - "@types/node": "^26.1.2", - "@types/ws": "^8.18.1", + "@types/node": "^26.6.5", + "@types/ws": "^8.18.2", "cross-env": "^10.1.0", "esbuild": "^0.28.1", "ts-node": "^10.9.2", - "tsx": "^4.23.5", + "tsx": "^4.23.15", "typescript": "^6.0.3" }, "ts-node": { diff --git a/mcp/pnpm-lock.yaml b/mcp/pnpm-lock.yaml index 13321c823a..0e558241f2 100644 --- a/mcp/pnpm-lock.yaml +++ b/mcp/pnpm-lock.yaml @@ -170,11 +170,11 @@ importers: .: devDependencies: concurrently: - specifier: ^10.0.5 - version: 10.0.5 + specifier: ^10.0.6 + version: 10.0.6 prettier: - specifier: ^3.9.6 - version: 3.9.6 + specifier: ^3.9.10 + version: 3.9.10 packages/common: devDependencies: @@ -198,17 +198,17 @@ importers: specifier: ^6.0.3 version: 6.0.3 vite: - specifier: ^8.2.0 - version: 8.2.2(@types/node@26.4.0)(esbuild@0.28.2)(tsx@4.23.12) + specifier: ^8.3.5 + version: 8.3.5(@types/node@26.6.5)(esbuild@0.28.2)(tsx@4.23.15) vite-live-preview: specifier: ^0.4.0 - version: 0.4.0(vite@8.2.2(@types/node@26.4.0)(esbuild@0.28.2)(tsx@4.23.12)) + version: 0.4.0(vite@8.3.5(@types/node@26.6.5)(esbuild@0.28.2)(tsx@4.23.15)) packages/server: dependencies: '@modelcontextprotocol/sdk': - specifier: ^1.29.0 - version: 1.30.0(supports-color@10.2.2)(zod@4.4.3) + specifier: ^1.32.2 + version: 1.32.2(supports-color@10.2.2)(zod@4.6.7) class-transformer: specifier: ^0.5.1 version: 0.5.1 @@ -216,38 +216,38 @@ importers: specifier: ^0.15.1 version: 0.15.1 express: - specifier: ^5.2.1 - version: 5.2.1(supports-color@10.2.2) + specifier: ^5.3.0 + version: 5.3.0(supports-color@10.2.2) ioredis: specifier: ^6.0.0 version: 6.0.0(supports-color@10.2.2) js-yaml: - specifier: ^5.2.3 - version: 5.4.1 + specifier: ^5.5.0 + version: 5.5.0 nrepl-client: specifier: ^0.3.0 version: 0.3.0 pino: - specifier: ^10.3.1 - version: 10.3.1 + specifier: ^10.4.0 + version: 10.4.0 pino-loki: specifier: ^3.0.0 version: 3.0.0 pino-pretty: - specifier: ^13.1.3 - version: 13.1.3 + specifier: ^13.2.0 + version: 13.2.0 reflect-metadata: specifier: ^0.2.2 version: 0.2.2 sharp: - specifier: ^0.35.3 - version: 0.35.4(@types/node@26.4.0) + specifier: ^0.35.5 + version: 0.35.5(@types/node@26.6.5) ws: - specifier: ^8.21.1 - version: 8.21.3 + specifier: ^8.22.0 + version: 8.22.0 zod: - specifier: ^4.4.3 - version: 4.4.3 + specifier: ^4.6.7 + version: 4.6.7 devDependencies: '@penpot/mcp-common': specifier: workspace:../common @@ -259,11 +259,11 @@ importers: specifier: ^4.0.9 version: 4.0.9 '@types/node': - specifier: ^26.1.2 - version: 26.4.0 + specifier: ^26.6.5 + version: 26.6.5 '@types/ws': - specifier: ^8.18.1 - version: 8.18.1 + specifier: ^8.18.2 + version: 8.18.2 cross-env: specifier: ^10.1.0 version: 10.1.0 @@ -272,10 +272,10 @@ importers: version: 0.28.2 ts-node: specifier: ^10.9.2 - version: 10.9.2(@types/node@26.4.0)(typescript@6.0.3) + version: 10.9.2(@types/node@26.6.5)(typescript@6.0.3) tsx: - specifier: ^4.23.5 - version: 4.23.12 + specifier: ^4.23.15 + version: 4.23.15 typescript: specifier: ^6.0.3 version: 6.0.3 @@ -448,170 +448,170 @@ packages: cpu: [x64] os: [win32] - '@hono/node-server@2.1.1': - resolution: {integrity: sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==} + '@hono/node-server@2.1.5': + resolution: {integrity: sha512-MgP/I06GdvsilDspMk/qmRzpk8LOUStP6jFAbSRi40W09DhoyUn+Mj7eyKICPqeYKybOjVFLVIAQzvu1bfIa7Q==} engines: {node: '>=20'} peerDependencies: - hono: ^4 + hono: ^4 || ^5.0.0-0 '@img/colour@1.1.0': resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} engines: {node: '>=18'} - '@img/sharp-darwin-arm64@0.35.4': - resolution: {integrity: sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==} + '@img/sharp-darwin-arm64@0.35.5': + resolution: {integrity: sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.35.4': - resolution: {integrity: sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==} + '@img/sharp-darwin-x64@0.35.5': + resolution: {integrity: sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==} engines: {node: '>=20.9.0'} cpu: [x64] os: [darwin] - '@img/sharp-freebsd-wasm32@0.35.4': - resolution: {integrity: sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==} + '@img/sharp-freebsd-wasm32@0.35.5': + resolution: {integrity: sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==} engines: {node: '>=20.9.0'} os: [freebsd] - '@img/sharp-libvips-darwin-arm64@1.3.3': - resolution: {integrity: sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==} + '@img/sharp-libvips-darwin-arm64@1.3.4': + resolution: {integrity: sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.3.3': - resolution: {integrity: sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==} + '@img/sharp-libvips-darwin-x64@1.3.4': + resolution: {integrity: sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.3.3': - resolution: {integrity: sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==} + '@img/sharp-libvips-linux-arm64@1.3.4': + resolution: {integrity: sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==} cpu: [arm64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-arm@1.3.3': - resolution: {integrity: sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==} + '@img/sharp-libvips-linux-arm@1.3.4': + resolution: {integrity: sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==} cpu: [arm] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-ppc64@1.3.3': - resolution: {integrity: sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==} + '@img/sharp-libvips-linux-ppc64@1.3.4': + resolution: {integrity: sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-riscv64@1.3.3': - resolution: {integrity: sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==} + '@img/sharp-libvips-linux-riscv64@1.3.4': + resolution: {integrity: sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==} cpu: [riscv64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-s390x@1.3.3': - resolution: {integrity: sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==} + '@img/sharp-libvips-linux-s390x@1.3.4': + resolution: {integrity: sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@img/sharp-libvips-linux-x64@1.3.3': - resolution: {integrity: sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==} + '@img/sharp-libvips-linux-x64@1.3.4': + resolution: {integrity: sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==} cpu: [x64] os: [linux] libc: [glibc] - '@img/sharp-libvips-linuxmusl-arm64@1.3.3': - resolution: {integrity: sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==} + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': + resolution: {integrity: sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==} cpu: [arm64] os: [linux] libc: [musl] - '@img/sharp-libvips-linuxmusl-x64@1.3.3': - resolution: {integrity: sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==} + '@img/sharp-libvips-linuxmusl-x64@1.3.4': + resolution: {integrity: sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==} cpu: [x64] os: [linux] libc: [musl] - '@img/sharp-linux-arm64@0.35.4': - resolution: {integrity: sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==} + '@img/sharp-linux-arm64@0.35.5': + resolution: {integrity: sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [linux] libc: [glibc] - '@img/sharp-linux-arm@0.35.4': - resolution: {integrity: sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==} + '@img/sharp-linux-arm@0.35.5': + resolution: {integrity: sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==} engines: {node: '>=20.9.0'} cpu: [arm] os: [linux] libc: [glibc] - '@img/sharp-linux-ppc64@0.35.4': - resolution: {integrity: sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==} + '@img/sharp-linux-ppc64@0.35.5': + resolution: {integrity: sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==} engines: {node: '>=20.9.0'} cpu: [ppc64] os: [linux] libc: [glibc] - '@img/sharp-linux-riscv64@0.35.4': - resolution: {integrity: sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==} + '@img/sharp-linux-riscv64@0.35.5': + resolution: {integrity: sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==} engines: {node: '>=20.9.0'} cpu: [riscv64] os: [linux] libc: [glibc] - '@img/sharp-linux-s390x@0.35.4': - resolution: {integrity: sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==} + '@img/sharp-linux-s390x@0.35.5': + resolution: {integrity: sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==} engines: {node: '>=20.9.0'} cpu: [s390x] os: [linux] libc: [glibc] - '@img/sharp-linux-x64@0.35.4': - resolution: {integrity: sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==} + '@img/sharp-linux-x64@0.35.5': + resolution: {integrity: sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==} engines: {node: '>=20.9.0'} cpu: [x64] os: [linux] libc: [glibc] - '@img/sharp-linuxmusl-arm64@0.35.4': - resolution: {integrity: sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==} + '@img/sharp-linuxmusl-arm64@0.35.5': + resolution: {integrity: sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [linux] libc: [musl] - '@img/sharp-linuxmusl-x64@0.35.4': - resolution: {integrity: sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==} + '@img/sharp-linuxmusl-x64@0.35.5': + resolution: {integrity: sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==} engines: {node: '>=20.9.0'} cpu: [x64] os: [linux] libc: [musl] - '@img/sharp-wasm32@0.35.4': - resolution: {integrity: sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==} + '@img/sharp-wasm32@0.35.5': + resolution: {integrity: sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==} engines: {node: '>=20.9.0'} - '@img/sharp-webcontainers-wasm32@0.35.4': - resolution: {integrity: sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==} + '@img/sharp-webcontainers-wasm32@0.35.5': + resolution: {integrity: sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==} engines: {node: '>=20.9.0'} cpu: [wasm32] - '@img/sharp-win32-arm64@0.35.4': - resolution: {integrity: sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==} + '@img/sharp-win32-arm64@0.35.5': + resolution: {integrity: sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==} engines: {node: '>=20.9.0'} cpu: [arm64] os: [win32] - '@img/sharp-win32-ia32@0.35.4': - resolution: {integrity: sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==} + '@img/sharp-win32-ia32@0.35.5': + resolution: {integrity: sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==} engines: {node: ^20.9.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.35.4': - resolution: {integrity: sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==} + '@img/sharp-win32-x64@0.35.5': + resolution: {integrity: sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==} engines: {node: '>=20.9.0'} cpu: [x64] os: [win32] @@ -623,14 +623,14 @@ packages: resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@modelcontextprotocol/sdk@1.30.0': - resolution: {integrity: sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==} + '@modelcontextprotocol/sdk@1.32.2': + resolution: {integrity: sha512-SWsVtH/0vULSQStoZ6xxH2K09Li8fXYTMC64ZeogCdpZ3XSi1eCPOByV1OpuJxuI3OcmHhosDWYyii07tpPsLw==} engines: {node: '>=18'} peerDependencies: '@cfworker/json-schema': ^4.1.1 @@ -639,8 +639,8 @@ packages: '@cfworker/json-schema': optional: true - '@oxc-project/types@0.147.0': - resolution: {integrity: sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==} + '@oxc-project/types@0.155.0': + resolution: {integrity: sha512-SeE8JPwW1xs1tHeNycjUtUBdhorRa8o4jlvjwk49R7/Z291i+4DQa7JJIgOm/TaYQZx+QrPQbVJ/9c8dMIZN8Q==} '@penpot/plugin-styles@1.5.0': resolution: {integrity: sha512-rwXFBRPd0IZs3ens+eRT8oA5WqkQgF6xlW6fCfH7U1NHRjej9HH7vTGXmfjoIVml6Xx1sbyYHZVxkQC8Ub8+zA==} @@ -651,98 +651,98 @@ packages: '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} - '@rolldown/binding-android-arm-eabi@1.2.6': - resolution: {integrity: sha512-b+jTcARdTiFLI6jB4a5XjTm0RWd6KcRfQj/I2356fxUZemiho9zQLxo0RtCuMDAyKcLo6cEltkgbQp6d1+sjjQ==} + '@rolldown/binding-android-arm-eabi@1.2.15': + resolution: {integrity: sha512-aLcgK9gIJ3YRvrrtfSBbRa27F5WrpiTaPulnFpsHPxpUHgFlSgnU4854MHwoRGEBhfRJDWCS2WQ7lIjskE9Olw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@rolldown/binding-android-arm64@1.2.6': - resolution: {integrity: sha512-lkWU8ZJaRk9q3CIEY1Tc7vIFALp3Xw5NfGJo2hQg5oIqNgxWi1zI+IiDEK3r70BF5Dzol1tcXsnzsRc8NLhG+Q==} + '@rolldown/binding-android-arm64@1.2.15': + resolution: {integrity: sha512-xD7DdZCrbThKuxNg7ooQmvp07ys4J/pnSEMTG3/OdOWl6daC67m/Q4fL78sRHMxTH/N4fGUbYhcPM0MF5WFHkg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.2.6': - resolution: {integrity: sha512-dgR56NYnvAszm7Ob1B2/Vn0e8bUQYZH2UjVaMMtMVOCKFSfjhfLmuA/9+O+F+ajUdG6B/bSssrKW6JJYASa8jA==} + '@rolldown/binding-darwin-arm64@1.2.15': + resolution: {integrity: sha512-m2WuQ6r0B4OTYxyPpNLtXaMRbRDUbG8YQV2Q3KTdSSK8Th6KHCnC8jVCJt8bvYeSB5WivkkNbc85mKadaSdOxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.2.6': - resolution: {integrity: sha512-vpVxFvUCFioJqug7OTvqptkc4yb8UX0AwfDmJpaR/0sWz+BUmqSVAf7c8JkUgnN8YLspb4a/N6NhTyMAmdyQ7Q==} + '@rolldown/binding-darwin-x64@1.2.15': + resolution: {integrity: sha512-5RtnsHM36nodM9WbMy+zip0LGS/G+y5wro5RHrpOlr4ac24+1zSi9kiV2MP1myZeZ/ifEHfulQcWjnAXzc2C2A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.2.6': - resolution: {integrity: sha512-h1wG6Y6K3JlRswxsI64qQJqBAy4vrLuHgRbc8CZMGSWTOFRY6ghMApM1NKzB2I0n5xV1fjkE18SuVl2QpLeNpA==} + '@rolldown/binding-freebsd-x64@1.2.15': + resolution: {integrity: sha512-g3l09pyFqhu+135JKkbkwiKGQmwU5hUMUPJ4VdBADvuqR8d33L6H578rh8m7rtxbdp+VmX/+nzI7nvhSZlzpUQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.2.6': - resolution: {integrity: sha512-tbCiqub0q2MVWJKgF5PoAlNWCtQydiOYSLIkd8sByqK/6MMYLJRcSXSYodqYtd0O+Fw7QaVmKKlS4oL94YRZ0w==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.15': + resolution: {integrity: sha512-nIe3VugI97nGQtspPxDqA4sXMUpeiocKIP/CqpY/u/vgbT+alX+cVxu1C/oVBPKg4feNTmYovE91v4DgXvXNwQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.2.6': - resolution: {integrity: sha512-oxK9+baEBPhZG5HB4URY+uU04zJWeZlH6Tb9rB5DK4DF9XR1uXNLXt5Q5ZsugTKayNCNLhkcwz/ye74hRI98dg==} + '@rolldown/binding-linux-arm64-gnu@1.2.15': + resolution: {integrity: sha512-iTBjXx+B5QSvgI89lJfmqh4wTh8NabR1YZIIN3hNx4zSG0EVfVqkOvLulNpG4251pbd6/IAmZ/LefVk1Y4rPhw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.2.6': - resolution: {integrity: sha512-muWCk27FVBEZtv0MsK8gnfSmgczA8KQ0uRVJbTABKhkRfQc38aUrcb7fhi3BNiyseFmgcRsoMfQsSNJ+DbZdSw==} + '@rolldown/binding-linux-arm64-musl@1.2.15': + resolution: {integrity: sha512-uN26XOnVR7rqQupG3V9oAG2EGGatWjcJHOeDOHUFCh4TBWmP2tHTFoVN13aYbwfm0aHqJAEmcwhAu6sooIjfqQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.2.6': - resolution: {integrity: sha512-eWDoSfU7Co2qj3vgB3Dt4lj1mG6CoWbcJQkRMP3XJplyCMtuaq3LHvPFjS9QIPvMGWVadJC04Xiy0IdcVPtnwQ==} + '@rolldown/binding-linux-ppc64-gnu@1.2.15': + resolution: {integrity: sha512-9nWkcdd+H+XhaA3fQIwpHnKIrfx/PQ6rO0pivr78Og07tXlUlctBBJoEYLPfhTmCR/QxEVdn6uPjHV5SymPhdw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.6': - resolution: {integrity: sha512-2bWNjRSIayvupRKxXUY2tWG9fYdoUlTqWywHRvE8Eq3GvuQ+f2HeIkve697fIt+IQs/PV8yFsdWuhp1aJ1PdnA==} + '@rolldown/binding-linux-s390x-gnu@1.2.15': + resolution: {integrity: sha512-Ggh0ciFjLwIusLSLz7LZYEaGdxOAUJXI+Qu5JCbhPJJHEt8vP+IjRATTJheiJsdzzTYgUiHUiw3X1Ea3ZpMBdA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.6': - resolution: {integrity: sha512-KekI0gS0wLxe1UBSQSjenBVwou/JkcQPDzBPICGZjxUv9k3RteHDPBQaiOicZUFKRIH2wKEimGwVpnJsbPzu7w==} + '@rolldown/binding-linux-x64-gnu@1.2.15': + resolution: {integrity: sha512-FHg60rS6DBePAYZ9X9F67x+JObFdmgn6tupA1C/a3B+CufFmTD4mX+e8M75tCiAO3foR/6xwVBI0KQiI7sn/rw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.2.6': - resolution: {integrity: sha512-TvtPnfVr+HtyGiDmPK4VWmlNm7QhNNAcK5Q9A7aOXsI8545yCyaoMaicXrFZ72JzeYjaUVk7yT243zT0jzjFKQ==} + '@rolldown/binding-linux-x64-musl@1.2.15': + resolution: {integrity: sha512-/cvV/7v5VGz/moiz0XKRj2dE8DzsKyhIu1KpOvJGPjRywg3yscON889UGvAe8zfiJLHup7VLjBduoGWi3HusWQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.2.6': - resolution: {integrity: sha512-iOo0VEay2XFhaCcH0sps5XIimkSuOnNaZrf6+ZkoSOQBJPKNU48RkmJv0/lSpipexu5P+ouFgafe5IGr/DiQfg==} + '@rolldown/binding-openharmony-arm64@1.2.15': + resolution: {integrity: sha512-MyzC5Hrv/sm+Z7TSGKP/j8001RO2xQm1zOpCNVL4j0cY/VhBZviludA2YFQ7i4lH6ZAXxQm0lcMdBzM+99mE7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-win32-arm64-msvc@1.2.6': - resolution: {integrity: sha512-y5NTmmasMS455JlOCO4ZM9krIchv3Mvm1crL1iUPGOPgEzSkves9n0SdC5Sjz6+qWDFhd8/JpfWMH8NSWNHe+A==} + '@rolldown/binding-win32-arm64-msvc@1.2.15': + resolution: {integrity: sha512-+PgYiS+AH5omy6L45ZLxybasauJaj3M8buoT83D+nzPmCayXlxUV9hydhciCKVyIg0B/v0BtXPDE1uGqNwCPpg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.6': - resolution: {integrity: sha512-np8iZSLfXlAD4kWhiyq/u0Yt8oZDtRQ8lGhQaCXo2rl37KNjeU0GjJuwr4P3oeZ++ROfofsKNBqR5LTO8aXyWQ==} + '@rolldown/binding-win32-x64-msvc@1.2.15': + resolution: {integrity: sha512-HFZd2QNQYn1JbIi+Hpd7H+r/lkWxcfIu28nirZ6eCn2LafuvmExMlb/P96Sfx5tf7pPArw39IdhmCF8vmV+NhQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -786,8 +786,8 @@ packages: '@types/js-yaml@4.0.9': resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} - '@types/node@26.4.0': - resolution: {integrity: sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==} + '@types/node@26.6.5': + resolution: {integrity: sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==} '@types/qs@6.15.1': resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==} @@ -804,8 +804,8 @@ packages: '@types/validator@13.15.10': resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} - '@types/ws@8.18.1': - resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@types/ws@8.18.2': + resolution: {integrity: sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==} accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} @@ -815,8 +815,8 @@ packages: resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} engines: {node: '>=0.4.0'} - acorn@8.18.0: - resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} engines: {node: '>=0.4.0'} hasBin: true @@ -831,8 +831,8 @@ packages: ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + ansi-regex@6.4.0: + resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==} engines: {node: '>=12'} ansi-styles@6.2.3: @@ -842,8 +842,8 @@ packages: arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + argparse@3.0.4: + resolution: {integrity: sha512-fwWK3Zq22l4XJJjx5mcBHGikIk+hJqO+32dPm0Jur7+rtG5x1scOjSfdT9ZKeWHPpsya/l0HHK4tDImBkTrtvA==} atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} @@ -852,8 +852,8 @@ packages: bencode@2.0.3: resolution: {integrity: sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==} - body-parser@2.3.0: - resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + body-parser@2.4.0: + resolution: {integrity: sha512-Ifk1KcLrxaGt1occQagQNFNNOqRt1LFuehEnHHzB8Z6cRgIxRU1TBaiIsUiCdA+gy5PL7Y1IX31DNKkRmxtXjQ==} engines: {node: '>=18'} bytes@3.1.2: @@ -889,13 +889,13 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - concurrently@10.0.5: - resolution: {integrity: sha512-JaP/CoftUrCcAFW/g//RbgEGwlelnEae6cfBLgH6ZdO6s8jPkn6p9SB9u6pdVxYXoiSnFqseOlHfrEfF82TVOg==} + concurrently@10.0.6: + resolution: {integrity: sha512-qgICXXFp2/3nAebRLmxcINKEXM1mLK3ij/y31P02VTs/KIkddIeC05n73DxOXsXMB9LFSqNU1/na3lDlOhcbIw==} engines: {node: '>=22'} hasBin: true - content-disposition@1.1.0: - resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + content-disposition@2.0.1: + resolution: {integrity: sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==} engines: {node: '>=18'} content-type@1.0.5: @@ -1015,18 +1015,18 @@ packages: resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} engines: {node: '>=18.0.0'} - express-rate-limit@8.6.2: - resolution: {integrity: sha512-YH4ru+eOJxQABscKFfRCy9R7x9QFGdezclVMwwgFFndzS2Xnm0uo6B0ABZsLhcpeptGv2qvuJVWlQr9gQZoC3A==} + express-rate-limit@8.7.1: + resolution: {integrity: sha512-2FXbqkygil3mZiXzEtM0IjE/UBmBNot0J1GEVrJT4JbrvwOSoEtqtO+wHbiMQELWe1eNvHoYRg2dkjOid+6JkA==} engines: {node: '>= 16'} peerDependencies: express: '>= 4.11' - express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + express@5.3.0: + resolution: {integrity: sha512-qCqy1xSoaugxOD4IVHb1ZWdkvCF2W3aE2okKouWj8VwJ+ztskSiXoBnCSJqfKT+cVPJhuJqe9YLbY425+Zh00g==} engines: {node: '>= 18'} - fast-copy@4.0.4: - resolution: {integrity: sha512-eVAiWVNPSEGIzDl5yPuLrx8fNMogScXvD9xp1Kzd41FjRIz2I3sSIcxsFeM5EzFfHAfobdvs8ZySffUopljvIA==} + fast-copy@4.3.1: + resolution: {integrity: sha512-CRzQaTFOFUs6PuhsAq7lk9Zqr995soJBcFNZlfJS/5keTSl1awREV9dZW4xS2nX4pWbhIIR0xp4h+J8PQxCkvg==} fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1034,8 +1034,8 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.1.6: - resolution: {integrity: sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==} + fast-uri@3.1.9: + resolution: {integrity: sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==} fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} @@ -1070,8 +1070,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -1097,8 +1097,8 @@ packages: help-me@5.0.0: resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} - hono@4.13.5: - resolution: {integrity: sha512-O6+/eCYRkzzzy0rPWwKLiGBR1nFuUPZynnwjxN1MBA62NNqbT0wQEzQyK2gSO5yDIDB336sXQleAhOHrzlYyKw==} + hono@4.13.14: + resolution: {integrity: sha512-yhRLQ21U6qa9Hsu2N7Qcbh8tE+WKEcoErjIo56LeSGiGXGp9sA7UpE86Ui9uexb61KakiGwuHMn2QdV7w6i6kQ==} engines: {node: '>=16.9.0'} http-errors@2.0.1: @@ -1116,8 +1116,8 @@ packages: resolution: {integrity: sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==} engines: {node: '>=20.0.0'} - ip-address@10.5.0: - resolution: {integrity: sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==} + ip-address@10.7.5: + resolution: {integrity: sha512-t2v0rkILYv9WXmSL7TpAaU3HXgaFYOPUcH3QHgwQ++gpJuH3bqyMy4Fvt/DJCTKwzH3Cf+bAp5W/mFL39KPLzA==} engines: {node: '>= 12'} ipaddr.js@1.9.1: @@ -1130,15 +1130,15 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - jose@6.2.10: - resolution: {integrity: sha512-iiW7J9qRFlGxvCOIBDBDxFePQSn7ZMAnrYGhrrOo6siO/MIqwfyilLR27pkfDgUk+raLuzADS8A3S/KLBisc0g==} + jose@6.2.13: + resolution: {integrity: sha512-7TIg10ZE1x82YediN+lcrPNvGMKge9yFHQD+Qho/b8y2adfugU3AsvvHfxV0fzyFllT6l9xCjf4RWY9g/Z9PJQ==} joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} - js-yaml@5.4.1: - resolution: {integrity: sha512-28R/k+NAjeuf7+CKlTxWZVExJGwVVLwY06DgEnOMz2gEpfNkDcD7QvyiVPT0xy0XXhU8vHsd4Ot42OOPdJG7dQ==} + js-yaml@5.5.0: + resolution: {integrity: sha512-paNr4LFIFPjeeSmwNYdrb8FafLLG/Cr2Af3GjbsHJ5CxIjH4r0c2emlmRdAtpPAieP1gRVzk6buBbVP5gBMGAg==} hasBin: true json-schema-traverse@1.0.0: @@ -1147,8 +1147,8 @@ packages: json-schema-typed@8.0.2: resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} - libphonenumber-js@1.13.11: - resolution: {integrity: sha512-ETER2kMaIFTI/Nh1a8Gk03dUF/SL0VZqtI+CcVHZxp5WIHYwNS7S+uiYZDYCvLy3lOR4/DAD5jf0h5WkePPpqg==} + libphonenumber-js@1.13.15: + resolution: {integrity: sha512-AHdhEQeDFEJ4GKDAQ9AwxChy+v2kUILUB3TGQRpkXMkWePjXTU/WQEzWVQoIx/Gz8fE73Wr5SEuZCy2vk8jrMQ==} lightningcss-android-arm64@1.33.0: resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} @@ -1253,8 +1253,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.18: - resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1277,8 +1277,8 @@ packages: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + on-finished@2.4.2: + resolution: {integrity: sha512-ATWUv387i+nLD49EiDoOft5scf32Vsdz3ktrQJG9bi7jRFmaXTssvyvj1EmeKVVgvesbqUtvQQvaS2TpTukAZQ==} engines: {node: '>= 0.8'} once@1.4.0: @@ -1310,42 +1310,42 @@ packages: engines: {node: '>=20'} hasBin: true - pino-pretty@13.1.3: - resolution: {integrity: sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==} + pino-pretty@13.2.0: + resolution: {integrity: sha512-jjghD1ML+Di/WxjJDz6j6Y4FT7hIXOlb8h27AyJ+ohtAXJXH4PS/xkv7si+RCCIW59HMgZsMKTDgzdr0RhuRrg==} hasBin: true pino-std-serializers@7.1.0: resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} - pino@10.3.1: - resolution: {integrity: sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==} + pino@10.4.0: + resolution: {integrity: sha512-bk1ZMTwG/Vymx+zPoa28MhNzucFvXJWp3csrSuxuHPSMeUettaCoQ5Jvg07mtC4JGNpcfTwz41oVCnNgBK9+vA==} hasBin: true pkce-challenge@5.0.1: resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} - postcss@8.5.26: - resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + postcss@8.5.32: + resolution: {integrity: sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==} engines: {node: ^10 || ^12 || >=14} - prettier@3.9.6: - resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} + prettier@3.9.10: + resolution: {integrity: sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==} engines: {node: '>=14'} hasBin: true - process-warning@5.1.0: - resolution: {integrity: sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw==} + process-warning@5.1.1: + resolution: {integrity: sha512-oCkNVj4OKnKEcocVBcDfiIugN1/cE6rgfT3nCtzeqZPA8+rIxMaQ0xXzIkGP8Gj2qUaP1UR7uhJ1VD8lUCpzCg==} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} engines: {node: '>= 0.10'} pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} - qs@6.15.3: - resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} + qs@6.17.0: + resolution: {integrity: sha512-5LK5BZ2XDHMvcUJaf0CQ5HL3aVgKbpklvByC7qLSxYkfE8COEEbJg5xCHWCTqzqi0Gs4Jn5Mv5v3R38W6edscA==} engines: {node: '>=0.6'} quick-format-unescaped@4.0.4: @@ -1359,10 +1359,6 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} - real-require@0.2.0: - resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} - engines: {node: '>= 12.13.0'} - real-require@1.0.0: resolution: {integrity: sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==} @@ -1377,8 +1373,8 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - rolldown@1.2.6: - resolution: {integrity: sha512-vMM4q3aixf46GiF1Kok8jDPFsEpXgFWGjUHXNkNHNm+Y2adXAG2dbX91jkti3i0ZRsOlcmbuzAz1poObSHCmUA==} + rolldown@1.2.15: + resolution: {integrity: sha512-6odND+fel5zVw3I4Yc2e69gvguDnX0CAAGiNDZSq4ik5WUcaLrkD2GLuog0XcODbor31hZ5ayEMgVDno+KPV5g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -1396,8 +1392,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - secure-json-parse@4.1.0: - resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} + secure-json-parse@4.1.1: + resolution: {integrity: sha512-lnd81MQEZKjhW/Gd2TQqdd4XP6QYNdDW/EP+I7nTrFHP9y2LmaGPIHk9xsnzcOiEr1c39c/e84xFgGviQKBTRw==} semver@7.8.5: resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} @@ -1415,8 +1411,8 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sharp@0.35.4: - resolution: {integrity: sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==} + sharp@0.35.5: + resolution: {integrity: sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==} engines: {node: '>=20.9.0'} peerDependencies: '@types/node': '*' @@ -1432,8 +1428,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.9.0: - resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==} + shell-quote@1.12.0: + resolution: {integrity: sha512-PcByqNyT/38F2kDNi006HAMRJaULuBzq/FOsw3qdZvX/GA9W/jamDaRskgHjubHiftXK5sIFxLNkvrXUwcof6Q==} engines: {node: '>= 0.4'} side-channel-list@1.0.1: @@ -1455,8 +1451,11 @@ packages: sonic-boom@4.2.1: resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + sonic-boom@5.0.2: + resolution: {integrity: sha512-/JEruzo6yhNVhsLblTRchgTQHIt7SsdJP0YyrfWaNKjIOQDfrdZv9gwYraYCAsmKV39/LAdV31FLL5NCDpoL/A==} + + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} engines: {node: '>=0.10.0'} split2@4.2.0: @@ -1519,8 +1518,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.23.12: - resolution: {integrity: sha512-FDf4L4sYzKtzWYhU/Xm0AQFdTjdIxNo9ElTf2mxXM6k8YMHXzYUe4yODVaXP4V9uMFbVg8c0qyBccK2OOxb45Q==} + tsx@4.23.15: + resolution: {integrity: sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==} engines: {node: '>=18.0.0'} hasBin: true @@ -1533,8 +1532,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - undici-types@8.3.0: - resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==} + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} @@ -1556,13 +1555,13 @@ packages: peerDependencies: vite: '>=5.4.0' - vite@8.2.2: - resolution: {integrity: sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==} + vite@8.3.5: + resolution: {integrity: sha512-z1YpjieJ9g0ebTmQpLBv/oq9E3F9EIlOe+7LahW8SrE3LTiG3udBRUXQOlYXP9b+IC2q2phHeVxj9xGlw34OEQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.4.0 || ^0.5.0 + '@vitejs/devtools': ^0.7.1 || ^0.8.0 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -1611,8 +1610,8 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.21.3: - resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + ws@8.22.0: + resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -1644,8 +1643,8 @@ packages: peerDependencies: zod: ^3.25.28 || ^4 - zod@4.4.3: - resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + zod@4.6.7: + resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==} snapshots: @@ -1738,130 +1737,130 @@ snapshots: '@esbuild/win32-x64@0.28.2': optional: true - '@hono/node-server@2.1.1(hono@4.13.5)': + '@hono/node-server@2.1.5(hono@4.13.14)': dependencies: - hono: 4.13.5 + hono: 4.13.14 '@img/colour@1.1.0': {} - '@img/sharp-darwin-arm64@0.35.4': + '@img/sharp-darwin-arm64@0.35.5': optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.3.3 + '@img/sharp-libvips-darwin-arm64': 1.3.4 optional: true - '@img/sharp-darwin-x64@0.35.4': + '@img/sharp-darwin-x64@0.35.5': optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.3.3 + '@img/sharp-libvips-darwin-x64': 1.3.4 optional: true - '@img/sharp-freebsd-wasm32@0.35.4': + '@img/sharp-freebsd-wasm32@0.35.5': dependencies: - '@img/sharp-wasm32': 0.35.4 + '@img/sharp-wasm32': 0.35.5 optional: true - '@img/sharp-libvips-darwin-arm64@1.3.3': + '@img/sharp-libvips-darwin-arm64@1.3.4': optional: true - '@img/sharp-libvips-darwin-x64@1.3.3': + '@img/sharp-libvips-darwin-x64@1.3.4': optional: true - '@img/sharp-libvips-linux-arm64@1.3.3': + '@img/sharp-libvips-linux-arm64@1.3.4': optional: true - '@img/sharp-libvips-linux-arm@1.3.3': + '@img/sharp-libvips-linux-arm@1.3.4': optional: true - '@img/sharp-libvips-linux-ppc64@1.3.3': + '@img/sharp-libvips-linux-ppc64@1.3.4': optional: true - '@img/sharp-libvips-linux-riscv64@1.3.3': + '@img/sharp-libvips-linux-riscv64@1.3.4': optional: true - '@img/sharp-libvips-linux-s390x@1.3.3': + '@img/sharp-libvips-linux-s390x@1.3.4': optional: true - '@img/sharp-libvips-linux-x64@1.3.3': + '@img/sharp-libvips-linux-x64@1.3.4': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.3.3': + '@img/sharp-libvips-linuxmusl-arm64@1.3.4': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.3.3': + '@img/sharp-libvips-linuxmusl-x64@1.3.4': optional: true - '@img/sharp-linux-arm64@0.35.4': + '@img/sharp-linux-arm64@0.35.5': optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.3.3 + '@img/sharp-libvips-linux-arm64': 1.3.4 optional: true - '@img/sharp-linux-arm@0.35.4': + '@img/sharp-linux-arm@0.35.5': optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.3.3 + '@img/sharp-libvips-linux-arm': 1.3.4 optional: true - '@img/sharp-linux-ppc64@0.35.4': + '@img/sharp-linux-ppc64@0.35.5': optionalDependencies: - '@img/sharp-libvips-linux-ppc64': 1.3.3 + '@img/sharp-libvips-linux-ppc64': 1.3.4 optional: true - '@img/sharp-linux-riscv64@0.35.4': + '@img/sharp-linux-riscv64@0.35.5': optionalDependencies: - '@img/sharp-libvips-linux-riscv64': 1.3.3 + '@img/sharp-libvips-linux-riscv64': 1.3.4 optional: true - '@img/sharp-linux-s390x@0.35.4': + '@img/sharp-linux-s390x@0.35.5': optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.3.3 + '@img/sharp-libvips-linux-s390x': 1.3.4 optional: true - '@img/sharp-linux-x64@0.35.4': + '@img/sharp-linux-x64@0.35.5': optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.3.3 + '@img/sharp-libvips-linux-x64': 1.3.4 optional: true - '@img/sharp-linuxmusl-arm64@0.35.4': + '@img/sharp-linuxmusl-arm64@0.35.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.3.3 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 optional: true - '@img/sharp-linuxmusl-x64@0.35.4': + '@img/sharp-linuxmusl-x64@0.35.5': optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.3.3 + '@img/sharp-libvips-linuxmusl-x64': 1.3.4 optional: true - '@img/sharp-wasm32@0.35.4': + '@img/sharp-wasm32@0.35.5': dependencies: '@emnapi/runtime': 1.11.3 optional: true - '@img/sharp-webcontainers-wasm32@0.35.4': + '@img/sharp-webcontainers-wasm32@0.35.5': dependencies: - '@img/sharp-wasm32': 0.35.4 + '@img/sharp-wasm32': 0.35.5 optional: true - '@img/sharp-win32-arm64@0.35.4': + '@img/sharp-win32-arm64@0.35.5': optional: true - '@img/sharp-win32-ia32@0.35.4': + '@img/sharp-win32-ia32@0.35.5': optional: true - '@img/sharp-win32-x64@0.35.4': + '@img/sharp-win32-x64@0.35.5': optional: true '@ioredis/commands@2.0.0': {} '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/sourcemap-codec@1.6.0': {} '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.6.0 - '@modelcontextprotocol/sdk@1.30.0(supports-color@10.2.2)(zod@4.4.3)': + '@modelcontextprotocol/sdk@1.32.2(supports-color@10.2.2)(zod@4.6.7)': dependencies: - '@hono/node-server': 2.1.1(hono@4.13.5) + '@hono/node-server': 2.1.5(hono@4.13.14) ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) content-type: 1.0.5 @@ -1869,19 +1868,19 @@ snapshots: cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.1.1 - express: 5.2.1(supports-color@10.2.2) - express-rate-limit: 8.6.2(express@5.2.1(supports-color@10.2.2))(supports-color@10.2.2) - hono: 4.13.5 - jose: 6.2.10 + express: 5.3.0(supports-color@10.2.2) + express-rate-limit: 8.7.1(express@5.3.0(supports-color@10.2.2))(supports-color@10.2.2) + hono: 4.13.14 + jose: 6.2.13 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 raw-body: 3.0.2 - zod: 4.4.3 - zod-to-json-schema: 3.25.2(zod@4.4.3) + zod: 4.6.7 + zod-to-json-schema: 3.25.2(zod@4.6.7) transitivePeerDependencies: - supports-color - '@oxc-project/types@0.147.0': {} + '@oxc-project/types@0.155.0': {} '@penpot/plugin-styles@1.5.0': {} @@ -1889,49 +1888,49 @@ snapshots: '@pinojs/redact@0.4.0': {} - '@rolldown/binding-android-arm-eabi@1.2.6': + '@rolldown/binding-android-arm-eabi@1.2.15': optional: true - '@rolldown/binding-android-arm64@1.2.6': + '@rolldown/binding-android-arm64@1.2.15': optional: true - '@rolldown/binding-darwin-arm64@1.2.6': + '@rolldown/binding-darwin-arm64@1.2.15': optional: true - '@rolldown/binding-darwin-x64@1.2.6': + '@rolldown/binding-darwin-x64@1.2.15': optional: true - '@rolldown/binding-freebsd-x64@1.2.6': + '@rolldown/binding-freebsd-x64@1.2.15': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.6': + '@rolldown/binding-linux-arm-gnueabihf@1.2.15': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.6': + '@rolldown/binding-linux-arm64-gnu@1.2.15': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.6': + '@rolldown/binding-linux-arm64-musl@1.2.15': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.6': + '@rolldown/binding-linux-ppc64-gnu@1.2.15': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.6': + '@rolldown/binding-linux-s390x-gnu@1.2.15': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.6': + '@rolldown/binding-linux-x64-gnu@1.2.15': optional: true - '@rolldown/binding-linux-x64-musl@1.2.6': + '@rolldown/binding-linux-x64-musl@1.2.15': optional: true - '@rolldown/binding-openharmony-arm64@1.2.6': + '@rolldown/binding-openharmony-arm64@1.2.15': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.6': + '@rolldown/binding-win32-arm64-msvc@1.2.15': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.6': + '@rolldown/binding-win32-x64-msvc@1.2.15': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -1951,15 +1950,15 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 26.4.0 + '@types/node': 26.6.5 '@types/connect@3.4.38': dependencies: - '@types/node': 26.4.0 + '@types/node': 26.6.5 '@types/express-serve-static-core@5.1.3': dependencies: - '@types/node': 26.4.0 + '@types/node': 26.6.5 '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -1974,9 +1973,9 @@ snapshots: '@types/js-yaml@4.0.9': {} - '@types/node@26.4.0': + '@types/node@26.6.5': dependencies: - undici-types: 8.3.0 + undici-types: 8.9.0 '@types/qs@6.15.1': {} @@ -1984,18 +1983,18 @@ snapshots: '@types/send@1.2.1': dependencies: - '@types/node': 26.4.0 + '@types/node': 26.6.5 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 26.4.0 + '@types/node': 26.6.5 '@types/validator@13.15.10': {} - '@types/ws@8.18.1': + '@types/ws@8.18.2': dependencies: - '@types/node': 26.4.0 + '@types/node': 26.6.5 accepts@2.0.0: dependencies: @@ -2004,9 +2003,9 @@ snapshots: acorn-walk@8.3.5: dependencies: - acorn: 8.18.0 + acorn: 8.19.0 - acorn@8.18.0: {} + acorn@8.19.0: {} ajv-formats@3.0.1(ajv@8.20.0): optionalDependencies: @@ -2015,31 +2014,31 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.6 + fast-uri: 3.1.9 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - ansi-regex@6.2.2: {} + ansi-regex@6.4.0: {} ansi-styles@6.2.3: {} arg@4.1.3: {} - argparse@2.0.1: {} + argparse@3.0.4: {} atomic-sleep@1.0.0: {} bencode@2.0.3: {} - body-parser@2.3.0(supports-color@10.2.2): + body-parser@2.4.0(supports-color@10.2.2): dependencies: bytes: 3.1.2 content-type: 2.1.0 debug: 4.4.3(supports-color@10.2.2) http-errors: 2.0.1 iconv-lite: 0.7.3 - on-finished: 2.4.1 - qs: 6.15.3 + on-finished: 2.4.2 + qs: 6.17.0 raw-body: 3.0.2 type-is: 2.1.0 transitivePeerDependencies: @@ -2064,7 +2063,7 @@ snapshots: class-validator@0.15.1: dependencies: '@types/validator': 13.15.10 - libphonenumber-js: 1.13.11 + libphonenumber-js: 1.13.15 validator: 13.15.35 cliui@9.0.1: @@ -2077,16 +2076,16 @@ snapshots: colorette@2.0.20: {} - concurrently@10.0.5: + concurrently@10.0.6: dependencies: chalk: 5.6.2 rxjs: 7.8.2 - shell-quote: 1.9.0 + shell-quote: 1.12.0 supports-color: 10.2.2 tree-kill: 1.2.2 yargs: 18.0.0 - content-disposition@1.1.0: {} + content-disposition@2.0.1: {} content-type@1.0.5: {} @@ -2197,20 +2196,20 @@ snapshots: dependencies: eventsource-parser: 3.1.1 - express-rate-limit@8.6.2(express@5.2.1(supports-color@10.2.2))(supports-color@10.2.2): + express-rate-limit@8.7.1(express@5.3.0(supports-color@10.2.2))(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) - express: 5.2.1(supports-color@10.2.2) - ip-address: 10.5.0 + express: 5.3.0(supports-color@10.2.2) + ip-address: 10.7.5 transitivePeerDependencies: - supports-color - express@5.2.1(supports-color@10.2.2): + express@5.3.0(supports-color@10.2.2): dependencies: accepts: 2.0.0 - body-parser: 2.3.0(supports-color@10.2.2) - content-disposition: 1.1.0 - content-type: 1.0.5 + body-parser: 2.4.0(supports-color@10.2.2) + content-disposition: 2.0.1 + content-type: 2.1.0 cookie: 0.7.2 cookie-signature: 1.2.2 debug: 4.4.3(supports-color@10.2.2) @@ -2223,11 +2222,11 @@ snapshots: http-errors: 2.0.1 merge-descriptors: 2.0.0 mime-types: 3.0.2 - on-finished: 2.4.1 + on-finished: 2.4.2 once: 1.4.0 parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.15.3 + proxy-addr: 2.0.8 + qs: 6.17.0 range-parser: 1.3.0 router: 2.2.0(supports-color@10.2.2) send: 1.2.1(supports-color@10.2.2) @@ -2238,13 +2237,13 @@ snapshots: transitivePeerDependencies: - supports-color - fast-copy@4.0.4: {} + fast-copy@4.3.1: {} fast-deep-equal@3.1.3: {} fast-safe-stringify@2.1.1: {} - fast-uri@3.1.6: {} + fast-uri@3.1.9: {} fdir@6.5.0(picomatch@4.0.7): optionalDependencies: @@ -2255,7 +2254,7 @@ snapshots: debug: 4.4.3(supports-color@10.2.2) encodeurl: 2.0.0 escape-html: 1.0.3 - on-finished: 2.4.1 + on-finished: 2.4.2 parseurl: 1.3.3 statuses: 2.0.2 transitivePeerDependencies: @@ -2272,7 +2271,7 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.6.0: {} + get-east-asian-width@1.7.0: {} get-intrinsic@1.3.0: dependencies: @@ -2302,7 +2301,7 @@ snapshots: help-me@5.0.0: {} - hono@4.13.5: {} + hono@4.13.14: {} http-errors@2.0.1: dependencies: @@ -2329,7 +2328,7 @@ snapshots: transitivePeerDependencies: - supports-color - ip-address@10.5.0: {} + ip-address@10.7.5: {} ipaddr.js@1.9.1: {} @@ -2337,19 +2336,19 @@ snapshots: isexe@2.0.0: {} - jose@6.2.10: {} + jose@6.2.13: {} joycon@3.1.1: {} - js-yaml@5.4.1: + js-yaml@5.5.0: dependencies: - argparse: 2.0.1 + argparse: 3.0.4 json-schema-traverse@1.0.0: {} json-schema-typed@8.0.2: {} - libphonenumber-js@1.13.11: {} + libphonenumber-js@1.13.15: {} lightningcss-android-arm64@1.33.0: optional: true @@ -2418,7 +2417,7 @@ snapshots: ms@2.1.3: {} - nanoid@3.3.18: {} + nanoid@3.3.20: {} negotiator@1.1.0: dependencies: @@ -2435,7 +2434,7 @@ snapshots: on-exit-leak-free@2.1.2: {} - on-finished@2.4.1: + on-finished@2.4.2: dependencies: ee-first: 1.1.1 @@ -2462,11 +2461,11 @@ snapshots: pino-abstract-transport: 3.0.0 pump: 3.0.4 - pino-pretty@13.1.3: + pino-pretty@13.2.0: dependencies: colorette: 2.0.20 dateformat: 4.6.3 - fast-copy: 4.0.4 + fast-copy: 4.3.1 fast-safe-stringify: 2.1.1 help-me: 5.0.0 joycon: 3.1.1 @@ -2474,39 +2473,39 @@ snapshots: on-exit-leak-free: 2.1.2 pino-abstract-transport: 3.0.0 pump: 3.0.4 - secure-json-parse: 4.1.0 - sonic-boom: 4.2.1 + secure-json-parse: 4.1.1 + sonic-boom: 5.0.2 strip-json-comments: 5.0.3 pino-std-serializers@7.1.0: {} - pino@10.3.1: + pino@10.4.0: dependencies: '@pinojs/redact': 0.4.0 atomic-sleep: 1.0.0 on-exit-leak-free: 2.1.2 pino-abstract-transport: 3.0.0 pino-std-serializers: 7.1.0 - process-warning: 5.1.0 + process-warning: 5.1.1 quick-format-unescaped: 4.0.4 - real-require: 0.2.0 + real-require: 1.0.0 safe-stable-stringify: 2.5.0 sonic-boom: 4.2.1 thread-stream: 4.2.0 pkce-challenge@5.0.1: {} - postcss@8.5.26: + postcss@8.5.32: dependencies: - nanoid: 3.3.18 + nanoid: 3.3.20 picocolors: 1.1.1 - source-map-js: 1.2.1 + source-map-js: 1.2.2 - prettier@3.9.6: {} + prettier@3.9.10: {} - process-warning@5.1.0: {} + process-warning@5.1.1: {} - proxy-addr@2.0.7: + proxy-addr@2.0.8: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 @@ -2516,7 +2515,7 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 - qs@6.15.3: + qs@6.17.0: dependencies: es-define-property: 1.0.1 side-channel: 1.1.1 @@ -2532,8 +2531,6 @@ snapshots: iconv-lite: 0.7.3 unpipe: 1.0.0 - real-require@0.2.0: {} - real-require@1.0.0: {} redis-errors@1.2.0: {} @@ -2542,26 +2539,26 @@ snapshots: require-from-string@2.0.2: {} - rolldown@1.2.6: + rolldown@1.2.15: dependencies: - '@oxc-project/types': 0.147.0 + '@oxc-project/types': 0.155.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm-eabi': 1.2.6 - '@rolldown/binding-android-arm64': 1.2.6 - '@rolldown/binding-darwin-arm64': 1.2.6 - '@rolldown/binding-darwin-x64': 1.2.6 - '@rolldown/binding-freebsd-x64': 1.2.6 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.6 - '@rolldown/binding-linux-arm64-gnu': 1.2.6 - '@rolldown/binding-linux-arm64-musl': 1.2.6 - '@rolldown/binding-linux-ppc64-gnu': 1.2.6 - '@rolldown/binding-linux-s390x-gnu': 1.2.6 - '@rolldown/binding-linux-x64-gnu': 1.2.6 - '@rolldown/binding-linux-x64-musl': 1.2.6 - '@rolldown/binding-openharmony-arm64': 1.2.6 - '@rolldown/binding-win32-arm64-msvc': 1.2.6 - '@rolldown/binding-win32-x64-msvc': 1.2.6 + '@rolldown/binding-android-arm-eabi': 1.2.15 + '@rolldown/binding-android-arm64': 1.2.15 + '@rolldown/binding-darwin-arm64': 1.2.15 + '@rolldown/binding-darwin-x64': 1.2.15 + '@rolldown/binding-freebsd-x64': 1.2.15 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.15 + '@rolldown/binding-linux-arm64-gnu': 1.2.15 + '@rolldown/binding-linux-arm64-musl': 1.2.15 + '@rolldown/binding-linux-ppc64-gnu': 1.2.15 + '@rolldown/binding-linux-s390x-gnu': 1.2.15 + '@rolldown/binding-linux-x64-gnu': 1.2.15 + '@rolldown/binding-linux-x64-musl': 1.2.15 + '@rolldown/binding-openharmony-arm64': 1.2.15 + '@rolldown/binding-win32-arm64-msvc': 1.2.15 + '@rolldown/binding-win32-x64-msvc': 1.2.15 router@2.2.0(supports-color@10.2.2): dependencies: @@ -2581,7 +2578,7 @@ snapshots: safer-buffer@2.1.2: {} - secure-json-parse@4.1.0: {} + secure-json-parse@4.1.1: {} semver@7.8.5: {} @@ -2595,7 +2592,7 @@ snapshots: http-errors: 2.0.1 mime-types: 3.0.2 ms: 2.1.3 - on-finished: 2.4.1 + on-finished: 2.4.2 range-parser: 1.3.0 statuses: 2.0.2 transitivePeerDependencies: @@ -2612,38 +2609,38 @@ snapshots: setprototypeof@1.2.0: {} - sharp@0.35.4(@types/node@26.4.0): + sharp@0.35.5(@types/node@26.6.5): dependencies: '@img/colour': 1.1.0 detect-libc: 2.1.2 semver: 7.8.5 optionalDependencies: - '@img/sharp-darwin-arm64': 0.35.4 - '@img/sharp-darwin-x64': 0.35.4 - '@img/sharp-freebsd-wasm32': 0.35.4 - '@img/sharp-libvips-darwin-arm64': 1.3.3 - '@img/sharp-libvips-darwin-x64': 1.3.3 - '@img/sharp-libvips-linux-arm': 1.3.3 - '@img/sharp-libvips-linux-arm64': 1.3.3 - '@img/sharp-libvips-linux-ppc64': 1.3.3 - '@img/sharp-libvips-linux-riscv64': 1.3.3 - '@img/sharp-libvips-linux-s390x': 1.3.3 - '@img/sharp-libvips-linux-x64': 1.3.3 - '@img/sharp-libvips-linuxmusl-arm64': 1.3.3 - '@img/sharp-libvips-linuxmusl-x64': 1.3.3 - '@img/sharp-linux-arm': 0.35.4 - '@img/sharp-linux-arm64': 0.35.4 - '@img/sharp-linux-ppc64': 0.35.4 - '@img/sharp-linux-riscv64': 0.35.4 - '@img/sharp-linux-s390x': 0.35.4 - '@img/sharp-linux-x64': 0.35.4 - '@img/sharp-linuxmusl-arm64': 0.35.4 - '@img/sharp-linuxmusl-x64': 0.35.4 - '@img/sharp-webcontainers-wasm32': 0.35.4 - '@img/sharp-win32-arm64': 0.35.4 - '@img/sharp-win32-ia32': 0.35.4 - '@img/sharp-win32-x64': 0.35.4 - '@types/node': 26.4.0 + '@img/sharp-darwin-arm64': 0.35.5 + '@img/sharp-darwin-x64': 0.35.5 + '@img/sharp-freebsd-wasm32': 0.35.5 + '@img/sharp-libvips-darwin-arm64': 1.3.4 + '@img/sharp-libvips-darwin-x64': 1.3.4 + '@img/sharp-libvips-linux-arm': 1.3.4 + '@img/sharp-libvips-linux-arm64': 1.3.4 + '@img/sharp-libvips-linux-ppc64': 1.3.4 + '@img/sharp-libvips-linux-riscv64': 1.3.4 + '@img/sharp-libvips-linux-s390x': 1.3.4 + '@img/sharp-libvips-linux-x64': 1.3.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.4 + '@img/sharp-libvips-linuxmusl-x64': 1.3.4 + '@img/sharp-linux-arm': 0.35.5 + '@img/sharp-linux-arm64': 0.35.5 + '@img/sharp-linux-ppc64': 0.35.5 + '@img/sharp-linux-riscv64': 0.35.5 + '@img/sharp-linux-s390x': 0.35.5 + '@img/sharp-linux-x64': 0.35.5 + '@img/sharp-linuxmusl-arm64': 0.35.5 + '@img/sharp-linuxmusl-x64': 0.35.5 + '@img/sharp-webcontainers-wasm32': 0.35.5 + '@img/sharp-win32-arm64': 0.35.5 + '@img/sharp-win32-ia32': 0.35.5 + '@img/sharp-win32-x64': 0.35.5 + '@types/node': 26.6.5 shebang-command@2.0.0: dependencies: @@ -2651,7 +2648,7 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.9.0: {} + shell-quote@1.12.0: {} side-channel-list@1.0.1: dependencies: @@ -2685,7 +2682,11 @@ snapshots: dependencies: atomic-sleep: 1.0.0 - source-map-js@1.2.1: {} + sonic-boom@5.0.2: + dependencies: + atomic-sleep: 1.0.0 + + source-map-js@1.2.2: {} split2@4.2.0: {} @@ -2696,12 +2697,12 @@ snapshots: string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 strip-ansi: 7.2.0 strip-ansi@7.2.0: dependencies: - ansi-regex: 6.2.2 + ansi-regex: 6.4.0 strip-json-comments@5.0.3: {} @@ -2720,15 +2721,15 @@ snapshots: tree-kill@1.2.2: {} - ts-node@10.9.2(@types/node@26.4.0)(typescript@6.0.3): + ts-node@10.9.2(@types/node@26.6.5)(typescript@6.0.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.13 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 26.4.0 - acorn: 8.18.0 + '@types/node': 26.6.5 + acorn: 8.19.0 acorn-walk: 8.3.5 arg: 4.1.3 create-require: 1.1.1 @@ -2740,7 +2741,7 @@ snapshots: tslib@2.8.1: {} - tsx@4.23.12: + tsx@4.23.15: dependencies: esbuild: 0.28.2 optionalDependencies: @@ -2754,7 +2755,7 @@ snapshots: typescript@6.0.3: {} - undici-types@8.3.0: {} + undici-types@8.9.0: {} unpipe@1.0.0: {} @@ -2764,31 +2765,31 @@ snapshots: vary@1.1.2: {} - vite-live-preview@0.4.0(vite@8.2.2(@types/node@26.4.0)(esbuild@0.28.2)(tsx@4.23.12)): + vite-live-preview@0.4.0(vite@8.3.5(@types/node@26.6.5)(esbuild@0.28.2)(tsx@4.23.15)): dependencies: '@seahax/deep-copy': 0.1.0 '@seahax/semaphore': 0.5.1 - '@types/ws': 8.18.1 + '@types/ws': 8.18.2 escape-goat: 4.0.0 strip-ansi: 7.2.0 - vite: 8.2.2(@types/node@26.4.0)(esbuild@0.28.2)(tsx@4.23.12) - ws: 8.21.3 + vite: 8.3.5(@types/node@26.6.5)(esbuild@0.28.2)(tsx@4.23.15) + ws: 8.22.0 transitivePeerDependencies: - bufferutil - utf-8-validate - vite@8.2.2(@types/node@26.4.0)(esbuild@0.28.2)(tsx@4.23.12): + vite@8.3.5(@types/node@26.6.5)(esbuild@0.28.2)(tsx@4.23.15): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 - postcss: 8.5.26 - rolldown: 1.2.6 + postcss: 8.5.32 + rolldown: 1.2.15 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 26.4.0 + '@types/node': 26.6.5 esbuild: 0.28.2 fsevents: 2.3.3 - tsx: 4.23.12 + tsx: 4.23.15 which@2.0.2: dependencies: @@ -2802,7 +2803,7 @@ snapshots: wrappy@1.0.2: {} - ws@8.21.3: {} + ws@8.22.0: {} y18n@5.0.8: {} @@ -2819,8 +2820,8 @@ snapshots: yn@3.1.1: {} - zod-to-json-schema@3.25.2(zod@4.4.3): + zod-to-json-schema@3.25.2(zod@4.6.7): dependencies: - zod: 4.4.3 + zod: 4.6.7 - zod@4.4.3: {} + zod@4.6.7: {} From d07a54562f7948e4066dc04073030e016d8e7d3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Thu, 29 Oct 2026 13:46:21 +0100 Subject: [PATCH 09/14] :bug: Add feature flag text-editor-wasm/v1-html-paste (#12689) --- common/src/app/common/features.cljc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/src/app/common/features.cljc b/common/src/app/common/features.cljc index c29b99aee3..e038356b4a 100644 --- a/common/src/app/common/features.cljc +++ b/common/src/app/common/features.cljc @@ -56,6 +56,7 @@ "text-editor/v2-html-paste" "text-editor/v2" "text-editor-wasm/v1" + "text-editor-wasm/v1-html-paste" "render-wasm/v1" "variants/v1"}) @@ -81,6 +82,7 @@ "text-editor/v2-html-paste" "text-editor/v2" "text-editor-wasm/v1" + "text-editor-wasm/v1-html-paste" "tokens/numeric-input" "render-wasm/v1"}) From c70cc5629988d3ad415734d82244226b30e390b3 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 29 Oct 2026 14:09:43 +0000 Subject: [PATCH 10/14] :wrench: Skip build output when stamping the pnpm version The script walks the filesystem, so it stamped generated copies too, such as media-processor/target/package.json: --check counted files git does not track and failed whenever one of those copies was stale. Prune target/ like the other generated trees, with a test for it. Memory: the JDK and ImageMagick image pins have traps the code cannot show, now in workflow/docker-images; memory-maintenance gains the rule that a memory must not restate what the code already says; updating-pnpm notes the lockfile-only refresh. AI-assisted-by: deepseek-v4.1-flash --- .serena/memories/critical-info.md | 1 + .serena/memories/memory-maintenance.md | 1 + .serena/memories/workflow/docker-images.md | 6 ++++++ .serena/memories/workflow/updating-pnpm.md | 5 +++-- scripts/sync-pnpm-version | 5 +++-- scripts/test_sync_pnpm_version.py | 17 +++++++++++++++++ 6 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 .serena/memories/workflow/docker-images.md diff --git a/.serena/memories/critical-info.md b/.serena/memories/critical-info.md index 63bbce922a..fc9133326a 100644 --- a/.serena/memories/critical-info.md +++ b/.serena/memories/critical-info.md @@ -16,6 +16,7 @@ You are working on the GitHub project `penpot/penpot`, a monorepo. - Before `gh issue create` → `mem:workflow/creating-issues` (title derivation, body template, labels, Issue Type) - Before `gh pr create` / `gh pr edit` → `mem:workflow/creating-prs` (title format, body structure, "Note:" line) - Before a repo-wide pnpm version update → `mem:workflow/updating-pnpm` (workspace layout, `scripts/sync-pnpm-version` flow, the stamp-missing-field and ignored-builds gotchas, verification steps) +- Before bumping a non-JS dependency pinned in `docker/images/` (JDK, ImageMagick) → `mem:workflow/docker-images` - **Never `git push`, force-push, or modify `git origin`** (or any other remote). The user pushes from their own shell; if a push is required, say so and wait. Never amend a commit that the user has already pushed unless explicitly asked. - **Never edit `CHANGES.md` by hand.** The changelog is generated from GitHub milestones during the release process; update it only via the `update-changelog` skill flow or on explicit user request. - You have access to the GitHub CLI `gh` or corresponding MCP tools. diff --git a/.serena/memories/memory-maintenance.md b/.serena/memories/memory-maintenance.md index fbb800b99c..67a480a770 100644 --- a/.serena/memories/memory-maintenance.md +++ b/.serena/memories/memory-maintenance.md @@ -26,6 +26,7 @@ No manual line wrapping: one line per bullet or paragraph, however long. Memorie ## Add/update threshold Add or update memories only with stable, non-obvious project conventions that avoid complex rediscovery in the future. +Do not restate what the code already says (comments included): keep only what code cannot represent — decisions and their reasons, cross-file invariants, ordering constraints, environment and tool behavior, and traps that break builds. Do not add: quick-read facts; generic language/framework knowledge; one-off task notes; volatile line-level details; behavior likely to change soon. ## Maintenance Actions diff --git a/.serena/memories/workflow/docker-images.md b/.serena/memories/workflow/docker-images.md new file mode 100644 index 0000000000..28d42bc9e7 --- /dev/null +++ b/.serena/memories/workflow/docker-images.md @@ -0,0 +1,6 @@ +# Non-JS dependencies in the production images + +Node and pnpm pins: `mem:workflow/updating-node` and `mem:workflow/updating-pnpm`. Only the parts the Dockerfiles cannot show: + +- JDK: the image tracks a non-LTS line, so there is no minor to pick — the last build of the line is the ceiling; moving line is a major and needs a real build to validate the `jlink` module list. +- ImageMagick: publish `penpotapp/imagemagick:` **before** bumping the `COPY --from` refs in the backend, exporter and devenv Dockerfiles; otherwise both builds break on the missing tag. diff --git a/.serena/memories/workflow/updating-pnpm.md b/.serena/memories/workflow/updating-pnpm.md index 1bb1596959..e355c47450 100644 --- a/.serena/memories/workflow/updating-pnpm.md +++ b/.serena/memories/workflow/updating-pnpm.md @@ -27,8 +27,8 @@ file (never pipe tool output through filters). members) must carry a `packageManager` field with the identical `pnpm@+sha512.` value. Do not let them drift. `external/` (vendored trees with their own lifecycles), `.opencode/`, - `.pnpm-store/`, `bundles/` and `docker/images/bundle-*` copies are - never stamped. + `.pnpm-store/`, `bundles/`, `target/` build output and + `docker/images/bundle-*` copies are never stamped. - pnpm is a system binary everywhere (devenv image, CI runners, Docker images). Nothing may call corepack: it is gone from Node 25+. pnpm auto-downloads the `packageManager` version on mismatch @@ -60,6 +60,7 @@ file (never pipe tool output through filters). 4. Run `scripts/sync-pnpm-version --install` (plain `pnpm install` in each of the 11 workspace roots) to refresh lockfile metadata, then fix any failing workspace (see gotchas) and re-run that directory. + For a version-only bump, `pnpm install --lockfile-only` in each root is enough: it rewrites only the pnpm self-reference entries and needs no node_modules. The repo-root `pnpm-lock.yaml` is rewritten by itself on the first `pnpm` call that self-installs the target version. ## Gotchas diff --git a/scripts/sync-pnpm-version b/scripts/sync-pnpm-version index e87cf17500..149b072955 100755 --- a/scripts/sync-pnpm-version +++ b/scripts/sync-pnpm-version @@ -27,7 +27,8 @@ Options: -h, --help Show this help. external/ (vendored trees with their own lifecycles), .opencode/, -.pnpm-store/, bundles/ and docker build-context copies are never stamped. +.pnpm-store/, bundles/, build output (target/) and docker build-context +copies are never stamped. EOF } @@ -91,7 +92,7 @@ mapfile -t files < <( find . \ \( -name .git -o -name node_modules -o -name .pnpm-store \ -o -name external -o -name .opencode -o -name bundles \ - -o -name .angular \) -type d -prune \ + -o -name target -o -name .angular \) -type d -prune \ -o -path './docker/images/bundle-*' -prune \ -o -name package.json -type f -print | sort ) diff --git a/scripts/test_sync_pnpm_version.py b/scripts/test_sync_pnpm_version.py index 889250f433..91089632f2 100644 --- a/scripts/test_sync_pnpm_version.py +++ b/scripts/test_sync_pnpm_version.py @@ -134,6 +134,23 @@ class SyncPnpmVersionTests(unittest.TestCase): self.assertNotEqual(proc.returncode, 0) self.assertIn("missing/package.json", proc.stdout + proc.stderr) + def test_target_dirs_are_never_stamped(self): + generated = self.tmp / "module" / "target" + generated.mkdir(parents=True) + package = generated / "package.json" + package.write_text( + '{\n' + ' "name": "generated",\n' + ' "packageManager": "pnpm@10.0.0+sha512.' + "00" * 64 + '"\n' + '}\n' + ) + before = package.read_bytes() + + self.assertEqual(self.stamp().returncode, 0) + self.assertEqual(package.read_bytes(), before) + # The stale copy must not make --check fail either. + self.assertEqual(self.stamp("--check").returncode, 0) + def test_stamp_is_idempotent(self): self.assertEqual(self.stamp().returncode, 0) first = { From 857c6660223a8a570612851b036804a21e401c54 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 29 Oct 2026 14:09:54 +0000 Subject: [PATCH 11/14] :arrow_up: Update pnpm to 12.16.1 and node to 24.22.2 pnpm 12.5.1 -> 12.16.1: the tarball pin of docker/devenv and of the media-processor, exporter and mcp images, the packageManager field of every workspace manifest, and the lockfile metadata of the 11 workspaces. The new pnpm also normalizes one engine range per lockfile (>=18.* to >=18). node 24.21.0 -> 24.22.2: devenv NODE_VERSION and both NODE_SHA256, .nvmrc, and the runtime pin of the two plugins-deploy workflows. The dhi.io image tags stay as they are until their digests are available. AI-assisted-by: deepseek-v4.1-flash --- .github/workflows/plugins-deploy-api-doc.yml | 2 +- .../workflows/plugins-deploy-styles-doc.yml | 2 +- .nvmrc | 2 +- backend/package.json | 2 +- backend/pnpm-lock.yaml | 124 +++++++++--------- common/package.json | 2 +- common/pnpm-lock.yaml | 124 +++++++++--------- docker/devenv/Dockerfile | 12 +- docker/images/Dockerfile.exporter | 6 +- docker/images/Dockerfile.mcp | 6 +- docker/images/Dockerfile.media-processor | 6 +- docs/package.json | 2 +- docs/pnpm-lock.yaml | 124 +++++++++--------- exporter/package.json | 2 +- exporter/pnpm-lock.yaml | 124 +++++++++--------- frontend/package.json | 2 +- frontend/packages/draft-js/package.json | 2 +- frontend/packages/mousetrap/package.json | 2 +- frontend/packages/tokenscript/package.json | 2 +- frontend/packages/ui/package.json | 2 +- frontend/pnpm-lock.yaml | 124 +++++++++--------- frontend/text-editor/package.json | 2 +- library/package.json | 2 +- library/pnpm-lock.yaml | 124 +++++++++--------- mcp/package.json | 2 +- mcp/packages/common/package.json | 2 +- mcp/packages/plugin/package.json | 2 +- mcp/packages/server/package.json | 2 +- mcp/pnpm-lock.yaml | 124 +++++++++--------- media-processor/package.json | 2 +- media-processor/pnpm-lock.yaml | 124 +++++++++--------- package.json | 2 +- .../apps/colors-to-tokens-plugin/package.json | 2 +- .../apps/composable-test-suite/package.json | 2 +- plugins/apps/contrast-plugin/package.json | 2 +- .../apps/create-palette-plugin/package.json | 2 +- plugins/apps/e2e/package.json | 2 +- plugins/apps/example-styles/package.json | 2 +- plugins/apps/icons-plugin/package.json | 2 +- plugins/apps/lorem-ipsum-plugin/package.json | 2 +- .../apps/plugin-api-test-suite/package.json | 2 +- plugins/apps/poc-state-plugin/package.json | 2 +- plugins/apps/poc-tokens-plugin/package.json | 2 +- .../apps/rename-layers-plugin/package.json | 2 +- plugins/apps/table-plugin/package.json | 2 +- plugins/libs/plugin-types/package.json | 2 +- plugins/libs/plugins-runtime/package.json | 2 +- plugins/libs/plugins-styles/package.json | 2 +- plugins/package.json | 2 +- plugins/pnpm-lock.yaml | 124 +++++++++--------- pnpm-lock.yaml | 124 +++++++++--------- render-wasm/package.json | 2 +- render-wasm/pnpm-lock.yaml | 124 +++++++++--------- 53 files changed, 735 insertions(+), 735 deletions(-) diff --git a/.github/workflows/plugins-deploy-api-doc.yml b/.github/workflows/plugins-deploy-api-doc.yml index f513ba6af9..ed7ec0e978 100644 --- a/.github/workflows/plugins-deploy-api-doc.yml +++ b/.github/workflows/plugins-deploy-api-doc.yml @@ -51,7 +51,7 @@ jobs: uses: pnpm/setup@a0881977cd8ea73b1ed212236c99ca10dcc80cf4 # v3.1.1 with: working-directory: plugins - runtime: node@24.22.1 + runtime: node@24.22.2 install: false - name: Install deps diff --git a/.github/workflows/plugins-deploy-styles-doc.yml b/.github/workflows/plugins-deploy-styles-doc.yml index 65ed5c80f3..72b67fa1cb 100644 --- a/.github/workflows/plugins-deploy-styles-doc.yml +++ b/.github/workflows/plugins-deploy-styles-doc.yml @@ -49,7 +49,7 @@ jobs: uses: pnpm/setup@a0881977cd8ea73b1ed212236c99ca10dcc80cf4 # v3.1.1 with: working-directory: plugins - runtime: node@24.22.1 + runtime: node@24.22.2 install: false - name: Install deps diff --git a/.nvmrc b/.nvmrc index 166aae1151..86456ddf02 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v24.21.0 +v24.22.2 diff --git a/backend/package.json b/backend/package.json index 6b65767aec..8b9dab8ed4 100644 --- a/backend/package.json +++ b/backend/package.json @@ -4,7 +4,7 @@ "license": "MPL-2.0", "author": "Kaleidos INC Sucursal en España SL", "private": true, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "repository": { "type": "git", "url": "https://github.com/penpot/penpot" diff --git a/backend/pnpm-lock.yaml b/backend/pnpm-lock.yaml index ce36558530..8d3278fb84 100644 --- a/backend/pnpm-lock.yaml +++ b/backend/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/common/package.json b/common/package.json index c149915f43..44dd497a55 100644 --- a/common/package.json +++ b/common/package.json @@ -4,7 +4,7 @@ "license": "MPL-2.0", "author": "Kaleidos INC Sucursal en España SL", "private": true, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "type": "module", "repository": { "type": "git", diff --git a/common/pnpm-lock.yaml b/common/pnpm-lock.yaml index 6026b397e6..dd35c2b992 100644 --- a/common/pnpm-lock.yaml +++ b/common/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/docker/devenv/Dockerfile b/docker/devenv/Dockerfile index 81fae7a791..73294cb15d 100644 --- a/docker/devenv/Dockerfile +++ b/docker/devenv/Dockerfile @@ -66,8 +66,8 @@ RUN set -ex; \ FROM base AS setup-node -ENV NODE_VERSION=v24.22.1 \ - PNPM_VERSION=12.15.0 \ +ENV NODE_VERSION=v24.22.2 \ + PNPM_VERSION=12.16.1 \ PATH=/opt/node/bin:$PATH RUN set -eux; \ @@ -76,16 +76,16 @@ RUN set -eux; \ aarch64|arm64) \ OPENSSL_ARCH='linux-aarch64'; \ BINARY_URL="https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-arm64.tar.gz"; \ - NODE_SHA256='33c37be234ba8bee041961047b19160f4d7d0f164e8e246f78bdd10feff148b3'; \ + NODE_SHA256='95c264150aceb7f3437a29fd6984924f5f8d1511ea3cbd6c508b83f6c555dae2'; \ PNPM_ARCH='arm64'; \ - PNPM_SHA256='d7ce93a2c7d847d3a34bd3f559b60c14f578b1320c17cc352a2c5c5fdf956117'; \ + PNPM_SHA256='f5847699e5d528f8f8e9bcfb385e58cb9fba7482af1b1aa7b70737be42277f81'; \ ;; \ amd64|x86_64) \ OPENSSL_ARCH='linux-x86_64'; \ BINARY_URL="https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-x64.tar.gz"; \ - NODE_SHA256='eb6728e77c576a35162c122c45ccadf224d89ff00abc8dae46cc2897c6002d7c'; \ + NODE_SHA256='361718c444e49af2ca5a110c83ba6a8901143f23ab285ebbef0341f391f482a9'; \ PNPM_ARCH='x64'; \ - PNPM_SHA256='55b5ed0092bd11176c1669598e231ae52e7cedac59de6efd0d415730f37d0598'; \ + PNPM_SHA256='565ff81174a14f6f7bd5d84c1b17e51031a80230d370a1fe24be5d16bd02a825'; \ ;; \ *) \ echo "Unsupported arch: ${ARCH}"; \ diff --git a/docker/images/Dockerfile.exporter b/docker/images/Dockerfile.exporter index 97daca2dfe..30186f3a9b 100644 --- a/docker/images/Dockerfile.exporter +++ b/docker/images/Dockerfile.exporter @@ -95,17 +95,17 @@ WORKDIR /opt/penpot/exporter # pnpm ships as a system binary (same tarball + SHA pin as # docker/devenv/Dockerfile); the generated ./setup expects it on PATH. # Corepack is gone from Node 25+, so nothing here may use it. -ARG PNPM_VERSION=12.15.0 +ARG PNPM_VERSION=12.16.1 RUN set -eux; \ ARCH="$(dpkg --print-architecture)"; \ case "${ARCH}" in \ aarch64|arm64) \ PNPM_ARCH='arm64'; \ - PNPM_SHA256='d7ce93a2c7d847d3a34bd3f559b60c14f578b1320c17cc352a2c5c5fdf956117'; \ + PNPM_SHA256='f5847699e5d528f8f8e9bcfb385e58cb9fba7482af1b1aa7b70737be42277f81'; \ ;; \ amd64|x86_64) \ PNPM_ARCH='x64'; \ - PNPM_SHA256='55b5ed0092bd11176c1669598e231ae52e7cedac59de6efd0d415730f37d0598'; \ + PNPM_SHA256='565ff81174a14f6f7bd5d84c1b17e51031a80230d370a1fe24be5d16bd02a825'; \ ;; \ *) \ echo "Unsupported arch: ${ARCH}"; \ diff --git a/docker/images/Dockerfile.mcp b/docker/images/Dockerfile.mcp index f018302d33..475df43098 100644 --- a/docker/images/Dockerfile.mcp +++ b/docker/images/Dockerfile.mcp @@ -11,7 +11,7 @@ WORKDIR /opt/penpot/mcp # pnpm ships as a system binary (same tarball + SHA pin as # docker/devenv/Dockerfile); ./setup expects it on PATH. # Corepack is gone from Node 25+, so nothing here may use it. -ARG PNPM_VERSION=12.15.0 +ARG PNPM_VERSION=12.16.1 RUN set -eux; \ apt-get -qq update; \ apt-get -qqy --no-install-recommends install curl ca-certificates gzip; \ @@ -20,11 +20,11 @@ RUN set -eux; \ case "${ARCH}" in \ aarch64|arm64) \ PNPM_ARCH='arm64'; \ - PNPM_SHA256='d7ce93a2c7d847d3a34bd3f559b60c14f578b1320c17cc352a2c5c5fdf956117'; \ + PNPM_SHA256='f5847699e5d528f8f8e9bcfb385e58cb9fba7482af1b1aa7b70737be42277f81'; \ ;; \ amd64|x86_64) \ PNPM_ARCH='x64'; \ - PNPM_SHA256='55b5ed0092bd11176c1669598e231ae52e7cedac59de6efd0d415730f37d0598'; \ + PNPM_SHA256='565ff81174a14f6f7bd5d84c1b17e51031a80230d370a1fe24be5d16bd02a825'; \ ;; \ *) \ echo "Unsupported arch: ${ARCH}"; \ diff --git a/docker/images/Dockerfile.media-processor b/docker/images/Dockerfile.media-processor index ee0694bc34..6d00d1eba4 100644 --- a/docker/images/Dockerfile.media-processor +++ b/docker/images/Dockerfile.media-processor @@ -58,7 +58,7 @@ WORKDIR /opt/penpot/media-processor # pnpm ships as a system binary (same tarball + SHA pin as # docker/devenv/Dockerfile); ./setup expects it on PATH. # Corepack is gone from Node 25+, so nothing here may use it. -ARG PNPM_VERSION=12.15.0 +ARG PNPM_VERSION=12.16.1 RUN set -eux; \ apt-get -qq update; \ apt-get -qqy --no-install-recommends install gzip; \ @@ -67,11 +67,11 @@ RUN set -eux; \ case "${ARCH}" in \ aarch64|arm64) \ PNPM_ARCH='arm64'; \ - PNPM_SHA256='d7ce93a2c7d847d3a34bd3f559b60c14f578b1320c17cc352a2c5c5fdf956117'; \ + PNPM_SHA256='f5847699e5d528f8f8e9bcfb385e58cb9fba7482af1b1aa7b70737be42277f81'; \ ;; \ amd64|x86_64) \ PNPM_ARCH='x64'; \ - PNPM_SHA256='55b5ed0092bd11176c1669598e231ae52e7cedac59de6efd0d415730f37d0598'; \ + PNPM_SHA256='565ff81174a14f6f7bd5d84c1b17e51031a80230d370a1fe24be5d16bd02a825'; \ ;; \ *) \ echo "Unsupported arch: ${ARCH}"; \ diff --git a/docs/package.json b/docs/package.json index 8a9c016f80..7d1040f05e 100644 --- a/docs/package.json +++ b/docs/package.json @@ -39,5 +39,5 @@ "markdown-it-anchor": "^9.2.1", "markdown-it-plantuml": "^1.4.1" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 0ca49e8270..cd379d7e6f 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/exporter/package.json b/exporter/package.json index db033dbf2f..3293d3c825 100644 --- a/exporter/package.json +++ b/exporter/package.json @@ -4,7 +4,7 @@ "license": "MPL-2.0", "author": "Kaleidos INC Sucursal en España SL", "private": true, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "repository": { "type": "git", "url": "https://github.com/penpot/penpot" diff --git a/exporter/pnpm-lock.yaml b/exporter/pnpm-lock.yaml index ec66e081a4..9ab3e227ce 100644 --- a/exporter/pnpm-lock.yaml +++ b/exporter/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/frontend/package.json b/frontend/package.json index 894e6e651d..bf5d259f09 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,7 +4,7 @@ "license": "MPL-2.0", "author": "Kaleidos INC Sucursal en España SL", "private": true, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "browserslist": [ "defaults" ], diff --git a/frontend/packages/draft-js/package.json b/frontend/packages/draft-js/package.json index d257b4bec2..6531f4ca78 100644 --- a/frontend/packages/draft-js/package.json +++ b/frontend/packages/draft-js/package.json @@ -4,7 +4,7 @@ "description": "Penpot Draft-JS Wrapper", "main": "index.js", "type": "module", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "author": "Andrey Antukh", "license": "MPL-2.0", "dependencies": { diff --git a/frontend/packages/mousetrap/package.json b/frontend/packages/mousetrap/package.json index e71ccbf825..a194a05ba3 100644 --- a/frontend/packages/mousetrap/package.json +++ b/frontend/packages/mousetrap/package.json @@ -4,7 +4,7 @@ "description": "Simple library for handling keyboard shortcuts", "main": "index.js", "type": "module", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "author": "Craig Campbell", "license": "Apache-2.0 WITH LLVM-exception" } diff --git a/frontend/packages/tokenscript/package.json b/frontend/packages/tokenscript/package.json index 32d7442bf5..a7d149ce62 100644 --- a/frontend/packages/tokenscript/package.json +++ b/frontend/packages/tokenscript/package.json @@ -4,7 +4,7 @@ "description": "", "main": "index.js", "type": "module", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "author": "Andrey Antukh", "license": "MPL-2.0", "dependencies": { diff --git a/frontend/packages/ui/package.json b/frontend/packages/ui/package.json index 38657cbad1..bff1b5d7b9 100644 --- a/frontend/packages/ui/package.json +++ b/frontend/packages/ui/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "types": "./dist/index.d.ts", "type": "module", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "exports": { ".": { "import": "./dist/index.js" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index eb187d1c4a..9b8c98ab5a 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/frontend/text-editor/package.json b/frontend/text-editor/package.json index 94d61aaaaa..7da3b29ec6 100644 --- a/frontend/text-editor/package.json +++ b/frontend/text-editor/package.json @@ -28,5 +28,5 @@ "vite": "^8.2.0", "vitest": "^4.1.10" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/library/package.json b/library/package.json index deb8096254..bb55132370 100644 --- a/library/package.json +++ b/library/package.json @@ -3,7 +3,7 @@ "version": "1.2.0", "license": "MPL-2.0", "author": "KALEIDOS SUBSIDIARY SL", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "type": "module", "repository": { "type": "git", diff --git a/library/pnpm-lock.yaml b/library/pnpm-lock.yaml index 8b8daa71b9..d9519ec0ac 100644 --- a/library/pnpm-lock.yaml +++ b/library/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/mcp/package.json b/mcp/package.json index 2b89cf1abc..97012b38b0 100644 --- a/mcp/package.json +++ b/mcp/package.json @@ -23,7 +23,7 @@ "type": "git", "url": "https://github.com/penpot/penpot.git" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "devDependencies": { "concurrently": "^10.0.6", "prettier": "^3.9.10" diff --git a/mcp/packages/common/package.json b/mcp/packages/common/package.json index 4e3dda0cc8..6ddd0bd605 100644 --- a/mcp/packages/common/package.json +++ b/mcp/packages/common/package.json @@ -4,7 +4,7 @@ "description": "Shared type definitions and interfaces for Penpot MCP", "main": "dist/index.js", "types": "dist/index.d.ts", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "scripts": { "build": "tsc --build --clean && tsc --build", "watch": "tsc --watch", diff --git a/mcp/packages/plugin/package.json b/mcp/packages/plugin/package.json index 6155889516..68ed69afa9 100644 --- a/mcp/packages/plugin/package.json +++ b/mcp/packages/plugin/package.json @@ -3,7 +3,7 @@ "private": true, "version": "1.0.0", "type": "module", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "scripts": { "start": "vite build --watch --config vite.config.ts", "start:multi-user": "pnpm run start", diff --git a/mcp/packages/server/package.json b/mcp/packages/server/package.json index 4fb0e12d41..9bd11569a7 100644 --- a/mcp/packages/server/package.json +++ b/mcp/packages/server/package.json @@ -24,7 +24,7 @@ ], "author": "", "license": "MIT", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "dependencies": { "@modelcontextprotocol/sdk": "^1.32.2", "class-transformer": "^0.5.1", diff --git a/mcp/pnpm-lock.yaml b/mcp/pnpm-lock.yaml index 0e558241f2..00c59046a8 100644 --- a/mcp/pnpm-lock.yaml +++ b/mcp/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/media-processor/package.json b/media-processor/package.json index 8190c530bf..110fdbb7c3 100644 --- a/media-processor/package.json +++ b/media-processor/package.json @@ -14,7 +14,7 @@ "fmt:check": "prettier --check src/ test/", "clean": "rm -rf dist/" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "dependencies": { "express": "^5.2.1", "multer": "^2.2.0", diff --git a/media-processor/pnpm-lock.yaml b/media-processor/pnpm-lock.yaml index 98803e8f77..f09b091862 100644 --- a/media-processor/pnpm-lock.yaml +++ b/media-processor/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/package.json b/package.json index 150214c26f..5779c600b5 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "license": "MPL-2.0", "author": "Kaleidos INC Sucursal en España SL", "private": true, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "repository": { "type": "git", "url": "https://github.com/penpot/penpot" diff --git a/plugins/apps/colors-to-tokens-plugin/package.json b/plugins/apps/colors-to-tokens-plugin/package.json index 30715f65e5..4c9690e2a2 100644 --- a/plugins/apps/colors-to-tokens-plugin/package.json +++ b/plugins/apps/colors-to-tokens-plugin/package.json @@ -13,5 +13,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/composable-test-suite/package.json b/plugins/apps/composable-test-suite/package.json index dbdc016c54..15d544f0af 100644 --- a/plugins/apps/composable-test-suite/package.json +++ b/plugins/apps/composable-test-suite/package.json @@ -27,5 +27,5 @@ "vite": "^8.2.2", "vite-live-preview": "^0.4.0" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/contrast-plugin/package.json b/plugins/apps/contrast-plugin/package.json index ee854f007f..641618631d 100644 --- a/plugins/apps/contrast-plugin/package.json +++ b/plugins/apps/contrast-plugin/package.json @@ -13,5 +13,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/create-palette-plugin/package.json b/plugins/apps/create-palette-plugin/package.json index c99b93bf8c..d52baaa757 100644 --- a/plugins/apps/create-palette-plugin/package.json +++ b/plugins/apps/create-palette-plugin/package.json @@ -12,5 +12,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/e2e/package.json b/plugins/apps/e2e/package.json index c0501e2733..d9c64e6bac 100644 --- a/plugins/apps/e2e/package.json +++ b/plugins/apps/e2e/package.json @@ -7,5 +7,5 @@ "test": "vitest", "lint": "eslint ." }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/example-styles/package.json b/plugins/apps/example-styles/package.json index 714fe4228d..227f8b7a9f 100644 --- a/plugins/apps/example-styles/package.json +++ b/plugins/apps/example-styles/package.json @@ -11,5 +11,5 @@ "serve": "vite preview", "lint": "eslint ." }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/icons-plugin/package.json b/plugins/apps/icons-plugin/package.json index 4c6eee5406..31f25c5e8a 100644 --- a/plugins/apps/icons-plugin/package.json +++ b/plugins/apps/icons-plugin/package.json @@ -13,5 +13,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/lorem-ipsum-plugin/package.json b/plugins/apps/lorem-ipsum-plugin/package.json index 6e1dcc3de4..f5d5be5541 100644 --- a/plugins/apps/lorem-ipsum-plugin/package.json +++ b/plugins/apps/lorem-ipsum-plugin/package.json @@ -13,5 +13,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/plugin-api-test-suite/package.json b/plugins/apps/plugin-api-test-suite/package.json index e49ce3dcf1..177c514477 100644 --- a/plugins/apps/plugin-api-test-suite/package.json +++ b/plugins/apps/plugin-api-test-suite/package.json @@ -20,5 +20,5 @@ "devDependencies": { "playwright": "^1.62.1" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/poc-state-plugin/package.json b/plugins/apps/poc-state-plugin/package.json index 7c593ede9f..df5bc13b27 100644 --- a/plugins/apps/poc-state-plugin/package.json +++ b/plugins/apps/poc-state-plugin/package.json @@ -13,5 +13,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/poc-tokens-plugin/package.json b/plugins/apps/poc-tokens-plugin/package.json index 06fcd3e9cc..41337275df 100644 --- a/plugins/apps/poc-tokens-plugin/package.json +++ b/plugins/apps/poc-tokens-plugin/package.json @@ -13,5 +13,5 @@ "lint": "eslint .", "test": "exit 0" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/rename-layers-plugin/package.json b/plugins/apps/rename-layers-plugin/package.json index ca69e49f14..38eb1e0939 100644 --- a/plugins/apps/rename-layers-plugin/package.json +++ b/plugins/apps/rename-layers-plugin/package.json @@ -13,5 +13,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/apps/table-plugin/package.json b/plugins/apps/table-plugin/package.json index be103b05ff..f2bc2d696b 100644 --- a/plugins/apps/table-plugin/package.json +++ b/plugins/apps/table-plugin/package.json @@ -13,5 +13,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/libs/plugin-types/package.json b/plugins/libs/plugin-types/package.json index 0f0da1e1e3..e4959293fa 100644 --- a/plugins/libs/plugin-types/package.json +++ b/plugins/libs/plugin-types/package.json @@ -7,5 +7,5 @@ "build": "node ../../tools/scripts/build-types.mjs", "lint": "tsc -p . --noEmit" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/libs/plugins-runtime/package.json b/plugins/libs/plugins-runtime/package.json index cf15cc95aa..ac294ebe8d 100644 --- a/plugins/libs/plugins-runtime/package.json +++ b/plugins/libs/plugins-runtime/package.json @@ -16,5 +16,5 @@ "lint": "eslint .", "test": "vitest" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/libs/plugins-styles/package.json b/plugins/libs/plugins-styles/package.json index 301ac323ef..5badd11056 100644 --- a/plugins/libs/plugins-styles/package.json +++ b/plugins/libs/plugins-styles/package.json @@ -6,5 +6,5 @@ "build": "node ../../tools/scripts/build-css.mjs", "lint": "echo 0" }, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f" + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1" } diff --git a/plugins/package.json b/plugins/package.json index 912a0a7f70..f953a80d17 100644 --- a/plugins/package.json +++ b/plugins/package.json @@ -3,7 +3,7 @@ "version": "0.6.0", "type": "module", "license": "MIT", - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "scripts": { "start": "pnpm run start:app:runtime", "start:app:runtime": "concurrently --kill-others --names build,server \"pnpm --filter @penpot/plugins-runtime run build:watch\" \"pnpm --filter @penpot/plugins-runtime run preview\"", diff --git a/plugins/pnpm-lock.yaml b/plugins/pnpm-lock.yaml index 0f3df9cca1..b3bfec17f4 100644 --- a/plugins/pnpm-lock.yaml +++ b/plugins/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6ef1b2c144..a52d2188bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' diff --git a/render-wasm/package.json b/render-wasm/package.json index 4b56c15f73..f1f4b196ab 100644 --- a/render-wasm/package.json +++ b/render-wasm/package.json @@ -4,7 +4,7 @@ "license": "MPL-2.0", "author": "Kaleidos INC Sucursal en España SL", "private": true, - "packageManager": "pnpm@12.5.1+sha512.e3f305bc784a2bc89f5ad3b6138889470fae8d2af5f36b61216ec91c2c3d64089775f9de38aac331044ea40f245cb0d5666392dfdf65824e1907ef6a2c62de5f", + "packageManager": "pnpm@12.16.1+sha512.091d1dee7927575661b25dab3c2ae31cafc1c54d6b71ed6a6600cf0c1cb10434a447eae14015f1b23e2e6bedeed79df94a932e2164d2832280dce3fb32f656d1", "repository": { "type": "git", "url": "https://github.com/penpot/penpot" diff --git a/render-wasm/pnpm-lock.yaml b/render-wasm/pnpm-lock.yaml index c00e4d1b27..a0180171fa 100644 --- a/render-wasm/pnpm-lock.yaml +++ b/render-wasm/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.16.1 + version: 12.16.1 packages: - '@pnpm/exe.android-arm64@12.5.1': - resolution: {integrity: sha512-6LGBmQuDzUmgpHSuy+haG0jrmkwFNa4EuShDZqK3cIBv4Wfb75CzjJmowkzr+iJg40vnBKMQ62t4Ko6mwsId7A==} + '@pnpm/exe.android-arm64@12.16.1': + resolution: {integrity: sha512-PKf78Ew+i0CBYf0Xc+eMcqQiqyBT+u8XCVg1F5roc98/6wWfdYlWhrUMmEBiKWaJ3JqHxrtt8l1NwZ7qfJt2/Q==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.5.1': - resolution: {integrity: sha512-091oCltP3Rx89yxL1Wh5rXkUXEyFzyxIzSHKRFDyDFlQkb8Ox8FaDcm+M8PNkMyqnLA+qeGOLzY7Rjj9izl1Ww==} + '@pnpm/exe.android-x64@12.16.1': + resolution: {integrity: sha512-xdu7gMbB98pdvhwMeA6612Of515FDlRUtfA/1f7nWPZfPLnEdSRBO2u+1N0XBtQ/ennhPH/lrxB1gC6gnR/cdg==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.5.1': - resolution: {integrity: sha512-r1vEMQPVjRexZMyL2HonxJoo3+nuB/+G+tg+f2PK6faRdXX1TDwevKXOxJAfqlPInTy6W/pm912+s+m0NcR4BQ==} + '@pnpm/exe.darwin-arm64@12.16.1': + resolution: {integrity: sha512-pVbmIIbhixiLvADLu1WA3TaW8FZy/D72R1De27WbbFx8/2mxvnsTyFVm4fO9kjpjMY7RzJd48CiQ96p8fO3ebQ==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.5.1': - resolution: {integrity: sha512-YHwI1g2B+Y2cAEylOR31r781GWijdJL7Gy7TEn/ZpZ5v/Cuwp5/Pz0EFCgo0M2MKLafAbL/laUMGvOpAdnerAw==} + '@pnpm/exe.darwin-x64@12.16.1': + resolution: {integrity: sha512-xZvQBFqcZjO7vFKTK3XsJpqY6lnBL9EWSLCzVUPq3kZ94+D96gwJCa76xxGNK8Cj32f4eeM91Qg+yNRR4sRpDw==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.5.1': - resolution: {integrity: sha512-sFUMHiYFs6q5syFwgaVppzhQSmqnXoJIz/YwTXIOXTDE76ndIpTRpDGAnBCBKjsaEBnqjJA/2l6hpJcNDNoMiA==} + '@pnpm/exe.freebsd-x64@12.16.1': + resolution: {integrity: sha512-zTtunfi9mBhRXiXEJYfwiJj0tk7MgTSfqDSRh+Az9FZ9THazVIiQiVNS8jpcsftDOqu7LKNffQdjmgwHDThfUg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.5.1': - resolution: {integrity: sha512-zupuxYZBuBEGjUz805/4/Asq01UNziFADANt8yp+LdUjU9bbMa3xY78Bx1PsGDqBy7aiad4sdUMK8ZxH4n4gmQ==} + '@pnpm/exe.linux-arm64-musl@12.16.1': + resolution: {integrity: sha512-BJ3mOmcmQgcUo92Ee/WfEOt1pRiv3y2MMAkhEiYHd85UiPpHTfFhv+SpCbALmfExzXk3UlaRtMYwHlkQymc4VA==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.5.1': - resolution: {integrity: sha512-6hbMWW2/eQo1b5wvQPe/ndLHVTH88Rav6N+ffD4/h6IuFMjWCgasFYYsFv0GrvpqREAx3SwmZSvli+0NFXqbxA==} + '@pnpm/exe.linux-arm64@12.16.1': + resolution: {integrity: sha512-JaRd5gNxwdNGBBkrZFt8bknrK4YmHVJBW0JMhUQ0fJ0dEYp6C2GT9ExaCqOO8EwYEyqM+jpKgJIK+8WFaJy3ew==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.5.1': - resolution: {integrity: sha512-Gg3maDzaE/ZFMV9HIx/BwMN0Y6QbEs13URfxmiYHtKjjLAs5wEQZRMUP87YNLYO7cNaEfbM8GRbS9vPosyD9Gw==} + '@pnpm/exe.linux-ppc64@12.16.1': + resolution: {integrity: sha512-FnSV0Jv40S1cMv7vFNWwvu0X567Lec4L4HCRead3CFcD6zQDNbGw81s8N5bcKPahtPD9ApVuhsbmFCx4rw6RMw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.5.1': - resolution: {integrity: sha512-6fgWxXYMBMsWQ8DAiRevscX4QZQjwh+FsyCj8ZOk8pMXvqeq84MqBLCmS6KckvnbdqJ+HlSVQ7fs/kd0ldwfhA==} + '@pnpm/exe.linux-riscv64@12.16.1': + resolution: {integrity: sha512-C1Sww4FN5IttD4atRRhAKmQtSGWVp04ZAKNxO8pfu2bkRPwOW+7v+2DH1Xs1W+kZYYpO86BYDvUcadefF+AgaQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.5.1': - resolution: {integrity: sha512-nzMZruRvxDhEfYUhzu+7EmM39+82Dgagc/6hPFPqGqzXNGcIG0anuxbUxfeNtI64SHt91KuuYUmCB/inlM+Pag==} + '@pnpm/exe.linux-s390x@12.16.1': + resolution: {integrity: sha512-kn2fautsTcxIMODoovQVqZyfpDRdNgGkoeVqNdrKqbeBBvrEl+fXLkmZiq5xDht1LMr4sYiCNcsMfNMT6JPFmg==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.5.1': - resolution: {integrity: sha512-kHCbegdTNHpzmPtUD4S5fqkVkqgdQR47spF9p2VPP3dIIkZl6Ytk8w0vhlAsAGgge8FmucfwX+vvPKgm0NtOCQ==} + '@pnpm/exe.linux-x64-musl@12.16.1': + resolution: {integrity: sha512-PM6ccHCOe/O9SsTflTJTYWfwogJZa6EmUvpnwZgiPguJBddh20wDQKgxUPXf48rDsPm9vMsIij0uHswwwbXL8g==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.5.1': - resolution: {integrity: sha512-3PkUBYo5z4dgtlnTNIFj7QGpcDUAuqXz9WGVigPDCeccEnhGiRkWmA5102TmYJHtwJP3LfmE+ZF9PGeWhn8p9Q==} + '@pnpm/exe.linux-x64@12.16.1': + resolution: {integrity: sha512-RK//8ZLcXGW8A2k8bQOXZDBN1Qu92zN4dYnG1bzj1zoQ1fkZ6jNzZ1AvXtsfGVma795CJtvoaF5bLXf4l/FIUw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.5.1': - resolution: {integrity: sha512-49NvjZIXHly56/PLoEDD7VphbO4N8dwMXoApElDFCpVGDNGeKlwlib1tXtnpTF6i2/XIsAj7GgatHB5KHXgBnA==} + '@pnpm/exe.win32-arm64@12.16.1': + resolution: {integrity: sha512-Ox3kNNVxtGw6pK7SVejmeOUgHhUTZgAM7NQQ6cU7frPw3ix9+j7d2MGbRg3fyEFAaKWq8ZAZLTQGcDyLnAu+qA==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.5.1': - resolution: {integrity: sha512-ePUmQFPAPJFNMwg1lelDx2PdjHqYRiF0yfg5e6qeDbPNOu97QNo557Ru/SxmCrmt8ydQWNuZXWpdEp019md5vw==} + '@pnpm/exe.win32-x64@12.16.1': + resolution: {integrity: sha512-k+FhRJ0ttphFoFIVB1Sk4v76YJAulafmA/Ly57cysesUhhIzVlApeOShUz0jXubKx317TThlEfpQrukldnqORA==} cpu: [x64] os: [win32] - pnpm@12.5.1: - resolution: {integrity: sha512-4/MFvHhKK8ifWtO2E4iJRw+ujSr182thIW7JHCw9ZAiXdfneOKrDMQROpA8kXLDVZmOS399lgk4ZB+9qLGLeXw==} - engines: {node: '>=18.*'} + pnpm@12.16.1: + resolution: {integrity: sha512-CR0d7nknV1Zhsl2rPCrjHK/BxU1rce1qZgDPDByxBDSkR+rhQBXxsj4ua+3u1535SpMuIWTSgyKA3OP7MvZW0Q==} + engines: {node: '>=18'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.5.1': + '@pnpm/exe.android-arm64@12.16.1': optional: true - '@pnpm/exe.android-x64@12.5.1': + '@pnpm/exe.android-x64@12.16.1': optional: true - '@pnpm/exe.darwin-arm64@12.5.1': + '@pnpm/exe.darwin-arm64@12.16.1': optional: true - '@pnpm/exe.darwin-x64@12.5.1': + '@pnpm/exe.darwin-x64@12.16.1': optional: true - '@pnpm/exe.freebsd-x64@12.5.1': + '@pnpm/exe.freebsd-x64@12.16.1': optional: true - '@pnpm/exe.linux-arm64-musl@12.5.1': + '@pnpm/exe.linux-arm64-musl@12.16.1': optional: true - '@pnpm/exe.linux-arm64@12.5.1': + '@pnpm/exe.linux-arm64@12.16.1': optional: true - '@pnpm/exe.linux-ppc64@12.5.1': + '@pnpm/exe.linux-ppc64@12.16.1': optional: true - '@pnpm/exe.linux-riscv64@12.5.1': + '@pnpm/exe.linux-riscv64@12.16.1': optional: true - '@pnpm/exe.linux-s390x@12.5.1': + '@pnpm/exe.linux-s390x@12.16.1': optional: true - '@pnpm/exe.linux-x64-musl@12.5.1': + '@pnpm/exe.linux-x64-musl@12.16.1': optional: true - '@pnpm/exe.linux-x64@12.5.1': + '@pnpm/exe.linux-x64@12.16.1': optional: true - '@pnpm/exe.win32-arm64@12.5.1': + '@pnpm/exe.win32-arm64@12.16.1': optional: true - '@pnpm/exe.win32-x64@12.5.1': + '@pnpm/exe.win32-x64@12.16.1': optional: true - pnpm@12.5.1: + pnpm@12.16.1: optionalDependencies: - '@pnpm/exe.android-arm64': 12.5.1 - '@pnpm/exe.android-x64': 12.5.1 - '@pnpm/exe.darwin-arm64': 12.5.1 - '@pnpm/exe.darwin-x64': 12.5.1 - '@pnpm/exe.freebsd-x64': 12.5.1 - '@pnpm/exe.linux-arm64': 12.5.1 - '@pnpm/exe.linux-arm64-musl': 12.5.1 - '@pnpm/exe.linux-ppc64': 12.5.1 - '@pnpm/exe.linux-riscv64': 12.5.1 - '@pnpm/exe.linux-s390x': 12.5.1 - '@pnpm/exe.linux-x64': 12.5.1 - '@pnpm/exe.linux-x64-musl': 12.5.1 - '@pnpm/exe.win32-arm64': 12.5.1 - '@pnpm/exe.win32-x64': 12.5.1 + '@pnpm/exe.android-arm64': 12.16.1 + '@pnpm/exe.android-x64': 12.16.1 + '@pnpm/exe.darwin-arm64': 12.16.1 + '@pnpm/exe.darwin-x64': 12.16.1 + '@pnpm/exe.freebsd-x64': 12.16.1 + '@pnpm/exe.linux-arm64': 12.16.1 + '@pnpm/exe.linux-arm64-musl': 12.16.1 + '@pnpm/exe.linux-ppc64': 12.16.1 + '@pnpm/exe.linux-riscv64': 12.16.1 + '@pnpm/exe.linux-s390x': 12.16.1 + '@pnpm/exe.linux-x64': 12.16.1 + '@pnpm/exe.linux-x64-musl': 12.16.1 + '@pnpm/exe.win32-arm64': 12.16.1 + '@pnpm/exe.win32-x64': 12.16.1 --- lockfileVersion: '9.0' From 41be5bfb5f0df0f6aa97fb8347e2fc5e620834c8 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 29 Oct 2026 15:28:19 +0100 Subject: [PATCH 12/14] :arrow_up: Bump docker base images --- docker/images/Dockerfile.backend | 4 ++-- docker/images/Dockerfile.exporter | 2 +- docker/images/Dockerfile.frontend | 2 +- docker/images/Dockerfile.mcp | 4 ++-- docker/images/Dockerfile.media-processor | 2 +- docker/images/Dockerfile.storybook | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docker/images/Dockerfile.backend b/docker/images/Dockerfile.backend index 32e8c2c1fa..4618c1ba91 100644 --- a/docker/images/Dockerfile.backend +++ b/docker/images/Dockerfile.backend @@ -1,4 +1,4 @@ -FROM dhi.io/debian-base:trixie-debian13-dev@sha256:9b025768946856e44f9775005eb199f2e1820484ea27bb5c8bcbb187b80464dc AS build +FROM dhi.io/debian-base:trixie-debian13-dev@sha256:cc4e05ff415ee2d83918f2af45c737983209924ef7362c53f00cfcdaa1c94326 AS build LABEL maintainer="Penpot " ENV LANG='C.UTF-8' \ @@ -53,7 +53,7 @@ RUN set -eux; \ --output /opt/jre; -FROM dhi.io/debian-base:trixie-debian13-dev@sha256:9b025768946856e44f9775005eb199f2e1820484ea27bb5c8bcbb187b80464dc AS image +FROM dhi.io/debian-base:trixie-debian13-dev@sha256:cc4e05ff415ee2d83918f2af45c737983209924ef7362c53f00cfcdaa1c94326 AS image LABEL maintainer="Penpot " ENV LANG='C.UTF-8' \ diff --git a/docker/images/Dockerfile.exporter b/docker/images/Dockerfile.exporter index 30186f3a9b..b427e0bc80 100644 --- a/docker/images/Dockerfile.exporter +++ b/docker/images/Dockerfile.exporter @@ -1,4 +1,4 @@ -FROM dhi.io/node:24.22.1-debian13-dev@sha256:20cf36e12660c68b1e28887d1e71a7f2494bcea9d034709368e0afce77728eb0 +FROM dhi.io/node:24.22.2-debian13-dev@sha256:53af56f14166cffcf9c4b9ef6f7025d1b0534edddfa1f333c53bd54766f39e5c LABEL maintainer="Penpot " ENV LANG=en_US.UTF-8 \ diff --git a/docker/images/Dockerfile.frontend b/docker/images/Dockerfile.frontend index 26f84d4640..05939a1982 100644 --- a/docker/images/Dockerfile.frontend +++ b/docker/images/Dockerfile.frontend @@ -1,4 +1,4 @@ -FROM dhi.io/nginx:1.31.7-debian13-dev@sha256:940ee353dd807f5c5e32720923bb9b34ef9e631ae567320f3eaea7797d6c7964 +FROM dhi.io/nginx:1.31.8-debian13-dev@sha256:fbff190f9162256975ed225adcc9a294e333897de543fd18be630de1d6c8de17 LABEL maintainer="Penpot " ENV DEBIAN_FRONTEND=noninteractive diff --git a/docker/images/Dockerfile.mcp b/docker/images/Dockerfile.mcp index 475df43098..aac0ff2a38 100644 --- a/docker/images/Dockerfile.mcp +++ b/docker/images/Dockerfile.mcp @@ -1,4 +1,4 @@ -FROM dhi.io/node:24.22.1-debian13-dev@sha256:20cf36e12660c68b1e28887d1e71a7f2494bcea9d034709368e0afce77728eb0 AS build +FROM dhi.io/node:24.22.2-debian13-dev@sha256:53af56f14166cffcf9c4b9ef6f7025d1b0534edddfa1f333c53bd54766f39e5c AS build LABEL maintainer="Penpot " ENV DEBIAN_FRONTEND=noninteractive @@ -42,7 +42,7 @@ RUN set -eux; \ RUN ./setup -FROM dhi.io/node:24.22.1-debian13@sha256:32a2fa6af5209698a9354cef0b19ada3dbfac3090b1010b70afa9f1a298ba2d9 AS image +FROM dhi.io/node:24.22.2-debian13@sha256:24fa6258b891ef66e6c3b7ed82daad550b81cdfcd76f6cc64eee4d2478366747 AS image LABEL maintainer="Penpot " ENV LANG=en_US.UTF-8 \ diff --git a/docker/images/Dockerfile.media-processor b/docker/images/Dockerfile.media-processor index 6d00d1eba4..b2e9eb4af2 100644 --- a/docker/images/Dockerfile.media-processor +++ b/docker/images/Dockerfile.media-processor @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM dhi.io/node:24.22.1-debian13-dev@sha256:20cf36e12660c68b1e28887d1e71a7f2494bcea9d034709368e0afce77728eb0 +FROM dhi.io/node:24.22.2-debian13-dev@sha256:53af56f14166cffcf9c4b9ef6f7025d1b0534edddfa1f333c53bd54766f39e5c LABEL maintainer="Penpot " ENV LANG=en_US.UTF-8 \ diff --git a/docker/images/Dockerfile.storybook b/docker/images/Dockerfile.storybook index 2b259ffb61..4832c60054 100644 --- a/docker/images/Dockerfile.storybook +++ b/docker/images/Dockerfile.storybook @@ -1,4 +1,4 @@ -FROM dhi.io/nginx:1.31.7-alpine3.24@sha256:6d3811fbc76c5d0652752b39a003769759ccfeb2c1e874bacf99e3d44e5da3b9 +FROM dhi.io/nginx:1.31.8-alpine3.24@sha256:83489ce440fa56cb5149c088dbf75422362e45c532c814100253e5ab71871366 LABEL maintainer="Penpot " ARG BUNDLE_PATH="./bundle-storybook/" From 04de86f9393263f896fdd318e8e7a59ca711e00f Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 29 Oct 2026 15:06:43 +0000 Subject: [PATCH 13/14] :sparkles: Add a build task to the local CI orchestrator `./scripts/ci --build` compiles each module the way production does, without going through `manage.sh build-bundle`, which wipes node_modules and reinstalls dependencies. It runs the release commands already defined per module and reuses existing caches, so a broken release build (shadow-cljs optimizations, the wasm targets, the backend uberjar, tsc/typedoc) shows up before a bundle is built. The task is opt-in and runs last, after lint, test and fmt, so the default flow keeps its duration. `common` has no build of its own and reports as skipped. `media-processor` joins as the ninth module, with its lint skipped and `tsc --noEmit` folded into its build. All build outputs are gitignored. `scripts/test_ci.py` covers the flag wiring and one command per module through `--dry-run`; it never runs a real build. AI-assisted-by: deepseek-v4.1-flash --- .agents/skills/local-ci/SKILL.md | 22 ++++- .serena/memories/scripts/ci.md | 72 +++++++++++--- scripts/ci | 38 +++++++- scripts/test_ci.py | 159 +++++++++++++++++++++++++++++++ 4 files changed, 273 insertions(+), 18 deletions(-) create mode 100644 scripts/test_ci.py diff --git a/.agents/skills/local-ci/SKILL.md b/.agents/skills/local-ci/SKILL.md index 5cda6acf89..d04f581dc1 100644 --- a/.agents/skills/local-ci/SKILL.md +++ b/.agents/skills/local-ci/SKILL.md @@ -1,6 +1,6 @@ --- name: local-ci -description: Run local CI-style checks with ./scripts/ci (lint, tests, format) per monorepo module. Use when verifying changes before declaring work done, running lint or tests locally, fixing formatting, or repairing Clojure delimiter errors. +description: Run local CI-style checks with ./scripts/ci (lint, tests, format, and on request production builds) per monorepo module. Use when verifying changes before declaring work done, running lint or tests locally, fixing formatting, repairing Clojure delimiter errors, or checking that a module still compiles. --- # Local CI @@ -29,10 +29,12 @@ Run from the repo root: ``` Modules: `frontend` `backend` `common` `render-wasm` `exporter` `mcp` -`plugins` `library`, or `--all` for every module. +`plugins` `library` `media-processor`, or `--all` for every module. With no task flags it runs three tasks per module, in order: **lint**, -**test**, **fmt** (format check; `--fix` formats files instead). +**test**, **fmt** (format check; `--fix` formats files instead). **build** +is opt-in: it compiles the module the way production does and is the slow +one, so it never runs unless you ask for it. | Flag | Effect | |------|--------| @@ -41,6 +43,7 @@ With no task flags it runs three tasks per module, in order: **lint**, | `--lint` / `--no-lint` | Run only lint / drop lint | | `--test` / `--no-test` | Run only tests / drop tests | | `--fmt` / `--no-fmt` | Run only format check / drop it | +| `--build` / `--no-build` | Run only the production build / drop it | | `--fix` | Format files instead of checking (other tasks unaffected) | | `--paren-repair` | Fix delimiter errors in Clojure/CLJS files | | `--fail-fast` | Stop at the first failure | @@ -72,6 +75,12 @@ log path. # Format the module without running the test suite ./scripts/ci --fix --no-test frontend +# Check that the module still compiles (slow: minutes) +./scripts/ci --build frontend + +# Compile every module (8 builds, ~4 min with warm caches) +./scripts/ci --build --all + # Broke delimiters in Clojure/CLJS files: repair first, then lint ./scripts/ci --paren-repair frontend ./scripts/ci --lint frontend @@ -89,7 +98,12 @@ log path. - Test tasks are long-running (backend runs `clojure -M:dev:test`); give the bash call a generous timeout (10–20 minutes) instead of letting it time out mid-run. -- `mcp` has no lint task — it shows as skipped, not failed. +- `mcp` and `media-processor` have no lint task — they show as skipped, + not failed. `common` has no build task for the same reason. +- Build runs are the slow ones (frontend ~2 min even with warm caches; + cold caches roughly double it). Give the shell a generous timeout and + do not run two builds at once in the same checkout: `render-wasm` takes + a build lock. - `--paren-repair` only fixes delimiters; run lint afterwards to catch what remains. See `mem:scripts/paren-repair`. - What to run and how to read test results: `mem:testing`. diff --git a/.serena/memories/scripts/ci.md b/.serena/memories/scripts/ci.md index e3ee25c614..d236bad383 100644 --- a/.serena/memories/scripts/ci.md +++ b/.serena/memories/scripts/ci.md @@ -1,8 +1,9 @@ # CI (scripts/ci) -`scripts/ci` runs CI-style checks — lint, tests, format — for one or more -monorepo modules and prints a per-task summary. It is the local equivalent -of CI; use it to verify changes before declaring work done. +`scripts/ci` runs CI-style checks — lint, tests, format — and, on request, +the production build of each module, for one or more monorepo modules, and +prints a per-task summary. It is the local equivalent of CI; use it to +verify changes before declaring work done. ## When to use @@ -19,6 +20,7 @@ Run from the repo root: ```bash ./scripts/ci MODULE... # lint + test + fmt per module +./scripts/ci --build MODULE # production build only ./scripts/ci --all --no-test # lint + fmt on all modules ./scripts/ci --lint frontend # lint only ./scripts/ci --fix --no-test frontend # format files, skip tests @@ -26,14 +28,15 @@ Run from the repo root: ./scripts/ci --dry-run --all # preview what would run ``` -Modules: `frontend backend common render-wasm exporter mcp plugins library`. +Modules: `frontend backend common render-wasm exporter mcp plugins library +media-processor`. Flags: - Default tasks: `lint`, `test`, `fmt` (format check; `--fix` formats - instead). -- `--lint` / `--test` / `--fmt` run one task only; `--no-lint` / - `--no-test` / `--no-fmt` drop one task from the default set. + instead). Build is **not** in the default set. +- `--lint` / `--test` / `--fmt` / `--build` run one task only; `--no-lint` / + `--no-test` / `--no-fmt` / `--no-build` drop one task from the default set. - `--paren-repair` runs only the delimiter repair — it wraps `scripts/paren-repair` over each module's Clojure/CLJS sources; see `mem:scripts/paren-repair`. @@ -42,6 +45,49 @@ Flags: output; `--dry-run` prints commands without running; `--clean` removes the log directory. +## Build task + +`--build` compiles each module the way production does, reusing caches +(`.shadow-cljs`, `target/`, `node_modules`) instead of clearing them. It +does not package bundles: `manage.sh build-bundle` remains the way to +produce deployable artifacts. + +| Module | Command | Output | +|---|---|---| +| `frontend` | `NODE_ENV=production pnpm run build:app:main && pnpm run build:app:libs && pnpm run build:app:assets` | `frontend/resources/public/`, `frontend/target/` | +| `backend` | `clojure -T:build jar` | `backend/target/penpot.jar` | +| `common` | *(none; skipped)* | — | +| `render-wasm` | `./build` (targets `frontend` and `export`) | `render-wasm/target/` | +| `exporter` | `NODE_ENV=production pnpm run build:app` | `exporter/target/` | +| `mcp` | `pnpm run build` | `mcp/*/dist` | +| `plugins` | `pnpm run build:runtime && pnpm run build:plugins && pnpm run build:styles-example && pnpm run build:doc` | `plugins/dist/` | +| `library` | `NODE_ENV=production clojure -M:dev:shadow-cljs release library` | `library/target/library/` | +| `media-processor` | `pnpm run types:check && pnpm run build` | `media-processor/dist/` | + +- Every output path above is gitignored, so a build leaves `git status` + clean. +- The module `build` scripts in each `scripts/build` are **not** used: they + delete `node_modules`, wipe `resources/public` and run `pnpm install`, + which belongs to the bundle pipeline, not to a local check. +- `frontend` and `library` have a `build` script that clears the shadow-cljs + cache first; the task calls the inner commands to stay incremental. + `exporter` uses `build:app` for the same reason. +- `common` has no artifact of its own: its compilation is exercised by its + `test` task and by the builds of `frontend`, `backend` and `exporter`. +- `media-processor` is the ninth module. It has no lint, so that task shows + as skipped; its build runs `tsc --noEmit` before esbuild because esbuild + does not type-check. +- Cold-cache cost measured on the devenv: `library` ~120 s, `frontend` ~120 s, + `exporter` ~80 s, `backend` ~35 s. With warm caches the whole set (8 + builds) takes ~4 min. The first run of `clojure -T:build jar` downloads + `tools.build` if it is not in `~/.m2`. +- `pnpm run` may trigger a dependency check/install when `node_modules` + drifts from the lockfile (`verify-deps-before-run`), so the first run + after a dependency change can need network. +- `render-wasm/build` takes a lock (`_build_lock`): never run two builds at + once in the same checkout. + + ## Logs and exit codes - Full output of every task: `.ci-logs/-.log`. @@ -53,12 +99,16 @@ Flags: ## Notes -- `mcp` has no lint task (shows as skipped). `render-wasm` uses `./lint`, - `./test`, and `cargo fmt`. +- `mcp` has no lint task and `media-processor` has no lint task; both show + as skipped. `render-wasm` uses `./lint`, `./test`, and `cargo fmt`. +- `scripts/test_ci.py` (unittest, `python3 scripts/test_ci.py`) covers the + flag wiring, one build command per module and the help text through + `--dry-run`; it executes no real build. - Exports `PENPOT_FLAGS` with `enable-backend-asserts` appended to any existing value, so backend test runs compile in and exercise precondition asserts; see `mem:backend/testing`. -- Test tasks are long-running (backend: `clojure -M:dev:test`); use a - generous timeout when calling it from an agent shell. +- Test and build tasks are long-running (backend: `clojure -M:dev:test`; + frontend build: ~2 min warm); use a generous timeout when calling it from + an agent shell. - Skill entry point: `.agents/skills/local-ci/SKILL.md`. - Testing principles and output discipline: `mem:testing`. diff --git a/scripts/ci b/scripts/ci index 4428b673f9..db58292ae9 100755 --- a/scripts/ci +++ b/scripts/ci @@ -24,7 +24,7 @@ BOLD='\033[1m' NC='\033[0m' # Available modules -ALL_MODULES=("frontend" "backend" "common" "render-wasm" "exporter" "mcp" "plugins" "library") +ALL_MODULES=("frontend" "backend" "common" "render-wasm" "exporter" "mcp" "plugins" "library" "media-processor") # Module commands declare -A LINT_CMD=( @@ -36,6 +36,7 @@ declare -A LINT_CMD=( [mcp]="" [plugins]="pnpm run lint" [library]="pnpm run lint" + [media-processor]="" ) declare -A TEST_CMD=( @@ -47,6 +48,7 @@ declare -A TEST_CMD=( [mcp]="pnpm run test" [plugins]="pnpm run test" [library]="pnpm run test" + [media-processor]="pnpm run test" ) declare -A FMT_CHECK_CMD=( @@ -58,6 +60,7 @@ declare -A FMT_CHECK_CMD=( [mcp]="pnpm run fmt:check" [plugins]="pnpm run format:check" [library]="pnpm run check-fmt:clj" + [media-processor]="pnpm run fmt:check" ) declare -A FMT_FIX_CMD=( @@ -69,6 +72,19 @@ declare -A FMT_FIX_CMD=( [mcp]="pnpm run fmt" [plugins]="pnpm run format" [library]="pnpm run fmt:clj" + [media-processor]="pnpm run fmt" +) + +declare -A BUILD_CMD=( + [frontend]="NODE_ENV=production pnpm run build:app:main && pnpm run build:app:libs && pnpm run build:app:assets" + [backend]="clojure -T:build jar" + [common]="" + [render-wasm]="./build" + [exporter]="NODE_ENV=production pnpm run build:app" + [mcp]="pnpm run build" + [plugins]="pnpm run build:runtime && pnpm run build:plugins && pnpm run build:styles-example && pnpm run build:doc" + [library]="NODE_ENV=production clojure -M:dev:shadow-cljs release library" + [media-processor]="pnpm run types:check && pnpm run build" ) declare -A PAREN_REPAIR_CMD=( @@ -80,6 +96,7 @@ declare -A PAREN_REPAIR_CMD=( [mcp]="" [plugins]="" [library]="find src test -name '*.clj' -o -name '*.cljs' -o -name '*.cljc' | xargs $PROJECT_ROOT/scripts/paren-repair" + [media-processor]="" ) # Default options @@ -197,6 +214,9 @@ run_module() { cmd="${FMT_CHECK_CMD[$module]:-}" fi ;; + build) + cmd="${BUILD_CMD[$module]:-}" + ;; paren-repair) cmd="${PAREN_REPAIR_CMD[$module]:-}" ;; @@ -282,8 +302,8 @@ Usage: $(basename "$0") [OPTIONS] [MODULES...] CI orchestration script for Penpot monorepo. MODULES: - frontend, backend, common, render-wasm, exporter, mcp, plugins, library - Use --all to run all modules. + frontend, backend, common, render-wasm, exporter, mcp, plugins, library, + media-processor. Use --all to run all modules. OPTIONS: --all Run all modules @@ -294,6 +314,8 @@ OPTIONS: --no-test Skip tests --fmt Run format check only --no-fmt Skip format check + --build Run production build only + --no-build Skip build --fix Run format fix instead of check --paren-repair Fix delimiter errors in Clojure/CLJS files --fail-fast Stop on first failure @@ -307,6 +329,8 @@ EXAMPLES: $(basename "$0") frontend backend # Run lint, test, fmt on frontend and backend $(basename "$0") --all --no-test # Run lint and fmt on all modules $(basename "$0") --lint common # Run only lint on common + $(basename "$0") --build frontend # Run only the production build of frontend + $(basename "$0") --build --all # Build every module $(basename "$0") --fix frontend # Fix formatting in frontend $(basename "$0") --paren-repair frontend # Fix delimiter errors in frontend $(basename "$0") --paren-repair --all # Fix delimiter errors in all Clojure modules @@ -353,6 +377,14 @@ main() { TASKS=("${TASKS[@]/fmt/}") shift ;; + --build) + TASKS=("build") + shift + ;; + --no-build) + TASKS=("${TASKS[@]/build/}") + shift + ;; --paren-repair) TASKS=("paren-repair") shift diff --git a/scripts/test_ci.py b/scripts/test_ci.py new file mode 100644 index 0000000000..405f385d8e --- /dev/null +++ b/scripts/test_ci.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python3 +"""Tests for scripts/ci. + +Run with: + + python3 scripts/test_ci.py + +Covers the wiring of the orchestrator around the `build` task and the +`media-processor` module: the flag set, one build command per module, the +help text, the dry-run mode (which must execute and write nothing), and the +default task list staying free of build. +""" + +import pathlib +import re +import subprocess +import sys +import unittest + +sys.dont_write_bytecode = True + +REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent +CI = REPO_ROOT / "scripts" / "ci" +LOG_DIR = REPO_ROOT / ".ci-logs" + +ANSI = re.compile(r"\x1b\[[0-9;]*m") + +# Modules with a production build. `common` has no build of its own: its +# compilation happens in its test task and in the modules consuming it. +BUILD_MODULES = ( + "frontend", + "backend", + "render-wasm", + "exporter", + "mcp", + "plugins", + "library", + "media-processor", +) + +ALL_MODULES = BUILD_MODULES + ("common",) + + +def run_ci(*args, cwd=REPO_ROOT): + """Run scripts/ci and return (exit_code, output without ANSI escapes).""" + proc = subprocess.run( + [str(CI), *args], + cwd=cwd, + capture_output=True, + text=True, + ) + return proc.returncode, ANSI.sub("", proc.stdout + proc.stderr) + + +def log_snapshot(): + """Names and mtimes of every entry under .ci-logs, or None when absent.""" + if not LOG_DIR.exists(): + return None + return sorted((p.name, p.stat().st_mtime_ns) for p in LOG_DIR.iterdir()) + + +class BuildTaskTests(unittest.TestCase): + def test_build_all_has_one_command_per_module_without_common(self): + code, out = run_ci("--build", "--dry-run", "--all") + + self.assertEqual(code, 0, out) + self.assertEqual(out.count("build: would run"), len(BUILD_MODULES), out) + self.assertIn("build: not defined for common, skipping", out) + for module in BUILD_MODULES: + self.assertIn(f" in {module}/", out) + + def test_build_is_not_part_of_the_default_tasks(self): + code, out = run_ci("--dry-run", "--all") + + self.assertEqual(code, 0, out) + self.assertNotIn("build:", out) + for task in ("lint", "test", "fmt"): + self.assertIn(f"{task}: would run", out) + + def test_build_flag_runs_build_only(self): + code, out = run_ci("--build", "--dry-run", "frontend") + + self.assertEqual(code, 0, out) + self.assertIn("build: would run", out) + for task in ("lint", "test", "fmt"): + self.assertNotIn(f"{task}:", out) + + def test_no_build_flag_is_accepted(self): + code, out = run_ci("--no-build", "--dry-run", "frontend") + + self.assertEqual(code, 0, out) + self.assertIn("lint: would run", out) + self.assertNotIn("build:", out) + + def test_dry_run_executes_nothing(self): + before = log_snapshot() + + run_ci("--build", "--dry-run", "mcp") + + self.assertEqual(before, log_snapshot()) + + +class MediaProcessorModuleTests(unittest.TestCase): + def test_module_is_accepted_and_lint_is_skipped(self): + code, out = run_ci("--dry-run", "media-processor") + + self.assertEqual(code, 0, out) + self.assertIn( + "lint: not defined for media-processor, skipping", + out, + ) + for task in ("test", "fmt"): + self.assertIn(f"{task}: would run", out) + + def test_module_is_included_in_all(self): + code, out = run_ci("--dry-run", "--all") + + self.assertEqual(code, 0, out) + self.assertIn("media-processor", out) + self.assertIn("media-processor:test", out) + + def test_build_runs_types_check_before_esbuild(self): + code, out = run_ci("--build", "--dry-run", "media-processor") + + self.assertEqual(code, 0, out) + self.assertIn( + "pnpm run types:check && pnpm run build", + out, + ) + + +class HelpTests(unittest.TestCase): + def help_options(self, out): + """Option tokens from the OPTIONS section, e.g. '--build'.""" + options = [] + for line in out.splitlines(): + stripped = line.strip() + if stripped.startswith("--"): + options.append(stripped.split()[0]) + return options + + def test_help_documents_the_build_flags(self): + code, out = run_ci("--help") + + self.assertEqual(code, 0, out) + options = self.help_options(out) + self.assertIn("--build", options) + self.assertIn("--no-build", options) + + def test_help_lists_every_module(self): + code, out = run_ci("--help") + + self.assertEqual(code, 0, out) + for module in ALL_MODULES: + self.assertIn(module, out) + + +if __name__ == "__main__": + unittest.main() From af2e5921feab4c2919048cdf74208286052e7fba Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 29 Oct 2026 15:15:34 +0000 Subject: [PATCH 14/14] :books: Document the CI build task in the memory index and AGENTS `critical-info` is the first memory every agent reads, and its `scripts/ci` entry still described the orchestrator as lint + tests + format over eight modules. `AGENTS.md` repeated the same incomplete description in its scripts section. Both now mention the opt-in production build and list `media-processor` among the modules. AI-assisted-by: deepseek-v4.1-flash --- .serena/memories/critical-info.md | 2 +- AGENTS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.serena/memories/critical-info.md b/.serena/memories/critical-info.md index a9a7564cdf..867eecdbd9 100644 --- a/.serena/memories/critical-info.md +++ b/.serena/memories/critical-info.md @@ -63,7 +63,7 @@ The memory is structured in a way that you can get the critical information abou - `scripts/error-reports.mjs` — Query error reports via RPC API with token authentication. Supports list/get operations with filtering and pagination. See `mem:scripts/error-reports`. - `scripts/clean-node-modules` — Remove stale `node_modules` from all pnpm workspaces (root, modules, member packages). Keeps the shared pnpm store at `/.pnpm-store` unless `--store`; ignores `external/` and `.opencode/`. Usage and reinstall steps: `mem:workflow/updating-pnpm`. - `scripts/setup-opencode` — Install the opencode CLI in-container as a global pnpm package in `$PNPM_HOME`. Not part of the devenv image; see `mem:devenv/core`. -- `scripts/ci` — CI orchestration script: runs lint, tests, and format checks per module (`frontend backend common render-wasm exporter mcp plugins library`). Logs go to `.ci-logs/`; read the log file on failure. See `mem:scripts/ci`. +- `scripts/ci` — CI orchestration script: runs lint, tests and format checks per module, plus the production build on request (`--build`). Modules: `frontend backend common render-wasm exporter mcp plugins library media-processor`. Logs go to `.ci-logs/`; read the log file on failure. See `mem:scripts/ci`. # Dependency graph diff --git a/AGENTS.md b/AGENTS.md index e900e32518..c95fb06920 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -152,6 +152,6 @@ precision while maintaining a strong focus on maintainability and performance. - `scripts/nrepl-eval.mjs` — Evaluate Clojure code via nREPL (backend + frontend). - `scripts/check-commit` — Validate commit messages against Penpot's commit guidelines. - `scripts/check-fmt-clj` — Check Clojure formatting without modifying files. -- `scripts/ci` — CI orchestration script for running lint, tests, and format checks across modules. See `mem:scripts/ci`. +- `scripts/ci` — CI orchestration script for running lint, tests, format checks and, on request (`--build`), production builds across modules. See `mem:scripts/ci`. - `scripts/gh.py` — Multi-purpose GitHub CLI helper. Subcommands: `issues` (list issues in a milestone), `prs` (fetch PR details), `advisories` (list/inspect security advisories). See `python3 scripts/gh.py --help`.