diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index af41c93d..8cc5715b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,13 +1,13 @@ # Copyright (c) 2021 Concurrent Technologies Corporation. -# +# # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software is distributed under the License is -# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. See the License for the specific language governing permissions and limitations under the License. +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software is distributed under the License is +# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing permissions and limitations under the License. --- name: Automatic Release @@ -16,7 +16,7 @@ on: tags: - 'v*.*.*' env: - node_version: 16 + node_version: 18 export_cmd: | GIT_TAG=$(echo ${GITHUB_REF#refs/*/} | cut -d 'v' -f 2) PKG_VERSION=$(echo $(node -p "JSON.stringify(require('./package.json').version)") | sed 's|"||g') @@ -42,7 +42,7 @@ jobs: # This check name is defined as the github action job name (in .github/workflows/testing.yaml) checkName: "Rat Check ๐Ÿ€" ref: ${{ github.event.pull_request.head.sha || github.sha }} - + - name: Check Scala format โœ… uses: fountainhead/action-wait-for-check@v1.2.0 id: scala-format @@ -51,7 +51,7 @@ jobs: # This check name is defined as the github action job name (in .github/workflows/testing.yaml) checkName: "Scala Code Format" ref: ${{ github.event.pull_request.head.sha || github.sha }} - + - name: Check TypeScript format โœ… uses: fountainhead/action-wait-for-check@v1.2.0 id: ts-format @@ -60,7 +60,7 @@ jobs: # This check name is defined as the github action job name (in .github/workflows/testing.yaml) checkName: "TypeScript code is properly formatted" ref: ${{ github.event.pull_request.head.sha || github.sha }} - + - name: Check tests - macOS 12 โœ… uses: fountainhead/action-wait-for-check@v1.2.0 id: macos12-tests @@ -69,7 +69,7 @@ jobs: # This check name is defined as the github action job name (in .github/workflows/testing.yaml) checkName: "Build middleware macos-12 ๐Ÿ”ง" ref: ${{ github.event.pull_request.head.sha || github.sha }} - + - name: Check tests - macOS 14 โœ… uses: fountainhead/action-wait-for-check@v1.2.0 id: macos14-tests @@ -96,7 +96,7 @@ jobs: # This check name is defined as the github action job name (in .github/workflows/testing.yaml) checkName: "Build middleware windows-2019 ๐Ÿ”ง" ref: ${{ github.event.pull_request.head.sha || github.sha }} - + - name: Check native build arm64 - Linux โœ… uses: fountainhead/action-wait-for-check@v1.2.0 id: ubuntu-arm64-native @@ -178,7 +178,7 @@ jobs: - name: Export git tag and package.json version ๐Ÿšข run: ${{ env.export_cmd }} shell: bash - + - name: Download upload_url ๐Ÿ”ป uses: actions/download-artifact@v4 with: @@ -195,7 +195,7 @@ jobs: distribution: temurin java-version: 8 cache: sbt - + - name: Make _install directory to store lib files run: mkdir -p _install @@ -207,7 +207,7 @@ jobs: workflow_conclusion: success name: ubuntu-20.04-x64-libomega_edit.so path: _install/libomega_edit_linux_amd64.so - + - name: Download linux arm64 library file ๐Ÿ”ป uses: dawidd6/action-download-artifact@v3 with: @@ -216,7 +216,7 @@ jobs: workflow_conclusion: success name: ubuntu-20.04-arm64-libomega_edit.so path: _install/libomega_edit_linux_aarch64.so - + - name: Download macos-12 library file ๐Ÿ”ป uses: dawidd6/action-download-artifact@v3 with: @@ -234,7 +234,7 @@ jobs: workflow_conclusion: success name: macos-12-x64-libomega_edit.dylib path: _install/libomega_edit_macos_x86_64.dylib - + - name: Download windows library file ๐Ÿ”ป uses: dawidd6/action-download-artifact@v3 with: diff --git a/.github/workflows/ts-format.yml b/.github/workflows/ts-format.yml index 3d942b60..bca818b4 100644 --- a/.github/workflows/ts-format.yml +++ b/.github/workflows/ts-format.yml @@ -29,12 +29,12 @@ jobs: with: fetch-depth: 0 persist-credentials: false - + - name: Setup Node ๐Ÿ“ uses: actions/setup-node@v4 with: registry-url: 'https://registry.npmjs.org' - node-version: 16 + node-version: 18 - name: yarn lint - all workspaces ๐Ÿงถ run: | diff --git a/packages/client/package.json b/packages/client/package.json index 9e854fd4..fdd25d8f 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -43,12 +43,12 @@ "ts-node": "^10.9.2" }, "dependencies": { - "@grpc/grpc-js": "1.10.9", + "@grpc/grpc-js": "1.12.2", "@omega-edit/server": "0.9.82", "@types/google-protobuf": "3.15.12", - "google-protobuf": "3.21.2", - "pid-port": "0.2.0", - "pino": "8.20.0", + "google-protobuf": "3.21.4", + "pid-port": "1.0.0", + "pino": "9.5.0", "wait-port": "1.1.0" } } diff --git a/packages/client/src/server.ts b/packages/client/src/server.ts index a99c904c..c5533b7d 100644 --- a/packages/client/src/server.ts +++ b/packages/client/src/server.ts @@ -33,6 +33,11 @@ import { ServerControlResponse, ServerInfoResponse, } from './omega_edit_pb' +import { execFile } from 'child_process' +import { promisify } from 'util' + +// Convert execFile to a promise-based function +const execFilePromise = promisify(execFile) const DEFAULT_PORT = 9000 // default port for the server const DEFAULT_HOST = '127.0.0.1' // default host for the server @@ -233,6 +238,36 @@ export async function stopProcessUsingPID( return true } +/** + * Get the process id using the port + * @param port port to check + * @returns process id or undefined if the port is not in use + */ +async function getPidByPort(port: number): Promise { + try { + // Try to get the PID using `lsof` + const { stdout } = await execFilePromise('lsof', [ + '-iTCP:' + port, + '-sTCP:LISTEN', + '-n', + '-P', + ]) + const lines = stdout.trim().split('\n') + if (lines.length > 1) { + const [_, pid] = lines[1].trim().split(/\s+/) + return parseInt(pid, 10) + } + return undefined + } catch (error) { + // Fallback to `portToPid` if `lsof` fails + try { + return await portToPid(port) + } catch (portToPidError) { + return undefined + } + } +} + /** * Stop the service running on a port * @param port port @@ -250,10 +285,31 @@ export async function stopServiceOnPort( signal, } log.debug(logMetadata) + try { - const pid = await portToPid(port) - return pid ? stopProcessUsingPID(pid as number, signal) : true + // Attempt to get the PID for the given port + const pid = await getPidByPort(port) + + if (pid) { + log.debug({ ...logMetadata, msg: `Found PID ${pid} for port ${port}` }) + + // Attempt to stop the process using the PID + const result = await stopProcessUsingPID(pid, signal) + log.debug({ + ...logMetadata, + msg: `stopProcessUsingPID result: ${result}`, + }) + return result + } else { + log.debug({ + ...logMetadata, + stopped: true, + msg: 'No process found using the port', + }) + return true // No process was using the port, so consider it as stopped + } } catch (err) { + // Handle case where `portToPid` cannot find a process for the port if (err instanceof Error) { if (err.message.startsWith('Could not find a process that uses port')) { log.debug({ @@ -261,10 +317,10 @@ export async function stopServiceOnPort( stopped: true, msg: err.message, }) - // if the port is not in use, return true - return true + return true // No process using the port, so we consider it stopped } - log.debug({ + // Log other types of errors that occur + log.error({ ...logMetadata, stopped: false, err: { @@ -279,8 +335,8 @@ export async function stopServiceOnPort( err: { msg: String(err) }, }) } + return false // Return false for any errors that occur } - return false } /** @@ -563,7 +619,10 @@ export function pidIsRunning(pid) { process.kill(pid, 0) return true } catch (e) { - return false + if ((e as NodeJS.ErrnoException).code === 'ESRCH') { + return false + } + throw e } } diff --git a/packages/client/tests/specs/common.ts b/packages/client/tests/specs/common.ts index 4b1f2897..4c2952ab 100644 --- a/packages/client/tests/specs/common.ts +++ b/packages/client/tests/specs/common.ts @@ -171,10 +171,13 @@ export async function subscribeViewport( : 1 ) const event = viewportEvent.getViewportEventKind() + const viewport_id_from_event = viewportEvent.getViewportId() if (ViewportEventKind.VIEWPORT_EVT_EDIT == event) { log_info( 'viewport_id: ' + viewport_id + + ', viewport_id_from_event: ' + + viewport_id_from_event + ', event: ' + event + ', serial: ' + @@ -188,6 +191,15 @@ export async function subscribeViewport( '", callbacks: ' + viewport_callbacks.get(viewport_id) ) + if (viewport_id_from_event !== viewport_id) { + log_error( + 'viewport ID mismatch: "' + + viewport_id + + '" not equal to "' + + viewport_id_from_event + + '"' + ) + } } else { log_info( 'viewport: ' + diff --git a/packages/client/tests/specs/viewport.spec.ts b/packages/client/tests/specs/viewport.spec.ts index b6cfbadc..b53c678f 100644 --- a/packages/client/tests/specs/viewport.spec.ts +++ b/packages/client/tests/specs/viewport.spec.ts @@ -176,12 +176,15 @@ describe('Viewports', () => { await checkCallbackCount(viewport_callbacks, viewport_1_id, 1) await checkCallbackCount(viewport_callbacks, viewport_2_id, 3) log_info(viewport_callbacks) + // Unsubscribe all viewporta - await unsubscribeViewport(viewport_1_id) - await unsubscribeViewport(viewport_2_id) + expect(await unsubscribeViewport(viewport_1_id)).to.equal(viewport_1_id) + expect(await unsubscribeViewport(viewport_2_id)).to.equal(viewport_2_id) + // Note the viewports are not destroyed, just unsubscribed expect(await getViewportCount(session_id)).to.equal(1) - await destroyViewport(viewport_1_id) + + expect(await destroyViewport(viewport_1_id)).to.equal(viewport_1_id) expect(await getViewportCount(session_id)).to.equal(0) }).timeout(8000) @@ -304,6 +307,7 @@ describe('Viewports', () => { false ) const viewport_id = viewport_response.getViewportId() + expect(viewport_id).to.equal(session_id + ':' + desired_viewport_id) expect(await viewportHasChanges(viewport_id)).to.be.false expect(viewport_response.getData_asU8()).to.deep.equal(Buffer.from('')) expect(viewport_response.getLength()).to.equal(0) @@ -414,7 +418,9 @@ describe('Viewports', () => { ) expect(await getViewportCount(session_id)).to.equal(1) // Unsubscribe the viewport - expect(await unsubscribeViewport(viewport_id)).to.equal(desired_viewport_id) + expect(await unsubscribeViewport(viewport_id)).to.equal( + session_id + ':' + desired_viewport_id + ) // Note the viewport is not destroyed, just unsubscribed expect(await getViewportCount(session_id)).to.equal(1) await destroyViewport(viewport_id) diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index c4f5e4ef..b4141192 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -91,6 +91,7 @@ async function executeServer(args: string[]): Promise { stdio: ['ignore', 'ignore', 'ignore'], detached: true, windowsHide: true, // avoid showing a console window + shell: os.platform().startsWith('win'), // use shell on Windows because it can't execute scripts directly }) serverProcess.on('error', (err: Error) => { diff --git a/server/scala/api/src/main/scala/com/ctc/omega_edit/ViewportImpl.scala b/server/scala/api/src/main/scala/com/ctc/omega_edit/ViewportImpl.scala index 658098a4..f53d0d93 100644 --- a/server/scala/api/src/main/scala/com/ctc/omega_edit/ViewportImpl.scala +++ b/server/scala/api/src/main/scala/com/ctc/omega_edit/ViewportImpl.scala @@ -67,6 +67,7 @@ private[omega_edit] class ViewportImpl(p: Pointer, i: FFI) extends Viewport { def modify(offset: Long, capacity: Long, isFloating: Boolean): Boolean = i.omega_viewport_modify(p, offset, capacity, if (isFloating) 1 else 0) == 0 + override def toString: String = data.mkString // TODO: probably render instead as hex diff --git a/server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/EditorService.scala b/server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/EditorService.scala index ffbdbcd7..c043e1eb 100644 --- a/server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/EditorService.scala +++ b/server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/EditorService.scala @@ -444,7 +444,7 @@ class EditorService(implicit val system: ActorSystem) extends Editor { ObjectId(in.id) match { case Viewport.Id(sid, vid) => (editors ? ViewportOp(sid, vid, Viewport.Unwatch)).mapTo[Result].map { - case Ok(id) => ObjectId(id) + case Ok(_) => in case Err(c) => throw grpcFailure(c) } case _ => diff --git a/server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/Session.scala b/server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/Session.scala index fb84530c..5efbcba4 100644 --- a/server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/Session.scala +++ b/server/scala/serv/src/main/scala/com/ctc/omega_edit/grpc/Session.scala @@ -194,7 +194,7 @@ class Session( val vid = id.getOrElse(Viewport.Id.uuid()) val fqid = s"$sessionId:$vid" - context.child(fqid) match { + context.child(vid) match { case Some(_) => sender() ! Err(Status.ALREADY_EXISTS) case None => @@ -204,8 +204,8 @@ class Session( val cb = ViewportCallback { (v, e, c) => input.queue.offer( ViewportEvent( - sessionId = fqid, - viewportId = vid, + sessionId = sessionId, + viewportId = fqid, serial = c.map(_.id), data = Option(ByteString.copyFrom(v.data)), length = Some(v.data.size.toLong), diff --git a/server/scala/serv/src/test/scala/com/ctc/omega_edit/grpc/Bug976Spec.scala b/server/scala/serv/src/test/scala/com/ctc/omega_edit/grpc/Bug976Spec.scala new file mode 100644 index 00000000..65d69144 --- /dev/null +++ b/server/scala/serv/src/test/scala/com/ctc/omega_edit/grpc/Bug976Spec.scala @@ -0,0 +1,55 @@ +/* + * Copyright 2021 Concurrent Technologies Corporation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ctc.omega_edit.grpc + +import com.google.protobuf.ByteString +import omega_edit.ChangeKind.CHANGE_INSERT +import omega_edit._ +import org.apache.pekko.stream.Materializer +import org.apache.pekko.stream.scaladsl.Sink +import org.scalatest.OptionValues +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AsyncWordSpecLike + +import scala.concurrent.duration.DurationInt + +class Bug976Spec extends AsyncWordSpecLike with Matchers with OptionValues with EditorServiceSupport { + "GitHub issue 976" should useService { implicit svc => + val requested_vid = "my_viewport" + implicit val mat = Materializer.matFromSystem(svc.system) + + "validate vid on viewport events and unsubs" in { + for { + s <- svc.createSession(CreateSessionRequest.defaultInstance) + sid = s.sessionId + v <- svc.createViewport(CreateViewportRequest(s.sessionId, 1, 0, false, Some(requested_vid))) + vid = v.viewportId + sub = svc.subscribeToViewportEvents(EventSubscriptionRequest(vid, None)) + _ = svc.submitChange(ChangeRequest(sid, CHANGE_INSERT, 0, 1, Some(ByteString.fromHex("ff")))) + evt <- sub.completionTimeout(1.second).runWith(Sink.headOption) + unsub <- svc.unsubscribeToViewportEvents(ObjectId(vid)) + } yield { + vid should startWith(sid) + evt.value should matchPattern { case ViewportEvent(`sid`, `vid`, _, _, _, _, _, _) => } + unsub.id shouldBe vid + val Array(s, v) = vid.split(":") + s shouldBe sid + v shouldBe requested_vid + } + } + } +} diff --git a/yarn.lock b/yarn.lock index c06055dd..f5b75f52 100644 --- a/yarn.lock +++ b/yarn.lock @@ -51,10 +51,10 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== -"@grpc/grpc-js@1.10.9": - version "1.10.9" - resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.10.9.tgz#468cc1549a3fe37b760a16745fb7685d91f4f10c" - integrity sha512-5tcgUctCG0qoNyfChZifz2tJqbRbXVO9J7X6duFcOjY3HUNCxg5D0ZCK7EP9vIcZ0zRpLU9bWkyCqVCLZ46IbQ== +"@grpc/grpc-js@1.12.2": + version "1.12.2" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.12.2.tgz#97eda82dd49bb9c24eaf6434ea8d7de446e95aac" + integrity sha512-bgxdZmgTrJZX50OjyVwz3+mNEnCTNkh3cIqGPWVNeW9jX6bn1ZkU80uPd+67/ZpIJIjRQ9qaHCjhavyoWYxumg== dependencies: "@grpc/proto-loader" "^0.7.13" "@js-sdsl/ordered-map" "^4.4.2" @@ -914,7 +914,14 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -debug@4, debug@4.3.4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: +debug@4: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + +debug@4.3.4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -980,9 +987,9 @@ delegates@^1.0.0: integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== detect-libc@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== diff@5.0.0: version "5.0.0" @@ -1172,7 +1179,7 @@ events@^3.2.0, events@^3.3.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.0.0, execa@^5.1.1: +execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -1202,6 +1209,21 @@ execa@^7.1.1: signal-exit "^3.0.7" strip-final-newline "^3.0.0" +execa@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1351,6 +1373,11 @@ get-stream@^6.0.0, get-stream@^6.0.1: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -1427,10 +1454,10 @@ google-protobuf@3.15.8: resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.15.8.tgz#5f3948905e4951c867d6bc143f385a80e2a39efe" integrity sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw== -google-protobuf@3.21.2: - version "3.21.2" - resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.2.tgz#4580a2bea8bbb291ee579d1fefb14d6fa3070ea4" - integrity sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA== +google-protobuf@3.21.4: + version "3.21.4" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.4.tgz#2f933e8b6e5e9f8edde66b7be0024b68f77da6c9" + integrity sha512-MnG7N936zcKTco4Jd2PX2U96Kf9PxygAPKBug+74LHzmHXmceN16MmRcdgZv+DGef/S9YvQAfRsNCn4cjf9yyQ== graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" @@ -1507,6 +1534,11 @@ human-signals@^4.3.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== + ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -1964,7 +1996,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@2.1.3, 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== @@ -2175,12 +2207,12 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pid-port@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/pid-port/-/pid-port-0.2.0.tgz#db45378e4dcdb8425f911b7c09d7b0187a399873" - integrity sha512-xVU9H1FCRSeGrD9Oim5bLg2U7B2BgW0qzK2oahpV5BIf9hwzqQaWyOkOVC0Kgbsc90A9x6525beawx+QK+JduQ== +pid-port@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pid-port/-/pid-port-1.0.0.tgz#b99a4d53dfeeae8b4e123d02c77e268de0413225" + integrity sha512-LSNBeKChRPA4Xlrs6+zV588G1hSrFvANtPV5rt/5MPfSPK3V9XPWxx1d29svsrOjngT9ifLisXWCLS7DvO9ZhQ== dependencies: - execa "^5.1.1" + execa "^8.0.1" pify@^2.0.0: version "2.3.0" @@ -2462,13 +2494,18 @@ semver@^6.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.3.5: +semver@^7.3.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" +semver@^7.3.5: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -2522,6 +2559,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + slash@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"