diff --git a/.config/vite.browser.mts b/.config/vite.browser.mts
new file mode 100644
index 00000000..4b5b0d90
--- /dev/null
+++ b/.config/vite.browser.mts
@@ -0,0 +1,50 @@
+///
+import { defineConfig, mergeConfig } from 'vite'
+import * as cjsLexer from 'cjs-module-lexer'
+import esbuild from 'esbuild'
+
+import baseConfig from './vite.mjs'
+
+await cjsLexer.init()
+
+export default mergeConfig(baseConfig, defineConfig({
+ test: {
+ browser: {
+ enabled: true,
+ name: 'chromium',
+ provider: 'playwright',
+ slowHijackESM: false,
+ },
+ fakeTimers: {
+ toFake: ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'Date']
+ },
+ // for whatever reason using exclude-s makes the vite never start the browser, so we use skip-s instead.
+ // exclude: [
+ // './packages/crypto-node/**',
+ // './packages/node/**',
+ // ],
+ },
+ plugins: [
+ {
+ name: 'fixup-cjs',
+ async transform(code, id) {
+ if (!id.match(/\/packages\/tl\/.*\.js$/)) return code
+
+ const lexed = cjsLexer.parse(code)
+ const r = await esbuild.transform(code, { format: 'esm' })
+ code = r.code.replace(/export default require_stdin\(\);/, '')
+
+ code += 'const __exp = require_stdin()\n'
+
+ for (const exp of lexed.exports) {
+ code += `export const ${exp} = __exp.${exp}\n`
+ }
+
+ return code
+ }
+ }
+ ],
+ define: {
+ 'import.meta.env.TEST_ENV': '"browser"'
+ }
+}))
diff --git a/.config/vite.mts b/.config/vite.mts
index d533ada6..aa150bb8 100644
--- a/.config/vite.mts
+++ b/.config/vite.mts
@@ -12,4 +12,7 @@ export default defineConfig({
],
},
},
+ define: {
+ 'import.meta.env.TEST_ENV': '"node"'
+ }
})
diff --git a/.github/actions/init/action.yml b/.github/actions/init/action.yml
new file mode 100644
index 00000000..ec461fea
--- /dev/null
+++ b/.github/actions/init/action.yml
@@ -0,0 +1,20 @@
+inputs:
+ node-version:
+ default: '18.x'
+
+runs:
+ using: 'composite'
+ steps:
+ - name: Use Node.js ${{ inputs.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ inputs.node-version }}
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: 8
+ - run: pnpm install --frozen-lockfile
+ shell: bash
+ - name: 'TL codegen'
+ run: pnpm -C packages/tl run gen-code
+ shell: bash
\ No newline at end of file
diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index b3717582..e40670e6 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -20,21 +20,10 @@ jobs:
if: github.repository == 'mtcute/mtcute' # do not run on forks
runs-on: ubuntu-latest
steps:
- - name: Checkout repository
- uses: actions/checkout@v3
- - name: Set up Node
- uses: actions/setup-node@v3
- with:
- node-version: "18"
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: 8
+ - uses: actions/checkout@v4
+ - uses: ./.github/actions/init
- name: Setup Pages
uses: actions/configure-pages@v3
- - run: pnpm install --frozen-lockfile
- - name: 'TL codegen'
- run: pnpm -C packages/tl run gen-code
- name: Build
run: pnpm run -r build
- name: Build docs
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index a7d3cf74..5b0746a6 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -29,17 +29,7 @@ jobs:
with:
fetch-depth: 0
token: ${{ secrets.BOT_PAT }}
- - name: Set up Node
- uses: actions/setup-node@v3
- with:
- node-version: "18"
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: 8
- - run: pnpm install --frozen-lockfile
- - name: 'TL codegen'
- run: pnpm -C packages/tl run gen-code
+ - uses: ./.github/actions/init
- name: Initialize configs
run: |
git config user.name "mtcute-bot"
diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml
index 868d094d..d969a9d8 100644
--- a/.github/workflows/test.yaml
+++ b/.github/workflows/test.yaml
@@ -9,33 +9,33 @@ on:
branches: [ master ]
jobs:
- test:
+ lint:
runs-on: ubuntu-latest
if: github.actor != 'mtcute-bot' # do not run after release
-
- strategy:
- matrix:
- node-version: [18.x, 20.x]
steps:
- uses: actions/checkout@v4
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v3
- with:
- node-version: ${{ matrix.node-version }}
- - name: Setup pnpm
- uses: pnpm/action-setup@v2
- with:
- version: 8
- - run: pnpm install --frozen-lockfile
- - name: 'TL codegen'
- run: pnpm -C packages/tl run gen-code
+ - uses: ./.github/actions/init
- name: 'TypeScript'
run: pnpm run lint:tsc:ci
- name: 'ESLint'
run: pnpm run lint:ci
- name: 'Circular dependencies'
run: pnpm run lint:dpdm
- - run: pnpm run test:ci
+
+ test-node:
+ runs-on: ubuntu-latest
+ needs: lint
+
+ strategy:
+ matrix:
+ node-version: [18.x, 20.x]
+ steps:
+ - uses: actions/checkout@v4
+ - uses: ./.github/actions/init
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: 'Run tests'
+ run: pnpm run test:ci
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
if: ${{ matrix.node-version == '18.x' }} # to avoid uploading twice
@@ -43,9 +43,25 @@ jobs:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
with:
files: ./coverage/coverage-final.json
+
+ test-web:
+ runs-on: ubuntu-latest
+ needs: lint
+
+ strategy:
+ matrix:
+ browser: [chromium, firefox]
+ steps:
+ - uses: actions/checkout@v4
+ - uses: ./.github/actions/init
+ - name: 'Initialize browser'
+ run: pnpm exec playwright install --with-deps ${{ matrix.browser }}
+ - name: 'Run tests'
+ run: pnpm run test:browser --browser.name=${{ matrix.browser }}
+
e2e:
runs-on: ubuntu-latest
- needs: test
+ needs: [test-node, test-web]
steps:
- uses: actions/checkout@v4
- name: Run end-to-end tests
diff --git a/e2e/ts/utils.ts b/e2e/ts/utils.ts
index 7e14ca6c..f747f8be 100644
--- a/e2e/ts/utils.ts
+++ b/e2e/ts/utils.ts
@@ -1,4 +1,4 @@
-import type { BaseTelegramClientOptions } from '@mtcute/core'
+import { BaseTelegramClientOptions } from '@mtcute/core'
export const getApiParams = (): BaseTelegramClientOptions => {
if (!process.env.API_ID || !process.env.API_HASH) {
diff --git a/package.json b/package.json
index 2d3caaaa..af2fba8f 100644
--- a/package.json
+++ b/package.json
@@ -8,14 +8,16 @@
"scripts": {
"prepare": "husky install .config/husky",
"postinstall": "node scripts/validate-deps-versions.mjs",
- "test": "vitest --config .config/vite.mts run && pnpm run -r test",
+ "test": "pnpm run -r test && vitest --config .config/vite.mts run",
"test:dev": "vitest --config .config/vite.mts watch",
"test:ui": "vitest --config .config/vite.mts --ui",
"test:coverage": "vitest --config .config/vite.mts run --coverage",
"test:ci": "vitest --config .config/vite.mts run --coverage.enabled --coverage.reporter=json",
+ "test:browser": "vitest --config .config/vite.browser.mts run",
+ "test:browser:dev": "vitest --config .config/vite.browser.mts watch",
"lint": "eslint .",
"lint:ci": "NODE_OPTIONS=\\\"--max_old_space_size=8192\\\" eslint --config .config/eslint.ci.js .",
- "lint:tsc": "pnpm -r --parallel exec tsc --build",
+ "lint:tsc": "pnpm -r --workspace-concurrency=4 exec tsc --build",
"lint:tsc:ci": "pnpm -r exec tsc --build",
"lint:dpdm": "dpdm -T --no-warning --no-tree --exit-code circular:1 packages/*",
"lint:fix": "eslint --fix .",
@@ -30,14 +32,18 @@
"devDependencies": {
"@commitlint/cli": "17.6.5",
"@commitlint/config-conventional": "17.6.5",
+ "@types/node": "20.10.0",
"@types/node-forge": "1.3.2",
"@types/ws": "8.5.4",
"@typescript-eslint/eslint-plugin": "6.4.0",
"@typescript-eslint/parser": "6.4.0",
+ "@vitest/browser": "0.34.6",
"@vitest/coverage-v8": "0.34.6",
"@vitest/ui": "0.34.6",
+ "cjs-module-lexer": "1.2.3",
"dotenv-flow": "3.2.0",
"dpdm": "3.14.0",
+ "esbuild": "0.18.20",
"eslint": "8.47.0",
"eslint-config-prettier": "8.8.0",
"eslint-import-resolver-typescript": "3.6.0",
@@ -48,6 +54,7 @@
"husky": "8.0.3",
"lint-staged": "13.2.2",
"node-forge": "1.3.1",
+ "playwright": "^1.40.1",
"prettier": "3.0.3",
"rimraf": "5.0.1",
"semver": "7.5.1",
@@ -55,7 +62,7 @@
"tsconfig-paths": "4.2.0",
"typedoc": "0.25.3",
"typescript": "5.0.4",
- "vite": "4.5.0",
+ "vite": "5.0.3",
"vitest": "0.34.6"
},
"prettier": "./.config/prettier.cjs",
diff --git a/packages/client/package.json b/packages/client/package.json
index e3fb81d8..f8215ecf 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -29,10 +29,8 @@
}
},
"browser": {
- "./cjs/methods/files/_platform.js": "./cjs/methods/files/_platform.web.js",
- "./esm/methods/files/_platform.js": "./esm/methods/files/_platform.web.js",
- "./cjs/methods/files/download-file.js": "./cjs/methods/files/download-file.web.js",
- "./esm/methods/files/download-file.js": "./esm/methods/files/download-file.web.js"
+ "./src/methods/files/_platform.js": "./src/methods/files/_platform.web.js",
+ "./src/methods/files/download-file.js": "./src/methods/files/download-file.web.js"
},
"dependencies": {
"@mtcute/core": "workspace:^",
diff --git a/packages/client/scripts/generate-client.cjs b/packages/client/scripts/generate-client.cjs
index d6cee0f2..e4bf48b7 100644
--- a/packages/client/scripts/generate-client.cjs
+++ b/packages/client/scripts/generate-client.cjs
@@ -632,7 +632,7 @@ on(name: string, handler: (...args: any[]) => void): this\n`)
)
output.write('}\n')
- output.write('\nexport { TelegramClientOptions }\n')
+ output.write('\nexport type { TelegramClientOptions }\n')
output.write('\nexport class TelegramClient extends BaseTelegramClient {\n')
state.fields.forEach(({ code }) => output.write(`protected ${code}\n`))
diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts
index 702022df..a8ef31c0 100644
--- a/packages/client/src/client.ts
+++ b/packages/client/src/client.ts
@@ -5075,7 +5075,7 @@ export interface TelegramClient extends BaseTelegramClient {
}): Promise
}
-export { TelegramClientOptions }
+export type { TelegramClientOptions }
export class TelegramClient extends BaseTelegramClient {
constructor(opts: TelegramClientOptions) {
diff --git a/packages/client/src/types/peers/chat-event/index.ts b/packages/client/src/types/peers/chat-event/index.ts
index 1875fde3..35e53a7b 100644
--- a/packages/client/src/types/peers/chat-event/index.ts
+++ b/packages/client/src/types/peers/chat-event/index.ts
@@ -7,7 +7,7 @@ import { User } from '../user.js'
import { _actionFromTl, ChatAction } from './actions.js'
export * from './actions.js'
-export { ChatEventFilters, InputChatEventFilters } from './filters.js'
+export type { ChatEventFilters, InputChatEventFilters } from './filters.js'
export class ChatEvent {
constructor(
diff --git a/packages/client/src/types/updates/index.ts b/packages/client/src/types/updates/index.ts
index c6f26a89..c5c52172 100644
--- a/packages/client/src/types/updates/index.ts
+++ b/packages/client/src/types/updates/index.ts
@@ -2,7 +2,8 @@ import type { CallbackQuery, InlineQuery, Message } from '../../types/index.js'
import { BotChatJoinRequestUpdate } from './bot-chat-join-request.js'
import { BotStoppedUpdate } from './bot-stopped.js'
import { ChatJoinRequestUpdate } from './chat-join-request.js'
-import { ChatMemberUpdate, ChatMemberUpdateType } from './chat-member-update.js'
+import { ChatMemberUpdate } from './chat-member-update.js'
+export type { ChatMemberUpdateType } from './chat-member-update.js'
import { ChosenInlineResult } from './chosen-inline-result.js'
import { DeleteMessageUpdate } from './delete-message-update.js'
import { DeleteStoryUpdate } from './delete-story-update.js'
@@ -19,7 +20,6 @@ export {
BotStoppedUpdate,
ChatJoinRequestUpdate,
ChatMemberUpdate,
- ChatMemberUpdateType,
ChosenInlineResult,
DeleteMessageUpdate,
DeleteStoryUpdate,
diff --git a/packages/client/src/utils/stream-utils.test.ts b/packages/client/src/utils/stream-utils.test.ts
index 2098d644..e07aebc8 100644
--- a/packages/client/src/utils/stream-utils.test.ts
+++ b/packages/client/src/utils/stream-utils.test.ts
@@ -83,23 +83,25 @@ describe('createChunkedReader', () => {
})
})
-describe('nodeReadableToWeb', () => {
- it('should correctly convert a readable stream', async () => {
- const stream = new Readable({
- read() {
- // eslint-disable-next-line no-restricted-globals
- this.push(Buffer.from([1, 2, 3]))
- // eslint-disable-next-line no-restricted-globals
- this.push(Buffer.from([4, 5, 6]))
- this.push(null)
- },
+if (import.meta.env.TEST_ENV === 'node') {
+ describe('nodeReadableToWeb', () => {
+ it('should correctly convert a readable stream', async () => {
+ const stream = new Readable({
+ read() {
+ // eslint-disable-next-line no-restricted-globals
+ this.push(Buffer.from([1, 2, 3]))
+ // eslint-disable-next-line no-restricted-globals
+ this.push(Buffer.from([4, 5, 6]))
+ this.push(null)
+ },
+ })
+
+ const webStream = nodeReadableToWeb(stream)
+ const reader = webStream.getReader()
+
+ expect(await reader.read()).to.deep.equal({ value: new Uint8Array([1, 2, 3]), done: false })
+ expect(await reader.read()).to.deep.equal({ value: new Uint8Array([4, 5, 6]), done: false })
+ expect(await reader.read()).to.deep.equal({ value: undefined, done: true })
})
-
- const webStream = nodeReadableToWeb(stream)
- const reader = webStream.getReader()
-
- expect(await reader.read()).to.deep.equal({ value: new Uint8Array([1, 2, 3]), done: false })
- expect(await reader.read()).to.deep.equal({ value: new Uint8Array([4, 5, 6]), done: false })
- expect(await reader.read()).to.deep.equal({ value: undefined, done: true })
})
-})
+}
diff --git a/packages/core/package.json b/packages/core/package.json
index 078ea846..eb1924d1 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -11,16 +11,11 @@
"build": "pnpm run -w build-package core"
},
"browser": {
- "./cjs/utils/platform/crypto.js": "./cjs/utils/platform/crypto.web.js",
- "./esm/utils/platform/crypto.js": "./esm/utils/platform/crypto.web.js",
- "./cjs/utils/platform/transport.js": "./cjs/utils/platform/transport.web.js",
- "./esm/utils/platform/transport.js": "./esm/utils/platform/transport.web.js",
- "./cjs/utils/platform/logging.js": "./cjs/utils/platform/logging.web.js",
- "./esm/utils/platform/logging.js": "./esm/utils/platform/logging.web.js",
- "./cjs/utils/platform/random.js": "./cjs/utils/platform/random.web.js",
- "./esm/utils/platform/random.js": "./esm/utils/platform/random.web.js",
- "./cjs/storage/json-file.js": false,
- "./esm/storage/json-file.js": false
+ "./src/utils/platform/crypto.js": "./src/utils/platform/crypto.web.js",
+ "./src/utils/platform/transport.js": "./src/utils/platform/transport.web.js",
+ "./src/utils/platform/logging.js": "./src/utils/platform/logging.web.js",
+ "./src/utils/platform/random.js": "./src/utils/platform/random.web.js",
+ "./src/storage/json-file.js": false
},
"distOnlyFields": {
"exports": {
diff --git a/packages/core/src/network/index.ts b/packages/core/src/network/index.ts
index 4973595f..7057a4f0 100644
--- a/packages/core/src/network/index.ts
+++ b/packages/core/src/network/index.ts
@@ -1,4 +1,4 @@
-export { ConnectionKind, NetworkManagerExtraParams, RpcCallOptions } from './network-manager.js'
+export type { ConnectionKind, NetworkManagerExtraParams, RpcCallOptions } from './network-manager.js'
export * from './reconnection.js'
export * from './session-connection.js'
export * from './transports/index.js'
diff --git a/packages/core/src/network/transports/intermediate.test.ts b/packages/core/src/network/transports/intermediate.test.ts
index 52670516..3f8f3de4 100644
--- a/packages/core/src/network/transports/intermediate.test.ts
+++ b/packages/core/src/network/transports/intermediate.test.ts
@@ -4,7 +4,6 @@ import { defaultTestCryptoProvider, useFakeMathRandom } from '@mtcute/test'
import { hexDecodeToBuffer, hexEncode } from '@mtcute/tl-runtime'
import { IntermediatePacketCodec, PaddedIntermediatePacketCodec, TransportError } from '../../index.js'
-import { concatBuffers } from '../../utils/index.js'
describe('IntermediatePacketCodec', () => {
it('should return correct tag', () => {
@@ -82,10 +81,7 @@ describe('IntermediatePacketCodec', () => {
it('should correctly frame packets', () => {
const data = hexDecodeToBuffer('6cfeffff')
- // eslint-disable-next-line no-restricted-globals
- expect(Buffer.from(new IntermediatePacketCodec().encode(data))).toEqual(
- concatBuffers([new Uint8Array([0x04, 0x00, 0x00, 0x00]), data]),
- )
+ expect(hexEncode(new IntermediatePacketCodec().encode(data))).toEqual('040000006cfeffff')
})
})
diff --git a/packages/core/src/network/transports/tcp.test.ts b/packages/core/src/network/transports/tcp.test.ts
index ceb546a7..1ef0b80d 100644
--- a/packages/core/src/network/transports/tcp.test.ts
+++ b/packages/core/src/network/transports/tcp.test.ts
@@ -1,150 +1,155 @@
import { Socket } from 'net'
import { describe, expect, it, MockedObject, vi } from 'vitest'
-import { defaultTestCryptoProvider, u8HexDecode } from '@mtcute/test'
+if (import.meta.env.TEST_ENV === 'node') {
+ vi.doMock('net', () => ({
+ connect: vi.fn().mockImplementation((port: number, ip: string, cb: () => void) => {
+ cb()
-import { defaultProductionDc, hexDecodeToBuffer, LogManager } from '../../utils/index.js'
-import { TransportState } from './abstract.js'
-import { TcpTransport } from './tcp.js'
+ return {
+ on: vi.fn(),
+ write: vi.fn().mockImplementation((data: Uint8Array, cb: () => void) => {
+ cb()
+ }),
+ end: vi.fn(),
+ removeAllListeners: vi.fn(),
+ destroy: vi.fn(),
+ }
+ }),
+ }))
-vi.mock('net', () => ({
- connect: vi.fn().mockImplementation((port: number, ip: string, cb: () => void) => {
- cb()
-
- return {
- on: vi.fn(),
- write: vi.fn().mockImplementation((data: Uint8Array, cb: () => void) => {
- cb()
- }),
- end: vi.fn(),
- removeAllListeners: vi.fn(),
- destroy: vi.fn(),
- }
- }),
-}))
-
-describe('TcpTransport', async () => {
const net = await import('net')
const connect = vi.mocked(net.connect)
- const getLastSocket = () => {
- return connect.mock.results[connect.mock.results.length - 1].value as MockedObject
- }
+ // we need to do these imports here because basically all of them import `net`
+ const { defaultTestCryptoProvider, u8HexDecode } = await import('@mtcute/test')
- const create = async () => {
- const transport = new TcpTransport()
- const logger = new LogManager()
- logger.level = 0
- transport.setup(await defaultTestCryptoProvider(), logger)
+ const { TcpTransport } = await import('./tcp.js')
+ const { defaultProductionDc, hexDecodeToBuffer, LogManager } = await import('../../utils/index.js')
+ const { TransportState } = await import('./abstract.js')
- return transport
- }
+ describe('TcpTransport', () => {
+ const getLastSocket = () => {
+ return connect.mock.results[connect.mock.results.length - 1].value as MockedObject
+ }
- it('should initiate a tcp connection to the given dc', async () => {
- const t = await create()
+ const create = async () => {
+ const transport = new TcpTransport()
+ const logger = new LogManager()
+ logger.level = 0
+ transport.setup(await defaultTestCryptoProvider(), logger)
- t.connect(defaultProductionDc.main, false)
+ return transport
+ }
- expect(connect).toHaveBeenCalledOnce()
- expect(connect).toHaveBeenCalledWith(
- defaultProductionDc.main.port,
- defaultProductionDc.main.ipAddress,
- expect.any(Function),
- )
- await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
- })
+ it('should initiate a tcp connection to the given dc', async () => {
+ const t = await create()
- it('should set up event handlers', async () => {
- const t = await create()
+ t.connect(defaultProductionDc.main, false)
- t.connect(defaultProductionDc.main, false)
-
- const socket = getLastSocket()
-
- expect(socket.on).toHaveBeenCalledTimes(3)
- expect(socket.on).toHaveBeenCalledWith('data', expect.any(Function))
- expect(socket.on).toHaveBeenCalledWith('error', expect.any(Function))
- expect(socket.on).toHaveBeenCalledWith('close', expect.any(Function))
- })
-
- it('should write packet codec tag once connected', async () => {
- const t = await create()
-
- t.connect(defaultProductionDc.main, false)
-
- const socket = getLastSocket()
-
- await vi.waitFor(() =>
- expect(socket.write).toHaveBeenCalledWith(
- u8HexDecode('eeeeeeee'), // intermediate
+ expect(connect).toHaveBeenCalledOnce()
+ expect(connect).toHaveBeenCalledWith(
+ defaultProductionDc.main.port,
+ defaultProductionDc.main.ipAddress,
expect.any(Function),
- ),
- )
+ )
+ await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
+ })
+
+ it('should set up event handlers', async () => {
+ const t = await create()
+
+ t.connect(defaultProductionDc.main, false)
+
+ const socket = getLastSocket()
+
+ expect(socket.on).toHaveBeenCalledTimes(3)
+ expect(socket.on).toHaveBeenCalledWith('data', expect.any(Function))
+ expect(socket.on).toHaveBeenCalledWith('error', expect.any(Function))
+ expect(socket.on).toHaveBeenCalledWith('close', expect.any(Function))
+ })
+
+ it('should write packet codec tag once connected', async () => {
+ const t = await create()
+
+ t.connect(defaultProductionDc.main, false)
+
+ const socket = getLastSocket()
+
+ await vi.waitFor(() =>
+ expect(socket.write).toHaveBeenCalledWith(
+ u8HexDecode('eeeeeeee'), // intermediate
+ expect.any(Function),
+ ),
+ )
+ })
+
+ it('should write to the underlying socket', async () => {
+ const t = await create()
+
+ t.connect(defaultProductionDc.main, false)
+ await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
+
+ await t.send(hexDecodeToBuffer('00010203040506070809'))
+
+ const socket = getLastSocket()
+
+ expect(socket.write).toHaveBeenCalledWith(u8HexDecode('0a00000000010203040506070809'), expect.any(Function))
+ })
+
+ it('should correctly close', async () => {
+ const t = await create()
+
+ t.connect(defaultProductionDc.main, false)
+ await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
+
+ t.close()
+
+ const socket = getLastSocket()
+
+ expect(socket.removeAllListeners).toHaveBeenCalledOnce()
+ expect(socket.destroy).toHaveBeenCalledOnce()
+ })
+
+ it('should feed data to the packet codec', async () => {
+ const t = await create()
+ const codec = t._packetCodec
+
+ const spyFeed = vi.spyOn(codec, 'feed')
+
+ t.connect(defaultProductionDc.main, false)
+ await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
+
+ const socket = getLastSocket()
+
+ const onDataCall = socket.on.mock.calls.find((c) => (c as string[])[0] === 'data') as unknown as [
+ string,
+ (data: Uint8Array) => void,
+ ]
+ onDataCall[1](u8HexDecode('00010203040506070809'))
+
+ expect(spyFeed).toHaveBeenCalledWith(u8HexDecode('00010203040506070809'))
+ })
+
+ it('should propagate errors', async () => {
+ const t = await create()
+
+ const spyEmit = vi.spyOn(t, 'emit').mockImplementation(() => true)
+
+ t.connect(defaultProductionDc.main, false)
+ await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
+
+ const socket = getLastSocket()
+
+ const onErrorCall = socket.on.mock.calls.find((c) => (c as string[])[0] === 'error') as unknown as [
+ string,
+ (error: Error) => void,
+ ]
+ onErrorCall[1](new Error('test error'))
+
+ expect(spyEmit).toHaveBeenCalledWith('error', new Error('test error'))
+ })
})
-
- it('should write to the underlying socket', async () => {
- const t = await create()
-
- t.connect(defaultProductionDc.main, false)
- await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
-
- await t.send(hexDecodeToBuffer('00010203040506070809'))
-
- const socket = getLastSocket()
-
- expect(socket.write).toHaveBeenCalledWith(u8HexDecode('0a00000000010203040506070809'), expect.any(Function))
- })
-
- it('should correctly close', async () => {
- const t = await create()
-
- t.connect(defaultProductionDc.main, false)
- await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
-
- t.close()
-
- const socket = getLastSocket()
-
- expect(socket.removeAllListeners).toHaveBeenCalledOnce()
- expect(socket.destroy).toHaveBeenCalledOnce()
- })
-
- it('should feed data to the packet codec', async () => {
- const t = await create()
- const codec = t._packetCodec
-
- const spyFeed = vi.spyOn(codec, 'feed')
-
- t.connect(defaultProductionDc.main, false)
- await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
-
- const socket = getLastSocket()
-
- const onDataCall = socket.on.mock.calls.find((c) => (c as string[])[0] === 'data') as unknown as [
- string,
- (data: Uint8Array) => void,
- ]
- onDataCall[1](u8HexDecode('00010203040506070809'))
-
- expect(spyFeed).toHaveBeenCalledWith(u8HexDecode('00010203040506070809'))
- })
-
- it('should propagate errors', async () => {
- const t = await create()
-
- const spyEmit = vi.spyOn(t, 'emit').mockImplementation(() => true)
-
- t.connect(defaultProductionDc.main, false)
- await vi.waitFor(() => expect(t.state()).toEqual(TransportState.Ready))
-
- const socket = getLastSocket()
-
- const onErrorCall = socket.on.mock.calls.find((c) => (c as string[])[0] === 'error') as unknown as [
- string,
- (error: Error) => void,
- ]
- onErrorCall[1](new Error('test error'))
-
- expect(spyEmit).toHaveBeenCalledWith('error', new Error('test error'))
- })
-})
+} else {
+ describe.skip('TcpTransport', () => {})
+}
diff --git a/packages/core/src/storage/json.test.ts b/packages/core/src/storage/json.test.ts
index 4aa14c97..0be416af 100644
--- a/packages/core/src/storage/json.test.ts
+++ b/packages/core/src/storage/json.test.ts
@@ -4,6 +4,9 @@ import { stubPeerUser } from '@mtcute/test'
import { JsonMemoryStorage } from './json.js'
+// eslint-disable-next-line no-restricted-globals
+const createBuffer = import.meta.env.TEST_ENV === 'node' ? Buffer.from : (d: number[]) => new Uint8Array(d)
+
describe('JsonMemoryStorage', () => {
class ExtJsonMemoryStorage extends JsonMemoryStorage {
loadJson(json: string): void {
@@ -25,9 +28,9 @@ describe('JsonMemoryStorage', () => {
s.setUpdatesPts(123)
s.setUpdatesQts(456)
// eslint-disable-next-line no-restricted-globals
- s.setAuthKeyFor(1, Buffer.from([1, 2, 3]))
+ s.setAuthKeyFor(1, createBuffer([1, 2, 3]))
// eslint-disable-next-line no-restricted-globals
- s.setTempAuthKeyFor(2, 0, Buffer.from([4, 5, 6]), 1234567890)
+ s.setTempAuthKeyFor(2, 0, createBuffer([4, 5, 6]), 1234567890)
s.setState('someState', 'someValue')
s.updatePeers([{ ...stubPeerUser, updated: 0 }])
diff --git a/packages/core/src/utils/crypto/mtproto.test.ts b/packages/core/src/utils/crypto/mtproto.test.ts
index 667fcff3..d64b5cf4 100644
--- a/packages/core/src/utils/crypto/mtproto.test.ts
+++ b/packages/core/src/utils/crypto/mtproto.test.ts
@@ -1,80 +1,85 @@
-/* eslint-disable no-restricted-globals */
-import { describe, expect, it, vi } from 'vitest'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
+import { defaultTestCryptoProvider, u8HexDecode } from '@mtcute/test'
+
+import { concatBuffers, hexDecodeToBuffer, hexEncode } from '../index.js'
import { createAesIgeForMessage, createAesIgeForMessageOld, generateKeyAndIvFromNonce } from './mtproto.js'
-import { NodeCryptoProvider } from './node.js'
-const authKey = Buffer.alloc(
- 2048 / 8,
- Buffer.from('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0', 'hex'),
-)
-const messageKey = Buffer.from('25d701f2a29205526757825a99eb2d32')
+const authKeyChunk = hexDecodeToBuffer('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0')
+const authKey = concatBuffers(Array.from({ length: 8 }, () => authKeyChunk))
+const messageKey = hexDecodeToBuffer('25d701f2a29205526757825a99eb2d32')
+
+describe('mtproto 2.0', async () => {
+ const crypto = await defaultTestCryptoProvider()
+ const createAesIgeSpy = vi.spyOn(crypto, 'createAesIge')
+
+ beforeEach(() => void createAesIgeSpy.mockClear())
-describe('mtproto 2.0', () => {
it('should correctly derive message key and iv for client', () => {
- const crypto = new NodeCryptoProvider()
- const spy = vi.spyOn(crypto, 'createAesIge')
-
createAesIgeForMessage(crypto, authKey, messageKey, true)
- expect(spy).toHaveBeenCalledWith(
- Buffer.from('7acac59ab48cd370e478daf6c64545ab9f32d5c9197f25febe052110f61875ca', 'hex'),
- Buffer.from('2746ccc19fc260c08f3d2696389f415392103dbcc3a8bf69da9394c3c3d95bd3', 'hex'),
+ expect(hexEncode(createAesIgeSpy.mock.calls[0][0])).toEqual(
+ 'af3f8e1ffa75f4c981eec33a3e5bbaa2ea48f9bb93e91597627eb1f67960a0c9',
+ )
+ expect(hexEncode(createAesIgeSpy.mock.calls[0][1])).toEqual(
+ '9874d77f95155b35221bff94b7df4594c6996e2a62e44fcb7d93c8c4e41b79ee',
)
})
it('should correctly derive message key and iv for server', () => {
- const crypto = new NodeCryptoProvider()
- const spy = vi.spyOn(crypto, 'createAesIge')
-
createAesIgeForMessage(crypto, authKey, messageKey, false)
- expect(spy).toHaveBeenCalledWith(
- Buffer.from('c7cf179e7ebab144ba87de05415db4157d2fc66df4790b2fd405a6c8cbe4c0b3', 'hex'),
- Buffer.from('0916a7bd9880eacd4eeb868577a4c6a50e76fca4ac5c1bcfbafe3b9f76ccd806', 'hex'),
+ expect(hexEncode(createAesIgeSpy.mock.calls[0][0])).toEqual(
+ 'd4b378e1e0525f10ff9d4c42807ccce5b30a033a8088c0b922b5259421751648',
+ )
+ expect(hexEncode(createAesIgeSpy.mock.calls[0][1])).toEqual(
+ '4d7194f42f0135d2fd83050b403265b4c40ee3e9e9fba56f0f4d8ea6bcb121f5',
)
})
})
-describe('mtproto 1.0', () => {
- it('should correctly derive message key and iv for client', () => {
- const crypto = new NodeCryptoProvider()
- const spy = vi.spyOn(crypto, 'createAesIge')
+describe('mtproto 1.0', async () => {
+ const crypto = await defaultTestCryptoProvider()
+ const createAesIgeSpy = vi.spyOn(crypto, 'createAesIge')
+ beforeEach(() => void createAesIgeSpy.mockClear())
+
+ it('should correctly derive message key and iv for client', () => {
createAesIgeForMessageOld(crypto, authKey, messageKey, true)
- expect(spy).toHaveBeenCalledWith(
- Buffer.from('aad61cb5b7be5e8435174d74665f8a978e85806d0970ad4958642ca49e3c8834', 'hex'),
- Buffer.from('4065736fe6586e94aad9f024062f1b9988e8a44e2aff4e11aad61cb5b7be5e84', 'hex'),
+ expect(hexEncode(createAesIgeSpy.mock.calls[0][0])).toEqual(
+ '1fc7b40b1d9ffbdaf4d652525a748864259698f89214abf27c0d36cb9d4cd5db',
+ )
+ expect(hexEncode(createAesIgeSpy.mock.calls[0][1])).toEqual(
+ '7251fbda39ec5e6e089f15ded5963b03d6d8d0f7078898431fc7b40b1d9ffbda',
)
})
it('should correctly derive message key and iv for server', () => {
- const crypto = new NodeCryptoProvider()
- const spy = vi.spyOn(crypto, 'createAesIge')
-
createAesIgeForMessageOld(crypto, authKey, messageKey, false)
- expect(spy).toHaveBeenCalledWith(
- Buffer.from('d57682a17105e43b92bc5025ea80e88ef708240fc19450dfe072a8760f9534da', 'hex'),
- Buffer.from('07addff7beeb7705ef3a9d5090bd73c992d57291bb8a7079d57682a17105e43b', 'hex'),
+ expect(hexEncode(createAesIgeSpy.mock.calls[0][0])).toEqual(
+ 'af0e4e01318654be40ab42b125909d43b44bdeef571ff1a5dfb81474ae26d467',
+ )
+ expect(hexEncode(createAesIgeSpy.mock.calls[0][1])).toEqual(
+ '15c9ba6021d2c5cf04f0842540ae216a970b4eac8f46ef01af0e4e01318654be',
)
})
})
-describe('mtproto key/iv from nonce', () => {
- it('should correctly derive message key and iv for given nonces', () => {
- const crypto = new NodeCryptoProvider()
+describe('mtproto key/iv from nonce', async () => {
+ const crypto = await defaultTestCryptoProvider()
+ it('should correctly derive message key and iv for given nonces', () => {
const res = generateKeyAndIvFromNonce(
crypto,
- Buffer.from('8af24c551836e5ed7002f5857e6e71b2', 'hex'),
- Buffer.from('3bf48b2d3152f383d82d1f2b32ac7fb5', 'hex'),
+ u8HexDecode('8af24c551836e5ed7002f5857e6e71b2'),
+ u8HexDecode('3bf48b2d3152f383d82d1f2b32ac7fb5'),
)
expect(res).to.eql([
- Buffer.from('b0b5ffeadff0249fa6292f5ae0351556fd6619ba5dd4809601669292456d3e5a', 'hex'),
- Buffer.from('13fef5bfd8c46b12dfd1753013b86cc012e1ce8ed6f8ecdd7bf36f3a3bf48b2d', 'hex'),
+ u8HexDecode('b0b5ffeadff0249fa6292f5ae0351556fd6619ba5dd4809601669292456d3e5a'),
+ u8HexDecode('13fef5bfd8c46b12dfd1753013b86cc012e1ce8ed6f8ecdd7bf36f3a3bf48b2d'),
])
})
})
diff --git a/packages/core/src/utils/crypto/node.test.ts b/packages/core/src/utils/crypto/node.test.ts
index 549ae186..13fdc573 100644
--- a/packages/core/src/utils/crypto/node.test.ts
+++ b/packages/core/src/utils/crypto/node.test.ts
@@ -2,14 +2,12 @@ import { describe } from 'vitest'
import { testCryptoProvider } from '@mtcute/test'
-import { NodeCryptoProvider } from './node.js'
+if (import.meta.env.TEST_ENV === 'node') {
+ describe('NodeCryptoProvider', async () => {
+ const { NodeCryptoProvider } = await import('./node.js')
-describe('NodeCryptoProvider', () => {
- if (typeof process === 'undefined') {
- console.warn('Skipping NodeCryptoProvider tests')
-
- return
- }
-
- testCryptoProvider(new NodeCryptoProvider())
-})
+ testCryptoProvider(new NodeCryptoProvider())
+ })
+} else {
+ describe.skip('NodeCryptoProvider', () => {})
+}
diff --git a/packages/core/src/utils/crypto/utils.test.ts b/packages/core/src/utils/crypto/utils.test.ts
index cd4faed4..e457dacf 100644
--- a/packages/core/src/utils/crypto/utils.test.ts
+++ b/packages/core/src/utils/crypto/utils.test.ts
@@ -10,8 +10,8 @@ describe('xorBuffer', () => {
const key = utf8EncodeToBuffer('xor')
const xored = xorBuffer(data, key)
- expect(data.toString()).eq('hello')
- expect(key.toString()).eq('xor')
+ expect(utf8Decode(data)).eq('hello')
+ expect(utf8Decode(key)).eq('xor')
expect(hexEncode(xored)).eq('100a1e6c6f')
})
@@ -45,7 +45,7 @@ describe('xorBufferInPlace', () => {
xorBufferInPlace(data, key)
expect(hexEncode(data)).eq('100a1e6c6f')
- expect(key.toString()).eq('xor')
+ expect(utf8Decode(key)).eq('xor')
})
it('second call should decode content', () => {
@@ -56,6 +56,6 @@ describe('xorBufferInPlace', () => {
expect(hexEncode(data)).eq('100a1e6c6f')
xorBufferInPlace(data, key)
- expect(data.toString()).eq('hello')
+ expect(utf8Decode(data)).eq('hello')
})
})
diff --git a/packages/core/src/utils/logger.test.ts b/packages/core/src/utils/logger.test.ts
index c1a4813e..50bebc91 100644
--- a/packages/core/src/utils/logger.test.ts
+++ b/packages/core/src/utils/logger.test.ts
@@ -130,16 +130,18 @@ describe('logger', () => {
expect(spy).toHaveBeenCalledWith(3, 3, 'base', 'test {"a":1}', [])
})
- it('should format buffers inside as hex strings', () => {
- const [mgr, spy] = createManager()
+ if (import.meta.env.TEST_ENV === 'node') {
+ it('should format Buffers inside as hex strings', () => {
+ const [mgr, spy] = createManager()
- // eslint-disable-next-line no-restricted-globals
- mgr.info('test %j', { a: Buffer.from([1, 2, 3]) })
- mgr.info('test Uint8Array %j', { a: new Uint8Array([1, 2, 3]) })
+ // eslint-disable-next-line no-restricted-globals
+ mgr.info('test %j', { a: Buffer.from([1, 2, 3]) })
+ mgr.info('test Uint8Array %j', { a: new Uint8Array([1, 2, 3]) })
- expect(spy).toHaveBeenCalledWith(3, 3, 'base', 'test {"a":"010203"}', [])
- expect(spy).toHaveBeenCalledWith(3, 3, 'base', 'test Uint8Array {"a":"010203"}', [])
- })
+ expect(spy).toHaveBeenCalledWith(3, 3, 'base', 'test {"a":"010203"}', [])
+ expect(spy).toHaveBeenCalledWith(3, 3, 'base', 'test Uint8Array {"a":"010203"}', [])
+ })
+ }
it('should trim long buffers', () => {
const [mgr, spy] = createManager()
diff --git a/packages/crypto-node/tests/node-native-crypto.test.ts b/packages/crypto-node/tests/node-native-crypto.test.ts
index 336534f5..435a03bb 100644
--- a/packages/crypto-node/tests/node-native-crypto.test.ts
+++ b/packages/crypto-node/tests/node-native-crypto.test.ts
@@ -2,9 +2,12 @@ import { describe } from 'vitest'
import { testCryptoProvider } from '@mtcute/test'
-import { NodeNativeCryptoProvider } from '../src/index.js'
+if (import.meta.env.TEST_ENV === 'node') {
+ describe('NodeNativeCryptoProvider', async () => {
+ const { NodeNativeCryptoProvider } = await import('../src/index.js')
-describe('NodeNativeCryptoProvider', () => {
- // eslint-disable-next-line
- testCryptoProvider(new NodeNativeCryptoProvider())
-})
+ testCryptoProvider(new NodeNativeCryptoProvider())
+ })
+} else {
+ describe.skip('NodeNativeCryptoProvider', () => {})
+}
diff --git a/packages/dispatcher/src/context/index.ts b/packages/dispatcher/src/context/index.ts
index 27c36013..aeafdf77 100644
--- a/packages/dispatcher/src/context/index.ts
+++ b/packages/dispatcher/src/context/index.ts
@@ -4,5 +4,5 @@ export * from './chat-join-request.js'
export * from './chosen-inline-result.js'
export * from './inline-query.js'
export * from './message.js'
-export { UpdateContextType } from './parse.js'
+export type { UpdateContextType } from './parse.js'
export * from './pre-checkout-query.js'
diff --git a/packages/dispatcher/src/filters/index.ts b/packages/dispatcher/src/filters/index.ts
index 73c8a129..3cb8bb92 100644
--- a/packages/dispatcher/src/filters/index.ts
+++ b/packages/dispatcher/src/filters/index.ts
@@ -1,3 +1,4 @@
import * as filters from './bundle.js'
import UpdateFilter = filters.UpdateFilter
-export { filters, UpdateFilter }
+export { filters }
+export type { UpdateFilter }
diff --git a/packages/sqlite/test/sqlite.test.ts b/packages/sqlite/test/sqlite.test.ts
index 5c79ea8a..6dedb356 100644
--- a/packages/sqlite/test/sqlite.test.ts
+++ b/packages/sqlite/test/sqlite.test.ts
@@ -4,47 +4,51 @@ import { stubPeerUser, testStateStorage, testStorage } from '@mtcute/test'
import { SqliteStorage } from '../src/index.js'
-describe('SqliteStorage', () => {
- testStorage(new SqliteStorage(), {
- // sqlite implements "unimportant" updates, which are batched once every 30sec (tested below)
- skipEntityOverwrite: true,
- customTests: (s) => {
- describe('batching', () => {
- beforeAll(() => void vi.useFakeTimers())
- afterAll(() => void vi.useRealTimers())
+if (import.meta.env.TEST_ENV === 'node') {
+ describe('SqliteStorage', () => {
+ testStorage(new SqliteStorage(), {
+ // sqlite implements "unimportant" updates, which are batched once every 30sec (tested below)
+ skipEntityOverwrite: true,
+ customTests: (s) => {
+ describe('batching', () => {
+ beforeAll(() => void vi.useFakeTimers())
+ afterAll(() => void vi.useRealTimers())
- it('should batch entity writes', async () => {
- s.updatePeers([stubPeerUser])
- s.updatePeers([{ ...stubPeerUser, username: 'test123' }])
- s.save()
+ it('should batch entity writes', async () => {
+ s.updatePeers([stubPeerUser])
+ s.updatePeers([{ ...stubPeerUser, username: 'test123' }])
+ s.save()
- // eslint-disable-next-line
- expect(Object.keys(s['_pendingUnimportant'])).toEqual([String(stubPeerUser.id)])
- // not yet updated
- expect(s.getPeerByUsername(stubPeerUser.username!)).not.toBeNull()
- expect(s.getPeerByUsername('test123')).toBeNull()
+ // eslint-disable-next-line
+ expect(Object.keys(s['_pendingUnimportant'])).toEqual([String(stubPeerUser.id)])
+ // not yet updated
+ expect(s.getPeerByUsername(stubPeerUser.username!)).not.toBeNull()
+ expect(s.getPeerByUsername('test123')).toBeNull()
- await vi.advanceTimersByTimeAsync(30001)
+ await vi.advanceTimersByTimeAsync(30001)
- expect(s.getPeerByUsername(stubPeerUser.username!)).toBeNull()
- expect(s.getPeerByUsername('test123')).not.toBeNull()
+ expect(s.getPeerByUsername(stubPeerUser.username!)).toBeNull()
+ expect(s.getPeerByUsername('test123')).not.toBeNull()
+ })
+
+ it('should batch update state writes', () => {
+ s.setUpdatesPts(123)
+ s.setUpdatesQts(456)
+ s.setUpdatesDate(789)
+ s.setUpdatesSeq(999)
+
+ // not yet updated
+ expect(s.getUpdatesState()).toBeNull()
+
+ s.save()
+
+ expect(s.getUpdatesState()).toEqual([123, 456, 789, 999])
+ })
})
-
- it('should batch update state writes', () => {
- s.setUpdatesPts(123)
- s.setUpdatesQts(456)
- s.setUpdatesDate(789)
- s.setUpdatesSeq(999)
-
- // not yet updated
- expect(s.getUpdatesState()).toBeNull()
-
- s.save()
-
- expect(s.getUpdatesState()).toEqual([123, 456, 789, 999])
- })
- })
- },
+ },
+ })
+ testStateStorage(new SqliteStorage())
})
- testStateStorage(new SqliteStorage())
-})
+} else {
+ describe.skip('SqliteStorage', () => {})
+}
diff --git a/packages/test/src/client.test.ts b/packages/test/src/client.test.ts
index aa5ca6ce..3fab4667 100644
--- a/packages/test/src/client.test.ts
+++ b/packages/test/src/client.test.ts
@@ -1,6 +1,7 @@
-/* eslint-disable no-restricted-globals */
import { describe, expect, it } from 'vitest'
+import { hexEncode } from '@mtcute/core/utils.js'
+
import { StubTelegramClient } from './client.js'
import { createStub } from './stub.js'
@@ -23,7 +24,7 @@ describe('client stub', () => {
const client = new StubTelegramClient()
client.onRawMessage((msg) => {
- log.push(`message ctor=${Buffer.from(msg.slice(0, 4)).toString('hex')}`)
+ log.push(`message ctor=${hexEncode(msg.subarray(0, 4))}`)
client.close().catch(() => {})
})
diff --git a/packages/test/src/crypto.ts b/packages/test/src/crypto.ts
index 104d7efe..cd68b8b0 100644
--- a/packages/test/src/crypto.ts
+++ b/packages/test/src/crypto.ts
@@ -1,4 +1,3 @@
-/* eslint-disable no-restricted-globals */
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
import { gzipSync, inflateSync } from 'zlib'
@@ -76,6 +75,28 @@ export async function defaultTestCryptoProvider(source = DEFAULT_ENTROPY): Promi
export function testCryptoProvider(c: ICryptoProvider): void {
beforeAll(() => c.initialize?.())
+ function gzipSyncWrap(data: Uint8Array) {
+ if (import.meta.env.TEST_ENV === 'browser') {
+ // @ts-expect-error fucking crutch because @jspm/core uses Buffer.isBuffer for some reason
+ data._isBuffer = true
+
+ return new Uint8Array(gzipSync(data))
+ }
+
+ return gzipSync(data)
+ }
+
+ function inflateSyncWrap(data: Uint8Array) {
+ if (import.meta.env.TEST_ENV === 'browser') {
+ // @ts-expect-error fucking crutch because @jspm/core uses Buffer.isBuffer for some reason
+ data._isBuffer = true
+
+ return new Uint8Array(inflateSync(data))
+ }
+
+ return inflateSync(data)
+ }
+
it('should calculate sha1', () => {
expect(hexEncode(c.sha1(utf8EncodeToBuffer('')))).to.eq('da39a3ee5e6b4b0d3255bfef95601890afd80709')
expect(hexEncode(c.sha1(utf8EncodeToBuffer('hello')))).to.eq('aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d')
@@ -188,21 +209,19 @@ export function testCryptoProvider(c: ICryptoProvider): void {
expect(compressed).not.toBeNull()
- const decompressed = inflateSync(compressed!)
+ const decompressed = inflateSyncWrap(compressed!)
expect(compressed!.length).toBeLessThan(data.length)
- // eslint-disable-next-line no-restricted-globals
- expect(decompressed).toEqual(Buffer.from(data))
+ expect(hexEncode(decompressed)).toEqual(hexEncode(data))
})
it('should correctly gunzip', () => {
const data = new Uint8Array(1000).fill(0x42)
- const compressed = gzipSync(data)
+ const compressed = gzipSyncWrap(data)
const decompressed = c.gunzip(compressed)
- // eslint-disable-next-line no-restricted-globals
- expect(Buffer.from(decompressed)).toEqual(Buffer.from(data))
+ expect(hexEncode(decompressed)).toEqual(hexEncode(data))
})
describe('randomBytes', () => {
@@ -229,7 +248,8 @@ export function testCryptoProvider(c: ICryptoProvider): void {
export function u8HexDecode(hex: string) {
const buf = hexDecodeToBuffer(hex)
- if (Buffer.isBuffer(buf)) {
+ // eslint-disable-next-line no-restricted-globals
+ if (import.meta.env.TEST_ENV === 'node' && Buffer.isBuffer(buf)) {
return new Uint8Array(buf)
}
diff --git a/packages/test/src/schema.ts b/packages/test/src/schema.ts
index 3889f5c9..61f17567 100644
--- a/packages/test/src/schema.ts
+++ b/packages/test/src/schema.ts
@@ -1,4 +1,6 @@
-import { createRequire } from 'module'
+import * as schema_ from '@mtcute/tl/api-schema.json' assert { type: 'json' }
+
+const schema = ('default' in schema_ ? schema_.default : schema_) as { e: TlEntry[] }
import type { TlEntry } from '@mtcute/tl-utils'
@@ -14,10 +16,6 @@ export function getEntriesMap() {
}
}
- const schema = createRequire(import.meta.url)('@mtcute/tl/api-schema.json') as {
- e: TlEntry[]
- }
-
_cachedEntriesMap = new Map()
_cachedUnionsMap = new Map()
diff --git a/packages/tl-runtime/package.json b/packages/tl-runtime/package.json
index 3a5d6a72..9144dbcf 100644
--- a/packages/tl-runtime/package.json
+++ b/packages/tl-runtime/package.json
@@ -11,12 +11,9 @@
"build": "pnpm run -w build-package tl-runtime"
},
"browser": {
- "./cjs/encodings/base64.js": "./cjs/encodings/base64.web.js",
- "./esm/encodings/base64.js": "./esm/encodings/base64.web.js",
- "./cjs/encodings/hex.js": "./cjs/encodings/hex.web.js",
- "./esm/encodings/hex.js": "./esm/encodings/hex.web.js",
- "./cjs/encodings/utf8.js": "./cjs/encodings/utf8.web.js",
- "./esm/encodings/utf8.js": "./esm/encodings/utf8.web.js"
+ "./src/encodings/hex.js": "./src/encodings/hex.web.js",
+ "./src/encodings/utf8.js": "./src/encodings/utf8.web.js",
+ "./src/encodings/base64.js": "./src/encodings/base64.web.js"
},
"distOnlyFields": {
"exports": {
diff --git a/packages/tl-runtime/src/encodings/base64.test.ts b/packages/tl-runtime/src/encodings/base64.test.ts
index 83333ea4..1441e5c7 100644
--- a/packages/tl-runtime/src/encodings/base64.test.ts
+++ b/packages/tl-runtime/src/encodings/base64.test.ts
@@ -1,7 +1,8 @@
import { describe, expect, it } from 'vitest'
-import { base64Decode, base64DecodeToBuffer, base64Encode } from './base64.js'
-import { base64Decode as base64DecodeWeb, base64Encode as base64EncodeWeb } from './base64.web.js'
+// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+const _imported = await import(import.meta.env.TEST_ENV === 'node' ? './base64.js' : './base64.web.js')
+const { base64Decode, base64DecodeToBuffer, base64Encode } = _imported as typeof import('./base64.js')
describe('base64', () => {
it('should decode base64 string to existing buffer', () => {
@@ -36,37 +37,3 @@ describe('base64', () => {
expect(base64Encode(buf, true)).toEqual('AQIDBA')
})
})
-
-describe('base64.web', () => {
- it('should decode base64 string to existing buffer', () => {
- const buf = new Uint8Array(4)
- base64DecodeWeb(buf, 'AQIDBA==')
- expect(buf).toEqual(new Uint8Array([1, 2, 3, 4]))
- })
-
- it('should decode base64 string to new buffer', () => {
- const buf = base64DecodeToBuffer('AQIDBA==')
- expect(new Uint8Array(buf)).toEqual(new Uint8Array([1, 2, 3, 4]))
- })
-
- it('should encode buffer to base64 string', () => {
- const buf = new Uint8Array([1, 2, 3, 4])
- expect(base64EncodeWeb(buf)).toEqual('AQIDBA==')
- })
-
- it('should decode url-safe base64 string to existing buffer', () => {
- const buf = new Uint8Array(4)
- base64DecodeWeb(buf, 'AQIDBA', true)
- expect(buf).toEqual(new Uint8Array([1, 2, 3, 4]))
- })
-
- it('should decode url-safe base64 string to new buffer', () => {
- const buf = base64DecodeToBuffer('AQIDBA', true)
- expect(new Uint8Array(buf)).toEqual(new Uint8Array([1, 2, 3, 4]))
- })
-
- it('should encode buffer to url-safe base64 string', () => {
- const buf = new Uint8Array([1, 2, 3, 4])
- expect(base64EncodeWeb(buf, true)).toEqual('AQIDBA')
- })
-})
diff --git a/packages/tl-runtime/src/encodings/hex.test.ts b/packages/tl-runtime/src/encodings/hex.test.ts
index 7e106c8a..3eb8185a 100644
--- a/packages/tl-runtime/src/encodings/hex.test.ts
+++ b/packages/tl-runtime/src/encodings/hex.test.ts
@@ -1,11 +1,8 @@
import { describe, expect, it } from 'vitest'
-import { hexDecode, hexDecodeToBuffer, hexEncode } from './hex.js'
-import {
- hexDecode as hexDecodeWeb,
- hexDecodeToBuffer as hexDecodeToBufferWeb,
- hexEncode as hexEncodeWeb,
-} from './hex.web.js'
+// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+const _imported = await import(import.meta.env.TEST_ENV === 'node' ? './hex.js' : './hex.web.js')
+const { hexDecode, hexDecodeToBuffer, hexEncode } = _imported as typeof import('./hex.js')
describe('hex', () => {
it('should decode hex string to existing buffer', () => {
@@ -24,21 +21,3 @@ describe('hex', () => {
expect(hexEncode(buf)).toEqual('01020304')
})
})
-
-describe('hex.web', () => {
- it('should decode hex string to existing buffer', () => {
- const buf = new Uint8Array(4)
- hexDecodeWeb(buf, '01020304')
- expect(buf).toEqual(new Uint8Array([1, 2, 3, 4]))
- })
-
- it('should decode hex string to new buffer', () => {
- const buf = hexDecodeToBufferWeb('01020304')
- expect(buf).toEqual(new Uint8Array([1, 2, 3, 4]))
- })
-
- it('should encode buffer to hex string', () => {
- const buf = new Uint8Array([1, 2, 3, 4])
- expect(hexEncodeWeb(buf)).toEqual('01020304')
- })
-})
diff --git a/packages/tl-runtime/src/encodings/utf8.test.ts b/packages/tl-runtime/src/encodings/utf8.test.ts
index 6d9c4526..fcc9e0c0 100644
--- a/packages/tl-runtime/src/encodings/utf8.test.ts
+++ b/packages/tl-runtime/src/encodings/utf8.test.ts
@@ -1,15 +1,8 @@
import { describe, expect, it } from 'vitest'
-import { byteLengthUtf8, utf8Decode, utf8Encode, utf8EncodeToBuffer } from './utf8.js'
-import {
- byteLengthUtf8 as byteLengthUtf8Web,
- utf8Decode as utf8DecodeWeb,
- utf8Encode as utf8EncodeWeb,
- utf8EncodeToBuffer as utf8EncodeToBufferWeb,
-} from './utf8.web.js'
-
-// since we use TextEncoder or native Buffer, we can skip testing the utf8 encoding itself
-// we only need to test that the functions work as expected with offsets and lengths
+// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+const _imported = await import(import.meta.env.TEST_ENV === 'node' ? './utf8.js' : './utf8.web.js')
+const { byteLengthUtf8, utf8Decode, utf8Encode, utf8EncodeToBuffer } = _imported as typeof import('./utf8.js')
describe('utf8', () => {
it('should encode utf8 string into existing buffer', () => {
@@ -29,24 +22,6 @@ describe('utf8', () => {
})
})
-describe('utf8.web', () => {
- it('should encode utf8 string into existing buffer', () => {
- const buf = new Uint8Array(4)
- utf8EncodeWeb(buf, 'abcd')
- expect(buf).toEqual(new Uint8Array([97, 98, 99, 100]))
- })
-
- it('should encode utf8 string into new buffer', () => {
- const buf = utf8EncodeToBufferWeb('abcd')
- expect(buf).toEqual(new Uint8Array([97, 98, 99, 100]))
- })
-
- it('should decode utf8 string from existing buffer', () => {
- const buf = new Uint8Array([97, 98, 99, 100])
- expect(utf8DecodeWeb(buf)).toEqual('abcd')
- })
-})
-
describe('byteLengthUtf8', () => {
it('should return byte length of utf8 string', () => {
expect(byteLengthUtf8('abcd')).toEqual(4)
@@ -56,10 +31,4 @@ describe('byteLengthUtf8', () => {
expect(byteLengthUtf8('абвг')).toEqual(8)
expect(byteLengthUtf8('🌸')).toEqual(4)
})
-
- it('should work in web', () => {
- expect(byteLengthUtf8Web('abcd')).toEqual(4)
- expect(byteLengthUtf8Web('абвг')).toEqual(8)
- expect(byteLengthUtf8Web('🌸')).toEqual(4)
- })
})
diff --git a/packages/tl-runtime/src/reader.test.ts b/packages/tl-runtime/src/reader.test.ts
index f919f78b..becbaca0 100644
--- a/packages/tl-runtime/src/reader.test.ts
+++ b/packages/tl-runtime/src/reader.test.ts
@@ -1,13 +1,26 @@
// eslint-disable-next-line max-len
/* eslint-disable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-argument */
-import { randomBytes } from 'crypto'
+// import { randomBytes } from 'crypto'
import Long from 'long'
import { describe, expect, it } from 'vitest'
import { hexDecodeToBuffer, hexEncode } from './encodings/hex.js'
import { TlBinaryReader, TlReaderMap } from './reader.js'
+let randomBytes: (n: number) => Uint8Array
+
+if (import.meta.env.TEST_ENV === 'node') {
+ randomBytes = await import('crypto').then((m) => m.randomBytes)
+} else {
+ randomBytes = (n: number) => {
+ const buf = new Uint8Array(n)
+ crypto.getRandomValues(buf)
+
+ return buf
+ }
+}
+
describe('TlBinaryReader', () => {
it('should read int32', () => {
expect(TlBinaryReader.manual(new Uint8Array([0, 0, 0, 0])).int()).toEqual(0)
@@ -111,10 +124,9 @@ describe('TlBinaryReader', () => {
expect(reader.pos).toEqual(252)
const random1000bytes = randomBytes(1000)
- // eslint-disable-next-line no-restricted-globals
- const buffer = Buffer.alloc(1010)
+ const buffer = new Uint8Array(1010)
buffer[0] = 254
- buffer.writeIntLE(1000, 1, 3)
+ new DataView(buffer.buffer).setUint32(1, 1000, true)
buffer.set(random1000bytes, 4)
reader = TlBinaryReader.manual(buffer)
expect([...reader.bytes()]).toEqual([...random1000bytes])
diff --git a/packages/tl-runtime/src/writer.test.ts b/packages/tl-runtime/src/writer.test.ts
index 9dac7788..ee7a78e8 100644
--- a/packages/tl-runtime/src/writer.test.ts
+++ b/packages/tl-runtime/src/writer.test.ts
@@ -1,11 +1,23 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
-import { randomBytes } from 'crypto'
import Long from 'long'
import { describe, expect, it } from 'vitest'
import { hexDecodeToBuffer, hexEncode } from '../src/encodings/hex.js'
import { TlBinaryWriter, TlSerializationCounter, TlWriterMap } from './writer.js'
+let randomBytes: (n: number) => Uint8Array
+
+if (import.meta.env.TEST_ENV === 'node') {
+ randomBytes = await import('crypto').then((m) => m.randomBytes)
+} else {
+ randomBytes = (n: number) => {
+ const buf = new Uint8Array(n)
+ crypto.getRandomValues(buf)
+
+ return buf
+ }
+}
+
describe('TlBinaryWriter', () => {
const testSingleMethod = (size: number, fn: (w: TlBinaryWriter) => void, map?: TlWriterMap): string => {
const w = TlBinaryWriter.alloc(map, size)
@@ -69,17 +81,14 @@ describe('TlBinaryWriter', () => {
expect(testSingleMethod(8, (w) => w.bytes(new Uint8Array([1, 2, 3, 4])))).toEqual('0401020304000000')
const random250bytes = randomBytes(250)
- expect(testSingleMethod(252, (w) => w.bytes(random250bytes))).toEqual(
- 'fa' + random250bytes.toString('hex') + '00',
- )
+ expect(testSingleMethod(252, (w) => w.bytes(random250bytes))).toEqual(`fa${hexEncode(random250bytes)}00`)
const random1000bytes = randomBytes(1000)
- // eslint-disable-next-line no-restricted-globals
- const buffer = Buffer.alloc(1004)
+ const buffer = new Uint8Array(1004)
buffer[0] = 254
- buffer.writeIntLE(1000, 1, 3)
+ new DataView(buffer.buffer).setUint32(1, 1000, true)
buffer.set(random1000bytes, 4)
- expect(testSingleMethod(1004, (w) => w.bytes(random1000bytes))).toEqual(buffer.toString('hex'))
+ expect(testSingleMethod(1004, (w) => w.bytes(random1000bytes))).toEqual(hexEncode(buffer))
})
const stubObjectsMap: TlWriterMap = {
diff --git a/packages/wasm/build.config.cjs b/packages/wasm/build.config.cjs
index a8c383ce..163724d9 100644
--- a/packages/wasm/build.config.cjs
+++ b/packages/wasm/build.config.cjs
@@ -13,7 +13,9 @@ module.exports = ({ path: { join }, fs, outDir, packageDir, transformFile }) =>
}
fixWasmPath('cjs/init.js')
+ fixWasmPath('cjs/init.web.js')
fixWasmPath('esm/init.js')
+ fixWasmPath('esm/init.web.js')
fs.cpSync(join(packageDir, 'lib/mtcute.wasm'), join(outDir, 'mtcute.wasm'))
},
diff --git a/packages/wasm/package.json b/packages/wasm/package.json
index a19ee81a..16b171d7 100644
--- a/packages/wasm/package.json
+++ b/packages/wasm/package.json
@@ -13,8 +13,7 @@
"build:wasm": "docker build --output=lib --target=binaries lib"
},
"browser": {
- "./cjs/init.js": "./cjs/init.web.js",
- "./esm/init.js": "./esm/init.web.js"
+ "./src/init.js": "./src/init.web.js"
},
"distOnlyFields": {
"exports": {
@@ -24,5 +23,8 @@
},
"./mtcute.wasm": "./mtcute.wasm"
}
+ },
+ "devDependencies": {
+ "@mtcute/tl-runtime": "workspace:^"
}
}
diff --git a/packages/wasm/src/init.web.ts b/packages/wasm/src/init.web.ts
index 51f09013..6e0cc1e1 100644
--- a/packages/wasm/src/init.web.ts
+++ b/packages/wasm/src/init.web.ts
@@ -2,7 +2,7 @@ import { InitInput } from './types.js'
export async function loadWasmBinary(input?: InitInput): Promise {
if (typeof input === 'undefined') {
- input = new URL('../mtcute.wasm', import.meta.url)
+ input = new URL('../lib/mtcute.wasm', import.meta.url)
}
if (
diff --git a/packages/wasm/tests/ctr.test.ts b/packages/wasm/tests/ctr.test.ts
index c302617c..ebe38127 100644
--- a/packages/wasm/tests/ctr.test.ts
+++ b/packages/wasm/tests/ctr.test.ts
@@ -1,6 +1,7 @@
-/* eslint-disable no-restricted-globals */
import { beforeAll, describe, expect, it } from 'vitest'
+import { hexDecodeToBuffer, hexEncode } from '@mtcute/tl-runtime'
+
import { __getWasm, createCtr256, ctr256, freeCtr256, initAsync } from '../src/index.js'
beforeAll(async () => {
@@ -8,24 +9,22 @@ beforeAll(async () => {
})
describe('aes-ctr', () => {
- const key = Buffer.from('603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4', 'hex')
- const iv = Buffer.from('F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF', 'hex')
+ const key = hexDecodeToBuffer('603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4')
+ const iv = hexDecodeToBuffer('F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF')
describe('NIST', () => {
// https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CTR.pdf
- const data = Buffer.from(
+ const data = hexDecodeToBuffer(
`6BC1BEE2 2E409F96 E93D7E11 7393172A
AE2D8A57 1E03AC9C 9EB76FAC 45AF8E51
30C81C46 A35CE411 E5FBC119 1A0A52EF
F69F2445 DF4F9B17 AD2B417B E66C3710`.replace(/\s/g, ''),
- 'hex',
)
- const dataEnc = Buffer.from(
+ const dataEnc = hexDecodeToBuffer(
`601EC313 775789A5 B7A7F504 BBF3D228
F443E3CA 4D62B59A CA84E990 CACAF5C5
2B0930DA A23DE94C E87017BA 2D84988D
DFC9C58D B67AADA6 13C2DD08 457941A6`.replace(/\s/g, ''),
- 'hex',
)
it('should correctly encrypt', () => {
@@ -33,7 +32,7 @@ describe('aes-ctr', () => {
const res = ctr256(ctr, data)
freeCtr256(ctr)
- expect(Buffer.from(res).toString('hex')).toEqual(dataEnc.toString('hex'))
+ expect(hexEncode(res)).toEqual(hexEncode(dataEnc))
})
it('should correctly decrypt', () => {
@@ -41,15 +40,15 @@ describe('aes-ctr', () => {
const res = ctr256(ctr, dataEnc)
freeCtr256(ctr)
- expect(Buffer.from(res).toString('hex')).toEqual(data.toString('hex'))
+ expect(hexEncode(res)).toEqual(hexEncode(data))
})
})
describe('stream', () => {
- const data = Buffer.from('6BC1BEE22E409F96E93D7E117393172A', 'hex')
- const dataEnc1 = Buffer.from('601ec313775789a5b7a7f504bbf3d228', 'hex')
- const dataEnc2 = Buffer.from('31afd77f7d218690bd0ef82dfcf66cbe', 'hex')
- const dataEnc3 = Buffer.from('7000927e2f2192cbe4b6a8b2441ddd48', 'hex')
+ const data = hexDecodeToBuffer('6BC1BEE22E409F96E93D7E117393172A')
+ const dataEnc1 = hexDecodeToBuffer('601ec313775789a5b7a7f504bbf3d228')
+ const dataEnc2 = hexDecodeToBuffer('31afd77f7d218690bd0ef82dfcf66cbe')
+ const dataEnc3 = hexDecodeToBuffer('7000927e2f2192cbe4b6a8b2441ddd48')
it('should correctly encrypt', () => {
const ctr = createCtr256(key, iv)
@@ -59,9 +58,9 @@ describe('aes-ctr', () => {
freeCtr256(ctr)
- expect(Buffer.from(res1).toString('hex')).toEqual(dataEnc1.toString('hex'))
- expect(Buffer.from(res2).toString('hex')).toEqual(dataEnc2.toString('hex'))
- expect(Buffer.from(res3).toString('hex')).toEqual(dataEnc3.toString('hex'))
+ expect(hexEncode(res1)).toEqual(hexEncode(dataEnc1))
+ expect(hexEncode(res2)).toEqual(hexEncode(dataEnc2))
+ expect(hexEncode(res3)).toEqual(hexEncode(dataEnc3))
})
it('should correctly decrypt', () => {
@@ -72,20 +71,20 @@ describe('aes-ctr', () => {
freeCtr256(ctr)
- expect(Buffer.from(res1).toString('hex')).toEqual(data.toString('hex'))
- expect(Buffer.from(res2).toString('hex')).toEqual(data.toString('hex'))
- expect(Buffer.from(res3).toString('hex')).toEqual(data.toString('hex'))
+ expect(hexEncode(res1)).toEqual(hexEncode(data))
+ expect(hexEncode(res2)).toEqual(hexEncode(data))
+ expect(hexEncode(res3)).toEqual(hexEncode(data))
})
})
describe('stream (unaligned)', () => {
- const data = Buffer.from('6BC1BEE22E40', 'hex')
- const dataEnc1 = Buffer.from('601ec3137757', 'hex')
- const dataEnc2 = Buffer.from('7df2e078a555', 'hex')
- const dataEnc3 = Buffer.from('a3a17be0742e', 'hex')
- const dataEnc4 = Buffer.from('025ced833746', 'hex')
- const dataEnc5 = Buffer.from('3ff238dea125', 'hex')
- const dataEnc6 = Buffer.from('1055a52302dc', 'hex')
+ const data = hexDecodeToBuffer('6BC1BEE22E40')
+ const dataEnc1 = hexDecodeToBuffer('601ec3137757')
+ const dataEnc2 = hexDecodeToBuffer('7df2e078a555')
+ const dataEnc3 = hexDecodeToBuffer('a3a17be0742e')
+ const dataEnc4 = hexDecodeToBuffer('025ced833746')
+ const dataEnc5 = hexDecodeToBuffer('3ff238dea125')
+ const dataEnc6 = hexDecodeToBuffer('1055a52302dc')
it('should correctly encrypt', () => {
const ctr = createCtr256(key, iv)
@@ -98,12 +97,12 @@ describe('aes-ctr', () => {
freeCtr256(ctr)
- expect(Buffer.from(res1).toString('hex')).toEqual(dataEnc1.toString('hex'))
- expect(Buffer.from(res2).toString('hex')).toEqual(dataEnc2.toString('hex'))
- expect(Buffer.from(res3).toString('hex')).toEqual(dataEnc3.toString('hex'))
- expect(Buffer.from(res4).toString('hex')).toEqual(dataEnc4.toString('hex'))
- expect(Buffer.from(res5).toString('hex')).toEqual(dataEnc5.toString('hex'))
- expect(Buffer.from(res6).toString('hex')).toEqual(dataEnc6.toString('hex'))
+ expect(hexEncode(res1)).toEqual(hexEncode(dataEnc1))
+ expect(hexEncode(res2)).toEqual(hexEncode(dataEnc2))
+ expect(hexEncode(res3)).toEqual(hexEncode(dataEnc3))
+ expect(hexEncode(res4)).toEqual(hexEncode(dataEnc4))
+ expect(hexEncode(res5)).toEqual(hexEncode(dataEnc5))
+ expect(hexEncode(res6)).toEqual(hexEncode(dataEnc6))
})
it('should correctly decrypt', () => {
@@ -117,17 +116,17 @@ describe('aes-ctr', () => {
freeCtr256(ctr)
- expect(Buffer.from(res1).toString('hex')).toEqual(data.toString('hex'))
- expect(Buffer.from(res2).toString('hex')).toEqual(data.toString('hex'))
- expect(Buffer.from(res3).toString('hex')).toEqual(data.toString('hex'))
- expect(Buffer.from(res4).toString('hex')).toEqual(data.toString('hex'))
- expect(Buffer.from(res5).toString('hex')).toEqual(data.toString('hex'))
- expect(Buffer.from(res6).toString('hex')).toEqual(data.toString('hex'))
+ expect(hexEncode(res1)).toEqual(hexEncode(data))
+ expect(hexEncode(res2)).toEqual(hexEncode(data))
+ expect(hexEncode(res3)).toEqual(hexEncode(data))
+ expect(hexEncode(res4)).toEqual(hexEncode(data))
+ expect(hexEncode(res5)).toEqual(hexEncode(data))
+ expect(hexEncode(res6)).toEqual(hexEncode(data))
})
})
it('should not leak memory', () => {
- const data = Buffer.from('6BC1BEE22E409F96E93D7E117393172A', 'hex')
+ const data = hexDecodeToBuffer('6BC1BEE22E409F96E93D7E117393172A')
const mem = __getWasm().memory.buffer
const memSize = mem.byteLength
diff --git a/packages/wasm/tests/gunzip.test.ts b/packages/wasm/tests/gunzip.test.ts
index ee3d3c0d..9a004a6c 100644
--- a/packages/wasm/tests/gunzip.test.ts
+++ b/packages/wasm/tests/gunzip.test.ts
@@ -1,17 +1,29 @@
-/* eslint-disable no-restricted-globals */
import { beforeAll, describe, expect, it } from 'vitest'
import { gzipSync } from 'zlib'
+import { utf8Decode, utf8EncodeToBuffer } from '@mtcute/tl-runtime'
+
import { __getWasm, gunzip, initAsync } from '../src/index.js'
beforeAll(async () => {
await initAsync()
})
+function gzipSyncWrap(data: Uint8Array) {
+ if (import.meta.env.TEST_ENV === 'browser') {
+ // @ts-expect-error fucking crutch because @jspm/core uses Buffer.isBuffer for some reason
+ data._isBuffer = true
+
+ return new Uint8Array(gzipSync(data))
+ }
+
+ return gzipSync(data)
+}
+
describe('gunzip', () => {
it('should correctly read zlib headers', () => {
const wasm = __getWasm()
- const data = gzipSync(Buffer.from('hello world'))
+ const data = gzipSyncWrap(utf8EncodeToBuffer('hello world'))
const inputPtr = wasm.__malloc(data.length)
new Uint8Array(wasm.memory.buffer).set(data, inputPtr)
@@ -21,11 +33,11 @@ describe('gunzip', () => {
it('should correctly inflate', () => {
const data = Array.from({ length: 1000 }, () => 'a').join('')
- const res = gzipSync(Buffer.from(data))
+ const res = gzipSyncWrap(utf8EncodeToBuffer(data))
expect(res).not.toBeNull()
expect(res.length).toBeLessThan(100)
- expect(gunzip(res)).toEqual(new Uint8Array(Buffer.from(data)))
+ expect(gunzip(res)).toEqual(new Uint8Array(utf8EncodeToBuffer(data)))
})
it('should not leak memory', () => {
@@ -33,11 +45,11 @@ describe('gunzip', () => {
for (let i = 0; i < 100; i++) {
const data = Array.from({ length: 1000 }, () => 'a').join('')
- const deflated = gzipSync(Buffer.from(data))
+ const deflated = gzipSyncWrap(utf8EncodeToBuffer(data))
const res = gunzip(deflated)
- expect(Buffer.from(res).toString()).toEqual(data)
+ expect(utf8Decode(res)).toEqual(data)
}
expect(__getWasm().memory.buffer.byteLength).toEqual(memSize)
diff --git a/packages/wasm/tests/hash.test.ts b/packages/wasm/tests/hash.test.ts
index bb6d6779..2f85f1bb 100644
--- a/packages/wasm/tests/hash.test.ts
+++ b/packages/wasm/tests/hash.test.ts
@@ -1,6 +1,7 @@
-/* eslint-disable no-restricted-globals */
import { beforeAll, describe, expect, it } from 'vitest'
+import { hexEncode, utf8EncodeToBuffer } from '@mtcute/tl-runtime'
+
import { __getWasm, initAsync, sha1, sha256 } from '../src/index.js'
beforeAll(async () => {
@@ -9,11 +10,9 @@ beforeAll(async () => {
describe('sha256', () => {
it('should correctly calculate sha-256 hash', () => {
- const hash = sha256(Buffer.from('abc'))
+ const hash = sha256(utf8EncodeToBuffer('abc'))
- expect(Buffer.from(hash).toString('hex')).toEqual(
- 'ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad',
- )
+ expect(hexEncode(hash)).toEqual('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad')
})
it('should not leak memory', () => {
@@ -21,7 +20,7 @@ describe('sha256', () => {
const memSize = mem.byteLength
for (let i = 0; i < 100; i++) {
- sha256(Buffer.from('abc'))
+ sha256(utf8EncodeToBuffer('abc'))
}
expect(mem.byteLength).toEqual(memSize)
@@ -30,9 +29,9 @@ describe('sha256', () => {
describe('sha1', () => {
it('should correctly calculate sha-1 hash', () => {
- const hash = sha1(Buffer.from('abc'))
+ const hash = sha1(utf8EncodeToBuffer('abc'))
- expect(Buffer.from(hash).toString('hex')).toEqual('a9993e364706816aba3e25717850c26c9cd0d89d')
+ expect(hexEncode(hash)).toEqual('a9993e364706816aba3e25717850c26c9cd0d89d')
})
it('should not leak memory', () => {
@@ -40,7 +39,7 @@ describe('sha1', () => {
const memSize = mem.byteLength
for (let i = 0; i < 100; i++) {
- sha1(Buffer.from('abc'))
+ sha1(utf8EncodeToBuffer('abc'))
}
expect(mem.byteLength).toEqual(memSize)
diff --git a/packages/wasm/tests/ige.test.ts b/packages/wasm/tests/ige.test.ts
index 121020c0..1edca67e 100644
--- a/packages/wasm/tests/ige.test.ts
+++ b/packages/wasm/tests/ige.test.ts
@@ -1,6 +1,8 @@
/* eslint-disable no-restricted-globals */
import { beforeAll, describe, expect, it } from 'vitest'
+import { hexDecodeToBuffer, hexEncode } from '@mtcute/tl-runtime'
+
import { __getWasm, ige256Decrypt, ige256Encrypt, initAsync } from '../src/index.js'
beforeAll(async () => {
@@ -8,22 +10,22 @@ beforeAll(async () => {
})
describe('aes-ige', () => {
- const key = Buffer.from('5468697320697320616E20696D706C655468697320697320616E20696D706C65', 'hex')
- const iv = Buffer.from('6D656E746174696F6E206F6620494745206D6F646520666F72204F70656E5353', 'hex')
+ const key = hexDecodeToBuffer('5468697320697320616E20696D706C655468697320697320616E20696D706C65')
+ const iv = hexDecodeToBuffer('6D656E746174696F6E206F6620494745206D6F646520666F72204F70656E5353')
- const data = Buffer.from('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b', 'hex')
- const dataEnc = Buffer.from('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69', 'hex')
+ const data = hexDecodeToBuffer('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b')
+ const dataEnc = hexDecodeToBuffer('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69')
it('should correctly encrypt', () => {
const aes = ige256Encrypt(data, key, iv)
- expect(Buffer.from(aes).toString('hex')).toEqual(dataEnc.toString('hex'))
+ expect(hexEncode(aes)).toEqual(hexEncode(dataEnc))
})
it('should correctly decrypt', () => {
const aes = ige256Decrypt(dataEnc, key, iv)
- expect(Buffer.from(aes).toString('hex')).toEqual(data.toString('hex'))
+ expect(hexEncode(aes)).toEqual(hexEncode(data))
})
it('should not leak memory', () => {
diff --git a/packages/wasm/tests/zlib.test.ts b/packages/wasm/tests/zlib.test.ts
index 03488807..4f67a514 100644
--- a/packages/wasm/tests/zlib.test.ts
+++ b/packages/wasm/tests/zlib.test.ts
@@ -1,34 +1,46 @@
-/* eslint-disable no-restricted-globals */
import { beforeAll, describe, expect, it } from 'vitest'
import { inflateSync } from 'zlib'
+import { utf8Decode, utf8EncodeToBuffer } from '@mtcute/tl-runtime'
+
import { __getWasm, deflateMaxSize, initAsync } from '../src/index.js'
beforeAll(async () => {
await initAsync()
})
+function inflateSyncWrap(data: Uint8Array) {
+ if (import.meta.env.TEST_ENV === 'browser') {
+ // @ts-expect-error fucking crutch because @jspm/core uses Buffer.isBuffer for some reason
+ data._isBuffer = true
+
+ return new Uint8Array(inflateSync(data))
+ }
+
+ return inflateSync(data)
+}
+
describe('zlib deflate', () => {
it('should add zlib headers', () => {
- const res = deflateMaxSize(Buffer.from('hello world'), 100)
+ const res = deflateMaxSize(utf8EncodeToBuffer('hello world'), 100)
expect(res).not.toBeNull()
expect(res!.slice(0, 2)).toEqual(new Uint8Array([0x78, 0x9c]))
})
it('should return null if compressed data is larger than size', () => {
- const res = deflateMaxSize(Buffer.from('hello world'), 1)
+ const res = deflateMaxSize(utf8EncodeToBuffer('hello world'), 1)
expect(res).toBeNull()
})
it('should correctly deflate', () => {
const data = Array.from({ length: 1000 }, () => 'a').join('')
- const res = deflateMaxSize(Buffer.from(data), 100)
+ const res = deflateMaxSize(utf8EncodeToBuffer(data), 100)
expect(res).not.toBeNull()
expect(res!.length).toBeLessThan(100)
- expect(inflateSync(res!)).toEqual(Buffer.from(data))
+ expect(inflateSyncWrap(res!)).toEqual(utf8EncodeToBuffer(data))
})
it('should not leak memory', () => {
@@ -36,11 +48,11 @@ describe('zlib deflate', () => {
for (let i = 0; i < 100; i++) {
const data = Array.from({ length: 1000 }, () => 'a').join('')
- const deflated = deflateMaxSize(Buffer.from(data), 100)
+ const deflated = deflateMaxSize(utf8EncodeToBuffer(data), 100)
- const res = inflateSync(deflated!)
+ const res = inflateSyncWrap(deflated!)
- expect(Buffer.from(res).toString()).toEqual(data)
+ expect(utf8Decode(res)).toEqual(data)
}
expect(__getWasm().memory.buffer.byteLength).toEqual(memSize)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5e7b075d..28babacf 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -18,6 +18,9 @@ importers:
'@commitlint/config-conventional':
specifier: 17.6.5
version: 17.6.5
+ '@types/node':
+ specifier: 20.10.0
+ version: 20.10.0
'@types/node-forge':
specifier: 1.3.2
version: 1.3.2
@@ -30,18 +33,27 @@ importers:
'@typescript-eslint/parser':
specifier: 6.4.0
version: 6.4.0(eslint@8.47.0)(typescript@5.0.4)
+ '@vitest/browser':
+ specifier: 0.34.6
+ version: 0.34.6(esbuild@0.18.20)(vitest@0.34.6)
'@vitest/coverage-v8':
specifier: 0.34.6
version: 0.34.6(vitest@0.34.6)
'@vitest/ui':
specifier: 0.34.6
version: 0.34.6(vitest@0.34.6)
+ cjs-module-lexer:
+ specifier: 1.2.3
+ version: 1.2.3
dotenv-flow:
specifier: 3.2.0
version: 3.2.0
dpdm:
specifier: 3.14.0
version: 3.14.0
+ esbuild:
+ specifier: 0.18.20
+ version: 0.18.20
eslint:
specifier: 8.47.0
version: 8.47.0
@@ -72,6 +84,9 @@ importers:
node-forge:
specifier: 1.3.1
version: 1.3.1
+ playwright:
+ specifier: ^1.40.1
+ version: 1.40.1
prettier:
specifier: 3.0.3
version: 3.0.3
@@ -83,7 +98,7 @@ importers:
version: 7.5.1
ts-node:
specifier: 10.9.1
- version: 10.9.1(@types/node@18.16.0)(typescript@5.0.4)
+ version: 10.9.1(@types/node@20.10.0)(typescript@5.0.4)
tsconfig-paths:
specifier: 4.2.0
version: 4.2.0
@@ -94,11 +109,11 @@ importers:
specifier: 5.0.4
version: 5.0.4
vite:
- specifier: 4.5.0
- version: 4.5.0(@types/node@18.16.0)
+ specifier: 5.0.3
+ version: 5.0.3(@types/node@20.10.0)
vitest:
specifier: 0.34.6
- version: 0.34.6(@vitest/ui@0.34.6)
+ version: 0.34.6(@vitest/browser@0.34.6)(@vitest/ui@0.34.6)(playwright@1.40.1)
packages/client:
dependencies:
@@ -297,7 +312,7 @@ importers:
version: 5.2.3
vitest:
specifier: ^0.34.6
- version: 0.34.6(@vitest/ui@0.34.6)
+ version: 0.34.6(@vitest/browser@0.34.6)(@vitest/ui@0.34.6)(playwright@1.40.1)
devDependencies:
'@mtcute/tl-utils':
specifier: workspace:^
@@ -347,7 +362,11 @@ importers:
specifier: workspace:^
version: link:../tl-runtime
- packages/wasm: {}
+ packages/wasm:
+ devDependencies:
+ '@mtcute/tl-runtime':
+ specifier: workspace:^
+ version: link:../tl-runtime
packages:
@@ -475,15 +494,15 @@ packages:
'@commitlint/execute-rule': 17.4.0
'@commitlint/resolve-extends': 17.4.4
'@commitlint/types': 17.4.4
- '@types/node': 18.16.0
+ '@types/node': 20.10.0
chalk: 4.1.2
cosmiconfig: 8.1.3
- cosmiconfig-typescript-loader: 4.3.0(@types/node@18.16.0)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.0.4)
+ cosmiconfig-typescript-loader: 4.3.0(@types/node@20.10.0)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.0.4)
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
lodash.uniq: 4.5.0
resolve-from: 5.0.0
- ts-node: 10.9.1(@types/node@18.16.0)(typescript@5.0.4)
+ ts-node: 10.9.1(@types/node@20.10.0)(typescript@5.0.4)
typescript: 5.0.4
transitivePeerDependencies:
- '@swc/core'
@@ -572,6 +591,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/android-arm64@0.19.8:
+ resolution: {integrity: sha512-B8JbS61bEunhfx8kasogFENgQfr/dIp+ggYXwTqdbMAgGDhRa3AaPpQMuQU0rNxDLECj6FhDzk1cF9WHMVwrtA==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ optional: true
+
/@esbuild/android-arm@0.18.20:
resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
engines: {node: '>=12'}
@@ -580,6 +607,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/android-arm@0.19.8:
+ resolution: {integrity: sha512-31E2lxlGM1KEfivQl8Yf5aYU/mflz9g06H6S15ITUFQueMFtFjESRMoDSkvMo8thYvLBax+VKTPlpnx+sPicOA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ optional: true
+
/@esbuild/android-x64@0.18.20:
resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
engines: {node: '>=12'}
@@ -588,6 +623,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/android-x64@0.19.8:
+ resolution: {integrity: sha512-rdqqYfRIn4jWOp+lzQttYMa2Xar3OK9Yt2fhOhzFXqg0rVWEfSclJvZq5fZslnz6ypHvVf3CT7qyf0A5pM682A==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+ requiresBuild: true
+ optional: true
+
/@esbuild/darwin-arm64@0.18.20:
resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
engines: {node: '>=12'}
@@ -596,6 +639,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/darwin-arm64@0.19.8:
+ resolution: {integrity: sha512-RQw9DemMbIq35Bprbboyf8SmOr4UXsRVxJ97LgB55VKKeJOOdvsIPy0nFyF2l8U+h4PtBx/1kRf0BelOYCiQcw==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
/@esbuild/darwin-x64@0.18.20:
resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
engines: {node: '>=12'}
@@ -604,6 +655,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/darwin-x64@0.19.8:
+ resolution: {integrity: sha512-3sur80OT9YdeZwIVgERAysAbwncom7b4bCI2XKLjMfPymTud7e/oY4y+ci1XVp5TfQp/bppn7xLw1n/oSQY3/Q==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
/@esbuild/freebsd-arm64@0.18.20:
resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
engines: {node: '>=12'}
@@ -612,6 +671,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/freebsd-arm64@0.19.8:
+ resolution: {integrity: sha512-WAnPJSDattvS/XtPCTj1tPoTxERjcTpH6HsMr6ujTT+X6rylVe8ggxk8pVxzf5U1wh5sPODpawNicF5ta/9Tmw==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+ requiresBuild: true
+ optional: true
+
/@esbuild/freebsd-x64@0.18.20:
resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
engines: {node: '>=12'}
@@ -620,6 +687,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/freebsd-x64@0.19.8:
+ resolution: {integrity: sha512-ICvZyOplIjmmhjd6mxi+zxSdpPTKFfyPPQMQTK/w+8eNK6WV01AjIztJALDtwNNfFhfZLux0tZLC+U9nSyA5Zg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-arm64@0.18.20:
resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
engines: {node: '>=12'}
@@ -628,6 +703,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-arm64@0.19.8:
+ resolution: {integrity: sha512-z1zMZivxDLHWnyGOctT9JP70h0beY54xDDDJt4VpTX+iwA77IFsE1vCXWmprajJGa+ZYSqkSbRQ4eyLCpCmiCQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-arm@0.18.20:
resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
engines: {node: '>=12'}
@@ -636,6 +719,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-arm@0.19.8:
+ resolution: {integrity: sha512-H4vmI5PYqSvosPaTJuEppU9oz1dq2A7Mr2vyg5TF9Ga+3+MGgBdGzcyBP7qK9MrwFQZlvNyJrvz6GuCaj3OukQ==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-ia32@0.18.20:
resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
engines: {node: '>=12'}
@@ -644,6 +735,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-ia32@0.19.8:
+ resolution: {integrity: sha512-1a8suQiFJmZz1khm/rDglOc8lavtzEMRo0v6WhPgxkrjcU0LkHj+TwBrALwoz/OtMExvsqbbMI0ChyelKabSvQ==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-loong64@0.18.20:
resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
engines: {node: '>=12'}
@@ -652,6 +751,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-loong64@0.19.8:
+ resolution: {integrity: sha512-fHZWS2JJxnXt1uYJsDv9+b60WCc2RlvVAy1F76qOLtXRO+H4mjt3Tr6MJ5l7Q78X8KgCFudnTuiQRBhULUyBKQ==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-mips64el@0.18.20:
resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
engines: {node: '>=12'}
@@ -660,6 +767,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-mips64el@0.19.8:
+ resolution: {integrity: sha512-Wy/z0EL5qZYLX66dVnEg9riiwls5IYnziwuju2oUiuxVc+/edvqXa04qNtbrs0Ukatg5HEzqT94Zs7J207dN5Q==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-ppc64@0.18.20:
resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
engines: {node: '>=12'}
@@ -668,6 +783,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-ppc64@0.19.8:
+ resolution: {integrity: sha512-ETaW6245wK23YIEufhMQ3HSeHO7NgsLx8gygBVldRHKhOlD1oNeNy/P67mIh1zPn2Hr2HLieQrt6tWrVwuqrxg==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-riscv64@0.18.20:
resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
engines: {node: '>=12'}
@@ -676,6 +799,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-riscv64@0.19.8:
+ resolution: {integrity: sha512-T2DRQk55SgoleTP+DtPlMrxi/5r9AeFgkhkZ/B0ap99zmxtxdOixOMI570VjdRCs9pE4Wdkz7JYrsPvsl7eESg==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-s390x@0.18.20:
resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
engines: {node: '>=12'}
@@ -684,6 +815,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-s390x@0.19.8:
+ resolution: {integrity: sha512-NPxbdmmo3Bk7mbNeHmcCd7R7fptJaczPYBaELk6NcXxy7HLNyWwCyDJ/Xx+/YcNH7Im5dHdx9gZ5xIwyliQCbg==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/linux-x64@0.18.20:
resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
engines: {node: '>=12'}
@@ -692,6 +831,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/linux-x64@0.19.8:
+ resolution: {integrity: sha512-lytMAVOM3b1gPypL2TRmZ5rnXl7+6IIk8uB3eLsV1JwcizuolblXRrc5ShPrO9ls/b+RTp+E6gbsuLWHWi2zGg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
/@esbuild/netbsd-x64@0.18.20:
resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
engines: {node: '>=12'}
@@ -700,6 +847,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/netbsd-x64@0.19.8:
+ resolution: {integrity: sha512-hvWVo2VsXz/8NVt1UhLzxwAfo5sioj92uo0bCfLibB0xlOmimU/DeAEsQILlBQvkhrGjamP0/el5HU76HAitGw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+ requiresBuild: true
+ optional: true
+
/@esbuild/openbsd-x64@0.18.20:
resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
engines: {node: '>=12'}
@@ -708,6 +863,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/openbsd-x64@0.19.8:
+ resolution: {integrity: sha512-/7Y7u77rdvmGTxR83PgaSvSBJCC2L3Kb1M/+dmSIvRvQPXXCuC97QAwMugBNG0yGcbEGfFBH7ojPzAOxfGNkwQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+ requiresBuild: true
+ optional: true
+
/@esbuild/sunos-x64@0.18.20:
resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
engines: {node: '>=12'}
@@ -716,6 +879,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/sunos-x64@0.19.8:
+ resolution: {integrity: sha512-9Lc4s7Oi98GqFA4HzA/W2JHIYfnXbUYgekUP/Sm4BG9sfLjyv6GKKHKKVs83SMicBF2JwAX6A1PuOLMqpD001w==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+ requiresBuild: true
+ optional: true
+
/@esbuild/win32-arm64@0.18.20:
resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
engines: {node: '>=12'}
@@ -724,6 +895,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/win32-arm64@0.19.8:
+ resolution: {integrity: sha512-rq6WzBGjSzihI9deW3fC2Gqiak68+b7qo5/3kmB6Gvbh/NYPA0sJhrnp7wgV4bNwjqM+R2AApXGxMO7ZoGhIJg==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
/@esbuild/win32-ia32@0.18.20:
resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
engines: {node: '>=12'}
@@ -732,6 +911,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/win32-ia32@0.19.8:
+ resolution: {integrity: sha512-AIAbverbg5jMvJznYiGhrd3sumfwWs8572mIJL5NQjJa06P8KfCPWZQ0NwZbPQnbQi9OWSZhFVSUWjjIrn4hSw==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
/@esbuild/win32-x64@0.18.20:
resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
engines: {node: '>=12'}
@@ -740,6 +927,14 @@ packages:
requiresBuild: true
optional: true
+ /@esbuild/win32-x64@0.19.8:
+ resolution: {integrity: sha512-bfZ0cQ1uZs2PqpulNL5j/3w+GDhP36k1K5c38QdQg+Swy51jFZWWeIkteNsufkQxp986wnqRRsb/bHbY1WQ7TA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
/@eslint-community/eslint-utils@4.4.0(eslint@8.47.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -873,6 +1068,9 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.11
dev: true
+ /@jspm/core@2.0.1:
+ resolution: {integrity: sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw==}
+
/@ljharb/through@2.3.11:
resolution: {integrity: sha512-ccfcIDlogiXNq5KcbAwbaO7lMh3Tm1i3khMPYpxlK8hH/W53zN81KM9coerRLOnTGu3nfXIniAmQbRI9OxbC0w==}
engines: {node: '>= 0.4'}
@@ -924,6 +1122,103 @@ packages:
/@polka/url@1.0.0-next.23:
resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==}
+ /@rollup/pluginutils@5.0.5:
+ resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+ dependencies:
+ '@types/estree': 1.0.5
+ estree-walker: 2.0.2
+ picomatch: 2.3.1
+
+ /@rollup/rollup-android-arm-eabi@4.6.0:
+ resolution: {integrity: sha512-keHkkWAe7OtdALGoutLY3utvthkGF+Y17ws9LYT8pxMBYXaCoH/8dXS2uzo6e8+sEhY7y/zi5RFo22Dy2lFpDw==}
+ cpu: [arm]
+ os: [android]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-android-arm64@4.6.0:
+ resolution: {integrity: sha512-y3Kt+34smKQNWilicPbBz/MXEY7QwDzMFNgwEWeYiOhUt9MTWKjHqe3EVkXwT2fR7izOvHpDWZ0o2IyD9SWX7A==}
+ cpu: [arm64]
+ os: [android]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-darwin-arm64@4.6.0:
+ resolution: {integrity: sha512-oLzzxcUIHltHxOCmaXl+pkIlU+uhSxef5HfntW7RsLh1eHm+vJzjD9Oo4oUKso4YuP4PpbFJNlZjJuOrxo8dPg==}
+ cpu: [arm64]
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-darwin-x64@4.6.0:
+ resolution: {integrity: sha512-+ANnmjkcOBaV25n0+M0Bere3roeVAnwlKW65qagtuAfIxXF9YxUneRyAn/RDcIdRa7QrjRNJL3jR7T43ObGe8Q==}
+ cpu: [x64]
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-linux-arm-gnueabihf@4.6.0:
+ resolution: {integrity: sha512-tBTSIkjSVUyrekddpkAqKOosnj1Fc0ZY0rJL2bIEWPKqlEQk0paORL9pUIlt7lcGJi3LzMIlUGXvtNi1Z6MOCQ==}
+ cpu: [arm]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-linux-arm64-gnu@4.6.0:
+ resolution: {integrity: sha512-Ed8uJI3kM11de9S0j67wAV07JUNhbAqIrDYhQBrQW42jGopgheyk/cdcshgGO4fW5Wjq97COCY/BHogdGvKVNQ==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-linux-arm64-musl@4.6.0:
+ resolution: {integrity: sha512-mZoNQ/qK4D7SSY8v6kEsAAyDgznzLLuSFCA3aBHZTmf3HP/dW4tNLTtWh9+LfyO0Z1aUn+ecpT7IQ3WtIg3ViQ==}
+ cpu: [arm64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-linux-x64-gnu@4.6.0:
+ resolution: {integrity: sha512-rouezFHpwCqdEXsqAfNsTgSWO0FoZ5hKv5p+TGO5KFhyN/dvYXNMqMolOb8BkyKcPqjYRBeT+Z6V3aM26rPaYg==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-linux-x64-musl@4.6.0:
+ resolution: {integrity: sha512-Bbm+fyn3S6u51urfj3YnqBXg5vI2jQPncRRELaucmhBVyZkbWClQ1fEsRmdnCPpQOQfkpg9gZArvtMVkOMsh1w==}
+ cpu: [x64]
+ os: [linux]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-win32-arm64-msvc@4.6.0:
+ resolution: {integrity: sha512-+MRMcyx9L2kTrTUzYmR61+XVsliMG4odFb5UmqtiT8xOfEicfYAGEuF/D1Pww1+uZkYhBqAHpvju7VN+GnC3ng==}
+ cpu: [arm64]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-win32-ia32-msvc@4.6.0:
+ resolution: {integrity: sha512-rxfeE6K6s/Xl2HGeK6cO8SiQq3k/3BYpw7cfhW5Bk2euXNEpuzi2cc7llxx1si1QgwfjNtdRNTGqdBzGlFZGFw==}
+ cpu: [ia32]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
+ /@rollup/rollup-win32-x64-msvc@4.6.0:
+ resolution: {integrity: sha512-QqmCsydHS172Y0Kc13bkMXvipbJSvzeglBncJG3LsYJSiPlxYACz7MmJBs4A8l1oU+jfhYEIC/+AUSlvjmiX/g==}
+ cpu: [x64]
+ os: [win32]
+ requiresBuild: true
+ optional: true
+
/@sinclair/typebox@0.27.8:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
@@ -951,7 +1246,7 @@ packages:
/@types/better-sqlite3@7.6.4:
resolution: {integrity: sha512-dzrRZCYPXIXfSR1/surNbJ/grU3scTaygS0OMzjlGf71i9sc2fGyHPXXiXmEvNIoE0cGwsanEFMVJxPXmco9Eg==}
dependencies:
- '@types/node': 18.16.0
+ '@types/node': 20.10.0
dev: true
/@types/chai-subset@1.3.5:
@@ -962,6 +1257,9 @@ packages:
/@types/chai@4.3.5:
resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==}
+ /@types/estree@1.0.5:
+ resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
+
/@types/events@3.0.0:
resolution: {integrity: sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==}
dev: false
@@ -996,11 +1294,13 @@ packages:
/@types/node-forge@1.3.2:
resolution: {integrity: sha512-TzX3ahoi9xbmaoT58smrBu7oa6dQXb/+PTNCslZyD/55tlJ/osofIMClzZsoo6buDFrg7e4DvVGkZqVgv6OLxw==}
dependencies:
- '@types/node': 18.16.0
+ '@types/node': 20.10.0
dev: true
- /@types/node@18.16.0:
- resolution: {integrity: sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ==}
+ /@types/node@20.10.0:
+ resolution: {integrity: sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==}
+ dependencies:
+ undici-types: 5.26.5
/@types/normalize-package-data@2.4.1:
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
@@ -1013,13 +1313,13 @@ packages:
/@types/through@0.0.32:
resolution: {integrity: sha512-7XsfXIsjdfJM2wFDRAtEWp3zb2aVPk5QeyZxGlVK57q4u26DczMHhJmlhr0Jqv0THwxam/L8REXkj8M2I/lcvw==}
dependencies:
- '@types/node': 18.16.0
+ '@types/node': 20.10.0
dev: true
/@types/ws@8.5.4:
resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==}
dependencies:
- '@types/node': 18.16.0
+ '@types/node': 20.10.0
dev: true
/@typescript-eslint/eslint-plugin@6.4.0(@typescript-eslint/parser@6.4.0)(eslint@8.47.0)(typescript@5.0.4):
@@ -1153,6 +1453,20 @@ packages:
eslint-visitor-keys: 3.4.1
dev: true
+ /@vitest/browser@0.34.6(esbuild@0.18.20)(vitest@0.34.6):
+ resolution: {integrity: sha512-XCIGROVgw3L+PwYw/T2l+HP/SPrXvh2MfmQNU3aULl5ekE+QVj9A1RYu/1mcYXdac9ES4ahxUz6n4wgcVd9tbA==}
+ peerDependencies:
+ vitest: '>=0.34.0'
+ dependencies:
+ estree-walker: 3.0.3
+ magic-string: 0.30.5
+ modern-node-polyfills: 1.0.0(esbuild@0.18.20)
+ sirv: 2.0.3
+ vitest: 0.34.6(@vitest/browser@0.34.6)(@vitest/ui@0.34.6)(playwright@1.40.1)
+ transitivePeerDependencies:
+ - esbuild
+ - rollup
+
/@vitest/coverage-v8@0.34.6(vitest@0.34.6):
resolution: {integrity: sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==}
peerDependencies:
@@ -1169,7 +1483,7 @@ packages:
std-env: 3.4.3
test-exclude: 6.0.0
v8-to-istanbul: 9.1.3
- vitest: 0.34.6(@vitest/ui@0.34.6)
+ vitest: 0.34.6(@vitest/browser@0.34.6)(@vitest/ui@0.34.6)(playwright@1.40.1)
transitivePeerDependencies:
- supports-color
dev: true
@@ -1212,7 +1526,7 @@ packages:
pathe: 1.1.1
picocolors: 1.0.0
sirv: 2.0.3
- vitest: 0.34.6(@vitest/ui@0.34.6)
+ vitest: 0.34.6(@vitest/browser@0.34.6)(@vitest/ui@0.34.6)(playwright@1.40.1)
/@vitest/utils@0.34.6:
resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==}
@@ -1654,6 +1968,10 @@ packages:
engines: {node: '>=10'}
dev: false
+ /cjs-module-lexer@1.2.3:
+ resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==}
+ dev: true
+
/clean-stack@2.2.0:
resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
engines: {node: '>=6'}
@@ -1792,7 +2110,7 @@ packages:
resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
dev: false
- /cosmiconfig-typescript-loader@4.3.0(@types/node@18.16.0)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.0.4):
+ /cosmiconfig-typescript-loader@4.3.0(@types/node@20.10.0)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.0.4):
resolution: {integrity: sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==}
engines: {node: '>=12', npm: '>=6'}
peerDependencies:
@@ -1801,9 +2119,9 @@ packages:
ts-node: '>=10'
typescript: '>=3'
dependencies:
- '@types/node': 18.16.0
+ '@types/node': 20.10.0
cosmiconfig: 8.1.3
- ts-node: 10.9.1(@types/node@18.16.0)(typescript@5.0.4)
+ ts-node: 10.9.1(@types/node@20.10.0)(typescript@5.0.4)
typescript: 5.0.4
dev: true
@@ -2232,6 +2550,35 @@ packages:
'@esbuild/win32-ia32': 0.18.20
'@esbuild/win32-x64': 0.18.20
+ /esbuild@0.19.8:
+ resolution: {integrity: sha512-l7iffQpT2OrZfH2rXIp7/FkmaeZM0vxbxN9KfiCwGYuZqzMg/JdvX26R31Zxn/Pxvsrg3Y9N6XTcnknqDyyv4w==}
+ engines: {node: '>=12'}
+ hasBin: true
+ requiresBuild: true
+ optionalDependencies:
+ '@esbuild/android-arm': 0.19.8
+ '@esbuild/android-arm64': 0.19.8
+ '@esbuild/android-x64': 0.19.8
+ '@esbuild/darwin-arm64': 0.19.8
+ '@esbuild/darwin-x64': 0.19.8
+ '@esbuild/freebsd-arm64': 0.19.8
+ '@esbuild/freebsd-x64': 0.19.8
+ '@esbuild/linux-arm': 0.19.8
+ '@esbuild/linux-arm64': 0.19.8
+ '@esbuild/linux-ia32': 0.19.8
+ '@esbuild/linux-loong64': 0.19.8
+ '@esbuild/linux-mips64el': 0.19.8
+ '@esbuild/linux-ppc64': 0.19.8
+ '@esbuild/linux-riscv64': 0.19.8
+ '@esbuild/linux-s390x': 0.19.8
+ '@esbuild/linux-x64': 0.19.8
+ '@esbuild/netbsd-x64': 0.19.8
+ '@esbuild/openbsd-x64': 0.19.8
+ '@esbuild/sunos-x64': 0.19.8
+ '@esbuild/win32-arm64': 0.19.8
+ '@esbuild/win32-ia32': 0.19.8
+ '@esbuild/win32-x64': 0.19.8
+
/escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
@@ -2464,6 +2811,14 @@ packages:
engines: {node: '>=4.0'}
dev: true
+ /estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ /estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+ dependencies:
+ '@types/estree': 1.0.5
+
/esutils@2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
@@ -2654,6 +3009,13 @@ packages:
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+ /fsevents@2.3.2:
+ resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+ requiresBuild: true
+ optional: true
+
/fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -3804,6 +4166,19 @@ packages:
pkg-types: 1.0.3
ufo: 1.3.1
+ /modern-node-polyfills@1.0.0(esbuild@0.18.20):
+ resolution: {integrity: sha512-w1yb6ae5qSUJJ2u41krkUAxs+L7i9143Qam8EuXwDMeZHxl1JN8RfTSXG4S2bt0RHIRMeoWm/HCeO0pNIHmIYQ==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ esbuild: ^0.14.0 || ^0.15.0 || ^0.16.0 || ^0.17.0 || ^0.18.0
+ dependencies:
+ '@jspm/core': 2.0.1
+ '@rollup/pluginutils': 5.0.5
+ esbuild: 0.18.20
+ local-pkg: 0.4.3
+ transitivePeerDependencies:
+ - rollup
+
/mrmime@1.0.1:
resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==}
engines: {node: '>=10'}
@@ -4190,6 +4565,20 @@ packages:
mlly: 1.4.2
pathe: 1.1.1
+ /playwright-core@1.40.1:
+ resolution: {integrity: sha512-+hkOycxPiV534c4HhpfX6yrlawqVUzITRKwHAmYfmsVreltEl6fAZJ3DPfLMOODw0H3s1Itd6MDCWmP1fl/QvQ==}
+ engines: {node: '>=16'}
+ hasBin: true
+
+ /playwright@1.40.1:
+ resolution: {integrity: sha512-2eHI7IioIpQ0bS1Ovg/HszsN/XKNwEG1kbzSDDmADpclKc7CyqkHw7Mg2JCz/bbCxg25QUPcjksoMW7JcIFQmw==}
+ engines: {node: '>=16'}
+ hasBin: true
+ dependencies:
+ playwright-core: 1.40.1
+ optionalDependencies:
+ fsevents: 2.3.2
+
/postcss@8.4.31:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
@@ -4432,11 +4821,23 @@ packages:
glob: 10.2.6
dev: true
- /rollup@3.29.4:
- resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
- engines: {node: '>=14.18.0', npm: '>=8.0.0'}
+ /rollup@4.6.0:
+ resolution: {integrity: sha512-R8i5Her4oO1LiMQ3jKf7MUglYV/mhQ5g5OKeld5CnkmPdIGo79FDDQYqPhq/PCVuTQVuxsWgIbDy9F+zdHn80w==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.6.0
+ '@rollup/rollup-android-arm64': 4.6.0
+ '@rollup/rollup-darwin-arm64': 4.6.0
+ '@rollup/rollup-darwin-x64': 4.6.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.6.0
+ '@rollup/rollup-linux-arm64-gnu': 4.6.0
+ '@rollup/rollup-linux-arm64-musl': 4.6.0
+ '@rollup/rollup-linux-x64-gnu': 4.6.0
+ '@rollup/rollup-linux-x64-musl': 4.6.0
+ '@rollup/rollup-win32-arm64-msvc': 4.6.0
+ '@rollup/rollup-win32-ia32-msvc': 4.6.0
+ '@rollup/rollup-win32-x64-msvc': 4.6.0
fsevents: 2.3.3
/run-applescript@5.0.0:
@@ -4929,7 +5330,7 @@ packages:
typescript: 5.0.4
dev: true
- /ts-node@10.9.1(@types/node@18.16.0)(typescript@5.0.4):
+ /ts-node@10.9.1(@types/node@20.10.0)(typescript@5.0.4):
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
@@ -4948,7 +5349,7 @@ packages:
'@tsconfig/node12': 1.0.9
'@tsconfig/node14': 1.0.1
'@tsconfig/node16': 1.0.2
- '@types/node': 18.16.0
+ '@types/node': 20.10.0
acorn: 8.10.0
acorn-walk: 8.2.0
arg: 4.1.3
@@ -5076,6 +5477,9 @@ packages:
which-boxed-primitive: 1.0.2
dev: true
+ /undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+
/unique-filename@1.1.1:
resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==}
dependencies:
@@ -5127,7 +5531,7 @@ packages:
spdx-expression-parse: 3.0.1
dev: true
- /vite-node@0.34.6(@types/node@18.16.0):
+ /vite-node@0.34.6(@types/node@20.10.0):
resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
engines: {node: '>=v14.18.0'}
hasBin: true
@@ -5137,7 +5541,7 @@ packages:
mlly: 1.4.2
pathe: 1.1.1
picocolors: 1.0.0
- vite: 4.5.0(@types/node@18.16.0)
+ vite: 5.0.3(@types/node@20.10.0)
transitivePeerDependencies:
- '@types/node'
- less
@@ -5148,12 +5552,12 @@ packages:
- supports-color
- terser
- /vite@4.5.0(@types/node@18.16.0):
- resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==}
- engines: {node: ^14.18.0 || >=16.0.0}
+ /vite@5.0.3(@types/node@20.10.0):
+ resolution: {integrity: sha512-WgEq8WEKpZ8c0DL4M1+E+kBZEJyjBmGVrul6z8Ljfhv+PPbNF4aGq014DwNYxGz2FGq6NKL0N8usdiESWd2l2w==}
+ engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
- '@types/node': '>= 14'
+ '@types/node': ^18.0.0 || >=20.0.0
less: '*'
lightningcss: ^1.21.0
sass: '*'
@@ -5176,14 +5580,14 @@ packages:
terser:
optional: true
dependencies:
- '@types/node': 18.16.0
- esbuild: 0.18.20
+ '@types/node': 20.10.0
+ esbuild: 0.19.8
postcss: 8.4.31
- rollup: 3.29.4
+ rollup: 4.6.0
optionalDependencies:
fsevents: 2.3.3
- /vitest@0.34.6(@vitest/ui@0.34.6):
+ /vitest@0.34.6(@vitest/browser@0.34.6)(@vitest/ui@0.34.6)(playwright@1.40.1):
resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==}
engines: {node: '>=v14.18.0'}
hasBin: true
@@ -5216,7 +5620,8 @@ packages:
dependencies:
'@types/chai': 4.3.5
'@types/chai-subset': 1.3.5
- '@types/node': 18.16.0
+ '@types/node': 20.10.0
+ '@vitest/browser': 0.34.6(esbuild@0.18.20)(vitest@0.34.6)
'@vitest/expect': 0.34.6
'@vitest/runner': 0.34.6
'@vitest/snapshot': 0.34.6
@@ -5232,12 +5637,13 @@ packages:
magic-string: 0.30.5
pathe: 1.1.1
picocolors: 1.0.0
+ playwright: 1.40.1
std-env: 3.4.3
strip-literal: 1.3.0
tinybench: 2.5.1
tinypool: 0.7.0
- vite: 4.5.0(@types/node@18.16.0)
- vite-node: 0.34.6(@types/node@18.16.0)
+ vite: 5.0.3(@types/node@20.10.0)
+ vite-node: 0.34.6(@types/node@20.10.0)
why-is-node-running: 2.2.2
transitivePeerDependencies:
- less
diff --git a/scripts/build-package.js b/scripts/build-package.js
index 4909afeb..9976e5cb 100644
--- a/scripts/build-package.js
+++ b/scripts/build-package.js
@@ -114,6 +114,31 @@ function buildPackageJson() {
delete pkgJson.typedoc
+ function maybeFixPath(p, repl) {
+ if (!p) return p
+
+ if (p.startsWith('./src/')) {
+ return repl + p.slice(6)
+ }
+
+ return p
+ }
+
+ if (pkgJson.browser) {
+ for (const key of Object.keys(pkgJson.browser)) {
+ if (!key.startsWith('./src/')) continue
+
+ const path = key.slice(6)
+ pkgJson.browser[`./esm/${path}`] = maybeFixPath(pkgJson.browser[key], './esm/')
+
+ if (buildConfig.buildCjs) {
+ pkgJson.browser[`./cjs/${path}`] = maybeFixPath(pkgJson.browser[key], './cjs/')
+ }
+
+ delete pkgJson.browser[key]
+ }
+ }
+
fs.writeFileSync(path.join(packageDir, 'dist/package.json'), JSON.stringify(pkgJson, null, 2))
}
diff --git a/tsconfig.json b/tsconfig.json
index 46f8f0a1..2b6ef48e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -16,7 +16,13 @@
"incremental": true,
"stripInternal": true,
"skipLibCheck": true,
- "composite": true
+ "composite": true,
+ "types": [
+ "node",
+ "vite/client"
+ ],
+ "resolveJsonModule": true,
+ "isolatedModules": true,
},
"ts-node": {
"esm": true,