diff --git a/.eslint/rules/enforce-array-buffer.js b/.eslint/rules/enforce-array-buffer.js new file mode 100644 index 0000000000..d3a49db5f2 --- /dev/null +++ b/.eslint/rules/enforce-array-buffer.js @@ -0,0 +1,41 @@ +// Copyright 2026 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +/** @type {import("eslint").Rule.RuleModule} */ +module.exports = { + meta: { + type: 'problem', + hasSuggestions: true, + fixable: true, + }, + create(context) { + return { + TSTypeReference(node) { + if (node.typeName.type !== 'Identifier') { + return; + } + + let replacement; + if (node.typeName.name === 'Uint8Array') { + replacement = 'Uint8Array'; + } else if (node.typeName.name === 'Buffer') { + replacement = 'Buffer'; + } else { + return; + } + + if (node.typeParameters != null) { + return; + } + + context.report({ + node, + message: `Should be ${replacement}`, + fix(fixer) { + return [fixer.replaceTextRange(node.range, replacement)]; + }, + }); + }, + }; + }, +}; diff --git a/.eslint/rules/enforce-array-buffer.test.js b/.eslint/rules/enforce-array-buffer.test.js new file mode 100644 index 0000000000..adf8c7b0e1 --- /dev/null +++ b/.eslint/rules/enforce-array-buffer.test.js @@ -0,0 +1,83 @@ +// Copyright 2026 Signal Messenger, LLC +// SPDX-License-Identifier: AGPL-3.0-only + +const rule = require('./enforce-array-buffer'); +const RuleTester = require('eslint').RuleTester; + +// avoid triggering mocha's global leak detection +require('@typescript-eslint/parser'); + +const ruleTester = new RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { + ecmaVersion: 2018, + sourceType: 'module', + }, +}); + +const EXPECTED_ARRAY_ERROR = { + message: 'Should be Uint8Array', + type: 'TSTypeReference', +}; + +const EXPECTED_BUFFER_ERROR = { + message: 'Should be Buffer', + type: 'TSTypeReference', +}; + +ruleTester.run('enforce-array-buffer', rule, { + valid: [ + { code: 'type T = number;' }, + { code: 'type T = Uint16Array;' }, + { code: 'type T = Uint8Array;' }, + { code: 'type T = Uint8Array;' }, + { code: 'type T = Uint8Array;' }, + { code: 'type T = Uint8Array;' }, + { code: 'function f(): Uint8Array {}' }, + { code: 'function f(p: Uint8Array) {}' }, + { code: 'let v: Uint8Array;' }, + { code: 'let v = new Uint8Array();' }, + { code: 'let v = new Uint8Array();' }, + { code: 'let v = Uint8Array.of();' }, + { code: 'let v = Uint8Array.from();' }, + { code: 'let v: { p: Uint8Array };' }, + { code: 'type T = Buffer;' }, + { code: 'type T = Buffer;' }, + { code: 'type T = Buffer;' }, + { code: 'type T = Buffer;' }, + { code: 'let v = new Buffer();' }, + { code: 'let v = Buffer.from();' }, + ], + invalid: [ + { + code: `type T = Uint8Array`, + output: `type T = Uint8Array`, + errors: [EXPECTED_ARRAY_ERROR], + }, + { + code: `function f(): Uint8Array {}`, + output: `function f(): Uint8Array {}`, + errors: [EXPECTED_ARRAY_ERROR], + }, + { + code: `function f(p: Uint8Array) {}`, + output: `function f(p: Uint8Array) {}`, + errors: [EXPECTED_ARRAY_ERROR], + }, + { + code: `let v: Uint8Array;`, + output: `let v: Uint8Array;`, + errors: [EXPECTED_ARRAY_ERROR], + }, + { + code: `let v: { p: Uint8Array };`, + output: `let v: { p: Uint8Array };`, + errors: [EXPECTED_ARRAY_ERROR], + }, + { + code: `type T = Buffer`, + output: `type T = Buffer`, + errors: [EXPECTED_BUFFER_ERROR], + }, + ], +}); diff --git a/.eslintrc.js b/.eslintrc.js index c4284ac583..72746679a5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -274,6 +274,8 @@ const typescriptRules = { ], }, ], + + 'local-rules/enforce-array-buffer': 'error', }; const TAILWIND_REPLACEMENTS = [ diff --git a/.npmrc b/.npmrc index 92a6b97c6d..e7f6774187 100644 --- a/.npmrc +++ b/.npmrc @@ -3,6 +3,7 @@ public-hoist-pattern[]=*eslint-* minimum-release-age=14400 minimum-release-age-exclude[]=@signalapp/* minimum-release-age-exclude[]=@indutny/* +minimum-release-age-exclude[]=@types/* minimum-release-age-exclude[]=electron minimum-release-age-exclude[]=react minimum-release-age-exclude[]=react-dom diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md index fb52689ae4..8874a789a7 100644 --- a/ACKNOWLEDGMENTS.md +++ b/ACKNOWLEDGMENTS.md @@ -3361,6 +3361,64 @@ Signal Desktop makes use of the following open source projects. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE +## @typescript/native-preview + + Apache License + + Version 2.0, January 2004 + + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + + "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + You must give any other recipients of the Work or Derivative Works a copy of this License; and + + You must cause any modified files to carry prominent notices stating that You changed the files; and + + You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + + If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + ## blob-util Apache License diff --git a/app/EmojiService.main.ts b/app/EmojiService.main.ts index 7e45e847f2..d14e38b344 100644 --- a/app/EmojiService.main.ts +++ b/app/EmojiService.main.ts @@ -23,7 +23,7 @@ type EmojiEntryType = Readonly<{ sheet: string; }>; -type SheetCacheEntry = Map; +type SheetCacheEntry = Map>; export class EmojiService { readonly #emojiMap = new Map(); @@ -83,10 +83,11 @@ export class EmojiService { const pack = Proto.JumbomojiPack.decode(proto); imageMap = new Map( - pack.items.map(({ name, image }) => [ - name != null ? utf16ToEmoji(name) : '', - image || new Uint8Array(0), - ]) + pack.items.map(({ name, image }) => { + const key = name != null ? utf16ToEmoji(name) : ''; + const value: Uint8Array = image || new Uint8Array(0); + return [key, value]; + }) ); this.#sheetCache.set(sheet, imageMap); } diff --git a/app/OptionalResourceService.main.ts b/app/OptionalResourceService.main.ts index 0b4236029c..653811ae3b 100644 --- a/app/OptionalResourceService.main.ts +++ b/app/OptionalResourceService.main.ts @@ -33,7 +33,7 @@ const MAX_CACHE_SIZE = 50 * 1024 * 1024; export class OptionalResourceService { #maybeDeclaration: OptionalResourcesDictType | undefined; - readonly #cache = new LRUCache({ + readonly #cache = new LRUCache>({ maxSize: MAX_CACHE_SIZE, sizeCalculation: buf => buf.length, @@ -53,7 +53,7 @@ export class OptionalResourceService { return new OptionalResourceService(resourcesDir); } - public async getData(name: string): Promise { + public async getData(name: string): Promise | undefined> { await this.#lazyInit(); const decl = this.#declaration[name]; @@ -172,8 +172,10 @@ export class OptionalResourceService { name: string, decl: OptionalResourceType, destPath: string - ): Promise { - const result = await got(decl.url, await getGotOptions()).buffer(); + ): Promise> { + const opts = await getGotOptions(); + // @ts-expect-error https://github.com/sindresorhus/got/issues/2418#issuecomment-4071277145 + const result: Buffer = await got(decl.url, opts).buffer(); const digest = createHash('sha512').update(result).digest(); diff --git a/app/attachment_channel.main.ts b/app/attachment_channel.main.ts index 19b8991347..cb5643f9aa 100644 --- a/app/attachment_channel.main.ts +++ b/app/attachment_channel.main.ts @@ -98,8 +98,8 @@ type RangeFinderContextType = Readonly< } | { type: 'incremental'; - digest: Uint8Array; - incrementalMac: Uint8Array; + digest: Uint8Array; + incrementalMac: Uint8Array; chunkSize: number; keysBase64: string; size: number; @@ -113,8 +113,8 @@ type RangeFinderContextType = Readonly< >; type DigestLRUEntryType = Readonly<{ - key: Buffer; - digest: Uint8Array; + key: Buffer; + digest: Uint8Array; }>; const digestLRU = new LRUCache({ diff --git a/app/attachments.node.ts b/app/attachments.node.ts index 04c76b5306..cdc3f49c74 100644 --- a/app/attachments.node.ts +++ b/app/attachments.node.ts @@ -294,10 +294,10 @@ export const readAndDecryptDataFromDisk = async ({ absolutePath: string; keysBase64: string; size: number; -}): Promise => { +}): Promise> => { const sink = new PassThrough(); - const chunks = new Array(); + const chunks = new Array>(); sink.on('data', chunk => chunks.push(chunk)); sink.resume(); @@ -321,7 +321,7 @@ export const writeNewAttachmentData = async ({ data, getAbsoluteAttachmentPath, }: { - data: Uint8Array; + data: Uint8Array; getAbsoluteAttachmentPath: (relativePath: string) => string; }): Promise => { const keys = generateKeys(); diff --git a/app/locale.node.ts b/app/locale.node.ts index 2c94d5d3ed..4286903f6f 100644 --- a/app/locale.node.ts +++ b/app/locale.node.ts @@ -5,7 +5,6 @@ import { join } from 'node:path'; import { readFileSync } from 'node:fs'; import lodash from 'lodash'; import * as LocaleMatcher from '@formatjs/intl-localematcher'; -import { z } from 'zod'; import { setupI18n } from '../ts/util/setupI18nMain.std.js'; import { shouldNeverBeCalled } from '../ts/util/shouldNeverBeCalled.std.js'; @@ -15,18 +14,12 @@ import type { LocaleMessagesType, } from '../ts/types/I18N.std.js'; import type { LocalizerType } from '../ts/types/Util.std.js'; -import * as Errors from '../ts/types/errors.std.js'; -import { parseUnknown } from '../ts/util/schemas.std.js'; const { merge } = lodash; type CompactLocaleMessagesType = ReadonlyArray; type CompactLocaleKeysType = ReadonlyArray; -const TextInfoSchema = z.object({ - direction: z.enum(['ltr', 'rtl']), -}); - function getLocaleMessages(locale: string): LocaleMessagesType { const targetFile = join(__dirname, '..', '_locales', locale, 'messages.json'); @@ -80,37 +73,8 @@ export type LocaleType = { countryDisplayNames: CountryDisplayNames; }; -function getLocaleDirection( - localeName: string, - logger: LoggerType -): LocaleDirection { - const locale = new Intl.Locale(localeName); - // TC39 proposal is now `locale.getTextInfo()` but in browsers its currently - // `locale.textInfo` - try { - // @ts-expect-error -- TS doesn't know about this method - if (typeof locale.getTextInfo === 'function') { - return parseUnknown( - TextInfoSchema, - // @ts-expect-error -- TS doesn't know about this method - locale.getTextInfo() as unknown - ).direction; - } - // @ts-expect-error -- TS doesn't know about this property - if (typeof locale.textInfo === 'object') { - return parseUnknown( - TextInfoSchema, - // @ts-expect-error -- TS doesn't know about this property - locale.textInfo as unknown - ).direction; - } - } catch (error) { - logger.error( - 'locale: Error getting text info for locale', - Errors.toLogFormat(error) - ); - } - return 'ltr'; +function getLocaleDirection(localeName: string): LocaleDirection { + return new Intl.Locale(localeName).getTextInfo().direction ?? 'ltr'; } export function _getAvailableLocales(): Array { @@ -202,7 +166,7 @@ export function load({ getHourCyclePreference: shouldNeverBeCalled, }); const direction = - localeDirectionTestingOverride ?? getLocaleDirection(matchedLocale, logger); + localeDirectionTestingOverride ?? getLocaleDirection(matchedLocale); logger.info(`locale: Text info direction for ${matchedLocale}: ${direction}`); return { diff --git a/eslint-local-rules.js b/eslint-local-rules.js index ce82e66752..101aa75303 100644 --- a/eslint-local-rules.js +++ b/eslint-local-rules.js @@ -6,5 +6,6 @@ module.exports = { 'license-comments': require('./.eslint/rules/license-comments'), 'type-alias-readonlydeep': require('./.eslint/rules/type-alias-readonlydeep'), 'enforce-tw': require('./.eslint/rules/enforce-tw'), + 'enforce-array-buffer': require('./.eslint/rules/enforce-array-buffer'), 'file-suffix': require('./.eslint/rules/file-suffix'), }; diff --git a/package.json b/package.json index f1fc003605..82461b48e0 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "format": "pprettier --write '**/*.{ts,tsx,d.ts,js,json,html,scss,md,yml,yaml}' '!node_modules/**'", "svgo": "svgo --multipass images/**/*.svg images/*.svg", "transpile": "run-p check:types build:esbuild", - "check:types": "tsc --noEmit", + "check:types": "tsgo --noEmit", "clean-transpile": "node ./scripts/clean-transpile.js", "ready": "npm-run-all --print-label clean-transpile generate --parallel lint lint-deps lint-intl test-node test-electron", "dev": "pnpm run build:protobuf && cross-env SIGNAL_ENV=storybook storybook dev --port 6006", @@ -104,8 +104,6 @@ "build:emoji": "run-p build:emoji:32 build:emoji:64", "build:emoji:32": "cwebp -progress -mt -preset icon -alpha_filter best -alpha_q 20 -pass 10 -q 75 ./node_modules/emoji-datasource-apple/img/apple/sheets/32.png -o ./images/emoji-sheet-32.webp", "build:emoji:64": "cwebp -progress -mt -preset icon -alpha_filter best -alpha_q 20 -pass 10 -q 75 ./node_modules/emoji-datasource-apple/img/apple/sheets/64.png -o ./images/emoji-sheet-64.webp", - "verify": "run-p --print-label verify:*", - "verify:ts": "tsc --noEmit", "electron:install-app-deps": "electron-builder install-app-deps", "check-upgradeable-deps": "ts-node ts/scripts/check-upgradeable-deps.node.ts", "react-devtools": "react-devtools", @@ -121,7 +119,7 @@ "@formatjs/intl-localematcher": "0.2.32", "@indutny/dicer": "0.3.2", "@indutny/mac-screen-share": "1.0.13", - "@indutny/protopiler": "3.2.0", + "@indutny/protopiler": "3.2.1", "@indutny/range-finder": "1.3.4", "@indutny/simple-windows-notifications": "2.0.16", "@indutny/sneequals": "4.0.0", @@ -132,16 +130,17 @@ "@react-aria/utils": "3.33.1", "@react-spring/web": "10.0.3", "@react-types/shared": "3.33.1", - "@signalapp/libsignal-client": "0.88.3", + "@signalapp/libsignal-client": "0.89.0", "@signalapp/minimask": "1.0.1", "@signalapp/mute-state-change": "workspace:1.0.0", "@signalapp/quill-cjs": "2.1.2", "@signalapp/ringrtc": "2.67.0", - "@signalapp/sqlcipher": "2.4.4", + "@signalapp/sqlcipher": "3.2.1", "@signalapp/windows-ucv": "1.0.1", "@tanstack/react-virtual": "3.11.2", "@types/dom-mediacapture-transform": "0.1.11", "@types/fabric": "4.5.3", + "@typescript/native-preview": "7.0.0-dev.20260303.1", "blob-util": "2.0.2", "blueimp-load-image": "5.16.0", "blurhash": "2.0.5", @@ -236,7 +235,7 @@ "@indutny/parallel-prettier": "3.0.0", "@indutny/rezip-electron": "3.0.2", "@napi-rs/canvas": "0.1.61", - "@signalapp/mock-server": "18.2.0", + "@signalapp/mock-server": "18.3.0", "@storybook/addon-a11y": "8.4.4", "@storybook/addon-actions": "8.4.4", "@storybook/addon-controls": "8.4.4", @@ -272,7 +271,7 @@ "@types/lodash": "4.14.106", "@types/memoizee": "0.4.11", "@types/mocha": "10.0.9", - "@types/node": "20.17.6", + "@types/node": "24.12.0", "@types/node-fetch": "2.6.12", "@types/normalize-path": "3.0.2", "@types/parsecurrency": "1.0.2", @@ -335,7 +334,7 @@ "npm-run-all": "4.1.5", "p-limit": "3.1.0", "pixelmatch": "5.3.0", - "playwright": "1.54.2", + "playwright": "1.58.2", "pngjs": "7.0.0", "postcss": "8.5.3", "postcss-loader": "8.1.1", @@ -359,7 +358,7 @@ "tailwindcss": "4.1.7", "terser-webpack-plugin": "5.3.10", "ts-node": "10.9.2", - "typescript": "5.6.3", + "typescript": "5.9.3", "wait-on": "8.0.1", "webpack": "5.96.1", "webpack-cli": "5.1.4", @@ -381,7 +380,7 @@ "@types/express@4.17.21": "patches/@types+express+4.17.21.patch", "@types/fabric@4.5.3": "patches/@types+fabric+4.5.3.patch", "qrcode-generator@1.4.4": "patches/qrcode-generator+1.4.4.patch", - "@types/node-fetch@2.6.12": "patches/@types+node-fetch+2.6.12.patch", + "@types/node-fetch@2.6.12": "patches/@types__node-fetch@2.6.12.patch", "fabric@4.6.0": "patches/fabric+4.6.0.patch", "@vitest/expect@2.0.5": "patches/@vitest+expect+2.0.5.patch", "got@11.8.5": "patches/got+11.8.5.patch", @@ -392,7 +391,9 @@ "dmg-builder": "patches/dmg-builder.patch", "eslint-plugin-better-tailwindcss": "patches/eslint-plugin-better-tailwindcss.patch", "fs-xattr": "patches/fs-xattr.patch", - "@types/chai": "patches/@types__chai.patch" + "@types/chai": "patches/@types__chai.patch", + "@napi-rs/canvas@0.1.61": "patches/@napi-rs__canvas@0.1.61.patch", + "playwright-core@1.58.2": "patches/playwright-core@1.58.2.patch" }, "onlyBuiltDependencies": [ "@indutny/mac-screen-share", diff --git a/patches/@napi-rs__canvas@0.1.61.patch b/patches/@napi-rs__canvas@0.1.61.patch new file mode 100644 index 0000000000..77710210c3 --- /dev/null +++ b/patches/@napi-rs__canvas@0.1.61.patch @@ -0,0 +1,61 @@ +diff --git a/index.d.ts b/index.d.ts +index 37f233281dac070b5b64ad810d766dce269e095e..3698e98b27ddf4849097811e1e8b25df955fb9b9 100644 +--- a/index.d.ts ++++ b/index.d.ts +@@ -195,7 +195,7 @@ export class Image { + readonly naturalHeight: number + readonly complete: boolean + alt: string +- src: Buffer ++ src: Buffer + onload?(): void + onerror?(err: Error): void + } +@@ -296,7 +296,7 @@ export interface SvgCanvas { + height: number + getContext(contextType: '2d', contextAttributes?: ContextAttributes): SKRSContext2D + +- getContent(): Buffer ++ getContent(): Buffer + } + + export interface AvifConfig { +@@ -360,18 +360,18 @@ export class Canvas { + width: number + height: number + getContext(contextType: '2d', contextAttributes?: ContextAttributes): SKRSContext2D +- encodeSync(format: 'webp' | 'jpeg', quality?: number): Buffer +- encodeSync(format: 'png'): Buffer +- encodeSync(format: 'avif', cfg?: AvifConfig): Buffer +- encode(format: 'webp' | 'jpeg', quality?: number): Promise +- encode(format: 'png'): Promise +- encode(format: 'avif', cfg?: AvifConfig): Promise +- +- toBuffer(mime: 'image/png'): Buffer +- toBuffer(mime: 'image/jpeg' | 'image/webp', quality?: number): Buffer +- toBuffer(mime: 'image/avif', cfg?: AvifConfig): Buffer ++ encodeSync(format: 'webp' | 'jpeg', quality?: number): Buffer ++ encodeSync(format: 'png'): Buffer ++ encodeSync(format: 'avif', cfg?: AvifConfig): Buffer ++ encode(format: 'webp' | 'jpeg', quality?: number): Promise> ++ encode(format: 'png'): Promise> ++ encode(format: 'avif', cfg?: AvifConfig): Promise> ++ ++ toBuffer(mime: 'image/png'): Buffer ++ toBuffer(mime: 'image/jpeg' | 'image/webp', quality?: number): Buffer ++ toBuffer(mime: 'image/avif', cfg?: AvifConfig): Buffer + // raw pixels +- data(): Buffer ++ data(): Buffer + toDataURL(mime?: 'image/png'): string + toDataURL(mime: 'image/jpeg' | 'image/webp', quality?: number): string + toDataURL(mime?: 'image/jpeg' | 'image/webp' | 'image/png', quality?: number): string +@@ -439,7 +439,7 @@ export enum SvgExportFlag { + RelativePathEncoding = 0x04, + } + +-export function convertSVGTextToPath(svg: Buffer | string): Buffer ++export function convertSVGTextToPath(svg: Buffer | string): Buffer + + export interface LoadImageOptions { + alt?: string diff --git a/patches/@types+node-fetch+2.6.12.patch b/patches/@types__node-fetch@2.6.12.patch similarity index 53% rename from patches/@types+node-fetch+2.6.12.patch rename to patches/@types__node-fetch@2.6.12.patch index ac4e27a8f4..2869a59514 100644 --- a/patches/@types+node-fetch+2.6.12.patch +++ b/patches/@types__node-fetch@2.6.12.patch @@ -1,5 +1,5 @@ diff --git a/index.d.ts b/index.d.ts -index f95f9c1..72b3814 100644 +index f95f9c1747a4cc6229b29ab450a859277ad3c16e..6650687fe938868555bb7ec2dbc67ea4a219a0e9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3,7 +3,8 @@ @@ -12,3 +12,12 @@ index f95f9c1..72b3814 100644 declare class Request extends Body { constructor(input: RequestInfo, init?: RequestInit); +@@ -130,7 +131,7 @@ declare class Body { + blob(): Promise; + body: NodeJS.ReadableStream; + bodyUsed: boolean; +- buffer(): Promise; ++ buffer(): Promise>; + json(): Promise; + size: number; + text(): Promise; diff --git a/patches/playwright-core@1.58.2.patch b/patches/playwright-core@1.58.2.patch new file mode 100644 index 0000000000..643e309d9a --- /dev/null +++ b/patches/playwright-core@1.58.2.patch @@ -0,0 +1,13 @@ +diff --git a/types/types.d.ts b/types/types.d.ts +index f6e6165885f0ae32b9d130797c77d5da04fba8cf..961c42536324ae50f48a8fbd0259228869a5487a 100644 +--- a/types/types.d.ts ++++ b/types/types.d.ts +@@ -4101,7 +4101,7 @@ export interface Page { + * Returns the buffer with the captured screenshot. + * @param options + */ +- screenshot(options?: PageScreenshotOptions): Promise; ++ screenshot(options?: PageScreenshotOptions): Promise>; + + /** + * **NOTE** Use locator-based diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5f3743cb28..12148d20cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,6 +15,9 @@ overrides: react-popper@2.3.0>react-dom: 19.2.4 patchedDependencies: + '@napi-rs/canvas@0.1.61': + hash: d232c1154bffd88fa8df40fc91dc36098b29aba725d826c24ce74cfac7803919 + path: patches/@napi-rs__canvas@0.1.61.patch '@types/chai': hash: 610a7faa9e043c420d54f80984cbbbe4d0c5940d76cf57de8112e93a70862fb1 path: patches/@types__chai.patch @@ -25,8 +28,8 @@ patchedDependencies: hash: e5f339ecf72fbab1c91505e7713e127a7184bfe8164aa3a9afe9bf45a0ad6b89 path: patches/@types+fabric+4.5.3.patch '@types/node-fetch@2.6.12': - hash: bc43fb8cfed85fb4f7917b5bd3b47644ae15a000c26a6fe23078b2f5217efaf0 - path: patches/@types+node-fetch+2.6.12.patch + hash: e5c9ff6ac5dd2c13f52c0eeed685f6d43b78c687ebd45d4e333a2f8602cc1ce2 + path: patches/@types__node-fetch@2.6.12.patch '@vitest/expect@2.0.5': hash: e8a96f71e52bf903c9f1eadba4740489a0beb48da33db52354adca484fe1f495 path: patches/@vitest+expect+2.0.5.patch @@ -57,6 +60,9 @@ patchedDependencies: node-fetch@2.6.7: hash: 94385e2da301d6873723275386bb0c70da98cf56487f2431668d8fd79623818d path: patches/node-fetch+2.6.7.patch + playwright-core@1.58.2: + hash: 7fb22c7946d93ff366ea2b93165653a6b7f988e3f1d08b5601a915959e0c49ce + path: patches/playwright-core@1.58.2.patch qrcode-generator@1.4.4: hash: 1f10c592d849ed4cfc9f81301196d39857b79240997ef5772138218cb3717e80 path: patches/qrcode-generator+1.4.4.patch @@ -87,8 +93,8 @@ importers: specifier: 1.0.13 version: 1.0.13 '@indutny/protopiler': - specifier: 3.2.0 - version: 3.2.0 + specifier: 3.2.1 + version: 3.2.1 '@indutny/range-finder': specifier: 1.3.4 version: 1.3.4 @@ -120,8 +126,8 @@ importers: specifier: 3.33.1 version: 3.33.1(react@19.2.4) '@signalapp/libsignal-client': - specifier: 0.88.3 - version: 0.88.3 + specifier: 0.89.0 + version: 0.89.0 '@signalapp/minimask': specifier: 1.0.1 version: 1.0.1 @@ -135,8 +141,8 @@ importers: specifier: 2.67.0 version: 2.67.0 '@signalapp/sqlcipher': - specifier: 2.4.4 - version: 2.4.4 + specifier: 3.2.1 + version: 3.2.1 '@signalapp/windows-ucv': specifier: 1.0.1 version: 1.0.1 @@ -149,6 +155,9 @@ importers: '@types/fabric': specifier: 4.5.3 version: 4.5.3(patch_hash=e5f339ecf72fbab1c91505e7713e127a7184bfe8164aa3a9afe9bf45a0ad6b89) + '@typescript/native-preview': + specifier: 7.0.0-dev.20260303.1 + version: 7.0.0-dev.20260303.1 blob-util: specifier: 2.0.2 version: 2.0.2 @@ -325,7 +334,7 @@ importers: version: 19.2.4(react@19.2.4) react-intl: specifier: 7.1.11 - version: 7.1.11(react@19.2.4)(typescript@5.6.3) + version: 7.1.11(react@19.2.4)(typescript@5.9.3) react-popper: specifier: 2.3.0 version: 2.3.0(@popperjs/core@2.11.8)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -416,7 +425,7 @@ importers: version: 2.3.1 '@formatjs/intl': specifier: 2.10.14 - version: 2.10.14(typescript@5.6.3) + version: 2.10.14(typescript@5.9.3) '@indutny/parallel-prettier': specifier: 3.0.0 version: 3.0.0(prettier@3.7.4) @@ -425,10 +434,10 @@ importers: version: 3.0.2 '@napi-rs/canvas': specifier: 0.1.61 - version: 0.1.61 + version: 0.1.61(patch_hash=d232c1154bffd88fa8df40fc91dc36098b29aba725d826c24ce74cfac7803919) '@signalapp/mock-server': - specifier: 18.2.0 - version: 18.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + specifier: 18.3.0 + version: 18.3.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@storybook/addon-a11y': specifier: 8.4.4 version: 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) @@ -464,16 +473,16 @@ importers: version: 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) '@storybook/react': specifier: 8.4.4 - version: 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3) + version: 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3) '@storybook/react-webpack5': specifier: 8.4.4 - version: 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3)(webpack-cli@5.1.4) + version: 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3)(webpack-cli@5.1.4) '@storybook/test': specifier: 8.4.4 version: 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) '@storybook/test-runner': specifier: 0.22.0 - version: 0.22.0(@swc/helpers@0.5.15)(@types/node@20.17.6)(debug@4.3.7)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + version: 0.22.0(@swc/helpers@0.5.15)(@types/node@24.12.0)(debug@4.3.7)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) '@storybook/types': specifier: 8.1.11 version: 8.1.11 @@ -535,11 +544,11 @@ importers: specifier: 10.0.9 version: 10.0.9 '@types/node': - specifier: 20.17.6 - version: 20.17.6 + specifier: 24.12.0 + version: 24.12.0 '@types/node-fetch': specifier: 2.6.12 - version: 2.6.12(patch_hash=bc43fb8cfed85fb4f7917b5bd3b47644ae15a000c26a6fe23078b2f5217efaf0) + version: 2.6.12(patch_hash=e5c9ff6ac5dd2c13f52c0eeed685f6d43b78c687ebd45d4e333a2f8602cc1ce2) '@types/normalize-path': specifier: 3.0.2 version: 3.0.2 @@ -590,10 +599,10 @@ importers: version: 17.0.33 '@typescript-eslint/eslint-plugin': specifier: 6.18.1 - version: 6.18.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0)(typescript@5.6.3) + version: 6.18.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0)(typescript@5.9.3) '@typescript-eslint/parser': specifier: 6.18.1 - version: 6.18.1(eslint@8.56.0)(typescript@5.6.3) + version: 6.18.1(eslint@8.56.0)(typescript@5.9.3) axe-core: specifier: 4.10.2 version: 4.10.2 @@ -665,7 +674,7 @@ importers: version: 8.56.0 eslint-config-airbnb-typescript-prettier: specifier: 5.0.0 - version: 5.0.0(@types/eslint@9.6.1)(eslint@8.56.0)(prettier@3.7.4)(typescript@5.6.3) + version: 5.0.0(@types/eslint@9.6.1)(eslint@8.56.0)(prettier@3.7.4)(typescript@5.9.3) eslint-config-prettier: specifier: 8.5.0 version: 8.5.0(eslint@8.56.0) @@ -674,7 +683,7 @@ importers: version: 3.7.2(patch_hash=a94affa4d170a27c4cfd44f7ac30ea11ae285cb4e270a5d930dd28cc79901b4f)(eslint@8.56.0)(tailwindcss@4.1.7) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0) + version: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0) eslint-plugin-local-rules: specifier: 1.3.2 version: 1.3.2 @@ -724,8 +733,8 @@ importers: specifier: 5.3.0 version: 5.3.0 playwright: - specifier: 1.54.2 - version: 1.54.2 + specifier: 1.58.2 + version: 1.58.2 pngjs: specifier: 7.0.0 version: 7.0.0 @@ -734,7 +743,7 @@ importers: version: 8.5.3 postcss-loader: specifier: 8.1.1 - version: 8.1.1(postcss@8.5.3)(typescript@5.6.3)(webpack@5.96.1) + version: 8.1.1(postcss@8.5.3)(typescript@5.9.3)(webpack@5.96.1) prettier: specifier: 3.7.4 version: 3.7.4 @@ -770,16 +779,16 @@ importers: version: 4.0.0(webpack@5.96.1) stylelint: specifier: 16.10.0 - version: 16.10.0(typescript@5.6.3) + version: 16.10.0(typescript@5.9.3) stylelint-config-css-modules: specifier: 4.4.0 - version: 4.4.0(stylelint@16.10.0(typescript@5.6.3)) + version: 4.4.0(stylelint@16.10.0(typescript@5.9.3)) stylelint-config-recommended-scss: specifier: 14.1.0 - version: 14.1.0(postcss@8.5.3)(stylelint@16.10.0(typescript@5.6.3)) + version: 14.1.0(postcss@8.5.3)(stylelint@16.10.0(typescript@5.9.3)) stylelint-use-logical-spec: specifier: 5.0.1 - version: 5.0.1(stylelint@16.10.0(typescript@5.6.3)) + version: 5.0.1(stylelint@16.10.0(typescript@5.9.3)) svgo: specifier: 3.3.2 version: 3.3.2 @@ -794,10 +803,10 @@ importers: version: 5.3.10(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(webpack@5.96.1) ts-node: specifier: 10.9.2 - version: 10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3) + version: 10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3) typescript: - specifier: 5.6.3 - version: 5.6.3 + specifier: 5.9.3 + version: 5.9.3 wait-on: specifier: 8.0.1 version: 8.0.1(debug@4.3.7) @@ -1672,12 +1681,8 @@ packages: peerDependencies: prettier: ^3.0.0 - '@indutny/protopiler@3.1.1': - resolution: {integrity: sha512-EOlIbOOSOiQrkXGNS2mRZRr6mOueYBF1F/Q4oPNn0lK0Cd01R4T0mfrPUysXALnmcNn/D0AENmx+g4xG5W7keQ==} - hasBin: true - - '@indutny/protopiler@3.2.0': - resolution: {integrity: sha512-BdteJtC8yXqyhRc6zEV/Xt/nyeRErrOWZm/esPAdTr3jW9EZqUm/ZzCPtqF1CJ6HbRrm/KR2T+l+qc7AIgytJg==} + '@indutny/protopiler@3.2.1': + resolution: {integrity: sha512-u3ZVLus/9wwkojVSO0es5tppdd+2f9zA6ogax3OytOwGueDWSj+eVU6sSWYiSY/zxMSgdnKxRik0D3D36u3iWw==} hasBin: true '@indutny/range-finder@1.3.4': @@ -3413,17 +3418,14 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - '@signalapp/libsignal-client@0.76.7': - resolution: {integrity: sha512-iGWTlFkko7IKlm96Iy91Wz5sIN089nj02ifOk6BWtLzeVi0kFaNj+jK26Sl1JRXy/VfXevcYtiOivOg43BPqpg==} - - '@signalapp/libsignal-client@0.88.3': - resolution: {integrity: sha512-azPdj/nGZqLrnN0GyVFKjF0yF3945YmcsL5GERtgAJnkbi0BQbuErne8iKzIEgwQgtJcdLXelvJRVn2ycKUD0A==} + '@signalapp/libsignal-client@0.89.0': + resolution: {integrity: sha512-/eiWJuW/k6bwLcW5CodB9NNRSc6kH5ThbT+7NdIAS4Z6NdknbFcgp58452zTZYO2E/3xmP6/UlpeRaXxz2Dh1Q==} '@signalapp/minimask@1.0.1': resolution: {integrity: sha512-QAwo0joA60urTNbW9RIz6vLKQjy+jdVtH7cvY0wD9PVooD46MAjE40MLssp4xUJrph91n2XvtJ3pbEUDrmT2AA==} - '@signalapp/mock-server@18.2.0': - resolution: {integrity: sha512-5oEurM6VXswK1krLRbcLR8270Gh9QS1Pw3hsSbdJteSnbtNusYvK4lYbMlJECmfhTtVRPJbGTcIGtV5lPumQSA==} + '@signalapp/mock-server@18.3.0': + resolution: {integrity: sha512-IDqt4YsyoN1myDZYeaMh42Sfx310F0APT/9hggrLhqYwOto43AIZPXaCzG2Cjbh3n9wCPVrtTGxO3Q74/BdEWg==} '@signalapp/parchment-cjs@3.0.1': resolution: {integrity: sha512-hSBMQ1M7wE4GcC8ZeNtvpJF+DAJg3eIRRf1SiHS3I3Algav/sgJJNm6HIYm6muHuK7IJmuEjkL3ILSXgmu0RfQ==} @@ -3436,8 +3438,8 @@ packages: resolution: {integrity: sha512-ddRhFzbQibBbU1b85eWYXRgLZ1JfY0ZYzG3NPlQmjB1TFCXcBIPi8pEdWEA6FXoGRQ+EHHi009uqkqCJwYBHfQ==} hasBin: true - '@signalapp/sqlcipher@2.4.4': - resolution: {integrity: sha512-43zkxlPA3ZJE3+qtkEnkcttgiE8OQvR1yxJY5gl7u/KoL7DRwgiMr5F6qCjnMAsbiHWrJfG3YMq6TXfLfS/bVA==} + '@signalapp/sqlcipher@3.2.1': + resolution: {integrity: sha512-QStHnLZiYp7YvdR6CnDO7TxdoSJQCeF02UxkyJE7+l/qES3wvwkc1IuAxSYCZEI8gS4PUBTYXSX70yod7PS9Mg==} '@signalapp/windows-ucv@1.0.1': resolution: {integrity: sha512-tArRaDzAFXQ6BcYseUtd9bp52/sb5C/zbCIoNkDH+FUoxnZRvX25Fv2HHbH7Xe2+bcdb4+DQmyoUeHMhTUxAmA==} @@ -4065,17 +4067,11 @@ packages: '@types/node@16.18.126': resolution: {integrity: sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==} - '@types/node@20.17.6': - resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==} - - '@types/node@22.13.4': - resolution: {integrity: sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==} - '@types/node@22.19.1': resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==} - '@types/node@24.10.9': - resolution: {integrity: sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==} + '@types/node@24.12.0': + resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} '@types/normalize-path@3.0.2': resolution: {integrity: sha512-DO++toKYPaFn0Z8hQ7Tx+3iT9t77IJo/nDiqTXilgEP+kPNIYdpS9kh3fXuc53ugqwp9pxC1PVjCpV1tQDyqMA==} @@ -4312,6 +4308,45 @@ packages: resolution: {integrity: sha512-/kvt0C5lRqGoCfsbmm7/CwMqoSkY3zzHLIjdhHZQW3VFrnz7ATecOHR7nb7V+xn4286MBxfnQfQhAmCI0u+bJA==} engines: {node: ^16.0.0 || >=18.0.0} + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260303.1': + resolution: {integrity: sha512-jIIQWmFi0bJY4ML8/7eyz1EGpkI6E0R1E5l4lxJdV/orpMr91vYfAajKICs7DUiMGEJX9HpeiA6TD2piw4DKPQ==} + cpu: [arm64] + os: [darwin] + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260303.1': + resolution: {integrity: sha512-UkaK+J3f185VXBiAGNG4UKHjGzn4R/nhAz5tArnCKHnIUI7rEnsIm4Xlo5YwmgIATFMU1sVwWUwRshVkMVeFAw==} + cpu: [x64] + os: [darwin] + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260303.1': + resolution: {integrity: sha512-ELJSV2Q4/mK+ampttssOl4H9s9ZBCc3k7y/u5ivJX8TdlMvZuH/JHqI6cS4Y00flt0R5wc70X+Nlcor4I4+rpw==} + cpu: [arm64] + os: [linux] + + '@typescript/native-preview-linux-arm@7.0.0-dev.20260303.1': + resolution: {integrity: sha512-H84jTRYqUfc/vhuVGQ6VKcBvJoZ4YmomWDx9U4uwYgW6eoUcRpDXqv3S3YqcNJcUmz22d/tTwIYz8ssXNLa/Qw==} + cpu: [arm] + os: [linux] + + '@typescript/native-preview-linux-x64@7.0.0-dev.20260303.1': + resolution: {integrity: sha512-HkddFrPJ0jcrohe+HnCqVTv8PunjqNs7FisRmtIAnc36+ccraDB6MVFEdPyAIL3PUID+TP/ESquqeKNnB7HdrQ==} + cpu: [x64] + os: [linux] + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260303.1': + resolution: {integrity: sha512-kTTMrBpWuxbHPt9hAFQSWeP//5Oa0KOdAEvceOfXUJhTS8RAA/kZSlFGE/Zw1EtrFLQx2J7uTHUZnYxH1hYXNw==} + cpu: [arm64] + os: [win32] + + '@typescript/native-preview-win32-x64@7.0.0-dev.20260303.1': + resolution: {integrity: sha512-UcVZbf4pra46Yx/eFV6m9F+awvihliPEud4Rq+A8Q3q3zI67VRaNH6R2/qeo4AqqKRahmiEdLM6Tnm+gPtLRQQ==} + cpu: [x64] + os: [win32] + + '@typescript/native-preview@7.0.0-dev.20260303.1': + resolution: {integrity: sha512-BDHJjXlPldInEogbzAc7OCLvT75p3rdkmb5YIA6Je0vjg+5z1UQp3moAvcBGvZQflO/gusOd9a74EfrMVUU/4g==} + hasBin: true + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} @@ -8696,13 +8731,13 @@ packages: engines: {node: '>=18'} hasBin: true - playwright-core@1.54.2: - resolution: {integrity: sha512-n5r4HFbMmWsB4twG7tJLDN9gmBUeSPcsBZiWSE4DnYz9mJMAFqr2ID7+eGC9kpEnxExJ1epttwR59LEWCk8mtA==} + playwright-core@1.58.2: + resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} engines: {node: '>=18'} hasBin: true - playwright@1.54.2: - resolution: {integrity: sha512-Hu/BMoA1NAdRUuulyvQC0pEqZ4vQbGfn8f7wPXcnqQmM+zct9UliKxsIkLNmz/ku7LElUNqmaiv1TG/aL5ACsw==} + playwright@1.58.2: + resolution: {integrity: sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==} engines: {node: '>=18'} hasBin: true @@ -10228,8 +10263,8 @@ packages: typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - typescript@5.6.3: - resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true @@ -10244,12 +10279,6 @@ packages: resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} engines: {node: '>=0.10.0'} - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -11587,7 +11616,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@formatjs/intl@2.10.14(typescript@5.6.3)': + '@formatjs/intl@2.10.14(typescript@5.9.3)': dependencies: '@formatjs/ecma402-abstract': 2.2.3 '@formatjs/fast-memoize': 2.2.3 @@ -11597,9 +11626,9 @@ snapshots: intl-messageformat: 10.7.6 tslib: 2.8.1 optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 - '@formatjs/intl@3.1.6(typescript@5.6.3)': + '@formatjs/intl@3.1.6(typescript@5.9.3)': dependencies: '@formatjs/ecma402-abstract': 2.3.4 '@formatjs/fast-memoize': 2.2.7 @@ -11607,7 +11636,7 @@ snapshots: intl-messageformat: 10.7.16 tslib: 2.8.1 optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 '@gar/promisify@1.1.3': {} @@ -11672,9 +11701,7 @@ snapshots: prettier: 3.7.4 rxjs: 6.6.7 - '@indutny/protopiler@3.1.1': {} - - '@indutny/protopiler@3.2.0': {} + '@indutny/protopiler@3.2.1': {} '@indutny/range-finder@1.3.4': dependencies: @@ -11752,27 +11779,27 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -11801,7 +11828,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -11819,7 +11846,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.17.6 + '@types/node': 24.12.0 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -11841,7 +11868,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.17.6 + '@types/node': 24.12.0 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -11911,7 +11938,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -12000,7 +12027,7 @@ snapshots: '@napi-rs/canvas-win32-x64-msvc@0.1.61': optional: true - '@napi-rs/canvas@0.1.61': + '@napi-rs/canvas@0.1.61(patch_hash=d232c1154bffd88fa8df40fc91dc36098b29aba725d826c24ce74cfac7803919)': optionalDependencies: '@napi-rs/canvas-android-arm64': 0.1.61 '@napi-rs/canvas-darwin-arm64': 0.1.61 @@ -14035,13 +14062,7 @@ snapshots: '@sideway/pinpoint@2.0.0': {} - '@signalapp/libsignal-client@0.76.7': - dependencies: - node-gyp-build: 4.8.4 - type-fest: 4.26.1 - uuid: 11.0.2 - - '@signalapp/libsignal-client@0.88.3': + '@signalapp/libsignal-client@0.89.0': dependencies: node-gyp-build: 4.8.4 type-fest: 4.26.1 @@ -14049,11 +14070,11 @@ snapshots: '@signalapp/minimask@1.0.1': {} - '@signalapp/mock-server@18.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@signalapp/mock-server@18.3.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@indutny/parallel-prettier': 3.0.0(prettier@3.7.4) - '@indutny/protopiler': 3.1.1 - '@signalapp/libsignal-client': 0.76.7 + '@indutny/protopiler': 3.2.1 + '@signalapp/libsignal-client': 0.89.0 '@tus/file-store': 1.5.1 '@tus/server': 1.10.2 debug: 4.3.7(supports-color@8.1.1) @@ -14087,9 +14108,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@signalapp/sqlcipher@2.4.4': + '@signalapp/sqlcipher@3.2.1': dependencies: - node-addon-api: 8.3.0 + node-addon-api: 8.5.0 node-gyp-build: 4.8.4 '@signalapp/windows-ucv@1.0.1': @@ -14188,7 +14209,7 @@ snapshots: - '@swc/helpers' - webpack - '@storybook/builder-webpack5@8.4.4(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3)(webpack-cli@5.1.4)': + '@storybook/builder-webpack5@8.4.4(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3)(webpack-cli@5.1.4)': dependencies: '@storybook/core-webpack': 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) '@types/node': 22.19.1 @@ -14199,7 +14220,7 @@ snapshots: constants-browserify: 1.0.0 css-loader: 6.11.0(webpack@5.96.1) es-module-lexer: 1.6.0 - fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.6.3)(webpack@5.96.1) + fork-ts-checker-webpack-plugin: 8.0.0(typescript@5.9.3)(webpack@5.96.1) html-webpack-plugin: 5.6.3(webpack@5.96.1) magic-string: 0.30.17 path-browserify: 1.0.1 @@ -14217,7 +14238,7 @@ snapshots: webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.6.2 optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - '@rspack/core' - '@swc/core' @@ -14288,11 +14309,11 @@ snapshots: dependencies: storybook: 8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10) - '@storybook/preset-react-webpack@8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3)(webpack-cli@5.1.4)': + '@storybook/preset-react-webpack@8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3)(webpack-cli@5.1.4)': dependencies: '@storybook/core-webpack': 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) - '@storybook/react': 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3) - '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.6.3)(webpack@5.96.1) + '@storybook/react': 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3) + '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.9.3)(webpack@5.96.1) '@types/node': 22.19.1 '@types/semver': 7.5.8 find-up: 5.0.0 @@ -14306,7 +14327,7 @@ snapshots: tsconfig-paths: 4.2.0 webpack: 5.96.1(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(webpack-cli@5.1.4) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - '@storybook/test' - '@swc/core' @@ -14319,16 +14340,16 @@ snapshots: dependencies: storybook: 8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10) - '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.6.3)(webpack@5.96.1)': + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.9.3)(webpack@5.96.1)': dependencies: debug: 4.3.7(supports-color@8.1.1) endent: 2.1.0 find-cache-dir: 3.3.2 flat-cache: 3.2.0 micromatch: 4.0.8 - react-docgen-typescript: 2.2.2(typescript@5.6.3) + react-docgen-typescript: 2.2.2(typescript@5.9.3) tslib: 2.8.1 - typescript: 5.6.3 + typescript: 5.9.3 webpack: 5.96.1(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(webpack-cli@5.1.4) transitivePeerDependencies: - supports-color @@ -14339,17 +14360,17 @@ snapshots: react-dom: 19.2.4(react@19.2.4) storybook: 8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10) - '@storybook/react-webpack5@8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3)(webpack-cli@5.1.4)': + '@storybook/react-webpack5@8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3)(webpack-cli@5.1.4)': dependencies: - '@storybook/builder-webpack5': 8.4.4(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3)(webpack-cli@5.1.4) - '@storybook/preset-react-webpack': 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3)(webpack-cli@5.1.4) - '@storybook/react': 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3) - '@types/node': 22.13.4 + '@storybook/builder-webpack5': 8.4.4(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3)(webpack-cli@5.1.4) + '@storybook/preset-react-webpack': 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3)(webpack-cli@5.1.4) + '@storybook/react': 8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3) + '@types/node': 22.19.1 react: 19.2.4 react-dom: 19.2.4(react@19.2.4) storybook: 8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - '@rspack/core' - '@storybook/test' @@ -14359,7 +14380,7 @@ snapshots: - uglify-js - webpack-cli - '@storybook/react@8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.6.3)': + '@storybook/react@8.4.4(@storybook/test@8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(typescript@5.9.3)': dependencies: '@storybook/components': 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) '@storybook/global': 5.0.0 @@ -14372,9 +14393,9 @@ snapshots: storybook: 8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10) optionalDependencies: '@storybook/test': 8.4.4(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10)) - typescript: 5.6.3 + typescript: 5.9.3 - '@storybook/test-runner@0.22.0(@swc/helpers@0.5.15)(@types/node@20.17.6)(debug@4.3.7)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3))': + '@storybook/test-runner@0.22.0(@swc/helpers@0.5.15)(@types/node@24.12.0)(debug@4.3.7)(storybook@8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10))(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3))': dependencies: '@babel/core': 7.26.0 '@babel/generator': 7.26.8 @@ -14385,16 +14406,16 @@ snapshots: '@swc/core': 1.10.16(@swc/helpers@0.5.15) '@swc/jest': 0.2.37(@swc/core@1.10.16(@swc/helpers@0.5.15)) expect-playwright: 0.8.0 - jest: 29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + jest: 29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) jest-circus: 29.7.0 jest-environment-node: 29.7.0 jest-junit: 16.0.0 - jest-playwright-preset: 4.0.0(debug@4.3.7)(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3))) + jest-playwright-preset: 4.0.0(debug@4.3.7)(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3))) jest-runner: 29.7.0 jest-serializer-html: 7.1.0 - jest-watch-typeahead: 2.2.2(jest@29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3))) + jest-watch-typeahead: 2.2.2(jest@29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3))) nyc: 15.1.0 - playwright: 1.54.2 + playwright: 1.58.2 storybook: 8.4.4(bufferutil@4.0.9)(prettier@3.7.4)(utf-8-validate@5.0.10) transitivePeerDependencies: - '@swc/helpers' @@ -14674,17 +14695,17 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/bonjour@3.5.13': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/responselike': 1.0.3 '@types/chai-as-promised@7.1.4': @@ -14698,11 +14719,11 @@ snapshots: '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.6 - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/connect@3.4.38': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/dashdash@1.14.3': {} @@ -14734,14 +14755,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express-serve-static-core@5.0.6': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -14758,17 +14779,17 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/fs-extra@9.0.13': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/google-libphonenumber@7.4.30': {} '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/hoist-non-react-statics@3.3.6': dependencies: @@ -14783,7 +14804,7 @@ snapshots: '@types/http-proxy@1.17.16': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/humanize-duration@3.18.1': {} @@ -14815,11 +14836,11 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/keyv@3.1.4': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/linkify-it@5.0.0': {} @@ -14837,30 +14858,22 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node-fetch@2.6.12(patch_hash=bc43fb8cfed85fb4f7917b5bd3b47644ae15a000c26a6fe23078b2f5217efaf0)': + '@types/node-fetch@2.6.12(patch_hash=e5c9ff6ac5dd2c13f52c0eeed685f6d43b78c687ebd45d4e333a2f8602cc1ce2)': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 form-data: 4.0.1 '@types/node-forge@1.3.11': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/node@16.18.126': {} - '@types/node@20.17.6': - dependencies: - undici-types: 6.19.8 - - '@types/node@22.13.4': - dependencies: - undici-types: 6.20.0 - '@types/node@22.19.1': dependencies: undici-types: 6.21.0 - '@types/node@24.10.9': + '@types/node@24.12.0': dependencies: undici-types: 7.16.0 @@ -14874,17 +14887,17 @@ snapshots: '@types/pixelmatch@5.2.6': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/plist@3.0.5': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 xmlbuilder: 15.1.1 optional: true '@types/pngjs@6.0.5': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/prop-types@15.7.14': {} @@ -14920,7 +14933,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/retry@0.12.2': {} @@ -14929,7 +14942,7 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/serve-index@1.9.4': dependencies: @@ -14938,7 +14951,7 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/send': 0.17.4 '@types/sinon@17.0.3': @@ -14951,11 +14964,11 @@ snapshots: '@types/sockjs@0.3.36': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/split2@4.2.3': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/stack-utils@2.0.3': {} @@ -14972,15 +14985,15 @@ snapshots: '@types/wait-on@5.3.4': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/write-file-atomic@4.0.3': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/ws@8.5.14': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 '@types/yargs-parser@21.0.3': {} @@ -14990,35 +15003,35 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 optional: true - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0)(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.9.3) '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.56.0)(typescript@5.6.3) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/type-utils': 5.62.0(eslint@8.56.0)(typescript@5.9.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.9.3) debug: 4.3.7(supports-color@8.1.1) eslint: 8.56.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare-lite: 1.4.0 semver: 7.6.3 - tsutils: 3.21.0(typescript@5.6.3) + tsutils: 3.21.0(typescript@5.9.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@6.18.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0)(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@6.18.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0)(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.9.3) '@typescript-eslint/scope-manager': 6.18.1 - '@typescript-eslint/type-utils': 6.18.1(eslint@8.56.0)(typescript@5.6.3) - '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/type-utils': 6.18.1(eslint@8.56.0)(typescript@5.9.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.9.3) '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.3.7(supports-color@8.1.1) eslint: 8.56.0 @@ -15026,34 +15039,34 @@ snapshots: ignore: 5.3.2 natural-compare: 1.4.0 semver: 7.6.3 - ts-api-utils: 1.4.3(typescript@5.6.3) + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.6.3)': + '@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) debug: 4.3.7(supports-color@8.1.1) eslint: 8.56.0 optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3)': + '@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3)': dependencies: '@typescript-eslint/scope-manager': 6.18.1 '@typescript-eslint/types': 6.18.1 - '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.9.3) '@typescript-eslint/visitor-keys': 6.18.1 debug: 4.3.7(supports-color@8.1.1) eslint: 8.56.0 optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -15067,27 +15080,27 @@ snapshots: '@typescript-eslint/types': 6.18.1 '@typescript-eslint/visitor-keys': 6.18.1 - '@typescript-eslint/type-utils@5.62.0(eslint@8.56.0)(typescript@5.6.3)': + '@typescript-eslint/type-utils@5.62.0(eslint@8.56.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.6.3) - '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + '@typescript-eslint/utils': 5.62.0(eslint@8.56.0)(typescript@5.9.3) debug: 4.3.7(supports-color@8.1.1) eslint: 8.56.0 - tsutils: 3.21.0(typescript@5.6.3) + tsutils: 3.21.0(typescript@5.9.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@6.18.1(eslint@8.56.0)(typescript@5.6.3)': + '@typescript-eslint/type-utils@6.18.1(eslint@8.56.0)(typescript@5.9.3)': dependencies: - '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.6.3) - '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.9.3) + '@typescript-eslint/utils': 6.18.1(eslint@8.56.0)(typescript@5.9.3) debug: 4.3.7(supports-color@8.1.1) eslint: 8.56.0 - ts-api-utils: 1.4.3(typescript@5.6.3) + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -15095,7 +15108,7 @@ snapshots: '@typescript-eslint/types@6.18.1': {} - '@typescript-eslint/typescript-estree@5.62.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 @@ -15103,13 +15116,13 @@ snapshots: globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 - tsutils: 3.21.0(typescript@5.6.3) + tsutils: 3.21.0(typescript@5.9.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@6.18.1(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@6.18.1(typescript@5.9.3)': dependencies: '@typescript-eslint/types': 6.18.1 '@typescript-eslint/visitor-keys': 6.18.1 @@ -15118,20 +15131,20 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.6.3 - ts-api-utils: 1.4.3(typescript@5.6.3) + ts-api-utils: 1.4.3(typescript@5.9.3) optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@5.6.3)': + '@typescript-eslint/utils@5.62.0(eslint@8.56.0)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@8.56.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) eslint: 8.56.0 eslint-scope: 5.1.1 semver: 7.6.3 @@ -15139,14 +15152,14 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@6.18.1(eslint@8.56.0)(typescript@5.6.3)': + '@typescript-eslint/utils@6.18.1(eslint@8.56.0)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@8.56.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 6.18.1 '@typescript-eslint/types': 6.18.1 - '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 6.18.1(typescript@5.9.3) eslint: 8.56.0 semver: 7.6.3 transitivePeerDependencies: @@ -15163,6 +15176,37 @@ snapshots: '@typescript-eslint/types': 6.18.1 eslint-visitor-keys: 3.4.3 + '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260303.1': + optional: true + + '@typescript/native-preview-darwin-x64@7.0.0-dev.20260303.1': + optional: true + + '@typescript/native-preview-linux-arm64@7.0.0-dev.20260303.1': + optional: true + + '@typescript/native-preview-linux-arm@7.0.0-dev.20260303.1': + optional: true + + '@typescript/native-preview-linux-x64@7.0.0-dev.20260303.1': + optional: true + + '@typescript/native-preview-win32-arm64@7.0.0-dev.20260303.1': + optional: true + + '@typescript/native-preview-win32-x64@7.0.0-dev.20260303.1': + optional: true + + '@typescript/native-preview@7.0.0-dev.20260303.1': + optionalDependencies: + '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260303.1 + '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260303.1 + '@typescript/native-preview-linux-arm': 7.0.0-dev.20260303.1 + '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260303.1 + '@typescript/native-preview-linux-x64': 7.0.0-dev.20260303.1 + '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260303.1 + '@typescript/native-preview-win32-x64': 7.0.0-dev.20260303.1 + '@ungap/structured-clone@1.3.0': {} '@vitest/expect@2.0.5(patch_hash=e8a96f71e52bf903c9f1eadba4740489a0beb48da33db52354adca484fe1f495)': @@ -16210,7 +16254,7 @@ snapshots: config-file-ts@0.2.8-rc1: dependencies: glob: 10.4.5 - typescript: 5.6.3 + typescript: 5.9.3 config@3.3.12: dependencies: @@ -16270,14 +16314,14 @@ snapshots: path-type: 4.0.0 yaml: 1.10.2 - cosmiconfig@9.0.0(typescript@5.6.3): + cosmiconfig@9.0.0(typescript@5.9.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 country-codes-list@2.0.0: {} @@ -16290,13 +16334,13 @@ snapshots: dependencies: capture-stack-trace: 1.0.2 - create-jest@29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)): + create-jest@29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -16846,7 +16890,7 @@ snapshots: electron@40.8.0: dependencies: '@electron/get': 2.0.3 - '@types/node': 24.10.9 + '@types/node': 24.12.0 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color @@ -17175,40 +17219,40 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0))(eslint@8.56.0): + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0))(eslint@8.56.0): dependencies: confusing-browser-globals: 1.0.11 eslint: 8.56.0 - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0) object.assign: 4.1.7 object.entries: 1.1.8 semver: 6.3.1 - eslint-config-airbnb-typescript-prettier@5.0.0(@types/eslint@9.6.1)(eslint@8.56.0)(prettier@3.7.4)(typescript@5.6.3): + eslint-config-airbnb-typescript-prettier@5.0.0(@types/eslint@9.6.1)(eslint@8.56.0)(prettier@3.7.4)(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0)(typescript@5.6.3) - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0)(typescript@5.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.9.3) eslint: 8.56.0 - eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.56.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.56.0))(eslint-plugin-react@7.31.10(eslint@8.56.0))(eslint@8.56.0) + eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.56.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.56.0))(eslint-plugin-react@7.31.10(eslint@8.56.0))(eslint@8.56.0) eslint-config-prettier: 6.15.0(eslint@8.56.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.56.0) eslint-plugin-prettier: 5.2.1(@types/eslint@9.6.1)(eslint-config-prettier@6.15.0(eslint@8.56.0))(eslint@8.56.0)(prettier@3.7.4) eslint-plugin-react: 7.31.10(eslint@8.56.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.56.0) prettier: 3.7.4 - typescript: 5.6.3 + typescript: 5.9.3 transitivePeerDependencies: - '@types/eslint' - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.56.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.56.0))(eslint-plugin-react@7.31.10(eslint@8.56.0))(eslint@8.56.0): + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.56.0))(eslint-plugin-react-hooks@4.6.2(eslint@8.56.0))(eslint-plugin-react@7.31.10(eslint@8.56.0))(eslint@8.56.0): dependencies: eslint: 8.56.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0))(eslint@8.56.0) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0) + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0))(eslint@8.56.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.56.0) eslint-plugin-react: 7.31.10(eslint@8.56.0) eslint-plugin-react-hooks: 4.6.2(eslint@8.56.0) @@ -17232,21 +17276,21 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.9.3) eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): + eslint-module-utils@2.12.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.9.3) eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: @@ -17265,7 +17309,7 @@ snapshots: tailwindcss: 4.1.7 tsconfig-paths-webpack-plugin: 4.2.0 - eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -17276,7 +17320,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.56.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -17288,13 +17332,13 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/parser': 5.62.0(eslint@8.56.0)(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint@8.56.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint@8.56.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -17305,7 +17349,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@6.18.1(eslint@8.56.0)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@8.56.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -17317,7 +17361,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.6.3) + '@typescript-eslint/parser': 6.18.1(eslint@8.56.0)(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -17772,7 +17816,7 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@8.0.0(typescript@5.6.3)(webpack@5.96.1): + fork-ts-checker-webpack-plugin@8.0.0(typescript@5.9.3)(webpack@5.96.1): dependencies: '@babel/code-frame': 7.26.2 chalk: 4.1.2 @@ -17786,7 +17830,7 @@ snapshots: schema-utils: 3.3.0 semver: 7.6.3 tapable: 2.2.1 - typescript: 5.6.3 + typescript: 5.9.3 webpack: 5.96.1(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(webpack-cli@5.1.4) form-data@4.0.1: @@ -18792,7 +18836,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -18812,16 +18856,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)): + jest-cli@29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + create-jest: 29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -18831,7 +18875,7 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)): + jest-config@29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -18856,8 +18900,8 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 20.17.6 - ts-node: 10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3) + '@types/node': 24.12.0 + ts-node: 10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -18886,7 +18930,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -18896,7 +18940,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.17.6 + '@types/node': 24.12.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -18942,13 +18986,13 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 jest-util: 29.7.0 - jest-playwright-preset@4.0.0(debug@4.3.7)(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3))): + jest-playwright-preset@4.0.0(debug@4.3.7)(jest-circus@29.7.0)(jest-environment-node@29.7.0)(jest-runner@29.7.0)(jest@29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3))): dependencies: expect-playwright: 0.8.0 - jest: 29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + jest: 29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) jest-circus: 29.7.0 jest-environment-node: 29.7.0 jest-process-manager: 0.4.0(debug@4.3.7) @@ -19009,7 +19053,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -19037,7 +19081,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 chalk: 4.1.2 cjs-module-lexer: 1.4.3 collect-v8-coverage: 1.0.2 @@ -19087,7 +19131,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -19102,11 +19146,11 @@ snapshots: leven: 3.1.0 pretty-format: 29.7.0 - jest-watch-typeahead@2.2.2(jest@29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3))): + jest-watch-typeahead@2.2.2(jest@29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3))): dependencies: ansi-escapes: 6.2.1 chalk: 5.4.1 - jest: 29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + jest: 29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) jest-regex-util: 29.6.3 jest-watcher: 29.7.0 slash: 5.1.0 @@ -19117,7 +19161,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.17.6 + '@types/node': 24.12.0 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -19126,23 +19170,23 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 20.17.6 + '@types/node': 24.12.0 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)): + jest@29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.17.6)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3)) + jest-cli: 29.7.0(@types/node@24.12.0)(ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -20425,11 +20469,11 @@ snapshots: playwright-core@1.50.1: {} - playwright-core@1.54.2: {} + playwright-core@1.58.2(patch_hash=7fb22c7946d93ff366ea2b93165653a6b7f988e3f1d08b5601a915959e0c49ce): {} - playwright@1.54.2: + playwright@1.58.2: dependencies: - playwright-core: 1.54.2 + playwright-core: 1.58.2(patch_hash=7fb22c7946d93ff366ea2b93165653a6b7f988e3f1d08b5601a915959e0c49ce) optionalDependencies: fsevents: 2.3.2 @@ -20464,9 +20508,9 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.10 - postcss-loader@8.1.1(postcss@8.5.3)(typescript@5.6.3)(webpack@5.96.1): + postcss-loader@8.1.1(postcss@8.5.3)(typescript@5.9.3)(webpack@5.96.1): dependencies: - cosmiconfig: 9.0.0(typescript@5.6.3) + cosmiconfig: 9.0.0(typescript@5.9.3) jiti: 1.21.7 postcss: 8.5.3 semver: 7.6.3 @@ -20871,9 +20915,9 @@ snapshots: - supports-color - utf-8-validate - react-docgen-typescript@2.2.2(typescript@5.6.3): + react-docgen-typescript@2.2.2(typescript@5.9.3): dependencies: - typescript: 5.6.3 + typescript: 5.9.3 react-docgen@7.1.1: dependencies: @@ -20897,11 +20941,11 @@ snapshots: react-fast-compare@3.2.2: {} - react-intl@7.1.11(react@19.2.4)(typescript@5.6.3): + react-intl@7.1.11(react@19.2.4)(typescript@5.9.3): dependencies: '@formatjs/ecma402-abstract': 2.3.4 '@formatjs/icu-messageformat-parser': 2.11.2 - '@formatjs/intl': 3.1.6(typescript@5.6.3) + '@formatjs/intl': 3.1.6(typescript@5.9.3) '@types/hoist-non-react-statics': 3.3.6 '@types/react': 19.2.14 hoist-non-react-statics: 3.3.2 @@ -20909,7 +20953,7 @@ snapshots: react: 19.2.4 tslib: 2.8.1 optionalDependencies: - typescript: 5.6.3 + typescript: 5.9.3 react-is@16.13.1: {} @@ -21805,26 +21849,26 @@ snapshots: dependencies: webpack: 5.96.1(@swc/core@1.10.16(@swc/helpers@0.5.15))(esbuild@0.25.9)(webpack-cli@5.1.4) - stylelint-config-css-modules@4.4.0(stylelint@16.10.0(typescript@5.6.3)): + stylelint-config-css-modules@4.4.0(stylelint@16.10.0(typescript@5.9.3)): dependencies: - stylelint: 16.10.0(typescript@5.6.3) + stylelint: 16.10.0(typescript@5.9.3) optionalDependencies: - stylelint-scss: 6.11.0(stylelint@16.10.0(typescript@5.6.3)) + stylelint-scss: 6.11.0(stylelint@16.10.0(typescript@5.9.3)) - stylelint-config-recommended-scss@14.1.0(postcss@8.5.3)(stylelint@16.10.0(typescript@5.6.3)): + stylelint-config-recommended-scss@14.1.0(postcss@8.5.3)(stylelint@16.10.0(typescript@5.9.3)): dependencies: postcss-scss: 4.0.9(postcss@8.5.3) - stylelint: 16.10.0(typescript@5.6.3) - stylelint-config-recommended: 14.0.1(stylelint@16.10.0(typescript@5.6.3)) - stylelint-scss: 6.11.0(stylelint@16.10.0(typescript@5.6.3)) + stylelint: 16.10.0(typescript@5.9.3) + stylelint-config-recommended: 14.0.1(stylelint@16.10.0(typescript@5.9.3)) + stylelint-scss: 6.11.0(stylelint@16.10.0(typescript@5.9.3)) optionalDependencies: postcss: 8.5.3 - stylelint-config-recommended@14.0.1(stylelint@16.10.0(typescript@5.6.3)): + stylelint-config-recommended@14.0.1(stylelint@16.10.0(typescript@5.9.3)): dependencies: - stylelint: 16.10.0(typescript@5.6.3) + stylelint: 16.10.0(typescript@5.9.3) - stylelint-scss@6.11.0(stylelint@16.10.0(typescript@5.6.3)): + stylelint-scss@6.11.0(stylelint@16.10.0(typescript@5.9.3)): dependencies: css-tree: 3.1.0 is-plain-object: 5.0.0 @@ -21834,13 +21878,13 @@ snapshots: postcss-resolve-nested-selector: 0.1.6 postcss-selector-parser: 7.1.0 postcss-value-parser: 4.2.0 - stylelint: 16.10.0(typescript@5.6.3) + stylelint: 16.10.0(typescript@5.9.3) - stylelint-use-logical-spec@5.0.1(stylelint@16.10.0(typescript@5.6.3)): + stylelint-use-logical-spec@5.0.1(stylelint@16.10.0(typescript@5.9.3)): dependencies: - stylelint: 16.10.0(typescript@5.6.3) + stylelint: 16.10.0(typescript@5.9.3) - stylelint@16.10.0(typescript@5.6.3): + stylelint@16.10.0(typescript@5.9.3): dependencies: '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) '@csstools/css-tokenizer': 3.0.3 @@ -21849,7 +21893,7 @@ snapshots: '@dual-bundle/import-meta-resolve': 4.1.0 balanced-match: 2.0.0 colord: 2.9.3 - cosmiconfig: 9.0.0(typescript@5.6.3) + cosmiconfig: 9.0.0(typescript@5.9.3) css-functions-list: 3.2.3 css-tree: 3.1.0 debug: 4.3.7(supports-color@8.1.1) @@ -22110,27 +22154,27 @@ snapshots: dependencies: utf8-byte-length: 1.0.5 - ts-api-utils@1.4.3(typescript@5.6.3): + ts-api-utils@1.4.3(typescript@5.9.3): dependencies: - typescript: 5.6.3 + typescript: 5.9.3 ts-dedent@2.2.0: {} - ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@20.17.6)(typescript@5.6.3): + ts-node@10.9.2(@swc/core@1.10.16(@swc/helpers@0.5.15))(@types/node@24.12.0)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.17.6 + '@types/node': 24.12.0 acorn: 8.14.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.6.3 + typescript: 5.9.3 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: @@ -22160,10 +22204,10 @@ snapshots: tslib@2.8.1: {} - tsutils@3.21.0(typescript@5.6.3): + tsutils@3.21.0(typescript@5.9.3): dependencies: tslib: 1.14.1 - typescript: 5.6.3 + typescript: 5.9.3 type-check@0.4.0: dependencies: @@ -22230,7 +22274,7 @@ snapshots: dependencies: is-typedarray: 1.0.0 - typescript@5.6.3: {} + typescript@5.9.3: {} uc.micro@2.1.0: {} @@ -22243,10 +22287,6 @@ snapshots: unc-path-regex@0.1.2: {} - undici-types@6.19.8: {} - - undici-types@6.20.0: {} - undici-types@6.21.0: {} undici-types@7.16.0: {} diff --git a/ts/AttachmentCrypto.node.ts b/ts/AttachmentCrypto.node.ts index aae42585e3..28389ef0be 100644 --- a/ts/AttachmentCrypto.node.ts +++ b/ts/AttachmentCrypto.node.ts @@ -64,19 +64,19 @@ const log = createLogger('AttachmentCrypto'); // This file was split from ts/Crypto.ts because it pulls things in from node, and // too many things pull in Crypto.ts, so it broke storybook. -export function _generateAttachmentIv(): Uint8Array { +export function _generateAttachmentIv(): Uint8Array { return randomBytes(IV_LENGTH); } -export function generateAttachmentKeys(): Uint8Array { +export function generateAttachmentKeys(): Uint8Array { return randomBytes(KEY_SET_LENGTH); } export type EncryptedAttachmentV2 = { chunkSize: number | undefined; - digest: Uint8Array; - incrementalMac: Uint8Array | undefined; - iv: Uint8Array; + digest: Uint8Array; + incrementalMac: Uint8Array | undefined; + iv: Uint8Array; plaintextHash: string; ciphertextSize: number; }; @@ -97,14 +97,14 @@ export type DecryptedAttachmentV2 = { }; export type PlaintextSourceType = - | { data: Uint8Array } + | { data: Uint8Array } | { stream: Readable; size?: number } | { absolutePath: string }; type EncryptAttachmentV2OptionsType = Readonly<{ - _testOnlyDangerousIv?: Uint8Array; + _testOnlyDangerousIv?: Uint8Array; _testOnlyDangerousSkipPadding?: boolean; - keys: Readonly; + keys: Readonly>; needIncrementalMac: boolean; plaintext: PlaintextSourceType; }>; @@ -170,7 +170,7 @@ export async function encryptAttachmentV2({ const digest = createHash(HashType.size256); let ciphertextSize: number | undefined; - let mac: Uint8Array | undefined; + let mac: Uint8Array | undefined; let incrementalDigestCreator: DigestingPassThrough | undefined; let chunkSizeChoice: ChunkSizeChoice | undefined; @@ -274,16 +274,16 @@ export async function encryptAttachmentV2({ } export type IntegrityCheckType = - | { type: 'plaintext'; plaintextHash: Readonly } - | { type: 'encrypted'; digest: Readonly }; + | { type: 'plaintext'; plaintextHash: Readonly> } + | { type: 'encrypted'; digest: Readonly> }; export type DecryptAttachmentToSinkOptionsType = Readonly< { idForLogging: string; size: number; outerEncryption?: { - aesKey: Readonly; - macKey: Readonly; + aesKey: Readonly>; + macKey: Readonly>; }; } & ( | { @@ -296,7 +296,7 @@ export type DecryptAttachmentToSinkOptionsType = Readonly< ( | { type: 'standard'; - theirIncrementalMac: Readonly | undefined; + theirIncrementalMac: Readonly> | undefined; theirChunkSize: number | undefined; integrityCheck: IntegrityCheckType; } @@ -308,8 +308,8 @@ export type DecryptAttachmentToSinkOptionsType = Readonly< ) & ( | { - aesKey: Readonly; - macKey: Readonly; + aesKey: Readonly>; + macKey: Readonly>; } | { // The format used by most stored attachments @@ -369,8 +369,8 @@ export async function decryptAttachmentV2ToSink( ): Promise> { const { idForLogging, outerEncryption } = options; - let aesKey: Uint8Array; - let macKey: Uint8Array; + let aesKey: Uint8Array; + let macKey: Uint8Array; if ('aesKey' in options) { ({ aesKey, macKey } = options); @@ -387,11 +387,11 @@ export async function decryptAttachmentV2ToSink( const hmac = createHmac(HashType.size256, macKey); const plaintextHash = createHash(HashType.size256); - let theirMac: Uint8Array | undefined; + let theirMac: Uint8Array | undefined; // When downloading from backup there is an outer encryption layer; in that case we // need to decrypt the outer layer and check its MAC - let theirOuterMac: Uint8Array | undefined; + let theirOuterMac: Uint8Array | undefined; const outerHmac = outerEncryption ? createHmac(HashType.size256, outerEncryption.macKey) : undefined; @@ -407,8 +407,8 @@ export async function decryptAttachmentV2ToSink( : undefined; let readFd: FileHandle | undefined; - let ourPlaintextHash: Uint8Array | undefined; - let ourDigest: Uint8Array | undefined; + let ourPlaintextHash: Uint8Array | undefined; + let ourDigest: Uint8Array | undefined; let ciphertextStream: Readable; try { @@ -616,10 +616,12 @@ export async function decryptAndReencryptLocally( */ type AttachmentEncryptionKeysType = { - aesKey: Uint8Array; - macKey: Uint8Array; + aesKey: Uint8Array; + macKey: Uint8Array; }; -export function splitKeys(keys: Uint8Array): AttachmentEncryptionKeysType { +export function splitKeys( + keys: Uint8Array +): AttachmentEncryptionKeysType { strictAssert( keys.byteLength === KEY_SET_LENGTH, `attachment keys must be ${KEY_SET_LENGTH} bytes, got ${keys.byteLength}` @@ -629,7 +631,7 @@ export function splitKeys(keys: Uint8Array): AttachmentEncryptionKeysType { return { aesKey, macKey }; } -export function generateKeys(): Uint8Array { +export function generateKeys(): Uint8Array { return randomBytes(KEY_SET_LENGTH); } @@ -679,8 +681,8 @@ function checkIntegrity({ integrityCheck, logId, }: { - locallyCalculatedDigest: Uint8Array; - locallyCalculatedPlaintextHash: Uint8Array; + locallyCalculatedDigest: Uint8Array; + locallyCalculatedPlaintextHash: Uint8Array; integrityCheck: IntegrityCheckType; logId: string; }): void { @@ -709,7 +711,7 @@ function checkIntegrity({ /** * Prepends the iv to the stream. */ -function prependIv(iv: Uint8Array) { +function prependIv(iv: Uint8Array) { strictAssert( iv.byteLength === IV_LENGTH, `prependIv: iv should be ${IV_LENGTH} bytes, got ${iv.byteLength} bytes` @@ -718,7 +720,7 @@ function prependIv(iv: Uint8Array) { } export function getPlaintextHashForInMemoryAttachment( - data: Uint8Array + data: Uint8Array ): string { return createHash(HashType.size256).update(data).digest('hex'); } diff --git a/ts/Bytes.std.ts b/ts/Bytes.std.ts index ccde15d8bc..b2546b5934 100644 --- a/ts/Bytes.std.ts +++ b/ts/Bytes.std.ts @@ -5,44 +5,44 @@ import { Bytes } from './context/Bytes.std.js'; const bytes = globalThis.window?.SignalContext?.bytes || new Bytes(); -export function fromBase64(value: string): Uint8Array { +export function fromBase64(value: string): Uint8Array { return bytes.fromBase64(value); } -export function fromBase64url(value: string): Uint8Array { +export function fromBase64url(value: string): Uint8Array { return bytes.fromBase64url(value); } -export function fromHex(value: string): Uint8Array { +export function fromHex(value: string): Uint8Array { return bytes.fromHex(value); } // TODO(indutny): deprecate it -export function fromBinary(value: string): Uint8Array { +export function fromBinary(value: string): Uint8Array { return bytes.fromBinary(value); } -export function fromString(value: string): Uint8Array { +export function fromString(value: string): Uint8Array { return bytes.fromString(value); } -export function toBase64(data: Uint8Array): string { +export function toBase64(data: Uint8Array): string { return bytes.toBase64(data); } -export function toBase64url(data: Uint8Array): string { +export function toBase64url(data: Uint8Array): string { return bytes.toBase64url(data); } -export function toHex(data: Uint8Array): string { +export function toHex(data: Uint8Array): string { return bytes.toHex(data); } // TODO(indutny): deprecate it -export function toBinary(data: Uint8Array): string { +export function toBinary(data: Uint8Array): string { return bytes.toBinary(data); } -export function toString(data: Uint8Array): string { +export function toString(data: Uint8Array): string { return bytes.toString(data); } @@ -50,27 +50,37 @@ export function byteLength(value: string): number { return bytes.byteLength(value); } -export function concatenate(list: ReadonlyArray): Uint8Array { +export function concatenate( + list: ReadonlyArray> +): Uint8Array { return bytes.concatenate(list); } -export function isEmpty(data: Uint8Array | null | undefined): boolean { +export function isEmpty( + data: Uint8Array | null | undefined +): boolean { return bytes.isEmpty(data); } export function isNotEmpty( - data: Uint8Array | null | undefined -): data is Uint8Array { + data: Uint8Array | null | undefined +): data is Uint8Array { return !bytes.isEmpty(data); } export function areEqual( - a: Uint8Array | null | undefined, - b: Uint8Array | null | undefined + a: Uint8Array | null | undefined, + b: Uint8Array | null | undefined ): boolean { return bytes.areEqual(a, b); } -export function readBigUint64BE(value: Uint8Array): bigint { +export function readBigUint64BE(value: Uint8Array): bigint { return bytes.readBigUint64BE(value); } + +export function isNonSharedUint8Array( + value: unknown +): value is Uint8Array { + return value instanceof Uint8Array && value.buffer instanceof ArrayBuffer; +} diff --git a/ts/Crypto.node.ts b/ts/Crypto.node.ts index 8b588d0fa5..a982120c0f 100644 --- a/ts/Crypto.node.ts +++ b/ts/Crypto.node.ts @@ -36,8 +36,8 @@ export const PaddedLengths = { }; export type EncryptedAttachment = { - ciphertext: Uint8Array; - digest: Uint8Array; + ciphertext: Uint8Array; + digest: Uint8Array; plaintextHash: string; }; @@ -45,7 +45,9 @@ export function generateRegistrationId(): number { return randomInt(1, 16383); } -export function deriveStickerPackKey(packKey: Uint8Array): Uint8Array { +export function deriveStickerPackKey( + packKey: Uint8Array +): Uint8Array { const salt = getZeroes(32); const info = Bytes.fromString('Sticker Pack'); @@ -55,10 +57,10 @@ export function deriveStickerPackKey(packKey: Uint8Array): Uint8Array { } export function deriveSecrets( - input: Uint8Array, - salt: Uint8Array, - info: Uint8Array -): [Uint8Array, Uint8Array, Uint8Array] { + input: Uint8Array, + salt: Uint8Array, + info: Uint8Array +): [Uint8Array, Uint8Array, Uint8Array] { const output = hkdf(3 * 32, input, info, salt); return [ output.subarray(0, 32), @@ -67,7 +69,9 @@ export function deriveSecrets( ]; } -export function deriveMasterKeyFromGroupV1(groupV1Id: Uint8Array): Uint8Array { +export function deriveMasterKeyFromGroupV1( + groupV1Id: Uint8Array +): Uint8Array { const salt = getZeroes(32); const info = Bytes.fromString('GV2 Migration'); @@ -96,7 +100,7 @@ export function hashProfileKey( return webSafe.slice(-3); } -export function computeHash(data: Uint8Array): string { +export function computeHash(data: Uint8Array): string { return Bytes.toBase64(hash(HashType.size512, data)); } @@ -104,8 +108,8 @@ export function computeHash(data: Uint8Array): string { export type EncryptedDeviceName = { ephemeralPublic: PublicKey; - syntheticIv: Uint8Array; - ciphertext: Uint8Array; + syntheticIv: Uint8Array; + ciphertext: Uint8Array; }; export function encryptDeviceName( @@ -163,7 +167,7 @@ export function encryptDeviceCreatedAt( deviceId: number, registrationId: number, identityPublic: PublicKey -): Uint8Array { +): Uint8Array { const createdAtBuffer = new ArrayBuffer(8); const dataView = new DataView(createdAtBuffer); dataView.setBigUint64(0, BigInt(createdAt), false); @@ -180,7 +184,7 @@ export function encryptDeviceCreatedAt( // createdAtCiphertext is an Int64, encrypted using the identity key // PrivateKey with 5 bytes of associated data (deviceId || registrationId). export function decryptDeviceCreatedAt( - createdAtCiphertext: Uint8Array, + createdAtCiphertext: Uint8Array, deviceId: number, registrationId: number, identityPrivate: PrivateKey @@ -200,7 +204,7 @@ export function decryptDeviceCreatedAt( function getAssociatedDataForDeviceCreatedAt( deviceId: number, registrationId: number -): Uint8Array { +): Uint8Array { if (deviceId > 255) { throw new Error('deviceId above 255, must be 1 byte'); } @@ -212,18 +216,22 @@ function getAssociatedDataForDeviceCreatedAt( return new Uint8Array(associatedDataBuffer); } -export function deriveMasterKey(accountEntropyPool: string): Uint8Array { +export function deriveMasterKey( + accountEntropyPool: string +): Uint8Array { return AccountEntropyPool.deriveSvrKey(accountEntropyPool); } -export function deriveStorageServiceKey(masterKey: Uint8Array): Uint8Array { +export function deriveStorageServiceKey( + masterKey: Uint8Array +): Uint8Array { return hmacSha256(masterKey, Bytes.fromString('Storage Service Encryption')); } export function deriveStorageManifestKey( - storageServiceKey: Uint8Array, + storageServiceKey: Uint8Array, version = 0n -): Uint8Array { +): Uint8Array { return hmacSha256(storageServiceKey, Bytes.fromString(`Manifest_${version}`)); } @@ -232,16 +240,16 @@ const STORAGE_SERVICE_ITEM_KEY_INFO_PREFIX = const STORAGE_SERVICE_ITEM_KEY_LEN = 32; export type DeriveStorageItemKeyOptionsType = Readonly<{ - storageServiceKey: Uint8Array; - recordIkm: Uint8Array | undefined; - key: Uint8Array; + storageServiceKey: Uint8Array; + recordIkm: Uint8Array | undefined; + key: Uint8Array; }>; export function deriveStorageItemKey({ storageServiceKey, recordIkm, key, -}: DeriveStorageItemKeyOptionsType): Uint8Array { +}: DeriveStorageItemKeyOptionsType): Uint8Array { if (recordIkm == null) { const itemID = Bytes.toBase64(key); return hmacSha256(storageServiceKey, Bytes.fromString(`Item_${itemID}`)); @@ -258,15 +266,17 @@ export function deriveStorageItemKey({ ); } -export function getAccessKeyVerifier(accessKey: Uint8Array): Uint8Array { +export function getAccessKeyVerifier( + accessKey: Uint8Array +): Uint8Array { const plaintext = getZeroes(32); return hmacSha256(accessKey, plaintext); } export function verifyAccessKey( - accessKey: Uint8Array, - theirVerifier: Uint8Array + accessKey: Uint8Array, + theirVerifier: Uint8Array ): boolean { const ourVerifier = getAccessKeyVerifier(accessKey); @@ -282,9 +292,9 @@ const NONCE_LENGTH = 16; const SYMMETRIC_MAC_LENGTH = 16; export function encryptSymmetric( - key: Uint8Array, - plaintext: Uint8Array -): Uint8Array { + key: Uint8Array, + plaintext: Uint8Array +): Uint8Array { const iv = getZeroes(IV_LENGTH); const nonce = getRandomBytes(NONCE_LENGTH); @@ -301,9 +311,9 @@ export function encryptSymmetric( } export function decryptSymmetric( - key: Uint8Array, - data: Uint8Array -): Uint8Array { + key: Uint8Array, + data: Uint8Array +): Uint8Array { const iv = getZeroes(IV_LENGTH); const nonce = getFirstBytes(data, NONCE_LENGTH); @@ -336,7 +346,10 @@ export function decryptSymmetric( // Encryption -export function hmacSha256(key: Uint8Array, plaintext: Uint8Array): Uint8Array { +export function hmacSha256( + key: Uint8Array, + plaintext: Uint8Array +): Uint8Array { return sign(key, plaintext); } @@ -344,9 +357,9 @@ export function hmacSha256(key: Uint8Array, plaintext: Uint8Array): Uint8Array { // to be longer than the passed-in length. This allows easy comparisons against // arbitrary MAC lengths. export function verifyHmacSha256( - plaintext: Uint8Array, - key: Uint8Array, - theirMac: Uint8Array, + plaintext: Uint8Array, + key: Uint8Array, + theirMac: Uint8Array, length: number ): void { const ourMac = hmacSha256(key, plaintext); @@ -366,10 +379,10 @@ export function verifyHmacSha256( } export function encryptAes256CbcPkcsPadding( - key: Uint8Array, - plaintext: Uint8Array, - iv: Uint8Array -): Uint8Array { + key: Uint8Array, + plaintext: Uint8Array, + iv: Uint8Array +): Uint8Array { return encrypt(CipherType.AES256CBC, { key, plaintext, @@ -378,10 +391,10 @@ export function encryptAes256CbcPkcsPadding( } export function decryptAes256CbcPkcsPadding( - key: Uint8Array, - ciphertext: Uint8Array, - iv: Uint8Array -): Uint8Array { + key: Uint8Array, + ciphertext: Uint8Array, + iv: Uint8Array +): Uint8Array { return decrypt(CipherType.AES256CBC, { key, ciphertext, @@ -390,10 +403,10 @@ export function decryptAes256CbcPkcsPadding( } export function encryptAesCtr( - key: Uint8Array, - plaintext: Uint8Array, - counter: Uint8Array -): Uint8Array { + key: Uint8Array, + plaintext: Uint8Array, + counter: Uint8Array +): Uint8Array { return encrypt(CipherType.AES256CTR, { key, plaintext, @@ -402,10 +415,10 @@ export function encryptAesCtr( } export function decryptAesCtr( - key: Uint8Array, - ciphertext: Uint8Array, - counter: Uint8Array -): Uint8Array { + key: Uint8Array, + ciphertext: Uint8Array, + counter: Uint8Array +): Uint8Array { return decrypt(CipherType.AES256CTR, { key, ciphertext, @@ -414,11 +427,11 @@ export function decryptAesCtr( } export function encryptAesGcm( - key: Uint8Array, - iv: Uint8Array, - plaintext: Uint8Array, - aad?: Uint8Array -): Uint8Array { + key: Uint8Array, + iv: Uint8Array, + plaintext: Uint8Array, + aad?: Uint8Array +): Uint8Array { return encrypt(CipherType.AES256GCM, { key, plaintext, @@ -428,10 +441,10 @@ export function encryptAesGcm( } export function decryptAesGcm( - key: Uint8Array, - iv: Uint8Array, - ciphertext: Uint8Array -): Uint8Array { + key: Uint8Array, + iv: Uint8Array, + ciphertext: Uint8Array +): Uint8Array { return decrypt(CipherType.AES256GCM, { key, ciphertext, @@ -441,13 +454,13 @@ export function decryptAesGcm( // Hashing -export function sha256(data: Uint8Array): Uint8Array { +export function sha256(data: Uint8Array): Uint8Array { return hash(HashType.size256, data); } // Utility -export function getZeroes(n: number): Uint8Array { +export function getZeroes(n: number): Uint8Array { return new Uint8Array(n); } @@ -464,11 +477,16 @@ export function intsToByteHighAndLow( return ((highValue << 4) | lowValue) & 0xff; } -export function getFirstBytes(data: Uint8Array, n: number): Uint8Array { +export function getFirstBytes( + data: Uint8Array, + n: number +): Uint8Array { return data.subarray(0, n); } -export function trimForDisplay(padded: Uint8Array): Uint8Array { +export function trimForDisplay( + padded: Uint8Array +): Uint8Array { let paddingEnd = 0; for (paddingEnd; paddingEnd < padded.length; paddingEnd += 1) { if (padded[paddingEnd] === 0x00) { @@ -478,7 +496,10 @@ export function trimForDisplay(padded: Uint8Array): Uint8Array { return padded.subarray(0, paddingEnd); } -function verifyDigest(data: Uint8Array, theirDigest: Uint8Array): void { +function verifyDigest( + data: Uint8Array, + theirDigest: Uint8Array +): void { const ourDigest = sha256(data); let result = 0; for (let i = 0; i < theirDigest.byteLength; i += 1) { @@ -491,10 +512,10 @@ function verifyDigest(data: Uint8Array, theirDigest: Uint8Array): void { } export function decryptAttachmentV1( - encryptedBin: Uint8Array, - keys: Uint8Array, - theirDigest?: Uint8Array -): Uint8Array { + encryptedBin: Uint8Array, + keys: Uint8Array, + theirDigest?: Uint8Array +): Uint8Array { if (keys.byteLength !== 64) { throw new Error('Got invalid length attachment keys'); } @@ -530,9 +551,9 @@ export function encryptAttachment({ keys, dangerousTestOnlyIv, }: { - plaintext: Readonly; - keys: Readonly; - dangerousTestOnlyIv?: Readonly; + plaintext: Readonly>; + keys: Readonly>; + dangerousTestOnlyIv?: Readonly>; }): Omit { const logId = 'encryptAttachment'; if (!(plaintext instanceof Uint8Array)) { @@ -573,9 +594,9 @@ export function padAndEncryptAttachment({ keys, dangerousTestOnlyIv, }: { - plaintext: Readonly; - keys: Readonly; - dangerousTestOnlyIv?: Readonly; + plaintext: Readonly>; + keys: Readonly>; + dangerousTestOnlyIv?: Readonly>; }): EncryptedAttachment { const size = plaintext.byteLength; const paddedSize = logPadSize(size); @@ -594,7 +615,10 @@ export function padAndEncryptAttachment({ }; } -export function encryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array { +export function encryptProfile( + data: Uint8Array, + key: Uint8Array +): Uint8Array { const iv = getRandomBytes(PROFILE_IV_LENGTH); if (key.byteLength !== PROFILE_KEY_LENGTH) { throw new Error('Got invalid length profile key'); @@ -606,7 +630,10 @@ export function encryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array { return Bytes.concatenate([iv, ciphertext]); } -export function decryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array { +export function decryptProfile( + data: Uint8Array, + key: Uint8Array +): Uint8Array { if (data.byteLength < 12 + 16 + 1) { throw new Error(`Got too short input: ${data.byteLength}`); } @@ -630,10 +657,10 @@ export function decryptProfile(data: Uint8Array, key: Uint8Array): Uint8Array { } export function encryptProfileItemWithPadding( - item: Uint8Array, - profileKey: Uint8Array, + item: Uint8Array, + profileKey: Uint8Array, paddedLengths: (typeof PaddedLengths)[keyof typeof PaddedLengths] -): Uint8Array { +): Uint8Array { const paddedLength = paddedLengths.find( (length: number) => item.byteLength <= length ); @@ -647,8 +674,8 @@ export function encryptProfileItemWithPadding( export function decryptProfileName( encryptedProfileName: string, - key: Uint8Array -): { given: Uint8Array; family: Uint8Array | null } { + key: Uint8Array +): { given: Uint8Array; family: Uint8Array | null } { const data = Bytes.fromBase64(encryptedProfileName); const padded = decryptProfile(data, key); @@ -681,23 +708,29 @@ export function decryptProfileName( const crypto = globalThis.window?.SignalContext.crypto || new Crypto(); -export function sign(key: Uint8Array, data: Uint8Array): Uint8Array { +export function sign( + key: Uint8Array, + data: Uint8Array +): Uint8Array { return crypto.sign(key, data); } -export function hash(type: HashType, data: Uint8Array): Uint8Array { +export function hash( + type: HashType, + data: Uint8Array +): Uint8Array { return crypto.hash(type, data); } export function encrypt( ...args: Parameters -): Uint8Array { +): Uint8Array { return crypto.encrypt(...args); } export function decrypt( ...args: Parameters -): Uint8Array { +): Uint8Array { return crypto.decrypt(...args); } @@ -708,13 +741,13 @@ export function randomInt(min: number, max: number): number { return crypto.randomInt(min, max + 1); } -export function getRandomBytes(size: number): Uint8Array { +export function getRandomBytes(size: number): Uint8Array { return crypto.getRandomBytes(size); } export function constantTimeEqual( - left: Uint8Array, - right: Uint8Array + left: Uint8Array, + right: Uint8Array ): boolean { return crypto.constantTimeEqual(left, right); } @@ -730,7 +763,7 @@ export function getIdentifierHash({ pni: PniString | undefined; groupId: string | undefined; }): number | null { - let identifier: Uint8Array; + let identifier: Uint8Array; if (aci != null) { identifier = Aci.parseFromServiceIdString(aci).getServiceIdBinary(); } else if (e164 != null) { diff --git a/ts/Curve.node.ts b/ts/Curve.node.ts index dd351e3420..e72e479c07 100644 --- a/ts/Curve.node.ts +++ b/ts/Curve.node.ts @@ -79,7 +79,9 @@ export function generateKeyPair(): KeyPairType { return new client.IdentityKeyPair(pubKey, privKey); } -export function createKeyPair(incomingKey: Uint8Array): KeyPairType { +export function createKeyPair( + incomingKey: Uint8Array +): KeyPairType { const copy = new Uint8Array(incomingKey); clampPrivateKey(copy); if (!constantTimeEqual(copy, incomingKey)) { @@ -96,7 +98,9 @@ export function createKeyPair(incomingKey: Uint8Array): KeyPairType { return new client.IdentityKeyPair(pubKey, privKey); } -export function prefixPublicKey(pubKey: Uint8Array): Uint8Array { +export function prefixPublicKey( + pubKey: Uint8Array +): Uint8Array { return Bytes.concatenate([ new Uint8Array([0x05]), validatePubKeyFormat(pubKey), @@ -106,26 +110,28 @@ export function prefixPublicKey(pubKey: Uint8Array): Uint8Array { export function calculateAgreement( pubKey: client.PublicKey, privKey: client.PrivateKey -): Uint8Array { +): Uint8Array { return privKey.agree(pubKey); } export function verifySignature( pubKey: client.PublicKey, - message: Uint8Array, - signature: Uint8Array + message: Uint8Array, + signature: Uint8Array ): boolean { return pubKey.verify(message, signature); } export function calculateSignature( privKey: client.PrivateKey, - plaintext: Uint8Array -): Uint8Array { + plaintext: Uint8Array +): Uint8Array { return privKey.sign(plaintext); } -function validatePubKeyFormat(pubKey: Uint8Array): Uint8Array { +function validatePubKeyFormat( + pubKey: Uint8Array +): Uint8Array { if ( pubKey === undefined || ((pubKey.byteLength !== 33 || pubKey[0] !== 5) && pubKey.byteLength !== 32) @@ -139,12 +145,12 @@ function validatePubKeyFormat(pubKey: Uint8Array): Uint8Array { return pubKey; } -export function setPublicKeyTypeByte(publicKey: Uint8Array): void { +export function setPublicKeyTypeByte(publicKey: Uint8Array): void { // eslint-disable-next-line no-param-reassign publicKey[0] = 5; } -export function clampPrivateKey(privateKey: Uint8Array): void { +export function clampPrivateKey(privateKey: Uint8Array): void { /* eslint-disable no-bitwise, no-param-reassign */ /* eslint-disable @typescript-eslint/no-non-null-assertion */ privateKey[0]! &= 248; diff --git a/ts/LibSignalStores.preload.ts b/ts/LibSignalStores.preload.ts index 7a42a022a4..089bb67756 100644 --- a/ts/LibSignalStores.preload.ts +++ b/ts/LibSignalStores.preload.ts @@ -332,21 +332,24 @@ export class SignedPreKeys extends SignedPreKeyStore { } export class KeyTransparencyStore implements KeyTransparencyStoreInterface { - async getLastDistinguishedTreeHead(): Promise { + async getLastDistinguishedTreeHead(): Promise | null> { return signalProtocolStore.getLastDistinguishedTreeHead(); } async setLastDistinguishedTreeHead( - bytes: Readonly | null + bytes: Readonly> | null ): Promise { return signalProtocolStore.setLastDistinguishedTreeHead(bytes); } - async getAccountData(aci: Aci): Promise { + async getAccountData(aci: Aci): Promise | null> { return signalProtocolStore.getKTAccountData(aci); } - async setAccountData(aci: Aci, bytes: Readonly): Promise { + async setAccountData( + aci: Aci, + bytes: Readonly> + ): Promise { return signalProtocolStore.setKTAccountData(aci, bytes); } } diff --git a/ts/SignalProtocolStore.preload.ts b/ts/SignalProtocolStore.preload.ts index dea6fcfc9c..8d2be46282 100644 --- a/ts/SignalProtocolStore.preload.ts +++ b/ts/SignalProtocolStore.preload.ts @@ -158,7 +158,7 @@ export type SaveIdentityOptions = Readonly<{ export type VerifyAlternateIdentityOptionsType = Readonly<{ aci: AciString; pni: PniString; - signature: Uint8Array; + signature: Uint8Array; }>; export type SetVerifiedExtra = Readonly<{ @@ -1933,7 +1933,7 @@ export class SignalProtocolStore extends EventEmitter { // https://github.com/signalapp/Signal-Android/blob/fc3db538bcaa38dc149712a483d3032c9c1f3998/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java#L128 async isTrustedIdentity( encodedAddress: Address, - publicKey: Uint8Array, + publicKey: Uint8Array, direction: number ): Promise { if (!this.identityKeys) { @@ -1978,7 +1978,7 @@ export class SignalProtocolStore extends EventEmitter { // https://github.com/signalapp/Signal-Android/blob/fc3db538bcaa38dc149712a483d3032c9c1f3998/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java#L233 isTrustedForSending( serviceId: ServiceIdString, - publicKey: Uint8Array, + publicKey: Uint8Array, identityRecord?: IdentityKeyType ): boolean { if (!identityRecord) { @@ -2029,7 +2029,7 @@ export class SignalProtocolStore extends EventEmitter { async loadIdentityKey( serviceId: ServiceIdString - ): Promise { + ): Promise | undefined> { if (serviceId == null) { throw new Error('loadIdentityKey: serviceId was undefined/null'); } @@ -2078,7 +2078,7 @@ export class SignalProtocolStore extends EventEmitter { // https://github.com/signalapp/Signal-Android/blob/fc3db538bcaa38dc149712a483d3032c9c1f3998/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java#L69 async saveIdentity( encodedAddress: Address, - publicKey: Uint8Array, + publicKey: Uint8Array, nonblockingApproval = false, { zone = GLOBAL_ZONE, noOverwrite = false }: SaveIdentityOptions = {} ): Promise { @@ -2350,7 +2350,7 @@ export class SignalProtocolStore extends EventEmitter { // the same! checkPreviousKey( serviceId: ServiceIdString, - publicKey: Uint8Array, + publicKey: Uint8Array, context: string ): void { const conversation = window.ConversationController.get(serviceId); @@ -2383,7 +2383,7 @@ export class SignalProtocolStore extends EventEmitter { async updateIdentityAfterSync( serviceId: ServiceIdString, verifiedStatus: number, - publicKey: Uint8Array + publicKey: Uint8Array ): Promise<{ shouldAddVerifiedChangedMessage: boolean }> { strictAssert( validateVerifiedStatus(verifiedStatus), @@ -2798,12 +2798,12 @@ export class SignalProtocolStore extends EventEmitter { // Key Transparency - getLastDistinguishedTreeHead(): Uint8Array | null { + getLastDistinguishedTreeHead(): Uint8Array | null { return itemStorage.get('lastDistinguishedTreeHead') ?? null; } async setLastDistinguishedTreeHead( - bytes: Readonly | null + bytes: Readonly> | null ): Promise { if (bytes == null) { await itemStorage.remove('lastDistinguishedTreeHead'); @@ -2812,7 +2812,9 @@ export class SignalProtocolStore extends EventEmitter { } } - async getKTAccountData(aciObject: Aci): Promise { + async getKTAccountData( + aciObject: Aci + ): Promise | null> { const aci = fromAciObject(aciObject); const data = await DataReader.getKTAccountData(aci); return data ?? null; @@ -2820,7 +2822,7 @@ export class SignalProtocolStore extends EventEmitter { async setKTAccountData( aciObject: Aci, - bytes: Readonly + bytes: Readonly> ): Promise { const aci = fromAciObject(aciObject); return DataWriter.setKTAccountData(aci, bytes); diff --git a/ts/calling/VideoSupport.preload.ts b/ts/calling/VideoSupport.preload.ts index 390aaf8ce9..b4589ae815 100644 --- a/ts/calling/VideoSupport.preload.ts +++ b/ts/calling/VideoSupport.preload.ts @@ -418,7 +418,7 @@ export const MAX_VIDEO_CAPTURE_BUFFER_SIZE = MAX_VIDEO_CAPTURE_AREA * 4; export class CanvasVideoRenderer { private canvas?: RefObject; private sizeCallback?: SizeCallbackType; - private buffer: Uint8Array; + private buffer: Uint8Array; private imageData?: ImageData; private source?: VideoFrameSource; private rafId?: ReturnType; diff --git a/ts/calling/useGetCallingFrameBuffer.std.ts b/ts/calling/useGetCallingFrameBuffer.std.ts index 3c353dc77a..74a3d39637 100644 --- a/ts/calling/useGetCallingFrameBuffer.std.ts +++ b/ts/calling/useGetCallingFrameBuffer.std.ts @@ -12,8 +12,8 @@ import { FRAME_BUFFER_SIZE } from './constants.std.js'; * of allocating one per participant. Be careful when using this buffer elsewhere, as it * is not cleaned up and may hold stale data. */ -export function useGetCallingFrameBuffer(): () => Uint8Array { - const ref = useRef(null); +export function useGetCallingFrameBuffer(): () => Uint8Array { + const ref = useRef | null>(null); return useCallback(() => { if (!ref.current) { diff --git a/ts/components/AvatarEditor.dom.tsx b/ts/components/AvatarEditor.dom.tsx index 7f130ef82c..0101ca76e6 100644 --- a/ts/components/AvatarEditor.dom.tsx +++ b/ts/components/AvatarEditor.dom.tsx @@ -29,14 +29,14 @@ const { isEqual } = lodash; export type PropsType = { avatarColor?: AvatarColorType; avatarUrl?: string; - avatarValue?: Uint8Array; + avatarValue?: Uint8Array; conversationId?: string; conversationTitle?: string; deleteAvatarFromDisk: DeleteAvatarFromDiskActionType; i18n: LocalizerType; isGroup?: boolean; onCancel: () => unknown; - onSave: (buffer: Uint8Array | undefined) => unknown; + onSave: (buffer: Uint8Array | undefined) => unknown; userAvatarData: ReadonlyArray; replaceAvatar: ReplaceAvatarActionType; saveAvatarToDisk: SaveAvatarToDiskActionType; @@ -66,12 +66,12 @@ export function AvatarEditor({ const [provisionalSelectedAvatar, setProvisionalSelectedAvatar] = useState< AvatarDataType | undefined >(); - const [avatarPreview, setAvatarPreview] = useState( - avatarValue - ); - const [initialAvatar, setInitialAvatar] = useState( - avatarValue - ); + const [avatarPreview, setAvatarPreview] = useState< + Uint8Array | undefined + >(avatarValue); + const [initialAvatar, setInitialAvatar] = useState< + Uint8Array | undefined + >(avatarValue); const [localAvatarData, setLocalAvatarData] = useState>( userAvatarData.slice() ); @@ -166,10 +166,13 @@ export function AvatarEditor({ ] ); - const handleAvatarLoaded = useCallback((avatarBuffer: Uint8Array) => { - setAvatarPreview(avatarBuffer); - setInitialAvatar(avatarBuffer); - }, []); + const handleAvatarLoaded = useCallback( + (avatarBuffer: Uint8Array) => { + setAvatarPreview(avatarBuffer); + setInitialAvatar(avatarBuffer); + }, + [] + ); let content: React.JSX.Element | undefined; diff --git a/ts/components/AvatarIconEditor.dom.tsx b/ts/components/AvatarIconEditor.dom.tsx index 61344b3e93..2cfa23dd69 100644 --- a/ts/components/AvatarIconEditor.dom.tsx +++ b/ts/components/AvatarIconEditor.dom.tsx @@ -22,7 +22,9 @@ export function AvatarIconEditor({ i18n, onClose, }: PropsType): React.JSX.Element { - const [avatarBuffer, setAvatarBuffer] = useState(); + const [avatarBuffer, setAvatarBuffer] = useState< + Uint8Array | undefined + >(); const [avatarData, setAvatarData] = useState(initialAvatarData); diff --git a/ts/components/AvatarPreview.dom.tsx b/ts/components/AvatarPreview.dom.tsx index 2aebd0721d..4a69dc11a5 100644 --- a/ts/components/AvatarPreview.dom.tsx +++ b/ts/components/AvatarPreview.dom.tsx @@ -21,13 +21,13 @@ const log = createLogger('AvatarPreview'); export type PropsType = { avatarColor?: AvatarColorType; avatarUrl?: string; - avatarValue?: Uint8Array; + avatarValue?: Uint8Array; conversationTitle?: string; i18n: LocalizerType; isEditable?: boolean; isGroup?: boolean; noteToSelf?: boolean; - onAvatarLoaded?: (avatarBuffer: Uint8Array) => unknown; + onAvatarLoaded?: (avatarBuffer: Uint8Array) => unknown; onClear?: () => unknown; onClick?: () => unknown; showUploadButton?: boolean; @@ -58,7 +58,9 @@ export function AvatarPreview({ showUploadButton, style = {}, }: PropsType): React.JSX.Element { - const [avatarPreview, setAvatarPreview] = useState(); + const [avatarPreview, setAvatarPreview] = useState< + Uint8Array | undefined + >(); // Loads the initial avatarUrl if one is provided, but only if we're in editable mode. // If we're not editable, we assume that we either have an avatarUrl or we show a diff --git a/ts/components/AvatarTextEditor.dom.tsx b/ts/components/AvatarTextEditor.dom.tsx index 05afb68288..3e8d14288f 100644 --- a/ts/components/AvatarTextEditor.dom.tsx +++ b/ts/components/AvatarTextEditor.dom.tsx @@ -28,7 +28,7 @@ import { const { noop } = lodash; type DoneHandleType = ( - avatarBuffer: Uint8Array, + avatarBuffer: Uint8Array, avatarData: AvatarDataType ) => unknown; diff --git a/ts/components/AvatarUploadButton.dom.tsx b/ts/components/AvatarUploadButton.dom.tsx index e4dfa87e5c..6d5fbf0f03 100644 --- a/ts/components/AvatarUploadButton.dom.tsx +++ b/ts/components/AvatarUploadButton.dom.tsx @@ -13,7 +13,7 @@ const { noop } = lodash; export type PropsType = { className: string; i18n: LocalizerType; - onChange: (avatar: Uint8Array) => unknown; + onChange: (avatar: Uint8Array) => unknown; }; export function AvatarUploadButton({ @@ -33,7 +33,7 @@ export function AvatarUploadButton({ let shouldCancel = false; void (async () => { - let newAvatar: Uint8Array; + let newAvatar: Uint8Array; try { newAvatar = await processImageFile(processingFile); } catch (err) { diff --git a/ts/components/BetterAvatar.dom.tsx b/ts/components/BetterAvatar.dom.tsx index e313e1ab5e..9681d49812 100644 --- a/ts/components/BetterAvatar.dom.tsx +++ b/ts/components/BetterAvatar.dom.tsx @@ -18,7 +18,7 @@ export type PropsType = { avatarData: AvatarDataType; i18n: LocalizerType; isSelected?: boolean; - onClick: (avatarBuffer: Uint8Array | undefined) => unknown; + onClick: (avatarBuffer: Uint8Array | undefined) => unknown; onDelete: () => unknown; size?: AvatarSize; }; @@ -31,9 +31,9 @@ export function BetterAvatar({ onDelete, size = 48, }: PropsType): React.JSX.Element { - const [avatarBuffer, setAvatarBuffer] = useState( - avatarData.buffer - ); + const [avatarBuffer, setAvatarBuffer] = useState< + Uint8Array | undefined + >(avatarData.buffer); const [avatarURL, setAvatarURL] = useState(undefined); useEffect(() => { diff --git a/ts/components/GroupCallOverflowArea.dom.tsx b/ts/components/GroupCallOverflowArea.dom.tsx index 04845d1c00..ec2dca7fcc 100644 --- a/ts/components/GroupCallOverflowArea.dom.tsx +++ b/ts/components/GroupCallOverflowArea.dom.tsx @@ -17,7 +17,7 @@ const OVERFLOW_SCROLL_BUTTON_RATIO = 0.75; export const OVERFLOW_PARTICIPANT_WIDTH = 107; export type PropsType = { - getFrameBuffer: () => Uint8Array; + getFrameBuffer: () => Uint8Array; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; i18n: LocalizerType; imageDataCache: React.RefObject; diff --git a/ts/components/GroupCallRemoteParticipant.dom.tsx b/ts/components/GroupCallRemoteParticipant.dom.tsx index 01b62f1dd2..e15a8ce6b2 100644 --- a/ts/components/GroupCallRemoteParticipant.dom.tsx +++ b/ts/components/GroupCallRemoteParticipant.dom.tsx @@ -42,7 +42,7 @@ const DELAY_TO_SHOW_MISSING_MEDIA_KEYS = 5000; const CONTAINER_TRANSITION_TIME = 200; type BasePropsType = { - getFrameBuffer: () => Uint8Array; + getFrameBuffer: () => Uint8Array; getGroupCallVideoFrameSource: (demuxId: number) => VideoFrameSource; i18n: LocalizerType; imageDataCache: React.RefObject; @@ -235,7 +235,7 @@ export const GroupCallRemoteParticipant: React.FC = React.memo( imageData?.data.buffer !== frameBuffer.buffer || imageData?.data.byteOffset !== frameBuffer.byteOffset ) { - const view = new Uint8ClampedArray( + const view = new Uint8ClampedArray( frameBuffer.buffer, frameBuffer.byteOffset, frameWidth * frameHeight * 4 diff --git a/ts/components/LeftPane.dom.tsx b/ts/components/LeftPane.dom.tsx index c52f415c25..7be46bbf0e 100644 --- a/ts/components/LeftPane.dom.tsx +++ b/ts/components/LeftPane.dom.tsx @@ -165,7 +165,7 @@ export type PropsType = { saveAlerts: (alerts: ServerAlertsType) => Promise; savePreferredLeftPaneWidth: (_: number) => void; searchInConversation: (conversationId: string) => unknown; - setComposeGroupAvatar: (_: undefined | Uint8Array) => void; + setComposeGroupAvatar: (_: undefined | Uint8Array) => void; setComposeGroupExpireTimer: (_: DurationInSeconds) => void; setComposeGroupName: (_: string) => void; setComposeSearchTerm: (composeSearchTerm: string) => void; diff --git a/ts/components/MediaEditor.dom.tsx b/ts/components/MediaEditor.dom.tsx index 712f6681da..1e497b61ef 100644 --- a/ts/components/MediaEditor.dom.tsx +++ b/ts/components/MediaEditor.dom.tsx @@ -72,7 +72,7 @@ const { get, has, noop } = lodash; const log = createLogger('MediaEditor'); export type MediaEditorResultType = Readonly<{ - data: Uint8Array; + data: Uint8Array; contentType: MIMEType; blurHash: string; caption?: string; @@ -1451,7 +1451,7 @@ export function MediaEditor({ setEditMode(undefined); setIsSaving(true); - let data: Uint8Array; + let data: Uint8Array; let blurHash: string; try { const renderFabricCanvas = diff --git a/ts/components/Preferences.dom.stories.tsx b/ts/components/Preferences.dom.stories.tsx index 994d06d163..c9cf03724a 100644 --- a/ts/components/Preferences.dom.stories.tsx +++ b/ts/components/Preferences.dom.stories.tsx @@ -247,7 +247,7 @@ function renderDonationsPane(props: { me: typeof me; donationReceipts: ReadonlyArray; saveAttachmentToDisk: (options: { - data: Uint8Array; + data: Uint8Array; name: string; baseDir?: string | undefined; }) => Promise<{ fullPath: string; name: string } | null>; diff --git a/ts/components/Preferences.dom.tsx b/ts/components/Preferences.dom.tsx index d153d2327d..96075e7418 100644 --- a/ts/components/Preferences.dom.tsx +++ b/ts/components/Preferences.dom.tsx @@ -287,7 +287,7 @@ type PropsFunctionType = { internalAddDonationReceipt: (receipt: DonationReceipt) => void; saveAttachmentToDisk: (options: { - data: Uint8Array; + data: Uint8Array; name: string; baseDir?: string | undefined; }) => Promise<{ fullPath: string; name: string } | null>; diff --git a/ts/components/PreferencesDonations.dom.tsx b/ts/components/PreferencesDonations.dom.tsx index 7667317b1c..661ee25152 100644 --- a/ts/components/PreferencesDonations.dom.tsx +++ b/ts/components/PreferencesDonations.dom.tsx @@ -85,7 +85,7 @@ export type PropsDataType = { donationReceipts: ReadonlyArray; theme: ThemeType; saveAttachmentToDisk: (options: { - data: Uint8Array; + data: Uint8Array; name: string; baseDir?: string | undefined; }) => Promise<{ fullPath: string; name: string } | null>; @@ -345,7 +345,7 @@ function PreferencesReceiptList({ i18n: LocalizerType; donationReceipts: ReadonlyArray; saveAttachmentToDisk: (options: { - data: Uint8Array; + data: Uint8Array; name: string; baseDir?: string | undefined; }) => Promise<{ fullPath: string; name: string } | null>; diff --git a/ts/components/PreferencesInternal.dom.tsx b/ts/components/PreferencesInternal.dom.tsx index bab02a7e6b..aad0868275 100644 --- a/ts/components/PreferencesInternal.dom.tsx +++ b/ts/components/PreferencesInternal.dom.tsx @@ -50,7 +50,7 @@ export function PreferencesInternal({ donationReceipts: ReadonlyArray; internalAddDonationReceipt: (receipt: DonationReceipt) => void; saveAttachmentToDisk: (options: { - data: Uint8Array; + data: Uint8Array; name: string; baseDir?: string | undefined; }) => Promise<{ fullPath: string; name: string } | null>; diff --git a/ts/components/ProfileEditor.dom.tsx b/ts/components/ProfileEditor.dom.tsx index b1baca3c59..0a4c73fe0d 100644 --- a/ts/components/ProfileEditor.dom.tsx +++ b/ts/components/ProfileEditor.dom.tsx @@ -230,11 +230,11 @@ export function ProfileEditor({ const [startingAvatarUrl, setStartingAvatarUrl] = useState(profileAvatarUrl); const [oldAvatarBuffer, setOldAvatarBuffer] = useState< - Uint8Array | undefined + Uint8Array | undefined + >(undefined); + const [avatarBuffer, setAvatarBuffer] = useState< + Uint8Array | undefined >(undefined); - const [avatarBuffer, setAvatarBuffer] = useState( - undefined - ); const [stagedProfile, setStagedProfile] = useState({ aboutEmoji, aboutText, @@ -285,7 +285,7 @@ export function ProfileEditor({ // To make AvatarEditor re-render less often const handleAvatarChanged = useCallback( - (avatar: Uint8Array | undefined) => { + (avatar: Uint8Array | undefined) => { // Do not display stale avatar from disk anymore. setStartingAvatarUrl(undefined); @@ -325,7 +325,7 @@ export function ProfileEditor({ // To make AvatarEditor re-render less often const handleAvatarLoaded = useCallback( - (avatar: Uint8Array) => { + (avatar: Uint8Array) => { setAvatarBuffer(avatar); setOldAvatarBuffer(avatar); }, diff --git a/ts/components/QrCode.dom.tsx b/ts/components/QrCode.dom.tsx index 42a89ab0d0..bb5bad837e 100644 --- a/ts/components/QrCode.dom.tsx +++ b/ts/components/QrCode.dom.tsx @@ -12,7 +12,7 @@ const ERROR_CORRECTION_LEVEL = 'L'; export type PropsType = Readonly<{ alt: string; className?: string; - data: string | Uint8Array; + data: string | Uint8Array; }>; export function QrCode(props: PropsType): ReactElement { diff --git a/ts/components/UsernameLinkEditor.dom.stories.tsx b/ts/components/UsernameLinkEditor.dom.stories.tsx index ea1d1c696b..1fb0f5a750 100644 --- a/ts/components/UsernameLinkEditor.dom.stories.tsx +++ b/ts/components/UsernameLinkEditor.dom.stories.tsx @@ -71,23 +71,26 @@ export default { // eslint-disable-next-line react/function-component-definition const Template: StoryFn = args => { const [attachment, setAttachment] = useState(); - const saveAttachment = useCallback(({ data }: { data?: Uint8Array }) => { - if (!data) { - setAttachment(undefined); - return; - } - - const blob = new Blob([data], { - type: 'image/png', - }); - - setAttachment(oldURL => { - if (oldURL) { - URL.revokeObjectURL(oldURL); + const saveAttachment = useCallback( + ({ data }: { data?: Uint8Array }) => { + if (!data) { + setAttachment(undefined); + return; } - return URL.createObjectURL(blob); - }); - }, []); + + const blob = new Blob([data], { + type: 'image/png', + }); + + setAttachment(oldURL => { + if (oldURL) { + URL.revokeObjectURL(oldURL); + } + return URL.createObjectURL(blob); + }); + }, + [] + ); return ( <> diff --git a/ts/components/UsernameLinkEditor.dom.tsx b/ts/components/UsernameLinkEditor.dom.tsx index 0c62cd969b..35a4ebee6e 100644 --- a/ts/components/UsernameLinkEditor.dom.tsx +++ b/ts/components/UsernameLinkEditor.dom.tsx @@ -432,7 +432,7 @@ export function UsernameLinkEditor({ onBack, }: PropsType): React.JSX.Element { - const [pngData, setPngData] = useState(); + const [pngData, setPngData] = useState | undefined>(); const [showColors, setShowColors] = useState(false); const [confirmReset, setConfirmReset] = useState(false); const [recoveryModalVisibility, setRecoveryModalVisibility] = useState( diff --git a/ts/components/conversation/Linkify.dom.tsx b/ts/components/conversation/Linkify.dom.tsx index 32c6decf6d..24815dda9e 100644 --- a/ts/components/conversation/Linkify.dom.tsx +++ b/ts/components/conversation/Linkify.dom.tsx @@ -3,7 +3,7 @@ import React from 'react'; -import LinkifyIt from 'linkify-it'; +import LinkifyIt, { type Match as LinkifyItMatch } from 'linkify-it'; import type { RenderTextCallbackType } from '../../types/Util.std.js'; import { @@ -335,7 +335,7 @@ export function Linkify(props: Props): React.JSX.Element { const chunkData: Array<{ chunk: string; - matchData: ReadonlyArray; + matchData: ReadonlyArray; }> = splitByEmoji(text).map(({ type, value: chunk }) => { if (type === 'text') { return { chunk, matchData: linkify.match(chunk) || [] }; diff --git a/ts/components/conversation/conversation-details/ConversationDetails.dom.tsx b/ts/components/conversation/conversation-details/ConversationDetails.dom.tsx index 62b9f4675c..6f26e411c6 100644 --- a/ts/components/conversation/conversation-details/ConversationDetails.dom.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetails.dom.tsx @@ -273,7 +273,7 @@ export function ConversationDetails({ } makeRequest={async ( options: Readonly<{ - avatar?: undefined | Uint8Array; + avatar?: undefined | Uint8Array; description?: string; title?: string; }> diff --git a/ts/components/conversation/conversation-details/EditConversationAttributesModal.dom.tsx b/ts/components/conversation/conversation-details/EditConversationAttributesModal.dom.tsx index e74c3f5dc4..e73dbb3d44 100644 --- a/ts/components/conversation/conversation-details/EditConversationAttributesModal.dom.tsx +++ b/ts/components/conversation/conversation-details/EditConversationAttributesModal.dom.tsx @@ -31,7 +31,7 @@ type PropsType = { initiallyFocusDescription: boolean; makeRequest: ( _: Readonly<{ - avatar?: undefined | Uint8Array; + avatar?: undefined | Uint8Array; description?: string; title?: undefined | string; }> @@ -70,7 +70,7 @@ export function EditConversationAttributesModal({ const startingAvatarUrlRef = useRef(externalAvatarUrl); const [editingAvatar, setEditingAvatar] = useState(false); - const [avatar, setAvatar] = useState(); + const [avatar, setAvatar] = useState>(); const [rawTitle, setRawTitle] = useState(externalTitle); const [rawGroupDescription, setRawGroupDescription] = useState( externalGroupDescription @@ -135,7 +135,7 @@ export function EditConversationAttributesModal({ event.preventDefault(); const request: { - avatar?: undefined | Uint8Array; + avatar?: undefined | Uint8Array; description?: string; title?: string; } = {}; diff --git a/ts/components/fun/FunPicker.dom.tsx b/ts/components/fun/FunPicker.dom.tsx index 6f0047721b..7911687a62 100644 --- a/ts/components/fun/FunPicker.dom.tsx +++ b/ts/components/fun/FunPicker.dom.tsx @@ -4,6 +4,7 @@ import type { ReactNode } from 'react'; import React, { memo, useCallback, useEffect } from 'react'; import type { Placement } from 'react-aria'; import { DialogTrigger } from 'react-aria-components'; +// @ts-expect-error - Needs tinykeys to update package.json type resolution import { createKeybindingsHandler } from 'tinykeys'; import { FunPickerTabKey } from './constants.dom.js'; import { FunPopover } from './base/FunPopover.dom.js'; diff --git a/ts/components/fun/data/segments.std.ts b/ts/components/fun/data/segments.std.ts index 4cf223d1e8..5e1b57570a 100644 --- a/ts/components/fun/data/segments.std.ts +++ b/ts/components/fun/data/segments.std.ts @@ -94,7 +94,7 @@ async function fetchSegment( contentLength: number, doFetchBytesViaProxy: typeof fetchBytesViaProxy, signal?: AbortSignal -): Promise { +): Promise> { const { data, response } = await doFetchBytesViaProxy({ method: 'GET', url, @@ -122,7 +122,7 @@ async function fetchSegment( 'Unexpected response buffer byte length' ); - let slice: ArrayBufferView; + let slice: Uint8Array; // Trim duplicate bytes from start of last segment if (segmentRange.sliceStart > 0) { slice = data.subarray(segmentRange.sliceStart); diff --git a/ts/components/fun/keyboard/FunKeyboard.dom.tsx b/ts/components/fun/keyboard/FunKeyboard.dom.tsx index 217734d129..5b4b3e7eb6 100644 --- a/ts/components/fun/keyboard/FunKeyboard.dom.tsx +++ b/ts/components/fun/keyboard/FunKeyboard.dom.tsx @@ -3,6 +3,7 @@ import { focusSafely, getFocusableTreeWalker } from '@react-aria/focus'; import type { ReactNode, RefObject } from 'react'; import React, { useEffect, useRef } from 'react'; +// @ts-expect-error - Needs tinykeys to update package.json type resolution import { createKeybindingsHandler } from 'tinykeys'; import { strictAssert } from '../../../util/assert.std.js'; diff --git a/ts/components/leftPane/LeftPaneHelper.dom.tsx b/ts/components/leftPane/LeftPaneHelper.dom.tsx index 6c862f89ea..759b6d7691 100644 --- a/ts/components/leftPane/LeftPaneHelper.dom.tsx +++ b/ts/components/leftPane/LeftPaneHelper.dom.tsx @@ -89,7 +89,9 @@ export abstract class LeftPaneHelper { i18n: LocalizerType; removeSelectedContact: (_: string) => unknown; renderLeftPaneChatFolders: () => React.JSX.Element; - setComposeGroupAvatar: (_: undefined | Uint8Array) => unknown; + setComposeGroupAvatar: ( + _: undefined | Uint8Array + ) => unknown; setComposeGroupExpireTimer: (_: DurationInSeconds) => void; setComposeGroupName: (_: string) => unknown; toggleComposeEditingAvatar: () => unknown; diff --git a/ts/components/leftPane/LeftPaneSetGroupMetadataHelper.dom.tsx b/ts/components/leftPane/LeftPaneSetGroupMetadataHelper.dom.tsx index 4b87995d02..384f0be05d 100644 --- a/ts/components/leftPane/LeftPaneSetGroupMetadataHelper.dom.tsx +++ b/ts/components/leftPane/LeftPaneSetGroupMetadataHelper.dom.tsx @@ -27,7 +27,7 @@ import type { import { AvatarColors } from '../../types/Colors.std.js'; export type LeftPaneSetGroupMetadataPropsType = { - groupAvatar: undefined | Uint8Array; + groupAvatar: undefined | Uint8Array; groupName: string; groupExpireTimer: DurationInSeconds; hasError: boolean; @@ -38,7 +38,7 @@ export type LeftPaneSetGroupMetadataPropsType = { }; export class LeftPaneSetGroupMetadataHelper extends LeftPaneHelper { - readonly #groupAvatar: undefined | Uint8Array; + readonly #groupAvatar: undefined | Uint8Array; readonly #groupName: string; readonly #groupExpireTimer: DurationInSeconds; readonly #hasError: boolean; @@ -121,7 +121,7 @@ export class LeftPaneSetGroupMetadataHelper extends LeftPaneHelper unknown; i18n: LocalizerType; - setComposeGroupAvatar: (_: undefined | Uint8Array) => unknown; + setComposeGroupAvatar: (_: undefined | Uint8Array) => unknown; setComposeGroupExpireTimer: (_: DurationInSeconds) => void; setComposeGroupName: (_: string) => unknown; toggleComposeEditingAvatar: () => unknown; diff --git a/ts/context/Bytes.std.ts b/ts/context/Bytes.std.ts index e2ed724d78..fa656db18c 100644 --- a/ts/context/Bytes.std.ts +++ b/ts/context/Bytes.std.ts @@ -7,45 +7,45 @@ import { Buffer } from 'buffer'; export class Bytes { - public fromBase64(value: string): Uint8Array { + public fromBase64(value: string): Uint8Array { return Buffer.from(value, 'base64'); } - public fromBase64url(value: string): Uint8Array { + public fromBase64url(value: string): Uint8Array { return Buffer.from(value, 'base64url'); } - public fromHex(value: string): Uint8Array { + public fromHex(value: string): Uint8Array { return Buffer.from(value, 'hex'); } // TODO(indutny): deprecate it - public fromBinary(value: string): Uint8Array { + public fromBinary(value: string): Uint8Array { return Buffer.from(value, 'binary'); } - public fromString(value: string): Uint8Array { + public fromString(value: string): Uint8Array { return Buffer.from(value); } - public toBase64(data: Uint8Array): string { + public toBase64(data: Uint8Array): string { return Buffer.from(data).toString('base64'); } - public toBase64url(data: Uint8Array): string { + public toBase64url(data: Uint8Array): string { return Buffer.from(data).toString('base64url'); } - public toHex(data: Uint8Array): string { + public toHex(data: Uint8Array): string { return Buffer.from(data).toString('hex'); } // TODO(indutny): deprecate it - public toBinary(data: Uint8Array): string { + public toBinary(data: Uint8Array): string { return Buffer.from(data).toString('binary'); } - public toString(data: Uint8Array): string { + public toString(data: Uint8Array): string { return Buffer.from(data).toString(); } @@ -53,24 +53,28 @@ export class Bytes { return Buffer.byteLength(value); } - public concatenate(list: ReadonlyArray): Uint8Array { + public concatenate( + list: ReadonlyArray> + ): Uint8Array { return Buffer.concat(list); } - public isEmpty(data: Uint8Array | null | undefined): boolean { + public isEmpty(data: Uint8Array | null | undefined): boolean { if (!data) { return true; } return data.length === 0; } - public isNotEmpty(data: Uint8Array | null | undefined): data is Uint8Array { + public isNotEmpty( + data: Uint8Array | null | undefined + ): data is Uint8Array { return !this.isEmpty(data); } public areEqual( - a: Uint8Array | null | undefined, - b: Uint8Array | null | undefined + a: Uint8Array | null | undefined, + b: Uint8Array | null | undefined ): boolean { if (!a || !b) { return !a && !b; @@ -79,7 +83,7 @@ export class Bytes { return Buffer.compare(a, b) === 0; } - public readBigUint64BE(value: Uint8Array): bigint { + public readBigUint64BE(value: Uint8Array): bigint { const buffer = Buffer.from(value); return buffer.readBigUint64BE(); } diff --git a/ts/context/Crypto.node.ts b/ts/context/Crypto.node.ts index 2fda16af75..0494a51d6b 100644 --- a/ts/context/Crypto.node.ts +++ b/ts/context/Crypto.node.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import { Buffer } from 'node:buffer'; -import type { Decipher } from 'node:crypto'; +import type { Decipheriv } from 'node:crypto'; import crypto from 'node:crypto'; import { strictAssert } from '../util/assert.std.js'; @@ -12,14 +12,20 @@ import { CipherType } from '../types/Crypto.std.js'; const AUTH_TAG_SIZE = 16; export class Crypto { - public sign(key: Uint8Array, data: Uint8Array): Uint8Array { + public sign( + key: Uint8Array, + data: Uint8Array + ): Uint8Array { return crypto .createHmac('sha256', Buffer.from(key)) .update(Buffer.from(data)) .digest(); } - public hash(type: HashType, data: Uint8Array): Uint8Array { + public hash( + type: HashType, + data: Uint8Array + ): Uint8Array { return crypto.createHash(type).update(Buffer.from(data)).digest(); } @@ -31,12 +37,12 @@ export class Crypto { iv, aad, }: Readonly<{ - key: Uint8Array; - plaintext: Uint8Array; - iv: Uint8Array; - aad?: Uint8Array; + key: Uint8Array; + plaintext: Uint8Array; + iv: Uint8Array; + aad?: Uint8Array; }> - ): Uint8Array { + ): Uint8Array { if (cipherType === CipherType.AES256GCM) { const gcm = crypto.createCipheriv( cipherType, @@ -76,13 +82,13 @@ export class Crypto { iv, aad, }: Readonly<{ - key: Uint8Array; - ciphertext: Uint8Array; - iv: Uint8Array; - aad?: Uint8Array; + key: Uint8Array; + ciphertext: Uint8Array; + iv: Uint8Array; + aad?: Uint8Array; }> - ): Uint8Array { - let decipher: Decipher; + ): Uint8Array { + let decipher: Decipheriv; let input = Buffer.from(ciphertext); if (cipherType === CipherType.AES256GCM) { const gcm = crypto.createDecipheriv( @@ -123,11 +129,14 @@ export class Crypto { return crypto.randomInt(min, max); } - public getRandomBytes(size: number): Uint8Array { + public getRandomBytes(size: number): Uint8Array { return crypto.randomBytes(size); } - public constantTimeEqual(left: Uint8Array, right: Uint8Array): boolean { + public constantTimeEqual( + left: Uint8Array, + right: Uint8Array + ): boolean { return crypto.timingSafeEqual(Buffer.from(left), Buffer.from(right)); } } diff --git a/ts/groups.preload.ts b/ts/groups.preload.ts index f5faa46931..d79aa7bf00 100644 --- a/ts/groups.preload.ts +++ b/ts/groups.preload.ts @@ -146,9 +146,9 @@ const log = createLogger('groups'); export { joinViaLink } from './groups/joinViaLink.preload.js'; export type GroupFields = { - readonly id: Uint8Array; - readonly secretParams: Uint8Array; - readonly publicParams: Uint8Array; + readonly id: Uint8Array; + readonly secretParams: Uint8Array; + readonly publicParams: Uint8Array; }; const MAX_CACHED_GROUP_FIELDS = 100; @@ -211,7 +211,7 @@ type UpdatesResultType = { }; type UploadedAvatarType = { - data: Uint8Array; + data: Uint8Array; hash: string; key: string; }; @@ -260,7 +260,7 @@ const GROUP_INVITE_LINK_PASSWORD_LENGTH = 16; // Group Links -export function generateGroupInviteLinkPassword(): Uint8Array { +export function generateGroupInviteLinkPassword(): Uint8Array { return getRandomBytes(GROUP_INVITE_LINK_PASSWORD_LENGTH); } @@ -357,7 +357,7 @@ async function uploadAvatar(options: { logId: string; publicParams: string; secretParams: string; - data: Uint8Array; + data: Uint8Array; }): Promise { const { logId, publicParams, secretParams, data } = options; @@ -397,7 +397,7 @@ async function uploadAvatar(options: { function buildGroupTitleBuffer( clientZkGroupCipher: ClientZkGroupCipher, title: string -): Uint8Array { +): Uint8Array { const titleBlobPlaintext = Proto.GroupAttributeBlob.encode({ content: { title, @@ -416,7 +416,7 @@ function buildGroupTitleBuffer( function buildGroupDescriptionBuffer( clientZkGroupCipher: ClientZkGroupCipher, description: string -): Uint8Array { +): Uint8Array { const attrsBlobPlaintext = Proto.GroupAttributeBlob.encode({ content: { descriptionText: description, @@ -474,7 +474,7 @@ function buildGroupProto( const publicKey = Bytes.fromBase64(publicParams); const version = attributes.revision || 0; - let title: Uint8Array | null = null; + let title: Uint8Array | null = null; if (attributes.name) { title = buildGroupTitleBuffer(clientZkGroupCipher, attributes.name); } @@ -484,7 +484,7 @@ function buildGroupProto( avatarUrl = attributes.avatarUrl; } - let disappearingMessagesTimer: Uint8Array | null = null; + let disappearingMessagesTimer: Uint8Array | null = null; if (attributes.expireTimer) { const timerBlobPlaintext = Proto.GroupAttributeBlob.encode({ content: { @@ -737,7 +737,7 @@ export async function buildUpdateAttributesChange( 'id' | 'revision' | 'publicParams' | 'secretParams' >, attributes: Readonly<{ - avatar?: undefined | Uint8Array; + avatar?: undefined | Uint8Array; description?: string; title?: string; }> @@ -1142,7 +1142,7 @@ export function buildAddMember({ return member.serviceId === serviceId; }); - let deletedUserId: Uint8Array | null = null; + let deletedUserId: Uint8Array | null = null; if (doesMemberNeedUnban) { const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); const userIdCipherText = encryptServiceId(clientZkGroupCipher, serviceId); @@ -1333,8 +1333,8 @@ export function buildModifyMemberLabelChange({ const clientZkGroupCipher = getClientZkGroupCipher(group.secretParams); const userIdCipherText = encryptServiceId(clientZkGroupCipher, serviceId); - let encryptedLabelEmoji: Uint8Array | null = null; - let encryptedLabelString: Uint8Array | null = null; + let encryptedLabelEmoji: Uint8Array | null = null; + let encryptedLabelString: Uint8Array | null = null; if (labelEmoji) { const labelEmojiBytes = Bytes.fromString(labelEmoji); @@ -1705,7 +1705,9 @@ export function idForLogging(groupId: string | undefined): string { return `groupv2(${groupId})`; } -export function deriveGroupFields(masterKey: Uint8Array): GroupFields { +export function deriveGroupFields( + masterKey: Uint8Array +): GroupFields { if (masterKey.length !== MASTER_KEY_LENGTH) { throw new Error( `deriveGroupFields: masterKey had length ${masterKey.length}, ` + @@ -1792,7 +1794,7 @@ export async function fetchMembershipProof({ export async function createGroupV2( options: Readonly<{ name: string; - avatar: undefined | Uint8Array; + avatar: undefined | Uint8Array; expireTimer: undefined | DurationInSeconds; conversationIds: ReadonlyArray; avatars?: ReadonlyArray; @@ -2450,7 +2452,10 @@ export async function initiateMigrationToGroupV2( avatarUrl: avatarAttribute?.url, }); - let groupSendEndorsementsResponse: Uint8Array | null | undefined; + let groupSendEndorsementsResponse: + | Uint8Array + | null + | undefined; try { const groupResponse = await makeRequestWithCredentials({ logId: `initiateMigrationToGroupV2/${logId}`, @@ -2790,7 +2795,7 @@ export async function respondToGroupV2Migration({ }; let firstGroupState: Proto.Group.Params | null | undefined; - let groupSendEndorsementsResponse: Uint8Array | null | undefined; + let groupSendEndorsementsResponse: Uint8Array | null | undefined; try { const fetchedAt = Date.now(); @@ -4079,7 +4084,7 @@ async function updateGroupViaLogs({ } let response: GroupLogResponseType; - let groupSendEndorsementsResponse: Uint8Array | null = null; + let groupSendEndorsementsResponse: Uint8Array | null = null; const changes: Array = []; do { const fetchedAt = Date.now(); @@ -5155,7 +5160,7 @@ function profileKeysToMap(items: ReadonlyArray) { } type GroupChangeMemberType = { - profileKey: Uint8Array; + profileKey: Uint8Array; aci: AciString; }; type GroupApplyResultType = { @@ -5776,7 +5781,7 @@ async function applyGroupChange({ export async function decryptGroupAvatar( avatarKey: string, secretParamsBase64: string -): Promise { +): Promise> { const ciphertext = await getGroupAvatar(avatarKey); const clientZkGroupCipher = getClientZkGroupCipher(secretParamsBase64); const plaintext = decryptGroupBlob(clientZkGroupCipher, ciphertext); @@ -5842,7 +5847,7 @@ export async function applyNewAvatar( return result; } - const data: Uint8Array = await decryptGroupAvatar( + const data: Uint8Array = await decryptGroupAvatar( avatarUrlToUse, attributes.secretParams ); @@ -5885,7 +5890,7 @@ export async function applyNewAvatar( function profileKeyHasChanged( userId: ServiceIdString, - newProfileKey: Uint8Array + newProfileKey: Uint8Array ) { const conversation = window.ConversationController.get(userId); if (!conversation) { @@ -6242,7 +6247,7 @@ function isValidLinkAccess( ); } -function isValidProfileKey(buffer?: Uint8Array): boolean { +function isValidProfileKey(buffer?: Uint8Array): boolean { return Boolean(buffer && buffer.length === 32); } @@ -6283,7 +6288,7 @@ type DecryptedGroupChangeActions = { }>; modifyMemberLabels?: ReadonlyArray; modifyMemberProfileKeys?: ReadonlyArray<{ - profileKey: Uint8Array; + profileKey: Uint8Array; aci: AciString; }>; addMembersPendingProfileKey?: ReadonlyArray<{ @@ -6294,11 +6299,11 @@ type DecryptedGroupChangeActions = { deletedUserId: ServiceIdString; }>; promoteMembersPendingProfileKey?: ReadonlyArray<{ - profileKey: Uint8Array; + profileKey: Uint8Array; aci: AciString; }>; promoteMembersPendingPniAciProfileKey?: ReadonlyArray<{ - profileKey: Uint8Array; + profileKey: Uint8Array; aci: AciString; pni: PniString; }>; @@ -6505,7 +6510,7 @@ function decryptGroupChange( ); let aci: AciString; - let profileKey: Uint8Array; + let profileKey: Uint8Array; try { aci = decryptAci(clientZkGroupCipher, userId); @@ -6630,7 +6635,7 @@ function decryptGroupChange( ); let aci: AciString; - let profileKey: Uint8Array; + let profileKey: Uint8Array; try { aci = decryptAci(clientZkGroupCipher, userId); @@ -6683,7 +6688,7 @@ function decryptGroupChange( let aci: AciString; let pni: PniString; - let profileKey: Uint8Array; + let profileKey: Uint8Array; try { aci = decryptAci(clientZkGroupCipher, promotePendingMember.userId); pni = decryptPni(clientZkGroupCipher, promotePendingMember.pni); @@ -6997,7 +7002,7 @@ function decryptGroupChange( } export function decryptGroupTitle( - title: Uint8Array | undefined, + title: Uint8Array | undefined, secretParams: string ): string | undefined { const clientZkGroupCipher = getClientZkGroupCipher(secretParams); @@ -7012,7 +7017,7 @@ export function decryptGroupTitle( } export function decryptGroupDescription( - description: Uint8Array | undefined, + description: Uint8Array | undefined, secretParams: string ): string | undefined { const clientZkGroupCipher = getClientZkGroupCipher(secretParams); @@ -7281,7 +7286,7 @@ function decryptGroupState( type DecryptedMember = Readonly<{ userId: AciString; - profileKey: Uint8Array; + profileKey: Uint8Array; role: MemberRole; joinedAtVersion: number; labelEmoji?: string; @@ -7457,7 +7462,7 @@ function decryptMemberPendingProfileKey( type DecryptedMemberPendingAdminApproval = { userId: AciString; - profileKey?: Uint8Array; + profileKey?: Uint8Array; timestamp: number; }; @@ -7489,7 +7494,7 @@ function decryptMemberPendingAdminApproval( } // profileKey - let decryptedProfileKey: Uint8Array | undefined; + let decryptedProfileKey: Uint8Array | undefined; if (Bytes.isNotEmpty(profileKey)) { try { decryptedProfileKey = decryptProfileKey( @@ -7522,7 +7527,7 @@ function decryptMemberPendingAdminApproval( export function getMembershipList( conversationId: string -): Array<{ aci: AciString; uuidCiphertext: Uint8Array }> { +): Array<{ aci: AciString; uuidCiphertext: Uint8Array }> { const conversation = window.ConversationController.get(conversationId); if (!conversation) { throw new Error('getMembershipList: cannot find conversation'); diff --git a/ts/heic-convert.d.ts b/ts/heic-convert.d.ts index d761222cbc..1f094bcf72 100644 --- a/ts/heic-convert.d.ts +++ b/ts/heic-convert.d.ts @@ -3,8 +3,8 @@ declare module 'heic-convert' { export default function heicConvert(options: { - buffer: Uint8Array; + buffer: Uint8Array; format: string; quality: number; - }): Promise; + }): Promise>; } diff --git a/ts/jobs/AttachmentBackupManager.preload.ts b/ts/jobs/AttachmentBackupManager.preload.ts index 6e21b906d8..4f04cbeb0a 100644 --- a/ts/jobs/AttachmentBackupManager.preload.ts +++ b/ts/jobs/AttachmentBackupManager.preload.ts @@ -529,7 +529,7 @@ async function uploadThumbnailToTransitTier({ logPrefix, dependencies, }: { - data: Uint8Array; + data: Uint8Array; keys: string; logPrefix: string; dependencies: { @@ -569,8 +569,8 @@ async function copyToBackupTier({ cdnKey: string; size: number; mediaId: string; - macKey: Uint8Array; - aesKey: Uint8Array; + macKey: Uint8Array; + aesKey: Uint8Array; dependencies: { backupMediaBatch?: typeof doBackupMediaBatch; backupsService: BackupsService; diff --git a/ts/jobs/helpers/sendDeleteForEveryone.preload.ts b/ts/jobs/helpers/sendDeleteForEveryone.preload.ts index 9d9d74b2f2..7d157b8bf9 100644 --- a/ts/jobs/helpers/sendDeleteForEveryone.preload.ts +++ b/ts/jobs/helpers/sendDeleteForEveryone.preload.ts @@ -136,7 +136,7 @@ export async function sendDeleteForEveryone( ` for message ${targetTimestamp}, isStory=${story}` ); - let profileKey: Uint8Array | undefined; + let profileKey: Uint8Array | undefined; if (conversation.get('profileSharing')) { profileKey = await ourProfileKeyService.get(); } diff --git a/ts/jobs/helpers/sendDirectExpirationTimerUpdate.preload.ts b/ts/jobs/helpers/sendDirectExpirationTimerUpdate.preload.ts index a0cc8fe946..64d0f19d70 100644 --- a/ts/jobs/helpers/sendDirectExpirationTimerUpdate.preload.ts +++ b/ts/jobs/helpers/sendDirectExpirationTimerUpdate.preload.ts @@ -69,7 +69,7 @@ export async function sendDirectExpirationTimerUpdate( const { expireTimer } = data; const sendOptions = await getSendOptions(conversation.attributes); - let profileKey: Uint8Array | undefined; + let profileKey: Uint8Array | undefined; if (conversation.get('profileSharing')) { profileKey = await ourProfileKeyService.get(); } diff --git a/ts/jobs/helpers/sendGroupUpdate.preload.ts b/ts/jobs/helpers/sendGroupUpdate.preload.ts index 9be62ab550..991d835e3d 100644 --- a/ts/jobs/helpers/sendGroupUpdate.preload.ts +++ b/ts/jobs/helpers/sendGroupUpdate.preload.ts @@ -78,7 +78,7 @@ export async function sendGroupUpdate( ? Bytes.fromBase64(groupChangeBase64) : undefined; - let profileKey: Uint8Array | undefined; + let profileKey: Uint8Array | undefined; if (conversation.get('profileSharing')) { profileKey = await ourProfileKeyService.get(); } diff --git a/ts/jobs/helpers/sendNormalMessage.preload.ts b/ts/jobs/helpers/sendNormalMessage.preload.ts index 6dc84b0df0..29e5753ac1 100644 --- a/ts/jobs/helpers/sendNormalMessage.preload.ts +++ b/ts/jobs/helpers/sendNormalMessage.preload.ts @@ -180,7 +180,7 @@ export async function sendNormalMessage( return; } - let profileKey: Uint8Array | undefined; + let profileKey: Uint8Array | undefined; if (conversation.get('profileSharing')) { profileKey = await ourProfileKeyService.get(); } diff --git a/ts/linkPreviews/linkPreviewFetch.preload.ts b/ts/linkPreviews/linkPreviewFetch.preload.ts index e2bfd5bfe5..d22a7ee0b2 100644 --- a/ts/linkPreviews/linkPreviewFetch.preload.ts +++ b/ts/linkPreviews/linkPreviewFetch.preload.ts @@ -69,7 +69,7 @@ export type LinkPreviewMetadata = { }; export type LinkPreviewImage = { - data: Uint8Array; + data: Uint8Array; contentType: MIMEType; }; @@ -228,7 +228,7 @@ const emptyHtmlDocument = (): HTMLDocument => // (This fallback could, perhaps, be smarter based on user locale.) // [0]: https://www.w3.org/International/questions/qa-html-encoding-declarations.en const parseHtmlBytes = ( - bytes: Readonly, + bytes: Readonly>, httpCharset: string | null ): HTMLDocument => { const hasBom = bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf; @@ -288,7 +288,7 @@ const parseHtmlBytes = ( }; const getHtmlDocument = async ( - body: AsyncIterable, + body: AsyncIterable>, httpCharset: string | null, abortSignal: AbortSignal, logger: Pick = log @@ -522,6 +522,7 @@ export async function fetchLinkPreviewMetadata( } const document = await getHtmlDocument( + // @ts-expect-error ReadableStream should actually be giving us ArrayBuffers response.body, contentType.charset, abortSignal, @@ -614,7 +615,7 @@ async function processImageResponse( return null; } - let data: Uint8Array; + let data: Uint8Array; try { data = await response.buffer(); } catch (err) { diff --git a/ts/logging/uploadDebugLog.node.ts b/ts/logging/uploadDebugLog.node.ts index e116ebe768..b4c4895416 100644 --- a/ts/logging/uploadDebugLog.node.ts +++ b/ts/logging/uploadDebugLog.node.ts @@ -41,7 +41,7 @@ const parseTokenBody = ( }; export type UploadOptionsType = Readonly<{ - content: string | Buffer | Uint8Array; + content: string | Buffer | Uint8Array; appVersion: string; logger: LoggerType; extension?: string; diff --git a/ts/messageModifiers/AttachmentDownloads.preload.ts b/ts/messageModifiers/AttachmentDownloads.preload.ts index 45c1c08b08..aeb77d534c 100644 --- a/ts/messageModifiers/AttachmentDownloads.preload.ts +++ b/ts/messageModifiers/AttachmentDownloads.preload.ts @@ -90,7 +90,7 @@ export async function addAttachmentToMessage( if (type === 'long-message') { let handledAnywhere = false; - let attachmentData: Uint8Array | undefined; + let attachmentData: Uint8Array | undefined; try { if (attachment.path) { diff --git a/ts/messages/send.preload.ts b/ts/messages/send.preload.ts index de286950d4..dc441f049e 100644 --- a/ts/messages/send.preload.ts +++ b/ts/messages/send.preload.ts @@ -276,7 +276,7 @@ export async function sendSyncMessageOnly( saveErrors, }: { targetTimestamp: number; - dataMessage: Uint8Array; + dataMessage: Uint8Array; saveErrors?: (errors: Array) => void; } ): Promise { diff --git a/ts/model-types.d.ts b/ts/model-types.d.ts index 551b64a844..568a4bf74f 100644 --- a/ts/model-types.d.ts +++ b/ts/model-types.d.ts @@ -191,7 +191,7 @@ export type MessageAttributesType = { callId?: string; canReplyToStory?: boolean; changedId?: string; - dataMessage?: Uint8Array | null; + dataMessage?: Uint8Array | null; decrypted_at?: number; deletedForEveryone?: boolean; deletedForEveryoneByAdminAci?: AciString; diff --git a/ts/models/conversations.preload.ts b/ts/models/conversations.preload.ts index d15596952e..21738ea045 100644 --- a/ts/models/conversations.preload.ts +++ b/ts/models/conversations.preload.ts @@ -1370,7 +1370,7 @@ export class ConversationModel { getGroupV2Info( options: Readonly< - { groupChange?: Uint8Array } & ( + { groupChange?: Uint8Array } & ( | { includePendingMembers?: boolean; extraConversationsForSend?: ReadonlyArray; @@ -1395,7 +1395,7 @@ export class ConversationModel { }; } - getGroupIdBuffer(): Uint8Array | undefined { + getGroupIdBuffer(): Uint8Array | undefined { const groupIdString = this.get('groupId'); if (!groupIdString) { @@ -2207,7 +2207,7 @@ export class ConversationModel { this.captureChange('updateServiceId'); } - trackPreviousIdentityKey(publicKey: Uint8Array): void { + trackPreviousIdentityKey(publicKey: Uint8Array): void { const logId = `trackPreviousIdentityKey/${this.idForLogging()}`; const identityKey = Bytes.toBase64(publicKey); @@ -2314,7 +2314,7 @@ export class ConversationModel { } } - async updateReportingToken(token?: Uint8Array): Promise { + async updateReportingToken(token?: Uint8Array): Promise { const oldValue = this.get('reportingToken'); const newValue = token ? Bytes.toBase64(token) : undefined; @@ -5094,7 +5094,7 @@ export class ConversationModel { async setEncryptedProfileName( encryptedName: string, - decryptionKey: Uint8Array + decryptionKey: Uint8Array ): Promise { if (!encryptedName) { return; @@ -5131,7 +5131,7 @@ export class ConversationModel { async setAndMaybeFetchProfileAvatar(options: { avatarUrl: undefined | null | string; - decryptionKey?: Uint8Array | null | undefined; + decryptionKey?: Uint8Array | null | undefined; forceFetch?: boolean; }): Promise { const { avatarUrl, decryptionKey, forceFetch } = options; @@ -5210,7 +5210,7 @@ export class ConversationModel { return false; } - let derivedAccessKey: Uint8Array; + let derivedAccessKey: Uint8Array; try { derivedAccessKey = deriveAccessKeyFromProfileKey( Bytes.fromBase64(profileKey) diff --git a/ts/scripts/better-blockmap.d.ts b/ts/scripts/better-blockmap.d.ts index 2d4ac52926..83c527b348 100644 --- a/ts/scripts/better-blockmap.d.ts +++ b/ts/scripts/better-blockmap.d.ts @@ -10,6 +10,6 @@ declare module 'better-blockmap' { export class BlockMap extends Writable { constructor(options?: BlockMapOptions); - compress(compression?: 'gzip' | 'deflate'): Buffer; + compress(compression?: 'gzip' | 'deflate'): Buffer; } } diff --git a/ts/scripts/gen-nsis-script.node.ts b/ts/scripts/gen-nsis-script.node.ts index 8dbc806d3f..a27fe9ab34 100644 --- a/ts/scripts/gen-nsis-script.node.ts +++ b/ts/scripts/gen-nsis-script.node.ts @@ -59,7 +59,7 @@ for (const lang of REQUIRED_LANGUAGES) { if (lang === 'zh_TW') { fallbacks.unshift('zh-Hant'); } - let json: Buffer | undefined; + let json: Buffer | undefined; for (const f of fallbacks) { try { json = fs.readFileSync(path.join(LOCALES_DIR, f, 'messages.json')); diff --git a/ts/scripts/generate-tray-icons.node.ts b/ts/scripts/generate-tray-icons.node.ts index eb21314b4c..3435ba249d 100644 --- a/ts/scripts/generate-tray-icons.node.ts +++ b/ts/scripts/generate-tray-icons.node.ts @@ -132,7 +132,7 @@ function trayIconValueToText( async function generateTrayIconImage( request: TrayIconImageRequest -): Promise { +): Promise> { const variant = Variants[request.size]; if (variant == null) { throw new TypeError(`Invalid variant size (${request.size})`); diff --git a/ts/services/backups/crypto.preload.ts b/ts/services/backups/crypto.preload.ts index 18884f72ca..40d89155cf 100644 --- a/ts/services/backups/crypto.preload.ts +++ b/ts/services/backups/crypto.preload.ts @@ -68,8 +68,8 @@ const getMemoizedKeyMaterial = memoizee( ); export type BackupKeyMaterialType = Readonly<{ - macKey: Uint8Array; - aesKey: Uint8Array; + macKey: Uint8Array; + aesKey: Uint8Array; }>; export function getKeyMaterial( @@ -80,8 +80,8 @@ export function getKeyMaterial( } export type BackupMediaKeyMaterialType = Readonly<{ - macKey: Uint8Array; - aesKey: Uint8Array; + macKey: Uint8Array; + aesKey: Uint8Array; }>; const BACKUP_MEDIA_AES_KEY_LEN = 32; @@ -89,7 +89,7 @@ const BACKUP_MEDIA_MAC_KEY_LEN = 32; export function deriveBackupMediaKeyMaterial( mediaRootKey: BackupKey, - mediaId: Uint8Array + mediaId: Uint8Array ): BackupMediaKeyMaterialType { if (!mediaId.length) { throw new Error('deriveBackupMediaKeyMaterial: mediaId missing'); @@ -108,7 +108,7 @@ export function deriveBackupMediaKeyMaterial( export function deriveBackupThumbnailTransitKeyMaterial( mediaRootKey: BackupKey, - mediaId: Uint8Array + mediaId: Uint8Array ): BackupMediaKeyMaterialType { if (!mediaId.length) { throw new Error('deriveBackupThumbnailTransitKeyMaterial: mediaId missing'); @@ -125,11 +125,11 @@ export function deriveBackupThumbnailTransitKeyMaterial( }; } -export function getBackupId(): Uint8Array { +export function getBackupId(): Uint8Array { const aci = itemStorage.user.getCheckedAci(); return getBackupKey().deriveBackupId(toAciObject(aci)); } -export function getLocalBackupMetadataKey(): Uint8Array { +export function getLocalBackupMetadataKey(): Uint8Array { return getBackupKey().deriveLocalBackupMetadataKey(); } diff --git a/ts/services/backups/export.preload.ts b/ts/services/backups/export.preload.ts index 9199acc010..d95b2cbd64 100644 --- a/ts/services/backups/export.preload.ts +++ b/ts/services/backups/export.preload.ts @@ -211,7 +211,7 @@ const BACKUP_QUOTE_BODY_LIMIT = 2048; type ToRecipientOptionsType = Readonly<{ identityKeysById: ReadonlyMap; - keyTransparencyData: Uint8Array | undefined; + keyTransparencyData: Uint8Array | undefined; }>; type GetRecipientIdOptionsType = @@ -300,7 +300,7 @@ export class BackupExportStream extends Readable { #attachmentBackupJobs: Array< CoreAttachmentBackupJobType | CoreAttachmentLocalBackupJobType > = []; - #buffers = new Array(); + #buffers = new Array>(); #nextRecipientId = 1n; #flushResolve: (() => void) | undefined; #jsonExporter: BackupJsonExporter | undefined; @@ -449,7 +449,7 @@ export class BackupExportStream extends Readable { const skippedConversationIds = new Set(); for (const { attributes } of window.ConversationController.getAll()) { - let keyTransparencyData: Uint8Array | undefined; + let keyTransparencyData: Uint8Array | undefined; if ( isDirectConversation(attributes) && isAciString(attributes.serviceId) && @@ -563,6 +563,8 @@ export class BackupExportStream extends Readable { const id = this.#getNextRecipientId(); const rootKey = CallLinkRootKey.parse(rootKeyString); + // @ts-expect-error needs ringrtc update + const rootKeyBytes: Uint8Array = rootKey.bytes; const roomId = getRoomIdFromRootKey(rootKey); this.#roomIdToRecipientId.set(roomId, id); @@ -572,7 +574,7 @@ export class BackupExportStream extends Readable { id, destination: { callLink: { - rootKey: rootKey.bytes, + rootKey: rootKeyBytes, adminKey: adminKey ? toAdminKeyBytes(adminKey) : null, name, restrictions: toCallLinkRestrictionsProto(restrictions), @@ -2015,11 +2017,11 @@ export class BackupExportStream extends Readable { }; } - #aciToBytes(aci: AciString | string): Uint8Array { + #aciToBytes(aci: AciString | string): Uint8Array { return Aci.parseFromServiceIdString(aci).getRawUuidBytes(); } - #aciToBytesOrNull(aci: AciString | string): Uint8Array | null { + #aciToBytesOrNull(aci: AciString | string): Uint8Array | null { if (isAciString(aci)) { return Aci.parseFromServiceIdString(aci).getRawUuidBytes(); } @@ -2027,13 +2029,13 @@ export class BackupExportStream extends Readable { } /** For fields explicitly marked as PNI (validator will expect 16 bytes) */ - #pniToRawBytes(pni: PniString | string): Uint8Array { + #pniToRawBytes(pni: PniString | string): Uint8Array { return Pni.parseFromServiceIdString(pni).getRawUuidBytes(); } /** For fields that can accept either ACI or PNI bytes */ - #serviceIdToBytes(serviceId: ServiceIdString): Uint8Array { - return ServiceId.parseFromServiceIdString(serviceId).getServiceIdBinary(); + #serviceIdToBytes(serviceId: ServiceIdString): Uint8Array { + return ServiceId.parseFromServiceIdString(serviceId).getRawUuidBytes(); } async #toChatItemFromNonBubble( @@ -2209,7 +2211,7 @@ export class BackupExportStream extends Readable { strictAssert(selfId, 'self must exist'); patch.authorId = selfId; - let updaterAci: Uint8Array | null = null; + let updaterAci: Uint8Array | null = null; if (sourceServiceId && Aci.parseFromServiceIdString(sourceServiceId)) { updaterAci = uuidToBytes(sourceServiceId); } diff --git a/ts/services/backups/import.preload.ts b/ts/services/backups/import.preload.ts index c5a79585a1..713da3ed47 100644 --- a/ts/services/backups/import.preload.ts +++ b/ts/services/backups/import.preload.ts @@ -303,7 +303,7 @@ export class BackupImportStream extends Writable { } override async _write( - data: Buffer, + data: Buffer, _enc: BufferEncoding, done: (error?: Error) => void ): Promise { @@ -4104,7 +4104,7 @@ export class BackupImportStream extends Writable { }; } - let wallpaperPhotoPointer: Uint8Array | undefined; + let wallpaperPhotoPointer: Uint8Array | undefined; let wallpaperPreset: number | undefined; const dimWallpaperInDarkMode = dropNull(chatStyle.dimWallpaperInDarkMode); diff --git a/ts/services/backups/index.preload.ts b/ts/services/backups/index.preload.ts index 7e04c2fe35..e116634a76 100644 --- a/ts/services/backups/index.preload.ts +++ b/ts/services/backups/index.preload.ts @@ -145,7 +145,7 @@ export type DownloadOptionsType = Readonly<{ type DoDownloadOptionsType = Readonly<{ downloadPath: string; - ephemeralKey?: Uint8Array; + ephemeralKey?: Uint8Array; onProgress?: ( backupStep: InstallScreenBackupStep, currentBytes: number, @@ -597,10 +597,10 @@ export class BackupsService { // Test harness public async exportBackupData( options: BackupExportOptions - ): Promise<{ data: Uint8Array } & ExportResultType> { + ): Promise<{ data: Uint8Array } & ExportResultType> { const sink = new PassThrough(); - const chunks = new Array(); + const chunks = new Array>(); sink.on('data', chunk => chunks.push(chunk)); const result = await this.#exportBackup(sink, options); @@ -850,7 +850,7 @@ export class BackupsService { // First pass - don't decrypt, only verify mac let hmac = createHmac(HashType.size256, macKey); - let theirMac: Uint8Array | undefined; + let theirMac: Uint8Array | undefined; let totalBytes = 0; const sink = new PassThrough(); diff --git a/ts/services/backups/types.std.ts b/ts/services/backups/types.std.ts index 8dcb6de1f2..607e5c949b 100644 --- a/ts/services/backups/types.std.ts +++ b/ts/services/backups/types.std.ts @@ -50,12 +50,12 @@ export type BackupImportOptions = ( localBackupSnapshotDir: string; } ) & { - ephemeralKey?: Uint8Array; + ephemeralKey?: Uint8Array; onProgress?: OnProgressCallback; }; export type LocalChatStyle = Readonly<{ - wallpaperPhotoPointer: Uint8Array | undefined; + wallpaperPhotoPointer: Uint8Array | undefined; wallpaperPreset: number | undefined; color: ConversationColorType | undefined; customColorId: string | undefined; diff --git a/ts/services/backups/util/FileStream.node.ts b/ts/services/backups/util/FileStream.node.ts index f642e034b3..ed8c4d61c4 100644 --- a/ts/services/backups/util/FileStream.node.ts +++ b/ts/services/backups/util/FileStream.node.ts @@ -20,7 +20,7 @@ export class FileStream extends InputStream { await this.#file?.close(); } - async read(amount: number): Promise { + async read(amount: number): Promise> { const file = await this.#lazyOpen(); if (this.#buffer.length < amount) { this.#buffer = Buffer.alloc(amount); diff --git a/ts/services/backups/util/mediaId.preload.ts b/ts/services/backups/util/mediaId.preload.ts index e4826f6048..c4fdae1581 100644 --- a/ts/services/backups/util/mediaId.preload.ts +++ b/ts/services/backups/util/mediaId.preload.ts @@ -12,7 +12,7 @@ import { sha256 } from '../../../Crypto.node.js'; export function getMediaIdFromMediaName(mediaName: string): { string: string; - bytes: Uint8Array; + bytes: Uint8Array; } { const mediaIdBytes = getBackupMediaRootKey().deriveMediaId(mediaName); return { @@ -23,7 +23,7 @@ export function getMediaIdFromMediaName(mediaName: string): { export function getMediaIdForAttachment(attachment: BackupableAttachmentType): { string: string; - bytes: Uint8Array; + bytes: Uint8Array; } { const mediaName = getMediaNameForAttachment(attachment); return getMediaIdFromMediaName(mediaName); @@ -33,7 +33,7 @@ export function getMediaIdForAttachmentThumbnail( attachment: BackupableAttachmentType ): { string: string; - bytes: Uint8Array; + bytes: Uint8Array; } { const mediaName = getMediaNameForAttachmentThumbnail( getMediaNameForAttachment(attachment) @@ -54,8 +54,8 @@ export function getMediaName({ plaintextHash, key, }: { - plaintextHash: Uint8Array; - key: Uint8Array; + plaintextHash: Uint8Array; + key: Uint8Array; }): string { return Bytes.toHex(Bytes.concatenate([plaintextHash, key])); } @@ -73,8 +73,8 @@ export function getLocalBackupFileName({ plaintextHash, localKey, }: { - plaintextHash: Uint8Array; - localKey: Uint8Array; + plaintextHash: Uint8Array; + localKey: Uint8Array; }): string { return Bytes.toHex(sha256(Bytes.concatenate([plaintextHash, localKey]))); } @@ -85,7 +85,9 @@ export function getMediaNameForAttachmentThumbnail( return `${fullsizeMediaName}_thumbnail`; } -export function getBytesFromMediaIdString(mediaId: string): Uint8Array { +export function getBytesFromMediaIdString( + mediaId: string +): Uint8Array { return Bytes.fromBase64url(mediaId); } diff --git a/ts/services/calling.preload.ts b/ts/services/calling.preload.ts index 7ac97bd6e8..0abfdb7ae3 100644 --- a/ts/services/calling.preload.ts +++ b/ts/services/calling.preload.ts @@ -622,10 +622,14 @@ export class CallingClass { RingRTC.handleRejectedIncomingCallRequest = this.#handleRejectedIncomingCallRequest.bind(this); RingRTC.handleLogMessage = this.#handleLogMessage.bind(this); + // @ts-expect-error needs ringrtc update RingRTC.handleSendHttpRequest = this.#handleSendHttpRequest.bind(this); + // @ts-expect-error needs ringrtc update RingRTC.handleSendCallMessage = this.#handleSendCallMessage.bind(this); + // @ts-expect-error needs ringrtc update RingRTC.handleSendCallMessageToGroup = this.#handleSendCallMessageToGroup.bind(this); + // @ts-expect-error needs ringrtc update RingRTC.handleGroupCallRingUpdate = this.#handleGroupCallRingUpdate.bind(this); @@ -857,15 +861,22 @@ export class CallingClass { ); const rootKey = CallLinkRootKey.generate(); + // @ts-expect-error needs ringrtc update + const rootKeyBytes: Uint8Array = rootKey.bytes; const roomId = rootKey.deriveRoomId(); - const roomIdHex = Bytes.toHex(roomId); + // @ts-expect-error needs ringrtc update + const roomIdBytes: Uint8Array = roomId; + const roomIdHex = Bytes.toHex(roomIdBytes); const logId = `createCallLink(${roomIdHex})`; log.info(`${logId}: Creating call link`); const adminKey = CallLinkRootKey.generateAdminPassKey(); + // @ts-expect-error needs ringrtc update + const adminKeyBytes: Uint8Array = adminKey; - const context = CreateCallLinkCredentialRequestContext.forRoomId(roomId); + const context = + CreateCallLinkCredentialRequestContext.forRoomId(roomIdBytes); const requestBase64 = Bytes.toBase64(context.getRequest().serialize()); const { credential: credentialBase64 } = @@ -884,10 +895,10 @@ export class CallingClass { genericServerPublicParams ); - const secretParams = CallLinkSecretParams.deriveFromRootKey(rootKey.bytes); + const secretParams = CallLinkSecretParams.deriveFromRootKey(rootKeyBytes); const credentialPresentation = credential - .present(roomId, userId, genericServerPublicParams, secretParams) + .present(roomIdBytes, userId, genericServerPublicParams, secretParams) .serialize(); const serializedPublicParams = secretParams.getPublicParams().serialize(); @@ -913,7 +924,7 @@ export class CallingClass { const callLink: CallLinkType = { roomId: roomIdHex, rootKey: maybeUpdatedRootKey, - adminKey: Bytes.toBase64(adminKey), + adminKey: Bytes.toBase64(adminKeyBytes), storageNeedsSync: true, ...state, }; @@ -1078,7 +1089,7 @@ export class CallingClass { preferLocalVideo = true, }: Readonly<{ callLinkRootKey: CallLinkRootKey; - adminPasskey: Uint8Array | undefined; + adminPasskey: Uint8Array | undefined; hasLocalAudio: boolean; preferLocalVideo?: boolean; }>): Promise< @@ -1468,8 +1479,8 @@ export class CallingClass { roomId: string; authCredentialPresentation: CallLinkAuthCredentialPresentation; callLinkRootKey: CallLinkRootKey; - adminPasskey: Uint8Array | undefined; - endorsementsPublicKey: Uint8Array; + adminPasskey: Uint8Array | undefined; + endorsementsPublicKey: Uint8Array; }): GroupCall { const existing = this.#getGroupCall(roomId); if (existing) { @@ -1867,7 +1878,13 @@ export class CallingClass { const ourAci = itemStorage.user.getCheckedAci(); const reason = `sendProfileKeysForAdhocCall(${roomId})`; peekInfo.devices.forEach(async device => { - const aci = device.userId ? this.#formatUserId(device.userId) : null; + let aci: AciString | null = null; + + if (device.userId) { + // @ts-expect-error needs ringrtc update + const userIdBytes: Uint8Array = device.userId; + aci = this.#formatUserId(userIdBytes); + } if ( !aci || aci === ourAci || @@ -2137,7 +2154,7 @@ export class CallingClass { } } - #formatUserId(userId: Uint8Array): AciString | null { + #formatUserId(userId: Uint8Array): AciString | null { const uuid = bytesToUuid(userId); if (uuid && isAciString(uuid)) { return uuid; @@ -2152,11 +2169,20 @@ export class CallingClass { public formatGroupCallPeekInfoForRedux( peekInfo: PeekInfo ): GroupCallPeekInfoType { - const creatorAci = peekInfo.creator && bytesToUuid(peekInfo.creator); + let creatorAci: string | undefined; + + if (peekInfo.creator) { + // @ts-expect-error needs ringrtc update + const creatorBytes: Uint8Array = peekInfo.creator; + creatorAci = bytesToUuid(creatorBytes); + } + return { acis: peekInfo.devices.map(peekDeviceInfo => { if (peekDeviceInfo.userId) { - const uuid = this.#formatUserId(peekDeviceInfo.userId); + // @ts-expect-error needs ringrtc update + const userIdBytes: Uint8Array = peekDeviceInfo.userId; + const uuid = this.#formatUserId(userIdBytes); if (uuid) { return uuid; } @@ -2171,7 +2197,11 @@ export class CallingClass { ); }), pendingAcis: compact( - peekInfo.pendingUsers.map(userId => this.#formatUserId(userId)) + peekInfo.pendingUsers.map(userId => { + // @ts-expect-error needs ringrtc update; + const userIdBytes: Uint8Array = userId; + return this.#formatUserId(userIdBytes); + }) ), creatorAci: creatorAci !== undefined @@ -2217,7 +2247,9 @@ export class CallingClass { ? this.formatGroupCallPeekInfoForRedux(peekInfo) : undefined, remoteParticipants: remoteDeviceStates.map(remoteDeviceState => { - let aci = bytesToUuid(remoteDeviceState.userId); + // @ts-expect-error needs ringrtc update + const userIdBytes: Uint8Array = remoteDeviceState.userId; + let aci = bytesToUuid(userIdBytes); if (!aci) { log.error( 'formatGroupCallForRedux: could not convert remote participant UUID Uint8Array to string; using fallback UUID' @@ -3225,8 +3257,8 @@ export class CallingClass { } async #handleSendCallMessage( - recipient: Uint8Array, - data: Uint8Array, + recipient: Uint8Array, + data: Uint8Array, urgency: CallMessageUrgency ): Promise { const userId = bytesToUuid(recipient); @@ -3242,10 +3274,10 @@ export class CallingClass { // Used to send a variety of group call messages, including the initial call message async #handleSendCallMessageToGroup( - groupIdBytes: Uint8Array, - data: Uint8Array, + groupIdBytes: Uint8Array, + data: Uint8Array, urgency: CallMessageUrgency, - overrideRecipients: Array = [] + overrideRecipients: Array> = [] ): Promise { const groupId = Bytes.toBase64(groupIdBytes); const conversation = window.ConversationController.get(groupId); @@ -3313,9 +3345,9 @@ export class CallingClass { } async #handleGroupCallRingUpdate( - groupIdBytes: Uint8Array, + groupIdBytes: Uint8Array, ringId: bigint, - ringerBytes: Uint8Array, + ringerBytes: Uint8Array, update: RingUpdate ): Promise { log.info(`handleGroupCallRingUpdate(): got ring update ${update}`); @@ -3773,7 +3805,7 @@ export class CallingClass { url: string, method: HttpMethod, headers: { [name: string]: string }, - body: Uint8Array | undefined + body: Uint8Array | undefined ) { const httpMethod = RINGRTC_HTTP_METHOD_TO_OUR_HTTP_METHOD.get(method); if (httpMethod === undefined) { diff --git a/ts/services/keyTransparency.preload.ts b/ts/services/keyTransparency.preload.ts index 056f8a36f5..2b4ed9dfd1 100644 --- a/ts/services/keyTransparency.preload.ts +++ b/ts/services/keyTransparency.preload.ts @@ -213,7 +213,7 @@ export class KeyTransparency { }; } - let usernameHash: Uint8Array | undefined; + let usernameHash: Uint8Array | undefined; const username = me.get('username'); if (username != null && !itemStorage.get('usernameCorrupted')) { diff --git a/ts/services/ourProfileKey.std.ts b/ts/services/ourProfileKey.std.ts index d747f72481..8225341d0d 100644 --- a/ts/services/ourProfileKey.std.ts +++ b/ts/services/ourProfileKey.std.ts @@ -9,7 +9,7 @@ import type { StorageInterface } from '../types/Storage.d.ts'; const log = createLogger('ourProfileKey'); export class OurProfileKeyService { - private getPromise: undefined | Promise; + private getPromise: undefined | Promise>; #promisesBlockingGet: Array> = []; #storage?: StorageInterface; @@ -28,7 +28,7 @@ export class OurProfileKeyService { this.#storage = storage; } - get(): Promise { + get(): Promise> { if (this.getPromise) { log.info( 'Our profile key service: was already fetching. Piggybacking off of that' @@ -40,7 +40,7 @@ export class OurProfileKeyService { return this.getPromise; } - async set(newValue: undefined | Uint8Array): Promise { + async set(newValue: undefined | Uint8Array): Promise { assertDev(this.#storage, 'OurProfileKeyService was not initialized'); if (newValue != null) { strictAssert( @@ -59,7 +59,7 @@ export class OurProfileKeyService { this.#promisesBlockingGet.push(promise); } - async #doGet(): Promise { + async #doGet(): Promise> { log.info( `Our profile key service: waiting for ${this.#promisesBlockingGet.length} promises before fetching` ); diff --git a/ts/services/profiles.preload.ts b/ts/services/profiles.preload.ts index a1274f3209..d6e96a6139 100644 --- a/ts/services/profiles.preload.ts +++ b/ts/services/profiles.preload.ts @@ -458,11 +458,14 @@ async function buildProfileFetchOptions({ }; } -function decryptField(field: string, decryptionKey: Uint8Array): Uint8Array { +function decryptField( + field: string, + decryptionKey: Uint8Array +): Uint8Array { return decryptProfile(Bytes.fromBase64(field), decryptionKey); } -function formatTextField(decrypted: Uint8Array): string { +function formatTextField(decrypted: Uint8Array): string { return Bytes.toString(trimForDisplay(decrypted)); } @@ -861,7 +864,7 @@ export type UpdateIdentityKeyOptionsType = Readonly<{ }>; export async function updateIdentityKey( - identityKey: Uint8Array, + identityKey: Uint8Array, serviceId: ServiceIdString, { noOverwrite = false }: UpdateIdentityKeyOptionsType = {} ): Promise { diff --git a/ts/services/storage.preload.ts b/ts/services/storage.preload.ts index 5c550a2fce..fa9165c443 100644 --- a/ts/services/storage.preload.ts +++ b/ts/services/storage.preload.ts @@ -154,7 +154,7 @@ const conflictBackOff = new BackOff([ function encryptRecord( storageID: string | undefined, - recordIkm: Uint8Array | undefined, + recordIkm: Uint8Array | undefined, storageRecord: Proto.StorageRecord.Params ): Proto.StorageItem.Params { const storageKeyBuffer = storageID @@ -183,13 +183,13 @@ function encryptRecord( }; } -function generateStorageID(): Uint8Array { +function generateStorageID(): Uint8Array { return getRandomBytes(16); } type GeneratedManifestType = { postUploadUpdateFunctions: Array<() => unknown>; - recordIkm: Uint8Array | undefined; + recordIkm: Uint8Array | undefined; recordsByID: Map; insertKeys: Set; deleteKeys: Set; @@ -892,7 +892,7 @@ async function generateManifest( // If we have a copy of what the current remote manifest is then we run these // additional validations comparing our pending manifest to the remote // manifest: - let recordIkm: Uint8Array | undefined; + let recordIkm: Uint8Array | undefined; if (previousManifest) { const pendingInserts: Set = new Set(); const pendingDeletes: Set = new Set(); @@ -984,7 +984,7 @@ async function generateManifest( type EncryptManifestOptionsType = { recordsByID: Map; - recordIkm: Uint8Array | undefined; + recordIkm: Uint8Array | undefined; insertKeys: Set; }; @@ -1833,7 +1833,7 @@ export type FetchRemoteRecordsResultType = Readonly<{ async function fetchRemoteRecords( storageVersion: number, - recordIkm: Uint8Array | undefined, + recordIkm: Uint8Array | undefined, remoteOnlyRecords: Map ): Promise { const storageKeyBase64 = itemStorage.get('storageKey'); diff --git a/ts/services/storageRecordOps.preload.ts b/ts/services/storageRecordOps.preload.ts index 20cb56f7e8..2c82b779bd 100644 --- a/ts/services/storageRecordOps.preload.ts +++ b/ts/services/storageRecordOps.preload.ts @@ -261,7 +261,7 @@ function addUnknownFieldsToConversation( function conversationUnknownFieldsToRecord( conversation: ConversationModel -): Array | null { +): Array> | null { const storageUnknownFields = conversation.get('storageUnknownFields'); if (storageUnknownFields == null) { return null; @@ -275,8 +275,8 @@ function conversationUnknownFieldsToRecord( // Other records save a UInt8Array to the database function toStorageUnknownFields( - unknownFields: ReadonlyArray | undefined -): Uint8Array | null { + unknownFields: ReadonlyArray> | undefined +): Uint8Array | null { if (!unknownFields) { return null; } @@ -284,8 +284,8 @@ function toStorageUnknownFields( return Bytes.concatenate(unknownFields); } function fromStorageUnknownFields( - storageUnknownFields: Uint8Array | null | undefined -): Array | null { + storageUnknownFields: Uint8Array | null | undefined +): Array> | null { if (storageUnknownFields == null) { return null; } @@ -974,7 +974,7 @@ function logRecordChanges( // Sometimes we have a ByteBuffer and an Uint8Array, this ensures that we // are comparing them both equally by converting them into base64 string. - if (localValue instanceof Uint8Array) { + if (Bytes.isNonSharedUint8Array(localValue)) { const areEqual = Bytes.areEqual(localValue, remoteValue); if (!areEqual) { details.push(`key=${key}: different bytes`); @@ -1148,7 +1148,7 @@ export async function mergeGroupV1Record( } function getGroupV2Conversation( - masterKeyBuffer: Uint8Array + masterKeyBuffer: Uint8Array ): ConversationModel { const groupFields = deriveGroupFields(masterKeyBuffer); diff --git a/ts/services/username.preload.ts b/ts/services/username.preload.ts index a19469338a..a8d5a39ad6 100644 --- a/ts/services/username.preload.ts +++ b/ts/services/username.preload.ts @@ -255,7 +255,7 @@ export async function confirmUsername( await itemStorage.remove('usernameLink'); let serverIdString: string; - let entropy: Uint8Array; + let entropy: Uint8Array; if (previousLink && isCaseChange(reservation)) { log.info('confirmUsername: updating link only'); diff --git a/ts/services/writeProfile.preload.ts b/ts/services/writeProfile.preload.ts index d2d5b6ab01..41d402ce16 100644 --- a/ts/services/writeProfile.preload.ts +++ b/ts/services/writeProfile.preload.ts @@ -62,7 +62,7 @@ export async function writeProfile( if (options.keepAvatar) { const profileAvatarUrl = getLocalAvatarUrl(model.attributes); - let avatarBuffer: Uint8Array | undefined; + let avatarBuffer: Uint8Array | undefined; if (profileAvatarUrl) { try { avatarBuffer = await imagePathToBytes(profileAvatarUrl); diff --git a/ts/sql/Client.preload.ts b/ts/sql/Client.preload.ts index 5eb49e4757..c986987b2e 100644 --- a/ts/sql/Client.preload.ts +++ b/ts/sql/Client.preload.ts @@ -301,7 +301,7 @@ function specToBytes( spec: ObjectMappingSpecType, data: Input ): Output { - return mapObjectWithSpec(spec, data, x => + return mapObjectWithSpec>(spec, data, x => Bytes.fromBase64(x) ); } @@ -310,7 +310,7 @@ function specFromBytes( spec: ObjectMappingSpecType, data: Input ): Output { - return mapObjectWithSpec(spec, data, x => + return mapObjectWithSpec, string>(spec, data, x => Bytes.toBase64(x) ); } diff --git a/ts/sql/Interface.std.ts b/ts/sql/Interface.std.ts index e005ca8b99..77fceed0eb 100644 --- a/ts/sql/Interface.std.ts +++ b/ts/sql/Interface.std.ts @@ -124,7 +124,7 @@ export type IdentityKeyType = { firstUse: boolean; id: ServiceIdString | `conversation:${string}`; nonblockingApproval: boolean; - publicKey: Uint8Array; + publicKey: Uint8Array; timestamp: number; verified: number; }; @@ -239,7 +239,7 @@ export type KyberPreKeyType = { id: PreKeyIdType; createdAt: number; - data: Uint8Array; + data: Uint8Array; isConfirmed: boolean; isLastResort: boolean; keyId: number; @@ -254,8 +254,8 @@ export type PreKeyType = { createdAt: number; keyId: number; ourServiceId: ServiceIdString; - privateKey: Uint8Array; - publicKey: Uint8Array; + privateKey: Uint8Array; + publicKey: Uint8Array; }; export type StoredPreKeyType = PreKeyType & { @@ -281,14 +281,14 @@ export type ClientSearchResultMessageType = MessageType & { export type SentProtoType = { contentHint: number; - proto: Uint8Array; + proto: Uint8Array; timestamp: number; urgent: boolean; hasPniSignatureMessage: boolean; }; export type SentProtoDBType = { contentHint: number; - proto: Uint8Array; + proto: Uint8Array; timestamp: number; urgent: number; hasPniSignatureMessage: number; @@ -317,7 +317,7 @@ export type SenderKeyType = { senderId: string; distributionId: string; // Raw data to serialize/deserialize into signal-client SenderKeyRecord - data: Uint8Array; + data: Uint8Array; lastUpdatedDate: number; }; export type SenderKeyIdType = SenderKeyType['id']; @@ -327,7 +327,7 @@ export type SessionType = { serviceId: ServiceIdString; conversationId: string; deviceId: number; - record: Uint8Array; + record: Uint8Array; }; export type SessionIdType = SessionType['id']; export type SignedPreKeyType = { @@ -336,8 +336,8 @@ export type SignedPreKeyType = { ourServiceId: ServiceIdString; id: `${ServiceIdString}:${number}`; keyId: number; - privateKey: Uint8Array; - publicKey: Uint8Array; + privateKey: Uint8Array; + publicKey: Uint8Array; }; export type StoredSignedPreKeyType = { confirmed: boolean; @@ -381,7 +381,7 @@ export type StickerPackStatusType = (typeof StickerPackStatuses)[number]; export type StorageServiceFieldsType = Readonly<{ storageID?: string | null; storageVersion?: number | null; - storageUnknownFields?: Uint8Array | null; + storageUnknownFields?: Uint8Array | null; storageNeedsSync: boolean; }>; @@ -441,7 +441,7 @@ export type UnprocessedType = { attempts: number; type: number; isEncrypted: boolean; - content: Uint8Array; + content: Uint8Array; messageAgeSec: number; source: string | undefined; @@ -453,7 +453,7 @@ export type UnprocessedType = { serverTimestamp: number; urgent: boolean; story: boolean; - reportingToken: Uint8Array | undefined; + reportingToken: Uint8Array | undefined; groupId: string | undefined; }; @@ -675,7 +675,7 @@ export type NonAttachmentMediaItemDBType = export type KyberPreKeyTripleType = Readonly<{ id: PreKeyIdType; signedPreKeyId: number; - baseKey: Uint8Array; + baseKey: Uint8Array; }>; export type GetMessagesBetweenOptions = Readonly<{ @@ -1074,7 +1074,7 @@ type ReadableInterface = { hasMegaphone: (megaphoneId: RemoteMegaphoneId) => boolean; getAllKTAcis: () => ReadonlyArray; - getKTAccountData: (aci: AciString) => Uint8Array | undefined; + getKTAccountData: (aci: AciString) => Uint8Array | undefined; getAllPinnedMessages: () => ReadonlyArray; getPinnedMessagesPreloadDataForConversation: ( @@ -1450,7 +1450,7 @@ type WritableInterface = { internalDeleteAllMegaphones: () => number; removeAllKTAccountData: () => void; - setKTAccountData: (aci: AciString, data: Uint8Array) => void; + setKTAccountData: (aci: AciString, data: Uint8Array) => void; appendPinnedMessage: ( pinnedMessagesLimit: number, diff --git a/ts/sql/Server.node.ts b/ts/sql/Server.node.ts index bdea648451..04f071c86e 100644 --- a/ts/sql/Server.node.ts +++ b/ts/sql/Server.node.ts @@ -346,7 +346,7 @@ type StickerRow = Readonly<{ type StorageServiceRowFields = Readonly<{ storageID?: string; storageVersion?: number; - storageUnknownFields?: Uint8Array | null; + storageUnknownFields?: Uint8Array | null; storageNeedsSync: number; }>; type InstalledStickerPackRow = Readonly<{ @@ -2978,9 +2978,9 @@ function getAndProtectExistingAttachmentPath( screenshotVersion, screenshotContentType, screenshotSize - FROM message_attachments - WHERE - plaintextHash = ${plaintextHash} AND + FROM message_attachments + WHERE + plaintextHash = ${plaintextHash} AND path IS NOT NULL AND version = ${version} AND contentType = ${contentType} @@ -3017,7 +3017,7 @@ function _protectAttachmentPathFromDeletion( const [protectQuery, protectParams] = sql` INSERT OR REPLACE INTO attachments_protected_from_deletion (path, messageId) - VALUES + VALUES (${path}, ${messageId}); `; db.prepare(protectQuery).run(protectParams); @@ -3038,11 +3038,11 @@ function getAllProtectedAttachmentPaths(db: ReadableDB): Array { function isAttachmentSafeToDelete(db: ReadableDB, path: string): boolean { const [query, params] = sql` SELECT EXISTS ( - SELECT 1 FROM attachments_protected_from_deletion + SELECT 1 FROM attachments_protected_from_deletion WHERE path = ${path} UNION ALL - SELECT 1 FROM message_attachments - WHERE + SELECT 1 FROM message_attachments + WHERE path = ${path} OR thumbnailPath = ${path} OR screenshotPath = ${path} OR @@ -3058,7 +3058,7 @@ function getMostRecentAttachmentUploadData( plaintextHash: string ): ExistingAttachmentUploadData | undefined { const [query, params] = sql` - SELECT + SELECT key, digest, transitCdnKey AS cdnKey, @@ -3068,7 +3068,7 @@ function getMostRecentAttachmentUploadData( incrementalMacChunkSize as chunkSize FROM message_attachments INDEXED BY message_attachments_plaintextHash - WHERE + WHERE plaintextHash = ${plaintextHash} AND key IS NOT NULL AND digest IS NOT NULL AND diff --git a/ts/sql/cleanDataForIpc.std.ts b/ts/sql/cleanDataForIpc.std.ts index 9f29675352..754b994d85 100644 --- a/ts/sql/cleanDataForIpc.std.ts +++ b/ts/sql/cleanDataForIpc.std.ts @@ -7,6 +7,7 @@ import { createLogger } from '../logging/log.std.js'; import { isIterable } from '../util/iterables.std.js'; import { toNumber } from '../util/toNumber.std.js'; +import { isNonSharedUint8Array } from '../Bytes.std.js'; const { isPlainObject } = lodash; @@ -42,7 +43,7 @@ type CleanedDataValue = | boolean | null | undefined - | Uint8Array + | Uint8Array | CleanedObject | CleanedArray; /* eslint-disable no-restricted-syntax */ @@ -129,7 +130,7 @@ function cleanDataInner( return undefined; } - if (data instanceof Uint8Array) { + if (isNonSharedUint8Array(data)) { return data; } diff --git a/ts/sql/migrations/1220-blob-sessions.node.ts b/ts/sql/migrations/1220-blob-sessions.node.ts index 75e1f8c457..b57ed73e08 100644 --- a/ts/sql/migrations/1220-blob-sessions.node.ts +++ b/ts/sql/migrations/1220-blob-sessions.node.ts @@ -48,7 +48,7 @@ type NextSessionRowType = Readonly<{ ourServiceId: string; serviceId: string; deviceId: number; - record: Buffer; + record: Buffer; }>; function migrateSession( diff --git a/ts/sql/server/callLinks.node.ts b/ts/sql/server/callLinks.node.ts index b61996b41c..3d84dba991 100644 --- a/ts/sql/server/callLinks.node.ts +++ b/ts/sql/server/callLinks.node.ts @@ -224,9 +224,10 @@ export function updateCallLinkAdminKeyByRoomId( } function assertRoomIdMatchesRootKey(roomId: string, rootKey: string): void { - const derivedRoomId = Bytes.toHex( - CallLinkRootKey.parse(rootKey).deriveRoomId() - ); + const parsedRoomId = CallLinkRootKey.parse(rootKey).deriveRoomId(); + // @ts-expect-error needs ringrtc update + const derivedRoomIdBytes: Uint8Array = parsedRoomId; + const derivedRoomId = Bytes.toHex(derivedRoomIdBytes); strictAssert( roomId === derivedRoomId, 'passed roomId must match roomId derived from root key' diff --git a/ts/sql/server/keyTransparency.std.ts b/ts/sql/server/keyTransparency.std.ts index 8ba8813cac..d9980dd75e 100644 --- a/ts/sql/server/keyTransparency.std.ts +++ b/ts/sql/server/keyTransparency.std.ts @@ -15,19 +15,21 @@ export function getAllKTAcis(db: ReadableDB): Array { export function getKTAccountData( db: ReadableDB, aci: AciString -): Uint8Array | undefined { +): Uint8Array | undefined { const [query, params] = sql` SELECT data FROM key_transparency_account_data WHERE aci IS ${aci} `; - return db.prepare(query, { pluck: true }).get(params); + return db + .prepare(query, { pluck: true }) + .get>(params); } export function setKTAccountData( db: WritableDB, aci: AciString, - data: Uint8Array + data: Uint8Array ): void { const [query, params] = sql` INSERT OR REPLACE INTO key_transparency_account_data diff --git a/ts/sql/util.std.ts b/ts/sql/util.std.ts index 79f5276401..693024a0c0 100644 --- a/ts/sql/util.std.ts +++ b/ts/sql/util.std.ts @@ -38,7 +38,11 @@ export function jsonToObject(json: string): T { return JSON.parse(json); } -export type QueryTemplateParam = Uint8Array | string | number | null; +export type QueryTemplateParam = + | Uint8Array + | string + | number + | null; export type QueryFragmentValue = QueryFragment | QueryTemplateParam; export class QueryFragment { diff --git a/ts/state/ducks/calling.preload.ts b/ts/state/ducks/calling.preload.ts index e68fafd67d..ea724240b7 100644 --- a/ts/state/ducks/calling.preload.ts +++ b/ts/state/ducks/calling.preload.ts @@ -131,6 +131,7 @@ import { import { itemStorage } from '../../textsecure/Storage.preload.js'; import type { SizeCallbackType } from '../../calling/VideoSupport.preload.js'; import type { NoopActionType } from './noop.std.js'; +import type { SignalService } from '../../protobuf/index.std.js'; const { omit } = lodash; @@ -2962,33 +2963,42 @@ function submitCallQualitySurvey( const { qualityStats } = callSummary; const { audioStats, videoStats } = qualityStats; - const surveyRequest = { - userSatisfied, - callQualityIssues: userSatisfied ? [] : Array.from(callQualityIssues), - additionalIssuesDescription: - !userSatisfied && - callQualityIssues.includes(CallQualitySurvey.Issue.OTHER) - ? additionalIssuesDescription - : null, - debugLogUrl: debugLogUrl ?? null, - startTimestamp: BigInt(callSummary.startTime), - endTimestamp: BigInt(callSummary.endTime), - callType, - success: !isCallFailure(callSummary.callEndReasonText), - callEndReason: callSummary.callEndReasonText, - connectionRttMedian: qualityStats.rttMedianConnectionMillis ?? null, - audioRttMedian: audioStats.rttMedianMillis ?? null, - videoRttMedian: videoStats.rttMedianMillis ?? null, - audioRecvJitterMedian: audioStats.jitterMedianRecvMillis ?? null, - videoRecvJitterMedian: videoStats.jitterMedianRecvMillis ?? null, - audioSendJitterMedian: audioStats.jitterMedianSendMillis ?? null, - videoSendJitterMedian: videoStats.jitterMedianSendMillis ?? null, - audioRecvPacketLossFraction: audioStats.packetLossFractionRecv ?? null, - videoRecvPacketLossFraction: videoStats.packetLossFractionRecv ?? null, - audioSendPacketLossFraction: audioStats.packetLossFractionSend ?? null, - videoSendPacketLossFraction: videoStats.packetLossFractionSend ?? null, - callTelemetry: callSummary.rawStats ?? null, - }; + // @ts-expect-error needs ringrtc update + const callTelemetry: Uint8Array | null = + callSummary.rawStats ?? null; + + const surveyRequest: SignalService.SubmitCallQualitySurveyRequest.Params = + { + userSatisfied, + callQualityIssues: userSatisfied ? [] : Array.from(callQualityIssues), + additionalIssuesDescription: + !userSatisfied && + callQualityIssues.includes(CallQualitySurvey.Issue.OTHER) + ? additionalIssuesDescription + : null, + debugLogUrl: debugLogUrl ?? null, + startTimestamp: BigInt(callSummary.startTime), + endTimestamp: BigInt(callSummary.endTime), + callType, + success: !isCallFailure(callSummary.callEndReasonText), + callEndReason: callSummary.callEndReasonText, + connectionRttMedian: qualityStats.rttMedianConnectionMillis ?? null, + audioRttMedian: audioStats.rttMedianMillis ?? null, + videoRttMedian: videoStats.rttMedianMillis ?? null, + audioRecvJitterMedian: audioStats.jitterMedianRecvMillis ?? null, + videoRecvJitterMedian: videoStats.jitterMedianRecvMillis ?? null, + audioSendJitterMedian: audioStats.jitterMedianSendMillis ?? null, + videoSendJitterMedian: videoStats.jitterMedianSendMillis ?? null, + audioRecvPacketLossFraction: + audioStats.packetLossFractionRecv ?? null, + videoRecvPacketLossFraction: + videoStats.packetLossFractionRecv ?? null, + audioSendPacketLossFraction: + audioStats.packetLossFractionSend ?? null, + videoSendPacketLossFraction: + videoStats.packetLossFractionSend ?? null, + callTelemetry, + }; await submitCallQualitySurveyToServer(surveyRequest); diff --git a/ts/state/ducks/conversations.preload.ts b/ts/state/ducks/conversations.preload.ts index 103edc75ba..9b0739b26f 100644 --- a/ts/state/ducks/conversations.preload.ts +++ b/ts/state/ducks/conversations.preload.ts @@ -552,7 +552,7 @@ export type PreJoinConversationType = ReadonlyDeep<{ }>; type ComposerGroupCreationState = ReadonlyDeep<{ - groupAvatar: undefined | Uint8Array; + groupAvatar: undefined | Uint8Array; groupName: string; groupExpireTimer: DurationInSeconds; maximumGroupSizeModalState: OneTimeModalState; @@ -1003,7 +1003,7 @@ export type ShowArchivedConversationsActionType = ReadonlyDeep<{ }>; type SetComposeGroupAvatarActionType = ReadonlyDeep<{ type: 'SET_COMPOSE_GROUP_AVATAR'; - payload: { groupAvatar: undefined | Uint8Array }; + payload: { groupAvatar: undefined | Uint8Array }; }>; type SetComposeGroupNameActionType = ReadonlyDeep<{ type: 'SET_COMPOSE_GROUP_NAME'; @@ -4474,7 +4474,7 @@ export function scrollToMessage( } function setComposeGroupAvatar( - groupAvatar: undefined | Uint8Array + groupAvatar: undefined | Uint8Array ): SetComposeGroupAvatarActionType { return { type: 'SET_COMPOSE_GROUP_AVATAR', @@ -4649,7 +4649,7 @@ export type UpdateGroupAttributesType = ReadonlyDeep< function updateGroupAttributes( conversationId: string, attributes: Readonly<{ - avatar?: undefined | Uint8Array; + avatar?: undefined | Uint8Array; description?: string; title?: string; }>, @@ -6957,7 +6957,7 @@ export function reducer( let recommendedGroupSizeModalState: OneTimeModalState; let maximumGroupSizeModalState: OneTimeModalState; let groupName: string; - let groupAvatar: undefined | Uint8Array; + let groupAvatar: undefined | Uint8Array; let groupExpireTimer: DurationInSeconds; let userAvatarData = getDefaultAvatars(true); diff --git a/ts/state/selectors/conversations.dom.ts b/ts/state/selectors/conversations.dom.ts index 959d747c15..432d7886b8 100644 --- a/ts/state/selectors/conversations.dom.ts +++ b/ts/state/selectors/conversations.dom.ts @@ -978,7 +978,7 @@ const getGroupCreationComposerState = createSelector( composerState ): { groupName: string; - groupAvatar: undefined | Uint8Array; + groupAvatar: undefined | Uint8Array; groupExpireTimer: DurationInSeconds; selectedConversationIds: ReadonlyArray; } => { @@ -1003,7 +1003,8 @@ const getGroupCreationComposerState = createSelector( export const getComposeGroupAvatar = createSelector( getGroupCreationComposerState, - (composerState): undefined | Uint8Array => composerState.groupAvatar + (composerState): undefined | Uint8Array => + composerState.groupAvatar ); export const getComposeGroupName = createSelector( diff --git a/ts/test-electron/ContactsParser_test.preload.ts b/ts/test-electron/ContactsParser_test.preload.ts index 0f6ce7a1f2..94ccc348c8 100644 --- a/ts/test-electron/ContactsParser_test.preload.ts +++ b/ts/test-electron/ContactsParser_test.preload.ts @@ -147,7 +147,7 @@ class SmallChunksTransform extends Transform { } override _transform( - incomingChunk: Buffer | undefined, + incomingChunk: Buffer | undefined, _encoding: string, done: (error?: Error) => void ) { @@ -179,7 +179,7 @@ class SmallChunksTransform extends Transform { } } -function generateAvatar(): Uint8Array { +function generateAvatar(): Uint8Array { const result = new Uint8Array(255); for (let i = 0; i < result.length; i += 1) { result[i] = i; @@ -187,11 +187,11 @@ function generateAvatar(): Uint8Array { return result; } -function getTestBuffer(): Uint8Array { +function getTestBuffer(): Uint8Array { const avatarBuffer = generateAvatar(); const prefixedContact = generatePrefixedContact(avatarBuffer); - const chunks: Array = []; + const chunks: Array> = []; for (let i = 0; i < 3; i += 1) { chunks.push(...prefixedContact); chunks.push(avatarBuffer); @@ -201,9 +201,9 @@ function getTestBuffer(): Uint8Array { } function generatePrefixedContact( - avatarBuffer: Uint8Array | undefined, + avatarBuffer: Uint8Array | undefined, aci: AciString | null = DEFAULT_ACI -): [Uint8Array, Uint8Array] { +): [Uint8Array, Uint8Array] { const contactInfoBuffer = Proto.ContactDetails.encode({ name: 'Zero Cool', number: '+10000000000', diff --git a/ts/test-electron/Crypto_test.preload.ts b/ts/test-electron/Crypto_test.preload.ts index 61494f4d93..8a5568ac48 100644 --- a/ts/test-electron/Crypto_test.preload.ts +++ b/ts/test-electron/Crypto_test.preload.ts @@ -728,9 +728,9 @@ describe('Crypto', () => { overrideSize, }: { path?: string; - data: Uint8Array; - plaintextHash?: Uint8Array; - encryptionKeys?: Uint8Array; + data: Uint8Array; + plaintextHash?: Uint8Array; + encryptionKeys?: Uint8Array; modifyIncrementalMac?: boolean; overrideSize?: number; }): Promise { @@ -986,8 +986,8 @@ describe('Crypto', () => { outerKeys, }: { plaintextAbsolutePath: string; - innerKeys: Uint8Array; - outerKeys: Uint8Array; + innerKeys: Uint8Array; + outerKeys: Uint8Array; }) { let innerCiphertextPath; let outerCiphertextPath; diff --git a/ts/test-electron/backup/calling_test.preload.ts b/ts/test-electron/backup/calling_test.preload.ts index fe0a90e9fb..0b48c5c890 100644 --- a/ts/test-electron/backup/calling_test.preload.ts +++ b/ts/test-electron/backup/calling_test.preload.ts @@ -179,10 +179,12 @@ describe('backup/calling', () => { beforeEach(async () => { const adminRootKey = CallLinkRootKey.generate(); const adminKey = CallLinkRootKey.generateAdminPassKey(); + // @ts-expect-error needs ringrtc update + const adminKeyBytes: Uint8Array = adminKey; adminCallLink = { rootKey: adminRootKey.toString(), roomId: getRoomIdFromRootKey(adminRootKey), - adminKey: fromAdminKeyBytes(adminKey), + adminKey: fromAdminKeyBytes(adminKeyBytes), name: "Let's Talk Rocks", restrictions: CallLinkRestrictions.AdminApproval, revoked: false, diff --git a/ts/test-electron/linkPreviews/linkPreviewFetch_test.preload.ts b/ts/test-electron/linkPreviews/linkPreviewFetch_test.preload.ts index 7d69d292cc..b0282d3363 100644 --- a/ts/test-electron/linkPreviews/linkPreviewFetch_test.preload.ts +++ b/ts/test-electron/linkPreviews/linkPreviewFetch_test.preload.ts @@ -18,7 +18,9 @@ import { fetchLinkPreviewMetadata, } from '../../linkPreviews/linkPreviewFetch.preload.js'; -async function readFixtureImage(filename: string): Promise { +async function readFixtureImage( + filename: string +): Promise> { const result = await fs.promises.readFile( path.join(__dirname, '..', '..', '..', 'fixtures', filename) ); @@ -60,11 +62,15 @@ describe('link preview fetching', () => { }: { status?: number; headers?: { [key: string]: null | string }; - body?: null | string | Uint8Array | AsyncIterable; + body?: + | null + | string + | Uint8Array + | AsyncIterable>; url?: string; } = {}) => { let bodyLength: null | number; - let bodyStream: null | AsyncIterable; + let bodyStream: null | AsyncIterable>; if (!body) { bodyLength = 0; bodyStream = null; diff --git a/ts/test-electron/services/AttachmentDownloadManager_test.preload.ts b/ts/test-electron/services/AttachmentDownloadManager_test.preload.ts index bc9b3d4062..2af64f98aa 100644 --- a/ts/test-electron/services/AttachmentDownloadManager_test.preload.ts +++ b/ts/test-electron/services/AttachmentDownloadManager_test.preload.ts @@ -955,6 +955,7 @@ describe('AttachmentDownloadManager.runDownloadAttachmentJobInner', () => { .returns(Promise.resolve(downloadedAttachment)); cleanupAttachmentFiles = sandbox.stub(); maybeDeleteAttachmentFile = sandbox.stub(); + deleteDownloadFile = sandbox.stub(); processNewAttachment = sandbox.stub().callsFake(attachment => attachment); }); diff --git a/ts/test-electron/services/senderCertificate_test.preload.ts b/ts/test-electron/services/senderCertificate_test.preload.ts index b298b0a78c..9456d7fbb8 100644 --- a/ts/test-electron/services/senderCertificate_test.preload.ts +++ b/ts/test-electron/services/senderCertificate_test.preload.ts @@ -25,7 +25,7 @@ import { DAY } from '../../util/durations/constants.std.js'; describe('SenderCertificateService', () => { let fakeValidCertificate: SenderCertificate; - let fakeValidEncodedCertificate: Uint8Array; + let fakeValidEncodedCertificate: Uint8Array; let fakeValidCertificateExpiry: number; let fakeServer: any; let fakeEvents: Pick; diff --git a/ts/test-electron/textsecure/generate_keys_test.preload.ts b/ts/test-electron/textsecure/generate_keys_test.preload.ts index 415ef17ff8..9b5bfa4336 100644 --- a/ts/test-electron/textsecure/generate_keys_test.preload.ts +++ b/ts/test-electron/textsecure/generate_keys_test.preload.ts @@ -16,7 +16,10 @@ import { DataWriter } from '../../sql/Client.preload.js'; import { signalProtocolStore } from '../../SignalProtocolStore.preload.js'; import { itemStorage } from '../../textsecure/Storage.preload.js'; -const assertEqualBuffers = (a: Uint8Array, b: Uint8Array) => { +const assertEqualBuffers = ( + a: Uint8Array, + b: Uint8Array +) => { assert.isTrue(constantTimeEqual(a, b)); }; diff --git a/ts/test-electron/util/encryptProfileData_test.preload.ts b/ts/test-electron/util/encryptProfileData_test.preload.ts index 5a0b682111..342651c7ce 100644 --- a/ts/test-electron/util/encryptProfileData_test.preload.ts +++ b/ts/test-electron/util/encryptProfileData_test.preload.ts @@ -15,7 +15,7 @@ import { generateAci } from '../../types/ServiceId.std.js'; import { encryptProfileData } from '../../util/encryptProfileData.preload.js'; describe('encryptProfileData', () => { - let keyBuffer: Uint8Array; + let keyBuffer: Uint8Array; let conversation: ConversationType; beforeEach(() => { diff --git a/ts/test-helpers/fakeGetGroupCallVideoFrameSource.std.ts b/ts/test-helpers/fakeGetGroupCallVideoFrameSource.std.ts index 7546c3bfeb..f22a787acd 100644 --- a/ts/test-helpers/fakeGetGroupCallVideoFrameSource.std.ts +++ b/ts/test-helpers/fakeGetGroupCallVideoFrameSource.std.ts @@ -14,7 +14,7 @@ const COLORS: Array<[number, number, number]> = [ ]; class FakeGroupCallVideoFrameSource implements VideoFrameSource { - readonly #sourceArray: Uint8Array; + readonly #sourceArray: Uint8Array; readonly #dimensions: [number, number]; constructor(width: number, height: number, r: number, g: number, b: number) { @@ -32,7 +32,7 @@ class FakeGroupCallVideoFrameSource implements VideoFrameSource { } receiveVideoFrame( - destinationBuffer: Uint8Array, + destinationBuffer: Uint8Array, _maxWidth: number, _maxHeight: number ): [number, number] | undefined { diff --git a/ts/test-helpers/generateBackup.node.ts b/ts/test-helpers/generateBackup.node.ts index 2a91a8a632..8399dff8e9 100644 --- a/ts/test-helpers/generateBackup.node.ts +++ b/ts/test-helpers/generateBackup.node.ts @@ -24,17 +24,17 @@ import { Backups } from '../protobuf/index.std.js'; export type BackupGeneratorConfigType = Readonly< { aci: AciString; - profileKey: Uint8Array; + profileKey: Uint8Array; conversations: number; conversationAcis?: ReadonlyArray; messages: number; - mediaRootBackupKey: Uint8Array; + mediaRootBackupKey: Uint8Array; } & ( | { accountEntropyPool: string; } | { - backupKey: Uint8Array; + backupKey: Uint8Array; } ) >; @@ -42,7 +42,7 @@ export type BackupGeneratorConfigType = Readonly< const IV_LENGTH = 16; export type GenerateBackupResultType = Readonly<{ - backupId: Uint8Array; + backupId: Uint8Array; stream: Readable; }>; @@ -77,7 +77,7 @@ export function generateBackup( function* frame( item: NonNullable -): Iterable { +): Iterable> { yield* encodeDelimited( Backups.Frame.encode({ item, @@ -97,7 +97,7 @@ function* createRecords({ conversationAcis = [], messages, mediaRootBackupKey, -}: BackupGeneratorConfigType): Iterable { +}: BackupGeneratorConfigType): Iterable> { yield* encodeDelimited( Backups.BackupInfo.encode({ version: BigInt(BACKUP_VERSION), @@ -182,7 +182,7 @@ function* createRecords({ const chats = new Array<{ id: bigint; - aci: Uint8Array; + aci: Uint8Array; }>(); for (let i = 1; i <= conversations; i += 1) { diff --git a/ts/test-mock/benchmarks/convo_open_bench.node.ts b/ts/test-mock/benchmarks/convo_open_bench.node.ts index 3092d96902..9367caa880 100644 --- a/ts/test-mock/benchmarks/convo_open_bench.node.ts +++ b/ts/test-mock/benchmarks/convo_open_bench.node.ts @@ -19,7 +19,7 @@ Bootstrap.benchmark(async (bootstrap: Bootstrap): Promise => { const [first, second] = contacts as [PrimaryDevice, PrimaryDevice]; - const messages = new Array(); + const messages = new Array>(); debug('encrypting'); // Send messages from just two contacts for (const contact of [second, first]) { diff --git a/ts/test-mock/benchmarks/group_send_bench.node.ts b/ts/test-mock/benchmarks/group_send_bench.node.ts index afe92afeb2..888081a029 100644 --- a/ts/test-mock/benchmarks/group_send_bench.node.ts +++ b/ts/test-mock/benchmarks/group_send_bench.node.ts @@ -49,7 +49,7 @@ Bootstrap.benchmark(async (bootstrap: Bootstrap): Promise => { const { server, desktop } = bootstrap; const [first] = members as [PrimaryDevice]; - const messages = new Array(); + const messages = new Array>(); debug('encrypting'); // Fill left pane for (const contact of members.slice(0, CONVERSATION_SIZE).reverse()) { @@ -190,7 +190,7 @@ Bootstrap.benchmark(async (bootstrap: Bootstrap): Promise => { runId, delay, }: { - receipts: Array; + receipts: Array>; batchSize: number; nextBatchSize: number; runId: number; @@ -216,7 +216,7 @@ Bootstrap.benchmark(async (bootstrap: Bootstrap): Promise => { } } - let receiptsFromPreviousMessage: Array = []; + let receiptsFromPreviousMessage: Array> = []; for (let runId = 0; runId < RUN_COUNT + DISCARD_COUNT; runId += 1) { debug(`sending previous ${receiptsFromPreviousMessage.length} receipts`); diff --git a/ts/test-mock/benchmarks/send_bench.node.ts b/ts/test-mock/benchmarks/send_bench.node.ts index c94f78b4b7..b600e80a30 100644 --- a/ts/test-mock/benchmarks/send_bench.node.ts +++ b/ts/test-mock/benchmarks/send_bench.node.ts @@ -22,7 +22,7 @@ Bootstrap.benchmark(async (bootstrap: Bootstrap): Promise => { const [first] = contacts as [PrimaryDevice]; - const messages = new Array(); + const messages = new Array>(); debug('encrypting'); // Note: make it so that we receive the latest message from the first // contact. diff --git a/ts/test-mock/benchmarks/startup_bench.node.ts b/ts/test-mock/benchmarks/startup_bench.node.ts index aca8bbd025..f6b1b0da3f 100644 --- a/ts/test-mock/benchmarks/startup_bench.node.ts +++ b/ts/test-mock/benchmarks/startup_bench.node.ts @@ -21,7 +21,7 @@ Bootstrap.regressionBenchmark( const { server, contacts, phone, desktop } = bootstrap; // Generate messages - const messagePromises = new Array>(); + const messagePromises = new Array>>(); debug('started generating messages'); for (let i = 0; i < messageCount; i += 1) { diff --git a/ts/test-mock/bootstrap.node.ts b/ts/test-mock/bootstrap.node.ts index 5cce73f693..d7d0bb37c0 100644 --- a/ts/test-mock/bootstrap.node.ts +++ b/ts/test-mock/bootstrap.node.ts @@ -617,7 +617,7 @@ export class Bootstrap { ) => Promise, test?: Mocha.Runnable ): Promise<(app: App) => Promise> { - const snapshots = new Array<{ name: string; data: Buffer }>(); + const snapshots = new Array<{ name: string; data: Buffer }>(); const viewportSize = { width: 1000, height: 2000 } as const; const window = await app.getWindow(); await window.setViewportSize(viewportSize); @@ -692,7 +692,7 @@ export class Bootstrap { } public async encryptAndStoreAttachmentOnCDN( - data: Buffer, + data: Buffer, contentType: MIMEType ): Promise { const cdnKey = uuid(); diff --git a/ts/test-mock/helpers.node.ts b/ts/test-mock/helpers.node.ts index 4de778e355..aadae12579 100644 --- a/ts/test-mock/helpers.node.ts +++ b/ts/test-mock/helpers.node.ts @@ -19,7 +19,7 @@ import { toNumber } from '../util/toNumber.std.js'; const debug = createDebug('mock:test:helpers'); -export function bufferToUuid(buffer: Buffer): string { +export function bufferToUuid(buffer: Buffer): string { const hex = buffer.toString('hex'); return [ diff --git a/ts/test-mock/pnp/merge_test.node.ts b/ts/test-mock/pnp/merge_test.node.ts index aaa42061de..dc4082c560 100644 --- a/ts/test-mock/pnp/merge_test.node.ts +++ b/ts/test-mock/pnp/merge_test.node.ts @@ -34,8 +34,8 @@ describe('pnp/merge', function (this: Mocha.Suite) { let bootstrap: Bootstrap; let app: App; let pniContact: PrimaryDevice; - let pniIdentityKey: Uint8Array; - let aciIdentityKey: Uint8Array; + let pniIdentityKey: Uint8Array; + let aciIdentityKey: Uint8Array; beforeEach(async () => { bootstrap = new Bootstrap({ contactCount: 0 }); diff --git a/ts/test-mock/pnp/phone_discovery_test.node.ts b/ts/test-mock/pnp/phone_discovery_test.node.ts index fe1616a72f..0c84207b5f 100644 --- a/ts/test-mock/pnp/phone_discovery_test.node.ts +++ b/ts/test-mock/pnp/phone_discovery_test.node.ts @@ -28,7 +28,7 @@ describe('pnp/phone discovery', function (this: Mocha.Suite) { let bootstrap: Bootstrap; let app: App; let pniContact: PrimaryDevice; - let pniIdentityKey: Uint8Array; + let pniIdentityKey: Uint8Array; beforeEach(async () => { bootstrap = new Bootstrap({ contactCount: 0 }); diff --git a/ts/test-mock/storage/fixtures.node.ts b/ts/test-mock/storage/fixtures.node.ts index 4913b17e0f..b8256ec337 100644 --- a/ts/test-mock/storage/fixtures.node.ts +++ b/ts/test-mock/storage/fixtures.node.ts @@ -162,8 +162,8 @@ export const FIXTURES = path.join(__dirname, '..', '..', '..', 'fixtures'); export const EMPTY = new Uint8Array(0); export type StickerPackType = Readonly<{ - id: Buffer; - key: Buffer; + id: Buffer; + key: Buffer; stickerCount: number; }>; diff --git a/ts/test-mock/storage/notification_profiles_test.node.ts b/ts/test-mock/storage/notification_profiles_test.node.ts index 206c8972a0..3a4d1d3cb2 100644 --- a/ts/test-mock/storage/notification_profiles_test.node.ts +++ b/ts/test-mock/storage/notification_profiles_test.node.ts @@ -104,7 +104,7 @@ describe('storage service/notification profiles', function (this: Mocha.Suite) { after: secondState, }); - let profileId: Uint8Array | undefined; + let profileId: Uint8Array | undefined; const profilewasAdded = thirdState.hasRecord(record => { if (record.record.notificationProfile == null) { return false; diff --git a/ts/test-node/logging/uploadDebugLogs_test.node.ts b/ts/test-node/logging/uploadDebugLogs_test.node.ts index a3715da799..c63f414d76 100644 --- a/ts/test-node/logging/uploadDebugLogs_test.node.ts +++ b/ts/test-node/logging/uploadDebugLogs_test.node.ts @@ -14,7 +14,8 @@ import { createLogger } from '../../logging/log.std.js'; const logger = createLogger('uploadDebugLogs_test'); -const gzip: (_: zlib.InputType) => Promise = util.promisify(zlib.gzip); +const gzip: (_: zlib.InputType) => Promise> = + util.promisify(zlib.gzip); describe('upload', () => { beforeEach(function (this: Mocha.Context) { diff --git a/ts/test-node/sql/helpers.node.ts b/ts/test-node/sql/helpers.node.ts index 1992147d9b..8b40bb9bea 100644 --- a/ts/test-node/sql/helpers.node.ts +++ b/ts/test-node/sql/helpers.node.ts @@ -47,7 +47,10 @@ export function updateToVersion(db: WritableDB, version: number): void { } type TableRows = ReadonlyArray< - Record> + Record< + string, + string | number | Buffer | null | Record + > >; export function insertData( diff --git a/ts/test-node/sql/migrations_test.node.ts b/ts/test-node/sql/migrations_test.node.ts index 3dd606ad23..bb56644ed4 100644 --- a/ts/test-node/sql/migrations_test.node.ts +++ b/ts/test-node/sql/migrations_test.node.ts @@ -2457,7 +2457,7 @@ describe('SQL migrations test', () => { const payload = db.prepare('SELECT * FROM sendLogPayloads LIMIT 1;').get<{ contentHint: number; timestamp: number; - proto: Uint8Array; + proto: Uint8Array; urgent: number; }>(); diff --git a/ts/test-node/types/Attachment_test.std.ts b/ts/test-node/types/Attachment_test.std.ts index f19be65fad..25f8c82dbc 100644 --- a/ts/test-node/types/Attachment_test.std.ts +++ b/ts/test-node/types/Attachment_test.std.ts @@ -446,7 +446,9 @@ describe('Attachment', () => { }; const expectedAttachmentData = Bytes.fromString('Above us only sky'); - const writeNewAttachmentData = async (attachmentData: Uint8Array) => { + const writeNewAttachmentData = async ( + attachmentData: Uint8Array + ) => { assert.deepEqual(attachmentData, expectedAttachmentData); return FAKE_LOCAL_ATTACHMENT; }; diff --git a/ts/test-node/types/Message2_test.preload.ts b/ts/test-node/types/Message2_test.preload.ts index 9b608d18b2..72a8672ab3 100644 --- a/ts/test-node/types/Message2_test.preload.ts +++ b/ts/test-node/types/Message2_test.preload.ts @@ -75,7 +75,7 @@ describe('Message', () => { logger: LoggerType; }) => new Blob(), makeObjectUrl: ( - _data: Uint8Array | ArrayBuffer, + _data: Uint8Array | ArrayBuffer, _contentType: MIME.MIMEType ) => 'fake-object-url', makeVideoScreenshot: async (_params: { @@ -86,14 +86,14 @@ describe('Message', () => { revokeObjectUrl: (_objectUrl: string) => undefined, readAttachmentData: async ( attachment: Partial - ): Promise => { + ): Promise> => { assert.strictEqual(attachment.version, 2); return Buffer.from('old data'); }, - writeNewAttachmentData: async (_data: Uint8Array) => { + writeNewAttachmentData: async (_data: Uint8Array) => { return FAKE_LOCAL_ATTACHMENT; }, - writeNewStickerData: async (_data: Uint8Array) => ({ + writeNewStickerData: async (_data: Uint8Array) => ({ version: 2, path: 'fake-sticker-path', size: 1, diff --git a/ts/test-node/util/DelimitedStream_test.node.ts b/ts/test-node/util/DelimitedStream_test.node.ts index 23e787a2ad..6c124cf6f0 100644 --- a/ts/test-node/util/DelimitedStream_test.node.ts +++ b/ts/test-node/util/DelimitedStream_test.node.ts @@ -19,7 +19,7 @@ describe('DelimitedStream', () => { } async function strideTest( - data: Uint8Array, + data: Uint8Array, result: ReadonlyArray ): Promise { // Just to keep reasonable run times diff --git a/ts/test-node/util/appendMacStream_test.node.ts b/ts/test-node/util/appendMacStream_test.node.ts index 8ce974d505..8b2d6094ff 100644 --- a/ts/test-node/util/appendMacStream_test.node.ts +++ b/ts/test-node/util/appendMacStream_test.node.ts @@ -23,7 +23,7 @@ describe('appendMacStream', () => { const stream = appendMacStream(macKey); stream.end(plaintext); - const chunks = new Array(); + const chunks = new Array>(); for await (const chunk of stream) { chunks.push(chunk); } diff --git a/ts/test-node/util/prependStream_test.node.ts b/ts/test-node/util/prependStream_test.node.ts index 7d59a5f167..af1a43c23f 100644 --- a/ts/test-node/util/prependStream_test.node.ts +++ b/ts/test-node/util/prependStream_test.node.ts @@ -10,7 +10,7 @@ describe('prependStream', () => { const stream = prependStream(Buffer.from('prefix:')); stream.end('hello'); - const chunks = new Array(); + const chunks = new Array>(); for await (const chunk of stream) { chunks.push(chunk); } diff --git a/ts/test-node/util/sniffImageMimeType_test.node.ts b/ts/test-node/util/sniffImageMimeType_test.node.ts index df17821a68..7e1865102a 100644 --- a/ts/test-node/util/sniffImageMimeType_test.node.ts +++ b/ts/test-node/util/sniffImageMimeType_test.node.ts @@ -16,7 +16,7 @@ import { import { sniffImageMimeType } from '../../util/sniffImageMimeType.std.js'; describe('sniffImageMimeType', () => { - const fixture = (filename: string): Promise => { + const fixture = (filename: string): Promise> => { const fixturePath = path.join( __dirname, '..', diff --git a/ts/test-node/util/uploads/helpers.node.ts b/ts/test-node/util/uploads/helpers.node.ts index a56a3bbe24..818d8a1c1b 100644 --- a/ts/test-node/util/uploads/helpers.node.ts +++ b/ts/test-node/util/uploads/helpers.node.ts @@ -20,13 +20,14 @@ export type LastRequestData = Readonly<{ method?: string; url?: string; headers: OutgoingHttpHeaders; - body: Buffer; + body: Buffer; }>; export class TestServer extends EventEmitter { #server: Server; #nextResponse: NextResponse = { status: 200, headers: {} }; - #lastRequest: { request: IncomingMessage; body: Buffer } | null = null; + #lastRequest: { request: IncomingMessage; body: Buffer } | null = + null; constructor() { super(); @@ -107,7 +108,7 @@ export class TestServer extends EventEmitter { export function body( server: TestServer, - steps: () => AsyncIterator + steps: () => AsyncIterator, void, number> ): Readable { const iter = steps(); let first = true; diff --git a/ts/textsecure/AccountManager.preload.ts b/ts/textsecure/AccountManager.preload.ts index f28b8839cc..8eba86b092 100644 --- a/ts/textsecure/AccountManager.preload.ts +++ b/ts/textsecure/AccountManager.preload.ts @@ -153,8 +153,8 @@ type CreateAccountSharedOptionsType = Readonly<{ verificationCode: string; aciKeyPair: KeyPairType; pniKeyPair: KeyPairType; - profileKey: Uint8Array; - masterKey: Uint8Array | undefined; + profileKey: Uint8Array; + masterKey: Uint8Array | undefined; accountEntropyPool: string | undefined; }>; @@ -166,11 +166,11 @@ type CreatePrimaryDeviceOptionsType = Readonly<{ ourPni?: undefined; userAgent?: undefined; ephemeralBackupKey?: undefined; - mediaRootBackupKey: Uint8Array; + mediaRootBackupKey: Uint8Array; readReceipts: true; - accessKey: Uint8Array; + accessKey: Uint8Array; sessionId: string; }> & CreateAccountSharedOptionsType; @@ -182,8 +182,8 @@ export type CreateLinkedDeviceOptionsType = Readonly<{ ourAci: AciString; ourPni: PniString; userAgent?: string; - ephemeralBackupKey: Uint8Array | undefined; - mediaRootBackupKey: Uint8Array | undefined; + ephemeralBackupKey: Uint8Array | undefined; + mediaRootBackupKey: Uint8Array | undefined; readReceipts: boolean; @@ -252,7 +252,7 @@ function signedPreKeyToUploadSignedPreKey({ export type ConfirmNumberResultType = Readonly<{ deviceName: string; - backupFile: Uint8Array | undefined; + backupFile: Uint8Array | undefined; }>; export default class AccountManager extends EventTarget { diff --git a/ts/textsecure/ContactsParser.preload.ts b/ts/textsecure/ContactsParser.preload.ts index 3b95baa986..ec14032240 100644 --- a/ts/textsecure/ContactsParser.preload.ts +++ b/ts/textsecure/ContactsParser.preload.ts @@ -81,14 +81,14 @@ export async function parseContactsV2( // while we wait for more chunks to get to the expected avatar size. // Note: exported only for testing export class ParseContactsTransform extends DelimitedStream { - protected override getTrailerSize(frame: Buffer): number { + protected override getTrailerSize(frame: Buffer): number { const contact = Proto.ContactDetails.decode(frame); return contact.avatar?.length ?? 0; } protected override async pushFrame( - frame: Buffer, - avatarData: Buffer + frame: Buffer, + avatarData: Buffer ): Promise { const contact = Proto.ContactDetails.decode(frame); @@ -98,7 +98,7 @@ export class ParseContactsTransform extends DelimitedStream { async function prepareContact( { aci: rawAci, aciBinary, ...proto }: Proto.ContactDetails, - avatarData: Uint8Array + avatarData: Uint8Array ): Promise { const expireTimer = proto.expireTimer != null diff --git a/ts/textsecure/Errors.std.ts b/ts/textsecure/Errors.std.ts index e7480a5719..92f4988df7 100644 --- a/ts/textsecure/Errors.std.ts +++ b/ts/textsecure/Errors.std.ts @@ -168,14 +168,14 @@ export class SendMessageProtoError extends Error implements CallbackResultType { public readonly unidentifiedDeliveries?: Array; - public readonly dataMessage: Uint8Array | undefined; + public readonly dataMessage: Uint8Array | undefined; - public readonly editMessage: Uint8Array | undefined; + public readonly editMessage: Uint8Array | undefined; // Fields necessary for send log save public readonly contentHint?: number; - public readonly contentProto?: Uint8Array; + public readonly contentProto?: Uint8Array; public readonly timestamp?: number; diff --git a/ts/textsecure/MessageReceiver.preload.ts b/ts/textsecure/MessageReceiver.preload.ts index 3a935ec37a..1641b95ae5 100644 --- a/ts/textsecure/MessageReceiver.preload.ts +++ b/ts/textsecure/MessageReceiver.preload.ts @@ -189,7 +189,7 @@ type UnsealedEnvelope = Readonly< unidentifiedDeliveryReceived?: boolean; contentHint?: number; groupId?: string; - cipherTextBytes?: Uint8Array; + cipherTextBytes?: Uint8Array; cipherTextType?: number; certificate?: SenderCertificate; unsealedContent?: UnidentifiedSenderMessageContent; @@ -199,7 +199,7 @@ type UnsealedEnvelope = Readonly< type DecryptResult = Readonly< | { envelope: UnsealedEnvelope; - plaintext: Uint8Array; + plaintext: Uint8Array; } | { envelope?: UnsealedEnvelope; @@ -208,12 +208,12 @@ type DecryptResult = Readonly< >; type DecryptSealedSenderResult = Readonly<{ - plaintext: Uint8Array; + plaintext: Uint8Array; wasEncrypted: boolean; }>; type InnerDecryptResultType = Readonly<{ - plaintext: Uint8Array; + plaintext: Uint8Array; wasEncrypted: boolean; }>; @@ -999,7 +999,7 @@ export default class MessageReceiver const decrypted: Array< Readonly<{ - plaintext: Uint8Array; + plaintext: Uint8Array; data: UnprocessedType; envelope: UnsealedEnvelope; }> @@ -1207,7 +1207,7 @@ export default class MessageReceiver async #queueDecryptedEnvelope( envelope: UnsealedEnvelope, - plaintext: Uint8Array + plaintext: Uint8Array ): Promise { const id = getEnvelopeId(envelope); log.info('queueing decrypted envelope', id); @@ -1313,7 +1313,7 @@ export default class MessageReceiver // Called after `decryptEnvelope` decrypted the message. async #handleDecryptedEnvelope( envelope: UnsealedEnvelope, - plaintext: Uint8Array + plaintext: Uint8Array ): Promise { if (this.#stoppingProcessing) { return; @@ -1443,7 +1443,7 @@ export default class MessageReceiver return { plaintext: undefined, envelope }; } - let ciphertext: Uint8Array; + let ciphertext: Uint8Array; if (envelope.content) { ciphertext = envelope.content; } else { @@ -1691,7 +1691,7 @@ export default class MessageReceiver ); } - #unpad(paddedPlaintext: Uint8Array): Uint8Array { + #unpad(paddedPlaintext: Uint8Array): Uint8Array { for (let i = paddedPlaintext.length - 1; i >= 0; i -= 1) { if (paddedPlaintext[i] === 0x80) { return new Uint8Array(paddedPlaintext.subarray(0, i)); @@ -1833,7 +1833,7 @@ export default class MessageReceiver async #innerDecrypt( stores: LockedStores, envelope: UnsealedEnvelope, - ciphertext: Uint8Array, + ciphertext: Uint8Array, serviceIdKind: ServiceIdKind ): Promise { const { @@ -1959,7 +1959,7 @@ export default class MessageReceiver async #decrypt( stores: LockedStores, envelope: UnsealedEnvelope, - ciphertext: Uint8Array, + ciphertext: Uint8Array, serviceIdKind: ServiceIdKind ): Promise { const uuid = envelope.sourceServiceId; @@ -2591,7 +2591,7 @@ export default class MessageReceiver async #innerHandleContentMessage( incomingEnvelope: UnsealedEnvelope, - plaintext: Uint8Array + plaintext: Uint8Array ): Promise { const content = Proto.Content.decode(plaintext); const envelope = await this.#maybeUpdateTimestamp(incomingEnvelope); @@ -2653,7 +2653,7 @@ export default class MessageReceiver #handleDecryptionError( envelope: UnsealedEnvelope, - decryptionError: Uint8Array + decryptionError: Uint8Array ): void { const logId = getEnvelopeId(envelope); log.info(`handleDecryptionError: ${logId}`); @@ -2688,7 +2688,7 @@ export default class MessageReceiver async #handleSenderKeyDistributionMessage( stores: LockedStores, envelope: UnsealedEnvelope, - distributionMessage: Uint8Array + distributionMessage: Uint8Array ): Promise { const envelopeId = getEnvelopeId(envelope); log.info(`handleSenderKeyDistributionMessage/${envelopeId}`); diff --git a/ts/textsecure/OutgoingMessage.preload.ts b/ts/textsecure/OutgoingMessage.preload.ts index 17619a076d..19a5156fe8 100644 --- a/ts/textsecure/OutgoingMessage.preload.ts +++ b/ts/textsecure/OutgoingMessage.preload.ts @@ -112,7 +112,9 @@ function getPaddedMessageLength(messageLength: number): number { return messagePartCount * PADDING_BLOCK; } -export function padMessage(messageBuffer: Uint8Array): Uint8Array { +export function padMessage( + messageBuffer: Uint8Array +): Uint8Array { const plaintext = new Uint8Array( getPaddedMessageLength(messageBuffer.byteLength + 1) - 1 ); @@ -131,7 +133,7 @@ export default class OutgoingMessage { callback: (result: CallbackResultType) => void; - plaintext?: Uint8Array; + plaintext?: Uint8Array; serviceIdsCompleted: number; @@ -210,8 +212,8 @@ export default class OutgoingMessage { const proto = this.message; const contentProto = this.getContentProtoBytes(); const { timestamp, contentHint, recipients, urgent } = this; - let dataMessage: Uint8Array | undefined; - let editMessage: Uint8Array | undefined; + let dataMessage: Uint8Array | undefined; + let editMessage: Uint8Array | undefined; let hasPniSignatureMessage = false; if (!(proto instanceof PlaintextContent)) { @@ -355,7 +357,7 @@ export default class OutgoingMessage { }); } - getPlaintext(): Uint8Array { + getPlaintext(): Uint8Array { if (!this.plaintext) { const { message } = this; @@ -368,7 +370,7 @@ export default class OutgoingMessage { return this.plaintext; } - getContentProtoBytes(): Uint8Array | undefined { + getContentProtoBytes(): Uint8Array | undefined { if (this.message instanceof PlaintextContent) { return undefined; } diff --git a/ts/textsecure/ProvisioningCipher.node.ts b/ts/textsecure/ProvisioningCipher.node.ts index f3049a826e..4beb56a4c2 100644 --- a/ts/textsecure/ProvisioningCipher.node.ts +++ b/ts/textsecure/ProvisioningCipher.node.ts @@ -39,11 +39,11 @@ export type ProvisionDecryptResult = Readonly<{ provisioningCode?: string; userAgent?: string; readReceipts?: boolean; - profileKey?: Uint8Array; - masterKey?: Uint8Array; + profileKey?: Uint8Array; + masterKey?: Uint8Array; accountEntropyPool: string | undefined; - mediaRootBackupKey: Uint8Array | undefined; - ephemeralBackupKey: Uint8Array | undefined; + mediaRootBackupKey: Uint8Array | undefined; + ephemeralBackupKey: Uint8Array | undefined; }>; class ProvisioningCipherInner { diff --git a/ts/textsecure/SendMessage.preload.ts b/ts/textsecure/SendMessage.preload.ts index fd68d379c5..a59cda14a6 100644 --- a/ts/textsecure/SendMessage.preload.ts +++ b/ts/textsecure/SendMessage.preload.ts @@ -161,8 +161,8 @@ export type OutgoingTextAttachmentType = Omit & { }; export type GroupV2InfoType = { - groupChange?: Uint8Array; - masterKey: Uint8Array; + groupChange?: Uint8Array; + masterKey: Uint8Array; revision: number; members: ReadonlyArray; }; @@ -221,7 +221,7 @@ export type SharedMessageOptionsType = Readonly<{ pinMessage?: SendPinMessageType; pollCreate?: PollCreateType; preview?: ReadonlyArray; - profileKey?: Uint8Array; + profileKey?: Uint8Array; quote?: OutgoingQuoteType; reaction?: ReactionType; sticker?: OutgoingStickerType; @@ -285,7 +285,7 @@ class Message { preview?: ReadonlyArray; - profileKey?: Uint8Array; + profileKey?: Uint8Array; quote?: OutgoingQuoteType; @@ -775,7 +775,7 @@ export class MessageSender { // Attachment upload functions - static getRandomPadding(): Uint8Array { + static getRandomPadding(): Uint8Array { // Generate a random int from 1 and 512 const buffer = getRandomBytes(2); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -836,7 +836,7 @@ export class MessageSender { async getDataOrEditMessage( options: Readonly - ): Promise { + ): Promise> { const message = await this.getHydratedMessage(options); const dataMessage = message.toProto(); @@ -909,7 +909,7 @@ export class MessageSender { expireTimer, expireTimerVersion, pollVote, - }: PollVoteBuildOptions): Promise { + }: PollVoteBuildOptions): Promise> { const proto = this.createDataMessageProtoForPollVote({ groupV2, timestamp, @@ -1031,7 +1031,7 @@ export class MessageSender { bodyRanges?: Array; fileAttachment?: UploadedAttachmentType; groupV2?: GroupV2InfoType; - profileKey: Uint8Array; + profileKey: Uint8Array; textAttachment?: OutgoingTextAttachmentType; }): Promise { let attachment: Proto.StoryMessage.Params['attachment']; @@ -1123,7 +1123,7 @@ export class MessageSender { getTypingContentMessage( options: Readonly<{ recipientId?: ServiceIdString; - groupId?: Uint8Array; + groupId?: Uint8Array; groupMembers: ReadonlyArray; isTyping: boolean; timestamp?: number; @@ -1505,8 +1505,8 @@ export class MessageSender { storyMessage, storyMessageRecipients, }: Readonly<{ - encodedDataMessage?: Uint8Array; - encodedEditMessage?: Uint8Array; + encodedDataMessage?: Uint8Array; + encodedEditMessage?: Uint8Array; timestamp: number; destinationE164: string | undefined; destinationServiceId: ServiceIdString | undefined; @@ -1547,7 +1547,7 @@ export class MessageSender { ): Promise => { const conv = window.ConversationController.get(conversationId); const serviceId = conv?.getServiceId(); - let destinationPniIdentityKey: Uint8Array | null = null; + let destinationPniIdentityKey: Uint8Array | null = null; if (conv) { if (isPniString(serviceId)) { const pniIdentityKey = @@ -2221,7 +2221,7 @@ export class MessageSender { options: Readonly<{ e164s: Array; acis: Array; - groupIds: Array; + groupIds: Array>; }> ): SingleProtoJobData { const myAci = itemStorage.user.getCheckedAci(); @@ -2267,7 +2267,7 @@ export class MessageSender { static getMessageRequestResponseSync( options: Readonly<{ threadAci?: AciString; - groupId?: Uint8Array; + groupId?: Uint8Array; type: number; }> ): SingleProtoJobData { @@ -2362,7 +2362,7 @@ export class MessageSender { destinationE164: string | undefined, destinationAci: AciString | undefined, state: number, - identityKey: Readonly + identityKey: Readonly> ): SingleProtoJobData { const myAci = itemStorage.user.getCheckedAci(); @@ -2540,7 +2540,7 @@ export class MessageSender { static getNullMessage( options: Readonly<{ - padding?: Uint8Array; + padding?: Uint8Array; }> = {} ): Proto.Content.Params { return { @@ -2570,7 +2570,7 @@ export class MessageSender { }: Readonly<{ contentHint: number; messageId?: string; - proto: Uint8Array; + proto: Uint8Array; sendType: SendTypesType; timestamp: number; urgent: boolean; diff --git a/ts/textsecure/SocketManager.preload.ts b/ts/textsecure/SocketManager.preload.ts index 0d3b09a15b..67b29f7de1 100644 --- a/ts/textsecure/SocketManager.preload.ts +++ b/ts/textsecure/SocketManager.preload.ts @@ -414,10 +414,10 @@ export class SocketManager extends EventListener { const { method = 'GET', body, timeout, signal } = init; - let bodyBytes: Uint8Array | undefined; + let bodyBytes: Uint8Array | undefined; if (body === undefined) { bodyBytes = undefined; - } else if (body instanceof Uint8Array) { + } else if (Bytes.isNonSharedUint8Array(body)) { bodyBytes = body; } else if (body instanceof ArrayBuffer) { throw new Error('Unsupported body type: ArrayBuffer'); diff --git a/ts/textsecure/Types.d.ts b/ts/textsecure/Types.d.ts index 6ae028d15f..53f3af3f25 100644 --- a/ts/textsecure/Types.d.ts +++ b/ts/textsecure/Types.d.ts @@ -59,7 +59,7 @@ export type DeviceType = { export type CompatSignedPreKeyType = { keyId: number; keyPair: KeyPairType; - signature: Uint8Array; + signature: Uint8Array; }; export type CompatPreKeyType = { @@ -76,8 +76,8 @@ export type OuterSignedPrekeyType = { created_at: number; keyId: number; - privKey: Uint8Array; - pubKey: Uint8Array; + privKey: Uint8Array; + pubKey: Uint8Array; }; export type SessionResetsType = Record; @@ -96,13 +96,13 @@ export type ProcessedEnvelope = Readonly<{ destinationServiceId: ServiceIdString; updatedPni: PniString | undefined; timestamp: number; - content: Uint8Array; + content: Uint8Array; serverGuid: string; serverTimestamp: number; groupId: string | undefined; urgent: boolean; story: boolean; - reportingToken: Uint8Array | undefined; + reportingToken: Uint8Array | undefined; groupId: string | undefined; }>; @@ -277,7 +277,7 @@ export type ProcessedDataMessage = { export type ProcessedUnidentifiedDeliveryStatus = Readonly<{ destinationServiceId?: ServiceIdString; isAllowedToReplyToStory?: boolean; - destinationPniIdentityKey?: Uint8Array; + destinationPniIdentityKey?: Uint8Array; unidentified?: boolean; }>; @@ -306,8 +306,8 @@ export type CallbackResultType = { failoverServiceIds?: Array; errors?: Array; unidentifiedDeliveries?: Array; - dataMessage: Uint8Array | undefined; - editMessage: Uint8Array | undefined; + dataMessage: Uint8Array | undefined; + editMessage: Uint8Array | undefined; // If this send is not the final step in a multi-step send, we shouldn't treat its // results we would treat a one-step send. @@ -315,7 +315,7 @@ export type CallbackResultType = { // Fields necessary for send log save contentHint?: number; - contentProto?: Uint8Array; + contentProto?: Uint8Array; timestamp?: number; recipients?: Record>; urgent?: boolean; @@ -328,13 +328,13 @@ export type IRequestHandler = { }; export type PniKeyMaterialType = Readonly<{ - identityKeyPair: Uint8Array; - signedPreKey: Uint8Array; - lastResortKyberPreKey?: Uint8Array; + identityKeyPair: Uint8Array; + signedPreKey: Uint8Array; + lastResortKyberPreKey?: Uint8Array; registrationId: number; }>; export type PniSignatureMessageType = Readonly<{ pni: PniString; - signature: Uint8Array; + signature: Uint8Array; }>; diff --git a/ts/textsecure/WebAPI.preload.ts b/ts/textsecure/WebAPI.preload.ts index 9917b170e3..47ab9803f3 100644 --- a/ts/textsecure/WebAPI.preload.ts +++ b/ts/textsecure/WebAPI.preload.ts @@ -219,7 +219,7 @@ type PromiseAjaxOptionsType = { certificateAuthority?: string; chatServiceUrl?: string; contentType?: string; - data?: Uint8Array | (() => Readable) | string; + data?: Uint8Array | (() => Readable) | string; disableRetries?: boolean; disableSessionResumption?: boolean; headers?: HeaderListType; @@ -264,7 +264,7 @@ type JSONWithDetailsType = { response: Response; }; type BytesWithDetailsType = { - data: Uint8Array; + data: Uint8Array; contentType: string | null; response: Response; }; @@ -511,7 +511,7 @@ async function _promiseAjax( } } - let result: string | Uint8Array | Readable | unknown; + let result: string | Uint8Array | Readable | unknown; try { if (DEBUG && !isSuccess(response.status)) { result = await response.text(); @@ -623,7 +623,10 @@ async function _promiseAjax( log.info(logId, response.status, 'Success'); if (options.responseType === 'byteswithdetails') { - assertDev(result instanceof Uint8Array, 'Expected Uint8Array result'); + assertDev( + Bytes.isNonSharedUint8Array(result), + 'Expected Uint8Array result' + ); const fullResult: BytesWithDetailsType = { data: result, contentType: getContentType(response), @@ -684,7 +687,7 @@ async function _retry( type OuterAjaxReturnType = { json: Promise; jsonwithdetails: Promise>; - bytes: Promise; + bytes: Promise>; byteswithdetails: Promise; stream: Promise; streamwithdetails: Promise; @@ -849,7 +852,7 @@ type AjaxOptionsType = ( | AjaxChatOptionsType ) & { contentType?: string; - data?: Buffer | Uint8Array | string; + data?: Buffer | Uint8Array | string; headers?: HeaderListType; httpType: HTTPCodeType; jsonData?: unknown; @@ -872,7 +875,7 @@ export type WebAPIConnectOptionsType = WebAPICredentials & { hasBuildExpired: boolean; }; -type StickerPackManifestType = Uint8Array; +type StickerPackManifestType = Uint8Array; export type GroupCredentialType = { credential: string; @@ -895,7 +898,7 @@ export type GetGroupLogOptionsType = Readonly<{ }>; export type GroupLogResponseType = { changes: Proto.GroupChanges; - groupSendEndorsementsResponse: Uint8Array | null; + groupSendEndorsementsResponse: Uint8Array | null; } & ( | { paginated: false; @@ -968,7 +971,7 @@ export type ProfileType = Readonly<{ }>; export type GetAccountForUsernameOptionsType = Readonly<{ - hash: Uint8Array; + hash: Uint8Array; }>; export type GetAccountForUsernameResultType = AciString | null; @@ -1045,19 +1048,19 @@ export type VerifyServiceIdResponseType = z.infer< >; export type ReserveUsernameOptionsType = Readonly<{ - hashes: ReadonlyArray; + hashes: ReadonlyArray>; abortSignal?: AbortSignal; }>; export type ReplaceUsernameLinkOptionsType = Readonly<{ - encryptedUsername: Uint8Array; + encryptedUsername: Uint8Array; keepLinkHandle: boolean; }>; export type ConfirmUsernameOptionsType = Readonly<{ - hash: Uint8Array; - proof: Uint8Array; - encryptedUsername: Uint8Array; + hash: Uint8Array; + proof: Uint8Array; + encryptedUsername: Uint8Array; abortSignal?: AbortSignal; }>; @@ -1085,12 +1088,12 @@ export type ReplaceUsernameLinkResultType = z.infer< >; export type ResolveUsernameByLinkOptionsType = Readonly<{ - entropy: Uint8Array; + entropy: Uint8Array; uuid: string; }>; export type ResolveUsernameLinkResultType = { username: string; - hash: Uint8Array; + hash: Uint8Array; } | null; export type CreateAccountOptionsType = Readonly<{ @@ -1100,7 +1103,7 @@ export type CreateAccountOptionsType = Readonly<{ newPassword: string; registrationId: number; pniRegistrationId: number; - accessKey: Uint8Array; + accessKey: Uint8Array; aciPublicKey: PublicKey; pniPublicKey: PublicKey; aciSignedPreKey: UploadSignedPreKeyType; @@ -1281,13 +1284,13 @@ export type RequestVerificationResultType = Readonly<{ }>; export type SetBackupIdOptionsType = Readonly<{ - messagesBackupAuthCredentialRequest: Uint8Array; - mediaBackupAuthCredentialRequest: Uint8Array; + messagesBackupAuthCredentialRequest: Uint8Array; + mediaBackupAuthCredentialRequest: Uint8Array; }>; export type SetBackupSignatureKeyOptionsType = Readonly<{ headers: BackupPresentationHeadersType; - backupIdPublicKey: Uint8Array; + backupIdPublicKey: Uint8Array; }>; export type UploadBackupOptionsType = Readonly<{ @@ -1302,8 +1305,8 @@ export type BackupMediaItemType = Readonly<{ }>; objectLength: number; mediaId: string; - hmacKey: Uint8Array; - encryptionKey: Uint8Array; + hmacKey: Uint8Array; + encryptionKey: Uint8Array; }>; export type BackupMediaBatchOptionsType = Readonly<{ @@ -1505,7 +1508,7 @@ export type ReleaseNotesManifestResponseType = z.infer< >; export type GetReleaseNoteImageAttachmentResultType = Readonly<{ - imageData: Uint8Array; + imageData: Uint8Array; contentType: string | null; }>; @@ -1609,7 +1612,7 @@ export type SubscriptionResponseType = z.infer< export type UploadSignedPreKeyType = { keyId: number; publicKey: PublicKey; - signature: Uint8Array; + signature: Uint8Array; }; export type UploadPreKeyType = { keyId: number; @@ -1618,7 +1621,7 @@ export type UploadPreKeyType = { export type UploadKyberPreKeyType = { keyId: number; publicKey: KEMPublicKey; - signature: Uint8Array; + signature: Uint8Array; }; type SerializedSignedPreKeyType = Readonly<{ @@ -1677,20 +1680,20 @@ export type ServerKeysType = { // We'll get a 404 if none of these keys are provided; we'll have at least one preKey?: { keyId: number; - publicKey: Uint8Array; + publicKey: Uint8Array; }; signedPreKey?: { keyId: number; - publicKey: Uint8Array; - signature: Uint8Array; + publicKey: Uint8Array; + signature: Uint8Array; }; pqPreKey?: { keyId: number; - publicKey: Uint8Array; - signature: Uint8Array; + publicKey: Uint8Array; + signature: Uint8Array; }; }>; - identityKey: Uint8Array; + identityKey: Uint8Array; }; export type ChallengeType = { @@ -1841,7 +1844,9 @@ const fetchForLinkPreviews: linkPreviewFetch.FetchFn = async (href, init) => { return fetch(href, { ...init, agent: fetchAgent }); }; -function _ajax(param: AjaxOptionsType<'bytes', never>): Promise; +function _ajax( + param: AjaxOptionsType<'bytes', never> +): Promise>; function _ajax( param: AjaxOptionsType<'byteswithdetails', never> ): Promise; @@ -2275,7 +2280,7 @@ export async function getReleaseNoteImageAttachment( export async function getStorageManifest( options: StorageServiceCallOptionsType = {} -): Promise { +): Promise> { const { credentials, greaterThanVersion } = options; const { data, response } = await _ajax({ @@ -2302,9 +2307,9 @@ export async function getStorageManifest( } export async function getStorageRecords( - data: Uint8Array, + data: Uint8Array, options: StorageServiceCallOptionsType = {} -): Promise { +): Promise> { const { credentials } = options; return _ajax({ @@ -2319,9 +2324,9 @@ export async function getStorageRecords( } export async function modifyStorageRecords( - data: Uint8Array, + data: Uint8Array, options: StorageServiceCallOptionsType = {} -): Promise { +): Promise> { const { credentials } = options; return _ajax({ @@ -2578,7 +2583,7 @@ export async function getProfileUnauth( export async function getBadgeImageFile( imageFileUrl: string -): Promise { +): Promise> { strictAssert( isBadgeImageFileUrlValid(imageFileUrl, updatesUrl), 'getBadgeImageFile got an invalid URL. Was bad data saved?' @@ -2607,7 +2612,7 @@ export async function getBadgeImageFile( export async function downloadOnboardingStories( manifestVersion: string, imageFiles: Array -): Promise> { +): Promise>> { return Promise.all( imageFiles.map(fileName => _outerAjax( @@ -2636,7 +2641,9 @@ export async function getSubscriptionConfiguration(): Promise { +export async function getAvatar( + path: string +): Promise> { // Using _outerAJAX, since it's not hardcoded to the Signal Server. Unlike our // attachment CDN, it uses our self-signed certificate, so we pass it in. return _outerAjax(`${cdnUrlObject['0']}/${path}`, { @@ -2895,11 +2902,11 @@ export async function createAccount({ function asSignedKey(key: { keyId: number; publicKey: K; - signature: Uint8Array; + signature: Uint8Array; }): { id: () => number; publicKey: () => K; - signature: () => Uint8Array; + signature: () => Uint8Array; } { return { id: () => key.keyId, @@ -3640,7 +3647,7 @@ function booleanToString(value: boolean | undefined): string { } export async function sendMulti( - payload: Uint8Array, + payload: Uint8Array, groupSendToken: GroupSendToken | null, timestamp: number, { @@ -3684,8 +3691,8 @@ export async function sendMulti( } export async function sendMultiLegacy( - data: Uint8Array, - accessKeys: Uint8Array | null, + data: Uint8Array, + accessKeys: Uint8Array | null, groupSendToken: GroupSendToken | null, timestamp: number, { @@ -3743,7 +3750,7 @@ function redactStickerUrl(stickerUrl: string): string { export async function getSticker( packId: string, stickerId: number -): Promise { +): Promise> { if (!isPackIdValid(packId)) { throw new Error('getSticker: pack ID was invalid'); } @@ -3796,7 +3803,7 @@ function makePutParams( policy, signature, }: ServerV2AttachmentType, - encryptedBin: Uint8Array + encryptedBin: Uint8Array ) { // Note: when using the boundary string in the POST body, it needs to be prefixed by // an extra --, and the final boundary string at the end gets a -- prefix and a -- @@ -3841,8 +3848,8 @@ function makePutParams( } export async function putStickers( - encryptedManifest: Uint8Array, - encryptedStickers: ReadonlyArray, + encryptedManifest: Uint8Array, + encryptedStickers: ReadonlyArray>, onProgress?: () => void ): Promise { // Get manifest and sticker upload parameters @@ -4280,7 +4287,7 @@ export async function makeSfuRequest( targetUrl: string, type: HTTPCodeType, headers: HeaderListType, - body: Uint8Array | undefined + body: Uint8Array | undefined ): Promise { return _outerAjax(targetUrl, { certificateAuthority, @@ -4380,7 +4387,7 @@ function verifyAttributes(attributes: Proto.AvatarUploadAttributes.Params) { export async function uploadAvatar( uploadAvatarRequestHeaders: UploadAvatarHeadersType, - avatarData: Uint8Array + avatarData: Uint8Array ): Promise { const verified = verifyAttributes(uploadAvatarRequestHeaders); const { key } = verified; @@ -4401,7 +4408,7 @@ export async function uploadAvatar( } export async function uploadGroupAvatar( - avatarData: Uint8Array, + avatarData: Uint8Array, options: GroupCredentialsType ): Promise { const basicAuth = generateGroupAuth( @@ -4437,7 +4444,9 @@ export async function uploadGroupAvatar( return key; } -export async function getGroupAvatar(key: string): Promise { +export async function getGroupAvatar( + key: string +): Promise> { return _outerAjax(`${cdnUrlObject['0']}/${key}`, { certificateAuthority, proxyUrl, @@ -4788,7 +4797,7 @@ export async function getGroupLog( } export async function getSubscription( - subscriberId: Uint8Array + subscriberId: Uint8Array ): Promise { const formattedId = toWebSafeBase64(Bytes.toBase64(subscriberId)); return _ajax({ @@ -4806,7 +4815,7 @@ export async function getSubscription( } export async function getHasSubscription( - subscriberId: Uint8Array + subscriberId: Uint8Array ): Promise { const data = await getSubscription(subscriberId); if (!data.subscription) { diff --git a/ts/textsecure/WebsocketResources.preload.ts b/ts/textsecure/WebsocketResources.preload.ts index b2a1f6b0de..e4c9122242 100644 --- a/ts/textsecure/WebsocketResources.preload.ts +++ b/ts/textsecure/WebsocketResources.preload.ts @@ -157,7 +157,7 @@ export enum ServerRequestType { export class IncomingWebSocketRequest { constructor( readonly requestType: ServerRequestType, - readonly body: Uint8Array | undefined, + readonly body: Uint8Array | undefined, readonly timestamp: number | undefined, private readonly ack: Pick | undefined ) {} @@ -170,7 +170,7 @@ export class IncomingWebSocketRequest { export type SendRequestOptions = Readonly<{ verb: string; path: string; - body?: Uint8Array; + body?: Uint8Array; timeout?: number; headers?: ReadonlyArray<[string, string]>; }>; @@ -178,7 +178,7 @@ export type SendRequestOptions = Readonly<{ export type SendRequestResult = Readonly<{ status: number; message: string; - response?: Uint8Array; + response?: Uint8Array; headers: ReadonlyArray; }>; @@ -287,7 +287,7 @@ export function connectAuthenticated({ const listener: WebSocketResourceHandler<'auth'> & ChatServiceListener = { resource: undefined, onIncomingMessage( - envelope: Uint8Array, + envelope: Uint8Array, timestamp: number, ack: ChatServerMessageAck ): void { diff --git a/ts/textsecure/messageReceiverEvents.std.ts b/ts/textsecure/messageReceiverEvents.std.ts index c346c1d509..0c3a1e3603 100644 --- a/ts/textsecure/messageReceiverEvents.std.ts +++ b/ts/textsecure/messageReceiverEvents.std.ts @@ -144,7 +144,7 @@ export class SuccessfulDecryptEvent extends Event { } export type DecryptionErrorEventData = Readonly<{ - cipherTextBytes: Uint8Array | undefined; + cipherTextBytes: Uint8Array | undefined; cipherTextType: number | undefined; contentHint: number | undefined; groupId: string | undefined; @@ -387,15 +387,15 @@ export class FetchLatestEvent extends ConfirmableEvent { } export type KeysEventData = Readonly<{ - masterKey: Uint8Array | undefined; + masterKey: Uint8Array | undefined; accountEntropyPool: string | undefined; - mediaRootBackupKey: Uint8Array | undefined; + mediaRootBackupKey: Uint8Array | undefined; }>; export class KeysEvent extends ConfirmableEvent { - public readonly masterKey: Uint8Array | undefined; + public readonly masterKey: Uint8Array | undefined; public readonly accountEntropyPool: string | undefined; - public readonly mediaRootBackupKey: Uint8Array | undefined; + public readonly mediaRootBackupKey: Uint8Array | undefined; constructor( { masterKey, accountEntropyPool, mediaRootBackupKey }: KeysEventData, @@ -478,8 +478,8 @@ export class CallEventSyncEvent extends ConfirmableEvent { export type CallLinkUpdateSyncEventData = Readonly<{ type: CallLinkUpdateSyncType; - rootKey: Uint8Array | undefined; - adminKey: Uint8Array | undefined; + rootKey: Uint8Array | undefined; + adminKey: Uint8Array | undefined; }>; export class CallLinkUpdateSyncEvent extends ConfirmableEvent { diff --git a/ts/textsecure/processSyncMessage.node.ts b/ts/textsecure/processSyncMessage.node.ts index 8389ce32dc..c3291f78f7 100644 --- a/ts/textsecure/processSyncMessage.node.ts +++ b/ts/textsecure/processSyncMessage.node.ts @@ -9,7 +9,7 @@ import type { ProcessedSent } from './Types.d.ts'; type ProtoServiceId = Readonly<{ destinationServiceId?: string | null; - destinationServiceIdBinary?: Uint8Array | null; + destinationServiceIdBinary?: Uint8Array | null; }>; function processProtoWithDestinationServiceId( diff --git a/ts/textsecure/storage/Blocked.std.ts b/ts/textsecure/storage/Blocked.std.ts index ab30902d13..f39c933bd5 100644 --- a/ts/textsecure/storage/Blocked.std.ts +++ b/ts/textsecure/storage/Blocked.std.ts @@ -109,7 +109,7 @@ export class Blocked { public getBlockedData(): { e164s: Array; acis: Array; - groupIds: Array; + groupIds: Array>; } { const e164s = this.getBlockedNumbers(); const acis = this.getBlockedServiceIds().filter(item => isAciString(item)); diff --git a/ts/types/Attachment.std.ts b/ts/types/Attachment.std.ts index 72ca2114b1..5a351e339d 100644 --- a/ts/types/Attachment.std.ts +++ b/ts/types/Attachment.std.ts @@ -27,13 +27,13 @@ export type BackupThumbnailType = WithOptionalProperties; // These fields do not get saved to the DB. export type EphemeralAttachmentFields = { totalDownloaded?: number; - data?: Uint8Array; + data?: Uint8Array; /** Not included in protobuf, needs to be pulled from flags */ isVoiceMessage?: boolean; /** For messages not already on disk, this will be a data url */ url?: string; incrementalUrl?: string; - screenshotData?: Uint8Array; + screenshotData?: Uint8Array; /** @deprecated Legacy field */ screenshotPath?: string; @@ -116,7 +116,7 @@ export type AddressableAttachmentType = Readonly<{ contentType: MIMEType; // In-memory data, for outgoing attachments that are not saved to disk. - data?: Uint8Array; + data?: Uint8Array; }>; export type AttachmentForUIType = AttachmentType & { @@ -135,15 +135,15 @@ export type UploadedAttachmentType = Omit< attachmentIdentifier: Readonly<{ cdnKey: string; }>; - key: Uint8Array; + key: Uint8Array; size: number; - digest: Uint8Array; + digest: Uint8Array; contentType: string; plaintextHash: string; }>; export type AttachmentWithHydratedData = AttachmentType & { - data: Uint8Array; + data: Uint8Array; }; export enum TextAttachmentStyleType { @@ -183,10 +183,10 @@ export type BaseAttachmentDraftType = { // a draft and final save on disk and in conversation.draftAttachments. export type InMemoryAttachmentDraftType = | ({ - data: Uint8Array; + data: Uint8Array; clientUuid: string; pending: false; - screenshotData?: Uint8Array; + screenshotData?: Uint8Array; duration?: number; fileName?: string; path?: string; diff --git a/ts/types/Avatar.std.ts b/ts/types/Avatar.std.ts index 8620cc99f7..200e01f6b1 100644 --- a/ts/types/Avatar.std.ts +++ b/ts/types/Avatar.std.ts @@ -57,7 +57,7 @@ export type AvatarIconType = GroupAvatarIconType | PersonalAvatarIconType; export type AvatarDataType = { id: number | string; - buffer?: Uint8Array; + buffer?: Uint8Array; color?: AvatarColorType; icon?: AvatarIconType; text?: string; @@ -86,8 +86,8 @@ export type SaveAvatarToDiskActionType = ( ) => unknown; export type AvatarUpdateType = Readonly<{ - oldAvatar: Uint8Array | undefined; - newAvatar: Uint8Array | undefined; + oldAvatar: Uint8Array | undefined; + newAvatar: Uint8Array | undefined; }>; export type AvatarUpdateOptionsType = Readonly< diff --git a/ts/types/CallLink.std.ts b/ts/types/CallLink.std.ts index 8f820806a9..9948f4f537 100644 --- a/ts/types/CallLink.std.ts +++ b/ts/types/CallLink.std.ts @@ -14,8 +14,8 @@ export enum CallLinkUpdateSyncType { } export type CallLinkUpdateData = Readonly<{ - rootKey: Uint8Array; - adminKey: Uint8Array | undefined; + rootKey: Uint8Array; + adminKey: Uint8Array | undefined; }>; /** @@ -100,11 +100,11 @@ export type DefunctCallLinkType = Readonly<{ export type DefunctCallLinkRecord = Readonly<{ roomId: string; - rootKey: Uint8Array; - adminKey: Uint8Array | null; + rootKey: Uint8Array; + adminKey: Uint8Array | null; storageID: string | null; storageVersion: number | null; - storageUnknownFields: Uint8Array | null; + storageUnknownFields: Uint8Array | null; storageNeedsSync: 1 | 0; }>; @@ -121,8 +121,8 @@ export const defunctCallLinkRecordSchema = z.object({ // DB Record export type CallLinkRecord = Readonly<{ roomId: string; - rootKey: Uint8Array | null; - adminKey: Uint8Array | null; + rootKey: Uint8Array | null; + adminKey: Uint8Array | null; name: string; restrictions: number; expiration: number | null; @@ -131,7 +131,7 @@ export type CallLinkRecord = Readonly<{ deletedAt?: number | null; storageID: string | null; storageVersion: number | null; - storageUnknownFields: Uint8Array | null; + storageUnknownFields: Uint8Array | null; storageNeedsSync: 1 | 0; }>; diff --git a/ts/types/CallQualitySurvey.std.ts b/ts/types/CallQualitySurvey.std.ts index 316c142e6e..314da94a3a 100644 --- a/ts/types/CallQualitySurvey.std.ts +++ b/ts/types/CallQualitySurvey.std.ts @@ -40,7 +40,7 @@ export namespace CallQualitySurvey { rttMedian: number | null; jitterMedian: number | null; packetLossFraction: number | null; - callTelemetry: Uint8Array | null; + callTelemetry: Uint8Array | null; }>; export type Form = Readonly<{ diff --git a/ts/types/ChatFolder.std.ts b/ts/types/ChatFolder.std.ts index dd00fba458..48b191e83c 100644 --- a/ts/types/ChatFolder.std.ts +++ b/ts/types/ChatFolder.std.ts @@ -46,7 +46,7 @@ export type ChatFolder = Simplify< deletedAtTimestampMs: number; storageID: string | null; storageVersion: number | null; - storageUnknownFields: Uint8Array | null; + storageUnknownFields: Uint8Array | null; storageNeedsSync: boolean; } > diff --git a/ts/types/GroupSendEndorsements.std.ts b/ts/types/GroupSendEndorsements.std.ts index 4b0949bd59..aea7b29fd6 100644 --- a/ts/types/GroupSendEndorsements.std.ts +++ b/ts/types/GroupSendEndorsements.std.ts @@ -15,7 +15,7 @@ export type GroupSendCombinedEndorsementRecord = Readonly<{ groupId: string; /** Unix timestamp in seconds */ expiration: number; - endorsement: Uint8Array; + endorsement: Uint8Array; }>; /** @@ -33,7 +33,7 @@ export type GroupSendMemberEndorsementRecord = Readonly<{ memberAci: AciString; /** Unix timestamp in seconds */ expiration: number; - endorsement: Uint8Array; + endorsement: Uint8Array; }>; /** @@ -94,6 +94,8 @@ export const groupSendTokenSchema = z export type GroupSendToken = z.infer; -export function toGroupSendToken(token: Uint8Array): GroupSendToken { +export function toGroupSendToken( + token: Uint8Array +): GroupSendToken { return parseStrict(groupSendTokenSchema, token); } diff --git a/ts/types/Message2.preload.ts b/ts/types/Message2.preload.ts index 7106d3c68b..fc6b07abab 100644 --- a/ts/types/Message2.preload.ts +++ b/ts/types/Message2.preload.ts @@ -92,7 +92,7 @@ export type ContextType = { logger: LoggerType; }) => Promise; makeObjectUrl: ( - data: Uint8Array | ArrayBuffer, + data: Uint8Array | ArrayBuffer, contentType: MIME.MIMEType ) => string; makeVideoScreenshot: (params: { @@ -104,9 +104,13 @@ export type ContextType = { revokeObjectUrl: (objectUrl: string) => void; readAttachmentData: ( attachment: Partial - ) => Promise; - writeNewAttachmentData: (data: Uint8Array) => Promise; - writeNewStickerData: (data: Uint8Array) => Promise; + ) => Promise>; + writeNewAttachmentData: ( + data: Uint8Array + ) => Promise; + writeNewStickerData: ( + data: Uint8Array + ) => Promise; maybeDeleteAttachmentFile: (path: string) => Promise<{ wasDeleted: boolean }>; getExistingAttachmentDataForReuse: typeof getExistingAttachmentDataForReuse; }; @@ -845,7 +849,7 @@ export const processNewAttachment = async ( }; export const processNewSticker = async ( - stickerData: Uint8Array, + stickerData: Uint8Array, isEphemeral: boolean, { writeNewStickerData, diff --git a/ts/types/Stickers.preload.ts b/ts/types/Stickers.preload.ts index 74f077949a..483590cdd1 100644 --- a/ts/types/Stickers.preload.ts +++ b/ts/types/Stickers.preload.ts @@ -444,7 +444,10 @@ function getReduxStickerActions() { return actions.stickers; } -function decryptSticker(packKey: string, ciphertext: Uint8Array): Uint8Array { +function decryptSticker( + packKey: string, + ciphertext: Uint8Array +): Uint8Array { const binaryKey = Bytes.fromBase64(packKey); const derivedKey = deriveStickerPackKey(binaryKey); diff --git a/ts/types/StorageKeys.std.ts b/ts/types/StorageKeys.std.ts index 356ffe2e81..8eb0cf0cd0 100644 --- a/ts/types/StorageKeys.std.ts +++ b/ts/types/StorageKeys.std.ts @@ -39,7 +39,7 @@ export type AutoDownloadAttachmentType = { export type SerializedCertificateType = { expires: number; - serialized: Uint8Array; + serialized: Uint8Array; }; export type ZoomFactorType = 0.75 | 1 | 1.25 | 1.5 | 2 | number; @@ -51,8 +51,8 @@ export type NotificationSettingType = 'message' | 'name' | 'count' | 'off'; export type IdentityKeyMap = Record< ServiceIdString, { - privKey: Uint8Array; - pubKey: Uint8Array; + privKey: Uint8Array; + pubKey: Uint8Array; } >; @@ -111,7 +111,7 @@ export type StorageAccessType = { maxKyberPreKeyIdPNI: number; number_id: string; password: string; - profileKey: Uint8Array; + profileKey: Uint8Array; regionCode: string; registrationIdMap: Record; remoteBuildExpiration: number; @@ -147,7 +147,7 @@ export type StorageAccessType = { storageFetchComplete: boolean; avatarUrl: string | undefined; manifestVersion: number; - manifestRecordIkm: Uint8Array; + manifestRecordIkm: Uint8Array; storageCredentials: StorageServiceCredentials; 'storage-service-error-records': ReadonlyArray; 'storage-service-unknown-records': ReadonlyArray; @@ -163,7 +163,7 @@ export type StorageAccessType = { callLinkAuthCredentials: ReadonlyArray; backupCombinedCredentials: ReadonlyArray; backupCombinedCredentialsLastRequestTime: number; - backupMediaRootKey: Uint8Array; + backupMediaRootKey: Uint8Array; backupMediaDownloadTotalBytes: number; backupMediaDownloadCompletedBytes: number; backupMediaDownloadPaused: boolean; @@ -188,11 +188,11 @@ export type StorageAccessType = { nextScheduledUpdateKeyTime: number; navTabsCollapsed: boolean; areWeASubscriber: boolean; - subscriberId: Uint8Array; + subscriberId: Uint8Array; subscriberCurrencyCode: string; // Note: for historical reasons, this has two l's donorSubscriptionManuallyCancelled: boolean; - backupsSubscriberId: Uint8Array; + backupsSubscriberId: Uint8Array; backupsSubscriberPurchaseToken: string; backupsSubscriberOriginalTransactionId: string; displayBadgesOnProfile: boolean; @@ -202,8 +202,8 @@ export type StorageAccessType = { usernameLinkCorrupted: boolean; usernameLinkColor: number; usernameLink: { - entropy: Uint8Array; - serverId: Uint8Array; + entropy: Uint8Array; + serverId: Uint8Array; }; serverAlerts: ServerAlertsType; needOrphanedAttachmentCheck: boolean; @@ -230,7 +230,7 @@ export type StorageAccessType = { // If present together with backupDownloadPath - we are downloading // link-and-sync backup - backupEphemeralKey: Uint8Array; + backupEphemeralKey: Uint8Array; // If present - we are resuming the download of known transfer archive backupTransitArchive: { @@ -274,7 +274,7 @@ export type StorageAccessType = { avatarsHaveBeenMigrated: boolean; // Key Transparency - lastDistinguishedTreeHead: Uint8Array; + lastDistinguishedTreeHead: Uint8Array; // Meaning of values: // // - undefined - status unknown or uninitialized @@ -286,7 +286,7 @@ export type StorageAccessType = { // Test-only // Not used UI, stored as is when imported from backup during tests - defaultWallpaperPhotoPointer: Uint8Array; + defaultWallpaperPhotoPointer: Uint8Array; defaultWallpaperPreset: number; defaultDimWallpaperInDarkMode: boolean; defaultAutoBubbleColor: boolean; diff --git a/ts/types/Username.std.ts b/ts/types/Username.std.ts index 76ac22c8ff..0ff00b0adc 100644 --- a/ts/types/Username.std.ts +++ b/ts/types/Username.std.ts @@ -4,7 +4,7 @@ export type UsernameReservationType = Readonly<{ username: string; previousUsername: string | undefined; - hash: Uint8Array; + hash: Uint8Array; }>; export enum ReserveUsernameError { diff --git a/ts/types/Util.std.ts b/ts/types/Util.std.ts index 1cd9f9211e..0e95feb7b0 100644 --- a/ts/types/Util.std.ts +++ b/ts/types/Util.std.ts @@ -92,9 +92,10 @@ export type AssertProps = InternalAssertProps; export type UnwrapPromise = Value extends Promise ? T : Value; -export type BytesToStrings = Value extends Uint8Array - ? string - : { [Key in keyof Value]: BytesToStrings }; +export type BytesToStrings = + Value extends Uint8Array + ? string + : { [Key in keyof Value]: BytesToStrings }; export type JSONWithUnknownFields = Value extends Record diff --git a/ts/types/VisualAttachment.dom.ts b/ts/types/VisualAttachment.dom.ts index ede002f6a4..04405a6b80 100644 --- a/ts/types/VisualAttachment.dom.ts +++ b/ts/types/VisualAttachment.dom.ts @@ -120,7 +120,7 @@ const MINIMUM_JPEG_QUALITY = 0.1; const ADDITIONAL_QUALITY_DECREASE_PER_ITERATION = 0.1; export type CreatedThumbnailType = { - data: Uint8Array; + data: Uint8Array; height: number; width: number; mimeType: MIMEType; @@ -285,7 +285,7 @@ export async function makeVideoScreenshot({ } export function makeObjectUrl( - data: Uint8Array | ArrayBuffer, + data: Uint8Array | ArrayBuffer, contentType: MIMEType ): string { const blob = new Blob([data], { diff --git a/ts/types/backups.node.ts b/ts/types/backups.node.ts index 0f8541f3b1..f455ec77ce 100644 --- a/ts/types/backups.node.ts +++ b/ts/types/backups.node.ts @@ -67,6 +67,6 @@ export type BackupsSubscriptionType = ( export type LocalBackupMetadataVerificationType = { snapshotDir: string; - backupId: Uint8Array; - metadataKey: Uint8Array; + backupId: Uint8Array; + metadataKey: Uint8Array; }; diff --git a/ts/types/safetyNumber.std.ts b/ts/types/safetyNumber.std.ts index 55f164f065..7047c3a6ce 100644 --- a/ts/types/safetyNumber.std.ts +++ b/ts/types/safetyNumber.std.ts @@ -3,5 +3,5 @@ export type SafetyNumberType = Readonly<{ numberBlocks: ReadonlyArray; - qrData: Uint8Array; + qrData: Uint8Array; }>; diff --git a/ts/updater/common.main.ts b/ts/updater/common.main.ts index 6f8448f348..2c82e874b4 100644 --- a/ts/updater/common.main.ts +++ b/ts/updater/common.main.ts @@ -113,7 +113,7 @@ enum DownloadMode { type DownloadUpdateResultType = Readonly<{ updateFilePath: string; - signature: Buffer; + signature: Buffer; }>; export type UpdaterOptionsType = Readonly<{ @@ -308,7 +308,7 @@ export abstract class Updater { markShouldQuit(); } - protected getUpdatesPublicKey(): Buffer { + protected getUpdatesPublicKey(): Buffer { return hexToBinary(config.get('updatesPublicKey')); } diff --git a/ts/updater/curve.node.ts b/ts/updater/curve.node.ts index 9af06952a3..96174908fc 100644 --- a/ts/updater/curve.node.ts +++ b/ts/updater/curve.node.ts @@ -4,8 +4,8 @@ import { PrivateKey, PublicKey } from '@signalapp/libsignal-client'; type KeyPair = Readonly<{ - publicKey: Uint8Array; - privateKey: Uint8Array; + publicKey: Uint8Array; + privateKey: Uint8Array; }>; export function keyPair(): KeyPair { @@ -18,16 +18,19 @@ export function keyPair(): KeyPair { }; } -export function sign(privateKey: Uint8Array, message: Uint8Array): Uint8Array { +export function sign( + privateKey: Uint8Array, + message: Uint8Array +): Uint8Array { const privKeyObj = PrivateKey.deserialize(privateKey); const signature = privKeyObj.sign(message); return signature; } export function verify( - publicKey: Uint8Array, - message: Uint8Array, - signature: Uint8Array + publicKey: Uint8Array, + message: Uint8Array, + signature: Uint8Array ): boolean { const pubKeyObj = PublicKey.deserialize(publicKey); const result = pubKeyObj.verify(message, signature); diff --git a/ts/updater/differential.node.ts b/ts/updater/differential.node.ts index 2cfdad5be1..4724c7878b 100644 --- a/ts/updater/differential.node.ts +++ b/ts/updater/differential.node.ts @@ -64,7 +64,7 @@ export type PrepareDownloadResultType = Readonly<{ diff: ComputeDiffResultType; // This could be used by caller to avoid extra download of the blockmap - newBlockMap: Buffer; + newBlockMap: Buffer; }>; export type PrepareDownloadOptionsType = Readonly<{ @@ -97,7 +97,9 @@ export function getBlockMapFileName(fileName: string): string { return `${fileName}.blockmap`; } -export async function parseBlockMap(data: Buffer): Promise { +export async function parseBlockMap( + data: Buffer +): Promise { const unpacked = await gunzip(data); const json: BlockMapFileJSONType = JSON.parse(unpacked.toString()); @@ -216,10 +218,11 @@ export async function prepareDownload({ await readFile(getBlockMapFileName(oldFile)) ); - const newBlockMapData = await got( - getBlockMapFileName(newUrl), - await getGotOptions() - ).buffer(); + const url = getBlockMapFileName(newUrl); + const opts = await getGotOptions(); + + // @ts-expect-error https://github.com/sindresorhus/got/issues/2418#issuecomment-4071277145 + const newBlockMapData: Buffer = await got(url, opts).buffer(); const newBlockMap = await parseBlockMap(newBlockMapData); diff --git a/ts/updater/linuxAppImage.main.ts b/ts/updater/linuxAppImage.main.ts index 78df7d2891..84582f771c 100644 --- a/ts/updater/linuxAppImage.main.ts +++ b/ts/updater/linuxAppImage.main.ts @@ -51,7 +51,7 @@ export class LinuxAppImageUpdater extends Updater { app.quit(); } - override getUpdatesPublicKey(): Buffer { + override getUpdatesPublicKey(): Buffer { return hexToBinary(config.get('appImageUpdatesPublicKey')); } diff --git a/ts/updater/signature.node.ts b/ts/updater/signature.node.ts index ef958816be..ae28530ce4 100644 --- a/ts/updater/signature.node.ts +++ b/ts/updater/signature.node.ts @@ -21,7 +21,7 @@ export async function generateSignature( updatePackagePath: string, version: string, privateKeyPath: string -): Promise { +): Promise> { const privateKey = await loadHexFromPath(privateKeyPath); const message = await generateMessage(updatePackagePath, version); @@ -31,8 +31,8 @@ export async function generateSignature( export async function verifySignature( updatePackagePath: string, version: string, - signature: Uint8Array, - publicKey: Uint8Array + signature: Uint8Array, + publicKey: Uint8Array ): Promise { const message = await generateMessage(updatePackagePath, version); @@ -44,7 +44,7 @@ export async function verifySignature( async function generateMessage( updatePackagePath: string, version: string -): Promise { +): Promise> { const hash = await _getFileHash(updatePackagePath); const messageString = `${Buffer.from(hash).toString('hex')}-${version}`; @@ -55,7 +55,7 @@ export async function writeSignature( updatePackagePath: string, version: string, privateKeyPath: string -): Promise { +): Promise> { const signaturePath = getSignaturePath(updatePackagePath); const signature = await generateSignature( updatePackagePath, @@ -67,7 +67,9 @@ export async function writeSignature( return signature; } -export async function _getFileHash(updatePackagePath: string): Promise { +export async function _getFileHash( + updatePackagePath: string +): Promise> { const hash = createHash('sha256'); await pipeline(createReadStream(updatePackagePath), hash); @@ -86,15 +88,17 @@ export function getSignaturePath(updatePackagePath: string): string { return join(updateDir, getSignatureFileName(updateFileName)); } -export function hexToBinary(target: string): Buffer { +export function hexToBinary(target: string): Buffer { return Buffer.from(target, 'hex'); } -export function binaryToHex(data: Uint8Array): string { +export function binaryToHex(data: Uint8Array): string { return Buffer.from(data).toString('hex'); } -export async function loadHexFromPath(target: string): Promise { +export async function loadHexFromPath( + target: string +): Promise> { const hexString = await readFile(target, 'utf8'); return hexToBinary(hexString); @@ -102,7 +106,7 @@ export async function loadHexFromPath(target: string): Promise { export async function writeHexToPath( target: string, - data: Uint8Array + data: Uint8Array ): Promise { await writeFile(target, binaryToHex(data)); } diff --git a/ts/util/Attachment.std.ts b/ts/util/Attachment.std.ts index 751207b855..6f1e097ce9 100644 --- a/ts/util/Attachment.std.ts +++ b/ts/util/Attachment.std.ts @@ -171,7 +171,7 @@ export function hasData(attachment: AttachmentType): boolean { export function loadData( readAttachmentV2Data: ( attachment: Partial - ) => Promise + ) => Promise> ): ( attachment: Partial ) => Promise { @@ -627,9 +627,9 @@ export const save = async ({ }) => string; readAttachmentData: ( attachment: Partial - ) => Promise; + ) => Promise>; saveAttachmentToDisk: (options: { - data: Uint8Array; + data: Uint8Array; name: string; baseDir?: string; }) => Promise<{ name: string; fullPath: string } | null>; @@ -640,7 +640,7 @@ export const save = async ({ */ baseDir?: string; }): Promise => { - let data: Uint8Array; + let data: Uint8Array; if (attachment.path) { data = await readAttachmentData(attachment); } else if (attachment.data) { diff --git a/ts/util/BodyRange.node.ts b/ts/util/BodyRange.node.ts index 8701699b10..52720caa12 100644 --- a/ts/util/BodyRange.node.ts +++ b/ts/util/BodyRange.node.ts @@ -13,6 +13,7 @@ import { createLogger } from '../logging/log.std.js'; import { isNotNil } from './isNotNil.std.js'; import { dropNull } from './dropNull.std.js'; import { fromAciUuidBytesOrString } from './ServiceId.node.js'; +import { isNonSharedUint8Array } from '../Bytes.std.js'; const { isNumber } = lodash; @@ -55,13 +56,13 @@ export function filterAndClean( } let rawMentionAci: string | undefined; - let mentionAciBinary: Uint8Array | undefined; + let mentionAciBinary: Uint8Array | undefined; if ('mentionAci' in range) { rawMentionAci = dropNull(range.mentionAci); } if ( 'mentionAciBinary' in range && - range.mentionAciBinary instanceof Uint8Array + isNonSharedUint8Array(range.mentionAciBinary) ) { mentionAciBinary = dropNull(range.mentionAciBinary); } diff --git a/ts/util/DelimitedStream.node.ts b/ts/util/DelimitedStream.node.ts index 6a52f312a4..2de656bf6a 100644 --- a/ts/util/DelimitedStream.node.ts +++ b/ts/util/DelimitedStream.node.ts @@ -14,13 +14,13 @@ type State = | { kind: 'frame'; remaining: number; - parts: Array; + parts: Array>; } | { kind: 'trailer'; - frame: Buffer; + frame: Buffer; remaining: number; - parts: Array; + parts: Array>; }; const EMPTY_TRAILER = Buffer.alloc(0); @@ -33,7 +33,7 @@ export class DelimitedStream extends Transform { } override async _transform( - chunk: Buffer, + chunk: Buffer, _encoding: BufferEncoding, done: (error?: Error) => void ): Promise { @@ -147,11 +147,14 @@ export class DelimitedStream extends Transform { done(); } - protected getTrailerSize(_frame: Buffer): number { + protected getTrailerSize(_frame: Buffer): number { return 0; } - protected async pushFrame(frame: Buffer, _trailer: Buffer): Promise { + protected async pushFrame( + frame: Buffer, + _trailer: Buffer + ): Promise { this.push(frame); } } diff --git a/ts/util/MemoryStream.node.ts b/ts/util/MemoryStream.node.ts index a61f3558fb..ed9e1c24ed 100644 --- a/ts/util/MemoryStream.node.ts +++ b/ts/util/MemoryStream.node.ts @@ -6,11 +6,11 @@ import { InputStream } from '@signalapp/libsignal-client/dist/io.js'; export class MemoryStream extends InputStream { #offset = 0; - constructor(private readonly buffer: Uint8Array) { + constructor(private readonly buffer: Uint8Array) { super(); } - public override async read(amount: number): Promise { + public override async read(amount: number): Promise> { const result = this.buffer.subarray(this.#offset, this.#offset + amount); this.#offset += amount; return result; diff --git a/ts/util/ServiceId.node.ts b/ts/util/ServiceId.node.ts index aaab7cad0d..3f9662da3a 100644 --- a/ts/util/ServiceId.node.ts +++ b/ts/util/ServiceId.node.ts @@ -32,19 +32,19 @@ export function toPniObject(pni: PniString): Pni { } export function fromServiceIdBinaryOrString( - bytes: Uint8Array, + bytes: Uint8Array, fallback: string | undefined | null, context: string ): ServiceIdString; export function fromServiceIdBinaryOrString( - bytes: Uint8Array | undefined | null, + bytes: Uint8Array | undefined | null, fallback: string | undefined | null, context: string ): ServiceIdString | undefined; export function fromServiceIdBinaryOrString( - bytes: Uint8Array | undefined | null, + bytes: Uint8Array | undefined | null, fallback: string | undefined | null, context: string ): ServiceIdString | undefined { @@ -57,14 +57,14 @@ export function fromServiceIdBinaryOrString( return undefined; } -export function fromAciUuidBytes(bytes: Uint8Array): AciString; +export function fromAciUuidBytes(bytes: Uint8Array): AciString; export function fromAciUuidBytes( - bytes: Uint8Array | undefined | null + bytes: Uint8Array | undefined | null ): AciString | undefined; export function fromAciUuidBytes( - bytes: Uint8Array | undefined | null + bytes: Uint8Array | undefined | null ): AciString | undefined { if (Bytes.isNotEmpty(bytes)) { return fromAciObject(Aci.fromUuidBytes(bytes)); @@ -73,25 +73,25 @@ export function fromAciUuidBytes( } export function fromAciUuidBytesOrString( - bytes: Uint8Array, + bytes: Uint8Array, fallback: string | undefined | null, context: string ): AciString; export function fromAciUuidBytesOrString( - bytes: Uint8Array | undefined | null, + bytes: Uint8Array | undefined | null, fallback: string, context: string ): AciString; export function fromAciUuidBytesOrString( - bytes: Uint8Array | undefined | null, + bytes: Uint8Array | undefined | null, fallback: string | undefined | null, context: string ): AciString | undefined; export function fromAciUuidBytesOrString( - bytes: Uint8Array | undefined | null, + bytes: Uint8Array | undefined | null, fallback: string | undefined | null, context: string ): AciString | undefined { @@ -105,7 +105,7 @@ export function fromAciUuidBytesOrString( } export function fromPniUuidBytesOrUntaggedString( - bytes: Uint8Array | undefined | null, + bytes: Uint8Array | undefined | null, fallback: string | undefined | null, context: string ): PniString | undefined { diff --git a/ts/util/appendMacStream.node.ts b/ts/util/appendMacStream.node.ts index b9d3d7fbeb..d442b2bdc2 100644 --- a/ts/util/appendMacStream.node.ts +++ b/ts/util/appendMacStream.node.ts @@ -12,8 +12,8 @@ export const MAC_KEY_SIZE = 32; export const MAC_SIZE = 32; export function appendMacStream( - macKey: Uint8Array, - onMac?: (mac: Uint8Array) => undefined + macKey: Uint8Array, + onMac?: (mac: Uint8Array) => undefined ): Duplex { if (macKey.byteLength !== MAC_KEY_SIZE) { throw new Error('appendMacStream: invalid macKey length'); diff --git a/ts/util/avatarDataToBytes.dom.ts b/ts/util/avatarDataToBytes.dom.ts index 2da88171e5..822feee61f 100644 --- a/ts/util/avatarDataToBytes.dom.ts +++ b/ts/util/avatarDataToBytes.dom.ts @@ -81,7 +81,7 @@ async function getFont(text: string): Promise { export async function avatarDataToBytes( avatarData: AvatarDataType -): Promise { +): Promise> { const canvas = document.createElement('canvas'); canvas.width = CANVAS_SIZE; canvas.height = CANVAS_SIZE; diff --git a/ts/util/callDisposition.preload.ts b/ts/util/callDisposition.preload.ts index 0e753361bb..49bc1c1088 100644 --- a/ts/util/callDisposition.preload.ts +++ b/ts/util/callDisposition.preload.ts @@ -127,7 +127,12 @@ export function formatCallHistoryGroup( export function formatPeekInfo(peekInfo: PeekInfo): string { const { eraId, deviceCount, creator } = peekInfo; const callId = eraId != null ? getCallIdFromEra(eraId) : null; - const creatorAci = creator != null ? getCreatorAci(creator) : null; + let creatorAci: AciString | null = null; + if (creator != null) { + // @ts-expect-error needs ringrtc update + const creatorBytes: Uint8Array = creator; + creatorAci = getCreatorAci(creatorBytes); + } return `PeekInfo (${eraId}, ${callId}, ${creatorAci}, ${deviceCount})`; } @@ -147,7 +152,7 @@ export function getCallIdFromEra(eraId: string): string { return BigInt(callIdFromEra(eraId)).toString(); } -export function getCreatorAci(creator: Uint8Array): AciString { +export function getCreatorAci(creator: Uint8Array): AciString { const aci = bytesToUuid(creator); strictAssert(aci != null, 'creator uuid buffer was not a valid uuid'); strictAssert(isAciString(aci), 'creator uuid buffer was not a valid aci'); @@ -161,7 +166,9 @@ export function getGroupCallMeta( return null; } const callId = getCallIdFromEra(peekInfo.eraId); - const ringerId = bytesToUuid(peekInfo.creator); + // @ts-expect-error needs ringrtc update + const creatorBytes: Uint8Array = peekInfo.creator; + const ringerId = bytesToUuid(creatorBytes); strictAssert(ringerId != null, 'peekInfo.creator was invalid uuid'); strictAssert(isAciString(ringerId), 'peekInfo.creator was invalid aci'); return { callId, ringerId }; @@ -354,7 +361,9 @@ function shouldSyncStatus(callStatus: CallStatus) { // For outgoing sync messages. peerId contains direct or group conversationId or // call link peerId. Locally conversationId is Base64 encoded but roomIds // are hex encoded. -export function getBytesForPeerId(callHistory: CallHistoryDetails): Uint8Array { +export function getBytesForPeerId( + callHistory: CallHistoryDetails +): Uint8Array { if (callHistory.mode === CallMode.Adhoc) { return Bytes.fromHex(callHistory.peerId); } diff --git a/ts/util/callLinks.std.ts b/ts/util/callLinks.std.ts index a1ac149cbf..567fccf5bc 100644 --- a/ts/util/callLinks.std.ts +++ b/ts/util/callLinks.std.ts @@ -70,11 +70,11 @@ export function getPlaceholderCallLinkConversation( }; } -export function toAdminKeyBytes(adminKey: string): Uint8Array { +export function toAdminKeyBytes(adminKey: string): Uint8Array { return Bytes.fromBase64(adminKey); } -export function fromAdminKeyBytes(adminKey: Uint8Array): string { +export function fromAdminKeyBytes(adminKey: Uint8Array): string { return Bytes.toBase64(adminKey); } diff --git a/ts/util/callLinks/zkgroup.preload.ts b/ts/util/callLinks/zkgroup.preload.ts index 33a90056ce..2e2b330eb4 100644 --- a/ts/util/callLinks/zkgroup.preload.ts +++ b/ts/util/callLinks/zkgroup.preload.ts @@ -35,9 +35,11 @@ export async function getCallLinkAuthCredentialPresentation( } const userId = Aci.fromUuid(ourAci); - const callLinkSecretParams = CallLinkSecretParams.deriveFromRootKey( - callLinkRootKey.bytes - ); + // @ts-expect-error needs ringrtc update + const rootKeyBytes: Uint8Array = callLinkRootKey.bytes; + + const callLinkSecretParams = + CallLinkSecretParams.deriveFromRootKey(rootKeyBytes); const presentation = credential.present( userId, credentials.today.redemptionTime / durations.SECOND, diff --git a/ts/util/callLinksRingrtc.node.ts b/ts/util/callLinksRingrtc.node.ts index c5e1c5cb74..9a57145f36 100644 --- a/ts/util/callLinksRingrtc.node.ts +++ b/ts/util/callLinksRingrtc.node.ts @@ -56,7 +56,10 @@ export function callLinkRestrictionsToRingRTC( } export function getRoomIdFromRootKey(rootKey: CallLinkRootKey): string { - return Bytes.toHex(rootKey.deriveRoomId()); + const roomId = rootKey.deriveRoomId(); + // @ts-expect-error needs ringrtc update + const roomIdBytes: Uint8Array = roomId; + return Bytes.toHex(roomIdBytes); } export function getRoomIdFromRootKeyString(rootKeyString: string): string { @@ -64,9 +67,13 @@ export function getRoomIdFromRootKeyString(rootKeyString: string): string { return getRoomIdFromRootKey(callLinkRootKey); } -export function getCallLinkRootKeyFromUrlKey(key: string): Uint8Array { - // Returns `Buffer` which inherits from `Uint8Array` - return CallLinkRootKey.parse(key).bytes; +export function getCallLinkRootKeyFromUrlKey( + key: string +): Uint8Array { + const rootKeyBytes = CallLinkRootKey.parse(key).bytes; + // @ts-expect-error needs ringrtc update + const result: Uint8Array = rootKeyBytes; + return result; } export function getRoomIdFromCallLink(url: string): string { @@ -75,12 +82,15 @@ export function getRoomIdFromCallLink(url: string): string { return getRoomIdFromRootKey(key); } -export function toRootKeyBytes(rootKey: string): Uint8Array { - return CallLinkRootKey.parse(rootKey).bytes; +export function toRootKeyBytes(rootKey: string): Uint8Array { + const rootKeyBytes = CallLinkRootKey.parse(rootKey).bytes; + // @ts-expect-error needs ringrtc update + const result: Uint8Array = rootKeyBytes; + return result; } -export function fromRootKeyBytes(rootKey: Uint8Array): string { - return CallLinkRootKey.fromBytes(rootKey as Buffer).toString(); +export function fromRootKeyBytes(rootKey: Uint8Array): string { + return CallLinkRootKey.fromBytes(rootKey as Buffer).toString(); } /** diff --git a/ts/util/callingMessageToProto.node.ts b/ts/util/callingMessageToProto.node.ts index 280a2a08da..390779fcdf 100644 --- a/ts/util/callingMessageToProto.node.ts +++ b/ts/util/callingMessageToProto.node.ts @@ -1,7 +1,7 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import type { CallingMessage } from '@signalapp/ringrtc'; +import type { AnswerMessage, CallingMessage } from '@signalapp/ringrtc'; import { CallMessageUrgency } from '@signalapp/ringrtc'; import { SignalService as Proto } from '../protobuf/index.std.js'; import { createLogger } from '../logging/log.std.js'; @@ -27,7 +27,7 @@ export function callingMessageToProto( opaqueField = { ...opaque, urgency: null, - data: opaque.data ?? null, + data: opaque.data != null ? opaqueToBytes(opaque.data) : null, }; } if (urgency !== undefined) { @@ -43,14 +43,14 @@ export function callingMessageToProto( ...offer, id: offer.callId, type: offer.type as number, - opaque: offer.opaque, + opaque: opaqueToBytes(offer.opaque), } : null, answer: answer ? { ...answer, id: answer.callId, - opaque: answer.opaque, + opaque: opaqueToBytes(answer.opaque), } : null, iceUpdate: iceCandidates @@ -58,7 +58,7 @@ export function callingMessageToProto( return { ...candidate, id: candidate.callId, - opaque: candidate.opaque, + opaque: opaqueToBytes(candidate.opaque), }; }) : null, @@ -80,6 +80,14 @@ export function callingMessageToProto( }; } +function opaqueToBytes( + opaque: AnswerMessage['opaque'] +): Uint8Array { + // @ts-expect-error needs ringrtc update + const bytes: Uint8Array = opaque; + return bytes; +} + function urgencyToProto( urgency: CallMessageUrgency ): Proto.CallMessage.Opaque.Urgency { diff --git a/ts/util/canvasToBytes.std.ts b/ts/util/canvasToBytes.std.ts index 965af9b74e..fee263ded2 100644 --- a/ts/util/canvasToBytes.std.ts +++ b/ts/util/canvasToBytes.std.ts @@ -8,7 +8,7 @@ export async function canvasToBytes( canvas: HTMLCanvasElement, mimeType?: MIMEType, quality?: number -): Promise { +): Promise> { const blob = await canvasToBlob(canvas, mimeType, quality); return new Uint8Array(await blob.arrayBuffer()); } diff --git a/ts/util/captureDimensionsAndScreenshot.dom.ts b/ts/util/captureDimensionsAndScreenshot.dom.ts index 9ed61a53f3..3e646ef83a 100644 --- a/ts/util/captureDimensionsAndScreenshot.dom.ts +++ b/ts/util/captureDimensionsAndScreenshot.dom.ts @@ -26,10 +26,10 @@ export async function captureDimensionsAndScreenshot( options: { generateThumbnail: boolean }, params: { writeNewAttachmentData: ( - data: Uint8Array + data: Uint8Array ) => Promise; makeObjectUrl: ( - data: Uint8Array | ArrayBuffer, + data: Uint8Array | ArrayBuffer, contentType: MIMEType ) => string; revokeObjectUrl: (path: string) => void; diff --git a/ts/util/computeBlurHashUrl.std.ts b/ts/util/computeBlurHashUrl.std.ts index d676a2e366..d0747e3af3 100644 --- a/ts/util/computeBlurHashUrl.std.ts +++ b/ts/util/computeBlurHashUrl.std.ts @@ -48,7 +48,11 @@ const BITMAP_HEADER = new Uint8Array([ const PIXEL_COUNT = 32 * 32; /* eslint-disable no-bitwise */ -function writeUInt32LE(bytes: Uint8Array, value: number, position: number) { +function writeUInt32LE( + bytes: Uint8Array, + value: number, + position: number +) { // eslint-disable-next-line no-param-reassign bytes[position + 0] = (value >>> 0) & 0xff; // eslint-disable-next-line no-param-reassign diff --git a/ts/util/createHTTPSAgent.node.ts b/ts/util/createHTTPSAgent.node.ts index 624a27ca94..a7d8da23ef 100644 --- a/ts/util/createHTTPSAgent.node.ts +++ b/ts/util/createHTTPSAgent.node.ts @@ -65,7 +65,8 @@ export class Agent extends HTTPSAgent { }); } - public createConnection = callbackify( + // @ts-expect-error - callbackify() returns the wrong type + public createConnection: HTTPSAgent['createConnection'] = callbackify( async (options: RequestOptions): Promise => { const { host = options.hostname, port: portString } = options; strictAssert(host, 'Agent.createConnection: Missing options.host'); diff --git a/ts/util/createIPCEvents.preload.ts b/ts/util/createIPCEvents.preload.ts index d6b298a21c..33a22fc95c 100644 --- a/ts/util/createIPCEvents.preload.ts +++ b/ts/util/createIPCEvents.preload.ts @@ -76,8 +76,8 @@ export type IPCEventsCallbacksType = { startCallingLobbyViaToken: (token: string) => void; unknownSignalLink: () => void; uploadStickerPack: ( - manifest: Uint8Array, - stickers: ReadonlyArray + manifest: Uint8Array, + stickers: ReadonlyArray> ) => Promise; }; @@ -439,8 +439,8 @@ export function createIPCEvents( showUnknownSgnlLinkModal(); }, uploadStickerPack: ( - manifest: Uint8Array, - stickers: ReadonlyArray + manifest: Uint8Array, + stickers: ReadonlyArray> ): Promise => { return putStickers(manifest, stickers, () => ipcRenderer.send('art-creator:onUploadProgress') diff --git a/ts/util/decipherWithAesKey.node.ts b/ts/util/decipherWithAesKey.node.ts index dd9fa31ca8..ad4f06c524 100644 --- a/ts/util/decipherWithAesKey.node.ts +++ b/ts/util/decipherWithAesKey.node.ts @@ -1,7 +1,7 @@ // Copyright 2024 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import { createDecipheriv, type Decipher } from 'node:crypto'; +import { createDecipheriv, type Decipheriv } from 'node:crypto'; import { Buffer } from 'node:buffer'; import { Transform } from 'node:stream'; @@ -12,9 +12,9 @@ import { strictAssert } from './assert.std.js'; * Gets the IV from the start of the stream and creates a decipher. * Then deciphers the rest of the stream. */ -export function decipherWithAesKey(aesKey: Uint8Array): Transform { - let maybeIvBytes: Buffer | null = Buffer.alloc(0); - let decipher: Decipher | null = null; +export function decipherWithAesKey(aesKey: Uint8Array): Transform { + let maybeIvBytes: Buffer | null = Buffer.alloc(0); + let decipher: Decipheriv | null = null; return new Transform({ transform(chunk, _encoding, callback) { try { diff --git a/ts/util/encodeDelimited.std.ts b/ts/util/encodeDelimited.std.ts index 7708d25d85..bf345fd05b 100644 --- a/ts/util/encodeDelimited.std.ts +++ b/ts/util/encodeDelimited.std.ts @@ -1,9 +1,11 @@ // Copyright 2026 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -export function encodeDelimited(buf: Uint8Array): [Uint8Array, Uint8Array] { +export function encodeDelimited( + buf: Uint8Array +): [Uint8Array, Uint8Array] { const len = buf.byteLength; - let prefix: Uint8Array; + let prefix: Uint8Array; /* eslint-disable no-bitwise */ if (len < 0x80) { prefix = new Uint8Array(1); diff --git a/ts/util/encryptLegacyAttachment.preload.ts b/ts/util/encryptLegacyAttachment.preload.ts index fbef4c58c2..fbf5fcb54f 100644 --- a/ts/util/encryptLegacyAttachment.preload.ts +++ b/ts/util/encryptLegacyAttachment.preload.ts @@ -32,8 +32,10 @@ export type EncryptLegacyAttachmentOptionsType = Readonly<{ disposition?: AttachmentDisposition; readAttachmentData: ( attachment: Partial - ) => Promise; - writeNewAttachmentData: (data: Uint8Array) => Promise; + ) => Promise>; + writeNewAttachmentData: ( + data: Uint8Array + ) => Promise; }>; export async function encryptLegacyAttachment< diff --git a/ts/util/encryptProfileData.preload.ts b/ts/util/encryptProfileData.preload.ts index f91d21cf42..a19227c663 100644 --- a/ts/util/encryptProfileData.preload.ts +++ b/ts/util/encryptProfileData.preload.ts @@ -21,7 +21,7 @@ import { itemStorage } from '../textsecure/Storage.preload.js'; export async function encryptProfileData( conversation: ConversationType, { oldAvatar, newAvatar }: AvatarUpdateType -): Promise<[ProfileRequestDataType, Uint8Array | undefined]> { +): Promise<[ProfileRequestDataType, Uint8Array | undefined]> { const { aboutEmoji, aboutText, diff --git a/ts/util/fileToBytes.std.ts b/ts/util/fileToBytes.std.ts index f0483de63c..cacd8d3575 100644 --- a/ts/util/fileToBytes.std.ts +++ b/ts/util/fileToBytes.std.ts @@ -1,7 +1,7 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -export function fileToBytes(file: Blob): Promise { +export function fileToBytes(file: Blob): Promise> { return new Promise((resolve, rejectPromise) => { const FR = new FileReader(); FR.onload = () => { diff --git a/ts/util/getMacAndUpdateHmac.node.ts b/ts/util/getMacAndUpdateHmac.node.ts index 9ed9f09685..73ce77d2b7 100644 --- a/ts/util/getMacAndUpdateHmac.node.ts +++ b/ts/util/getMacAndUpdateHmac.node.ts @@ -13,7 +13,7 @@ import { MAC_LENGTH } from '../types/Crypto.std.js'; */ export function getMacAndUpdateHmac( hmac: Hmac, - onTheirMac: (theirMac: Uint8Array) => void + onTheirMac: (theirMac: Uint8Array) => void ): Transform { // Because we don't have a view of the entire stream, we don't know when we're // at the end. We need to omit the last MAC_LENGTH bytes from diff --git a/ts/util/getStreamWithTimeout.node.ts b/ts/util/getStreamWithTimeout.node.ts index a251213964..6fc36b9181 100644 --- a/ts/util/getStreamWithTimeout.node.ts +++ b/ts/util/getStreamWithTimeout.node.ts @@ -19,10 +19,11 @@ export class StreamTimeoutError extends Error {} export function getStreamWithTimeout( stream: Readable, { name, timeout, abortController }: OptionsType -): Promise { - const { promise, resolve, reject } = explodePromise(); +): Promise> { + const { promise, resolve, reject } = + explodePromise>(); - const chunks = new Array(); + const chunks = new Array>(); let timer: NodeJS.Timeout | undefined; diff --git a/ts/util/grapheme.std.ts b/ts/util/grapheme.std.ts index 15d8626097..bd775525fc 100644 --- a/ts/util/grapheme.std.ts +++ b/ts/util/grapheme.std.ts @@ -41,7 +41,8 @@ export function isSingleGrapheme(str: string): boolean { return false; } const segments = getSegmenter().segment(str); - return segments.containing(0).segment === str; + const first = segments.containing(0); + return first != null && first.segment === str; } export function hasAtMostGraphemes(str: string, max: number): boolean { diff --git a/ts/util/groupSendEndorsements.preload.ts b/ts/util/groupSendEndorsements.preload.ts index e66c7405ab..2e2e706bfd 100644 --- a/ts/util/groupSendEndorsements.preload.ts +++ b/ts/util/groupSendEndorsements.preload.ts @@ -46,7 +46,7 @@ export function decodeGroupSendEndorsementsResponse({ groupMembersV2, }: { groupId: string; - groupSendEndorsementsResponse: Uint8Array; + groupSendEndorsementsResponse: Uint8Array; groupSecretParamsBase64: string; groupMembersV2: ReadonlyArray; }): GroupSendEndorsementsData { @@ -114,6 +114,7 @@ export function decodeGroupSendEndorsementsResponse({ endorsement != null, `Missing endorsement at index ${index}` ); + return { groupId, memberAci: fromAciObject(groupMember), @@ -170,7 +171,10 @@ export class GroupSendEndorsementState { #memberEndorsementsAcis = new Set(); #groupSecretParamsBase64: string; #ourAci: ServiceIdString; - #endorsementCache = new WeakMap(); + #endorsementCache = new WeakMap< + Uint8Array, + GroupSendEndorsement + >(); constructor( data: GroupSendEndorsementsData, @@ -194,7 +198,7 @@ export class GroupSendEndorsementState { return this.#memberEndorsements.has(serviceId); } - #toEndorsement(contents: Uint8Array): GroupSendEndorsement { + #toEndorsement(contents: Uint8Array): GroupSendEndorsement { let endorsement = this.#endorsementCache.get(contents); if (endorsement == null) { endorsement = new GroupSendEndorsement(contents); diff --git a/ts/util/handleImageAttachment.preload.ts b/ts/util/handleImageAttachment.preload.ts index 84642a5484..f027f95594 100644 --- a/ts/util/handleImageAttachment.preload.ts +++ b/ts/util/handleImageAttachment.preload.ts @@ -22,16 +22,18 @@ export async function handleImageAttachment( const uuid = genUuid(); const bytes = new Uint8Array(await file.arrayBuffer()); - const convertedData = await new Promise((resolve, reject) => { - ipcRenderer.once(`convert-image:${uuid}`, (_, { error, response }) => { - if (response) { - resolve(response); - } else { - reject(error); - } - }); - ipcRenderer.send('convert-image', uuid, bytes); - }); + const convertedData = await new Promise>( + (resolve, reject) => { + ipcRenderer.once(`convert-image:${uuid}`, (_, { error, response }) => { + if (response) { + resolve(response); + } else { + reject(error); + } + }); + ipcRenderer.send('convert-image', uuid, bytes); + } + ); processedFile = new Blob([convertedData]); } diff --git a/ts/util/imagePathToBytes.dom.ts b/ts/util/imagePathToBytes.dom.ts index 8563cb6370..8ea456f11c 100644 --- a/ts/util/imagePathToBytes.dom.ts +++ b/ts/util/imagePathToBytes.dom.ts @@ -3,7 +3,9 @@ import { canvasToBytes } from './canvasToBytes.std.js'; -export async function imagePathToBytes(src: string): Promise { +export async function imagePathToBytes( + src: string +): Promise> { const image = new Image(); const canvas = document.createElement('canvas'); const context = canvas.getContext('2d'); diff --git a/ts/util/inspectProtobufs.std.ts b/ts/util/inspectProtobufs.std.ts index 5172951d99..52f83489d3 100644 --- a/ts/util/inspectProtobufs.std.ts +++ b/ts/util/inspectProtobufs.std.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only type MessageWithUnknownFields = { - $unknown?: ReadonlyArray; + $unknown?: ReadonlyArray>; }; /** diff --git a/ts/util/logPadding.node.ts b/ts/util/logPadding.node.ts index c1dc7aebe4..9c3b6db400 100644 --- a/ts/util/logPadding.node.ts +++ b/ts/util/logPadding.node.ts @@ -29,7 +29,7 @@ function* generatePadding(size: number) { // Push as much padding as we can. If we reach the end // of the padding, return true. function pushPadding( - paddingIterator: Iterator, + paddingIterator: Iterator>, readable: Readable ): boolean { // eslint-disable-next-line no-constant-condition diff --git a/ts/util/lookupConversationWithoutServiceId.preload.ts b/ts/util/lookupConversationWithoutServiceId.preload.ts index e0f6f96a3a..8f084c50e4 100644 --- a/ts/util/lookupConversationWithoutServiceId.preload.ts +++ b/ts/util/lookupConversationWithoutServiceId.preload.ts @@ -141,7 +141,7 @@ export async function lookupConversationWithoutServiceId( export async function checkForUsername( username: string ): Promise { - let hash: Uint8Array; + let hash: Uint8Array; let fixedUsername = username; if (fixedUsername.startsWith('@')) { fixedUsername = fixedUsername.slice(1); diff --git a/ts/util/migrations.preload.ts b/ts/util/migrations.preload.ts index ce38d07d2c..03e7394065 100644 --- a/ts/util/migrations.preload.ts +++ b/ts/util/migrations.preload.ts @@ -58,9 +58,11 @@ const logger = createLogger('migrations'); type EncryptedReader = ( attachment: Partial -) => Promise; +) => Promise>; -type EncryptedWriter = (data: Uint8Array) => Promise; +type EncryptedWriter = ( + data: Uint8Array +) => Promise; function createEncryptedReader(basePath: string): EncryptedReader { const fallbackReader = createPlaintextReader(basePath); @@ -68,7 +70,7 @@ function createEncryptedReader(basePath: string): EncryptedReader { return async ( attachment: Partial - ): Promise => { + ): Promise> => { // In-memory if (attachment.data != null) { return attachment.data; @@ -192,7 +194,7 @@ export const processNewAttachment = ( logger, }); export const processNewSticker = ( - stickerData: Uint8Array + stickerData: Uint8Array ): ReturnType => doProcessNewSticker(stickerData, false, { writeNewStickerData, @@ -200,7 +202,7 @@ export const processNewSticker = ( logger, }); export const processNewEphemeralSticker = ( - stickerData: Uint8Array + stickerData: Uint8Array ): ReturnType => doProcessNewSticker(stickerData, true, { writeNewStickerData: writeNewTempData, diff --git a/ts/util/onCallLinkUpdateSync.preload.ts b/ts/util/onCallLinkUpdateSync.preload.ts index f42b5969f6..c355aa5519 100644 --- a/ts/util/onCallLinkUpdateSync.preload.ts +++ b/ts/util/onCallLinkUpdateSync.preload.ts @@ -27,7 +27,7 @@ export async function onCallLinkUpdateSync( let callLinkRootKey: CallLinkRootKey; let roomId: string; try { - callLinkRootKey = CallLinkRootKey.fromBytes(rootKey as Buffer); + callLinkRootKey = CallLinkRootKey.fromBytes(rootKey as Buffer); roomId = getRoomIdFromRootKey(callLinkRootKey); strictAssert( roomId, diff --git a/ts/util/pemToDer.std.ts b/ts/util/pemToDer.std.ts index f6e4825b28..cd5348f894 100644 --- a/ts/util/pemToDer.std.ts +++ b/ts/util/pemToDer.std.ts @@ -3,7 +3,7 @@ import * as Bytes from '../Bytes.std.js'; -export function pemToDer(pem: string): Uint8Array { +export function pemToDer(pem: string): Uint8Array { const pemContent = pem .replace(/-----BEGIN [^-]+-----/, '') .replace(/-----END [^-]+-----/, '') diff --git a/ts/util/prependStream.node.ts b/ts/util/prependStream.node.ts index 3e92771bf5..c314b5a349 100644 --- a/ts/util/prependStream.node.ts +++ b/ts/util/prependStream.node.ts @@ -4,7 +4,7 @@ import { Transform } from 'node:stream'; import type { Duplex } from 'node:stream'; -export function prependStream(data: Uint8Array): Duplex { +export function prependStream(data: Uint8Array): Duplex { return new Transform({ construct(callback) { this.push(data); diff --git a/ts/util/processImageFile.dom.ts b/ts/util/processImageFile.dom.ts index ded5363bf1..4e90608c8c 100644 --- a/ts/util/processImageFile.dom.ts +++ b/ts/util/processImageFile.dom.ts @@ -5,7 +5,9 @@ import type { LoadImageOptions } from 'blueimp-load-image'; import loadImage from 'blueimp-load-image'; import { canvasToBytes } from './canvasToBytes.std.js'; -export async function processImageFile(file: File): Promise { +export async function processImageFile( + file: File +): Promise> { const { image } = await loadImage(file, { canvas: true, cover: true, diff --git a/ts/util/sendToGroup.preload.ts b/ts/util/sendToGroup.preload.ts index 8c0a6fd235..cdee0a5284 100644 --- a/ts/util/sendToGroup.preload.ts +++ b/ts/util/sendToGroup.preload.ts @@ -543,7 +543,7 @@ export async function sendToGroupViaSenderKey( }); let groupSendToken: GroupSendToken | null = null; - let accessKeys: Buffer | null = null; + let accessKeys: Buffer | null = null; if (groupSendEndorsementState != null) { groupSendToken = groupSendEndorsementState.buildToken( new Set(senderKeyRecipients) @@ -1228,7 +1228,7 @@ async function handle410Response( function getXorOfAccessKeys( devices: Array, { story }: { story?: boolean } = {} -): Buffer { +): Buffer { const uuids = getServiceIdsFromDevices(devices); const result = Buffer.alloc(ACCESS_KEY_LENGTH); @@ -1278,11 +1278,11 @@ async function encryptForSenderKey({ groupId, }: { contentHint: number; - contentMessage: Uint8Array; + contentMessage: Uint8Array; devices: Array; distributionId: string; groupId?: string; -}): Promise { +}): Promise> { const ourAci = itemStorage.user.getCheckedAci(); const ourDeviceId = itemStorage.user.getDeviceId(); if (!ourDeviceId) { diff --git a/ts/util/sessionTranslation.node.ts b/ts/util/sessionTranslation.node.ts index b39d678e4d..0c3a152aa1 100644 --- a/ts/util/sessionTranslation.node.ts +++ b/ts/util/sessionTranslation.node.ts @@ -70,13 +70,13 @@ type SessionRecordType = { }; export type LocalUserDataType = { - identityKeyPublic: Uint8Array; + identityKeyPublic: Uint8Array; registrationId: number; }; export function sessionStructureToBytes( recordStructure: signal.proto.storage.RecordStructure.Params -): Uint8Array { +): Uint8Array { return signal.proto.storage.RecordStructure.encode(recordStructure); } @@ -308,7 +308,7 @@ function toProtobufChain( const WHISPER_MESSAGE_KEYS = 'WhisperMessageKeys'; -function translateMessageKey(key: Uint8Array) { +function translateMessageKey(key: Uint8Array) { const input = key; const salt = new Uint8Array(32); const info = Bytes.fromString(WHISPER_MESSAGE_KEYS); @@ -327,7 +327,7 @@ function binaryToUint8Array( object: any, path: string, length: number -): Uint8Array { +): Uint8Array { const target = get(object, path); if (target == null) { throw new Error(`binaryToUint8Array: Falsey path ${path}`); diff --git a/ts/util/sniffImageMimeType.std.ts b/ts/util/sniffImageMimeType.std.ts index 74626651f9..b4ad6c263f 100644 --- a/ts/util/sniffImageMimeType.std.ts +++ b/ts/util/sniffImageMimeType.std.ts @@ -16,7 +16,9 @@ import { * * [0]: https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern */ -export function sniffImageMimeType(bytes: Uint8Array): undefined | MIMEType { +export function sniffImageMimeType( + bytes: Uint8Array +): undefined | MIMEType { for (const type of TYPES) { if (matchesType(bytes, type)) { return type.mimeType; @@ -27,8 +29,8 @@ export function sniffImageMimeType(bytes: Uint8Array): undefined | MIMEType { type Type = { mimeType: MIMEType; - bytePattern: Uint8Array; - patternMask?: Uint8Array; + bytePattern: Uint8Array; + patternMask?: Uint8Array; }; const TYPES: Array = [ { @@ -76,7 +78,7 @@ const TYPES: Array = [ // This follows the [pattern matching algorithm in the spec][1]. // [1]: https://mimesniff.spec.whatwg.org/#pattern-matching-algorithm -function matchesType(input: Uint8Array, type: Type): boolean { +function matchesType(input: Uint8Array, type: Type): boolean { if (input.byteLength < type.bytePattern.byteLength) { return false; } diff --git a/ts/util/toWebStream.node.ts b/ts/util/toWebStream.node.ts index ff9c56c4ba..7ec2f7b09e 100644 --- a/ts/util/toWebStream.node.ts +++ b/ts/util/toWebStream.node.ts @@ -6,8 +6,10 @@ import { once } from 'node:events'; // Note: can be removed once https://github.com/nodejs/node/issues/54205 is // resolved and ported to Electron. -export function toWebStream(readable: Readable): ReadableStream { - let controller: ReadableStreamDefaultController; +export function toWebStream( + readable: Readable +): ReadableStream> { + let controller: ReadableStreamDefaultController>; const cleanup = finished(readable, err => { cleanup(); diff --git a/ts/util/uploadAttachment.preload.ts b/ts/util/uploadAttachment.preload.ts index 6923af6579..a078aa1d53 100644 --- a/ts/util/uploadAttachment.preload.ts +++ b/ts/util/uploadAttachment.preload.ts @@ -47,12 +47,12 @@ const log = createLogger('uploadAttachment'); export async function uploadAttachment( attachment: AttachmentWithHydratedData ): Promise { - let keys: Uint8Array; + let keys: Uint8Array; let cdnKey: string; let cdnNumber: number; - let digest: Uint8Array; + let digest: Uint8Array; let plaintextHash: string; - let incrementalMac: Uint8Array | undefined; + let incrementalMac: Uint8Array | undefined; let chunkSize: number | undefined; let uploadTimestamp: number; @@ -130,7 +130,7 @@ export async function encryptAndUploadAttachment({ plaintext, uploadType, }: { - keys: Uint8Array; + keys: Uint8Array; needIncrementalMac: boolean; plaintext: PlaintextSourceType; uploadType: 'standard' | 'backup'; diff --git a/ts/util/uploads/tusProtocol.node.ts b/ts/util/uploads/tusProtocol.node.ts index 3b5a3b627f..37e0049385 100644 --- a/ts/util/uploads/tusProtocol.node.ts +++ b/ts/util/uploads/tusProtocol.node.ts @@ -59,7 +59,7 @@ function addProgressHandler( // Explicitly stop the flow, otherwise we might emit 'data' before `fetch()` // starts reading the stream. readable.pause(); - readable.on('data', (chunk: Buffer) => { + readable.on('data', (chunk: Buffer) => { bytesUploaded += chunk.byteLength; onProgress(bytesUploaded); }); diff --git a/ts/util/uuidToBytes.std.ts b/ts/util/uuidToBytes.std.ts index 2377d7dff0..527164eb35 100644 --- a/ts/util/uuidToBytes.std.ts +++ b/ts/util/uuidToBytes.std.ts @@ -11,14 +11,16 @@ const { chunk } = lodash; const log = createLogger('uuidToBytes'); export function getBytesSubarray( - data: Uint8Array, + data: Uint8Array, start: number, n: number -): Uint8Array { +): Uint8Array { return data.subarray(start, start + n); } -export function bytesToUuid(bytes: Uint8Array): undefined | string { +export function bytesToUuid( + bytes: Uint8Array +): undefined | string { if (bytes.byteLength !== UUID_BYTE_SIZE) { log.warn( 'bytesToUuid: received an Uint8Array of invalid length. ' + @@ -34,7 +36,9 @@ export function bytesToUuid(bytes: Uint8Array): undefined | string { return undefined; } -export function splitUuids(buffer: Uint8Array): Array { +export function splitUuids( + buffer: Uint8Array +): Array { const uuids = new Array(); for (let i = 0; i < buffer.byteLength; i += UUID_BYTE_SIZE) { const bytes = getBytesSubarray(buffer, i, UUID_BYTE_SIZE); @@ -56,7 +60,7 @@ export function splitUuids(buffer: Uint8Array): Array { return uuids; } -export function uuidToBytes(uuid: string): Uint8Array { +export function uuidToBytes(uuid: string): Uint8Array { if (uuid.length !== 36) { log.warn( 'received a string of invalid length. Returning an empty Uint8Array' diff --git a/ts/util/zkgroup.node.ts b/ts/util/zkgroup.node.ts index 9480790676..1ab844f8bd 100644 --- a/ts/util/zkgroup.node.ts +++ b/ts/util/zkgroup.node.ts @@ -39,14 +39,14 @@ export * from '@signalapp/libsignal-client/zkgroup.js'; export function decryptGroupBlob( clientZkGroupCipher: ClientZkGroupCipher, - ciphertext: Uint8Array -): Uint8Array { + ciphertext: Uint8Array +): Uint8Array { return clientZkGroupCipher.decryptBlob(ciphertext); } export function decodeProfileKeyCredentialPresentation( - presentationBuffer: Uint8Array -): { profileKey: Uint8Array; userId: Uint8Array } { + presentationBuffer: Uint8Array +): { profileKey: Uint8Array; userId: Uint8Array } { const presentation = new ProfileKeyCredentialPresentation(presentationBuffer); const userId = presentation.getUuidCiphertext().serialize(); @@ -60,9 +60,9 @@ export function decodeProfileKeyCredentialPresentation( export function decryptProfileKey( clientZkGroupCipher: ClientZkGroupCipher, - profileKeyCiphertextBuffer: Uint8Array, + profileKeyCiphertextBuffer: Uint8Array, serviceId: ServiceIdString -): Uint8Array { +): Uint8Array { const profileKeyCiphertext = new ProfileKeyCiphertext( profileKeyCiphertextBuffer ); @@ -77,7 +77,7 @@ export function decryptProfileKey( function decryptServiceIdObj( clientZkGroupCipher: ClientZkGroupCipher, - uuidCiphertextBuffer: Uint8Array + uuidCiphertextBuffer: Uint8Array ): ServiceId { const uuidCiphertext = new UuidCiphertext(uuidCiphertextBuffer); @@ -86,7 +86,7 @@ function decryptServiceIdObj( export function decryptServiceId( clientZkGroupCipher: ClientZkGroupCipher, - uuidCiphertextBuffer: Uint8Array + uuidCiphertextBuffer: Uint8Array ): ServiceIdString { return fromServiceIdObject( decryptServiceIdObj(clientZkGroupCipher, uuidCiphertextBuffer) @@ -95,7 +95,7 @@ export function decryptServiceId( export function decryptAci( clientZkGroupCipher: ClientZkGroupCipher, - uuidCiphertextBuffer: Uint8Array + uuidCiphertextBuffer: Uint8Array ): AciString { const obj = decryptServiceIdObj(clientZkGroupCipher, uuidCiphertextBuffer); strictAssert(obj instanceof Aci, 'userId is not ACI'); @@ -104,7 +104,7 @@ export function decryptAci( export function decryptPni( clientZkGroupCipher: ClientZkGroupCipher, - uuidCiphertextBuffer: Uint8Array + uuidCiphertextBuffer: Uint8Array ): PniString { const obj = decryptServiceIdObj(clientZkGroupCipher, uuidCiphertextBuffer); strictAssert(obj instanceof Pni, 'userId is not PNI'); @@ -126,29 +126,31 @@ export function deriveProfileKeyVersion( } export function deriveAccessKeyFromProfileKey( - profileKeyBytes: Uint8Array -): Uint8Array { + profileKeyBytes: Uint8Array +): Uint8Array { const profileKey = new ProfileKey(profileKeyBytes); return profileKey.deriveAccessKey(); } export function deriveGroupPublicParams( - groupSecretParamsBuffer: Uint8Array -): Uint8Array { + groupSecretParamsBuffer: Uint8Array +): Uint8Array { const groupSecretParams = new GroupSecretParams(groupSecretParamsBuffer); return groupSecretParams.getPublicParams().serialize(); } -export function deriveGroupID(groupSecretParamsBuffer: Uint8Array): Uint8Array { +export function deriveGroupID( + groupSecretParamsBuffer: Uint8Array +): Uint8Array { const groupSecretParams = new GroupSecretParams(groupSecretParamsBuffer); return groupSecretParams.getPublicParams().getGroupIdentifier().serialize(); } export function deriveGroupSecretParams( - masterKeyBuffer: Uint8Array -): Uint8Array { + masterKeyBuffer: Uint8Array +): Uint8Array { const masterKey = new GroupMasterKey(masterKeyBuffer); const groupSecretParams = GroupSecretParams.deriveFromMasterKey(masterKey); @@ -157,15 +159,15 @@ export function deriveGroupSecretParams( export function encryptGroupBlob( clientZkGroupCipher: ClientZkGroupCipher, - plaintext: Uint8Array -): Uint8Array { + plaintext: Uint8Array +): Uint8Array { return clientZkGroupCipher.encryptBlob(plaintext); } export function encryptServiceId( clientZkGroupCipher: ClientZkGroupCipher, serviceIdPlaintext: ServiceIdString -): Uint8Array { +): Uint8Array { const uuidCiphertext = clientZkGroupCipher.encryptServiceId( toServiceIdObject(serviceIdPlaintext) ); @@ -199,7 +201,7 @@ export function getAuthCredentialPresentation( clientZkAuthOperations: ClientZkAuthOperations, authCredentialBase64: string, groupSecretParamsBase64: string -): Uint8Array { +): Uint8Array { const authCredential = new AuthCredentialWithPni( Bytes.fromBase64(authCredentialBase64) ); @@ -219,7 +221,7 @@ export function createProfileKeyCredentialPresentation( clientZkProfileCipher: ClientZkProfileOperations, profileKeyCredentialBase64: string, groupSecretParamsBase64: string -): Uint8Array { +): Uint8Array { const profileKeyCredentialArray = Bytes.fromBase64( profileKeyCredentialBase64 ); @@ -307,8 +309,8 @@ export function deriveProfileKeyCommitment( export function verifyNotarySignature( serverPublicParamsBase64: string, - message: Uint8Array, - signature: Uint8Array + message: Uint8Array, + signature: Uint8Array ): void { const serverPublicParams = new ServerPublicParams( Bytes.fromBase64(serverPublicParamsBase64) diff --git a/ts/windows/main/attachments.preload.ts b/ts/windows/main/attachments.preload.ts index d30859286d..d866500b44 100644 --- a/ts/windows/main/attachments.preload.ts +++ b/ts/windows/main/attachments.preload.ts @@ -42,12 +42,12 @@ try { export const createPlaintextReader = ( root: string -): ((relativePath: string) => Promise) => { +): ((relativePath: string) => Promise>) => { if (!isString(root)) { throw new TypeError("'root' must be a path"); } - return async (relativePath: string): Promise => { + return async (relativePath: string): Promise> => { if (!isString(relativePath)) { throw new TypeError("'relativePath' must be a string"); } @@ -110,12 +110,12 @@ export const copyIntoAttachmentsDirectory = ({ export const createWriterForNew = ( root: string, suffix?: string -): ((bytes: Uint8Array) => Promise) => { +): ((bytes: Uint8Array) => Promise) => { if (!isString(root)) { throw new TypeError("'root' must be a path"); } - return async (bytes: Uint8Array) => { + return async (bytes: Uint8Array) => { if (!isTypedArray(bytes)) { throw new TypeError("'bytes' must be a typed array"); } @@ -131,7 +131,10 @@ export const createWriterForNew = ( const createWriterForExisting = ( root: string -): ((options: { data?: Uint8Array; path?: string }) => Promise) => { +): ((options: { + data?: Uint8Array; + path?: string; +}) => Promise) => { if (!isString(root)) { throw new TypeError("'root' must be a path"); } @@ -140,7 +143,7 @@ const createWriterForExisting = ( data: bytes, path: relativePath, }: { - data?: Uint8Array; + data?: Uint8Array; path?: string; }): Promise => { if (!isString(relativePath)) { @@ -212,7 +215,7 @@ const showSaveDialog = ( async function writeWithAttributes( target: string, - data: Uint8Array + data: Uint8Array ): Promise { await fse.writeFile(target, Buffer.from(data)); @@ -245,7 +248,7 @@ export const saveAttachmentToDisk = async ({ name, baseDir, }: { - data: Uint8Array; + data: Uint8Array; name: string; /** * Base directory for saving the attachment. diff --git a/ts/windows/main/phase1-ipc.preload.ts b/ts/windows/main/phase1-ipc.preload.ts index 849e41d556..96f63e71ef 100644 --- a/ts/windows/main/phase1-ipc.preload.ts +++ b/ts/windows/main/phase1-ipc.preload.ts @@ -550,7 +550,10 @@ ipc.on( { manifest, stickers, - }: { manifest: Uint8Array; stickers: ReadonlyArray } + }: { + manifest: Uint8Array; + stickers: ReadonlyArray>; + } ) => { const packId = await window.Events?.uploadStickerPack(manifest, stickers); diff --git a/ts/windows/main/phase2-dependencies.preload.ts b/ts/windows/main/phase2-dependencies.preload.ts index 2393f7389e..4c62677793 100644 --- a/ts/windows/main/phase2-dependencies.preload.ts +++ b/ts/windows/main/phase2-dependencies.preload.ts @@ -2,7 +2,6 @@ // SPDX-License-Identifier: AGPL-3.0-only import * as moment from 'moment'; -// @ts-expect-error -- no types import 'moment/min/locales.min.js'; import { initialize as initializeLogging } from '../../logging/set_up_renderer_logging.preload.js'; diff --git a/ts/windows/sticker-creator/preload.preload.ts b/ts/windows/sticker-creator/preload.preload.ts index c3e33b17cf..58edf3f752 100644 --- a/ts/windows/sticker-creator/preload.preload.ts +++ b/ts/windows/sticker-creator/preload.preload.ts @@ -12,8 +12,8 @@ ipcRenderer.on('art-creator:onUploadProgress', () => { contextBridge.exposeInMainWorld( 'uploadStickerPack', async ( - manifest: Uint8Array, - stickers: Readonly, + manifest: Uint8Array, + stickers: Readonly>, newOnProgress: (() => void) | undefined ): Promise => { onProgress = newOnProgress; diff --git a/ts/workers/heicConverterMain.main.ts b/ts/workers/heicConverterMain.main.ts index 9a8034b2d2..2b6a26c32f 100644 --- a/ts/workers/heicConverterMain.main.ts +++ b/ts/workers/heicConverterMain.main.ts @@ -7,18 +7,18 @@ import { app } from 'electron'; export type WrappedWorkerRequest = { readonly uuid: string; - readonly data: Uint8Array; + readonly data: Uint8Array; }; export type WrappedWorkerResponse = { readonly uuid: string; readonly error: string | undefined; - readonly response?: Buffer; + readonly response?: Buffer; }; export function getHeicConverter(): ( uuid: string, - data: Uint8Array + data: Uint8Array ) => Promise { const scriptDir = join( app.getAppPath(), diff --git a/ts/workers/heicConverterWorker.node.ts b/ts/workers/heicConverterWorker.node.ts index 743245f3ee..db431283be 100644 --- a/ts/workers/heicConverterWorker.node.ts +++ b/ts/workers/heicConverterWorker.node.ts @@ -15,7 +15,11 @@ if (!parentPort) { const port = parentPort; -function respond(uuid: string, error: Error | undefined, response?: Buffer) { +function respond( + uuid: string, + error: Error | undefined, + response?: Buffer +) { const wrappedResponse: WrappedWorkerResponse = { uuid, error: error?.stack,