major cleanup (part 1) (#66)

This commit is contained in:
alina sireneva 2024-08-18 15:36:34 +03:00 committed by GitHub
commit e53b845508
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
935 changed files with 11687 additions and 10128 deletions

View file

@ -1,30 +0,0 @@
const baseConfig = require('./eslint.cjs')
module.exports = {
...baseConfig,
overrides: [
baseConfig.overrides[0],
{
...baseConfig.overrides[0],
files: ['packages/**/*.ts'],
extends: ['plugin:@typescript-eslint/strict-type-checked', 'plugin:import/typescript'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
},
rules: {
...baseConfig.overrides[0].rules,
'@typescript-eslint/restrict-template-expressions': ['error', { allowNever: true }],
},
reportUnusedDisableDirectives: false,
},
...baseConfig.overrides.slice(1),
{
files: ['e2e/**'],
rules: {
'import/no-unresolved': 'off',
},
},
],
}

View file

@ -1,301 +0,0 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:import/recommended', 'prettier'],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['ascii', 'import', 'simple-import-sort'],
reportUnusedDisableDirectives: true,
rules: {
// see https://github.com/airbnb/javascript/blob/master/packages/eslint-config-airbnb-base/rules/style.js#L122
indent: [
2,
4,
{
SwitchCase: 1,
VariableDeclarator: 1,
outerIIFEBody: 1,
// MemberExpression: null,
FunctionDeclaration: {
parameters: 1,
body: 1,
},
FunctionExpression: {
parameters: 1,
body: 1,
},
CallExpression: {
arguments: 1,
},
ArrayExpression: 1,
ObjectExpression: 1,
ImportDeclaration: 1,
flatTernaryExpressions: false,
// list derived from https://github.com/benjamn/ast-types/blob/HEAD/def/jsx.js
ignoredNodes: [
'JSXElement',
'JSXElement > *',
'JSXAttribute',
'JSXIdentifier',
'JSXNamespacedName',
'JSXMemberExpression',
'JSXSpreadAttribute',
'JSXExpressionContainer',
'JSXOpeningElement',
'JSXClosingElement',
'JSXText',
'JSXEmptyExpression',
'JSXSpreadChild',
],
ignoreComments: false,
},
],
semi: [2, 'never', { beforeStatementContinuationChars: 'never' }],
'semi-spacing': [2, { before: false, after: true }],
'wrap-iife': [2, 'inside'],
'no-caller': 2,
'no-cond-assign': [2, 'except-parens'],
'no-constant-condition': 0,
'no-debugger': 2,
'no-dupe-args': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty': [2, { allowEmptyCatch: true }],
'no-empty-function': 'off',
'no-extra-boolean-cast': 2,
// "no-extra-parens": [2, "all"],
'no-extra-semi': 2,
'no-func-assign': 2,
'no-new': 2,
'no-sparse-arrays': 2,
'no-unexpected-multiline': 2,
'no-unreachable': 2,
'max-params': [1, 5],
'max-depth': [1, 4],
'no-eq-null': 0,
'no-unused-expressions': 0,
'dot-notation': 2,
'use-isnan': 2,
// Best practices
'block-scoped-var': 2,
complexity: [0, 11],
curly: [2, 'multi-line'],
eqeqeq: [2, 'always', { null: 'ignore' }],
'no-else-return': 2,
'no-extra-bind': 2,
'no-implicit-coercion': 2,
'no-return-assign': 0,
'no-sequences': 2,
yoda: 2,
// Variables
'no-restricted-globals': ['error'],
'no-var': 1,
// Codestyle
'arrow-parens': [2, 'always'],
'array-bracket-spacing': [2, 'never'],
'brace-style': [2, '1tbs', { allowSingleLine: true }],
camelcase: [2, { properties: 'never' }],
'comma-dangle': ['warn', 'always-multiline'],
'comma-spacing': [2, { before: false, after: true }],
'eol-last': 2,
'func-call-spacing': [2, 'never'],
'block-spacing': 2,
'keyword-spacing': [2, { before: true, after: true }],
'max-len': [
2,
{
code: 120,
ignoreUrls: true,
ignoreComments: false,
ignoreRegExpLiterals: true,
ignoreStrings: true,
ignoreTemplateLiterals: true,
ignorePattern: 'require',
},
],
'no-lonely-if': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multiple-empty-lines': [2, { max: 1, maxBOF: 0, maxEOF: 0 }],
'no-trailing-spaces': 2,
'ascii/valid-name': 2,
'no-unneeded-ternary': 2,
'no-nested-ternary': 2,
'object-curly-spacing': [2, 'always'],
'one-var-declaration-per-line': [2, 'initializations'],
'one-var': [2, { let: 'never', const: 'never' }],
'operator-linebreak': [2, 'after'],
'padded-blocks': [2, 'never'],
'quote-props': [2, 'as-needed', { numbers: true }],
quotes: [2, 'single', { avoidEscape: true }],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [
2,
{
named: 'never',
anonymous: 'always',
},
],
'space-in-parens': 2,
'key-spacing': [2, { beforeColon: false, afterColon: true, mode: 'strict' }],
'space-infix-ops': 2,
'padding-line-between-statements': [
'error',
{ blankLine: 'always', prev: '*', next: 'return' },
{ blankLine: 'always', prev: '*', next: 'block-like' },
{ blankLine: 'any', prev: 'block-like', next: 'block-like' },
{ blankLine: 'any', prev: 'case', next: 'case' },
],
'simple-import-sort/imports': [
'error',
{
groups: [['^[a-z]'], ['^@?mtcute'], ['^@/'], ['^~/'], ['^\\.']],
},
],
'simple-import-sort/exports': 'error',
'import/no-relative-packages': 'error',
'import/no-mutable-exports': 'error',
'import/no-default-export': 'error',
'no-console': ['error', { allow: ['warn', 'error'] }],
},
ignorePatterns: [
'node_modules/',
'.config/',
'.idea/',
'.vscode/',
'private/',
'docs/',
'dist/',
'*.json',
// codegen
'packages/tl/binary/rsa-keys.js',
'packages/tl/binary/reader.js',
'packages/tl/binary/writer.js',
'packages/tl/index.js',
'packages/tl/index.d.ts',
'packages/tl/*.json',
'packages/client/utils.ts',
'packages/core/utils.ts'
],
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
env: { browser: true, es6: true, node: true },
extends: ['plugin:@typescript-eslint/strict', 'plugin:import/typescript'],
globals: { Atomics: 'readonly', SharedArrayBuffer: 'readonly' },
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
rules: {
// https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin#supported-rules
'@typescript-eslint/member-delimiter-style': [
'error',
{
multiline: {
delimiter: 'none',
},
singleline: {
delimiter: 'semi', // because prettier
},
},
],
'@typescript-eslint/consistent-type-assertions': 2,
'@typescript-eslint/no-explicit-any': 2,
'@typescript-eslint/no-unused-vars': [
2,
{
args: 'after-used',
argsIgnorePattern: '^_',
ignoreRestSiblings: true,
vars: 'all',
varsIgnorePattern: '^_',
},
],
'@typescript-eslint/no-non-null-assertion': 'off', // todo MTQ-36
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-confusing-void-expression': 'off',
'@typescript-eslint/no-unnecessary-condition': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
'@typescript-eslint/no-invalid-void-type': 'off',
'@typescript-eslint/unbound-method': 'off',
'@typescript-eslint/no-dynamic-delete': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'no-restricted-globals': ['error', 'Buffer', '__dirname', 'require'],
'no-restricted-imports': [
'error',
{
paths: ['buffer', 'crypto', 'fs', 'path', 'stream'],
patterns: ['@mtcute/*/dist**'],
},
],
},
reportUnusedDisableDirectives: false,
settings: {
'import/resolver': {
node: true,
typescript: true,
},
},
},
{
files: ['**/scripts/**', '*.test.ts', 'packages/create-*/**', '**/build.config.cjs', 'packages/node/**'],
rules: {
'no-console': 'off',
'no-restricted-imports': [
'error',
{
patterns: ['@mtcute/*/dist**'],
},
],
},
},
{
files: ['packages/client/src/methods/**/*.ts'],
rules: {
// this + max 3 more
'max-params': ['error', 4],
},
},
{
files: ['e2e/**', 'packages/node/**', 'packages/bun/**'],
rules: {
'no-restricted-globals': 'off',
},
},
{
files: ['packages/bun/**', 'packages/deno/**'],
rules: {
'import/no-unresolved': 'off',
'no-restricted-imports': 'off',
'import/no-relative-packages': 'off', // common-internals is symlinked from node
}
},
{
files: ['e2e/deno/**'],
rules: {
'import/no-unresolved': 'off',
}
},
],
settings: {
'import/resolver': {
node: true,
},
},
}

View file

@ -27,9 +27,9 @@ module.exports = {
'packages/tl/*.json',
'*.d.ts',
'**/dist'
'**/dist',
],
options: { requirePragma: true },
}
},
],
}

View file

@ -3,6 +3,6 @@
"exclude": [
"../**/*.test.ts",
"../**/*.test-utils.ts",
"../**/__fixtures__/**",
"../**/__fixtures__/**"
]
}

View file

@ -1,5 +1,5 @@
const fs = require('fs')
const path = require('path')
const fs = require('node:fs')
const path = require('node:path')
module.exports = {
...require('./config.base.cjs'),
@ -7,8 +7,8 @@ module.exports = {
out: '../../docs',
entryPoints: fs
.readdirSync(path.join(__dirname, '../../packages'))
.filter((it) => !['crypto', 'tl', 'create-bot'].includes(it))
.map((it) => `../../packages/${it}`),
.filter(it => !['crypto', 'tl', 'create-bot'].includes(it))
.map(it => `../../packages/${it}`),
entryPointStrategy: 'packages',
// logLevel: 'Verbose',
}

View file

@ -1,6 +1,6 @@
function load(app) {
app.converter.addUnknownSymbolResolver((declaration) => {
const symbol = declaration.symbolReference?.path?.map((path) => path.path).join('.')
const symbol = declaration.symbolReference?.path?.map(path => path.path).join('.')
if (symbol === 'Long' || symbol === 'tl.Long') {
return {
@ -40,7 +40,7 @@ function load(app) {
}
}
name = (ns ? ns + '.' : '') + name
name = (ns ? `${ns}.` : '') + name
let url

View file

@ -7,14 +7,14 @@ const UMAMI_NOSCRIPT = `https://tei.su/zond.php?website=${WEBSITE_ID}`
const { createElement: h } = JSX
function load(app) {
app.renderer.hooks.on('head.end', (event) => {
app.renderer.hooks.on('head.end', () => {
return h('script', {
async: true,
src: `${UMAMI_URL}/script.js`,
'async': true,
'src': `${UMAMI_URL}/script.js`,
'data-website-id': WEBSITE_ID,
})
})
app.renderer.hooks.on('body.begin', (event) => {
app.renderer.hooks.on('body.begin', () => {
return h(
'noscript',
null,

View file

@ -1,13 +1,15 @@
import { join, resolve } from 'path'
import * as fs from 'fs'
import { join, resolve } from 'node:path'
import * as fs from 'node:fs'
import { globSync } from 'glob'
export function collectTestEntrypoints(params: { skipPackages: string[]; skipTests: string[] }) {
export function collectTestEntrypoints(params: { skipPackages: string[], skipTests: string[] }) {
const files: string[] = []
// eslint-disable-next-line no-restricted-globals
const packages = resolve(__dirname, '../../packages')
const skipTests = params.skipTests.map((path) => resolve(packages, path))
const skipTests = params.skipTests.map(path => resolve(packages, path))
for (const dir of fs.readdirSync(packages)) {
if (dir.startsWith('.') || params.skipPackages.includes(dir)) continue

View file

@ -1,4 +1,4 @@
import { Plugin } from 'vite'
import type { Plugin } from 'vite'
import * as cjsLexer from 'cjs-module-lexer'
import esbuild from 'esbuild'

View file

@ -1,9 +1,9 @@
import { describe, it, beforeEach, afterEach, beforeAll, afterAll, jest, vi as bunVi } from 'bun:test'
import { afterAll, afterEach, beforeAll, beforeEach, vi as bunVi, it, jest } from 'bun:test'
// https://github.com/oven-sh/bun/issues/6044
import console from 'console'
import * as chai from 'chai'
import * as vitestExpect from '@vitest/expect'
import * as vitestSpy from '@vitest/spy'
import { setupChai, stubGlobal, unstubAllGlobals, waitFor } from './polyfills'
setupChai(chai, vitestExpect)
@ -15,7 +15,7 @@ export const vi = {
...jest,
...bunVi,
...vitestSpy,
mocked: (fn) => fn,
mocked: fn => fn,
stubGlobal,
unstubAllGlobals,
waitFor,

View file

@ -1,12 +1,14 @@
// @ts-expect-error no typings
import { describe as _describe, it, beforeEach, afterEach, beforeAll, afterAll } from 'jsr:@std/testing/bdd'
import util from 'node:util'
import { describe as _describe, afterAll, afterEach, beforeAll, beforeEach, it } from 'jsr:@std/testing/bdd'
// @ts-expect-error no typings
import * as vitestSpy from 'npm:@vitest/spy@1.4.0'
// @ts-expect-error no typings
import * as chai from 'npm:chai'
// @ts-expect-error no typings
import * as vitestExpect from 'npm:@vitest/expect@1.4.0'
import util from 'node:util'
import { setupChai, stubGlobal, unstubAllGlobals, waitFor } from './polyfills'
export { it, beforeEach, afterEach, beforeAll, afterAll }
@ -15,6 +17,7 @@ setupChai(chai, vitestExpect)
// https://github.com/denoland/deno_std/issues/2213
Object.defineProperty(it, 'each', {
// eslint-disable-next-line ts/no-unsafe-function-type
value: (items: any[][]) => (name: string, fn: Function) => {
return items.map((item) => {
return it(`${util.format(name, ...item)}`, () => fn(...item))
@ -23,8 +26,8 @@ Object.defineProperty(it, 'each', {
})
// https://github.com/denoland/deno_std/issues/4634
export const describe = (...args) => {
const fn = args.find((arg) => typeof arg === 'function')
export function describe(...args) {
const fn = args.find(arg => typeof arg === 'function')
if (fn.toString().startsWith('async')) {
return
}

View file

@ -6,32 +6,32 @@ export function setupChai(chai: any, vitestExpect: any) {
utils.addMethod(
chai.Assertion.prototype,
'toMatchInlineSnapshot',
function (properties?: object, inlineSnapshot?: string, message?: string) {
function (properties?: object, inlineSnapshot?: string) {
// based on https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/integrations/snapshot/chai.ts
const received = utils.flag(this, 'object')
if (typeof properties === 'string') {
message = inlineSnapshot
inlineSnapshot = properties
properties = undefined
}
if (typeof inlineSnapshot !== 'string') {
throw new Error('toMatchInlineSnapshot requires a string argument')
throw new TypeError('toMatchInlineSnapshot requires a string argument')
}
// todo use @vitest/snapshot
if (typeof received === 'string') {
const snapshot = '"' + received + '"'
const snapshot = `"${received}"`
return chai.expect(snapshot).eql(inlineSnapshot.trim())
} else {
const obj = eval('(' + inlineSnapshot + ')') // idc lol
// eslint-disable-next-line no-eval
const obj = eval(`(${inlineSnapshot})`) // idc lol
return chai.expect(received).eql(obj)
}
},
)
utils.addMethod(chai.Assertion.prototype, 'toMatchSnapshot', function () {
utils.addMethod(chai.Assertion.prototype, 'toMatchSnapshot', () => {
// todo use @vitest/snapshot
})
})
@ -71,6 +71,7 @@ export function unstubAllGlobals() {
stubbedGlobal.clear()
}
// eslint-disable-next-line ts/no-unsafe-function-type
export async function waitFor(fn: Function) {
// less customizations than vi.waitFor but it's good enough for now
const timeout = Date.now() + 5000
@ -81,7 +82,7 @@ export async function waitFor(fn: Function) {
return await fn()
} catch (e) {
lastError = e
await new Promise((resolve) => setTimeout(resolve, 10))
await new Promise(resolve => setTimeout(resolve, 10))
}
}

View file

@ -1,7 +1,8 @@
import { Plugin } from 'vite'
import { fileURLToPath } from 'url'
import { fileURLToPath } from 'node:url'
const setupFile = fileURLToPath(new URL('./test-setup.mts', import.meta.url))
import type { Plugin } from 'vite'
const setupFile = fileURLToPath(new URL('./test-setup.ts', import.meta.url))
export function testSetup(params?: { additionalCode?: string }): Plugin {
const { additionalCode = '' } = params || {}
@ -12,7 +13,7 @@ export function testSetup(params?: { additionalCode?: string }): Plugin {
if (!id.match(/\.test\.m?[tj]s/)) return
return {
code: `import '${setupFile}'\n` + additionalCode + code,
code: `import '${setupFile}'\n${additionalCode}${code}`,
map: null,
}
},

View file

@ -1,4 +1,5 @@
import { expect } from 'vitest'
import { setPlatform } from '../../packages/core/src/platform.js'
import { buffersEqual } from '../../packages/core/src/utils/buffer-utils.js'
@ -15,5 +16,5 @@ expect.addEqualityTesters([
if (a instanceof Uint8Array && b instanceof Uint8Array) {
return buffersEqual(a, b)
}
}
},
])

View file

@ -1,11 +1,11 @@
/// <reference types="vitest" />
import { defineConfig, mergeConfig } from 'vite'
import { mergeConfig } from 'vite'
import { nodePolyfills } from 'vite-plugin-node-polyfills'
import baseConfig from './vite.mjs'
import baseConfig from './vite.js'
import { fixupCjs } from './vite-utils/fixup-cjs'
export default mergeConfig(baseConfig, defineConfig({
export default mergeConfig(baseConfig, {
test: {
browser: {
enabled: true,
@ -14,7 +14,7 @@ export default mergeConfig(baseConfig, defineConfig({
slowHijackESM: false,
},
fakeTimers: {
toFake: ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'Date']
toFake: ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'Date'],
},
retry: process.env.CI ? 3 : 0,
isolate: false,
@ -28,15 +28,20 @@ export default mergeConfig(baseConfig, defineConfig({
plugins: [
fixupCjs(),
nodePolyfills({
include: ['stream', 'path', 'zlib', 'util'],
include: ['stream', 'path', 'zlib', 'util', 'events'],
globals: {
Buffer: false,
global: false,
process: false,
},
})
}),
],
build: {
rollupOptions: {
external: ['bun:sqlite'],
},
},
define: {
'import.meta.env.TEST_ENV': '"browser"'
}
}))
'import.meta.env.TEST_ENV': '"browser"',
},
})

View file

@ -1,7 +1,8 @@
/* eslint-disable no-restricted-globals */
import { resolve } from 'node:path'
import { defineConfig } from 'vite'
import { globSync } from 'glob'
import { resolve, join } from 'path'
import * as fs from 'fs'
import { fixupCjs } from './vite-utils/fixup-cjs'
import { testSetup } from './vite-utils/test-setup-plugin'
import { collectTestEntrypoints } from './vite-utils/collect-test-entrypoints'
@ -11,7 +12,9 @@ const POLYFILLS = resolve(__dirname, 'vite-utils/polyfills-bun.ts')
export default defineConfig({
build: {
lib: {
entry: process.env.ENTRYPOINT ? [process.env.ENTRYPOINT] : collectTestEntrypoints({
entry: process.env.ENTRYPOINT
? [process.env.ENTRYPOINT]
: collectTestEntrypoints({
// https://github.com/oven-sh/bun/issues/4145 prevents us from using vitest directly
// so we have to use bun's native test runner
skipPackages: ['create-bot', 'crypto-node'],
@ -27,23 +30,8 @@ export default defineConfig({
},
rollupOptions: {
external: [
'node:zlib',
/^(node|bun):.*/,
'vitest',
'stream',
'net',
'crypto',
'module',
'fs',
'fs/promises',
'node:fs',
'readline',
'worker_threads',
'events',
'path',
'util',
'os',
'bun:test',
'bun:sqlite',
],
output: {
chunkFileNames: 'chunk-[hash].js',
@ -66,8 +54,8 @@ export default defineConfig({
name: 'polyfills',
transform(code) {
if (!code.includes('vitest')) return code
code = code.replace(/^import {(.+?)} from ['"]vitest['"]/gms, (_, names) => {
const namesParsed = names.split(',').map((name) => name.trim())
code = code.replace(/^import \{(.+?)\} from ['"]vitest['"]/gms, (_, names) => {
const namesParsed = names.split(',').map(name => name.trim())
const namesFromFixup: string[] = []
const newNames = namesParsed
@ -92,13 +80,13 @@ export default defineConfig({
},
{
name: 'fix-wasm-load',
async transform(code, id) {
async transform(code) {
if (code.includes('@mtcute/wasm/mtcute.wasm')) {
return code.replace('@mtcute/wasm/mtcute.wasm', resolve(__dirname, '../packages/wasm/mtcute.wasm'))
}
return code
}
},
},
testSetup(),
],

View file

@ -1,15 +1,20 @@
import { resolve } from 'node:path'
import { defineConfig } from 'vite'
import { resolve, join } from 'path'
import { fixupCjs } from './vite-utils/fixup-cjs'
import { testSetup } from './vite-utils/test-setup-plugin'
import { collectTestEntrypoints } from './vite-utils/collect-test-entrypoints'
// eslint-disable-next-line no-restricted-globals
const POLYFILLS = resolve(__dirname, 'vite-utils/polyfills-deno.ts')
export default defineConfig({
build: {
lib: {
entry: process.env.ENTRYPOINT ? [process.env.ENTRYPOINT] : collectTestEntrypoints({
entry: process.env.ENTRYPOINT
? [process.env.ENTRYPOINT]
: collectTestEntrypoints({
// these packages rely on node apis and are not meant to be run under deno
skipPackages: ['create-bot', 'crypto-node', 'bun', 'node', 'http-proxy', 'socks-proxy', 'mtproxy'],
skipTests: [
@ -48,8 +53,8 @@ export default defineConfig({
name: 'polyfills',
transform(code) {
if (!code.includes('vitest')) return code
code = code.replace(/^import {(.+?)} from ['"]vitest['"]/gms, (_, names) => {
const namesParsed = names.split(',').map((name) => name.trim())
code = code.replace(/^import \{(.+?)\} from ['"]vitest['"]/gms, (_, names) => {
const namesParsed = names.split(',').map(name => name.trim())
return `import {${namesParsed.join(', ')}} from '${POLYFILLS}'`
})

View file

@ -17,13 +17,21 @@ export default defineConfig({
],
exclude: [
'packages/**/index.ts',
]
],
},
setupFiles: [
'./.config/vite-utils/test-setup.mts'
]
'./.config/vite-utils/test-setup.ts',
],
},
define: {
'import.meta.env.TEST_ENV': '"node"'
}
'import.meta.env.TEST_ENV': '"node"',
},
optimizeDeps: {
esbuildOptions: {
// for WHATEVER REASON browserify-zlib uses `global` and it dies in browser lol
define: {
global: 'globalThis',
},
},
},
})

View file

@ -59,14 +59,14 @@ jobs:
GH_RELEASE: 1
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/publish.js ${{ steps.find.outputs.modified }}
- uses: denoland/setup-deno@v1
with:
deno-version: '1.43.1'
- name: Build packages and publish to JSR
env:
JSR: 1
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: node scripts/publish.js ${{ steps.find.outputs.modified }}
# - uses: denoland/setup-deno@v1
# with:
# deno-version: '1.45.5'
# - name: Build packages and publish to JSR
# env:
# JSR: 1
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# run: node scripts/publish.js ${{ steps.find.outputs.modified }}
- name: Commit version bumps
run: |
git commit -am "v${{ steps.bump.outputs.version }}"

View file

@ -52,7 +52,7 @@ jobs:
with:
bun-version: '1.1.4'
- name: 'Build tests'
run: pnpm exec vite build -c .config/vite.bun.mts
run: pnpm exec vite build -c .config/vite.bun.ts
- name: 'Run tests'
run: cd dist/tests && bun test
@ -63,9 +63,9 @@ jobs:
- uses: ./.github/actions/init
- uses: denoland/setup-deno@v1
with:
deno-version: '1.43.1'
deno-version: '1.45.5'
- name: 'Build tests'
run: pnpm exec vite build -c .config/vite.deno.mts
run: pnpm exec vite build -c .config/vite.deno.ts
- name: 'Run tests'
run: cd dist/tests && deno test -A --unstable-ffi
@ -110,22 +110,22 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REGISTRY: 'https://npm.tei.su'
run: cd e2e/node && ./cli.sh ci-publish
e2e-deno:
runs-on: ubuntu-latest
needs: [lint, test-node, test-web, test-bun, test-deno]
permissions:
contents: read
actions: write
steps:
- uses: actions/checkout@v4
- name: Run end-to-end tests under Deno
env:
API_ID: ${{ secrets.TELEGRAM_API_ID }}
API_HASH: ${{ secrets.TELEGRAM_API_HASH }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-fields/retry@v2
# thanks docker networking very cool
with:
max_attempts: 3
timeout_minutes: 30
command: cd e2e/deno && ./cli.sh ci
# e2e-deno:
# runs-on: ubuntu-latest
# needs: [lint, test-node, test-web, test-bun, test-deno]
# permissions:
# contents: read
# actions: write
# steps:
# - uses: actions/checkout@v4
# - name: Run end-to-end tests under Deno
# env:
# API_ID: ${{ secrets.TELEGRAM_API_ID }}
# API_HASH: ${{ secrets.TELEGRAM_API_HASH }}
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# uses: nick-fields/retry@v2
# # thanks docker networking very cool
# with:
# max_attempts: 3
# timeout_minutes: 30
# command: cd e2e/deno && ./cli.sh ci

View file

@ -29,7 +29,7 @@ import { TelegramClient } from '@mtcute/node'
import { Dispatcher, filters } from '@mtcute/dispatcher'
const tg = new TelegramClient({
apiId: parseInt(process.env.API_ID),
apiId: Number.parseInt(process.env.API_ID),
apiHash: process.env.API_HASH,
storage: 'my-account'
})

View file

@ -1,4 +1,4 @@
FROM denoland/deno:bin-1.43.1 as deno-bin
FROM denoland/deno:bin-1.45.5 as deno-bin
FROM node:20
WORKDIR /app

View file

@ -1,4 +1,4 @@
FROM denoland/deno:1.43.1
FROM denoland/deno:1.45.5
WORKDIR /app
RUN apt update && apt install -y socat

View file

@ -1,5 +1,5 @@
/* eslint-disable no-console */
const { execSync } = require('child_process')
import { execSync } from 'node:child_process'
function getDockerContainerIp(name) {
const containerId = execSync(`docker compose ps -q ${name}`).toString().trim()
@ -41,7 +41,6 @@ async function createBucket(name) {
}
}
(async () => {
for (const bucket of ['modules', 'docs', 'publishing', 'npm']) {
const ok = await createBucket(bucket)
console.log(`[i] Created bucket ${bucket}: ${ok}`)
@ -52,7 +51,7 @@ async function createBucket(name) {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Cookie: 'token=token',
'Cookie': 'token=token',
},
body: JSON.stringify({ scope: 'mtcute' }),
})
@ -64,4 +63,3 @@ async function createBucket(name) {
if (resp.status === 200) {
console.log('[i] Created scope mtcute')
}
})()

View file

@ -1,14 +1,14 @@
import { assertEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { tl, User } from '@mtcute/core'
import { User, tl } from '@mtcute/core'
import { BaseTelegramClient, TelegramClient } from '@mtcute/core/client.js'
import { getApiParams } from '../utils.ts'
const getAccountId = () =>
Math.floor(Math.random() * 10000)
function getAccountId() {
return Math.floor(Math.random() * 10000)
.toString()
.padStart(4, '0')
}
async function authorizeInDc(dc: number, base: BaseTelegramClient) {
const tg = new TelegramClient({ client: base })

View file

@ -1,5 +1,4 @@
import { assertEquals, assertNotEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { MtPeerNotFoundError } from '@mtcute/core'
import { TelegramClient } from '@mtcute/core/client.js'

View file

@ -1,7 +1,8 @@
import { assertEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { createHash } from 'node:crypto'
import { FileDownloadLocation, Thumbnail } from '@mtcute/core'
import { assertEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import type { FileDownloadLocation } from '@mtcute/core'
import { Thumbnail } from '@mtcute/core'
import { TelegramClient } from '@mtcute/core/client.js'
import { sleep } from '@mtcute/core/utils.js'

View file

@ -1,6 +1,5 @@
import { assertEquals, assertNotEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { Message } from '@mtcute/core'
import type { Message } from '@mtcute/core'
import { TelegramClient } from '@mtcute/core/client.js'
import { getApiParams, waitFor } from '../utils.ts'
@ -18,7 +17,7 @@ Deno.test('4. handling updates', { sanitizeResources: false }, async (t) => {
await t.step('should send and receive messages', async () => {
const tg1Messages: Message[] = []
tg1.on('new_message', (msg) => tg1Messages.push(msg))
tg1.on('new_message', msg => tg1Messages.push(msg))
const [tg1User] = await tg1.getUsers('self')
let username = tg1User!.username
@ -36,7 +35,7 @@ Deno.test('4. handling updates', { sanitizeResources: false }, async (t) => {
await waitFor(() => {
assertNotEquals(
tg1Messages.find((msg) => msg.text === messageText),
tg1Messages.find(msg => msg.text === messageText),
undefined,
)
})

View file

@ -1,9 +1,10 @@
import { assertEquals, assertGreater, assertInstanceOf } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { TelegramClient } from '@mtcute/core/client.js'
import { Long, Message, TelegramWorkerPort, tl } from '@mtcute/deno'
import type { Message } from '@mtcute/deno'
import { Long, TelegramWorkerPort, tl } from '@mtcute/deno'
import { getApiParams, waitFor } from '../utils.ts'
import type { CustomMethods } from './_worker.ts'
Deno.test('5. worker', { sanitizeResources: false }, async (t) => {
@ -16,7 +17,7 @@ Deno.test('5. worker', { sanitizeResources: false }, async (t) => {
})
const portClient = new TelegramClient({ client: port })
await t.step('should make api calls', async function () {
await t.step('should make api calls', async () => {
const res = await port.call({ _: 'help.getConfig' })
assertEquals(res._, 'config')
@ -25,7 +26,7 @@ Deno.test('5. worker', { sanitizeResources: false }, async (t) => {
assertEquals(Long.isLong((premiumPromo.users[0] as tl.RawUser).accessHash), true)
})
await t.step('should call custom methods', async function () {
await t.step('should call custom methods', async () => {
const hello = await port.invokeCustom('hello')
assertEquals(hello, 'world')
@ -33,7 +34,7 @@ Deno.test('5. worker', { sanitizeResources: false }, async (t) => {
assertEquals(sum, 5)
})
await t.step('should throw errors', async function () {
await t.step('should throw errors', async () => {
try {
await port.call({ _: 'test.useConfigSimple' })
throw new Error('should have thrown')
@ -42,7 +43,7 @@ Deno.test('5. worker', { sanitizeResources: false }, async (t) => {
}
})
await t.step('should receive updates', async function () {
await t.step('should receive updates', async () => {
const client2 = new TelegramClient(getApiParams('dc2.session'))
try {

View file

@ -1,4 +1,4 @@
import { WorkerCustomMethods } from '@mtcute/core/worker.js'
import type { WorkerCustomMethods } from '@mtcute/core/worker.js'
import { BaseTelegramClient, TelegramWorker } from '@mtcute/deno'
import { getApiParams } from '../utils.ts'

View file

@ -1,5 +1,4 @@
import { assertEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { BaseTelegramClient } from '@mtcute/core/client.js'
import { getApiParams } from '../../utils.ts'

View file

@ -1,6 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { assertEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { Long } from '@mtcute/core'
import { setPlatform } from '@mtcute/core/platform.js'
import { TlBinaryReader, TlBinaryWriter, TlSerializationCounter } from '@mtcute/tl-runtime'
@ -19,7 +17,7 @@ Deno.test('encodings', () => {
Deno.test('TlBinaryReader', () => {
const map = {
'85337187': function (r: any) {
85337187(r: any) {
const ret: any = {}
ret._ = 'mt_resPQ'
ret.nonce = r.int128()
@ -30,8 +28,8 @@ Deno.test('TlBinaryReader', () => {
return ret
},
}
const data =
'000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3'
const data
= '000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3'
const buf = p.hexDecode(data)
const r = new TlBinaryReader(map, buf, 8)
@ -45,7 +43,7 @@ Deno.test('TlBinaryReader', () => {
Deno.test('TlBinaryWriter', () => {
const map = {
mt_resPQ: function (w: any, obj: any) {
mt_resPQ(w: any, obj: any) {
w.uint(85337187)
w.bytes(obj.pq)
w.vector(w.long, obj.serverPublicKeyFingerprints)

View file

@ -1,5 +1,4 @@
import { assertEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { Long } from '@mtcute/core'
import { setPlatform } from '@mtcute/core/platform.js'
import { tl } from '@mtcute/tl'
@ -29,7 +28,7 @@ Deno.test('@mtcute/tl', async (t) => {
await t.step('readers map works with TlBinaryReader', () => {
const buf = p.hexDecode('4ca5e8dd7b00000000000000c801000000000000')
// eslint-disable-next-line
const obj = TlBinaryReader.deserializeObject<any>(__tlReaderMap, buf)
assertEquals(obj._, 'inputPeerUser')

View file

@ -1,5 +1,4 @@
import { assertEquals } from 'https://deno.land/std@0.223.0/assert/mod.ts'
import { ige256Decrypt, ige256Encrypt } from '@mtcute/wasm'
import { WebCryptoProvider, WebPlatform } from '@mtcute/web'

View file

@ -1,9 +1,10 @@
import { MaybePromise, MemoryStorage } from '@mtcute/core'
import type { MaybePromise } from '@mtcute/core'
import { MemoryStorage } from '@mtcute/core'
import { setPlatform } from '@mtcute/core/platform.js'
import { LogManager, sleep } from '@mtcute/core/utils.js'
import { DenoCryptoProvider, DenoPlatform, SqliteStorage, TcpTransport } from '@mtcute/deno'
export const getApiParams = (storage?: string) => {
export function getApiParams(storage?: string) {
if (!Deno.env.has('API_ID') || !Deno.env.has('API_HASH')) {
throw new Error('API_ID and API_HASH env variables must be set')
}
@ -13,7 +14,7 @@ export const getApiParams = (storage?: string) => {
setPlatform(new DenoPlatform())
return {
apiId: parseInt(Deno.env.get('API_ID')!),
apiId: Number.parseInt(Deno.env.get('API_ID')!),
apiHash: Deno.env.get('API_HASH')!,
testMode: true,
storage: storage ? new SqliteStorage(`.sessions/${storage}`) : new MemoryStorage(),

View file

@ -24,7 +24,7 @@ describe('@mtcute/tl-runtime', () => {
describe('TlBinaryReader', () => {
const map = {
'85337187': function (r) {
85337187(r) {
const ret = {}
ret._ = 'mt_resPQ'
ret.nonce = r.int128()
@ -35,8 +35,8 @@ describe('@mtcute/tl-runtime', () => {
return ret
},
}
const data =
'000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3'
const data
= '000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3'
it('should work with Buffers', () => {
const buf = Buffer.from(data, 'hex')
@ -64,7 +64,7 @@ describe('@mtcute/tl-runtime', () => {
describe('TlBinaryWriter', () => {
const map = {
mt_resPQ: function (w, obj) {
mt_resPQ(w, obj) {
w.uint(85337187)
w.bytes(obj.pq)
w.vector(w.long, obj.serverPublicKeyFingerprints)

View file

@ -1,5 +1,4 @@
const Long = require('long')
const { TlBinaryReader, TlBinaryWriter } = require('@mtcute/tl-runtime')
const { tl } = require('@mtcute/tl')
const { __tlReaderMap } = require('@mtcute/tl/binary/reader')
@ -35,6 +34,6 @@ describe('@mtcute/tl', () => {
})
it('correctly checks for combinator types', () => {
expect(tl.isAnyInputUser({ _: 'inputUserEmpty' })).to.be.true
expect(tl.isAnyInputUser({ _: 'inputUserEmpty' })).to.eq(true)
})
})

View file

@ -12,7 +12,7 @@ exports.getApiParams = () => {
setPlatform(new NodePlatform())
return {
apiId: parseInt(process.env.API_ID),
apiId: Number.parseInt(process.env.API_ID),
apiHash: process.env.API_HASH,
testMode: true,
storage: new MemoryStorage(),

View file

@ -1,17 +1,17 @@
module.exports = {
cjs: {
getFiles: () => 'tests/**/*.js',
runFile: (file) => `mocha ${file}`,
runFile: file => `mocha ${file}`,
},
esm: {
getFiles: () => 'tests/**/*.js',
runFile: (file) => `mocha ${file}`,
runFile: file => `mocha ${file}`,
},
ts: {
getFiles: () => 'tests/**/*.ts',
beforeAll: () => ['tsc', 'node build-esm.cjs'],
runFile: (file) => {
if (require('path').basename(file)[0] === '_') return null
if (require('node:path').basename(file)[0] === '_') return null
if (file.startsWith('tests/packaging/')) {
// packaging tests - we need to make sure everything imports and works

View file

@ -1,6 +1,5 @@
import { expect } from 'chai'
import { describe, it } from 'mocha'
import { BaseTelegramClient } from '@mtcute/core/client.js'
import { getApiParams } from '../utils.js'

View file

@ -1,7 +1,6 @@
import { expect } from 'chai'
import Long from 'long'
import { describe, it } from 'mocha'
import { NodePlatform } from '@mtcute/node'
import { TlBinaryReader, TlBinaryWriter, TlSerializationCounter } from '@mtcute/tl-runtime'
@ -24,7 +23,7 @@ describe('encodings', () => {
describe('TlBinaryReader', () => {
const map = {
'85337187': function (r) {
85337187(r) {
const ret = {}
ret._ = 'mt_resPQ'
ret.nonce = r.int128()
@ -35,8 +34,8 @@ describe('TlBinaryReader', () => {
return ret
},
}
const data =
'000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3'
const data
= '000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3'
it('should work with Buffers', () => {
const buf = Buffer.from(data, 'hex')
@ -64,7 +63,7 @@ describe('TlBinaryReader', () => {
describe('TlBinaryWriter', () => {
const map = {
mt_resPQ: function (w, obj) {
mt_resPQ(w, obj) {
w.uint(85337187)
w.bytes(obj.pq)
w.vector(w.long, obj.serverPublicKeyFingerprints)

View file

@ -1,7 +1,6 @@
import { expect } from 'chai'
import Long from 'long'
import { describe, it } from 'mocha'
import { NodePlatform } from '@mtcute/node'
import { tl } from '@mtcute/tl'
import { __tlReaderMap } from '@mtcute/tl/binary/reader.js'
@ -35,6 +34,6 @@ describe('@mtcute/tl', () => {
})
it('correctly checks for combinator types', () => {
expect(tl.isAnyInputUser({ _: 'inputUserEmpty' })).to.be.true
expect(tl.isAnyInputUser({ _: 'inputUserEmpty' })).to.eq(true)
})
})

View file

@ -1,6 +1,5 @@
import { expect } from 'chai'
import { before, describe, it } from 'mocha'
import { NodeCryptoProvider } from '@mtcute/node/utils.js'
import { ige256Decrypt, ige256Encrypt } from '@mtcute/wasm'

View file

@ -4,7 +4,7 @@ import { LogManager } from '@mtcute/core/utils.js'
import { NodePlatform, TcpTransport } from '@mtcute/node'
import { NodeCryptoProvider } from '@mtcute/node/utils.js'
export const getApiParams = () => {
export function getApiParams() {
if (!process.env.API_ID || !process.env.API_HASH) {
throw new Error('API_ID and API_HASH env variables must be set')
}
@ -12,7 +12,7 @@ export const getApiParams = () => {
setPlatform(new NodePlatform())
return {
apiId: parseInt(process.env.API_ID),
apiId: Number.parseInt(process.env.API_ID),
apiHash: process.env.API_HASH,
testMode: true,
storage: new MemoryStorage(),

View file

@ -2,9 +2,9 @@
// at this point, we should have all our packages installed in node_modules
// so it should be safe to just cd into them and run `npm publish` on them
const fs = require('fs')
const path = require('path')
const { execSync } = require('child_process')
const fs = require('node:fs')
const path = require('node:path')
const { execSync } = require('node:child_process')
// setup tokenw
const { NPM_TOKEN, REGISTRY, CURRENT_COMMIT } = process.env
@ -19,8 +19,8 @@ const commit = CURRENT_COMMIT.slice(0, 7)
const myPkgJson = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'))
const packages = Object.keys(myPkgJson.dependencies)
.filter((x) => x.startsWith('@mtcute/'))
.map((x) => x.slice('@mtcute/'.length))
.filter(x => x.startsWith('@mtcute/'))
.map(x => x.slice('@mtcute/'.length))
const workDir = path.join(__dirname, 'temp')
fs.mkdirSync(workDir, { recursive: true })
@ -41,7 +41,7 @@ async function main() {
// prepare working directory
for (const pkg of packages) {
const data = await fetch(`http://localhost:4873/@mtcute/${pkg}`).then((x) => x.json())
const data = await fetch(`http://localhost:4873/@mtcute/${pkg}`).then(x => x.json())
const version = data['dist-tags'].latest
const tarball = data.versions[version].dist.tarball

View file

@ -1,7 +1,8 @@
/* eslint-disable no-console */
const cp = require('node:child_process')
const path = require('node:path')
const glob = require('glob')
const cp = require('child_process')
const path = require('path')
const env = {}
require('dotenv').config({ processEnv: env })
@ -44,7 +45,7 @@ function runForFile(dir, file, single = true) {
for (const c of cmds) {
console.log('%s $ %s', dir, c)
cp.execSync('pnpm exec ' + c, options)
cp.execSync(`pnpm exec ${c}`, options)
}
}
@ -69,7 +70,7 @@ function runForDir(dir) {
if (beforeAll) {
for (const c of beforeAll()) {
console.log('%s $ %s', dir, c)
cp.execSync('pnpm exec ' + c, options)
cp.execSync(`pnpm exec ${c}`, options)
}
}
@ -116,7 +117,7 @@ async function main() {
if (file) {
const files = glob.sync(config[dir].getFiles(), { cwd: path.join(__dirname, dir) })
const matchingFile = files.find((f) => f.endsWith(file))
const matchingFile = files.find(f => f.endsWith(file))
if (!matchingFile) {
console.log("Can't find file %s", file)

View file

@ -1,6 +1,7 @@
const fs = require('fs')
const path = require('path')
const cp = require('child_process')
const fs = require('node:fs')
const path = require('node:path')
const cp = require('node:child_process')
const glob = require('glob')
function fixForEsm() {

View file

@ -1,4 +1,4 @@
const cp = require('child_process')
const cp = require('node:child_process')
const { fixForEsm } = require('./build-esm.cjs')

View file

@ -1,15 +1,15 @@
import { expect } from 'chai'
import { describe, it } from 'mocha'
import { tl, User } from '@mtcute/core'
import { User, tl } from '@mtcute/core'
import { BaseTelegramClient, TelegramClient } from '@mtcute/core/client.js'
import { getApiParams } from '../utils.js'
const getAccountId = () =>
Math.floor(Math.random() * 10000)
function getAccountId() {
return Math.floor(Math.random() * 10000)
.toString()
.padStart(4, '0')
}
async function authorizeInDc(dc: number, base: BaseTelegramClient) {
const tg = new TelegramClient({ client: base })
@ -61,7 +61,7 @@ async function authorizeInDc(dc: number, base: BaseTelegramClient) {
await tg.close()
expect(user.isSelf).to.be.true
expect(user.isSelf).to.eq(true)
expect(user.phoneNumber).to.equal(phone)
break
}

View file

@ -1,6 +1,5 @@
import { expect } from 'chai'
import { describe, it } from 'mocha'
import { MtPeerNotFoundError } from '@mtcute/core'
import { TelegramClient } from '@mtcute/core/client.js'
@ -16,14 +15,14 @@ describe('2. calling methods', function () {
it('getUsers(@BotFather)', async () => {
const [user] = await tg.getUsers('botfather')
expect(user?.isBot).to.be.true
expect(user?.isBot).to.eq(true)
expect(user?.displayName).to.equal('BotFather')
})
it('getUsers(@BotFather) - cached', async () => {
const [user] = await tg.getUsers('botfather')
expect(user?.isBot).to.be.true
expect(user?.isBot).to.eq(true)
expect(user?.displayName).to.equal('BotFather')
})
@ -53,7 +52,7 @@ describe('2. calling methods', function () {
const res = await tg.updateProfile({ bio })
const newSelf = await tg.getFullChat('self')
expect(res.isSelf).to.be.true
expect(res.isSelf).to.eq(true)
expect(oldSelf.bio).to.not.equal(newSelf.bio)
expect(newSelf.bio).to.equal(bio)
})

View file

@ -1,9 +1,9 @@
/* eslint-disable no-restricted-imports */
import { expect } from 'chai'
import { createHash } from 'crypto'
import { describe, it } from 'mocha'
import { createHash } from 'node:crypto'
import { FileDownloadLocation, Thumbnail } from '@mtcute/core'
import { expect } from 'chai'
import { describe, it } from 'mocha'
import type { FileDownloadLocation } from '@mtcute/core'
import { Thumbnail } from '@mtcute/core'
import { TelegramClient } from '@mtcute/core/client.js'
import { sleep } from '@mtcute/core/utils.js'

View file

@ -1,12 +1,11 @@
import { expect } from 'chai'
import { describe, it } from 'mocha'
import { Message } from '@mtcute/core'
import type { Message } from '@mtcute/core'
import { TelegramClient } from '@mtcute/core/client.js'
import { getApiParams, waitFor } from '../utils.js'
describe('4. handling updates', async function () {
describe('4. handling updates', function () {
this.timeout(300_000)
const tg1 = new TelegramClient(getApiParams('dc1.session'))
@ -27,7 +26,7 @@ describe('4. handling updates', async function () {
it('should send and receive messages', async () => {
const tg1Messages: Message[] = []
tg1.on('new_message', (msg) => tg1Messages.push(msg))
tg1.on('new_message', msg => tg1Messages.push(msg))
const [tg1User] = await tg1.getUsers('self')
let username = tg1User!.username
@ -44,7 +43,8 @@ describe('4. handling updates', async function () {
expect(sentMsg.chat.id).to.equal(tg1User!.id)
await waitFor(() => {
expect(tg1Messages.find((msg) => msg.text === messageText)).to.exist
// eslint-disable-next-line ts/no-unused-expressions
expect(tg1Messages.find(msg => msg.text === messageText)).to.exist
})
})
})

View file

@ -1,16 +1,17 @@
/* eslint-disable no-restricted-imports */
import path from 'node:path'
import { Worker } from 'node:worker_threads'
import { expect } from 'chai'
import { describe, it } from 'mocha'
import path from 'path'
import { Worker } from 'worker_threads'
import { TelegramClient } from '@mtcute/core/client.js'
import { Long, Message, TelegramWorkerPort, tl } from '@mtcute/node'
import type { Message } from '@mtcute/node'
import { Long, TelegramWorkerPort, tl } from '@mtcute/node'
import { getApiParams, waitFor } from '../utils.js'
import type { CustomMethods } from './_worker.js'
describe('5. worker', async function () {
describe('5. worker', function () {
this.timeout(300_000)
const worker = new Worker(path.resolve(__dirname, '_worker.js'))
@ -20,7 +21,7 @@ describe('5. worker', async function () {
})
const portClient = new TelegramClient({ client: port })
it('should make api calls', async function () {
it('should make api calls', async () => {
const res = await port.call({ _: 'help.getConfig' })
expect(res._).to.equal('config')
@ -29,7 +30,7 @@ describe('5. worker', async function () {
expect(Long.isLong((premiumPromo.users[0] as tl.RawUser).accessHash)).to.equal(true)
})
it('should call custom methods', async function () {
it('should call custom methods', async () => {
const hello = await port.invokeCustom('hello')
expect(hello).to.equal('world')
@ -37,7 +38,7 @@ describe('5. worker', async function () {
expect(sum).to.equal(5)
})
it('should throw errors', async function () {
it('should throw errors', async () => {
try {
await port.call({ _: 'test.useConfigSimple' })
throw new Error('should have thrown')
@ -46,7 +47,7 @@ describe('5. worker', async function () {
}
})
it('should receive updates', async function () {
it('should receive updates', async () => {
const client2 = new TelegramClient(getApiParams('dc2.session'))
try {
@ -86,6 +87,6 @@ describe('5. worker', async function () {
this.afterAll(async () => {
await port.close()
worker.terminate()
void worker.terminate()
})
})

View file

@ -1,4 +1,4 @@
import { WorkerCustomMethods } from '@mtcute/core/worker.js'
import type { WorkerCustomMethods } from '@mtcute/core/worker.js'
import { BaseTelegramClient, TelegramWorker } from '@mtcute/node'
import { getApiParams } from '../utils.js'

View file

@ -1,6 +1,5 @@
import { expect } from 'chai'
import { describe, it } from 'mocha'
import { BaseTelegramClient } from '@mtcute/core/client.js'
// @fix-import

View file

@ -1,7 +1,6 @@
import { expect } from 'chai'
import Long from 'long'
import { describe, it } from 'mocha'
import { setPlatform } from '@mtcute/core/platform.js'
import { NodePlatform } from '@mtcute/node'
import { tl } from '@mtcute/tl'
@ -29,16 +28,14 @@ describe('@mtcute/tl', () => {
it('readers map works with TlBinaryReader', () => {
const buf = p.hexDecode('4ca5e8dd7b00000000000000c801000000000000')
// eslint-disable-next-line
const obj = TlBinaryReader.deserializeObject<any>(__tlReaderMap, buf)
expect(obj._).equal('inputPeerUser')
expect(obj.userId).equal(123)
// eslint-disable-next-line
expect(obj.accessHash.toString()).equal('456')
})
it('correctly checks for combinator types', () => {
expect(tl.isAnyInputUser({ _: 'inputUserEmpty' })).to.be.true
expect(tl.isAnyInputUser({ _: 'inputUserEmpty' })).to.eq(true)
})
})

View file

@ -1,6 +1,5 @@
import { expect } from 'chai'
import { before, describe, it } from 'mocha'
import { NodeCryptoProvider } from '@mtcute/node/utils.js'
import { ige256Decrypt, ige256Encrypt } from '@mtcute/wasm'

View file

@ -1,28 +1,28 @@
{
"compilerOptions": {
"outDir": "./dist",
"incremental": true,
"target": "es2020",
"rootDir": ".",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "es2020",
"allowJs": true,
"sourceMap": true,
"inlineSources": true,
"declaration": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"incremental": true,
"declaration": true,
"inlineSources": true,
"outDir": "./dist",
"sourceMap": true,
"stripInternal": true,
"skipLibCheck": true,
"rootDir": "."
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"skipLibCheck": true
},
"exclude": [
"**/node_modules",
],
"include": [
"./tests",
"./utils.ts"
],
"exclude": [
"**/node_modules"
]
}

View file

@ -1,13 +1,13 @@
// eslint-disable-next-line no-restricted-imports
import { join } from 'path'
import { join } from 'node:path'
import { MaybePromise, MemoryStorage } from '@mtcute/core'
import type { MaybePromise } from '@mtcute/core'
import { MemoryStorage } from '@mtcute/core'
import { setPlatform } from '@mtcute/core/platform.js'
import { LogManager, sleep } from '@mtcute/core/utils.js'
import { NodePlatform, SqliteStorage, TcpTransport } from '@mtcute/node'
import { NodeCryptoProvider } from '@mtcute/node/utils.js'
export const getApiParams = (storage?: string) => {
export function getApiParams(storage?: string) {
if (!process.env.API_ID || !process.env.API_HASH) {
throw new Error('API_ID and API_HASH env variables must be set')
}
@ -15,7 +15,7 @@ export const getApiParams = (storage?: string) => {
setPlatform(new NodePlatform())
return {
apiId: parseInt(process.env.API_ID),
apiId: Number.parseInt(process.env.API_ID),
apiHash: process.env.API_HASH,
testMode: true,
storage: storage ? new SqliteStorage(join(__dirname, storage)) : new MemoryStorage(),

126
eslint.config.js Normal file
View file

@ -0,0 +1,126 @@
import antfu from '@antfu/eslint-config'
export default antfu({
type: 'lib',
typescript: process.env.CI
? {
tsconfigPath: 'tsconfig.json',
ignoresTypeAware: [
'.config/**/*',
'e2e/**',
],
overrides: {
'ts/consistent-type-imports': 'off',
},
}
: true,
yaml: false,
markdown: false,
linterOptions: {
reportUnusedDisableDirectives: Boolean(process.env.CI),
},
rules: {
'style/indent': ['error', 4, {
offsetTernaryExpressions: false,
// the rest is from default config: https://github.com/eslint-stylistic/eslint-stylistic/blob/main/packages/eslint-plugin/configs/customize.ts
ArrayExpression: 1,
CallExpression: { arguments: 1 },
flatTernaryExpressions: false,
FunctionDeclaration: { body: 1, parameters: 1 },
FunctionExpression: { body: 1, parameters: 1 },
ignoreComments: false,
ignoredNodes: [
'TemplateLiteral *',
'TSUnionType',
'TSIntersectionType',
'TSTypeParameterInstantiation',
'FunctionExpression > .params[decorators.length > 0]',
'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
],
ImportDeclaration: 1,
MemberExpression: 1,
ObjectExpression: 1,
outerIIFEBody: 1,
SwitchCase: 1,
VariableDeclarator: 1,
}],
'style/max-len': ['error', {
code: 120,
ignoreComments: true,
ignoreStrings: true,
ignoreTemplateLiterals: true,
}],
'curly': ['error', 'multi-line'],
'style/brace-style': ['error', '1tbs', { allowSingleLine: true }],
'node/prefer-global/process': ['error', 'always'],
'node/prefer-global/buffer': ['error', 'always'],
'no-restricted-globals': ['error', 'Buffer', '__dirname', 'require'],
'style/quotes': ['error', 'single', { avoidEscape: true }],
'test/consistent-test-it': 'off',
'test/prefer-lowercase-title': 'off',
'test/no-identical-title': 'off',
'import/order': ['error', { 'newlines-between': 'always' }],
'antfu/if-newline': 'off',
'import/no-relative-packages': 'error',
'style/max-statements-per-line': ['error', { max: 2 }],
'ts/no-redeclare': 'off',
'eslint-comments/no-unlimited-disable': 'off',
'no-cond-assign': 'off',
'ts/explicit-function-return-type': 'off',
'no-labels': 'off',
'no-restricted-syntax': 'off',
'unicorn/no-new-array': 'off',
'jsdoc/check-param-names': 'off', // todo: will fix in another iteration
'jsdoc/require-returns-description': 'off', // todo: will fix in another iteration
'ts/no-unsafe-member-access': 'off',
'ts/no-dynamic-delete': 'off',
'ts/strict-boolean-expressions': 'off',
'ts/unbound-method': 'off',
'ts/no-invalid-void-type': 'off',
'ts/no-unsafe-enum-comparison': 'off',
'ts/promise-function-async': 'off',
'dot-notation': 'off',
'ts/dot-notation': 'off',
'ts/switch-exhaustiveness-check': 'off',
'ts/restrict-template-expressions': 'off',
'ts/method-signature-style': 'off',
},
}, {
ignores: [
// codegen
'packages/tl/binary/rsa-keys.js',
'packages/tl/binary/reader.js',
'packages/tl/binary/writer.js',
'packages/tl/index.js',
'packages/tl/index.d.ts',
'packages/tl/*.json',
'packages/core/utils.ts',
'e2e/deno/.jsr-data',
'e2e/node/.verdaccio',
],
}, {
files: ['e2e/**', 'packages/node/**', 'packages/bun/**'],
rules: {
'no-restricted-globals': 'off',
},
}, {
files: ['packages/bun/**', 'packages/deno/**'],
rules: {
'no-restricted-imports': 'off',
'import/no-relative-packages': 'off', // common-internals is symlinked from node
},
}, {
files: ['**/scripts/**', '**/*.cjs'],
rules: {
'no-restricted-imports': 'off',
'no-restricted-globals': 'off',
'no-console': 'off',
},
}, {
files: ['packages/create-*/**', 'packages/deno/**'],
rules: {
'node/prefer-global/process': ['error', 'never'],
'node/prefer-global/buffer': ['error', 'never'],
'no-console': 'off',
},
})

View file

@ -1,10 +1,17 @@
{
"name": "mtcute-workspace",
"private": true,
"type": "module",
"version": "0.16.6",
"private": true,
"packageManager": "pnpm@9.0.6",
"description": "Type-safe library for MTProto (Telegram API) for browser and NodeJS",
"license": "MIT",
"author": "alina sireneva <alina@tei.su>",
"license": "MIT",
"homepage": "https://mtcute.dev",
"repository": {
"type": "git",
"url": "https://github.com/mtcute/mtcute"
},
"keywords": [
"telegram",
"telegram-api",
@ -15,73 +22,54 @@
"userbot",
"api"
],
"repository": {
"type": "git",
"url": "https://github.com/mtcute/mtcute"
},
"homepage": "https://mtcute.dev",
"workspaces": [
"packages/*"
],
"scripts": {
"postinstall": "node scripts/validate-deps-versions.mjs && node scripts/remove-jsr-sourcefiles.mjs",
"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": "rimraf packages/**/dist && pnpm -r --workspace-concurrency=4 exec tsc --build",
"postinstall": "node scripts/validate-deps-versions.js && node scripts/remove-jsr-sourcefiles.js",
"test": "pnpm run -r test && vitest --config .config/vite.ts run",
"test:dev": "vitest --config .config/vite.ts watch",
"test:ui": "vitest --config .config/vite.ts --ui",
"test:coverage": "vitest --config .config/vite.ts run --coverage",
"test:ci": "vitest --config .config/vite.ts run --coverage.enabled --coverage.reporter=json",
"test:browser": "vitest --config .config/vite.browser.ts run",
"test:browser:dev": "vitest --config .config/vite.browser.ts watch",
"lint": "eslint",
"lint:ci": "CI=1 NODE_OPTIONS=\\\"--max_old_space_size=8192\\\" eslint",
"lint:tsc": "rimraf packages/**/dist packages/**/*.tsbuildinfo && 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 .",
"format": "prettier --write \"packages/**/*.ts\"",
"publish-all": "node scripts/publish.js all",
"docs": "typedoc --options .config/typedoc/config.cjs",
"build-package": "node scripts/build-package.js"
},
"devDependencies": {
"@antfu/eslint-config": "2.26.0",
"@teidesu/slow-types-compiler": "1.1.0",
"@types/deno": "npm:@teidesu/deno-types@1.45.5",
"@types/node": "20.10.0",
"@types/deno": "npm:@teidesu/deno-types@1.43.1",
"@types/ws": "8.5.4",
"@typescript-eslint/eslint-plugin": "6.4.0",
"@typescript-eslint/parser": "6.4.0",
"@vitest/browser": "1.4.0",
"@vitest/coverage-v8": "1.4.0",
"@vitest/expect": "1.4.0",
"@vitest/spy": "1.4.0",
"@vitest/ui": "1.4.0",
"@vitest/browser": "2.0.5",
"@vitest/coverage-v8": "2.0.5",
"@vitest/expect": "2.0.5",
"@vitest/spy": "2.0.5",
"@vitest/ui": "2.0.5",
"chai": "5.1.0",
"cjs-module-lexer": "1.2.3",
"dotenv-flow": "3.2.0",
"dotenv-flow": "4.1.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",
"eslint-plugin-ascii": "1.0.0",
"eslint-plugin-import": "2.28.0",
"eslint-plugin-simple-import-sort": "10.0.0",
"glob": "10.2.6",
"esbuild": "0.23.0",
"eslint": "9.9.0",
"glob": "11.0.0",
"playwright": "1.42.1",
"prettier": "3.0.3",
"rimraf": "5.0.1",
"rimraf": "6.0.1",
"semver": "7.5.1",
"ts-node": "10.9.1",
"tsconfig-paths": "4.2.0",
"typedoc": "0.25.12",
"typescript": "5.4.3",
"tsx": "4.17.0",
"typedoc": "0.26.5",
"typescript": "5.5.4",
"vite": "5.1.6",
"vite-plugin-node-polyfills": "0.21.0",
"vitest": "1.4.0"
},
"packageManager": "pnpm@9.0.6",
"prettier": "./.config/prettier.cjs",
"eslintConfig": {
"extends": "./.config/eslint.cjs"
"vite-plugin-node-polyfills": "0.22.0",
"vitest": "2.0.5"
}
}

View file

@ -1,26 +1,26 @@
{
"name": "@mtcute/bun",
"private": true,
"type": "module",
"version": "0.16.6",
"private": true,
"description": "Meta-package for Bun",
"author": "alina sireneva <alina@tei.su>",
"license": "MIT",
"type": "module",
"sideEffects": false,
"scripts": {
"docs": "typedoc",
"build": "pnpm run -w build-package bun"
},
"exports": {
".": "./src/index.ts",
"./utils.js": "./src/utils.ts",
"./methods.js": "./src/methods.ts"
},
"scripts": {
"docs": "typedoc",
"build": "pnpm run -w build-package bun"
},
"dependencies": {
"@mtcute/core": "workspace:^",
"@mtcute/wasm": "workspace:^",
"@mtcute/html-parser": "workspace:^",
"@mtcute/markdown-parser": "workspace:^",
"@mtcute/html-parser": "workspace:^"
"@mtcute/wasm": "workspace:^"
},
"devDependencies": {
"@mtcute/test": "workspace:^",

View file

@ -1,11 +1,15 @@
import { createInterface, Interface as RlInterface } from 'readline'
import type { Interface as RlInterface } from 'node:readline'
import { createInterface } from 'node:readline'
import type { Readable } from 'node:stream'
import { FileDownloadLocation, FileDownloadParameters, ITelegramStorageProvider, PartialOnly, User } from '@mtcute/core'
import type { FileDownloadLocation, FileDownloadParameters, ITelegramStorageProvider, PartialOnly, User } from '@mtcute/core'
import type {
BaseTelegramClientOptions as BaseTelegramClientOptionsBase,
TelegramClientOptions,
} from '@mtcute/core/client.js'
import {
BaseTelegramClient as BaseTelegramClientBase,
BaseTelegramClientOptions as BaseTelegramClientOptionsBase,
TelegramClient as TelegramClientBase,
TelegramClientOptions,
} from '@mtcute/core/client.js'
import { setPlatform } from '@mtcute/core/platform.js'
@ -48,9 +52,9 @@ export class BaseTelegramClient extends BaseTelegramClientBase {
transport: () => new TcpTransport(),
...opts,
storage:
typeof opts.storage === 'string' ?
new SqliteStorage(opts.storage) :
opts.storage ?? new SqliteStorage('client.session'),
typeof opts.storage === 'string'
? new SqliteStorage(opts.storage)
: opts.storage ?? new SqliteStorage('client.session'),
})
}
}
@ -91,7 +95,7 @@ export class TelegramClient extends TelegramClientBase {
})
}
return new Promise((res) => this._rl?.question(text, res))
return new Promise(res => this._rl?.question(text, res))
}
close(): Promise<void> {
@ -131,7 +135,7 @@ export class TelegramClient extends TelegramClientBase {
this.start(params)
.then(then)
.catch((err) => this.emitError(err))
.catch(err => this.emitError(err))
}
downloadToFile(
@ -142,7 +146,7 @@ export class TelegramClient extends TelegramClientBase {
return downloadToFile(this, filename, location, params)
}
downloadAsNodeStream(location: FileDownloadLocation, params?: FileDownloadParameters | undefined) {
downloadAsNodeStream(location: FileDownloadLocation, params?: FileDownloadParameters | undefined): Readable {
return downloadAsNodeStream(this, location, params)
}
}

View file

@ -1,6 +1,7 @@
import { unlinkSync } from 'node:fs'
import { FileDownloadLocation, FileDownloadParameters, FileLocation, ITelegramClient } from '@mtcute/core'
import type { FileDownloadLocation, FileDownloadParameters, ITelegramClient } from '@mtcute/core'
import { FileLocation } from '@mtcute/core'
import { downloadAsIterable } from '@mtcute/core/methods.js'
/**

View file

@ -1,6 +1,6 @@
import { Readable } from 'stream'
import { Readable } from 'node:stream'
import { FileDownloadLocation, FileDownloadParameters, ITelegramClient } from '@mtcute/core'
import type { FileDownloadLocation, FileDownloadParameters, ITelegramClient } from '@mtcute/core'
import { downloadAsStream } from '@mtcute/core/methods.js'
/**

View file

@ -1,4 +1,4 @@
import * as os from 'os'
import * as os from 'node:os'
import { NodePlatform } from './common-internals-node/platform.js'
import { normalizeFile } from './utils/normalize-file.js'

View file

@ -1,6 +1,6 @@
import { Database } from 'bun:sqlite'
import { BaseSqliteStorageDriver, ISqliteDatabase } from '@mtcute/core'
import type { ISqliteDatabase } from '@mtcute/core'
import { BaseSqliteStorageDriver } from '@mtcute/core'
export interface SqliteStorageDriverOptions {
/**
@ -19,7 +19,7 @@ export interface SqliteStorageDriverOptions {
export class SqliteStorageDriver extends BaseSqliteStorageDriver {
constructor(
readonly filename = ':memory:',
readonly params?: SqliteStorageDriverOptions,
readonly params?: SqliteStorageDriverOptions | undefined,
) {
super()
}

View file

@ -1,13 +1,14 @@
import { BaseSqliteStorage } from '@mtcute/core'
import { SqliteStorageDriver, SqliteStorageDriverOptions } from './driver.js'
import type { SqliteStorageDriverOptions } from './driver.js'
import { SqliteStorageDriver } from './driver.js'
export { SqliteStorageDriver } from './driver.js'
export class SqliteStorage extends BaseSqliteStorage {
constructor(
readonly filename = ':memory:',
readonly params?: SqliteStorageDriverOptions,
readonly params?: SqliteStorageDriverOptions | undefined,
) {
super(new SqliteStorageDriver(filename, params))
}

View file

@ -1,5 +1,4 @@
import { afterAll, beforeAll, describe } from 'vitest'
import { LogManager } from '@mtcute/core/utils.js'
import {
testAuthKeysRepository,

View file

@ -1,5 +1,4 @@
import { describe } from 'vitest'
import { testCryptoProvider } from '@mtcute/test'
if (import.meta.env.TEST_ENV === 'bun') {

View file

@ -1,7 +1,7 @@
// eslint-disable-next-line no-restricted-imports
import { readFile } from 'fs/promises'
import { readFile } from 'node:fs/promises'
import { BaseCryptoProvider, IAesCtr, ICryptoProvider, IEncryptionScheme } from '@mtcute/core/utils.js'
import type { IAesCtr, ICryptoProvider, IEncryptionScheme } from '@mtcute/core/utils.js'
import { BaseCryptoProvider } from '@mtcute/core/utils.js'
import {
createCtr256,
ctr256,
@ -28,7 +28,6 @@ const ALGO_TO_SUBTLE: Record<string, string> = {
export class BunCryptoProvider extends BaseCryptoProvider implements ICryptoProvider {
async initialize(): Promise<void> {
// eslint-disable-next-line no-restricted-globals
const wasmFile = require.resolve('@mtcute/wasm/mtcute.wasm')
const wasm = await readFile(wasmFile)
initSync(wasm)
@ -49,7 +48,7 @@ export class BunCryptoProvider extends BaseCryptoProvider implements ICryptoProv
const ctx = createCtr256(key, iv)
return {
process: (data) => ctr256(ctx, data),
process: data => ctr256(ctx, data),
close: () => freeCtr256(ctx),
}
}
@ -74,7 +73,7 @@ export class BunCryptoProvider extends BaseCryptoProvider implements ICryptoProv
keyMaterial,
(keylen || 64) * 8,
)
.then((result) => new Uint8Array(result))
.then(result => new Uint8Array(result))
}
sha1(data: Uint8Array): Uint8Array {
@ -113,7 +112,7 @@ export class BunCryptoProvider extends BaseCryptoProvider implements ICryptoProv
return gunzip(data)
}
randomFill(buf: Uint8Array) {
randomFill(buf: Uint8Array): void {
crypto.getRandomValues(buf)
}
}

View file

@ -1,24 +1,28 @@
import { BunFile } from 'bun'
import { ReadStream } from 'fs'
import { stat } from 'fs/promises'
import { basename } from 'path'
import { Readable as NodeReadable } from 'stream'
import { ReadStream } from 'node:fs'
import { stat } from 'node:fs/promises'
import { basename } from 'node:path'
import { Readable as NodeReadable } from 'node:stream'
import { UploadFileLike } from '@mtcute/core'
import type { BunFile } from 'bun'
import type { UploadFileLike } from '@mtcute/core'
// https://github.com/oven-sh/bun/issues/10481
function isBunFile(file: unknown): file is BunFile {
return file instanceof Blob && 'name' in file && file.name.length > 0
}
export async function normalizeFile(file: UploadFileLike) {
export async function normalizeFile(file: UploadFileLike): Promise<{
file: UploadFileLike
fileName?: string | undefined
fileSize?: number
} | null> {
if (typeof file === 'string') {
file = Bun.file(file)
}
if (isBunFile(file)) {
return {
file: file,
file,
fileName: file.name,
fileSize: file.size,
}
@ -27,7 +31,7 @@ export async function normalizeFile(file: UploadFileLike) {
// while these are not Bun-specific, they still may happen
if (file instanceof ReadStream) {
const fileName = basename(file.path.toString())
const fileSize = await stat(file.path.toString()).then((stat) => stat.size)
const fileSize = await stat(file.path.toString()).then(stat => stat.size)
return {
file: NodeReadable.toWeb(file) as unknown as ReadableStream<Uint8Array>,

View file

@ -1,8 +1,9 @@
import { Socket } from 'bun'
import EventEmitter from 'events'
import EventEmitter from 'node:events'
import { IntermediatePacketCodec, IPacketCodec, ITelegramTransport, MtcuteError, TransportState } from '@mtcute/core'
import { BasicDcOption, ICryptoProvider, Logger } from '@mtcute/core/utils.js'
import type { Socket } from 'bun'
import type { IPacketCodec, ITelegramTransport } from '@mtcute/core'
import { IntermediatePacketCodec, MtcuteError, TransportState } from '@mtcute/core'
import type { BasicDcOption, ICryptoProvider, Logger } from '@mtcute/core/utils.js'
/**
* Base for TCP transports.
@ -41,7 +42,7 @@ export abstract class BaseTcpTransport extends EventEmitter implements ITelegram
return this._currentDc
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
// eslint-disable-next-line unused-imports/no-unused-vars
connect(dc: BasicDcOption, testMode: boolean): void {
if (this._state !== TransportState.Idle) {
throw new MtcuteError('Transport is not IDLE')
@ -49,8 +50,8 @@ export abstract class BaseTcpTransport extends EventEmitter implements ITelegram
if (!this.packetCodecInitialized) {
this._packetCodec.setup?.(this._crypto, this.log)
this._packetCodec.on('error', (err) => this.emit('error', err))
this._packetCodec.on('packet', (buf) => this.emit('message', buf))
this._packetCodec.on('error', err => this.emit('error', err))
this._packetCodec.on('packet', buf => this.emit('message', buf))
this.packetCodecInitialized = true
}
@ -148,5 +149,5 @@ export abstract class BaseTcpTransport extends EventEmitter implements ITelegram
}
export class TcpTransport extends BaseTcpTransport {
_packetCodec = new IntermediatePacketCodec()
_packetCodec: IntermediatePacketCodec = new IntermediatePacketCodec()
}

View file

@ -1,18 +1,20 @@
import { parentPort, Worker } from 'worker_threads'
import { Worker, parentPort } from 'node:worker_threads'
import { setPlatform } from '@mtcute/core/platform.js'
import {
import type {
ClientMessageHandler,
RespondFn,
SendFn,
SomeWorker,
TelegramWorker as TelegramWorkerBase,
TelegramWorkerOptions,
TelegramWorkerPort as TelegramWorkerPortBase,
TelegramWorkerPortOptions,
WorkerCustomMethods,
WorkerMessageHandler,
} from '@mtcute/core/worker.js'
import {
TelegramWorker as TelegramWorkerBase,
TelegramWorkerPort as TelegramWorkerPortBase,
} from '@mtcute/core/worker.js'
import { BunPlatform } from './platform.js'
@ -35,8 +37,8 @@ export class TelegramWorker<T extends WorkerCustomMethods> extends TelegramWorke
const respond: RespondFn = port.postMessage.bind(port)
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
parentPort.on('message', (message) => handler(message, respond))
// eslint-disable-next-line ts/no-unsafe-argument
parentPort.on('message', message => handler(message, respond))
return respond
}
@ -50,7 +52,7 @@ export class TelegramWorkerPort<T extends WorkerCustomMethods> extends TelegramW
connectToWorker(worker: SomeWorker, handler: ClientMessageHandler): [SendFn, () => void] {
if (!(worker instanceof Worker)) {
throw new Error('Only worker_threads are supported')
throw new TypeError('Only worker_threads are supported')
}
const send: SendFn = worker.postMessage.bind(worker)

View file

@ -1,20 +1,20 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"types": [
"bun-types",
"vite/client"
]
},
"include": [
"./src",
],
"outDir": "./dist"
},
"references": [
{ "path": "../core" },
{ "path": "../dispatcher" },
{ "path": "../html-parser" },
{ "path": "../markdown-parser" }
],
"include": [
"./src"
]
}

View file

@ -1,16 +1,16 @@
{
"name": "@mtcute/convert",
"private": true,
"type": "module",
"version": "0.16.0",
"private": true,
"description": "Cross-library session conversion utilities",
"author": "alina sireneva <alina@tei.su>",
"license": "MIT",
"type": "module",
"sideEffects": false,
"exports": "./src/index.ts",
"scripts": {
"build": "pnpm run -w build-package convert"
},
"exports": "./src/index.ts",
"dependencies": {
"@mtcute/core": "workspace:^"
},

View file

@ -1,4 +1,4 @@
import { DcOptions } from '@mtcute/core/utils.js'
import type { DcOptions } from '@mtcute/core/utils.js'
// some libraries only store the DCs in the source code, so we need to map them to the correct DCs
// this may not be very accurate, but it's better than nothing
@ -7,7 +7,7 @@ import { DcOptions } from '@mtcute/core/utils.js'
// we'll also only map to ipv4 since that's more portable
export const DC_MAPPING_PROD: Record<number, DcOptions> = {
'1': {
1: {
main: {
id: 1,
ipAddress: '149.154.175.56',
@ -19,7 +19,7 @@ export const DC_MAPPING_PROD: Record<number, DcOptions> = {
port: 443,
},
},
'2': {
2: {
main: {
id: 2,
ipAddress: '149.154.167.41',
@ -31,7 +31,7 @@ export const DC_MAPPING_PROD: Record<number, DcOptions> = {
port: 443,
},
},
'3': {
3: {
main: {
id: 3,
ipAddress: '149.154.175.100',
@ -43,7 +43,7 @@ export const DC_MAPPING_PROD: Record<number, DcOptions> = {
port: 443,
},
},
'4': {
4: {
main: {
id: 4,
ipAddress: '149.154.167.91',
@ -55,7 +55,7 @@ export const DC_MAPPING_PROD: Record<number, DcOptions> = {
port: 443,
},
},
'5': {
5: {
main: {
id: 5,
ipAddress: '91.108.56.179',
@ -70,7 +70,7 @@ export const DC_MAPPING_PROD: Record<number, DcOptions> = {
}
export const DC_MAPPING_TEST: Record<number, DcOptions> = {
'1': {
1: {
main: {
id: 1,
ipAddress: '149.154.175.10',
@ -82,7 +82,7 @@ export const DC_MAPPING_TEST: Record<number, DcOptions> = {
port: 80,
},
},
'2': {
2: {
main: {
id: 2,
ipAddress: '149.154.167.40',
@ -94,7 +94,7 @@ export const DC_MAPPING_TEST: Record<number, DcOptions> = {
port: 443,
},
},
'3': {
3: {
main: {
id: 3,
ipAddress: '149.154.175.117',
@ -109,5 +109,5 @@ export const DC_MAPPING_TEST: Record<number, DcOptions> = {
}
export function isTestDc(ip: string): boolean {
return Object.values(DC_MAPPING_TEST).some((dc) => dc.main.ipAddress === ip || dc.media.ipAddress === ip)
return Object.values(DC_MAPPING_TEST).some(dc => dc.main.ipAddress === ip || dc.media.ipAddress === ip)
}

View file

@ -1,6 +1,5 @@
/* eslint-disable no-console */
const { execSync } = require('child_process')
const fs = require('fs')
const { execSync } = require('node:child_process')
const fs = require('node:fs')
const VERSION = '2.19.20'
const TMP_DIR = '/tmp/gramjs'
@ -36,6 +35,7 @@ async function main() {
const session = stringSession.save()
fs.writeFileSync(
// eslint-disable-next-line node/no-path-concat
`${__dirname}/session.ts`,
`export const GRAMJS_SESSION = '${session}'\n`,
)

View file

@ -1,2 +1,2 @@
export const GRAMJS_SESSION =
'1AgAOMTQ5LjE1NC4xNjcuNDABu60obcEYS8Yb/I7YlCwaLvW84dXCX2oGnBYG+zuMciJhHP99c8ZJvwxJgH8yU1QrqI+Gh0kK0JAuQucIpDfq/jJVLZ1ZRimq5yy1XbeEs65gtZA1+SUwZRXahh+NzGbPmOVUMCnCtRONo9GNvcx/QxSXRrh7T/K0YYN1iHsK1vJDk8/SUnthvTNmRycC+JLn4fMtctqP4Le2WPOH/deYbUF0BlwmR77M7fv1GZSInqCgWReaIl5nvn0IqA4mOCTkdOgcvwOiB2UmXwiyInxRuLdBIyLbBUDCuTlmL1m3FJqbuEpZEUJnoJf2YDFZ1wR6TfL0MUS1VwnjOcy3WIIFwwg='
export const GRAMJS_SESSION
= '1AgAOMTQ5LjE1NC4xNjcuNDABu60obcEYS8Yb/I7YlCwaLvW84dXCX2oGnBYG+zuMciJhHP99c8ZJvwxJgH8yU1QrqI+Gh0kK0JAuQucIpDfq/jJVLZ1ZRimq5yy1XbeEs65gtZA1+SUwZRXahh+NzGbPmOVUMCnCtRONo9GNvcx/QxSXRrh7T/K0YYN1iHsK1vJDk8/SUnthvTNmRycC+JLn4fMtctqP4Le2WPOH/deYbUF0BlwmR77M7fv1GZSInqCgWReaIl5nvn0IqA4mOCTkdOgcvwOiB2UmXwiyInxRuLdBIyLbBUDCuTlmL1m3FJqbuEpZEUJnoJf2YDFZ1wR6TfL0MUS1VwnjOcy3WIIFwwg='

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { getPlatform } from '@mtcute/core/platform.js'
import { GRAMJS_SESSION } from './__fixtures__/session.js'
@ -9,14 +8,14 @@ describe('gramjs/convert', () => {
it('should correctly convert from gramjs sessions', () => {
expect(convertFromGramjsSession(GRAMJS_SESSION)).toEqual({
authKey: getPlatform().hexDecode(
'ad286dc1184bc61bfc8ed8942c1a2ef5bce1d5c25f6a069c1606fb3b8c722261' +
'1cff7d73c649bf0c49807f3253542ba88f8687490ad0902e42e708a437eafe32' +
'552d9d594629aae72cb55db784b3ae60b59035f925306515da861f8dcc66cf98' +
'e5543029c2b5138da3d18dbdcc7f43149746b87b4ff2b4618375887b0ad6f243' +
'93cfd2527b61bd3366472702f892e7e1f32d72da8fe0b7b658f387fdd7986d41' +
'74065c2647beccedfbf51994889ea0a059179a225e67be7d08a80e263824e474' +
'e81cbf03a20765265f08b2227c51b8b7412322db0540c2b939662f59b7149a9b' +
'b84a59114267a097f6603159d7047a4df2f43144b55709e339ccb7588205c308',
'ad286dc1184bc61bfc8ed8942c1a2ef5bce1d5c25f6a069c1606fb3b8c722261'
+ '1cff7d73c649bf0c49807f3253542ba88f8687490ad0902e42e708a437eafe32'
+ '552d9d594629aae72cb55db784b3ae60b59035f925306515da861f8dcc66cf98'
+ 'e5543029c2b5138da3d18dbdcc7f43149746b87b4ff2b4618375887b0ad6f243'
+ '93cfd2527b61bd3366472702f892e7e1f32d72da8fe0b7b658f387fdd7986d41'
+ '74065c2647beccedfbf51994889ea0a059179a225e67be7d08a80e263824e474'
+ 'e81cbf03a20765265f08b2227c51b8b7412322db0540c2b939662f59b7149a9b'
+ 'b84a59114267a097f6603159d7047a4df2f43144b55709e339ccb7588205c308',
),
primaryDcs: {
main: {
@ -41,14 +40,14 @@ describe('gramjs/convert', () => {
expect(
convertToGramjsSession({
authKey: getPlatform().hexDecode(
'ad286dc1184bc61bfc8ed8942c1a2ef5bce1d5c25f6a069c1606fb3b8c722261' +
'1cff7d73c649bf0c49807f3253542ba88f8687490ad0902e42e708a437eafe32' +
'552d9d594629aae72cb55db784b3ae60b59035f925306515da861f8dcc66cf98' +
'e5543029c2b5138da3d18dbdcc7f43149746b87b4ff2b4618375887b0ad6f243' +
'93cfd2527b61bd3366472702f892e7e1f32d72da8fe0b7b658f387fdd7986d41' +
'74065c2647beccedfbf51994889ea0a059179a225e67be7d08a80e263824e474' +
'e81cbf03a20765265f08b2227c51b8b7412322db0540c2b939662f59b7149a9b' +
'b84a59114267a097f6603159d7047a4df2f43144b55709e339ccb7588205c308',
'ad286dc1184bc61bfc8ed8942c1a2ef5bce1d5c25f6a069c1606fb3b8c722261'
+ '1cff7d73c649bf0c49807f3253542ba88f8687490ad0902e42e708a437eafe32'
+ '552d9d594629aae72cb55db784b3ae60b59035f925306515da861f8dcc66cf98'
+ 'e5543029c2b5138da3d18dbdcc7f43149746b87b4ff2b4618375887b0ad6f243'
+ '93cfd2527b61bd3366472702f892e7e1f32d72da8fe0b7b658f387fdd7986d41'
+ '74065c2647beccedfbf51994889ea0a059179a225e67be7d08a80e263824e474'
+ 'e81cbf03a20765265f08b2227c51b8b7412322db0540c2b939662f59b7149a9b'
+ 'b84a59114267a097f6603159d7047a4df2f43144b55709e339ccb7588205c308',
),
primaryDcs: {
main: {

View file

@ -1,7 +1,9 @@
import { readStringSession, StringSessionData } from '@mtcute/core/utils.js'
import type { StringSessionData } from '@mtcute/core/utils.js'
import { readStringSession } from '@mtcute/core/utils.js'
import { convertFromTelethonSession } from '../telethon/convert.js'
import { TelethonSession } from '../telethon/types.js'
import type { TelethonSession } from '../telethon/types.js'
import { parseGramjsSession } from './parse.js'
import { serializeGramjsSession } from './serialize.js'

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { getPlatform } from '@mtcute/core/platform.js'
import { GRAMJS_SESSION } from './__fixtures__/session.js'
@ -13,14 +12,14 @@ describe('gramjs/parse', () => {
port: 443,
ipv6: false,
authKey: getPlatform().hexDecode(
'ad286dc1184bc61bfc8ed8942c1a2ef5bce1d5c25f6a069c1606fb3b8c722261' +
'1cff7d73c649bf0c49807f3253542ba88f8687490ad0902e42e708a437eafe32' +
'552d9d594629aae72cb55db784b3ae60b59035f925306515da861f8dcc66cf98' +
'e5543029c2b5138da3d18dbdcc7f43149746b87b4ff2b4618375887b0ad6f243' +
'93cfd2527b61bd3366472702f892e7e1f32d72da8fe0b7b658f387fdd7986d41' +
'74065c2647beccedfbf51994889ea0a059179a225e67be7d08a80e263824e474' +
'e81cbf03a20765265f08b2227c51b8b7412322db0540c2b939662f59b7149a9b' +
'b84a59114267a097f6603159d7047a4df2f43144b55709e339ccb7588205c308',
'ad286dc1184bc61bfc8ed8942c1a2ef5bce1d5c25f6a069c1606fb3b8c722261'
+ '1cff7d73c649bf0c49807f3253542ba88f8687490ad0902e42e708a437eafe32'
+ '552d9d594629aae72cb55db784b3ae60b59035f925306515da861f8dcc66cf98'
+ 'e5543029c2b5138da3d18dbdcc7f43149746b87b4ff2b4618375887b0ad6f243'
+ '93cfd2527b61bd3366472702f892e7e1f32d72da8fe0b7b658f387fdd7986d41'
+ '74065c2647beccedfbf51994889ea0a059179a225e67be7d08a80e263824e474'
+ 'e81cbf03a20765265f08b2227c51b8b7412322db0540c2b939662f59b7149a9b'
+ 'b84a59114267a097f6603159d7047a4df2f43144b55709e339ccb7588205c308',
),
})
})

View file

@ -2,7 +2,7 @@ import { MtArgumentError } from '@mtcute/core'
import { getPlatform } from '@mtcute/core/platform.js'
import { dataViewFromBuffer } from '@mtcute/core/utils.js'
import { TelethonSession } from '../telethon/types.js'
import type { TelethonSession } from '../telethon/types.js'
export function parseGramjsSession(session: string): TelethonSession {
if (session[0] !== '1') {

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { getPlatform } from '@mtcute/core/platform.js'
import { GRAMJS_SESSION } from './__fixtures__/session.js'
@ -14,14 +13,14 @@ describe('gramjs/serialize', () => {
port: 443,
ipv6: false,
authKey: getPlatform().hexDecode(
'ad286dc1184bc61bfc8ed8942c1a2ef5bce1d5c25f6a069c1606fb3b8c722261' +
'1cff7d73c649bf0c49807f3253542ba88f8687490ad0902e42e708a437eafe32' +
'552d9d594629aae72cb55db784b3ae60b59035f925306515da861f8dcc66cf98' +
'e5543029c2b5138da3d18dbdcc7f43149746b87b4ff2b4618375887b0ad6f243' +
'93cfd2527b61bd3366472702f892e7e1f32d72da8fe0b7b658f387fdd7986d41' +
'74065c2647beccedfbf51994889ea0a059179a225e67be7d08a80e263824e474' +
'e81cbf03a20765265f08b2227c51b8b7412322db0540c2b939662f59b7149a9b' +
'b84a59114267a097f6603159d7047a4df2f43144b55709e339ccb7588205c308',
'ad286dc1184bc61bfc8ed8942c1a2ef5bce1d5c25f6a069c1606fb3b8c722261'
+ '1cff7d73c649bf0c49807f3253542ba88f8687490ad0902e42e708a437eafe32'
+ '552d9d594629aae72cb55db784b3ae60b59035f925306515da861f8dcc66cf98'
+ 'e5543029c2b5138da3d18dbdcc7f43149746b87b4ff2b4618375887b0ad6f243'
+ '93cfd2527b61bd3366472702f892e7e1f32d72da8fe0b7b658f387fdd7986d41'
+ '74065c2647beccedfbf51994889ea0a059179a225e67be7d08a80e263824e474'
+ 'e81cbf03a20765265f08b2227c51b8b7412322db0540c2b939662f59b7149a9b'
+ 'b84a59114267a097f6603159d7047a4df2f43144b55709e339ccb7588205c308',
),
}),
).toEqual(GRAMJS_SESSION)

View file

@ -2,7 +2,7 @@ import { MtArgumentError } from '@mtcute/core'
import { getPlatform } from '@mtcute/core/platform.js'
import { dataViewFromBuffer } from '@mtcute/core/utils.js'
import { TelethonSession } from '../telethon/types.js'
import type { TelethonSession } from '../telethon/types.js'
export function serializeGramjsSession(session: TelethonSession) {
if (session.authKey.length !== 256) {
@ -24,5 +24,5 @@ export function serializeGramjsSession(session: TelethonSession) {
pos += 2
u8.set(session.authKey, pos)
return '1' + getPlatform().base64Encode(u8)
return `1${getPlatform().base64Encode(u8)}`
}

View file

@ -1,4 +1,4 @@
/* eslint-disable import/no-unresolved, no-undef, no-console */
/* eslint-disable no-undef, no-console */
import { Client, StorageMemory } from 'https://deno.land/x/mtkruto@0.1.157/mod.ts'

View file

@ -1,2 +1,2 @@
export const MTKRUTO_SESSION =
'BjItdGVzdAAB_gABAQABWEIKa07Ch-9zoA024mDOpsv20TW4YwuoRRROqSi41YQCbD3c4nKnz7BcFIu1mfn6f6Xm3OTVqoT0zib4p_AuZD9H-t8j5AagecRg-oSpQlmjoiUazKQSxnxWotGWf1mPNntAeOvDNa5t1NjXUxmqdB3e2AjYLF_E2jDESVgUuDBQUMBHIDc_xFBAlz6kVxCZ6iINJHbnyJ2F19tbEPFJvSM999RKaFj5lUUVs0qKNXEUmsFYUuIdPBzjWilY8Uvf9nYU_xXd9CUAAXS5_i4aaWlHoTIf3zn8ZEINhDIU1DMauh5vhSWt7F0fkxODjtou-7PdIunuDtqyQm4steuNJc8'
export const MTKRUTO_SESSION
= 'BjItdGVzdAAB_gABAQABWEIKa07Ch-9zoA024mDOpsv20TW4YwuoRRROqSi41YQCbD3c4nKnz7BcFIu1mfn6f6Xm3OTVqoT0zib4p_AuZD9H-t8j5AagecRg-oSpQlmjoiUazKQSxnxWotGWf1mPNntAeOvDNa5t1NjXUxmqdB3e2AjYLF_E2jDESVgUuDBQUMBHIDc_xFBAlz6kVxCZ6iINJHbnyJ2F19tbEPFJvSM999RKaFj5lUUVs0qKNXEUmsFYUuIdPBzjWilY8Uvf9nYU_xXd9CUAAXS5_i4aaWlHoTIf3zn8ZEINhDIU1DMauh5vhSWt7F0fkxODjtou-7PdIunuDtqyQm4steuNJc8'

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { u8HexDecode } from '@mtcute/test'
import { MTKRUTO_SESSION } from './__fixtures__/session.js'
@ -9,14 +8,14 @@ describe('mtkruto/convert', () => {
it('should correctly convert from mtkruto sessions', () => {
expect(convertFromMtkrutoSession(MTKRUTO_SESSION)).toEqual({
authKey: u8HexDecode(
'58420a6b4ec287ef73a00d36e260cea6cbf6d135b8630ba845144ea928b8d584' +
'026c3ddce272a7cfb05c148bb599f9fa7fa5e6dce4d5aa84f4ce26f8a7f02e64' +
'3f47fadf23e406a079c460fa84a94259a3a2251acca412c67c56a2d1967f598f' +
'367b4078ebc335ae6dd4d8d75319aa741dded808d82c5fc4da30c4495814b830' +
'5050c04720373fc45040973ea4571099ea220d2476e7c89d85d7db5b10f149bd' +
'233df7d44a6858f9954515b34a8a3571149ac15852e21d3c1ce35a2958f14bdf' +
'f67614ff15ddf4250074b9fe2e1a696947a1321fdf39fc64420d843214d4331a' +
'ba1e6f8525adec5d1f9313838eda2efbb3dd22e9ee0edab2426e2cb5eb8d25cf',
'58420a6b4ec287ef73a00d36e260cea6cbf6d135b8630ba845144ea928b8d584'
+ '026c3ddce272a7cfb05c148bb599f9fa7fa5e6dce4d5aa84f4ce26f8a7f02e64'
+ '3f47fadf23e406a079c460fa84a94259a3a2251acca412c67c56a2d1967f598f'
+ '367b4078ebc335ae6dd4d8d75319aa741dded808d82c5fc4da30c4495814b830'
+ '5050c04720373fc45040973ea4571099ea220d2476e7c89d85d7db5b10f149bd'
+ '233df7d44a6858f9954515b34a8a3571149ac15852e21d3c1ce35a2958f14bdf'
+ 'f67614ff15ddf4250074b9fe2e1a696947a1321fdf39fc64420d843214d4331a'
+ 'ba1e6f8525adec5d1f9313838eda2efbb3dd22e9ee0edab2426e2cb5eb8d25cf',
),
primaryDcs: {
main: {
@ -39,14 +38,14 @@ describe('mtkruto/convert', () => {
expect(
convertToMtkrutoSession({
authKey: u8HexDecode(
'58420a6b4ec287ef73a00d36e260cea6cbf6d135b8630ba845144ea928b8d584' +
'026c3ddce272a7cfb05c148bb599f9fa7fa5e6dce4d5aa84f4ce26f8a7f02e64' +
'3f47fadf23e406a079c460fa84a94259a3a2251acca412c67c56a2d1967f598f' +
'367b4078ebc335ae6dd4d8d75319aa741dded808d82c5fc4da30c4495814b830' +
'5050c04720373fc45040973ea4571099ea220d2476e7c89d85d7db5b10f149bd' +
'233df7d44a6858f9954515b34a8a3571149ac15852e21d3c1ce35a2958f14bdf' +
'f67614ff15ddf4250074b9fe2e1a696947a1321fdf39fc64420d843214d4331a' +
'ba1e6f8525adec5d1f9313838eda2efbb3dd22e9ee0edab2426e2cb5eb8d25cf',
'58420a6b4ec287ef73a00d36e260cea6cbf6d135b8630ba845144ea928b8d584'
+ '026c3ddce272a7cfb05c148bb599f9fa7fa5e6dce4d5aa84f4ce26f8a7f02e64'
+ '3f47fadf23e406a079c460fa84a94259a3a2251acca412c67c56a2d1967f598f'
+ '367b4078ebc335ae6dd4d8d75319aa741dded808d82c5fc4da30c4495814b830'
+ '5050c04720373fc45040973ea4571099ea220d2476e7c89d85d7db5b10f149bd'
+ '233df7d44a6858f9954515b34a8a3571149ac15852e21d3c1ce35a2958f14bdf'
+ 'f67614ff15ddf4250074b9fe2e1a696947a1321fdf39fc64420d843214d4331a'
+ 'ba1e6f8525adec5d1f9313838eda2efbb3dd22e9ee0edab2426e2cb5eb8d25cf',
),
primaryDcs: {
main: {

View file

@ -1,9 +1,11 @@
import { readStringSession, StringSessionData } from '@mtcute/core/utils.js'
import type { StringSessionData } from '@mtcute/core/utils.js'
import { readStringSession } from '@mtcute/core/utils.js'
import { DC_MAPPING_PROD, DC_MAPPING_TEST } from '../dcs.js'
import { parseMtkrutoSession } from './parse.js'
import { serializeMtkrutoSession } from './serialize.js'
import { MtkrutoSession } from './types.js'
import type { MtkrutoSession } from './types.js'
export function convertFromMtkrutoSession(session: MtkrutoSession | string): StringSessionData {
if (typeof session === 'string') {

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { u8HexDecode } from '@mtcute/test'
import { MTKRUTO_SESSION } from './__fixtures__/session.js'
@ -11,14 +10,14 @@ describe('mtkruto/parse', () => {
dcId: 2,
isTest: true,
authKey: u8HexDecode(
'58420a6b4ec287ef73a00d36e260cea6cbf6d135b8630ba845144ea928b8d584' +
'026c3ddce272a7cfb05c148bb599f9fa7fa5e6dce4d5aa84f4ce26f8a7f02e64' +
'3f47fadf23e406a079c460fa84a94259a3a2251acca412c67c56a2d1967f598f' +
'367b4078ebc335ae6dd4d8d75319aa741dded808d82c5fc4da30c4495814b830' +
'5050c04720373fc45040973ea4571099ea220d2476e7c89d85d7db5b10f149bd' +
'233df7d44a6858f9954515b34a8a3571149ac15852e21d3c1ce35a2958f14bdf' +
'f67614ff15ddf4250074b9fe2e1a696947a1321fdf39fc64420d843214d4331a' +
'ba1e6f8525adec5d1f9313838eda2efbb3dd22e9ee0edab2426e2cb5eb8d25cf',
'58420a6b4ec287ef73a00d36e260cea6cbf6d135b8630ba845144ea928b8d584'
+ '026c3ddce272a7cfb05c148bb599f9fa7fa5e6dce4d5aa84f4ce26f8a7f02e64'
+ '3f47fadf23e406a079c460fa84a94259a3a2251acca412c67c56a2d1967f598f'
+ '367b4078ebc335ae6dd4d8d75319aa741dded808d82c5fc4da30c4495814b830'
+ '5050c04720373fc45040973ea4571099ea220d2476e7c89d85d7db5b10f149bd'
+ '233df7d44a6858f9954515b34a8a3571149ac15852e21d3c1ce35a2958f14bdf'
+ 'f67614ff15ddf4250074b9fe2e1a696947a1321fdf39fc64420d843214d4331a'
+ 'ba1e6f8525adec5d1f9313838eda2efbb3dd22e9ee0edab2426e2cb5eb8d25cf',
),
})
})

View file

@ -3,7 +3,8 @@ import { getPlatform } from '@mtcute/core/platform.js'
import { TlBinaryReader } from '@mtcute/core/utils.js'
import { telegramRleDecode } from '../utils/rle.js'
import { MtkrutoSession } from './types.js'
import type { MtkrutoSession } from './types.js'
export function parseMtkrutoSession(session: string): MtkrutoSession {
const data = telegramRleDecode(getPlatform().base64Decode(session, true))
@ -19,7 +20,7 @@ export function parseMtkrutoSession(session: string): MtkrutoSession {
}
const dcId = Number(dcIdStr)
if (isNaN(dcId)) {
if (Number.isNaN(dcId)) {
throw new MtArgumentError(`Invalid DC ID: ${dcIdStr}`)
}

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { u8HexDecode } from '@mtcute/test'
import { MTKRUTO_SESSION } from './__fixtures__/session.js'
@ -12,14 +11,14 @@ describe('mtkruto/serialize', () => {
dcId: 2,
isTest: true,
authKey: u8HexDecode(
'58420a6b4ec287ef73a00d36e260cea6cbf6d135b8630ba845144ea928b8d584' +
'026c3ddce272a7cfb05c148bb599f9fa7fa5e6dce4d5aa84f4ce26f8a7f02e64' +
'3f47fadf23e406a079c460fa84a94259a3a2251acca412c67c56a2d1967f598f' +
'367b4078ebc335ae6dd4d8d75319aa741dded808d82c5fc4da30c4495814b830' +
'5050c04720373fc45040973ea4571099ea220d2476e7c89d85d7db5b10f149bd' +
'233df7d44a6858f9954515b34a8a3571149ac15852e21d3c1ce35a2958f14bdf' +
'f67614ff15ddf4250074b9fe2e1a696947a1321fdf39fc64420d843214d4331a' +
'ba1e6f8525adec5d1f9313838eda2efbb3dd22e9ee0edab2426e2cb5eb8d25cf',
'58420a6b4ec287ef73a00d36e260cea6cbf6d135b8630ba845144ea928b8d584'
+ '026c3ddce272a7cfb05c148bb599f9fa7fa5e6dce4d5aa84f4ce26f8a7f02e64'
+ '3f47fadf23e406a079c460fa84a94259a3a2251acca412c67c56a2d1967f598f'
+ '367b4078ebc335ae6dd4d8d75319aa741dded808d82c5fc4da30c4495814b830'
+ '5050c04720373fc45040973ea4571099ea220d2476e7c89d85d7db5b10f149bd'
+ '233df7d44a6858f9954515b34a8a3571149ac15852e21d3c1ce35a2958f14bdf'
+ 'f67614ff15ddf4250074b9fe2e1a696947a1321fdf39fc64420d843214d4331a'
+ 'ba1e6f8525adec5d1f9313838eda2efbb3dd22e9ee0edab2426e2cb5eb8d25cf',
),
}),
).toEqual(MTKRUTO_SESSION)

View file

@ -2,7 +2,8 @@ import { getPlatform } from '@mtcute/core/platform.js'
import { TlBinaryWriter } from '@mtcute/core/utils.js'
import { telegramRleEncode } from '../utils/rle.js'
import { MtkrutoSession } from './types.js'
import type { MtkrutoSession } from './types.js'
export function serializeMtkrutoSession(session: MtkrutoSession): string {
const dcIdStr = `${session.dcId}${session.isTest ? '-test' : ''}`

View file

@ -1,2 +1,2 @@
export const PYROGRAM_TEST_SESSION =
'AgAyyvcBTk6KssqikKPxEhxfXJpkoFIgQ_o8VpCk_4g0tcHe0rVCXx34AaDKvaNOlbkJOZ4jA3AI8iDYkI2opuifbM_7S2u9MMdnrjfg5jpfkXfI9-wF8DK_UBGIe1zk_Ibn0IHLRz-lkb-QqZNhh8O8Ggb8cieamatEYwLrkjkZR7JG53q76F0ktUd22L6_bUlp9p_qgXqBg8vZdkIIs9T1OiShw2X6TNO0lYqfJVaczMVQcT9Zt0FiyrAMpovFuT7-96OFKWcQ9gzrs_SHfz9HrQgBwvNSdkVziXTtxLJXsaNz3smGeyh-CEuEgdF3enIECnzftlvvUClLN_ylcPir1bi4_wAAAAEqEi1JAA'
export const PYROGRAM_TEST_SESSION
= 'AgAyyvcBTk6KssqikKPxEhxfXJpkoFIgQ_o8VpCk_4g0tcHe0rVCXx34AaDKvaNOlbkJOZ4jA3AI8iDYkI2opuifbM_7S2u9MMdnrjfg5jpfkXfI9-wF8DK_UBGIe1zk_Ibn0IHLRz-lkb-QqZNhh8O8Ggb8cieamatEYwLrkjkZR7JG53q76F0ktUd22L6_bUlp9p_qgXqBg8vZdkIIs9T1OiShw2X6TNO0lYqfJVaczMVQcT9Zt0FiyrAMpovFuT7-96OFKWcQ9gzrs_SHfz9HrQgBwvNSdkVziXTtxLJXsaNz3smGeyh-CEuEgdF3enIECnzftlvvUClLN_ylcPir1bi4_wAAAAEqEi1JAA'

View file

@ -1,2 +1,2 @@
export const PYROGRAM_TEST_SESSION_OLD =
'AgEWdHMtuA1pC01YkNiHpL1bC0yBC3wzGZCwSRWKlA_a69RhePUN3M51NpnwSXrW3pZV9FS8WjAwUkA23uT_49t8c7Umw3ihhKD6-hTpZ5wXC2MuC0EsF0-Z6WshYhT3gmN6QhEt0jlXo5cW1BJ3MYmXtsTWNf_hJfd3_wF_ZFa58ntVV-3qd08wQRhiL_IxM7L5YazjPw0dg2z92CqRARku_oq5D29V6W6bo8T-SLzF_ujj5ZcAQL25mJtCcXfhhjp9atxcrqnKzEs05xyrehnlJZKoGmnX0mF2P_6wUHqZC9tcTBUV4AmFcbuy7m_4SYLnJ8MbftNs7aWHHNcB1R4fAAAAASoSLUkA'
export const PYROGRAM_TEST_SESSION_OLD
= 'AgEWdHMtuA1pC01YkNiHpL1bC0yBC3wzGZCwSRWKlA_a69RhePUN3M51NpnwSXrW3pZV9FS8WjAwUkA23uT_49t8c7Umw3ihhKD6-hTpZ5wXC2MuC0EsF0-Z6WshYhT3gmN6QhEt0jlXo5cW1BJ3MYmXtsTWNf_hJfd3_wF_ZFa58ntVV-3qd08wQRhiL_IxM7L5YazjPw0dg2z92CqRARku_oq5D29V6W6bo8T-SLzF_ujj5ZcAQL25mJtCcXfhhjp9atxcrqnKzEs05xyrehnlJZKoGmnX0mF2P_6wUHqZC9tcTBUV4AmFcbuy7m_4SYLnJ8MbftNs7aWHHNcB1R4fAAAAASoSLUkA'

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { getPlatform } from '@mtcute/core/platform.js'
import { PYROGRAM_TEST_SESSION_OLD } from './__fixtures__/session_old.js'
@ -9,14 +8,14 @@ describe('pyrogram/convert', () => {
it('should correctly convert from pyrogram sessions', () => {
expect(convertFromPyrogramSession(PYROGRAM_TEST_SESSION_OLD)).toEqual({
authKey: getPlatform().hexDecode(
'1674732db80d690b4d5890d887a4bd5b0b4c810b7c331990b049158a940fdaeb' +
'd46178f50ddcce753699f0497ad6de9655f454bc5a3030524036dee4ffe3db7c' +
'73b526c378a184a0fafa14e9679c170b632e0b412c174f99e96b216214f78263' +
'7a42112dd23957a39716d41277318997b6c4d635ffe125f777ff017f6456b9f2' +
'7b5557edea774f304118622ff23133b2f961ace33f0d1d836cfdd82a9101192e' +
'fe8ab90f6f55e96e9ba3c4fe48bcc5fee8e3e5970040bdb9989b427177e1863a' +
'7d6adc5caea9cacc4b34e71cab7a19e52592a81a69d7d261763ffeb0507a990b' +
'db5c4c1515e0098571bbb2ee6ff84982e727c31b7ed36ceda5871cd701d51e1f',
'1674732db80d690b4d5890d887a4bd5b0b4c810b7c331990b049158a940fdaeb'
+ 'd46178f50ddcce753699f0497ad6de9655f454bc5a3030524036dee4ffe3db7c'
+ '73b526c378a184a0fafa14e9679c170b632e0b412c174f99e96b216214f78263'
+ '7a42112dd23957a39716d41277318997b6c4d635ffe125f777ff017f6456b9f2'
+ '7b5557edea774f304118622ff23133b2f961ace33f0d1d836cfdd82a9101192e'
+ 'fe8ab90f6f55e96e9ba3c4fe48bcc5fee8e3e5970040bdb9989b427177e1863a'
+ '7d6adc5caea9cacc4b34e71cab7a19e52592a81a69d7d261763ffeb0507a990b'
+ 'db5c4c1515e0098571bbb2ee6ff84982e727c31b7ed36ceda5871cd701d51e1f',
),
primaryDcs: {
main: {
@ -45,14 +44,14 @@ describe('pyrogram/convert', () => {
expect(
convertToPyrogramSession({
authKey: getPlatform().hexDecode(
'1674732db80d690b4d5890d887a4bd5b0b4c810b7c331990b049158a940fdaeb' +
'd46178f50ddcce753699f0497ad6de9655f454bc5a3030524036dee4ffe3db7c' +
'73b526c378a184a0fafa14e9679c170b632e0b412c174f99e96b216214f78263' +
'7a42112dd23957a39716d41277318997b6c4d635ffe125f777ff017f6456b9f2' +
'7b5557edea774f304118622ff23133b2f961ace33f0d1d836cfdd82a9101192e' +
'fe8ab90f6f55e96e9ba3c4fe48bcc5fee8e3e5970040bdb9989b427177e1863a' +
'7d6adc5caea9cacc4b34e71cab7a19e52592a81a69d7d261763ffeb0507a990b' +
'db5c4c1515e0098571bbb2ee6ff84982e727c31b7ed36ceda5871cd701d51e1f',
'1674732db80d690b4d5890d887a4bd5b0b4c810b7c331990b049158a940fdaeb'
+ 'd46178f50ddcce753699f0497ad6de9655f454bc5a3030524036dee4ffe3db7c'
+ '73b526c378a184a0fafa14e9679c170b632e0b412c174f99e96b216214f78263'
+ '7a42112dd23957a39716d41277318997b6c4d635ffe125f777ff017f6456b9f2'
+ '7b5557edea774f304118622ff23133b2f961ace33f0d1d836cfdd82a9101192e'
+ 'fe8ab90f6f55e96e9ba3c4fe48bcc5fee8e3e5970040bdb9989b427177e1863a'
+ '7d6adc5caea9cacc4b34e71cab7a19e52592a81a69d7d261763ffeb0507a990b'
+ 'db5c4c1515e0098571bbb2ee6ff84982e727c31b7ed36ceda5871cd701d51e1f',
),
primaryDcs: {
main: {

View file

@ -1,9 +1,11 @@
import { readStringSession, StringSessionData } from '@mtcute/core/utils.js'
import type { StringSessionData } from '@mtcute/core/utils.js'
import { readStringSession } from '@mtcute/core/utils.js'
import { DC_MAPPING_PROD, DC_MAPPING_TEST } from '../dcs.js'
import { parsePyrogramSession } from './parse.js'
import { serializePyrogramSession } from './serialize.js'
import { PyrogramSession } from './types.js'
import type { PyrogramSession } from './types.js'
export function convertFromPyrogramSession(session: PyrogramSession | string): StringSessionData {
if (typeof session === 'string') {

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { getPlatform } from '@mtcute/core/platform.js'
import { PYROGRAM_TEST_SESSION } from './__fixtures__/session.js'
@ -14,14 +13,14 @@ describe('pyrogram/parse', () => {
userId: 5000801609,
dcId: 2,
authKey: getPlatform().hexDecode(
'1674732db80d690b4d5890d887a4bd5b0b4c810b7c331990b049158a940fdaeb' +
'd46178f50ddcce753699f0497ad6de9655f454bc5a3030524036dee4ffe3db7c' +
'73b526c378a184a0fafa14e9679c170b632e0b412c174f99e96b216214f78263' +
'7a42112dd23957a39716d41277318997b6c4d635ffe125f777ff017f6456b9f2' +
'7b5557edea774f304118622ff23133b2f961ace33f0d1d836cfdd82a9101192e' +
'fe8ab90f6f55e96e9ba3c4fe48bcc5fee8e3e5970040bdb9989b427177e1863a' +
'7d6adc5caea9cacc4b34e71cab7a19e52592a81a69d7d261763ffeb0507a990b' +
'db5c4c1515e0098571bbb2ee6ff84982e727c31b7ed36ceda5871cd701d51e1f',
'1674732db80d690b4d5890d887a4bd5b0b4c810b7c331990b049158a940fdaeb'
+ 'd46178f50ddcce753699f0497ad6de9655f454bc5a3030524036dee4ffe3db7c'
+ '73b526c378a184a0fafa14e9679c170b632e0b412c174f99e96b216214f78263'
+ '7a42112dd23957a39716d41277318997b6c4d635ffe125f777ff017f6456b9f2'
+ '7b5557edea774f304118622ff23133b2f961ace33f0d1d836cfdd82a9101192e'
+ 'fe8ab90f6f55e96e9ba3c4fe48bcc5fee8e3e5970040bdb9989b427177e1863a'
+ '7d6adc5caea9cacc4b34e71cab7a19e52592a81a69d7d261763ffeb0507a990b'
+ 'db5c4c1515e0098571bbb2ee6ff84982e727c31b7ed36ceda5871cd701d51e1f',
),
})
})
@ -34,14 +33,14 @@ describe('pyrogram/parse', () => {
userId: 5000801609,
dcId: 2,
authKey: getPlatform().hexDecode(
'4e4e8ab2caa290a3f1121c5f5c9a64a0522043fa3c5690a4ff8834b5c1ded2b5' +
'425f1df801a0cabda34e95b909399e23037008f220d8908da8a6e89f6ccffb4b' +
'6bbd30c767ae37e0e63a5f9177c8f7ec05f032bf5011887b5ce4fc86e7d081cb' +
'473fa591bf90a9936187c3bc1a06fc72279a99ab446302eb92391947b246e77a' +
'bbe85d24b54776d8bebf6d4969f69fea817a8183cbd9764208b3d4f53a24a1c3' +
'65fa4cd3b4958a9f25569cccc550713f59b74162cab00ca68bc5b93efef7a385' +
'296710f60cebb3f4877f3f47ad0801c2f3527645738974edc4b257b1a373dec9' +
'867b287e084b8481d1777a72040a7cdfb65bef50294b37fca570f8abd5b8b8ff',
'4e4e8ab2caa290a3f1121c5f5c9a64a0522043fa3c5690a4ff8834b5c1ded2b5'
+ '425f1df801a0cabda34e95b909399e23037008f220d8908da8a6e89f6ccffb4b'
+ '6bbd30c767ae37e0e63a5f9177c8f7ec05f032bf5011887b5ce4fc86e7d081cb'
+ '473fa591bf90a9936187c3bc1a06fc72279a99ab446302eb92391947b246e77a'
+ 'bbe85d24b54776d8bebf6d4969f69fea817a8183cbd9764208b3d4f53a24a1c3'
+ '65fa4cd3b4958a9f25569cccc550713f59b74162cab00ca68bc5b93efef7a385'
+ '296710f60cebb3f4877f3f47ad0801c2f3527645738974edc4b257b1a373dec9'
+ '867b287e084b8481d1777a72040a7cdfb65bef50294b37fca570f8abd5b8b8ff',
),
})
})

View file

@ -4,7 +4,7 @@ import { Long } from '@mtcute/core'
import { getPlatform } from '@mtcute/core/platform.js'
import { dataViewFromBuffer, longFromBuffer } from '@mtcute/core/utils.js'
import { PyrogramSession } from './types.js'
import type { PyrogramSession } from './types.js'
const SESSION_STRING_SIZE = 351
const SESSION_STRING_SIZE_64 = 356

View file

@ -1,5 +1,4 @@
import { describe, expect, it } from 'vitest'
import { getPlatform } from '@mtcute/core/platform.js'
import { PYROGRAM_TEST_SESSION } from './__fixtures__/session.js'
@ -15,14 +14,14 @@ describe('pyrogram/serialize', () => {
userId: 5000801609,
dcId: 2,
authKey: getPlatform().hexDecode(
'1674732db80d690b4d5890d887a4bd5b0b4c810b7c331990b049158a940fdaeb' +
'd46178f50ddcce753699f0497ad6de9655f454bc5a3030524036dee4ffe3db7c' +
'73b526c378a184a0fafa14e9679c170b632e0b412c174f99e96b216214f78263' +
'7a42112dd23957a39716d41277318997b6c4d635ffe125f777ff017f6456b9f2' +
'7b5557edea774f304118622ff23133b2f961ace33f0d1d836cfdd82a9101192e' +
'fe8ab90f6f55e96e9ba3c4fe48bcc5fee8e3e5970040bdb9989b427177e1863a' +
'7d6adc5caea9cacc4b34e71cab7a19e52592a81a69d7d261763ffeb0507a990b' +
'db5c4c1515e0098571bbb2ee6ff84982e727c31b7ed36ceda5871cd701d51e1f',
'1674732db80d690b4d5890d887a4bd5b0b4c810b7c331990b049158a940fdaeb'
+ 'd46178f50ddcce753699f0497ad6de9655f454bc5a3030524036dee4ffe3db7c'
+ '73b526c378a184a0fafa14e9679c170b632e0b412c174f99e96b216214f78263'
+ '7a42112dd23957a39716d41277318997b6c4d635ffe125f777ff017f6456b9f2'
+ '7b5557edea774f304118622ff23133b2f961ace33f0d1d836cfdd82a9101192e'
+ 'fe8ab90f6f55e96e9ba3c4fe48bcc5fee8e3e5970040bdb9989b427177e1863a'
+ '7d6adc5caea9cacc4b34e71cab7a19e52592a81a69d7d261763ffeb0507a990b'
+ 'db5c4c1515e0098571bbb2ee6ff84982e727c31b7ed36ceda5871cd701d51e1f',
),
}),
).toEqual(PYROGRAM_TEST_SESSION_OLD)
@ -37,14 +36,14 @@ describe('pyrogram/serialize', () => {
userId: 5000801609,
dcId: 2,
authKey: getPlatform().hexDecode(
'4e4e8ab2caa290a3f1121c5f5c9a64a0522043fa3c5690a4ff8834b5c1ded2b5' +
'425f1df801a0cabda34e95b909399e23037008f220d8908da8a6e89f6ccffb4b' +
'6bbd30c767ae37e0e63a5f9177c8f7ec05f032bf5011887b5ce4fc86e7d081cb' +
'473fa591bf90a9936187c3bc1a06fc72279a99ab446302eb92391947b246e77a' +
'bbe85d24b54776d8bebf6d4969f69fea817a8183cbd9764208b3d4f53a24a1c3' +
'65fa4cd3b4958a9f25569cccc550713f59b74162cab00ca68bc5b93efef7a385' +
'296710f60cebb3f4877f3f47ad0801c2f3527645738974edc4b257b1a373dec9' +
'867b287e084b8481d1777a72040a7cdfb65bef50294b37fca570f8abd5b8b8ff',
'4e4e8ab2caa290a3f1121c5f5c9a64a0522043fa3c5690a4ff8834b5c1ded2b5'
+ '425f1df801a0cabda34e95b909399e23037008f220d8908da8a6e89f6ccffb4b'
+ '6bbd30c767ae37e0e63a5f9177c8f7ec05f032bf5011887b5ce4fc86e7d081cb'
+ '473fa591bf90a9936187c3bc1a06fc72279a99ab446302eb92391947b246e77a'
+ 'bbe85d24b54776d8bebf6d4969f69fea817a8183cbd9764208b3d4f53a24a1c3'
+ '65fa4cd3b4958a9f25569cccc550713f59b74162cab00ca68bc5b93efef7a385'
+ '296710f60cebb3f4877f3f47ad0801c2f3527645738974edc4b257b1a373dec9'
+ '867b287e084b8481d1777a72040a7cdfb65bef50294b37fca570f8abd5b8b8ff',
),
}),
).toEqual(PYROGRAM_TEST_SESSION)

Some files were not shown because too many files have changed in this diff Show more