From 4a41ee806d94cf2b71c13a7f36dad5facde892f5 Mon Sep 17 00:00:00 2001 From: michalharakal Date: Sun, 9 Aug 2026 20:49:03 +0200 Subject: [PATCH] fix(deps): pin webpack and diff, scope npm pins per lockfile Closes the three Scorecard vulnerability warnings left open by the previous npm pin pass: GHSA-73rr-hh4g-fpgx diff 7.0.0 -> 8.0.3 GHSA-8fgc-7cc6-rx7x webpack 5.101.3 -> 5.104.1 GHSA-38r7-794h-5758 webpack 5.101.3 -> 5.104.1 Both are overrides Yarn warns about and applies. webpack overrides KGP's own exact pin, so the bundler now runs ahead of the version the Kotlin toolchain was tested against; the catalog entry says to re-check on every Kotlin upgrade and drop the pin once KGP passes 5.104.1. diff 7 -> 8 is a semver-major override of a mocha-only dependency. Pinning webpack unscoped grew kotlin-js-store/wasm/yarn.lock by 520 lines -- webpack's whole tree landing in a lockfile that bundles nothing with webpack. Yarn writes an entry for every resolutions key whether or not the graph requests the package, and npmPins applied every pin to both Yarn roots. So pin() now takes an optional NpmPinTarget: pin("ws", libs.versions.npm.ws) // both pin("webpack", libs.versions.npm.webpack, NpmPinTarget.JS) // JS only No target still means both, so existing declarations keep their meaning. The extension exposes jsPins/wasmPins instead of one flat map, the plugin feeds each Yarn root only its own pins, and verifyNpmPins checks each lockfile against its own pin map so a scoped pin is never reported missing from a lockfile it was never meant to reach. kotlin-js-store/wasm/yarn.lock is now byte-identical to develop again, which also retires the phantom entries the previous pass added to it. Verified with kotlinUpgradeYarnLock, kotlinWasmUpgradeYarnLock, verifyNpmPins, jsTest, wasmJsTest and wasmWasiTest. --- .../sk/ainet/buildlogic/npm/NpmPinTarget.kt | 35 ++++++ .../ainet/buildlogic/npm/NpmPinsExtension.kt | 52 ++++++-- .../sk/ainet/buildlogic/npm/NpmPinsPlugin.kt | 23 ++-- .../ainet/buildlogic/npm/VerifyNpmPinsTask.kt | 63 +++++++--- build.gradle.kts | 22 +++- .../pages/contributing/build-from-source.adoc | 29 +++++ gradle/libs.versions.toml | 17 ++- kotlin-js-store/wasm/yarn.lock | 59 --------- kotlin-js-store/yarn.lock | 116 +++++++++--------- 9 files changed, 254 insertions(+), 162 deletions(-) create mode 100644 build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinTarget.kt diff --git a/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinTarget.kt b/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinTarget.kt new file mode 100644 index 000000000..7bd442c02 --- /dev/null +++ b/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinTarget.kt @@ -0,0 +1,35 @@ +package sk.ainet.buildlogic.npm + +/** + * Which Yarn root — and so which committed lockfile — a pin applies to. + * + * Most pins want both, which is the default. Scope a pin when the package exists in + * only one of the two dependency graphs, because Yarn writes a lockfile entry for + * **every** `resolutions` key whether or not anything in that graph requests the + * package. An unscoped `webpack` pin therefore adds webpack and its ~76 transitive + * packages to `kotlin-js-store/wasm/yarn.lock`, which bundles nothing with webpack — + * they would be downloaded and installed by the wasm build for no reason, and + * Dependabot would start reporting them against a lockfile that never uses them. + * + * Check which graph actually holds a package before scoping a pin: + * + * ``` + * grep -c '^webpack@' kotlin-js-store/yarn.lock kotlin-js-store/wasm/yarn.lock + * ``` + */ +enum class NpmPinTarget { + + /** `kotlin-js-store/yarn.lock`, driven by the `js` target's Yarn root. */ + JS, + + /** `kotlin-js-store/wasm/yarn.lock`, driven by the `wasmJs` target's Yarn root. */ + WASM, + + ; + + companion object { + + /** The default scope of [NpmPinsExtension.pin]: force the version everywhere. */ + val ALL: Set = entries.toSet() + } +} diff --git a/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinsExtension.kt b/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinsExtension.kt index b81b3b353..bf04a7a7d 100644 --- a/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinsExtension.kt +++ b/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinsExtension.kt @@ -31,30 +31,48 @@ import org.gradle.api.provider.Provider * pin("socket.io", libs.versions.npm.socketio) * pin("@types/node", libs.versions.npm.typesNode) * ``` + * + * ## Scoping a pin to one lockfile + * + * A pin applies to both Yarn roots unless told otherwise. Pass [NpmPinTarget] values + * when the package lives in only one graph, so the other lockfile does not acquire an + * entry — and a whole transitive tree — for a package it never resolves: + * + * ```kotlin + * pin("webpack", libs.versions.npm.webpack, NpmPinTarget.JS) + * ``` */ abstract class NpmPinsExtension { /** - * Package name -> exact version, as declared by [pin]. Consumed by + * Package name -> exact version for `kotlin-js-store/yarn.lock`. Consumed by * [NpmPinsPlugin] and [VerifyNpmPinsTask]; declare pins through [pin] rather than * mutating this directly, which skips validation and duplicate detection. */ - abstract val pins: MapProperty + abstract val jsPins: MapProperty + + /** Package name -> exact version for `kotlin-js-store/wasm/yarn.lock`. See [jsPins]. */ + abstract val wasmPins: MapProperty /** - * Whether `verifyNpmPins` fails when a pinned package is absent from every - * lockfile. Defaults to `false`: a pin that outlives its package (because the - * Kotlin toolchain dropped the dependency) is stale rather than broken, and + * Whether `verifyNpmPins` fails when a pinned package is absent from the lockfile + * it is scoped to. Defaults to `false`: a pin that outlives its package (because + * the Kotlin toolchain dropped the dependency) is stale rather than broken, and * should be reported without breaking the build. */ abstract val failOnMissingPackage: Property private val declared = mutableSetOf() - /** Pins [packageName] to a version held in the version catalog. */ - fun pin(packageName: String, version: Provider) { + /** + * Pins [packageName] to a version held in the version catalog. + * + * With no [targets] the pin applies to every lockfile; name them to restrict it. + */ + fun pin(packageName: String, version: Provider, vararg targets: NpmPinTarget) { val name = validatePackageName(packageName) - pins.put(name, version.map { validateVersion(name, it) }) + val checked = version.map { validateVersion(name, it) } + scopeOf(targets).forEach { target -> mapFor(target).put(name, checked) } } /** @@ -63,9 +81,18 @@ abstract class NpmPinsExtension { * Prefer the [Provider] overload — a number in `libs.versions.toml` is visible to * dependency-update tooling, a number in the build script is not. */ - fun pin(packageName: String, version: String) { + fun pin(packageName: String, version: String, vararg targets: NpmPinTarget) { val name = validatePackageName(packageName) - pins.put(name, validateVersion(name, version)) + val checked = validateVersion(name, version) + scopeOf(targets).forEach { target -> mapFor(target).put(name, checked) } + } + + private fun scopeOf(targets: Array): Set = + if (targets.isEmpty()) NpmPinTarget.ALL else targets.toSet() + + private fun mapFor(target: NpmPinTarget): MapProperty = when (target) { + NpmPinTarget.JS -> jsPins + NpmPinTarget.WASM -> wasmPins } private fun validatePackageName(packageName: String): String { @@ -75,8 +102,9 @@ abstract class NpmPinsExtension { "[npm-pins] Package name '$packageName' must not contain whitespace" } require(declared.add(name)) { - "[npm-pins] '$name' is pinned twice — a Yarn resolution is global, so the " + - "second declaration would silently win" + "[npm-pins] '$name' is pinned twice — a Yarn resolution is global within a " + + "Yarn root, so the second declaration would silently win. Declare it " + + "once and pass both targets, or scope each pin to a different target." } return name } diff --git a/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinsPlugin.kt b/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinsPlugin.kt index 3981a6cde..0b9ab550f 100644 --- a/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinsPlugin.kt +++ b/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/NpmPinsPlugin.kt @@ -27,7 +27,8 @@ import sk.ainet.buildlogic.root.SkainetRootExtension * * There are two such extensions — one for JS, one for Wasm — each with its own * lockfile, so a pin has to be applied twice. This plugin does that from a single - * declaration. + * declaration, and lets a pin opt out of one of them via [NpmPinTarget] when the + * package exists in only one graph. * * ## Declaring a pin * @@ -42,6 +43,9 @@ import sk.ainet.buildlogic.root.SkainetRootExtension * skainet { * npmPins { * pin("ws", libs.versions.npm.ws) + * // Only the JS graph bundles with webpack; scoping keeps webpack's ~76 + * // transitive packages out of kotlin-js-store/wasm/yarn.lock. + * pin("webpack", libs.versions.npm.webpack, NpmPinTarget.JS) * } * } * ``` @@ -75,30 +79,31 @@ class NpmPinsPlugin : Plugin { // Resolved lazily: pins are declared in the root script body, which runs after // the plugins block that applies this plugin. - val pinsProvider: Provider> = extension.pins + val jsPins: Provider> = extension.jsPins + val wasmPins: Provider> = extension.wasmPins // The Yarn plugins are applied by KGP only once a js/wasmJs target is configured, // which happens well after this plugin is applied — hence the reactive hooks. + // Each root gets only the pins scoped to it; see NpmPinTarget for why that matters. project.plugins.withType(YarnPlugin::class.java) { - project.extensions.getByType(YarnRootExtension::class.java).applyPins(pinsProvider.get()) + project.extensions.getByType(YarnRootExtension::class.java).applyPins(jsPins.get()) } project.plugins.withType(WasmYarnPlugin::class.java) { // getByName rather than WasmYarnRootExtension[project]: the latter applies // WasmYarnPlugin as a side effect, dragging wasm Yarn setup into js-only builds. val wasmYarn = project.extensions.getByName(WasmYarnRootExtension.YARN) as WasmYarnRootExtension - wasmYarn.applyPins(pinsProvider.get()) + wasmYarn.applyPins(wasmPins.get()) } val verify = project.tasks.register("verifyNpmPins", VerifyNpmPinsTask::class.java) { group = "verification" description = "Check the committed Yarn lockfiles against the pins declared in skainet { npmPins { } }" - pins.set(pinsProvider) + this.jsPins.set(jsPins) + this.wasmPins.set(wasmPins) failOnMissingPackage.set(extension.failOnMissingPackage) rootDirectory.set(project.layout.projectDirectory) - lockFiles.from( - project.layout.projectDirectory.file("kotlin-js-store/yarn.lock"), - project.layout.projectDirectory.file("kotlin-js-store/wasm/yarn.lock"), - ) + jsLockFile.from(project.layout.projectDirectory.file("kotlin-js-store/yarn.lock")) + wasmLockFile.from(project.layout.projectDirectory.file("kotlin-js-store/wasm/yarn.lock")) // The lockfiles are outputs of the store tasks. Order after them rather than // depending on them, so `verifyNpmPins` stays a cheap file check on its own but // still sees the current state when a full build refreshes the lockfiles. diff --git a/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/VerifyNpmPinsTask.kt b/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/VerifyNpmPinsTask.kt index 58d98f6ca..a2720c6ed 100644 --- a/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/VerifyNpmPinsTask.kt +++ b/build-logic/convention/src/main/kotlin/sk/ainet/buildlogic/npm/VerifyNpmPinsTask.kt @@ -13,6 +13,7 @@ import org.gradle.api.tasks.PathSensitive import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.TaskAction import org.gradle.work.DisableCachingByDefault +import java.io.File /** * Fails when a committed Yarn lockfile disagrees with a declared npm pin. @@ -20,21 +21,33 @@ import org.gradle.work.DisableCachingByDefault * Yarn `resolutions` make the pin take effect, but only the next time the lockfile * is regenerated. Without this check a stale or hand-edited lockfile silently wins * — which is exactly how PR #894's `ws` bump ended up as a zero-line diff. + * + * Each lockfile is checked against its own pin map, so a pin scoped to one + * [NpmPinTarget] is never reported as missing from the other lockfile. */ @DisableCachingByDefault(because = "Reads two small lockfiles; caching costs more than it saves") abstract class VerifyNpmPinsTask : DefaultTask() { - /** Package name -> pinned version, sourced from the `npm-*` catalog aliases. */ + /** Package name -> pinned version for the Kotlin/JS lockfile. */ + @get:Input + abstract val jsPins: MapProperty + + /** Package name -> pinned version for the Kotlin/Wasm lockfile. */ @get:Input - abstract val pins: MapProperty + abstract val wasmPins: MapProperty @get:Input abstract val failOnMissingPackage: Property - /** The committed lockfiles under `kotlin-js-store/`. Missing files are skipped. */ + /** `kotlin-js-store/yarn.lock`. Missing file is skipped. */ + @get:InputFiles + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val jsLockFile: ConfigurableFileCollection + + /** `kotlin-js-store/wasm/yarn.lock`. Missing file is skipped. */ @get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE) - abstract val lockFiles: ConfigurableFileCollection + abstract val wasmLockFile: ConfigurableFileCollection /** Only used to render lockfile paths relative to the repository root in messages. */ @get:Internal @@ -42,31 +55,49 @@ abstract class VerifyNpmPinsTask : DefaultTask() { @TaskAction fun verify() { - val expected = pins.get() - if (expected.isEmpty()) { + val lanes = listOf( + Lane("Kotlin/JS", jsPins.get(), jsLockFile.files), + Lane("Kotlin/Wasm", wasmPins.get(), wasmLockFile.files), + ) + + val pinnedPackages = lanes.flatMap { it.pins.keys }.toSortedSet() + if (pinnedPackages.isEmpty()) { logger.lifecycle("[npm-pins] No npm pins declared; nothing to verify.") return } - val mismatches = mutableListOf() - val seen = mutableSetOf() val rootDir = rootDirectory.get().asFile + val mismatches = mutableListOf() + val missing = mutableListOf() + var checkedLockFiles = 0 + + for (lane in lanes) { + if (lane.pins.isEmpty()) continue + val lockFile = lane.lockFiles.firstOrNull { it.isFile } ?: continue + checkedLockFiles++ - lockFiles.files.filter { it.isFile }.sortedBy { it.path }.forEach { lockFile -> val relative = lockFile.relativeToOrSelf(rootDir).path + val seen = mutableSetOf() YarnLockParser.parse(lockFile.readText()).forEach { (packageName, version) -> - val pinned = expected[packageName] ?: return@forEach + val pinned = lane.pins[packageName] ?: return@forEach seen += packageName if (version != pinned) { mismatches += "$relative: $packageName resolved to $version, pinned to $pinned" } } + (lane.pins.keys - seen).sorted().forEach { missing += "$relative (${lane.label}): $it" } } - val missing = expected.keys - seen if (missing.isNotEmpty()) { - val message = "[npm-pins] Pinned but absent from every lockfile: ${missing.sorted().joinToString(", ")}. " + - "The pin may be stale — drop it from gradle/libs.versions.toml if the package is gone for good." + val message = buildString { + appendLine("[npm-pins] Pinned but absent from the lockfile the pin is scoped to:") + missing.sorted().forEach { appendLine(" - $it") } + append( + "The pin may be stale — drop it from gradle/libs.versions.toml if the " + + "package is gone for good, or narrow its NpmPinTarget if it only ever " + + "existed in the other graph." + ) + } if (failOnMissingPackage.get()) throw GradleException(message) logger.warn(message) } @@ -84,6 +115,10 @@ abstract class VerifyNpmPinsTask : DefaultTask() { ) } - logger.lifecycle("[npm-pins] ${expected.size} pin(s) verified against ${lockFiles.files.count { it.isFile }} lockfile(s).") + logger.lifecycle( + "[npm-pins] ${pinnedPackages.size} pin(s) verified against $checkedLockFiles lockfile(s)." + ) } + + private data class Lane(val label: String, val pins: Map, val lockFiles: Set) } diff --git a/build.gradle.kts b/build.gradle.kts index 68337f7bd..b7617fff1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import sk.ainet.buildlogic.npm.NpmPinTarget + plugins { alias(libs.plugins.androidLibrary) apply false alias(libs.plugins.kotlinMultiplatform) apply false @@ -19,16 +21,24 @@ allprojects { version = providers.gradleProperty("VERSION_NAME").getOrElse("unspecified") } -// Root-project SKaiNET conventions. npm pins are forced onto both kotlin-js-store +// Root-project SKaiNET conventions. npm pins are forced onto the kotlin-js-store // lockfiles via Yarn resolutions; see docs "Pinning npm Packages". +// +// `ws` is the only pinned package present in both dependency graphs, so it is the only +// unscoped pin. Everything else lives solely in the Kotlin/JS graph and is scoped to it: +// Yarn writes a lockfile entry for every resolutions key whether or not that graph +// requests the package, so an unscoped pin would add the package — and, for webpack, its +// ~76 transitive dependencies — to kotlin-js-store/wasm/yarn.lock for nothing. skainet { npmPins { pin("ws", libs.versions.npm.ws) - pin("js-yaml", libs.versions.npm.js.yaml) - pin("socket.io-parser", libs.versions.npm.socketio.parser) - pin("fast-uri", libs.versions.npm.fast.uri) - pin("serialize-javascript", libs.versions.npm.serialize.javascript) - pin("brace-expansion", libs.versions.npm.brace.expansion) + pin("js-yaml", libs.versions.npm.js.yaml, NpmPinTarget.JS) + pin("socket.io-parser", libs.versions.npm.socketio.parser, NpmPinTarget.JS) + pin("fast-uri", libs.versions.npm.fast.uri, NpmPinTarget.JS) + pin("serialize-javascript", libs.versions.npm.serialize.javascript, NpmPinTarget.JS) + pin("brace-expansion", libs.versions.npm.brace.expansion, NpmPinTarget.JS) + pin("diff", libs.versions.npm.diff, NpmPinTarget.JS) + pin("webpack", libs.versions.npm.webpack, NpmPinTarget.JS) } } diff --git a/docs/modules/ROOT/pages/contributing/build-from-source.adoc b/docs/modules/ROOT/pages/contributing/build-from-source.adoc index a6247f27e..ebe3cd226 100644 --- a/docs/modules/ROOT/pages/contributing/build-from-source.adoc +++ b/docs/modules/ROOT/pages/contributing/build-from-source.adoc @@ -194,6 +194,35 @@ skainet { ./gradlew kotlinUpgradeYarnLock kotlinWasmUpgradeYarnLock ---- +==== Scoping a pin to one lockfile + +Yarn writes a lockfile entry for *every* `resolutions` key, whether or not that dependency graph actually requests the package. An unscoped pin for a package that only the JS graph uses therefore adds it — and everything it depends on — to `kotlin-js-store/wasm/yarn.lock`, where nothing imports it. For `webpack` that is roughly 76 extra packages the Wasm build would download and install for nothing, and which Dependabot would then report against a lockfile that never uses them. + +Pass an `NpmPinTarget` when a package lives in only one graph: + +[source,kotlin] +---- +import sk.ainet.buildlogic.npm.NpmPinTarget + +skainet { + npmPins { + pin("ws", libs.versions.npm.ws) // <1> + pin("webpack", libs.versions.npm.webpack, NpmPinTarget.JS) // <2> + } +} +---- +<1> No target: applies to both lockfiles. Correct for `ws`, which both graphs resolve. +<2> `NpmPinTarget.JS`: only `kotlin-js-store/yarn.lock` gets the resolution. + +Check which graph holds a package before deciding: + +[source,bash] +---- +grep -c '^webpack@' kotlin-js-store/yarn.lock kotlin-js-store/wasm/yarn.lock +---- + +`verifyNpmPins` checks each lockfile against its own pin map, so a scoped pin is never reported as missing from the lockfile it was never meant to reach. + `verifyNpmPins` re-reads the committed lockfiles and fails if any pinned package resolved elsewhere. It is wired into `check` and runs on the `js-wasm` leg of `.github/workflows/build.yml`. The root plugin is not optional for web modules: `sk.ainet.multiplatform` fails at configuration time if a module builds `js`/`wasmJs` while the root project does not apply `sk.ainet.npm-pins`. Without it no `resolutions` are written *and* `verifyNpmPins` does not exist to notice — a silent security regression rather than a build error. diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 350878db8..9481c056c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,10 +37,12 @@ kotest = "6.2.2" # Never edit kotlin-js-store/**/yarn.lock by hand — it is generated and will be # overwritten (see PR #894). # -# Expect a pin to show up in BOTH lockfiles even when only one graph uses the -# package: Yarn writes an entry for every `resolutions` key, matched or not. That -# is why kotlin-js-store/wasm/yarn.lock lists packages the wasm build never -# imports. Harmless, and the price of a single pin covering both targets. +# A pin lands in BOTH lockfiles by default, because Yarn writes an entry for every +# `resolutions` key whether or not that graph requests the package. Scope the pin +# when only one graph has it: +# pin("webpack", libs.versions.npm.webpack, NpmPinTarget.JS) +# Check which graph holds a package before deciding: +# grep -c '^webpack@' kotlin-js-store/yarn.lock kotlin-js-store/wasm/yarn.lock npm-ws = "8.21.1" # GHSA-96hv-2xvq-fx4p npm-js-yaml = "4.3.1" # GHSA-5p4m-2wfm-xmqj npm-socketio-parser = "4.2.7" # GHSA-2m8v-j782-fhvr @@ -51,6 +53,13 @@ npm-serialize-javascript = "7.0.5" # GHSA-5c6j-r48x-rmvq, GHSA-qj8w-gfj5-8c6v # set of both advisories (<1.1.18 and >=2.0.0 <2.1.4); the exported API is unchanged # between the two majors, so the 3.x consumer is unaffected. npm-brace-expansion = "2.1.4" # GHSA-rgw5-rvv9-x895, GHSA-mh99-v99m-4gvg +npm-diff = "8.0.3" # GHSA-73rr-hh4g-fpgx +# KGP pins webpack to an exact version (5.101.3 for Kotlin 2.4.10), so this +# resolution deliberately overrides the Kotlin toolchain's own choice. 5.104.1 is +# the first release clearing both advisories. Re-check this pin on every Kotlin +# upgrade: once KGP's own webpack moves past 5.104.1, drop the pin rather than +# holding the bundler behind the version KGP was tested against. +npm-webpack = "5.104.1" # GHSA-8fgc-7cc6-rx7x, GHSA-38r7-794h-5758 [libraries] jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jacksonDatabind" } diff --git a/kotlin-js-store/wasm/yarn.lock b/kotlin-js-store/wasm/yarn.lock index 00218d347..d12e41c53 100644 --- a/kotlin-js-store/wasm/yarn.lock +++ b/kotlin-js-store/wasm/yarn.lock @@ -2,65 +2,6 @@ # yarn lockfile v1 -"@socket.io/component-emitter@~3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" - integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -brace-expansion@2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.4.tgz#589dab11c0018d0366be64cd8bf12c8dbecc8326" - integrity sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg== - dependencies: - balanced-match "^1.0.0" - -debug@~4.4.1: - version "4.4.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - -fast-uri@3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.5.tgz#610f37419a030270430cecd68d74e3d4d96725d0" - integrity sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw== - -js-yaml@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.1.tgz#01216c001d67f48e2cd560d708c7af21090a3848" - integrity sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ== - dependencies: - argparse "^2.0.1" - -ms@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -serialize-javascript@7.0.5: - version "7.0.5" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-7.0.5.tgz#c798cc0552ffbb08981914a42a8756e339d0d5b1" - integrity sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw== - -socket.io-parser@4.2.7: - version "4.2.7" - resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.7.tgz#679e51fe24d1c81df90fc5f7efe4a5f432fe99c0" - integrity sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg== - dependencies: - "@socket.io/component-emitter" "~3.1.0" - debug "~4.4.1" - ws@8.20.1, ws@8.21.1: version "8.21.1" resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.1.tgz#045650cd4b1207809e7547146223c3814a9af586" diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 557136ade..508c036c5 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -348,10 +348,10 @@ base64id@2.0.0, base64id@~2.0.0: resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== -baseline-browser-mapping@^2.10.42: - version "2.10.43" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz#7b5d11590ce5acdbe4859443e3c940e81ce8c02d" - integrity sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ== +baseline-browser-mapping@^2.11.12: + version "2.11.13" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz#660073103c1bee93e54df55f117b7528adf6af19" + integrity sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ== binary-extensions@^2.0.0: version "2.3.0" @@ -395,16 +395,16 @@ browser-stdout@^1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserslist@^4.24.0: - version "4.28.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.5.tgz#438b7d38c0d4b47740bbb36778d5bdca01b37838" - integrity sha512-Cu2E6QejHWzuDMTkuwgpABFgDfZrXLQq5V13YOACZx4mFAG4IwGTbTfHPMr4WtxlHoXSM8FIuRwYYCz5XiabaQ== +browserslist@^4.28.1: + version "4.28.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.8.tgz#a3c79ceb70028527e5da7dafc887f3200b5168c0" + integrity sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA== dependencies: - baseline-browser-mapping "^2.10.42" - caniuse-lite "^1.0.30001800" - electron-to-chromium "^1.5.387" - node-releases "^2.0.50" - update-browserslist-db "^1.2.3" + baseline-browser-mapping "^2.11.12" + caniuse-lite "^1.0.30001809" + electron-to-chromium "^1.5.402" + node-releases "^2.0.53" + update-browserslist-db "^1.3.0" buffer-from@^1.0.0: version "1.1.2" @@ -437,10 +437,10 @@ camelcase@^6.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001800: - version "1.0.30001803" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001803.tgz#b2a5d696e042bc8304dcd4942c39fe330fbbcb24" - integrity sha512-g/uHREV2ZpK9qMalCsWaxmA6ol+DX8GYhuf3T40RKoP+oL7vhRJh8LNt73PCjpnR6l14FzfPrB5Yux4PKm2meg== +caniuse-lite@^1.0.30001809: + version "1.0.30001809" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz#e6cf71f14ddfe008f114dd2a846923be3c03a07b" + integrity sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ== chalk@^4.1.0: version "4.1.2" @@ -612,10 +612,10 @@ di@^0.0.1: resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" integrity sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA== -diff@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a" - integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw== +diff@8.0.3, diff@^7.0.0: + version "8.0.3" + resolved "https://registry.yarnpkg.com/diff/-/diff-8.0.3.tgz#c7da3d9e0e8c283bb548681f8d7174653720c2d5" + integrity sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ== dom-serialize@^2.2.1: version "2.2.1" @@ -646,10 +646,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.5.387: - version "1.5.389" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.389.tgz#538be9ebec78026d4daba6be321ab854dfac2a8f" - integrity sha512-cEto7aeOqBfU1D+c5py5pE+ooscKE75JifxLBdFUZsqAxRS6y7kebtxAZvICszSl05gPjYHDTjY+lXpyGvpJbg== +electron-to-chromium@^1.5.402: + version "1.5.403" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.403.tgz#8a6e422bc68c5d2fa4d8c5fa2ba9a583c3d4452c" + integrity sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA== emoji-regex@^8.0.0: version "8.0.0" @@ -687,10 +687,10 @@ engine.io@~6.6.0: engine.io-parser "~5.2.1" ws "~8.21.0" -enhanced-resolve@^5.17.3: - version "5.24.2" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.24.2.tgz#f25d703a24431cb1e02f944adb74aefa4fcb8d7e" - integrity sha512-rpsZEGT1jFuve6QlpyRp9ckQ+kN61hvF9BzCPyMdaKTm8UJce96KBn3sorXOFXlzjPrs3Vc4T1NsSroZ3PxlFw== +enhanced-resolve@^5.17.4: + version "5.24.5" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz#b4dad3255b7545f07ba5535189868e9f85f47573" + integrity sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A== dependencies: graceful-fs "^4.2.4" tapable "^2.3.3" @@ -720,10 +720,10 @@ es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-module-lexer@^1.2.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" - integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== +es-module-lexer@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.3.1.tgz#5bf2df06999dbbe5f006a5f46a11fb9f5b7b391b" + integrity sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA== es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.2" @@ -1250,7 +1250,7 @@ kotlin-web-helpers@3.0.0: dependencies: format-util "^1.0.5" -loader-runner@^4.2.0: +loader-runner@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.2.tgz#9913d3a15971f8f635915e601fb5c9d495d918e9" integrity sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w== @@ -1408,10 +1408,10 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -node-releases@^2.0.50: - version "2.0.51" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.51.tgz#cdc08433577f5b32ad01694481726e22eeb54aef" - integrity sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ== +node-releases@^2.0.53: + version "2.0.53" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.53.tgz#0fe5ad8a7935e075172f574e56f0c20f07fa41af" + integrity sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -1652,7 +1652,7 @@ safe-regex-test@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-utils@^4.3.0, schema-utils@^4.3.2: +schema-utils@^4.3.0, schema-utils@^4.3.3: version "4.3.3" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== @@ -1882,12 +1882,12 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -tapable@^2.1.1, tapable@^2.3.3: +tapable@^2.3.0, tapable@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.3.tgz#5da7c9992c46038221267985ab28421a8879f160" integrity sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A== -terser-webpack-plugin@^5.3.11: +terser-webpack-plugin@^5.3.16: version "5.6.1" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.6.1.tgz#47bc41bd8b8fab8383b62ec763b7394829097e7b" integrity sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ== @@ -1952,10 +1952,10 @@ unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -update-browserslist-db@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" - integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== +update-browserslist-db@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.3.0.tgz#9ff2604d5b949051639c01a223a16619f8a2b2c7" + integrity sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -1975,7 +1975,7 @@ void-elements@^2.0.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung== -watchpack@^2.4.1: +watchpack@^2.4.4: version "2.5.2" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.2.tgz#e12e82d84674266fc1c6dbfe38891b92ff0522ec" integrity sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg== @@ -2022,10 +2022,10 @@ webpack-sources@^3.3.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.5.1.tgz#76c2418486dcc02b2aa0694c104176c2858fe84a" integrity sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw== -webpack@5.101.3: - version "5.101.3" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.101.3.tgz#3633b2375bb29ea4b06ffb1902734d977bc44346" - integrity sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A== +webpack@5.101.3, webpack@5.104.1: + version "5.104.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.104.1.tgz#94bd41eb5dbf06e93be165ba8be41b8260d4fb1a" + integrity sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA== dependencies: "@types/eslint-scope" "^3.7.7" "@types/estree" "^1.0.8" @@ -2035,22 +2035,22 @@ webpack@5.101.3: "@webassemblyjs/wasm-parser" "^1.14.1" acorn "^8.15.0" acorn-import-phases "^1.0.3" - browserslist "^4.24.0" + browserslist "^4.28.1" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.3" - es-module-lexer "^1.2.1" + enhanced-resolve "^5.17.4" + es-module-lexer "^2.0.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" + loader-runner "^4.3.1" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^4.3.2" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.11" - watchpack "^2.4.1" + schema-utils "^4.3.3" + tapable "^2.3.0" + terser-webpack-plugin "^5.3.16" + watchpack "^2.4.4" webpack-sources "^3.3.3" which@^1.2.1: