ejsc-ma-api
v1.0.9
Published
Native Hardware Bridge API for 365 Mini App environment. Facilitates real-time, asynchronous communication with system-level APIs including Media, UI, and Location services.
Readme
@ejsc/ma-api 🔌
The Universal Bridge API for 365 Mini App Native Communication.
ejsc-ma-api là lớp cầu nối (Bridge) chính thức giữa môi trường Web của Mini App và các tính năng Native của Super App host. Thư viện bọc lại window.ejsc với đầy đủ TypeScript types và cung cấp các helper async/await giúp lập trình viên thao tác với phần cứng (Camera, GPS, Biometrics...) một cách an toàn và tinh giản.
Cài đặt
npm install ejsc-ma-apisCách dùng
Sync — callback-based
Proxy trực tiếp tới window.ejsc. Dùng khi cần tương thích với native bridge pattern.
import { apisSync } from 'ejsc-ma-apis';
apisSync.getSystemInfo({
success: (res) => console.log(res.platform),
fail: (err) => console.error(err),
});Async — Promise-based
Tất cả method đều trả về Promise. Khuyến nghị dùng với async/await.
import { apisAsync } from 'ejsc-ma-apis';
const info = await apisAsync.getSystemInfo();
console.log(info.platform); // 'ios' | 'android' | ...Import async-only entry
import apisAsync from 'ejsc-ma-apis/async';Default export
import apis from 'ejsc-ma-apis';
// apis === apisSyncPackage Exports
| Entry | Mô tả |
|-------|-------|
| ejsc-ma-apis | Main — export apis, apisSync, apisAsync, tất cả types |
| ejsc-ma-apis/async | Async-only — default export là apisAsync |
API Reference
Tất cả method đều có 2 dạng:
- Sync: nhận
optionskèmsuccess,fail,completecallbacks - Async: nhận
optionsthuần, trả vềPromise
System
getSystemInfo(options?)
Lấy thông tin hệ thống và thiết bị.
const res = await apisAsync.getSystemInfo();
// hoặc chỉ lấy một số field
const res = await apisAsync.getSystemInfo({ keys: ['platform', 'locale'] });| Options | Type | Mô tả |
|---------|------|-------|
| keys | Array<keyof IEjscGetSystemInfoData> | Các field cần lấy. Bỏ trống = lấy tất cả |
| Response | Type | Mô tả |
|----------|------|-------|
| app | string | Tên super app |
| brand | string | Nhãn hiệu thiết bị |
| currentBattery | number | Mức pin (0–1) |
| model | string | Model thiết bị |
| platform | 'ios' \| 'android' \| 'macos' \| 'windows' \| 'web' \| 'native' | Nền tảng |
| system | 'Android' \| 'iOS' \| 'iPhone OS' \| 'iPadOS' | Hệ điều hành |
| version | string | Phiên bản OS |
| hostVersion | string | Phiên bản host app |
| runtimeVersion | string | Phiên bản runtime |
| freeStorage | number | Dung lượng trống (bytes) |
| screenWidth / screenHeight | number | Kích thước màn hình (px) |
| windowWidth / windowHeight | number | Kích thước cửa sổ (px) |
| titleBarHeight / statusBarHeight | number | Chiều cao bar (px) |
| locale | 'vi' \| 'en' | Ngôn ngữ |
| deviceId | string | UUID thiết bị |
exitMiniApp(options)
Thoát mini app, quay về host app.
await apisAsync.exitMiniApp();confirmBeforeExit(options)
Bật/tắt xác nhận trước khi thoát.
await apisAsync.confirmBeforeExit({ enable: true, message: 'Bạn có chắc muốn thoát?' });| Options | Type | Mô tả |
|---------|------|-------|
| enable | boolean | Bắt buộc. Bật hay tắt xác nhận |
| message | string | Nội dung popup xác nhận |
Navigation Bar
setNavigationBar(options?)
Tùy chỉnh thanh điều hướng.
await apisAsync.setNavigationBar({
title: 'Trang chủ',
titleBarColor: '#ffffff',
theme: 'dark',
});| Options | Type | Mô tả |
|---------|------|-------|
| title | string | Tiêu đề |
| image | string | URL ảnh thay tiêu đề |
| titleBarColor | string | Màu nền thanh |
| borderBottomColor | string | Màu viền dưới |
| reset | boolean | Reset về mặc định |
| theme | 'dark' \| 'light' | Giao diện |
Storage
setStorage(options)
await apisAsync.setStorage({ key: 'token', data: 'abc123' });| Options | Type | Mô tả |
|---------|------|-------|
| key | string | Bắt buộc |
| data | string \| Record<string, any> | Bắt buộc |
getStorage(options)
const { data } = await apisAsync.getStorage({ key: 'token' });removeStorage(options)
await apisAsync.removeStorage({ key: 'token' });clearStorage()
Xóa toàn bộ storage.
await apisAsync.clearStorage();getStorageInfo()
const { keys, currentSize, limitSize } = await apisAsync.getStorageInfo();| Response | Type | Mô tả |
|----------|------|-------|
| keys | string[] | Danh sách key đang lưu |
| currentSize | number | Dung lượng đang dùng (bytes) |
| limitSize | number | Dung lượng tối đa (bytes) |
Clipboard
getClipboard()
const { text } = await apisAsync.getClipboard();setClipboard(options)
await apisAsync.setClipboard({ text: 'nội dung cần copy' });UI Dialogs
alert(options?)
await apisAsync.alert({ title: 'Thông báo', content: 'Thao tác thành công', buttonText: 'OK' });confirm(options?)
const { confirm } = await apisAsync.confirm({
title: 'Xác nhận',
content: 'Bạn có chắc không?',
confirmButtonText: 'Có',
cancelButtonText: 'Không',
});| Response | Type | Mô tả |
|----------|------|-------|
| confirm | boolean | true nếu bấm xác nhận |
prompt(options?)
const { ok, inputValue } = await apisAsync.prompt({
title: 'Nhập tên',
placeholder: 'Họ và tên...',
okButtonText: 'Xác nhận',
cancelButtonText: 'Hủy',
});| Response | Type | Mô tả |
|----------|------|-------|
| ok | boolean | true nếu bấm OK |
| inputValue | string | Giá trị người dùng nhập |
showToast(options?)
await apisAsync.showToast({ type: 'success', content: 'Lưu thành công', duration: 2000 });| Options | Type | Mô tả |
|---------|------|-------|
| type | 'success' \| 'fail' \| 'info' | Loại toast |
| content | string | Nội dung |
| buttonText | string | Text nút |
| duration | number | Thời gian hiển thị (ms) |
showLoading(options?) / hideLoading()
await apisAsync.showLoading({ content: 'Đang tải...' });
// ... xử lý xong
await apisAsync.hideLoading();showActionSheet(options)
const { index } = await apisAsync.showActionSheet({
title: 'Chọn hành động',
items: ['Chỉnh sửa', 'Xóa'],
cancelButton: 'Hủy',
destructiveBtnIndex: 1,
});| Response | Type | Mô tả |
|----------|------|-------|
| index | number | Vị trí item được chọn (0-indexed) |
Media
chooseImage(options?)
const { filePaths, tempFiles } = await apisAsync.chooseImage({
count: 3,
sourceType: ['album', 'camera'],
includeBase64: false,
});| Options | Type | Mô tả |
|---------|------|-------|
| count | number | Số ảnh tối đa. Mặc định: 1 |
| sourceType | Array<'camera' \| 'album'> | Nguồn ảnh |
| includeBase64 | boolean | Kèm data base64 |
| Response | Type | Mô tả |
|----------|------|-------|
| filePaths | string[] | Đường dẫn các ảnh |
| tempFiles | IEjscChooseImageTempFile[] | Chi tiết từng ảnh (path, size, width, height, data?) |
previewImage(options)
await apisAsync.previewImage({
urls: ['https://...', 'https://...'],
current: 0,
enablesavephoto: true,
});saveImage(options)
await apisAsync.saveImage({ url: 'https://...' });getImageInfo(options)
const { width, height, orientation, type } = await apisAsync.getImageInfo({ src: 'https://...' });| Response | Type |
|----------|------|
| width / height | number |
| orientation | 'up' \| 'down' \| 'left' \| 'right' \| 'up-mirrored' \| 'down-mirrored' \| 'left-mirrored' \| 'right-mirrored' |
| path | string |
| type | string |
compressImage(options)
const { filePaths } = await apisAsync.compressImage({
filePaths: ['/tmp/img.jpg'],
options: { quality: 80, maxWidth: 1024 },
});Network
request(options)
HTTP request — dùng thay cho fetch trong môi trường mini app (chỉ hỗ trợ HTTPS).
const res = await apisAsync.request({
url: 'https://api.example.com/data',
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: { key: 'value' },
timeout: 10000,
dataType: 'JSON',
});| Options | Type | Mô tả |
|---------|------|-------|
| url | string | Bắt buộc |
| method | string | Mặc định: 'GET' |
| headers | Record<string, string> | |
| data | any | Request body |
| timeout | number | ms. Mặc định: 30000 |
| dataType | string | 'JSON', 'text', 'base64', 'arraybuffer' |
| includeHeader | boolean | Kèm headers trong response |
| stepup | boolean | |
downloadFile(options)
const { filePath } = await apisAsync.downloadFile({
url: 'https://example.com/file.pdf',
headers: { Authorization: 'Bearer ...' },
});uploadFile(options)
const res = await apisAsync.uploadFile({
url: 'https://api.example.com/upload',
fileName: 'file',
filePath: '/tmp/img.jpg',
fileType: 'image',
formData: { userId: '123' },
});| Options | Type | Mô tả |
|---------|------|-------|
| url | string | Bắt buộc |
| fileName | string | Bắt buộc. Key trong form data |
| fileType | 'image' \| 'video' \| 'audio' | Bắt buộc |
| filePath | string | Đường dẫn file đơn |
| filePaths | string[] | Upload nhiều file |
| formData | Record<string, any> | Các field form khác |
| method | string | Mặc định: 'POST' |
| headers | Record<string, string> | |
Auth & User
getAuthCode(options?)
const { authCode, authSuccessScopes } = await apisAsync.getAuthCode({
scopes: ['profile', 'phone'],
});| Response | Type | Mô tả |
|----------|------|-------|
| authCode | string | Mã xác thực |
| authSuccessScopes | Array<'profile' \| 'phone' \| 'email'> | Scope được cấp |
| authErrorScopes | Record<string, string> | Scope bị lỗi |
getUserInfo()
const { avatar, name, gender } = await apisAsync.getUserInfo();getSetting()
const { authSetting } = await apisAsync.getSetting();
// authSetting: Record<string, boolean>openSetting()
Mở trang cài đặt quyền của mini app.
const { authSetting } = await apisAsync.openSetting();openAppSetting()
Mở cài đặt ứng dụng của thiết bị cho host app.
await apisAsync.openAppSetting();Navigation
openDeeplink(options)
const success = await apisAsync.openDeeplink({ url: 'myapp://screen/home' });openPublicDeepLink(options)
const success = await apisAsync.openPublicDeepLink({
url: 'https://example.com/path',
inAppBrowser: true,
});openNativeAppStore(options)
await apisAsync.openNativeAppStore({
appleStoreId: '123456789',
googlePlayId: 'com.example.app',
});shareApp(options?)
await apisAsync.shareApp({
title: 'Chia sẻ app',
desc: 'Mô tả ngắn',
path: '/pages/home',
});Device
makePhoneCall(options)
await apisAsync.makePhoneCall({ number: '0901234567' });choosePhoneContact()
Mở danh bạ để chọn liên hệ.
const { full_name, phone_number } = await apisAsync.choosePhoneContact();getLocation(options?)
const { latitude, longitude, accuracy } = await apisAsync.getLocation({
type: 1, // 0 = WiFi (thấp), 1 = GPS (cao)
cacheTimeout: 30,
});scan(options?)
Quét QR / barcode.
const result = await apisAsync.scan({ hideAlbum: false });
// result: string — nội dung mã quét đượcaddCalendarEvent(options)
await apisAsync.addCalendarEvent({
title: 'Họp nhóm',
startDate: '2026-04-01T09:00:00.000Z',
endDate: '2026-04-01T10:00:00.000Z',
location: 'Phòng họp A',
allDay: false,
notes: 'Mang theo laptop',
});reportAnalytics(name, options?)
await apisAsync.reportAnalytics('button_click', { screen: 'home', buttonId: 'cta' });Payment
initPayment(options)
const transactionId = await apisAsync.initPayment({
paymentApiKey: 'your-api-key',
orderInfo: {
amount: 100000,
currency: 'VND',
description: 'Thanh toán đơn hàng',
orderId: 'ORD-001',
referenceId: 'REF-001',
secureHash: 'hash...',
orderInfo: {
customerName: 'Nguyễn Văn A',
customerPhone: '0901234567',
items: [{ itemName: 'Sản phẩm A', quantity: 1, unitPrice: 100000 }],
},
},
});| IEjscOrderInfo | Type | Mô tả |
|-----------------|------|-------|
| amount | number | Số tiền |
| currency | string | Đơn vị tiền tệ |
| description | string | Mô tả |
| orderId | string | Mã đơn hàng |
| referenceId | string | Mã tham chiếu |
| secureHash | string | Hash bảo mật |
| orderInfo | IEjscCustomerOrderInfo | Thông tin khách hàng |
| paymentMethodCode | string | Mã phương thức thanh toán |
| providerId | string | ID nhà cung cấp |
| platformCode | string | Mã nền tảng |
| returnURL | string | URL callback |
| providerData | string | Dữ liệu nhà cung cấp |
showPaymentMethod(options)
const method = await apisAsync.showPaymentMethod({
paymentApiKey: 'your-api-key',
amount: 100000,
});| Response (IEjscPaymentMethod) | Type |
|-------------------------------|------|
| code | string |
| type | string |
| name | string |
| providerId | string |
| providerName | string |
| paymentMethodId | string |
| iconUrl | string |
| category | string |
| platformPaymentMethodId | string |
getDefaultPaymentMethod(options)
const method = await apisAsync.getDefaultPaymentMethod({ paymentApiKey: 'your-api-key' });
// method: IEjscPaymentMethodBeacon
startBeaconDiscovery(options?)
await apisAsync.startBeaconDiscovery({ UUID: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' });stopBeaconDiscovery()
await apisAsync.stopBeaconDiscovery();getBeaconDiscoveryStatus()
const status = await apisAsync.getBeaconDiscoveryStatus();
// status: 'initializing' | 'started' | 'stopped'onBeaconDiscovery(callback) / offBeaconDiscovery(callback)
Event-based — không có dạng async.
const handler = (data: IEjscBeaconInfo) => {
console.log(data.type, data.data);
};
apisSync.onBeaconDiscovery(handler);
// ...
apisSync.offBeaconDiscovery(handler);| IEjscBeaconInfo | Type |
|-----------------|------|
| type | 'iBeacon' \| 'Eddystone' \| string |
| data | any |
BioMetrics
Tất cả method nằm trong namespace bioMetrics.
bioMetrics.isSupported()
const { isSupported, mode, error } = await apisAsync.bioMetrics.isSupported();bioMetrics.localAuth(options)
Xác thực sinh trắc học.
const success = await apisAsync.bioMetrics.localAuth({ content: 'Xác nhận danh tính' });
// success: booleanbioMetrics.keyExists()
const exists = await apisAsync.bioMetrics.keyExists();
// exists: booleanbioMetrics.createKey()
const { publicKey } = await apisAsync.bioMetrics.createKey();bioMetrics.createSignature(options)
const { signature } = await apisAsync.bioMetrics.createSignature({
challenge: 'random-challenge-string',
content: 'Xác nhận giao dịch',
});bioMetrics.deleteKey()
const success = await apisAsync.bioMetrics.deleteKey();
// success: booleanCloud
Types dùng cho upload file lên cloud storage. Không được wire vào apisSync/apisAsync — dùng trực tiếp với bridge tùy platform.
import type { IEjscCloudUploadFile, IEjscCloudUploadFileAsync } from 'ejsc-ma-apis';| Type | Mô tả |
|------|-------|
| IEjscCloudUploadFileOptions | { fileType, fileName, filePath } |
| IEjscCloudUploadFileData | any |
| IEjscCloudUploadFile | Sync function type |
| IEjscCloudUploadFileAsync | Async function type |
Types
Tất cả types được export từ main entry:
import type {
IEjsc,
IEjscGetSystemInfoData,
IEjscRequestAsync,
IEjscPaymentMethod,
IEjscBeaconInfo,
IEjscOptionsWithCallback,
IEjscPlatform,
IEjscSystem,
IEjscLocale,
} from 'ejsc-ma-apis';Common types
| Type | Mô tả |
|------|-------|
| IEjscOptionsWithCallback<Options, Success> | Base type cho tất cả callback options |
| IEjscPlatform | 'ios' \| 'android' \| 'macos' \| 'windows' \| 'web' \| 'native' |
| IEjscSystem | 'Android' \| 'iOS' \| 'iPhone OS' \| 'iPadOS' |
| IEjscLocale | 'en' \| 'vi' |
| IEjsc | Interface đầy đủ của window.ejsc |
� 2026 EJSC Technology. All rights reserved.
© 2026 EJSC Technology. All rights reserved.
