From f3c0daa835f816da936e14c4197e25c1d1c53104 Mon Sep 17 00:00:00 2001 From: alina sireneva Date: Sat, 7 Sep 2024 18:52:21 +0300 Subject: [PATCH] chore!: use more utils from fuman --- packages/convert/package.json | 3 +- packages/convert/src/telethon/parse.ts | 12 ++- packages/convert/src/telethon/serialize.ts | 7 +- packages/convert/src/utils/ip.ts | 49 ----------- packages/node/package.json | 2 +- .../node/src/methods/download-node-stream.ts | 3 +- packages/node/src/utils/normalize-file.ts | 3 +- packages/node/src/utils/proxies.ts | 2 +- packages/node/src/utils/stream-utils.test.ts | 59 ------------- packages/node/src/utils/stream-utils.ts | 83 ------------------- packages/node/src/utils/tcp.ts | 2 +- packages/node/src/utils/version.ts | 16 ---- packages/tl/package.json | 2 +- packages/tl/scripts/documentation.ts | 44 +++++----- pnpm-lock.yaml | 13 +-- 15 files changed, 48 insertions(+), 252 deletions(-) delete mode 100644 packages/convert/src/utils/ip.ts delete mode 100644 packages/node/src/utils/stream-utils.test.ts delete mode 100644 packages/node/src/utils/stream-utils.ts delete mode 100644 packages/node/src/utils/version.ts diff --git a/packages/convert/package.json b/packages/convert/package.json index add2c059..f02a51dc 100644 --- a/packages/convert/package.json +++ b/packages/convert/package.json @@ -13,7 +13,8 @@ }, "dependencies": { "@mtcute/core": "workspace:^", - "@fuman/utils": "workspace:^" + "@fuman/utils": "workspace:^", + "@fuman/ip": "workspace:^" }, "devDependencies": { "@mtcute/test": "workspace:^" diff --git a/packages/convert/src/telethon/parse.ts b/packages/convert/src/telethon/parse.ts index db0df758..c5df6f20 100644 --- a/packages/convert/src/telethon/parse.ts +++ b/packages/convert/src/telethon/parse.ts @@ -1,7 +1,6 @@ import { MtArgumentError } from '@mtcute/core' import { base64, typed } from '@fuman/utils' - -import { parseIpFromBytes } from '../utils/ip.js' +import { ip } from '@fuman/ip' import type { TelethonSession } from './types.js' @@ -26,11 +25,16 @@ export function parseTelethonSession(session: string): TelethonSession { pos += 2 const authKey = data.subarray(pos, pos + 256) - const ip = parseIpFromBytes(ipBytes) + let parsedIp + if (ipSize === 16) { + parsedIp = ip.stringifyV6(ip.fromBytesV6(ipBytes)) + } else { + parsedIp = ip.stringifyV4({ type: 'ipv4', parts: ipBytes }) + } return { dcId, - ipAddress: ip, + ipAddress: parsedIp, ipv6: ipSize === 16, port, authKey, diff --git a/packages/convert/src/telethon/serialize.ts b/packages/convert/src/telethon/serialize.ts index 4110cc31..6ba34d69 100644 --- a/packages/convert/src/telethon/serialize.ts +++ b/packages/convert/src/telethon/serialize.ts @@ -1,7 +1,6 @@ import { MtArgumentError } from '@mtcute/core' import { base64, typed } from '@fuman/utils' - -import { serializeIpv4ToBytes, serializeIpv6ToBytes } from '../utils/ip.js' +import { ip } from '@fuman/ip' import type { TelethonSession } from './types.js' @@ -19,10 +18,10 @@ export function serializeTelethonSession(session: TelethonSession): string { let pos if (session.ipv6) { - serializeIpv6ToBytes(session.ipAddress, u8.subarray(1, 17)) + u8.subarray(1, 17).set(ip.toBytesV6(ip.parseV6(session.ipAddress))) pos = 17 } else { - serializeIpv4ToBytes(session.ipAddress, u8.subarray(1, 5)) + u8.subarray(1, 5).set(ip.parseV4(session.ipAddress).parts) pos = 5 } diff --git a/packages/convert/src/utils/ip.ts b/packages/convert/src/utils/ip.ts deleted file mode 100644 index 90dcbbc5..00000000 --- a/packages/convert/src/utils/ip.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { MtArgumentError } from '@mtcute/core' - -// todo: use @fuman/ip -export function parseIpFromBytes(data: Uint8Array): string { - if (data.length === 4) { - return `${data[0]}.${data[1]}.${data[2]}.${data[3]}` - } - - if (data.length === 16) { - let res = '' - - for (let i = 0; i < 16; i += 2) { - res += data[i].toString(16).padStart(2, '0') - res += data[i + 1].toString(16).padStart(2, '0') - if (i < 14) res += ':' - } - - return res - } - - throw new MtArgumentError('Invalid IP address length') -} - -export function serializeIpv4ToBytes(ip: string, buf: Uint8Array): void { - const parts = ip.split('.') - - if (parts.length !== 4) { - throw new MtArgumentError('Invalid IPv4 address') - } - - buf[0] = Number(parts[0]) - buf[1] = Number(parts[1]) - buf[2] = Number(parts[2]) - buf[3] = Number(parts[3]) -} - -export function serializeIpv6ToBytes(ip: string, buf: Uint8Array): void { - const parts = ip.split(':') - - if (parts.length !== 8) { - throw new MtArgumentError('Invalid IPv6 address') - } - - for (let i = 0; i < 8; i++) { - const val = Number.parseInt(parts[i], 16) - buf[i * 2] = val >> 8 - buf[i * 2 + 1] = val & 0xFF - } -} diff --git a/packages/node/package.json b/packages/node/package.json index 01f62945..fc79b9a3 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -22,7 +22,7 @@ "@mtcute/markdown-parser": "workspace:^", "@mtcute/wasm": "workspace:^", "@fuman/net": "workspace:^", - "@fuman/node-net": "workspace:^", + "@fuman/node": "workspace:^", "better-sqlite3": "11.3.0" }, "devDependencies": { diff --git a/packages/node/src/methods/download-node-stream.ts b/packages/node/src/methods/download-node-stream.ts index 05fa45f7..a68d5bbc 100644 --- a/packages/node/src/methods/download-node-stream.ts +++ b/packages/node/src/methods/download-node-stream.ts @@ -2,8 +2,7 @@ import type { Readable } from 'node:stream' import type { FileDownloadLocation, FileDownloadParameters, ITelegramClient } from '@mtcute/core' import { downloadAsStream } from '@mtcute/core/methods.js' - -import { webStreamToNode } from '../utils/stream-utils.js' +import { webStreamToNode } from '@fuman/node' /** * Download a remote file as a Node.js Readable stream. diff --git a/packages/node/src/utils/normalize-file.ts b/packages/node/src/utils/normalize-file.ts index 3f8eb784..b69ec94d 100644 --- a/packages/node/src/utils/normalize-file.ts +++ b/packages/node/src/utils/normalize-file.ts @@ -4,8 +4,7 @@ import { basename } from 'node:path' import { Readable } from 'node:stream' import type { UploadFileLike } from '@mtcute/core' - -import { nodeStreamToWeb } from './stream-utils.js' +import { nodeStreamToWeb } from '@fuman/node' export async function normalizeFile(file: UploadFileLike): Promise<{ file: UploadFileLike diff --git a/packages/node/src/utils/proxies.ts b/packages/node/src/utils/proxies.ts index 519408f7..5246e4fa 100644 --- a/packages/node/src/utils/proxies.ts +++ b/packages/node/src/utils/proxies.ts @@ -2,7 +2,7 @@ import type { SecureContextOptions } from 'node:tls' import type { HttpProxySettings as FumanHttpProxySettings, ITcpConnection, SocksProxySettings, TcpEndpoint } from '@fuman/net' import { performHttpProxyHandshake, performSocksHandshake } from '@fuman/net' -import { connectTcp, connectTls } from '@fuman/node-net' +import { connectTcp, connectTls } from '@fuman/node' import { BaseMtProxyTransport, type ITelegramConnection, IntermediatePacketCodec, type TelegramTransport } from '@mtcute/core' import type { BasicDcOption } from '@mtcute/core/utils.js' diff --git a/packages/node/src/utils/stream-utils.test.ts b/packages/node/src/utils/stream-utils.test.ts deleted file mode 100644 index 8d163500..00000000 --- a/packages/node/src/utils/stream-utils.test.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Readable } from 'node:stream' - -import { describe, expect, it } from 'vitest' - -if (import.meta.env.TEST_ENV === 'node' || import.meta.env.TEST_ENV === 'bun') { - const { nodeStreamToWeb, webStreamToNode } = await import('./stream-utils.js') - - describe('nodeStreamToWeb', () => { - it('should correctly convert a readable stream', async () => { - const stream = new Readable({ - read() { - this.push(Buffer.from([1, 2, 3])) - - this.push(Buffer.from([4, 5, 6])) - this.push(null) - }, - }) - - const webStream = nodeStreamToWeb(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 }) - }) - }) - - describe('webStreamToNode', () => { - it('should correctly convert a readable stream', async () => { - const stream = new ReadableStream({ - start(controller) { - controller.enqueue(new Uint8Array([1, 2, 3])) - controller.enqueue(new Uint8Array([4, 5, 6])) - controller.close() - }, - }) - - const nodeStream = webStreamToNode(stream) - const chunks: Buffer[] = [] - - nodeStream.on('data', (chunk) => { - chunks.push(chunk as Buffer) - }) - - await new Promise((resolve, reject) => { - nodeStream.on('end', () => { - try { - expect(chunks).to.deep.equal([Buffer.from([1, 2, 3]), Buffer.from([4, 5, 6])]) - resolve() - } catch (err) { - reject(err) - } - }) - }) - }) - }) -} else { - describe.skip('node stream utils', () => {}) -} diff --git a/packages/node/src/utils/stream-utils.ts b/packages/node/src/utils/stream-utils.ts deleted file mode 100644 index f1e37d37..00000000 --- a/packages/node/src/utils/stream-utils.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Readable } from 'node:stream' - -import { isNodeVersionAfter } from './version.js' - -export function nodeStreamToWeb(stream: Readable): ReadableStream { - if (typeof Readable.toWeb === 'function') { - return Readable.toWeb(stream) as unknown as ReadableStream - } - - // otherwise, use a silly little adapter - - stream.pause() - - return new ReadableStream({ - start(c) { - stream.on('data', (chunk) => { - c.enqueue(chunk as Uint8Array) - }) - stream.on('end', () => { - c.close() - }) - stream.on('error', (err) => { - c.error(err) - }) - }, - pull() { - stream.resume() - }, - }) -} - -export function webStreamToNode(stream: ReadableStream): Readable { - if ( - typeof Readable.fromWeb === 'function' - && isNodeVersionAfter(18, 13, 0) // https://github.com/nodejs/node/issues/42694 - ) { - // @ts-expect-error node typings are wrong lmao - return Readable.fromWeb(stream) - } - - const reader = stream.getReader() - let ended = false - - const readable = new Readable({ - async read() { - try { - const { done, value } = await reader.read() - - if (done) { - this.push(null) - } else { - this.push(Buffer.from(value.buffer, value.byteOffset, value.byteLength)) - } - } catch (err) { - this.destroy(err as Error) - } - }, - destroy(error, cb) { - if (!ended) { - void reader - .cancel(error) - .catch(() => {}) - .then(() => { - cb(error) - }) - - return - } - - cb(error) - }, - }) - - reader.closed - .then(() => { - ended = true - }) - .catch((err) => { - readable.destroy(err as Error) - }) - - return readable -} diff --git a/packages/node/src/utils/tcp.ts b/packages/node/src/utils/tcp.ts index 535d6502..c7a278db 100644 --- a/packages/node/src/utils/tcp.ts +++ b/packages/node/src/utils/tcp.ts @@ -1,4 +1,4 @@ -import { connectTcp } from '@fuman/node-net' +import { connectTcp } from '@fuman/node' import type { TelegramTransport } from '@mtcute/core' import { IntermediatePacketCodec } from '@mtcute/core' diff --git a/packages/node/src/utils/version.ts b/packages/node/src/utils/version.ts deleted file mode 100644 index 8f3ee833..00000000 --- a/packages/node/src/utils/version.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const NODE_VERSION: string | null - = typeof process !== 'undefined' && 'node' in process.versions ? process.versions.node : null -export const NODE_VERSION_TUPLE: number[] | null - = NODE_VERSION ? /* #__PURE__ */ NODE_VERSION.split('.').map(Number) : null - -export function isNodeVersionAfter(major: number, minor: number, patch: number): boolean { - if (!NODE_VERSION_TUPLE) return true // assume non-node environment is always "after" - - const [a, b, c] = NODE_VERSION_TUPLE - if (a > major) return true - if (a < major) return false - if (b > minor) return true - if (b < minor) return false - - return c >= patch -} diff --git a/packages/tl/package.json b/packages/tl/package.json index e49235f0..cef465f6 100644 --- a/packages/tl/package.json +++ b/packages/tl/package.json @@ -22,10 +22,10 @@ "@mtcute/core": "workspace:^", "@mtcute/node": "workspace:^", "@mtcute/tl-utils": "workspace:^", + "@fuman/utils": "workspace:^", "@types/js-yaml": "^4.0.5", "cheerio": "1.0.0-rc.12", "csv-parse": "^5.5.0", - "eager-async-pool": "^1.0.0", "js-yaml": "4.1.0" }, "typedoc": { diff --git a/packages/tl/scripts/documentation.ts b/packages/tl/scripts/documentation.ts index cbe09922..a40e8dd3 100644 --- a/packages/tl/scripts/documentation.ts +++ b/packages/tl/scripts/documentation.ts @@ -3,7 +3,7 @@ import { fileURLToPath } from 'node:url' import { createInterface } from 'node:readline' import * as cheerio from 'cheerio' -import { asyncPoolCallback } from 'eager-async-pool' +import { asyncPool } from '@fuman/utils' import jsYaml from 'js-yaml' import type { TlEntry, @@ -408,6 +408,8 @@ export async function fetchDocumentation( } ret[entry.kind === 'class' ? 'classes' : 'methods'][entry.name] = retClass + + log(`📥 ${entry.kind} ${entry.name}`) } async function fetchDocsForUnion(name: string) { @@ -427,36 +429,32 @@ export async function fetchDocumentation( const description = extractDescription($) if (description) ret.unions[name] = description + + log(`📥 union ${name}`) } - await asyncPoolCallback( - fetchDocsForEntry, + await asyncPool( schema.entries, - ({ item, error }) => { - if (error) { - console.log(`❌ ${item.kind} ${item.name} (${error.message})`) - - return - } - - log(`📥 ${item.kind} ${item.name}`) + fetchDocsForEntry, + { + limit: 16, + onError: (item, error) => { + console.log(`❌ ${item.kind} ${item.name} (${error})`) + return 'throw' + }, }, - { limit: 16 }, ) - await asyncPoolCallback( - fetchDocsForUnion, + await asyncPool( Object.keys(schema.unions), - ({ item, error }) => { - if (error) { - console.log(`❌ union ${item} (${error.message})`) - - return - } - - log(`📥 union ${item}`) + fetchDocsForUnion, + { + limit: 16, + onError: (item, error) => { + console.log(`❌ union ${item} (${error})`) + return 'throw' + }, }, - { limit: 16 }, ) log('✨ Patching descriptions') diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed41de06..e0321e78 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,6 +132,9 @@ importers: packages/convert: dependencies: + '@fuman/ip': + specifier: workspace:^ + version: link:../../private/fuman/packages/ip '@fuman/utils': specifier: workspace:^ version: link:../../private/fuman/packages/utils @@ -324,9 +327,9 @@ importers: '@fuman/net': specifier: workspace:^ version: link:../../private/fuman/packages/net - '@fuman/node-net': + '@fuman/node': specifier: workspace:^ - version: link:../../private/fuman/packages/node-net + version: link:../../private/fuman/packages/node '@mtcute/core': specifier: workspace:^ version: link:../core @@ -384,6 +387,9 @@ importers: specifier: 5.2.3 version: 5.2.3 devDependencies: + '@fuman/utils': + specifier: workspace:^ + version: link:../../private/fuman/packages/utils '@mtcute/core': specifier: workspace:^ version: link:../core @@ -402,9 +408,6 @@ importers: csv-parse: specifier: ^5.5.0 version: 5.5.0 - eager-async-pool: - specifier: ^1.0.0 - version: 1.0.0 js-yaml: specifier: 4.1.0 version: 4.1.0