@softtynet/zca-js 2.2.6 → 2.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,54 +1,72 @@
1
- # ZCA-JS (Forked Version)
1
+ # @softtynet/zca-js — Softtynet Zalo API SDK for Node.js & Bun
2
2
 
3
- > [!NOTE]
4
- > **This is a forked version of the original [zca-js](https://github.com/RFS-ADRENO/zca-js) project by RFS-ADRENO.** This package (`@softtynet/zca-js`) is maintained separately for quick hotfixes.
5
- >
6
- > This is an unofficial Zalo API for personal account. It work by simulating the browser to interact with Zalo Web.
3
+ <p align="left">
4
+ <a href="https://www.npmjs.com/package/@softtynet/zca-js"><img src="https://img.shields.io/npm/v/@softtynet/zca-js.svg?label=%40softtynet%2Fzca-js&color=0068ff" alt="npm version" /></a>
5
+ <a href="https://github.com/softtyos/zca-js"><img src="https://img.shields.io/badge/Maintained%20by-Softtynet%20Co.%2C%20Ltd.-0a7cff" alt="Maintained by Softtynet" /></a>
6
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="License: MIT" /></a>
7
+ </p>
8
+
9
+ **`@softtynet/zca-js`** là bộ thư viện Zalo API nâng cao dành cho Node.js / TypeScript / Bun, được phát triển, tối ưu hoá và duy trì bởi **Softtynet Co., Ltd.** nhằm đáp ứng các bài toán tích hợp chuyên sâu: **Đồng bộ dữ liệu đa thiết bị (Offline Catch-up & Mobile Backup Sync `ZDB4.0`)**, **Tín hiệu Gọi Thoại & Gọi Video (Voice / Video Call Signaling)**, và **Xử lý WebSocket thời gian thực độ tin cậy cao**.
7
10
 
8
11
  > [!WARNING]
9
- > Using this API could get your account locked or banned. We are not responsible for any issues that may happen. Use it at your own risk.
12
+ > Đây là thư viện tương tác không chính thức thông qua giao thức Zalo Web / Zalo PC dành cho tài khoản cá nhân. Vui lòng sử dụng có trách nhiệm và tuân thủ quy định an toàn tài khoản.
13
+
14
+ ---
15
+
16
+ ## Mục lục
17
+
18
+ - [Điểm nổi bật trên phiên bản Softtynet (`@softtynet/zca-js`)](#-điểm-nổi-bật-trên-phiên-bản-softtynet-softtynetzca-js)
19
+ - [Cài đặt](#-cài-đặt)
20
+ - [Tài liệu chuyên sâu](#-tài-liệu-chuyên-sâu)
21
+ - [Hướng dẫn sử dụng nhanh](#-hướng-dẫn-sử-dụng-nhanh)
22
+ - [1. Đăng nhập & Lưu phiên](#1-đăng-nhập--lưu-phiên)
23
+ - [2. Lắng nghe tin nhắn thời gian thực](#2-lắng-nghe-tin-nhắn-thời-gian-thực)
24
+ - [3. Đồng bộ bù tin nhắn khi Offline (Catch-up Sync)](#3-đồng-bộ-bù-tin-nhắn-khi-offline-catch-up-sync)
25
+ - [4. Đồng bộ lịch sử sao lưu từ Điện thoại (`ZDB4.0`)](#4-đồng-bộ-lịch-sử-sao-lưu-từ-điện-thoại-zdb40)
26
+ - [5. Khởi tạo Cuộc gọi Thoại & Gọi Video](#5-khởi-tạo-cuộc-gọi-thoại--gọi-video)
27
+ - [6. Gửi tin nhắn & Sticker](#6-gửi-tin-nhắn--sticker)
28
+ - [Kiểm định & Chạy thử nghiệm](#-kiểm-định--chạy-thử-nghiệm)
29
+ - [Nguồn gốc & Ghi nhận (Credits & Attribution)](#-nguồn-gốc--ghi-nhận-credits--attribution)
30
+ - [Giấy phép (License)](#-giấy-phép-license)
10
31
 
11
32
  ---
12
33
 
13
- ## Table of Contents
14
-
15
- - [Installation](#installation)
16
- - [Migrate to V2](#migrate-to-v2)
17
- - [Documentation](#documentation)
18
- - [Basic Usages](#basic-usages)
19
- - [Login](#login)
20
- - [Listen for new messages](#listen-for-new-messages)
21
- - [Synchronize Messages from Mobile](#synchronize-messages-from-mobile)
22
- - [Send a message](#send-a-message)
23
- - [Get/Send a sticker](#getsend-a-sticker)
24
- - [Example](#example)
25
- - [Projects & Useful Resources](#projects--useful-resources)
26
- - [Contributing](#contributing)
27
- - [License](#license)
28
- - [Support Us](#support-us)
29
-
30
- ## Installation
34
+ ## 🚀 Điểm nổi bật trên phiên bản Softtynet (`@softtynet/zca-js`)
35
+
36
+ So với phiên bản cộng đồng tiêu chuẩn, **`@softtynet/zca-js`** bổ sung các phân hệ cốt lõi đã được kiểm định trực tiếp trên máy chủ Zalo thật:
37
+
38
+ | Phân hệ | Tính năng trên `@softtynet/zca-js` |
39
+ | :--- | :--- |
40
+ | **Đồng bộ bù khi Offline (Catch-up Sync)** | Hỗ trợ [`api.preloadConversations()`](src/apis/preloadConversations.ts) (`cmd 10053`), kéo hàng đợi tin nhắn cá nhân & nhóm qua [`api.listener.requestOldMessages()`](src/apis/listen.ts) (`cmd 510` / `511`, cả `subCmd 0` & `1`), kèm cờ phân trang `hasMore`, tách biệt sự kiện thu hồi `undo` và đồng bộ trạng thái đã đọc `unread_cleared` (`cmd 504` / `524`). |
41
+ | **Đồng bộ sao lưu từ Điện thoại (`ZDB4.0`)** | Hỗ trợ trọn vẹn chu trình [`api.requestSyncFromPhone()`](src/apis/requestSyncFromPhone.ts) (`cmd 12000`), [`api.cancelPullMobile()`](src/apis/cancelPullMobile.ts) (`cmd 12700`), sự kiện `sync_event` (`user_confirm`, `syncmsg_info`, `transfer_after_login`), tải gói `.db.crypt` qua [`api.getSyncData()`](src/apis/getSyncData.ts) và giải mã RSA-2048 PKCS#1 v1.5 + AES-256-CBC đa khối 64KB + đọc mục lục SQLite (`parseZdbHeader`). |
42
+ | **Ánh xạ ID ẩn danh (Noised / Global ID)** | Hỗ trợ [`api.getNoisedIds()`](src/apis/getNoisedIds.ts) (`cmd 12390` kèm cơ chế tự động fallback sang `zwid.api.zalo.me`) và [`api.decryptGids()`](src/apis/decryptGids.ts) (`cmd 12054`) để ánh xạ tên file SQLite `3_<me>_<peer>.db` về User ID / Group ID thật. |
43
+ | **Gọi Thoại & Gọi Video (Signaling 2 bước)** | Hỗ trợ [`api.sendVoiceCall()`](src/apis/sendVoiceCall.ts) (`cmd 11300` + `11301`), [`api.cancelVoiceCall()`](src/apis/cancelVoiceCall.ts) (`cmd 11305`), [`api.endVoiceCall()`](src/apis/endVoiceCall.ts) (`cmd 11306`) và sự kiện `call_event` chuẩn giao thức C++ `ZaloCall` cho cả **Gọi Thoại (`CallType.Audio = 1`)** lẫn **Gọi Video (`CallType.Video = 3`, H.264)**. |
44
+ | **Độ ổn định & Bảo vệ bộ nhớ** | Tự động giải phóng bộ nhớ `uploadCallbacks` sau 5 phút trong [`uploadAttachment`](src/apis/uploadAttachment.ts), xử lý phản hồi rỗng hợp lệ (`error_code === 0, data === ""`) và bảo toàn độ chính xác chuỗi UID 19 chữ số. |
45
+
46
+ ---
47
+
48
+ ## 📦 Cài đặt
31
49
 
32
50
  ```bash
33
- bun add zca-js # or npm install zca-js
51
+ npm install @softtynet/zca-js
52
+ # hoặc dùng Bun
53
+ bun add @softtynet/zca-js
34
54
  ```
35
55
 
36
- ### Migrate to V2
56
+ ### Cấu hình `imageMetadataGetter` (Khi gửi ảnh từ đường dẫn file)
37
57
 
38
- Since official version 2.0.0, `zca-js` has removed sharp dependency for image metadata extraction. It now requires users to provide their own `imageMetadataGetter` function when initializing the `Zalo` class if they want to send images/gifs by file path.
39
-
40
- Example of custom `imageMetadataGetter` using `sharp`:
58
+ Từ kiến trúc V2, thư viện tách rời phụ thuộc xử lý ảnh để giữ dung lượng gọn nhẹ. Nếu ứng dụng của bạn gửi ảnh/GIF từ file nội bộ, hãy truyền hàm `imageMetadataGetter` (ví dụ dùng `sharp`):
41
59
 
42
60
  ```bash
43
- bun add sharp # or npm install sharp
61
+ npm install sharp
44
62
  ```
45
63
 
46
- ```javascript
47
- import { Zalo } from "zca-js";
64
+ ```ts
65
+ import { Zalo } from "@softtynet/zca-js";
48
66
  import sharp from "sharp";
49
67
  import fs from "node:fs";
50
68
 
51
- async function imageMetadataGetter(filePath) {
69
+ async function imageMetadataGetter(filePath: string) {
52
70
  const data = await fs.promises.readFile(filePath);
53
71
  const metadata = await sharp(data).metadata();
54
72
  return {
@@ -58,78 +76,75 @@ async function imageMetadataGetter(filePath) {
58
76
  };
59
77
  }
60
78
 
61
- const zalo = new Zalo({
62
- imageMetadataGetter,
63
- });
79
+ const zalo = new Zalo({ imageMetadataGetter });
64
80
  ```
65
81
 
66
82
  ---
67
83
 
68
- ## Documentation
84
+ ## 📚 Tài liệu chuyên sâu
69
85
 
70
- See [API Documentation](https://zca-js.tdung.com) for more details.
86
+ - **[Hướng dẫn Tích hợp: Đồng bộ Tin nhắn Đa Thiết bị (`ZDB4.0`) & Gọi Thoại / Video](docs/INTEGRATION_GUIDE_SYNC_AND_CALL.md)** — Tài liệu đầy đủ kèm sơ đồ kiến trúc và code mẫu tích hợp thực tế của Softtynet.
87
+ - **[Kế hoạch & Hướng dẫn Dịch ngược Zalo bằng REA (`morluto/rea`)](docs/REA_REVERSE_ENGINEERING_PLAN.md)** — Tài liệu quy trình phân tích tĩnh Binary C++ (`ZaloCall`, `libzdatabase.dylib`) và ASAR.
88
+ - **[API Reference Cơ bản](https://zca-js.tdung.com)** — Tra cứu danh mục các API cơ bản.
71
89
 
72
90
  ---
73
91
 
74
- ## Basic Usages
92
+ ## ⚡ Hướng dẫn sử dụng nhanh
75
93
 
76
- ### Login
94
+ ### 1. Đăng nhập & Lưu phiên
77
95
 
78
- ```javascript
79
- import { Zalo } from "zca-js";
96
+ ```ts
97
+ import { Zalo } from "@softtynet/zca-js";
80
98
 
81
- const zalo = new Zalo();
99
+ const zalo = new Zalo({ selfListen: true });
82
100
  const api = await zalo.loginQR();
101
+ console.log("Đã đăng nhập với UID:", api.getOwnId());
83
102
  ```
84
103
 
85
- ### Listen for new messages
104
+ ### 2. Lắng nghe tin nhắn thời gian thực
86
105
 
87
- ```javascript
88
- import { Zalo, ThreadType } from "zca-js";
106
+ ```ts
107
+ import { Zalo, ThreadType } from "@softtynet/zca-js";
89
108
 
90
- const zalo = new Zalo();
109
+ const zalo = new Zalo({ selfListen: true });
91
110
  const api = await zalo.loginQR();
92
111
 
93
112
  api.listener.on("message", (message) => {
94
113
  const isPlainText = typeof message.data.content === "string";
114
+ if (!isPlainText) return;
95
115
 
96
- switch (message.type) {
97
- case ThreadType.User: {
98
- if (isPlainText) {
99
- // received plain text direct message
100
- }
101
- break;
102
- }
103
- case ThreadType.Group: {
104
- if (isPlainText) {
105
- // received plain text group message
106
- }
107
- break;
108
- }
116
+ if (message.type === ThreadType.User) {
117
+ console.log(`[Cá nhân] ${message.data.dName}: ${message.data.content}`);
118
+ } else if (message.type === ThreadType.Group) {
119
+ console.log(`[Nhóm ${message.threadId}] ${message.data.dName}: ${message.data.content}`);
109
120
  }
110
121
  });
111
122
 
112
- api.listener.start();
123
+ api.listener.start({ retryOnClose: true });
113
124
  ```
114
125
 
115
126
  > [!IMPORTANT]
116
- > Only one web listener can run per account at a time. If you open Zalo in the browser while the listener is active, the listener will be automatically stopped.
127
+ > Mỗi tài khoản Zalo chỉ duy trì một kết nối WebSocket Web tại một thời điểm. Nếu bạn mở thêm tab Zalo Web trên trình duyệt, kết nối WebSocket cũ sẽ nhận sự kiện `duplicate_connection`.
117
128
 
118
- ### Synchronize Messages & Offline Catch-up
129
+ ### 3. Đồng bộ bù tin nhắn khi Offline (Catch-up Sync)
119
130
 
120
- `zca-js` supports both **offline message catch-up** (when reconnecting or restarting your app) and **full mobile backup synchronization** (`ZDB4.0`) from the Zalo mobile app:
121
-
122
- #### 1. Catch Up Missed Messages After Reconnect / Restart
123
- ```javascript
124
- import { Zalo, ThreadType } from "zca-js";
131
+ ```ts
132
+ import { ThreadType } from "@softtynet/zca-js";
125
133
 
134
+ // 1. Lấy nhanh các tin nhắn mới nhất & danh sách đã đọc qua HTTP (cmd 10053)
126
135
  const preload = await api.preloadConversations();
127
- console.log(`Preloaded ${preload.messages.length} latest messages`);
136
+ console.log(`Preloaded: ${preload.messages.length} tin nhắn, ${preload.unreadCleared.length} trạng thái đã đọc`);
128
137
 
138
+ // 2. Nhận tin nhắn từ hàng đợi WebSocket (cmd 510 & 511)
129
139
  api.listener.on("old_messages", (messages, type, hasMore) => {
130
- console.log(`Received ${messages.length} queued offline messages (type=${type}, hasMore=${hasMore})`);
140
+ console.log(`Nhận ${messages.length} tin nhắn cũ (type=${type}, hasMore=${hasMore})`);
141
+ if (hasMore && messages.length > 0) {
142
+ const lastMsgId = messages[messages.length - 1].data.msgId;
143
+ api.listener.requestOldMessages(type, lastMsgId);
144
+ }
131
145
  });
132
146
 
147
+ // 3. Kích hoạt kéo hàng đợi ngay khi nhận khoá giải mã WebSocket
133
148
  api.listener.on("cipher_key", () => {
134
149
  api.listener.requestOldMessages(ThreadType.User);
135
150
  api.listener.requestOldMessages(ThreadType.Group);
@@ -138,155 +153,122 @@ api.listener.on("cipher_key", () => {
138
153
  api.listener.start({ retryOnClose: true });
139
154
  ```
140
155
 
141
- #### 2. Trigger Mobile Backup Sync (`pull_mobile_msg`)
142
- ```javascript
143
- import { SyncEventType, decryptWithPrivateKey, deriveZdbAesKey, decryptZdbBuffer } from "zca-js";
156
+ ### 4. Đồng bộ lịch sử sao lưu từ Điện thoại (`ZDB4.0`)
157
+
158
+ ```ts
159
+ import fs from "node:fs";
160
+ import {
161
+ SyncEventType,
162
+ decryptWithPrivateKey,
163
+ deriveZdbAesKey,
164
+ decryptZdbBuffer,
165
+ parseZdbHeader,
166
+ } from "@softtynet/zca-js";
144
167
 
145
168
  let privateKey = "";
146
169
 
147
170
  api.listener.on("sync_event", async (event) => {
148
171
  if (event.type === SyncEventType.USER_CONFIRM) {
149
- console.log("User confirmed sync on phone, waiting for backup upload...");
172
+ console.log("Người dùng đã bấm xác nhận trên điện thoại, đang chờ tải gói sao lưu...");
150
173
  } else if (event.type === SyncEventType.SYNCMSG_INFO) {
151
174
  const res = await api.getSyncData({ ...event.data, savePath: "./sync_data" });
152
175
  if (res.success && res.data && privateKey) {
153
176
  const rawRsa = decryptWithPrivateKey(privateKey, res.data.encrypted_key);
154
177
  const aesKey = deriveZdbAesKey(rawRsa);
155
- console.log("Downloaded backup:", res.data.file_path, "AES key length:", aesKey.length);
178
+ const zdbPlain = decryptZdbBuffer(fs.readFileSync(res.data.file_path), aesKey);
179
+ const toc = parseZdbHeader(zdbPlain);
180
+ console.log(`Giải mã thành công ZDB4.0 (${toc.entries.length} hội thoại SQLite):`, toc.entries.slice(0, 5));
156
181
  }
157
182
  }
158
183
  });
159
184
 
160
- api.listener.on("connected", async () => {
161
- const session = await api.requestSyncFromPhone();
185
+ api.listener.on("cipher_key", async () => {
186
+ const session = await api.requestSyncFromPhone({ pcName: "Web" });
162
187
  privateKey = session.privateKey;
163
- console.log("Please tap 'Sync now' on your phone!");
188
+ console.log("Vui lòng mở điện thoại và bấm 'Đồng bộ ngay' trên thông báo Zalo!");
164
189
  });
165
-
166
- api.listener.start();
167
190
  ```
168
191
 
169
- ### Voice / Video Call Signaling
192
+ ### 5. Khởi tạo Cuộc gọi Thoại & Gọi Video
170
193
 
171
- ```javascript
172
- import { CallType } from "zca-js";
194
+ ```ts
195
+ import { CallType } from "@softtynet/zca-js";
173
196
 
174
- // Ring a user's phone (Audio or Video call)
175
- const call = await api.sendVoiceCall("target_user_id", { callType: CallType.Audio });
176
- console.log("Ringing callId:", call.callId, "session:", call.sessId);
177
-
178
- // Cancel ringing or end an active call
179
- await api.cancelVoiceCall("target_user_id", call.callId);
180
- ```
197
+ const targetUid = "5249661060655759359"; // Chuỗi UID 19 chữ số
181
198
 
182
- ### Send a message
183
-
184
- ```javascript
185
- import { Zalo, ThreadType } from "zca-js";
186
-
187
- const zalo = new Zalo();
188
- const api = await zalo.loginQR();
199
+ // Gọi Video (CallType.Video = 3, tự động đính kèm H.264 payload 97)
200
+ const videoCall = await api.sendVoiceCall(targetUid, {
201
+ callType: CallType.Video,
202
+ });
203
+ console.log("Đang đổ chuông Video:", videoCall.callId, videoCall.rtpServer);
189
204
 
190
- // Echo bot
191
- api.listener.on("message", (message) => {
192
- const isPlainText = typeof message.data.content === "string";
193
- if (message.isSelf || !isPlainText) return;
194
-
195
- switch (message.type) {
196
- case ThreadType.User: {
197
- api.sendMessage(
198
- {
199
- msg: "echo: " + message.data.content,
200
- quote: message.data, // the message to reply to (optional)
201
- },
202
- message.threadId,
203
- message.type, // ThreadType.User
204
- );
205
- break;
206
- }
207
- case ThreadType.Group: {
208
- api.sendMessage(
209
- {
210
- msg: "echo: " + message.data.content,
211
- quote: message.data, // the message to reply to (optional)
212
- },
213
- message.threadId,
214
- message.type, // ThreadType.Group
215
- );
216
- break;
217
- }
218
- }
205
+ // Huỷ cuộc gọi khi đang đổ chuông
206
+ await api.cancelVoiceCall(targetUid, videoCall.callId, {
207
+ callType: CallType.Video,
219
208
  });
220
209
 
221
- api.listener.start();
210
+ // Hoặc gọi Thoại (CallType.Audio = 1)
211
+ const audioCall = await api.sendVoiceCall(targetUid, {
212
+ callType: CallType.Audio,
213
+ });
214
+ await api.cancelVoiceCall(targetUid, audioCall.callId);
222
215
  ```
223
216
 
224
- ### Get/Send a sticker
225
-
226
- ```javascript
227
- api.getStickers("hello").then(async (stickerIds) => {
228
- // Get the first sticker
217
+ ### 6. Gửi tin nhắn & Sticker
218
+
219
+ ```ts
220
+ // Trả lời tin nhắn văn bản
221
+ await api.sendMessage(
222
+ {
223
+ msg: "Xin chào từ hệ thống Softtynet!",
224
+ quote: message.data,
225
+ },
226
+ message.threadId,
227
+ message.type,
228
+ );
229
+
230
+ // Tìm và gửi Sticker
231
+ const stickerIds = await api.getStickers("xin chào");
232
+ if (stickerIds.length > 0) {
229
233
  const stickerObject = await api.getStickersDetail(stickerIds[0]);
230
- api.sendMessageSticker(
231
- stickerObject,
232
- message.threadId,
233
- message.type, // ThreadType.User or ThreadType.Group
234
- );
235
- });
234
+ await api.sendMessageSticker(stickerObject, message.threadId, message.type);
235
+ }
236
236
  ```
237
237
 
238
238
  ---
239
239
 
240
- ## Example
241
-
242
- See [examples](examples) folder for more details.
243
-
244
- ---
240
+ ## 🧪 Kiểm định & Chạy thử nghiệm
245
241
 
246
- ## Projects & Useful Resources
242
+ Dự án đi kèm bộ kiểm định 2 lớp trong thư mục [`test/`](test):
247
243
 
248
- <div align="center">
244
+ 1. **Kiểm định tự động (Offline / Unit Verification Suite)**:
245
+ ```bash
246
+ npm run test:verify
247
+ ```
248
+ Kiểm tra tự động toàn bộ 6 hạng mục: `preloadConversations`, `requestSyncFromPhone` / `pullMobile` / `cancelPullMobile`, `getNoisedIds` / `decryptGids`, giải mã `RSA-2048` + `ZDB4.0` đa khối 64KB, `sendVoiceCall` (Audio & Video) / `cancelVoiceCall` / `endVoiceCall`, và các sự kiện WebSocket (`510`, `511`, `504`, `601`).
249
249
 
250
- | Repository | Description |
251
- | :--- | :--- |
252
- | [**ZaloDataExtractor**](https://github.com/JustKemForFun/ZaloDataExtractor) | A browser `Extension` to extract IMEI, cookies, and user agent from Zalo Web. |
253
- | [**MultiZlogin**](https://github.com/ChickenAI/multizlogin) | A multi-account Zalo management system that lets you log in to and manage multiple accounts simultaneously, with proxy and webhook integration. |
254
- | [**n8n-nodes-zalo-tools**](https://github.com/ChickenAI/zalo-node) | N8N node for personal Zalo account. |
255
- | [**Zalo-F12**](https://github.com/ElectroHeavenVN/Zalo-F12) | A collection of JavaScript code snippets to paste into DevTools to change how Zalo Web/PC works. |
256
- | [**Zalo-F12-Tools**](https://github.com/JustKemForFun/Zalo-F12-Tools) | Toggle hidden modes for Zalo Web. |
250
+ 2. **Kiểm định trực tiếp trên tài khoản Zalo thật (Live Verification Suite)**:
251
+ ```bash
252
+ # Chạy toàn bộ 6 bước (Quét QR -> Preload -> ZNoise -> OldMessages -> Đồng bộ ZDB4.0 từ ĐT -> Voice/Video Call)
253
+ npm run test:live
257
254
 
258
- </div>
255
+ # Chỉ test nhanh Gọi Thoại + Gọi Video tới 1 UID bạn bè
256
+ npm run test:live -- --only-call --call <UID_BAN_BE>
257
+ ```
259
258
 
260
259
  ---
261
260
 
262
- ## Contributing
263
-
264
- We welcome contributions from the community! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details on how to:
265
-
266
- - 🐛 Report bugs and issues
267
- - ✨ Suggest new features
268
- - 🔧 Submit code contributions
269
- - 📚 Improve documentation
270
- - 🧪 Add or improve tests
271
- - 🔒 Report security vulnerabilities
261
+ ## 🤝 Nguồn gốc & Ghi nhận (Credits & Attribution)
272
262
 
273
- For more information, please read our [Code of Conduct](CODE_OF_CONDUCT.md) and [Security Policy](SECURITY.md) before participating.
274
-
275
- ---
263
+ Dự án **`@softtynet/zca-js`** được phát triển, nâng cấp và duy trì bởi **Softtynet Co., Ltd.** ([`softtyos/zca-js`](https://github.com/softtyos/zca-js)), kế thừa nền tảng mã nguồn mở từ dự án gốc:
276
264
 
277
- ## License
265
+ - **Dự án gốc**: [RFS-ADRENO/zca-js](https://github.com/RFS-ADRENO/zca-js)
266
+ - **Tác giả nền tảng gốc**: RFS-ADRENO, truong9c2208, JustKemForFun cùng các thành viên đóng góp từ cộng đồng mã nguồn mở.
278
267
 
279
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
268
+ Chúng tôi trân trọng cảm ơn các tác giả của dự án gốc đã xây dựng nền tảng ban đầu cho cộng đồng JavaScript/TypeScript.
280
269
 
281
270
  ---
282
271
 
283
- ## **Support Us**
272
+ ## 📄 Giấy phép (License)
284
273
 
285
- - ⭐ **Star our repositories** if you find them useful!
286
- - 🔄 **Share** with your network to help us grow
287
- - 💡 **Contribute** your ideas and code
288
- - ☕ **A coffee**:
289
- - [Buy Me a Coffee](https://ko-fi.com/grosse)
290
- - [Paypal](https://www.paypal.com/paypalme/dungto213)
291
- - [VietQR](https://github.com/user-attachments/assets/e1f319d6-9d11-4082-8248-55b55e645caa)
292
- - [Momo](https://me.momo.vn/gMIMulsaUqsbf6iAiXt3)
274
+ Phát hành theo giấy phép [MIT License](LICENSE).
@@ -3,10 +3,10 @@
3
3
  var semver = require('semver');
4
4
  var utils = require('./utils.cjs');
5
5
 
6
- const VERSION = "2.2.0";
7
- const NPM_REGISTRY = "https://registry.npmjs.org/zca-js";
6
+ const VERSION = "2.2.7";
7
+ const NPM_REGISTRY = "https://registry.npmjs.org/@softtynet/zca-js";
8
8
  async function checkUpdate(ctx) {
9
- var _a, _b;
9
+ var _a, _b, _c;
10
10
  if (!ctx.options.checkUpdate)
11
11
  return;
12
12
  const _options = Object.assign({}, (utils.isBun
@@ -22,12 +22,14 @@ async function checkUpdate(ctx) {
22
22
  const data = await response.json().catch(() => null);
23
23
  if (!data)
24
24
  return;
25
- const latestVersion = data["dist-tags"].latest;
25
+ const latestVersion = (_c = data["dist-tags"]) === null || _c === void 0 ? void 0 : _c.latest;
26
+ if (!latestVersion)
27
+ return;
26
28
  if (semver.compare(VERSION, latestVersion) === -1) {
27
- utils.logger(ctx).info(`A new version of zca-js is available: ${latestVersion}`);
29
+ utils.logger(ctx).info(`A new version of @softtynet/zca-js is available: ${latestVersion}`);
28
30
  }
29
31
  else {
30
- utils.logger(ctx).info("zca-js is up to date");
32
+ utils.logger(ctx).info("@softtynet/zca-js is up to date");
31
33
  }
32
34
  }
33
35
 
package/dist/update.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { compare } from "semver";
2
2
  import { isBun, logger } from "./utils.js";
3
- const VERSION = "2.2.0";
4
- const NPM_REGISTRY = "https://registry.npmjs.org/zca-js";
3
+ const VERSION = "2.2.7";
4
+ const NPM_REGISTRY = "https://registry.npmjs.org/@softtynet/zca-js";
5
5
  export async function checkUpdate(ctx) {
6
- var _a, _b;
6
+ var _a, _b, _c;
7
7
  if (!ctx.options.checkUpdate)
8
8
  return;
9
9
  const _options = Object.assign({}, (isBun
@@ -19,11 +19,13 @@ export async function checkUpdate(ctx) {
19
19
  const data = await response.json().catch(() => null);
20
20
  if (!data)
21
21
  return;
22
- const latestVersion = data["dist-tags"].latest;
22
+ const latestVersion = (_c = data["dist-tags"]) === null || _c === void 0 ? void 0 : _c.latest;
23
+ if (!latestVersion)
24
+ return;
23
25
  if (compare(VERSION, latestVersion) === -1) {
24
- logger(ctx).info(`A new version of zca-js is available: ${latestVersion}`);
26
+ logger(ctx).info(`A new version of @softtynet/zca-js is available: ${latestVersion}`);
25
27
  }
26
28
  else {
27
- logger(ctx).info("zca-js is up to date");
29
+ logger(ctx).info("@softtynet/zca-js is up to date");
28
30
  }
29
31
  }