diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c09a29bf..9c83cc4c 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,13 +1,15 @@ { "name": "xterm.js", - "image": "mcr.microsoft.com/devcontainers/typescript-node:0-18-buster", + "image": "mcr.microsoft.com/devcontainers/typescript-node:18-bookworm", "features": { - "ghcr.io/devcontainers/features/node:1": {} // yarn + "ghcr.io/devcontainers/features/node:1": { + "version": 18 + } // yarn }, "forwardPorts": [ 3000 ], - "postCreateCommand": "yarn install", + "postCreateCommand": "yarn install && yarn setup", "customizations": { "vscode": { "extensions": [ diff --git a/.nvmrc b/.nvmrc index b6a7d89c..3c032078 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +18 diff --git a/.vscode/launch.json b/.vscode/launch.json index 5dbd01ce..eaa5e12e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -61,7 +61,7 @@ "runtimeExecutable": "npm", "runtimeArgs": ["start"], "stopOnEntry": true, - "runtimeVersion": "16", + "runtimeVersion": "18", "serverReadyAction": { "action": "openExternally", "pattern": "App listening to (http://.*?:[0-9]+)" diff --git a/README.md b/README.md index 4ecd58b2..d9392de3 100644 --- a/README.md +++ b/README.md @@ -223,6 +223,7 @@ Xterm.js is used in several world-class applications to provide great terminal e - [**Cloudtutor.io**](https://cloudtutor.io): innovative online learning platform that offers users access to an interactive lab. - [**Helix Editor Playground**](https://github.com/tomgroenwoldt/helix-editor-playground): Online playground for the terminal based helix editor. - [**Coder**](https://github.com/coder/coder): Self-Hosted Remote Development Environments +- [**Wave Terminal**](https://waveterm.dev): An open-source, ai-native, terminal built for seamless workflows. - [And much more...](https://github.com/xtermjs/xterm.js/network/dependents?package_id=UGFja2FnZS0xNjYzMjc4OQ%3D%3D) Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it on our list. Note: Please add any new contributions to the end of the list only. diff --git a/addons/addon-attach/webpack.config.js b/addons/addon-attach/webpack.config.js index 599bb142..3599a977 100644 --- a/addons/addon-attach/webpack.config.js +++ b/addons/addon-attach/webpack.config.js @@ -25,7 +25,9 @@ module.exports = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-canvas/webpack.config.js b/addons/addon-canvas/webpack.config.js index 9daa08f9..e0c7fde2 100644 --- a/addons/addon-canvas/webpack.config.js +++ b/addons/addon-canvas/webpack.config.js @@ -33,7 +33,9 @@ module.exports = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-fit/webpack.config.js b/addons/addon-fit/webpack.config.js index e220668c..aebb523a 100644 --- a/addons/addon-fit/webpack.config.js +++ b/addons/addon-fit/webpack.config.js @@ -25,7 +25,9 @@ module.exports = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-image/webpack.config.js b/addons/addon-image/webpack.config.js index b4283b66..239ebd24 100644 --- a/addons/addon-image/webpack.config.js +++ b/addons/addon-image/webpack.config.js @@ -33,7 +33,9 @@ const addon = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-ligatures/webpack.config.js b/addons/addon-ligatures/webpack.config.js index 6ec7f42d..f9e9f347 100644 --- a/addons/addon-ligatures/webpack.config.js +++ b/addons/addon-ligatures/webpack.config.js @@ -25,7 +25,9 @@ module.exports = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production', externals: { diff --git a/addons/addon-ligatures/yarn.lock b/addons/addon-ligatures/yarn.lock index 966fc113..ac58cbe2 100644 --- a/addons/addon-ligatures/yarn.lock +++ b/addons/addon-ligatures/yarn.lock @@ -86,9 +86,9 @@ fd-slicer@~1.1.0: pend "~1.2.0" follow-redirects@^1.15.0: - version "1.15.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" - integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== font-finder@^1.0.3: version "1.0.4" diff --git a/addons/addon-search/webpack.config.js b/addons/addon-search/webpack.config.js index a770f93f..78580548 100644 --- a/addons/addon-search/webpack.config.js +++ b/addons/addon-search/webpack.config.js @@ -32,7 +32,9 @@ module.exports = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-serialize/src/SerializeAddon.test.ts b/addons/addon-serialize/src/SerializeAddon.test.ts index ac485e54..7cb071bf 100644 --- a/addons/addon-serialize/src/SerializeAddon.test.ts +++ b/addons/addon-serialize/src/SerializeAddon.test.ts @@ -138,6 +138,16 @@ describe('SerializeAddon', () => { assert.equal((output.match(/
terminal<\/span><\/div>/g) || []).length, 1, output); }); + it('basic terminal with html unsafe chars', async () => { + await writeP(terminal, ' π '); + terminal.select(1, 0, 7); + + const output = serializeAddon.serializeAsHTML({ + onlySelection: true + }); + assert.equal((output.match(/
<a>&pi;<\/span><\/div>/g) || []).length, 1, output); + }); + it('cells with bold styling', async () => { await writeP(terminal, ' ' + sgr('1') + 'terminal' + sgr('22') + ' '); diff --git a/addons/addon-serialize/src/SerializeAddon.ts b/addons/addon-serialize/src/SerializeAddon.ts index e654eddb..cd15cfc3 100644 --- a/addons/addon-serialize/src/SerializeAddon.ts +++ b/addons/addon-serialize/src/SerializeAddon.ts @@ -14,6 +14,14 @@ function constrain(value: number, low: number, high: number): number { return Math.max(low, Math.min(value, high)); } +function escapeHTMLChar(c: string): string { + switch (c) { + case '&': return '&'; + case '<': return '<'; + } + return c; +} + // TODO: Refine this template class later abstract class BaseSerializeHandler { constructor( @@ -669,7 +677,7 @@ export class HTMLSerializeHandler extends BaseSerializeHandler { if (isEmptyCell) { this._currentRow += ' '; } else { - this._currentRow += cell.getChars(); + this._currentRow += escapeHTMLChar(cell.getChars()); } } diff --git a/addons/addon-serialize/webpack.config.js b/addons/addon-serialize/webpack.config.js index bd08ca37..837a73a3 100644 --- a/addons/addon-serialize/webpack.config.js +++ b/addons/addon-serialize/webpack.config.js @@ -34,7 +34,8 @@ module.exports = { path: path.resolve('./lib'), library: addonName, libraryTarget: 'umd', - globalObject: 'this' + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-unicode-graphemes/webpack.config.js b/addons/addon-unicode-graphemes/webpack.config.js index 6a80bdea..1ebaecaa 100644 --- a/addons/addon-unicode-graphemes/webpack.config.js +++ b/addons/addon-unicode-graphemes/webpack.config.js @@ -32,7 +32,9 @@ module.exports = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-unicode11/webpack.config.js b/addons/addon-unicode11/webpack.config.js index 1913481d..746d2581 100644 --- a/addons/addon-unicode11/webpack.config.js +++ b/addons/addon-unicode11/webpack.config.js @@ -33,7 +33,8 @@ module.exports = { path: path.resolve('./lib'), library: addonName, libraryTarget: 'umd', - globalObject: 'this' + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-web-links/webpack.config.js b/addons/addon-web-links/webpack.config.js index 4484dbf6..e8dcecef 100644 --- a/addons/addon-web-links/webpack.config.js +++ b/addons/addon-web-links/webpack.config.js @@ -25,7 +25,9 @@ module.exports = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/addons/addon-webgl/webpack.config.js b/addons/addon-webgl/webpack.config.js index f31ffd51..7365acff 100644 --- a/addons/addon-webgl/webpack.config.js +++ b/addons/addon-webgl/webpack.config.js @@ -33,7 +33,9 @@ module.exports = { filename: mainFile, path: path.resolve('./lib'), library: addonName, - libraryTarget: 'umd' + libraryTarget: 'umd', + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, mode: 'production' }; diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index 1b2f7b5b..cb0f35ea 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -51,6 +51,8 @@ export class Viewport extends Disposable implements IViewport { target: -1 }; + private _ensureTimeout: number; + private readonly _onRequestScrollLines = this.register(new EventEmitter<{ amount: number, suppressScrollEvent: boolean }>()); public readonly onRequestScrollLines = this._onRequestScrollLines.event; @@ -83,7 +85,7 @@ export class Viewport extends Disposable implements IViewport { this.register(this._optionsService.onSpecificOptionChange('scrollback', () => this.syncScrollArea())); // Perform this async to ensure the ICharSizeService is ready. - setTimeout(() => this.syncScrollArea()); + this._ensureTimeout = window.setTimeout(() => this.syncScrollArea()); } private _handleThemeChange(colors: ReadonlyColorSet): void { @@ -405,4 +407,8 @@ export class Viewport extends Disposable implements IViewport { this._viewportElement.scrollTop += deltaY; return this._bubbleScroll(ev, deltaY); } + + public dispose(): void { + clearTimeout(this._ensureTimeout); + } } diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index c89cee62..92d152f0 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -343,6 +343,9 @@ export class DomRenderer extends Disposable implements IRenderer { } this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode); + if (!this._selectionRenderModel.hasSelection) { + return; + } // Translate from buffer position to viewport position const viewportStartRow = this._selectionRenderModel.viewportStartRow; @@ -350,11 +353,6 @@ export class DomRenderer extends Disposable implements IRenderer { const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow; const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow; - // No need to draw the selection - if (viewportCappedStartRow >= this._bufferService.rows || viewportCappedEndRow < 0) { - return; - } - // Create the selections const documentFragment = this._document.createDocumentFragment(); diff --git a/src/browser/services/CoreBrowserService.ts b/src/browser/services/CoreBrowserService.ts index 575b62b6..a6c066b2 100644 --- a/src/browser/services/CoreBrowserService.ts +++ b/src/browser/services/CoreBrowserService.ts @@ -13,7 +13,7 @@ export class CoreBrowserService extends Disposable implements ICoreBrowserServic private _isFocused = false; private _cachedIsFocused: boolean | undefined = undefined; - private _screenDprMonitor = new ScreenDprMonitor(this._window); + private _screenDprMonitor = this.register(new ScreenDprMonitor(this._window)); private readonly _onDprChange = this.register(new EventEmitter()); public readonly onDprChange = this._onDprChange.event; @@ -31,8 +31,12 @@ export class CoreBrowserService extends Disposable implements ICoreBrowserServic this.register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w))); this.register(forwardEvent(this._screenDprMonitor.onDprChange, this._onDprChange)); - this._textarea.addEventListener('focus', () => this._isFocused = true); - this._textarea.addEventListener('blur', () => this._isFocused = false); + this.register( + addDisposableDomListener(this._textarea, 'focus', () => (this._isFocused = true)) + ); + this.register( + addDisposableDomListener(this._textarea, 'blur', () => (this._isFocused = false)) + ); } public get window(): Window & typeof globalThis { diff --git a/src/common/InputHandler.test.ts b/src/common/InputHandler.test.ts index 8f9a988f..0f17a3e6 100644 --- a/src/common/InputHandler.test.ts +++ b/src/common/InputHandler.test.ts @@ -12,11 +12,12 @@ import { Attributes, BgFlags, UnderlineStyle } from 'common/buffer/Constants'; import { AttributeData, ExtendedAttrs } from 'common/buffer/AttributeData'; import { Params } from 'common/parser/Params'; import { MockCoreService, MockBufferService, MockOptionsService, MockLogService, MockCoreMouseService, MockCharsetService, MockUnicodeService, MockOscLinkService } from 'common/TestUtils.test'; -import { IBufferService, ICoreService } from 'common/services/Services'; +import { IBufferService, ICoreService, type IOscLinkService } from 'common/services/Services'; import { DEFAULT_OPTIONS } from 'common/services/OptionsService'; import { clone } from 'common/Clone'; import { BufferService } from 'common/services/BufferService'; import { CoreService } from 'common/services/CoreService'; +import { OscLinkService } from 'common/services/OscLinkService'; function getCursor(bufferService: IBufferService): number[] { @@ -59,6 +60,7 @@ describe('InputHandler', () => { let bufferService: IBufferService; let coreService: ICoreService; let optionsService: MockOptionsService; + let oscLinkService: IOscLinkService; let inputHandler: TestInputHandler; beforeEach(() => { @@ -66,8 +68,9 @@ describe('InputHandler', () => { bufferService = new BufferService(optionsService); bufferService.resize(80, 30); coreService = new CoreService(bufferService, new MockLogService(), optionsService); + oscLinkService = new OscLinkService(bufferService); - inputHandler = new TestInputHandler(bufferService, new MockCharsetService(), coreService, new MockLogService(), optionsService, new MockOscLinkService(), new MockCoreMouseService(), new MockUnicodeService()); + inputHandler = new TestInputHandler(bufferService, new MockCharsetService(), coreService, new MockLogService(), optionsService, oscLinkService, new MockCoreMouseService(), new MockUnicodeService()); }); describe('SL/SR/DECIC/DECDC', () => { @@ -1982,6 +1985,32 @@ describe('InputHandler', () => { assert.deepEqual(stack, [[{ type: ColorRequestType.SET, index: 0, color: [170, 187, 204] }, { type: ColorRequestType.SET, index: 123, color: [0, 17, 34] }]]); stack.length = 0; }); + it('8: hyperlink with id', async () => { + await inputHandler.parseP('\x1b]8;id=100;http://localhost:3000\x07'); + assert.notStrictEqual(inputHandler.curAttrData.extended.urlId, 0); + assert.deepStrictEqual( + oscLinkService.getLinkData(inputHandler.curAttrData.extended.urlId), + { + id: '100', + uri: 'http://localhost:3000' + } + ); + await inputHandler.parseP('\x1b]8;;\x07'); + assert.strictEqual(inputHandler.curAttrData.extended.urlId, 0); + }); + it('8: hyperlink with semi-colon', async () => { + await inputHandler.parseP('\x1b]8;;http://localhost:3000;abc=def\x07'); + assert.notStrictEqual(inputHandler.curAttrData.extended.urlId, 0); + assert.deepStrictEqual( + oscLinkService.getLinkData(inputHandler.curAttrData.extended.urlId), + { + id: undefined, + uri: 'http://localhost:3000;abc=def' + } + ); + await inputHandler.parseP('\x1b]8;;\x07'); + assert.strictEqual(inputHandler.curAttrData.extended.urlId, 0); + }); it('104: restore events', async () => { const stack: IColorEvent[] = []; inputHandler.onColor(ev => stack.push(ev)); diff --git a/src/common/InputHandler.ts b/src/common/InputHandler.ts index 9b300993..6db8751e 100644 --- a/src/common/InputHandler.ts +++ b/src/common/InputHandler.ts @@ -2972,14 +2972,18 @@ export class InputHandler extends Disposable implements IInputHandler { * feedback. Use `OSC 8 ; ; BEL` to finish the current hyperlink. */ public setHyperlink(data: string): boolean { - const args = data.split(';'); - if (args.length < 2) { - return false; + // Arg parsing is special cases to support unencoded semi-colons in the URIs (#4944) + const idx = data.indexOf(';'); + if (idx === -1) { + // malformed sequence, just return as handled + return true; } - if (args[1]) { - return this._createHyperlink(args[0], args[1]); + const id = data.slice(0, idx).trim(); + const uri = data.slice(idx + 1); + if (uri) { + return this._createHyperlink(id, uri); } - if (args[0].trim()) { + if (id.trim()) { return false; } return this._finishHyperlink(); diff --git a/test/playwright/SharedRendererTests.ts b/test/playwright/SharedRendererTests.ts index c4b66536..68492b3d 100644 --- a/test/playwright/SharedRendererTests.ts +++ b/test/playwright/SharedRendererTests.ts @@ -1234,6 +1234,20 @@ export function injectSharedRendererTests(ctx: ISharedRendererTestContext): void await pollFor(ctx.value.page, () => getCellColor(ctx.value, 1, rows), [0, 0, 0, 255]); await pollFor(ctx.value.page, () => getCellColor(ctx.value, 1, rows, CellColorPosition.FIRST), [0, 0, 255, 255]); }); + test('#4917 The selection should not be displayed if it is not within the scope of the viewport.', async () => { + const theme: ITheme = { + selectionBackground: '#FF0000' + }; + await ctx.value.page.evaluate(`window.term.options.theme = ${JSON.stringify(theme)};`); + for (let index = 0; index < 160; index++) { + await ctx.value.proxy.writeln(``); + } + await ctx.value.proxy.scrollToBottom(); + const rows = await ctx.value.proxy.buffer.active.length; + await ctx.value.proxy.selectLines(rows - 1, rows - 1); + await ctx.value.proxy.scrollLines(-2); + await pollFor(ctx.value.page, () => getCellColor(ctx.value, 1, 1), [0, 0, 0, 255]); + }); }); } diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 33008289..b6470275 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -47,11 +47,13 @@ declare module '@xterm/xterm' { /** * When enabled the cursor will be set to the beginning of the next line - * with every new line. This is equivalent to sending '\r\n' for each '\n'. - * Normally the termios settings of the underlying PTY deals with the - * translation of '\n' to '\r\n' and this setting should not be used. If you + * with every new line. This is equivalent to sending `\r\n` for each `\n`. + * Normally the settings of the underlying PTY (`termios`) deal with the + * translation of `\n` to `\r\n` and this setting should not be used. If you * deal with data from a non-PTY related source, this settings might be * useful. + * + * @see https://pubs.opengroup.org/onlinepubs/007904975/basedefs/termios.h.html */ convertEol?: boolean; diff --git a/webpack.config.headless.js b/webpack.config.headless.js index 9e9099cd..12e7484d 100644 --- a/webpack.config.headless.js +++ b/webpack.config.headless.js @@ -39,8 +39,10 @@ const config = { path: path.resolve('./headless/lib-headless'), library: { type: 'commonjs' - } + }, + // Force usage of globalThis instead of global / self. (This is cross-env compatible) + globalObject: 'globalThis', }, - mode: 'production' + mode: 'production', }; module.exports = config; diff --git a/yarn.lock b/yarn.lock index b2788793..e566fff2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1099,13 +1099,13 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== dependencies: bytes "3.1.2" - content-type "~1.0.4" + content-type "~1.0.5" debug "2.6.9" depd "2.0.0" destroy "1.2.0" @@ -1113,7 +1113,7 @@ body-parser@1.20.1: iconv-lite "0.4.24" on-finished "2.4.1" qs "6.11.0" - raw-body "2.5.1" + raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -1402,7 +1402,7 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4: +content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== @@ -1417,10 +1417,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== cross-env@^7.0.3: version "7.0.3" @@ -1832,16 +1832,16 @@ express-ws@^5.0.2: ws "^7.4.6" express@^4.17.1: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.1" + body-parser "1.20.2" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.5.0" + cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" @@ -3242,10 +3242,10 @@ range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: bytes "3.1.2" http-errors "2.0.0"