From f5976a2d744a04100bd714901fd81ac808921fab Mon Sep 17 00:00:00 2001 From: Alina Tumanova Date: Mon, 16 Oct 2023 19:23:53 +0300 Subject: [PATCH] ESM + end-to-end tests (#11) * feat: moved tl-runtime to esm and native ArrayBuffers * feat: migration to esm * fix(core): web-related fixes * test: finally, some good fucking e2e * chore: fixed linters etc * ci: added e2e to ci * build(tl): fixed gen-code on node 20 * fix: codegen Uint8Array, not Buffer never `git reset --hard` kids * build: only do type-aware linting for `packages/*` * build: ignore no-unresolved in ci for e2e * fix: node 16 doesn't have subtle crypto apparently? * fix(tests): use Uint8Array for gods sake please can i just merge this already * ci: don't parallel tasks in ci because machines are utter garbage and it may just randomly break * ci: pass secrets to e2e tests * ci: separate cli command for ci apparently im retarded * fix: run codegen in e2e im actually retarded * ci: more fixes for e2e * ci: debugging stuff * ci: still debugging * ci: hopefully fix ci??? --- .dockerignore | 3 + .eslintrc.ci.js | 18 +- .eslintrc.js | 10 +- .github/workflows/test.yaml | 16 +- .gitignore | 2 + .mocharc.json | 3 + .npmrc | 2 +- e2e/.dockerignore | 7 + e2e/.env.example | 3 + e2e/.gitignore | 4 + e2e/.mocharc.json | 3 + e2e/.verdaccio/config.yaml | 13 + e2e/.verdaccio/htpasswd | 1 + e2e/Dockerfile.build | 19 + e2e/Dockerfile.test | 13 + e2e/README.md | 48 ++ e2e/cjs/package.json | 1 + e2e/cjs/tests/base-client.js | 23 + e2e/cjs/tests/tl-runtime.js | 123 +++++ e2e/cjs/tests/tl-schema.js | 39 ++ e2e/cjs/utils.js | 11 + e2e/cli.sh | 41 ++ e2e/config.js | 23 + e2e/docker-compose.yaml | 31 ++ e2e/docker-entrypoint.sh | 8 + e2e/esm/package.json | 1 + e2e/esm/tests/base-client.js | 24 + e2e/esm/tests/tl-runtime.js | 122 +++++ e2e/esm/tests/tl-schema.js | 35 ++ e2e/esm/utils.js | 11 + e2e/package.json | 31 ++ e2e/pnpm-workspace.yaml | 2 + e2e/runner.js | 123 +++++ e2e/ts/build-esm.cjs | 52 ++ e2e/ts/mocha.esm.json | 3 + e2e/ts/package.json | 1 + e2e/ts/run-esm.cjs | 26 + e2e/ts/tests/base-client.ts | 25 + e2e/ts/tests/tl-runtime.ts | 124 +++++ e2e/ts/tests/tl-schema.ts | 39 ++ e2e/ts/tsconfig.json | 28 + e2e/ts/utils.ts | 13 + package.json | 13 +- packages/client/package.json | 26 +- ...generate-client.js => generate-client.cjs} | 8 +- ...nerate-updates.js => generate-updates.cjs} | 1 + packages/client/src/client.ts | 501 ++++++++---------- packages/client/src/index.ts | 8 +- packages/client/src/methods/README.md | 2 +- packages/client/src/methods/_imports.ts | 2 +- packages/client/src/methods/_init.ts | 8 +- packages/client/src/methods/auth/_state.ts | 10 +- .../client/src/methods/auth/check-password.ts | 6 +- packages/client/src/methods/auth/log-out.ts | 2 +- .../src/methods/auth/recover-password.ts | 4 +- .../client/src/methods/auth/resend-code.ts | 6 +- packages/client/src/methods/auth/run.ts | 4 +- packages/client/src/methods/auth/send-code.ts | 6 +- .../client/src/methods/auth/sign-in-bot.ts | 4 +- packages/client/src/methods/auth/sign-in.ts | 6 +- .../client/src/methods/auth/start-test.ts | 6 +- packages/client/src/methods/auth/start.ts | 16 +- .../src/methods/bots/answer-callback-query.ts | 2 +- .../src/methods/bots/answer-inline-query.ts | 2 +- .../methods/bots/answer-pre-checkout-query.ts | 2 +- .../src/methods/bots/delete-my-commands.ts | 4 +- .../client/src/methods/bots/get-bot-info.ts | 6 +- .../src/methods/bots/get-bot-menu-button.ts | 6 +- .../src/methods/bots/get-callback-answer.ts | 10 +- .../src/methods/bots/get-game-high-scores.ts | 8 +- .../src/methods/bots/get-my-commands.ts | 4 +- .../methods/bots/normalize-command-scope.ts | 6 +- .../client/src/methods/bots/set-bot-info.ts | 6 +- .../src/methods/bots/set-bot-menu-button.ts | 6 +- .../client/src/methods/bots/set-game-score.ts | 10 +- .../src/methods/bots/set-my-commands.ts | 4 +- .../src/methods/chats/add-chat-members.ts | 8 +- .../client/src/methods/chats/archive-chats.ts | 4 +- .../src/methods/chats/ban-chat-member.ts | 8 +- .../src/methods/chats/create-channel.ts | 4 +- .../client/src/methods/chats/create-group.ts | 8 +- .../src/methods/chats/create-supergroup.ts | 4 +- .../src/methods/chats/delete-channel.ts | 6 +- .../src/methods/chats/delete-chat-photo.ts | 6 +- .../client/src/methods/chats/delete-group.ts | 6 +- .../src/methods/chats/delete-history.ts | 8 +- .../src/methods/chats/delete-user-history.ts | 8 +- .../src/methods/chats/edit-admin-rights.ts | 6 +- .../src/methods/chats/get-chat-event-log.ts | 10 +- .../src/methods/chats/get-chat-member.ts | 8 +- .../src/methods/chats/get-chat-members.ts | 10 +- .../src/methods/chats/get-chat-preview.ts | 4 +- packages/client/src/methods/chats/get-chat.ts | 6 +- .../client/src/methods/chats/get-full-chat.ts | 6 +- .../src/methods/chats/get-nearby-chats.ts | 6 +- .../src/methods/chats/iter-chat-event-log.ts | 12 +- .../src/methods/chats/iter-chat-members.ts | 8 +- .../client/src/methods/chats/join-chat.ts | 8 +- .../src/methods/chats/kick-chat-member.ts | 12 +- .../client/src/methods/chats/leave-chat.ts | 8 +- .../src/methods/chats/mark-chat-unread.ts | 4 +- .../src/methods/chats/reorder-usernames.ts | 8 +- .../src/methods/chats/restrict-chat-member.ts | 8 +- .../client/src/methods/chats/save-draft.ts | 4 +- .../chats/set-chat-default-permissions.ts | 6 +- .../src/methods/chats/set-chat-description.ts | 4 +- .../src/methods/chats/set-chat-photo.ts | 8 +- .../src/methods/chats/set-chat-title.ts | 6 +- .../client/src/methods/chats/set-chat-ttl.ts | 4 +- .../src/methods/chats/set-chat-username.ts | 6 +- .../client/src/methods/chats/set-slow-mode.ts | 6 +- .../chats/toggle-content-protection.ts | 4 +- .../methods/chats/toggle-fragment-username.ts | 8 +- .../src/methods/chats/toggle-join-requests.ts | 6 +- .../src/methods/chats/toggle-join-to-send.ts | 6 +- .../src/methods/chats/unarchive-chats.ts | 4 +- .../src/methods/chats/unban-chat-member.ts | 6 +- .../src/methods/contacts/add-contact.ts | 8 +- .../src/methods/contacts/delete-contacts.ts | 8 +- .../src/methods/contacts/get-contacts.ts | 4 +- .../src/methods/dialogs/create-folder.ts | 2 +- .../client/src/methods/dialogs/edit-folder.ts | 2 +- .../client/src/methods/dialogs/find-folder.ts | 2 +- .../client/src/methods/dialogs/get-folders.ts | 2 +- .../src/methods/dialogs/get-peer-dialogs.ts | 6 +- .../src/methods/dialogs/iter-dialogs.ts | 6 +- .../src/methods/files/download-buffer.ts | 14 +- .../client/src/methods/files/download-file.ts | 11 +- .../src/methods/files/download-iterable.ts | 12 +- .../src/methods/files/download-stream.ts | 8 +- .../files/normalize-file-to-document.ts | 6 +- .../src/methods/files/normalize-input-file.ts | 4 +- .../methods/files/normalize-input-media.ts | 26 +- .../client/src/methods/files/upload-file.ts | 24 +- .../client/src/methods/files/upload-media.ts | 10 +- .../src/methods/forums/create-forum-topic.ts | 10 +- .../forums/delete-forum-topic-history.ts | 10 +- .../src/methods/forums/edit-forum-topic.ts | 8 +- .../methods/forums/get-forum-topics-by-id.ts | 6 +- .../src/methods/forums/get-forum-topics.ts | 8 +- .../src/methods/forums/iter-forum-topics.ts | 8 +- .../forums/reorder-pinned-forum-topics.ts | 6 +- .../forums/toggle-forum-topic-closed.ts | 8 +- .../forums/toggle-forum-topic-pinned.ts | 6 +- .../client/src/methods/forums/toggle-forum.ts | 6 +- .../forums/toggle-general-topic-hidden.ts | 8 +- .../invite-links/create-invite-link.ts | 6 +- .../methods/invite-links/edit-invite-link.ts | 6 +- .../invite-links/export-invite-link.ts | 4 +- .../invite-links/get-invite-link-members.ts | 6 +- .../methods/invite-links/get-invite-link.ts | 4 +- .../methods/invite-links/get-invite-links.ts | 8 +- .../invite-links/get-primary-invite-link.ts | 4 +- .../invite-links/hide-all-join-requests.ts | 4 +- .../methods/invite-links/hide-join-request.ts | 6 +- .../invite-links/iter-invite-link-members.ts | 6 +- .../methods/invite-links/iter-invite-links.ts | 6 +- .../invite-links/revoke-invite-link.ts | 4 +- .../client/src/methods/messages/close-poll.ts | 8 +- .../src/methods/messages/delete-messages.ts | 10 +- .../messages/delete-scheduled-messages.ts | 4 +- .../methods/messages/edit-inline-message.ts | 8 +- .../src/methods/messages/edit-message.ts | 10 +- .../src/methods/messages/find-in-update.ts | 6 +- .../src/methods/messages/forward-messages.ts | 10 +- .../messages/get-discussion-message.ts | 6 +- .../src/methods/messages/get-history.ts | 8 +- .../src/methods/messages/get-message-group.ts | 10 +- .../methods/messages/get-message-reactions.ts | 8 +- .../methods/messages/get-messages-unsafe.ts | 4 +- .../src/methods/messages/get-messages.ts | 12 +- .../methods/messages/get-reaction-users.ts | 6 +- .../src/methods/messages/get-reply-to.ts | 6 +- .../messages/get-scheduled-messages.ts | 6 +- .../src/methods/messages/iter-history.ts | 6 +- .../methods/messages/iter-reaction-users.ts | 6 +- .../methods/messages/iter-search-global.ts | 6 +- .../methods/messages/iter-search-messages.ts | 8 +- .../src/methods/messages/parse-entities.ts | 8 +- .../src/methods/messages/pin-message.ts | 6 +- .../src/methods/messages/read-history.ts | 8 +- .../src/methods/messages/read-reactions.ts | 6 +- .../src/methods/messages/search-global.ts | 6 +- .../src/methods/messages/search-messages.ts | 8 +- .../src/methods/messages/send-answer.ts | 10 +- .../src/methods/messages/send-comment.ts | 12 +- .../src/methods/messages/send-common.ts | 14 +- .../src/methods/messages/send-copy-group.ts | 14 +- .../client/src/methods/messages/send-copy.ts | 12 +- .../src/methods/messages/send-media-group.ts | 22 +- .../client/src/methods/messages/send-media.ts | 26 +- .../src/methods/messages/send-reaction.ts | 8 +- .../client/src/methods/messages/send-reply.ts | 10 +- .../src/methods/messages/send-scheduled.ts | 6 +- .../client/src/methods/messages/send-text.ts | 28 +- .../src/methods/messages/send-typing.ts | 4 +- .../client/src/methods/messages/send-vote.ts | 14 +- .../src/methods/messages/translate-message.ts | 4 +- .../methods/messages/unpin-all-messages.ts | 8 +- .../src/methods/messages/unpin-message.ts | 4 +- .../src/methods/misc/init-takeout-session.ts | 2 +- .../methods/misc/normalize-privacy-rules.ts | 6 +- .../client/src/methods/parse-modes/_state.ts | 7 +- .../src/methods/parse-modes/parse-modes.ts | 4 +- .../methods/password/change-cloud-password.ts | 2 +- .../methods/password/enable-cloud-password.ts | 2 +- .../methods/password/remove-cloud-password.ts | 4 +- .../methods/stickers/add-sticker-to-set.ts | 4 +- .../methods/stickers/create-sticker-set.ts | 8 +- .../stickers/delete-sticker-from-set.ts | 2 +- .../src/methods/stickers/get-custom-emojis.ts | 6 +- .../stickers/get-installed-stickers.ts | 4 +- .../src/methods/stickers/get-sticker-set.ts | 2 +- .../methods/stickers/move-sticker-in-set.ts | 2 +- .../methods/stickers/set-chat-sticker-set.ts | 6 +- .../methods/stickers/set-sticker-set-thumb.ts | 4 +- .../client/src/methods/stories/apply-boost.ts | 4 +- .../src/methods/stories/can-apply-boost.ts | 4 +- .../src/methods/stories/can-send-story.ts | 4 +- .../src/methods/stories/delete-stories.ts | 4 +- .../client/src/methods/stories/edit-story.ts | 12 +- .../src/methods/stories/find-in-update.ts | 6 +- .../src/methods/stories/get-all-stories.ts | 4 +- .../src/methods/stories/get-boost-stats.ts | 6 +- .../src/methods/stories/get-boosters.ts | 8 +- .../src/methods/stories/get-peer-stories.ts | 4 +- .../methods/stories/get-profile-stories.ts | 8 +- .../src/methods/stories/get-stories-by-id.ts | 6 +- .../stories/get-stories-interactions.ts | 4 +- .../src/methods/stories/get-story-link.ts | 4 +- .../src/methods/stories/get-story-viewers.ts | 4 +- .../methods/stories/hide-my-stories-views.ts | 4 +- .../stories/increment-stories-views.ts | 4 +- .../src/methods/stories/iter-all-stories.ts | 4 +- .../src/methods/stories/iter-boosters.ts | 8 +- .../methods/stories/iter-profile-stories.ts | 6 +- .../src/methods/stories/iter-story-viewers.ts | 6 +- .../src/methods/stories/read-stories.ts | 4 +- .../src/methods/stories/report-story.ts | 4 +- .../methods/stories/send-story-reaction.ts | 4 +- .../client/src/methods/stories/send-story.ts | 14 +- .../stories/toggle-peer-stories-archived.ts | 4 +- .../methods/stories/toggle-stories-pinned.ts | 4 +- packages/client/src/methods/updates/index.ts | 6 +- .../client/src/methods/updates/manager.ts | 16 +- packages/client/src/methods/updates/parsed.ts | 8 +- packages/client/src/methods/updates/types.ts | 10 +- .../client/src/methods/users/block-user.ts | 4 +- .../src/methods/users/edit-close-friends.ts | 6 +- .../src/methods/users/get-common-chats.ts | 6 +- packages/client/src/methods/users/get-me.ts | 6 +- .../src/methods/users/get-my-username.ts | 2 +- .../src/methods/users/get-profile-photo.ts | 8 +- .../src/methods/users/get-profile-photos.ts | 10 +- .../client/src/methods/users/get-users.ts | 6 +- .../src/methods/users/iter-profile-photos.ts | 8 +- .../src/methods/users/resolve-peer-many.ts | 6 +- .../client/src/methods/users/resolve-peer.ts | 6 +- .../src/methods/users/set-emoji-status.ts | 2 +- .../src/methods/users/set-profile-photo.ts | 4 +- .../client/src/methods/users/set-username.ts | 4 +- .../client/src/methods/users/unblock-user.ts | 4 +- .../src/methods/users/update-profile.ts | 2 +- packages/client/src/types/auth/index.ts | 2 +- packages/client/src/types/auth/sent-code.ts | 2 +- .../client/src/types/bots/callback-query.ts | 14 +- .../client/src/types/bots/command-scope.ts | 2 +- .../client/src/types/bots/game-high-score.ts | 8 +- packages/client/src/types/bots/index.ts | 14 +- .../client/src/types/bots/inline-query.ts | 8 +- packages/client/src/types/bots/input/index.ts | 4 +- .../types/bots/input/input-inline-message.ts | 8 +- .../types/bots/input/input-inline-result.ts | 4 +- .../client/src/types/bots/keyboard-builder.ts | 2 +- packages/client/src/types/bots/keyboards.ts | 9 +- packages/client/src/types/calls/index.ts | 2 +- packages/client/src/types/conversation.ts | 22 +- packages/client/src/types/errors.ts | 2 +- .../client/src/types/files/file-location.ts | 6 +- packages/client/src/types/files/index.ts | 8 +- packages/client/src/types/files/utils.ts | 8 +- .../client/src/types/files/web-document.ts | 4 +- packages/client/src/types/index.ts | 30 +- packages/client/src/types/media/audio.ts | 6 +- packages/client/src/types/media/contact.ts | 2 +- packages/client/src/types/media/dice.ts | 2 +- .../client/src/types/media/document-utils.ts | 10 +- packages/client/src/types/media/document.ts | 8 +- packages/client/src/types/media/game.ts | 8 +- packages/client/src/types/media/index.ts | 32 +- .../client/src/types/media/input-media.ts | 12 +- packages/client/src/types/media/invoice.ts | 10 +- packages/client/src/types/media/location.ts | 4 +- packages/client/src/types/media/photo.ts | 8 +- packages/client/src/types/media/poll.ts | 10 +- packages/client/src/types/media/sticker.ts | 6 +- packages/client/src/types/media/thumbnail.ts | 12 +- packages/client/src/types/media/venue.ts | 8 +- packages/client/src/types/media/video.ts | 6 +- packages/client/src/types/media/voice.ts | 8 +- packages/client/src/types/media/web-page.ts | 10 +- packages/client/src/types/messages/dialog.ts | 14 +- .../src/types/messages/draft-message.ts | 6 +- packages/client/src/types/messages/index.ts | 18 +- .../src/types/messages/input-message-id.ts | 4 +- .../src/types/messages/message-action.ts | 8 +- .../src/types/messages/message-entity.ts | 4 +- .../src/types/messages/message-media.ts | 32 +- .../src/types/messages/message-reactions.ts | 10 +- packages/client/src/types/messages/message.ts | 22 +- packages/client/src/types/misc/index.ts | 6 +- .../src/types/misc/input-privacy-rule.ts | 2 +- packages/client/src/types/misc/sticker-set.ts | 14 +- .../client/src/types/misc/takeout-session.ts | 2 +- .../src/types/peers/chat-event/actions.ts | 20 +- .../src/types/peers/chat-event/filters.ts | 2 +- .../src/types/peers/chat-event/index.ts | 14 +- .../types/peers/chat-invite-link-member.ts | 8 +- .../src/types/peers/chat-invite-link.ts | 10 +- .../client/src/types/peers/chat-location.ts | 6 +- .../client/src/types/peers/chat-member.ts | 12 +- .../src/types/peers/chat-permissions.ts | 2 +- packages/client/src/types/peers/chat-photo.ts | 10 +- .../client/src/types/peers/chat-preview.ts | 8 +- packages/client/src/types/peers/chat.ts | 16 +- .../client/src/types/peers/forum-topic.ts | 14 +- packages/client/src/types/peers/index.ts | 30 +- packages/client/src/types/peers/user.ts | 12 +- .../src/types/reactions/emoji-status.ts | 2 +- packages/client/src/types/reactions/index.ts | 4 +- .../src/types/reactions/peer-reaction.ts | 12 +- .../src/types/reactions/reaction-count.ts | 4 +- .../client/src/types/stories/all-stories.ts | 10 +- .../client/src/types/stories/boost-stats.ts | 2 +- packages/client/src/types/stories/booster.ts | 6 +- packages/client/src/types/stories/index.ts | 18 +- .../src/types/stories/interactive/base.ts | 2 +- .../src/types/stories/interactive/index.ts | 8 +- .../src/types/stories/interactive/input.ts | 4 +- .../src/types/stories/interactive/location.ts | 10 +- .../src/types/stories/interactive/reaction.ts | 6 +- .../src/types/stories/interactive/venue.ts | 10 +- .../client/src/types/stories/peer-stories.ts | 8 +- .../client/src/types/stories/stealth-mode.ts | 2 +- .../src/types/stories/story-interactions.ts | 8 +- .../client/src/types/stories/story-viewer.ts | 8 +- packages/client/src/types/stories/story.ts | 16 +- .../types/updates/bot-chat-join-request.ts | 6 +- .../client/src/types/updates/bot-stopped.ts | 6 +- .../src/types/updates/chat-join-request.ts | 6 +- .../src/types/updates/chat-member-update.ts | 14 +- .../src/types/updates/chosen-inline-result.ts | 10 +- .../types/updates/delete-message-update.ts | 2 +- .../src/types/updates/delete-story-update.ts | 6 +- .../src/types/updates/history-read-update.ts | 2 +- packages/client/src/types/updates/index.ts | 30 +- .../client/src/types/updates/parse-update.ts | 2 +- .../client/src/types/updates/poll-update.ts | 8 +- .../client/src/types/updates/poll-vote.ts | 10 +- .../src/types/updates/pre-checkout-query.ts | 8 +- .../client/src/types/updates/story-update.ts | 8 +- .../src/types/updates/user-status-update.ts | 6 +- .../src/types/updates/user-typing-update.ts | 4 +- packages/client/src/utils/file-utils.ts | 18 +- packages/client/src/utils/index.ts | 20 +- packages/client/src/utils/inline-utils.ts | 12 +- packages/client/src/utils/inspectable.ts | 17 +- packages/client/src/utils/misc-utils.ts | 2 +- packages/client/src/utils/peer-utils.ts | 4 +- packages/client/src/utils/rps-meter.ts | 2 +- packages/client/src/utils/stream-utils.ts | 8 +- packages/client/src/utils/voice-utils.ts | 19 +- packages/client/tests/buffer-utils.spec.ts | 22 +- packages/client/tests/memoize.spec.ts | 2 +- packages/client/tests/tsconfig.json | 9 + packages/client/tsconfig.json | 10 +- packages/client/utils.ts | 2 +- packages/core/package.json | 39 +- packages/core/src/base-client.ts | 18 +- packages/core/src/index.ts | 12 +- packages/core/src/network/auth-key.ts | 63 ++- packages/core/src/network/authorization.ts | 75 ++- packages/core/src/network/index.ts | 8 +- packages/core/src/network/mtproto-session.ts | 24 +- .../src/network/multi-session-connection.ts | 10 +- packages/core/src/network/network-manager.ts | 43 +- .../core/src/network/persistent-connection.ts | 14 +- .../core/src/network/session-connection.ts | 76 +-- .../core/src/network/transports/abstract.ts | 14 +- packages/core/src/network/transports/index.ts | 18 +- .../src/network/transports/intermediate.ts | 43 +- .../core/src/network/transports/obfuscated.ts | 75 +-- .../core/src/network/transports/streamed.ts | 10 +- packages/core/src/network/transports/tcp.ts | 10 +- .../core/src/network/transports/websocket.ts | 20 +- .../core/src/network/transports/wrapped.ts | 4 +- packages/core/src/storage/abstract.ts | 10 +- packages/core/src/storage/index.ts | 10 +- packages/core/src/storage/json-file.ts | 8 +- packages/core/src/storage/json.ts | 15 +- packages/core/src/storage/localstorage.ts | 4 +- packages/core/src/storage/memory.ts | 19 +- packages/core/src/types/index.ts | 6 +- packages/core/src/utils/async-lock.ts | 2 +- packages/core/src/utils/bigint-utils.ts | 12 +- packages/core/src/utils/binary/asn1-parser.ts | 18 +- packages/core/src/utils/buffer-utils.ts | 54 +- packages/core/src/utils/crypto/abstract.ts | 46 +- packages/core/src/utils/crypto/common.ts | 46 +- .../core/src/utils/crypto/factorization.ts | 4 +- .../core/src/utils/crypto/forge-crypto.ts | 95 ---- packages/core/src/utils/crypto/index.ts | 15 +- packages/core/src/utils/crypto/keys.ts | 16 +- .../core/src/utils/crypto/miller-rabin.ts | 2 +- packages/core/src/utils/crypto/mtproto.ts | 52 +- packages/core/src/utils/crypto/node-crypto.ts | 35 +- packages/core/src/utils/crypto/password.ts | 43 +- packages/core/src/utils/crypto/subtle.ts | 98 ++++ packages/core/src/utils/crypto/utils.ts | 6 +- packages/core/src/utils/default-dcs.ts | 2 +- packages/core/src/utils/index.ts | 46 +- packages/core/src/utils/logger.ts | 14 +- packages/core/src/utils/long-utils.ts | 11 +- packages/core/src/utils/lru-map.ts | 2 +- packages/core/src/utils/lru-set.ts | 2 +- packages/core/src/utils/peer-utils.ts | 4 +- packages/core/src/utils/platform/crypto.ts | 2 +- .../core/src/utils/platform/crypto.web.ts | 11 +- .../src/utils/platform/error-reporting.ts | 2 +- .../core/src/utils/platform/logging.web.ts | 21 +- packages/core/src/utils/platform/random.ts | 2 +- .../core/src/utils/platform/random.web.ts | 6 +- packages/core/src/utils/platform/transport.ts | 2 +- .../core/src/utils/platform/transport.web.ts | 4 +- packages/core/src/utils/string-session.ts | 22 +- packages/core/src/utils/tl-json.ts | 2 +- packages/core/src/utils/type-assertions.ts | 2 +- packages/core/src/utils/web-utils.ts | 13 - packages/core/tests/auth-key.spec.ts | 53 ++ packages/core/tests/bigint-utils.spec.ts | 20 +- packages/core/tests/buffer-utils.spec.ts | 83 +-- packages/core/tests/crypto-providers.spec.ts | 129 +++-- packages/core/tests/fuzz/fuzz-packet.spec.ts | 2 +- packages/core/tests/fuzz/fuzz-session.spec.ts | 4 +- .../core/tests/fuzz/fuzz-transport.spec.ts | 2 +- packages/core/tests/fuzz/utils.ts | 30 +- packages/core/tests/keys.spec.ts | 3 +- packages/core/tests/lru-map.spec.ts | 2 +- packages/core/tests/lru-set.spec.ts | 2 +- packages/core/tests/miller-rabin.spec.ts | 2 +- packages/core/tests/mtproto-crypto.spec.ts | 89 ++++ .../core/tests/prime-factorization.spec.ts | 10 +- .../intermediate-codec.spec.ts | 32 +- packages/core/tests/tsconfig.json | 9 + packages/core/tsconfig.json | 12 +- packages/core/utils.ts | 2 +- packages/crypto-node/package.json | 14 +- packages/crypto-node/src/index.ts | 13 +- packages/crypto-node/src/native.cjs | 10 + packages/crypto-node/src/native.d.cts | 4 + packages/crypto-node/src/native.d.ts | 2 - packages/crypto-node/src/native.js | 9 - .../tests/node-native-crypto.spec.ts | 6 +- packages/crypto-node/tests/tsconfig.json | 9 + packages/crypto-node/tsconfig.json | 7 +- packages/dispatcher/package.json | 16 +- .../scripts/{generate.js => generate.cjs} | 3 +- .../dispatcher/src/callback-data-builder.ts | 5 +- .../dispatcher/src/context/callback-query.ts | 2 +- .../src/context/chat-join-request.ts | 2 +- .../src/context/chosen-inline-result.ts | 2 +- packages/dispatcher/src/context/index.ts | 15 +- .../dispatcher/src/context/inline-query.ts | 2 +- packages/dispatcher/src/context/message.ts | 10 +- packages/dispatcher/src/context/parse.ts | 16 +- .../src/context/pre-checkout-query.ts | 2 +- packages/dispatcher/src/dispatcher.ts | 16 +- packages/dispatcher/src/filters/bots.ts | 11 +- packages/dispatcher/src/filters/bundle.ts | 20 +- packages/dispatcher/src/filters/chat.ts | 6 +- packages/dispatcher/src/filters/group.ts | 7 +- packages/dispatcher/src/filters/index.ts | 2 +- packages/dispatcher/src/filters/logic.ts | 4 +- packages/dispatcher/src/filters/message.ts | 4 +- packages/dispatcher/src/filters/state.ts | 4 +- packages/dispatcher/src/filters/text.ts | 4 +- packages/dispatcher/src/filters/types.ts | 4 +- packages/dispatcher/src/filters/updates.ts | 5 +- packages/dispatcher/src/filters/user.ts | 6 +- packages/dispatcher/src/handler.ts | 6 +- packages/dispatcher/src/index.ts | 16 +- packages/dispatcher/src/state/index.ts | 6 +- packages/dispatcher/src/state/key.ts | 3 +- packages/dispatcher/src/state/storage.ts | 2 +- packages/dispatcher/src/state/update-state.ts | 6 +- packages/dispatcher/src/wizard.ts | 8 +- packages/dispatcher/tests/dispatcher.spec.ts | 2 +- packages/dispatcher/tests/tsconfig.json | 9 + packages/dispatcher/tsconfig.json | 7 +- packages/file-id/package.json | 14 +- packages/file-id/src/convert.ts | 6 +- packages/file-id/src/index.ts | 10 +- packages/file-id/src/parse.ts | 37 +- packages/file-id/src/serialize-unique.ts | 31 +- packages/file-id/src/serialize.ts | 13 +- packages/file-id/src/types.ts | 2 +- packages/file-id/src/utils.ts | 10 +- packages/file-id/tests/parse.spec.ts | 11 +- .../file-id/tests/serialize-unique.spec.ts | 2 +- packages/file-id/tests/tsconfig.json | 9 + packages/file-id/tests/utils.spec.ts | 26 +- packages/file-id/tsconfig.json | 9 +- packages/html-parser/package.json | 13 +- .../html-parser/tests/html-parser.spec.ts | 2 +- packages/html-parser/tests/tsconfig.json | 9 + packages/html-parser/tsconfig.json | 7 +- packages/http-proxy/index.ts | 3 +- packages/http-proxy/package.json | 11 +- packages/http-proxy/tsconfig.json | 5 +- packages/i18n/package.json | 16 +- packages/i18n/src/index.ts | 8 +- packages/i18n/src/plurals/english.ts | 2 +- packages/i18n/src/plurals/russian.ts | 2 +- packages/i18n/src/utils.ts | 63 +-- packages/i18n/tests/i18n.spec.ts | 11 +- packages/i18n/tests/tsconfig.json | 9 + packages/i18n/tsconfig.json | 7 +- packages/markdown-parser/package.json | 13 +- .../tests/markdown-parser.spec.ts | 5 +- packages/markdown-parser/tests/tsconfig.json | 9 + packages/markdown-parser/tsconfig.json | 7 +- packages/mtproxy/fake-tls.ts | 16 +- packages/mtproxy/index.ts | 44 +- packages/mtproxy/package.json | 11 +- packages/mtproxy/tsconfig.json | 6 +- packages/node/index.ts | 11 +- packages/node/package.json | 12 +- packages/node/tsconfig.json | 9 +- packages/socks-proxy/index.ts | 44 +- packages/socks-proxy/package.json | 12 +- packages/socks-proxy/tsconfig.json | 19 +- packages/sqlite/index.ts | 35 +- packages/sqlite/package.json | 12 +- packages/sqlite/tsconfig.json | 5 +- packages/tl-runtime/package.json | 24 +- packages/tl-runtime/src/encodings/base64.ts | 39 ++ .../tl-runtime/src/encodings/base64.web.ts | 142 +++++ .../src/{platform => encodings}/gzip.ts | 10 +- .../src/{platform => encodings}/gzip.web.ts | 12 +- packages/tl-runtime/src/encodings/hex.ts | 13 + packages/tl-runtime/src/encodings/hex.web.ts | 78 +++ packages/tl-runtime/src/encodings/index.ts | 4 + packages/tl-runtime/src/encodings/utf8.ts | 21 + packages/tl-runtime/src/encodings/utf8.web.ts | 15 + packages/tl-runtime/src/index.ts | 9 +- packages/tl-runtime/src/reader.ts | 75 +-- packages/tl-runtime/src/writer.ts | 115 ++-- .../tl-runtime/tests/binary-reader.spec.ts | 85 +-- .../tl-runtime/tests/binary-writer.spec.ts | 18 +- .../tl-runtime/tests/encodings/base64.spec.ts | 73 +++ .../tl-runtime/tests/encodings/hex.spec.ts | 41 ++ .../tl-runtime/tests/encodings/utf8.spec.ts | 66 +++ packages/tl-runtime/tests/tsconfig.json | 9 + packages/tl-runtime/tsconfig.json | 6 +- packages/tl-utils/package.json | 8 +- packages/tl-utils/src/calculator.ts | 2 +- packages/tl-utils/src/codegen/errors.ts | 6 +- packages/tl-utils/src/codegen/reader.ts | 6 +- packages/tl-utils/src/codegen/types.ts | 16 +- packages/tl-utils/src/codegen/writer.ts | 8 +- packages/tl-utils/src/ctor-id.ts | 4 +- packages/tl-utils/src/diff.ts | 6 +- packages/tl-utils/src/index.ts | 28 +- packages/tl-utils/src/merge.ts | 4 +- packages/tl-utils/src/parse.ts | 6 +- packages/tl-utils/src/patch.ts | 6 +- packages/tl-utils/src/schema.ts | 6 +- packages/tl-utils/src/stringify.ts | 4 +- packages/tl-utils/src/utils.ts | 2 +- packages/tl-utils/tests/calculator.spec.ts | 4 +- .../tl-utils/tests/codegen/reader.spec.ts | 2 +- packages/tl-utils/tests/codegen/types.spec.ts | 4 +- .../tl-utils/tests/codegen/writer.spec.ts | 2 +- packages/tl-utils/tests/ctor-id.spec.ts | 2 +- packages/tl-utils/tests/diff.spec.ts | 8 +- packages/tl-utils/tests/merge.spec.ts | 2 +- packages/tl-utils/tests/parse.spec.ts | 2 +- packages/tl-utils/tests/schema.spec.ts | 4 +- packages/tl-utils/tests/stringify.spec.ts | 4 +- packages/tl-utils/tests/tsconfig.json | 9 + packages/tl-utils/tsconfig.json | 6 +- packages/tl/binary/reader.d.ts | 4 +- packages/tl/binary/rsa-keys.d.ts | 4 +- packages/tl/binary/rsa-keys.js | 2 +- packages/tl/binary/writer.d.ts | 4 +- packages/tl/package.json | 18 +- packages/tl/scripts/constants.ts | 3 + packages/tl/scripts/documentation.ts | 22 +- packages/tl/scripts/fetch-api.ts | 13 +- packages/tl/scripts/fetch-errors.ts | 2 +- packages/tl/scripts/fetch-mtp.ts | 4 +- packages/tl/scripts/gen-code.ts | 8 +- packages/tl/scripts/gen-rsa-keys.ts | 7 +- packages/tl/scripts/package.json | 1 + .../tl/scripts/process-descriptions-yaml.ts | 2 +- packages/tl/tests/types.ts | 10 +- pnpm-lock.yaml | 78 ++- pnpm-workspace.yaml | 1 + scripts/build-package.js | 265 +++++++++ scripts/gen-deps-graph.mjs | 38 ++ scripts/publish.js | 324 +++-------- scripts/utils.mjs | 2 +- tsconfig.json | 12 +- 613 files changed, 5532 insertions(+), 3261 deletions(-) create mode 100644 .dockerignore create mode 100644 .mocharc.json create mode 100644 e2e/.dockerignore create mode 100644 e2e/.env.example create mode 100644 e2e/.gitignore create mode 100644 e2e/.mocharc.json create mode 100644 e2e/.verdaccio/config.yaml create mode 100644 e2e/.verdaccio/htpasswd create mode 100644 e2e/Dockerfile.build create mode 100644 e2e/Dockerfile.test create mode 100644 e2e/README.md create mode 100644 e2e/cjs/package.json create mode 100644 e2e/cjs/tests/base-client.js create mode 100644 e2e/cjs/tests/tl-runtime.js create mode 100644 e2e/cjs/tests/tl-schema.js create mode 100644 e2e/cjs/utils.js create mode 100755 e2e/cli.sh create mode 100644 e2e/config.js create mode 100644 e2e/docker-compose.yaml create mode 100644 e2e/docker-entrypoint.sh create mode 100644 e2e/esm/package.json create mode 100644 e2e/esm/tests/base-client.js create mode 100644 e2e/esm/tests/tl-runtime.js create mode 100644 e2e/esm/tests/tl-schema.js create mode 100644 e2e/esm/utils.js create mode 100644 e2e/package.json create mode 100644 e2e/pnpm-workspace.yaml create mode 100644 e2e/runner.js create mode 100644 e2e/ts/build-esm.cjs create mode 100644 e2e/ts/mocha.esm.json create mode 100644 e2e/ts/package.json create mode 100644 e2e/ts/run-esm.cjs create mode 100644 e2e/ts/tests/base-client.ts create mode 100644 e2e/ts/tests/tl-runtime.ts create mode 100644 e2e/ts/tests/tl-schema.ts create mode 100644 e2e/ts/tsconfig.json create mode 100644 e2e/ts/utils.ts rename packages/client/scripts/{generate-client.js => generate-client.cjs} (99%) rename packages/client/scripts/{generate-updates.js => generate-updates.cjs} (98%) create mode 100644 packages/client/tests/tsconfig.json delete mode 100644 packages/core/src/utils/crypto/forge-crypto.ts create mode 100644 packages/core/src/utils/crypto/subtle.ts delete mode 100644 packages/core/src/utils/web-utils.ts create mode 100644 packages/core/tests/auth-key.spec.ts create mode 100644 packages/core/tests/mtproto-crypto.spec.ts create mode 100644 packages/core/tests/tsconfig.json create mode 100644 packages/crypto-node/src/native.cjs create mode 100644 packages/crypto-node/src/native.d.cts delete mode 100644 packages/crypto-node/src/native.d.ts delete mode 100644 packages/crypto-node/src/native.js create mode 100644 packages/crypto-node/tests/tsconfig.json rename packages/dispatcher/scripts/{generate.js => generate.cjs} (97%) create mode 100644 packages/dispatcher/tests/tsconfig.json create mode 100644 packages/file-id/tests/tsconfig.json create mode 100644 packages/html-parser/tests/tsconfig.json create mode 100644 packages/i18n/tests/tsconfig.json create mode 100644 packages/markdown-parser/tests/tsconfig.json create mode 100644 packages/tl-runtime/src/encodings/base64.ts create mode 100644 packages/tl-runtime/src/encodings/base64.web.ts rename packages/tl-runtime/src/{platform => encodings}/gzip.ts (70%) rename packages/tl-runtime/src/{platform => encodings}/gzip.web.ts (66%) create mode 100644 packages/tl-runtime/src/encodings/hex.ts create mode 100644 packages/tl-runtime/src/encodings/hex.web.ts create mode 100644 packages/tl-runtime/src/encodings/index.ts create mode 100644 packages/tl-runtime/src/encodings/utf8.ts create mode 100644 packages/tl-runtime/src/encodings/utf8.web.ts create mode 100644 packages/tl-runtime/tests/encodings/base64.spec.ts create mode 100644 packages/tl-runtime/tests/encodings/hex.spec.ts create mode 100644 packages/tl-runtime/tests/encodings/utf8.spec.ts create mode 100644 packages/tl-runtime/tests/tsconfig.json create mode 100644 packages/tl-utils/tests/tsconfig.json create mode 100644 packages/tl/scripts/package.json create mode 100644 scripts/build-package.js create mode 100644 scripts/gen-deps-graph.mjs diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..7224b67d --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +**/node_modules +**/private +**/dist \ No newline at end of file diff --git a/.eslintrc.ci.js b/.eslintrc.ci.js index 6696dbe4..ca76b17d 100644 --- a/.eslintrc.ci.js +++ b/.eslintrc.ci.js @@ -3,12 +3,11 @@ const baseConfig = require('./.eslintrc.js') module.exports = { ...baseConfig, overrides: [ + baseConfig.overrides[0], { ...baseConfig.overrides[0], - extends: [ - 'plugin:@typescript-eslint/strict-type-checked', - 'plugin:import/typescript', - ], + files: ['packages/**/*.ts'], + extends: ['plugin:@typescript-eslint/strict-type-checked', 'plugin:import/typescript'], parser: '@typescript-eslint/parser', parserOptions: { project: true, @@ -16,13 +15,16 @@ module.exports = { }, rules: { ...baseConfig.overrides[0].rules, - '@typescript-eslint/restrict-template-expressions': [ - 'error', - { allowNever: true }, - ], + '@typescript-eslint/restrict-template-expressions': ['error', { allowNever: true }], }, reportUnusedDisableDirectives: false, }, ...baseConfig.overrides.slice(1), + { + files: ['e2e/**'], + rules: { + 'import/no-unresolved': 'off', + }, + }, ], } diff --git a/.eslintrc.js b/.eslintrc.js index b17f58b7..a7063bd6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -97,7 +97,7 @@ module.exports = { yoda: 2, // Variables - 'no-restricted-globals': [2], + 'no-restricted-globals': ['error'], 'no-var': 1, // Codestyle @@ -169,6 +169,7 @@ module.exports = { 'import/no-default-export': 'error', 'no-console': ['error', { allow: ['warn', 'error'] }], }, + ignorePatterns: ['packages/client/utils.ts', 'packages/core/utils.ts'], overrides: [ { files: ['**/*.ts', '**/*.tsx'], @@ -213,6 +214,7 @@ module.exports = { '@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'], }, reportUnusedDisableDirectives: false, settings: { @@ -235,6 +237,12 @@ module.exports = { 'max-params': ['error', 4], }, }, + { + files: ['e2e/cjs/**'], + rules: { + 'no-restricted-globals': 'off', + }, + }, ], settings: { 'import/resolver': { diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index d96f814b..ea07f6a2 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -28,11 +28,19 @@ jobs: - name: 'TL codegen' run: pnpm -C packages/tl run gen-code - name: 'TypeScript' - run: pnpm run lint:tsc + run: pnpm run lint:tsc:ci - name: 'ESLint' - env: - NODE_OPTIONS: "--max_old_space_size=4096" run: pnpm run lint:ci - name: 'Circular dependencies' run: pnpm run lint:dpdm - - run: pnpm run test:all \ No newline at end of file + - run: pnpm run test:all:ci + e2e: + runs-on: ubuntu-latest + needs: test + steps: + - uses: actions/checkout@v4 + - name: Run end-to-end tests + env: + API_ID: ${{ secrets.TELEGRAM_API_ID }} + API_HASH: ${{ secrets.TELEGRAM_API_HASH }} + run: cd e2e && ./cli.sh ci \ No newline at end of file diff --git a/.gitignore b/.gitignore index b6b333f3..e9923809 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ private/ docs/* !docs/.nojekyll + +*.tsbuildinfo \ No newline at end of file diff --git a/.mocharc.json b/.mocharc.json new file mode 100644 index 00000000..95448eb3 --- /dev/null +++ b/.mocharc.json @@ -0,0 +1,3 @@ +{ + "node-option": ["experimental-specifier-resolution=node", "loader=ts-node/esm"] +} diff --git a/.npmrc b/.npmrc index 62f0ebfa..68335980 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1 @@ -@mtcute:registry=https://npm.tei.su +@mtcute:registry=https://npm.tei.su \ No newline at end of file diff --git a/e2e/.dockerignore b/e2e/.dockerignore new file mode 100644 index 00000000..ee6ac304 --- /dev/null +++ b/e2e/.dockerignore @@ -0,0 +1,7 @@ +.verdaccio +node_modules +private +dist +pnpm-lock.yaml +.npmrc +.env* \ No newline at end of file diff --git a/e2e/.env.example b/e2e/.env.example new file mode 100644 index 00000000..2a7641ed --- /dev/null +++ b/e2e/.env.example @@ -0,0 +1,3 @@ +# obtain these values from my.telegram.org +API_ID= +API_HASH= diff --git a/e2e/.gitignore b/e2e/.gitignore new file mode 100644 index 00000000..3f599169 --- /dev/null +++ b/e2e/.gitignore @@ -0,0 +1,4 @@ +.verdaccio/storage +.npmrc +pnpm-lock.yaml +.env \ No newline at end of file diff --git a/e2e/.mocharc.json b/e2e/.mocharc.json new file mode 100644 index 00000000..1c46b480 --- /dev/null +++ b/e2e/.mocharc.json @@ -0,0 +1,3 @@ +{ + "node-option": [] +} diff --git a/e2e/.verdaccio/config.yaml b/e2e/.verdaccio/config.yaml new file mode 100644 index 00000000..91b1c240 --- /dev/null +++ b/e2e/.verdaccio/config.yaml @@ -0,0 +1,13 @@ +storage: ./storage + +auth: + htpasswd: + file: ./htpasswd + max_users: -1 + +packages: + '**': + access: $all + publish: $all + +logs: { type: stdout, format: pretty, level: trace } \ No newline at end of file diff --git a/e2e/.verdaccio/htpasswd b/e2e/.verdaccio/htpasswd new file mode 100644 index 00000000..a3bd7a7a --- /dev/null +++ b/e2e/.verdaccio/htpasswd @@ -0,0 +1 @@ +mtcute-bot:$apr1$7rbqxva0$zyfFgknsbAxni.cq158Sf. \ No newline at end of file diff --git a/e2e/Dockerfile.build b/e2e/Dockerfile.build new file mode 100644 index 00000000..7d5721a0 --- /dev/null +++ b/e2e/Dockerfile.build @@ -0,0 +1,19 @@ +FROM node:20-alpine +WORKDIR /app + +RUN apk add python3 make g++ && \ + corepack enable && \ + corepack prepare pnpm@8.7.1 --activate + +COPY ../ /app/ + +RUN pnpm install --frozen-lockfile && \ + pnpm -C packages/tl run gen-code && \ + # verdaccio is configured to allow anonymous publish, but npm requires a token 🥴 + npm config set //verdaccio:4873/:_authToken fake-token + +ENV REGISTRY="http://verdaccio:4873/" +ENV E2E="1" + +ENTRYPOINT [ "node", "/app/scripts/publish.js" ] +CMD [ "all" ] \ No newline at end of file diff --git a/e2e/Dockerfile.test b/e2e/Dockerfile.test new file mode 100644 index 00000000..50246c29 --- /dev/null +++ b/e2e/Dockerfile.test @@ -0,0 +1,13 @@ +FROM node:20-alpine +WORKDIR /app + +RUN apk add python3 make g++ && \ + corepack enable && \ + corepack prepare pnpm@8.7.1 --activate + +COPY ./ /app/ +RUN npm config set -L project @mtcute:registry http://verdaccio:4873/ && \ + chmod +x ./docker-entrypoint.sh + +ENTRYPOINT [ "./docker-entrypoint.sh" ] +CMD [ "all" ] \ No newline at end of file diff --git a/e2e/README.md b/e2e/README.md new file mode 100644 index 00000000..842f184f --- /dev/null +++ b/e2e/README.md @@ -0,0 +1,48 @@ +# mtcute e2e tests + +This directory contains end-to-end tests for mtcute. + +They are made for 2 purposes: + - Ensure published packages work as expected and can properly be imported + - Ensure that the library works with the actual Telegram API (WIP) + +To achieve the first goal, we use a Verdaccio container to publish the package to, +and then install it from there in another container + +## Setting up + +Before running the tests, you need to copy `.env.example` to `.env` and fill in the values + +## Running tests + +To run tests, you need to have Docker installed. + +```bash +# first start Verdaccio: +./cli.sh start + +# build and publish the package +./cli.sh update +# or a particular package +./cli.sh update tl-runtime + +# run the tests +./cli.sh run +# or in docker +./cli.sh run-docker +``` + +## Developing + +Once you have Verdaccio running, you can run the following commands to setup +the environment for development: + +```bash +npm config set -L project @mtcute:registry http://verdaccio.e2e.orb.local/ +./cli.sh install +``` + +> Replace the URL above with the one generated with your Docker GUI of choice +> (e2e > verdaccio > RMB > Open in browser). Example above assumes OrbStack + +Then use `./cli.sh run` to run the tests \ No newline at end of file diff --git a/e2e/cjs/package.json b/e2e/cjs/package.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/e2e/cjs/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/e2e/cjs/tests/base-client.js b/e2e/cjs/tests/base-client.js new file mode 100644 index 00000000..f3ecddf6 --- /dev/null +++ b/e2e/cjs/tests/base-client.js @@ -0,0 +1,23 @@ +const { BaseTelegramClient } = require('@mtcute/core') +const { describe, it } = require('mocha') +const { expect } = require('chai') + +const { getApiParams } = require('../utils') + +describe('@mtcute/core', function () { + this.timeout(60_000) + + it('connects to test DC and makes help.getNearestDc', async () => { + const tg = new BaseTelegramClient({ + ...getApiParams(), + }) + + await tg.connect() + const config = await tg.call({ _: 'help.getNearestDc' }) + await tg.close() + + expect(config).to.be.an('object') + expect(config._).to.equal('nearestDc') + expect(config.thisDc).to.equal(2) + }) +}) diff --git a/e2e/cjs/tests/tl-runtime.js b/e2e/cjs/tests/tl-runtime.js new file mode 100644 index 00000000..0db623e2 --- /dev/null +++ b/e2e/cjs/tests/tl-runtime.js @@ -0,0 +1,123 @@ +const { + TlBinaryReader, + TlBinaryWriter, + TlSerializationCounter, + hexEncode, + hexDecode, + hexDecodeToBuffer, +} = require('@mtcute/tl-runtime') +const Long = require('long') +const { describe, it } = require('mocha') +const { expect } = require('chai') + +// here we primarily want to check that everything imports properly, +// and that the code is actually executable. The actual correctness +// of the implementation is covered tested by unit tests + +describe('@mtcute/tl-runtime', () => { + describe('encodings', () => { + it('works with Buffers', () => { + const buf = Buffer.alloc(5) + hexDecode(buf, '0102030405') + + expect(hexEncode(Buffer.from('hello'))).to.equal('68656c6c6f') + expect(buf).eql(Buffer.from([1, 2, 3, 4, 5])) + }) + + it('works with Uint8Arrays', () => { + const buf = new Uint8Array(5) + hexDecode(buf, '0102030405') + + expect(hexEncode(new Uint8Array([1, 2, 3, 4, 5]))).to.equal('0102030405') + expect(buf).eql(new Uint8Array([1, 2, 3, 4, 5])) + }) + }) + + describe('TlBinaryReader', () => { + const map = { + '85337187': function (r) { + const ret = {} + ret._ = 'mt_resPQ' + ret.nonce = r.int128() + ret.serverNonce = r.int128() + ret.pq = r.bytes() + ret.serverPublicKeyFingerprints = r.vector(r.long) + + return ret + }, + } + const data = + '000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3' + + it('should work with Buffers', () => { + const buf = Buffer.from(data, 'hex') + const r = new TlBinaryReader(map, buf, 8) + + expect(r.long().toString(16)).to.equal('51e57ac91e83c801') + expect(r.uint()).to.equal(64) + + const obj = r.object() + expect(obj._).equal('mt_resPQ') + }) + + it('should work with Uint8Arrays', () => { + const buf = hexDecodeToBuffer(data) + + const r = new TlBinaryReader(map, buf, 8) + + expect(r.long().toString(16)).to.equal('51e57ac91e83c801') + expect(r.uint()).to.equal(64) + + const obj = r.object() + expect(obj._).equal('mt_resPQ') + }) + }) + + describe('TlBinaryWriter', () => { + const map = { + mt_resPQ: function (w, obj) { + w.uint(85337187) + w.bytes(obj.pq) + w.vector(w.long, obj.serverPublicKeyFingerprints) + }, + } + + it('should work with Buffers', () => { + const obj = { + _: 'mt_resPQ', + pq: Buffer.from('17ED48941A08F981', 'hex'), + serverPublicKeyFingerprints: [Long.fromString('c3b42b026ce86b21', 16)], + } + + expect(TlSerializationCounter.countNeededBytes(map, obj)).to.equal(32) + + const w = TlBinaryWriter.alloc(map, 48) + w.long(Long.ZERO) + w.long(Long.fromString('51E57AC91E83C801', true, 16)) // messageId + w.object(obj) + + expect(hexEncode(w.result())).eq( + '000000000000000001c8831ec97ae551632416050817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3', + ) + }) + + it('should work with Uint8Arrays', () => { + const obj = { + _: 'mt_resPQ', + pq: hexDecodeToBuffer('17ED48941A08F981'), + serverPublicKeyFingerprints: [Long.fromString('c3b42b026ce86b21', 16)], + } + + expect(TlSerializationCounter.countNeededBytes(map, obj)).to.equal(32) + + const w = TlBinaryWriter.alloc(map, 48) + w.long(Long.ZERO) + w.long(Long.fromString('51E57AC91E83C801', true, 16)) // messageId + w.object(obj) + + expect(hexEncode(w.result())).eq( + '000000000000000001c8831ec97ae551632416050817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3', + ) + }) + }) +}) diff --git a/e2e/cjs/tests/tl-schema.js b/e2e/cjs/tests/tl-schema.js new file mode 100644 index 00000000..7bab1853 --- /dev/null +++ b/e2e/cjs/tests/tl-schema.js @@ -0,0 +1,39 @@ +const Long = require('long') + +const { + TlBinaryReader, + TlBinaryWriter, + hexEncode, +} = require('@mtcute/tl-runtime') +const { tl } = require('@mtcute/tl') +const { __tlReaderMap } = require('@mtcute/tl/binary/reader') +const { __tlWriterMap } = require('@mtcute/tl/binary/writer') +const { describe, it } = require('mocha') +const { expect } = require('chai') + +// here we primarily want to check that @mtcute/tl correctly works with @mtcute/tl-runtime + +describe('@mtcute/tl', () => { + it('writers map works with TlBinaryWriter', () => { + const obj = { + _: 'inputPeerUser', + userId: 123, + accessHash: Long.fromNumber(456), + } + + expect(hexEncode(TlBinaryWriter.serializeObject(__tlWriterMap, obj))).to.equal('4ca5e8dd7b00000000000000c801000000000000') + }) + + it('readers map works with TlBinaryReader', () => { + const buf = Buffer.from('4ca5e8dd7b00000000000000c801000000000000', 'hex') + const obj = TlBinaryReader.deserializeObject(__tlReaderMap, buf) + + expect(obj._).equal('inputPeerUser') + expect(obj.userId).equal(123) + expect(obj.accessHash.toString()).equal('456') + }) + + it('correctly checks for combinator types', () => { + expect(tl.isAnyInputUser({ _: 'inputUserEmpty' })).to.be.true + }) +}) diff --git a/e2e/cjs/utils.js b/e2e/cjs/utils.js new file mode 100644 index 00000000..a0832c51 --- /dev/null +++ b/e2e/cjs/utils.js @@ -0,0 +1,11 @@ +exports.getApiParams = () => { + if (!process.env.API_ID || !process.env.API_HASH) { + throw new Error('API_ID and API_HASH env variables must be set') + } + + return { + apiId: parseInt(process.env.API_ID), + apiHash: process.env.API_HASH, + testMode: true, + } +} diff --git a/e2e/cli.sh b/e2e/cli.sh new file mode 100755 index 00000000..27609223 --- /dev/null +++ b/e2e/cli.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +set -eau + +method=$1 +shift + +# rewrite using switch: + +case "$method" in + "run") + node runner.js $@ + ;; + "run-docker") + source .env + docker compose run --rm --build test $@ + ;; + "update") + docker compose run --build build $@ + ./cli.sh install + ;; + "start") + docker compose up -d verdaccio + ;; + "stop") + docker compose down + ;; + "install") + rm -rf pnpm-lock.yaml node_modules + pnpm install + ;; + "ci") + chmod -R 777 .verdaccio + docker compose up -d verdaccio + docker compose run --rm --build build + docker compose run --rm --build test + ;; + *) + echo "Unknown command" + ;; +esac \ No newline at end of file diff --git a/e2e/config.js b/e2e/config.js new file mode 100644 index 00000000..1e9a7953 --- /dev/null +++ b/e2e/config.js @@ -0,0 +1,23 @@ +module.exports = { + cjs: { + getFiles: () => 'tests/**/*.js', + runFile: (file) => `mocha ${file}`, + }, + esm: { + getFiles: () => 'tests/**/*.js', + runFile: (file) => `mocha ${file}`, + }, + ts: { + getFiles: () => 'tests/**/*.ts', + beforeAll: () => [ + 'tsc', + 'node build-esm.cjs', + ], + runFile: (file) => [ + `mocha -r ts-node/register ${file}`, + `mocha dist/${file.replace(/\.ts$/, '.js')}`, + `node run-esm.cjs ${file}`, + `mocha dist/esm/${file.replace(/\.ts$/, '.js')}`, + ], + }, +} diff --git a/e2e/docker-compose.yaml b/e2e/docker-compose.yaml new file mode 100644 index 00000000..1bf2c7e4 --- /dev/null +++ b/e2e/docker-compose.yaml @@ -0,0 +1,31 @@ +version: "3" +services: + verdaccio: + restart: unless-stopped + image: verdaccio/verdaccio:5.27 + container_name: "verdaccio" + volumes: + - "./.verdaccio:/verdaccio/conf" + networks: + - mtcute-e2e + build: + build: + context: .. + dockerfile: e2e/Dockerfile.build + networks: + - mtcute-e2e + depends_on: + - verdaccio + test: + build: + context: . + dockerfile: Dockerfile.test + environment: + - API_ID=${API_ID} + - API_HASH=${API_HASH} + networks: + - mtcute-e2e + depends_on: + - verdaccio +networks: + mtcute-e2e: {} \ No newline at end of file diff --git a/e2e/docker-entrypoint.sh b/e2e/docker-entrypoint.sh new file mode 100644 index 00000000..3675a1e0 --- /dev/null +++ b/e2e/docker-entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +set -e + +# we can't do this during build because we don't have network access +pnpm install + +node runner.js $@ \ No newline at end of file diff --git a/e2e/esm/package.json b/e2e/esm/package.json new file mode 100644 index 00000000..7c34deb5 --- /dev/null +++ b/e2e/esm/package.json @@ -0,0 +1 @@ +{"type":"module"} \ No newline at end of file diff --git a/e2e/esm/tests/base-client.js b/e2e/esm/tests/base-client.js new file mode 100644 index 00000000..d8e9e2a0 --- /dev/null +++ b/e2e/esm/tests/base-client.js @@ -0,0 +1,24 @@ +import { expect } from 'chai' +import { describe, it } from 'mocha' + +import { BaseTelegramClient } from '@mtcute/core' + +import { getApiParams } from '../utils.js' + +describe('@mtcute/core', function () { + this.timeout(60_000) + + it('connects to test DC and makes help.getNearestDc', async () => { + const tg = new BaseTelegramClient({ + ...getApiParams(), + }) + + await tg.connect() + const config = await tg.call({ _: 'help.getNearestDc' }) + await tg.close() + + expect(config).to.be.an('object') + expect(config._).to.equal('nearestDc') + expect(config.thisDc).to.equal(2) + }) +}) diff --git a/e2e/esm/tests/tl-runtime.js b/e2e/esm/tests/tl-runtime.js new file mode 100644 index 00000000..7e6c0407 --- /dev/null +++ b/e2e/esm/tests/tl-runtime.js @@ -0,0 +1,122 @@ +import { expect } from 'chai' +import Long from 'long' +import { describe, it } from 'mocha' + +import { + hexDecode, + hexDecodeToBuffer, + hexEncode, + TlBinaryReader, + TlBinaryWriter, + TlSerializationCounter, +} from '@mtcute/tl-runtime' + +// here we primarily want to check that everything imports properly, +// and that the code is actually executable. The actual correctness +// of the implementation is covered tested by unit tests + +describe('encodings', () => { + it('works with Buffers', () => { + const buf = Buffer.alloc(5) + hexDecode(buf, '0102030405') + + expect(hexEncode(Buffer.from('hello'))).to.equal('68656c6c6f') + expect(buf).eql(Buffer.from([1, 2, 3, 4, 5])) + }) + + it('works with Uint8Arrays', () => { + const buf = new Uint8Array(5) + hexDecode(buf, '0102030405') + + expect(hexEncode(new Uint8Array([1, 2, 3, 4, 5]))).to.equal('0102030405') + expect(buf).eql(new Uint8Array([1, 2, 3, 4, 5])) + }) +}) + +describe('TlBinaryReader', () => { + const map = { + '85337187': function (r) { + const ret = {} + ret._ = 'mt_resPQ' + ret.nonce = r.int128() + ret.serverNonce = r.int128() + ret.pq = r.bytes() + ret.serverPublicKeyFingerprints = r.vector(r.long) + + return ret + }, + } + const data = + '000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3' + + it('should work with Buffers', () => { + const buf = Buffer.from(data, 'hex') + const r = new TlBinaryReader(map, buf, 8) + + expect(r.long().toString(16)).to.equal('51e57ac91e83c801') + expect(r.uint()).to.equal(64) + + const obj = r.object() + expect(obj._).equal('mt_resPQ') + }) + + it('should work with Uint8Arrays', () => { + const buf = hexDecodeToBuffer(data) + + const r = new TlBinaryReader(map, buf, 8) + + expect(r.long().toString(16)).to.equal('51e57ac91e83c801') + expect(r.uint()).to.equal(64) + + const obj = r.object() + expect(obj._).equal('mt_resPQ') + }) +}) + +describe('TlBinaryWriter', () => { + const map = { + mt_resPQ: function (w, obj) { + w.uint(85337187) + w.bytes(obj.pq) + w.vector(w.long, obj.serverPublicKeyFingerprints) + }, + } + + it('should work with Buffers', () => { + const obj = { + _: 'mt_resPQ', + pq: Buffer.from('17ED48941A08F981', 'hex'), + serverPublicKeyFingerprints: [Long.fromString('c3b42b026ce86b21', 16)], + } + + expect(TlSerializationCounter.countNeededBytes(map, obj)).to.equal(32) + + const w = TlBinaryWriter.alloc(map, 48) + w.long(Long.ZERO) + w.long(Long.fromString('51E57AC91E83C801', true, 16)) // messageId + w.object(obj) + + expect(hexEncode(w.result())).eq( + '000000000000000001c8831ec97ae551632416050817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3', + ) + }) + + it('should work with Uint8Arrays', () => { + const obj = { + _: 'mt_resPQ', + pq: hexDecodeToBuffer('17ED48941A08F981'), + serverPublicKeyFingerprints: [Long.fromString('c3b42b026ce86b21', 16)], + } + + expect(TlSerializationCounter.countNeededBytes(map, obj)).to.equal(32) + + const w = TlBinaryWriter.alloc(map, 48) + w.long(Long.ZERO) + w.long(Long.fromString('51E57AC91E83C801', true, 16)) // messageId + w.object(obj) + + expect(hexEncode(w.result())).eq( + '000000000000000001c8831ec97ae551632416050817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3', + ) + }) +}) diff --git a/e2e/esm/tests/tl-schema.js b/e2e/esm/tests/tl-schema.js new file mode 100644 index 00000000..7c37cd27 --- /dev/null +++ b/e2e/esm/tests/tl-schema.js @@ -0,0 +1,35 @@ +import { expect } from 'chai' +import Long from 'long' +import { describe, it } from 'mocha' + +import { tl } from '@mtcute/tl' +import { __tlReaderMap } from '@mtcute/tl/binary/reader.js' +import { __tlWriterMap } from '@mtcute/tl/binary/writer.js' +import { hexDecodeToBuffer, hexEncode, TlBinaryReader, TlBinaryWriter } from '@mtcute/tl-runtime' + +// here we primarily want to check that @mtcute/tl correctly works with @mtcute/tl-runtime + +describe('@mtcute/tl', () => { + it('writers map works with TlBinaryWriter', () => { + const obj = { + _: 'inputPeerUser', + userId: 123, + accessHash: Long.fromNumber(456), + } + + expect(hexEncode(TlBinaryWriter.serializeObject(__tlWriterMap, obj))).to.equal('4ca5e8dd7b00000000000000c801000000000000') + }) + + it('readers map works with TlBinaryReader', () => { + const buf = hexDecodeToBuffer('4ca5e8dd7b00000000000000c801000000000000') + const obj = TlBinaryReader.deserializeObject(__tlReaderMap, buf) + + expect(obj._).equal('inputPeerUser') + expect(obj.userId).equal(123) + expect(obj.accessHash.toString()).equal('456') + }) + + it('correctly checks for combinator types', () => { + expect(tl.isAnyInputUser({ _: 'inputUserEmpty' })).to.be.true + }) +}) diff --git a/e2e/esm/utils.js b/e2e/esm/utils.js new file mode 100644 index 00000000..67fa1e68 --- /dev/null +++ b/e2e/esm/utils.js @@ -0,0 +1,11 @@ +export const getApiParams = () => { + if (!process.env.API_ID || !process.env.API_HASH) { + throw new Error('API_ID and API_HASH env variables must be set') + } + + return { + apiId: parseInt(process.env.API_ID), + apiHash: process.env.API_HASH, + testMode: true, + } +} diff --git a/e2e/package.json b/e2e/package.json new file mode 100644 index 00000000..0cc78c3f --- /dev/null +++ b/e2e/package.json @@ -0,0 +1,31 @@ +{ + "name": "mtcute-e2e", + "private": true, + "dependencies": { + "@mtcute/client": "*", + "@mtcute/core": "*", + "@mtcute/crypto-node": "*", + "@mtcute/dispatcher": "*", + "@mtcute/file-id": "*", + "@mtcute/html-parser": "*", + "@mtcute/http-proxy": "*", + "@mtcute/i18n": "*", + "@mtcute/markdown-parser": "*", + "@mtcute/mtproxy": "*", + "@mtcute/node": "*", + "@mtcute/socks-proxy": "*", + "@mtcute/sqlite": "*", + "@mtcute/tl": "*", + "@mtcute/tl-runtime": "*", + "@mtcute/tl-utils": "*", + "@types/chai": "^4.3.8", + "@types/mocha": "^10.0.2", + "chai": "^4.3.10", + "dotenv": "16.3.1", + "glob": "10.3.10", + "long": "^5.2.3", + "mocha": "^10.2.0", + "ts-node": "^10.9.1", + "typescript": "^5.2.2" + } +} \ No newline at end of file diff --git a/e2e/pnpm-workspace.yaml b/e2e/pnpm-workspace.yaml new file mode 100644 index 00000000..1a3cf7ae --- /dev/null +++ b/e2e/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - . diff --git a/e2e/runner.js b/e2e/runner.js new file mode 100644 index 00000000..8a40eba3 --- /dev/null +++ b/e2e/runner.js @@ -0,0 +1,123 @@ +/* eslint-disable no-console */ +const glob = require('glob') +const cp = require('child_process') +const path = require('path') + +const env = {} +require('dotenv').config({ processEnv: env }) + +const config = require('./config') + +const DIRS = Object.keys(config) + +function runForFile(dir, file, single = true) { + const { runFile, beforeAll } = config[dir] + + if (!runFile) { + console.log('No runFile for %s', dir) + + return + } + + let cmds = runFile(file) + + const options = { + env: { + ...env, + ...process.env, + }, + cwd: path.join(__dirname, dir), + stdio: 'inherit', + } + + if (!Array.isArray(cmds)) { + cmds = [cmds] + } + + if (beforeAll && single) { + cmds.unshift(...beforeAll()) + } + + for (const c of cmds) { + console.log('%s $ %s', dir, c) + cp.execSync('pnpm exec ' + c, options) + } +} + +function runForDir(dir) { + const { getFiles, beforeAll } = config[dir] + + if (!getFiles) { + console.log('No getFiles for %s', dir) + + return + } + + const options = { + env: { + ...env, + ...process.env, + }, + cwd: path.join(__dirname, dir), + stdio: 'inherit', + } + + if (beforeAll) { + for (const c of beforeAll()) { + console.log('%s $ %s', dir, c) + cp.execSync('pnpm exec ' + c, options) + } + } + + const files = glob.sync(getFiles(), { cwd: path.join(__dirname, dir) }) + + for (const file of files) { + runForFile(dir, file, false) + } +} + +async function main() { + if (!process.argv[2]) { + console.log('Usage: node runner.js ') + console.log(' where is one of:') + console.log(' all - run all tests') + console.log(' - (one of %s) - run tests for that directory', DIRS.join(', ')) + console.log(' - run tests for that file') + process.exit(1) + } + + const [dir, file] = process.argv.slice(2) + + if (dir === 'all') { + for (const d of DIRS) { + console.log('Entering %s', d) + runForDir(d) + } + + return + } + + if (!DIRS.includes(dir)) { + console.log('Unknown directory %s', dir) + process.exit(1) + } + + if (file) { + const files = glob.sync(config[dir].getFiles(), { cwd: path.join(__dirname, dir) }) + const matchingFile = files.find((f) => f.endsWith(file)) + + if (!matchingFile) { + console.log("Can't find file %s", file) + process.exit(1) + } + + runForFile(dir, matchingFile) + } else { + runForDir(dir) + } +} + +main().catch((e) => { + console.error(e) + process.exit(1) +}) diff --git a/e2e/ts/build-esm.cjs b/e2e/ts/build-esm.cjs new file mode 100644 index 00000000..2a95bfa7 --- /dev/null +++ b/e2e/ts/build-esm.cjs @@ -0,0 +1,52 @@ +/* eslint-disable no-restricted-globals */ +const fs = require('fs') +const path = require('path') +const cp = require('child_process') +const glob = require('glob') + +function fixForEsm() { + const modified = {} + + fs.writeFileSync(path.join(__dirname, 'package.json'), JSON.stringify({ type: 'module' })) + + for (const file of glob.sync('tests/**/*.ts')) { + let content = fs.readFileSync(file, 'utf8') + + if (content.includes('@fix-import')) { + modified[file] = content + content = content.replace(/(?<=@fix-import\nimport.*?')(.*?)(?='$)/gms, '$1.js') + fs.writeFileSync(file, content) + } + } + + return () => { + fs.writeFileSync(path.join(__dirname, 'package.json'), JSON.stringify({ type: 'commonjs' })) + + for (const file of Object.keys(modified)) { + fs.writeFileSync(file, modified[file]) + } + } +} +exports.fixForEsm = fixForEsm + +function main() { + const restore = fixForEsm() + let error = null + + try { + cp.execSync('pnpm exec tsc --outDir dist/esm', { stdio: 'inherit' }) + fs.writeFileSync(path.join(__dirname, 'dist/esm/package.json'), JSON.stringify({ type: 'module' })) + } catch (e) { + error = e + } + + restore() + + if (error) { + throw error + } +} + +if (require.main === module) { + main() +} diff --git a/e2e/ts/mocha.esm.json b/e2e/ts/mocha.esm.json new file mode 100644 index 00000000..95448eb3 --- /dev/null +++ b/e2e/ts/mocha.esm.json @@ -0,0 +1,3 @@ +{ + "node-option": ["experimental-specifier-resolution=node", "loader=ts-node/esm"] +} diff --git a/e2e/ts/package.json b/e2e/ts/package.json new file mode 100644 index 00000000..0292b995 --- /dev/null +++ b/e2e/ts/package.json @@ -0,0 +1 @@ +{"type":"commonjs"} \ No newline at end of file diff --git a/e2e/ts/run-esm.cjs b/e2e/ts/run-esm.cjs new file mode 100644 index 00000000..bfa24fec --- /dev/null +++ b/e2e/ts/run-esm.cjs @@ -0,0 +1,26 @@ +/* eslint-disable no-restricted-globals */ +const cp = require('child_process') + +const { fixForEsm } = require('./build-esm.cjs') + +const file = process.argv[2] + +if (!file) { + console.error('Usage: run-esm.cjs ') + process.exit(1) +} + +let error = null +const restore = fixForEsm() + +try { + cp.execSync(`pnpm exec mocha --config=mocha.esm.json ${file}`, { stdio: 'inherit' }) +} catch (e) { + error = e +} + +restore() + +if (error) { + throw error +} diff --git a/e2e/ts/tests/base-client.ts b/e2e/ts/tests/base-client.ts new file mode 100644 index 00000000..e3918ab2 --- /dev/null +++ b/e2e/ts/tests/base-client.ts @@ -0,0 +1,25 @@ +import { expect } from 'chai' +import { describe, it } from 'mocha' + +import { BaseTelegramClient } from '@mtcute/core' + +// @fix-import +import { getApiParams } from '../utils' + +describe('@mtcute/core', function () { + this.timeout(60_000) + + it('connects to test DC and makes help.getNearestDc', async () => { + const tg = new BaseTelegramClient({ + ...getApiParams(), + }) + + await tg.connect() + const config = await tg.call({ _: 'help.getNearestDc' }) + await tg.close() + + expect(config).to.be.an('object') + expect(config._).to.equal('nearestDc') + expect(config.thisDc).to.equal(2) + }) +}) diff --git a/e2e/ts/tests/tl-runtime.ts b/e2e/ts/tests/tl-runtime.ts new file mode 100644 index 00000000..9e20a1f9 --- /dev/null +++ b/e2e/ts/tests/tl-runtime.ts @@ -0,0 +1,124 @@ +/* eslint-disable */ +import { expect } from 'chai' +import Long from 'long' +import { describe, it } from 'mocha' + +import { + hexDecode, + hexDecodeToBuffer, + hexEncode, + TlBinaryReader, + TlBinaryWriter, + TlSerializationCounter, +} from '@mtcute/tl-runtime' + +// here we primarily want to check that everything imports properly, +// and that the code is actually executable. The actual correctness +// of the implementation is covered tested by unit tests + +describe('encodings', () => { + it('works with Buffers', () => { + const buf = Buffer.alloc(5) + hexDecode(buf, '0102030405') + + expect(hexEncode(Buffer.from('hello'))).to.equal('68656c6c6f') + expect(buf).eql(Buffer.from([1, 2, 3, 4, 5])) + }) + + it('works with Uint8Arrays', () => { + const buf = new Uint8Array(5) + hexDecode(buf, '0102030405') + + expect(hexEncode(new Uint8Array([1, 2, 3, 4, 5]))).to.equal('0102030405') + expect(buf).eql(new Uint8Array([1, 2, 3, 4, 5])) + }) +}) + +describe('TlBinaryReader', () => { + const map = { + '85337187': function (r: any) { + const ret: any = {} + ret._ = 'mt_resPQ' + ret.nonce = r.int128() + ret.serverNonce = r.int128() + ret.pq = r.bytes() + ret.serverPublicKeyFingerprints = r.vector(r.long) + + return ret + }, + } + const data = + '000000000000000001c8831ec97ae55140000000632416053e0549828cca27e966b301a48fece2fca5cf4d33f4a11ea877ba4aa5739073300817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3' + + it('should work with Buffers', () => { + const buf = Buffer.from(data, 'hex') + const r = new TlBinaryReader(map, buf, 8) + + expect(r.long().toString(16)).to.equal('51e57ac91e83c801') + expect(r.uint()).to.equal(64) + + const obj: any = r.object() + expect(obj._).equal('mt_resPQ') + }) + + it('should work with Uint8Arrays', () => { + const buf = hexDecodeToBuffer(data) + + const r = new TlBinaryReader(map, buf, 8) + + expect(r.long().toString(16)).to.equal('51e57ac91e83c801') + expect(r.uint()).to.equal(64) + + const obj: any = r.object() + expect(obj._).equal('mt_resPQ') + }) +}) + +describe('TlBinaryWriter', () => { + const map = { + mt_resPQ: function (w: any, obj: any) { + w.uint(85337187) + w.bytes(obj.pq) + w.vector(w.long, obj.serverPublicKeyFingerprints) + }, + _staticSize: {} as any + } + + it('should work with Buffers', () => { + const obj = { + _: 'mt_resPQ', + pq: Buffer.from('17ED48941A08F981', 'hex'), + serverPublicKeyFingerprints: [Long.fromString('c3b42b026ce86b21', 16)], + } + + expect(TlSerializationCounter.countNeededBytes(map, obj)).to.equal(32) + + const w = TlBinaryWriter.alloc(map, 48) + w.long(Long.ZERO) + w.long(Long.fromString('51E57AC91E83C801', true, 16)) // messageId + w.object(obj) + + expect(hexEncode(w.result())).eq( + '000000000000000001c8831ec97ae551632416050817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3', + ) + }) + + it('should work with Uint8Arrays', () => { + const obj = { + _: 'mt_resPQ', + pq: hexDecodeToBuffer('17ED48941A08F981'), + serverPublicKeyFingerprints: [Long.fromString('c3b42b026ce86b21', 16)], + } + + expect(TlSerializationCounter.countNeededBytes(map, obj)).to.equal(32) + + const w = TlBinaryWriter.alloc(map, 48) + w.long(Long.ZERO) + w.long(Long.fromString('51E57AC91E83C801', true, 16)) // messageId + w.object(obj) + + expect(hexEncode(w.result())).eq( + '000000000000000001c8831ec97ae551632416050817ed48941a08f98100000015c4b51c01000000216be86c022bb4c3', + ) + }) +}) diff --git a/e2e/ts/tests/tl-schema.ts b/e2e/ts/tests/tl-schema.ts new file mode 100644 index 00000000..dd62f287 --- /dev/null +++ b/e2e/ts/tests/tl-schema.ts @@ -0,0 +1,39 @@ +import { expect } from 'chai' +import Long from 'long' +import { describe, it } from 'mocha' + +import { tl } from '@mtcute/tl' +import { __tlReaderMap } from '@mtcute/tl/binary/reader.js' +import { __tlWriterMap } from '@mtcute/tl/binary/writer.js' +import { hexDecodeToBuffer, hexEncode, TlBinaryReader, TlBinaryWriter } from '@mtcute/tl-runtime' + +// here we primarily want to check that @mtcute/tl correctly works with @mtcute/tl-runtime + +describe('@mtcute/tl', () => { + it('writers map works with TlBinaryWriter', () => { + const obj = { + _: 'inputPeerUser', + userId: 123, + accessHash: Long.fromNumber(456), + } + + expect(hexEncode(TlBinaryWriter.serializeObject(__tlWriterMap, obj))).to.equal( + '4ca5e8dd7b00000000000000c801000000000000', + ) + }) + + it('readers map works with TlBinaryReader', () => { + const buf = hexDecodeToBuffer('4ca5e8dd7b00000000000000c801000000000000') + // eslint-disable-next-line + const obj = TlBinaryReader.deserializeObject(__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 + }) +}) diff --git a/e2e/ts/tsconfig.json b/e2e/ts/tsconfig.json new file mode 100644 index 00000000..deed9d5a --- /dev/null +++ b/e2e/ts/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "outDir": "./dist", + "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, + "stripInternal": true, + "skipLibCheck": true, + "rootDir": "." + }, + "exclude": [ + "**/node_modules", + ], + "include": [ + "./tests", + "./utils.ts" + ] +} diff --git a/e2e/ts/utils.ts b/e2e/ts/utils.ts new file mode 100644 index 00000000..7e14ca6c --- /dev/null +++ b/e2e/ts/utils.ts @@ -0,0 +1,13 @@ +import type { BaseTelegramClientOptions } from '@mtcute/core' + +export const getApiParams = (): BaseTelegramClientOptions => { + if (!process.env.API_ID || !process.env.API_HASH) { + throw new Error('API_ID and API_HASH env variables must be set') + } + + return { + apiId: parseInt(process.env.API_ID), + apiHash: process.env.API_HASH, + testMode: true, + } +} diff --git a/package.json b/package.json index 10d06fad..4b727080 100644 --- a/package.json +++ b/package.json @@ -8,15 +8,18 @@ "scripts": { "prepare": "husky install", "postinstall": "node scripts/validate-deps-versions.mjs", - "test:all": "pnpm run -r test", + "test:all": "pnpm run -r --parallel test", + "test:all:ci": "pnpm run -r test", "lint": "eslint .", - "lint:ci": "eslint --config .eslintrc.ci.js .", - "lint:tsc": "pnpm run -r build --noEmit", + "lint:ci": "NODE_OPTIONS=\"--max_old_space_size=8192\" eslint --config .eslintrc.ci.js .", + "lint:tsc": "pnpm -r --filter=!crypto --parallel exec tsc --build", + "lint:tsc:ci": "pnpm -r --filter=!crypto 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": "pnpm run -r docs" + "docs": "pnpm run -r docs", + "build-package": "node scripts/build-package.js" }, "dependencies": { "node-gyp": "9.3.1" @@ -25,6 +28,7 @@ "@commitlint/cli": "^17.6.5", "@commitlint/config-conventional": "^17.6.5", "@types/chai": "4.3.5", + "@types/chai-spies": "^1.0.4", "@types/mocha": "10.0.1", "@types/node": "18.16.0", "@types/node-forge": "1.3.2", @@ -32,6 +36,7 @@ "@typescript-eslint/eslint-plugin": "6.4.0", "@typescript-eslint/parser": "6.4.0", "chai": "4.3.7", + "chai-spies": "^1.0.0", "dotenv-flow": "3.2.0", "dpdm": "^3.14.0", "eslint": "8.47.0", diff --git a/packages/client/package.json b/packages/client/package.json index 235e380d..8d92a66a 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -6,13 +6,29 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "src/index.ts", - "module": "_esm/index.js", + "type": "module", "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "docs": "typedoc", - "build": "tsc", - "gen-client": "node ./scripts/generate-client.js", - "gen-updates": "node ./scripts/generate-updates.js" + "build": "pnpm run -w build-package client", + "gen-client": "node ./scripts/generate-client.cjs", + "gen-updates": "node ./scripts/generate-updates.cjs" + }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + }, + "./methods/*.js": { + "import": "./esm/methods/*.js", + "require": "./cjs/methods/*.js" + }, + "./utils.js": { + "import": "./esm/utils/index.js", + "require": "./cjs/utils/index.js" + } + } }, "dependencies": { "@types/node": "18.16.0", diff --git a/packages/client/scripts/generate-client.js b/packages/client/scripts/generate-client.cjs similarity index 99% rename from packages/client/scripts/generate-client.js rename to packages/client/scripts/generate-client.cjs index bd24ac12..944f43cb 100644 --- a/packages/client/scripts/generate-client.js +++ b/packages/client/scripts/generate-client.cjs @@ -1,8 +1,9 @@ +/* eslint-disable no-restricted-globals */ const ts = require('typescript') const path = require('path') const fs = require('fs') const prettier = require('prettier') -const updates = require('./generate-updates') +const updates = require('./generate-updates.cjs') const schema = require('../../tl/api-schema.json') @@ -189,7 +190,7 @@ async function addSingleMethod(state, fileName) { const fileFullText = await fs.promises.readFile(fileName, 'utf-8') const program = ts.createSourceFile(path.basename(fileName), fileFullText, ts.ScriptTarget.ES2018, true) const relPath = path.relative(targetDir, fileName).replace(/\\/g, '/') // replace path delim to unix - const module = `./${relPath.replace(/\.ts$/, '')}` + const module = `./${relPath.replace(/\.ts$/, '.js')}` state.files[relPath] = fileFullText @@ -319,7 +320,7 @@ async function addSingleMethod(state, fileName) { const isPrivate = checkForFlag(stmt, '@internal') const isManual = checkForFlag(stmt, '@manual') const isNoemit = checkForFlag(stmt, '@noemit') - const shouldEmit = !isNoemit && !(isPrivate && !isOverload && !hasOverloads) + const shouldEmit = !isNoemit && !(isPrivate && !isOverload && !Object.keys(hasOverloads).length) if (shouldEmit) { state.methods.list.push({ @@ -432,6 +433,7 @@ async function main() { ) Object.entries(state.imports).forEach(([module, items]) => { items = [...items] + if (!items.length) return output.write(`import { ${items.sort().join(', ')} } from '${module}'\n`) }) diff --git a/packages/client/scripts/generate-updates.js b/packages/client/scripts/generate-updates.cjs similarity index 98% rename from packages/client/scripts/generate-updates.js rename to packages/client/scripts/generate-updates.cjs index c02734cc..180fc727 100644 --- a/packages/client/scripts/generate-updates.js +++ b/packages/client/scripts/generate-updates.cjs @@ -1,3 +1,4 @@ +/* eslint-disable no-restricted-globals */ const fs = require('fs') const path = require('path') const prettier = require('prettier') diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 47a3dc4c..ecffaa0b 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -2,224 +2,208 @@ /* THIS FILE WAS AUTO-GENERATED */ import { Readable } from 'stream' -import { - BaseTelegramClient, - BaseTelegramClientOptions, - Long, - MaybeArray, - MaybeAsync, - PartialExcept, - PartialOnly, - tl, -} from '@mtcute/core' +import { BaseTelegramClient, BaseTelegramClientOptions, Long, MaybeArray, MaybeAsync, PartialExcept, PartialOnly, tl } from '@mtcute/core' import { tdFileId } from '@mtcute/file-id' -import { _onAuthorization, AuthState, getAuthState } from './methods/auth/_state' -import { checkPassword } from './methods/auth/check-password' -import { getPasswordHint } from './methods/auth/get-password-hint' -import { logOut } from './methods/auth/log-out' -import { recoverPassword } from './methods/auth/recover-password' -import { resendCode } from './methods/auth/resend-code' -import {} from './methods/auth/run' -import { sendCode } from './methods/auth/send-code' -import { sendRecoveryCode } from './methods/auth/send-recovery-code' -import { signIn } from './methods/auth/sign-in' -import { signInBot } from './methods/auth/sign-in-bot' -import { start } from './methods/auth/start' -import { startTest } from './methods/auth/start-test' -import { answerCallbackQuery } from './methods/bots/answer-callback-query' -import { answerInlineQuery } from './methods/bots/answer-inline-query' -import { answerPreCheckoutQuery } from './methods/bots/answer-pre-checkout-query' -import { deleteMyCommands } from './methods/bots/delete-my-commands' -import { getBotInfo } from './methods/bots/get-bot-info' -import { getBotMenuButton } from './methods/bots/get-bot-menu-button' -import { getCallbackAnswer } from './methods/bots/get-callback-answer' -import { getGameHighScores, getInlineGameHighScores } from './methods/bots/get-game-high-scores' -import { getMyCommands } from './methods/bots/get-my-commands' -import { _normalizeCommandScope } from './methods/bots/normalize-command-scope' -import { setBotInfo } from './methods/bots/set-bot-info' -import { setBotMenuButton } from './methods/bots/set-bot-menu-button' -import { setGameScore, setInlineGameScore } from './methods/bots/set-game-score' -import { setMyCommands } from './methods/bots/set-my-commands' -import { setMyDefaultRights } from './methods/bots/set-my-default-rights' -import { addChatMembers } from './methods/chats/add-chat-members' -import { archiveChats } from './methods/chats/archive-chats' -import { banChatMember } from './methods/chats/ban-chat-member' -import { createChannel } from './methods/chats/create-channel' -import { createGroup } from './methods/chats/create-group' -import { createSupergroup } from './methods/chats/create-supergroup' -import { deleteChannel } from './methods/chats/delete-channel' -import { deleteChatPhoto } from './methods/chats/delete-chat-photo' -import { deleteGroup } from './methods/chats/delete-group' -import { deleteHistory } from './methods/chats/delete-history' -import { deleteUserHistory } from './methods/chats/delete-user-history' -import { editAdminRights } from './methods/chats/edit-admin-rights' -import { getChat } from './methods/chats/get-chat' -import { getChatEventLog } from './methods/chats/get-chat-event-log' -import { getChatMember } from './methods/chats/get-chat-member' -import { getChatMembers } from './methods/chats/get-chat-members' -import { getChatPreview } from './methods/chats/get-chat-preview' -import { getFullChat } from './methods/chats/get-full-chat' -import { getNearbyChats } from './methods/chats/get-nearby-chats' -import { iterChatEventLog } from './methods/chats/iter-chat-event-log' -import { iterChatMembers } from './methods/chats/iter-chat-members' -import { joinChat } from './methods/chats/join-chat' -import { kickChatMember } from './methods/chats/kick-chat-member' -import { leaveChat } from './methods/chats/leave-chat' -import { markChatUnread } from './methods/chats/mark-chat-unread' -import { reorderUsernames } from './methods/chats/reorder-usernames' -import { restrictChatMember } from './methods/chats/restrict-chat-member' -import { saveDraft } from './methods/chats/save-draft' -import { setChatDefaultPermissions } from './methods/chats/set-chat-default-permissions' -import { setChatDescription } from './methods/chats/set-chat-description' -import { setChatPhoto } from './methods/chats/set-chat-photo' -import { setChatTitle } from './methods/chats/set-chat-title' -import { setChatTtl } from './methods/chats/set-chat-ttl' -import { setChatUsername } from './methods/chats/set-chat-username' -import { setSlowMode } from './methods/chats/set-slow-mode' -import { toggleContentProtection } from './methods/chats/toggle-content-protection' -import { toggleFragmentUsername } from './methods/chats/toggle-fragment-username' -import { toggleJoinRequests } from './methods/chats/toggle-join-requests' -import { toggleJoinToSend } from './methods/chats/toggle-join-to-send' -import { unarchiveChats } from './methods/chats/unarchive-chats' -import { unbanChatMember } from './methods/chats/unban-chat-member' -import { addContact } from './methods/contacts/add-contact' -import { deleteContacts } from './methods/contacts/delete-contacts' -import { getContacts } from './methods/contacts/get-contacts' -import { importContacts } from './methods/contacts/import-contacts' -import { createFolder } from './methods/dialogs/create-folder' -import { deleteFolder } from './methods/dialogs/delete-folder' -import { editFolder } from './methods/dialogs/edit-folder' -import { findFolder } from './methods/dialogs/find-folder' -import { _normalizeInputFolder, getFolders } from './methods/dialogs/get-folders' -import { getPeerDialogs } from './methods/dialogs/get-peer-dialogs' -import { iterDialogs } from './methods/dialogs/iter-dialogs' -import { setFoldersOrder } from './methods/dialogs/set-folders-order' -import { downloadAsBuffer } from './methods/files/download-buffer' -import { downloadToFile } from './methods/files/download-file' -import { downloadAsIterable } from './methods/files/download-iterable' -import { downloadAsStream } from './methods/files/download-stream' -import { _normalizeFileToDocument } from './methods/files/normalize-file-to-document' -import { _normalizeInputFile } from './methods/files/normalize-input-file' -import { _normalizeInputMedia } from './methods/files/normalize-input-media' -import { uploadFile } from './methods/files/upload-file' -import { uploadMedia } from './methods/files/upload-media' -import { createForumTopic } from './methods/forums/create-forum-topic' -import { deleteForumTopicHistory } from './methods/forums/delete-forum-topic-history' -import { editForumTopic } from './methods/forums/edit-forum-topic' -import { getForumTopics, GetForumTopicsOffset } from './methods/forums/get-forum-topics' -import { getForumTopicsById } from './methods/forums/get-forum-topics-by-id' -import { iterForumTopics } from './methods/forums/iter-forum-topics' -import { reorderPinnedForumTopics } from './methods/forums/reorder-pinned-forum-topics' -import { toggleForum } from './methods/forums/toggle-forum' -import { toggleForumTopicClosed } from './methods/forums/toggle-forum-topic-closed' -import { toggleForumTopicPinned } from './methods/forums/toggle-forum-topic-pinned' -import { toggleGeneralTopicHidden } from './methods/forums/toggle-general-topic-hidden' -import { createInviteLink } from './methods/invite-links/create-invite-link' -import { editInviteLink } from './methods/invite-links/edit-invite-link' -import { exportInviteLink } from './methods/invite-links/export-invite-link' -import { getInviteLink } from './methods/invite-links/get-invite-link' -import { getInviteLinkMembers } from './methods/invite-links/get-invite-link-members' -import { getInviteLinks, GetInviteLinksOffset } from './methods/invite-links/get-invite-links' -import { getPrimaryInviteLink } from './methods/invite-links/get-primary-invite-link' -import { hideAllJoinRequests } from './methods/invite-links/hide-all-join-requests' -import { hideJoinRequest } from './methods/invite-links/hide-join-request' -import { iterInviteLinkMembers } from './methods/invite-links/iter-invite-link-members' -import { iterInviteLinks } from './methods/invite-links/iter-invite-links' -import { revokeInviteLink } from './methods/invite-links/revoke-invite-link' -import { closePoll } from './methods/messages/close-poll' -import { deleteMessages, deleteMessagesById, DeleteMessagesParams } from './methods/messages/delete-messages' -import { deleteScheduledMessages } from './methods/messages/delete-scheduled-messages' -import { editInlineMessage } from './methods/messages/edit-inline-message' -import { editMessage } from './methods/messages/edit-message' -import { _findMessageInUpdate } from './methods/messages/find-in-update' -import { ForwardMessageOptions, forwardMessages, forwardMessagesById } from './methods/messages/forward-messages' -import { _getDiscussionMessage, getDiscussionMessage } from './methods/messages/get-discussion-message' -import { getHistory, GetHistoryOffset } from './methods/messages/get-history' -import { getMessageGroup } from './methods/messages/get-message-group' -import { getMessageReactions, getMessageReactionsById } from './methods/messages/get-message-reactions' -import { getMessages } from './methods/messages/get-messages' -import { getMessagesUnsafe } from './methods/messages/get-messages-unsafe' -import { getReactionUsers, GetReactionUsersOffset } from './methods/messages/get-reaction-users' -import { getReplyTo } from './methods/messages/get-reply-to' -import { getScheduledMessages } from './methods/messages/get-scheduled-messages' -import { iterHistory } from './methods/messages/iter-history' -import { iterReactionUsers } from './methods/messages/iter-reaction-users' -import { iterSearchGlobal } from './methods/messages/iter-search-global' -import { iterSearchMessages } from './methods/messages/iter-search-messages' -import { _parseEntities } from './methods/messages/parse-entities' -import { pinMessage } from './methods/messages/pin-message' -import { readHistory } from './methods/messages/read-history' -import { readReactions } from './methods/messages/read-reactions' -import { searchGlobal, SearchGlobalOffset } from './methods/messages/search-global' -import { searchMessages, SearchMessagesOffset } from './methods/messages/search-messages' -import { answerMedia, answerMediaGroup, answerText } from './methods/messages/send-answer' -import { commentMedia, commentMediaGroup, commentText } from './methods/messages/send-comment' -import { CommonSendParams } from './methods/messages/send-common' -import { sendCopy, SendCopyParams } from './methods/messages/send-copy' -import { sendCopyGroup, SendCopyGroupParams } from './methods/messages/send-copy-group' -import { sendMedia } from './methods/messages/send-media' -import { sendMediaGroup } from './methods/messages/send-media-group' -import { sendReaction } from './methods/messages/send-reaction' -import { replyMedia, replyMediaGroup, replyText } from './methods/messages/send-reply' -import { sendScheduled } from './methods/messages/send-scheduled' -import { sendText } from './methods/messages/send-text' -import { sendTyping } from './methods/messages/send-typing' -import { sendVote } from './methods/messages/send-vote' -import { translateMessage } from './methods/messages/translate-message' -import { translateText } from './methods/messages/translate-text' -import { unpinAllMessages } from './methods/messages/unpin-all-messages' -import { unpinMessage } from './methods/messages/unpin-message' -import { initTakeoutSession } from './methods/misc/init-takeout-session' -import { _normalizePrivacyRules } from './methods/misc/normalize-privacy-rules' -import { getParseModesState, ParseModesState } from './methods/parse-modes/_state' +import { AuthState, getAuthState } from './methods/auth/_state.js' +import { checkPassword } from './methods/auth/check-password.js' +import { getPasswordHint } from './methods/auth/get-password-hint.js' +import { logOut } from './methods/auth/log-out.js' +import { recoverPassword } from './methods/auth/recover-password.js' +import { resendCode } from './methods/auth/resend-code.js' +import { sendCode } from './methods/auth/send-code.js' +import { sendRecoveryCode } from './methods/auth/send-recovery-code.js' +import { signIn } from './methods/auth/sign-in.js' +import { signInBot } from './methods/auth/sign-in-bot.js' +import { start } from './methods/auth/start.js' +import { startTest } from './methods/auth/start-test.js' +import { answerCallbackQuery } from './methods/bots/answer-callback-query.js' +import { answerInlineQuery } from './methods/bots/answer-inline-query.js' +import { answerPreCheckoutQuery } from './methods/bots/answer-pre-checkout-query.js' +import { deleteMyCommands } from './methods/bots/delete-my-commands.js' +import { getBotInfo } from './methods/bots/get-bot-info.js' +import { getBotMenuButton } from './methods/bots/get-bot-menu-button.js' +import { getCallbackAnswer } from './methods/bots/get-callback-answer.js' +import { getGameHighScores, getInlineGameHighScores } from './methods/bots/get-game-high-scores.js' +import { getMyCommands } from './methods/bots/get-my-commands.js' +import { setBotInfo } from './methods/bots/set-bot-info.js' +import { setBotMenuButton } from './methods/bots/set-bot-menu-button.js' +import { setGameScore, setInlineGameScore } from './methods/bots/set-game-score.js' +import { setMyCommands } from './methods/bots/set-my-commands.js' +import { setMyDefaultRights } from './methods/bots/set-my-default-rights.js' +import { addChatMembers } from './methods/chats/add-chat-members.js' +import { archiveChats } from './methods/chats/archive-chats.js' +import { banChatMember } from './methods/chats/ban-chat-member.js' +import { createChannel } from './methods/chats/create-channel.js' +import { createGroup } from './methods/chats/create-group.js' +import { createSupergroup } from './methods/chats/create-supergroup.js' +import { deleteChannel } from './methods/chats/delete-channel.js' +import { deleteChatPhoto } from './methods/chats/delete-chat-photo.js' +import { deleteGroup } from './methods/chats/delete-group.js' +import { deleteHistory } from './methods/chats/delete-history.js' +import { deleteUserHistory } from './methods/chats/delete-user-history.js' +import { editAdminRights } from './methods/chats/edit-admin-rights.js' +import { getChat } from './methods/chats/get-chat.js' +import { getChatEventLog } from './methods/chats/get-chat-event-log.js' +import { getChatMember } from './methods/chats/get-chat-member.js' +import { getChatMembers } from './methods/chats/get-chat-members.js' +import { getChatPreview } from './methods/chats/get-chat-preview.js' +import { getFullChat } from './methods/chats/get-full-chat.js' +import { getNearbyChats } from './methods/chats/get-nearby-chats.js' +import { iterChatEventLog } from './methods/chats/iter-chat-event-log.js' +import { iterChatMembers } from './methods/chats/iter-chat-members.js' +import { joinChat } from './methods/chats/join-chat.js' +import { kickChatMember } from './methods/chats/kick-chat-member.js' +import { leaveChat } from './methods/chats/leave-chat.js' +import { markChatUnread } from './methods/chats/mark-chat-unread.js' +import { reorderUsernames } from './methods/chats/reorder-usernames.js' +import { restrictChatMember } from './methods/chats/restrict-chat-member.js' +import { saveDraft } from './methods/chats/save-draft.js' +import { setChatDefaultPermissions } from './methods/chats/set-chat-default-permissions.js' +import { setChatDescription } from './methods/chats/set-chat-description.js' +import { setChatPhoto } from './methods/chats/set-chat-photo.js' +import { setChatTitle } from './methods/chats/set-chat-title.js' +import { setChatTtl } from './methods/chats/set-chat-ttl.js' +import { setChatUsername } from './methods/chats/set-chat-username.js' +import { setSlowMode } from './methods/chats/set-slow-mode.js' +import { toggleContentProtection } from './methods/chats/toggle-content-protection.js' +import { toggleFragmentUsername } from './methods/chats/toggle-fragment-username.js' +import { toggleJoinRequests } from './methods/chats/toggle-join-requests.js' +import { toggleJoinToSend } from './methods/chats/toggle-join-to-send.js' +import { unarchiveChats } from './methods/chats/unarchive-chats.js' +import { unbanChatMember } from './methods/chats/unban-chat-member.js' +import { addContact } from './methods/contacts/add-contact.js' +import { deleteContacts } from './methods/contacts/delete-contacts.js' +import { getContacts } from './methods/contacts/get-contacts.js' +import { importContacts } from './methods/contacts/import-contacts.js' +import { createFolder } from './methods/dialogs/create-folder.js' +import { deleteFolder } from './methods/dialogs/delete-folder.js' +import { editFolder } from './methods/dialogs/edit-folder.js' +import { findFolder } from './methods/dialogs/find-folder.js' +import { getFolders } from './methods/dialogs/get-folders.js' +import { getPeerDialogs } from './methods/dialogs/get-peer-dialogs.js' +import { iterDialogs } from './methods/dialogs/iter-dialogs.js' +import { setFoldersOrder } from './methods/dialogs/set-folders-order.js' +import { downloadAsBuffer } from './methods/files/download-buffer.js' +import { downloadToFile } from './methods/files/download-file.js' +import { downloadAsIterable } from './methods/files/download-iterable.js' +import { downloadAsStream } from './methods/files/download-stream.js' +import { _normalizeInputFile } from './methods/files/normalize-input-file.js' +import { _normalizeInputMedia } from './methods/files/normalize-input-media.js' +import { uploadFile } from './methods/files/upload-file.js' +import { uploadMedia } from './methods/files/upload-media.js' +import { createForumTopic } from './methods/forums/create-forum-topic.js' +import { deleteForumTopicHistory } from './methods/forums/delete-forum-topic-history.js' +import { editForumTopic } from './methods/forums/edit-forum-topic.js' +import { getForumTopics, GetForumTopicsOffset } from './methods/forums/get-forum-topics.js' +import { getForumTopicsById } from './methods/forums/get-forum-topics-by-id.js' +import { iterForumTopics } from './methods/forums/iter-forum-topics.js' +import { reorderPinnedForumTopics } from './methods/forums/reorder-pinned-forum-topics.js' +import { toggleForum } from './methods/forums/toggle-forum.js' +import { toggleForumTopicClosed } from './methods/forums/toggle-forum-topic-closed.js' +import { toggleForumTopicPinned } from './methods/forums/toggle-forum-topic-pinned.js' +import { toggleGeneralTopicHidden } from './methods/forums/toggle-general-topic-hidden.js' +import { createInviteLink } from './methods/invite-links/create-invite-link.js' +import { editInviteLink } from './methods/invite-links/edit-invite-link.js' +import { exportInviteLink } from './methods/invite-links/export-invite-link.js' +import { getInviteLink } from './methods/invite-links/get-invite-link.js' +import { getInviteLinkMembers } from './methods/invite-links/get-invite-link-members.js' +import { getInviteLinks, GetInviteLinksOffset } from './methods/invite-links/get-invite-links.js' +import { getPrimaryInviteLink } from './methods/invite-links/get-primary-invite-link.js' +import { hideAllJoinRequests } from './methods/invite-links/hide-all-join-requests.js' +import { hideJoinRequest } from './methods/invite-links/hide-join-request.js' +import { iterInviteLinkMembers } from './methods/invite-links/iter-invite-link-members.js' +import { iterInviteLinks } from './methods/invite-links/iter-invite-links.js' +import { revokeInviteLink } from './methods/invite-links/revoke-invite-link.js' +import { closePoll } from './methods/messages/close-poll.js' +import { deleteMessages, deleteMessagesById, DeleteMessagesParams } from './methods/messages/delete-messages.js' +import { deleteScheduledMessages } from './methods/messages/delete-scheduled-messages.js' +import { editInlineMessage } from './methods/messages/edit-inline-message.js' +import { editMessage } from './methods/messages/edit-message.js' +import { ForwardMessageOptions, forwardMessages, forwardMessagesById } from './methods/messages/forward-messages.js' +import { getDiscussionMessage } from './methods/messages/get-discussion-message.js' +import { getHistory, GetHistoryOffset } from './methods/messages/get-history.js' +import { getMessageGroup } from './methods/messages/get-message-group.js' +import { getMessageReactions, getMessageReactionsById } from './methods/messages/get-message-reactions.js' +import { getMessages } from './methods/messages/get-messages.js' +import { getMessagesUnsafe } from './methods/messages/get-messages-unsafe.js' +import { getReactionUsers, GetReactionUsersOffset } from './methods/messages/get-reaction-users.js' +import { getReplyTo } from './methods/messages/get-reply-to.js' +import { getScheduledMessages } from './methods/messages/get-scheduled-messages.js' +import { iterHistory } from './methods/messages/iter-history.js' +import { iterReactionUsers } from './methods/messages/iter-reaction-users.js' +import { iterSearchGlobal } from './methods/messages/iter-search-global.js' +import { iterSearchMessages } from './methods/messages/iter-search-messages.js' +import { pinMessage } from './methods/messages/pin-message.js' +import { readHistory } from './methods/messages/read-history.js' +import { readReactions } from './methods/messages/read-reactions.js' +import { searchGlobal, SearchGlobalOffset } from './methods/messages/search-global.js' +import { searchMessages, SearchMessagesOffset } from './methods/messages/search-messages.js' +import { answerMedia, answerMediaGroup, answerText } from './methods/messages/send-answer.js' +import { commentMedia, commentMediaGroup, commentText } from './methods/messages/send-comment.js' +import { CommonSendParams } from './methods/messages/send-common.js' +import { sendCopy, SendCopyParams } from './methods/messages/send-copy.js' +import { sendCopyGroup, SendCopyGroupParams } from './methods/messages/send-copy-group.js' +import { sendMedia } from './methods/messages/send-media.js' +import { sendMediaGroup } from './methods/messages/send-media-group.js' +import { sendReaction } from './methods/messages/send-reaction.js' +import { replyMedia, replyMediaGroup, replyText } from './methods/messages/send-reply.js' +import { sendScheduled } from './methods/messages/send-scheduled.js' +import { sendText } from './methods/messages/send-text.js' +import { sendTyping } from './methods/messages/send-typing.js' +import { sendVote } from './methods/messages/send-vote.js' +import { translateMessage } from './methods/messages/translate-message.js' +import { translateText } from './methods/messages/translate-text.js' +import { unpinAllMessages } from './methods/messages/unpin-all-messages.js' +import { unpinMessage } from './methods/messages/unpin-message.js' +import { initTakeoutSession } from './methods/misc/init-takeout-session.js' +import { _normalizePrivacyRules } from './methods/misc/normalize-privacy-rules.js' import { getParseMode, registerParseMode, setDefaultParseMode, unregisterParseMode, -} from './methods/parse-modes/parse-modes' -import { changeCloudPassword } from './methods/password/change-cloud-password' -import { enableCloudPassword } from './methods/password/enable-cloud-password' -import { cancelPasswordEmail, resendPasswordEmail, verifyPasswordEmail } from './methods/password/password-email' -import { removeCloudPassword } from './methods/password/remove-cloud-password' -import { addStickerToSet } from './methods/stickers/add-sticker-to-set' -import { createStickerSet } from './methods/stickers/create-sticker-set' -import { deleteStickerFromSet } from './methods/stickers/delete-sticker-from-set' -import { getCustomEmojis, getCustomEmojisFromMessages } from './methods/stickers/get-custom-emojis' -import { getInstalledStickers } from './methods/stickers/get-installed-stickers' -import { getStickerSet } from './methods/stickers/get-sticker-set' -import { moveStickerInSet } from './methods/stickers/move-sticker-in-set' -import { setChatStickerSet } from './methods/stickers/set-chat-sticker-set' -import { setStickerSetThumb } from './methods/stickers/set-sticker-set-thumb' -import { applyBoost } from './methods/stories/apply-boost' -import { canApplyBoost, CanApplyBoostResult } from './methods/stories/can-apply-boost' -import { canSendStory, CanSendStoryResult } from './methods/stories/can-send-story' -import { deleteStories } from './methods/stories/delete-stories' -import { editStory } from './methods/stories/edit-story' -import { _findStoryInUpdate } from './methods/stories/find-in-update' -import { getAllStories } from './methods/stories/get-all-stories' -import { getBoostStats } from './methods/stories/get-boost-stats' -import { getBoosters } from './methods/stories/get-boosters' -import { getPeerStories } from './methods/stories/get-peer-stories' -import { getProfileStories } from './methods/stories/get-profile-stories' -import { getStoriesById } from './methods/stories/get-stories-by-id' -import { getStoriesInteractions } from './methods/stories/get-stories-interactions' -import { getStoryLink } from './methods/stories/get-story-link' -import { getStoryViewers } from './methods/stories/get-story-viewers' -import { hideMyStoriesViews } from './methods/stories/hide-my-stories-views' -import { incrementStoriesViews } from './methods/stories/increment-stories-views' -import { iterAllStories } from './methods/stories/iter-all-stories' -import { iterBoosters } from './methods/stories/iter-boosters' -import { iterProfileStories } from './methods/stories/iter-profile-stories' -import { iterStoryViewers } from './methods/stories/iter-story-viewers' -import { readStories } from './methods/stories/read-stories' -import { reportStory } from './methods/stories/report-story' -import { sendStory } from './methods/stories/send-story' -import { sendStoryReaction } from './methods/stories/send-story-reaction' -import { togglePeerStoriesArchived } from './methods/stories/toggle-peer-stories-archived' -import { toggleStoriesPinned } from './methods/stories/toggle-stories-pinned' -import { enableUpdatesProcessing, makeParsedUpdateHandler, ParsedUpdateHandlerParams } from './methods/updates' +} from './methods/parse-modes/parse-modes.js' +import { changeCloudPassword } from './methods/password/change-cloud-password.js' +import { enableCloudPassword } from './methods/password/enable-cloud-password.js' +import { cancelPasswordEmail, resendPasswordEmail, verifyPasswordEmail } from './methods/password/password-email.js' +import { removeCloudPassword } from './methods/password/remove-cloud-password.js' +import { addStickerToSet } from './methods/stickers/add-sticker-to-set.js' +import { createStickerSet } from './methods/stickers/create-sticker-set.js' +import { deleteStickerFromSet } from './methods/stickers/delete-sticker-from-set.js' +import { getCustomEmojis, getCustomEmojisFromMessages } from './methods/stickers/get-custom-emojis.js' +import { getInstalledStickers } from './methods/stickers/get-installed-stickers.js' +import { getStickerSet } from './methods/stickers/get-sticker-set.js' +import { moveStickerInSet } from './methods/stickers/move-sticker-in-set.js' +import { setChatStickerSet } from './methods/stickers/set-chat-sticker-set.js' +import { setStickerSetThumb } from './methods/stickers/set-sticker-set-thumb.js' +import { applyBoost } from './methods/stories/apply-boost.js' +import { canApplyBoost, CanApplyBoostResult } from './methods/stories/can-apply-boost.js' +import { canSendStory, CanSendStoryResult } from './methods/stories/can-send-story.js' +import { deleteStories } from './methods/stories/delete-stories.js' +import { editStory } from './methods/stories/edit-story.js' +import { getAllStories } from './methods/stories/get-all-stories.js' +import { getBoostStats } from './methods/stories/get-boost-stats.js' +import { getBoosters } from './methods/stories/get-boosters.js' +import { getPeerStories } from './methods/stories/get-peer-stories.js' +import { getProfileStories } from './methods/stories/get-profile-stories.js' +import { getStoriesById } from './methods/stories/get-stories-by-id.js' +import { getStoriesInteractions } from './methods/stories/get-stories-interactions.js' +import { getStoryLink } from './methods/stories/get-story-link.js' +import { getStoryViewers } from './methods/stories/get-story-viewers.js' +import { hideMyStoriesViews } from './methods/stories/hide-my-stories-views.js' +import { incrementStoriesViews } from './methods/stories/increment-stories-views.js' +import { iterAllStories } from './methods/stories/iter-all-stories.js' +import { iterBoosters } from './methods/stories/iter-boosters.js' +import { iterProfileStories } from './methods/stories/iter-profile-stories.js' +import { iterStoryViewers } from './methods/stories/iter-story-viewers.js' +import { readStories } from './methods/stories/read-stories.js' +import { reportStory } from './methods/stories/report-story.js' +import { sendStory } from './methods/stories/send-story.js' +import { sendStoryReaction } from './methods/stories/send-story-reaction.js' +import { togglePeerStoriesArchived } from './methods/stories/toggle-peer-stories-archived.js' +import { toggleStoriesPinned } from './methods/stories/toggle-stories-pinned.js' +import { enableUpdatesProcessing, makeParsedUpdateHandler, ParsedUpdateHandlerParams } from './methods/updates/index.js' import { catchUp, enableRps, @@ -227,27 +211,28 @@ import { getCurrentRpsProcessing, startUpdatesLoop, stopUpdatesLoop, -} from './methods/updates/manager' -import { blockUser } from './methods/users/block-user' -import { deleteProfilePhotos } from './methods/users/delete-profile-photos' -import { editCloseFriends, editCloseFriendsRaw } from './methods/users/edit-close-friends' -import { getCommonChats } from './methods/users/get-common-chats' -import { getGlobalTtl } from './methods/users/get-global-ttl' -import { getMe } from './methods/users/get-me' -import { getMyUsername } from './methods/users/get-my-username' -import { getProfilePhoto } from './methods/users/get-profile-photo' -import { getProfilePhotos } from './methods/users/get-profile-photos' -import { getUsers } from './methods/users/get-users' -import { iterProfilePhotos } from './methods/users/iter-profile-photos' -import { resolvePeer } from './methods/users/resolve-peer' -import { resolvePeerMany } from './methods/users/resolve-peer-many' -import { setEmojiStatus } from './methods/users/set-emoji-status' -import { setGlobalTtl } from './methods/users/set-global-ttl' -import { setOffline } from './methods/users/set-offline' -import { setProfilePhoto } from './methods/users/set-profile-photo' -import { setUsername } from './methods/users/set-username' -import { unblockUser } from './methods/users/unblock-user' -import { updateProfile } from './methods/users/update-profile' +} from './methods/updates/manager.js' +import { blockUser } from './methods/users/block-user.js' +import { deleteProfilePhotos } from './methods/users/delete-profile-photos.js' +import { editCloseFriends, editCloseFriendsRaw } from './methods/users/edit-close-friends.js' +import { getCommonChats } from './methods/users/get-common-chats.js' +import { getGlobalTtl } from './methods/users/get-global-ttl.js' +import { getMe } from './methods/users/get-me.js' +import { getMyUsername } from './methods/users/get-my-username.js' +import { getProfilePhoto } from './methods/users/get-profile-photo.js' +import { getProfilePhotos } from './methods/users/get-profile-photos.js' +import { getUsers } from './methods/users/get-users.js' +import { iterProfilePhotos } from './methods/users/iter-profile-photos.js' +import { resolvePeer } from './methods/users/resolve-peer.js' +import { resolvePeerMany } from './methods/users/resolve-peer-many.js' +import { setEmojiStatus } from './methods/users/set-emoji-status.js' +import { setGlobalTtl } from './methods/users/set-global-ttl.js' +import { setOffline } from './methods/users/set-offline.js' +import { setProfilePhoto } from './methods/users/set-profile-photo.js' +import { setUsername } from './methods/users/set-username.js' +import { unblockUser } from './methods/users/unblock-user.js' +import { updateProfile } from './methods/users/update-profile.js' +import { Conversation } from './types/conversation.js' import { AllStories, ArrayPaginated, @@ -323,8 +308,7 @@ import { User, UserStatusUpdate, UserTypingUpdate, -} from './types' -import { Conversation } from './types/conversation' +} from './types/index.js' // from methods/_init.ts interface TelegramClientOptions extends BaseTelegramClientOptions { @@ -484,8 +468,6 @@ export interface TelegramClient extends BaseTelegramClient { on(name: 'delete_story', handler: (upd: DeleteStoryUpdate) => void): this getAuthState(): AuthState - - _onAuthorization(auth: tl.auth.TypeAuthorization, bot?: boolean): User /** * Check your Two-Step verification password and log in * @@ -928,7 +910,7 @@ export interface TelegramClient extends BaseTelegramClient { message: number /** Data contained in the button */ - data: string | Buffer + data: string | Uint8Array /** * Timeout for the query in ms. @@ -994,10 +976,6 @@ export interface TelegramClient extends BaseTelegramClient { */ langCode?: string }): Promise - - _normalizeCommandScope( - scope: tl.TypeBotCommandScope | BotCommands.IntermediateScope, - ): Promise /** * Sets information about a bot the current uzer owns (or the current bot) * **Available**: ✅ both users and bots @@ -1997,8 +1975,6 @@ export interface TelegramClient extends BaseTelegramClient { * */ getFolders(): Promise - - _normalizeInputFolder(folder: InputDialogFolder): Promise /** * Get dialogs with certain peers. * @@ -2135,7 +2111,7 @@ export interface TelegramClient extends BaseTelegramClient { * * @param params File download parameters */ - downloadAsBuffer(params: FileDownloadParameters): Promise + downloadAsBuffer(params: FileDownloadParameters): Promise /** * Download a remote file to a local file (only for NodeJS). * Promise will resolve once the download is complete. @@ -2155,7 +2131,7 @@ export interface TelegramClient extends BaseTelegramClient { * * @param params Download parameters */ - downloadAsIterable(params: FileDownloadParameters): AsyncIterableIterator + downloadAsIterable(params: FileDownloadParameters): AsyncIterableIterator /** * Download a file and return it as a Node readable stream, * streaming file contents. @@ -2165,16 +2141,6 @@ export interface TelegramClient extends BaseTelegramClient { * @param params File download parameters */ downloadAsStream(params: FileDownloadParameters): Readable - /** - * **Available**: ✅ both users and bots - * - */ - _normalizeFileToDocument( - file: InputFileLike | tl.TypeInputDocument, - params: { - progressCallback?: (uploaded: number, total: number) => void - }, - ): Promise /** * Normalize a {@link InputFileLike} to `InputFile`, * uploading it if needed. @@ -3001,8 +2967,6 @@ export interface TelegramClient extends BaseTelegramClient { shouldDispatch?: true }, ): Promise - - _findMessageInUpdate(res: tl.TypeUpdates, isEdit?: boolean, noDispatch?: boolean): Message /** * Forward one or more messages by their IDs. * You can forward no more than 100 messages at once. @@ -3037,8 +3001,6 @@ export interface TelegramClient extends BaseTelegramClient { messages: Message[] }, ): Promise - - _getDiscussionMessage(peer: InputPeerLike, message: number): Promise<[tl.TypeInputPeer, number]> // public version of the same method because why not /** * Get discussion message for some channel post. @@ -3356,12 +3318,6 @@ export interface TelegramClient extends BaseTelegramClient { chunkSize?: number }, ): AsyncIterableIterator - - _parseEntities( - text?: string | FormattedString, - mode?: string | null, - entities?: tl.TypeMessageEntity[], - ): Promise<[string, tl.TypeMessageEntity[] | undefined]> /** * Pin a message in a group, supergroup, channel or PM. * @@ -3856,7 +3812,7 @@ export interface TelegramClient extends BaseTelegramClient { * representing them. In case of indexes, the poll will first * be requested from the server. */ - options: null | MaybeArray + options: null | MaybeArray }, ): Promise /** @@ -3928,8 +3884,6 @@ export interface TelegramClient extends BaseTelegramClient { * */ _normalizePrivacyRules(rules: InputPrivacyRule[]): Promise - - getParseModesState(): ParseModesState /** * Register a given {@link IMessageEntityParser} as a parse mode * for messages. When this method is first called, given parse @@ -4344,8 +4298,6 @@ export interface TelegramClient extends BaseTelegramClient { */ privacyRules?: InputPrivacyRule[] }): Promise - - _findStoryInUpdate(res: tl.TypeUpdates): Story /** * Get all stories (e.g. to load the top bar) * **Available**: ✅ both users and bots @@ -5148,7 +5100,6 @@ export class TelegramClient extends BaseTelegramClient { } } getAuthState = getAuthState.bind(null, this) - _onAuthorization = _onAuthorization.bind(null, this) checkPassword = checkPassword.bind(null, this) getPasswordHint = getPasswordHint.bind(null, this) logOut = logOut.bind(null, this) @@ -5169,7 +5120,6 @@ export class TelegramClient extends BaseTelegramClient { getGameHighScores = getGameHighScores.bind(null, this) getInlineGameHighScores = getInlineGameHighScores.bind(null, this) getMyCommands = getMyCommands.bind(null, this) - _normalizeCommandScope = _normalizeCommandScope.bind(null, this) setBotInfo = setBotInfo.bind(null, this) setBotMenuButton = setBotMenuButton.bind(null, this) setGameScore = setGameScore.bind(null, this) @@ -5228,7 +5178,6 @@ export class TelegramClient extends BaseTelegramClient { editFolder = editFolder.bind(null, this) findFolder = findFolder.bind(null, this) getFolders = getFolders.bind(null, this) - _normalizeInputFolder = _normalizeInputFolder.bind(null, this) getPeerDialogs = getPeerDialogs.bind(null, this) iterDialogs = iterDialogs.bind(null, this) setFoldersOrder = setFoldersOrder.bind(null, this) @@ -5236,7 +5185,6 @@ export class TelegramClient extends BaseTelegramClient { downloadToFile = downloadToFile.bind(null, this) downloadAsIterable = downloadAsIterable.bind(null, this) downloadAsStream = downloadAsStream.bind(null, this) - _normalizeFileToDocument = _normalizeFileToDocument.bind(null, this) _normalizeInputFile = _normalizeInputFile.bind(null, this) _normalizeInputMedia = _normalizeInputMedia.bind(null, this) uploadFile = uploadFile.bind(null, this) @@ -5270,10 +5218,8 @@ export class TelegramClient extends BaseTelegramClient { deleteScheduledMessages = deleteScheduledMessages.bind(null, this) editInlineMessage = editInlineMessage.bind(null, this) editMessage = editMessage.bind(null, this) - _findMessageInUpdate = _findMessageInUpdate.bind(null, this) forwardMessagesById = forwardMessagesById.bind(null, this) forwardMessages = forwardMessages.bind(null, this) - _getDiscussionMessage = _getDiscussionMessage.bind(null, this) getDiscussionMessage = getDiscussionMessage.bind(null, this) getHistory = getHistory.bind(null, this) getMessageGroup = getMessageGroup.bind(null, this) @@ -5288,7 +5234,6 @@ export class TelegramClient extends BaseTelegramClient { iterReactionUsers = iterReactionUsers.bind(null, this) iterSearchGlobal = iterSearchGlobal.bind(null, this) iterSearchMessages = iterSearchMessages.bind(null, this) - _parseEntities = _parseEntities.bind(null, this) pinMessage = pinMessage.bind(null, this) readHistory = readHistory.bind(null, this) readReactions = readReactions.bind(null, this) @@ -5318,7 +5263,6 @@ export class TelegramClient extends BaseTelegramClient { unpinMessage = unpinMessage.bind(null, this) initTakeoutSession = initTakeoutSession.bind(null, this) _normalizePrivacyRules = _normalizePrivacyRules.bind(null, this) - getParseModesState = getParseModesState.bind(null, this) registerParseMode = registerParseMode.bind(null, this) unregisterParseMode = unregisterParseMode.bind(null, this) getParseMode = getParseMode.bind(null, this) @@ -5344,7 +5288,6 @@ export class TelegramClient extends BaseTelegramClient { canSendStory = canSendStory.bind(null, this) deleteStories = deleteStories.bind(null, this) editStory = editStory.bind(null, this) - _findStoryInUpdate = _findStoryInUpdate.bind(null, this) getAllStories = getAllStories.bind(null, this) getBoostStats = getBoostStats.bind(null, this) getBoosters = getBoosters.bind(null, this) diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index ce84f215..4aaf6b14 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -1,5 +1,5 @@ -export * from './client' -export * from './types' -export * from './utils/peer-utils' -export { createDummyUpdate } from './utils/updates-utils' +export * from './client.js' +export * from './types/index.js' +export * from './utils/peer-utils.js' +export { createDummyUpdate } from './utils/updates-utils.js' export * from '@mtcute/core' diff --git a/packages/client/src/methods/README.md b/packages/client/src/methods/README.md index 20f79a15..ca13f810 100644 --- a/packages/client/src/methods/README.md +++ b/packages/client/src/methods/README.md @@ -24,7 +24,7 @@ Example: ```typescript // @copy -import { Something } from '../../somewhere' +import { Something } from '../../somewhere.js' // @copy interface SomeGreatInterface { ... } diff --git a/packages/client/src/methods/_imports.ts b/packages/client/src/methods/_imports.ts index 7008a832..8632163d 100644 --- a/packages/client/src/methods/_imports.ts +++ b/packages/client/src/methods/_imports.ts @@ -83,4 +83,4 @@ import { User, UserStatusUpdate, UserTypingUpdate, -} from '../types' +} from '../types/index.js' diff --git a/packages/client/src/methods/_init.ts b/packages/client/src/methods/_init.ts index 054e92cd..34d3d4bc 100644 --- a/packages/client/src/methods/_init.ts +++ b/packages/client/src/methods/_init.ts @@ -2,13 +2,13 @@ import { BaseTelegramClientOptions } from '@mtcute/core' -import { TelegramClient } from '../client' +import { TelegramClient } from '../client.js' // @copy -import { Conversation } from '../types/conversation' +import { Conversation } from '../types/conversation.js' // @copy -import { start } from './auth/start' +import { start } from './auth/start.js' // @copy -import { enableUpdatesProcessing, makeParsedUpdateHandler, ParsedUpdateHandlerParams } from './updates' +import { enableUpdatesProcessing, makeParsedUpdateHandler, ParsedUpdateHandlerParams } from './updates/index.js' // @copy interface TelegramClientOptions extends BaseTelegramClientOptions { diff --git a/packages/client/src/methods/auth/_state.ts b/packages/client/src/methods/auth/_state.ts index a699a279..edc1b627 100644 --- a/packages/client/src/methods/auth/_state.ts +++ b/packages/client/src/methods/auth/_state.ts @@ -1,14 +1,11 @@ /* eslint-disable no-inner-declarations */ import { BaseTelegramClient, MtUnsupportedError, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { User } from '../../types/peers/user' +import { User } from '../../types/peers/user.js' const STATE_SYMBOL = Symbol('authState') -/** - * @internal - * @exported - */ +/** @exported */ export interface AuthState { // local copy of "self" in storage, // so we can use it w/out relying on storage. @@ -20,7 +17,6 @@ export interface AuthState { selfChanged?: boolean } -/** @internal */ export function getAuthState(client: BaseTelegramClient): AuthState { // eslint-disable-next-line let state: AuthState = (client as any)[STATE_SYMBOL] diff --git a/packages/client/src/methods/auth/check-password.ts b/packages/client/src/methods/auth/check-password.ts index c2625511..88c594e9 100644 --- a/packages/client/src/methods/auth/check-password.ts +++ b/packages/client/src/methods/auth/check-password.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { computeSrpParams } from '@mtcute/core/utils' +import { computeSrpParams } from '@mtcute/core/utils.js' -import { User } from '../../types' -import { _onAuthorization } from './_state' +import { User } from '../../types/index.js' +import { _onAuthorization } from './_state.js' /** * Check your Two-Step verification password and log in diff --git a/packages/client/src/methods/auth/log-out.ts b/packages/client/src/methods/auth/log-out.ts index 07070270..b1aedcca 100644 --- a/packages/client/src/methods/auth/log-out.ts +++ b/packages/client/src/methods/auth/log-out.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient } from '@mtcute/core' -import { getAuthState } from './_state' +import { getAuthState } from './_state.js' /** * Log out from Telegram account and optionally reset the session storage. diff --git a/packages/client/src/methods/auth/recover-password.ts b/packages/client/src/methods/auth/recover-password.ts index 1a8b22b5..dfeaa5e2 100644 --- a/packages/client/src/methods/auth/recover-password.ts +++ b/packages/client/src/methods/auth/recover-password.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { User } from '../../types' -import { _onAuthorization } from './_state' +import { User } from '../../types/index.js' +import { _onAuthorization } from './_state.js' /** * Recover your password with a recovery code and log in. diff --git a/packages/client/src/methods/auth/resend-code.ts b/packages/client/src/methods/auth/resend-code.ts index 853ff9af..ec49825a 100644 --- a/packages/client/src/methods/auth/resend-code.ts +++ b/packages/client/src/methods/auth/resend-code.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { SentCode } from '../../types' -import { normalizePhoneNumber } from '../../utils/misc-utils' +import { SentCode } from '../../types/index.js' +import { normalizePhoneNumber } from '../../utils/misc-utils.js' /** * Re-send the confirmation code using a different type. diff --git a/packages/client/src/methods/auth/run.ts b/packages/client/src/methods/auth/run.ts index a385616e..f554ce94 100644 --- a/packages/client/src/methods/auth/run.ts +++ b/packages/client/src/methods/auth/run.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { User } from '../../types' -import { start } from './start' +import { User } from '../../types/index.js' +import { start } from './start.js' /** * Simple wrapper that calls {@link start} and then diff --git a/packages/client/src/methods/auth/send-code.ts b/packages/client/src/methods/auth/send-code.ts index b36ed406..370775f0 100644 --- a/packages/client/src/methods/auth/send-code.ts +++ b/packages/client/src/methods/auth/send-code.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { SentCode } from '../../types' -import { normalizePhoneNumber } from '../../utils/misc-utils' +import { SentCode } from '../../types/index.js' +import { normalizePhoneNumber } from '../../utils/misc-utils.js' /** * Send the confirmation code to the given phone number diff --git a/packages/client/src/methods/auth/sign-in-bot.ts b/packages/client/src/methods/auth/sign-in-bot.ts index a2ae64fe..70679712 100644 --- a/packages/client/src/methods/auth/sign-in-bot.ts +++ b/packages/client/src/methods/auth/sign-in-bot.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { User } from '../../types' -import { _onAuthorization } from './_state' +import { User } from '../../types/index.js' +import { _onAuthorization } from './_state.js' /** * Authorize a bot using its token issued by [@BotFather](//t.me/BotFather) diff --git a/packages/client/src/methods/auth/sign-in.ts b/packages/client/src/methods/auth/sign-in.ts index 3aae1a26..43e2d3ab 100644 --- a/packages/client/src/methods/auth/sign-in.ts +++ b/packages/client/src/methods/auth/sign-in.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { User } from '../../types' -import { normalizePhoneNumber } from '../../utils/misc-utils' -import { _onAuthorization } from './_state' +import { User } from '../../types/index.js' +import { normalizePhoneNumber } from '../../utils/misc-utils.js' +import { _onAuthorization } from './_state.js' /** * Authorize a user in Telegram with a valid confirmation code. diff --git a/packages/client/src/methods/auth/start-test.ts b/packages/client/src/methods/auth/start-test.ts index aa63a256..566a7c50 100644 --- a/packages/client/src/methods/auth/start-test.ts +++ b/packages/client/src/methods/auth/start-test.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { User } from '../../types' -import { logOut } from './log-out' -import { start } from './start' +import { User } from '../../types/index.js' +import { logOut } from './log-out.js' +import { start } from './start.js' /** * Utility function to quickly authorize on test DC diff --git a/packages/client/src/methods/auth/start.ts b/packages/client/src/methods/auth/start.ts index 89debe31..f737b614 100644 --- a/packages/client/src/methods/auth/start.ts +++ b/packages/client/src/methods/auth/start.ts @@ -1,14 +1,14 @@ /* eslint-disable no-console */ import { BaseTelegramClient, MaybeAsync, MtArgumentError, tl } from '@mtcute/core' -import { MaybeDynamic, SentCode, User } from '../../types' -import { normalizePhoneNumber, resolveMaybeDynamic } from '../../utils/misc-utils' -import { getMe } from '../users/get-me' -import { checkPassword } from './check-password' -import { resendCode } from './resend-code' -import { sendCode } from './send-code' -import { signIn } from './sign-in' -import { signInBot } from './sign-in-bot' +import { MaybeDynamic, SentCode, User } from '../../types/index.js' +import { normalizePhoneNumber, resolveMaybeDynamic } from '../../utils/misc-utils.js' +import { getMe } from '../users/get-me.js' +import { checkPassword } from './check-password.js' +import { resendCode } from './resend-code.js' +import { sendCode } from './send-code.js' +import { signIn } from './sign-in.js' +import { signInBot } from './sign-in-bot.js' // @manual // @available=both diff --git a/packages/client/src/methods/bots/answer-callback-query.ts b/packages/client/src/methods/bots/answer-callback-query.ts index 20bb7d86..3a9dee66 100644 --- a/packages/client/src/methods/bots/answer-callback-query.ts +++ b/packages/client/src/methods/bots/answer-callback-query.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, Long } from '@mtcute/core' -import { CallbackQuery } from '../../types/bots/callback-query' +import { CallbackQuery } from '../../types/bots/callback-query.js' /** * Send an answer to a callback query. diff --git a/packages/client/src/methods/bots/answer-inline-query.ts b/packages/client/src/methods/bots/answer-inline-query.ts index 3370cd7e..622829d2 100644 --- a/packages/client/src/methods/bots/answer-inline-query.ts +++ b/packages/client/src/methods/bots/answer-inline-query.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import { BotInline, InlineQuery, InputInlineResult } from '../../types/bots' +import { BotInline, InlineQuery, InputInlineResult } from '../../types/bots/index.js' /** * Answer an inline query. diff --git a/packages/client/src/methods/bots/answer-pre-checkout-query.ts b/packages/client/src/methods/bots/answer-pre-checkout-query.ts index ffa004a6..82928c18 100644 --- a/packages/client/src/methods/bots/answer-pre-checkout-query.ts +++ b/packages/client/src/methods/bots/answer-pre-checkout-query.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import { PreCheckoutQuery } from '../../types/updates' +import type { PreCheckoutQuery } from '../../types/updates/pre-checkout-query.js' /** * Answer a pre-checkout query. diff --git a/packages/client/src/methods/bots/delete-my-commands.ts b/packages/client/src/methods/bots/delete-my-commands.ts index da2216f2..cf3de435 100644 --- a/packages/client/src/methods/bots/delete-my-commands.ts +++ b/packages/client/src/methods/bots/delete-my-commands.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { BotCommands } from '../../types' -import { _normalizeCommandScope } from './normalize-command-scope' +import { BotCommands } from '../../types/index.js' +import { _normalizeCommandScope } from './normalize-command-scope.js' /** * Delete commands for the current bot and the given scope. diff --git a/packages/client/src/methods/bots/get-bot-info.ts b/packages/client/src/methods/bots/get-bot-info.ts index 4f7a29cb..3d655171 100644 --- a/packages/client/src/methods/bots/get-bot-info.ts +++ b/packages/client/src/methods/bots/get-bot-info.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Gets information about a bot the current uzer owns (or the current bot) diff --git a/packages/client/src/methods/bots/get-bot-menu-button.ts b/packages/client/src/methods/bots/get-bot-menu-button.ts index e3c23fa0..d3f8330e 100644 --- a/packages/client/src/methods/bots/get-bot-menu-button.ts +++ b/packages/client/src/methods/bots/get-bot-menu-button.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Fetches the menu button set for the given user. diff --git a/packages/client/src/methods/bots/get-callback-answer.ts b/packages/client/src/methods/bots/get-callback-answer.ts index 2693e7e3..b8f3d8c8 100644 --- a/packages/client/src/methods/bots/get-callback-answer.ts +++ b/packages/client/src/methods/bots/get-callback-answer.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { computeSrpParams } from '@mtcute/core/utils' +import { computeSrpParams, utf8EncodeToBuffer } from '@mtcute/core/utils.js' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Request a callback answer from a bot, @@ -20,7 +20,7 @@ export async function getCallbackAnswer( message: number /** Data contained in the button */ - data: string | Buffer + data: string | Uint8Array /** * Timeout for the query in ms. @@ -57,7 +57,7 @@ export async function getCallbackAnswer( _: 'messages.getBotCallbackAnswer', peer: await resolvePeer(client, chatId), msgId: message, - data: typeof data === 'string' ? Buffer.from(data) : data, + data: typeof data === 'string' ? utf8EncodeToBuffer(data) : data, password, game: game, }, diff --git a/packages/client/src/methods/bots/get-game-high-scores.ts b/packages/client/src/methods/bots/get-game-high-scores.ts index 86abc2da..3db07066 100644 --- a/packages/client/src/methods/bots/get-game-high-scores.ts +++ b/packages/client/src/methods/bots/get-game-high-scores.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { GameHighScore, InputMessageId, InputPeerLike, normalizeInputMessageId, PeersIndex } from '../../types' -import { normalizeInlineId } from '../../utils/inline-utils' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { GameHighScore, InputMessageId, InputPeerLike, normalizeInputMessageId, PeersIndex } from '../../types/index.js' +import { normalizeInlineId } from '../../utils/inline-utils.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get high scores of a game diff --git a/packages/client/src/methods/bots/get-my-commands.ts b/packages/client/src/methods/bots/get-my-commands.ts index 97375cb5..0c98be6e 100644 --- a/packages/client/src/methods/bots/get-my-commands.ts +++ b/packages/client/src/methods/bots/get-my-commands.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { BotCommands } from '../../types' -import { _normalizeCommandScope } from './normalize-command-scope' +import { BotCommands } from '../../types/index.js' +import { _normalizeCommandScope } from './normalize-command-scope.js' /** * Get a list of current bot's commands for the given command scope diff --git a/packages/client/src/methods/bots/normalize-command-scope.ts b/packages/client/src/methods/bots/normalize-command-scope.ts index 6b6597a9..4a0f3673 100644 --- a/packages/client/src/methods/bots/normalize-command-scope.ts +++ b/packages/client/src/methods/bots/normalize-command-scope.ts @@ -1,8 +1,8 @@ import { assertNever, BaseTelegramClient, tl } from '@mtcute/core' -import { BotCommands } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { BotCommands } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** @internal */ export async function _normalizeCommandScope( diff --git a/packages/client/src/methods/bots/set-bot-info.ts b/packages/client/src/methods/bots/set-bot-info.ts index dab0835a..7b43726f 100644 --- a/packages/client/src/methods/bots/set-bot-info.ts +++ b/packages/client/src/methods/bots/set-bot-info.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Sets information about a bot the current uzer owns (or the current bot) diff --git a/packages/client/src/methods/bots/set-bot-menu-button.ts b/packages/client/src/methods/bots/set-bot-menu-button.ts index 2a54aba9..2a095395 100644 --- a/packages/client/src/methods/bots/set-bot-menu-button.ts +++ b/packages/client/src/methods/bots/set-bot-menu-button.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Sets a menu button for the given user. diff --git a/packages/client/src/methods/bots/set-game-score.ts b/packages/client/src/methods/bots/set-game-score.ts index 9545adf2..5fbc58bc 100644 --- a/packages/client/src/methods/bots/set-game-score.ts +++ b/packages/client/src/methods/bots/set-game-score.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputMessageId, InputPeerLike, Message, normalizeInputMessageId } from '../../types' -import { normalizeInlineId } from '../../utils/inline-utils' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { _findMessageInUpdate } from '../messages/find-in-update' -import { resolvePeer } from '../users/resolve-peer' +import { InputMessageId, InputPeerLike, Message, normalizeInputMessageId } from '../../types/index.js' +import { normalizeInlineId } from '../../utils/inline-utils.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { _findMessageInUpdate } from '../messages/find-in-update.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set a score of a user in a game diff --git a/packages/client/src/methods/bots/set-my-commands.ts b/packages/client/src/methods/bots/set-my-commands.ts index 2e9f9eff..2600760d 100644 --- a/packages/client/src/methods/bots/set-my-commands.ts +++ b/packages/client/src/methods/bots/set-my-commands.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { BotCommands } from '../../types' -import { _normalizeCommandScope } from './normalize-command-scope' +import { BotCommands } from '../../types/index.js' +import { _normalizeCommandScope } from './normalize-command-scope.js' /** * Set or delete commands for the current bot and the given scope diff --git a/packages/client/src/methods/chats/add-chat-members.ts b/packages/client/src/methods/chats/add-chat-members.ts index 5243a8fd..e53e0b69 100644 --- a/packages/client/src/methods/chats/add-chat-members.ts +++ b/packages/client/src/methods/chats/add-chat-members.ts @@ -1,14 +1,14 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' +import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js' import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel, normalizeToInputUser, -} from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' -import { resolvePeerMany } from '../users/resolve-peer-many' +} from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { resolvePeerMany } from '../users/resolve-peer-many.js' /** * Add one or more new members to a group, supergroup or channel. diff --git a/packages/client/src/methods/chats/archive-chats.ts b/packages/client/src/methods/chats/archive-chats.ts index 47d159e6..a0c78e55 100644 --- a/packages/client/src/methods/chats/archive-chats.ts +++ b/packages/client/src/methods/chats/archive-chats.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeerMany } from '../users/resolve-peer-many' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeerMany } from '../users/resolve-peer-many.js' /** * Archive one or more chats diff --git a/packages/client/src/methods/chats/ban-chat-member.ts b/packages/client/src/methods/chats/ban-chat-member.ts index 17df1a47..343f4e31 100644 --- a/packages/client/src/methods/chats/ban-chat-member.ts +++ b/packages/client/src/methods/chats/ban-chat-member.ts @@ -1,14 +1,14 @@ import { BaseTelegramClient, MtTypeAssertionError } from '@mtcute/core' -import { InputPeerLike, Message, MtInvalidPeerTypeError } from '../../types' +import { InputPeerLike, Message, MtInvalidPeerTypeError } from '../../types/index.js' import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel, normalizeToInputUser, -} from '../../utils/peer-utils' -import { _findMessageInUpdate } from '../messages/find-in-update' -import { resolvePeer } from '../users/resolve-peer' +} from '../../utils/peer-utils.js' +import { _findMessageInUpdate } from '../messages/find-in-update.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Ban a user/channel from a legacy group, a supergroup or a channel. diff --git a/packages/client/src/methods/chats/create-channel.ts b/packages/client/src/methods/chats/create-channel.ts index b9388506..15c8acde 100644 --- a/packages/client/src/methods/chats/create-channel.ts +++ b/packages/client/src/methods/chats/create-channel.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Chat } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' +import { Chat } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' /** * Create a new broadcast channel diff --git a/packages/client/src/methods/chats/create-group.ts b/packages/client/src/methods/chats/create-group.ts index ae8d7d5d..2167d206 100644 --- a/packages/client/src/methods/chats/create-group.ts +++ b/packages/client/src/methods/chats/create-group.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { Chat, InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeerMany } from '../users/resolve-peer-many' +import { Chat, InputPeerLike } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeerMany } from '../users/resolve-peer-many.js' /** * Create a legacy group chat diff --git a/packages/client/src/methods/chats/create-supergroup.ts b/packages/client/src/methods/chats/create-supergroup.ts index 843ae040..70db4510 100644 --- a/packages/client/src/methods/chats/create-supergroup.ts +++ b/packages/client/src/methods/chats/create-supergroup.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Chat } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' +import { Chat } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' /** * Create a new supergroup diff --git a/packages/client/src/methods/chats/delete-channel.ts b/packages/client/src/methods/chats/delete-channel.ts index 5223386f..e4284eae 100644 --- a/packages/client/src/methods/chats/delete-channel.ts +++ b/packages/client/src/methods/chats/delete-channel.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' // @alias=deleteSupergroup /** diff --git a/packages/client/src/methods/chats/delete-chat-photo.ts b/packages/client/src/methods/chats/delete-chat-photo.ts index 37dc277a..aab09e23 100644 --- a/packages/client/src/methods/chats/delete-chat-photo.ts +++ b/packages/client/src/methods/chats/delete-chat-photo.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' -import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js' +import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Delete a chat photo diff --git a/packages/client/src/methods/chats/delete-group.ts b/packages/client/src/methods/chats/delete-group.ts index 3c3a3547..595cdeb2 100644 --- a/packages/client/src/methods/chats/delete-group.ts +++ b/packages/client/src/methods/chats/delete-group.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' -import { isInputPeerChat } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js' +import { isInputPeerChat } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Delete a legacy group chat for all members diff --git a/packages/client/src/methods/chats/delete-history.ts b/packages/client/src/methods/chats/delete-history.ts index 042500c9..4433ead5 100644 --- a/packages/client/src/methods/chats/delete-history.ts +++ b/packages/client/src/methods/chats/delete-history.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { isInputPeerChannel } from '../../utils/peer-utils' -import { createDummyUpdate } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { isInputPeerChannel } from '../../utils/peer-utils.js' +import { createDummyUpdate } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Delete communication history (for private chats and legacy groups) diff --git a/packages/client/src/methods/chats/delete-user-history.ts b/packages/client/src/methods/chats/delete-user-history.ts index 660f63ad..e69f9aa0 100644 --- a/packages/client/src/methods/chats/delete-user-history.ts +++ b/packages/client/src/methods/chats/delete-user-history.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { createDummyUpdate } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { createDummyUpdate } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Delete all messages of a user (or channel) in a supergroup diff --git a/packages/client/src/methods/chats/edit-admin-rights.ts b/packages/client/src/methods/chats/edit-admin-rights.ts index 2187ffb4..0b4bb1f0 100644 --- a/packages/client/src/methods/chats/edit-admin-rights.ts +++ b/packages/client/src/methods/chats/edit-admin-rights.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Edit supergroup/channel admin rights of a user. diff --git a/packages/client/src/methods/chats/get-chat-event-log.ts b/packages/client/src/methods/chats/get-chat-event-log.ts index d5f32392..e62d16ae 100644 --- a/packages/client/src/methods/chats/get-chat-event-log.ts +++ b/packages/client/src/methods/chats/get-chat-event-log.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import { ChatEvent, InputPeerLike, PeersIndex } from '../../types' -import { InputChatEventFilters, normalizeChatEventFilters } from '../../types/peers/chat-event/filters' -import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' -import { resolvePeerMany } from '../users/resolve-peer-many' +import { ChatEvent, InputPeerLike, PeersIndex } from '../../types/index.js' +import { InputChatEventFilters, normalizeChatEventFilters } from '../../types/peers/chat-event/filters.js' +import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { resolvePeerMany } from '../users/resolve-peer-many.js' /** * Get chat event log ("Recent actions" in official clients). diff --git a/packages/client/src/methods/chats/get-chat-member.ts b/packages/client/src/methods/chats/get-chat-member.ts index 3a37aa0b..940dce32 100644 --- a/packages/client/src/methods/chats/get-chat-member.ts +++ b/packages/client/src/methods/chats/get-chat-member.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types' -import { isInputPeerChannel, isInputPeerChat, isInputPeerUser, normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types/index.js' +import { isInputPeerChannel, isInputPeerChat, isInputPeerUser, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get information about a single chat member diff --git a/packages/client/src/methods/chats/get-chat-members.ts b/packages/client/src/methods/chats/get-chat-members.ts index 24a56ece..ca0c3902 100644 --- a/packages/client/src/methods/chats/get-chat-members.ts +++ b/packages/client/src/methods/chats/get-chat-members.ts @@ -1,10 +1,10 @@ import { assertNever, BaseTelegramClient, Long, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { ArrayWithTotal, ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types' -import { makeArrayWithTotal } from '../../utils' -import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { ArrayWithTotal, ChatMember, InputPeerLike, MtInvalidPeerTypeError, PeersIndex } from '../../types/index.js' +import { makeArrayWithTotal } from '../../utils/index.js' +import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get a chunk of members of some chat. diff --git a/packages/client/src/methods/chats/get-chat-preview.ts b/packages/client/src/methods/chats/get-chat-preview.ts index d07143c5..5cbec222 100644 --- a/packages/client/src/methods/chats/get-chat-preview.ts +++ b/packages/client/src/methods/chats/get-chat-preview.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { ChatPreview, MtPeerNotFoundError } from '../../types' -import { INVITE_LINK_REGEX } from '../../utils/peer-utils' +import { ChatPreview, MtPeerNotFoundError } from '../../types/index.js' +import { INVITE_LINK_REGEX } from '../../utils/peer-utils.js' /** * Get preview information about a private chat. diff --git a/packages/client/src/methods/chats/get-chat.ts b/packages/client/src/methods/chats/get-chat.ts index 9f295a2d..67c1aba1 100644 --- a/packages/client/src/methods/chats/get-chat.ts +++ b/packages/client/src/methods/chats/get-chat.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { Chat, InputPeerLike } from '../../types' +import { Chat, InputPeerLike } from '../../types/index.js' import { INVITE_LINK_REGEX, isInputPeerChannel, @@ -8,8 +8,8 @@ import { isInputPeerUser, normalizeToInputChannel, normalizeToInputUser, -} from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +} from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' // @available=both /** diff --git a/packages/client/src/methods/chats/get-full-chat.ts b/packages/client/src/methods/chats/get-full-chat.ts index 08900cc9..cb806171 100644 --- a/packages/client/src/methods/chats/get-full-chat.ts +++ b/packages/client/src/methods/chats/get-full-chat.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { Chat, InputPeerLike } from '../../types' +import { Chat, InputPeerLike } from '../../types/index.js' import { INVITE_LINK_REGEX, isInputPeerChannel, @@ -8,8 +8,8 @@ import { isInputPeerUser, normalizeToInputChannel, normalizeToInputUser, -} from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +} from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' // @available=both /** diff --git a/packages/client/src/methods/chats/get-nearby-chats.ts b/packages/client/src/methods/chats/get-nearby-chats.ts index 3122044b..376811ca 100644 --- a/packages/client/src/methods/chats/get-nearby-chats.ts +++ b/packages/client/src/methods/chats/get-nearby-chats.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, getMarkedPeerId, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { Chat } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' +import { Chat } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' /** * Get nearby chats diff --git a/packages/client/src/methods/chats/iter-chat-event-log.ts b/packages/client/src/methods/chats/iter-chat-event-log.ts index ac2ae9eb..52e634d1 100644 --- a/packages/client/src/methods/chats/iter-chat-event-log.ts +++ b/packages/client/src/methods/chats/iter-chat-event-log.ts @@ -1,11 +1,11 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import { ChatEvent, InputPeerLike } from '../../types' -import { normalizeChatEventFilters } from '../../types/peers/chat-event/filters' -import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' -import { resolvePeerMany } from '../users/resolve-peer-many' -import { getChatEventLog } from './get-chat-event-log' +import { ChatEvent, InputPeerLike } from '../../types/index.js' +import { normalizeChatEventFilters } from '../../types/peers/chat-event/filters.js' +import { normalizeToInputChannel, normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { resolvePeerMany } from '../users/resolve-peer-many.js' +import { getChatEventLog } from './get-chat-event-log.js' /** * Iterate over chat event log. diff --git a/packages/client/src/methods/chats/iter-chat-members.ts b/packages/client/src/methods/chats/iter-chat-members.ts index c3cd16c4..405b4f71 100644 --- a/packages/client/src/methods/chats/iter-chat-members.ts +++ b/packages/client/src/methods/chats/iter-chat-members.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ChatMember, InputPeerLike } from '../../types' -import { isInputPeerChat } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' -import { getChatMembers } from './get-chat-members' +import { ChatMember, InputPeerLike } from '../../types/index.js' +import { isInputPeerChat } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getChatMembers } from './get-chat-members.js' /** * Iterate through chat members diff --git a/packages/client/src/methods/chats/join-chat.ts b/packages/client/src/methods/chats/join-chat.ts index fe93678d..c630adc3 100644 --- a/packages/client/src/methods/chats/join-chat.ts +++ b/packages/client/src/methods/chats/join-chat.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Chat, InputPeerLike } from '../../types' -import { INVITE_LINK_REGEX, normalizeToInputChannel } from '../../utils/peer-utils' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { Chat, InputPeerLike } from '../../types/index.js' +import { INVITE_LINK_REGEX, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Join a channel or supergroup diff --git a/packages/client/src/methods/chats/kick-chat-member.ts b/packages/client/src/methods/chats/kick-chat-member.ts index ba98369a..10947afa 100644 --- a/packages/client/src/methods/chats/kick-chat-member.ts +++ b/packages/client/src/methods/chats/kick-chat-member.ts @@ -1,11 +1,11 @@ import { BaseTelegramClient } from '@mtcute/core' -import { sleep } from '@mtcute/core/utils' +import { sleep } from '@mtcute/core/utils.js' -import { InputPeerLike } from '../../types' -import { isInputPeerChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' -import { banChatMember } from './ban-chat-member' -import { unbanChatMember } from './unban-chat-member' +import { InputPeerLike } from '../../types/index.js' +import { isInputPeerChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { banChatMember } from './ban-chat-member.js' +import { unbanChatMember } from './unban-chat-member.js' /** * Kick a user from a chat. diff --git a/packages/client/src/methods/chats/leave-chat.ts b/packages/client/src/methods/chats/leave-chat.ts index ffd9c641..1b308fd0 100644 --- a/packages/client/src/methods/chats/leave-chat.ts +++ b/packages/client/src/methods/chats/leave-chat.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' -import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' -import { deleteHistory } from './delete-history' +import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js' +import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { deleteHistory } from './delete-history.js' /** * Leave a group chat, supergroup or channel diff --git a/packages/client/src/methods/chats/mark-chat-unread.ts b/packages/client/src/methods/chats/mark-chat-unread.ts index 232d024d..8e5131fc 100644 --- a/packages/client/src/methods/chats/mark-chat-unread.ts +++ b/packages/client/src/methods/chats/mark-chat-unread.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Mark a chat as unread diff --git a/packages/client/src/methods/chats/reorder-usernames.ts b/packages/client/src/methods/chats/reorder-usernames.ts index 47c29cf7..09b0c9e3 100644 --- a/packages/client/src/methods/chats/reorder-usernames.ts +++ b/packages/client/src/methods/chats/reorder-usernames.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { isInputPeerChannel, isInputPeerUser, normalizeToInputChannel, normalizeToInputUser } from '../../utils' -import { getAuthState } from '../auth/_state' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { isInputPeerChannel, isInputPeerUser, normalizeToInputChannel, normalizeToInputUser } from '../../utils/index.js' +import { getAuthState } from '../auth/_state.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Reorder usernames diff --git a/packages/client/src/methods/chats/restrict-chat-member.ts b/packages/client/src/methods/chats/restrict-chat-member.ts index f821a7d7..81a306f0 100644 --- a/packages/client/src/methods/chats/restrict-chat-member.ts +++ b/packages/client/src/methods/chats/restrict-chat-member.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' -import { normalizeDate } from '../../utils/misc-utils' -import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Restrict a user in a supergroup. diff --git a/packages/client/src/methods/chats/save-draft.ts b/packages/client/src/methods/chats/save-draft.ts index 434d0e59..d2bb4dd1 100644 --- a/packages/client/src/methods/chats/save-draft.ts +++ b/packages/client/src/methods/chats/save-draft.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Save or delete a draft message associated with some chat diff --git a/packages/client/src/methods/chats/set-chat-default-permissions.ts b/packages/client/src/methods/chats/set-chat-default-permissions.ts index 8d98001a..bd99fcd4 100644 --- a/packages/client/src/methods/chats/set-chat-default-permissions.ts +++ b/packages/client/src/methods/chats/set-chat-default-permissions.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { Chat, InputPeerLike } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { Chat, InputPeerLike } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Change default chat permissions for all members. diff --git a/packages/client/src/methods/chats/set-chat-description.ts b/packages/client/src/methods/chats/set-chat-description.ts index 65c378d4..a41bc5cc 100644 --- a/packages/client/src/methods/chats/set-chat-description.ts +++ b/packages/client/src/methods/chats/set-chat-description.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Change chat description diff --git a/packages/client/src/methods/chats/set-chat-photo.ts b/packages/client/src/methods/chats/set-chat-photo.ts index 3f3b9a3b..bbd48a4f 100644 --- a/packages/client/src/methods/chats/set-chat-photo.ts +++ b/packages/client/src/methods/chats/set-chat-photo.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' import { fileIdToInputPhoto, tdFileId } from '@mtcute/file-id' -import { InputFileLike, InputPeerLike, isUploadedFile, MtInvalidPeerTypeError } from '../../types' -import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils' -import { uploadFile } from '../files/upload-file' -import { resolvePeer } from '../users/resolve-peer' +import { InputFileLike, InputPeerLike, isUploadedFile, MtInvalidPeerTypeError } from '../../types/index.js' +import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { uploadFile } from '../files/upload-file.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set a new chat photo or video. diff --git a/packages/client/src/methods/chats/set-chat-title.ts b/packages/client/src/methods/chats/set-chat-title.ts index d5eb7981..35f54865 100644 --- a/packages/client/src/methods/chats/set-chat-title.ts +++ b/packages/client/src/methods/chats/set-chat-title.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' -import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js' +import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Change chat title diff --git a/packages/client/src/methods/chats/set-chat-ttl.ts b/packages/client/src/methods/chats/set-chat-ttl.ts index ba29f6f8..317bc08e 100644 --- a/packages/client/src/methods/chats/set-chat-ttl.ts +++ b/packages/client/src/methods/chats/set-chat-ttl.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set maximum Time-To-Live of all newly sent messages in the specified chat diff --git a/packages/client/src/methods/chats/set-chat-username.ts b/packages/client/src/methods/chats/set-chat-username.ts index 4ea2ec9c..0f475084 100644 --- a/packages/client/src/methods/chats/set-chat-username.ts +++ b/packages/client/src/methods/chats/set-chat-username.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Change supergroup/channel username diff --git a/packages/client/src/methods/chats/set-slow-mode.ts b/packages/client/src/methods/chats/set-slow-mode.ts index 7ca3fefb..5ebfa939 100644 --- a/packages/client/src/methods/chats/set-slow-mode.ts +++ b/packages/client/src/methods/chats/set-slow-mode.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set supergroup's slow mode interval. diff --git a/packages/client/src/methods/chats/toggle-content-protection.ts b/packages/client/src/methods/chats/toggle-content-protection.ts index eddfdc15..5c79dbf2 100644 --- a/packages/client/src/methods/chats/toggle-content-protection.ts +++ b/packages/client/src/methods/chats/toggle-content-protection.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set whether a chat has content protection (i.e. forwarding messages is disabled) diff --git a/packages/client/src/methods/chats/toggle-fragment-username.ts b/packages/client/src/methods/chats/toggle-fragment-username.ts index 913eb3ec..5d09fdb2 100644 --- a/packages/client/src/methods/chats/toggle-fragment-username.ts +++ b/packages/client/src/methods/chats/toggle-fragment-username.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { isInputPeerChannel, isInputPeerUser, normalizeToInputChannel, normalizeToInputUser } from '../../utils' -import { getAuthState } from '../auth/_state' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { isInputPeerChannel, isInputPeerUser, normalizeToInputChannel, normalizeToInputUser } from '../../utils/index.js' +import { getAuthState } from '../auth/_state.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Toggle a collectible (Fragment) username diff --git a/packages/client/src/methods/chats/toggle-join-requests.ts b/packages/client/src/methods/chats/toggle-join-requests.ts index da9cbb57..d3e9e7cc 100644 --- a/packages/client/src/methods/chats/toggle-join-requests.ts +++ b/packages/client/src/methods/chats/toggle-join-requests.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set whether a channel/supergroup has join requests enabled. diff --git a/packages/client/src/methods/chats/toggle-join-to-send.ts b/packages/client/src/methods/chats/toggle-join-to-send.ts index fd36864e..cde28beb 100644 --- a/packages/client/src/methods/chats/toggle-join-to-send.ts +++ b/packages/client/src/methods/chats/toggle-join-to-send.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set whether a channel/supergroup has join-to-send setting enabled. diff --git a/packages/client/src/methods/chats/unarchive-chats.ts b/packages/client/src/methods/chats/unarchive-chats.ts index 554cefbe..b00c5626 100644 --- a/packages/client/src/methods/chats/unarchive-chats.ts +++ b/packages/client/src/methods/chats/unarchive-chats.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MaybeArray, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Unarchive one or more chats diff --git a/packages/client/src/methods/chats/unban-chat-member.ts b/packages/client/src/methods/chats/unban-chat-member.ts index 69228a36..11f5db78 100644 --- a/packages/client/src/methods/chats/unban-chat-member.ts +++ b/packages/client/src/methods/chats/unban-chat-member.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, MtInvalidPeerTypeError } from '../../types' -import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, MtInvalidPeerTypeError } from '../../types/index.js' +import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' // @alias=unrestrictChatMember /** diff --git a/packages/client/src/methods/contacts/add-contact.ts b/packages/client/src/methods/contacts/add-contact.ts index 9e4c0c82..d5f3e6bf 100644 --- a/packages/client/src/methods/contacts/add-contact.ts +++ b/packages/client/src/methods/contacts/add-contact.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, User } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, User } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Add an existing Telegram user as a contact diff --git a/packages/client/src/methods/contacts/delete-contacts.ts b/packages/client/src/methods/contacts/delete-contacts.ts index 48138d3d..3f2b7320 100644 --- a/packages/client/src/methods/contacts/delete-contacts.ts +++ b/packages/client/src/methods/contacts/delete-contacts.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { InputPeerLike, MtInvalidPeerTypeError, User } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeerMany } from '../users/resolve-peer-many' +import { InputPeerLike, MtInvalidPeerTypeError, User } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeerMany } from '../users/resolve-peer-many.js' /** * Delete one or more contacts from your Telegram contacts list diff --git a/packages/client/src/methods/contacts/get-contacts.ts b/packages/client/src/methods/contacts/get-contacts.ts index 91635195..d6b8b4a5 100644 --- a/packages/client/src/methods/contacts/get-contacts.ts +++ b/packages/client/src/methods/contacts/get-contacts.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, Long } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { User } from '../../types' +import { User } from '../../types/index.js' /** * Get list of contacts from your Telegram contacts list. diff --git a/packages/client/src/methods/dialogs/create-folder.ts b/packages/client/src/methods/dialogs/create-folder.ts index b1372636..5043af43 100644 --- a/packages/client/src/methods/dialogs/create-folder.ts +++ b/packages/client/src/methods/dialogs/create-folder.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, PartialExcept, tl } from '@mtcute/core' -import { getFolders } from './get-folders' +import { getFolders } from './get-folders.js' /** * Create a folder from given parameters diff --git a/packages/client/src/methods/dialogs/edit-folder.ts b/packages/client/src/methods/dialogs/edit-folder.ts index fc04c922..c711e2d4 100644 --- a/packages/client/src/methods/dialogs/edit-folder.ts +++ b/packages/client/src/methods/dialogs/edit-folder.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { getFolders } from './get-folders' +import { getFolders } from './get-folders.js' /** * Edit a folder with given modification diff --git a/packages/client/src/methods/dialogs/find-folder.ts b/packages/client/src/methods/dialogs/find-folder.ts index 39121f22..655f60a9 100644 --- a/packages/client/src/methods/dialogs/find-folder.ts +++ b/packages/client/src/methods/dialogs/find-folder.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { getFolders } from './get-folders' +import { getFolders } from './get-folders.js' /** * Find a folder by its parameter. diff --git a/packages/client/src/methods/dialogs/get-folders.ts b/packages/client/src/methods/dialogs/get-folders.ts index b4a8e716..cd709fd0 100644 --- a/packages/client/src/methods/dialogs/get-folders.ts +++ b/packages/client/src/methods/dialogs/get-folders.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { InputDialogFolder } from '../../types' +import { InputDialogFolder } from '../../types/index.js' /** * Get list of folders. diff --git a/packages/client/src/methods/dialogs/get-peer-dialogs.ts b/packages/client/src/methods/dialogs/get-peer-dialogs.ts index 36634cb4..85ea32a4 100644 --- a/packages/client/src/methods/dialogs/get-peer-dialogs.ts +++ b/packages/client/src/methods/dialogs/get-peer-dialogs.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { Dialog } from '../../types/messages/dialog' -import { InputPeerLike } from '../../types/peers' -import { resolvePeerMany } from '../users/resolve-peer-many' +import { Dialog } from '../../types/messages/dialog.js' +import { InputPeerLike } from '../../types/peers/index.js' +import { resolvePeerMany } from '../users/resolve-peer-many.js' /** * Get dialogs with certain peers. diff --git a/packages/client/src/methods/dialogs/iter-dialogs.ts b/packages/client/src/methods/dialogs/iter-dialogs.ts index 44b3137a..170754a3 100644 --- a/packages/client/src/methods/dialogs/iter-dialogs.ts +++ b/packages/client/src/methods/dialogs/iter-dialogs.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, Long, MtUnsupportedError, tl } from '@mtcute/core' -import { Dialog, InputDialogFolder } from '../../types' -import { normalizeDate } from '../../utils/misc-utils' -import { _normalizeInputFolder } from './get-folders' +import { Dialog, InputDialogFolder } from '../../types/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { _normalizeInputFolder } from './get-folders.js' /** * Iterate over dialogs. diff --git a/packages/client/src/methods/files/download-buffer.ts b/packages/client/src/methods/files/download-buffer.ts index 7130122f..419cbeb7 100644 --- a/packages/client/src/methods/files/download-buffer.ts +++ b/packages/client/src/methods/files/download-buffer.ts @@ -1,7 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' +import { concatBuffers } from '@mtcute/core/utils.js' -import { FileDownloadParameters, FileLocation } from '../../types' -import { downloadAsIterable } from './download-iterable' +import { FileDownloadParameters, FileLocation } from '../../types/index.js' +import { downloadAsIterable } from './download-iterable.js' /** * Download a file and return its contents as a Buffer. @@ -11,8 +12,11 @@ import { downloadAsIterable } from './download-iterable' * * @param params File download parameters */ -export async function downloadAsBuffer(client: BaseTelegramClient, params: FileDownloadParameters): Promise { - if (params.location instanceof FileLocation && Buffer.isBuffer(params.location.location)) { +export async function downloadAsBuffer( + client: BaseTelegramClient, + params: FileDownloadParameters, +): Promise { + if (params.location instanceof FileLocation && ArrayBuffer.isView(params.location.location)) { return params.location.location } @@ -22,5 +26,5 @@ export async function downloadAsBuffer(client: BaseTelegramClient, params: FileD chunks.push(chunk) } - return Buffer.concat(chunks) + return concatBuffers(chunks) } diff --git a/packages/client/src/methods/files/download-file.ts b/packages/client/src/methods/files/download-file.ts index 3f22267c..23c82531 100644 --- a/packages/client/src/methods/files/download-file.ts +++ b/packages/client/src/methods/files/download-file.ts @@ -1,10 +1,15 @@ +import { createRequire } from 'module' + import { BaseTelegramClient, MtUnsupportedError } from '@mtcute/core' -import { FileDownloadParameters, FileLocation } from '../../types' -import { downloadAsStream } from './download-stream' +import { FileDownloadParameters, FileLocation } from '../../types/index.js' +import { downloadAsStream } from './download-stream.js' let fs: typeof import('fs') | null = null try { + // @only-if-esm + const require = createRequire(import.meta.url) + // @/only-if-esm fs = require('fs') as typeof import('fs') } catch (e) {} @@ -24,7 +29,7 @@ export function downloadToFile( throw new MtUnsupportedError('Downloading to file is only supported in NodeJS') } - if (params.location instanceof FileLocation && Buffer.isBuffer(params.location.location)) { + if (params.location instanceof FileLocation && ArrayBuffer.isView(params.location.location)) { // early return for inline files const buf = params.location.location diff --git a/packages/client/src/methods/files/download-iterable.ts b/packages/client/src/methods/files/download-iterable.ts index 2501828a..f313fa2c 100644 --- a/packages/client/src/methods/files/download-iterable.ts +++ b/packages/client/src/methods/files/download-iterable.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, ConnectionKind, MtArgumentError, MtUnsupportedError, tl } from '@mtcute/core' -import { ConditionVariable } from '@mtcute/core/utils' +import { ConditionVariable } from '@mtcute/core/utils.js' import { fileIdToInputFileLocation, fileIdToInputWebFileLocation, parseFileId } from '@mtcute/file-id' -import { FileDownloadParameters, FileLocation } from '../../types' -import { determinePartSize } from '../../utils/file-utils' +import { FileDownloadParameters, FileLocation } from '../../types/index.js' +import { determinePartSize } from '../../utils/file-utils.js' // small files (less than 128 kb) are downloaded using the "downloadSmall" pool // furthermore, if the file is small and is located on our main DC, it will be downloaded @@ -21,7 +21,7 @@ const REQUESTS_PER_CONNECTION = 3 // some arbitrary magic value that seems to wo export async function* downloadAsIterable( client: BaseTelegramClient, params: FileDownloadParameters, -): AsyncIterableIterator { +): AsyncIterableIterator { const offset = params.offset ?? 0 if (offset % 4096 !== 0) { @@ -40,7 +40,7 @@ export async function* downloadAsIterable( locationInner = locationInner() } - if (Buffer.isBuffer(locationInner)) { + if (ArrayBuffer.isView(locationInner)) { yield locationInner return @@ -79,7 +79,7 @@ export async function* downloadAsIterable( let nextChunkIdx = 0 let nextWorkerChunkIdx = 0 const nextChunkCv = new ConditionVariable() - const buffer: Record = {} + const buffer: Record = {} const isSmall = fileSize && fileSize <= SMALL_FILE_MAX_SIZE let connectionKind: ConnectionKind diff --git a/packages/client/src/methods/files/download-stream.ts b/packages/client/src/methods/files/download-stream.ts index f29b79c2..528ec613 100644 --- a/packages/client/src/methods/files/download-stream.ts +++ b/packages/client/src/methods/files/download-stream.ts @@ -2,9 +2,9 @@ import { Readable } from 'stream' import { BaseTelegramClient } from '@mtcute/core' -import { FileDownloadParameters, FileLocation } from '../../types' -import { bufferToStream } from '../../utils/stream-utils' -import { downloadAsIterable } from './download-iterable' +import { FileDownloadParameters, FileLocation } from '../../types/index.js' +import { bufferToStream } from '../../utils/stream-utils.js' +import { downloadAsIterable } from './download-iterable.js' /** * Download a file and return it as a Node readable stream, @@ -13,7 +13,7 @@ import { downloadAsIterable } from './download-iterable' * @param params File download parameters */ export function downloadAsStream(client: BaseTelegramClient, params: FileDownloadParameters): Readable { - if (params.location instanceof FileLocation && Buffer.isBuffer(params.location.location)) { + if (params.location instanceof FileLocation && ArrayBuffer.isView(params.location.location)) { return bufferToStream(params.location.location) } diff --git a/packages/client/src/methods/files/normalize-file-to-document.ts b/packages/client/src/methods/files/normalize-file-to-document.ts index b5bf9ebe..3b49c420 100644 --- a/packages/client/src/methods/files/normalize-file-to-document.ts +++ b/packages/client/src/methods/files/normalize-file-to-document.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { InputFileLike } from '../../types' -import { _normalizeInputMedia } from './normalize-input-media' +import { InputFileLike } from '../../types/index.js' +import { _normalizeInputMedia } from './normalize-input-media.js' /** * @internal diff --git a/packages/client/src/methods/files/normalize-input-file.ts b/packages/client/src/methods/files/normalize-input-file.ts index e38bc1b5..c3e35b9e 100644 --- a/packages/client/src/methods/files/normalize-input-file.ts +++ b/packages/client/src/methods/files/normalize-input-file.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' import { tdFileId } from '@mtcute/file-id' -import { InputFileLike, isUploadedFile } from '../../types/files' -import { uploadFile } from './upload-file' +import { InputFileLike, isUploadedFile } from '../../types/files/index.js' +import { uploadFile } from './upload-file.js' /** * Normalize a {@link InputFileLike} to `InputFile`, diff --git a/packages/client/src/methods/files/normalize-input-media.ts b/packages/client/src/methods/files/normalize-input-media.ts index 60f9711e..d44d2129 100644 --- a/packages/client/src/methods/files/normalize-input-media.ts +++ b/packages/client/src/methods/files/normalize-input-media.ts @@ -1,17 +1,17 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' import { fileIdToInputDocument, fileIdToInputPhoto, parseFileId, tdFileId } from '@mtcute/file-id' -import { isUploadedFile } from '../../types/files/uploaded-file' -import { UploadFileLike } from '../../types/files/utils' -import { InputMediaLike } from '../../types/media/input-media' -import { extractFileName } from '../../utils/file-utils' -import { normalizeDate } from '../../utils/misc-utils' -import { encodeWaveform } from '../../utils/voice-utils' -import { _parseEntities } from '../messages/parse-entities' -import { resolvePeer } from '../users/resolve-peer' -import { _normalizeInputFile } from './normalize-input-file' -import { uploadFile } from './upload-file' +import { isUploadedFile } from '../../types/files/uploaded-file.js' +import { UploadFileLike } from '../../types/files/utils.js' +import { InputMediaLike } from '../../types/media/input-media.js' +import { extractFileName } from '../../utils/file-utils.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { encodeWaveform } from '../../utils/voice-utils.js' +import { _parseEntities } from '../messages/parse-entities.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _normalizeInputFile } from './normalize-input-file.js' +import { uploadFile } from './upload-file.js' /** * Normalize an {@link InputMediaLike} to `InputMedia`, @@ -142,14 +142,14 @@ export async function _normalizeInputMedia( _: 'pollAnswer', text: ans, // emulate the behaviour of most implementations - option: Buffer.from([48 /* '0' */ + idx]), + option: new Uint8Array([48 /* '0' */ + idx]), } } return ans }) - let correct: Buffer[] | undefined = undefined + let correct: Uint8Array[] | undefined = undefined let solution: string | undefined = undefined let solutionEntities: tl.TypeMessageEntity[] | undefined = undefined diff --git a/packages/client/src/methods/files/upload-file.ts b/packages/client/src/methods/files/upload-file.ts index 470eaa22..2dc6344f 100644 --- a/packages/client/src/methods/files/upload-file.ts +++ b/packages/client/src/methods/files/upload-file.ts @@ -1,18 +1,24 @@ -import { fromBuffer as fileTypeFromBuffer } from 'file-type' +import fileType from 'file-type' import type { ReadStream } from 'fs' +import { createRequire } from 'module' import { Readable } from 'stream' import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { AsyncLock, randomLong } from '@mtcute/core/utils' +import { AsyncLock, randomLong } from '@mtcute/core/utils.js' -import { UploadedFile, UploadFileLike } from '../../types' -import { determinePartSize, isProbablyPlainText } from '../../utils/file-utils' -import { bufferToStream, convertWebStreamToNodeReadable, readBytesFromStream } from '../../utils/stream-utils' +import { UploadedFile, UploadFileLike } from '../../types/index.js' +import { determinePartSize, isProbablyPlainText } from '../../utils/file-utils.js' +import { bufferToStream, convertWebStreamToNodeReadable, readBytesFromStream } from '../../utils/stream-utils.js' + +const { fromBuffer: fileTypeFromBuffer } = fileType let fs: typeof import('fs') | null = null let path: typeof import('path') | null = null try { + // @only-if-esm + const require = createRequire(import.meta.url) + // @/only-if-esm fs = require('fs') as typeof import('fs') path = require('path') as typeof import('path') } catch (e) {} @@ -104,7 +110,7 @@ export async function uploadFile( let fileName = DEFAULT_FILE_NAME let fileMime = params.fileMime - if (Buffer.isBuffer(file)) { + if (ArrayBuffer.isView(file)) { fileSize = file.length file = bufferToStream(file) } @@ -252,12 +258,12 @@ export async function uploadFile( if (fileSize === -1 && (stream.readableEnded || !part)) { fileSize = pos + (part?.length ?? 0) partCount = ~~((fileSize + partSize - 1) / partSize) - if (!part) part = Buffer.alloc(0) + if (!part) part = new Uint8Array(0) client.log.debug('readable ended, file size = %d, part count = %d', fileSize, partCount) } - if (!Buffer.isBuffer(part)) { - throw new MtArgumentError(`Part ${thisIdx} was not a Buffer!`) + if (!ArrayBuffer.isView(part)) { + throw new MtArgumentError(`Part ${thisIdx} was not a Uint8Array!`) } if (part.length > partSize) { throw new MtArgumentError(`Part ${thisIdx} had invalid size (expected ${partSize}, got ${part.length})`) diff --git a/packages/client/src/methods/files/upload-media.ts b/packages/client/src/methods/files/upload-media.ts index 71b15275..48cfacde 100644 --- a/packages/client/src/methods/files/upload-media.ts +++ b/packages/client/src/methods/files/upload-media.ts @@ -1,10 +1,10 @@ import { assertNever, BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { assertTypeIs, assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIs, assertTypeIsNot } from '@mtcute/core/utils.js' -import { InputMediaLike, InputPeerLike, MessageMedia, Photo, RawDocument } from '../../types' -import { parseDocument } from '../../types/media/document-utils' -import { resolvePeer } from '../users/resolve-peer' -import { _normalizeInputMedia } from './normalize-input-media' +import { InputMediaLike, InputPeerLike, MessageMedia, Photo, RawDocument } from '../../types/index.js' +import { parseDocument } from '../../types/media/document-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _normalizeInputMedia } from './normalize-input-media.js' /** * Upload a media to Telegram servers, without actually diff --git a/packages/client/src/methods/forums/create-forum-topic.ts b/packages/client/src/methods/forums/create-forum-topic.ts index 0933496f..9acc7e42 100644 --- a/packages/client/src/methods/forums/create-forum-topic.ts +++ b/packages/client/src/methods/forums/create-forum-topic.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { randomLong } from '@mtcute/core/utils' +import { randomLong } from '@mtcute/core/utils.js' -import { InputPeerLike, Message } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { _findMessageInUpdate } from '../messages/find-in-update' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, Message } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { _findMessageInUpdate } from '../messages/find-in-update.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Create a topic in a forum diff --git a/packages/client/src/methods/forums/delete-forum-topic-history.ts b/packages/client/src/methods/forums/delete-forum-topic-history.ts index 6f13f71e..85b9d9b3 100644 --- a/packages/client/src/methods/forums/delete-forum-topic-history.ts +++ b/packages/client/src/methods/forums/delete-forum-topic-history.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import type { ForumTopic, InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { createDummyUpdate } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import type { ForumTopic, InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { createDummyUpdate } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Delete a forum topic and all its history diff --git a/packages/client/src/methods/forums/edit-forum-topic.ts b/packages/client/src/methods/forums/edit-forum-topic.ts index f00c71c9..0ad4a8be 100644 --- a/packages/client/src/methods/forums/edit-forum-topic.ts +++ b/packages/client/src/methods/forums/edit-forum-topic.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import type { ForumTopic, InputPeerLike, Message } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { _findMessageInUpdate } from '../messages/find-in-update' -import { resolvePeer } from '../users/resolve-peer' +import type { ForumTopic, InputPeerLike, Message } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { _findMessageInUpdate } from '../messages/find-in-update.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Modify a topic in a forum diff --git a/packages/client/src/methods/forums/get-forum-topics-by-id.ts b/packages/client/src/methods/forums/get-forum-topics-by-id.ts index 29eec967..203441b5 100644 --- a/packages/client/src/methods/forums/get-forum-topics-by-id.ts +++ b/packages/client/src/methods/forums/get-forum-topics-by-id.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { ForumTopic, InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils' -import { resolvePeer } from '../users/resolve-peer' +import { ForumTopic, InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get forum topics by their IDs diff --git a/packages/client/src/methods/forums/get-forum-topics.ts b/packages/client/src/methods/forums/get-forum-topics.ts index daf18d24..6575a371 100644 --- a/packages/client/src/methods/forums/get-forum-topics.ts +++ b/packages/client/src/methods/forums/get-forum-topics.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ArrayPaginated, ForumTopic, InputPeerLike } from '../../types' -import { makeArrayPaginated } from '../../utils' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { ArrayPaginated, ForumTopic, InputPeerLike } from '../../types/index.js' +import { makeArrayPaginated } from '../../utils/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' // @exported export interface GetForumTopicsOffset { diff --git a/packages/client/src/methods/forums/iter-forum-topics.ts b/packages/client/src/methods/forums/iter-forum-topics.ts index 624db236..556b08cb 100644 --- a/packages/client/src/methods/forums/iter-forum-topics.ts +++ b/packages/client/src/methods/forums/iter-forum-topics.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ForumTopic, InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' -import { getForumTopics } from './get-forum-topics' +import { ForumTopic, InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getForumTopics } from './get-forum-topics.js' /** * Iterate over forum topics. Wrapper over {@link getForumTopics}. diff --git a/packages/client/src/methods/forums/reorder-pinned-forum-topics.ts b/packages/client/src/methods/forums/reorder-pinned-forum-topics.ts index f66a66d2..c2dfe281 100644 --- a/packages/client/src/methods/forums/reorder-pinned-forum-topics.ts +++ b/packages/client/src/methods/forums/reorder-pinned-forum-topics.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import type { ForumTopic, InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import type { ForumTopic, InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Reorder pinned forum topics diff --git a/packages/client/src/methods/forums/toggle-forum-topic-closed.ts b/packages/client/src/methods/forums/toggle-forum-topic-closed.ts index 76969a3c..ebacd204 100644 --- a/packages/client/src/methods/forums/toggle-forum-topic-closed.ts +++ b/packages/client/src/methods/forums/toggle-forum-topic-closed.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import type { ForumTopic, InputPeerLike, Message } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { _findMessageInUpdate } from '../messages/find-in-update' -import { resolvePeer } from '../users/resolve-peer' +import type { ForumTopic, InputPeerLike, Message } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { _findMessageInUpdate } from '../messages/find-in-update.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Toggle open/close status of a topic in a forum diff --git a/packages/client/src/methods/forums/toggle-forum-topic-pinned.ts b/packages/client/src/methods/forums/toggle-forum-topic-pinned.ts index 800f007d..7d105386 100644 --- a/packages/client/src/methods/forums/toggle-forum-topic-pinned.ts +++ b/packages/client/src/methods/forums/toggle-forum-topic-pinned.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ForumTopic, InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { ForumTopic, InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Toggle whether a topic in a forum is pinned diff --git a/packages/client/src/methods/forums/toggle-forum.ts b/packages/client/src/methods/forums/toggle-forum.ts index d9538ce1..a1fb0f82 100644 --- a/packages/client/src/methods/forums/toggle-forum.ts +++ b/packages/client/src/methods/forums/toggle-forum.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set whether a supergroup is a forum. diff --git a/packages/client/src/methods/forums/toggle-general-topic-hidden.ts b/packages/client/src/methods/forums/toggle-general-topic-hidden.ts index 493e285b..8535aecc 100644 --- a/packages/client/src/methods/forums/toggle-general-topic-hidden.ts +++ b/packages/client/src/methods/forums/toggle-general-topic-hidden.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, Message } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { _findMessageInUpdate } from '../messages/find-in-update' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, Message } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { _findMessageInUpdate } from '../messages/find-in-update.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Toggle whether "General" topic in a forum is hidden or not diff --git a/packages/client/src/methods/invite-links/create-invite-link.ts b/packages/client/src/methods/invite-links/create-invite-link.ts index f4a98789..c7034e4b 100644 --- a/packages/client/src/methods/invite-links/create-invite-link.ts +++ b/packages/client/src/methods/invite-links/create-invite-link.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ChatInviteLink, InputPeerLike } from '../../types' -import { normalizeDate } from '../../utils/misc-utils' -import { resolvePeer } from '../users/resolve-peer' +import { ChatInviteLink, InputPeerLike } from '../../types/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Create an additional invite link for the chat. diff --git a/packages/client/src/methods/invite-links/edit-invite-link.ts b/packages/client/src/methods/invite-links/edit-invite-link.ts index 8bb51db7..ea22269e 100644 --- a/packages/client/src/methods/invite-links/edit-invite-link.ts +++ b/packages/client/src/methods/invite-links/edit-invite-link.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types' -import { normalizeDate } from '../../utils/misc-utils' -import { resolvePeer } from '../users/resolve-peer' +import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Edit an invite link. You can only edit non-primary diff --git a/packages/client/src/methods/invite-links/export-invite-link.ts b/packages/client/src/methods/invite-links/export-invite-link.ts index 4f6a9695..ef63c1f8 100644 --- a/packages/client/src/methods/invite-links/export-invite-link.ts +++ b/packages/client/src/methods/invite-links/export-invite-link.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ChatInviteLink, InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { ChatInviteLink, InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Generate a new primary invite link for a chat, diff --git a/packages/client/src/methods/invite-links/get-invite-link-members.ts b/packages/client/src/methods/invite-links/get-invite-link-members.ts index a91b0660..b2ffebe7 100644 --- a/packages/client/src/methods/invite-links/get-invite-link-members.ts +++ b/packages/client/src/methods/invite-links/get-invite-link-members.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { ArrayPaginated, ChatInviteLink, ChatInviteLinkMember, InputPeerLike, PeersIndex } from '../../types' -import { makeArrayPaginated, normalizeDate, normalizeToInputUser } from '../../utils' -import { resolvePeer } from '../users/resolve-peer' +import { ArrayPaginated, ChatInviteLink, ChatInviteLinkMember, InputPeerLike, PeersIndex } from '../../types/index.js' +import { makeArrayPaginated, normalizeDate, normalizeToInputUser } from '../../utils/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Iterate over users who have joined diff --git a/packages/client/src/methods/invite-links/get-invite-link.ts b/packages/client/src/methods/invite-links/get-invite-link.ts index 272fb4ce..3485e78c 100644 --- a/packages/client/src/methods/invite-links/get-invite-link.ts +++ b/packages/client/src/methods/invite-links/get-invite-link.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get detailed information about an invite link diff --git a/packages/client/src/methods/invite-links/get-invite-links.ts b/packages/client/src/methods/invite-links/get-invite-links.ts index 08f101d0..c7b5fe8c 100644 --- a/packages/client/src/methods/invite-links/get-invite-links.ts +++ b/packages/client/src/methods/invite-links/get-invite-links.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ArrayPaginated, ChatInviteLink, InputPeerLike, PeersIndex } from '../../types' -import { makeArrayPaginated } from '../../utils' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { ArrayPaginated, ChatInviteLink, InputPeerLike, PeersIndex } from '../../types/index.js' +import { makeArrayPaginated } from '../../utils/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' // @exported export interface GetInviteLinksOffset { diff --git a/packages/client/src/methods/invite-links/get-primary-invite-link.ts b/packages/client/src/methods/invite-links/get-primary-invite-link.ts index 27a110ae..c34d95a2 100644 --- a/packages/client/src/methods/invite-links/get-primary-invite-link.ts +++ b/packages/client/src/methods/invite-links/get-primary-invite-link.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MtTypeAssertionError } from '@mtcute/core' -import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get primary invite link of a chat diff --git a/packages/client/src/methods/invite-links/hide-all-join-requests.ts b/packages/client/src/methods/invite-links/hide-all-join-requests.ts index 7273fea6..b1a479c1 100644 --- a/packages/client/src/methods/invite-links/hide-all-join-requests.ts +++ b/packages/client/src/methods/invite-links/hide-all-join-requests.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import type { ChatInviteLink, InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import type { ChatInviteLink, InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Approve or decline multiple join requests to a chat. diff --git a/packages/client/src/methods/invite-links/hide-join-request.ts b/packages/client/src/methods/invite-links/hide-join-request.ts index f30f885c..357a4ec5 100644 --- a/packages/client/src/methods/invite-links/hide-join-request.ts +++ b/packages/client/src/methods/invite-links/hide-join-request.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Approve or decline join request to a chat. diff --git a/packages/client/src/methods/invite-links/iter-invite-link-members.ts b/packages/client/src/methods/invite-links/iter-invite-link-members.ts index 4ffe3a47..d0edcfa4 100644 --- a/packages/client/src/methods/invite-links/iter-invite-link-members.ts +++ b/packages/client/src/methods/invite-links/iter-invite-link-members.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ChatInviteLinkMember, InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' -import { getInviteLinkMembers } from './get-invite-link-members' +import { ChatInviteLinkMember, InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getInviteLinkMembers } from './get-invite-link-members.js' /** * Iterate over users who have joined diff --git a/packages/client/src/methods/invite-links/iter-invite-links.ts b/packages/client/src/methods/invite-links/iter-invite-links.ts index 0050d94f..2fca8eff 100644 --- a/packages/client/src/methods/invite-links/iter-invite-links.ts +++ b/packages/client/src/methods/invite-links/iter-invite-links.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ChatInviteLink, InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' -import { getInviteLinks } from './get-invite-links' +import { ChatInviteLink, InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getInviteLinks } from './get-invite-links.js' /** * Iterate over invite links created by some administrator in the chat. diff --git a/packages/client/src/methods/invite-links/revoke-invite-link.ts b/packages/client/src/methods/invite-links/revoke-invite-link.ts index aa702cf7..14df0ef9 100644 --- a/packages/client/src/methods/invite-links/revoke-invite-link.ts +++ b/packages/client/src/methods/invite-links/revoke-invite-link.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { ChatInviteLink, InputPeerLike, PeersIndex } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Revoke an invite link. diff --git a/packages/client/src/methods/messages/close-poll.ts b/packages/client/src/methods/messages/close-poll.ts index 3ceeab4c..bb0ead38 100644 --- a/packages/client/src/methods/messages/close-poll.ts +++ b/packages/client/src/methods/messages/close-poll.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, Long, MtTypeAssertionError } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { InputMessageId, normalizeInputMessageId, PeersIndex, Poll } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputMessageId, normalizeInputMessageId, PeersIndex, Poll } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Close a poll sent by you. diff --git a/packages/client/src/methods/messages/delete-messages.ts b/packages/client/src/methods/messages/delete-messages.ts index 4101d1f8..f8cb805d 100644 --- a/packages/client/src/methods/messages/delete-messages.ts +++ b/packages/client/src/methods/messages/delete-messages.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike, Message } from '../../types' -import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils' -import { createDummyUpdate } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' -import { deleteScheduledMessages } from './delete-scheduled-messages' +import { InputPeerLike, Message } from '../../types/index.js' +import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { createDummyUpdate } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { deleteScheduledMessages } from './delete-scheduled-messages.js' // @exported export interface DeleteMessagesParams { diff --git a/packages/client/src/methods/messages/delete-scheduled-messages.ts b/packages/client/src/methods/messages/delete-scheduled-messages.ts index a5c8a8ba..07ee3ca1 100644 --- a/packages/client/src/methods/messages/delete-scheduled-messages.ts +++ b/packages/client/src/methods/messages/delete-scheduled-messages.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Delete scheduled messages by their IDs. diff --git a/packages/client/src/methods/messages/edit-inline-message.ts b/packages/client/src/methods/messages/edit-inline-message.ts index 238d9f27..9bcd4154 100644 --- a/packages/client/src/methods/messages/edit-inline-message.ts +++ b/packages/client/src/methods/messages/edit-inline-message.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { BotKeyboard, FormattedString, InputMediaLike, ReplyMarkup } from '../../types' -import { normalizeInlineId } from '../../utils/inline-utils' -import { _normalizeInputMedia } from '../files/normalize-input-media' -import { _parseEntities } from './parse-entities' +import { BotKeyboard, FormattedString, InputMediaLike, ReplyMarkup } from '../../types/index.js' +import { normalizeInlineId } from '../../utils/inline-utils.js' +import { _normalizeInputMedia } from '../files/normalize-input-media.js' +import { _parseEntities } from './parse-entities.js' /** * Edit sent inline message text, media and reply markup. diff --git a/packages/client/src/methods/messages/edit-message.ts b/packages/client/src/methods/messages/edit-message.ts index 2a106a40..79258c81 100644 --- a/packages/client/src/methods/messages/edit-message.ts +++ b/packages/client/src/methods/messages/edit-message.ts @@ -8,11 +8,11 @@ import { Message, normalizeInputMessageId, ReplyMarkup, -} from '../../types' -import { _normalizeInputMedia } from '../files/normalize-input-media' -import { resolvePeer } from '../users/resolve-peer' -import { _findMessageInUpdate } from './find-in-update' -import { _parseEntities } from './parse-entities' +} from '../../types/index.js' +import { _normalizeInputMedia } from '../files/normalize-input-media.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _findMessageInUpdate } from './find-in-update.js' +import { _parseEntities } from './parse-entities.js' /** * Edit message text, media, reply markup and schedule date. diff --git a/packages/client/src/methods/messages/find-in-update.ts b/packages/client/src/methods/messages/find-in-update.ts index 830a867a..829f4d31 100644 --- a/packages/client/src/methods/messages/find-in-update.ts +++ b/packages/client/src/methods/messages/find-in-update.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MtTypeAssertionError, tl } from '@mtcute/core' -import { Message } from '../../types/messages' -import { PeersIndex } from '../../types/peers' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' +import { Message } from '../../types/messages/index.js' +import { PeersIndex } from '../../types/peers/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' /** @internal */ export function _findMessageInUpdate( diff --git a/packages/client/src/methods/messages/forward-messages.ts b/packages/client/src/methods/messages/forward-messages.ts index 580c0635..17d38925 100644 --- a/packages/client/src/methods/messages/forward-messages.ts +++ b/packages/client/src/methods/messages/forward-messages.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { randomLong } from '@mtcute/core/utils' +import { randomLong } from '@mtcute/core/utils.js' -import { FormattedString, InputMediaLike, InputPeerLike, Message, PeersIndex } from '../../types' -import { normalizeDate } from '../../utils/misc-utils' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { FormattedString, InputMediaLike, InputPeerLike, Message, PeersIndex } from '../../types/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' // @exported export interface ForwardMessageOptions { diff --git a/packages/client/src/methods/messages/get-discussion-message.ts b/packages/client/src/methods/messages/get-discussion-message.ts index 392f65ba..784c43b5 100644 --- a/packages/client/src/methods/messages/get-discussion-message.ts +++ b/packages/client/src/methods/messages/get-discussion-message.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputMessageId, Message, normalizeInputMessageId } from '../../types/messages' -import { InputPeerLike, PeersIndex } from '../../types/peers' -import { resolvePeer } from '../users/resolve-peer' +import { InputMessageId, Message, normalizeInputMessageId } from '../../types/messages/index.js' +import { InputPeerLike, PeersIndex } from '../../types/peers/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** @internal */ export async function _getDiscussionMessage( diff --git a/packages/client/src/methods/messages/get-history.ts b/packages/client/src/methods/messages/get-history.ts index 2e6a6aef..71f25bdc 100644 --- a/packages/client/src/methods/messages/get-history.ts +++ b/packages/client/src/methods/messages/get-history.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { ArrayPaginated, InputPeerLike, Message, PeersIndex } from '../../types' -import { makeArrayPaginated } from '../../utils' -import { resolvePeer } from '../users/resolve-peer' +import { ArrayPaginated, InputPeerLike, Message, PeersIndex } from '../../types/index.js' +import { makeArrayPaginated } from '../../utils/index.js' +import { resolvePeer } from '../users/resolve-peer.js' // @exported export interface GetHistoryOffset { diff --git a/packages/client/src/methods/messages/get-message-group.ts b/packages/client/src/methods/messages/get-message-group.ts index 19d4bdfd..13aed8d6 100644 --- a/packages/client/src/methods/messages/get-message-group.ts +++ b/packages/client/src/methods/messages/get-message-group.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { isPresent } from '@mtcute/core/utils' +import { isPresent } from '@mtcute/core/utils.js' -import { InputMessageId, Message, normalizeInputMessageId } from '../../types' -import { isInputPeerChannel } from '../../utils/peer-utils' -import { resolvePeer } from '../users/resolve-peer' -import { getMessages } from './get-messages' +import { InputMessageId, Message, normalizeInputMessageId } from '../../types/index.js' +import { isInputPeerChannel } from '../../utils/peer-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getMessages } from './get-messages.js' /** * Get all messages inside of a message group diff --git a/packages/client/src/methods/messages/get-message-reactions.ts b/packages/client/src/methods/messages/get-message-reactions.ts index 6213089e..1f49d6d7 100644 --- a/packages/client/src/methods/messages/get-message-reactions.ts +++ b/packages/client/src/methods/messages/get-message-reactions.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, getMarkedPeerId } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { InputPeerLike, Message, MessageReactions, PeersIndex } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, Message, MessageReactions, PeersIndex } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get reactions to messages by their IDs. diff --git a/packages/client/src/methods/messages/get-messages-unsafe.ts b/packages/client/src/methods/messages/get-messages-unsafe.ts index e83aeac0..a4542953 100644 --- a/packages/client/src/methods/messages/get-messages-unsafe.ts +++ b/packages/client/src/methods/messages/get-messages-unsafe.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MaybeArray, tl } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { Message, PeersIndex } from '../../types' +import { Message, PeersIndex } from '../../types/index.js' /** * Get messages from PM or legacy group by their IDs. diff --git a/packages/client/src/methods/messages/get-messages.ts b/packages/client/src/methods/messages/get-messages.ts index 441f9a81..d4a5189d 100644 --- a/packages/client/src/methods/messages/get-messages.ts +++ b/packages/client/src/methods/messages/get-messages.ts @@ -1,11 +1,11 @@ import { BaseTelegramClient, MaybeArray, tl } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { Message } from '../../types/messages' -import { InputPeerLike, PeersIndex } from '../../types/peers' -import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils' -import { getAuthState } from '../auth/_state' -import { resolvePeer } from '../users/resolve-peer' +import { Message } from '../../types/messages/index.js' +import { InputPeerLike, PeersIndex } from '../../types/peers/index.js' +import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { getAuthState } from '../auth/_state.js' +import { resolvePeer } from '../users/resolve-peer.js' // @available=both /** diff --git a/packages/client/src/methods/messages/get-reaction-users.ts b/packages/client/src/methods/messages/get-reaction-users.ts index b9f780de..2f23eb45 100644 --- a/packages/client/src/methods/messages/get-reaction-users.ts +++ b/packages/client/src/methods/messages/get-reaction-users.ts @@ -8,9 +8,9 @@ import { normalizeInputReaction, PeerReaction, PeersIndex, -} from '../../types' -import { makeArrayPaginated } from '../../utils' -import { resolvePeer } from '../users/resolve-peer' +} from '../../types/index.js' +import { makeArrayPaginated } from '../../utils/index.js' +import { resolvePeer } from '../users/resolve-peer.js' // @exported export type GetReactionUsersOffset = string diff --git a/packages/client/src/methods/messages/get-reply-to.ts b/packages/client/src/methods/messages/get-reply-to.ts index 81bd4175..0e8ec414 100644 --- a/packages/client/src/methods/messages/get-reply-to.ts +++ b/packages/client/src/methods/messages/get-reply-to.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Message } from '../../types/messages' -import { getMessages } from './get-messages' -import { getMessagesUnsafe } from './get-messages-unsafe' +import { Message } from '../../types/messages/index.js' +import { getMessages } from './get-messages.js' +import { getMessagesUnsafe } from './get-messages-unsafe.js' /** * For messages containing a reply, fetch the message that is being replied. diff --git a/packages/client/src/methods/messages/get-scheduled-messages.ts b/packages/client/src/methods/messages/get-scheduled-messages.ts index 4bbe1577..17e6d1e7 100644 --- a/packages/client/src/methods/messages/get-scheduled-messages.ts +++ b/packages/client/src/methods/messages/get-scheduled-messages.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { InputPeerLike, Message, PeersIndex } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, Message, PeersIndex } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get scheduled messages in chat by their IDs diff --git a/packages/client/src/methods/messages/iter-history.ts b/packages/client/src/methods/messages/iter-history.ts index 77e1c09e..988f6fa7 100644 --- a/packages/client/src/methods/messages/iter-history.ts +++ b/packages/client/src/methods/messages/iter-history.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, Message } from '../../types' -import { resolvePeer } from '../users/resolve-peer' -import { getHistory } from './get-history' +import { InputPeerLike, Message } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getHistory } from './get-history.js' /** * Iterate over chat history. Wrapper over {@link getHistory} diff --git a/packages/client/src/methods/messages/iter-reaction-users.ts b/packages/client/src/methods/messages/iter-reaction-users.ts index 5f2972a5..c30c3c02 100644 --- a/packages/client/src/methods/messages/iter-reaction-users.ts +++ b/packages/client/src/methods/messages/iter-reaction-users.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { normalizeInputMessageId, normalizeInputReaction, PeerReaction } from '../../types' -import { resolvePeer } from '../users/resolve-peer' -import { getReactionUsers } from './get-reaction-users' +import { normalizeInputMessageId, normalizeInputReaction, PeerReaction } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getReactionUsers } from './get-reaction-users.js' /** * Iterate over users who have reacted to the message. diff --git a/packages/client/src/methods/messages/iter-search-global.ts b/packages/client/src/methods/messages/iter-search-global.ts index 58ea2794..7f63a1d1 100644 --- a/packages/client/src/methods/messages/iter-search-global.ts +++ b/packages/client/src/methods/messages/iter-search-global.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Message, SearchFilters } from '../../types' -import { normalizeDate } from '../../utils' -import { searchGlobal } from './search-global' +import { Message, SearchFilters } from '../../types/index.js' +import { normalizeDate } from '../../utils/index.js' +import { searchGlobal } from './search-global.js' /** * Search for messages globally from all of your chats. diff --git a/packages/client/src/methods/messages/iter-search-messages.ts b/packages/client/src/methods/messages/iter-search-messages.ts index 9fc17346..b61c2799 100644 --- a/packages/client/src/methods/messages/iter-search-messages.ts +++ b/packages/client/src/methods/messages/iter-search-messages.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Message, SearchFilters } from '../../types' -import { normalizeDate } from '../../utils/misc-utils' -import { resolvePeer } from '../users/resolve-peer' -import { searchMessages } from './search-messages' +import { Message, SearchFilters } from '../../types/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { searchMessages } from './search-messages.js' /** * Search for messages inside a specific chat diff --git a/packages/client/src/methods/messages/parse-entities.ts b/packages/client/src/methods/messages/parse-entities.ts index f1f45371..9e513585 100644 --- a/packages/client/src/methods/messages/parse-entities.ts +++ b/packages/client/src/methods/messages/parse-entities.ts @@ -1,10 +1,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { FormattedString } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { getParseModesState } from '../parse-modes/_state' -import { resolvePeer } from '../users/resolve-peer' +import { FormattedString } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { getParseModesState } from '../parse-modes/_state.js' +import { resolvePeer } from '../users/resolve-peer.js' const empty: [string, undefined] = ['', undefined] diff --git a/packages/client/src/methods/messages/pin-message.ts b/packages/client/src/methods/messages/pin-message.ts index eaa57a35..ee95eb90 100644 --- a/packages/client/src/methods/messages/pin-message.ts +++ b/packages/client/src/methods/messages/pin-message.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MtTypeAssertionError } from '@mtcute/core' -import { InputMessageId, Message, normalizeInputMessageId } from '../../types' -import { resolvePeer } from '../users/resolve-peer' -import { _findMessageInUpdate } from './find-in-update' +import { InputMessageId, Message, normalizeInputMessageId } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _findMessageInUpdate } from './find-in-update.js' /** * Pin a message in a group, supergroup, channel or PM. diff --git a/packages/client/src/methods/messages/read-history.ts b/packages/client/src/methods/messages/read-history.ts index 6141735e..ed6b97ab 100644 --- a/packages/client/src/methods/messages/read-history.ts +++ b/packages/client/src/methods/messages/read-history.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils' -import { createDummyUpdate } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils.js' +import { createDummyUpdate } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Mark chat history as read. diff --git a/packages/client/src/methods/messages/read-reactions.ts b/packages/client/src/methods/messages/read-reactions.ts index 6d5d81a6..d0fbdd06 100644 --- a/packages/client/src/methods/messages/read-reactions.ts +++ b/packages/client/src/methods/messages/read-reactions.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { createDummyUpdate } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { createDummyUpdate } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Mark all reactions in chat as read. diff --git a/packages/client/src/methods/messages/search-global.ts b/packages/client/src/methods/messages/search-global.ts index 8dc2cf77..b6abf7b9 100644 --- a/packages/client/src/methods/messages/search-global.ts +++ b/packages/client/src/methods/messages/search-global.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { ArrayPaginated, Message, PeersIndex, SearchFilters } from '../../types' -import { makeArrayPaginated, normalizeDate } from '../../utils' +import { ArrayPaginated, Message, PeersIndex, SearchFilters } from '../../types/index.js' +import { makeArrayPaginated, normalizeDate } from '../../utils/index.js' // @exported export interface SearchGlobalOffset { diff --git a/packages/client/src/methods/messages/search-messages.ts b/packages/client/src/methods/messages/search-messages.ts index ebdbefdc..f4b5d127 100644 --- a/packages/client/src/methods/messages/search-messages.ts +++ b/packages/client/src/methods/messages/search-messages.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { ArrayPaginated, InputPeerLike, Message, PeersIndex, SearchFilters } from '../../types' -import { makeArrayPaginated, normalizeDate } from '../../utils/misc-utils' -import { resolvePeer } from '../users/resolve-peer' +import { ArrayPaginated, InputPeerLike, Message, PeersIndex, SearchFilters } from '../../types/index.js' +import { makeArrayPaginated, normalizeDate } from '../../utils/misc-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' // @exported export type SearchMessagesOffset = number diff --git a/packages/client/src/methods/messages/send-answer.ts b/packages/client/src/methods/messages/send-answer.ts index 93961a9e..956db5b6 100644 --- a/packages/client/src/methods/messages/send-answer.ts +++ b/packages/client/src/methods/messages/send-answer.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Message } from '../../types/messages/message' -import { ParametersSkip2 } from '../../types/utils' -import { sendMedia } from './send-media' -import { sendMediaGroup } from './send-media-group' -import { sendText } from './send-text' +import { Message } from '../../types/messages/message.js' +import { ParametersSkip2 } from '../../types/utils.js' +import { sendMedia } from './send-media.js' +import { sendMediaGroup } from './send-media-group.js' +import { sendText } from './send-text.js' /** Send a text to the same chat (and topic, if applicable) as a given message */ export function answerText( diff --git a/packages/client/src/methods/messages/send-comment.ts b/packages/client/src/methods/messages/send-comment.ts index 3ef6431a..c1c378f4 100644 --- a/packages/client/src/methods/messages/send-comment.ts +++ b/packages/client/src/methods/messages/send-comment.ts @@ -1,11 +1,11 @@ import { BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { Message } from '../../types/messages/message' -import { ParametersSkip2 } from '../../types/utils' -import { sendMedia } from './send-media' -import { sendMediaGroup } from './send-media-group' -import { replyMedia, replyMediaGroup, replyText } from './send-reply' -import { sendText } from './send-text' +import { Message } from '../../types/messages/message.js' +import { ParametersSkip2 } from '../../types/utils.js' +import { sendMedia } from './send-media.js' +import { sendMediaGroup } from './send-media-group.js' +import { replyMedia, replyMediaGroup, replyText } from './send-reply.js' +import { sendText } from './send-text.js' /** * Send a text comment to a given message. diff --git a/packages/client/src/methods/messages/send-common.ts b/packages/client/src/methods/messages/send-common.ts index 8b9f4cbc..026fb207 100644 --- a/packages/client/src/methods/messages/send-common.ts +++ b/packages/client/src/methods/messages/send-common.ts @@ -1,12 +1,12 @@ import { BaseTelegramClient, getMarkedPeerId, MtArgumentError } from '@mtcute/core' -import { MtMessageNotFoundError } from '../../types/errors' -import { Message } from '../../types/messages/message' -import { InputPeerLike } from '../../types/peers' -import { normalizeMessageId } from '../../utils' -import { resolvePeer } from '../users/resolve-peer' -import { _getDiscussionMessage } from './get-discussion-message' -import { getMessages } from './get-messages' +import { MtMessageNotFoundError } from '../../types/errors.js' +import { Message } from '../../types/messages/message.js' +import { InputPeerLike } from '../../types/peers/index.js' +import { normalizeMessageId } from '../../utils/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _getDiscussionMessage } from './get-discussion-message.js' +import { getMessages } from './get-messages.js' // @exported export interface CommonSendParams { diff --git a/packages/client/src/methods/messages/send-copy-group.ts b/packages/client/src/methods/messages/send-copy-group.ts index d1301b7b..dfb4f175 100644 --- a/packages/client/src/methods/messages/send-copy-group.ts +++ b/packages/client/src/methods/messages/send-copy-group.ts @@ -1,12 +1,12 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { isPresent } from '@mtcute/core/utils' +import { isPresent } from '@mtcute/core/utils.js' -import { Message } from '../../types/messages/message' -import { InputPeerLike } from '../../types/peers' -import { resolvePeer } from '../users/resolve-peer' -import { getMessages } from './get-messages' -import { CommonSendParams } from './send-common' -import { sendMediaGroup } from './send-media-group' +import { Message } from '../../types/messages/message.js' +import { InputPeerLike } from '../../types/peers/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getMessages } from './get-messages.js' +import { CommonSendParams } from './send-common.js' +import { sendMediaGroup } from './send-media-group.js' // @exported export interface SendCopyGroupParams extends CommonSendParams { diff --git a/packages/client/src/methods/messages/send-copy.ts b/packages/client/src/methods/messages/send-copy.ts index 499f74fe..3c788483 100644 --- a/packages/client/src/methods/messages/send-copy.ts +++ b/packages/client/src/methods/messages/send-copy.ts @@ -1,11 +1,11 @@ import { BaseTelegramClient, getMarkedPeerId, MtArgumentError, tl } from '@mtcute/core' -import { FormattedString, InputPeerLike, Message, MtMessageNotFoundError, ReplyMarkup } from '../../types' -import { resolvePeer } from '../users/resolve-peer' -import { getMessages } from './get-messages' -import { CommonSendParams } from './send-common' -import { sendMedia } from './send-media' -import { sendText } from './send-text' +import { FormattedString, InputPeerLike, Message, MtMessageNotFoundError, ReplyMarkup } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getMessages } from './get-messages.js' +import { CommonSendParams } from './send-common.js' +import { sendMedia } from './send-media.js' +import { sendText } from './send-text.js' // @exported export interface SendCopyParams extends CommonSendParams { diff --git a/packages/client/src/methods/messages/send-media-group.ts b/packages/client/src/methods/messages/send-media-group.ts index 02b34dc0..21da640d 100644 --- a/packages/client/src/methods/messages/send-media-group.ts +++ b/packages/client/src/methods/messages/send-media-group.ts @@ -1,16 +1,16 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { randomLong } from '@mtcute/core/utils' +import { randomLong } from '@mtcute/core/utils.js' -import { InputMediaLike } from '../../types/media/input-media' -import { Message } from '../../types/messages/message' -import { InputPeerLike, PeersIndex } from '../../types/peers' -import { normalizeDate } from '../../utils/misc-utils' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { _normalizeInputMedia } from '../files/normalize-input-media' -import { resolvePeer } from '../users/resolve-peer' -import { _getDiscussionMessage } from './get-discussion-message' -import { _parseEntities } from './parse-entities' -import { _processCommonSendParameters, CommonSendParams } from './send-common' +import { InputMediaLike } from '../../types/media/input-media.js' +import { Message } from '../../types/messages/message.js' +import { InputPeerLike, PeersIndex } from '../../types/peers/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { _normalizeInputMedia } from '../files/normalize-input-media.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _getDiscussionMessage } from './get-discussion-message.js' +import { _parseEntities } from './parse-entities.js' +import { _processCommonSendParameters, CommonSendParams } from './send-common.js' /** * Send a group of media. diff --git a/packages/client/src/methods/messages/send-media.ts b/packages/client/src/methods/messages/send-media.ts index 67badb35..35be44fd 100644 --- a/packages/client/src/methods/messages/send-media.ts +++ b/packages/client/src/methods/messages/send-media.ts @@ -1,18 +1,18 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { randomLong } from '@mtcute/core/utils' +import { randomLong } from '@mtcute/core/utils.js' -import { BotKeyboard, ReplyMarkup } from '../../types/bots/keyboards' -import { InputMediaLike } from '../../types/media/input-media' -import { Message } from '../../types/messages/message' -import { FormattedString } from '../../types/parser' -import { InputPeerLike } from '../../types/peers' -import { normalizeDate } from '../../utils/misc-utils' -import { _normalizeInputMedia } from '../files/normalize-input-media' -import { resolvePeer } from '../users/resolve-peer' -import { _findMessageInUpdate } from './find-in-update' -import { _getDiscussionMessage } from './get-discussion-message' -import { _parseEntities } from './parse-entities' -import { _processCommonSendParameters, CommonSendParams } from './send-common' +import { BotKeyboard, ReplyMarkup } from '../../types/bots/keyboards.js' +import { InputMediaLike } from '../../types/media/input-media.js' +import { Message } from '../../types/messages/message.js' +import { FormattedString } from '../../types/parser.js' +import { InputPeerLike } from '../../types/peers/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { _normalizeInputMedia } from '../files/normalize-input-media.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _findMessageInUpdate } from './find-in-update.js' +import { _getDiscussionMessage } from './get-discussion-message.js' +import { _parseEntities } from './parse-entities.js' +import { _processCommonSendParameters, CommonSendParams } from './send-common.js' /** * Send a single media (a photo or a document-based media) diff --git a/packages/client/src/methods/messages/send-reaction.ts b/packages/client/src/methods/messages/send-reaction.ts index a9c381d9..347e43af 100644 --- a/packages/client/src/methods/messages/send-reaction.ts +++ b/packages/client/src/methods/messages/send-reaction.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputMessageId, InputReaction, Message, normalizeInputMessageId, normalizeInputReaction } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' -import { _findMessageInUpdate } from './find-in-update' +import { InputMessageId, InputReaction, Message, normalizeInputMessageId, normalizeInputReaction } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _findMessageInUpdate } from './find-in-update.js' /** * Send or remove a reaction. diff --git a/packages/client/src/methods/messages/send-reply.ts b/packages/client/src/methods/messages/send-reply.ts index 38bd7e89..87348a6f 100644 --- a/packages/client/src/methods/messages/send-reply.ts +++ b/packages/client/src/methods/messages/send-reply.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Message } from '../../types/messages/message' -import { ParametersSkip2 } from '../../types/utils' -import { sendMedia } from './send-media' -import { sendMediaGroup } from './send-media-group' -import { sendText } from './send-text' +import { Message } from '../../types/messages/message.js' +import { ParametersSkip2 } from '../../types/utils.js' +import { sendMedia } from './send-media.js' +import { sendMediaGroup } from './send-media-group.js' +import { sendText } from './send-text.js' /** Send a text in reply to a given message */ export function replyText( diff --git a/packages/client/src/methods/messages/send-scheduled.ts b/packages/client/src/methods/messages/send-scheduled.ts index aed5fa64..2cc1828d 100644 --- a/packages/client/src/methods/messages/send-scheduled.ts +++ b/packages/client/src/methods/messages/send-scheduled.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MaybeArray, tl } from '@mtcute/core' -import { InputPeerLike, Message, PeersIndex } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, Message, PeersIndex } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Send previously scheduled message(s) diff --git a/packages/client/src/methods/messages/send-text.ts b/packages/client/src/methods/messages/send-text.ts index ffd6af81..1c93a313 100644 --- a/packages/client/src/methods/messages/send-text.ts +++ b/packages/client/src/methods/messages/send-text.ts @@ -1,19 +1,19 @@ import { BaseTelegramClient, getMarkedPeerId, MtTypeAssertionError, tl } from '@mtcute/core' -import { randomLong } from '@mtcute/core/utils' +import { randomLong } from '@mtcute/core/utils.js' -import { BotKeyboard, ReplyMarkup } from '../../types/bots/keyboards' -import { Message } from '../../types/messages/message' -import { FormattedString } from '../../types/parser' -import { InputPeerLike, PeersIndex } from '../../types/peers' -import { normalizeDate } from '../../utils/misc-utils' -import { inputPeerToPeer } from '../../utils/peer-utils' -import { createDummyUpdate } from '../../utils/updates-utils' -import { getAuthState } from '../auth/_state' -import { resolvePeer } from '../users/resolve-peer' -import { _findMessageInUpdate } from './find-in-update' -import { _getDiscussionMessage } from './get-discussion-message' -import { _parseEntities } from './parse-entities' -import { _processCommonSendParameters, CommonSendParams } from './send-common' +import { BotKeyboard, ReplyMarkup } from '../../types/bots/keyboards.js' +import { Message } from '../../types/messages/message.js' +import { FormattedString } from '../../types/parser.js' +import { InputPeerLike, PeersIndex } from '../../types/peers/index.js' +import { normalizeDate } from '../../utils/misc-utils.js' +import { inputPeerToPeer } from '../../utils/peer-utils.js' +import { createDummyUpdate } from '../../utils/updates-utils.js' +import { getAuthState } from '../auth/_state.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _findMessageInUpdate } from './find-in-update.js' +import { _getDiscussionMessage } from './get-discussion-message.js' +import { _parseEntities } from './parse-entities.js' +import { _processCommonSendParameters, CommonSendParams } from './send-common.js' /** * Send a text message diff --git a/packages/client/src/methods/messages/send-typing.ts b/packages/client/src/methods/messages/send-typing.ts index 87c617c1..ec370b0f 100644 --- a/packages/client/src/methods/messages/send-typing.ts +++ b/packages/client/src/methods/messages/send-typing.ts @@ -1,7 +1,7 @@ import { assertNever, BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike, TypingStatus } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, TypingStatus } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Sends a current user/bot typing event diff --git a/packages/client/src/methods/messages/send-vote.ts b/packages/client/src/methods/messages/send-vote.ts index 7a5b7eec..0afcf767 100644 --- a/packages/client/src/methods/messages/send-vote.ts +++ b/packages/client/src/methods/messages/send-vote.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, getMarkedPeerId, MaybeArray, MtArgumentError, MtTypeAssertionError } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { InputMessageId, MtMessageNotFoundError, normalizeInputMessageId, PeersIndex, Poll } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' -import { getMessages } from './get-messages' +import { InputMessageId, MtMessageNotFoundError, normalizeInputMessageId, PeersIndex, Poll } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getMessages } from './get-messages.js' /** * Send or retract a vote in a poll. @@ -18,7 +18,7 @@ export async function sendVote( * representing them. In case of indexes, the poll will first * be requested from the server. */ - options: null | MaybeArray + options: null | MaybeArray }, ): Promise { const { chatId, message } = normalizeInputMessageId(params) @@ -56,7 +56,7 @@ export async function sendVote( _: 'messages.sendVote', peer, msgId: message, - options: options as Buffer[], + options: options as Uint8Array[], }) assertIsUpdatesGroup('messages.sendVote', res) diff --git a/packages/client/src/methods/messages/translate-message.ts b/packages/client/src/methods/messages/translate-message.ts index 5bb76794..c2297344 100644 --- a/packages/client/src/methods/messages/translate-message.ts +++ b/packages/client/src/methods/messages/translate-message.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputMessageId, MessageEntity, normalizeInputMessageId } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputMessageId, MessageEntity, normalizeInputMessageId } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Translate message text to a given language. diff --git a/packages/client/src/methods/messages/unpin-all-messages.ts b/packages/client/src/methods/messages/unpin-all-messages.ts index fce30ea7..6645ac47 100644 --- a/packages/client/src/methods/messages/unpin-all-messages.ts +++ b/packages/client/src/methods/messages/unpin-all-messages.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { isInputPeerChannel } from '../../utils/peer-utils' -import { createDummyUpdate } from '../../utils/updates-utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { isInputPeerChannel } from '../../utils/peer-utils.js' +import { createDummyUpdate } from '../../utils/updates-utils.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Unpin all pinned messages in a chat. diff --git a/packages/client/src/methods/messages/unpin-message.ts b/packages/client/src/methods/messages/unpin-message.ts index 3b392ce5..84c46389 100644 --- a/packages/client/src/methods/messages/unpin-message.ts +++ b/packages/client/src/methods/messages/unpin-message.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputMessageId, normalizeInputMessageId } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputMessageId, normalizeInputMessageId } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Unpin a message in a group, supergroup, channel or PM. diff --git a/packages/client/src/methods/misc/init-takeout-session.ts b/packages/client/src/methods/misc/init-takeout-session.ts index affeca2d..c30699e6 100644 --- a/packages/client/src/methods/misc/init-takeout-session.ts +++ b/packages/client/src/methods/misc/init-takeout-session.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { TakeoutSession } from '../../types' +import { TakeoutSession } from '../../types/index.js' /** * Create a new takeout session diff --git a/packages/client/src/methods/misc/normalize-privacy-rules.ts b/packages/client/src/methods/misc/normalize-privacy-rules.ts index e1825a1f..5cf69cef 100644 --- a/packages/client/src/methods/misc/normalize-privacy-rules.ts +++ b/packages/client/src/methods/misc/normalize-privacy-rules.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPrivacyRule } from '../../types' -import { normalizeToInputUser } from '../../utils' -import { resolvePeerMany } from '../users/resolve-peer-many' +import { InputPrivacyRule } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/index.js' +import { resolvePeerMany } from '../users/resolve-peer-many.js' /** * Normalize {@link InputPrivacyRule}[] to `tl.TypeInputPrivacyRule`, diff --git a/packages/client/src/methods/parse-modes/_state.ts b/packages/client/src/methods/parse-modes/_state.ts index dc392eeb..744b5faa 100644 --- a/packages/client/src/methods/parse-modes/_state.ts +++ b/packages/client/src/methods/parse-modes/_state.ts @@ -1,14 +1,11 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { BaseTelegramClient } from '@mtcute/core' -import { IMessageEntityParser } from '../../types' +import { IMessageEntityParser } from '../../types/index.js' const STATE_SYMBOL = Symbol('parseModesState') -/** - * @internal - * @exported - */ +/** @internal */ export interface ParseModesState { parseModes: Map defaultParseMode: string | null diff --git a/packages/client/src/methods/parse-modes/parse-modes.ts b/packages/client/src/methods/parse-modes/parse-modes.ts index b1bc469e..101c70cb 100644 --- a/packages/client/src/methods/parse-modes/parse-modes.ts +++ b/packages/client/src/methods/parse-modes/parse-modes.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { IMessageEntityParser } from '../../types' -import { getParseModesState } from './_state' +import { IMessageEntityParser } from '../../types/index.js' +import { getParseModesState } from './_state.js' /** * Register a given {@link IMessageEntityParser} as a parse mode diff --git a/packages/client/src/methods/password/change-cloud-password.ts b/packages/client/src/methods/password/change-cloud-password.ts index 347f7542..b563136f 100644 --- a/packages/client/src/methods/password/change-cloud-password.ts +++ b/packages/client/src/methods/password/change-cloud-password.ts @@ -1,5 +1,5 @@ import { BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { assertTypeIs, computeNewPasswordHash, computeSrpParams } from '@mtcute/core/utils' +import { assertTypeIs, computeNewPasswordHash, computeSrpParams } from '@mtcute/core/utils.js' /** * Change your 2FA password diff --git a/packages/client/src/methods/password/enable-cloud-password.ts b/packages/client/src/methods/password/enable-cloud-password.ts index e114278e..9111eac8 100644 --- a/packages/client/src/methods/password/enable-cloud-password.ts +++ b/packages/client/src/methods/password/enable-cloud-password.ts @@ -1,5 +1,5 @@ import { BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { assertTypeIs, computeNewPasswordHash } from '@mtcute/core/utils' +import { assertTypeIs, computeNewPasswordHash } from '@mtcute/core/utils.js' /** * Enable 2FA password on your account diff --git a/packages/client/src/methods/password/remove-cloud-password.ts b/packages/client/src/methods/password/remove-cloud-password.ts index a65f498d..fabbeb8a 100644 --- a/packages/client/src/methods/password/remove-cloud-password.ts +++ b/packages/client/src/methods/password/remove-cloud-password.ts @@ -1,5 +1,5 @@ import { BaseTelegramClient, MtArgumentError } from '@mtcute/core' -import { computeSrpParams } from '@mtcute/core/utils' +import { computeSrpParams } from '@mtcute/core/utils.js' /** * Remove 2FA password from your account @@ -21,7 +21,7 @@ export async function removeCloudPassword(client: BaseTelegramClient, password: newSettings: { _: 'account.passwordInputSettings', newAlgo: { _: 'passwordKdfAlgoUnknown' }, - newPasswordHash: Buffer.alloc(0), + newPasswordHash: new Uint8Array(0), hint: '', }, }) diff --git a/packages/client/src/methods/stickers/add-sticker-to-set.ts b/packages/client/src/methods/stickers/add-sticker-to-set.ts index 7355b16d..53a1b109 100644 --- a/packages/client/src/methods/stickers/add-sticker-to-set.ts +++ b/packages/client/src/methods/stickers/add-sticker-to-set.ts @@ -6,8 +6,8 @@ import { MASK_POSITION_POINT_TO_TL, normalizeInputStickerSet, StickerSet, -} from '../../types' -import { _normalizeFileToDocument } from '../files/normalize-file-to-document' +} from '../../types/index.js' +import { _normalizeFileToDocument } from '../files/normalize-file-to-document.js' /** * Add a sticker to a sticker set. diff --git a/packages/client/src/methods/stickers/create-sticker-set.ts b/packages/client/src/methods/stickers/create-sticker-set.ts index dd4fd973..613db7ae 100644 --- a/packages/client/src/methods/stickers/create-sticker-set.ts +++ b/packages/client/src/methods/stickers/create-sticker-set.ts @@ -8,10 +8,10 @@ import { StickerSet, StickerSourceType, StickerType, -} from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { _normalizeFileToDocument } from '../files/normalize-file-to-document' -import { resolvePeer } from '../users/resolve-peer' +} from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { _normalizeFileToDocument } from '../files/normalize-file-to-document.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Create a new sticker set. diff --git a/packages/client/src/methods/stickers/delete-sticker-from-set.ts b/packages/client/src/methods/stickers/delete-sticker-from-set.ts index f07f9c8b..6e08fcdd 100644 --- a/packages/client/src/methods/stickers/delete-sticker-from-set.ts +++ b/packages/client/src/methods/stickers/delete-sticker-from-set.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' import { fileIdToInputDocument, tdFileId } from '@mtcute/file-id' -import { StickerSet } from '../../types' +import { StickerSet } from '../../types/index.js' /** * Delete a sticker from a sticker set diff --git a/packages/client/src/methods/stickers/get-custom-emojis.ts b/packages/client/src/methods/stickers/get-custom-emojis.ts index 8254668d..e68cff5b 100644 --- a/packages/client/src/methods/stickers/get-custom-emojis.ts +++ b/packages/client/src/methods/stickers/get-custom-emojis.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MaybeArray, MtTypeAssertionError, tl } from '@mtcute/core' -import { assertTypeIs, LongSet } from '@mtcute/core/utils' +import { assertTypeIs, LongSet } from '@mtcute/core/utils.js' -import { Message, Sticker } from '../../types' -import { parseDocument } from '../../types/media/document-utils' +import { Message, Sticker } from '../../types/index.js' +import { parseDocument } from '../../types/media/document-utils.js' /** * Get custom emoji stickers by their IDs diff --git a/packages/client/src/methods/stickers/get-installed-stickers.ts b/packages/client/src/methods/stickers/get-installed-stickers.ts index 1e08e524..115959f6 100644 --- a/packages/client/src/methods/stickers/get-installed-stickers.ts +++ b/packages/client/src/methods/stickers/get-installed-stickers.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, Long } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { StickerSet } from '../../types' +import { StickerSet } from '../../types/index.js' /** * Get a list of all installed sticker packs diff --git a/packages/client/src/methods/stickers/get-sticker-set.ts b/packages/client/src/methods/stickers/get-sticker-set.ts index 368aedfd..7bb7e0ea 100644 --- a/packages/client/src/methods/stickers/get-sticker-set.ts +++ b/packages/client/src/methods/stickers/get-sticker-set.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputStickerSet, normalizeInputStickerSet, StickerSet } from '../../types' +import { InputStickerSet, normalizeInputStickerSet, StickerSet } from '../../types/index.js' /** * Get a sticker pack and stickers inside of it. diff --git a/packages/client/src/methods/stickers/move-sticker-in-set.ts b/packages/client/src/methods/stickers/move-sticker-in-set.ts index 7c6d136a..ae2dfe89 100644 --- a/packages/client/src/methods/stickers/move-sticker-in-set.ts +++ b/packages/client/src/methods/stickers/move-sticker-in-set.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' import { fileIdToInputDocument, tdFileId } from '@mtcute/file-id' -import { StickerSet } from '../../types' +import { StickerSet } from '../../types/index.js' /** * Move a sticker in a sticker set diff --git a/packages/client/src/methods/stickers/set-chat-sticker-set.ts b/packages/client/src/methods/stickers/set-chat-sticker-set.ts index 932491d9..ab2ede8f 100644 --- a/packages/client/src/methods/stickers/set-chat-sticker-set.ts +++ b/packages/client/src/methods/stickers/set-chat-sticker-set.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, InputStickerSet, normalizeInputStickerSet } from '../../types' -import { normalizeToInputChannel } from '../../utils' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, InputStickerSet, normalizeInputStickerSet } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Set group sticker set for a supergroup diff --git a/packages/client/src/methods/stickers/set-sticker-set-thumb.ts b/packages/client/src/methods/stickers/set-sticker-set-thumb.ts index eebde11e..6487c46b 100644 --- a/packages/client/src/methods/stickers/set-sticker-set-thumb.ts +++ b/packages/client/src/methods/stickers/set-sticker-set-thumb.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputFileLike, InputStickerSet, normalizeInputStickerSet, StickerSet } from '../../types' -import { _normalizeFileToDocument } from '../files/normalize-file-to-document' +import { InputFileLike, InputStickerSet, normalizeInputStickerSet, StickerSet } from '../../types/index.js' +import { _normalizeFileToDocument } from '../files/normalize-file-to-document.js' /** * Set sticker set thumbnail diff --git a/packages/client/src/methods/stories/apply-boost.ts b/packages/client/src/methods/stories/apply-boost.ts index b714b232..17165ae2 100644 --- a/packages/client/src/methods/stories/apply-boost.ts +++ b/packages/client/src/methods/stories/apply-boost.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Boost a given channel diff --git a/packages/client/src/methods/stories/can-apply-boost.ts b/packages/client/src/methods/stories/can-apply-boost.ts index 5763c68c..938417d0 100644 --- a/packages/client/src/methods/stories/can-apply-boost.ts +++ b/packages/client/src/methods/stories/can-apply-boost.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { Chat, InputPeerLike, PeersIndex } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { Chat, InputPeerLike, PeersIndex } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' // @exported export type CanApplyBoostResult = diff --git a/packages/client/src/methods/stories/can-send-story.ts b/packages/client/src/methods/stories/can-send-story.ts index 39278ec3..2a962dcf 100644 --- a/packages/client/src/methods/stories/can-send-story.ts +++ b/packages/client/src/methods/stories/can-send-story.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' // @exported export type CanSendStoryResult = true | 'need_admin' | 'need_boosts' diff --git a/packages/client/src/methods/stories/delete-stories.ts b/packages/client/src/methods/stories/delete-stories.ts index 13041f24..f8c5cfb4 100644 --- a/packages/client/src/methods/stories/delete-stories.ts +++ b/packages/client/src/methods/stories/delete-stories.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Delete a story diff --git a/packages/client/src/methods/stories/edit-story.ts b/packages/client/src/methods/stories/edit-story.ts index 1fce7409..7fcd04c1 100644 --- a/packages/client/src/methods/stories/edit-story.ts +++ b/packages/client/src/methods/stories/edit-story.ts @@ -1,11 +1,11 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { FormattedString, InputMediaLike, InputPeerLike, InputPrivacyRule, Story } from '../../types' -import { _normalizeInputMedia } from '../files/normalize-input-media' -import { _parseEntities } from '../messages/parse-entities' -import { _normalizePrivacyRules } from '../misc/normalize-privacy-rules' -import { resolvePeer } from '../users/resolve-peer' -import { _findStoryInUpdate } from './find-in-update' +import { FormattedString, InputMediaLike, InputPeerLike, InputPrivacyRule, Story } from '../../types/index.js' +import { _normalizeInputMedia } from '../files/normalize-input-media.js' +import { _parseEntities } from '../messages/parse-entities.js' +import { _normalizePrivacyRules } from '../misc/normalize-privacy-rules.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _findStoryInUpdate } from './find-in-update.js' /** * Edit a sent story diff --git a/packages/client/src/methods/stories/find-in-update.ts b/packages/client/src/methods/stories/find-in-update.ts index b8e5be53..2c02e925 100644 --- a/packages/client/src/methods/stories/find-in-update.ts +++ b/packages/client/src/methods/stories/find-in-update.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MtTypeAssertionError, tl } from '@mtcute/core' -import { assertTypeIs, hasValueAtKey } from '@mtcute/core/utils' +import { assertTypeIs, hasValueAtKey } from '@mtcute/core/utils.js' -import { PeersIndex, Story } from '../../types' -import { assertIsUpdatesGroup } from '../../utils/updates-utils' +import { PeersIndex, Story } from '../../types/index.js' +import { assertIsUpdatesGroup } from '../../utils/updates-utils.js' /** @internal */ export function _findStoryInUpdate(client: BaseTelegramClient, res: tl.TypeUpdates): Story { diff --git a/packages/client/src/methods/stories/get-all-stories.ts b/packages/client/src/methods/stories/get-all-stories.ts index 2e40ae2b..fdf05c9f 100644 --- a/packages/client/src/methods/stories/get-all-stories.ts +++ b/packages/client/src/methods/stories/get-all-stories.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { AllStories } from '../../types' +import { AllStories } from '../../types/index.js' /** * Get all stories (e.g. to load the top bar) diff --git a/packages/client/src/methods/stories/get-boost-stats.ts b/packages/client/src/methods/stories/get-boost-stats.ts index 6ca3cddc..90825cec 100644 --- a/packages/client/src/methods/stories/get-boost-stats.ts +++ b/packages/client/src/methods/stories/get-boost-stats.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { BoostStats } from '../../types/stories/boost-stats' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { BoostStats } from '../../types/stories/boost-stats.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get information about boosts in a channel diff --git a/packages/client/src/methods/stories/get-boosters.ts b/packages/client/src/methods/stories/get-boosters.ts index 52bae994..d5d30cb0 100644 --- a/packages/client/src/methods/stories/get-boosters.ts +++ b/packages/client/src/methods/stories/get-boosters.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { ArrayPaginated, InputPeerLike, PeersIndex } from '../../types' -import { Booster } from '../../types/stories/booster' -import { makeArrayPaginated } from '../../utils' -import { resolvePeer } from '../users/resolve-peer' +import { ArrayPaginated, InputPeerLike, PeersIndex } from '../../types/index.js' +import { Booster } from '../../types/stories/booster.js' +import { makeArrayPaginated } from '../../utils/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get boosters of a channel diff --git a/packages/client/src/methods/stories/get-peer-stories.ts b/packages/client/src/methods/stories/get-peer-stories.ts index a4435a0e..f3fa6082 100644 --- a/packages/client/src/methods/stories/get-peer-stories.ts +++ b/packages/client/src/methods/stories/get-peer-stories.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, PeersIndex, PeerStories } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, PeersIndex, PeerStories } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get stories of a given peer diff --git a/packages/client/src/methods/stories/get-profile-stories.ts b/packages/client/src/methods/stories/get-profile-stories.ts index deea120d..3cd11451 100644 --- a/packages/client/src/methods/stories/get-profile-stories.ts +++ b/packages/client/src/methods/stories/get-profile-stories.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { ArrayPaginated, InputPeerLike, PeersIndex, Story } from '../../types' -import { makeArrayPaginated } from '../../utils' -import { resolvePeer } from '../users/resolve-peer' +import { ArrayPaginated, InputPeerLike, PeersIndex, Story } from '../../types/index.js' +import { makeArrayPaginated } from '../../utils/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get profile stories diff --git a/packages/client/src/methods/stories/get-stories-by-id.ts b/packages/client/src/methods/stories/get-stories-by-id.ts index beb01724..91ce3d52 100644 --- a/packages/client/src/methods/stories/get-stories-by-id.ts +++ b/packages/client/src/methods/stories/get-stories-by-id.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { InputPeerLike, PeersIndex, Story } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, PeersIndex, Story } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get one or more stories by their IDs diff --git a/packages/client/src/methods/stories/get-stories-interactions.ts b/packages/client/src/methods/stories/get-stories-interactions.ts index 38ea708d..a1cb21a7 100644 --- a/packages/client/src/methods/stories/get-stories-interactions.ts +++ b/packages/client/src/methods/stories/get-stories-interactions.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { InputPeerLike, PeersIndex, StoryInteractions } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, PeersIndex, StoryInteractions } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get brief information about stories interactions. diff --git a/packages/client/src/methods/stories/get-story-link.ts b/packages/client/src/methods/stories/get-story-link.ts index f6074ff7..8ddcf963 100644 --- a/packages/client/src/methods/stories/get-story-link.ts +++ b/packages/client/src/methods/stories/get-story-link.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Generate a link to a story. diff --git a/packages/client/src/methods/stories/get-story-viewers.ts b/packages/client/src/methods/stories/get-story-viewers.ts index 83a322d5..6d03ecf3 100644 --- a/packages/client/src/methods/stories/get-story-viewers.ts +++ b/packages/client/src/methods/stories/get-story-viewers.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, StoryViewersList } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, StoryViewersList } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Get viewers list of a story diff --git a/packages/client/src/methods/stories/hide-my-stories-views.ts b/packages/client/src/methods/stories/hide-my-stories-views.ts index adcc7aa5..42e09bcb 100644 --- a/packages/client/src/methods/stories/hide-my-stories-views.ts +++ b/packages/client/src/methods/stories/hide-my-stories-views.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MtTypeAssertionError } from '@mtcute/core' -import { StoriesStealthMode } from '../../types/stories/stealth-mode' -import { assertIsUpdatesGroup, hasValueAtKey } from '../../utils' +import { StoriesStealthMode } from '../../types/stories/stealth-mode.js' +import { assertIsUpdatesGroup, hasValueAtKey } from '../../utils/index.js' /** * Hide own stories views (activate so called "stealth mode") diff --git a/packages/client/src/methods/stories/increment-stories-views.ts b/packages/client/src/methods/stories/increment-stories-views.ts index 9ccdd30d..ed49e05b 100644 --- a/packages/client/src/methods/stories/increment-stories-views.ts +++ b/packages/client/src/methods/stories/increment-stories-views.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Increment views of one or more stories. diff --git a/packages/client/src/methods/stories/iter-all-stories.ts b/packages/client/src/methods/stories/iter-all-stories.ts index dff4db19..418c302e 100644 --- a/packages/client/src/methods/stories/iter-all-stories.ts +++ b/packages/client/src/methods/stories/iter-all-stories.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { PeerStories } from '../../types' -import { getAllStories } from './get-all-stories' +import { PeerStories } from '../../types/index.js' +import { getAllStories } from './get-all-stories.js' /** * Iterate over all stories (e.g. to load the top bar) diff --git a/packages/client/src/methods/stories/iter-boosters.ts b/packages/client/src/methods/stories/iter-boosters.ts index 7ce3a7f2..15985296 100644 --- a/packages/client/src/methods/stories/iter-boosters.ts +++ b/packages/client/src/methods/stories/iter-boosters.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { Booster } from '../../types/stories/booster' -import { resolvePeer } from '../users/resolve-peer' -import { getBoosters } from './get-boosters' +import { InputPeerLike } from '../../types/index.js' +import { Booster } from '../../types/stories/booster.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getBoosters } from './get-boosters.js' /** * Iterate over boosters of a channel. diff --git a/packages/client/src/methods/stories/iter-profile-stories.ts b/packages/client/src/methods/stories/iter-profile-stories.ts index 089d027b..30a9af9a 100644 --- a/packages/client/src/methods/stories/iter-profile-stories.ts +++ b/packages/client/src/methods/stories/iter-profile-stories.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, Story } from '../../types' -import { resolvePeer } from '../users/resolve-peer' -import { getProfileStories } from './get-profile-stories' +import { InputPeerLike, Story } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getProfileStories } from './get-profile-stories.js' /** * Iterate over profile stories. Wrapper over {@link getProfileStories} diff --git a/packages/client/src/methods/stories/iter-story-viewers.ts b/packages/client/src/methods/stories/iter-story-viewers.ts index 5bb8c5be..66acd5fe 100644 --- a/packages/client/src/methods/stories/iter-story-viewers.ts +++ b/packages/client/src/methods/stories/iter-story-viewers.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, StoryViewer } from '../../types' -import { resolvePeer } from '../users/resolve-peer' -import { getStoryViewers } from './get-story-viewers' +import { InputPeerLike, StoryViewer } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { getStoryViewers } from './get-story-viewers.js' /** * Iterate over viewers list of a story. diff --git a/packages/client/src/methods/stories/read-stories.ts b/packages/client/src/methods/stories/read-stories.ts index 210bb543..53c0c459 100644 --- a/packages/client/src/methods/stories/read-stories.ts +++ b/packages/client/src/methods/stories/read-stories.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Mark all stories up to a given ID as read diff --git a/packages/client/src/methods/stories/report-story.ts b/packages/client/src/methods/stories/report-story.ts index 27a08558..5ea88969 100644 --- a/packages/client/src/methods/stories/report-story.ts +++ b/packages/client/src/methods/stories/report-story.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MaybeArray, tl } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Report a story (or multiple stories) to the moderation team diff --git a/packages/client/src/methods/stories/send-story-reaction.ts b/packages/client/src/methods/stories/send-story-reaction.ts index 9c34d7db..9921b8a7 100644 --- a/packages/client/src/methods/stories/send-story-reaction.ts +++ b/packages/client/src/methods/stories/send-story-reaction.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, InputReaction, normalizeInputReaction } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike, InputReaction, normalizeInputReaction } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Send (or remove) a reaction to a story diff --git a/packages/client/src/methods/stories/send-story.ts b/packages/client/src/methods/stories/send-story.ts index b7b4bb6e..4a97283b 100644 --- a/packages/client/src/methods/stories/send-story.ts +++ b/packages/client/src/methods/stories/send-story.ts @@ -1,12 +1,12 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { randomLong } from '@mtcute/core/utils' +import { randomLong } from '@mtcute/core/utils.js' -import { FormattedString, InputMediaLike, InputPeerLike, InputPrivacyRule, Story } from '../../types' -import { _normalizeInputMedia } from '../files/normalize-input-media' -import { _parseEntities } from '../messages/parse-entities' -import { _normalizePrivacyRules } from '../misc/normalize-privacy-rules' -import { resolvePeer } from '../users/resolve-peer' -import { _findStoryInUpdate } from './find-in-update' +import { FormattedString, InputMediaLike, InputPeerLike, InputPrivacyRule, Story } from '../../types/index.js' +import { _normalizeInputMedia } from '../files/normalize-input-media.js' +import { _parseEntities } from '../messages/parse-entities.js' +import { _normalizePrivacyRules } from '../misc/normalize-privacy-rules.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { _findStoryInUpdate } from './find-in-update.js' /** * Send a story diff --git a/packages/client/src/methods/stories/toggle-peer-stories-archived.ts b/packages/client/src/methods/stories/toggle-peer-stories-archived.ts index 83d6865c..4db18044 100644 --- a/packages/client/src/methods/stories/toggle-peer-stories-archived.ts +++ b/packages/client/src/methods/stories/toggle-peer-stories-archived.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Toggle whether peer's stories are archived (hidden) or not. diff --git a/packages/client/src/methods/stories/toggle-stories-pinned.ts b/packages/client/src/methods/stories/toggle-stories-pinned.ts index 22342e50..02faa14c 100644 --- a/packages/client/src/methods/stories/toggle-stories-pinned.ts +++ b/packages/client/src/methods/stories/toggle-stories-pinned.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from '../users/resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from '../users/resolve-peer.js' /** * Toggle one or more stories pinned status diff --git a/packages/client/src/methods/updates/index.ts b/packages/client/src/methods/updates/index.ts index 6cb2eb61..09bef6a2 100644 --- a/packages/client/src/methods/updates/index.ts +++ b/packages/client/src/methods/updates/index.ts @@ -1,3 +1,3 @@ -export * from './manager' -export * from './parsed' -export * from './types' +export * from './manager.js' +export * from './parsed.js' +export * from './types.js' diff --git a/packages/client/src/methods/updates/manager.ts b/packages/client/src/methods/updates/manager.ts index 53e8dc7a..ff38994e 100644 --- a/packages/client/src/methods/updates/manager.ts +++ b/packages/client/src/methods/updates/manager.ts @@ -1,14 +1,14 @@ /* eslint-disable max-depth,max-params */ import { assertNever, BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' -import { getBarePeerId, getMarkedPeerId, markedPeerIdToBare, toggleChannelIdMark } from '@mtcute/core/utils' +import { getBarePeerId, getMarkedPeerId, markedPeerIdToBare, toggleChannelIdMark } from '@mtcute/core/utils.js' -import { PeersIndex } from '../../types' -import { normalizeToInputChannel } from '../../utils/peer-utils' -import { RpsMeter } from '../../utils/rps-meter' -import { getAuthState } from '../auth/_state' -import { resolvePeer } from '../users/resolve-peer' -import { createUpdatesState, PendingUpdate, toPendingUpdate, UpdatesManagerParams, UpdatesState } from './types' -import { extractChannelIdFromUpdate, messageToUpdate } from './utils' +import { PeersIndex } from '../../types/index.js' +import { normalizeToInputChannel } from '../../utils/peer-utils.js' +import { RpsMeter } from '../../utils/rps-meter.js' +import { getAuthState } from '../auth/_state.js' +import { resolvePeer } from '../users/resolve-peer.js' +import { createUpdatesState, PendingUpdate, toPendingUpdate, UpdatesManagerParams, UpdatesState } from './types.js' +import { extractChannelIdFromUpdate, messageToUpdate } from './utils.js' // code in this file is very bad, thanks to Telegram's awesome updates mechanism diff --git a/packages/client/src/methods/updates/parsed.ts b/packages/client/src/methods/updates/parsed.ts index 74e7bfed..5934e791 100644 --- a/packages/client/src/methods/updates/parsed.ts +++ b/packages/client/src/methods/updates/parsed.ts @@ -1,7 +1,7 @@ -import { Message } from '../../types/messages' -import { ParsedUpdate } from '../../types/updates/index' -import { _parseUpdate } from '../../types/updates/parse-update' -import { RawUpdateHandler } from './types' +import { Message } from '../../types/messages/index.js' +import { ParsedUpdate } from '../../types/updates/index.js' +import { _parseUpdate } from '../../types/updates/parse-update.js' +import { RawUpdateHandler } from './types.js' export interface ParsedUpdateHandlerParams { /** diff --git a/packages/client/src/methods/updates/types.ts b/packages/client/src/methods/updates/types.ts index b0c2f833..4e78be5b 100644 --- a/packages/client/src/methods/updates/types.ts +++ b/packages/client/src/methods/updates/types.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { AsyncLock, ConditionVariable, Deque, EarlyTimer, Logger, SortedLinkedList } from '@mtcute/core/utils' +import { AsyncLock, ConditionVariable, Deque, EarlyTimer, Logger, SortedLinkedList } from '@mtcute/core/utils.js' -import { PeersIndex } from '../../types' -import { RpsMeter } from '../../utils' -import { AuthState } from '../auth/_state' -import { extractChannelIdFromUpdate } from './utils' +import { PeersIndex } from '../../types/index.js' +import { RpsMeter } from '../../utils/index.js' +import { AuthState } from '../auth/_state.js' +import { extractChannelIdFromUpdate } from './utils.js' /** * Function to be called for each update. diff --git a/packages/client/src/methods/users/block-user.ts b/packages/client/src/methods/users/block-user.ts index fc8dd872..6dd5edd9 100644 --- a/packages/client/src/methods/users/block-user.ts +++ b/packages/client/src/methods/users/block-user.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from './resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from './resolve-peer.js' /** * Block a user diff --git a/packages/client/src/methods/users/edit-close-friends.ts b/packages/client/src/methods/users/edit-close-friends.ts index 86baff6c..b2a82125 100644 --- a/packages/client/src/methods/users/edit-close-friends.ts +++ b/packages/client/src/methods/users/edit-close-friends.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils' -import { resolvePeerMany } from './resolve-peer-many' +import { InputPeerLike } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/index.js' +import { resolvePeerMany } from './resolve-peer-many.js' /** * Edit "close friends" list directly using user IDs diff --git a/packages/client/src/methods/users/get-common-chats.ts b/packages/client/src/methods/users/get-common-chats.ts index b97eaae6..53f9fded 100644 --- a/packages/client/src/methods/users/get-common-chats.ts +++ b/packages/client/src/methods/users/get-common-chats.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { Chat, InputPeerLike } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from './resolve-peer' +import { Chat, InputPeerLike } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from './resolve-peer.js' /** * Get a list of common chats you have with a given user diff --git a/packages/client/src/methods/users/get-me.ts b/packages/client/src/methods/users/get-me.ts index f25da618..06a51379 100644 --- a/packages/client/src/methods/users/get-me.ts +++ b/packages/client/src/methods/users/get-me.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { User } from '../../types' -import { getAuthState } from '../auth/_state' +import { User } from '../../types/index.js' +import { getAuthState } from '../auth/_state.js' /** * Get currently authorized user's full information diff --git a/packages/client/src/methods/users/get-my-username.ts b/packages/client/src/methods/users/get-my-username.ts index 6b10e7ea..b5a13871 100644 --- a/packages/client/src/methods/users/get-my-username.ts +++ b/packages/client/src/methods/users/get-my-username.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient } from '@mtcute/core' -import { getAuthState } from '../auth/_state' +import { getAuthState } from '../auth/_state.js' /** * Get currently authorized user's username. diff --git a/packages/client/src/methods/users/get-profile-photo.ts b/packages/client/src/methods/users/get-profile-photo.ts index e957fbc3..12a8fb5c 100644 --- a/packages/client/src/methods/users/get-profile-photo.ts +++ b/packages/client/src/methods/users/get-profile-photo.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { InputPeerLike, Photo } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from './resolve-peer' +import { InputPeerLike, Photo } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from './resolve-peer.js' /** * Get a single profile picture of a user by its ID diff --git a/packages/client/src/methods/users/get-profile-photos.ts b/packages/client/src/methods/users/get-profile-photos.ts index c5f4609e..de53a0a7 100644 --- a/packages/client/src/methods/users/get-profile-photos.ts +++ b/packages/client/src/methods/users/get-profile-photos.ts @@ -1,10 +1,10 @@ import { BaseTelegramClient, Long, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { ArrayPaginated, InputPeerLike, Photo } from '../../types' -import { makeArrayPaginated } from '../../utils' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeer } from './resolve-peer' +import { ArrayPaginated, InputPeerLike, Photo } from '../../types/index.js' +import { makeArrayPaginated } from '../../utils/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeer } from './resolve-peer.js' /** * Get a list of profile pictures of a user diff --git a/packages/client/src/methods/users/get-users.ts b/packages/client/src/methods/users/get-users.ts index 283543fe..5e08d969 100644 --- a/packages/client/src/methods/users/get-users.ts +++ b/packages/client/src/methods/users/get-users.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core' -import { InputPeerLike, User } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { resolvePeerMany } from './resolve-peer-many' +import { InputPeerLike, User } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { resolvePeerMany } from './resolve-peer-many.js' /** * Get information about multiple users. diff --git a/packages/client/src/methods/users/iter-profile-photos.ts b/packages/client/src/methods/users/iter-profile-photos.ts index ebb435ec..5d2dd9f9 100644 --- a/packages/client/src/methods/users/iter-profile-photos.ts +++ b/packages/client/src/methods/users/iter-profile-photos.ts @@ -1,9 +1,9 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike, Photo } from '../../types' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { getProfilePhotos } from './get-profile-photos' -import { resolvePeer } from './resolve-peer' +import { InputPeerLike, Photo } from '../../types/index.js' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { getProfilePhotos } from './get-profile-photos.js' +import { resolvePeer } from './resolve-peer.js' /** * Iterate over profile photos diff --git a/packages/client/src/methods/users/resolve-peer-many.ts b/packages/client/src/methods/users/resolve-peer-many.ts index d3cecc13..8263ee9e 100644 --- a/packages/client/src/methods/users/resolve-peer-many.ts +++ b/packages/client/src/methods/users/resolve-peer-many.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { ConditionVariable } from '@mtcute/core/utils' +import { ConditionVariable } from '@mtcute/core/utils.js' -import { InputPeerLike } from '../../types' -import { resolvePeer } from './resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from './resolve-peer.js' /** * Get multiple `InputPeer`s at once, diff --git a/packages/client/src/methods/users/resolve-peer.ts b/packages/client/src/methods/users/resolve-peer.ts index 929da3da..b9b4a66a 100644 --- a/packages/client/src/methods/users/resolve-peer.ts +++ b/packages/client/src/methods/users/resolve-peer.ts @@ -8,9 +8,9 @@ import { toggleChannelIdMark, } from '@mtcute/core' -import { MtPeerNotFoundError } from '../../types/errors' -import { InputPeerLike } from '../../types/peers' -import { normalizeToInputPeer } from '../../utils/peer-utils' +import { MtPeerNotFoundError } from '../../types/errors.js' +import { InputPeerLike } from '../../types/peers/index.js' +import { normalizeToInputPeer } from '../../utils/peer-utils.js' // @available=both /** diff --git a/packages/client/src/methods/users/set-emoji-status.ts b/packages/client/src/methods/users/set-emoji-status.ts index 58f2d078..c2aa690c 100644 --- a/packages/client/src/methods/users/set-emoji-status.ts +++ b/packages/client/src/methods/users/set-emoji-status.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, tl } from '@mtcute/core' -import { normalizeDate } from '../../utils' +import { normalizeDate } from '../../utils/index.js' /** * Set an emoji status for the current user diff --git a/packages/client/src/methods/users/set-profile-photo.ts b/packages/client/src/methods/users/set-profile-photo.ts index f8ab09ce..610980a7 100644 --- a/packages/client/src/methods/users/set-profile-photo.ts +++ b/packages/client/src/methods/users/set-profile-photo.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' import { fileIdToInputPhoto, tdFileId } from '@mtcute/file-id' -import { InputFileLike, Photo } from '../../types' -import { _normalizeInputFile } from '../files/normalize-input-file' +import { InputFileLike, Photo } from '../../types/index.js' +import { _normalizeInputFile } from '../files/normalize-input-file.js' /** * Set a new profile photo or video. diff --git a/packages/client/src/methods/users/set-username.ts b/packages/client/src/methods/users/set-username.ts index 619b53ce..f2a58c41 100644 --- a/packages/client/src/methods/users/set-username.ts +++ b/packages/client/src/methods/users/set-username.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { User } from '../../types' -import { getAuthState } from '../auth/_state' +import { User } from '../../types/index.js' +import { getAuthState } from '../auth/_state.js' /** * Change username of the current user. diff --git a/packages/client/src/methods/users/unblock-user.ts b/packages/client/src/methods/users/unblock-user.ts index b8ddf7f9..dbf1146b 100644 --- a/packages/client/src/methods/users/unblock-user.ts +++ b/packages/client/src/methods/users/unblock-user.ts @@ -1,7 +1,7 @@ import { BaseTelegramClient } from '@mtcute/core' -import { InputPeerLike } from '../../types' -import { resolvePeer } from './resolve-peer' +import { InputPeerLike } from '../../types/index.js' +import { resolvePeer } from './resolve-peer.js' /** * Unblock a user diff --git a/packages/client/src/methods/users/update-profile.ts b/packages/client/src/methods/users/update-profile.ts index 8a00f7ca..97585db4 100644 --- a/packages/client/src/methods/users/update-profile.ts +++ b/packages/client/src/methods/users/update-profile.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient } from '@mtcute/core' -import { User } from '../../types' +import { User } from '../../types/index.js' /** * Update your profile details. diff --git a/packages/client/src/types/auth/index.ts b/packages/client/src/types/auth/index.ts index 11fab783..92ed94fc 100644 --- a/packages/client/src/types/auth/index.ts +++ b/packages/client/src/types/auth/index.ts @@ -1 +1 @@ -export * from './sent-code' +export * from './sent-code.js' diff --git a/packages/client/src/types/auth/sent-code.ts b/packages/client/src/types/auth/sent-code.ts index 14066706..900f20d2 100644 --- a/packages/client/src/types/auth/sent-code.ts +++ b/packages/client/src/types/auth/sent-code.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' const sentCodeMap: Record = { 'auth.sentCodeTypeApp': 'app', diff --git a/packages/client/src/types/bots/callback-query.ts b/packages/client/src/types/bots/callback-query.ts index 4fe714e8..c55d0500 100644 --- a/packages/client/src/types/bots/callback-query.ts +++ b/packages/client/src/types/bots/callback-query.ts @@ -1,10 +1,10 @@ import { BasicPeerType, getBasicPeerType, getMarkedPeerId, MtArgumentError, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { encodeInlineMessageId } from '../../utils/inline-utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex } from '../peers/peers-index' -import { User } from '../peers/user' +import { makeInspectable, utf8Decode } from '../../utils/index.js' +import { encodeInlineMessageId } from '../../utils/inline-utils.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex } from '../peers/peers-index.js' +import { User } from '../peers/user.js' /** * An incoming callback query, originated from a callback button @@ -121,7 +121,7 @@ export class CallbackQuery { * Note that this field is defined by the client, and a bad * client can send arbitrary data in this field. */ - get data(): Buffer | null { + get data(): Uint8Array | null { return this.raw.data ?? null } @@ -135,7 +135,7 @@ export class CallbackQuery { get dataStr(): string | null { if (!this.raw.data) return null - return this.raw.data.toString('utf8') + return utf8Decode(this.raw.data) } /** diff --git a/packages/client/src/types/bots/command-scope.ts b/packages/client/src/types/bots/command-scope.ts index ffda9b83..01ba9b69 100644 --- a/packages/client/src/types/bots/command-scope.ts +++ b/packages/client/src/types/bots/command-scope.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { InputPeerLike } from '../peers' +import { InputPeerLike } from '../peers/index.js' /** * Helper constants and builder functions for methods diff --git a/packages/client/src/types/bots/game-high-score.ts b/packages/client/src/types/bots/game-high-score.ts index db2debaa..0a9cd53f 100644 --- a/packages/client/src/types/bots/game-high-score.ts +++ b/packages/client/src/types/bots/game-high-score.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex } from '../peers/peers-index' -import { User } from '../peers/user' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex } from '../peers/peers-index.js' +import { User } from '../peers/user.js' /** * Game high score diff --git a/packages/client/src/types/bots/index.ts b/packages/client/src/types/bots/index.ts index a9fd4829..97447ca3 100644 --- a/packages/client/src/types/bots/index.ts +++ b/packages/client/src/types/bots/index.ts @@ -1,7 +1,7 @@ -export * from './callback-query' -export * from './command-scope' -export * from './game-high-score' -export * from './inline-query' -export * from './input' -export * from './keyboard-builder' -export * from './keyboards' +export * from './callback-query.js' +export * from './command-scope.js' +export * from './game-high-score.js' +export * from './inline-query.js' +export * from './input/index.js' +export * from './keyboard-builder.js' +export * from './keyboards.js' diff --git a/packages/client/src/types/bots/inline-query.ts b/packages/client/src/types/bots/inline-query.ts index 071fa105..5d897d4e 100644 --- a/packages/client/src/types/bots/inline-query.ts +++ b/packages/client/src/types/bots/inline-query.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Location } from '../media' -import { PeersIndex, PeerType, User } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Location } from '../media/location.js' +import { PeersIndex, PeerType, User } from '../peers/index.js' const PEER_TYPE_MAP: Record = { inlineQueryPeerTypeBroadcast: 'channel', diff --git a/packages/client/src/types/bots/input/index.ts b/packages/client/src/types/bots/input/index.ts index 12413a8a..a36c1b8f 100644 --- a/packages/client/src/types/bots/input/index.ts +++ b/packages/client/src/types/bots/input/index.ts @@ -1,2 +1,2 @@ -export * from './input-inline-message' -export * from './input-inline-result' +export * from './input-inline-message.js' +export * from './input-inline-result.js' diff --git a/packages/client/src/types/bots/input/input-inline-message.ts b/packages/client/src/types/bots/input/input-inline-message.ts index 55af3833..af7bb778 100644 --- a/packages/client/src/types/bots/input/input-inline-message.ts +++ b/packages/client/src/types/bots/input/input-inline-message.ts @@ -1,9 +1,9 @@ import { assertNever, BaseTelegramClient, tl } from '@mtcute/core' -import { _parseEntities } from '../../../methods/messages/parse-entities' -import { InputMediaContact, InputMediaGeo, InputMediaGeoLive, InputMediaVenue } from '../../media' -import { FormattedString } from '../../parser' -import { BotKeyboard, ReplyMarkup } from '../keyboards' +import { _parseEntities } from '../../../methods/messages/parse-entities.js' +import { InputMediaContact, InputMediaGeo, InputMediaGeoLive, InputMediaVenue } from '../../media/index.js' +import { FormattedString } from '../../parser.js' +import { BotKeyboard, ReplyMarkup } from '../keyboards.js' /** * Inline message containing only text diff --git a/packages/client/src/types/bots/input/input-inline-result.ts b/packages/client/src/types/bots/input/input-inline-result.ts index 19f7fe64..de572200 100644 --- a/packages/client/src/types/bots/input/input-inline-result.ts +++ b/packages/client/src/types/bots/input/input-inline-result.ts @@ -1,8 +1,8 @@ import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core' import { fileIdToInputDocument, fileIdToInputPhoto } from '@mtcute/file-id' -import { extractFileName } from '../../../utils/file-utils' -import { BotInlineMessage, InputInlineMessage } from './input-inline-message' +import { extractFileName } from '../../../utils/file-utils.js' +import { BotInlineMessage, InputInlineMessage } from './input-inline-message.js' export interface BaseInputInlineResult { /** diff --git a/packages/client/src/types/bots/keyboard-builder.ts b/packages/client/src/types/bots/keyboard-builder.ts index af792734..936815e8 100644 --- a/packages/client/src/types/bots/keyboard-builder.ts +++ b/packages/client/src/types/bots/keyboard-builder.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import type { InlineKeyboardMarkup, ReplyKeyboardMarkup } from './keyboards' +import type { InlineKeyboardMarkup, ReplyKeyboardMarkup } from './keyboards.js' export type ButtonLike = tl.TypeKeyboardButton | false | null | undefined | void diff --git a/packages/client/src/types/bots/keyboards.ts b/packages/client/src/types/bots/keyboards.ts index 88f7ebc1..2c72297e 100644 --- a/packages/client/src/types/bots/keyboards.ts +++ b/packages/client/src/types/bots/keyboards.ts @@ -1,7 +1,8 @@ import { assertNever, tl } from '@mtcute/core' +import { utf8EncodeToBuffer } from '@mtcute/core/utils.js' -import { normalizeToInputUser } from '../../utils/peer-utils' -import { BotKeyboardBuilder } from './keyboard-builder' +import { normalizeToInputUser } from '../../utils/peer-utils.js' +import { BotKeyboardBuilder } from './keyboard-builder.js' /** * Reply keyboard markup @@ -208,14 +209,14 @@ export namespace BotKeyboard { */ export function callback( text: string, - data: string | Buffer, + data: string | Uint8Array, requiresPassword?: boolean, ): tl.RawKeyboardButtonCallback { return { _: 'keyboardButtonCallback', text, requiresPassword, - data: typeof data === 'string' ? Buffer.from(data) : data, + data: typeof data === 'string' ? utf8EncodeToBuffer(data) : data, } } diff --git a/packages/client/src/types/calls/index.ts b/packages/client/src/types/calls/index.ts index b6d8b456..d77431e0 100644 --- a/packages/client/src/types/calls/index.ts +++ b/packages/client/src/types/calls/index.ts @@ -1 +1 @@ -export * from './discard-reason' +export * from './discard-reason.js' diff --git a/packages/client/src/types/conversation.ts b/packages/client/src/types/conversation.ts index 08c0577c..02a434da 100644 --- a/packages/client/src/types/conversation.ts +++ b/packages/client/src/types/conversation.ts @@ -1,16 +1,16 @@ import { BaseTelegramClient, getMarkedPeerId, MaybeAsync, MtArgumentError, MtTimeoutError, tl } from '@mtcute/core' -import { AsyncLock, ControllablePromise, createControllablePromise, Deque } from '@mtcute/core/utils' +import { AsyncLock, ControllablePromise, createControllablePromise, Deque } from '@mtcute/core/utils.js' -import { getPeerDialogs } from '../methods/dialogs/get-peer-dialogs' -import { readHistory } from '../methods/messages/read-history' -import { sendMedia } from '../methods/messages/send-media' -import { sendMediaGroup } from '../methods/messages/send-media-group' -import { sendText } from '../methods/messages/send-text' -import { resolvePeer } from '../methods/users/resolve-peer' -import type { Message } from './messages' -import type { InputPeerLike } from './peers' -import type { HistoryReadUpdate, ParsedUpdate } from './updates' -import { ParametersSkip2 } from './utils' +import { getPeerDialogs } from '../methods/dialogs/get-peer-dialogs.js' +import { readHistory } from '../methods/messages/read-history.js' +import { sendMedia } from '../methods/messages/send-media.js' +import { sendMediaGroup } from '../methods/messages/send-media-group.js' +import { sendText } from '../methods/messages/send-text.js' +import { resolvePeer } from '../methods/users/resolve-peer.js' +import type { Message } from './messages/message.js' +import type { InputPeerLike } from './peers/index.js' +import type { HistoryReadUpdate, ParsedUpdate } from './updates/index.js' +import { ParametersSkip2 } from './utils.js' interface QueuedHandler { promise: ControllablePromise diff --git a/packages/client/src/types/errors.ts b/packages/client/src/types/errors.ts index 0655689d..2f5e32f4 100644 --- a/packages/client/src/types/errors.ts +++ b/packages/client/src/types/errors.ts @@ -1,6 +1,6 @@ import { MtcuteError } from '@mtcute/core' -import { InputPeerLike } from './peers' +import { InputPeerLike } from './peers/index.js' /** * Could not find a peer by the provided information diff --git a/packages/client/src/types/files/file-location.ts b/packages/client/src/types/files/file-location.ts index 80ac5141..c31fd28b 100644 --- a/packages/client/src/types/files/file-location.ts +++ b/packages/client/src/types/files/file-location.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' /** * Information about file location. @@ -23,8 +23,8 @@ export class FileLocation { readonly location: | tl.TypeInputFileLocation | tl.TypeInputWebFileLocation - | Buffer - | (() => tl.TypeInputFileLocation | tl.TypeInputWebFileLocation | Buffer), + | Uint8Array + | (() => tl.TypeInputFileLocation | tl.TypeInputWebFileLocation | Uint8Array), /** * File size in bytes, when available */ diff --git a/packages/client/src/types/files/index.ts b/packages/client/src/types/files/index.ts index 099a52f3..01a538d9 100644 --- a/packages/client/src/types/files/index.ts +++ b/packages/client/src/types/files/index.ts @@ -1,4 +1,4 @@ -export * from './file-location' -export * from './uploaded-file' -export * from './utils' -export * from './web-document' +export * from './file-location.js' +export * from './uploaded-file.js' +export * from './utils.js' +export * from './web-document.js' diff --git a/packages/client/src/types/files/utils.ts b/packages/client/src/types/files/utils.ts index cf5008aa..22e63064 100644 --- a/packages/client/src/types/files/utils.ts +++ b/packages/client/src/types/files/utils.ts @@ -4,13 +4,13 @@ import type { Readable } from 'stream' import { tl } from '@mtcute/core' import { tdFileId } from '@mtcute/file-id' -import { FileLocation } from './file-location' -import { UploadedFile } from './uploaded-file' +import { FileLocation } from './file-location.js' +import { UploadedFile } from './uploaded-file.js' /** * Describes types that can be used in {@link TelegramClient.uploadFile} * method. Can be one of: - * - `Buffer`, which will be interpreted as raw file contents + * - `Uint8Array`/`Buffer`, which will be interpreted as raw file contents * - `File` (from the Web API) * - `string`, which will be interpreted as file path (**Node only!**) * - `ReadStream` (for NodeJS, from the `fs` module) @@ -19,7 +19,7 @@ import { UploadedFile } from './uploaded-file' * - `Response` (from `window.fetch` or `node-fetch`) */ export type UploadFileLike = - | Buffer + | Uint8Array | File | string | ReadStream diff --git a/packages/client/src/types/files/web-document.ts b/packages/client/src/types/files/web-document.ts index 2d63c97b..b24e6958 100644 --- a/packages/client/src/types/files/web-document.ts +++ b/packages/client/src/types/files/web-document.ts @@ -1,7 +1,7 @@ import { MtArgumentError, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { FileLocation } from './file-location' +import { makeInspectable } from '../../utils/index.js' +import { FileLocation } from './file-location.js' const STUB_LOCATION = () => { throw new MtArgumentError('This web document is not downloadable through Telegram') diff --git a/packages/client/src/types/index.ts b/packages/client/src/types/index.ts index 47c40eeb..46001bcf 100644 --- a/packages/client/src/types/index.ts +++ b/packages/client/src/types/index.ts @@ -1,15 +1,15 @@ -export * from './auth' -export * from './bots' -export * from './calls' -export * from './conversation' -export * from './errors' -export * from './files' -export * from './media' -export * from './messages' -export * from './misc' -export * from './parser' -export * from './peers' -export * from './reactions' -export * from './stories' -export * from './updates' -export * from './utils' +export * from './auth/index.js' +export * from './bots/index.js' +export * from './calls/index.js' +export * from './conversation.js' +export * from './errors.js' +export * from './files/index.js' +export * from './media/index.js' +export * from './messages/index.js' +export * from './misc/index.js' +export * from './parser.js' +export * from './peers/index.js' +export * from './reactions/index.js' +export * from './stories/index.js' +export * from './updates/index.js' +export * from './utils.js' diff --git a/packages/client/src/types/media/audio.ts b/packages/client/src/types/media/audio.ts index 78b5a099..4ce977c5 100644 --- a/packages/client/src/types/media/audio.ts +++ b/packages/client/src/types/media/audio.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' import { tdFileId } from '@mtcute/file-id' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { RawDocument } from './document' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { RawDocument } from './document.js' /** * An audio file diff --git a/packages/client/src/types/media/contact.ts b/packages/client/src/types/media/contact.ts index 8c5ba9ee..885e06d4 100644 --- a/packages/client/src/types/media/contact.ts +++ b/packages/client/src/types/media/contact.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' /** * A phone contact diff --git a/packages/client/src/types/media/dice.ts b/packages/client/src/types/media/dice.ts index 298c420a..59b4180b 100644 --- a/packages/client/src/types/media/dice.ts +++ b/packages/client/src/types/media/dice.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' /** * A dice or another interactive random emoji. diff --git a/packages/client/src/types/media/document-utils.ts b/packages/client/src/types/media/document-utils.ts index 7adef26a..644fca76 100644 --- a/packages/client/src/types/media/document-utils.ts +++ b/packages/client/src/types/media/document-utils.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' -import { Audio } from './audio' -import { Document } from './document' -import { Sticker } from './sticker' -import { Video } from './video' -import { Voice } from './voice' +import { Audio } from './audio.js' +import { Document } from './document.js' +import { Sticker } from './sticker.js' +import { Video } from './video.js' +import { Voice } from './voice.js' export type ParsedDocument = Sticker | Voice | Audio | Video | Document diff --git a/packages/client/src/types/media/document.ts b/packages/client/src/types/media/document.ts index dc217430..a4311191 100644 --- a/packages/client/src/types/media/document.ts +++ b/packages/client/src/types/media/document.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' import { tdFileId as td, toFileId, toUniqueFileId } from '@mtcute/file-id' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { FileLocation } from '../files' -import { Thumbnail } from './thumbnail' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { FileLocation } from '../files/index.js' +import { Thumbnail } from './thumbnail.js' /** * A file that is represented as a document in MTProto. diff --git a/packages/client/src/types/media/game.ts b/packages/client/src/types/media/game.ts index 56be2b5f..f6a1702b 100644 --- a/packages/client/src/types/media/game.ts +++ b/packages/client/src/types/media/game.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Photo } from './photo' -import { Video } from './video' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Photo } from './photo.js' +import { Video } from './video.js' export class Game { readonly type = 'game' as const diff --git a/packages/client/src/types/media/index.ts b/packages/client/src/types/media/index.ts index 3972433d..a5bb7904 100644 --- a/packages/client/src/types/media/index.ts +++ b/packages/client/src/types/media/index.ts @@ -1,16 +1,16 @@ -export * from './audio' -export * from './contact' -export * from './dice' -export * from './document' -export * from './game' -export * from './input-media' -export * from './invoice' -export * from './location' -export * from './photo' -export * from './poll' -export * from './sticker' -export * from './thumbnail' -export * from './venue' -export * from './video' -export * from './voice' -export * from './web-page' +export * from './audio.js' +export * from './contact.js' +export * from './dice.js' +export * from './document.js' +export * from './game.js' +export * from './input-media.js' +export * from './invoice.js' +export * from './location.js' +export * from './photo.js' +export * from './poll.js' +export * from './sticker.js' +export * from './thumbnail.js' +export * from './venue.js' +export * from './video.js' +export * from './voice.js' +export * from './web-page.js' diff --git a/packages/client/src/types/media/input-media.ts b/packages/client/src/types/media/input-media.ts index 7a475a81..1635f457 100644 --- a/packages/client/src/types/media/input-media.ts +++ b/packages/client/src/types/media/input-media.ts @@ -1,9 +1,9 @@ import { MaybeArray, tl } from '@mtcute/core' -import { InputFileLike } from '../files' -import { FormattedString } from '../parser' -import { InputPeerLike } from '../peers' -import { VenueSource } from './venue' +import { InputFileLike } from '../files/index.js' +import { FormattedString } from '../parser.js' +import { InputPeerLike } from '../peers/index.js' +import { VenueSource } from './venue.js' export interface CaptionMixin { /** @@ -418,7 +418,7 @@ export interface InputMediaInvoice extends CaptionMixin { * Will not be displayed to the user and can be used * for internal processes */ - payload: Buffer + payload: Uint8Array /** * Payments provider token, obtained from @@ -536,7 +536,7 @@ export interface InputMediaQuiz extends Omit { * > But since the API has that option, we also provide it, * > maybe to future-proof this :shrug: */ - correct: MaybeArray + correct: MaybeArray /** * Explanation of the quiz solution diff --git a/packages/client/src/types/media/invoice.ts b/packages/client/src/types/media/invoice.ts index a19602fb..9e7d5155 100644 --- a/packages/client/src/types/media/invoice.ts +++ b/packages/client/src/types/media/invoice.ts @@ -1,10 +1,10 @@ import { MtArgumentError, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { WebDocument } from '../files/web-document' -import type { MessageMedia } from '../messages/message-media' -import { Thumbnail } from './thumbnail' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { WebDocument } from '../files/web-document.js' +import type { MessageMedia } from '../messages/message-media.js' +import { Thumbnail } from './thumbnail.js' /** * Information about invoice's extended media. diff --git a/packages/client/src/types/media/location.ts b/packages/client/src/types/media/location.ts index 5450bf8a..5affcc53 100644 --- a/packages/client/src/types/media/location.ts +++ b/packages/client/src/types/media/location.ts @@ -1,7 +1,7 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { FileLocation } from '../files' +import { makeInspectable } from '../../utils/index.js' +import { FileLocation } from '../files/index.js' /** * A point on the map diff --git a/packages/client/src/types/media/photo.ts b/packages/client/src/types/media/photo.ts index fb960636..9b2869a2 100644 --- a/packages/client/src/types/media/photo.ts +++ b/packages/client/src/types/media/photo.ts @@ -1,9 +1,9 @@ import { MtArgumentError, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { FileLocation } from '../files' -import { Thumbnail } from './thumbnail' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { FileLocation } from '../files/index.js' +import { Thumbnail } from './thumbnail.js' /** * A photo diff --git a/packages/client/src/types/media/poll.ts b/packages/client/src/types/media/poll.ts index 65d6c140..42f4a8d0 100644 --- a/packages/client/src/types/media/poll.ts +++ b/packages/client/src/types/media/poll.ts @@ -1,9 +1,9 @@ import { Long, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { MessageEntity } from '../messages/message-entity' -import { PeersIndex } from '../peers/peers-index' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { MessageEntity } from '../messages/message-entity.js' +import { PeersIndex } from '../peers/peers-index.js' export interface PollAnswer { /** @@ -15,7 +15,7 @@ export interface PollAnswer { * Answer data, to be passed to * {@link TelegramClient.sendVote} */ - data: Buffer + data: Uint8Array /** * Number of people who has chosen this result. diff --git a/packages/client/src/types/media/sticker.ts b/packages/client/src/types/media/sticker.ts index 683a0830..9dcb7878 100644 --- a/packages/client/src/types/media/sticker.ts +++ b/packages/client/src/types/media/sticker.ts @@ -1,9 +1,9 @@ import { MtArgumentError, tl } from '@mtcute/core' import { tdFileId } from '@mtcute/file-id' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { RawDocument } from './document' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { RawDocument } from './document.js' export const MASK_POSITION_POINT_TO_TL = { forehead: 0, diff --git a/packages/client/src/types/media/thumbnail.ts b/packages/client/src/types/media/thumbnail.ts index 54cb3800..c7b29ea5 100644 --- a/packages/client/src/types/media/thumbnail.ts +++ b/packages/client/src/types/media/thumbnail.ts @@ -1,11 +1,11 @@ import { Long, MtArgumentError, MtTypeAssertionError, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' import { tdFileId as td, toFileId, toUniqueFileId } from '@mtcute/file-id' -import { makeInspectable } from '../../utils' -import { inflateSvgPath, strippedPhotoToJpg, svgPathToFile } from '../../utils/file-utils' -import { memoizeGetters } from '../../utils/memoize' -import { FileLocation } from '../files' +import { inflateSvgPath, strippedPhotoToJpg, svgPathToFile } from '../../utils/file-utils.js' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { FileLocation } from '../files/index.js' /** * One size of some thumbnail @@ -65,7 +65,7 @@ export class Thumbnail extends FileLocation { throw new MtTypeAssertionError('sz', 'not (photoSizeEmpty | photoCachedSize)', sz._) } - let location: tl.TypeInputFileLocation | Buffer | (() => tl.TypeInputFileLocation | Buffer) + let location: tl.TypeInputFileLocation | Uint8Array | (() => tl.TypeInputFileLocation | Uint8Array) let size let width let height: number diff --git a/packages/client/src/types/media/venue.ts b/packages/client/src/types/media/venue.ts index 0a983944..6efb74ad 100644 --- a/packages/client/src/types/media/venue.ts +++ b/packages/client/src/types/media/venue.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Location } from './location' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Location } from './location.js' export interface VenueSource { /** diff --git a/packages/client/src/types/media/video.ts b/packages/client/src/types/media/video.ts index e2931b54..5fac890a 100644 --- a/packages/client/src/types/media/video.ts +++ b/packages/client/src/types/media/video.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' import { tdFileId } from '@mtcute/file-id' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { RawDocument } from './document' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { RawDocument } from './document.js' /** * A video, round video message or GIF animation. diff --git a/packages/client/src/types/media/voice.ts b/packages/client/src/types/media/voice.ts index 94555876..4e019a4c 100644 --- a/packages/client/src/types/media/voice.ts +++ b/packages/client/src/types/media/voice.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' import { tdFileId } from '@mtcute/file-id' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { decodeWaveform } from '../../utils/voice-utils' -import { RawDocument } from './document' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { decodeWaveform } from '../../utils/voice-utils.js' +import { RawDocument } from './document.js' /** * An voice note. diff --git a/packages/client/src/types/media/web-page.ts b/packages/client/src/types/media/web-page.ts index 59497057..4eef9ec5 100644 --- a/packages/client/src/types/media/web-page.ts +++ b/packages/client/src/types/media/web-page.ts @@ -1,10 +1,10 @@ import { MtArgumentError, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { RawDocument } from './document' -import { parseDocument } from './document-utils' -import { Photo } from './photo' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { RawDocument } from './document.js' +import { parseDocument } from './document-utils.js' +import { Photo } from './photo.js' /** * Web page preview. diff --git a/packages/client/src/types/messages/dialog.ts b/packages/client/src/types/messages/dialog.ts index 57a94006..50c40ef5 100644 --- a/packages/client/src/types/messages/dialog.ts +++ b/packages/client/src/types/messages/dialog.ts @@ -1,12 +1,12 @@ import { getMarkedPeerId, tl } from '@mtcute/core' -import { assertTypeIsNot, hasValueAtKey, makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { MtMessageNotFoundError } from '../errors' -import { Chat } from '../peers/chat' -import { PeersIndex } from '../peers/peers-index' -import { DraftMessage } from './draft-message' -import { Message } from './message' +import { assertTypeIsNot, hasValueAtKey, makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { MtMessageNotFoundError } from '../errors.js' +import { Chat } from '../peers/chat.js' +import { PeersIndex } from '../peers/peers-index.js' +import { DraftMessage } from './draft-message.js' +import { Message } from './message.js' /** * Type used as an input for a folder in client methods diff --git a/packages/client/src/types/messages/draft-message.ts b/packages/client/src/types/messages/draft-message.ts index 61caacc1..1fe8ac2f 100644 --- a/packages/client/src/types/messages/draft-message.ts +++ b/packages/client/src/types/messages/draft-message.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { MessageEntity } from './message-entity' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { MessageEntity } from './message-entity.js' /** * A draft message diff --git a/packages/client/src/types/messages/index.ts b/packages/client/src/types/messages/index.ts index 4e010729..e35cc919 100644 --- a/packages/client/src/types/messages/index.ts +++ b/packages/client/src/types/messages/index.ts @@ -1,9 +1,9 @@ -export * from './dialog' -export * from './draft-message' -export * from './input-message-id' -export * from './message' -export * from './message-action' -export * from './message-entity' -export * from './message-media' -export * from './message-reactions' -export * from './search-filters' +export * from './dialog.js' +export * from './draft-message.js' +export * from './input-message-id.js' +export * from './message.js' +export * from './message-action.js' +export * from './message-entity.js' +export * from './message-media.js' +export * from './message-reactions.js' +export * from './search-filters.js' diff --git a/packages/client/src/types/messages/input-message-id.ts b/packages/client/src/types/messages/input-message-id.ts index f7a67378..a1f64489 100644 --- a/packages/client/src/types/messages/input-message-id.ts +++ b/packages/client/src/types/messages/input-message-id.ts @@ -1,5 +1,5 @@ -import type { InputPeerLike } from '../peers' -import type { Message } from './message' +import type { InputPeerLike } from '../peers/index.js' +import type { Message } from './message.js' /** * Parameters for methods that accept a message diff --git a/packages/client/src/types/messages/message-action.ts b/packages/client/src/types/messages/message-action.ts index 0583cb42..3cccae30 100644 --- a/packages/client/src/types/messages/message-action.ts +++ b/packages/client/src/types/messages/message-action.ts @@ -1,8 +1,8 @@ import { getMarkedPeerId, tl } from '@mtcute/core' -import { _callDiscardReasonFromTl, CallDiscardReason } from '../calls' -import { Photo } from '../media' -import type { Message } from './message' +import { _callDiscardReasonFromTl, CallDiscardReason } from '../calls/index.js' +import { Photo } from '../media/index.js' +import type { Message } from './message.js' /** Group was created */ export interface ActionChatCreated { @@ -145,7 +145,7 @@ export interface ActionPaymentReceived { readonly amount: tl.Long /** Bot specified invoice payload */ - readonly payload: Buffer + readonly payload: Uint8Array /** Order information provided by the user */ readonly info?: tl.TypePaymentRequestedInfo diff --git a/packages/client/src/types/messages/message-entity.ts b/packages/client/src/types/messages/message-entity.ts index d12f27fa..209e06aa 100644 --- a/packages/client/src/types/messages/message-entity.ts +++ b/packages/client/src/types/messages/message-entity.ts @@ -1,7 +1,7 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' /** * Params of the entity. `.kind` can be: diff --git a/packages/client/src/types/messages/message-media.ts b/packages/client/src/types/messages/message-media.ts index ce9c2113..d51e3fb9 100644 --- a/packages/client/src/types/messages/message-media.ts +++ b/packages/client/src/types/messages/message-media.ts @@ -1,21 +1,21 @@ import { MtTypeAssertionError, tl } from '@mtcute/core' -import { Audio } from '../media/audio' -import { Contact } from '../media/contact' -import { Dice } from '../media/dice' -import { Document } from '../media/document' -import { parseDocument } from '../media/document-utils' -import { Game } from '../media/game' -import { Invoice } from '../media/invoice' -import { LiveLocation, Location } from '../media/location' -import { Photo } from '../media/photo' -import { Poll } from '../media/poll' -import { Sticker } from '../media/sticker' -import { Venue } from '../media/venue' -import { Video } from '../media/video' -import { Voice } from '../media/voice' -import { WebPage } from '../media/web-page' -import { PeersIndex } from '../peers/peers-index' +import { Audio } from '../media/audio.js' +import { Contact } from '../media/contact.js' +import { Dice } from '../media/dice.js' +import { Document } from '../media/document.js' +import { parseDocument } from '../media/document-utils.js' +import { Game } from '../media/game.js' +import { Invoice } from '../media/invoice.js' +import { LiveLocation, Location } from '../media/location.js' +import { Photo } from '../media/photo.js' +import { Poll } from '../media/poll.js' +import { Sticker } from '../media/sticker.js' +import { Venue } from '../media/venue.js' +import { Video } from '../media/video.js' +import { Voice } from '../media/voice.js' +import { WebPage } from '../media/web-page.js' +import { PeersIndex } from '../peers/peers-index.js' /** A media inside of a {@link Message} */ export type MessageMedia = diff --git a/packages/client/src/types/messages/message-reactions.ts b/packages/client/src/types/messages/message-reactions.ts index 26be0757..371f21d0 100644 --- a/packages/client/src/types/messages/message-reactions.ts +++ b/packages/client/src/types/messages/message-reactions.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex } from '../peers' -import { PeerReaction } from '../reactions/peer-reaction' -import { ReactionCount } from '../reactions/reaction-count' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex } from '../peers/index.js' +import { PeerReaction } from '../reactions/peer-reaction.js' +import { ReactionCount } from '../reactions/reaction-count.js' /** * Reactions on a message diff --git a/packages/client/src/types/messages/message.ts b/packages/client/src/types/messages/message.ts index a0c55702..098ed198 100644 --- a/packages/client/src/types/messages/message.ts +++ b/packages/client/src/types/messages/message.ts @@ -6,18 +6,18 @@ import { tl, toggleChannelIdMark, } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { BotKeyboard, ReplyMarkup } from '../bots/keyboards' -import { Chat } from '../peers/chat' -import { PeersIndex } from '../peers/peers-index' -import { User } from '../peers/user' -import { _messageActionFromTl, MessageAction } from './message-action' -import { MessageEntity } from './message-entity' -import { _messageMediaFromTl, MessageMedia } from './message-media' -import { MessageReactions } from './message-reactions' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { BotKeyboard, ReplyMarkup } from '../bots/keyboards.js' +import { Chat } from '../peers/chat.js' +import { PeersIndex } from '../peers/peers-index.js' +import { User } from '../peers/user.js' +import { _messageActionFromTl, MessageAction } from './message-action.js' +import { MessageEntity } from './message-entity.js' +import { _messageMediaFromTl, MessageMedia } from './message-media.js' +import { MessageReactions } from './message-reactions.js' /** Information about a forward */ export interface MessageForwardInfo { diff --git a/packages/client/src/types/misc/index.ts b/packages/client/src/types/misc/index.ts index 1ff8d3c9..4e8a6d05 100644 --- a/packages/client/src/types/misc/index.ts +++ b/packages/client/src/types/misc/index.ts @@ -1,3 +1,3 @@ -export * from './input-privacy-rule' -export * from './sticker-set' -export * from './takeout-session' +export * from './input-privacy-rule.js' +export * from './sticker-set.js' +export * from './takeout-session.js' diff --git a/packages/client/src/types/misc/input-privacy-rule.ts b/packages/client/src/types/misc/input-privacy-rule.ts index efdddcc9..6f9eef8e 100644 --- a/packages/client/src/types/misc/input-privacy-rule.ts +++ b/packages/client/src/types/misc/input-privacy-rule.ts @@ -2,7 +2,7 @@ import { MaybeArray, tl } from '@mtcute/core' -import { InputPeerLike } from '../peers' +import { InputPeerLike } from '../peers/index.js' interface InputPrivacyRuleUsers { allow: boolean diff --git a/packages/client/src/types/misc/sticker-set.ts b/packages/client/src/types/misc/sticker-set.ts index a13c2722..22f194dc 100644 --- a/packages/client/src/types/misc/sticker-set.ts +++ b/packages/client/src/types/misc/sticker-set.ts @@ -1,12 +1,12 @@ import { MtTypeAssertionError, tl } from '@mtcute/core' -import { LongMap } from '@mtcute/core/utils' +import { LongMap } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { MtEmptyError } from '../errors' -import { InputFileLike } from '../files' -import { MaskPosition, Sticker, StickerSourceType, StickerType, Thumbnail } from '../media' -import { parseDocument } from '../media/document-utils' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { MtEmptyError } from '../errors.js' +import { InputFileLike } from '../files/index.js' +import { parseDocument } from '../media/document-utils.js' +import { MaskPosition, Sticker, StickerSourceType, StickerType, Thumbnail } from '../media/index.js' /** * Input sticker set. diff --git a/packages/client/src/types/misc/takeout-session.ts b/packages/client/src/types/misc/takeout-session.ts index 38578a25..90b00895 100644 --- a/packages/client/src/types/misc/takeout-session.ts +++ b/packages/client/src/types/misc/takeout-session.ts @@ -1,6 +1,6 @@ import { BaseTelegramClient, MustEqual, RpcCallOptions, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' /** * Account takeout session diff --git a/packages/client/src/types/peers/chat-event/actions.ts b/packages/client/src/types/peers/chat-event/actions.ts index 1f6cbf83..854cf03d 100644 --- a/packages/client/src/types/peers/chat-event/actions.ts +++ b/packages/client/src/types/peers/chat-event/actions.ts @@ -1,15 +1,15 @@ import { tl, toggleChannelIdMark } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { Photo } from '../../media/photo' -import { Message } from '../../messages/message' -import { ChatInviteLink } from '../chat-invite-link' -import { ChatLocation } from '../chat-location' -import { ChatMember } from '../chat-member' -import { ChatPermissions } from '../chat-permissions' -import { ForumTopic } from '../forum-topic' -import { PeersIndex } from '../peers-index' -import { User } from '../user' +import { Photo } from '../../media/photo.js' +import { Message } from '../../messages/message.js' +import { ChatInviteLink } from '../chat-invite-link.js' +import { ChatLocation } from '../chat-location.js' +import { ChatMember } from '../chat-member.js' +import { ChatPermissions } from '../chat-permissions.js' +import { ForumTopic } from '../forum-topic.js' +import { PeersIndex } from '../peers-index.js' +import { User } from '../user.js' /** A user has joined the channel (in the case of big groups, info of the user that has joined isn't shown) */ export interface ChatActionUserJoined { diff --git a/packages/client/src/types/peers/chat-event/filters.ts b/packages/client/src/types/peers/chat-event/filters.ts index 06dcc94c..336ab2fd 100644 --- a/packages/client/src/types/peers/chat-event/filters.ts +++ b/packages/client/src/types/peers/chat-event/filters.ts @@ -1,6 +1,6 @@ import { assertNever, MaybeArray, tl } from '@mtcute/core' -import { ChatAction } from './actions' +import { ChatAction } from './actions.js' export interface ChatEventFilters { serverFilter?: tl.TypeChannelAdminLogEventsFilter diff --git a/packages/client/src/types/peers/chat-event/index.ts b/packages/client/src/types/peers/chat-event/index.ts index 4b2c3ab9..6296feda 100644 --- a/packages/client/src/types/peers/chat-event/index.ts +++ b/packages/client/src/types/peers/chat-event/index.ts @@ -1,13 +1,13 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../../utils' -import { memoizeGetters } from '../../../utils/memoize' -import { PeersIndex } from '../peers-index' -import { User } from '../user' -import { _actionFromTl, ChatAction } from './actions' +import { makeInspectable } from '../../../utils/index.js' +import { memoizeGetters } from '../../../utils/memoize.js' +import { PeersIndex } from '../peers-index.js' +import { User } from '../user.js' +import { _actionFromTl, ChatAction } from './actions.js' -export * from './actions' -export { InputChatEventFilters } from './filters' +export * from './actions.js' +export { InputChatEventFilters } from './filters.js' export class ChatEvent { constructor( diff --git a/packages/client/src/types/peers/chat-invite-link-member.ts b/packages/client/src/types/peers/chat-invite-link-member.ts index 84d9ffd7..9761e864 100644 --- a/packages/client/src/types/peers/chat-invite-link-member.ts +++ b/packages/client/src/types/peers/chat-invite-link-member.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex } from './peers-index' -import { User } from './user' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex } from './peers-index.js' +import { User } from './user.js' export class ChatInviteLinkMember { constructor( diff --git a/packages/client/src/types/peers/chat-invite-link.ts b/packages/client/src/types/peers/chat-invite-link.ts index 84627df2..52b689bc 100644 --- a/packages/client/src/types/peers/chat-invite-link.ts +++ b/packages/client/src/types/peers/chat-invite-link.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' -import { assertTypeIsNot } from '@mtcute/core/utils' +import { assertTypeIsNot } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex } from './index' -import { User } from './user' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex } from './index.js' +import { User } from './user.js' /** * An invite link diff --git a/packages/client/src/types/peers/chat-location.ts b/packages/client/src/types/peers/chat-location.ts index 84d45eb0..24e8a27c 100644 --- a/packages/client/src/types/peers/chat-location.ts +++ b/packages/client/src/types/peers/chat-location.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Location } from '../media/location' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Location } from '../media/location.js' /** * Geolocation of a supergroup diff --git a/packages/client/src/types/peers/chat-member.ts b/packages/client/src/types/peers/chat-member.ts index 3226f666..b864e139 100644 --- a/packages/client/src/types/peers/chat-member.ts +++ b/packages/client/src/types/peers/chat-member.ts @@ -1,11 +1,11 @@ import { tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { ChatPermissions } from './chat-permissions' -import { PeersIndex } from './index' -import { User } from './user' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { ChatPermissions } from './chat-permissions.js' +import { PeersIndex } from './index.js' +import { User } from './user.js' /** * Status of the member: diff --git a/packages/client/src/types/peers/chat-permissions.ts b/packages/client/src/types/peers/chat-permissions.ts index fde3d14e..55182a37 100644 --- a/packages/client/src/types/peers/chat-permissions.ts +++ b/packages/client/src/types/peers/chat-permissions.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' /** * Represents the permissions of a user in a {@link Chat}. diff --git a/packages/client/src/types/peers/chat-photo.ts b/packages/client/src/types/peers/chat-photo.ts index 6d9f2682..3ee3a2f3 100644 --- a/packages/client/src/types/peers/chat-photo.ts +++ b/packages/client/src/types/peers/chat-photo.ts @@ -1,10 +1,10 @@ import { Long, MtArgumentError, tl, toggleChannelIdMark } from '@mtcute/core' import { tdFileId, toFileId, toUniqueFileId } from '@mtcute/file-id' -import { makeInspectable } from '../../utils' -import { strippedPhotoToJpg } from '../../utils/file-utils' -import { memoizeGetters } from '../../utils/memoize' -import { FileLocation } from '../files' +import { strippedPhotoToJpg } from '../../utils/file-utils.js' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { FileLocation } from '../files/index.js' /** * A size of a chat photo @@ -126,7 +126,7 @@ export class ChatPhoto { /** * Chat photo preview in *very* small resolution, if available */ - get thumb(): Buffer | null { + get thumb(): Uint8Array | null { if (!this.raw.strippedThumb) return null return strippedPhotoToJpg(this.raw.strippedThumb) diff --git a/packages/client/src/types/peers/chat-preview.ts b/packages/client/src/types/peers/chat-preview.ts index b78126f0..180b56c1 100644 --- a/packages/client/src/types/peers/chat-preview.ts +++ b/packages/client/src/types/peers/chat-preview.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Photo } from '../media' -import { User } from './user' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Photo } from '../media/index.js' +import { User } from './user.js' /** * Chat type. Can be: diff --git a/packages/client/src/types/peers/chat.ts b/packages/client/src/types/peers/chat.ts index 12557639..0c5cee3d 100644 --- a/packages/client/src/types/peers/chat.ts +++ b/packages/client/src/types/peers/chat.ts @@ -1,13 +1,13 @@ import { getMarkedPeerId, MtArgumentError, MtTypeAssertionError, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { MessageEntity } from '../messages/message-entity' -import { ChatLocation } from './chat-location' -import { ChatPermissions } from './chat-permissions' -import { ChatPhoto } from './chat-photo' -import { PeersIndex } from './peers-index' -import { User } from './user' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { MessageEntity } from '../messages/message-entity.js' +import { ChatLocation } from './chat-location.js' +import { ChatPermissions } from './chat-permissions.js' +import { ChatPhoto } from './chat-photo.js' +import { PeersIndex } from './peers-index.js' +import { User } from './user.js' /** * Chat type. Can be: diff --git a/packages/client/src/types/peers/forum-topic.ts b/packages/client/src/types/peers/forum-topic.ts index fd76623b..a4bd400b 100644 --- a/packages/client/src/types/peers/forum-topic.ts +++ b/packages/client/src/types/peers/forum-topic.ts @@ -1,12 +1,12 @@ import { MtTypeAssertionError, tl } from '@mtcute/core' -import { hasValueAtKey, makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { MtMessageNotFoundError } from '../errors' -import { DraftMessage, Message } from '../messages' -import { Chat } from './chat' -import { PeersIndex } from './peers-index' -import { User } from './user' +import { hasValueAtKey, makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { MtMessageNotFoundError } from '../errors.js' +import { DraftMessage, Message } from '../messages/index.js' +import { Chat } from './chat.js' +import { PeersIndex } from './peers-index.js' +import { User } from './user.js' export class ForumTopic { static COLOR_BLUE = 0x6fb9f0 diff --git a/packages/client/src/types/peers/index.ts b/packages/client/src/types/peers/index.ts index 20afb4e1..347574b5 100644 --- a/packages/client/src/types/peers/index.ts +++ b/packages/client/src/types/peers/index.ts @@ -1,21 +1,21 @@ import { tl } from '@mtcute/core' -import { Chat } from './chat' -import { User } from './user' +import { Chat } from './chat.js' +import { User } from './user.js' -export * from './chat' -export * from './chat-event' -export * from './chat-invite-link' -export * from './chat-invite-link-member' -export * from './chat-location' -export * from './chat-member' -export * from './chat-permissions' -export * from './chat-photo' -export * from './chat-preview' -export * from './forum-topic' -export * from './peers-index' -export * from './typing-status' -export * from './user' +export * from './chat.js' +export * from './chat-event/index.js' +export * from './chat-invite-link.js' +export * from './chat-invite-link-member.js' +export * from './chat-location.js' +export * from './chat-member.js' +export * from './chat-permissions.js' +export * from './chat-photo.js' +export * from './chat-preview.js' +export * from './forum-topic.js' +export * from './peers-index.js' +export * from './typing-status.js' +export * from './user.js' /** * More extensive peer types, that differentiate between diff --git a/packages/client/src/types/peers/user.ts b/packages/client/src/types/peers/user.ts index 0d21e3b4..35c9cbf7 100644 --- a/packages/client/src/types/peers/user.ts +++ b/packages/client/src/types/peers/user.ts @@ -1,11 +1,11 @@ import { MtArgumentError, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { MessageEntity } from '../messages/message-entity' -import { EmojiStatus } from '../reactions/emoji-status' -import { ChatPhoto } from './chat-photo' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { MessageEntity } from '../messages/message-entity.js' +import { EmojiStatus } from '../reactions/emoji-status.js' +import { ChatPhoto } from './chat-photo.js' /** * User's Last Seen & Online status. diff --git a/packages/client/src/types/reactions/emoji-status.ts b/packages/client/src/types/reactions/emoji-status.ts index 17c73bb4..a95761c2 100644 --- a/packages/client/src/types/reactions/emoji-status.ts +++ b/packages/client/src/types/reactions/emoji-status.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' /** * Information about user's emoji status diff --git a/packages/client/src/types/reactions/index.ts b/packages/client/src/types/reactions/index.ts index 39e5e80a..87baae8a 100644 --- a/packages/client/src/types/reactions/index.ts +++ b/packages/client/src/types/reactions/index.ts @@ -1,2 +1,2 @@ -export * from './peer-reaction' -export * from './types' +export * from './peer-reaction.js' +export * from './types.js' diff --git a/packages/client/src/types/reactions/peer-reaction.ts b/packages/client/src/types/reactions/peer-reaction.ts index be16ef01..f819fd3e 100644 --- a/packages/client/src/types/reactions/peer-reaction.ts +++ b/packages/client/src/types/reactions/peer-reaction.ts @@ -1,11 +1,11 @@ import { getMarkedPeerId, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex } from '../peers/peers-index' -import { User } from '../peers/user' -import { ReactionEmoji, toReactionEmoji } from './types' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex } from '../peers/peers-index.js' +import { User } from '../peers/user.js' +import { ReactionEmoji, toReactionEmoji } from './types.js' /** * Reactions of a user to a message diff --git a/packages/client/src/types/reactions/reaction-count.ts b/packages/client/src/types/reactions/reaction-count.ts index 6c844fd2..3cef298e 100644 --- a/packages/client/src/types/reactions/reaction-count.ts +++ b/packages/client/src/types/reactions/reaction-count.ts @@ -1,7 +1,7 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { ReactionEmoji, toReactionEmoji } from './types' +import { makeInspectable } from '../../utils/index.js' +import { ReactionEmoji, toReactionEmoji } from './types.js' /** * Reaction count diff --git a/packages/client/src/types/stories/all-stories.ts b/packages/client/src/types/stories/all-stories.ts index f5475379..4d5dca38 100644 --- a/packages/client/src/types/stories/all-stories.ts +++ b/packages/client/src/types/stories/all-stories.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex } from '../peers' -import { PeerStories } from './peer-stories' -import { StoriesStealthMode } from './stealth-mode' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex } from '../peers/index.js' +import { PeerStories } from './peer-stories.js' +import { StoriesStealthMode } from './stealth-mode.js' /** * All stories of the current user diff --git a/packages/client/src/types/stories/boost-stats.ts b/packages/client/src/types/stories/boost-stats.ts index 55178d65..6096840b 100644 --- a/packages/client/src/types/stories/boost-stats.ts +++ b/packages/client/src/types/stories/boost-stats.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' /** * Information about boosts in a channel diff --git a/packages/client/src/types/stories/booster.ts b/packages/client/src/types/stories/booster.ts index ba70d6cf..7d3c8f2b 100644 --- a/packages/client/src/types/stories/booster.ts +++ b/packages/client/src/types/stories/booster.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex, User } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex, User } from '../peers/index.js' /** * Information about a user who is boosting a channel diff --git a/packages/client/src/types/stories/index.ts b/packages/client/src/types/stories/index.ts index 6a12ca8a..8b584432 100644 --- a/packages/client/src/types/stories/index.ts +++ b/packages/client/src/types/stories/index.ts @@ -1,9 +1,9 @@ -export * from './all-stories' -export * from './boost-stats' -export * from './booster' -export * from './interactive' -export * from './peer-stories' -export * from './stealth-mode' -export * from './story' -export * from './story-interactions' -export * from './story-viewer' +export * from './all-stories.js' +export * from './boost-stats.js' +export * from './booster.js' +export * from './interactive/index.js' +export * from './peer-stories.js' +export * from './stealth-mode.js' +export * from './story.js' +export * from './story-interactions.js' +export * from './story-viewer.js' diff --git a/packages/client/src/types/stories/interactive/base.ts b/packages/client/src/types/stories/interactive/base.ts index c56c5471..823ebbbe 100644 --- a/packages/client/src/types/stories/interactive/base.ts +++ b/packages/client/src/types/stories/interactive/base.ts @@ -1,4 +1,4 @@ -import { tl } from '@mtcute/core/src' +import { tl } from '@mtcute/core' export abstract class StoryInteractiveArea { abstract type: string diff --git a/packages/client/src/types/stories/interactive/index.ts b/packages/client/src/types/stories/interactive/index.ts index 33510b7e..070d88d1 100644 --- a/packages/client/src/types/stories/interactive/index.ts +++ b/packages/client/src/types/stories/interactive/index.ts @@ -1,10 +1,10 @@ import { MtTypeAssertionError, tl } from '@mtcute/core' -import { StoryInteractiveLocation } from './location' -import { StoryInteractiveReaction } from './reaction' -import { StoryInteractiveVenue } from './venue' +import { StoryInteractiveLocation } from './location.js' +import { StoryInteractiveReaction } from './reaction.js' +import { StoryInteractiveVenue } from './venue.js' -export * from './input' +export * from './input.js' export type StoryInteractiveElement = StoryInteractiveReaction | StoryInteractiveLocation | StoryInteractiveVenue diff --git a/packages/client/src/types/stories/interactive/input.ts b/packages/client/src/types/stories/interactive/input.ts index 5f3d825a..60000b0c 100644 --- a/packages/client/src/types/stories/interactive/input.ts +++ b/packages/client/src/types/stories/interactive/input.ts @@ -1,7 +1,7 @@ import { Long, tl } from '@mtcute/core' -import { VenueSource } from '../../media' -import { InputReaction, normalizeInputReaction } from '../../reactions' +import { VenueSource } from '../../media/index.js' +import { InputReaction, normalizeInputReaction } from '../../reactions/index.js' /** * Constructor for interactive story elements. diff --git a/packages/client/src/types/stories/interactive/location.ts b/packages/client/src/types/stories/interactive/location.ts index e92e7690..c826d2fa 100644 --- a/packages/client/src/types/stories/interactive/location.ts +++ b/packages/client/src/types/stories/interactive/location.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../../utils' -import { memoizeGetters } from '../../../utils/memoize' -import { Location } from '../../media' -import { StoryInteractiveArea } from './base' +import { makeInspectable } from '../../../utils/index.js' +import { memoizeGetters } from '../../../utils/memoize.js' +import { Location } from '../../media/index.js' +import { StoryInteractiveArea } from './base.js' /** * Interactive element containing a location on the map diff --git a/packages/client/src/types/stories/interactive/reaction.ts b/packages/client/src/types/stories/interactive/reaction.ts index 86865562..5ba50ca9 100644 --- a/packages/client/src/types/stories/interactive/reaction.ts +++ b/packages/client/src/types/stories/interactive/reaction.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../../utils' -import { ReactionEmoji, toReactionEmoji } from '../../reactions' -import { StoryInteractiveArea } from './base' +import { makeInspectable } from '../../../utils/index.js' +import { ReactionEmoji, toReactionEmoji } from '../../reactions/index.js' +import { StoryInteractiveArea } from './base.js' /** * Interactive element containing a reaction. diff --git a/packages/client/src/types/stories/interactive/venue.ts b/packages/client/src/types/stories/interactive/venue.ts index 1c471a70..aeaaa5c3 100644 --- a/packages/client/src/types/stories/interactive/venue.ts +++ b/packages/client/src/types/stories/interactive/venue.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../../utils' -import { memoizeGetters } from '../../../utils/memoize' -import { Location, VenueSource } from '../../media' -import { StoryInteractiveArea } from './base' +import { makeInspectable } from '../../../utils/index.js' +import { memoizeGetters } from '../../../utils/memoize.js' +import { Location, VenueSource } from '../../media/index.js' +import { StoryInteractiveArea } from './base.js' /** * Interactive element containing a venue diff --git a/packages/client/src/types/stories/peer-stories.ts b/packages/client/src/types/stories/peer-stories.ts index 837e6f05..d6a173d1 100644 --- a/packages/client/src/types/stories/peer-stories.ts +++ b/packages/client/src/types/stories/peer-stories.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { assertTypeIs, makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Chat, PeersIndex, User } from '../peers' -import { Story } from './story' +import { assertTypeIs, makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Chat, PeersIndex, User } from '../peers/index.js' +import { Story } from './story.js' export class PeerStories { constructor( diff --git a/packages/client/src/types/stories/stealth-mode.ts b/packages/client/src/types/stories/stealth-mode.ts index 5f7b9e23..49c8fc30 100644 --- a/packages/client/src/types/stories/stealth-mode.ts +++ b/packages/client/src/types/stories/stealth-mode.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' export class StoriesStealthMode { constructor(readonly raw: tl.RawStoriesStealthMode) {} diff --git a/packages/client/src/types/stories/story-interactions.ts b/packages/client/src/types/stories/story-interactions.ts index eeaaaf33..62dfc0a8 100644 --- a/packages/client/src/types/stories/story-interactions.ts +++ b/packages/client/src/types/stories/story-interactions.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex, User } from '../peers' -import { ReactionCount } from '../reactions/reaction-count' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex, User } from '../peers/index.js' +import { ReactionCount } from '../reactions/reaction-count.js' /** * Brief information about story views/interactions diff --git a/packages/client/src/types/stories/story-viewer.ts b/packages/client/src/types/stories/story-viewer.ts index 323315d5..bbfd4d25 100644 --- a/packages/client/src/types/stories/story-viewer.ts +++ b/packages/client/src/types/stories/story-viewer.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex, User } from '../peers' -import { ReactionEmoji, toReactionEmoji } from '../reactions' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex, User } from '../peers/index.js' +import { ReactionEmoji, toReactionEmoji } from '../reactions/index.js' /** * Information about a single user who has viewed a story. diff --git a/packages/client/src/types/stories/story.ts b/packages/client/src/types/stories/story.ts index 5c79f47c..6aba4dce 100644 --- a/packages/client/src/types/stories/story.ts +++ b/packages/client/src/types/stories/story.ts @@ -1,13 +1,13 @@ import { MtUnsupportedError, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Photo, Video } from '../media' -import { _messageMediaFromTl, MessageEntity } from '../messages' -import { PeersIndex } from '../peers' -import { ReactionEmoji, toReactionEmoji } from '../reactions' -import { _storyInteractiveElementFromTl, StoryInteractiveElement } from './interactive' -import { StoryInteractions } from './story-interactions' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Photo, Video } from '../media/index.js' +import { _messageMediaFromTl, MessageEntity } from '../messages/index.js' +import { PeersIndex } from '../peers/index.js' +import { ReactionEmoji, toReactionEmoji } from '../reactions/index.js' +import { _storyInteractiveElementFromTl, StoryInteractiveElement } from './interactive/index.js' +import { StoryInteractions } from './story-interactions.js' /** * Information about story visibility. diff --git a/packages/client/src/types/updates/bot-chat-join-request.ts b/packages/client/src/types/updates/bot-chat-join-request.ts index 7d6548f2..2f285ae1 100644 --- a/packages/client/src/types/updates/bot-chat-join-request.ts +++ b/packages/client/src/types/updates/bot-chat-join-request.ts @@ -1,8 +1,8 @@ import { getBarePeerId, getMarkedPeerId, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Chat, ChatInviteLink, PeersIndex, User } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Chat, ChatInviteLink, PeersIndex, User } from '../peers/index.js' /** * This update is sent when a user requests to join a chat diff --git a/packages/client/src/types/updates/bot-stopped.ts b/packages/client/src/types/updates/bot-stopped.ts index e989768a..ae4cc328 100644 --- a/packages/client/src/types/updates/bot-stopped.ts +++ b/packages/client/src/types/updates/bot-stopped.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex, User } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex, User } from '../peers/index.js' /** * A user has stopped or restarted the bot. diff --git a/packages/client/src/types/updates/chat-join-request.ts b/packages/client/src/types/updates/chat-join-request.ts index 36e7c41c..49d2904b 100644 --- a/packages/client/src/types/updates/chat-join-request.ts +++ b/packages/client/src/types/updates/chat-join-request.ts @@ -1,8 +1,8 @@ import { getBarePeerId, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex, User } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex, User } from '../peers/index.js' /** * This update is sent when a user requests to join a chat diff --git a/packages/client/src/types/updates/chat-member-update.ts b/packages/client/src/types/updates/chat-member-update.ts index 6b33fee2..abe15528 100644 --- a/packages/client/src/types/updates/chat-member-update.ts +++ b/packages/client/src/types/updates/chat-member-update.ts @@ -1,12 +1,12 @@ import { getMarkedPeerId, tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Chat } from '../peers/chat' -import { ChatInviteLink } from '../peers/chat-invite-link' -import { ChatMember } from '../peers/chat-member' -import { PeersIndex } from '../peers/peers-index' -import { User } from '../peers/user' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Chat } from '../peers/chat.js' +import { ChatInviteLink } from '../peers/chat-invite-link.js' +import { ChatMember } from '../peers/chat-member.js' +import { PeersIndex } from '../peers/peers-index.js' +import { User } from '../peers/user.js' /** * Type of the event. Can be one of: diff --git a/packages/client/src/types/updates/chosen-inline-result.ts b/packages/client/src/types/updates/chosen-inline-result.ts index 2ef46072..36d846cf 100644 --- a/packages/client/src/types/updates/chosen-inline-result.ts +++ b/packages/client/src/types/updates/chosen-inline-result.ts @@ -1,10 +1,10 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { encodeInlineMessageId } from '../../utils/inline-utils' -import { memoizeGetters } from '../../utils/memoize' -import { Location } from '../media/location' -import { PeersIndex, User } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { encodeInlineMessageId } from '../../utils/inline-utils.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Location } from '../media/location.js' +import { PeersIndex, User } from '../peers/index.js' /** * An inline result was chosen by the user and sent to some chat diff --git a/packages/client/src/types/updates/delete-message-update.ts b/packages/client/src/types/updates/delete-message-update.ts index 3f61e03f..9357f4db 100644 --- a/packages/client/src/types/updates/delete-message-update.ts +++ b/packages/client/src/types/updates/delete-message-update.ts @@ -1,6 +1,6 @@ import { tl, toggleChannelIdMark } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' /** * One or more messages were deleted diff --git a/packages/client/src/types/updates/delete-story-update.ts b/packages/client/src/types/updates/delete-story-update.ts index c15f4b80..eedd9023 100644 --- a/packages/client/src/types/updates/delete-story-update.ts +++ b/packages/client/src/types/updates/delete-story-update.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' -import { Chat, PeersIndex, User } from '../../types/peers' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' +import { Chat, PeersIndex, User } from '../../types/peers/index.js' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' /** * A story was deleted diff --git a/packages/client/src/types/updates/history-read-update.ts b/packages/client/src/types/updates/history-read-update.ts index 61523569..434c8c96 100644 --- a/packages/client/src/types/updates/history-read-update.ts +++ b/packages/client/src/types/updates/history-read-update.ts @@ -1,6 +1,6 @@ import { getMarkedPeerId, tl, toggleChannelIdMark } from '@mtcute/core' -import { makeInspectable } from '../../utils' +import { makeInspectable } from '../../utils/index.js' export class HistoryReadUpdate { constructor( diff --git a/packages/client/src/types/updates/index.ts b/packages/client/src/types/updates/index.ts index a03a6da7..c6f26a89 100644 --- a/packages/client/src/types/updates/index.ts +++ b/packages/client/src/types/updates/index.ts @@ -1,18 +1,18 @@ -import type { CallbackQuery, InlineQuery, Message } from '../../types' -import { BotChatJoinRequestUpdate } from './bot-chat-join-request' -import { BotStoppedUpdate } from './bot-stopped' -import { ChatJoinRequestUpdate } from './chat-join-request' -import { ChatMemberUpdate, ChatMemberUpdateType } from './chat-member-update' -import { ChosenInlineResult } from './chosen-inline-result' -import { DeleteMessageUpdate } from './delete-message-update' -import { DeleteStoryUpdate } from './delete-story-update' -import { HistoryReadUpdate } from './history-read-update' -import { PollUpdate } from './poll-update' -import { PollVoteUpdate } from './poll-vote' -import { PreCheckoutQuery } from './pre-checkout-query' -import { StoryUpdate } from './story-update' -import { UserStatusUpdate } from './user-status-update' -import { UserTypingUpdate } from './user-typing-update' +import type { CallbackQuery, InlineQuery, Message } from '../../types/index.js' +import { BotChatJoinRequestUpdate } from './bot-chat-join-request.js' +import { BotStoppedUpdate } from './bot-stopped.js' +import { ChatJoinRequestUpdate } from './chat-join-request.js' +import { ChatMemberUpdate, ChatMemberUpdateType } from './chat-member-update.js' +import { ChosenInlineResult } from './chosen-inline-result.js' +import { DeleteMessageUpdate } from './delete-message-update.js' +import { DeleteStoryUpdate } from './delete-story-update.js' +import { HistoryReadUpdate } from './history-read-update.js' +import { PollUpdate } from './poll-update.js' +import { PollVoteUpdate } from './poll-vote.js' +import { PreCheckoutQuery } from './pre-checkout-query.js' +import { StoryUpdate } from './story-update.js' +import { UserStatusUpdate } from './user-status-update.js' +import { UserTypingUpdate } from './user-typing-update.js' export { BotChatJoinRequestUpdate, diff --git a/packages/client/src/types/updates/parse-update.ts b/packages/client/src/types/updates/parse-update.ts index 9112326d..4dcbaa9f 100644 --- a/packages/client/src/types/updates/parse-update.ts +++ b/packages/client/src/types/updates/parse-update.ts @@ -21,7 +21,7 @@ import { StoryUpdate, UserStatusUpdate, UserTypingUpdate, -} from '../index' +} from '../index.js' /** @internal */ export function _parseUpdate(update: tl.TypeUpdate, peers: PeersIndex): ParsedUpdate | null { diff --git a/packages/client/src/types/updates/poll-update.ts b/packages/client/src/types/updates/poll-update.ts index a4e63a02..1c04b653 100644 --- a/packages/client/src/types/updates/poll-update.ts +++ b/packages/client/src/types/updates/poll-update.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Poll } from '../media/poll' -import { PeersIndex } from '../peers/peers-index' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Poll } from '../media/poll.js' +import { PeersIndex } from '../peers/peers-index.js' /** * Poll state has changed (stopped, somebody diff --git a/packages/client/src/types/updates/poll-vote.ts b/packages/client/src/types/updates/poll-vote.ts index 87d88fbe..503d3a12 100644 --- a/packages/client/src/types/updates/poll-vote.ts +++ b/packages/client/src/types/updates/poll-vote.ts @@ -1,9 +1,9 @@ import { MtUnsupportedError, tl } from '@mtcute/core' -import { assertTypeIs } from '@mtcute/core/utils' +import { assertTypeIs } from '@mtcute/core/utils.js' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { Chat, PeersIndex, User } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { Chat, PeersIndex, User } from '../peers/index.js' /** * Some user has voted in a public poll. @@ -59,7 +59,7 @@ export class PollVoteUpdate { * This might break at any time, but seems to be consistent for now. * To get chosen answer indexes derived as before, use {@link chosenIndexesAuto}. */ - get chosen(): ReadonlyArray { + get chosen(): ReadonlyArray { return this.raw.options } diff --git a/packages/client/src/types/updates/pre-checkout-query.ts b/packages/client/src/types/updates/pre-checkout-query.ts index f8b23adc..f42caa9b 100644 --- a/packages/client/src/types/updates/pre-checkout-query.ts +++ b/packages/client/src/types/updates/pre-checkout-query.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { PeersIndex, User } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { PeersIndex, User } from '../peers/index.js' export class PreCheckoutQuery { constructor( @@ -35,7 +35,7 @@ export class PreCheckoutQuery { * Bot-defined payload of the original invoice * (see {@link InputMediaInvoice.payload}) */ - get payload(): Buffer { + get payload(): Uint8Array { return this.raw.payload } diff --git a/packages/client/src/types/updates/story-update.ts b/packages/client/src/types/updates/story-update.ts index 123c7943..b9f1e787 100644 --- a/packages/client/src/types/updates/story-update.ts +++ b/packages/client/src/types/updates/story-update.ts @@ -1,9 +1,9 @@ import { tl } from '@mtcute/core' -import { Chat, PeersIndex, User } from '../../types/peers' -import { Story } from '../../types/stories' -import { assertTypeIs, makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' +import { Chat, PeersIndex, User } from '../../types/peers/index.js' +import { Story } from '../../types/stories/index.js' +import { assertTypeIs, makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' /** * A story was posted or edited diff --git a/packages/client/src/types/updates/user-status-update.ts b/packages/client/src/types/updates/user-status-update.ts index 2403448e..3e64c0c5 100644 --- a/packages/client/src/types/updates/user-status-update.ts +++ b/packages/client/src/types/updates/user-status-update.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { memoizeGetters } from '../../utils/memoize' -import { User, UserStatus } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { memoizeGetters } from '../../utils/memoize.js' +import { User, UserStatus } from '../peers/index.js' /** * User status has changed diff --git a/packages/client/src/types/updates/user-typing-update.ts b/packages/client/src/types/updates/user-typing-update.ts index 1aa0a4ff..3fb47262 100644 --- a/packages/client/src/types/updates/user-typing-update.ts +++ b/packages/client/src/types/updates/user-typing-update.ts @@ -1,7 +1,7 @@ import { BasicPeerType, getBarePeerId, MtUnsupportedError, tl, toggleChannelIdMark } from '@mtcute/core' -import { makeInspectable } from '../../utils' -import { TypingStatus } from '../peers' +import { makeInspectable } from '../../utils/index.js' +import { TypingStatus } from '../peers/index.js' /** * User's typing status has changed. diff --git a/packages/client/src/utils/file-utils.ts b/packages/client/src/utils/file-utils.ts index 82753f37..c444090c 100644 --- a/packages/client/src/utils/file-utils.ts +++ b/packages/client/src/utils/file-utils.ts @@ -1,4 +1,5 @@ import { MtArgumentError } from '@mtcute/core' +import { concatBuffers, hexDecodeToBuffer, utf8EncodeToBuffer } from '@mtcute/core/utils.js' /** * Given file size, determine the appropriate chunk size (in KB) @@ -15,7 +16,7 @@ export function determinePartSize(fileSize: number): number { /** * Returns `true` if all bytes in `buf` are printable ASCII characters */ -export function isProbablyPlainText(buf: Buffer): boolean { +export function isProbablyPlainText(buf: Uint8Array): boolean { return !buf.some( (it) => !( @@ -30,7 +31,7 @@ export function isProbablyPlainText(buf: Buffer): boolean { } // from https://github.com/telegramdesktop/tdesktop/blob/bec39d89e19670eb436dc794a8f20b657cb87c71/Telegram/SourceFiles/ui/image/image.cpp#L225 -const JPEG_HEADER = Buffer.from( +const JPEG_HEADER = hexDecodeToBuffer( 'ffd8ffe000104a46494600010100000100010000ffdb004300281c1e231e1928' + '2321232d2b28303c64413c37373c7b585d4964918099968f808c8aa0b4e6c3a0aad' + 'aad8a8cc8ffcbdaeef5ffffff9bc1fffffffaffe6fdfff8ffdb0043012b2d2d3c35' + @@ -50,19 +51,18 @@ const JPEG_HEADER = Buffer.from( '8797a82838485868788898a92939495969798999aa2a3a4a5a6a7a8a9aab2b3b4b5' + 'b6b7b8b9bac2c3c4c5c6c7c8c9cad2d3d4d5d6d7d8d9dae2e3e4e5e6e7e8e9eaf2f' + '3f4f5f6f7f8f9faffda000c03010002110311003f00', - 'hex', ) -const JPEG_FOOTER = Buffer.from('ffd9', 'hex') +const JPEG_FOOTER = new Uint8Array([0xff, 0xd9]) /** * Convert stripped JPEG (from `photoStrippedSize`) to full JPEG */ -export function strippedPhotoToJpg(stripped: Buffer): Buffer { +export function strippedPhotoToJpg(stripped: Uint8Array): Uint8Array { if (stripped.length < 3 || stripped[0] !== 1) { return stripped } - const result = Buffer.concat([JPEG_HEADER, stripped.slice(3), JPEG_FOOTER]) + const result = concatBuffers([JPEG_HEADER, stripped.slice(3), JPEG_FOOTER]) result[164] = stripped[1] result[166] = stripped[2] @@ -75,7 +75,7 @@ const SVG_LOOKUP = 'AACAAAAHAAALMAAAQASTAVAAAZaacaaaahaaalmaaaqastava.az01234567 * Inflate compressed preview SVG path to full SVG path * @param encoded */ -export function inflateSvgPath(encoded: Buffer): string { +export function inflateSvgPath(encoded: Uint8Array): string { let path = 'M' const len = encoded.length @@ -103,8 +103,8 @@ export function inflateSvgPath(encoded: Buffer): string { * Convert SVG path to SVG file * @param path */ -export function svgPathToFile(path: string): Buffer { - return Buffer.from( +export function svgPathToFile(path: string): Uint8Array { + return utf8EncodeToBuffer( '' + '' + diff --git a/packages/client/src/utils/index.ts b/packages/client/src/utils/index.ts index cefb0c04..2c595af5 100644 --- a/packages/client/src/utils/index.ts +++ b/packages/client/src/utils/index.ts @@ -1,10 +1,10 @@ -export * from './file-utils' -export * from './inline-utils' -export * from './inspectable' -export * from './misc-utils' -export * from './peer-utils' -export * from './rps-meter' -export * from './stream-utils' -export * from './updates-utils' -export * from './voice-utils' -export * from '@mtcute/core/utils' +export * from './file-utils.js' +export * from './inline-utils.js' +export * from './inspectable.js' +export * from './misc-utils.js' +export * from './peer-utils.js' +export * from './rps-meter.js' +export * from './stream-utils.js' +export * from './updates-utils.js' +export * from './voice-utils.js' +export * from '@mtcute/core/utils.js' diff --git a/packages/client/src/utils/inline-utils.ts b/packages/client/src/utils/inline-utils.ts index a4f0431b..22240acb 100644 --- a/packages/client/src/utils/inline-utils.ts +++ b/packages/client/src/utils/inline-utils.ts @@ -1,5 +1,5 @@ -import { assertNever, tl, TlBinaryReader, TlBinaryWriter } from '@mtcute/core' -import { encodeUrlSafeBase64, parseUrlSafeBase64 } from '@mtcute/core/utils' +import { assertNever, tl } from '@mtcute/core' +import { base64DecodeToBuffer, base64Encode, TlBinaryReader, TlBinaryWriter } from '@mtcute/core/utils.js' /** * Parse TDLib style inline message ID @@ -7,7 +7,7 @@ import { encodeUrlSafeBase64, parseUrlSafeBase64 } from '@mtcute/core/utils' * @param id Inline message ID */ export function parseInlineMessageId(id: string): tl.TypeInputBotInlineMessageID { - const buf = parseUrlSafeBase64(id) + const buf = base64DecodeToBuffer(id, true) const reader = TlBinaryReader.manual(buf) if (buf.length === 20) { @@ -38,13 +38,13 @@ export function encodeInlineMessageId(id: tl.TypeInputBotInlineMessageID): strin switch (id._) { case 'inputBotInlineMessageID': - writer = TlBinaryWriter.manualAlloc(20) + writer = TlBinaryWriter.manual(20) writer.int(id.dcId) writer.long(id.id) writer.long(id.accessHash) break case 'inputBotInlineMessageID64': - writer = TlBinaryWriter.manualAlloc(24) + writer = TlBinaryWriter.manual(24) writer.int(id.dcId) writer.long(id.ownerId) writer.int(id.id) @@ -54,7 +54,7 @@ export function encodeInlineMessageId(id: tl.TypeInputBotInlineMessageID): strin assertNever(id) } - return encodeUrlSafeBase64(writer.result()) + return base64Encode(writer.result(), true) } export function normalizeInlineId(id: string | tl.TypeInputBotInlineMessageID) { diff --git a/packages/client/src/utils/inspectable.ts b/packages/client/src/utils/inspectable.ts index bb8b42fd..8408c41b 100644 --- a/packages/client/src/utils/inspectable.ts +++ b/packages/client/src/utils/inspectable.ts @@ -1,9 +1,16 @@ /* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-argument */ +import { createRequire } from 'module' + +import { base64Encode } from '@mtcute/core/utils.js' + let util: typeof import('util') | null = null try { + // @only-if-esm + const require = createRequire(import.meta.url) + // @/only-if-esm util = require('util') as typeof import('util') } catch (e) {} @@ -27,10 +34,8 @@ function getAllGettersNames(obj: T): (keyof T)[] { return getters } -const bufferToJsonOriginal = Buffer.prototype.toJSON - -const bufferToJsonInspect = function (this: Buffer) { - return this.toString('base64') +const bufferToJsonInspect = function (this: Uint8Array) { + return base64Encode(this) } /** @@ -54,7 +59,7 @@ export function makeInspectable(obj: new (...args: any[]) => T, props?: (keyo obj.prototype.toJSON = function (nested = false) { if (!nested) { - (Buffer as any).toJSON = bufferToJsonInspect + (Uint8Array as any).toJSON = bufferToJsonInspect } const ret: any = Object.create(proto) @@ -72,7 +77,7 @@ export function makeInspectable(obj: new (...args: any[]) => T, props?: (keyo }) if (!nested) { - Buffer.prototype.toJSON = bufferToJsonOriginal + delete (Uint8Array as any).prototype.toJSON } // eslint-disable-next-line @typescript-eslint/no-unsafe-return diff --git a/packages/client/src/utils/misc-utils.ts b/packages/client/src/utils/misc-utils.ts index 52a01228..b54a0422 100644 --- a/packages/client/src/utils/misc-utils.ts +++ b/packages/client/src/utils/misc-utils.ts @@ -1,6 +1,6 @@ import { MtArgumentError } from '@mtcute/core' -import { ArrayPaginated, ArrayWithTotal, MaybeDynamic, Message } from '../types' +import { ArrayPaginated, ArrayWithTotal, MaybeDynamic, Message } from '../types/index.js' /** * Normalize phone number by stripping formatting diff --git a/packages/client/src/utils/peer-utils.ts b/packages/client/src/utils/peer-utils.ts index b497a663..44e437cd 100644 --- a/packages/client/src/utils/peer-utils.ts +++ b/packages/client/src/utils/peer-utils.ts @@ -1,7 +1,7 @@ import { assertNever, Long, tl } from '@mtcute/core' -import { MtInvalidPeerTypeError } from '../types/errors' -import { InputPeerLike } from '../types/peers' +import { MtInvalidPeerTypeError } from '../types/errors.js' +import { InputPeerLike } from '../types/peers/index.js' export const INVITE_LINK_REGEX = /^(?:https?:\/\/)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)\/(?:joinchat\/|\+))([\w-]+)$/i diff --git a/packages/client/src/utils/rps-meter.ts b/packages/client/src/utils/rps-meter.ts index e2eeca9a..28525053 100644 --- a/packages/client/src/utils/rps-meter.ts +++ b/packages/client/src/utils/rps-meter.ts @@ -1,4 +1,4 @@ -import { Deque } from '@mtcute/core/utils' +import { Deque } from '@mtcute/core/utils.js' export class RpsMeter { _hits: Deque diff --git a/packages/client/src/utils/stream-utils.ts b/packages/client/src/utils/stream-utils.ts index d3ebd7ac..265023e8 100644 --- a/packages/client/src/utils/stream-utils.ts +++ b/packages/client/src/utils/stream-utils.ts @@ -76,7 +76,7 @@ export function convertWebStreamToNodeReadable(webStream: ReadableStream, opts?: return new NodeReadable(webStream, opts) } -export function bufferToStream(buf: Buffer): Readable { +export function bufferToStream(buf: Uint8Array): Readable { return new Readable({ read() { this.push(buf) @@ -85,15 +85,15 @@ export function bufferToStream(buf: Buffer): Readable { }) } -export async function readBytesFromStream(stream: Readable, size: number): Promise { +export async function readBytesFromStream(stream: Readable, size: number): Promise { if (stream.readableEnded) return null - let res = stream.read(size) as Buffer + let res = stream.read(size) as Uint8Array if (!res) { return new Promise((resolve, reject) => { stream.on('readable', function handler() { - res = stream.read(size) as Buffer + res = stream.read(size) as Uint8Array if (res) { stream.off('readable', handler) diff --git a/packages/client/src/utils/voice-utils.ts b/packages/client/src/utils/voice-utils.ts index 0575a89b..e6f2a677 100644 --- a/packages/client/src/utils/voice-utils.ts +++ b/packages/client/src/utils/voice-utils.ts @@ -1,10 +1,12 @@ +import { dataViewFromBuffer } from '@mtcute/core/utils.js' + /** * Decode 5-bit encoded voice message waveform into * an array of waveform values (0-32). * * @param wf Encoded waveform */ -export function decodeWaveform(wf: Buffer): number[] { +export function decodeWaveform(wf: Uint8Array): number[] { const bitsCount = wf.length * 8 const valuesCount = ~~(bitsCount / 5) @@ -22,16 +24,17 @@ export function decodeWaveform(wf: Buffer): number[] { // So we read in a general way all the entries except the last one. const result: number[] = [] + const dv = dataViewFromBuffer(wf) for (let i = 0, j = 0; i < lastIdx; i++, j += 5) { const byteIdx = ~~(j / 8) const bitShift = j % 8 - result[i] = (wf.readUInt16LE(byteIdx) >> bitShift) & 0b11111 + result[i] = (dv.getUint16(byteIdx, true) >> bitShift) & 0b11111 } const lastByteIdx = ~~((lastIdx * 5) / 8) const lastBitShift = (lastIdx * 5) % 8 - const lastValue = lastByteIdx === wf.length - 1 ? wf[lastByteIdx] : wf.readUInt16LE(lastByteIdx) + const lastValue = lastByteIdx === wf.length - 1 ? wf[lastByteIdx] : dv.getUint16(lastByteIdx, true) result[lastIdx] = (lastValue >> lastBitShift) & 0b11111 return result @@ -43,10 +46,11 @@ export function decodeWaveform(wf: Buffer): number[] { * * @param wf Waveform values */ -export function encodeWaveform(wf: number[]): Buffer { +export function encodeWaveform(wf: number[]): Uint8Array { const bitsCount = wf.length * 5 const bytesCount = ~~(bitsCount + 7) / 8 - const result = Buffer.alloc(bytesCount + 1) + const result = new Uint8Array(bytesCount + 1) + const dv = dataViewFromBuffer(result) // Write each 0-31 unsigned char as 5 bit to result. // We reserve one extra byte to be able to dereference any of required bytes @@ -57,8 +61,9 @@ export function encodeWaveform(wf: number[]): Buffer { const bitShift = j % 8 const value = (wf[i] & 0b11111) << bitShift - const old = result.readUInt16LE(byteIdx) - result.writeUInt16LE(old | value, byteIdx) + // const old = result.readUInt16LE(byteIdx) + // result.writeUInt16LE(old | value, byteIdx) + dv.setUint16(byteIdx, dv.getUint16(byteIdx, true) | value, true) } return result.slice(0, bytesCount) diff --git a/packages/client/tests/buffer-utils.spec.ts b/packages/client/tests/buffer-utils.spec.ts index 079f3b1d..24e1bfd4 100644 --- a/packages/client/tests/buffer-utils.spec.ts +++ b/packages/client/tests/buffer-utils.spec.ts @@ -1,25 +1,27 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { isProbablyPlainText } from '../src/utils/file-utils' +import { hexDecodeToBuffer, utf8EncodeToBuffer } from '@mtcute/core/utils.js' + +import { isProbablyPlainText } from '../src/utils/file-utils.js' describe('isProbablyPlainText', () => { it('should return true for buffers only containing printable ascii', () => { - expect(isProbablyPlainText(Buffer.from('hello this is some ascii text'))).to.be.true - expect(isProbablyPlainText(Buffer.from('hello this is some ascii text\nwith unix new lines'))).to.be.true - expect(isProbablyPlainText(Buffer.from('hello this is some ascii text\r\nwith windows new lines'))).to.be.true - expect(isProbablyPlainText(Buffer.from('hello this is some ascii text\n\twith unix new lines and tabs'))).to.be + expect(isProbablyPlainText(utf8EncodeToBuffer('hello this is some ascii text'))).to.be.true + expect(isProbablyPlainText(utf8EncodeToBuffer('hello this is some ascii text\nwith unix new lines'))).to.be.true + expect(isProbablyPlainText(utf8EncodeToBuffer('hello this is some ascii text\r\nwith windows new lines'))).to.be.true + expect(isProbablyPlainText(utf8EncodeToBuffer('hello this is some ascii text\n\twith unix new lines and tabs'))).to.be .true - expect(isProbablyPlainText(Buffer.from('hello this is some ascii text\r\n\twith windows new lines and tabs'))) + expect(isProbablyPlainText(utf8EncodeToBuffer('hello this is some ascii text\r\n\twith windows new lines and tabs'))) .to.be.true }) it('should return false for buffers containing some binary data', () => { - expect(isProbablyPlainText(Buffer.from('hello this is cedilla: ç'))).to.be.false - expect(isProbablyPlainText(Buffer.from('hello this is some ascii text with emojis 🌸'))).to.be.false + expect(isProbablyPlainText(utf8EncodeToBuffer('hello this is cedilla: ç'))).to.be.false + expect(isProbablyPlainText(utf8EncodeToBuffer('hello this is some ascii text with emojis 🌸'))).to.be.false // random strings of 16 bytes - expect(isProbablyPlainText(Buffer.from('717f80f08eb9d88c3931712c0e2be32f', 'hex'))).to.be.false - expect(isProbablyPlainText(Buffer.from('20e8e218e54254c813b261432b0330d7', 'hex'))).to.be.false + expect(isProbablyPlainText(hexDecodeToBuffer('717f80f08eb9d88c3931712c0e2be32f'))).to.be.false + expect(isProbablyPlainText(hexDecodeToBuffer('20e8e218e54254c813b261432b0330d7'))).to.be.false }) }) diff --git a/packages/client/tests/memoize.spec.ts b/packages/client/tests/memoize.spec.ts index 19b3135f..5405bb82 100644 --- a/packages/client/tests/memoize.spec.ts +++ b/packages/client/tests/memoize.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { memoizeGetters } from '../src/utils/memoize' +import { memoizeGetters } from '../src/utils/memoize.js' describe('memoizeGetters', () => { it('should memoize getters', () => { diff --git a/packages/client/tests/tsconfig.json b/packages/client/tests/tsconfig.json new file mode 100644 index 00000000..cfa0657b --- /dev/null +++ b/packages/client/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + ".", + ], + "references": [ + { "path": "../" }, + ] +} diff --git a/packages/client/tsconfig.json b/packages/client/tsconfig.json index 062216e2..6a5497ee 100644 --- a/packages/client/tsconfig.json +++ b/packages/client/tsconfig.json @@ -1,13 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "module": "NodeNext", - "moduleResolution": "NodeNext", - "outDir": "./dist", + "outDir": "./dist/esm", + "rootDir": "./src" }, "include": [ "./src", - "./tests", - "./utils.ts" + ], + "references": [ + { "path": "../core" } ] } diff --git a/packages/client/utils.ts b/packages/client/utils.ts index d014f0a3..50894ad2 100644 --- a/packages/client/utils.ts +++ b/packages/client/utils.ts @@ -1,4 +1,4 @@ // this file only exists as a hint to IDEs that we can use @mtcute/core/utils instead of @mtcute/core/src/utils. // it is not present in the built package, just a DX improvement -export * from './src/utils' +export * from './src/utils/index.js' diff --git a/packages/core/package.json b/packages/core/package.json index 0962aaac..b21c0bce 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -6,17 +6,39 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "src/index.ts", + "type": "module", "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", - "build": "tsc", + "test": "mocha \"tests/**/*.spec.ts\"", + "build": "pnpm run -w build-package core", "docs": "typedoc" }, "browser": { - "./utils/platform/crypto.js": "./utils/platform/crypto.web.js", - "./utils/platform/transport.js": "./utils/platform/transport.web.js", - "./utils/platform/logging.js": "./utils/platform/logging.web.js", - "./utils/platform/random.js": "./utils/platform/random.web.js", - "./storage/json-file.js": false + "./cjs/utils/platform/crypto.js": "./cjs/utils/platform/crypto.web.js", + "./esm/utils/platform/crypto.js": "./esm/utils/platform/crypto.web.js", + "./cjs/utils/platform/transport.js": "./cjs/utils/platform/transport.web.js", + "./esm/utils/platform/transport.js": "./esm/utils/platform/transport.web.js", + "./cjs/utils/platform/logging.js": "./cjs/utils/platform/logging.web.js", + "./esm/utils/platform/logging.js": "./esm/utils/platform/logging.web.js", + "./cjs/utils/platform/random.js": "./cjs/utils/platform/random.web.js", + "./esm/utils/platform/random.js": "./esm/utils/platform/random.web.js", + "./cjs/storage/json-file.js": false, + "./esm/storage/json-file.js": false + }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + }, + "./utils.js": { + "import": "./esm/utils/index.js", + "require": "./cjs/utils/index.js" + }, + "./utils/crypto/*.js": { + "import": "./esm/utils/crypto/*.js", + "require": "./cjs/utils/crypto/*.js" + } + } }, "dependencies": { "@mtcute/tl": "workspace:^165.0.0", @@ -28,8 +50,9 @@ "long": "5.2.3" }, "devDependencies": { - "@mtcute/dispatcher": "workspace:^1.0.0", + "@cryptography/aes": "^0.1.1", "@types/ws": "8.5.4", + "node-forge": "1.3.1", "ws": "8.13.0" } } diff --git a/packages/core/src/base-client.ts b/packages/core/src/base-client.ts index df7c2fdd..ed572050 100644 --- a/packages/core/src/base-client.ts +++ b/packages/core/src/base-client.ts @@ -3,16 +3,16 @@ import EventEmitter from 'events' import Long from 'long' import { tl } from '@mtcute/tl' -import defaultReaderMap from '@mtcute/tl/binary/reader' -import defaultWriterMap from '@mtcute/tl/binary/writer' +import { __tlReaderMap as defaultReaderMap } from '@mtcute/tl/binary/reader.js' +import { __tlWriterMap as defaultWriterMap } from '@mtcute/tl/binary/writer.js' import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime' -import { ReconnectionStrategy, SessionConnection, TransportFactory } from './network' -import { ConfigManager } from './network/config-manager' -import { NetworkManager, NetworkManagerExtraParams, RpcCallOptions } from './network/network-manager' -import { PersistentConnectionParams } from './network/persistent-connection' -import { ITelegramStorage, MemoryStorage } from './storage' -import { MustEqual } from './types' +import { ConfigManager } from './network/config-manager.js' +import { ReconnectionStrategy, SessionConnection, TransportFactory } from './network/index.js' +import { NetworkManager, NetworkManagerExtraParams, RpcCallOptions } from './network/network-manager.js' +import { PersistentConnectionParams } from './network/persistent-connection.js' +import { ITelegramStorage, MemoryStorage } from './storage/index.js' +import { MustEqual } from './types/index.js' import { ControllablePromise, createControllablePromise, @@ -28,7 +28,7 @@ import { readStringSession, toggleChannelIdMark, writeStringSession, -} from './utils' +} from './utils/index.js' export interface BaseTelegramClientOptions { /** diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index c13001d1..792b33ff 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,13 +1,11 @@ -export * from './base-client' -export * from './network' -export * from './storage' -export * from './types' -export * from './utils/peer-utils' +export * from './base-client.js' +export * from './network/index.js' +export * from './storage/index.js' +export * from './types/index.js' +export * from './utils/peer-utils.js' /** @hidden */ export * from '@mtcute/tl' -/** @hidden */ -export * from '@mtcute/tl-runtime' import Long from 'long' /** @hidden */ export { Long } diff --git a/packages/core/src/network/auth-key.ts b/packages/core/src/network/auth-key.ts index 021cea89..deb12791 100644 --- a/packages/core/src/network/auth-key.ts +++ b/packages/core/src/network/auth-key.ts @@ -3,17 +3,17 @@ import Long from 'long' import { tl } from '@mtcute/tl' import { TlBinaryReader, TlReaderMap } from '@mtcute/tl-runtime' -import { MtcuteError } from '../types' -import { buffersEqual, ICryptoProvider, Logger, randomBytes } from '../utils' -import { createAesIgeForMessage } from '../utils/crypto/mtproto' +import { MtcuteError } from '../types/errors.js' +import { createAesIgeForMessage } from '../utils/crypto/mtproto.js' +import { buffersEqual, concatBuffers, dataViewFromBuffer, ICryptoProvider, Logger, randomBytes } from '../utils/index.js' export class AuthKey { ready = false - key!: Buffer - id!: Buffer - clientSalt!: Buffer - serverSalt!: Buffer + key!: Uint8Array + id!: Uint8Array + clientSalt!: Uint8Array + serverSalt!: Uint8Array constructor( readonly _crypto: ICryptoProvider, @@ -21,56 +21,67 @@ export class AuthKey { readonly _readerMap: TlReaderMap, ) {} - match(keyId: Buffer): boolean { + match(keyId: Uint8Array): boolean { return this.ready && buffersEqual(keyId, this.id) } - async setup(authKey?: Buffer | null): Promise { + async setup(authKey?: Uint8Array | null): Promise { if (!authKey) return this.reset() this.ready = true this.key = authKey - this.clientSalt = authKey.slice(88, 120) - this.serverSalt = authKey.slice(96, 128) - this.id = (await this._crypto.sha1(authKey)).slice(-8) + this.clientSalt = authKey.subarray(88, 120) + this.serverSalt = authKey.subarray(96, 128) + this.id = (await this._crypto.sha1(authKey)).subarray(-8) this.log.verbose('auth key set up, id = %h', this.id) } - async encryptMessage(message: Buffer, serverSalt: Long, sessionId: Long): Promise { + async encryptMessage(message: Uint8Array, serverSalt: Long, sessionId: Long): Promise { if (!this.ready) throw new MtcuteError('Keys are not set up!') let padding = (16 /* header size */ + message.length + 12) /* min padding */ % 16 padding = 12 + (padding ? 16 - padding : 0) - const buf = Buffer.alloc(16 + message.length + padding) + const buf = new Uint8Array(16 + message.length + padding) + const dv = dataViewFromBuffer(buf) - buf.writeInt32LE(serverSalt.low) - buf.writeInt32LE(serverSalt.high, 4) - buf.writeInt32LE(sessionId.low, 8) - buf.writeInt32LE(sessionId.high, 12) - message.copy(buf, 16) - randomBytes(padding).copy(buf, 16 + message.length) + dv.setInt32(0, serverSalt.low, true) + dv.setInt32(4, serverSalt.high, true) + dv.setInt32(8, sessionId.low, true) + dv.setInt32(12, sessionId.high, true) + buf.set(message, 16) + buf.set(randomBytes(padding), 16 + message.length) - const messageKey = (await this._crypto.sha256(Buffer.concat([this.clientSalt, buf]))).slice(8, 24) + const messageKey = (await this._crypto.sha256(concatBuffers([this.clientSalt, buf]))).subarray(8, 24) const ige = await createAesIgeForMessage(this._crypto, this.key, messageKey, true) const encryptedData = await ige.encrypt(buf) - return Buffer.concat([this.id, messageKey, encryptedData]) + return concatBuffers([this.id, messageKey, encryptedData]) } async decryptMessage( - data: Buffer, + data: Uint8Array, sessionId: Long, callback: (msgId: tl.Long, seqNo: number, data: TlBinaryReader) => void, ): Promise { - const messageKey = data.slice(8, 24) - const encryptedData = data.slice(24) + const messageKey = data.subarray(8, 24) + let encryptedData = data.subarray(24) + + const mod16 = encryptedData.byteLength % 16 + + if (mod16 !== 0) { + // strip padding in case of padded transport. + // i wish this could be done at transport level, but we can't properly align anything there + // because padding size is not known, and transport level should not be aware of MTProto structure + encryptedData = encryptedData.subarray(0, encryptedData.byteLength - mod16) + } const ige = await createAesIgeForMessage(this._crypto, this.key, messageKey, false) const innerData = await ige.decrypt(encryptedData) - const expectedMessageKey = (await this._crypto.sha256(Buffer.concat([this.serverSalt, innerData]))).slice(8, 24) + const msgKeySource = await this._crypto.sha256(concatBuffers([this.serverSalt, innerData])) + const expectedMessageKey = msgKeySource.subarray(8, 24) if (!buffersEqual(messageKey, expectedMessageKey)) { this.log.warn( diff --git a/packages/core/src/network/authorization.ts b/packages/core/src/network/authorization.ts index dea2cd0e..7b184a5e 100644 --- a/packages/core/src/network/authorization.ts +++ b/packages/core/src/network/authorization.ts @@ -2,18 +2,18 @@ import bigInt from 'big-integer' import Long from 'long' import { mtp } from '@mtcute/tl' -import { TlPublicKey } from '@mtcute/tl/binary/rsa-keys' +import { TlPublicKey } from '@mtcute/tl/binary/rsa-keys.js' import { TlBinaryReader, TlBinaryWriter, TlSerializationCounter } from '@mtcute/tl-runtime' -import { MtArgumentError, MtSecurityError, MtTypeAssertionError } from '../types' -import { bigIntToBuffer, bufferToBigInt, ICryptoProvider, Logger } from '../utils' -import { buffersEqual, randomBytes } from '../utils/buffer-utils' -import { findKeyByFingerprints } from '../utils/crypto/keys' -import { millerRabin } from '../utils/crypto/miller-rabin' -import { generateKeyAndIvFromNonce } from '../utils/crypto/mtproto' -import { xorBuffer, xorBufferInPlace } from '../utils/crypto/utils' -import { mtpAssertTypeIs } from '../utils/type-assertions' -import { SessionConnection } from './session-connection' +import { MtArgumentError, MtSecurityError, MtTypeAssertionError } from '../types/index.js' +import { buffersEqual, concatBuffers, dataViewFromBuffer, randomBytes } from '../utils/buffer-utils.js' +import { findKeyByFingerprints } from '../utils/crypto/keys.js' +import { millerRabin } from '../utils/crypto/miller-rabin.js' +import { generateKeyAndIvFromNonce } from '../utils/crypto/mtproto.js' +import { xorBuffer, xorBufferInPlace } from '../utils/crypto/utils.js' +import { bigIntToBuffer, bufferToBigInt, ICryptoProvider, Logger } from '../utils/index.js' +import { mtpAssertTypeIs } from '../utils/type-assertions.js' +import { SessionConnection } from './session-connection.js' // Heavily based on code from https://github.com/LonamiWebs/Telethon/blob/master/telethon/network/authenticator.py @@ -120,7 +120,7 @@ function checkDhPrime(log: Logger, dhPrime: bigInt.BigInteger, g: number) { log.debug('g = %d is safe to use with dh_prime', g) } -async function rsaPad(data: Buffer, crypto: ICryptoProvider, key: TlPublicKey): Promise { +async function rsaPad(data: Uint8Array, crypto: ICryptoProvider, key: TlPublicKey): Promise { // since Summer 2021, they use "version of RSA with a variant of OAEP+ padding explained below" const keyModulus = bigInt(key.modulus, 16) @@ -130,23 +130,23 @@ async function rsaPad(data: Buffer, crypto: ICryptoProvider, key: TlPublicKey): throw new MtArgumentError('Failed to pad: too big data') } - data = Buffer.concat([data, randomBytes(192 - data.length)]) + data = concatBuffers([data, randomBytes(192 - data.length)]) for (;;) { - const aesIv = Buffer.alloc(32) + const aesIv = new Uint8Array(32) const aesKey = randomBytes(32) - const dataWithHash = Buffer.concat([data, await crypto.sha256(Buffer.concat([aesKey, data]))]) + const dataWithHash = concatBuffers([data, await crypto.sha256(concatBuffers([aesKey, data]))]) // we only need to reverse the data - dataWithHash.slice(0, 192).reverse() + dataWithHash.subarray(0, 192).reverse() - const aes = crypto.createAesIge(aesKey, aesIv) + const aes = await crypto.createAesIge(aesKey, aesIv) const encrypted = await aes.encrypt(dataWithHash) const encryptedHash = await crypto.sha256(encrypted) xorBufferInPlace(aesKey, encryptedHash) - const decryptedData = Buffer.concat([aesKey, encrypted]) + const decryptedData = concatBuffers([aesKey, encrypted]) const decryptedDataBigint = bufferToBigInt(decryptedData) @@ -160,8 +160,8 @@ async function rsaPad(data: Buffer, crypto: ICryptoProvider, key: TlPublicKey): } } -async function rsaEncrypt(data: Buffer, crypto: ICryptoProvider, key: TlPublicKey): Promise { - const toEncrypt = Buffer.concat([ +async function rsaEncrypt(data: Uint8Array, crypto: ICryptoProvider, key: TlPublicKey): Promise { + const toEncrypt = concatBuffers([ await crypto.sha1(data), data, // sha1 is always 20 bytes, so we're left with 255 - 20 - x padding @@ -182,7 +182,7 @@ export async function doAuthorization( connection: SessionConnection, crypto: ICryptoProvider, expiresIn?: number, -): Promise<[Buffer, Long, number]> { +): Promise<[Uint8Array, Long, number]> { // eslint-disable-next-line dot-notation const session = connection['_session'] const readerMap = session._readerMap @@ -292,15 +292,6 @@ export async function doAuthorization( throw new MtSecurityError('Step 2: invalid server nonce from server') } - // type was removed from schema in July 2021 - // if (serverDhParams._ === 'mt_server_DH_params_fail') { - // // why would i want to do that? we are gonna fail anyways. - // // let expectedNnh = (await crypto.sha1(newNonce)).slice(4, 20) - // // if (!buffersEqual(serverDhParams.newNonceHash, expectedNnh)) - // // throw new MtSecurityError('Step 2: invalid DH fail nonce from server') - // throw new MtSecurityError('Step 2: server DH failed') - // } - log.debug('server DH ok') if (serverDhParams.encryptedAnswer.length % 16 !== 0) { @@ -309,14 +300,14 @@ export async function doAuthorization( // Step 3: complete DH exchange const [key, iv] = await generateKeyAndIvFromNonce(crypto, resPq.serverNonce, newNonce) - const ige = crypto.createAesIge(key, iv) + const ige = await crypto.createAesIge(key, iv) const plainTextAnswer = await ige.decrypt(serverDhParams.encryptedAnswer) - const innerDataHash = plainTextAnswer.slice(0, 20) + const innerDataHash = plainTextAnswer.subarray(0, 20) const serverDhInnerReader = new TlBinaryReader(readerMap, plainTextAnswer, 20) const serverDhInner = serverDhInnerReader.object() as mtp.TlObject - if (!buffersEqual(innerDataHash, await crypto.sha1(plainTextAnswer.slice(20, serverDhInnerReader.pos)))) { + if (!buffersEqual(innerDataHash, await crypto.sha1(plainTextAnswer.subarray(20, serverDhInnerReader.pos)))) { throw new MtSecurityError('Step 3: invalid inner data hash') } @@ -338,14 +329,14 @@ export async function doAuthorization( checkDhPrime(log, dhPrime, serverDhInner.g) let retryId = Long.ZERO - const serverSalt = xorBuffer(newNonce.slice(0, 8), resPq.serverNonce.slice(0, 8)) + const serverSalt = xorBuffer(newNonce.subarray(0, 8), resPq.serverNonce.subarray(0, 8)) for (;;) { const b = bufferToBigInt(randomBytes(256)) const gB = g.modPow(b, dhPrime) const authKey = bigIntToBuffer(gA.modPow(b, dhPrime)) - const authKeyAuxHash = (await crypto.sha1(authKey)).slice(0, 8) + const authKeyAuxHash = (await crypto.sha1(authKey)).subarray(0, 8) // validate DH params if (g.lesserOrEquals(1) || g.greaterOrEquals(dhPrime.minus(bigInt.one))) { @@ -382,13 +373,13 @@ export async function doAuthorization( const clientDhInnerWriter = TlBinaryWriter.alloc(writerMap, innerLength) clientDhInnerWriter.pos = 20 clientDhInnerWriter.object(clientDhInner) - const clientDhInnerHash = await crypto.sha1(clientDhInnerWriter.buffer.slice(20, clientDhInnerWriter.pos)) + const clientDhInnerHash = await crypto.sha1(clientDhInnerWriter.uint8View.subarray(20, clientDhInnerWriter.pos)) clientDhInnerWriter.pos = 0 clientDhInnerWriter.raw(clientDhInnerHash) log.debug('sending client DH (timeOffset = %d)', timeOffset) - const clientDhEncrypted = await ige.encrypt(clientDhInnerWriter.buffer) + const clientDhEncrypted = await ige.encrypt(clientDhInnerWriter.uint8View) await sendPlainMessage({ _: 'mt_set_client_DH_params', nonce, @@ -417,9 +408,9 @@ export async function doAuthorization( } if (dhGen._ === 'mt_dh_gen_retry') { - const expectedHash = await crypto.sha1(Buffer.concat([newNonce, Buffer.from([2]), authKeyAuxHash])) + const expectedHash = await crypto.sha1(concatBuffers([newNonce, new Uint8Array([2]), authKeyAuxHash])) - if (!buffersEqual(expectedHash.slice(4, 20), dhGen.newNonceHash2)) { + if (!buffersEqual(expectedHash.subarray(4, 20), dhGen.newNonceHash2)) { throw Error('Step 4: invalid retry nonce hash from server') } retryId = Long.fromBytesLE(authKeyAuxHash as unknown as number[]) @@ -428,14 +419,16 @@ export async function doAuthorization( if (dhGen._ !== 'mt_dh_gen_ok') throw new Error() // unreachable - const expectedHash = await crypto.sha1(Buffer.concat([newNonce, Buffer.from([1]), authKeyAuxHash])) + const expectedHash = await crypto.sha1(concatBuffers([newNonce, new Uint8Array([1]), authKeyAuxHash])) - if (!buffersEqual(expectedHash.slice(4, 20), dhGen.newNonceHash1)) { + if (!buffersEqual(expectedHash.subarray(4, 20), dhGen.newNonceHash1)) { throw Error('Step 4: invalid nonce hash from server') } log.info('authorization successful') - return [authKey, new Long(serverSalt.readInt32LE(), serverSalt.readInt32LE(4)), timeOffset] + const dv = dataViewFromBuffer(serverSalt) + + return [authKey, new Long(dv.getInt32(0, true), dv.getInt32(4, true)), timeOffset] } } diff --git a/packages/core/src/network/index.ts b/packages/core/src/network/index.ts index cbc1ccb6..4973595f 100644 --- a/packages/core/src/network/index.ts +++ b/packages/core/src/network/index.ts @@ -1,4 +1,4 @@ -export { ConnectionKind, NetworkManagerExtraParams, RpcCallOptions } from './network-manager' -export * from './reconnection' -export * from './session-connection' -export * from './transports' +export { ConnectionKind, NetworkManagerExtraParams, RpcCallOptions } from './network-manager.js' +export * from './reconnection.js' +export * from './session-connection.js' +export * from './transports/index.js' diff --git a/packages/core/src/network/mtproto-session.ts b/packages/core/src/network/mtproto-session.ts index 00624661..f4a0052f 100644 --- a/packages/core/src/network/mtproto-session.ts +++ b/packages/core/src/network/mtproto-session.ts @@ -3,7 +3,7 @@ import Long from 'long' import { mtp, tl } from '@mtcute/tl' import { TlBinaryWriter, TlReaderMap, TlSerializationCounter, TlWriterMap } from '@mtcute/tl-runtime' -import { MtcuteError } from '../types' +import { MtcuteError } from '../types/index.js' import { ControllablePromise, Deque, @@ -14,12 +14,12 @@ import { LruSet, randomLong, SortedArray, -} from '../utils' -import { AuthKey } from './auth-key' +} from '../utils/index.js' +import { AuthKey } from './auth-key.js' export interface PendingRpc { method: string - data: Buffer + data: Uint8Array promise: ControllablePromise stack?: string gzipOverhead?: number @@ -243,17 +243,17 @@ export class MtprotoSession { } /** Encrypt a single MTProto message using session's keys */ - async encryptMessage(message: Buffer): Promise { + async encryptMessage(message: Uint8Array): Promise { const key = this._authKeyTemp.ready ? this._authKeyTemp : this._authKey return key.encryptMessage(message, this.serverSalt, this._sessionId) } /** Decrypt a single MTProto message using session's keys */ - async decryptMessage(data: Buffer, callback: Parameters[2]): Promise { + async decryptMessage(data: Uint8Array, callback: Parameters[2]): Promise { if (!this._authKey.ready) throw new MtcuteError('Keys are not set up!') - const authKeyId = data.slice(0, 8) + const authKeyId = data.subarray(0, 8) let key: AuthKey @@ -278,18 +278,22 @@ export class MtprotoSession { return key.decryptMessage(data, this._sessionId, callback) } - writeMessage(writer: TlBinaryWriter, content: tl.TlObject | mtp.TlObject | Buffer, isContentRelated = true): Long { + writeMessage( + writer: TlBinaryWriter, + content: tl.TlObject | mtp.TlObject | Uint8Array, + isContentRelated = true, + ): Long { const messageId = this.getMessageId() const seqNo = this.getSeqNo(isContentRelated) - const length = Buffer.isBuffer(content) ? + const length = ArrayBuffer.isView(content) ? content.length : TlSerializationCounter.countNeededBytes(writer.objectMap!, content) writer.long(messageId) writer.int(seqNo) writer.uint(length) - if (Buffer.isBuffer(content)) writer.raw(content) + if (ArrayBuffer.isView(content)) writer.raw(content) else writer.object(content as tl.TlObject) return messageId diff --git a/packages/core/src/network/multi-session-connection.ts b/packages/core/src/network/multi-session-connection.ts index c04c09c9..4128a2a3 100644 --- a/packages/core/src/network/multi-session-connection.ts +++ b/packages/core/src/network/multi-session-connection.ts @@ -2,10 +2,10 @@ import EventEmitter from 'events' import { tl } from '@mtcute/tl' -import { Logger } from '../utils' -import { MtprotoSession } from './mtproto-session' -import { SessionConnection, SessionConnectionParams } from './session-connection' -import { TransportFactory } from './transports' +import { Logger } from '../utils/index.js' +import { MtprotoSession } from './mtproto-session.js' +import { SessionConnection, SessionConnectionParams } from './session-connection.js' +import { TransportFactory } from './transports/index.js' export class MultiSessionConnection extends EventEmitter { private _log: Logger @@ -237,7 +237,7 @@ export class MultiSessionConnection extends EventEmitter { this.connect() } - async setAuthKey(authKey: Buffer | null, temp = false, idx = 0): Promise { + async setAuthKey(authKey: Uint8Array | null, temp = false, idx = 0): Promise { const session = this._sessions[idx] const key = temp ? session._authKeyTemp : session._authKey await key.setup(authKey) diff --git a/packages/core/src/network/network-manager.ts b/packages/core/src/network/network-manager.ts index 92d36842..5805e61a 100644 --- a/packages/core/src/network/network-manager.ts +++ b/packages/core/src/network/network-manager.ts @@ -1,16 +1,16 @@ import { tl } from '@mtcute/tl' import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime' -import { ITelegramStorage } from '../storage' -import { MtArgumentError, MtcuteError } from '../types' -import { createControllablePromise, ICryptoProvider, Logger, sleep } from '../utils' -import { assertTypeIs } from '../utils/type-assertions' -import { ConfigManager } from './config-manager' -import { MultiSessionConnection } from './multi-session-connection' -import { PersistentConnectionParams } from './persistent-connection' -import { defaultReconnectionStrategy, ReconnectionStrategy } from './reconnection' -import { SessionConnection, SessionConnectionParams } from './session-connection' -import { defaultTransportFactory, TransportFactory } from './transports' +import { ITelegramStorage } from '../storage/index.js' +import { MtArgumentError, MtcuteError } from '../types/index.js' +import { createControllablePromise, ICryptoProvider, Logger, sleep } from '../utils/index.js' +import { assertTypeIs } from '../utils/type-assertions.js' +import { ConfigManager } from './config-manager.js' +import { MultiSessionConnection } from './multi-session-connection.js' +import { PersistentConnectionParams } from './persistent-connection.js' +import { defaultReconnectionStrategy, ReconnectionStrategy } from './reconnection.js' +import { SessionConnection, SessionConnectionParams } from './session-connection.js' +import { defaultTransportFactory, TransportFactory } from './transports/index.js' export type ConnectionKind = 'main' | 'upload' | 'download' | 'downloadSmall' @@ -223,7 +223,7 @@ export class DcConnectionManager { private _setupMulti(kind: ConnectionKind): void { const connection = this[kind] - connection.on('key-change', (idx, key: Buffer | null) => { + connection.on('key-change', (idx, key: Uint8Array | null) => { if (kind !== 'main') { // main connection is responsible for authorization, // and keys are then sent to other connections @@ -248,7 +248,7 @@ export class DcConnectionManager { }) .catch((e: Error) => this.manager.params._emitError(e)) }) - connection.on('tmp-key-change', (idx: number, key: Buffer | null, expires: number) => { + connection.on('tmp-key-change', (idx: number, key: Uint8Array | null, expires: number) => { if (kind !== 'main') { this.manager._log.warn('got tmp-key-change from non-main connection, ignoring') @@ -370,22 +370,11 @@ export class NetworkManager { readonly config: ConfigManager, ) { let deviceModel = 'mtcute on ' - let appVersion = 'unknown' + /* eslint-disable no-restricted-globals */ if (typeof process !== 'undefined' && typeof require !== 'undefined') { const os = require('os') as typeof import('os') deviceModel += `${os.type()} ${os.arch()} ${os.release()}` - - try { - // for production builds - - appVersion = (require('../package.json') as { version: string }).version - } catch (e) { - try { - // for development builds (additional /src/ in path) - - appVersion = (require('../../package.json') as { version: string }).version - } catch (e) {} - } + /* eslint-enable no-restricted-globals */ } else if (typeof navigator !== 'undefined') { deviceModel += navigator.userAgent } else deviceModel += 'unknown' @@ -394,7 +383,7 @@ export class NetworkManager { _: 'initConnection', deviceModel, systemVersion: '1.0', - appVersion, + appVersion: '%VERSION%', systemLangCode: 'en', langPack: '', // "langPacks are for official apps only" langCode: 'en', @@ -734,7 +723,7 @@ export class NetworkManager { throw lastError! } - setUpdateHandler(handler: NetworkManager['_updateHandler']): void { + setUpdateHandler(handler: (upd: tl.TypeUpdates, fromClient: boolean) => void): void { this._updateHandler = handler } diff --git a/packages/core/src/network/persistent-connection.ts b/packages/core/src/network/persistent-connection.ts index 26caf942..e1be85bf 100644 --- a/packages/core/src/network/persistent-connection.ts +++ b/packages/core/src/network/persistent-connection.ts @@ -2,10 +2,10 @@ import EventEmitter from 'events' import { tl } from '@mtcute/tl' -import { MtcuteError } from '../types' -import { ICryptoProvider, Logger } from '../utils' -import { ReconnectionStrategy } from './reconnection' -import { ITelegramTransport, TransportFactory, TransportState } from './transports' +import { MtcuteError } from '../types/index.js' +import { ICryptoProvider, Logger } from '../utils/index.js' +import { ReconnectionStrategy } from './reconnection.js' +import { ITelegramTransport, TransportFactory, TransportState } from './transports/index.js' export interface PersistentConnectionParams { crypto: ICryptoProvider @@ -29,7 +29,7 @@ export abstract class PersistentConnection extends EventEmitter { readonly params: PersistentConnectionParams protected _transport!: ITelegramTransport - private _sendOnceConnected: Buffer[] = [] + private _sendOnceConnected: Uint8Array[] = [] // reconnection private _lastError: Error | null = null @@ -48,7 +48,7 @@ export abstract class PersistentConnection extends EventEmitter { protected abstract onError(err: Error): void - protected abstract onMessage(data: Buffer): void + protected abstract onMessage(data: Uint8Array): void protected constructor( params: PersistentConnectionParams, @@ -219,7 +219,7 @@ export abstract class PersistentConnection extends EventEmitter { } } - async send(data: Buffer): Promise { + async send(data: Uint8Array): Promise { if (this._inactive) { this.connect() } diff --git a/packages/core/src/network/session-connection.ts b/packages/core/src/network/session-connection.ts index 4ac6ccba..31b9297e 100644 --- a/packages/core/src/network/session-connection.ts +++ b/packages/core/src/network/session-connection.ts @@ -3,11 +3,20 @@ import Long from 'long' import { mtp, tl } from '@mtcute/tl' -import { TlBinaryReader, TlBinaryWriter, TlReaderMap, TlSerializationCounter, TlWriterMap } from '@mtcute/tl-runtime' -import { gzipDeflate, gzipInflate } from '@mtcute/tl-runtime/src/platform/gzip' - -import { MtArgumentError, MtcuteError, MtTimeoutError } from '../types' import { + gzipDeflate, + gzipInflate, + TlBinaryReader, + TlBinaryWriter, + TlReaderMap, + TlSerializationCounter, + TlWriterMap, +} from '@mtcute/tl-runtime' + +import { MtArgumentError, MtcuteError, MtTimeoutError } from '../types/index.js' +import { createAesIgeForMessageOld } from '../utils/crypto/mtproto.js' +import { + concatBuffers, ControllablePromise, createControllablePromise, EarlyTimer, @@ -15,13 +24,12 @@ import { randomBytes, randomLong, removeFromLongArray, -} from '../utils' -import { createAesIgeForMessageOld } from '../utils/crypto/mtproto' -import { reportUnknownError } from '../utils/platform/error-reporting' -import { doAuthorization } from './authorization' -import { MtprotoSession, PendingMessage, PendingRpc } from './mtproto-session' -import { PersistentConnection, PersistentConnectionParams } from './persistent-connection' -import { TransportError } from './transports' +} from '../utils/index.js' +import { reportUnknownError } from '../utils/platform/error-reporting.js' +import { doAuthorization } from './authorization.js' +import { MtprotoSession, PendingMessage, PendingRpc } from './mtproto-session.js' +import { PersistentConnection, PersistentConnectionParams } from './persistent-connection.js' +import { TransportError } from './transports/abstract.js' const TEMP_AUTH_KEY_EXPIRY = 86400 @@ -61,7 +69,7 @@ export class SessionConnection extends PersistentConnection { private _queuedDestroySession: Long[] = [] // waitForMessage - private _pendingWaitForUnencrypted: [ControllablePromise, NodeJS.Timeout][] = [] + private _pendingWaitForUnencrypted: [ControllablePromise, NodeJS.Timeout][] = [] private _usePfs = this.params.usePfs ?? false private _isPfsBindingPending = false @@ -85,7 +93,7 @@ export class SessionConnection extends PersistentConnection { this._handleRawMessage = this._handleRawMessage.bind(this) } - getAuthKey(temp = false): Buffer | null { + getAuthKey(temp = false): Uint8Array | null { const key = temp ? this._session._authKeyTemp : this._session._authKey if (!key.ready) return null @@ -350,7 +358,7 @@ export class SessionConnection extends PersistentConnection { const msgWithPadding = writer.result() const hash = await this.params.crypto.sha1(msgWithoutPadding) - const msgKey = hash.slice(4, 20) + const msgKey = hash.subarray(4, 20) const ige = await createAesIgeForMessageOld( this.params.crypto, @@ -359,7 +367,7 @@ export class SessionConnection extends PersistentConnection { true, ) const encryptedData = await ige.encrypt(msgWithPadding) - const encryptedMessage = Buffer.concat([this._session._authKey.id, msgKey, encryptedData]) + const encryptedMessage = concatBuffers([this._session._authKey.id, msgKey, encryptedData]) const promise = createControllablePromise() @@ -461,8 +469,8 @@ export class SessionConnection extends PersistentConnection { }) } - waitForUnencryptedMessage(timeout = 5000): Promise { - const promise = createControllablePromise() + waitForUnencryptedMessage(timeout = 5000): Promise { + const promise = createControllablePromise() const timeoutId = setTimeout(() => { promise.reject(new MtTimeoutError(timeout)) this._pendingWaitForUnencrypted = this._pendingWaitForUnencrypted.filter((it) => it[0] !== promise) @@ -472,19 +480,19 @@ export class SessionConnection extends PersistentConnection { return promise } - protected async onMessage(data: Buffer): Promise { - if (data.readInt32LE(0) === 0 && data.readInt32LE(4) === 0) { - // auth_key_id = 0, meaning it's an unencrypted message used for authorization + protected async onMessage(data: Uint8Array): Promise { + if (this._pendingWaitForUnencrypted.length) { + const int32 = new Int32Array(data.buffer, data.byteOffset, 2) + + if (int32[0] === 0 && int32[1] === 0) { + // auth_key_id = 0, meaning it's an unencrypted message used for authorization - if (this._pendingWaitForUnencrypted.length) { const [promise, timeout] = this._pendingWaitForUnencrypted.shift()! clearTimeout(timeout) promise.resolve(data) - } else { - this.log.debug('unencrypted message received, but no one is waiting for it') - } - return + return + } } if (!this._session._authKey.ready) { @@ -1119,7 +1127,7 @@ export class SessionConnection extends PersistentConnection { this.log.debug('received message info for %l, and answer (%l) was already received', msgId, answerMsgId) } - private _onMessagesInfo(msgIds: Long[], info: Buffer): void { + private _onMessagesInfo(msgIds: Long[], info: Uint8Array): void { if (msgIds.length !== info.length) { this.log.warn('messages state info was invalid: msg_ids.length !== info.length') } @@ -1254,7 +1262,7 @@ export class SessionConnection extends PersistentConnection { // if it is less than 0.9, then try to compress the whole request const middle = ~~((content.length - 1024) / 2) - const gzipped = gzipDeflate(content.slice(middle, middle + 1024), 0.9) + const gzipped = gzipDeflate(content.subarray(middle, middle + 1024), 0.9) if (!gzipped) shouldGzip = false } @@ -1417,23 +1425,24 @@ export class SessionConnection extends PersistentConnection { let containerMessageCount = 0 let containerSize = 0 - let ackRequest: Buffer | null = null + let ackRequest: Uint8Array | null = null let ackMsgIds: Long[] | null = null - let pingRequest: Buffer | null = null + let pingRequest: Uint8Array | null = null let pingId: Long | null = null let pingMsgId: Long | null = null - let getStateRequest: Buffer | null = null + let getStateRequest: Uint8Array | null = null let getStateMsgId: Long | null = null let getStateMsgIds: Long[] | null = null - let resendRequest: Buffer | null = null + let resendRequest: Uint8Array | null = null let resendMsgId: Long | null = null let resendMsgIds: Long[] | null = null let cancelRpcs: Long[] | null = null let destroySessions: Long[] | null = null + let rootMsgId: Long | null = null const now = Date.now() @@ -1706,6 +1715,7 @@ export class SessionConnection extends PersistentConnection { this._session.getStateSchedule.insert(msg) } + if (rootMsgId === null) rootMsgId = msg.msgId writer.long(this._registerOutgoingMsgId(msg.msgId)) writer.uint(msg.seqNo!) @@ -1730,6 +1740,7 @@ export class SessionConnection extends PersistentConnection { const containerId = this._session.getMessageId() writer.pos = 0 + rootMsgId = containerId writer.long(this._registerOutgoingMsgId(containerId)) writer.uint(this._session.getSeqNo(false)) writer.uint(packetSize - 16) @@ -1758,7 +1769,6 @@ export class SessionConnection extends PersistentConnection { const result = writer.result() // probably the easiest way lol - const rootMsgId = new Long(result.readInt32LE(), result.readInt32LE(4)) this.log.debug( 'sending %d messages: size = %db, acks = %d (msg_id = %s), ping = %s (msg_id = %s), state_req = %s (msg_id = %s), resend = %s (msg_id = %s), cancels = %s (msg_id = %s), rpc = %s, container = %s, root msg_id = %l', @@ -1789,7 +1799,7 @@ export class SessionConnection extends PersistentConnection { if (ackMsgIds) { this._session.queuedAcks.splice(0, 0, ...ackMsgIds) } - this._onMessageFailed(rootMsgId, 'unknown error') + this._onMessageFailed(rootMsgId!, 'unknown error') }) } } diff --git a/packages/core/src/network/transports/abstract.ts b/packages/core/src/network/transports/abstract.ts index 435f0718..dcd79e09 100644 --- a/packages/core/src/network/transports/abstract.ts +++ b/packages/core/src/network/transports/abstract.ts @@ -2,8 +2,8 @@ import EventEmitter from 'events' import { tl } from '@mtcute/tl' -import { MaybeAsync } from '../../types' -import { ICryptoProvider, Logger } from '../../utils' +import { MaybeAsync } from '../../types/index.js' +import { ICryptoProvider, Logger } from '../../utils/index.js' export enum TransportState { /** @@ -49,7 +49,7 @@ export interface ITelegramTransport extends EventEmitter { /** call to close existing connection to some DC */ close(): void /** send a message */ - send(data: Buffer): Promise + send(data: Uint8Array): Promise /** * Provides crypto and logging for the transport. @@ -72,13 +72,13 @@ export type TransportFactory = () => ITelegramTransport */ export interface IPacketCodec { /** Initial tag of the codec. Will be sent immediately once connected. */ - tag(): MaybeAsync + tag(): MaybeAsync /** Encodes and frames a single packet */ - encode(packet: Buffer): MaybeAsync + encode(packet: Uint8Array): MaybeAsync /** Feed packet to the codec. Once packet is processed, codec is supposed to emit `packet` or `error` */ - feed(data: Buffer): void + feed(data: Uint8Array): void /** Reset codec state (for example, reset buffer) */ reset(): void @@ -91,7 +91,7 @@ export interface IPacketCodec { */ on(event: 'error', handler: (error: Error) => void): void /** Emitted when a full packet has been processed. */ - on(event: 'packet', handler: (packet: Buffer) => void): void + on(event: 'packet', handler: (packet: Uint8Array) => void): void /** * For codecs that use crypto functions and/or logging. diff --git a/packages/core/src/network/transports/index.ts b/packages/core/src/network/transports/index.ts index eeb620f5..29580033 100644 --- a/packages/core/src/network/transports/index.ts +++ b/packages/core/src/network/transports/index.ts @@ -1,14 +1,14 @@ -import { TransportFactory } from './abstract' +import { TransportFactory } from './abstract.js' -export * from './abstract' -export * from './intermediate' -export * from './obfuscated' -export * from './streamed' -export * from './tcp' -export * from './websocket' -export * from './wrapped' +export * from './abstract.js' +export * from './intermediate.js' +export * from './obfuscated.js' +export * from './streamed.js' +export * from './tcp.js' +export * from './websocket.js' +export * from './wrapped.js' -import { _defaultTransportFactory } from '../../utils/platform/transport' +import { _defaultTransportFactory } from '../../utils/platform/transport.js' /** Platform-defined default transport factory */ export const defaultTransportFactory: TransportFactory = _defaultTransportFactory diff --git a/packages/core/src/network/transports/intermediate.ts b/packages/core/src/network/transports/intermediate.ts index 91de3b50..dca4876c 100644 --- a/packages/core/src/network/transports/intermediate.ts +++ b/packages/core/src/network/transports/intermediate.ts @@ -1,23 +1,24 @@ -import { randomBytes } from '../../utils' -import { IPacketCodec, TransportError } from './abstract' -import { StreamedCodec } from './streamed' +import { dataViewFromBuffer, randomBytes } from '../../utils/index.js' +import { IPacketCodec, TransportError } from './abstract.js' +import { StreamedCodec } from './streamed.js' -const TAG = Buffer.from([0xee, 0xee, 0xee, 0xee]) -const PADDED_TAG = Buffer.from([0xdd, 0xdd, 0xdd, 0xdd]) +const TAG = new Uint8Array([0xee, 0xee, 0xee, 0xee]) +const PADDED_TAG = new Uint8Array([0xdd, 0xdd, 0xdd, 0xdd]) /** * Intermediate packet codec. * See https://core.telegram.org/mtproto/mtproto-transports#intermediate */ export class IntermediatePacketCodec extends StreamedCodec implements IPacketCodec { - tag(): Buffer { + tag(): Uint8Array { return TAG } - encode(packet: Buffer): Buffer { - const ret = Buffer.alloc(packet.length + 4) - ret.writeUInt32LE(packet.length) - packet.copy(ret, 4) + encode(packet: Uint8Array): Uint8Array { + const ret = new Uint8Array(packet.length + 4) + const dv = dataViewFromBuffer(ret) + dv.setUint32(0, packet.length, true) + ret.set(packet, 4) return ret } @@ -27,18 +28,19 @@ export class IntermediatePacketCodec extends StreamedCodec implements IPacketCod } protected _handlePacket(): boolean { - const payloadLength = this._stream.readUInt32LE(0) + const dv = dataViewFromBuffer(this._stream) + const payloadLength = dv.getUint32(0, true) if (payloadLength <= this._stream.length - 4) { if (payloadLength === 4) { - const code = this._stream.readInt32LE(4) * -1 + const code = dv.getInt32(4, true) * -1 this.emit('error', new TransportError(code)) } else { - const payload = this._stream.slice(4, payloadLength + 4) + const payload = this._stream.subarray(4, payloadLength + 4) this.emit('packet', payload) } - this._stream = this._stream.slice(payloadLength + 4) + this._stream = this._stream.subarray(payloadLength + 4) return true } @@ -52,19 +54,20 @@ export class IntermediatePacketCodec extends StreamedCodec implements IPacketCod * See https://core.telegram.org/mtproto/mtproto-transports#padded-intermediate */ export class PaddedIntermediatePacketCodec extends IntermediatePacketCodec { - tag(): Buffer { + tag(): Uint8Array { return PADDED_TAG } - encode(packet: Buffer): Buffer { + encode(packet: Uint8Array): Uint8Array { // padding size, 0-15 const padSize = Math.floor(Math.random() * 16) const padding = randomBytes(padSize) - const ret = Buffer.alloc(packet.length + 4 + padSize) - ret.writeUInt32LE(packet.length + padSize) - packet.copy(ret, 4) - padding.copy(ret, 4 + ret.length) + const ret = new Uint8Array(packet.length + 4 + padSize) + const dv = dataViewFromBuffer(ret) + dv.setUint32(0, packet.length + padSize, true) + ret.set(packet, 4) + ret.set(padding, 4 + packet.length) return ret } diff --git a/packages/core/src/network/transports/obfuscated.ts b/packages/core/src/network/transports/obfuscated.ts index 7187b855..b9631125 100644 --- a/packages/core/src/network/transports/obfuscated.ts +++ b/packages/core/src/network/transports/obfuscated.ts @@ -1,19 +1,11 @@ -import { buffersEqual, IEncryptionScheme, randomBytes } from '../../utils' -import { IPacketCodec } from './abstract' -import { WrappedCodec } from './wrapped' - -// initial payload can't start with these -const BAD_HEADERS = [ - Buffer.from('GET', 'utf8'), - Buffer.from('POST', 'utf8'), - Buffer.from('HEAD', 'utf8'), - Buffer.from('PVrG', 'utf8'), - Buffer.from('eeeeeeee', 'hex'), -] +import { concatBuffers, dataViewFromBuffer } from '../../utils/buffer-utils.js' +import { IEncryptionScheme, randomBytes } from '../../utils/index.js' +import { IPacketCodec } from './abstract.js' +import { WrappedCodec } from './wrapped.js' export interface MtProxyInfo { dcId: number - secret: Buffer + secret: Uint8Array test: boolean media: boolean } @@ -29,17 +21,29 @@ export class ObfuscatedPacketCodec extends WrappedCodec implements IPacketCodec this._proxy = proxy } - async tag(): Promise { - let random: Buffer + async tag(): Promise { + let random: Uint8Array + let dv: DataView - r: for (;;) { + for (;;) { random = randomBytes(64) if (random[0] === 0xef) continue - for (const h of BAD_HEADERS) { - if (buffersEqual(random.slice(0, h.length), h)) continue r + dv = dataViewFromBuffer(random) + const firstInt = dv.getInt32(0, true) + + if ( + firstInt === 0x44414548 || // HEAD + firstInt === 0x54534f50 || // POST + firstInt === 0x20544547 || // GET(space) + firstInt === 0x4954504f || // OPTI + firstInt === 0xdddddddd || // padded intermediate + firstInt === 0xeeeeeeee || // intermediate + firstInt === 0x02010316 // no idea, taken from tdlib + ) { + continue } - if (random.readUInt32LE(4) === 0) continue + if (dv.getInt32(4, true) === 0) continue break } @@ -48,48 +52,49 @@ export class ObfuscatedPacketCodec extends WrappedCodec implements IPacketCodec if (innerTag.length !== 4) { const b = innerTag[0] - innerTag = Buffer.from([b, b, b, b]) + innerTag = new Uint8Array([b, b, b, b]) } - innerTag.copy(random, 56) + random.set(innerTag, 56) if (this._proxy) { let dcId = this._proxy.dcId if (this._proxy.test) dcId += 10000 if (this._proxy.media) dcId = -dcId - random.writeInt16LE(dcId, 60) + dv.setInt16(60, dcId, true) } - const randomRev = Buffer.from(random.slice(8, 56)).reverse() + // randomBytes may return a Buffer in Node.js, whose .slice() doesn't copy + const randomRev = Uint8Array.prototype.slice.call(random, 8, 56).reverse() - let encryptKey = random.slice(8, 40) - const encryptIv = random.slice(40, 56) + let encryptKey = random.subarray(8, 40) + const encryptIv = random.subarray(40, 56) - let decryptKey = randomRev.slice(0, 32) - const decryptIv = randomRev.slice(32, 48) + let decryptKey = randomRev.subarray(0, 32) + const decryptIv = randomRev.subarray(32, 48) if (this._proxy) { - encryptKey = await this._crypto.sha256(Buffer.concat([encryptKey, this._proxy.secret])) - decryptKey = await this._crypto.sha256(Buffer.concat([decryptKey, this._proxy.secret])) + encryptKey = await this._crypto.sha256(concatBuffers([encryptKey, this._proxy.secret])) + decryptKey = await this._crypto.sha256(concatBuffers([decryptKey, this._proxy.secret])) } - this._encryptor = this._crypto.createAesCtr(encryptKey, encryptIv, true) - this._decryptor = this._crypto.createAesCtr(decryptKey, decryptIv, false) + this._encryptor = await this._crypto.createAesCtr(encryptKey, encryptIv, true) + this._decryptor = await this._crypto.createAesCtr(decryptKey, decryptIv, false) const encrypted = await this._encryptor.encrypt(random) - encrypted.copy(random, 56, 56, 64) + random.set(encrypted.subarray(56, 64), 56) return random } - async encode(packet: Buffer): Promise { + async encode(packet: Uint8Array): Promise { return this._encryptor!.encrypt(await this._inner.encode(packet)) } - feed(data: Buffer): void { + feed(data: Uint8Array): void { const dec = this._decryptor!.decrypt(data) - if (Buffer.isBuffer(dec)) this._inner.feed(dec) + if (ArrayBuffer.isView(dec)) this._inner.feed(dec) else { dec.then((dec) => this._inner.feed(dec)).catch((err) => this.emit('error', err)) } diff --git a/packages/core/src/network/transports/streamed.ts b/packages/core/src/network/transports/streamed.ts index c043d5c1..c5289996 100644 --- a/packages/core/src/network/transports/streamed.ts +++ b/packages/core/src/network/transports/streamed.ts @@ -1,5 +1,7 @@ import EventEmitter from 'events' +import { concatBuffers } from '../../utils/index.js' + /** * Base for streamed codecs. * @@ -7,7 +9,7 @@ import EventEmitter from 'events' * multiple transport packets. */ export abstract class StreamedCodec extends EventEmitter { - protected _stream = Buffer.alloc(0) + protected _stream = new Uint8Array(0) /** * Should return whether a full packet is available @@ -22,8 +24,8 @@ export abstract class StreamedCodec extends EventEmitter { */ protected abstract _handlePacket(): boolean - feed(data: Buffer): void { - this._stream = Buffer.concat([this._stream, data]) + feed(data: Uint8Array): void { + this._stream = concatBuffers([this._stream, data]) while (this._packetAvailable()) { if (!this._handlePacket()) break @@ -31,6 +33,6 @@ export abstract class StreamedCodec extends EventEmitter { } reset(): void { - this._stream = Buffer.alloc(0) + this._stream = new Uint8Array(0) } } diff --git a/packages/core/src/network/transports/tcp.ts b/packages/core/src/network/transports/tcp.ts index 86c76e76..3954f1f3 100644 --- a/packages/core/src/network/transports/tcp.ts +++ b/packages/core/src/network/transports/tcp.ts @@ -3,10 +3,10 @@ import { connect, Socket } from 'net' import { tl } from '@mtcute/tl' -import { MtcuteError } from '../../types' -import { ICryptoProvider, Logger } from '../../utils' -import { IPacketCodec, ITelegramTransport, TransportState } from './abstract' -import { IntermediatePacketCodec } from './intermediate' +import { MtcuteError } from '../../types/errors.js' +import { ICryptoProvider, Logger } from '../../utils/index.js' +import { IPacketCodec, ITelegramTransport, TransportState } from './abstract.js' +import { IntermediatePacketCodec } from './intermediate.js' /** * Base for TCP transports. @@ -115,7 +115,7 @@ export abstract class BaseTcpTransport extends EventEmitter implements ITelegram .catch((err) => this.emit('error', err)) } - async send(bytes: Buffer): Promise { + async send(bytes: Uint8Array): Promise { if (this._state !== TransportState.Ready) { throw new MtcuteError('Transport is not READY') } diff --git a/packages/core/src/network/transports/websocket.ts b/packages/core/src/network/transports/websocket.ts index ba3f902e..b9cfeed0 100644 --- a/packages/core/src/network/transports/websocket.ts +++ b/packages/core/src/network/transports/websocket.ts @@ -1,12 +1,13 @@ import EventEmitter from 'events' +import { createRequire } from 'module' import { tl } from '@mtcute/tl' -import { MtcuteError, MtUnsupportedError } from '../../types' -import { ICryptoProvider, Logger, typedArrayToBuffer } from '../../utils' -import { IPacketCodec, ITelegramTransport, TransportState } from './abstract' -import { IntermediatePacketCodec } from './intermediate' -import { ObfuscatedPacketCodec } from './obfuscated' +import { MtcuteError, MtUnsupportedError } from '../../types/errors.js' +import { ICryptoProvider, Logger } from '../../utils/index.js' +import { IPacketCodec, ITelegramTransport, TransportState } from './abstract.js' +import { IntermediatePacketCodec } from './intermediate.js' +import { ObfuscatedPacketCodec } from './obfuscated.js' let ws: { new (address: string, options?: string): WebSocket @@ -14,7 +15,10 @@ let ws: { if (typeof window === 'undefined' || typeof window.WebSocket === 'undefined') { try { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + // @only-if-esm + const require = createRequire(import.meta.url) + // @/only-if-esm + // eslint-disable-next-line ws = require('ws') } catch (e) { ws = null @@ -111,7 +115,7 @@ export abstract class BaseWebSocketTransport extends EventEmitter implements ITe this._socket.binaryType = 'arraybuffer' this._socket.addEventListener('message', (evt) => - this._packetCodec.feed(typedArrayToBuffer(evt.data as NodeJS.TypedArray)), + this._packetCodec.feed(new Uint8Array(evt.data as ArrayBuffer)), ) this._socket.addEventListener('open', this.handleConnect.bind(this)) this._socket.addEventListener('error', this.handleError.bind(this)) @@ -150,7 +154,7 @@ export abstract class BaseWebSocketTransport extends EventEmitter implements ITe .catch((err) => this.emit('error', err)) } - async send(bytes: Buffer): Promise { + async send(bytes: Uint8Array): Promise { if (this._state !== TransportState.Ready) { throw new MtcuteError('Transport is not READY') } diff --git a/packages/core/src/network/transports/wrapped.ts b/packages/core/src/network/transports/wrapped.ts index aac36bca..539b46fd 100644 --- a/packages/core/src/network/transports/wrapped.ts +++ b/packages/core/src/network/transports/wrapped.ts @@ -1,7 +1,7 @@ import EventEmitter from 'events' -import { ICryptoProvider, Logger } from '../../utils' -import { IPacketCodec } from './abstract' +import { ICryptoProvider, Logger } from '../../utils/index.js' +import { IPacketCodec } from './abstract.js' export abstract class WrappedCodec extends EventEmitter { protected _crypto!: ICryptoProvider diff --git a/packages/core/src/storage/abstract.ts b/packages/core/src/storage/abstract.ts index 3b9bcdb6..4a457c9b 100644 --- a/packages/core/src/storage/abstract.ts +++ b/packages/core/src/storage/abstract.ts @@ -1,8 +1,8 @@ import { tl } from '@mtcute/tl' import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime' -import { BasicPeerType, MaybeAsync } from '../types' -import { Logger } from '../utils' +import { BasicPeerType, MaybeAsync } from '../types/index.js' +import { Logger } from '../utils/index.js' // eslint-disable-next-line @typescript-eslint/no-namespace export namespace ITelegramStorage { @@ -88,16 +88,16 @@ export interface ITelegramStorage { * @param dcId DC ID * @param tempIndex Index of the temporary key (usually 0, used for multi-connections) */ - getAuthKeyFor(dcId: number, tempIndex?: number): MaybeAsync + getAuthKeyFor(dcId: number, tempIndex?: number): MaybeAsync /** * Set auth_key for a given DC */ - setAuthKeyFor(dcId: number, key: Buffer | null): MaybeAsync + setAuthKeyFor(dcId: number, key: Uint8Array | null): MaybeAsync /** * Set temp_auth_key for a given DC * expiresAt is unix time in ms */ - setTempAuthKeyFor(dcId: number, index: number, key: Buffer | null, expiresAt: number): MaybeAsync + setTempAuthKeyFor(dcId: number, index: number, key: Uint8Array | null, expiresAt: number): MaybeAsync /** * Remove all saved auth keys (both temp and perm) * for the given DC. Used when perm_key becomes invalid, diff --git a/packages/core/src/storage/index.ts b/packages/core/src/storage/index.ts index 6204365f..29b3f9c7 100644 --- a/packages/core/src/storage/index.ts +++ b/packages/core/src/storage/index.ts @@ -1,5 +1,5 @@ -export * from './abstract' -export * from './json' -export * from './json-file' -export * from './localstorage' -export * from './memory' +export * from './abstract.js' +export * from './json.js' +export * from './json-file.js' +export * from './localstorage.js' +export * from './memory.js' diff --git a/packages/core/src/storage/json-file.ts b/packages/core/src/storage/json-file.ts index 9b09c4c9..a5ac2ce3 100644 --- a/packages/core/src/storage/json-file.ts +++ b/packages/core/src/storage/json-file.ts @@ -1,12 +1,16 @@ import type * as fsNs from 'fs' +import { createRequire } from 'module' -import { MtUnsupportedError } from '../types' -import { JsonMemoryStorage } from './json' +import { MtUnsupportedError } from '../types/index.js' +import { JsonMemoryStorage } from './json.js' type fs = typeof fsNs let fs: fs | null = null try { + // @only-if-esm + const require = createRequire(import.meta.url) + // @/only-if-esm fs = require('fs') as fs } catch (e) {} diff --git a/packages/core/src/storage/json.ts b/packages/core/src/storage/json.ts index e6d45ab8..21922cb2 100644 --- a/packages/core/src/storage/json.ts +++ b/packages/core/src/storage/json.ts @@ -1,8 +1,9 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ import { tl } from '@mtcute/tl' +import { base64DecodeToBuffer, base64Encode } from '@mtcute/tl-runtime' -import { longFromFastString, longToFastString } from '../utils' -import { MemorySessionState, MemoryStorage } from './memory' +import { longFromFastString, longToFastString } from '../utils/long-utils.js' +import { MemorySessionState, MemoryStorage } from './memory.js' /** * Helper class that provides json serialization functions @@ -15,11 +16,11 @@ export class JsonMemoryStorage extends MemoryStorage { switch (key) { case 'authKeys': case 'authKeysTemp': { - const ret: Record = {} + const ret: Record = {} ;(value as string).split('|').forEach((pair: string) => { const [dcId, b64] = pair.split(',') - ret[dcId] = Buffer.from(b64, 'base64') + ret[dcId] = base64DecodeToBuffer(b64) }) return ret @@ -46,11 +47,11 @@ export class JsonMemoryStorage extends MemoryStorage { switch (key) { case 'authKeys': case 'authKeysTemp': { - const value_ = value as Map + const value_ = value as Map return [...value_.entries()] - .filter((it): it is [string, Buffer] => it[1] !== null) - .map(([dcId, key]) => dcId + ',' + key.toString('base64')) + .filter((it): it is [string, Uint8Array] => it[1] !== null) + .map(([dcId, key]) => dcId + ',' + base64Encode(key)) .join('|') } case 'authKeysTempExpiry': diff --git a/packages/core/src/storage/localstorage.ts b/packages/core/src/storage/localstorage.ts index 9c102bcd..beef3a29 100644 --- a/packages/core/src/storage/localstorage.ts +++ b/packages/core/src/storage/localstorage.ts @@ -1,5 +1,5 @@ -import { MtUnsupportedError } from '../types' -import { JsonMemoryStorage } from './json' +import { MtUnsupportedError } from '../types/index.js' +import { JsonMemoryStorage } from './json.js' export class LocalstorageStorage extends JsonMemoryStorage { private readonly _key: string diff --git a/packages/core/src/storage/memory.ts b/packages/core/src/storage/memory.ts index 32943afc..9247fc2c 100644 --- a/packages/core/src/storage/memory.ts +++ b/packages/core/src/storage/memory.ts @@ -1,9 +1,8 @@ -import { IStateStorage } from '@mtcute/dispatcher' import { tl } from '@mtcute/tl' -import { MaybeAsync } from '../types' -import { LruMap, toggleChannelIdMark } from '../utils' -import { ITelegramStorage } from './abstract' +import { MaybeAsync } from '../types/index.js' +import { LruMap, toggleChannelIdMark } from '../utils/index.js' +import { ITelegramStorage } from './abstract.js' const CURRENT_VERSION = 1 @@ -14,8 +13,8 @@ export interface MemorySessionState { $version: typeof CURRENT_VERSION defaultDcs: ITelegramStorage.DcOptions | null - authKeys: Map - authKeysTemp: Map + authKeys: Map + authKeysTemp: Map authKeysTempExpiry: Map // marked peer id -> entity info @@ -57,7 +56,7 @@ export interface MemorySessionState { const USERNAME_TTL = 86400000 // 24 hours -export class MemoryStorage implements ITelegramStorage, IStateStorage { +export class MemoryStorage implements ITelegramStorage /*, IStateStorage*/ { protected _state!: MemorySessionState private _cachedInputPeers: LruMap = new LruMap(100) @@ -185,7 +184,7 @@ export class MemoryStorage implements ITelegramStorage, IStateStorage { this._state.defaultDcs = dcs } - setTempAuthKeyFor(dcId: number, index: number, key: Buffer | null, expiresAt: number): void { + setTempAuthKeyFor(dcId: number, index: number, key: Uint8Array | null, expiresAt: number): void { const k = `${dcId}:${index}` if (key) { @@ -197,7 +196,7 @@ export class MemoryStorage implements ITelegramStorage, IStateStorage { } } - setAuthKeyFor(dcId: number, key: Buffer | null): void { + setAuthKeyFor(dcId: number, key: Uint8Array | null): void { if (key) { this._state.authKeys.set(dcId, key) } else { @@ -205,7 +204,7 @@ export class MemoryStorage implements ITelegramStorage, IStateStorage { } } - getAuthKeyFor(dcId: number, tempIndex?: number): Buffer | null { + getAuthKeyFor(dcId: number, tempIndex?: number): Uint8Array | null { if (tempIndex !== undefined) { const k = `${dcId}:${tempIndex}` diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index c7b15238..a7b27468 100644 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -1,3 +1,3 @@ -export * from './errors' -export * from './peers' -export * from './utils' +export * from './errors.js' +export * from './peers.js' +export * from './utils.js' diff --git a/packages/core/src/utils/async-lock.ts b/packages/core/src/utils/async-lock.ts index 356506a4..53586c90 100644 --- a/packages/core/src/utils/async-lock.ts +++ b/packages/core/src/utils/async-lock.ts @@ -1,4 +1,4 @@ -import { Deque } from './deque' +import { Deque } from './deque.js' type LockInfo = [Promise, () => void] diff --git a/packages/core/src/utils/bigint-utils.ts b/packages/core/src/utils/bigint-utils.ts index 5b821e8b..ddb6a00b 100644 --- a/packages/core/src/utils/bigint-utils.ts +++ b/packages/core/src/utils/bigint-utils.ts @@ -1,6 +1,6 @@ import bigInt, { BigInteger } from 'big-integer' -import { randomBytes } from './buffer-utils' +import { randomBytes } from './buffer-utils.js' /** * Convert a big integer to a buffer @@ -9,7 +9,7 @@ import { randomBytes } from './buffer-utils' * @param length Length of the resulting buffer (by default it's computed automatically) * @param le Whether to use little-endian encoding */ -export function bigIntToBuffer(value: BigInteger, length = 0, le = false): Buffer { +export function bigIntToBuffer(value: BigInteger, length = 0, le = false): Uint8Array { const array = value.toArray(256).value if (length !== 0 && array.length > length) { @@ -23,7 +23,7 @@ export function bigIntToBuffer(value: BigInteger, length = 0, le = false): Buffe if (le) array.reverse() - const buffer = Buffer.alloc(length || array.length) + const buffer = new Uint8Array(length || array.length) buffer.set(array, 0) return buffer @@ -37,12 +37,12 @@ export function bigIntToBuffer(value: BigInteger, length = 0, le = false): Buffe * @param length Length to read * @param le Whether to use little-endian encoding */ -export function bufferToBigInt(buffer: Buffer, offset = 0, length = buffer.length, le = false): BigInteger { - const arr = [...buffer.slice(offset, offset + length)] +export function bufferToBigInt(buffer: Uint8Array, offset = 0, length = buffer.length, le = false): BigInteger { + const arr = [...buffer.subarray(offset, offset + length)] if (le) arr.reverse() - return bigInt.fromArray(arr, 256) + return bigInt.fromArray(arr as unknown as number[], 256) } /** diff --git a/packages/core/src/utils/binary/asn1-parser.ts b/packages/core/src/utils/binary/asn1-parser.ts index 8da558c2..ef49cdf2 100644 --- a/packages/core/src/utils/binary/asn1-parser.ts +++ b/packages/core/src/utils/binary/asn1-parser.ts @@ -1,11 +1,13 @@ // all available libraries either suck or are extremely large for the use case, so i made my own~ +import { base64DecodeToBuffer, hexEncode } from '@mtcute/tl-runtime' + /** * Parses a single PEM block to buffer. * In fact just strips begin/end tags and parses the rest as Base64 */ -export function parsePemContents(pem: string): Buffer { - return Buffer.from(pem.replace(/^-----(BEGIN|END)( RSA)? PUBLIC KEY-----$|\n/gm, ''), 'base64') +export function parsePemContents(pem: string): Uint8Array { + return base64DecodeToBuffer(pem.replace(/^-----(BEGIN|END)( RSA)? PUBLIC KEY-----$|\n/gm, '')) } // based on https://git.coolaj86.com/coolaj86/asn1-parser.js/src/branch/master/asn1-parser.js @@ -16,7 +18,7 @@ interface Asn1Object { lengthSize: number length: number children?: Asn1Object[] - value?: Buffer + value?: Uint8Array } const ELOOPN = 102 @@ -47,8 +49,8 @@ const VTYPES: Record = { /** * Parses ASN.1 data to an object */ -export function parseAsn1(data: Buffer): Asn1Object { - function parseAsn1Inner(buf: Buffer, depth: number[], eager = false) { +export function parseAsn1(data: Uint8Array): Asn1Object { + function parseAsn1Inner(buf: Uint8Array, depth: number[], eager = false) { if (depth.length >= EDEEPN) { throw new Error(EDEEP) } @@ -64,7 +66,7 @@ export function parseAsn1(data: Buffer): Asn1Object { if (0x80 & asn1.length) { asn1.lengthSize = 0x7f & asn1.length // I think that buf->hex->int solves the problem of Endianness... not sure - asn1.length = buf.readIntBE(index, asn1.lengthSize) + asn1.length = parseInt(hexEncode(buf.subarray(index, index + asn1.lengthSize)), 16) index += asn1.lengthSize } @@ -85,7 +87,7 @@ export function parseAsn1(data: Buffer): Asn1Object { while (iters < ELOOPN && index < 2 + asn1.length + asn1.lengthSize) { iters += 1 depth.length += 1 - child = parseAsn1Inner(buf.slice(index, index + adjustedLen), depth, eager) + child = parseAsn1Inner(buf.subarray(index, index + adjustedLen), depth, eager) depth.length -= 1 // The numbers don't match up exactly and I don't remember why... // probably something with adjustedLen or some such, but the tests pass @@ -117,7 +119,7 @@ export function parseAsn1(data: Buffer): Asn1Object { } // Return types that are _always_ values - asn1.value = buf.slice(index, index + adjustedLen) + asn1.value = buf.subarray(index, index + adjustedLen) if (VTYPES[asn1.type]) { return asn1 diff --git a/packages/core/src/utils/buffer-utils.ts b/packages/core/src/utils/buffer-utils.ts index e581995e..e5fe86e2 100644 --- a/packages/core/src/utils/buffer-utils.ts +++ b/packages/core/src/utils/buffer-utils.ts @@ -1,6 +1,4 @@ -export { _randomBytes as randomBytes } from './platform/random' - -const b64urlAvailable = Buffer.isEncoding('base64url') +export { _randomBytes as randomBytes } from './platform/random.js' /** * Check if two buffers are equal @@ -8,7 +6,7 @@ const b64urlAvailable = Buffer.isEncoding('base64url') * @param a First buffer * @param b Second buffer */ -export function buffersEqual(a: Buffer, b: Buffer): boolean { +export function buffersEqual(a: Uint8Array, b: Uint8Array): boolean { if (a.length !== b.length) return false for (let i = 0; i < a.length; i++) { @@ -25,38 +23,40 @@ export function buffersEqual(a: Buffer, b: Buffer): boolean { * @param start Start offset * @param end End offset */ -export function cloneBuffer(buf: Buffer, start = 0, end = buf.length): Buffer { - const ret = Buffer.alloc(end - start) - buf.copy(ret, 0, start, end) +export function cloneBuffer(buf: Uint8Array, start = 0, end = buf.length): Uint8Array { + const ret = new Uint8Array(end - start) + ret.set(buf.subarray(start, end)) return ret } /** - * Parse url-safe base64 string - * - * @param str String to parse + * Concatenate multiple buffers into one */ -export function parseUrlSafeBase64(str: string): Buffer { - if (b64urlAvailable) { - return Buffer.from(str, 'base64url') +export function concatBuffers(buffers: Uint8Array[]): Uint8Array { + /* eslint-disable no-restricted-globals */ + if (typeof Buffer !== 'undefined') { + return Buffer.concat(buffers) + } + /* eslint-enable no-restricted-globals */ + + let length = 0 + + for (const buf of buffers) { + length += buf.length } - str = str.replace(/-/g, '+').replace(/_/g, '/') - while (str.length % 4) str += '=' + const ret = new Uint8Array(length) + let offset = 0 - return Buffer.from(str, 'base64') -} - -/** - * Convert a buffer to url-safe base64 string - * - * @param buf Buffer to convert - */ -export function encodeUrlSafeBase64(buf: Buffer): string { - if (b64urlAvailable) { - return buf.toString('base64url') + for (const buf of buffers) { + ret.set(buf, offset) + offset += buf.length } - return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '') + return ret +} + +export function dataViewFromBuffer(buf: Uint8Array): DataView { + return new DataView(buf.buffer, buf.byteOffset, buf.byteLength) } diff --git a/packages/core/src/utils/crypto/abstract.ts b/packages/core/src/utils/crypto/abstract.ts index 419d666e..c3b0fde8 100644 --- a/packages/core/src/utils/crypto/abstract.ts +++ b/packages/core/src/utils/crypto/abstract.ts @@ -1,52 +1,56 @@ -import { MaybeAsync } from '../../types' -import { AesModeOfOperationIge } from './common' -import { factorizePQSync } from './factorization' +import { MaybeAsync } from '../../types/index.js' +import { AesModeOfOperationIge } from './common.js' +import { factorizePQSync } from './factorization.js' export interface IEncryptionScheme { - encrypt(data: Buffer): MaybeAsync + encrypt(data: Uint8Array): MaybeAsync - decrypt(data: Buffer): MaybeAsync + decrypt(data: Uint8Array): MaybeAsync } export interface ICryptoProvider { initialize?(): MaybeAsync - sha1(data: Buffer): MaybeAsync + sha1(data: Uint8Array): MaybeAsync - sha256(data: Buffer): MaybeAsync + sha256(data: Uint8Array): MaybeAsync pbkdf2( - password: Buffer, - salt: Buffer, + password: Uint8Array, + salt: Uint8Array, iterations: number, keylen?: number, // = 64 algo?: string, // sha1 or sha512 (default sha512) - ): MaybeAsync + ): MaybeAsync - hmacSha256(data: Buffer, key: Buffer): MaybeAsync + hmacSha256(data: Uint8Array, key: Uint8Array): MaybeAsync // in telegram, iv is always either used only once, or is the same for all calls for the key - createAesCtr(key: Buffer, iv: Buffer, encrypt: boolean): IEncryptionScheme + createAesCtr(key: Uint8Array, iv: Uint8Array, encrypt: boolean): MaybeAsync - createAesIge(key: Buffer, iv: Buffer): IEncryptionScheme + createAesIge(key: Uint8Array, iv: Uint8Array): MaybeAsync - createAesEcb(key: Buffer): IEncryptionScheme + createAesEcb(key: Uint8Array): MaybeAsync - factorizePQ(pq: Buffer): MaybeAsync<[Buffer, Buffer]> + factorizePQ(pq: Uint8Array): MaybeAsync<[Uint8Array, Uint8Array]> } export abstract class BaseCryptoProvider { - createAesIge(key: Buffer, iv: Buffer): IEncryptionScheme { - return new AesModeOfOperationIge(key, iv, this.createAesEcb(key)) + createAesIge(key: Uint8Array, iv: Uint8Array): MaybeAsync { + const ecb = this.createAesEcb(key) + + if ('then' in ecb) { + return ecb.then((ecb) => new AesModeOfOperationIge(key, iv, ecb)) + } + + return new AesModeOfOperationIge(key, iv, ecb) } - factorizePQ(pq: Buffer): MaybeAsync<[Buffer, Buffer]> { + factorizePQ(pq: Uint8Array) { return factorizePQSync(pq) } - initialize(): void {} - - abstract createAesEcb(key: Buffer): IEncryptionScheme + abstract createAesEcb(key: Uint8Array): MaybeAsync } export type CryptoProviderFactory = () => ICryptoProvider diff --git a/packages/core/src/utils/crypto/common.ts b/packages/core/src/utils/crypto/common.ts index ca2172e9..b8dfb83f 100644 --- a/packages/core/src/utils/crypto/common.ts +++ b/packages/core/src/utils/crypto/common.ts @@ -1,65 +1,65 @@ -import type { IEncryptionScheme } from './abstract' -import { xorBufferInPlace } from './utils' +import type { IEncryptionScheme } from './abstract.js' +import { xorBufferInPlace } from './utils.js' /** * AES mode of operation IGE implementation in JS */ export class AesModeOfOperationIge implements IEncryptionScheme { - private _key: Buffer - private _iv: Buffer + private _key: Uint8Array + private _iv: Uint8Array private _aes: IEncryptionScheme - constructor(key: Buffer, iv: Buffer, ecb: IEncryptionScheme) { + constructor(key: Uint8Array, iv: Uint8Array, ecb: IEncryptionScheme) { this._key = key this._iv = iv this._aes = ecb } - async encrypt(data: Buffer): Promise { + async encrypt(data: Uint8Array): Promise { if (data.length % 16 !== 0) { throw new Error('invalid plaintext size (must be multiple of 16 bytes)') } - const ciphertext = Buffer.alloc(data.length) - let block = Buffer.alloc(16) + const ciphertext = new Uint8Array(data.length) + let block = new Uint8Array(16) - let iv1 = this._iv.slice(0, 16) - let iv2 = this._iv.slice(16, 32) + let iv1 = this._iv.subarray(0, 16) + let iv2 = this._iv.subarray(16, 32) for (let i = 0; i < data.length; i += 16) { - data.copy(block, 0, i, i + 16) + block.set(data.subarray(i, i + 16)) xorBufferInPlace(block, iv1) block = await this._aes.encrypt(block) xorBufferInPlace(block, iv2) - block.copy(ciphertext, i) + ciphertext.set(block, i) - iv1 = ciphertext.slice(i, i + 16) - iv2 = data.slice(i, i + 16) + iv1 = ciphertext.subarray(i, i + 16) + iv2 = data.subarray(i, i + 16) } return ciphertext } - async decrypt(data: Buffer): Promise { + async decrypt(data: Uint8Array): Promise { if (data.length % 16 !== 0) { throw new Error('invalid ciphertext size (must be multiple of 16 bytes)') } - const plaintext = Buffer.alloc(data.length) - let block = Buffer.alloc(16) + const plaintext = new Uint8Array(data.length) + let block = new Uint8Array(16) - let iv1 = this._iv.slice(16, 32) - let iv2 = this._iv.slice(0, 16) + let iv1 = this._iv.subarray(16, 32) + let iv2 = this._iv.subarray(0, 16) for (let i = 0; i < data.length; i += 16) { - data.copy(block, 0, i, i + 16) + block.set(data.subarray(i, i + 16)) xorBufferInPlace(block, iv1) block = await this._aes.decrypt(block) xorBufferInPlace(block, iv2) - block.copy(plaintext, i) + plaintext.set(block, i) - iv1 = plaintext.slice(i, i + 16) - iv2 = data.slice(i, i + 16) + iv1 = plaintext.subarray(i, i + 16) + iv2 = data.subarray(i, i + 16) } return plaintext diff --git a/packages/core/src/utils/crypto/factorization.ts b/packages/core/src/utils/crypto/factorization.ts index c27c7276..181aa916 100644 --- a/packages/core/src/utils/crypto/factorization.ts +++ b/packages/core/src/utils/crypto/factorization.ts @@ -1,12 +1,12 @@ import bigInt, { BigInteger } from 'big-integer' -import { bigIntToBuffer, bufferToBigInt, randomBigIntInRange } from '../bigint-utils' +import { bigIntToBuffer, bufferToBigInt, randomBigIntInRange } from '../bigint-utils.js' /** * Factorize `p*q` to `p` and `q` synchronously using Brent-Pollard rho algorithm * @param pq */ -export function factorizePQSync(pq: Buffer): [Buffer, Buffer] { +export function factorizePQSync(pq: Uint8Array): [Uint8Array, Uint8Array] { const pq_ = bufferToBigInt(pq) const n = PollardRhoBrent(pq_) diff --git a/packages/core/src/utils/crypto/forge-crypto.ts b/packages/core/src/utils/crypto/forge-crypto.ts deleted file mode 100644 index 7778e792..00000000 --- a/packages/core/src/utils/crypto/forge-crypto.ts +++ /dev/null @@ -1,95 +0,0 @@ -import type * as forgeNs from 'node-forge' - -import { MaybeAsync } from '../../types' -import { BaseCryptoProvider, ICryptoProvider, IEncryptionScheme } from './abstract' - -type forge = typeof forgeNs -let forge: forge | null = null - -try { - forge = require('node-forge') as forge -} catch (e) {} - -export class ForgeCryptoProvider extends BaseCryptoProvider implements ICryptoProvider { - constructor() { - super() - - if (!forge) { - throw new Error('For ForgeCryptoProvider you must have node-forge installed!') - } - } - - createAesCtr(key: Buffer, iv: Buffer, encrypt: boolean): IEncryptionScheme { - const cipher = forge!.cipher[encrypt ? 'createCipher' : 'createDecipher']('AES-CTR', key.toString('binary')) - cipher.start({ iv: iv.toString('binary') }) - - const update = (data: Buffer): Buffer => { - cipher.output.data = '' - cipher.update(forge!.util.createBuffer(data.toString('binary'))) - - return Buffer.from(cipher.output.data, 'binary') - } - - return { - encrypt: update, - decrypt: update, - } - } - - createAesEcb(key: Buffer): IEncryptionScheme { - const keyBuffer = key.toString('binary') - - return { - encrypt(data: Buffer) { - const cipher = forge!.cipher.createCipher('AES-ECB', keyBuffer) - cipher.start({}) - // @ts-expect-error wrong types - cipher.mode.pad = cipher.mode.unpad = false - cipher.update(forge!.util.createBuffer(data.toString('binary'))) - cipher.finish() - - return Buffer.from(cipher.output.data, 'binary') - }, - decrypt(data: Buffer) { - const cipher = forge!.cipher.createDecipher('AES-ECB', keyBuffer) - cipher.start({}) - // @ts-expect-error wrong types - cipher.mode.pad = cipher.mode.unpad = false - cipher.update(forge!.util.createBuffer(data.toString('binary'))) - cipher.finish() - - return Buffer.from(cipher.output.data, 'binary') - }, - } - } - - pbkdf2(password: Buffer, salt: Buffer, iterations: number, keylen = 64, algo = 'sha512'): MaybeAsync { - return new Promise((resolve, reject) => - forge!.pkcs5.pbkdf2( - password.toString('binary'), - salt.toString('binary'), - iterations, - keylen, - // eslint-disable-next-line - (forge!.md as any)[algo].create(), - (err: Error | null, buf: string) => (err !== null ? reject(err) : resolve(Buffer.from(buf, 'binary'))), - ), - ) - } - - sha1(data: Buffer): MaybeAsync { - return Buffer.from(forge!.md.sha1.create().update(data.toString('binary')).digest().data, 'binary') - } - - sha256(data: Buffer): MaybeAsync { - return Buffer.from(forge!.md.sha256.create().update(data.toString('binary')).digest().data, 'binary') - } - - hmacSha256(data: Buffer, key: Buffer): MaybeAsync { - const hmac = forge!.hmac.create() - hmac.start('sha256', key.toString('binary')) - hmac.update(data.toString('binary')) - - return Buffer.from(hmac.digest().data, 'binary') - } -} diff --git a/packages/core/src/utils/crypto/index.ts b/packages/core/src/utils/crypto/index.ts index db4124f5..ea6e0ec5 100644 --- a/packages/core/src/utils/crypto/index.ts +++ b/packages/core/src/utils/crypto/index.ts @@ -1,13 +1,8 @@ -import { ForgeCryptoProvider } from './forge-crypto' -import { NodeCryptoProvider } from './node-crypto' +export * from './abstract.js' +export * from './keys.js' +export * from './password.js' -export * from './abstract' -export * from './keys' -export * from './password' - -export { ForgeCryptoProvider, NodeCryptoProvider } - -import { _defaultCryptoProviderFactory } from '../platform/crypto' -import { CryptoProviderFactory } from './abstract' +import { _defaultCryptoProviderFactory } from '../platform/crypto.js' +import { CryptoProviderFactory } from './abstract.js' export const defaultCryptoProviderFactory: CryptoProviderFactory = _defaultCryptoProviderFactory diff --git a/packages/core/src/utils/crypto/keys.ts b/packages/core/src/utils/crypto/keys.ts index 99ee11a6..337304a7 100644 --- a/packages/core/src/utils/crypto/keys.ts +++ b/packages/core/src/utils/crypto/keys.ts @@ -1,10 +1,10 @@ import Long from 'long' -import keysIndex, { TlPublicKey } from '@mtcute/tl/binary/rsa-keys' -import { TlBinaryWriter } from '@mtcute/tl-runtime' +import { __publicKeyIndex as keysIndex, TlPublicKey } from '@mtcute/tl/binary/rsa-keys.js' +import { hexEncode, TlBinaryWriter } from '@mtcute/tl-runtime' -import { parseAsn1, parsePemContents } from '../binary/asn1-parser' -import { ICryptoProvider } from './abstract' +import { parseAsn1, parsePemContents } from '../binary/asn1-parser.js' +import { ICryptoProvider } from './abstract.js' /** * Parse PEM-encoded RSA public key information into modulus and exponent @@ -20,18 +20,18 @@ export async function parsePublicKey(crypto: ICryptoProvider, key: string, old = const exponent = asn1.children?.[1].value if (!modulus || !exponent) throw new Error('Invalid public key') - const writer = TlBinaryWriter.manualAlloc(512) + const writer = TlBinaryWriter.manual(512) // they are actually smaller, about 270 bytes, but idc :D writer.bytes(modulus) writer.bytes(exponent) const data = writer.result() const sha = await crypto.sha1(data) - const fp = sha.slice(-8).reverse().toString('hex') + const fp = hexEncode(sha.slice(-8).reverse()) return { - modulus: modulus.toString('hex'), - exponent: exponent.toString('hex'), + modulus: hexEncode(modulus), + exponent: hexEncode(exponent), fingerprint: fp, old, } diff --git a/packages/core/src/utils/crypto/miller-rabin.ts b/packages/core/src/utils/crypto/miller-rabin.ts index f7cd62d6..554adb16 100644 --- a/packages/core/src/utils/crypto/miller-rabin.ts +++ b/packages/core/src/utils/crypto/miller-rabin.ts @@ -1,6 +1,6 @@ import bigInt, { BigInteger } from 'big-integer' -import { randomBigIntBits, twoMultiplicity } from '../bigint-utils' +import { randomBigIntBits, twoMultiplicity } from '../bigint-utils.js' export function millerRabin(n: BigInteger, rounds = 20): boolean { // small numbers: 0, 1 are not prime, 2, 3 are prime diff --git a/packages/core/src/utils/crypto/mtproto.ts b/packages/core/src/utils/crypto/mtproto.ts index 52cc3711..6a063dec 100644 --- a/packages/core/src/utils/crypto/mtproto.ts +++ b/packages/core/src/utils/crypto/mtproto.ts @@ -1,4 +1,5 @@ -import { ICryptoProvider, IEncryptionScheme } from './abstract' +import { concatBuffers } from '../buffer-utils.js' +import { ICryptoProvider, IEncryptionScheme } from './abstract.js' /** * Generate AES key and IV from nonces as defined by MTProto. @@ -11,15 +12,15 @@ import { ICryptoProvider, IEncryptionScheme } from './abstract' */ export async function generateKeyAndIvFromNonce( crypto: ICryptoProvider, - serverNonce: Buffer, - newNonce: Buffer, -): Promise<[Buffer, Buffer]> { - const hash1 = await crypto.sha1(Buffer.concat([newNonce, serverNonce])) - const hash2 = await crypto.sha1(Buffer.concat([serverNonce, newNonce])) - const hash3 = await crypto.sha1(Buffer.concat([newNonce, newNonce])) + serverNonce: Uint8Array, + newNonce: Uint8Array, +): Promise<[Uint8Array, Uint8Array]> { + const hash1 = await crypto.sha1(concatBuffers([newNonce, serverNonce])) + const hash2 = await crypto.sha1(concatBuffers([serverNonce, newNonce])) + const hash3 = await crypto.sha1(concatBuffers([newNonce, newNonce])) - const key = Buffer.concat([hash1, hash2.slice(0, 12)]) - const iv = Buffer.concat([hash2.slice(12, 20), hash3, newNonce.slice(0, 4)]) + const key = concatBuffers([hash1, hash2.subarray(0, 12)]) + const iv = concatBuffers([hash2.subarray(12, 20), hash3, newNonce.subarray(0, 4)]) return [key, iv] } @@ -35,16 +36,16 @@ export async function generateKeyAndIvFromNonce( */ export async function createAesIgeForMessage( crypto: ICryptoProvider, - authKey: Buffer, - messageKey: Buffer, + authKey: Uint8Array, + messageKey: Uint8Array, client: boolean, ): Promise { const x = client ? 0 : 8 - const sha256a = await crypto.sha256(Buffer.concat([messageKey, authKey.slice(x, 36 + x)])) - const sha256b = await crypto.sha256(Buffer.concat([authKey.slice(40 + x, 76 + x), messageKey])) + const sha256a = await crypto.sha256(concatBuffers([messageKey, authKey.subarray(x, 36 + x)])) + const sha256b = await crypto.sha256(concatBuffers([authKey.subarray(40 + x, 76 + x), messageKey])) - const key = Buffer.concat([sha256a.slice(0, 8), sha256b.slice(8, 24), sha256a.slice(24, 32)]) - const iv = Buffer.concat([sha256b.slice(0, 8), sha256a.slice(8, 24), sha256b.slice(24, 32)]) + const key = concatBuffers([sha256a.subarray(0, 8), sha256b.subarray(8, 24), sha256a.subarray(24, 32)]) + const iv = concatBuffers([sha256b.subarray(0, 8), sha256a.subarray(8, 24), sha256b.subarray(24, 32)]) return crypto.createAesIge(key, iv) } @@ -60,20 +61,25 @@ export async function createAesIgeForMessage( */ export async function createAesIgeForMessageOld( crypto: ICryptoProvider, - authKey: Buffer, - messageKey: Buffer, + authKey: Uint8Array, + messageKey: Uint8Array, client: boolean, ): Promise { const x = client ? 0 : 8 - const sha1a = await crypto.sha1(Buffer.concat([messageKey, authKey.slice(x, 32 + x)])) + const sha1a = await crypto.sha1(concatBuffers([messageKey, authKey.subarray(x, 32 + x)])) const sha1b = await crypto.sha1( - Buffer.concat([authKey.slice(32 + x, 48 + x), messageKey, authKey.slice(48 + x, 64 + x)]), + concatBuffers([authKey.subarray(32 + x, 48 + x), messageKey, authKey.subarray(48 + x, 64 + x)]), ) - const sha1c = await crypto.sha1(Buffer.concat([authKey.slice(64 + x, 96 + x), messageKey])) - const sha1d = await crypto.sha1(Buffer.concat([messageKey, authKey.slice(96 + x, 128 + x)])) + const sha1c = await crypto.sha1(concatBuffers([authKey.subarray(64 + x, 96 + x), messageKey])) + const sha1d = await crypto.sha1(concatBuffers([messageKey, authKey.subarray(96 + x, 128 + x)])) - const key = Buffer.concat([sha1a.slice(0, 8), sha1b.slice(8, 20), sha1c.slice(4, 16)]) - const iv = Buffer.concat([sha1a.slice(8, 20), sha1b.slice(0, 8), sha1c.slice(16, 20), sha1d.slice(0, 8)]) + const key = concatBuffers([sha1a.subarray(0, 8), sha1b.subarray(8, 20), sha1c.subarray(4, 16)]) + const iv = concatBuffers([ + sha1a.subarray(8, 20), + sha1b.subarray(0, 8), + sha1c.subarray(16, 20), + sha1d.subarray(0, 8), + ]) return crypto.createAesIge(key, iv) } diff --git a/packages/core/src/utils/crypto/node-crypto.ts b/packages/core/src/utils/crypto/node-crypto.ts index 3eac6b61..e23c4893 100644 --- a/packages/core/src/utils/crypto/node-crypto.ts +++ b/packages/core/src/utils/crypto/node-crypto.ts @@ -1,13 +1,14 @@ import { createCipheriv, createDecipheriv, createHash, createHmac, pbkdf2 } from 'crypto' -import { MaybeAsync } from '../../types' -import { BaseCryptoProvider, ICryptoProvider, IEncryptionScheme } from './abstract' +import { MaybeAsync } from '../../types/index.js' +import { concatBuffers } from '../buffer-utils.js' +import { BaseCryptoProvider, ICryptoProvider, IEncryptionScheme } from './abstract.js' export class NodeCryptoProvider extends BaseCryptoProvider implements ICryptoProvider { - createAesCtr(key: Buffer, iv: Buffer, encrypt: boolean): IEncryptionScheme { + createAesCtr(key: Uint8Array, iv: Uint8Array, encrypt: boolean): IEncryptionScheme { const cipher = (encrypt ? createCipheriv : createDecipheriv)(`aes-${key.length * 8}-ctr`, key, iv) - const update = (data: Buffer) => cipher.update(data) + const update = (data: Uint8Array) => cipher.update(data) return { encrypt: update, @@ -15,42 +16,48 @@ export class NodeCryptoProvider extends BaseCryptoProvider implements ICryptoPro } } - createAesEcb(key: Buffer): IEncryptionScheme { + createAesEcb(key: Uint8Array): IEncryptionScheme { const methodName = `aes-${key.length * 8}-ecb` return { - encrypt(data: Buffer) { + encrypt(data: Uint8Array) { const cipher = createCipheriv(methodName, key, null) cipher.setAutoPadding(false) - return Buffer.concat([cipher.update(data), cipher.final()]) + return concatBuffers([cipher.update(data), cipher.final()]) }, - decrypt(data: Buffer) { + decrypt(data: Uint8Array) { const cipher = createDecipheriv(methodName, key, null) cipher.setAutoPadding(false) - return Buffer.concat([cipher.update(data), cipher.final()]) + return concatBuffers([cipher.update(data), cipher.final()]) }, } } - pbkdf2(password: Buffer, salt: Buffer, iterations: number, keylen = 64, algo = 'sha512'): MaybeAsync { + pbkdf2( + password: Uint8Array, + salt: Uint8Array, + iterations: number, + keylen = 64, + algo = 'sha512', + ): MaybeAsync { return new Promise((resolve, reject) => - pbkdf2(password, salt, iterations, keylen, algo, (err: Error | null, buf: Buffer) => + pbkdf2(password, salt, iterations, keylen, algo, (err: Error | null, buf: Uint8Array) => err !== null ? reject(err) : resolve(buf), ), ) } - sha1(data: Buffer): Buffer { + sha1(data: Uint8Array): Uint8Array { return createHash('sha1').update(data).digest() } - sha256(data: Buffer): Buffer { + sha256(data: Uint8Array): Uint8Array { return createHash('sha256').update(data).digest() } - hmacSha256(data: Buffer, key: Buffer): MaybeAsync { + hmacSha256(data: Uint8Array, key: Uint8Array): MaybeAsync { return createHmac('sha256', key).update(data).digest() } } diff --git a/packages/core/src/utils/crypto/password.ts b/packages/core/src/utils/crypto/password.ts index 4b088870..b0a0b402 100644 --- a/packages/core/src/utils/crypto/password.ts +++ b/packages/core/src/utils/crypto/password.ts @@ -1,12 +1,13 @@ import bigInt from 'big-integer' import { tl } from '@mtcute/tl' +import { utf8EncodeToBuffer } from '@mtcute/tl-runtime' -import { MtSecurityError, MtUnsupportedError } from '../../types' -import { bigIntToBuffer, bufferToBigInt } from '../bigint-utils' -import { randomBytes } from '../buffer-utils' -import { ICryptoProvider } from './abstract' -import { xorBuffer } from './utils' +import { MtSecurityError, MtUnsupportedError } from '../../types/errors.js' +import { bigIntToBuffer, bufferToBigInt } from '../bigint-utils.js' +import { concatBuffers, randomBytes } from '../buffer-utils.js' +import { ICryptoProvider } from './abstract.js' +import { xorBuffer } from './utils.js' /** * Compute password hash as defined by MTProto. @@ -20,16 +21,14 @@ import { xorBuffer } from './utils' */ export async function computePasswordHash( crypto: ICryptoProvider, - password: Buffer, - salt1: Buffer, - salt2: Buffer, -): Promise { - const SH = (data: Buffer, salt: Buffer) => crypto.sha256(Buffer.concat([salt, data, salt])) - const PH1 = async (pwd: Buffer, salt1: Buffer, salt2: Buffer) => SH(await SH(pwd, salt1), salt2) - const PH2 = async (pwd: Buffer, salt1: Buffer, salt2: Buffer) => - SH(await crypto.pbkdf2(await PH1(pwd, salt1, salt2), salt1, 100000), salt2) + password: Uint8Array, + salt1: Uint8Array, + salt2: Uint8Array, +): Promise { + const SH = (data: Uint8Array, salt: Uint8Array) => crypto.sha256(concatBuffers([salt, data, salt])) + const PH1 = async (pwd: Uint8Array, salt1: Uint8Array, salt2: Uint8Array) => SH(await SH(pwd, salt1), salt2) - return PH2(password, salt1, salt2) + return SH(await crypto.pbkdf2(await PH1(password, salt1, salt2), salt1, 100000), salt2) } /** @@ -43,10 +42,10 @@ export async function computeNewPasswordHash( crypto: ICryptoProvider, algo: tl.RawPasswordKdfAlgoSHA256SHA256PBKDF2HMACSHA512iter100000SHA256ModPow, password: string, -): Promise { - (algo as tl.Mutable).salt1 = Buffer.concat([algo.salt1, randomBytes(32)]) +): Promise { + (algo as tl.Mutable).salt1 = concatBuffers([algo.salt1, randomBytes(32)]) - const _x = await computePasswordHash(crypto, Buffer.from(password), algo.salt1, algo.salt2) + const _x = await computePasswordHash(crypto, utf8EncodeToBuffer(password), algo.salt1, algo.salt2) const g = bigInt(algo.g) const p = bufferToBigInt(algo.p) @@ -96,13 +95,13 @@ export async function computeSrpParams( const gA = g.modPow(a, p) const _gA = bigIntToBuffer(gA, 256) - const H = (data: Buffer) => crypto.sha256(data) + const H = (data: Uint8Array) => crypto.sha256(data) const [_k, _u, _x] = await Promise.all([ // maybe, just maybe this will be a bit faster with some crypto providers - /* k = */ crypto.sha256(Buffer.concat([algo.p, _g])), - /* u = */ crypto.sha256(Buffer.concat([_gA, request.srpB])), - /* x = */ computePasswordHash(crypto, Buffer.from(password), algo.salt1, algo.salt2), + /* k = */ crypto.sha256(concatBuffers([algo.p, _g])), + /* u = */ crypto.sha256(concatBuffers([_gA, request.srpB])), + /* x = */ computePasswordHash(crypto, utf8EncodeToBuffer(password), algo.salt1, algo.salt2), ]) const k = bufferToBigInt(_k) const u = bufferToBigInt(_u) @@ -117,7 +116,7 @@ export async function computeSrpParams( const _kA = await H(bigIntToBuffer(sA, 256)) const _M1 = await H( - Buffer.concat([ + concatBuffers([ xorBuffer(await H(algo.p), await H(_g)), await H(algo.salt1), await H(algo.salt2), diff --git a/packages/core/src/utils/crypto/subtle.ts b/packages/core/src/utils/crypto/subtle.ts new file mode 100644 index 00000000..498f3553 --- /dev/null +++ b/packages/core/src/utils/crypto/subtle.ts @@ -0,0 +1,98 @@ +import { MaybeAsync } from '../../index.js' +import { BaseCryptoProvider, ICryptoProvider, IEncryptionScheme } from './abstract.js' + +import AES_, { CTR } from '@cryptography/aes' + +// fucking weird flex with es modules. +// i hate default imports please for the love of god never use them +type AES_ = typeof AES_.default +const AES = 'default' in AES_ ? AES_.default : AES_ as AES_ + +const ALGO_TO_SUBTLE: Record = { + sha256: 'SHA-256', + sha1: 'SHA-1', + sha512: 'SHA-512', +} + +function wordsToBytes(words: Uint32Array): Uint8Array { + const o = new Uint8Array(words.byteLength) + + const len = words.length * 4 + + for (let i = 0; i < len; ++i) { + o[i] = ((words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff) + } + + return o +} + +export class SubtleCryptoProvider extends BaseCryptoProvider implements ICryptoProvider { + constructor( + readonly subtle: SubtleCrypto, + ) { + super() + } + + sha1(data: Uint8Array): MaybeAsync { + return this.subtle.digest('SHA-1', data).then((result) => new Uint8Array(result)) + } + + sha256(data: Uint8Array): MaybeAsync { + return this.subtle.digest('SHA-256', data).then((result) => new Uint8Array(result)) + } + + async pbkdf2( + password: Uint8Array, + salt: Uint8Array, + iterations: number, + keylen?: number | undefined, + algo?: string | undefined, + ): Promise { + const keyMaterial = await this.subtle.importKey('raw', password, 'PBKDF2', false, ['deriveBits']) + + return this.subtle + .deriveBits( + { + name: 'PBKDF2', + salt, + iterations, + hash: algo ? ALGO_TO_SUBTLE[algo] : 'SHA-512', + }, + keyMaterial, + (keylen || 64) * 8, + ) + .then((result) => new Uint8Array(result)) + } + + async hmacSha256(data: Uint8Array, key: Uint8Array): Promise { + const keyMaterial = await this.subtle.importKey( + 'raw', + key, + { name: 'HMAC', hash: { name: 'SHA-256' } }, + false, + ['sign'], + ) + + const res = await this.subtle.sign({ name: 'HMAC' }, keyMaterial, data) + + return new Uint8Array(res) + } + + createAesCtr(key: Uint8Array, iv: Uint8Array): IEncryptionScheme { + const aes = new CTR(key, iv) + + return { + encrypt: (data) => wordsToBytes(aes.encrypt(data)), + decrypt: (data) => wordsToBytes(aes.decrypt(data)), + } + } + + createAesEcb(key: Uint8Array): IEncryptionScheme { + const aes = new AES(key) + + return { + encrypt: (data) => wordsToBytes(aes.encrypt(data)), + decrypt: (data) => wordsToBytes(aes.decrypt(data)), + } + } +} diff --git a/packages/core/src/utils/crypto/utils.ts b/packages/core/src/utils/crypto/utils.ts index 8ab366e2..2bacf734 100644 --- a/packages/core/src/utils/crypto/utils.ts +++ b/packages/core/src/utils/crypto/utils.ts @@ -4,8 +4,8 @@ * @param data Buffer to XOR * @param key Key to XOR with */ -export function xorBuffer(data: Buffer, key: Buffer): Buffer { - const ret = Buffer.alloc(data.length) +export function xorBuffer(data: Uint8Array, key: Uint8Array): Uint8Array { + const ret = new Uint8Array(data.length) for (let i = 0; i < data.length; i++) { ret[i] = data[i] ^ key[i] @@ -20,7 +20,7 @@ export function xorBuffer(data: Buffer, key: Buffer): Buffer { * @param data Buffer to XOR * @param key Key to XOR with */ -export function xorBufferInPlace(data: Buffer, key: Buffer): void { +export function xorBufferInPlace(data: Uint8Array, key: Uint8Array): void { for (let i = 0; i < data.length; i++) { data[i] ^= key[i] } diff --git a/packages/core/src/utils/default-dcs.ts b/packages/core/src/utils/default-dcs.ts index fe595277..97924b14 100644 --- a/packages/core/src/utils/default-dcs.ts +++ b/packages/core/src/utils/default-dcs.ts @@ -1,4 +1,4 @@ -import { ITelegramStorage } from '../storage' +import { ITelegramStorage } from '../storage/abstract.js' /** @internal */ export const defaultProductionDc: ITelegramStorage.DcOptions = { diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index 5f8212cf..b8aa09b7 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1,23 +1,23 @@ -export * from './async-lock' -export * from './bigint-utils' -export * from './buffer-utils' -export * from './condition-variable' -export * from './controllable-promise' -export * from './crypto' -export * from './default-dcs' -export * from './deque' -export * from './early-timer' -export * from './flood-control' -export * from './function-utils' -export * from './linked-list' -export * from './logger' -export * from './long-utils' -export * from './lru-map' -export * from './lru-set' -export * from './misc-utils' -export * from './peer-utils' -export * from './sorted-array' -export * from './string-session' -export * from './tl-json' -export * from './type-assertions' -export * from './web-utils' +export * from './async-lock.js' +export * from './bigint-utils.js' +export * from './buffer-utils.js' +export * from './condition-variable.js' +export * from './controllable-promise.js' +export * from './crypto/index.js' +export * from './default-dcs.js' +export * from './deque.js' +export * from './early-timer.js' +export * from './flood-control.js' +export * from './function-utils.js' +export * from './linked-list.js' +export * from './logger.js' +export * from './long-utils.js' +export * from './lru-map.js' +export * from './lru-set.js' +export * from './misc-utils.js' +export * from './peer-utils.js' +export * from './sorted-array.js' +export * from './string-session.js' +export * from './tl-json.js' +export * from './type-assertions.js' +export * from '@mtcute/tl-runtime' diff --git a/packages/core/src/utils/logger.ts b/packages/core/src/utils/logger.ts index 4c1d1e0b..4855f3e0 100644 --- a/packages/core/src/utils/logger.ts +++ b/packages/core/src/utils/logger.ts @@ -1,4 +1,6 @@ -import { _defaultLoggingHandler } from './platform/logging' +import { hexEncode } from '@mtcute/tl-runtime' + +import { _defaultLoggingHandler } from './platform/logging.js' let defaultLogLevel = 2 @@ -76,7 +78,7 @@ export class Logger { args.splice(idx, 1) if (m === '%h') { - if (Buffer.isBuffer(val)) return val.toString('hex') + if (ArrayBuffer.isView(val)) return hexEncode(val as Uint8Array) if (typeof val === 'number') return val.toString(16) return String(val) @@ -89,8 +91,12 @@ export class Logger { } return JSON.stringify(val, (k, v) => { - if (typeof v === 'object' && v.type === 'Buffer' && Array.isArray(v.data)) { - let str = Buffer.from(v.data as number[]).toString('base64') + if ( + ArrayBuffer.isView(v) || + (typeof v === 'object' && v.type === 'Buffer' && Array.isArray(v.data)) + ) { + // eslint-disable-next-line + let str = v.data ? Buffer.from(v.data as number[]).toString('hex') : hexEncode(v) if (str.length > 300) { str = str.slice(0, 300) + '...' diff --git a/packages/core/src/utils/long-utils.ts b/packages/core/src/utils/long-utils.ts index 3dc3b109..564f5319 100644 --- a/packages/core/src/utils/long-utils.ts +++ b/packages/core/src/utils/long-utils.ts @@ -1,6 +1,7 @@ import Long from 'long' -import { getRandomInt } from './misc-utils' +import { dataViewFromBuffer } from './buffer-utils.js' +import { getRandomInt } from './misc-utils.js' /** * Get a random Long @@ -21,12 +22,14 @@ export function randomLong(unsigned = false): Long { * @param unsigned Whether the number should be unsigned * @param le Whether the number is little-endian */ -export function longFromBuffer(buf: Buffer, unsigned = false, le = true): Long { +export function longFromBuffer(buf: Uint8Array, unsigned = false, le = true): Long { + const dv = dataViewFromBuffer(buf) + if (le) { - return new Long(buf.readInt32LE(0), buf.readInt32LE(4), unsigned) + return new Long(dv.getInt32(0, true), dv.getInt32(4, true), unsigned) } - return new Long(buf.readInt32BE(4), buf.readInt32BE(0), unsigned) + return new Long(dv.getInt32(4, false), dv.getInt32(0, false), unsigned) } /** diff --git a/packages/core/src/utils/lru-map.ts b/packages/core/src/utils/lru-map.ts index f7631f9f..ba12d55d 100644 --- a/packages/core/src/utils/lru-map.ts +++ b/packages/core/src/utils/lru-map.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-argument */ // ^^ because of performance reasons -import { LongMap } from './long-utils' +import { LongMap } from './long-utils.js' interface TwoWayLinkedList { // k = key diff --git a/packages/core/src/utils/lru-set.ts b/packages/core/src/utils/lru-set.ts index 50d6d779..6d8a5d28 100644 --- a/packages/core/src/utils/lru-set.ts +++ b/packages/core/src/utils/lru-set.ts @@ -3,7 +3,7 @@ // ^^ because of performance reasons import Long from 'long' -import { LongSet } from './long-utils' +import { LongSet } from './long-utils.js' interface OneWayLinkedList { v: T diff --git a/packages/core/src/utils/peer-utils.ts b/packages/core/src/utils/peer-utils.ts index eecc15e0..e0fbc111 100644 --- a/packages/core/src/utils/peer-utils.ts +++ b/packages/core/src/utils/peer-utils.ts @@ -1,7 +1,7 @@ import { tl } from '@mtcute/tl' -import { MtArgumentError, MtUnsupportedError } from '../types/errors' -import { BasicPeerType } from '../types/peers' +import { MtArgumentError, MtUnsupportedError } from '../types/errors.js' +import { BasicPeerType } from '../types/peers.js' // src: https://github.com/tdlib/td/blob/master/td/telegram/DialogId.h const ZERO_CHANNEL_ID = -1000000000000 diff --git a/packages/core/src/utils/platform/crypto.ts b/packages/core/src/utils/platform/crypto.ts index 4aafd292..e2b8c3d6 100644 --- a/packages/core/src/utils/platform/crypto.ts +++ b/packages/core/src/utils/platform/crypto.ts @@ -1,4 +1,4 @@ -import { NodeCryptoProvider } from '../crypto/node-crypto' +import { NodeCryptoProvider } from '../crypto/node-crypto.js' /** @internal */ export const _defaultCryptoProviderFactory = () => new NodeCryptoProvider() diff --git a/packages/core/src/utils/platform/crypto.web.ts b/packages/core/src/utils/platform/crypto.web.ts index 25cf4412..5e792bbf 100644 --- a/packages/core/src/utils/platform/crypto.web.ts +++ b/packages/core/src/utils/platform/crypto.web.ts @@ -1,4 +1,11 @@ -import { ForgeCryptoProvider } from '../crypto' +import { MtUnsupportedError } from '../../index.js' +import { SubtleCryptoProvider } from '../crypto/subtle.js' /** @internal */ -export const _defaultCryptoProviderFactory = () => new ForgeCryptoProvider() +export const _defaultCryptoProviderFactory = () => { + if (typeof crypto === 'undefined' || typeof crypto.subtle === 'undefined') { + throw new MtUnsupportedError('WebCrypto API is not available') + } + + return new SubtleCryptoProvider(crypto.subtle) +} diff --git a/packages/core/src/utils/platform/error-reporting.ts b/packages/core/src/utils/platform/error-reporting.ts index 1eece79d..93b49328 100644 --- a/packages/core/src/utils/platform/error-reporting.ts +++ b/packages/core/src/utils/platform/error-reporting.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/tl' -import { Logger } from '../logger' +import { Logger } from '../logger.js' export function reportUnknownError(log: Logger, error: tl.RpcError, method: string): void { if (typeof fetch !== 'function') return diff --git a/packages/core/src/utils/platform/logging.web.ts b/packages/core/src/utils/platform/logging.web.ts index 56ce2dd1..4a28557b 100644 --- a/packages/core/src/utils/platform/logging.web.ts +++ b/packages/core/src/utils/platform/logging.web.ts @@ -1,4 +1,4 @@ -const BASE_FORMAT = '%s [%с%s%с] [%c%s%c] ' +const BASE_FORMAT = '%s [%c%s%c] [%c%s%c] ' const LEVEL_NAMES = [ '', // OFF 'ERR', @@ -9,13 +9,20 @@ const LEVEL_NAMES = [ ] const COLORS = [ '', // OFF - '#ff0000', - '#ffff00', - '#0000ff', - '#00ffff', - '#ff00ff', + 'color: #7a5f9d', + 'color: #8d7041', + 'color: #396c9e', + 'color: #437761', + 'color: #7a5f9d', +] +const TAG_COLORS = [ + 'color: #437761', + 'color: #537a36', + 'color: #8d7041', + 'color: #396c9e', + 'color: #7a5f9d', + 'color: #7a5f9d', ] -const TAG_COLORS = ['#44ffff', '#44ff44', '#ffff44', '#4444ff', '#ff44ff', '#ff4444'] /** @internal */ export const _defaultLoggingHandler = ( diff --git a/packages/core/src/utils/platform/random.ts b/packages/core/src/utils/platform/random.ts index 674fbf46..caa2c8a4 100644 --- a/packages/core/src/utils/platform/random.ts +++ b/packages/core/src/utils/platform/random.ts @@ -1,3 +1,3 @@ import { randomBytes } from 'crypto' -export const _randomBytes = randomBytes +export const _randomBytes = randomBytes as (size: number) => Uint8Array diff --git a/packages/core/src/utils/platform/random.web.ts b/packages/core/src/utils/platform/random.web.ts index 1c45db0a..6e54d974 100644 --- a/packages/core/src/utils/platform/random.web.ts +++ b/packages/core/src/utils/platform/random.web.ts @@ -1,8 +1,6 @@ -import { typedArrayToBuffer } from '../web-utils' - -export function _randomBytes(size: number): Buffer { +export function _randomBytes(size: number): Uint8Array { const ret = new Uint8Array(size) crypto.getRandomValues(ret) - return typedArrayToBuffer(ret) + return ret } diff --git a/packages/core/src/utils/platform/transport.ts b/packages/core/src/utils/platform/transport.ts index 88f858ab..8a9c0244 100644 --- a/packages/core/src/utils/platform/transport.ts +++ b/packages/core/src/utils/platform/transport.ts @@ -1,4 +1,4 @@ -import { TcpTransport } from '../../network/transports/tcp' +import { TcpTransport } from '../../network/transports/tcp.js' /** @internal */ export const _defaultTransportFactory = () => new TcpTransport() diff --git a/packages/core/src/utils/platform/transport.web.ts b/packages/core/src/utils/platform/transport.web.ts index 9c25daea..fdeb1614 100644 --- a/packages/core/src/utils/platform/transport.web.ts +++ b/packages/core/src/utils/platform/transport.web.ts @@ -1,5 +1,5 @@ -import { WebSocketTransport } from '../../network/transports/websocket' -import { MtUnsupportedError } from '../../types' +import { WebSocketTransport } from '../../network/transports/websocket.js' +import { MtUnsupportedError } from '../../types/index.js' /** @internal */ export const _defaultTransportFactory = diff --git a/packages/core/src/utils/string-session.ts b/packages/core/src/utils/string-session.ts index cb64de5d..cf15a21f 100644 --- a/packages/core/src/utils/string-session.ts +++ b/packages/core/src/utils/string-session.ts @@ -1,16 +1,22 @@ import { tl } from '@mtcute/tl' -import { TlBinaryReader, TlBinaryWriter, TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime' +import { + base64DecodeToBuffer, + base64Encode, + TlBinaryReader, + TlBinaryWriter, + TlReaderMap, + TlWriterMap, +} from '@mtcute/tl-runtime' -import { ITelegramStorage } from '../storage' -import { MtArgumentError } from '../types' -import { encodeUrlSafeBase64, parseUrlSafeBase64 } from './buffer-utils' +import { ITelegramStorage } from '../storage/index.js' +import { MtArgumentError } from '../types/index.js' export interface StringSessionData { version: number testMode: boolean primaryDcs: ITelegramStorage.DcOptions self?: ITelegramStorage.SelfInfo | null - authKey: Buffer + authKey: Uint8Array } export function writeStringSession(writerMap: TlWriterMap, data: StringSessionData): string { @@ -32,7 +38,7 @@ export function writeStringSession(writerMap: TlWriterMap, data: StringSessionDa flags |= 2 } - writer.buffer[0] = version + writer.uint8View[0] = version writer.pos += 1 writer.int(flags) @@ -50,11 +56,11 @@ export function writeStringSession(writerMap: TlWriterMap, data: StringSessionDa writer.bytes(data.authKey) - return encodeUrlSafeBase64(writer.result()) + return base64Encode(writer.result(), true) } export function readStringSession(readerMap: TlReaderMap, data: string): StringSessionData { - const buf = parseUrlSafeBase64(data) + const buf = base64DecodeToBuffer(data, true) const version = buf[0] diff --git a/packages/core/src/utils/tl-json.ts b/packages/core/src/utils/tl-json.ts index ecb4c5c7..ea3cf500 100644 --- a/packages/core/src/utils/tl-json.ts +++ b/packages/core/src/utils/tl-json.ts @@ -1,6 +1,6 @@ import { tl } from '@mtcute/tl' -import { MtArgumentError } from '../types' +import { MtArgumentError } from '../types/errors.js' /** * Convert a JS object to TL JSON diff --git a/packages/core/src/utils/type-assertions.ts b/packages/core/src/utils/type-assertions.ts index 6c6c781b..f6453243 100644 --- a/packages/core/src/utils/type-assertions.ts +++ b/packages/core/src/utils/type-assertions.ts @@ -1,6 +1,6 @@ import { mtp, tl } from '@mtcute/tl' -import { MtTypeAssertionError } from '../types' +import { MtTypeAssertionError } from '../types/errors.js' // mostly taken from https://github.com/robertmassaioli/ts-is-present diff --git a/packages/core/src/utils/web-utils.ts b/packages/core/src/utils/web-utils.ts deleted file mode 100644 index 9930ad80..00000000 --- a/packages/core/src/utils/web-utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -// from https://github.com/feross/typedarray-to-buffer -// licensed under MIT -/** - * Convert a typed array to a Buffer. - * @param arr Typed array to convert - */ -export function typedArrayToBuffer(arr: NodeJS.TypedArray): Buffer { - // To avoid a copy, use the typed array's underlying ArrayBuffer to back - // new Buffer, respecting the "view", i.e. byteOffset and byteLength - return ArrayBuffer.isView(arr) ? - Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength) : // Pass through all other types to `Buffer.from` - Buffer.from(arr) -} diff --git a/packages/core/tests/auth-key.spec.ts b/packages/core/tests/auth-key.spec.ts new file mode 100644 index 00000000..880ca391 --- /dev/null +++ b/packages/core/tests/auth-key.spec.ts @@ -0,0 +1,53 @@ +/* eslint-disable no-restricted-globals */ +import chai, { expect } from 'chai' +import spies from 'chai-spies' +import { describe, it } from 'mocha' + +import { TlReaderMap } from '@mtcute/tl-runtime' + +import { AuthKey } from '../src/network/auth-key.js' +import { NodeCryptoProvider } from '../src/utils/crypto/node-crypto.js' +import { LogManager } from '../src/utils/index.js' + +chai.use(spies) + +const authKey = Buffer.alloc( + 2048 / 8, + Buffer.from('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0', 'hex'), +) + +describe('AuthKey', () => { + const crypto = new NodeCryptoProvider() + const logger = new LogManager() + const readerMap: TlReaderMap = {} + + it('should correctly calculate derivatives', async () => { + const key = new AuthKey(crypto, logger, readerMap) + await key.setup(authKey) + + expect(key.key).to.eql(authKey) + expect(key.clientSalt).to.eql( + Buffer.from('f73c3622dec230e098cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4b', 'hex'), + ) + expect(key.serverSalt).to.eql( + Buffer.from('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0', 'hex'), + ) + expect(key.id).to.eql(Buffer.from('40fa5bb7cb56a895', 'hex')) + }) + + // todo - need predictable random bytes + // it('should correctly encrypt a message', async () => { + // const crypto = new NodeCryptoProvider() + // const key = new AuthKey(crypto, logger, readerMap) + // await key.setup(authKey) + // + // const msg = await key.encryptMessage(message, serverSalt, sessionId) + // + // expect(msg).to.eql( + // Buffer.from( + // '...', + // 'hex', + // ), + // ) + // }) +}) diff --git a/packages/core/tests/bigint-utils.spec.ts b/packages/core/tests/bigint-utils.spec.ts index ac8ec14f..8e9f9c98 100644 --- a/packages/core/tests/bigint-utils.spec.ts +++ b/packages/core/tests/bigint-utils.spec.ts @@ -2,7 +2,9 @@ import bigInt from 'big-integer' import { expect } from 'chai' import { describe, it } from 'mocha' -import { bigIntToBuffer, bufferToBigInt } from '../utils' +import { hexDecodeToBuffer } from '@mtcute/tl-runtime' + +import { bigIntToBuffer, bufferToBigInt } from '../src/utils/index.js' // since bigIntToBuffer is a tiny wrapper over writeBigInt, no need to test it individually describe('bigIntToBuffer', () => { @@ -12,7 +14,7 @@ describe('bigIntToBuffer', () => { expect([...bigIntToBuffer(bigInt('10495708'), 8, false)]).eql([0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x26, 0xdc]) expect([...bigIntToBuffer(bigInt('3038102549'), 4, false)]).eql([0xb5, 0x15, 0xc4, 0x15]) expect([...bigIntToBuffer(bigInt('9341376580368336208'), 8, false)]).eql([ - ...Buffer.from('81A33C81D2020550', 'hex'), + ...hexDecodeToBuffer('81A33C81D2020550'), ]) }) it('should handle writing to LE', () => { @@ -21,21 +23,21 @@ describe('bigIntToBuffer', () => { expect([...bigIntToBuffer(bigInt('10495708'), 8, true)]).eql([0xdc, 0x26, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00]) expect([...bigIntToBuffer(bigInt('3038102549'), 4, true)]).eql([0x15, 0xc4, 0x15, 0xb5]) expect([...bigIntToBuffer(bigInt('9341376580368336208'), 8, true)]).eql([ - ...Buffer.from('81A33C81D2020550', 'hex').reverse(), + ...hexDecodeToBuffer('81A33C81D2020550').reverse(), ]) }) }) describe('bufferToBigInt', () => { it('should handle reading BE', () => { - expect(bufferToBigInt(Buffer.from([0xa0, 0x26, 0xdc]), 0, 3, false).toString()).eq('10495708') - expect(bufferToBigInt(Buffer.from([0x00, 0xa0, 0x26, 0xdc]), 0, 4, false).toString()).eq('10495708') - expect(bufferToBigInt(Buffer.from([0xb5, 0x15, 0xc4, 0x15]), 0, 4, false).toString()).eq('3038102549') + expect(bufferToBigInt(new Uint8Array([0xa0, 0x26, 0xdc]), 0, 3, false).toString()).eq('10495708') + expect(bufferToBigInt(new Uint8Array([0x00, 0xa0, 0x26, 0xdc]), 0, 4, false).toString()).eq('10495708') + expect(bufferToBigInt(new Uint8Array([0xb5, 0x15, 0xc4, 0x15]), 0, 4, false).toString()).eq('3038102549') }) it('should handle reading LE', () => { - expect(bufferToBigInt(Buffer.from([0xdc, 0x26, 0xa0]), 0, 3, true).toString()).eq('10495708') - expect(bufferToBigInt(Buffer.from([0xdc, 0x26, 0xa0, 0x00]), 0, 4, true).toString()).eq('10495708') - expect(bufferToBigInt(Buffer.from([0x15, 0xc4, 0x15, 0xb5]), 0, 4, true).toString()).eq('3038102549') + expect(bufferToBigInt(new Uint8Array([0xdc, 0x26, 0xa0]), 0, 3, true).toString()).eq('10495708') + expect(bufferToBigInt(new Uint8Array([0xdc, 0x26, 0xa0, 0x00]), 0, 4, true).toString()).eq('10495708') + expect(bufferToBigInt(new Uint8Array([0x15, 0xc4, 0x15, 0xb5]), 0, 4, true).toString()).eq('3038102549') }) }) diff --git a/packages/core/tests/buffer-utils.spec.ts b/packages/core/tests/buffer-utils.spec.ts index 3e86b25d..067ca39a 100644 --- a/packages/core/tests/buffer-utils.spec.ts +++ b/packages/core/tests/buffer-utils.spec.ts @@ -1,77 +1,77 @@ import { expect } from 'chai' import { describe, it } from 'mocha' +import { hexEncode, utf8Decode, utf8EncodeToBuffer } from '@mtcute/tl-runtime' + import { buffersEqual, - cloneBuffer, - encodeUrlSafeBase64, - parseUrlSafeBase64, + cloneBuffer, concatBuffers, randomBytes, -} from '../src/utils/buffer-utils' -import { xorBuffer, xorBufferInPlace } from '../src/utils/crypto/utils' +} from '../src/utils/buffer-utils.js' +import { xorBuffer, xorBufferInPlace } from '../src/utils/crypto/utils.js' describe('buffersEqual', () => { it('should return true for equal buffers', () => { - expect(buffersEqual(Buffer.from([]), Buffer.from([]))).is.true - expect(buffersEqual(Buffer.from([1, 2, 3]), Buffer.from([1, 2, 3]))).is.true + expect(buffersEqual(new Uint8Array([]), new Uint8Array([]))).is.true + expect(buffersEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3]))).is.true }) it('should return false for non-equal buffers', () => { - expect(buffersEqual(Buffer.from([1]), Buffer.from([]))).is.false - expect(buffersEqual(Buffer.from([1, 2, 3]), Buffer.from([1, 2, 4]))).is.false + expect(buffersEqual(new Uint8Array([1]), new Uint8Array([]))).is.false + expect(buffersEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 4]))).is.false }) }) describe('xorBuffer', () => { it('should xor buffers without modifying original', () => { - const data = Buffer.from('hello') - const key = Buffer.from('xor') + const data = utf8EncodeToBuffer('hello') + const key = utf8EncodeToBuffer('xor') const xored = xorBuffer(data, key) expect(data.toString()).eq('hello') expect(key.toString()).eq('xor') - expect(xored.toString('hex')).eq('100a1e6c6f') + expect(hexEncode(xored)).eq('100a1e6c6f') }) it('should be deterministic', () => { - const data = Buffer.from('hello') - const key = Buffer.from('xor') + const data = utf8EncodeToBuffer('hello') + const key = utf8EncodeToBuffer('xor') const xored1 = xorBuffer(data, key) - expect(xored1.toString('hex')).eq('100a1e6c6f') + expect(hexEncode(xored1)).eq('100a1e6c6f') const xored2 = xorBuffer(data, key) - expect(xored2.toString('hex')).eq('100a1e6c6f') + expect(hexEncode(xored2)).eq('100a1e6c6f') }) it('second call should decode content', () => { - const data = Buffer.from('hello') - const key = Buffer.from('xor') + const data = utf8EncodeToBuffer('hello') + const key = utf8EncodeToBuffer('xor') const xored1 = xorBuffer(data, key) - expect(xored1.toString('hex')).eq('100a1e6c6f') + expect(hexEncode(xored1)).eq('100a1e6c6f') const xored2 = xorBuffer(xored1, key) - expect(xored2.toString()).eq('hello') + expect(utf8Decode(xored2)).eq('hello') }) }) describe('xorBufferInPlace', () => { it('should xor buffers by modifying original', () => { - const data = Buffer.from('hello') - const key = Buffer.from('xor') + const data = utf8EncodeToBuffer('hello') + const key = utf8EncodeToBuffer('xor') xorBufferInPlace(data, key) - expect(data.toString('hex')).eq('100a1e6c6f') + expect(hexEncode(data)).eq('100a1e6c6f') expect(key.toString()).eq('xor') }) it('second call should decode content', () => { - const data = Buffer.from('hello') - const key = Buffer.from('xor') + const data = utf8EncodeToBuffer('hello') + const key = utf8EncodeToBuffer('xor') xorBufferInPlace(data, key) - expect(data.toString('hex')).eq('100a1e6c6f') + expect(hexEncode(data)).eq('100a1e6c6f') xorBufferInPlace(data, key) expect(data.toString()).eq('hello') @@ -93,7 +93,7 @@ describe('randomBytes', () => { describe('cloneBuffer', () => { it('should clone buffer', () => { - const orig = Buffer.from([1, 2, 3]) + const orig = new Uint8Array([1, 2, 3]) const copy = cloneBuffer(orig) expect([...copy]).eql([1, 2, 3]) @@ -102,7 +102,7 @@ describe('cloneBuffer', () => { }) it('should clone buffer partially', () => { - const orig = Buffer.from([1, 2, 3, 4, 5]) + const orig = new Uint8Array([1, 2, 3, 4, 5]) const copy = cloneBuffer(orig, 1, 4) expect([...copy]).eql([2, 3, 4]) @@ -111,17 +111,22 @@ describe('cloneBuffer', () => { }) }) -describe('parseUrlSafeBase64', () => { - it('should parse url-safe base64', () => { - expect(parseUrlSafeBase64('qu7d8aGTeuF6-g').toString('hex')).eq('aaeeddf1a1937ae17afa') - }) - it('should parse normal base64', () => { - expect(parseUrlSafeBase64('qu7d8aGTeuF6+g==').toString('hex')).eq('aaeeddf1a1937ae17afa') - }) -}) +describe('concatBuffers', () => { + it('should concat buffers', () => { + const buf = concatBuffers([ + new Uint8Array([1, 2, 3]), + new Uint8Array([4, 5, 6]), + ]) -describe('encodeUrlSafeBase64', () => { - it('should encode to url-safe base64', () => { - expect(encodeUrlSafeBase64(Buffer.from('aaeeddf1a1937ae17afa', 'hex'))).eq('qu7d8aGTeuF6-g') + expect([...buf]).eql([1, 2, 3, 4, 5, 6]) + }) + + it('should create a new buffer', () => { + const buf1 = new Uint8Array([1, 2, 3]) + const buf2 = new Uint8Array([4, 5, 6]) + const buf = concatBuffers([buf1, buf2]) + + buf[0] = 0xff + expect(buf1[0]).not.eql(0xff) }) }) diff --git a/packages/core/tests/crypto-providers.spec.ts b/packages/core/tests/crypto-providers.spec.ts index d1b0b3a9..2d0a410a 100644 --- a/packages/core/tests/crypto-providers.spec.ts +++ b/packages/core/tests/crypto-providers.spec.ts @@ -1,95 +1,128 @@ import { expect } from 'chai' +import * as crypto from 'crypto' import { describe, it } from 'mocha' -import { ForgeCryptoProvider, ICryptoProvider, NodeCryptoProvider } from '../utils' +import { hexDecodeToBuffer, hexEncode, utf8EncodeToBuffer } from '@mtcute/tl-runtime' + +import { NodeCryptoProvider } from '../src/utils/crypto/node-crypto.js' +import { SubtleCryptoProvider } from '../src/utils/crypto/subtle.js' +import { ICryptoProvider } from '../src/utils/index.js' export function testCryptoProvider(c: ICryptoProvider): void { it('should calculate sha1', async () => { - expect((await c.sha1(Buffer.from(''))).toString('hex')).to.eq('da39a3ee5e6b4b0d3255bfef95601890afd80709') - expect((await c.sha1(Buffer.from('hello'))).toString('hex')).to.eq('aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d') - expect((await c.sha1(Buffer.from('aebb1f', 'hex'))).toString('hex')).to.eq( - '62849d15c5dea495916c5eea8dba5f9551288850', - ) + expect(hexEncode(await c.sha1(utf8EncodeToBuffer('')))).to.eq('da39a3ee5e6b4b0d3255bfef95601890afd80709') + expect(hexEncode(await c.sha1(utf8EncodeToBuffer('hello')))).to.eq('aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d') + expect(hexEncode(await c.sha1(hexDecodeToBuffer('aebb1f')))).to.eq('62849d15c5dea495916c5eea8dba5f9551288850') }) it('should calculate sha256', async () => { - expect((await c.sha256(Buffer.from(''))).toString('hex')).to.eq( + expect(hexEncode(await c.sha256(utf8EncodeToBuffer('')))).to.eq( 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', ) - expect((await c.sha256(Buffer.from('hello'))).toString('hex')).to.eq( + expect(hexEncode(await c.sha256(utf8EncodeToBuffer('hello')))).to.eq( '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824', ) - expect((await c.sha256(Buffer.from('aebb1f', 'hex'))).toString('hex')).to.eq( + expect(hexEncode(await c.sha256(hexDecodeToBuffer('aebb1f')))).to.eq( '2d29658aba48f2b286fe8bbddb931b7ad297e5adb5b9a6fc3aab67ef7fbf4e80', ) }) it('should calculate hmac-sha256', async () => { - const key = Buffer.from('aaeeff', 'hex') + const key = hexDecodeToBuffer('aaeeff') - expect((await c.hmacSha256(Buffer.from(''), key)).toString('hex')).to.eq( + expect(hexEncode(await c.hmacSha256(utf8EncodeToBuffer(''), key))).to.eq( '642711307c9e4437df09d6ebaa6bdc1b3a810c7f15c50fd1d0f8d7d5490f44dd', ) - expect((await c.hmacSha256(Buffer.from('hello'), key)).toString('hex')).to.eq( + expect(hexEncode(await c.hmacSha256(utf8EncodeToBuffer('hello'), key))).to.eq( '39b00bab151f9868e6501655c580b5542954711181243474d46b894703b1c1c2', ) - expect((await c.hmacSha256(Buffer.from('aebb1f', 'hex'), key)).toString('hex')).to.eq( + expect(hexEncode(await c.hmacSha256(hexDecodeToBuffer('aebb1f'), key))).to.eq( 'a3a7273871808711cab17aba14f58e96f63f3ccfc5097d206f0f00ead2c3dd35', ) }) it('should derive pbkdf2 key', async () => { - expect((await c.pbkdf2(Buffer.from('pbkdf2 test'), Buffer.from('some salt'), 10)).toString('hex')).to.eq( + expect(hexEncode(await c.pbkdf2(utf8EncodeToBuffer('pbkdf2 test'), utf8EncodeToBuffer('some salt'), 10))).to.eq( 'e43276cfa27f135f261cec8ddcf593fd74ec251038e459c165461f2308f3a7235e0744ee1aed9710b00db28d1a2112e20fea3601c60e770ac57ffe6b33ca8be1', ) }) it('should encrypt and decrypt aes-ctr', async () => { - let aes = c.createAesCtr( - Buffer.from('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b', 'hex'), - Buffer.from('0182de2bd789c295c3c6c875c5e9e190', 'hex'), + let aes = await c.createAesCtr( + hexDecodeToBuffer('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b'), + hexDecodeToBuffer('0182de2bd789c295c3c6c875c5e9e190'), true, ) - expect((await aes.encrypt(Buffer.from([1, 2, 3]))).toString('hex')).eq('a5fea1') - expect((await aes.encrypt(Buffer.from([1, 2, 3]))).toString('hex')).eq('ab51ca') - expect((await aes.encrypt(Buffer.from([1, 2, 3]))).toString('hex')).eq('365e5c') - expect((await aes.encrypt(Buffer.from([1, 2, 3]))).toString('hex')).eq('4b94a9') - expect((await aes.encrypt(Buffer.from([1, 2, 3]))).toString('hex')).eq('776387') - expect((await aes.encrypt(Buffer.from([1, 2, 3]))).toString('hex')).eq('c940be') + const data = hexDecodeToBuffer('7baae571e4c2f4cfadb1931d5923aca7') + expect(hexEncode(await aes.encrypt(data))).eq('df5647dbb70bc393f2fb05b72f42286f') + expect(hexEncode(await aes.encrypt(data))).eq('3917147082672516b3177150129bc579') + expect(hexEncode(await aes.encrypt(data))).eq('2a7a9089270a5de45d5e3dd399cac725') + expect(hexEncode(await aes.encrypt(data))).eq('56d085217771398ac13583de4d677dd8') + expect(hexEncode(await aes.encrypt(data))).eq('cc639b488126cf36e79c4515e8012b92') + expect(hexEncode(await aes.encrypt(data))).eq('01384d100646cd562cc5586ec3f8f8c4') - aes = c.createAesCtr( - Buffer.from('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b', 'hex'), - Buffer.from('0182de2bd789c295c3c6c875c5e9e190', 'hex'), + aes = await c.createAesCtr( + hexDecodeToBuffer('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b'), + hexDecodeToBuffer('0182de2bd789c295c3c6c875c5e9e190'), false, ) - expect((await aes.decrypt(Buffer.from('a5fea1', 'hex'))).toString('hex')).eq('010203') - expect((await aes.decrypt(Buffer.from('ab51ca', 'hex'))).toString('hex')).eq('010203') - expect((await aes.decrypt(Buffer.from('365e5c', 'hex'))).toString('hex')).eq('010203') - expect((await aes.decrypt(Buffer.from('4b94a9', 'hex'))).toString('hex')).eq('010203') - expect((await aes.decrypt(Buffer.from('776387', 'hex'))).toString('hex')).eq('010203') - expect((await aes.decrypt(Buffer.from('c940be', 'hex'))).toString('hex')).eq('010203') + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('df5647dbb70bc393f2fb05b72f42286f')))).eq(hexEncode(data)) + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('3917147082672516b3177150129bc579')))).eq(hexEncode(data)) + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('2a7a9089270a5de45d5e3dd399cac725')))).eq(hexEncode(data)) + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('56d085217771398ac13583de4d677dd8')))).eq(hexEncode(data)) + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('cc639b488126cf36e79c4515e8012b92')))).eq(hexEncode(data)) + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('01384d100646cd562cc5586ec3f8f8c4')))).eq(hexEncode(data)) + }) + + it('should encrypt and decrypt aes-ecb', async () => { + let aes = await c.createAesEcb( + hexDecodeToBuffer('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b'), + ) + + expect(hexEncode(await aes.encrypt(hexDecodeToBuffer('f71eed6018f1ef976d39c19f9d29fd29')))).eq( + '038ef30acb438b64159f484aec541fd2', + ) + expect(hexEncode(await aes.encrypt(hexDecodeToBuffer('f71eed6018f1ef976d39c19f9d29fd29')))).eq( + '038ef30acb438b64159f484aec541fd2', + ) + expect(hexEncode(await aes.encrypt(hexDecodeToBuffer('460af382084b7960d2e9f3bca4cdc25b')))).eq( + '29c3af710c3c56f7fbb97ca06af3b974', + ) + + aes = await c.createAesEcb( + hexDecodeToBuffer('d450aae0bf0060a4af1044886b42a13f7c506b35255d134a7e87ab3f23a9493b'), + ) + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('038ef30acb438b64159f484aec541fd2')))).eq( + 'f71eed6018f1ef976d39c19f9d29fd29', + ) + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('038ef30acb438b64159f484aec541fd2')))).eq( + 'f71eed6018f1ef976d39c19f9d29fd29', + ) + expect(hexEncode(await aes.decrypt(hexDecodeToBuffer('29c3af710c3c56f7fbb97ca06af3b974')))).eq( + '460af382084b7960d2e9f3bca4cdc25b', + ) }) it('should encrypt and decrypt aes-ige', async () => { - const aes = c.createAesIge( - Buffer.from('5468697320697320616E20696D706C655468697320697320616E20696D706C65', 'hex'), - Buffer.from('6D656E746174696F6E206F6620494745206D6F646520666F72204F70656E5353', 'hex'), + const aes = await c.createAesIge( + hexDecodeToBuffer('5468697320697320616E20696D706C655468697320697320616E20696D706C65'), + hexDecodeToBuffer('6D656E746174696F6E206F6620494745206D6F646520666F72204F70656E5353'), ) expect( - ( + hexEncode( await aes.encrypt( - Buffer.from('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b', 'hex'), - ) - ).toString('hex'), + hexDecodeToBuffer('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b'), + ), + ), ).to.eq('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69') expect( - ( + hexEncode( await aes.decrypt( - Buffer.from('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69', 'hex'), - ) - ).toString('hex'), + hexDecodeToBuffer('792ea8ae577b1a66cb3bd92679b8030ca54ee631976bd3a04547fdcb4639fa69'), + ), + ), ).to.eq('99706487a1cde613bc6de0b6f24b1c7aa448c8b9c3403e3467a8cad89340f53b') }) } @@ -104,14 +137,12 @@ describe('NodeCryptoProvider', () => { testCryptoProvider(new NodeCryptoProvider()) }) -describe('ForgeCryptoProvider', () => { - try { - require('node-forge') - } catch (e) { - console.warn('Skipping ForgeCryptoProvider tests') +describe('SubtleCryptoProvider', () => { + if (typeof crypto.subtle === 'undefined') { + console.warn('Skipping SubtleCryptoProvider tests') return } - testCryptoProvider(new ForgeCryptoProvider()) + testCryptoProvider(new SubtleCryptoProvider(crypto.subtle)) }) diff --git a/packages/core/tests/fuzz/fuzz-packet.spec.ts b/packages/core/tests/fuzz/fuzz-packet.spec.ts index 3a013ef7..16f19994 100644 --- a/packages/core/tests/fuzz/fuzz-packet.spec.ts +++ b/packages/core/tests/fuzz/fuzz-packet.spec.ts @@ -5,7 +5,7 @@ // import __tlReaderMap from '@mtcute/tl/binary/reader' // import { TlBinaryReader } from '@mtcute/tl-runtime' // -// import { createTestTelegramClient } from './utils' +// import { createTestTelegramClient } from './utils.js' // // // eslint-disable-next-line @typescript-eslint/no-var-requires // require('dotenv-flow').config() diff --git a/packages/core/tests/fuzz/fuzz-session.spec.ts b/packages/core/tests/fuzz/fuzz-session.spec.ts index 1a8af750..7ed48f98 100644 --- a/packages/core/tests/fuzz/fuzz-session.spec.ts +++ b/packages/core/tests/fuzz/fuzz-session.spec.ts @@ -2,8 +2,8 @@ // import { randomBytes } from 'crypto' // import { describe, it } from 'mocha' // -// import { sleep } from '../../src' -// import { createTestTelegramClient } from './utils' +// import { sleep } from '../../src.js' +// import { createTestTelegramClient } from './utils.js' // // // eslint-disable-next-line @typescript-eslint/no-var-requires // require('dotenv-flow').config() diff --git a/packages/core/tests/fuzz/fuzz-transport.spec.ts b/packages/core/tests/fuzz/fuzz-transport.spec.ts index 3be4e27a..b12e7362 100644 --- a/packages/core/tests/fuzz/fuzz-transport.spec.ts +++ b/packages/core/tests/fuzz/fuzz-transport.spec.ts @@ -11,7 +11,7 @@ // sleep, // tl, // TransportState, -// } from '../../src' +// } from '../../src.js' // // // eslint-disable-next-line @typescript-eslint/no-var-requires // require('dotenv-flow').config() diff --git a/packages/core/tests/fuzz/utils.ts b/packages/core/tests/fuzz/utils.ts index 79679a78..f2621ff8 100644 --- a/packages/core/tests/fuzz/utils.ts +++ b/packages/core/tests/fuzz/utils.ts @@ -1,17 +1,17 @@ -import { BaseTelegramClient, TcpTransport } from '../../src' -import { NodeCryptoProvider } from '../../utils' +// import { BaseTelegramClient, TcpTransport } from '../../src.js' +// import { NodeCryptoProvider } from '../../utils.js' -export function createTestTelegramClient() { - const tg = new BaseTelegramClient({ - // provided explicitly because mocha - crypto: () => new NodeCryptoProvider(), - transport: () => new TcpTransport(), - // example values from tdlib - apiId: 94575, - apiHash: 'a3406de8d171bb422bb6ddf3bbd800e2', - testMode: true, - }) - tg.log.level = 0 +// export function createTestTelegramClient() { +// const tg = new BaseTelegramClient({ +// // provided explicitly because mocha +// crypto: () => new NodeCryptoProvider(), +// transport: () => new TcpTransport(), +// // example values from tdlib +// apiId: 94575, +// apiHash: 'a3406de8d171bb422bb6ddf3bbd800e2', +// testMode: true, +// }) +// tg.log.level = 0 - return tg -} +// return tg +// } diff --git a/packages/core/tests/keys.spec.ts b/packages/core/tests/keys.spec.ts index f3a094e2..a85415cc 100644 --- a/packages/core/tests/keys.spec.ts +++ b/packages/core/tests/keys.spec.ts @@ -1,7 +1,8 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { NodeCryptoProvider, parsePublicKey } from '../utils' +import { NodeCryptoProvider } from '../src/utils/crypto/node-crypto.js' +import { parsePublicKey } from '../src/utils/index.js' const crypto = new NodeCryptoProvider() diff --git a/packages/core/tests/lru-map.spec.ts b/packages/core/tests/lru-map.spec.ts index 4e07cb39..d32f0cb5 100644 --- a/packages/core/tests/lru-map.spec.ts +++ b/packages/core/tests/lru-map.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { LruMap } from '../utils' +import { LruMap } from '../utils.js' describe('LruMap', () => { it('Map backend', () => { diff --git a/packages/core/tests/lru-set.spec.ts b/packages/core/tests/lru-set.spec.ts index a281d4a5..36919b2a 100644 --- a/packages/core/tests/lru-set.spec.ts +++ b/packages/core/tests/lru-set.spec.ts @@ -2,7 +2,7 @@ import { expect } from 'chai' import Long from 'long' import { describe, it } from 'mocha' -import { LruSet } from '../utils' +import { LruSet } from '../utils.js' describe('LruSet', () => { describe('for strings', () => { diff --git a/packages/core/tests/miller-rabin.spec.ts b/packages/core/tests/miller-rabin.spec.ts index 57583da1..5bb2c079 100644 --- a/packages/core/tests/miller-rabin.spec.ts +++ b/packages/core/tests/miller-rabin.spec.ts @@ -2,7 +2,7 @@ import bigInt from 'big-integer' import { expect } from 'chai' import { describe, it } from 'mocha' -import { millerRabin } from '../src/utils/crypto/miller-rabin' +import { millerRabin } from '../src/utils/crypto/miller-rabin.js' describe('miller-rabin test', function () { this.timeout(10000) // since miller-rabin factorization relies on RNG, it may take a while (or may not!) diff --git a/packages/core/tests/mtproto-crypto.spec.ts b/packages/core/tests/mtproto-crypto.spec.ts new file mode 100644 index 00000000..c21340f2 --- /dev/null +++ b/packages/core/tests/mtproto-crypto.spec.ts @@ -0,0 +1,89 @@ +/* eslint-disable no-restricted-globals,@typescript-eslint/no-unsafe-assignment */ +// for whatever reason eslint doesn't properly handle chai-spies typings +import chai, { expect } from 'chai' +import spies from 'chai-spies' +import { describe, it } from 'mocha' + +import { + createAesIgeForMessage, + createAesIgeForMessageOld, + generateKeyAndIvFromNonce, +} from '../src/utils/crypto/mtproto.js' +import { NodeCryptoProvider } from '../src/utils/crypto/node-crypto.js' + +chai.use(spies) + +const authKey = Buffer.alloc( + 2048 / 8, + Buffer.from('98cb29c6ffa89e79da695a54f572e6cb101e81c688b63a4bf73c3622dec230e0', 'hex'), +) +const messageKey = Buffer.from('25d701f2a29205526757825a99eb2d32') + +describe('mtproto 2.0', () => { + it('should correctly derive message key and iv for client', async () => { + const crypto = new NodeCryptoProvider() + const spy = chai.spy.on(crypto, 'createAesIge') + + await createAesIgeForMessage(crypto, authKey, messageKey, true) + + expect(spy).to.have.been.called.with.exactly( + Buffer.from('7acac59ab48cd370e478daf6c64545ab9f32d5c9197f25febe052110f61875ca', 'hex'), + Buffer.from('2746ccc19fc260c08f3d2696389f415392103dbcc3a8bf69da9394c3c3d95bd3', 'hex'), + ) + }) + + it('should correctly derive message key and iv for server', async () => { + const crypto = new NodeCryptoProvider() + const spy = chai.spy.on(crypto, 'createAesIge') + + await createAesIgeForMessage(crypto, authKey, messageKey, false) + + expect(spy).to.have.been.called.with.exactly( + Buffer.from('c7cf179e7ebab144ba87de05415db4157d2fc66df4790b2fd405a6c8cbe4c0b3', 'hex'), + Buffer.from('0916a7bd9880eacd4eeb868577a4c6a50e76fca4ac5c1bcfbafe3b9f76ccd806', 'hex'), + ) + }) +}) + +describe('mtproto 1.0', () => { + it('should correctly derive message key and iv for client', async () => { + const crypto = new NodeCryptoProvider() + const spy = chai.spy.on(crypto, 'createAesIge') + + await createAesIgeForMessageOld(crypto, authKey, messageKey, true) + + expect(spy).to.have.been.called.with.exactly( + Buffer.from('aad61cb5b7be5e8435174d74665f8a978e85806d0970ad4958642ca49e3c8834', 'hex'), + Buffer.from('4065736fe6586e94aad9f024062f1b9988e8a44e2aff4e11aad61cb5b7be5e84', 'hex'), + ) + }) + + it('should correctly derive message key and iv for server', async () => { + const crypto = new NodeCryptoProvider() + const spy = chai.spy.on(crypto, 'createAesIge') + + await createAesIgeForMessageOld(crypto, authKey, messageKey, false) + + expect(spy).to.have.been.called.with.exactly( + Buffer.from('d57682a17105e43b92bc5025ea80e88ef708240fc19450dfe072a8760f9534da', 'hex'), + Buffer.from('07addff7beeb7705ef3a9d5090bd73c992d57291bb8a7079d57682a17105e43b', 'hex'), + ) + }) +}) + +describe('mtproto key/iv from nonce', () => { + it('should correctly derive message key and iv for given nonces', async () => { + const crypto = new NodeCryptoProvider() + + const res = await generateKeyAndIvFromNonce( + crypto, + Buffer.from('8af24c551836e5ed7002f5857e6e71b2', 'hex'), + Buffer.from('3bf48b2d3152f383d82d1f2b32ac7fb5', 'hex'), + ) + + expect(res).to.eql([ + Buffer.from('b0b5ffeadff0249fa6292f5ae0351556fd6619ba5dd4809601669292456d3e5a', 'hex'), + Buffer.from('13fef5bfd8c46b12dfd1753013b86cc012e1ce8ed6f8ecdd7bf36f3a3bf48b2d', 'hex'), + ]) + }) +}) diff --git a/packages/core/tests/prime-factorization.spec.ts b/packages/core/tests/prime-factorization.spec.ts index ed3c2d23..b5212c2f 100644 --- a/packages/core/tests/prime-factorization.spec.ts +++ b/packages/core/tests/prime-factorization.spec.ts @@ -1,16 +1,18 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { factorizePQSync } from '../src/utils/crypto/factorization' +import { hexDecodeToBuffer, hexEncode } from '@mtcute/tl-runtime' + +import { factorizePQSync } from '../src/utils/crypto/factorization.js' describe('prime factorization', function () { this.timeout(10000) // since PQ factorization relies on RNG, it may take a while (or may not!) it('should decompose PQ to prime factors P and Q', () => { const testFactorization = (pq: string, p: string, q: string) => { - const [p1, q1] = factorizePQSync(Buffer.from(pq, 'hex')) - expect(p1.toString('hex')).eq(p.toLowerCase()) - expect(q1.toString('hex')).eq(q.toLowerCase()) + const [p1, q1] = factorizePQSync(hexDecodeToBuffer(pq)) + expect(hexEncode(p1)).eq(p.toLowerCase()) + expect(hexEncode(q1)).eq(q.toLowerCase()) } // from samples at https://core.telegram.org/mtproto/samples-auth_key diff --git a/packages/core/tests/transport-codecs/intermediate-codec.spec.ts b/packages/core/tests/transport-codecs/intermediate-codec.spec.ts index ecda29ec..d9807294 100644 --- a/packages/core/tests/transport-codecs/intermediate-codec.spec.ts +++ b/packages/core/tests/transport-codecs/intermediate-codec.spec.ts @@ -1,30 +1,32 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { IntermediatePacketCodec, TransportError } from '../../src' +import { hexDecodeToBuffer, hexEncode } from '@mtcute/tl-runtime' + +import { IntermediatePacketCodec, TransportError } from '../../src/index.js' describe('IntermediatePacketCodec', () => { it('should return correct tag', () => { - expect(new IntermediatePacketCodec().tag().toString('hex')).eq('eeeeeeee') + expect(hexEncode(new IntermediatePacketCodec().tag())).eq('eeeeeeee') }) it('should correctly parse immediate framing', (done) => { const codec = new IntermediatePacketCodec() - codec.on('packet', (data: Buffer) => { + codec.on('packet', (data: Uint8Array) => { expect([...data]).eql([5, 1, 2, 3, 4]) done() }) - codec.feed(Buffer.from('050000000501020304', 'hex')) + codec.feed(hexDecodeToBuffer('050000000501020304')) }) it('should correctly parse incomplete framing', (done) => { const codec = new IntermediatePacketCodec() - codec.on('packet', (data: Buffer) => { + codec.on('packet', (data: Uint8Array) => { expect([...data]).eql([5, 1, 2, 3, 4]) done() }) - codec.feed(Buffer.from('050000000501', 'hex')) - codec.feed(Buffer.from('020304', 'hex')) + codec.feed(hexDecodeToBuffer('050000000501')) + codec.feed(hexDecodeToBuffer('020304')) }) it('should correctly parse multiple streamed packets', (done) => { @@ -32,7 +34,7 @@ describe('IntermediatePacketCodec', () => { let number = 0 - codec.on('packet', (data: Buffer) => { + codec.on('packet', (data: Uint8Array) => { if (number === 0) { expect([...data]).eql([5, 1, 2, 3, 4]) number = 1 @@ -41,9 +43,9 @@ describe('IntermediatePacketCodec', () => { done() } }) - codec.feed(Buffer.from('050000000501', 'hex')) - codec.feed(Buffer.from('020304050000', 'hex')) - codec.feed(Buffer.from('000301020301', 'hex')) + codec.feed(hexDecodeToBuffer('050000000501')) + codec.feed(hexDecodeToBuffer('020304050000')) + codec.feed(hexDecodeToBuffer('000301020301')) }) it('should correctly parse transport errors', (done) => { @@ -55,19 +57,19 @@ describe('IntermediatePacketCodec', () => { done() }) - codec.feed(Buffer.from('040000006cfeffff', 'hex')) + codec.feed(hexDecodeToBuffer('040000006cfeffff')) }) it('should reset when called reset()', (done) => { const codec = new IntermediatePacketCodec() - codec.on('packet', (data: Buffer) => { + codec.on('packet', (data: Uint8Array) => { expect([...data]).eql([1, 2, 3, 4, 5]) done() }) - codec.feed(Buffer.from('ff0000001234567812345678', 'hex')) + codec.feed(hexDecodeToBuffer('ff0000001234567812345678')) codec.reset() - codec.feed(Buffer.from('050000000102030405', 'hex')) + codec.feed(hexDecodeToBuffer('050000000102030405')) }) }) diff --git a/packages/core/tests/tsconfig.json b/packages/core/tests/tsconfig.json new file mode 100644 index 00000000..cfa0657b --- /dev/null +++ b/packages/core/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + ".", + ], + "references": [ + { "path": "../" }, + ] +} diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 85468e53..b840c259 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -1,12 +1,18 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src", + "paths": { + "@mtcute/dispatcher": ["../dispatcher/src/state/storage.ts"], + } }, "include": [ "./src", - "./tests", - "./utils.ts", + ], + "references": [ + { "path": "../tl" }, + { "path": "../tl-runtime" }, ], "typedocOptions": { "name": "@mtcute/core", diff --git a/packages/core/utils.ts b/packages/core/utils.ts index d014f0a3..50894ad2 100644 --- a/packages/core/utils.ts +++ b/packages/core/utils.ts @@ -1,4 +1,4 @@ // this file only exists as a hint to IDEs that we can use @mtcute/core/utils instead of @mtcute/core/src/utils. // it is not present in the built package, just a DX improvement -export * from './src/utils' +export * from './src/utils/index.js' diff --git a/packages/crypto-node/package.json b/packages/crypto-node/package.json index 6d9c0b47..30cd0ada 100644 --- a/packages/crypto-node/package.json +++ b/packages/crypto-node/package.json @@ -6,17 +6,27 @@ "main": "src/index.ts", "private": true, "license": "MIT", + "type": "module", "scripts": { "build:bin": "node-gyp configure && node-gyp -j 16 build ", "build:dev": "node-gyp -j 16 build --debug", - "build": "tsc", + "build": "pnpm run -w build-package crypto-node", "install": "node-gyp configure && node-gyp -j 16 build", "rebuild:dev": "node-gyp configure --debug && node-gyp -j 16 rebuild --debug", "rebuild": "node-gyp configure && node-gyp -j 16 rebuild", "clean": "node-gyp clean", - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "docs": "typedoc" }, + "keepScripts": ["install"], + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } + }, "dependencies": { "@mtcute/core": "workspace:^1.0.0" } diff --git a/packages/crypto-node/src/index.ts b/packages/crypto-node/src/index.ts index 631d5bb5..21521222 100644 --- a/packages/crypto-node/src/index.ts +++ b/packages/crypto-node/src/index.ts @@ -1,7 +1,10 @@ -import { IEncryptionScheme, NodeCryptoProvider } from '@mtcute/core/utils' +import { NodeCryptoProvider } from '@mtcute/core/src/utils/crypto/node-crypto.js' +import { IEncryptionScheme } from '@mtcute/core/utils.js' + +import { native } from './native.cjs' // eslint-disable-next-line camelcase -import { ige256_decrypt, ige256_encrypt } from './native' +const { ige256_decrypt, ige256_encrypt } = native /** * Crypto provider for NodeJS that uses a native extension to improve @@ -11,12 +14,12 @@ import { ige256_decrypt, ige256_encrypt } from './native' * they *are* faster than the custom ones. */ export class NodeNativeCryptoProvider extends NodeCryptoProvider { - createAesIge(key: Buffer, iv: Buffer): IEncryptionScheme { + createAesIge(key: Uint8Array, iv: Uint8Array): IEncryptionScheme { return { - encrypt(data: Buffer): Buffer { + encrypt(data: Uint8Array): Uint8Array { return ige256_encrypt(data, key, iv) }, - decrypt(data: Buffer): Buffer { + decrypt(data: Uint8Array): Uint8Array { return ige256_decrypt(data, key, iv) }, } diff --git a/packages/crypto-node/src/native.cjs b/packages/crypto-node/src/native.cjs new file mode 100644 index 00000000..005665d6 --- /dev/null +++ b/packages/crypto-node/src/native.cjs @@ -0,0 +1,10 @@ +/* eslint-disable no-restricted-globals */ +let native + +try { + native = require('../build/Release/crypto') +} catch (e) { + native = require('../build/Debug/crypto') +} + +module.exports = { native } diff --git a/packages/crypto-node/src/native.d.cts b/packages/crypto-node/src/native.d.cts new file mode 100644 index 00000000..131cd7c4 --- /dev/null +++ b/packages/crypto-node/src/native.d.cts @@ -0,0 +1,4 @@ +export const native: { + ige256_encrypt(data: Uint8Array, key: Uint8Array, iv: Uint8Array): Uint8Array + ige256_decrypt(data: Uint8Array, key: Uint8Array, iv: Uint8Array): Uint8Array +} diff --git a/packages/crypto-node/src/native.d.ts b/packages/crypto-node/src/native.d.ts deleted file mode 100644 index 4a153318..00000000 --- a/packages/crypto-node/src/native.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export function ige256_encrypt(data: Buffer, key: Buffer, iv: Buffer): Buffer -export function ige256_decrypt(data: Buffer, key: Buffer, iv: Buffer): Buffer diff --git a/packages/crypto-node/src/native.js b/packages/crypto-node/src/native.js deleted file mode 100644 index 8212ce0d..00000000 --- a/packages/crypto-node/src/native.js +++ /dev/null @@ -1,9 +0,0 @@ -let mod - -try { - mod = require('../build/Release/crypto') -} catch (e) { - mod = require('../build/Debug/crypto') -} - -module.exports = mod diff --git a/packages/crypto-node/tests/node-native-crypto.spec.ts b/packages/crypto-node/tests/node-native-crypto.spec.ts index 5cc1ad44..a38e9061 100644 --- a/packages/crypto-node/tests/node-native-crypto.spec.ts +++ b/packages/crypto-node/tests/node-native-crypto.spec.ts @@ -1,8 +1,8 @@ import { describe } from 'mocha' -import { testCryptoProvider } from '@mtcute/core/tests/crypto-providers.spec' - -import { NodeNativeCryptoProvider } from '../src' +// eslint-disable-next-line import/no-relative-packages +import { testCryptoProvider } from '../../core/tests/crypto-providers.spec.js' +import { NodeNativeCryptoProvider } from '../src/index.js' describe('NodeNativeCryptoProvider', () => { testCryptoProvider(new NodeNativeCryptoProvider()) diff --git a/packages/crypto-node/tests/tsconfig.json b/packages/crypto-node/tests/tsconfig.json new file mode 100644 index 00000000..cfa0657b --- /dev/null +++ b/packages/crypto-node/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + ".", + ], + "references": [ + { "path": "../" }, + ] +} diff --git a/packages/crypto-node/tsconfig.json b/packages/crypto-node/tsconfig.json index 24505be8..6a5497ee 100644 --- a/packages/crypto-node/tsconfig.json +++ b/packages/crypto-node/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src" }, "include": [ "./src", - "./tests" + ], + "references": [ + { "path": "../core" } ] } diff --git a/packages/dispatcher/package.json b/packages/dispatcher/package.json index 9ea43195..ced40730 100644 --- a/packages/dispatcher/package.json +++ b/packages/dispatcher/package.json @@ -6,14 +6,22 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "src/index.ts", + "type": "module", + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } + }, "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "docs": "typedoc", - "build": "tsc", - "gen-updates": "node ./scripts/generate.js" + "build": "pnpm run -w build-package dispatcher", + "gen-updates": "node ./scripts/generate.cjs" }, "dependencies": { - "@mtcute/core": "workspace:^1.0.0", "@mtcute/client": "workspace:^1.0.0", "events": "3.2.0" } diff --git a/packages/dispatcher/scripts/generate.js b/packages/dispatcher/scripts/generate.cjs similarity index 97% rename from packages/dispatcher/scripts/generate.js rename to packages/dispatcher/scripts/generate.cjs index 4d06039e..5f6acdc5 100644 --- a/packages/dispatcher/scripts/generate.js +++ b/packages/dispatcher/scripts/generate.cjs @@ -1,3 +1,4 @@ +/* eslint-disable no-restricted-globals */ const { types, toSentence, replaceSections, formatFile } = require('../../client/scripts/generate-updates') function generateHandler() { @@ -96,7 +97,7 @@ ${ .sort() .map((i) => ` ${i},\n`) .join('') + - "} from './handler'", + "} from './handler.js'", }, __dirname, ) diff --git a/packages/dispatcher/src/callback-data-builder.ts b/packages/dispatcher/src/callback-data-builder.ts index d20ea07d..c93d7fd9 100644 --- a/packages/dispatcher/src/callback-data-builder.ts +++ b/packages/dispatcher/src/callback-data-builder.ts @@ -1,7 +1,6 @@ -import { CallbackQuery } from '@mtcute/client' -import { MaybeArray, MtArgumentError } from '@mtcute/core' +import { CallbackQuery, MaybeArray, MtArgumentError } from '@mtcute/client' -import { UpdateFilter } from './filters' +import { UpdateFilter } from './filters/types.js' /** * Callback data builder, inspired by [aiogram](https://github.com/aiogram/aiogram). diff --git a/packages/dispatcher/src/context/callback-query.ts b/packages/dispatcher/src/context/callback-query.ts index 0d6ad787..a17d323c 100644 --- a/packages/dispatcher/src/context/callback-query.ts +++ b/packages/dispatcher/src/context/callback-query.ts @@ -1,6 +1,6 @@ import { CallbackQuery, getMarkedPeerId, MtArgumentError, MtMessageNotFoundError, TelegramClient } from '@mtcute/client' -import { UpdateContext } from './base' +import { UpdateContext } from './base.js' /** * Context of a callback query update. diff --git a/packages/dispatcher/src/context/chat-join-request.ts b/packages/dispatcher/src/context/chat-join-request.ts index ebe8c186..0bad1eda 100644 --- a/packages/dispatcher/src/context/chat-join-request.ts +++ b/packages/dispatcher/src/context/chat-join-request.ts @@ -1,6 +1,6 @@ import { BotChatJoinRequestUpdate, TelegramClient } from '@mtcute/client' -import { UpdateContext } from './base' +import { UpdateContext } from './base.js' /** * Context of a chat join request update (for bots). diff --git a/packages/dispatcher/src/context/chosen-inline-result.ts b/packages/dispatcher/src/context/chosen-inline-result.ts index 39df89b2..575d9b0e 100644 --- a/packages/dispatcher/src/context/chosen-inline-result.ts +++ b/packages/dispatcher/src/context/chosen-inline-result.ts @@ -1,6 +1,6 @@ import { ChosenInlineResult, MtArgumentError, TelegramClient } from '@mtcute/client' -import { UpdateContext } from './base' +import { UpdateContext } from './base.js' /** * Context of a chosen inline result update. diff --git a/packages/dispatcher/src/context/index.ts b/packages/dispatcher/src/context/index.ts index 64eada26..27c36013 100644 --- a/packages/dispatcher/src/context/index.ts +++ b/packages/dispatcher/src/context/index.ts @@ -1,7 +1,8 @@ -export * from './base' -export * from './callback-query' -export * from './chat-join-request' -export * from './chosen-inline-result' -export * from './inline-query' -export * from './message' -export * from './pre-checkout-query' +export * from './base.js' +export * from './callback-query.js' +export * from './chat-join-request.js' +export * from './chosen-inline-result.js' +export * from './inline-query.js' +export * from './message.js' +export { UpdateContextType } from './parse.js' +export * from './pre-checkout-query.js' diff --git a/packages/dispatcher/src/context/inline-query.ts b/packages/dispatcher/src/context/inline-query.ts index 5417259c..e9594f59 100644 --- a/packages/dispatcher/src/context/inline-query.ts +++ b/packages/dispatcher/src/context/inline-query.ts @@ -1,6 +1,6 @@ import { InlineQuery, ParametersSkip1, TelegramClient } from '@mtcute/client' -import { UpdateContext } from './base' +import { UpdateContext } from './base.js' /** * Context of an inline query update. diff --git a/packages/dispatcher/src/context/message.ts b/packages/dispatcher/src/context/message.ts index eb45048e..b7958dcb 100644 --- a/packages/dispatcher/src/context/message.ts +++ b/packages/dispatcher/src/context/message.ts @@ -1,10 +1,10 @@ import { Message, OmitInputMessageId, ParametersSkip1, TelegramClient } from '@mtcute/client' -import { DeleteMessagesParams } from '@mtcute/client/src/methods/messages/delete-messages' -import { ForwardMessageOptions } from '@mtcute/client/src/methods/messages/forward-messages' -import { SendCopyParams } from '@mtcute/client/src/methods/messages/send-copy' -import { SendCopyGroupParams } from '@mtcute/client/src/methods/messages/send-copy-group' +import { DeleteMessagesParams } from '@mtcute/client/src/methods/messages/delete-messages.js' +import { ForwardMessageOptions } from '@mtcute/client/src/methods/messages/forward-messages.js' +import { SendCopyParams } from '@mtcute/client/src/methods/messages/send-copy.js' +import { SendCopyGroupParams } from '@mtcute/client/src/methods/messages/send-copy-group.js' -import { UpdateContext } from './base' +import { UpdateContext } from './base.js' /** * Context of a message-related update. diff --git a/packages/dispatcher/src/context/parse.ts b/packages/dispatcher/src/context/parse.ts index dc91243f..416e9754 100644 --- a/packages/dispatcher/src/context/parse.ts +++ b/packages/dispatcher/src/context/parse.ts @@ -1,12 +1,12 @@ import { ParsedUpdate, TelegramClient } from '@mtcute/client' -import { UpdateContext } from './base' -import { CallbackQueryContext } from './callback-query' -import { ChatJoinRequestUpdateContext } from './chat-join-request' -import { ChosenInlineResultContext } from './chosen-inline-result' -import { InlineQueryContext } from './inline-query' -import { MessageContext } from './message' -import { PreCheckoutQueryContext } from './pre-checkout-query' +import { UpdateContextDistributed } from './base.js' +import { CallbackQueryContext } from './callback-query.js' +import { ChatJoinRequestUpdateContext } from './chat-join-request.js' +import { ChosenInlineResultContext } from './chosen-inline-result.js' +import { InlineQueryContext } from './inline-query.js' +import { MessageContext } from './message.js' +import { PreCheckoutQueryContext } from './pre-checkout-query.js' /** @internal */ export function _parsedUpdateToContext(client: TelegramClient, update: ParsedUpdate) { @@ -27,7 +27,7 @@ export function _parsedUpdateToContext(client: TelegramClient, update: ParsedUpd return new PreCheckoutQueryContext(client, update.data) } - const _update = update.data as UpdateContext + const _update = update.data as UpdateContextDistributed _update.client = client _update._name = update.name diff --git a/packages/dispatcher/src/context/pre-checkout-query.ts b/packages/dispatcher/src/context/pre-checkout-query.ts index eb605e53..da5f6077 100644 --- a/packages/dispatcher/src/context/pre-checkout-query.ts +++ b/packages/dispatcher/src/context/pre-checkout-query.ts @@ -1,6 +1,6 @@ import { PreCheckoutQuery, TelegramClient } from '@mtcute/client' -import { UpdateContext } from './base' +import { UpdateContext } from './base.js' /** * Context of a pre-checkout query update diff --git a/packages/dispatcher/src/dispatcher.ts b/packages/dispatcher/src/dispatcher.ts index 716f0994..3dffde34 100644 --- a/packages/dispatcher/src/dispatcher.ts +++ b/packages/dispatcher/src/dispatcher.ts @@ -11,6 +11,7 @@ import { DeleteStoryUpdate, HistoryReadUpdate, MaybeAsync, + MtArgumentError, ParsedUpdate, PeersIndex, PollUpdate, @@ -21,8 +22,8 @@ import { UserStatusUpdate, UserTypingUpdate, } from '@mtcute/client' -import { MtArgumentError } from '@mtcute/core' +import { UpdateContext } from './context/base.js' import { CallbackQueryContext, ChatJoinRequestUpdateContext, @@ -30,10 +31,9 @@ import { InlineQueryContext, MessageContext, PreCheckoutQueryContext, -} from './context' -import { UpdateContext } from './context/base' -import { _parsedUpdateToContext, UpdateContextType } from './context/parse' -import { filters, UpdateFilter } from './filters' +} from './context/index.js' +import { _parsedUpdateToContext, UpdateContextType } from './context/parse.js' +import { filters, UpdateFilter } from './filters/index.js' // begin-codegen-imports import { BotChatJoinRequestHandler, @@ -57,10 +57,10 @@ import { UpdateHandler, UserStatusUpdateHandler, UserTypingHandler, -} from './handler' +} from './handler.js' // end-codegen-imports -import { PropagationAction } from './propagation' -import { defaultStateKeyDelegate, IStateStorage, StateKeyDelegate, UpdateState } from './state' +import { PropagationAction } from './propagation.js' +import { defaultStateKeyDelegate, IStateStorage, StateKeyDelegate, UpdateState } from './state/index.js' /** * Updates dispatcher diff --git a/packages/dispatcher/src/filters/bots.ts b/packages/dispatcher/src/filters/bots.ts index 87091036..7e9710ba 100644 --- a/packages/dispatcher/src/filters/bots.ts +++ b/packages/dispatcher/src/filters/bots.ts @@ -1,10 +1,9 @@ -import { Message } from '@mtcute/client' -import { MaybeArray, MaybeAsync } from '@mtcute/core' +import { MaybeArray, MaybeAsync, Message } from '@mtcute/client' -import { MessageContext } from '../context' -import { chat } from './chat' -import { and } from './logic' -import { UpdateFilter } from './types' +import { MessageContext } from '../context/message.js' +import { chat } from './chat.js' +import { and } from './logic.js' +import { UpdateFilter } from './types.js' /** * Filter messages that call the given command(s).. diff --git a/packages/dispatcher/src/filters/bundle.ts b/packages/dispatcher/src/filters/bundle.ts index f6d0bd12..94984b28 100644 --- a/packages/dispatcher/src/filters/bundle.ts +++ b/packages/dispatcher/src/filters/bundle.ts @@ -1,10 +1,10 @@ -export * from './bots' -export * from './chat' -export * from './group' -export * from './logic' -export * from './message' -export * from './state' -export * from './text' -export * from './types' -export * from './updates' -export * from './user' +export * from './bots.js' +export * from './chat.js' +export * from './group.js' +export * from './logic.js' +export * from './message.js' +export * from './state.js' +export * from './text.js' +export * from './types.js' +export * from './updates.js' +export * from './user.js' diff --git a/packages/dispatcher/src/filters/chat.ts b/packages/dispatcher/src/filters/chat.ts index 61d32dca..76c2fbf0 100644 --- a/packages/dispatcher/src/filters/chat.ts +++ b/packages/dispatcher/src/filters/chat.ts @@ -4,15 +4,15 @@ import { ChatMemberUpdate, ChatType, HistoryReadUpdate, + MaybeArray, Message, PollVoteUpdate, User, UserTypingUpdate, } from '@mtcute/client' -import { MaybeArray } from '@mtcute/core' -import { UpdateContextDistributed } from '../context' -import { Modify, UpdateFilter } from './types' +import { UpdateContextDistributed } from '../context/base.js' +import { Modify, UpdateFilter } from './types.js' /** * Filter messages by chat type diff --git a/packages/dispatcher/src/filters/group.ts b/packages/dispatcher/src/filters/group.ts index 154ced31..b6df1306 100644 --- a/packages/dispatcher/src/filters/group.ts +++ b/packages/dispatcher/src/filters/group.ts @@ -1,8 +1,7 @@ -import { Message } from '@mtcute/client' -import { MaybeAsync } from '@mtcute/core' +import { MaybeAsync, Message } from '@mtcute/client' -import { MessageContext } from '../context' -import { Modify, UpdateFilter } from './types' +import { MessageContext } from '../context/message.js' +import { Modify, UpdateFilter } from './types.js' /** * For message groups, apply a filter to every message in the group. diff --git a/packages/dispatcher/src/filters/index.ts b/packages/dispatcher/src/filters/index.ts index b25624e7..73c8a129 100644 --- a/packages/dispatcher/src/filters/index.ts +++ b/packages/dispatcher/src/filters/index.ts @@ -1,3 +1,3 @@ -import * as filters from './bundle' +import * as filters from './bundle.js' import UpdateFilter = filters.UpdateFilter export { filters, UpdateFilter } diff --git a/packages/dispatcher/src/filters/logic.ts b/packages/dispatcher/src/filters/logic.ts index 81f6701c..982091ec 100644 --- a/packages/dispatcher/src/filters/logic.ts +++ b/packages/dispatcher/src/filters/logic.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ // ^^ will be looked into in MTQ-29 -import { MaybeAsync } from '@mtcute/core' +import { MaybeAsync } from '@mtcute/client' -import { ExtractBaseMany, ExtractMod, Invert, UnionToIntersection, UpdateFilter } from './types' +import { ExtractBaseMany, ExtractMod, Invert, UnionToIntersection, UpdateFilter } from './types.js' /** * Filter that matches any update diff --git a/packages/dispatcher/src/filters/message.ts b/packages/dispatcher/src/filters/message.ts index 64adaf22..289974bb 100644 --- a/packages/dispatcher/src/filters/message.ts +++ b/packages/dispatcher/src/filters/message.ts @@ -2,6 +2,7 @@ // ^^ will be looked into in MTQ-29 import { Chat, + MaybeArray, Message, MessageAction, MessageMediaType, @@ -13,9 +14,8 @@ import { User, Video, } from '@mtcute/client' -import { MaybeArray } from '@mtcute/core' -import { Modify, UpdateFilter } from './types' +import { Modify, UpdateFilter } from './types.js' /** * Filter incoming messages. diff --git a/packages/dispatcher/src/filters/state.ts b/packages/dispatcher/src/filters/state.ts index fd18a5ff..2d0a0bdf 100644 --- a/packages/dispatcher/src/filters/state.ts +++ b/packages/dispatcher/src/filters/state.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { MaybeAsync } from '@mtcute/core' +import { MaybeAsync } from '@mtcute/client' -import { UpdateFilter } from './types' +import { UpdateFilter } from './types.js' /** * Create a filter for the cases when the state is empty diff --git a/packages/dispatcher/src/filters/text.ts b/packages/dispatcher/src/filters/text.ts index 8d003319..c7714414 100644 --- a/packages/dispatcher/src/filters/text.ts +++ b/packages/dispatcher/src/filters/text.ts @@ -1,7 +1,7 @@ import { CallbackQuery, ChosenInlineResult, InlineQuery, Message } from '@mtcute/client' -import { UpdateContextDistributed } from '../context' -import { UpdateFilter } from './types' +import { UpdateContextDistributed } from '../context/base.js' +import { UpdateFilter } from './types.js' type UpdatesWithText = UpdateContextDistributed diff --git a/packages/dispatcher/src/filters/types.ts b/packages/dispatcher/src/filters/types.ts index ec2ce541..0897ef6b 100644 --- a/packages/dispatcher/src/filters/types.ts +++ b/packages/dispatcher/src/filters/types.ts @@ -2,9 +2,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ // ^^ will be looked into in MTQ-29 -import { MaybeAsync } from '@mtcute/core' +import { MaybeAsync } from '@mtcute/client' -import { UpdateState } from '../state' +import { UpdateState } from '../state/update-state.js' /** * Type describing a primitive filter, which is a function taking some `Base` * and a {@link TelegramClient}, checking it against some condition diff --git a/packages/dispatcher/src/filters/updates.ts b/packages/dispatcher/src/filters/updates.ts index b8f05596..15dce9da 100644 --- a/packages/dispatcher/src/filters/updates.ts +++ b/packages/dispatcher/src/filters/updates.ts @@ -1,7 +1,6 @@ -import { CallbackQuery, ChatMemberUpdate, ChatMemberUpdateType, UserStatus, UserStatusUpdate } from '@mtcute/client' -import { MaybeArray } from '@mtcute/core' +import { CallbackQuery, ChatMemberUpdate, ChatMemberUpdateType, MaybeArray, UserStatus, UserStatusUpdate } from '@mtcute/client' -import { UpdateFilter } from './types' +import { UpdateFilter } from './types.js' /** * Create a filter for {@link ChatMemberUpdate} by update type diff --git a/packages/dispatcher/src/filters/user.ts b/packages/dispatcher/src/filters/user.ts index 0aee850c..45b2f4f1 100644 --- a/packages/dispatcher/src/filters/user.ts +++ b/packages/dispatcher/src/filters/user.ts @@ -6,6 +6,7 @@ import { DeleteStoryUpdate, HistoryReadUpdate, InlineQuery, + MaybeArray, Message, PollVoteUpdate, StoryUpdate, @@ -13,10 +14,9 @@ import { UserStatusUpdate, UserTypingUpdate, } from '@mtcute/client' -import { MaybeArray } from '@mtcute/core' -import { UpdateContextDistributed } from '../context' -import { UpdateFilter } from './types' +import { UpdateContextDistributed } from '../context/base.js' +import { UpdateFilter } from './types.js' /** * Filter messages generated by yourself (including Saved Messages) diff --git a/packages/dispatcher/src/handler.ts b/packages/dispatcher/src/handler.ts index 657f637f..a55098dc 100644 --- a/packages/dispatcher/src/handler.ts +++ b/packages/dispatcher/src/handler.ts @@ -16,6 +16,7 @@ import { UserTypingUpdate, } from '@mtcute/client' +import { UpdateContext } from './context/base.js' import { CallbackQueryContext, ChatJoinRequestUpdateContext, @@ -23,9 +24,8 @@ import { InlineQueryContext, MessageContext, PreCheckoutQueryContext, -} from './context' -import { UpdateContext } from './context/base' -import { PropagationAction } from './propagation' +} from './context/index.js' +import { PropagationAction } from './propagation.js' export interface BaseUpdateHandler { name: Name diff --git a/packages/dispatcher/src/index.ts b/packages/dispatcher/src/index.ts index d23ce406..f275f560 100644 --- a/packages/dispatcher/src/index.ts +++ b/packages/dispatcher/src/index.ts @@ -1,8 +1,8 @@ -export * from './callback-data-builder' -export * from './context' -export * from './dispatcher' -export * from './filters' -export * from './handler' -export * from './propagation' -export * from './state' -export * from './wizard' +export * from './callback-data-builder.js' +export * from './context/index.js' +export * from './dispatcher.js' +export * from './filters/index.js' +export * from './handler.js' +export * from './propagation.js' +export * from './state/index.js' +export * from './wizard.js' diff --git a/packages/dispatcher/src/state/index.ts b/packages/dispatcher/src/state/index.ts index d791e554..f44fb9f0 100644 --- a/packages/dispatcher/src/state/index.ts +++ b/packages/dispatcher/src/state/index.ts @@ -1,3 +1,3 @@ -export * from './key' -export * from './storage' -export * from './update-state' +export * from './key.js' +export * from './storage.js' +export * from './update-state.js' diff --git a/packages/dispatcher/src/state/key.ts b/packages/dispatcher/src/state/key.ts index 3e212956..8c46d143 100644 --- a/packages/dispatcher/src/state/key.ts +++ b/packages/dispatcher/src/state/key.ts @@ -1,5 +1,4 @@ -import { CallbackQuery, Message } from '@mtcute/client' -import { assertNever, MaybeAsync } from '@mtcute/core' +import { assertNever, CallbackQuery, MaybeAsync, Message } from '@mtcute/client' /** * Function that determines how the state key is derived. diff --git a/packages/dispatcher/src/state/storage.ts b/packages/dispatcher/src/state/storage.ts index e76925d6..4fac20aa 100644 --- a/packages/dispatcher/src/state/storage.ts +++ b/packages/dispatcher/src/state/storage.ts @@ -1,4 +1,4 @@ -import { MaybeAsync } from '@mtcute/core' +import { MaybeAsync } from '@mtcute/client' /** * Interface for FSM storage for the dispatcher. diff --git a/packages/dispatcher/src/state/update-state.ts b/packages/dispatcher/src/state/update-state.ts index f331c983..0fc560db 100644 --- a/packages/dispatcher/src/state/update-state.ts +++ b/packages/dispatcher/src/state/update-state.ts @@ -1,7 +1,7 @@ -import { MtArgumentError, MtcuteError } from '@mtcute/core' -import { sleep } from '@mtcute/core/utils' +import { MtArgumentError, MtcuteError } from '@mtcute/client' +import { sleep } from '@mtcute/client/utils.js' -import { IStateStorage } from './storage' +import { IStateStorage } from './storage.js' /** * Error thrown by `.rateLimit()` diff --git a/packages/dispatcher/src/wizard.ts b/packages/dispatcher/src/wizard.ts index ff1ba2d4..ee032302 100644 --- a/packages/dispatcher/src/wizard.ts +++ b/packages/dispatcher/src/wizard.ts @@ -1,9 +1,9 @@ import { MaybeAsync } from '@mtcute/client' -import { MessageContext } from './context' -import { Dispatcher } from './dispatcher' -import { filters } from './filters' -import { UpdateState } from './state' +import { MessageContext } from './context/message.js' +import { Dispatcher } from './dispatcher.js' +import { filters } from './filters/index.js' +import { UpdateState } from './state/update-state.js' /** * Action for the wizard scene. diff --git a/packages/dispatcher/tests/dispatcher.spec.ts b/packages/dispatcher/tests/dispatcher.spec.ts index af5f20ca..348b657e 100644 --- a/packages/dispatcher/tests/dispatcher.spec.ts +++ b/packages/dispatcher/tests/dispatcher.spec.ts @@ -3,7 +3,7 @@ import { describe, it } from 'mocha' import { PeersIndex, TelegramClient } from '@mtcute/client' -import { Dispatcher, PropagationAction } from '../src' +import { Dispatcher, PropagationAction } from '../src/index.js' describe('Dispatcher', () => { // todo: replace with proper mocked TelegramClient diff --git a/packages/dispatcher/tests/tsconfig.json b/packages/dispatcher/tests/tsconfig.json new file mode 100644 index 00000000..cfa0657b --- /dev/null +++ b/packages/dispatcher/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + ".", + ], + "references": [ + { "path": "../" }, + ] +} diff --git a/packages/dispatcher/tsconfig.json b/packages/dispatcher/tsconfig.json index 24505be8..554df3b9 100644 --- a/packages/dispatcher/tsconfig.json +++ b/packages/dispatcher/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src" }, "include": [ "./src", - "./tests" + ], + "references": [ + { "path": "../client" } ] } diff --git a/packages/file-id/package.json b/packages/file-id/package.json index 0fd50728..7a312f07 100644 --- a/packages/file-id/package.json +++ b/packages/file-id/package.json @@ -6,13 +6,21 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "src/index.ts", + "type": "module", "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "docs": "typedoc", - "build": "tsc" + "build": "pnpm run -w build-package file-id" + }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } }, "dependencies": { - "@mtcute/tl-runtime": "workspace:^1.0.0", "@mtcute/core": "workspace:^1.0.0" } } \ No newline at end of file diff --git a/packages/file-id/src/convert.ts b/packages/file-id/src/convert.ts index 2c8341d7..b5a7fe97 100644 --- a/packages/file-id/src/convert.ts +++ b/packages/file-id/src/convert.ts @@ -1,10 +1,10 @@ import { assertNever, getBasicPeerType, Long, markedPeerIdToBare, tl } from '@mtcute/core' -import { parseFileId } from './parse' -import { tdFileId as td } from './types' +import { parseFileId } from './parse.js' +import { tdFileId as td } from './types.js' import FileType = td.FileType -const EMPTY_BUFFER = Buffer.alloc(0) +const EMPTY_BUFFER = new Uint8Array(0) type FileId = td.RawFullRemoteFileLocation diff --git a/packages/file-id/src/index.ts b/packages/file-id/src/index.ts index f744251d..ce6e80e5 100644 --- a/packages/file-id/src/index.ts +++ b/packages/file-id/src/index.ts @@ -1,5 +1,5 @@ -export * from './convert' -export * from './parse' -export * from './serialize' -export * from './serialize-unique' -export * from './types' +export * from './convert.js' +export * from './parse.js' +export * from './serialize.js' +export * from './serialize-unique.js' +export * from './types.js' diff --git a/packages/file-id/src/parse.ts b/packages/file-id/src/parse.ts index f935df42..8a3bd257 100644 --- a/packages/file-id/src/parse.ts +++ b/packages/file-id/src/parse.ts @@ -1,8 +1,7 @@ -import { parseUrlSafeBase64 } from '@mtcute/core/utils' -import { TlBinaryReader } from '@mtcute/tl-runtime' +import { base64DecodeToBuffer, base64Encode, TlBinaryReader } from '@mtcute/core/utils.js' -import { tdFileId as td } from './types' -import { telegramRleDecode } from './utils' +import { tdFileId as td } from './types.js' +import { telegramRleDecode } from './utils.js' function parseWebFileLocation(reader: TlBinaryReader): td.RawWebRemoteFileLocation { return { @@ -25,14 +24,14 @@ function parsePhotoSizeSource(reader: TlBinaryReader): td.TypePhotoSizeSource { const fileType = reader.int() if (fileType < 0 || fileType >= td.FileType.Size) { - throw new td.UnsupportedError(`Unsupported file type: ${fileType} (${reader.data.toString('base64')})`) + throw new td.UnsupportedError(`Unsupported file type: ${fileType} (${base64Encode(reader.uint8View)})`) } const thumbnailType = reader.int() if (thumbnailType < 0 || thumbnailType > 255) { throw new td.InvalidFileIdError( - `Wrong thumbnail type: ${thumbnailType} (${reader.data.toString('base64')})`, + `Wrong thumbnail type: ${thumbnailType} (${base64Encode(reader.uint8View)})`, ) } @@ -111,7 +110,7 @@ function parsePhotoSizeSource(reader: TlBinaryReader): td.TypePhotoSizeSource { } default: throw new td.UnsupportedError( - `Unsupported photo size source ${variant} (${reader.data.toString('base64')})`, + `Unsupported photo size source ${variant} (${base64Encode(reader.uint8View)})`, ) } } @@ -191,9 +190,9 @@ function parseCommonFileLocation(reader: TlBinaryReader): td.RawCommonRemoteFile } } -function fromPersistentIdV23(binary: Buffer, version: number): td.RawFullRemoteFileLocation { +function fromPersistentIdV23(binary: Uint8Array, version: number): td.RawFullRemoteFileLocation { if (version < 0 || version > td.CURRENT_VERSION) { - throw new td.UnsupportedError(`Unsupported file ID v3 subversion: ${version} (${binary.toString('base64')})`) + throw new td.UnsupportedError(`Unsupported file ID v3 subversion: ${version} (${base64Encode(binary)})`) } binary = telegramRleDecode(binary) @@ -209,12 +208,12 @@ function fromPersistentIdV23(binary: Buffer, version: number): td.RawFullRemoteF fileType &= ~td.FILE_REFERENCE_FLAG if (fileType < 0 || fileType >= td.FileType.Size) { - throw new td.UnsupportedError(`Unsupported file type: ${fileType} (${binary.toString('base64')})`) + throw new td.UnsupportedError(`Unsupported file type: ${fileType} (${base64Encode(binary)})`) } const dcId = reader.int() - let fileReference: Buffer | null = null + let fileReference: Uint8Array | null = null if (hasFileReference) { fileReference = reader.bytes() @@ -288,7 +287,7 @@ function fromPersistentIdV23(binary: Buffer, version: number): td.RawFullRemoteF break } default: - throw new td.UnsupportedError(`Invalid file type: ${fileType} (${binary.toString('base64')})`) + throw new td.UnsupportedError(`Invalid file type: ${fileType} (${base64Encode(binary)})`) } } @@ -301,14 +300,14 @@ function fromPersistentIdV23(binary: Buffer, version: number): td.RawFullRemoteF } } -function fromPersistentIdV2(binary: Buffer) { - return fromPersistentIdV23(binary.slice(0, -1), 0) +function fromPersistentIdV2(binary: Uint8Array) { + return fromPersistentIdV23(binary.subarray(0, -1), 0) } -function fromPersistentIdV3(binary: Buffer) { +function fromPersistentIdV3(binary: Uint8Array) { const subversion = binary[binary.length - 2] - return fromPersistentIdV23(binary.slice(0, -2), subversion) + return fromPersistentIdV23(binary.subarray(0, -2), subversion) } /** @@ -316,8 +315,8 @@ function fromPersistentIdV3(binary: Buffer) { * * @param fileId File ID as a base-64 encoded string or Buffer */ -export function parseFileId(fileId: string | Buffer): td.RawFullRemoteFileLocation { - if (typeof fileId === 'string') fileId = parseUrlSafeBase64(fileId) +export function parseFileId(fileId: string | Uint8Array): td.RawFullRemoteFileLocation { + if (typeof fileId === 'string') fileId = base64DecodeToBuffer(fileId, true) const version = fileId[fileId.length - 1] @@ -329,5 +328,5 @@ export function parseFileId(fileId: string | Buffer): td.RawFullRemoteFileLocati return fromPersistentIdV3(fileId) } - throw new td.UnsupportedError(`Unsupported file ID version: ${version} (${fileId.toString('base64')})`) + throw new td.UnsupportedError(`Unsupported file ID version: ${version} (${base64Encode(fileId)})`) } diff --git a/packages/file-id/src/serialize-unique.ts b/packages/file-id/src/serialize-unique.ts index d4985dd4..e8c727af 100644 --- a/packages/file-id/src/serialize-unique.ts +++ b/packages/file-id/src/serialize-unique.ts @@ -1,9 +1,8 @@ import { assertNever } from '@mtcute/core' -import { encodeUrlSafeBase64 } from '@mtcute/core/utils' -import { TlBinaryWriter } from '@mtcute/tl-runtime' +import { base64Encode, byteLengthUtf8, TlBinaryWriter } from '@mtcute/core/utils.js' -import { tdFileId as td } from './types' -import { telegramRleEncode } from './utils' +import { tdFileId as td } from './types.js' +import { telegramRleEncode } from './utils.js' export type InputUniqueLocation = | Pick @@ -82,7 +81,7 @@ export function toUniqueFileId( switch (source._) { case 'legacy': { // tdlib does not implement this - writer = TlBinaryWriter.manualAlloc(16) + writer = TlBinaryWriter.manual(16) writer.int(type) writer.int(100) writer.long(source.secret) @@ -90,7 +89,7 @@ export function toUniqueFileId( } case 'stickerSetThumbnail': { // tdlib does not implement this - writer = TlBinaryWriter.manualAlloc(24) + writer = TlBinaryWriter.manual(24) writer.int(type) writer.int(150) writer.long(source.id) @@ -98,15 +97,15 @@ export function toUniqueFileId( break } case 'dialogPhoto': { - writer = TlBinaryWriter.manualAlloc(13) + writer = TlBinaryWriter.manual(13) writer.int(type) writer.long(inputLocation.id) - writer.raw(Buffer.from([Number(source.big)])) + writer.raw(new Uint8Array([Number(source.big)])) // it doesn't matter to which Dialog the photo belongs break } case 'thumbnail': { - writer = TlBinaryWriter.manualAlloc(13) + writer = TlBinaryWriter.manual(13) let thumbType = source.thumbnailType.charCodeAt(0) @@ -120,21 +119,21 @@ export function toUniqueFileId( writer.int(type) writer.long(inputLocation.id) - writer.raw(Buffer.from([thumbType])) + writer.raw(new Uint8Array([thumbType])) break } case 'fullLegacy': case 'dialogPhotoLegacy': case 'stickerSetThumbnailLegacy': - writer = TlBinaryWriter.manualAlloc(16) + writer = TlBinaryWriter.manual(16) writer.int(type) writer.long(source.volumeId) writer.int(source.localId) break case 'stickerSetThumbnailVersion': - writer = TlBinaryWriter.manualAlloc(17) + writer = TlBinaryWriter.manual(17) writer.int(type) - writer.raw(Buffer.from([2])) + writer.raw(new Uint8Array([2])) writer.long(source.id) writer.int(source.version) break @@ -142,12 +141,12 @@ export function toUniqueFileId( break } case 'web': - writer = TlBinaryWriter.alloc(undefined, Buffer.byteLength(inputLocation.url, 'utf-8') + 8) + writer = TlBinaryWriter.alloc(undefined, byteLengthUtf8(inputLocation.url) + 8) writer.int(type) writer.string(inputLocation.url) break case 'common': - writer = TlBinaryWriter.manualAlloc(12) + writer = TlBinaryWriter.manual(12) writer.int(type) writer.long(inputLocation.id) break @@ -155,5 +154,5 @@ export function toUniqueFileId( assertNever(inputLocation) } - return encodeUrlSafeBase64(telegramRleEncode(writer.result())) + return base64Encode(telegramRleEncode(writer.result()), true) } diff --git a/packages/file-id/src/serialize.ts b/packages/file-id/src/serialize.ts index 6079cf2f..d3343d0d 100644 --- a/packages/file-id/src/serialize.ts +++ b/packages/file-id/src/serialize.ts @@ -1,11 +1,10 @@ import { assertNever } from '@mtcute/core' -import { encodeUrlSafeBase64 } from '@mtcute/core/utils' -import { TlBinaryWriter } from '@mtcute/tl-runtime' +import { base64Encode, byteLengthUtf8, concatBuffers, TlBinaryWriter } from '@mtcute/core/utils.js' -import { tdFileId as td } from './types' -import { telegramRleEncode } from './utils' +import { tdFileId as td } from './types.js' +import { telegramRleEncode } from './utils.js' -const SUFFIX = Buffer.from([td.CURRENT_VERSION, td.PERSISTENT_ID_VERSION]) +const SUFFIX = new Uint8Array([td.CURRENT_VERSION, td.PERSISTENT_ID_VERSION]) /** * Serialize an object with information about file @@ -27,7 +26,7 @@ export function toFileId(location: Omit): str // // longest file ids are around 80 bytes, so i guess // we are safe with allocating 100 bytes - const writer = TlBinaryWriter.alloc(undefined, loc._ === 'web' ? Buffer.byteLength(loc.url, 'utf8') + 32 : 100) + const writer = TlBinaryWriter.alloc(undefined, loc._ === 'web' ? byteLengthUtf8(loc.url) + 32 : 100) writer.int(type) writer.int(location.dcId) @@ -105,5 +104,5 @@ export function toFileId(location: Omit): str assertNever(loc) } - return encodeUrlSafeBase64(Buffer.concat([telegramRleEncode(writer.result()), SUFFIX])) + return base64Encode(concatBuffers([telegramRleEncode(writer.result()), SUFFIX]), true) } diff --git a/packages/file-id/src/types.ts b/packages/file-id/src/types.ts index 6716e813..b4e31521 100644 --- a/packages/file-id/src/types.ts +++ b/packages/file-id/src/types.ts @@ -224,7 +224,7 @@ export namespace tdFileId { /** * File reference (if any) */ - readonly fileReference: Buffer | null + readonly fileReference: Uint8Array | null /** * Context of the file location */ diff --git a/packages/file-id/src/utils.ts b/packages/file-id/src/utils.ts index a0aa5dbd..1cc6def2 100644 --- a/packages/file-id/src/utils.ts +++ b/packages/file-id/src/utils.ts @@ -1,6 +1,6 @@ -// telegram has some cursed RLE which only encodes consecutive \x00 +// tdlib's RLE only encodes consecutive \x00 -export function telegramRleEncode(buf: Buffer): Buffer { +export function telegramRleEncode(buf: Uint8Array): Uint8Array { const len = buf.length const ret: number[] = [] let count = 0 @@ -24,10 +24,10 @@ export function telegramRleEncode(buf: Buffer): Buffer { ret.push(0, count) } - return Buffer.from(ret) + return new Uint8Array(ret) } -export function telegramRleDecode(buf: Buffer): Buffer { +export function telegramRleDecode(buf: Uint8Array): Uint8Array { const len = buf.length const ret: number[] = [] let prev = -1 @@ -48,5 +48,5 @@ export function telegramRleDecode(buf: Buffer): Buffer { if (prev !== -1) ret.push(prev) - return Buffer.from(ret) + return new Uint8Array(ret) } diff --git a/packages/file-id/tests/parse.spec.ts b/packages/file-id/tests/parse.spec.ts index 2f0c7036..1f2a5bd7 100644 --- a/packages/file-id/tests/parse.spec.ts +++ b/packages/file-id/tests/parse.spec.ts @@ -2,9 +2,10 @@ import { expect } from 'chai' import { describe, it } from 'mocha' import { Long } from '@mtcute/core' +import { hexDecodeToBuffer } from '@mtcute/core/utils.js' -import { parseFileId } from '../src' -import { tdFileId as td } from '../src/types' +import { parseFileId } from '../src/index.js' +import { tdFileId as td } from '../src/types.js' // test file IDs are partially taken from https://github.com/luckydonald/telegram_file_id @@ -17,7 +18,7 @@ describe('parsing file ids', () => { test('CAACAgIAAxkBAAEJny9gituz1_V_uSKBUuG_nhtzEtFOeQACXFoAAuCjggfYjw_KAAGSnkgfBA', { _: 'remoteFileLocation', dcId: 2, - fileReference: Buffer.from('0100099f2f608adbb3d7f57fb9228152e1bf9e1b7312d14e79', 'hex'), + fileReference: hexDecodeToBuffer('0100099f2f608adbb3d7f57fb9228152e1bf9e1b7312d14e79'), location: { _: 'common', accessHash: Long.fromString('5232780349138767832'), @@ -28,7 +29,7 @@ describe('parsing file ids', () => { test('BQACAgIAAxkBAAEJnzNgit00IDsKd07OdSeanwz8osecYAACdAwAAueoWEicaPvNdOYEwB8E', { _: 'remoteFileLocation', dcId: 2, - fileReference: Buffer.from('0100099f33608add34203b0a774ece75279a9f0cfca2c79c60', 'hex'), + fileReference: hexDecodeToBuffer('0100099f33608add34203b0a774ece75279a9f0cfca2c79c60'), location: { _: 'common', accessHash: Long.fromString('-4610306729174144868'), @@ -42,7 +43,7 @@ describe('parsing file ids', () => { test('AAMCAgADGQEAAQmfL2CK27PX9X-5IoFS4b-eG3MS0U55AAJcWgAC4KOCB9iPD8oAAZKeSK1c8w4ABAEAB20AA1kCAAIfBA', { _: 'remoteFileLocation', dcId: 2, - fileReference: Buffer.from('0100099f2f608adbb3d7f57fb9228152e1bf9e1b7312d14e79', 'hex'), + fileReference: hexDecodeToBuffer('0100099f2f608adbb3d7f57fb9228152e1bf9e1b7312d14e79'), location: { _: 'photo', accessHash: Long.fromString('5232780349138767832'), diff --git a/packages/file-id/tests/serialize-unique.spec.ts b/packages/file-id/tests/serialize-unique.spec.ts index 45a7dac3..000ff72a 100644 --- a/packages/file-id/tests/serialize-unique.spec.ts +++ b/packages/file-id/tests/serialize-unique.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { describe } from 'mocha' -import { parseFileId, toUniqueFileId } from '../src' +import { parseFileId, toUniqueFileId } from '../src/index.js' // test file IDs are partially taken from https://github.com/luckydonald/telegram_file_id diff --git a/packages/file-id/tests/tsconfig.json b/packages/file-id/tests/tsconfig.json new file mode 100644 index 00000000..cfa0657b --- /dev/null +++ b/packages/file-id/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + ".", + ], + "references": [ + { "path": "../" }, + ] +} diff --git a/packages/file-id/tests/utils.spec.ts b/packages/file-id/tests/utils.spec.ts index 3056a16c..aa0ac1c3 100644 --- a/packages/file-id/tests/utils.spec.ts +++ b/packages/file-id/tests/utils.spec.ts @@ -1,31 +1,33 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { telegramRleDecode, telegramRleEncode } from '../src/utils' +import { hexDecodeToBuffer, hexEncode } from '@mtcute/core/utils.js' + +import { telegramRleDecode, telegramRleEncode } from '../src/utils.js' describe('telegramRleEncode', () => { it('should not modify input if there are no \\x00', () => { - expect(telegramRleEncode(Buffer.from('aaeeff', 'hex')).toString('hex')).eq('aaeeff') + expect(hexEncode(telegramRleEncode(hexDecodeToBuffer('aaeeff')))).eq('aaeeff') }) it('should collapse consecutive \\x00', () => { - expect(telegramRleEncode(Buffer.from('00000000aa', 'hex')).toString('hex')).eq('0004aa') - expect(telegramRleEncode(Buffer.from('00000000aa000000aa', 'hex')).toString('hex')).eq('0004aa0003aa') - expect(telegramRleEncode(Buffer.from('00000000aa0000', 'hex')).toString('hex')).eq('0004aa0002') - expect(telegramRleEncode(Buffer.from('00aa00', 'hex')).toString('hex')).eq('0001aa0001') + expect(hexEncode(telegramRleEncode(hexDecodeToBuffer('00000000aa')))).eq('0004aa') + expect(hexEncode(telegramRleEncode(hexDecodeToBuffer('00000000aa000000aa')))).eq('0004aa0003aa') + expect(hexEncode(telegramRleEncode(hexDecodeToBuffer('00000000aa0000')))).eq('0004aa0002') + expect(hexEncode(telegramRleEncode(hexDecodeToBuffer('00aa00')))).eq('0001aa0001') }) }) describe('telegramRleDecode', () => { it('should not mofify input if there are no \\x00', () => { - expect(telegramRleDecode(Buffer.from('aaeeff', 'hex')).toString('hex')).eq('aaeeff') + expect(hexEncode(telegramRleDecode(hexDecodeToBuffer('aaeeff')))).eq('aaeeff') }) it('should expand two-byte sequences starting with \\x00', () => { - expect(telegramRleDecode(Buffer.from('0004aa', 'hex')).toString('hex')).eq('00000000aa') - expect(telegramRleDecode(Buffer.from('0004aa0000', 'hex')).toString('hex')).eq('00000000aa') - expect(telegramRleDecode(Buffer.from('0004aa0003aa', 'hex')).toString('hex')).eq('00000000aa000000aa') - expect(telegramRleDecode(Buffer.from('0004aa0002', 'hex')).toString('hex')).eq('00000000aa0000') - expect(telegramRleDecode(Buffer.from('0001aa0001', 'hex')).toString('hex')).eq('00aa00') + expect(hexEncode(telegramRleDecode(hexDecodeToBuffer('0004aa')))).eq('00000000aa') + expect(hexEncode(telegramRleDecode(hexDecodeToBuffer('0004aa0000')))).eq('00000000aa') + expect(hexEncode(telegramRleDecode(hexDecodeToBuffer('0004aa0003aa')))).eq('00000000aa000000aa') + expect(hexEncode(telegramRleDecode(hexDecodeToBuffer('0004aa0002')))).eq('00000000aa0000') + expect(hexEncode(telegramRleDecode(hexDecodeToBuffer('0001aa0001')))).eq('00aa00') }) }) diff --git a/packages/file-id/tsconfig.json b/packages/file-id/tsconfig.json index 7cd839c6..798d46cb 100644 --- a/packages/file-id/tsconfig.json +++ b/packages/file-id/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src", }, "include": [ "./src", - "./tests", - ] + ], + "references": [ + { "path": "../core" }, + ], } diff --git a/packages/html-parser/package.json b/packages/html-parser/package.json index 8ac515e2..d8571fd3 100644 --- a/packages/html-parser/package.json +++ b/packages/html-parser/package.json @@ -6,12 +6,21 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "src/index.ts", + "type": "module", "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "coverage": "nyc npm run test", - "build": "tsc", + "build": "pnpm run -w build-package html-parser", "docs": "typedoc" }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } + }, "dependencies": { "@mtcute/tl": "workspace:^165.0.0", "htmlparser2": "^6.0.1", diff --git a/packages/html-parser/tests/html-parser.spec.ts b/packages/html-parser/tests/html-parser.spec.ts index 5e477dfc..98d56132 100644 --- a/packages/html-parser/tests/html-parser.spec.ts +++ b/packages/html-parser/tests/html-parser.spec.ts @@ -4,7 +4,7 @@ import { describe, it } from 'mocha' import { FormattedString, tl } from '@mtcute/client' -import { html, HtmlMessageEntityParser } from '../src' +import { html, HtmlMessageEntityParser } from '../src/index.js' const createEntity = ( type: T, diff --git a/packages/html-parser/tests/tsconfig.json b/packages/html-parser/tests/tsconfig.json new file mode 100644 index 00000000..cfa0657b --- /dev/null +++ b/packages/html-parser/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + ".", + ], + "references": [ + { "path": "../" }, + ] +} diff --git a/packages/html-parser/tsconfig.json b/packages/html-parser/tsconfig.json index 7cd839c6..554df3b9 100644 --- a/packages/html-parser/tsconfig.json +++ b/packages/html-parser/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src" }, "include": [ "./src", - "./tests", + ], + "references": [ + { "path": "../client" } ] } diff --git a/packages/http-proxy/index.ts b/packages/http-proxy/index.ts index e7bc45d9..67f8a541 100644 --- a/packages/http-proxy/index.ts +++ b/packages/http-proxy/index.ts @@ -4,6 +4,7 @@ import { connect as connectTcp } from 'net' import { connect as connectTls, SecureContextOptions } from 'tls' import { BaseTcpTransport, IntermediatePacketCodec, MtcuteError, tl, TransportState } from '@mtcute/core' +import { base64Encode, utf8EncodeToBuffer } from '@mtcute/core/utils.js' /** * An error has occurred while connecting to an HTTP(s) proxy @@ -110,7 +111,7 @@ export abstract class BaseHttpProxyTcpTransport extends BaseTcpTransport { if (this._proxy.password) { auth += ':' + this._proxy.password } - headers['Proxy-Authorization'] = 'Basic ' + Buffer.from(auth).toString('base64') + headers['Proxy-Authorization'] = 'Basic ' + base64Encode(utf8EncodeToBuffer(auth)) } headers['Proxy-Connection'] = 'Keep-Alive' diff --git a/packages/http-proxy/package.json b/packages/http-proxy/package.json index 15663e57..95029af3 100644 --- a/packages/http-proxy/package.json +++ b/packages/http-proxy/package.json @@ -6,9 +6,18 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "index.ts", + "type": "module", "scripts": { "docs": "typedoc", - "build": "tsc" + "build": "pnpm run -w build-package http-proxy" + }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } }, "dependencies": { "@mtcute/core": "workspace:^1.0.0" diff --git a/packages/http-proxy/tsconfig.json b/packages/http-proxy/tsconfig.json index ef79725a..1793937a 100644 --- a/packages/http-proxy/tsconfig.json +++ b/packages/http-proxy/tsconfig.json @@ -1,9 +1,12 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm" }, "include": [ "./index.ts", + ], + "references": [ + { "path": "../core" } ] } diff --git a/packages/i18n/package.json b/packages/i18n/package.json index bac903f3..99f47b55 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -6,13 +6,23 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "src/index.ts", + "type": "module", "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "coverage": "nyc npm run test", - "build": "tsc", + "build": "pnpm run -w build-package i18n", "docs": "typedoc" }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } + }, "devDependencies": { - "@mtcute/client": "workspace:^1.0.0" + "@mtcute/client": "workspace:^1.0.0", + "@mtcute/dispatcher": "workspace:^1.0.0" } } diff --git a/packages/i18n/src/index.ts b/packages/i18n/src/index.ts index b8ee241f..a11dc94d 100644 --- a/packages/i18n/src/index.ts +++ b/packages/i18n/src/index.ts @@ -1,8 +1,8 @@ -import { I18nStrings, I18nValue, MtcuteI18nAdapter, MtcuteI18nFunction, OtherLanguageWrap } from './types' -import { createI18nStringsIndex, extractLanguageFromUpdate } from './utils' +import { I18nStrings, I18nValue, MtcuteI18nAdapter, MtcuteI18nFunction, OtherLanguageWrap } from './types.js' +import { createI18nStringsIndex, extractLanguageFromUpdate } from './utils.js' -export * from './types' -export { extractLanguageFromUpdate } from './utils' +export * from './types.js' +export { extractLanguageFromUpdate } from './utils.js' export interface MtcuteI18nParameters { /** diff --git a/packages/i18n/src/plurals/english.ts b/packages/i18n/src/plurals/english.ts index e2796ee3..42cc5b0c 100644 --- a/packages/i18n/src/plurals/english.ts +++ b/packages/i18n/src/plurals/english.ts @@ -1,4 +1,4 @@ -import { I18nValue, I18nValueDynamic } from '../types' +import { I18nValue, I18nValueDynamic } from '../types.js' /** * Get an English ordinal suffix (st/nd/rd/th) for a given number. diff --git a/packages/i18n/src/plurals/russian.ts b/packages/i18n/src/plurals/russian.ts index ed83c828..3a691a20 100644 --- a/packages/i18n/src/plurals/russian.ts +++ b/packages/i18n/src/plurals/russian.ts @@ -1,4 +1,4 @@ -import { I18nValue, I18nValueDynamic } from '../types' +import { I18nValue, I18nValueDynamic } from '../types.js' /** * Pluralize a value by Russian rules diff --git a/packages/i18n/src/utils.ts b/packages/i18n/src/utils.ts index 6b596542..7ad92400 100644 --- a/packages/i18n/src/utils.ts +++ b/packages/i18n/src/utils.ts @@ -1,12 +1,6 @@ -import type * as clientNs from '@mtcute/client' +import type * as dispatcherNs from '@mtcute/dispatcher' -import { I18nStrings, I18nValue } from './types' - -let client: typeof clientNs - -try { - client = require('@mtcute/client') as typeof clientNs -} catch (e) {} +import { I18nStrings, I18nValue } from './types.js' /** * Create an index of i18n strings delimited by "." @@ -34,39 +28,36 @@ export function createI18nStringsIndex(strings: I18nStrings): Record { const en = { @@ -83,12 +84,12 @@ describe('i18n', () => { }) it('should parse language from a message', () => { - const message = new Message( + const message = new MessageContext(null as never, new Message( { _: 'message', peerId: { _: 'peerUser', userId: 1 } } as never, PeersIndex.from({ users: [{ _: 'user', id: 1, firstName: 'Пыня', langCode: 'ru' }], }), - ) + )) expect(tr(message, 'direct')).to.equal('Привет') }) diff --git a/packages/i18n/tests/tsconfig.json b/packages/i18n/tests/tsconfig.json new file mode 100644 index 00000000..cfa0657b --- /dev/null +++ b/packages/i18n/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + ".", + ], + "references": [ + { "path": "../" }, + ] +} diff --git a/packages/i18n/tsconfig.json b/packages/i18n/tsconfig.json index 7cd839c6..870bc27b 100644 --- a/packages/i18n/tsconfig.json +++ b/packages/i18n/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src" }, "include": [ "./src", - "./tests", + ], + "references": [ + { "path": "../dispatcher" }, ] } diff --git a/packages/markdown-parser/package.json b/packages/markdown-parser/package.json index 80cd72cf..5e842847 100644 --- a/packages/markdown-parser/package.json +++ b/packages/markdown-parser/package.json @@ -6,12 +6,21 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "src/index.ts", + "type": "module", "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "coverage": "nyc npm run test", - "build": "tsc", + "build": "pnpm run -w build-package markdown-parser", "docs": "typedoc" }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } + }, "dependencies": { "@mtcute/tl": "workspace:^165.0.0", "long": "5.2.3" diff --git a/packages/markdown-parser/tests/markdown-parser.spec.ts b/packages/markdown-parser/tests/markdown-parser.spec.ts index eddc9dea..c3ddd5e8 100644 --- a/packages/markdown-parser/tests/markdown-parser.spec.ts +++ b/packages/markdown-parser/tests/markdown-parser.spec.ts @@ -4,7 +4,7 @@ import { describe, it } from 'mocha' import { FormattedString, tl } from '@mtcute/client' -import { MarkdownMessageEntityParser, md } from '../src' +import { MarkdownMessageEntityParser, md } from '../src/index.js' const createEntity = ( type: T, @@ -553,8 +553,7 @@ describe('MarkdownMessageEntityParser', () => { const unsafeString2 = new FormattedString('<&>', 'some-other-mode') expect(() => md`${unsafeString}`.value).not.throw(Error) - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error + // @ts-expect-error this is intentional expect(() => md`${unsafeString2}`.value).throw(Error) }) }) diff --git a/packages/markdown-parser/tests/tsconfig.json b/packages/markdown-parser/tests/tsconfig.json new file mode 100644 index 00000000..cfa0657b --- /dev/null +++ b/packages/markdown-parser/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + ".", + ], + "references": [ + { "path": "../" }, + ] +} diff --git a/packages/markdown-parser/tsconfig.json b/packages/markdown-parser/tsconfig.json index 7cd839c6..554df3b9 100644 --- a/packages/markdown-parser/tsconfig.json +++ b/packages/markdown-parser/tsconfig.json @@ -1,10 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src" }, "include": [ "./src", - "./tests", + ], + "references": [ + { "path": "../client" } ] } diff --git a/packages/mtproxy/fake-tls.ts b/packages/mtproxy/fake-tls.ts index ba787dfd..10e43a4d 100644 --- a/packages/mtproxy/fake-tls.ts +++ b/packages/mtproxy/fake-tls.ts @@ -1,7 +1,9 @@ +/* eslint-disable no-restricted-globals */ +// todo fixme import bigInt, { BigInteger } from 'big-integer' import { IPacketCodec, WrappedCodec } from '@mtcute/core' -import { bigIntToBuffer, bufferToBigInt, ICryptoProvider, randomBytes } from '@mtcute/core/utils' +import { bigIntToBuffer, bufferToBigInt, ICryptoProvider, randomBytes } from '@mtcute/core/utils.js' const MAX_TLS_PACKET_LENGTH = 2878 const TLS_FIRST_PREFIX = Buffer.from('140303000101', 'hex') @@ -158,7 +160,7 @@ function initGrease(size: number): Buffer { } } - return buf + return Buffer.from(buf) } class TlsHelloWriter implements TlsOperationHandler { @@ -180,7 +182,7 @@ class TlsHelloWriter implements TlsOperationHandler { } random(size: number) { - this.string(randomBytes(size)) + this.string(Buffer.from(randomBytes(size))) } zero(size: number) { @@ -210,7 +212,7 @@ class TlsHelloWriter implements TlsOperationHandler { } const key = bigIntToBuffer(x, 32, true) - this.string(key) + this.string(Buffer.from(key)) return } @@ -243,7 +245,7 @@ class TlsHelloWriter implements TlsOperationHandler { this.zero(padSize) this.endScope() - const hash = await crypto.hmacSha256(this.buf, secret) + const hash = Buffer.from(await crypto.hmacSha256(this.buf, secret)) const old = hash.readInt32LE(28) hash.writeInt32LE(old ^ unixTime, 28) @@ -277,7 +279,7 @@ export class FakeTlsPacketCodec extends WrappedCodec implements IPacketCodec { private _isFirstTls = true async tag(): Promise { - this._header = await this._inner.tag() + this._header = Buffer.from(await this._inner.tag()) return Buffer.alloc(0) } @@ -301,7 +303,7 @@ export class FakeTlsPacketCodec extends WrappedCodec implements IPacketCodec { } async encode(packet: Buffer): Promise { - packet = await this._inner.encode(packet) + packet = Buffer.from(await this._inner.encode(packet)) if (packet.length + this._header.length > MAX_TLS_PACKET_LENGTH) { const ret: Buffer[] = [] diff --git a/packages/mtproxy/index.ts b/packages/mtproxy/index.ts index de3551c0..3e702236 100644 --- a/packages/mtproxy/index.ts +++ b/packages/mtproxy/index.ts @@ -1,4 +1,5 @@ -// ^^ because of this._socket. we know it's not null, almost everywhere, but TS doesn't +/* eslint-disable no-restricted-globals */ +// todo fixme import { connect } from 'net' @@ -14,9 +15,9 @@ import { tl, TransportState, } from '@mtcute/core' -import { parseUrlSafeBase64 } from '@mtcute/core/utils' +import { buffersEqual } from '@mtcute/core/dist/esm/utils/index.js' -import { FakeTlsPacketCodec, generateFakeTlsHeader } from './fake-tls' +import { FakeTlsPacketCodec, generateFakeTlsHeader } from './fake-tls.js' /** * MTProto proxy settings @@ -67,7 +68,7 @@ export class MtProxyTcpTransport extends BaseTcpTransport { } else if (proxy.secret.match(/^[0-9a-f]+$/i)) { secret = Buffer.from(proxy.secret, 'hex') } else { - secret = parseUrlSafeBase64(proxy.secret) + secret = Buffer.from(proxy.secret, 'base64url') } if (secret.length > 17 + MAX_DOMAIN_LENGTH) { @@ -174,16 +175,22 @@ export class MtProxyTcpTransport extends BaseTcpTransport { const hello = await generateFakeTlsHeader(this._fakeTlsDomain!, this._rawSecret, this._crypto) const helloRand = hello.slice(11, 11 + 32) - const checkHelloResponse = async (buf: Buffer): Promise => { + let serverHelloBuffer: Buffer | null = null + + const checkHelloResponse = async (buf: Buffer): Promise => { + if (serverHelloBuffer) { + buf = Buffer.concat([serverHelloBuffer, buf]) + } + const resp = buf for (const first of TLS_START) { if (buf.length < first.length + 2) { - return + throw new MtSecurityError('Server hello is too short') } - if (first.compare(first, 0, first.length) !== 0) { - throw new MtSecurityError('First part of hello response is invalid') + if (!buffersEqual(buf.slice(0, first.length), first)) { + throw new MtSecurityError('Server hello is invalid') } buf = buf.slice(first.length) @@ -191,7 +198,14 @@ export class MtProxyTcpTransport extends BaseTcpTransport { buf = buf.slice(2) if (buf.length < skipSize) { - return + // likely got split into multiple packets + if (serverHelloBuffer) { + throw new MtSecurityError('Server hello is too short') + } + + serverHelloBuffer = resp + + return false } buf = buf.slice(skipSize) @@ -203,16 +217,22 @@ export class MtProxyTcpTransport extends BaseTcpTransport { this._rawSecret, ) - if (hash.compare(respRand) !== 0) { + if (!buffersEqual(hash, respRand)) { throw new MtSecurityError('Response hash is invalid') } + + return true } const packetHandler = (buf: Buffer): void => { checkHelloResponse(buf) - .then(() => { + .then((done) => { + if (!done) return + this._socket!.off('data', packetHandler) - this._socket!.on('data', (data) => this._packetCodec.feed(data)) + this._socket!.on('data', (data) => { + this._packetCodec.feed(data) + }) return this.handleConnect() }) diff --git a/packages/mtproxy/package.json b/packages/mtproxy/package.json index aafccd39..bf4f482e 100644 --- a/packages/mtproxy/package.json +++ b/packages/mtproxy/package.json @@ -6,9 +6,18 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "index.ts", + "type": "module", "scripts": { "docs": "typedoc", - "build": "tsc" + "build": "pnpm run -w build-package mtproxy" + }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } }, "dependencies": { "@mtcute/core": "workspace:^1.0.0", diff --git a/packages/mtproxy/tsconfig.json b/packages/mtproxy/tsconfig.json index ef79725a..a975a7d0 100644 --- a/packages/mtproxy/tsconfig.json +++ b/packages/mtproxy/tsconfig.json @@ -1,9 +1,13 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", }, "include": [ "./index.ts", + "./fake-tls.ts", + ], + "references": [ + { "path": "../core" } ] } diff --git a/packages/node/index.ts b/packages/node/index.ts index b26cc87c..b21de908 100644 --- a/packages/node/index.ts +++ b/packages/node/index.ts @@ -1,7 +1,7 @@ +import { createRequire } from 'module' import { createInterface, Interface as RlInterface } from 'readline' -import { TelegramClient, User } from '@mtcute/client' -import { BaseTelegramClientOptions } from '@mtcute/core' +import { TelegramClient, TelegramClientOptions, User } from '@mtcute/client' import { HtmlMessageEntityParser } from '@mtcute/html-parser' import { MarkdownMessageEntityParser } from '@mtcute/markdown-parser' import { SqliteStorage } from '@mtcute/sqlite' @@ -16,11 +16,14 @@ export { SqliteStorage } let nativeCrypto: any try { + // @only-if-esm + const require = createRequire(import.meta.url) + // @/only-if-esm // eslint-disable-next-line nativeCrypto = require('@mtcute/crypto-node').NodeNativeCryptoProvider } catch (e) {} -export interface NodeTelegramClientOptions extends Omit { +export interface NodeTelegramClientOptions extends Omit { /** * Default parse mode to use. * @@ -40,7 +43,7 @@ export interface NodeTelegramClientOptions extends Omit", "license": "MIT", "main": "index.ts", + "type": "module", "scripts": { "docs": "typedoc", - "build": "tsc" + "build": "pnpm run -w build-package node" + }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } }, "dependencies": { - "@mtcute/core": "workspace:^1.0.0", "@mtcute/client": "workspace:^1.0.0", "@mtcute/sqlite": "workspace:^1.0.0", "@mtcute/markdown-parser": "workspace:^1.0.0", diff --git a/packages/node/tsconfig.json b/packages/node/tsconfig.json index e1330eba..29f8029f 100644 --- a/packages/node/tsconfig.json +++ b/packages/node/tsconfig.json @@ -1,9 +1,16 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm" }, "include": [ "./index.ts" + ], + "references": [ + { "path": "../client" }, + { "path": "../sqlite" }, + { "path": "../dispatcher" }, + { "path": "../html-parser" }, + { "path": "../markdown-parser" } ] } diff --git a/packages/socks-proxy/index.ts b/packages/socks-proxy/index.ts index 2175b0b4..d55836b8 100644 --- a/packages/socks-proxy/index.ts +++ b/packages/socks-proxy/index.ts @@ -13,6 +13,7 @@ import { tl, TransportState, } from '@mtcute/core' +import { dataViewFromBuffer, utf8EncodeToBuffer } from '@mtcute/core/utils.js' /** * An error has occurred while connecting to an SOCKS proxy @@ -58,7 +59,7 @@ export interface SocksProxySettings { version?: 4 | 5 } -function writeIpv4(ip: string, buf: Buffer, offset: number): void { +function writeIpv4(ip: string, buf: Uint8Array, offset: number): void { const parts = ip.split('.') if (parts.length !== 4) { @@ -75,22 +76,22 @@ function writeIpv4(ip: string, buf: Buffer, offset: number): void { } } -function buildSocks4ConnectRequest(ip: string, port: number, username = ''): Buffer { - const userId = Buffer.from(username) - const buf = Buffer.alloc(9 + userId.length) +function buildSocks4ConnectRequest(ip: string, port: number, username = ''): Uint8Array { + const userId = utf8EncodeToBuffer(username) + const buf = new Uint8Array(9 + userId.length) buf[0] = 0x04 // VER buf[1] = 0x01 // CMD = establish a TCP/IP stream connection - buf.writeUInt16BE(port, 2) // DSTPORT + dataViewFromBuffer(buf).setUint16(2, port, false) writeIpv4(ip, buf, 4) // DSTIP - userId.copy(buf, 8) // ID + buf.set(userId, 8) buf[8 + userId.length] = 0x00 // ID (null-termination) return buf } -function buildSocks5Greeting(authAvailable: boolean): Buffer { - const buf = Buffer.alloc(authAvailable ? 4 : 3) +function buildSocks5Greeting(authAvailable: boolean): Uint8Array { + const buf = new Uint8Array(authAvailable ? 4 : 3) buf[0] = 0x05 // VER @@ -107,8 +108,8 @@ function buildSocks5Greeting(authAvailable: boolean): Buffer { } function buildSocks5Auth(username: string, password: string) { - const usernameBuf = Buffer.from(username) - const passwordBuf = Buffer.from(password) + const usernameBuf = utf8EncodeToBuffer(username) + const passwordBuf = utf8EncodeToBuffer(password) if (usernameBuf.length > 255) { throw new MtArgumentError(`Too long username (${usernameBuf.length} > 255)`) @@ -117,17 +118,17 @@ function buildSocks5Auth(username: string, password: string) { throw new MtArgumentError(`Too long password (${passwordBuf.length} > 255)`) } - const buf = Buffer.alloc(3 + usernameBuf.length + passwordBuf.length) + const buf = new Uint8Array(3 + usernameBuf.length + passwordBuf.length) buf[0] = 0x01 // VER of auth buf[1] = usernameBuf.length - usernameBuf.copy(buf, 2) + buf.set(usernameBuf, 2) buf[2 + usernameBuf.length] = passwordBuf.length - passwordBuf.copy(buf, 3 + usernameBuf.length) + buf.set(passwordBuf, 3 + usernameBuf.length) return buf } -function writeIpv6(ip: string, buf: Buffer, offset: number): void { +function writeIpv6(ip: string, buf: Uint8Array, offset: number): void { // eslint-disable-next-line @typescript-eslint/no-unsafe-call ip = normalize(ip) as string const parts = ip.split(':') @@ -136,6 +137,8 @@ function writeIpv6(ip: string, buf: Buffer, offset: number): void { throw new MtArgumentError('Invalid IPv6 address') } + const dv = dataViewFromBuffer(buf) + for (let i = 0, j = offset; i < 8; i++, j += 2) { const n = parseInt(parts[i]) @@ -143,12 +146,13 @@ function writeIpv6(ip: string, buf: Buffer, offset: number): void { throw new MtArgumentError('Invalid IPv6 address') } - buf.writeUInt16BE(n, j) + dv.setUint16(j, n, false) } } -function buildSocks5Connect(ip: string, port: number, ipv6 = false): Buffer { - const buf = Buffer.alloc(ipv6 ? 22 : 10) +function buildSocks5Connect(ip: string, port: number, ipv6 = false): Uint8Array { + const buf = new Uint8Array(ipv6 ? 22 : 10) + const dv = dataViewFromBuffer(buf) buf[0] = 0x05 // VER buf[1] = 0x01 // CMD = establish a TCP/IP stream connection @@ -157,11 +161,11 @@ function buildSocks5Connect(ip: string, port: number, ipv6 = false): Buffer { if (ipv6) { buf[3] = 0x04 // TYPE = IPv6 writeIpv6(ip, buf, 4) // ADDR - buf.writeUInt16BE(port, 20) // DSTPORT + dv.setUint16(20, port, false) } else { buf[3] = 0x01 // TYPE = IPv4 writeIpv4(ip, buf, 4) // ADDR - buf.writeUInt16BE(port, 8) // DSTPORT + dv.setUint16(8, port, false) } return buf @@ -225,7 +229,7 @@ export abstract class BaseSocksTcpTransport extends BaseTcpTransport { } private _onProxyConnected() { - let packetHandler: (msg: Buffer) => void + let packetHandler: (msg: Uint8Array) => void if (this._proxy.version === 4) { packetHandler = (msg) => { diff --git a/packages/socks-proxy/package.json b/packages/socks-proxy/package.json index be4dae0a..e31b0941 100644 --- a/packages/socks-proxy/package.json +++ b/packages/socks-proxy/package.json @@ -6,9 +6,19 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "index.ts", + "type": "module", "scripts": { "docs": "typedoc", - "build": "tsc" + "build": "pnpm run -w build-package socks-proxy" + }, + + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } }, "dependencies": { "@mtcute/core": "workspace:^1.0.0", diff --git a/packages/socks-proxy/tsconfig.json b/packages/socks-proxy/tsconfig.json index ef79725a..4aac0c93 100644 --- a/packages/socks-proxy/tsconfig.json +++ b/packages/socks-proxy/tsconfig.json @@ -1,9 +1,14 @@ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "./dist" - }, - "include": [ - "./index.ts", - ] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist/esm" + }, + "include": [ + "./index.ts" + ], + "references": [ + { + "path": "../core" + } + ] } diff --git a/packages/sqlite/index.ts b/packages/sqlite/index.ts index ee9f1e9a..656ca90b 100644 --- a/packages/sqlite/index.ts +++ b/packages/sqlite/index.ts @@ -2,17 +2,18 @@ import sqlite3, { Options } from 'better-sqlite3' +import { ITelegramStorage, tl, toggleChannelIdMark } from '@mtcute/core' import { - ITelegramStorage, - tl, + Logger, + longFromFastString, + longToFastString, + LruMap, + throttle, TlBinaryReader, TlBinaryWriter, TlReaderMap, TlWriterMap, - toggleChannelIdMark, -} from '@mtcute/core' -import { Logger, longFromFastString, longToFastString, LruMap, throttle } from '@mtcute/core/utils' -import { IStateStorage } from '@mtcute/dispatcher' +} from '@mtcute/core/utils.js' // todo: add testMode to "self" @@ -111,7 +112,7 @@ interface SqliteEntity { username?: string phone?: string updated: number - full: Buffer + full: Uint8Array } interface CacheItem { @@ -155,14 +156,14 @@ const STATEMENTS = { delStaleState: 'delete from state where expires < ?', } as const -const EMPTY_BUFFER = Buffer.alloc(0) +const EMPTY_BUFFER = new Uint8Array(0) /** * SQLite backed storage for mtcute. * * Uses `better-sqlite3` library */ -export class SqliteStorage implements ITelegramStorage, IStateStorage { +export class SqliteStorage implements ITelegramStorage /*, IStateStorage*/ { private _db!: sqlite3.Database private _statements!: Record private readonly _filename: string @@ -318,10 +319,8 @@ export class SqliteStorage implements ITelegramStorage, IStateStorage { this._reader = new TlBinaryReader(readerMap, EMPTY_BUFFER) } - private _readFullPeer(data: Buffer): tl.TypeUser | tl.TypeChat | null { - // reuse reader because why not - this._reader.pos = 0 - this._reader.data = data + private _readFullPeer(data: Uint8Array): tl.TypeUser | tl.TypeChat | null { + this._reader = new TlBinaryReader(this.readerMap, data) let obj try { @@ -331,8 +330,6 @@ export class SqliteStorage implements ITelegramStorage, IStateStorage { // it should be ignored (i guess?????) obj = null } - // remove reference to allow GC-ing - this._reader.data = EMPTY_BUFFER return obj as tl.TypeUser | tl.TypeChat | null } @@ -490,7 +487,7 @@ export class SqliteStorage implements ITelegramStorage, IStateStorage { return this._getFromKv('def_dc') } - getAuthKeyFor(dcId: number, tempIndex?: number): Buffer | null { + getAuthKeyFor(dcId: number, tempIndex?: number): Uint8Array | null { let row if (tempIndex !== undefined) { @@ -499,17 +496,17 @@ export class SqliteStorage implements ITelegramStorage, IStateStorage { row = this._statements.getAuth.get(dcId) } - return row ? (row as { key: Buffer }).key : null + return row ? (row as { key: Uint8Array }).key : null } - setAuthKeyFor(dcId: number, key: Buffer | null): void { + setAuthKeyFor(dcId: number, key: Uint8Array | null): void { this._pending.push([ key === null ? this._statements.delAuth : this._statements.setAuth, key === null ? [dcId] : [dcId, key], ]) } - setTempAuthKeyFor(dcId: number, index: number, key: Buffer | null, expires: number): void { + setTempAuthKeyFor(dcId: number, index: number, key: Uint8Array | null, expires: number): void { this._pending.push([ key === null ? this._statements.delAuthTemp : this._statements.setAuthTemp, key === null ? [dcId, index] : [dcId, index, key, expires], diff --git a/packages/sqlite/package.json b/packages/sqlite/package.json index 534551f3..586215c8 100644 --- a/packages/sqlite/package.json +++ b/packages/sqlite/package.json @@ -6,9 +6,18 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "index.ts", + "type": "module", + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } + }, "scripts": { "docs": "typedoc", - "build": "tsc" + "build": "pnpm run -w build-package sqlite" }, "dependencies": { "@mtcute/core": "workspace:^1.0.0", @@ -16,7 +25,6 @@ "better-sqlite3": "8.4.0" }, "devDependencies": { - "@mtcute/dispatcher": "workspace:^1.0.0", "@types/better-sqlite3": "7.6.4" } } diff --git a/packages/sqlite/tsconfig.json b/packages/sqlite/tsconfig.json index e1330eba..0a60d15e 100644 --- a/packages/sqlite/tsconfig.json +++ b/packages/sqlite/tsconfig.json @@ -1,9 +1,12 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm" }, "include": [ "./index.ts" + ], + "references": [ + { "path": "../core" } ] } diff --git a/packages/tl-runtime/package.json b/packages/tl-runtime/package.json index ccee02f7..5843363d 100644 --- a/packages/tl-runtime/package.json +++ b/packages/tl-runtime/package.json @@ -5,15 +5,31 @@ "description": "Runtime for TL", "author": "Alina Sireneva ", "license": "MIT", - "main": "src/index.ts", + "type": "module", "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "docs": "typedoc", - "build": "tsc" + "build": "pnpm run -w build-package tl-runtime" }, "browser": { - "./platform/gzip.js": "./platform/gzip.web.js" + "./cjs/encodings/base64.js": "./cjs/encodings/base64.web.js", + "./esm/encodings/base64.js": "./esm/encodings/base64.web.js", + "./cjs/encodings/hex.js": "./cjs/encodings/hex.web.js", + "./esm/encodings/hex.js": "./esm/encodings/hex.web.js", + "./cjs/encodings/utf8.js": "./cjs/encodings/utf8.web.js", + "./esm/encodings/utf8.js": "./esm/encodings/utf8.web.js", + "./cjs/encodings/gzip.js": "./cjs/encodings/gzip.web.js", + "./esm/encodings/gzip.js": "./esm/encodings/gzip.web.js" }, + "distOnlyFields": { + "exports": { + ".": { + "import": "./esm/index.js", + "require": "./cjs/index.js" + } + } + }, + "main": "src/index.ts", "dependencies": { "long": "5.2.3", "pako": "2.1.0" diff --git a/packages/tl-runtime/src/encodings/base64.ts b/packages/tl-runtime/src/encodings/base64.ts new file mode 100644 index 00000000..ea1a5c74 --- /dev/null +++ b/packages/tl-runtime/src/encodings/base64.ts @@ -0,0 +1,39 @@ +/* eslint-disable no-restricted-globals */ + +export const BUFFER_BASE64_URL_AVAILABLE = Buffer.isEncoding('base64url') + +export function base64Encode(buf: Uint8Array, url = false): string { + const nodeBuffer = Buffer.from( + buf.buffer, + buf.byteOffset, + buf.byteLength, + ) + + if (url && BUFFER_BASE64_URL_AVAILABLE) return nodeBuffer.toString('base64url') + + const str = nodeBuffer.toString('base64') + if (url) return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '') + + return str +} + +export function base64DecodeToBuffer(string: string, url = false): Uint8Array { + let buffer + + if (url && BUFFER_BASE64_URL_AVAILABLE) { + buffer = Buffer.from(string, 'base64url') + } else { + buffer = Buffer.from(string, 'base64') + + if (url) { + string = string.replace(/-/g, '+').replace(/_/g, '/') + while (string.length % 4) string += '=' + } + } + + return buffer +} + +export function base64Decode(buf: Uint8Array, string: string, url = false): void { + (base64DecodeToBuffer(string, url) as Buffer).copy(buf) +} diff --git a/packages/tl-runtime/src/encodings/base64.web.ts b/packages/tl-runtime/src/encodings/base64.web.ts new file mode 100644 index 00000000..e76fe5e6 --- /dev/null +++ b/packages/tl-runtime/src/encodings/base64.web.ts @@ -0,0 +1,142 @@ +/// Based on https://github.com/beatgammit/base64-js, MIT license +const lookup: string[] = [] +const revLookup: number[] = [] + +const code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + +for (let i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i +} + +function getLens(b64: string): [number, number] { + const len = b64.length + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // Trim off extra bytes after placeholder bytes are found + // See: https://github.com/beatgammit/base64-js/issues/42 + let validLen = b64.indexOf('=') + if (validLen === -1) validLen = len + + const placeHoldersLen = validLen === len ? 0 : 4 - (validLen % 4) + + return [validLen, placeHoldersLen] +} + +function _byteLength(b64: string, validLen: number, placeHoldersLen: number) { + return ((validLen + placeHoldersLen) * 3) / 4 - placeHoldersLen +} + +function toByteArray(b64: string, arr: Uint8Array) { + let tmp + const lens = getLens(b64) + const validLen = lens[0] + const placeHoldersLen = lens[1] + + let curByte = 0 + + // if there are placeholders, only get up to the last complete 4 chars + const len = placeHoldersLen > 0 ? validLen - 4 : validLen + + let i + + for (i = 0; i < len; i += 4) { + tmp = + (revLookup[b64.charCodeAt(i)] << 18) | + (revLookup[b64.charCodeAt(i + 1)] << 12) | + (revLookup[b64.charCodeAt(i + 2)] << 6) | + revLookup[b64.charCodeAt(i + 3)] + arr[curByte++] = (tmp >> 16) & 0xff + arr[curByte++] = (tmp >> 8) & 0xff + arr[curByte++] = tmp & 0xff + } + + if (placeHoldersLen === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[curByte++] = tmp & 0xff + } + + if (placeHoldersLen === 1) { + tmp = + (revLookup[b64.charCodeAt(i)] << 10) | + (revLookup[b64.charCodeAt(i + 1)] << 4) | + (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[curByte++] = (tmp >> 8) & 0xff + arr[curByte++] = tmp & 0xff + } + + return arr +} + +function tripletToBase64(num: number) { + return lookup[(num >> 18) & 0x3f] + lookup[(num >> 12) & 0x3f] + lookup[(num >> 6) & 0x3f] + lookup[num & 0x3f] +} + +function encodeChunk(uint8: Uint8Array, start: number, end: number) { + let tmp + const output = [] + + for (let i = start; i < end; i += 3) { + tmp = ((uint8[i] << 16) & 0xff0000) + ((uint8[i + 1] << 8) & 0xff00) + (uint8[i + 2] & 0xff) + output.push(tripletToBase64(tmp)) + } + + return output.join('') +} + +function fromByteArray(uint8: Uint8Array) { + let tmp + const len = uint8.length + const extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + const parts = [] + const maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (let i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, i + maxChunkLength > len2 ? len2 : i + maxChunkLength)) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + parts.push(lookup[tmp >> 2] + lookup[(tmp << 4) & 0x3f] + '==') + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + uint8[len - 1] + parts.push(lookup[tmp >> 10] + lookup[(tmp >> 4) & 0x3f] + lookup[(tmp << 2) & 0x3f] + '=') + } + + return parts.join('') +} + +export function base64Encode(buf: Uint8Array, url = false): string { + const str = fromByteArray(buf) + if (url) return str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '') + + return str +} + +export function base64Decode(buf: Uint8Array, string: string, url = false): void { + if (url) { + string = string.replace(/-/g, '+').replace(/_/g, '/') + while (string.length % 4) string += '=' + } + + const res = toByteArray(string, buf) + buf.set(res) +} + +export function base64DecodeToBuffer(string: string, url = false): Uint8Array { + if (url) { + string = string.replace(/-/g, '+').replace(/_/g, '/') + while (string.length % 4) string += '=' + } + + const buf = new Uint8Array(_byteLength(string, ...getLens(string))) + + toByteArray(string, buf) + + return buf +} diff --git a/packages/tl-runtime/src/platform/gzip.ts b/packages/tl-runtime/src/encodings/gzip.ts similarity index 70% rename from packages/tl-runtime/src/platform/gzip.ts rename to packages/tl-runtime/src/encodings/gzip.ts index 13d5e393..f865052b 100644 --- a/packages/tl-runtime/src/platform/gzip.ts +++ b/packages/tl-runtime/src/encodings/gzip.ts @@ -1,10 +1,12 @@ -import { deflateSync, gunzipSync } from 'zlib' +/* eslint-disable no-restricted-globals */ + +import { deflateSync, gunzipSync } from 'node:zlib' /** * Decompress a buffer with gzip. * @param buf Buffer to decompress */ -export function gzipInflate(buf: Buffer): Buffer { +export function gzipInflate(buf: Uint8Array): Uint8Array { return gunzipSync(buf) } @@ -16,11 +18,11 @@ export function gzipInflate(buf: Buffer): Buffer { * Maximum compression ratio. If the resulting buffer is smaller than * `buf.length * ratio`, `null` is returned. */ -export function gzipDeflate(buf: Buffer, maxRatio?: number): Buffer | null { +export function gzipDeflate(buf: ArrayBuffer, maxRatio?: number): Buffer | null { if (maxRatio) { try { return deflateSync(buf, { - maxOutputLength: Math.floor(buf.length * maxRatio), + maxOutputLength: Math.floor(buf.byteLength * maxRatio), }) // hot path, avoid additional runtime checks // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/tl-runtime/src/platform/gzip.web.ts b/packages/tl-runtime/src/encodings/gzip.web.ts similarity index 66% rename from packages/tl-runtime/src/platform/gzip.web.ts rename to packages/tl-runtime/src/encodings/gzip.web.ts index 5d39827a..797f0d0f 100644 --- a/packages/tl-runtime/src/platform/gzip.web.ts +++ b/packages/tl-runtime/src/encodings/gzip.web.ts @@ -1,11 +1,7 @@ import { Data, Deflate, inflate } from 'pako' -export function typedArrayToBuffer(arr: NodeJS.TypedArray): Buffer { - return ArrayBuffer.isView(arr) ? Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength) : Buffer.from(arr) -} - -export function gzipInflate(buf: Buffer): Buffer { - return typedArrayToBuffer(inflate(buf)) +export function gzipInflate(buf: Uint8Array): Uint8Array { + return inflate(buf) } const ERROR_SIZE_LIMIT_REACHED = 'ERR_SIZE_LIMIT_REACHED' @@ -30,7 +26,7 @@ class DeflateLimited extends Deflate { } } -export function gzipDeflate(buf: Buffer, maxRatio?: number): Buffer | null { +export function gzipDeflate(buf: Uint8Array, maxRatio?: number): Uint8Array | null { const deflator = maxRatio ? new DeflateLimited(Math.floor(buf.length * maxRatio)) : new Deflate() try { @@ -40,5 +36,5 @@ export function gzipDeflate(buf: Buffer, maxRatio?: number): Buffer | null { throw e } - return typedArrayToBuffer(deflator.result) + return deflator.result } diff --git a/packages/tl-runtime/src/encodings/hex.ts b/packages/tl-runtime/src/encodings/hex.ts new file mode 100644 index 00000000..db76f585 --- /dev/null +++ b/packages/tl-runtime/src/encodings/hex.ts @@ -0,0 +1,13 @@ +/* eslint-disable no-restricted-globals */ + +export function hexEncode(buf: Uint8Array): string { + return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString('hex') +} + +export function hexDecodeToBuffer(string: string): Uint8Array { + return Buffer.from(string, 'hex') +} + +export function hexDecode(buf: Uint8Array, string: string): number { + return (hexDecodeToBuffer(string) as Buffer).copy(buf) +} diff --git a/packages/tl-runtime/src/encodings/hex.web.ts b/packages/tl-runtime/src/encodings/hex.web.ts new file mode 100644 index 00000000..a084b8fb --- /dev/null +++ b/packages/tl-runtime/src/encodings/hex.web.ts @@ -0,0 +1,78 @@ +/// Based on https://github.com/feross/buffer, MIT license + +const hexSliceLookupTable = (function () { + const alphabet = '0123456789abcdef' + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const table: string[] = new Array(256) + + for (let i = 0; i < 16; ++i) { + const i16 = i * 16 + + for (let j = 0; j < 16; ++j) { + table[i16 + j] = alphabet[i] + alphabet[j] + } + } + + return table +})() + +const hexCharValueTable: Record = { + '0': 0, + '1': 1, + '2': 2, + '3': 3, + '4': 4, + '5': 5, + '6': 6, + '7': 7, + '8': 8, + '9': 9, + a: 10, + b: 11, + c: 12, + d: 13, + e: 14, + f: 15, + A: 10, + B: 11, + C: 12, + D: 13, + E: 14, + F: 15, +} + +export function hexEncode(buf: Uint8Array): string { + let out = '' + + for (let i = 0; i < buf.byteLength; ++i) { + out += hexSliceLookupTable[buf[i]] + } + + return out +} + +export function hexDecode(buf: Uint8Array, string: string): void { + const strLen = string.length + const length = Math.min(buf.length, strLen / 2) + + let i + + for (i = 0; i < length; ++i) { + const a = hexCharValueTable[string[i * 2]] + const b = hexCharValueTable[string[i * 2 + 1]] + + if (a === undefined || b === undefined) { + return + } + buf[i] = (a << 4) | b + } + + return +} + +export function hexDecodeToBuffer(string: string): Uint8Array { + const buf = new Uint8Array(Math.ceil(string.length / 2)) + hexDecode(buf, string) + + return buf +} diff --git a/packages/tl-runtime/src/encodings/index.ts b/packages/tl-runtime/src/encodings/index.ts new file mode 100644 index 00000000..3c14a235 --- /dev/null +++ b/packages/tl-runtime/src/encodings/index.ts @@ -0,0 +1,4 @@ +export * from './base64.js' +export * from './gzip.js' +export * from './hex.js' +export * from './utf8.js' diff --git a/packages/tl-runtime/src/encodings/utf8.ts b/packages/tl-runtime/src/encodings/utf8.ts new file mode 100644 index 00000000..5543e8c0 --- /dev/null +++ b/packages/tl-runtime/src/encodings/utf8.ts @@ -0,0 +1,21 @@ +/* eslint-disable no-restricted-globals */ + +export function byteLengthUtf8(str: string) { + return Buffer.byteLength(str, 'utf8') +} + +export function utf8Decode(buf: Uint8Array): string { + return Buffer.from( + buf.buffer, + buf.byteOffset, + buf.byteLength, + ).toString('utf8') +} + +export function utf8Encode(buf: Uint8Array, str: string) { + return Buffer.from(str, 'utf8').copy(buf) +} + +export function utf8EncodeToBuffer(str: string): Uint8Array { + return Buffer.from(str, 'utf8') +} diff --git a/packages/tl-runtime/src/encodings/utf8.web.ts b/packages/tl-runtime/src/encodings/utf8.web.ts new file mode 100644 index 00000000..5eeb30e4 --- /dev/null +++ b/packages/tl-runtime/src/encodings/utf8.web.ts @@ -0,0 +1,15 @@ +export function byteLengthUtf8(str: string) { + return new TextEncoder().encode(str).length +} + +export function utf8Decode(buf: Uint8Array): string { + return new TextDecoder('utf8').decode(buf) +} + +export function utf8Encode(buf: Uint8Array, str: string) { + return new TextEncoder().encodeInto(str, buf) +} + +export function utf8EncodeToBuffer(str: string): Uint8Array { + return new TextEncoder().encode(str) +} diff --git a/packages/tl-runtime/src/index.ts b/packages/tl-runtime/src/index.ts index fbf53d6f..b112fec0 100644 --- a/packages/tl-runtime/src/index.ts +++ b/packages/tl-runtime/src/index.ts @@ -1,3 +1,6 @@ -export * from './platform/gzip' -export * from './reader' -export * from './writer' +export * from './encodings/base64.js' +export * from './encodings/gzip.js' +export * from './encodings/hex.js' +export * from './encodings/utf8.js' +export * from './reader.js' +export * from './writer.js' diff --git a/packages/tl-runtime/src/reader.ts b/packages/tl-runtime/src/reader.ts index 6e5e7acf..99abefdc 100644 --- a/packages/tl-runtime/src/reader.ts +++ b/packages/tl-runtime/src/reader.ts @@ -1,6 +1,8 @@ import Long from 'long' -import { gzipInflate } from './platform/gzip' +import { gzipInflate } from './encodings/gzip.js' +import { hexEncode } from './encodings/hex.js' +import { utf8Decode } from './encodings/utf8.js' const TWO_PWR_32_DBL = (1 << 16) * (1 << 16) @@ -27,14 +29,9 @@ export type TlReaderMap = Record unknown> & { * Reader for TL objects. */ export class TlBinaryReader { - /** - * Underlying buffer. - */ - data: Buffer + readonly dataView: DataView + readonly uint8View: Uint8Array - /** - * Position in the buffer. - */ pos = 0 /** @@ -44,11 +41,18 @@ export class TlBinaryReader { */ constructor( readonly objectsMap: TlReaderMap | undefined, - data: Buffer, + data: ArrayBuffer, start = 0, ) { - this.data = data - this.pos = start + if (ArrayBuffer.isView(data)) { + this.pos = start + this.dataView = new DataView(data.buffer, data.byteOffset, data.byteLength) + this.uint8View = new Uint8Array(data.buffer, data.byteOffset, data.byteLength) + } else { + this.pos = start + this.dataView = new DataView(data) + this.uint8View = new Uint8Array(data) + } } /** @@ -57,7 +61,7 @@ export class TlBinaryReader { * @param data Buffer to read from * @param start Position to start reading from */ - static manual(data: Buffer, start = 0): TlBinaryReader { + static manual(data: ArrayBuffer, start = 0): TlBinaryReader { return new TlBinaryReader(undefined, data, start) } @@ -68,19 +72,19 @@ export class TlBinaryReader { * @param data Buffer to read from * @param start Position to start reading from */ - static deserializeObject(objectsMap: TlReaderMap, data: Buffer, start = 0): T { + static deserializeObject(objectsMap: TlReaderMap, data: Uint8Array, start = 0): T { return new TlBinaryReader(objectsMap, data, start).object() as T } int(): number { - const res = this.data.readInt32LE(this.pos) + const res = this.dataView.getInt32(this.pos, true) this.pos += 4 return res } uint(): number { - const res = this.data.readUInt32LE(this.pos) + const res = this.dataView.getUint32(this.pos, true) this.pos += 4 return res @@ -91,20 +95,21 @@ export class TlBinaryReader { */ peekUint(): number { // e.g. for checking ctor number - return this.data.readUInt32LE(this.pos) + return this.dataView.getUint32(this.pos, true) } int53(): number { // inlined toNumber from Long - const res = (this.data.readInt32LE(this.pos) >>> 0) + TWO_PWR_32_DBL * this.data.readInt32LE(this.pos + 4) + const res = + (this.dataView.getInt32(this.pos, true) >>> 0) + TWO_PWR_32_DBL * this.dataView.getInt32(this.pos + 4, true) this.pos += 8 return res } long(unsigned = false): Long { - const lo = this.data.readInt32LE(this.pos) - const hi = this.data.readInt32LE(this.pos + 4) + const lo = this.dataView.getInt32(this.pos, true) + const hi = this.dataView.getInt32(this.pos + 4, true) this.pos += 8 @@ -112,14 +117,14 @@ export class TlBinaryReader { } float(): number { - const res = this.data.readFloatLE(this.pos) + const res = this.dataView.getFloat32(this.pos, true) this.pos += 4 return res } double(): number { - const res = this.data.readDoubleLE(this.pos) + const res = this.dataView.getFloat64(this.pos, true) this.pos += 8 return res @@ -136,27 +141,27 @@ export class TlBinaryReader { * Read raw bytes of the given length * @param bytes Length of the buffer to read */ - raw(bytes = -1): Buffer { - if (bytes === -1) bytes = this.data.length - this.pos + raw(bytes = -1): Uint8Array { + if (bytes === -1) bytes = this.uint8View.length - this.pos - return this.data.slice(this.pos, (this.pos += bytes)) + return this.uint8View.subarray(this.pos, (this.pos += bytes)) } - int128(): Buffer { - return this.data.slice(this.pos, (this.pos += 16)) + int128(): Uint8Array { + return this.uint8View.subarray(this.pos, (this.pos += 16)) } - int256(): Buffer { - return this.data.slice(this.pos, (this.pos += 32)) + int256(): Uint8Array { + return this.uint8View.subarray(this.pos, (this.pos += 32)) } - bytes(): Buffer { - const firstByte = this.data[this.pos++] + bytes(): Uint8Array { + const firstByte = this.uint8View[this.pos++] let length let padding if (firstByte === 254) { - length = this.data[this.pos++] | (this.data[this.pos++] << 8) | (this.data[this.pos++] << 16) + length = this.uint8View[this.pos++] | (this.uint8View[this.pos++] << 8) | (this.uint8View[this.pos++] << 16) padding = length % 4 } else { length = firstByte @@ -170,7 +175,7 @@ export class TlBinaryReader { } string(): string { - return this.bytes().toString('utf-8') + return utf8Decode(this.bytes()) } object(): unknown { @@ -196,9 +201,7 @@ export class TlBinaryReader { // mtproto sucks and there's no way we can just skip it this.seek(-4) const pos = this.pos - const error = new TypeError( - `Unknown object id: 0x${id.toString(16)}. Content: ${this.raw().toString('hex')}`, - ) + const error = new TypeError(`Unknown object id: 0x${id.toString(16)}. Content: ${hexEncode(this.raw())}`) this.pos = pos throw error } @@ -239,7 +242,7 @@ export class TlBinaryReader { * @param pos Position to seek to */ seekTo(pos: number): void { - if (pos >= this.data.length || pos < 0) { + if (pos >= this.uint8View.length || pos < 0) { throw new RangeError('New position is out of range') } this.pos = pos diff --git a/packages/tl-runtime/src/writer.ts b/packages/tl-runtime/src/writer.ts index 5f0c89c4..72345551 100644 --- a/packages/tl-runtime/src/writer.ts +++ b/packages/tl-runtime/src/writer.ts @@ -1,5 +1,7 @@ import Long from 'long' +import { byteLengthUtf8, utf8EncodeToBuffer } from './encodings/utf8.js' + const TWO_PWR_32_DBL = (1 << 16) * (1 << 16) /** @@ -104,16 +106,16 @@ export class TlSerializationCounter { this.count += 4 } - raw(val: Buffer): void { - this.count += val.length + raw(val: Uint8Array): void { + this.count += val.byteLength } - bytes(val: Buffer): void { + bytes(val: Uint8Array): void { this.count += TlSerializationCounter.countBytesOverhead(val.length) + val.length } string(val: string): void { - const length = Buffer.byteLength(val, 'utf8') + const length = byteLengthUtf8(val) this.count += TlSerializationCounter.countBytesOverhead(length) + length } @@ -132,10 +134,8 @@ export class TlSerializationCounter { * Writer for TL objects. */ export class TlBinaryWriter { - /** - * Underlying buffer. - */ - buffer: Buffer + readonly dataView: DataView + readonly uint8View: Uint8Array /** * Current position in the buffer. @@ -149,11 +149,18 @@ export class TlBinaryWriter { */ constructor( readonly objectMap: TlWriterMap | undefined, - buffer: Buffer, + data: ArrayBuffer, start = 0, ) { - this.buffer = buffer - this.pos = start + if (ArrayBuffer.isView(data)) { + this.pos = start + this.dataView = new DataView(data.buffer, data.byteOffset, data.byteLength) + this.uint8View = new Uint8Array(data.buffer, data.byteOffset, data.byteLength) + } else { + this.pos = start + this.dataView = new DataView(data) + this.uint8View = new Uint8Array(data) + } } /** @@ -163,27 +170,19 @@ export class TlBinaryWriter { * @param size Size of the writer's buffer */ static alloc(objectMap: TlWriterMap | undefined, size: number): TlBinaryWriter { - return new TlBinaryWriter(objectMap, Buffer.allocUnsafe(size)) + return new TlBinaryWriter(objectMap, new ArrayBuffer(size)) } /** * Create a new writer without objects map for manual usage * - * @param buffer Buffer to write to + * @param buffer Buffer to write to, or its size * @param start Position to start writing at */ - static manual(buffer: Buffer, start = 0): TlBinaryWriter { - return new TlBinaryWriter(undefined, buffer, start) - } + static manual(buffer: ArrayBuffer | number, start = 0): TlBinaryWriter { + if (typeof buffer === 'number') buffer = new ArrayBuffer(buffer) - /** - * Create a new writer without objects map for manual usage - * with a given size - * - * @param size Size of the writer's buffer - */ - static manualAlloc(size: number): TlBinaryWriter { - return new TlBinaryWriter(undefined, Buffer.allocUnsafe(size)) + return new TlBinaryWriter(undefined, buffer, start) } /** @@ -193,7 +192,7 @@ export class TlBinaryWriter { * @param obj Object to serialize * @param knownSize In case the size is known, pass it here */ - static serializeObject(objectMap: TlWriterMap, obj: { _: string }, knownSize = -1): Buffer { + static serializeObject(objectMap: TlWriterMap, obj: { _: string }, knownSize = -1): Uint8Array { if (knownSize === -1) { knownSize = objectMap._staticSize[obj._] || TlSerializationCounter.countNeededBytes(objectMap, obj) } @@ -202,27 +201,27 @@ export class TlBinaryWriter { writer.object(obj) - return writer.buffer + return writer.uint8View } int(val: number): void { - this.buffer.writeInt32LE(val, this.pos) + this.dataView.setInt32(this.pos, val, true) this.pos += 4 } uint(val: number): void { - this.buffer.writeUInt32LE(val, this.pos) + this.dataView.setUint32(this.pos, val, true) this.pos += 4 } int53(val: number): void { // inlined fromNumber from Long - this.buffer.writeInt32LE(val % TWO_PWR_32_DBL | 0, this.pos) + this.dataView.setInt32(this.pos, val % TWO_PWR_32_DBL | 0, true) if (val < 0) { - this.buffer.writeInt32LE((val / TWO_PWR_32_DBL - 1) | 0, this.pos + 4) + this.dataView.setInt32(this.pos + 4, (val / TWO_PWR_32_DBL - 1) | 0, true) } else { - this.buffer.writeInt32LE((val / TWO_PWR_32_DBL) | 0, this.pos + 4) + this.dataView.setInt32(this.pos + 4, (val / TWO_PWR_32_DBL) | 0, true) } this.pos += 8 @@ -233,24 +232,24 @@ export class TlBinaryWriter { } long(val: Long): void { - this.buffer.writeInt32LE(val.low, this.pos) - this.buffer.writeInt32LE(val.high, this.pos + 4) + this.dataView.setInt32(this.pos, val.low, true) + this.dataView.setInt32(this.pos + 4, val.high, true) this.pos += 8 } float(val: number): void { - this.buffer.writeFloatLE(val, this.pos) + this.dataView.setFloat32(this.pos, val, true) this.pos += 4 } double(val: number): void { - this.buffer.writeDoubleLE(val, this.pos) + this.dataView.setFloat64(this.pos, val, true) this.pos += 8 } boolean(val: boolean): void { - this.buffer.writeUInt32LE(val ? 0x997275b5 : 0xbc799737, this.pos) + this.dataView.setInt32(this.pos, val ? 0x997275b5 : 0xbc799737, true) this.pos += 4 } @@ -258,48 +257,48 @@ export class TlBinaryWriter { * Write raw bytes to the buffer * @param val Buffer to write */ - raw(val: Buffer): void { - val.copy(this.buffer, this.pos) - this.pos += val.length + raw(val: Uint8Array): void { + this.uint8View.set(val, this.pos) + this.pos += val.byteLength } - int128(val: Buffer): void { - val.copy(this.buffer, this.pos) - this.pos += 16 + int128(val: Uint8Array): void { + if (val.byteLength !== 16) throw new Error('Invalid int128 length') + this.raw(val) } - int256(val: Buffer): void { - val.copy(this.buffer, this.pos) - this.pos += 32 + int256(val: Uint8Array): void { + if (val.byteLength !== 32) throw new Error('Invalid int256 length') + this.raw(val) } - bytes(val: Buffer): void { - const length = val.length + bytes(val: Uint8Array): void { + const length = val.byteLength let padding if (length <= 253) { - this.buffer[this.pos++] = val.length + this.uint8View[this.pos++] = length padding = (length + 1) % 4 } else { - this.buffer[this.pos++] = 254 - this.buffer[this.pos++] = val.length & 0xff - this.buffer[this.pos++] = (val.length >> 8) & 0xff - this.buffer[this.pos++] = (val.length >> 16) & 0xff + this.uint8View[this.pos++] = 254 + this.uint8View[this.pos++] = length & 0xff + this.uint8View[this.pos++] = (length >> 8) & 0xff + this.uint8View[this.pos++] = (length >> 16) & 0xff padding = length % 4 } - val.copy(this.buffer, this.pos) - this.pos += val.length + this.uint8View.set(val, this.pos) + this.pos += length if (padding > 0) { padding = 4 - padding - while (padding--) this.buffer[this.pos++] = 0 + while (padding--) this.uint8View[this.pos++] = 0 } } string(val: string): void { - this.bytes(Buffer.from(val, 'utf-8')) + this.bytes(utf8EncodeToBuffer(val)) } // hot path, avoid additional runtime checks @@ -320,7 +319,7 @@ export class TlBinaryWriter { /** * Get the resulting buffer */ - result(): Buffer { - return this.buffer.slice(0, this.pos) + result(): Uint8Array { + return this.uint8View.subarray(0, this.pos) } } diff --git a/packages/tl-runtime/tests/binary-reader.spec.ts b/packages/tl-runtime/tests/binary-reader.spec.ts index f58c3bf1..01378f6b 100644 --- a/packages/tl-runtime/tests/binary-reader.spec.ts +++ b/packages/tl-runtime/tests/binary-reader.spec.ts @@ -1,70 +1,70 @@ // eslint-disable-next-line max-len -/* eslint-disable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-argument */ import { expect } from 'chai' import { randomBytes } from 'crypto' import Long from 'long' import { describe, it } from 'mocha' -import { TlBinaryReader, TlReaderMap } from '../src' +import { hexDecodeToBuffer, hexEncode } from '../src/encodings/hex.js' +import { TlBinaryReader, TlReaderMap } from '../src/index.js' describe('TlBinaryReader', () => { it('should read int32', () => { - expect(TlBinaryReader.manual(Buffer.from([0, 0, 0, 0])).int()).eq(0) - expect(TlBinaryReader.manual(Buffer.from([1, 0, 0, 0])).int()).eq(1) - expect(TlBinaryReader.manual(Buffer.from([1, 2, 3, 4])).int()).eq(67305985) - expect(new TlBinaryReader({}, Buffer.from([0xff, 0xff, 0xff, 0xff])).int()).eq(-1) + expect(TlBinaryReader.manual(new Uint8Array([0, 0, 0, 0])).int()).eq(0) + expect(TlBinaryReader.manual(new Uint8Array([1, 0, 0, 0])).int()).eq(1) + expect(TlBinaryReader.manual(new Uint8Array([1, 2, 3, 4])).int()).eq(67305985) + expect(TlBinaryReader.manual(new Uint8Array([0xff, 0xff, 0xff, 0xff])).int()).eq(-1) }) it('should read uint32', () => { - expect(TlBinaryReader.manual(Buffer.from([0, 0, 0, 0])).uint()).eq(0) - expect(TlBinaryReader.manual(Buffer.from([1, 0, 0, 0])).uint()).eq(1) - expect(TlBinaryReader.manual(Buffer.from([1, 2, 3, 4])).uint()).eq(67305985) - expect(new TlBinaryReader({}, Buffer.from([0xff, 0xff, 0xff, 0xff])).uint()).eq(4294967295) + expect(TlBinaryReader.manual(new Uint8Array([0, 0, 0, 0])).uint()).eq(0) + expect(TlBinaryReader.manual(new Uint8Array([1, 0, 0, 0])).uint()).eq(1) + expect(TlBinaryReader.manual(new Uint8Array([1, 2, 3, 4])).uint()).eq(67305985) + expect(TlBinaryReader.manual(new Uint8Array([0xff, 0xff, 0xff, 0xff])).uint()).eq(4294967295) }) it('should read int53', () => { - expect(TlBinaryReader.manual(Buffer.from([0, 0, 0, 0, 0, 0, 0, 0])).int53()).eq(0) - expect(TlBinaryReader.manual(Buffer.from([1, 0, 0, 0, 0, 0, 0, 0])).int53()).eq(1) - expect(TlBinaryReader.manual(Buffer.from([1, 2, 3, 4, 0, 0, 0, 0])).int53()).eq(67305985) - expect(TlBinaryReader.manual(Buffer.from([1, 0, 1, 0, 1, 0, 1, 0])).int53()).eq(281479271743489) - expect(new TlBinaryReader({}, Buffer.from([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])).int53()).eq(-1) + expect(TlBinaryReader.manual(new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0])).int53()).eq(0) + expect(TlBinaryReader.manual(new Uint8Array([1, 0, 0, 0, 0, 0, 0, 0])).int53()).eq(1) + expect(TlBinaryReader.manual(new Uint8Array([1, 2, 3, 4, 0, 0, 0, 0])).int53()).eq(67305985) + expect(TlBinaryReader.manual(new Uint8Array([1, 0, 1, 0, 1, 0, 1, 0])).int53()).eq(281479271743489) + expect(TlBinaryReader.manual(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])).int53()).eq(-1) }) it('should read long', () => { expect( - new TlBinaryReader({}, Buffer.from([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])).long().toString(), + TlBinaryReader.manual(new Uint8Array([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff])).long().toString(), ).eq('-1') expect( - new TlBinaryReader({}, Buffer.from([0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78])).long().toString(), + TlBinaryReader.manual(new Uint8Array([0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78])).long().toString(), ).eq('8671175386481439762') expect( - new TlBinaryReader({}, Buffer.from([0x15, 0xc4, 0x15, 0xb5, 0xc4, 0x1c, 0x03, 0xa3])).long().toString(), + TlBinaryReader.manual(new Uint8Array([0x15, 0xc4, 0x15, 0xb5, 0xc4, 0x1c, 0x03, 0xa3])).long().toString(), ).eq('-6700480189419895787') }) it('should read float', () => { - expect(TlBinaryReader.manual(Buffer.from([0, 0, 0x80, 0x3f])).float()).closeTo(1, 0.001) - expect(new TlBinaryReader({}, Buffer.from([0xb6, 0xf3, 0x9d, 0x3f])).float()).closeTo(1.234, 0.001) - expect(new TlBinaryReader({}, Buffer.from([0xfa, 0x7e, 0x2a, 0x3f])).float()).closeTo(0.666, 0.001) + expect(TlBinaryReader.manual(new Uint8Array([0, 0, 0x80, 0x3f])).float()).closeTo(1, 0.001) + expect(TlBinaryReader.manual(new Uint8Array([0xb6, 0xf3, 0x9d, 0x3f])).float()).closeTo(1.234, 0.001) + expect(TlBinaryReader.manual(new Uint8Array([0xfa, 0x7e, 0x2a, 0x3f])).float()).closeTo(0.666, 0.001) }) it('should read double', () => { - expect(new TlBinaryReader({}, Buffer.from([0, 0, 0, 0, 0, 0, 0xf0, 0x3f])).double()).closeTo(1, 0.001) - expect(new TlBinaryReader({}, Buffer.from([0, 0, 0, 0, 0, 0, 0x25, 0x40])).double()).closeTo(10.5, 0.001) - expect(new TlBinaryReader({}, Buffer.from([0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x21, 0x40])).double()).closeTo( - 8.8, - 0.001, - ) + expect(TlBinaryReader.manual(new Uint8Array([0, 0, 0, 0, 0, 0, 0xf0, 0x3f])).double()).closeTo(1, 0.001) + expect(TlBinaryReader.manual(new Uint8Array([0, 0, 0, 0, 0, 0, 0x25, 0x40])).double()).closeTo(10.5, 0.001) + expect( + TlBinaryReader.manual(new Uint8Array([0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x21, 0x40])).double(), + ).closeTo(8.8, 0.001) }) it('should read raw bytes', () => { - expect([...TlBinaryReader.manual(Buffer.from([1, 2, 3, 4])).raw(2)]).eql([1, 2]) - expect([...TlBinaryReader.manual(Buffer.from([1, 2, 3, 4])).raw()]).eql([1, 2, 3, 4]) - expect([...TlBinaryReader.manual(Buffer.from([1, 2, 3, 4])).raw(0)]).eql([]) + expect([...TlBinaryReader.manual(new Uint8Array([1, 2, 3, 4])).raw(2)]).eql([1, 2]) + expect([...TlBinaryReader.manual(new Uint8Array([1, 2, 3, 4])).raw()]).eql([1, 2, 3, 4]) + expect([...TlBinaryReader.manual(new Uint8Array([1, 2, 3, 4])).raw(0)]).eql([]) }) it('should move cursor', () => { - const reader = new TlBinaryReader({}, Buffer.from([1, 2, 3, 4, 5, 6, 7, 8])) + const reader = TlBinaryReader.manual(new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8])) reader.int() expect(reader.pos).eq(4) @@ -95,14 +95,15 @@ describe('TlBinaryReader', () => { }) it('should read tg-encoded bytes', () => { - expect([...TlBinaryReader.manual(Buffer.from([1, 2, 3, 4])).bytes()]).eql([2]) + expect([...TlBinaryReader.manual(new Uint8Array([1, 2, 3, 4])).bytes()]).eql([2]) const random250bytes = randomBytes(250) - let reader = new TlBinaryReader({}, Buffer.from([250, ...random250bytes, 0, 0, 0, 0, 0])) + let reader = TlBinaryReader.manual(new Uint8Array([250, ...random250bytes, 0, 0, 0, 0, 0])) expect([...reader.bytes()]).eql([...random250bytes]) expect(reader.pos).eq(252) const random1000bytes = randomBytes(1000) + // eslint-disable-next-line no-restricted-globals const buffer = Buffer.alloc(1010) buffer[0] = 254 buffer.writeIntLE(1000, 1, 3) @@ -126,7 +127,7 @@ describe('TlBinaryReader', () => { } it('should read tg-encoded objects', () => { - const buffer = Buffer.from([ + const buffer = new Uint8Array([ 0xef, 0xbe, 0xad, @@ -158,7 +159,7 @@ describe('TlBinaryReader', () => { }) it('should read tg-encoded vectors', () => { - const buffer = Buffer.from([ + const buffer = new Uint8Array([ 0x15, 0xc4, 0xb5, @@ -241,13 +242,13 @@ describe('TlBinaryReader', () => { } const expected = { - nonce: Buffer.from('3E0549828CCA27E966B301A48FECE2FC', 'hex'), - serverNonce: Buffer.from('A5CF4D33F4A11EA877BA4AA573907330', 'hex'), - pq: Buffer.from('17ED48941A08F981', 'hex'), + nonce: hexDecodeToBuffer('3E0549828CCA27E966B301A48FECE2FC'), + serverNonce: hexDecodeToBuffer('A5CF4D33F4A11EA877BA4AA573907330'), + pq: hexDecodeToBuffer('17ED48941A08F981'), serverPublicKeyFingerprints: [Long.fromString('c3b42b026ce86b21', false, 16)], } - const r = new TlBinaryReader(map, Buffer.from(input, 'hex')) + const r = new TlBinaryReader(map, hexDecodeToBuffer(input)) expect(r.long().toString()).eq('0') // authKeyId expect(r.long().toString(16)).eq('51E57AC91E83C801'.toLowerCase()) // messageId expect(r.uint()).eq(64) // messageLength @@ -255,9 +256,9 @@ describe('TlBinaryReader', () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const obj = r.object() as any expect(obj._).eq('mt_resPQ') - expect(obj.nonce.toString('hex')).eq(expected.nonce.toString('hex')) - expect(obj.serverNonce.toString('hex')).eq(expected.serverNonce.toString('hex')) - expect(obj.pq.toString('hex')).eq(expected.pq.toString('hex')) + expect(hexEncode(obj.nonce)).eq(hexEncode(expected.nonce)) + expect(hexEncode(obj.serverNonce)).eq(hexEncode(expected.serverNonce)) + expect(hexEncode(obj.pq)).eq(hexEncode(expected.pq)) expect(obj.serverPublicKeyFingerprints.length).eq(1) expect(obj.serverPublicKeyFingerprints[0].toString(16)).eq( expected.serverPublicKeyFingerprints[0].toString(16), diff --git a/packages/tl-runtime/tests/binary-writer.spec.ts b/packages/tl-runtime/tests/binary-writer.spec.ts index 4a5b5b2e..cc3fd07e 100644 --- a/packages/tl-runtime/tests/binary-writer.spec.ts +++ b/packages/tl-runtime/tests/binary-writer.spec.ts @@ -4,7 +4,8 @@ import { randomBytes } from 'crypto' import Long from 'long' import { describe, it } from 'mocha' -import { TlBinaryWriter, TlSerializationCounter, TlWriterMap } from '../src' +import { hexDecodeToBuffer, hexEncode } from '../src/encodings/hex.js' +import { TlBinaryWriter, TlSerializationCounter, TlWriterMap } from '../src/index.js' describe('TlBinaryWriter', () => { const testSingleMethod = (size: number, fn: (w: TlBinaryWriter) => void, map?: TlWriterMap): string => { @@ -12,7 +13,7 @@ describe('TlBinaryWriter', () => { fn(w) expect(w.pos).eq(size) - return w.buffer.toString('hex') + return hexEncode(w.uint8View) } it('should write int32', () => { @@ -56,7 +57,7 @@ describe('TlBinaryWriter', () => { }) it('should write raw bytes', () => { - expect(testSingleMethod(5, (w) => w.raw(Buffer.from([4, 3, 5, 1, 1])))).eq('0403050101') + expect(testSingleMethod(5, (w) => w.raw(new Uint8Array([4, 3, 5, 1, 1])))).eq('0403050101') }) it('should write tg-encoded boolean', () => { @@ -65,13 +66,14 @@ describe('TlBinaryWriter', () => { }) it('should write tg-encoded bytes', () => { - expect(testSingleMethod(4, (w) => w.bytes(Buffer.from([1, 2, 3])))).eq('03010203') - expect(testSingleMethod(8, (w) => w.bytes(Buffer.from([1, 2, 3, 4])))).eq('0401020304000000') + expect(testSingleMethod(4, (w) => w.bytes(new Uint8Array([1, 2, 3])))).eq('03010203') + expect(testSingleMethod(8, (w) => w.bytes(new Uint8Array([1, 2, 3, 4])))).eq('0401020304000000') const random250bytes = randomBytes(250) expect(testSingleMethod(252, (w) => w.bytes(random250bytes))).eq('fa' + random250bytes.toString('hex') + '00') const random1000bytes = randomBytes(1000) + // eslint-disable-next-line no-restricted-globals const buffer = Buffer.alloc(1004) buffer[0] = 254 buffer.writeIntLE(1000, 1, 3) @@ -169,9 +171,9 @@ describe('TlBinaryWriter', () => { const resPq = { _: 'mt_resPQ', - nonce: Buffer.from('3E0549828CCA27E966B301A48FECE2FC', 'hex'), - serverNonce: Buffer.from('A5CF4D33F4A11EA877BA4AA573907330', 'hex'), - pq: Buffer.from('17ED48941A08F981', 'hex'), + nonce: hexDecodeToBuffer('3E0549828CCA27E966B301A48FECE2FC'), + serverNonce: hexDecodeToBuffer('A5CF4D33F4A11EA877BA4AA573907330'), + pq: hexDecodeToBuffer('17ED48941A08F981'), serverPublicKeyFingerprints: [Long.fromString('c3b42b026ce86b21', 16)], } diff --git a/packages/tl-runtime/tests/encodings/base64.spec.ts b/packages/tl-runtime/tests/encodings/base64.spec.ts new file mode 100644 index 00000000..7a2e6d5e --- /dev/null +++ b/packages/tl-runtime/tests/encodings/base64.spec.ts @@ -0,0 +1,73 @@ +import { expect } from 'chai' +import { describe, it } from 'mocha' + +import { base64Decode, base64DecodeToBuffer, base64Encode } from '../../src/encodings/base64.js' +import { base64Decode as base64DecodeWeb, base64Encode as base64EncodeWeb } from '../../src/encodings/base64.web.js' + +describe('base64', () => { + it('should decode base64 string to existing buffer', () => { + const buf = new Uint8Array(4) + base64Decode(buf, 'AQIDBA==') + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should decode base64 string to new buffer', () => { + const buf = base64DecodeToBuffer('AQIDBA==') + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should encode buffer to base64 string', () => { + const buf = new Uint8Array([1, 2, 3, 4]) + expect(base64Encode(buf)).eq('AQIDBA==') + }) + + it('should decode url-safe base64 string to existing buffer', () => { + const buf = new Uint8Array(4) + base64Decode(buf, 'AQIDBA', true) + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should decode url-safe base64 string to new buffer', () => { + const buf = base64DecodeToBuffer('AQIDBA', true) + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should encode buffer to url-safe base64 string', () => { + const buf = new Uint8Array([1, 2, 3, 4]) + expect(base64Encode(buf, true)).eq('AQIDBA') + }) +}) + +describe('base64.web', () => { + it('should decode base64 string to existing buffer', () => { + const buf = new Uint8Array(4) + base64DecodeWeb(buf, 'AQIDBA==') + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should decode base64 string to new buffer', () => { + const buf = base64DecodeToBuffer('AQIDBA==') + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should encode buffer to base64 string', () => { + const buf = new Uint8Array([1, 2, 3, 4]) + expect(base64EncodeWeb(buf)).eq('AQIDBA==') + }) + + it('should decode url-safe base64 string to existing buffer', () => { + const buf = new Uint8Array(4) + base64DecodeWeb(buf, 'AQIDBA', true) + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should decode url-safe base64 string to new buffer', () => { + const buf = base64DecodeToBuffer('AQIDBA', true) + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should encode buffer to url-safe base64 string', () => { + const buf = new Uint8Array([1, 2, 3, 4]) + expect(base64EncodeWeb(buf, true)).eq('AQIDBA') + }) +}) diff --git a/packages/tl-runtime/tests/encodings/hex.spec.ts b/packages/tl-runtime/tests/encodings/hex.spec.ts new file mode 100644 index 00000000..a7245d37 --- /dev/null +++ b/packages/tl-runtime/tests/encodings/hex.spec.ts @@ -0,0 +1,41 @@ +import { expect } from 'chai' +import { describe, it } from 'mocha' + +import { hexDecode, hexDecodeToBuffer, hexEncode } from '../../src/encodings/hex.js' +import { hexDecode as hexDecodeWeb, hexDecodeToBuffer as hexDecodeToBufferWeb, hexEncode as hexEncodeWeb } from '../../src/encodings/hex.web.js' + +describe('hex', () => { + it('should decode hex string to existing buffer', () => { + const buf = new Uint8Array(4) + hexDecode(buf, '01020304') + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should decode hex string to new buffer', () => { + const buf = hexDecodeToBuffer('01020304') + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should encode buffer to hex string', () => { + const buf = new Uint8Array([1, 2, 3, 4]) + expect(hexEncode(buf)).eq('01020304') + }) +}) + +describe('hex.web', () => { + it('should decode hex string to existing buffer', () => { + const buf = new Uint8Array(4) + hexDecodeWeb(buf, '01020304') + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should decode hex string to new buffer', () => { + const buf = hexDecodeToBufferWeb('01020304') + expect(buf).eql(new Uint8Array([1, 2, 3, 4])) + }) + + it('should encode buffer to hex string', () => { + const buf = new Uint8Array([1, 2, 3, 4]) + expect(hexEncodeWeb(buf)).eq('01020304') + }) +}) diff --git a/packages/tl-runtime/tests/encodings/utf8.spec.ts b/packages/tl-runtime/tests/encodings/utf8.spec.ts new file mode 100644 index 00000000..42325a62 --- /dev/null +++ b/packages/tl-runtime/tests/encodings/utf8.spec.ts @@ -0,0 +1,66 @@ +import { expect } from 'chai' +import { describe, it } from 'mocha' + +import { byteLengthUtf8, utf8Decode, utf8Encode, utf8EncodeToBuffer } from '../../src/encodings/utf8.js' +import { + byteLengthUtf8 as byteLengthUtf8Web, + utf8Decode as utf8DecodeWeb, + utf8Encode as utf8EncodeWeb, + utf8EncodeToBuffer as utf8EncodeToBufferWeb, +} from '../../src/encodings/utf8.web.js' + +// since we use TextEncoder or native Buffer, we can skip testing the utf8 encoding itself +// we only need to test that the functions work as expected with offsets and lengths + +describe('utf8', () => { + it('should encode utf8 string into existing buffer', () => { + const buf = new Uint8Array(4) + utf8Encode(buf, 'abcd') + expect(buf).eql(new Uint8Array([97, 98, 99, 100])) + }) + + it('should encode utf8 string into new buffer', () => { + const buf = utf8EncodeToBuffer('abcd') + expect(buf).eql(new Uint8Array([97, 98, 99, 100])) + }) + + it('should decode utf8 string from existing buffer', () => { + const buf = new Uint8Array([97, 98, 99, 100]) + expect(utf8Decode(buf)).eq('abcd') + }) +}) + +describe('utf8.web', () => { + it('should encode utf8 string into existing buffer', () => { + const buf = new Uint8Array(4) + utf8EncodeWeb(buf, 'abcd') + expect(buf).eql(new Uint8Array([97, 98, 99, 100])) + }) + + it('should encode utf8 string into new buffer', () => { + const buf = utf8EncodeToBufferWeb('abcd') + expect(buf).eql(new Uint8Array([97, 98, 99, 100])) + }) + + it('should decode utf8 string from existing buffer', () => { + const buf = new Uint8Array([97, 98, 99, 100]) + expect(utf8DecodeWeb(buf)).eq('abcd') + }) +}) + +describe('byteLengthUtf8', () => { + it('should return byte length of utf8 string', () => { + expect(byteLengthUtf8('abcd')).eq(4) + }) + + it('should properly handle utf8 string with non-ascii characters', () => { + expect(byteLengthUtf8('абвг')).eq(8) + expect(byteLengthUtf8('🌸')).eq(4) + }) + + it('should work in web', () => { + expect(byteLengthUtf8Web('abcd')).eq(4) + expect(byteLengthUtf8Web('абвг')).eq(8) + expect(byteLengthUtf8Web('🌸')).eq(4) + }) +}) diff --git a/packages/tl-runtime/tests/tsconfig.json b/packages/tl-runtime/tests/tsconfig.json new file mode 100644 index 00000000..23b6b033 --- /dev/null +++ b/packages/tl-runtime/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + "." + ], + "references": [ + { "path": "../" } + ] +} diff --git a/packages/tl-runtime/tsconfig.json b/packages/tl-runtime/tsconfig.json index 7cd839c6..7f5a1406 100644 --- a/packages/tl-runtime/tsconfig.json +++ b/packages/tl-runtime/tsconfig.json @@ -1,10 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src" }, "include": [ - "./src", - "./tests", + "./src" ] } diff --git a/packages/tl-utils/package.json b/packages/tl-utils/package.json index 5985b3c2..7f1181f2 100644 --- a/packages/tl-utils/package.json +++ b/packages/tl-utils/package.json @@ -6,13 +6,11 @@ "author": "Alina Sireneva ", "license": "MIT", "main": "src/index.ts", + "type": "module", "scripts": { - "test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"", + "test": "mocha \"tests/**/*.spec.ts\"", "docs": "typedoc", - "build": "tsc" - }, - "browser": { - "./platform/gzip.js": "./platform/gzip.web.js" + "build": "pnpm run -w build-package tl-utils" }, "dependencies": { "crc-32": "1.2.0" diff --git a/packages/tl-utils/src/calculator.ts b/packages/tl-utils/src/calculator.ts index c16f7d77..10b2b86c 100644 --- a/packages/tl-utils/src/calculator.ts +++ b/packages/tl-utils/src/calculator.ts @@ -1,4 +1,4 @@ -import { TlEntry } from './types' +import { TlEntry } from './types.js' const PRIMITIVES_SIZES: Record = { int: 4, diff --git a/packages/tl-utils/src/codegen/errors.ts b/packages/tl-utils/src/codegen/errors.ts index 9d5d518c..f848d511 100644 --- a/packages/tl-utils/src/codegen/errors.ts +++ b/packages/tl-utils/src/codegen/errors.ts @@ -1,5 +1,5 @@ -import { TlErrors } from '../types' -import { snakeToCamel } from './utils' +import { TlErrors } from '../types.js' +import { snakeToCamel } from './utils.js' const TEMPLATE_JS = ` const _descriptionsMap = JSON.parse('{descriptionsMap}') @@ -31,7 +31,7 @@ RpcError.create = function(code, text) { var err = new RpcError(code, text, desc); if (!desc) { err.unknown = true; - } + } return err; } {statics} diff --git a/packages/tl-utils/src/codegen/reader.ts b/packages/tl-utils/src/codegen/reader.ts index de202000..1f552309 100644 --- a/packages/tl-utils/src/codegen/reader.ts +++ b/packages/tl-utils/src/codegen/reader.ts @@ -1,6 +1,6 @@ -import { computeConstructorIdFromEntry } from '../ctor-id' -import { TL_PRIMITIVES, TlEntry } from '../types' -import { snakeToCamel } from './utils' +import { computeConstructorIdFromEntry } from '../ctor-id.js' +import { TL_PRIMITIVES, TlEntry } from '../types.js' +import { snakeToCamel } from './utils.js' export interface ReaderCodegenOptions { /** diff --git a/packages/tl-utils/src/codegen/types.ts b/packages/tl-utils/src/codegen/types.ts index 7356bc32..8aeeb644 100644 --- a/packages/tl-utils/src/codegen/types.ts +++ b/packages/tl-utils/src/codegen/types.ts @@ -1,7 +1,7 @@ -import { TlEntry, TlErrors, TlFullSchema, TlTypeModifiers } from '../types' -import { groupTlEntriesByNamespace, splitNameToNamespace } from '../utils' -import { generateCodeForErrors } from './errors' -import { camelToPascal, indent, jsComment, snakeToCamel } from './utils' +import { TlEntry, TlErrors, TlFullSchema, TlTypeModifiers } from '../types.js' +import { groupTlEntriesByNamespace, splitNameToNamespace } from '../utils.js' +import { generateCodeForErrors } from './errors.js' +import { camelToPascal, indent, jsComment, snakeToCamel } from './utils.js' /** * Mapping of TL primitive types to TS types @@ -14,7 +14,7 @@ export const PRIMITIVE_TO_TS: Record = { int256: 'Int256', double: 'Double', string: 'string', - bytes: 'Buffer', + bytes: 'Uint8Array', Bool: 'boolean', true: 'boolean', null: 'null', @@ -186,9 +186,9 @@ export declare namespace $NS$ { function $extendTypes(types: Record): void type Long = _Long; - type RawLong = Buffer; - type Int128 = Buffer; - type Int256 = Buffer; + type RawLong = Uint8Array; + type Int128 = Uint8Array; + type Int256 = Uint8Array; type Double = number; type FindByName = Extract diff --git a/packages/tl-utils/src/codegen/writer.ts b/packages/tl-utils/src/codegen/writer.ts index 9f74defd..ae3622fa 100644 --- a/packages/tl-utils/src/codegen/writer.ts +++ b/packages/tl-utils/src/codegen/writer.ts @@ -1,7 +1,7 @@ -import { calculateStaticSizes } from '../calculator' -import { computeConstructorIdFromEntry } from '../ctor-id' -import { TL_PRIMITIVES, TlArgument, TlEntry } from '../types' -import { snakeToCamel } from './utils' +import { calculateStaticSizes } from '../calculator.js' +import { computeConstructorIdFromEntry } from '../ctor-id.js' +import { TL_PRIMITIVES, TlArgument, TlEntry } from '../types.js' +import { snakeToCamel } from './utils.js' export interface WriterCodegenOptions { /** diff --git a/packages/tl-utils/src/ctor-id.ts b/packages/tl-utils/src/ctor-id.ts index 3f45ee77..0c773fba 100644 --- a/packages/tl-utils/src/ctor-id.ts +++ b/packages/tl-utils/src/ctor-id.ts @@ -1,7 +1,7 @@ import CRC32 from 'crc-32' -import { writeTlEntryToString } from './stringify' -import { TlEntry } from './types' +import { writeTlEntryToString } from './stringify.js' +import { TlEntry } from './types.js' /** * Computes the constructor id for a given TL entry. diff --git a/packages/tl-utils/src/diff.ts b/packages/tl-utils/src/diff.ts index 1a259508..5d1ef2b0 100644 --- a/packages/tl-utils/src/diff.ts +++ b/packages/tl-utils/src/diff.ts @@ -1,6 +1,6 @@ -import { computeConstructorIdFromEntry } from './ctor-id' -import { TlArgument, TlArgumentDiff, TlEntry, TlEntryDiff, TlFullSchema, TlSchemaDiff } from './types' -import { stringifyArgumentType } from './utils' +import { computeConstructorIdFromEntry } from './ctor-id.js' +import { TlArgument, TlArgumentDiff, TlEntry, TlEntryDiff, TlFullSchema, TlSchemaDiff } from './types.js' +import { stringifyArgumentType } from './utils.js' /** * Compute difference between two TL entries. diff --git a/packages/tl-utils/src/index.ts b/packages/tl-utils/src/index.ts index 941a51f6..e2672d0f 100644 --- a/packages/tl-utils/src/index.ts +++ b/packages/tl-utils/src/index.ts @@ -1,14 +1,14 @@ -export * from './codegen/errors' -export * from './codegen/reader' -export * from './codegen/types' -export * from './codegen/utils' -export * from './codegen/writer' -export * from './ctor-id' -export * from './diff' -export * from './merge' -export * from './parse' -export * from './patch' -export * from './schema' -export * from './stringify' -export * from './types' -export * from './utils' +export * from './codegen/errors.js' +export * from './codegen/reader.js' +export * from './codegen/types.js' +export * from './codegen/utils.js' +export * from './codegen/writer.js' +export * from './ctor-id.js' +export * from './diff.js' +export * from './merge.js' +export * from './parse.js' +export * from './patch.js' +export * from './schema.js' +export * from './stringify.js' +export * from './types.js' +export * from './utils.js' diff --git a/packages/tl-utils/src/merge.ts b/packages/tl-utils/src/merge.ts index 527c7fbb..bac7c479 100644 --- a/packages/tl-utils/src/merge.ts +++ b/packages/tl-utils/src/merge.ts @@ -1,5 +1,5 @@ -import { computeConstructorIdFromEntry } from './ctor-id' -import { TlArgument, TlEntry, TlFullSchema } from './types' +import { computeConstructorIdFromEntry } from './ctor-id.js' +import { TlArgument, TlEntry, TlFullSchema } from './types.js' /** * Merge multiple TL entries into a single entry. diff --git a/packages/tl-utils/src/parse.ts b/packages/tl-utils/src/parse.ts index f0ddfb66..14f29b26 100644 --- a/packages/tl-utils/src/parse.ts +++ b/packages/tl-utils/src/parse.ts @@ -1,6 +1,6 @@ -import { computeConstructorIdFromEntry } from './ctor-id' -import { TL_PRIMITIVES, TlArgument, TlEntry } from './types' -import { parseArgumentType, parseTdlibStyleComment } from './utils' +import { computeConstructorIdFromEntry } from './ctor-id.js' +import { TL_PRIMITIVES, TlArgument, TlEntry } from './types.js' +import { parseArgumentType, parseTdlibStyleComment } from './utils.js' const SINGLE_REGEX = /^(.+?)(?:#([0-9a-f]{1,8}))?(?: \?)?(?: {(.+?:.+?)})? ((?:.+? )*)= (.+);$/ diff --git a/packages/tl-utils/src/patch.ts b/packages/tl-utils/src/patch.ts index 2b6980d9..3a9cea2e 100644 --- a/packages/tl-utils/src/patch.ts +++ b/packages/tl-utils/src/patch.ts @@ -1,8 +1,8 @@ import { TlReaderMap, TlWriterMap } from '@mtcute/tl-runtime' -import { generateReaderCodeForTlEntries } from './codegen/reader' -import { generateWriterCodeForTlEntries } from './codegen/writer' -import { parseTlToEntries } from './parse' +import { generateReaderCodeForTlEntries } from './codegen/reader.js' +import { generateWriterCodeForTlEntries } from './codegen/writer.js' +import { parseTlToEntries } from './parse.js' function evalForResult(js: string): T { // eslint-disable-next-line @typescript-eslint/no-implied-eval diff --git a/packages/tl-utils/src/schema.ts b/packages/tl-utils/src/schema.ts index 481d0d6f..e5511e5f 100644 --- a/packages/tl-utils/src/schema.ts +++ b/packages/tl-utils/src/schema.ts @@ -1,6 +1,6 @@ -import { computeConstructorIdFromEntry } from './ctor-id' -import { writeTlEntryToString } from './stringify' -import { TlEntry, TlFullSchema } from './types' +import { computeConstructorIdFromEntry } from './ctor-id.js' +import { writeTlEntryToString } from './stringify.js' +import { TlEntry, TlFullSchema } from './types.js' const replaceNewlineInComment = (s: string): string => s.replace(/\n/g, '\n//- ') diff --git a/packages/tl-utils/src/stringify.ts b/packages/tl-utils/src/stringify.ts index 3fd0d8c4..3664957e 100644 --- a/packages/tl-utils/src/stringify.ts +++ b/packages/tl-utils/src/stringify.ts @@ -1,5 +1,5 @@ -import { TlEntry } from './types' -import { stringifyArgumentType } from './utils' +import { TlEntry } from './types.js' +import { stringifyArgumentType } from './utils.js' function normalizeType(s: string): string { return s diff --git a/packages/tl-utils/src/utils.ts b/packages/tl-utils/src/utils.ts index c98fad73..c585185e 100644 --- a/packages/tl-utils/src/utils.ts +++ b/packages/tl-utils/src/utils.ts @@ -1,4 +1,4 @@ -import { TlEntry, TlTypeModifiers } from './types' +import { TlEntry, TlTypeModifiers } from './types.js' /** * Split qualified TL entry name into namespace and name diff --git a/packages/tl-utils/tests/calculator.spec.ts b/packages/tl-utils/tests/calculator.spec.ts index 91a976fe..eda76de3 100644 --- a/packages/tl-utils/tests/calculator.spec.ts +++ b/packages/tl-utils/tests/calculator.spec.ts @@ -1,8 +1,8 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { parseTlToEntries } from '../src' -import { calculateStaticSizes } from '../src/calculator' +import { calculateStaticSizes } from '../src/calculator.js' +import { parseTlToEntries } from '../src/parse.js' describe('calculateStaticSizes', () => { const test = (tl: string, expected: object) => { diff --git a/packages/tl-utils/tests/codegen/reader.spec.ts b/packages/tl-utils/tests/codegen/reader.spec.ts index c7488ada..5ad28666 100644 --- a/packages/tl-utils/tests/codegen/reader.spec.ts +++ b/packages/tl-utils/tests/codegen/reader.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { generateReaderCodeForTlEntry, parseTlToEntries } from '../../src' +import { generateReaderCodeForTlEntry, parseTlToEntries } from '../../src/index.js' describe('generateReaderCodeForTlEntry', () => { const test = (tl: string, ...js: string[]) => { diff --git a/packages/tl-utils/tests/codegen/types.spec.ts b/packages/tl-utils/tests/codegen/types.spec.ts index 31a2249a..b320a216 100644 --- a/packages/tl-utils/tests/codegen/types.spec.ts +++ b/packages/tl-utils/tests/codegen/types.spec.ts @@ -6,7 +6,7 @@ import { generateTypescriptDefinitionsForTlSchema, parseFullTlSchema, parseTlToEntries, -} from '../../src' +} from '../../src/index.js' describe('generateTypescriptDefinitionsForTlEntry', () => { const test = (tl: string, ...ts: string[]) => { @@ -23,7 +23,7 @@ describe('generateTypescriptDefinitionsForTlEntry', () => { ' b: Long;', ' c: Double;', ' d: string;', - ' e: Buffer;', + ' e: Uint8Array;', ' f: boolean;', ' g: number[];', '}', diff --git a/packages/tl-utils/tests/codegen/writer.spec.ts b/packages/tl-utils/tests/codegen/writer.spec.ts index 3d456370..54af0896 100644 --- a/packages/tl-utils/tests/codegen/writer.spec.ts +++ b/packages/tl-utils/tests/codegen/writer.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { generateWriterCodeForTlEntries, generateWriterCodeForTlEntry, parseTlToEntries } from '../../src' +import { generateWriterCodeForTlEntries, generateWriterCodeForTlEntry, parseTlToEntries } from '../../src/index.js' describe('generateWriterCodeForTlEntry', () => { const test = (tl: string, ...js: string[]) => { diff --git a/packages/tl-utils/tests/ctor-id.spec.ts b/packages/tl-utils/tests/ctor-id.spec.ts index 4cfc14fc..bf3fde4a 100644 --- a/packages/tl-utils/tests/ctor-id.spec.ts +++ b/packages/tl-utils/tests/ctor-id.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { computeConstructorIdFromEntry, TlArgument, TlEntry } from '../src' +import { computeConstructorIdFromEntry, TlArgument, TlEntry } from '../src/index.js' describe('computeConstructorIdFromEntry', () => { const make = (name: string, type: string, ...args: string[]): TlEntry => ({ diff --git a/packages/tl-utils/tests/diff.spec.ts b/packages/tl-utils/tests/diff.spec.ts index 20cefb91..037e2f48 100644 --- a/packages/tl-utils/tests/diff.spec.ts +++ b/packages/tl-utils/tests/diff.spec.ts @@ -1,10 +1,10 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { generateTlEntriesDifference, generateTlSchemasDifference } from '../src/diff' -import { parseTlToEntries } from '../src/parse' -import { parseFullTlSchema } from '../src/schema' -import { TlEntryDiff, TlSchemaDiff } from '../src/types' +import { generateTlEntriesDifference, generateTlSchemasDifference } from '../src/diff.js' +import { parseTlToEntries } from '../src/parse.js' +import { parseFullTlSchema } from '../src/schema.js' +import { TlEntryDiff, TlSchemaDiff } from '../src/types.js' describe('generateTlEntriesDifference', () => { const test = (tl: string[], expected: TlEntryDiff) => { diff --git a/packages/tl-utils/tests/merge.spec.ts b/packages/tl-utils/tests/merge.spec.ts index 4147d1d4..69b4a067 100644 --- a/packages/tl-utils/tests/merge.spec.ts +++ b/packages/tl-utils/tests/merge.spec.ts @@ -8,7 +8,7 @@ import { parseTlToEntries, writeTlEntriesToString, writeTlEntryToString, -} from '../src' +} from '../src/index.js' describe('mergeTlEntries', () => { const test = (tl: string, expected: string) => { diff --git a/packages/tl-utils/tests/parse.spec.ts b/packages/tl-utils/tests/parse.spec.ts index 0433c924..a57925c4 100644 --- a/packages/tl-utils/tests/parse.spec.ts +++ b/packages/tl-utils/tests/parse.spec.ts @@ -1,7 +1,7 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { parseTlToEntries, TlEntry } from '../src' +import { parseTlToEntries, TlEntry } from '../src/index.js' describe('tl parser', () => { const test = (tl: string, expected: TlEntry[], params?: Parameters[1]) => { diff --git a/packages/tl-utils/tests/schema.spec.ts b/packages/tl-utils/tests/schema.spec.ts index 69b69f38..ace5b87e 100644 --- a/packages/tl-utils/tests/schema.spec.ts +++ b/packages/tl-utils/tests/schema.spec.ts @@ -1,8 +1,8 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { writeTlEntriesToString } from '../src/schema' -import { TlEntry } from '../src/types' +import { writeTlEntriesToString } from '../src/schema.js' +import { TlEntry } from '../src/types.js' describe('writeTlEntriesToString', () => { const test = (entries: TlEntry[], params: Parameters[1], ...expected: string[]) => { diff --git a/packages/tl-utils/tests/stringify.spec.ts b/packages/tl-utils/tests/stringify.spec.ts index aae001f4..09a5b61d 100644 --- a/packages/tl-utils/tests/stringify.spec.ts +++ b/packages/tl-utils/tests/stringify.spec.ts @@ -1,8 +1,8 @@ import { expect } from 'chai' import { describe, it } from 'mocha' -import { writeTlEntryToString } from '../src/stringify' -import { TlArgument, TlEntry } from '../src/types' +import { writeTlEntryToString } from '../src/stringify.js' +import { TlArgument, TlEntry } from '../src/types.js' describe('writeTlEntryToString', () => { const make = (name: string, type: string, ...args: string[]): TlEntry => ({ diff --git a/packages/tl-utils/tests/tsconfig.json b/packages/tl-utils/tests/tsconfig.json new file mode 100644 index 00000000..23b6b033 --- /dev/null +++ b/packages/tl-utils/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "include": [ + "." + ], + "references": [ + { "path": "../" } + ] +} diff --git a/packages/tl-utils/tsconfig.json b/packages/tl-utils/tsconfig.json index f9556918..6a3f7a53 100644 --- a/packages/tl-utils/tsconfig.json +++ b/packages/tl-utils/tsconfig.json @@ -1,10 +1,10 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./dist/esm", + "rootDir": "./src" }, "include": [ - "./src/**/*.ts", - "./tests/**/*.ts" + "./src", ] } diff --git a/packages/tl/binary/reader.d.ts b/packages/tl/binary/reader.d.ts index 8e483c39..c452c020 100644 --- a/packages/tl/binary/reader.d.ts +++ b/packages/tl/binary/reader.d.ts @@ -1,5 +1,3 @@ -declare const __tlReaderMap: Record unknown> & { +export const __tlReaderMap: Record unknown> & { _results: Record unknown> } -// eslint-disable-next-line import/no-default-export -export default __tlReaderMap diff --git a/packages/tl/binary/rsa-keys.d.ts b/packages/tl/binary/rsa-keys.d.ts index 8b9751ec..ed4c28f7 100644 --- a/packages/tl/binary/rsa-keys.d.ts +++ b/packages/tl/binary/rsa-keys.d.ts @@ -35,6 +35,4 @@ export interface TlPublicKey { */ type TlPublicKeyIndex = Record -declare const __publicKeyIndex: TlPublicKeyIndex -// eslint-disable-next-line import/no-default-export -export default __publicKeyIndex +export const __publicKeyIndex: TlPublicKeyIndex diff --git a/packages/tl/binary/rsa-keys.js b/packages/tl/binary/rsa-keys.js index 2c253878..f586d0e5 100644 --- a/packages/tl/binary/rsa-keys.js +++ b/packages/tl/binary/rsa-keys.js @@ -1,4 +1,4 @@ // This file is auto-generated. Do not edit. "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.default=JSON.parse('{"b25898df208d2603":{"modulus":"c8c11d635691fac091dd9489aedced2932aa8a0bcefef05fa800892d9b52ed03200865c9e97211cb2ee6c7ae96d3fb0e15aeffd66019b44a08a240cfdd2868a85e1f54d6fa5deaa041f6941ddf302690d61dc476385c2fa655142353cb4e4b59f6e5b6584db76fe8b1370263246c010c93d011014113ebdf987d093f9d37c2be48352d69a1683f8f6e6c2167983c761e3ab169fde5daaa12123fa1beab621e4da5935e9c198f82f35eae583a99386d8110ea6bd1abb0f568759f62694419ea5f69847c43462abef858b4cb5edc84e7b9226cd7bd7e183aa974a712c079dde85b9dc063b8a5c08e8f859c0ee5dcd824c7807f20153361a7f63cfd2a433a1be7f5","exponent":"010001","fingerprint":"b25898df208d2603","old":false},"d09d1d85de64fd85":{"modulus":"e8bb3305c0b52c6cf2afdf7637313489e63e05268e5badb601af417786472e5f93b85438968e20e6729a301c0afc121bf7151f834436f7fda680847a66bf64accec78ee21c0b316f0edafe2f41908da7bd1f4a5107638eeb67040ace472a14f90d9f7c2b7def99688ba3073adb5750bb02964902a359fe745d8170e36876d4fd8a5d41b2a76cbff9a13267eb9580b2d06d10357448d20d9da2191cb5d8c93982961cdfdeda629e37f1fb09a0722027696032fe61ed663db7a37f6f263d370f69db53a0dc0a1748bdaaff6209d5645485e6e001d1953255757e4b8e42813347b11da6ab500fd0ace7e6dfa3736199ccaf9397ed0745a427dcfa6cd67bcb1acff3","exponent":"010001","fingerprint":"d09d1d85de64fd85","old":false},"0bc35f3509f7b7a5":{"modulus":"aeec36c8ffc109cb099624685b97815415657bd76d8c9c3e398103d7ad16c9bba6f525ed0412d7ae2c2de2b44e77d72cbf4b7438709a4e646a05c43427c7f184debf72947519680e651500890c6832796dd11f772c25ff8f576755afe055b0a3752c696eb7d8da0d8be1faf38c9bdd97ce0a77d3916230c4032167100edd0f9e7a3a9b602d04367b689536af0d64b613ccba7962939d3b57682beb6dae5b608130b2e52aca78ba023cf6ce806b1dc49c72cf928a7199d22e3d7ac84e47bc9427d0236945d10dbd15177bab413fbf0edfda09f014c7a7da088dde9759702ca760af2b8e4e97cc055c617bd74c3d97008635b98dc4d621b4891da9fb0473047927","exponent":"010001","fingerprint":"0bc35f3509f7b7a5","old":true},"15ae5fa8b5529542":{"modulus":"bdf2c77d81f6afd47bd30f29ac76e55adfe70e487e5e48297e5a9055c9c07d2b93b4ed3994d3eca5098bf18d978d54f8b7c713eb10247607e69af9ef44f38e28f8b439f257a11572945cc0406fe3f37bb92b79112db69eedf2dc71584a661638ea5becb9e23585074b80d57d9f5710dd30d2da940e0ada2f1b878397dc1a72b5ce2531b6f7dd158e09c828d03450ca0ff8a174deacebcaa22dde84ef66ad370f259d18af806638012da0ca4a70baa83d9c158f3552bc9158e69bf332a45809e1c36905a5caa12348dd57941a482131be7b2355a5f4635374f3bd3ddf5ff925bf4809ee27c1e67d9120c5fe08a9de458b1b4a3c5d0a428437f2beca81f4e2d5ff","exponent":"010001","fingerprint":"15ae5fa8b5529542","old":true},"aeae98e13cd7f94f":{"modulus":"b3f762b739be98f343eb1921cf0148cfa27ff7af02b6471213fed9daa0098976e667750324f1abcea4c31e43b7d11f1579133f2b3d9fe27474e462058884e5e1b123be9cbbc6a443b2925c08520e7325e6f1a6d50e117eb61ea49d2534c8bb4d2ae4153fabe832b9edf4c5755fdd8b19940b81d1d96cf433d19e6a22968a85dc80f0312f596bd2530c1cfb28b5fe019ac9bc25cd9c2a5d8a0f3a1c0c79bcca524d315b5e21b5c26b46babe3d75d06d1cd33329ec782a0f22891ed1db42a1d6c0dea431428bc4d7aabdcf3e0eb6fda4e23eb7733e7727e9a1915580796c55188d2596d2665ad1182ba7abf15aaa5a8b779ea996317a20ae044b820bff35b6e8a1","exponent":"010001","fingerprint":"aeae98e13cd7f94f","old":true},"5a181b2235057d98":{"modulus":"be6a71558ee577ff03023cfa17aab4e6c86383cff8a7ad38edb9fafe6f323f2d5106cbc8cafb83b869cffd1ccf121cd743d509e589e68765c96601e813dc5b9dfc4be415c7a6526132d0035ca33d6d6075d4f535122a1cdfe017041f1088d1419f65c8e5490ee613e16dbf662698c0f54870f0475fa893fc41eb55b08ff1ac211bc045ded31be27d12c96d8d3cfc6a7ae8aa50bf2ee0f30ed507cc2581e3dec56de94f5dc0a7abee0be990b893f2887bd2c6310a1e0a9e3e38bd34fded2541508dc102a9c9b4c95effd9dd2dfe96c29be647d6c69d66ca500843cfaed6e440196f1dbe0e2e22163c61ca48c79116fa77216726749a976a1c4b0944b5121e8c01","exponent":"010001","fingerprint":"5a181b2235057d98","old":true},"c3b42b026ce86b21":{"modulus":"c150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135a6f91f8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e580230e3ae97d95c8b19442b3c0a10d8f5633fecedd6926a7f6dab0ddb7d457f9ea81b8465fcd6fffeed114011df91c059caedaf97625f6c96ecc74725556934ef781d866b34f011fce4d835a090196e9a5f0e4449af7eb697ddb9076494ca5f81104a305b6dd27665722c46b60e5df680fb16b210607ef217652e60236c255f6a28315f4083a96791d7214bf64c1df4fd0db1944fb26a2a57031b32eee64ad15a8ba68885cde74a5bfc920f6abf59ba5c75506373e7130f9042da922179251f","exponent":"010001","fingerprint":"c3b42b026ce86b21","old":true},"9a996a1db11c729b":{"modulus":"c6aeda78b02a251db4b6441031f467fa871faed32526c436524b1fb3b5dca28efb8c089dd1b46d92c895993d87108254951c5f001a0f055f3063dcd14d431a300eb9e29517e359a1c9537e5e87ab1b116faecf5d17546ebc21db234d9d336a693efcb2b6fbcca1e7d1a0be414dca408a11609b9c4269a920b09fed1f9a1597be02761430f09e4bc48fcafbe289054c99dba51b6b5eb7d9c3a2ab4e490545b4676bd620e93804bcac93bf94f73f92c729ca899477ff17625ef14a934d51dc11d5f8650a3364586b3a52fcff2fedec8a8406cac4e751705a472e55707e3c8cd5594342b119c6c3293532d85dbe9271ed54a2fd18b4dc79c04a30951107d5639397","exponent":"010001","fingerprint":"9a996a1db11c729b","old":true},"b05b2a6f70cdea78":{"modulus":"b1066749655935f0a5936f517034c943bea7f3365a8931ae52c8bcb14856f004b83d26cf2839be0f22607470d67481771c1ce5ec31de16b20bbaa4ecd2f7d2ecf6b6356f27501c226984263edc046b89fb6d3981546b01d7bd34fedcfcc1058e2d494bda732ff813e50e1c6ae249890b225f82b22b1e55fcb063dc3c0e18e91c28d0c4aa627dec8353eee6038a95a4fd1ca984eb09f94aeb7a2220635a8ceb450ea7e61d915cdb4eecedaa083aa3801daf071855ec1fb38516cb6c2996d2d60c0ecbcfa57e4cf1fb0ed39b2f37e94ab4202ecf595e167b3ca62669a6da520859fb6d6c6203dfdfc79c75ec3ee97da8774b2da903e3435f2cd294670a75a526c1","exponent":"010001","fingerprint":"b05b2a6f70cdea78","old":true},"71e025b6c76033e3":{"modulus":"c2a8c55b4a62e2b78a19b91cf692bcdc4ba7c23fe4d06f194e2a0c30f6d9996f7d1a2bcc89bc1ac4333d44359a6c433252d1a8402d9970378b5912b75bc8cc3fa76710a025bcb9032df0b87d7607cc53b928712a174ea2a80a8176623588119d42ffce40205c6d72160860d8d80b22a8b8651907cf388effbef29cd7cf2b4eb8a872052da1351cfe7fec214ce48304ea472bd66329d60115b3420d08f6894b0410b6ab9450249967617670c932f7cbdb5d6fbcce1e492c595f483109999b2661fcdeec31b196429b7834c7211a93c6789d9ee601c18c39e521fda9d7264e61e518add6f0712d2d5228204b851e13c4f322e5c5431c3b7f31089668486aadc59f","exponent":"010001","fingerprint":"71e025b6c76033e3","old":true}}'); \ No newline at end of file +exports.__publicKeyIndex=JSON.parse('{"b25898df208d2603":{"modulus":"c8c11d635691fac091dd9489aedced2932aa8a0bcefef05fa800892d9b52ed03200865c9e97211cb2ee6c7ae96d3fb0e15aeffd66019b44a08a240cfdd2868a85e1f54d6fa5deaa041f6941ddf302690d61dc476385c2fa655142353cb4e4b59f6e5b6584db76fe8b1370263246c010c93d011014113ebdf987d093f9d37c2be48352d69a1683f8f6e6c2167983c761e3ab169fde5daaa12123fa1beab621e4da5935e9c198f82f35eae583a99386d8110ea6bd1abb0f568759f62694419ea5f69847c43462abef858b4cb5edc84e7b9226cd7bd7e183aa974a712c079dde85b9dc063b8a5c08e8f859c0ee5dcd824c7807f20153361a7f63cfd2a433a1be7f5","exponent":"010001","fingerprint":"b25898df208d2603","old":false},"d09d1d85de64fd85":{"modulus":"e8bb3305c0b52c6cf2afdf7637313489e63e05268e5badb601af417786472e5f93b85438968e20e6729a301c0afc121bf7151f834436f7fda680847a66bf64accec78ee21c0b316f0edafe2f41908da7bd1f4a5107638eeb67040ace472a14f90d9f7c2b7def99688ba3073adb5750bb02964902a359fe745d8170e36876d4fd8a5d41b2a76cbff9a13267eb9580b2d06d10357448d20d9da2191cb5d8c93982961cdfdeda629e37f1fb09a0722027696032fe61ed663db7a37f6f263d370f69db53a0dc0a1748bdaaff6209d5645485e6e001d1953255757e4b8e42813347b11da6ab500fd0ace7e6dfa3736199ccaf9397ed0745a427dcfa6cd67bcb1acff3","exponent":"010001","fingerprint":"d09d1d85de64fd85","old":false},"0bc35f3509f7b7a5":{"modulus":"aeec36c8ffc109cb099624685b97815415657bd76d8c9c3e398103d7ad16c9bba6f525ed0412d7ae2c2de2b44e77d72cbf4b7438709a4e646a05c43427c7f184debf72947519680e651500890c6832796dd11f772c25ff8f576755afe055b0a3752c696eb7d8da0d8be1faf38c9bdd97ce0a77d3916230c4032167100edd0f9e7a3a9b602d04367b689536af0d64b613ccba7962939d3b57682beb6dae5b608130b2e52aca78ba023cf6ce806b1dc49c72cf928a7199d22e3d7ac84e47bc9427d0236945d10dbd15177bab413fbf0edfda09f014c7a7da088dde9759702ca760af2b8e4e97cc055c617bd74c3d97008635b98dc4d621b4891da9fb0473047927","exponent":"010001","fingerprint":"0bc35f3509f7b7a5","old":true},"15ae5fa8b5529542":{"modulus":"bdf2c77d81f6afd47bd30f29ac76e55adfe70e487e5e48297e5a9055c9c07d2b93b4ed3994d3eca5098bf18d978d54f8b7c713eb10247607e69af9ef44f38e28f8b439f257a11572945cc0406fe3f37bb92b79112db69eedf2dc71584a661638ea5becb9e23585074b80d57d9f5710dd30d2da940e0ada2f1b878397dc1a72b5ce2531b6f7dd158e09c828d03450ca0ff8a174deacebcaa22dde84ef66ad370f259d18af806638012da0ca4a70baa83d9c158f3552bc9158e69bf332a45809e1c36905a5caa12348dd57941a482131be7b2355a5f4635374f3bd3ddf5ff925bf4809ee27c1e67d9120c5fe08a9de458b1b4a3c5d0a428437f2beca81f4e2d5ff","exponent":"010001","fingerprint":"15ae5fa8b5529542","old":true},"aeae98e13cd7f94f":{"modulus":"b3f762b739be98f343eb1921cf0148cfa27ff7af02b6471213fed9daa0098976e667750324f1abcea4c31e43b7d11f1579133f2b3d9fe27474e462058884e5e1b123be9cbbc6a443b2925c08520e7325e6f1a6d50e117eb61ea49d2534c8bb4d2ae4153fabe832b9edf4c5755fdd8b19940b81d1d96cf433d19e6a22968a85dc80f0312f596bd2530c1cfb28b5fe019ac9bc25cd9c2a5d8a0f3a1c0c79bcca524d315b5e21b5c26b46babe3d75d06d1cd33329ec782a0f22891ed1db42a1d6c0dea431428bc4d7aabdcf3e0eb6fda4e23eb7733e7727e9a1915580796c55188d2596d2665ad1182ba7abf15aaa5a8b779ea996317a20ae044b820bff35b6e8a1","exponent":"010001","fingerprint":"aeae98e13cd7f94f","old":true},"5a181b2235057d98":{"modulus":"be6a71558ee577ff03023cfa17aab4e6c86383cff8a7ad38edb9fafe6f323f2d5106cbc8cafb83b869cffd1ccf121cd743d509e589e68765c96601e813dc5b9dfc4be415c7a6526132d0035ca33d6d6075d4f535122a1cdfe017041f1088d1419f65c8e5490ee613e16dbf662698c0f54870f0475fa893fc41eb55b08ff1ac211bc045ded31be27d12c96d8d3cfc6a7ae8aa50bf2ee0f30ed507cc2581e3dec56de94f5dc0a7abee0be990b893f2887bd2c6310a1e0a9e3e38bd34fded2541508dc102a9c9b4c95effd9dd2dfe96c29be647d6c69d66ca500843cfaed6e440196f1dbe0e2e22163c61ca48c79116fa77216726749a976a1c4b0944b5121e8c01","exponent":"010001","fingerprint":"5a181b2235057d98","old":true},"c3b42b026ce86b21":{"modulus":"c150023e2f70db7985ded064759cfecf0af328e69a41daf4d6f01b538135a6f91f8f8b2a0ec9ba9720ce352efcf6c5680ffc424bd634864902de0b4bd6d49f4e580230e3ae97d95c8b19442b3c0a10d8f5633fecedd6926a7f6dab0ddb7d457f9ea81b8465fcd6fffeed114011df91c059caedaf97625f6c96ecc74725556934ef781d866b34f011fce4d835a090196e9a5f0e4449af7eb697ddb9076494ca5f81104a305b6dd27665722c46b60e5df680fb16b210607ef217652e60236c255f6a28315f4083a96791d7214bf64c1df4fd0db1944fb26a2a57031b32eee64ad15a8ba68885cde74a5bfc920f6abf59ba5c75506373e7130f9042da922179251f","exponent":"010001","fingerprint":"c3b42b026ce86b21","old":true},"9a996a1db11c729b":{"modulus":"c6aeda78b02a251db4b6441031f467fa871faed32526c436524b1fb3b5dca28efb8c089dd1b46d92c895993d87108254951c5f001a0f055f3063dcd14d431a300eb9e29517e359a1c9537e5e87ab1b116faecf5d17546ebc21db234d9d336a693efcb2b6fbcca1e7d1a0be414dca408a11609b9c4269a920b09fed1f9a1597be02761430f09e4bc48fcafbe289054c99dba51b6b5eb7d9c3a2ab4e490545b4676bd620e93804bcac93bf94f73f92c729ca899477ff17625ef14a934d51dc11d5f8650a3364586b3a52fcff2fedec8a8406cac4e751705a472e55707e3c8cd5594342b119c6c3293532d85dbe9271ed54a2fd18b4dc79c04a30951107d5639397","exponent":"010001","fingerprint":"9a996a1db11c729b","old":true},"b05b2a6f70cdea78":{"modulus":"b1066749655935f0a5936f517034c943bea7f3365a8931ae52c8bcb14856f004b83d26cf2839be0f22607470d67481771c1ce5ec31de16b20bbaa4ecd2f7d2ecf6b6356f27501c226984263edc046b89fb6d3981546b01d7bd34fedcfcc1058e2d494bda732ff813e50e1c6ae249890b225f82b22b1e55fcb063dc3c0e18e91c28d0c4aa627dec8353eee6038a95a4fd1ca984eb09f94aeb7a2220635a8ceb450ea7e61d915cdb4eecedaa083aa3801daf071855ec1fb38516cb6c2996d2d60c0ecbcfa57e4cf1fb0ed39b2f37e94ab4202ecf595e167b3ca62669a6da520859fb6d6c6203dfdfc79c75ec3ee97da8774b2da903e3435f2cd294670a75a526c1","exponent":"010001","fingerprint":"b05b2a6f70cdea78","old":true},"71e025b6c76033e3":{"modulus":"c2a8c55b4a62e2b78a19b91cf692bcdc4ba7c23fe4d06f194e2a0c30f6d9996f7d1a2bcc89bc1ac4333d44359a6c433252d1a8402d9970378b5912b75bc8cc3fa76710a025bcb9032df0b87d7607cc53b928712a174ea2a80a8176623588119d42ffce40205c6d72160860d8d80b22a8b8651907cf388effbef29cd7cf2b4eb8a872052da1351cfe7fec214ce48304ea472bd66329d60115b3420d08f6894b0410b6ab9450249967617670c932f7cbdb5d6fbcce1e492c595f483109999b2661fcdeec31b196429b7834c7211a93c6789d9ee601c18c39e521fda9d7264e61e518add6f0712d2d5228204b851e13c4f322e5c5431c3b7f31089668486aadc59f","exponent":"010001","fingerprint":"71e025b6c76033e3","old":true}}'); diff --git a/packages/tl/binary/writer.d.ts b/packages/tl/binary/writer.d.ts index 16f7910e..1e534ba5 100644 --- a/packages/tl/binary/writer.d.ts +++ b/packages/tl/binary/writer.d.ts @@ -1,6 +1,4 @@ -declare const __tlWriterMap: Record void> & { +export const __tlWriterMap: Record void> & { _bare: Record unknown> _staticSize: Record } -// eslint-disable-next-line import/no-default-export -export default __tlWriterMap diff --git a/packages/tl/package.json b/packages/tl/package.json index 79b81474..4b7146c3 100644 --- a/packages/tl/package.json +++ b/packages/tl/package.json @@ -7,16 +7,18 @@ "license": "MIT", "scripts": { "test": "tsc --noEmit --esModuleInterop tests/types.ts", - "fetch-mtp": "ts-node scripts/fetch-mtp.ts", - "fetch-api": "ts-node scripts/fetch-api.ts", - "fetch-errors": "ts-node scripts/fetch-errors.ts", - "docs-cli": "ts-node scripts/documentation.ts", - "gen-code": "ts-node scripts/gen-code.ts", - "gen-rsa": "ts-node scripts/gen-rsa-keys.ts", - "fetch-and-gen": "pnpm run fetch-api && pnpm run gen-code" + "fetch-mtp": "node --loader ts-node/esm scripts/fetch-mtp.ts", + "fetch-api": "node --loader ts-node/esm scripts/fetch-api.ts", + "fetch-errors": "node --loader ts-node/esm scripts/fetch-errors.ts", + "docs-cli": "node --loader ts-node/esm scripts/documentation.ts", + "gen-code": "node --loader ts-node/esm scripts/gen-code.ts", + "gen-rsa": "node --loader ts-node/esm scripts/gen-rsa-keys.ts", + "fetch-and-gen": "pnpm run fetch-api && pnpm run gen-code", + "build": "pnpm run -w build-package tl" }, "dependencies": { - "long": "5.2.3" + "long": "5.2.3", + "ts-node": "10.9.1" }, "devDependencies": { "@mtcute/core": "workspace:^1.0.0", diff --git a/packages/tl/scripts/constants.ts b/packages/tl/scripts/constants.ts index a0a82b64..422004a2 100644 --- a/packages/tl/scripts/constants.ts +++ b/packages/tl/scripts/constants.ts @@ -1,4 +1,7 @@ import { join } from 'path' +import * as url from 'url' + +export const __dirname = url.fileURLToPath(new URL('.', import.meta.url)) export const DOC_CACHE_FILE = join(__dirname, '.documentation.cache.json') export const DESCRIPTIONS_YAML_FILE = join(__dirname, '../data/descriptions.yaml') diff --git a/packages/tl/scripts/documentation.ts b/packages/tl/scripts/documentation.ts index 875f41ca..3eab1100 100644 --- a/packages/tl/scripts/documentation.ts +++ b/packages/tl/scripts/documentation.ts @@ -1,6 +1,7 @@ import * as cheerio from 'cheerio' import { readFile, writeFile } from 'fs/promises' import jsYaml from 'js-yaml' +import { fileURLToPath } from 'node:url' import { createInterface } from 'readline' import { @@ -19,10 +20,10 @@ import { COREFORK_DOMAIN, DESCRIPTIONS_YAML_FILE, DOC_CACHE_FILE, -} from './constants' -import { applyDescriptionsYamlFile } from './process-descriptions-yaml' -import { packTlSchema, TlPackedSchema, unpackTlSchema } from './schema' -import { fetchRetry } from './utils' +} from './constants.js' +import { applyDescriptionsYamlFile } from './process-descriptions-yaml.js' +import { packTlSchema, TlPackedSchema, unpackTlSchema } from './schema.js' +import { fetchRetry } from './utils.js' export interface CachedDocumentationEntry { comment?: string @@ -384,6 +385,15 @@ async function main() { } } -if (require.main === module) { - main().catch(console.error) +if (import.meta.url.startsWith('file:')) { + // (A) + const modulePath = fileURLToPath(import.meta.url) + + if (process.argv[1] === modulePath) { + // (B) + main().catch((err) => { + console.error(err) + process.exit(1) + }) + } } diff --git a/packages/tl/scripts/fetch-api.ts b/packages/tl/scripts/fetch-api.ts index dca3a279..b64e1626 100644 --- a/packages/tl/scripts/fetch-api.ts +++ b/packages/tl/scripts/fetch-api.ts @@ -9,7 +9,7 @@ import { readFile, writeFile } from 'fs/promises' import { join } from 'path' import * as readline from 'readline' -import { hasPresentKey, isPresent } from '@mtcute/core/utils' +import { hasPresentKey, isPresent } from '@mtcute/core/utils.js' import { generateTlSchemasDifference, mergeTlEntries, @@ -22,6 +22,7 @@ import { } from '@mtcute/tl-utils' import { + __dirname, API_SCHEMA_DIFF_JSON_FILE, API_SCHEMA_JSON_FILE, BLOGFORK_DOMAIN, @@ -30,12 +31,12 @@ import { TDESKTOP_LAYER, TDESKTOP_SCHEMA, TDLIB_SCHEMA, -} from './constants' -import { applyDocumentation, fetchDocumentation, getCachedDocumentation } from './documentation' -import { packTlSchema, TlPackedSchema, unpackTlSchema } from './schema' -import { fetchRetry } from './utils' +} from './constants.js' +import { applyDocumentation, fetchDocumentation, getCachedDocumentation } from './documentation.js' +import { packTlSchema, TlPackedSchema, unpackTlSchema } from './schema.js' +import { fetchRetry } from './utils.js' -import { bumpVersion } from '~scripts/version' +import { bumpVersion } from '~scripts/version.js' const README_MD_FILE = join(__dirname, '../README.md') const PACKAGE_JSON_FILE = join(__dirname, '../package.json') diff --git a/packages/tl/scripts/fetch-errors.ts b/packages/tl/scripts/fetch-errors.ts index bfe2c5bf..bbc30eb9 100644 --- a/packages/tl/scripts/fetch-errors.ts +++ b/packages/tl/scripts/fetch-errors.ts @@ -3,7 +3,7 @@ import { writeFile } from 'fs/promises' import { TlErrors } from '@mtcute/tl-utils' -import { ERRORS_JSON_FILE } from './constants' +import { ERRORS_JSON_FILE } from './constants.js' const ERRORS_PAGE_TG = 'https://corefork.telegram.org/api/errors' const ERRORS_PAGE_TELETHON = diff --git a/packages/tl/scripts/fetch-mtp.ts b/packages/tl/scripts/fetch-mtp.ts index c12463cc..530a851e 100644 --- a/packages/tl/scripts/fetch-mtp.ts +++ b/packages/tl/scripts/fetch-mtp.ts @@ -5,8 +5,8 @@ import { writeFile } from 'fs/promises' import { parseTlToEntries } from '@mtcute/tl-utils' -import { CORE_DOMAIN, MTP_SCHEMA_JSON_FILE } from './constants' -import { fetchRetry } from './utils' +import { CORE_DOMAIN, MTP_SCHEMA_JSON_FILE } from './constants.js' +import { fetchRetry } from './utils.js' async function fetchMtprotoSchema(): Promise { const html = await fetchRetry(`${CORE_DOMAIN}/schema/mtproto`) diff --git a/packages/tl/scripts/gen-code.ts b/packages/tl/scripts/gen-code.ts index 1eebbbf6..736f22bb 100644 --- a/packages/tl/scripts/gen-code.ts +++ b/packages/tl/scripts/gen-code.ts @@ -11,8 +11,8 @@ import { TlFullSchema, } from '@mtcute/tl-utils' -import { API_SCHEMA_JSON_FILE, ERRORS_JSON_FILE, ESM_PRELUDE, MTP_SCHEMA_JSON_FILE } from './constants' -import { TlPackedSchema, unpackTlSchema } from './schema' +import { __dirname, API_SCHEMA_JSON_FILE, ERRORS_JSON_FILE, ESM_PRELUDE, MTP_SCHEMA_JSON_FILE } from './constants.js' +import { TlPackedSchema, unpackTlSchema } from './schema.js' const OUT_TYPINGS_FILE = join(__dirname, '../index.d.ts') const OUT_TYPINGS_JS_FILE = join(__dirname, '../index.js') @@ -41,7 +41,7 @@ async function generateReaders(apiSchema: TlFullSchema, mtpSchema: TlFullSchema) variableName: 'm', }) code = code.substring(0, code.length - 1) + mtpCode.substring(8) - code += '\nexports.default = m;' + code += '\nexports.__tlReaderMap = m;' await writeFile(OUT_READERS_FILE, ESM_PRELUDE + code) } @@ -54,7 +54,7 @@ async function generateWriters(apiSchema: TlFullSchema, mtpSchema: TlFullSchema) includeStaticSizes: true, }) - code += '\nexports.default = m;' + code += '\nexports.__tlWriterMap = m;' await writeFile(OUT_WRITERS_FILE, ESM_PRELUDE + code) } diff --git a/packages/tl/scripts/gen-rsa-keys.ts b/packages/tl/scripts/gen-rsa-keys.ts index 76bb4906..05dbab3b 100644 --- a/packages/tl/scripts/gen-rsa-keys.ts +++ b/packages/tl/scripts/gen-rsa-keys.ts @@ -3,10 +3,11 @@ import { writeFile } from 'fs/promises' import { join } from 'path' import readline from 'readline' -import { NodeCryptoProvider, parsePublicKey } from '@mtcute/core/utils' +import { NodeCryptoProvider } from '@mtcute/core/src/utils/crypto/node-crypto.js' +import { parsePublicKey } from '@mtcute/core/utils.js' -import { TlPublicKey } from '../binary/rsa-keys' -import { ESM_PRELUDE } from './constants' +import { TlPublicKey } from '../binary/rsa-keys.js' +import { __dirname, ESM_PRELUDE } from './constants.js' const IN_TXT_FILE = join(__dirname, '.rsa-keys.txt') const OUT_JS_FILE = join(__dirname, '../binary/rsa-keys.js') diff --git a/packages/tl/scripts/package.json b/packages/tl/scripts/package.json new file mode 100644 index 00000000..089153bc --- /dev/null +++ b/packages/tl/scripts/package.json @@ -0,0 +1 @@ +{"type":"module"} diff --git a/packages/tl/scripts/process-descriptions-yaml.ts b/packages/tl/scripts/process-descriptions-yaml.ts index 6606ae03..1ef03113 100644 --- a/packages/tl/scripts/process-descriptions-yaml.ts +++ b/packages/tl/scripts/process-descriptions-yaml.ts @@ -1,4 +1,4 @@ -import { CachedDocumentation, CachedDocumentationEntry } from './documentation' +import { CachedDocumentation, CachedDocumentationEntry } from './documentation.js' type MaybeOverwrite = | string diff --git a/packages/tl/tests/types.ts b/packages/tl/tests/types.ts index 65b3c322..395e95f5 100644 --- a/packages/tl/tests/types.ts +++ b/packages/tl/tests/types.ts @@ -2,12 +2,12 @@ // This is a test for TypeScript typings // This file is never executed, only compiled -import readerMap from '../binary/reader' -import writerMap from '../binary/writer' -import { tl } from '../' +import { __tlReaderMap } from '../binary/reader.js' +import { __tlWriterMap } from '../binary/writer.js' +import { tl } from '../index.js' -readerMap[0].call(null, null) -writerMap['mt_message'].call(null, null, {}) +__tlReaderMap[0].call(null, null) +__tlWriterMap['mt_message'].call(null, null, {}) const error: tl.RpcError = tl.RpcError.create(400, 'BAD_REQUEST') diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 66cd9295..967f8804 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,6 +21,9 @@ importers: '@types/chai': specifier: 4.3.5 version: 4.3.5 + '@types/chai-spies': + specifier: ^1.0.4 + version: 1.0.4 '@types/mocha': specifier: 10.0.1 version: 10.0.1 @@ -42,6 +45,9 @@ importers: chai: specifier: 4.3.7 version: 4.3.7 + chai-spies: + specifier: ^1.0.0 + version: 1.0.0(chai@4.3.7) dotenv-flow: specifier: 3.2.0 version: 3.2.0 @@ -145,12 +151,15 @@ importers: specifier: 5.2.3 version: 5.2.3 devDependencies: - '@mtcute/dispatcher': - specifier: workspace:^1.0.0 - version: link:../dispatcher + '@cryptography/aes': + specifier: ^0.1.1 + version: 0.1.1 '@types/ws': specifier: 8.5.4 version: 8.5.4 + node-forge: + specifier: 1.3.1 + version: 1.3.1 ws: specifier: 8.13.0 version: 8.13.0 @@ -168,9 +177,6 @@ importers: '@mtcute/client': specifier: workspace:^1.0.0 version: link:../client - '@mtcute/core': - specifier: workspace:^1.0.0 - version: link:../core events: specifier: 3.2.0 version: 3.2.0 @@ -180,9 +186,6 @@ importers: '@mtcute/core': specifier: workspace:^1.0.0 version: link:../core - '@mtcute/tl-runtime': - specifier: workspace:^1.0.0 - version: link:../tl-runtime packages/html-parser: dependencies: @@ -211,6 +214,9 @@ importers: '@mtcute/client': specifier: workspace:^1.0.0 version: link:../client + '@mtcute/dispatcher': + specifier: workspace:^1.0.0 + version: link:../dispatcher packages/markdown-parser: dependencies: @@ -239,9 +245,6 @@ importers: '@mtcute/client': specifier: workspace:^1.0.0 version: link:../client - '@mtcute/core': - specifier: workspace:^1.0.0 - version: link:../core '@mtcute/dispatcher': specifier: workspace:^1.0.0 version: link:../dispatcher @@ -276,9 +279,6 @@ importers: specifier: 8.4.0 version: 8.4.0 devDependencies: - '@mtcute/dispatcher': - specifier: workspace:^1.0.0 - version: link:../dispatcher '@types/better-sqlite3': specifier: 7.6.4 version: 7.6.4 @@ -288,6 +288,9 @@ importers: long: specifier: 5.2.3 version: 5.2.3 + ts-node: + specifier: 10.9.1 + version: 10.9.1(@types/node@18.16.0)(typescript@5.0.4) devDependencies: '@mtcute/core': specifier: workspace:^1.0.0 @@ -703,12 +706,15 @@ packages: chalk: 4.1.2 dev: true + /@cryptography/aes@0.1.1: + resolution: {integrity: sha512-PcYz4FDGblO6tM2kSC+VzhhK62vml6k6/YAkiWtyPvrgJVfnDRoHGDtKn5UiaRRUrvUTTocBpvc2rRgTCqxjsg==} + dev: true + /@cspotcode/source-map-support@0.8.1: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} dependencies: '@jridgewell/trace-mapping': 0.3.9 - dev: true /@eslint-community/eslint-utils@4.4.0(eslint@8.47.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} @@ -815,7 +821,6 @@ packages: /@jridgewell/resolve-uri@3.0.6: resolution: {integrity: sha512-R7xHtBSNm+9SyvpJkdQl+qrM3Hm2fea3Ef197M3mUug+v+yR+Rhfbs7PBtcBUVnIWJ4JcAdjvij+c8hXS9p5aw==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/set-array@1.1.0: resolution: {integrity: sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg==} @@ -824,14 +829,12 @@ packages: /@jridgewell/sourcemap-codec@1.4.11: resolution: {integrity: sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==} - dev: true /@jridgewell/trace-mapping@0.3.9: resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} dependencies: '@jridgewell/resolve-uri': 3.0.6 '@jridgewell/sourcemap-codec': 1.4.11 - dev: true /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -889,19 +892,15 @@ packages: /@tsconfig/node10@1.0.8: resolution: {integrity: sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==} - dev: true /@tsconfig/node12@1.0.9: resolution: {integrity: sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==} - dev: true /@tsconfig/node14@1.0.1: resolution: {integrity: sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==} - dev: true /@tsconfig/node16@1.0.2: resolution: {integrity: sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==} - dev: true /@types/better-sqlite3@7.6.4: resolution: {integrity: sha512-dzrRZCYPXIXfSR1/surNbJ/grU3scTaygS0OMzjlGf71i9sc2fGyHPXXiXmEvNIoE0cGwsanEFMVJxPXmco9Eg==} @@ -909,6 +908,12 @@ packages: '@types/node': 18.16.0 dev: true + /@types/chai-spies@1.0.4: + resolution: {integrity: sha512-HCG1EUGpVYmmqIG9rnSIxkng/tOzARG1HmUIV5miCp55ykqxSnVj2vlXaf6nDwaMm7qzkvNe9SHW15ywPKDqTA==} + dependencies: + '@types/chai': 4.3.5 + dev: true + /@types/chai@4.3.5: resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} dev: true @@ -1118,19 +1123,11 @@ packages: /acorn-walk@8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} - dev: true /acorn@8.10.0: resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} engines: {node: '>=0.4.0'} hasBin: true - dev: true - - /acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -1270,7 +1267,6 @@ packages: /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - dev: true /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -1511,6 +1507,15 @@ packages: resolution: {integrity: sha512-kbaCEBRRVSoeNs74sCuq92MJyGrMtjWVfhltoHUCW4t4pXFvGjUBrfo47weBRViHkiV3eBYyIsfl956NtHGazw==} dev: true + /chai-spies@1.0.0(chai@4.3.7): + resolution: {integrity: sha512-elF2ZUczBsFoP07qCfMO/zeggs8pqCf3fZGyK5+2X4AndS8jycZYID91ztD9oQ7d/0tnS963dPkd0frQEThDsg==} + engines: {node: '>= 4.0.0'} + peerDependencies: + chai: '*' + dependencies: + chai: 4.3.7 + dev: true + /chai@4.3.7: resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} engines: {node: '>=4'} @@ -1794,7 +1799,6 @@ packages: /create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - dev: true /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} @@ -1931,7 +1935,6 @@ packages: /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} - dev: true /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} @@ -3605,7 +3608,6 @@ packages: /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - dev: true /make-fetch-happen@10.1.2: resolution: {integrity: sha512-GWMGiZsKVeJACQGJ1P3Z+iNec7pLsU6YW1q11eaPn3RR8nRXHppFWfP7Eu0//55JK3hSjrAQRl8sDa5uXpq1Ew==} @@ -5072,7 +5074,7 @@ packages: '@tsconfig/node14': 1.0.1 '@tsconfig/node16': 1.0.2 '@types/node': 18.16.0 - acorn: 8.8.2 + acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 @@ -5081,7 +5083,6 @@ packages: typescript: 5.0.4 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 - dev: true /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} @@ -5184,7 +5185,6 @@ packages: resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} engines: {node: '>=12.20'} hasBin: true - dev: true /typescript@5.2.2: resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} @@ -5235,7 +5235,6 @@ packages: /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - dev: true /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -5449,7 +5448,6 @@ packages: /yn@3.1.1: resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} engines: {node: '>=6'} - dev: true /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 924b55f4..e6912143 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - packages/* + - '!e2e/*' diff --git a/scripts/build-package.js b/scripts/build-package.js new file mode 100644 index 00000000..1907e531 --- /dev/null +++ b/scripts/build-package.js @@ -0,0 +1,265 @@ +const cp = require('child_process') +const path = require('path') +const fs = require('fs') +const glob = require('glob') + +if (process.argv.length < 3) { + console.log('Usage: build-package.js ') + process.exit(0) +} + +const packageDir = path.join(__dirname, '../packages', process.argv[2]) +const BUILD_CONFIGS = { + tl: { + buildTs: false, + buildCjs: false, + customScript(packageDir, outDir) { + // create package by copying all the needed files + const files = [ + 'binary/reader.d.ts', + 'binary/reader.js', + 'binary/rsa-keys.d.ts', + 'binary/rsa-keys.js', + 'binary/writer.d.ts', + 'binary/writer.js', + 'index.d.ts', + 'index.js', + 'raw-errors.json', + 'mtp-schema.json', + 'api-schema.json', + ] + + fs.mkdirSync(path.join(outDir, 'binary'), { recursive: true }) + + for (const f of files) { + fs.copyFileSync(path.join(packageDir, f), path.join(outDir, f)) + } + }, + }, + core: { + esmOnlyDirectives: true, + customScript(packageDir, outDir) { + const version = require(path.join(packageDir, 'package.json')).version + const replaceVersion = (content) => content.replace('%VERSION%', version) + + transformFile(path.join(outDir, 'cjs/network/network-manager.js'), replaceVersion) + transformFile(path.join(outDir, 'esm/network/network-manager.js'), replaceVersion) + }, + }, + client: { + esmOnlyDirectives: true, + customScript(packageDir, outDir) { + function fixClient(file) { + // make TelegramClient a class, not an interface + const dTsContent = fs.readFileSync(path.join(outDir, file), 'utf8') + + fs.writeFileSync( + path.join(outDir, file), + dTsContent.replace('export interface TelegramClient', 'export class TelegramClient'), + ) + } + + fixClient('esm/client.d.ts') + fixClient('cjs/client.d.ts') + }, + }, + 'crypto-node': { + customScript(packageDir, outDir) { + // copy native sources and binding.gyp file + + fs.mkdirSync(path.join(outDir, 'lib'), { recursive: true }) + fs.mkdirSync(path.join(outDir, 'crypto'), { recursive: true }) + + const bindingGyp = fs.readFileSync(path.join(packageDir, 'binding.gyp'), 'utf8') + fs.writeFileSync( + path.join(outDir, 'binding.gyp'), + bindingGyp + // replace paths to crypto + .replace(/"\.\.\/crypto/g, '"crypto'), + ) + + for (const f of fs.readdirSync(path.join(packageDir, 'lib'))) { + const content = fs.readFileSync(path.join(packageDir, 'lib', f), 'utf8') + + fs.writeFileSync( + path.join(outDir, 'lib', f), + content + // replace paths to crypto + .replace(/#include "\.\.\/\.\.\/crypto/g, '#include "../crypto'), + ) + } + + for (const f of fs.readdirSync(path.join(packageDir, '../crypto'))) { + fs.copyFileSync(path.join(packageDir, '../crypto', f), path.join(outDir, 'crypto', f)) + } + + // for some unknown fucking reason ts doesn't do this + fs.copyFileSync(path.join(packageDir, 'src/native.cjs'), path.join(outDir, 'cjs/native.cjs')) + fs.copyFileSync(path.join(packageDir, 'src/native.cjs'), path.join(outDir, 'esm/native.cjs')) + }, + }, + node: { esmOnlyDirectives: true }, +} + +const buildConfig = { + buildTs: true, + buildCjs: true, + removeReferenceComments: true, + replaceSrcImports: true, + esmOnlyDirectives: false, + customScript: () => {}, + ...BUILD_CONFIGS[process.argv[2]], +} + +function buildPackageJson() { + const pkgJson = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json'), 'utf-8')) + + if (buildConfig.buildCjs) { + pkgJson.main = 'cjs/index.js' + pkgJson.module = 'esm/index.js' + } + + const newScripts = {} + + if (pkgJson.keepScripts) { + for (const script of pkgJson.keepScripts) { + newScripts[script] = pkgJson.scripts[script] + } + delete pkgJson.keepScripts + } + pkgJson.scripts = newScripts + delete pkgJson.devDependencies + delete pkgJson.private + + if (pkgJson.distOnlyFields) { + Object.assign(pkgJson, pkgJson.distOnlyFields) + delete pkgJson.distOnlyFields + } + + function replaceWorkspaceDependencies(field) { + if (!pkgJson[field]) return + + const dependencies = pkgJson[field] + + for (const name of Object.keys(dependencies)) { + const value = dependencies[name] + + if (value.startsWith('workspace:')) { + dependencies[name] = value.replace('workspace:', '') + } + } + } + + replaceWorkspaceDependencies('dependencies') + replaceWorkspaceDependencies('devDependencies') + replaceWorkspaceDependencies('peerDependencies') + replaceWorkspaceDependencies('optionalDependencies') + + delete pkgJson.typedoc + + fs.writeFileSync(path.join(packageDir, 'dist/package.json'), JSON.stringify(pkgJson, null, 2)) +} + +function exec(cmd) { + cp.execSync(cmd, { cwd: packageDir, stdio: 'inherit' }) +} + +function transformFile(file, transform) { + const content = fs.readFileSync(file, 'utf8') + fs.writeFileSync(file, transform(content)) +} + +const outDir = path.join(packageDir, 'dist') + +// clean +fs.rmSync(path.join(outDir), { recursive: true, force: true }) +fs.mkdirSync(path.join(outDir), { recursive: true }) + +if (buildConfig.buildTs) { + console.log('[i] Building typescript...') + exec('pnpm exec tsc --build', { cwd: packageDir, stdio: 'inherit' }) + + if (buildConfig.buildCjs) { + console.log('[i] Building typescript (CJS)...') + const originalFiles = {} + + if (buildConfig.esmOnlyDirectives) { + for (const f of glob.sync(path.join(packageDir, '**/*.ts'))) { + const content = fs.readFileSync(f, 'utf8') + if (!content.includes('@only-if-esm')) continue + originalFiles[f] = content + + fs.writeFileSync(f, content.replace(/@only-if-esm.*?@\/only-if-esm/gs, '')) + } + } + + let error = false + + try { + exec('pnpm exec tsc --module commonjs --outDir dist/cjs', { cwd: packageDir, stdio: 'inherit' }) + } catch (e) { + error = e + } + + for (const f of Object.keys(originalFiles)) { + fs.writeFileSync(f, originalFiles[f]) + } + + if (error) throw error + } + + console.log('[i] Post-processing...') + + if (buildConfig.removeReferenceComments) { + for (const f of glob.sync(path.join(outDir, '**/*.d.ts'))) { + let content = fs.readFileSync(f, 'utf8') + let changed = false + + if (content.indexOf('/// ') !== -1) { + changed = true + content = content.replace('/// ', '') + } + + if (content.match(/@mtcute\/[a-z-]+\/src/)) { + changed = true + content = content.replace(/(@mtcute\/[a-z-]+)\/src/g, '$1') + } + + if (changed) fs.writeFileSync(f, content) + } + } + + if (buildConfig.replaceSrcImports) { + for (const f of glob.sync(path.join(outDir, '**/*.js'))) { + let content = fs.readFileSync(f, 'utf8') + let changed = false + + if (content.match(/@mtcute\/[a-z-]+\/src/)) { + changed = true + content = content.replace(/(@mtcute\/[a-z-]+)\/src/g, '$1') + } + + if (changed) fs.writeFileSync(f, content) + } + } +} + +console.log('[i] Copying files...') + +if (buildConfig.buildCjs) { + fs.writeFileSync(path.join(outDir, 'cjs/package.json'), JSON.stringify({ type: 'commonjs' }, null, 2)) +} + +buildPackageJson() + +try { + fs.cpSync(path.join(packageDir, 'README.md'), path.join(outDir, 'README.md')) +} catch (e) { + console.log('[!] Failed to copy README.md: ' + e.message) +} + +fs.writeFileSync(path.join(outDir, '.npmignore'), '*.tsbuildinfo\n') + +buildConfig.customScript(packageDir, outDir) + +console.log('[v] Done!') diff --git a/scripts/gen-deps-graph.mjs b/scripts/gen-deps-graph.mjs new file mode 100644 index 00000000..5072beec --- /dev/null +++ b/scripts/gen-deps-graph.mjs @@ -0,0 +1,38 @@ +// node scripts/gen-deps-graph.mjs | dot -Tsvg > deps.svg +import { getPackageJsons } from './utils.mjs' + +const packageJsons = await getPackageJsons() + +function getMtcuteName(name) { + if (!name.startsWith('@mtcute/')) return null + + return name.slice(8) +} + +const output = [] + +for (const pkg of packageJsons) { + if (!pkg) continue + + const name = getMtcuteName(pkg.name) + + if (!name) continue + + for (const dep of Object.keys(pkg.dependencies || {})) { + const depName = getMtcuteName(dep) + if (!depName) continue + + output.push(`"${name}" -> "${depName}"`) + } + + for (const dep of Object.keys(pkg.devDependencies || {})) { + const depName = getMtcuteName(dep) + if (!depName) continue + + output.push(`"${name}" -> "${depName}" [style=dashed,color=grey]`) + } +} + +console.log('digraph {') +console.log(output.join('\n')) +console.log('}') diff --git a/scripts/publish.js b/scripts/publish.js index c8482966..72c3ded1 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -1,267 +1,111 @@ const fs = require('fs') const path = require('path') -const glob = require('glob') const cp = require('child_process') -const rimraf = require('rimraf') -function publishSinglePackage(name) { - let dir = path.join(__dirname, '../packages', name) +// const REGISTRY = 'https://registry.npmjs.org' +const REGISTRY = process.env.REGISTRY || 'https://npm.tei.su/' +exports.REGISTRY = REGISTRY + +async function checkVersion(name, version, retry = 0) { + return fetch(`${REGISTRY}@mtcute/${name}/${version}`) + .then((r) => r.status === 200) + .catch((err) => { + if (retry >= 5) throw err + + // for whatever reason this request sometimes fails with ECONNRESET + // no idea why, probably some issue in orbstack networking + console.log('[i] Error checking version:') + console.log(err) + + return new Promise((resolve) => setTimeout(resolve, 1000)).then(() => + checkVersion(name, version, retry + 1), + ) + }) +} + +async function publishSinglePackage(name) { + let packageDir = path.join(__dirname, '../packages', name) console.log('[i] Building %s', name) - // cleanup dist folder - rimraf.sync(path.join(dir, 'dist')) - if (name === 'tl') { - // create package by copying all the needed files - const files = [ - 'binary/reader.d.ts', - 'binary/reader.js', - 'binary/rsa-keys.d.ts', - 'binary/rsa-keys.js', - 'binary/writer.d.ts', - 'binary/writer.js', - 'index.d.ts', - 'index.js', - 'raw-errors.json', - 'mtp-schema.json', - 'api-schema.json', - 'package.json', - 'README.md', - ] - - fs.mkdirSync(path.join(dir, 'dist/binary'), { recursive: true }) - - for (const f of files) { - fs.copyFileSync(path.join(dir, f), path.join(dir, 'dist', f)) - } - } else { - // build ts - cp.execSync( - 'pnpm run build', - { - cwd: dir, - stdio: 'inherit', - }, - ) - - // remove reference comments - for (const f of glob.sync(path.join(dir, 'dist/**/*.d.ts'))) { - let content = fs.readFileSync(f, 'utf8') - let changed = false - - if (content.indexOf('/// ') !== -1) { - changed = true - content = content.replace('/// ', '') - } - - if (content.match(/@mtcute\/[a-z-]+\/src/)) { - changed = true - content = content.replace(/(@mtcute\/[a-z-]+)\/src/g, '$1') - } - - if (changed) fs.writeFileSync(f, content) - } - - // replace /src/ imports - for (const f of glob.sync(path.join(dir, 'dist/**/*.js'))) { - let content = fs.readFileSync(f, 'utf8') - let changed = false - - if (content.match(/@mtcute\/[a-z-]+\/src/)) { - changed = true - content = content.replace(/(@mtcute\/[a-z-]+)\/src/g, '$1') - } - - if (changed) fs.writeFileSync(f, content) - } - - if (name === 'client') { - // // make TelegramClient a class, not an interface - // const dTsContent = fs.readFileSync( - // path.join(dir, 'dist/client.d.ts'), - // 'utf8' - // ) - // - // fs.writeFileSync( - // path.join(dir, 'dist/client.d.ts'), - // dTsContent.replace( - // 'export interface TelegramClient', - // 'export class TelegramClient' - // ) - // ) - - // make methods prototype methods, not properties - let jsContent = fs.readFileSync( - path.join(dir, 'dist/client.js'), - 'utf8', - ) - - let methods = [] - jsContent = jsContent.replace( - /^\s*this\.([a-zA-Z0-9_]+) = ([a-zA-Z0-9_]+\.[a-zA-Z0-9_]+);\r?\n/gm, - (_, name, imported) => { - methods.push( - `TelegramClient.prototype.${name} = ${imported};`, - ) - - return '' - }, - ) - - const idx = jsContent.indexOf( - 'exports.TelegramClient = TelegramClient;', - ) - - if (idx === -1) { throw new Error('client.js exports.TelegramClient not found') } - - jsContent = - jsContent.substring(0, idx) + - methods.join('\n') + - '\n' + - jsContent.substring(idx) - - fs.writeFileSync(path.join(dir, 'dist/client.js'), jsContent) - } - - if (name === 'crypto-node') { - // copy native sources and binding.gyp file - - fs.mkdirSync(path.join(dir, 'dist/lib'), { recursive: true }) - fs.mkdirSync(path.join(dir, 'dist/crypto'), { recursive: true }) - - const bindingGyp = fs.readFileSync( - path.join(dir, 'binding.gyp'), - 'utf8', - ) - fs.writeFileSync( - path.join(dir, 'dist/binding.gyp'), - bindingGyp - // replace paths to crypto - .replace(/"\.\.\/crypto/g, '"crypto'), - ) - - for (const f of fs.readdirSync(path.join(dir, 'lib'))) { - const content = fs.readFileSync( - path.join(dir, 'lib', f), - 'utf8', - ) - - fs.writeFileSync( - path.join(dir, 'dist/lib', f), - content - // replace paths to crypto - .replace( - /#include "\.\.\/\.\.\/crypto/g, - '#include "../crypto', - ), - ) - } - - for (const f of fs.readdirSync(path.join(dir, '../crypto'))) { - fs.copyFileSync( - path.join(dir, '../crypto', f), - path.join(dir, 'dist/crypto', f), - ) - } - - const nativeJs = fs.readFileSync( - path.join(dir, 'dist/native.js'), - 'utf8', - ) - - fs.writeFileSync( - path.join(dir, 'dist/native.js'), - nativeJs.replace(/'\.\.\/build/g, "'./build"), - ) - } - } - - // copy package.json, replacing private with false - const packJson = JSON.parse( - fs.readFileSync(path.join(dir, 'package.json'), 'utf8'), - ) - - if (!packJson.main) { throw new Error(`${name}'s package.json does not contain "main"`) } - - // since "src" is compiled to "dist", we need to remove that prefix - packJson.main = packJson.main - .replace(/^(?:\.\/)?src\//, '') - .replace(/\.ts$/, '.js') - packJson.private = false - - function replaceWorkspaceDependencies(field) { - if (packJson[field]) { - const dependencies = packJson[field] - - for (const name of Object.keys(dependencies)) { - const value = dependencies[name] - - if (value.startsWith('workspace:')) { - dependencies[name] = value.replace('workspace:', '') - } - } - } - } - - replaceWorkspaceDependencies('dependencies') - replaceWorkspaceDependencies('devDependencies') - replaceWorkspaceDependencies('peerDependencies') - replaceWorkspaceDependencies('optionalDependencies') - - fs.writeFileSync( - path.join(dir, 'dist/package.json'), - JSON.stringify(packJson, null, 4), - ) - - // copy tsconfig - try { - fs.copyFileSync( - path.join(__dirname, '../tsconfig.json'), - path.join(dir, 'dist/tsconfig.json'), - ) - } catch (e) { - if (e.code !== 'ENOENT') throw e - } - - // copy readme - try { - fs.copyFileSync( - path.join(dir, 'README.md'), - path.join(dir, 'dist/README.md'), - ) - } catch (e) { - if (e.code !== 'ENOENT') throw e - } - - dir = path.join(dir, 'dist') + // run build script + cp.execSync('pnpm run build', { + cwd: packageDir, + stdio: 'inherit', + }) console.log('[i] Publishing %s', name) + if (process.env.E2E) { + const version = require(path.join(packageDir, 'dist/package.json')).version + + const exists = await checkVersion(name, version) + + if (exists) { + console.log('[i] %s already exists, unpublishing..', name) + cp.execSync(`npm unpublish --registry ${REGISTRY} --force @mtcute/${name}`, { + cwd: path.join(packageDir, 'dist'), + stdio: 'inherit', + }) + } + } + // publish to npm - cp.execSync('npm publish', { - cwd: dir, + cp.execSync(`npm publish --registry ${REGISTRY} --force -q`, { + cwd: path.join(packageDir, 'dist'), stdio: 'inherit', }) } const LOCAL = ['crypto'] -if (require.main === module) { - const arg = process.argv[2] +function listPackages() { + const packages = [] + for (const f of fs.readdirSync(path.join(__dirname, '../packages'))) { + if (LOCAL.indexOf(f) > -1) continue + if (f[0] === '.') continue + + packages.push(f) + } + + return packages +} + +exports.listPackages = listPackages + +async function main(arg = process.argv[2]) { if (!arg) { - console.log('Usage: publish.js ') + console.log('Usage: publish.js ') process.exit(0) } - if (arg === 'all') { - for (const f of fs.readdirSync(path.join(__dirname, '../packages'))) { - if (LOCAL.indexOf(f) > -1) continue - if (f[0] === '.') continue + console.log('[i] Using registry %s', REGISTRY) - publishSinglePackage(f) + if (arg === 'all' || arg === 'updated') { + for (const pkg of listPackages()) { + if (arg === 'updated') { + const pkgVersion = require(`../packages/${pkg}/package.json`).version + const published = await checkVersion(pkg, pkgVersion) + + if (published) { + console.log('[i] %s is up to date', pkg) + continue + } + } + + await publishSinglePackage(pkg) } } else { - publishSinglePackage(arg) + await publishSinglePackage(arg) } } + +exports.main = main + +if (require.main === module) { + main().catch((e) => { + console.error(e) + process.exit(1) + }) +} diff --git a/scripts/utils.mjs b/scripts/utils.mjs index 4c847146..a91ff53e 100644 --- a/scripts/utils.mjs +++ b/scripts/utils.mjs @@ -24,5 +24,5 @@ export async function getPackageJsons(includeRoot = false) { if (includeRoot) packages.push('$root') - return Promise.all(packages.map(tryParsePackageJson)) + return Promise.all(packages.map(tryParsePackageJson)).then((f) => f.filter(Boolean)) } diff --git a/tsconfig.json b/tsconfig.json index 32036028..c87d5ebd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,8 @@ { "compilerOptions": { "outDir": "./dist", - "module": "commonjs", + "module": "NodeNext", + "moduleResolution": "NodeNext", "target": "es2020", "allowJs": true, "sourceMap": true, @@ -18,15 +19,14 @@ "paths": { "~scripts/*": ["./scripts/*"], }, - "typeRoots": [ - "./node_modules/@types", - "./tsfixes.d.ts" - ] + "composite": true }, "ts-node": { "require": [ "tsconfig-paths/register" - ] + ], + "esm": true, + "experimentalSpecifierResolution": "node" }, "exclude": [ "**/node_modules",