@vqh2602/mini-app-sdk 1.0.0 → 1.0.1

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.
Files changed (179) hide show
  1. package/README.md +131 -29
  2. package/bin/miniapp.js +6 -0
  3. package/bin/simulator.js +74 -0
  4. package/dist/cli/commands/build.d.ts +5 -0
  5. package/dist/cli/commands/build.d.ts.map +1 -0
  6. package/dist/cli/commands/build.js +65 -0
  7. package/dist/cli/commands/build.js.map +1 -0
  8. package/dist/cli/commands/create.d.ts +5 -0
  9. package/dist/cli/commands/create.d.ts.map +1 -0
  10. package/dist/cli/commands/create.js +220 -0
  11. package/dist/cli/commands/create.js.map +1 -0
  12. package/dist/cli/commands/dev.d.ts +8 -0
  13. package/dist/cli/commands/dev.d.ts.map +1 -0
  14. package/dist/cli/commands/dev.js +41 -0
  15. package/dist/cli/commands/dev.js.map +1 -0
  16. package/dist/cli/commands/doctor.d.ts +2 -0
  17. package/dist/cli/commands/doctor.d.ts.map +1 -0
  18. package/dist/cli/commands/doctor.js +47 -0
  19. package/dist/cli/commands/doctor.js.map +1 -0
  20. package/dist/cli/commands/simulator.d.ts +6 -0
  21. package/dist/cli/commands/simulator.d.ts.map +1 -0
  22. package/dist/cli/commands/simulator.js +14 -0
  23. package/dist/cli/commands/simulator.js.map +1 -0
  24. package/dist/cli/commands/upload.d.ts +9 -0
  25. package/dist/cli/commands/upload.d.ts.map +1 -0
  26. package/dist/cli/commands/upload.js +107 -0
  27. package/dist/cli/commands/upload.js.map +1 -0
  28. package/dist/cli/index.d.ts +2 -0
  29. package/dist/cli/index.d.ts.map +1 -0
  30. package/dist/cli/index.js +63 -0
  31. package/dist/cli/index.js.map +1 -0
  32. package/dist/cli/utils/config.d.ts +13 -0
  33. package/dist/cli/utils/config.d.ts.map +1 -0
  34. package/dist/cli/utils/config.js +26 -0
  35. package/dist/cli/utils/config.js.map +1 -0
  36. package/dist/cli/utils/logger.d.ts +9 -0
  37. package/dist/cli/utils/logger.d.ts.map +1 -0
  38. package/dist/cli/utils/logger.js +18 -0
  39. package/dist/cli/utils/logger.js.map +1 -0
  40. package/dist/cli/utils/server.d.ts +3 -0
  41. package/dist/cli/utils/server.d.ts.map +1 -0
  42. package/dist/cli/utils/server.js +71 -0
  43. package/dist/cli/utils/server.js.map +1 -0
  44. package/dist/{client.d.ts → core/client.d.ts} +2 -2
  45. package/dist/core/client.d.ts.map +1 -0
  46. package/dist/{client.js → core/client.js} +2 -2
  47. package/dist/core/client.js.map +1 -0
  48. package/dist/core/index.d.ts +13 -0
  49. package/dist/core/index.d.ts.map +1 -0
  50. package/dist/core/index.js +14 -0
  51. package/dist/core/index.js.map +1 -0
  52. package/dist/{modules → core/modules}/auth.d.ts +1 -1
  53. package/dist/core/modules/auth.d.ts.map +1 -0
  54. package/dist/core/modules/auth.js.map +1 -0
  55. package/dist/{modules → core/modules}/device.d.ts +1 -1
  56. package/dist/core/modules/device.d.ts.map +1 -0
  57. package/dist/core/modules/device.js.map +1 -0
  58. package/dist/{modules → core/modules}/lifecycle.d.ts +1 -1
  59. package/dist/core/modules/lifecycle.d.ts.map +1 -0
  60. package/dist/core/modules/lifecycle.js.map +1 -0
  61. package/dist/{modules → core/modules}/media.d.ts +1 -1
  62. package/dist/core/modules/media.d.ts.map +1 -0
  63. package/dist/core/modules/media.js.map +1 -0
  64. package/dist/{modules → core/modules}/navigation.d.ts +1 -1
  65. package/dist/core/modules/navigation.d.ts.map +1 -0
  66. package/dist/core/modules/navigation.js.map +1 -0
  67. package/dist/{modules → core/modules}/storage.d.ts +1 -1
  68. package/dist/core/modules/storage.d.ts.map +1 -0
  69. package/dist/core/modules/storage.js.map +1 -0
  70. package/dist/{modules → core/modules}/ui.d.ts +1 -1
  71. package/dist/core/modules/ui.d.ts.map +1 -0
  72. package/dist/core/modules/ui.js.map +1 -0
  73. package/dist/core/types/index.d.ts.map +1 -0
  74. package/dist/{types → core/types}/index.js.map +1 -1
  75. package/dist/index.d.ts +7 -11
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +11 -12
  78. package/dist/index.js.map +1 -1
  79. package/dist/mock/handlers/auth.handler.d.ts +16 -0
  80. package/dist/mock/handlers/auth.handler.d.ts.map +1 -0
  81. package/dist/mock/handlers/auth.handler.js +62 -0
  82. package/dist/mock/handlers/auth.handler.js.map +1 -0
  83. package/dist/mock/handlers/device.handler.d.ts +16 -0
  84. package/dist/mock/handlers/device.handler.d.ts.map +1 -0
  85. package/dist/mock/handlers/device.handler.js +53 -0
  86. package/dist/mock/handlers/device.handler.js.map +1 -0
  87. package/dist/mock/handlers/media.handler.d.ts +9 -0
  88. package/dist/mock/handlers/media.handler.d.ts.map +1 -0
  89. package/dist/mock/handlers/media.handler.js +20 -0
  90. package/dist/mock/handlers/media.handler.js.map +1 -0
  91. package/dist/mock/handlers/storage.handler.d.ts +18 -0
  92. package/dist/mock/handlers/storage.handler.d.ts.map +1 -0
  93. package/dist/mock/handlers/storage.handler.js +40 -0
  94. package/dist/mock/handlers/storage.handler.js.map +1 -0
  95. package/dist/mock/handlers/ui.handler.d.ts +34 -0
  96. package/dist/mock/handlers/ui.handler.d.ts.map +1 -0
  97. package/dist/mock/handlers/ui.handler.js +59 -0
  98. package/dist/mock/handlers/ui.handler.js.map +1 -0
  99. package/dist/mock/index.d.ts +10 -0
  100. package/dist/mock/index.d.ts.map +1 -0
  101. package/dist/mock/index.js +10 -0
  102. package/dist/mock/index.js.map +1 -0
  103. package/dist/mock/mock-engine.d.ts +39 -0
  104. package/dist/mock/mock-engine.d.ts.map +1 -0
  105. package/dist/mock/mock-engine.js +205 -0
  106. package/dist/mock/mock-engine.js.map +1 -0
  107. package/dist/mock/presets.d.ts +3 -0
  108. package/dist/mock/presets.d.ts.map +1 -0
  109. package/dist/mock/presets.js +43 -0
  110. package/dist/mock/presets.js.map +1 -0
  111. package/dist/mock/store.d.ts +36 -0
  112. package/dist/mock/store.d.ts.map +1 -0
  113. package/dist/mock/store.js +133 -0
  114. package/dist/mock/store.js.map +1 -0
  115. package/dist/mock/types.d.ts +60 -0
  116. package/dist/mock/types.d.ts.map +1 -0
  117. package/dist/mock/types.js +2 -0
  118. package/dist/mock/types.js.map +1 -0
  119. package/dist/transport/index.d.ts +7 -0
  120. package/dist/transport/index.d.ts.map +1 -0
  121. package/dist/transport/index.js +7 -0
  122. package/dist/transport/index.js.map +1 -0
  123. package/dist/transport/mock-transport.d.ts +20 -0
  124. package/dist/transport/mock-transport.d.ts.map +1 -0
  125. package/dist/transport/mock-transport.js +79 -0
  126. package/dist/transport/mock-transport.js.map +1 -0
  127. package/dist/transport/native-transport.d.ts +19 -0
  128. package/dist/transport/native-transport.d.ts.map +1 -0
  129. package/dist/transport/native-transport.js +151 -0
  130. package/dist/transport/native-transport.js.map +1 -0
  131. package/dist/transport/postmessage-transport.d.ts +20 -0
  132. package/dist/transport/postmessage-transport.d.ts.map +1 -0
  133. package/dist/transport/postmessage-transport.js +130 -0
  134. package/dist/transport/postmessage-transport.js.map +1 -0
  135. package/dist/transport/resolver.d.ts +11 -0
  136. package/dist/transport/resolver.d.ts.map +1 -0
  137. package/dist/transport/resolver.js +41 -0
  138. package/dist/transport/resolver.js.map +1 -0
  139. package/dist/transport/transport.interface.d.ts +10 -0
  140. package/dist/transport/transport.interface.d.ts.map +1 -0
  141. package/dist/transport/transport.interface.js +2 -0
  142. package/dist/transport/transport.interface.js.map +1 -0
  143. package/dist/transport/types.d.ts +46 -0
  144. package/dist/transport/types.d.ts.map +1 -0
  145. package/dist/transport/types.js +2 -0
  146. package/dist/transport/types.js.map +1 -0
  147. package/package.json +47 -11
  148. package/simulator-dist/assets/index-D5M_HJio.js +199 -0
  149. package/simulator-dist/index.html +15 -0
  150. package/dist/client.d.ts.map +0 -1
  151. package/dist/client.js.map +0 -1
  152. package/dist/modules/auth.d.ts.map +0 -1
  153. package/dist/modules/auth.js.map +0 -1
  154. package/dist/modules/device.d.ts.map +0 -1
  155. package/dist/modules/device.js.map +0 -1
  156. package/dist/modules/lifecycle.d.ts.map +0 -1
  157. package/dist/modules/lifecycle.js.map +0 -1
  158. package/dist/modules/media.d.ts.map +0 -1
  159. package/dist/modules/media.js.map +0 -1
  160. package/dist/modules/navigation.d.ts.map +0 -1
  161. package/dist/modules/navigation.js.map +0 -1
  162. package/dist/modules/payment.d.ts +0 -15
  163. package/dist/modules/payment.d.ts.map +0 -1
  164. package/dist/modules/payment.js +0 -25
  165. package/dist/modules/payment.js.map +0 -1
  166. package/dist/modules/storage.d.ts.map +0 -1
  167. package/dist/modules/storage.js.map +0 -1
  168. package/dist/modules/ui.d.ts.map +0 -1
  169. package/dist/modules/ui.js.map +0 -1
  170. package/dist/types/index.d.ts.map +0 -1
  171. /package/dist/{modules → core/modules}/auth.js +0 -0
  172. /package/dist/{modules → core/modules}/device.js +0 -0
  173. /package/dist/{modules → core/modules}/lifecycle.js +0 -0
  174. /package/dist/{modules → core/modules}/media.js +0 -0
  175. /package/dist/{modules → core/modules}/navigation.js +0 -0
  176. /package/dist/{modules → core/modules}/storage.js +0 -0
  177. /package/dist/{modules → core/modules}/ui.js +0 -0
  178. /package/dist/{types → core/types}/index.d.ts +0 -0
  179. /package/dist/{types → core/types}/index.js +0 -0
package/README.md CHANGED
@@ -1,58 +1,160 @@
1
- # @vqh2602/mini-app-sdk
1
+ # SuperApp Mini App Developer SDK Ecosystem
2
2
 
3
- Bộ TypeScript SDK chính thức dành cho các nhà phát triển thứ ba xây dựng ứng dụng nhỏ (Mini App) trên nền tảng SuperApp.
3
+ Hệ sinh thái bộ công cụ SDK, Bridge Transport, Mock Engine, CLI và Browser Simulator dành riêng cho các nhà phát triển thứ ba (3rd-party developers) xây dựng, kiểm thử và xuất bản Mini App trên nền tảng SuperApp.
4
4
 
5
- ## 🚀 Tính năng nổi bật
5
+ ---
6
6
 
7
- - **100% TypeScript**: Định kiểu rõ ràng, tự động gợi ý code (IntelliSense) cho mọi hàm và tham số.
8
- - **Tự động chuyển đổi môi trường**: Chạy mượt mà trên cả Flutter WebView thật, trong iframe Browser Simulator, hay độc lập (Mock Engine tự động).
9
- - **Hỗ trợ đầy đủ nghiệp vụ SuperApp**:
10
- - `auth`: Đăng nhập, cấp quyền OAuth, lấy User Profile, quản lý token.
11
- - `payment`: Tích hợp thanh toán trực tiếp qua ví SuperApp.
12
- - `device`: Pin, thông tin mạng, rung xúc giác haptic feedback, thông số màn hình.
13
- - `storage`: Lưu trữ key-value cách ly và an toàn theo từng Mini App.
14
- - `ui`: Toast thông báo, Alert, Confirm, đổi tiêu đề thanh điều hướng.
15
- - `media`: Quét QR code camera, chọn ảnh.
16
- - `lifecycle`: Bắt sự kiện app vào nền (Background) hoặc ra màn hình (Foreground).
7
+ ## 🏗️ 1. Kiến Trúc Hợp Nhất (All-in-One Package: `@vqh2602/mini-app-sdk`)
17
8
 
18
- ## 📦 Cài đặt
9
+ Toàn bộ hệ thống SDK, Mock Engine, Bridge Transport, CLI và Browser Simulator đã được hợp nhất vào **1 gói npm duy nhất**:
19
10
 
11
+ | Khối chức năng | Thư mục source | Vai trò & Trách nhiệm |
12
+ | :--- | :--- | :--- |
13
+ | **Mini App Core SDK** | `src/core/` | Bộ API chính thức cho bên thứ ba (`npm install @vqh2602/mini-app-sdk`): `auth`, `payment`, `device`, `storage`, `ui`, `media`, `lifecycle`. |
14
+ | **Bridge Transport** | `src/transport/` | Lớp trừu tượng hoá Bridge: chuyển đổi linh hoạt giữa Flutter WebView Native (`FlutterBridge`), PostMessage trong iframe Simulator, hoặc Mock cục bộ. |
15
+ | **SDK Mock Engine** | `src/mock/` | Động cơ giả lập Native: sinh mã `authCode`, cấp `accessToken`, hồ sơ người dùng, quản lý số dư ví, trừ tiền thanh toán, giả lập pin, mạng, độ trễ và lưu trữ cách ly. |
16
+ | **Mini App CLI** | `src/cli/` & `bin/` | Công cụ dòng lệnh: `create` (tạo dự án mẫu), `dev` (khởi chạy dev server + simulator), `build` (biên dịch + checksum), `upload` (gửi lên Registry), `simulator`. |
17
+ | **Browser Simulator** | `simulator/` & `simulator-dist/` | Giao diện web giả lập điện thoại đã được build sẵn tĩnh, tích hợp trực tiếp vào lệnh `miniapp dev` và `miniapp simulator`. |
18
+
19
+ ---
20
+
21
+ ## ⚡ 2. Hướng Dẫn Vận Hành Cho Nhà Phát Triển (Quickstart)
22
+
23
+ ### Bước 1: Khởi tạo Mini App mới bằng CLI
24
+ Lập trình viên bên thứ ba có thể chạy trực tiếp thông qua `npx`:
25
+ ```bash
26
+ npx @vqh2602/mini-app-sdk create my_awesome_app
27
+ ```
28
+ Hoặc nếu đã cài đặt toàn cục (`npm install -g @vqh2602/mini-app-sdk`):
29
+ ```bash
30
+ miniapp create my_awesome_app
31
+ ```
32
+ Lệnh này sẽ tự động sinh:
33
+ - `app.json`: Manifest khai báo `appId`, `name`, `version`, `permissions`, `themeColor`.
34
+ - `package.json`: Cài đặt sẵn `@vqh2602/mini-app-sdk`.
35
+ - `src/main.ts`: Code mẫu gọi các hàm đăng nhập, thanh toán, pin, toast.
36
+ - `index.html` & `vite.config.ts`.
37
+
38
+ ### Bước 2: Chạy Dev Server & Browser Simulator đồng thời
39
+ ```bash
40
+ cd my_awesome_app
41
+ npx miniapp dev
42
+ ```
43
+ Lệnh `miniapp dev` sẽ khởi chạy cả:
44
+ * Vite dev server của Mini App (Port 3000)
45
+ * Browser Simulator tích hợp sẵn (Port 5175 tại `http://localhost:5175/?url=http://localhost:3000`)
46
+
47
+ ### Bước 3: Đóng gói và xuất bản Mini App
20
48
  ```bash
21
- npm install @vqh2602/mini-app-sdk
49
+ # Đóng gói và kiểm tra checksum
50
+ npx miniapp build
51
+
52
+ # Tải lên SuperApp Dynamic Registry và gửi xét duyệt
53
+ npx miniapp upload --submit --notes "Phát hành phiên bản 1.0.0"
22
54
  ```
23
55
 
24
- ## 💡 Hướng dẫn nhanh (Quickstart)
56
+ ---
57
+
58
+ ## 📖 3. Bảng Tra Cứu API Mini App SDK (`@vqh2602/mini-app-sdk`)
25
59
 
60
+ ### 🔐 3.1. Xác thực & Người dùng (`superApp.auth`)
26
61
  ```typescript
27
62
  import superApp from '@vqh2602/mini-app-sdk';
28
63
 
29
- // 1. Đăng nhập người dùng
30
- const authData = await superApp.auth.login({
64
+ // Đăng nhập và xin cấp quyền profile + phone
65
+ const loginRes = await superApp.auth.login({
31
66
  scopes: ['user.profile', 'user.phone'],
32
67
  });
33
- console.log('Xin chào:', authData.user.name);
68
+ console.log('User Name:', loginRes.user.name);
69
+ console.log('Access Token:', loginRes.accessToken);
70
+
71
+ // Lấy thông tin người dùng hiện tại
72
+ const profile = await superApp.auth.getUserProfile();
73
+
74
+ // Lấy Access Token
75
+ const token = await superApp.auth.getAccessToken();
34
76
 
35
- // 2. Gọi thanh toán đơn hàng
77
+ // Đăng xuất
78
+ await superApp.auth.logout();
79
+ ```
80
+
81
+ ### 💳 3.2. Thanh toán SuperApp Pay (`superApp.payment`)
82
+ ```typescript
36
83
  try {
37
84
  const result = await superApp.payment.requestPayment({
38
- orderId: 'ORDER_12345',
39
- amount: 50000,
40
- description: 'Thanh toán cà phê sữa đá',
85
+ orderId: 'ORDER_2026_001',
86
+ amount: 150000,
87
+ description: 'Thanh toán Combo Cơm Trưa',
41
88
  });
42
89
 
43
90
  if (result.status === 'SUCCESS') {
44
- await superApp.ui.showToast('Thanh toán thành công!');
91
+ await superApp.ui.showToast('Thanh toán thành công qua Ví SuperApp!');
92
+ }
93
+ } catch (error: any) {
94
+ if (error.code === 'INSUFFICIENT_FUNDS') {
95
+ await superApp.ui.showAlert({ title: 'Lỗi', message: 'Số dư ví không đủ' });
96
+ } else if (error.code === 'USER_CANCELLED') {
97
+ await superApp.ui.showToast('Bạn đã huỷ thanh toán');
45
98
  }
46
- } catch (error) {
47
- await superApp.ui.showToast('Giao dịch thất bại');
48
99
  }
100
+ ```
49
101
 
50
- // 3. Đọc ghi bộ nhớ cục bộ
51
- await superApp.storage.setItem('user_cart', { items: 2, total: 50000 });
102
+ ### 📱 3.3. Thiết bị & Phần cứng (`superApp.device`)
103
+ ```typescript
104
+ // Mức pin và trạng thái sạc
105
+ const battery = await superApp.device.getBatteryInfo();
106
+ console.log(`Pin: ${battery.batteryLevel}%, Đang sạc: ${battery.isCharging}`);
107
+
108
+ // Trạng thái mạng
109
+ const network = await superApp.device.getNetworkInfo();
110
+ console.log(`Kết nối: ${network.networkType}, WiFi: ${network.isWifi}`);
111
+
112
+ // Rung xúc giác haptic feedback
113
+ await superApp.device.vibrate('light'); // 'light' | 'medium' | 'heavy'
114
+ ```
115
+
116
+ ### 💾 3.4. Lưu trữ cách ly (`superApp.storage`)
117
+ ```typescript
118
+ // Ghi dữ liệu
119
+ await superApp.storage.setItem('user_cart', { items: [{ id: 1, name: 'Trà Sữa' }] });
120
+
121
+ // Đọc dữ liệu (Tự động deserialize JSON)
52
122
  const cart = await superApp.storage.getItem('user_cart');
53
123
 
54
- // 4. Lắng nghe trạng thái ứng dụng
124
+ // Xoá key
125
+ await superApp.storage.removeItem('user_cart');
126
+ ```
127
+
128
+ ### 🔔 3.5. Giao diện & Điều hướng (`superApp.ui` / `superApp.navigation`)
129
+ ```typescript
130
+ // Toast
131
+ await superApp.ui.showToast('Cập nhật thành công!');
132
+
133
+ // Alert Dialog
134
+ await superApp.ui.showAlert({ title: 'Chúc mừng', message: 'Nhận được voucher 50%' });
135
+
136
+ // Confirm Dialog
137
+ const agreed = await superApp.ui.showConfirm({
138
+ title: 'Xoá giỏ hàng',
139
+ message: 'Bạn có chắc chắn muốn làm trống giỏ hàng?',
140
+ });
141
+
142
+ // Đặt tiêu đề thanh điều hướng
143
+ await superApp.ui.setNavigationBarTitle('Menu Quán Cà Phê');
144
+
145
+ // Đóng Mini App về màn hình chính SuperApp
146
+ await superApp.closeApp();
147
+ ```
148
+
149
+ ### 🔄 3.6. Vòng đời ứng dụng (`superApp.lifecycle`)
150
+ ```typescript
151
+ // Bắt sự kiện khi app ra màn hình (Foreground)
55
152
  superApp.lifecycle.onAppShow(() => {
56
153
  console.log('Mini App hiển thị trở lại');
57
154
  });
155
+
156
+ // Bắt sự kiện khi app bị ẩn xuống nền (Background)
157
+ superApp.lifecycle.onAppHide(() => {
158
+ console.log('Mini App tạm dừng');
159
+ });
58
160
  ```
package/bin/miniapp.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+
3
+ import('../dist/cli/index.js').catch((err) => {
4
+ console.error('[miniapp fatal error]', err);
5
+ process.exit(1);
6
+ });
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+
3
+ import http from 'node:http';
4
+ import fs from 'node:fs';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+ let distDir = path.resolve(__dirname, '../simulator-dist');
11
+ if (!fs.existsSync(distDir)) {
12
+ distDir = path.resolve(__dirname, '../dist/simulator');
13
+ }
14
+
15
+ const args = process.argv.slice(2);
16
+ const portIndex = args.indexOf('--port');
17
+ const port = portIndex !== -1 && args[portIndex + 1] ? parseInt(args[portIndex + 1], 10) : 5175;
18
+
19
+ const MIME_TYPES = {
20
+ '.html': 'text/html; charset=utf-8',
21
+ '.js': 'application/javascript; charset=utf-8',
22
+ '.css': 'text/css; charset=utf-8',
23
+ '.json': 'application/json',
24
+ '.png': 'image/png',
25
+ '.jpg': 'image/jpeg',
26
+ '.svg': 'image/svg+xml',
27
+ '.ico': 'image/x-icon',
28
+ '.woff2': 'font/woff2',
29
+ };
30
+
31
+ const server = http.createServer((req, res) => {
32
+ res.setHeader('Access-Control-Allow-Origin', '*');
33
+ res.setHeader('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS');
34
+
35
+ if (req.method === 'OPTIONS') {
36
+ res.writeHead(204);
37
+ res.end();
38
+ return;
39
+ }
40
+
41
+ const parsedUrl = new URL(req.url, `http://localhost:${port}`);
42
+ let pathname = parsedUrl.pathname;
43
+ let filePath = path.join(distDir, pathname);
44
+
45
+ if (!filePath.startsWith(distDir)) {
46
+ res.writeHead(403);
47
+ res.end('Forbidden');
48
+ return;
49
+ }
50
+
51
+ fs.stat(filePath, (err, stats) => {
52
+ if (err || !stats.isFile()) {
53
+ filePath = path.join(distDir, 'index.html');
54
+ }
55
+
56
+ const ext = path.extname(filePath).toLowerCase();
57
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
58
+
59
+ fs.readFile(filePath, (readErr, data) => {
60
+ if (readErr) {
61
+ res.writeHead(404);
62
+ res.end('Not Found');
63
+ return;
64
+ }
65
+ res.writeHead(200, { 'Content-Type': contentType });
66
+ res.end(data);
67
+ });
68
+ });
69
+ });
70
+
71
+ server.listen(port, () => {
72
+ console.log(`\n📱 \x1b[36mSuperApp Browser Simulator\x1b[0m is running at: \x1b[1mhttp://localhost:${port}\x1b[0m`);
73
+ console.log(`🔗 Open with target Mini App: \x1b[32mhttp://localhost:${port}/?url=http://localhost:3000\x1b[0m\n`);
74
+ });
@@ -0,0 +1,5 @@
1
+ export interface BuildCommandOptions {
2
+ outDir?: string;
3
+ }
4
+ export declare function buildProject(options?: BuildCommandOptions): Promise<void>;
5
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgEnF"}
@@ -0,0 +1,65 @@
1
+ import { execSync } from 'node:child_process';
2
+ import crypto from 'node:crypto';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { loadManifest } from '../utils/config.js';
6
+ import { logger } from '../utils/logger.js';
7
+ export async function buildProject(options = {}) {
8
+ const manifest = loadManifest();
9
+ const outDir = options.outDir || 'dist';
10
+ logger.title(`Đóng gói Mini App: ${manifest.name} (v${manifest.version})`);
11
+ logger.step(1, 3, 'Xác thực cấu hình app.json và các quyền permissions...');
12
+ if (manifest.permissions) {
13
+ logger.info(`Permissions: ${manifest.permissions.join(', ')}`);
14
+ }
15
+ logger.step(2, 3, 'Biên dịch mã nguồn với Vite & TypeScript...');
16
+ try {
17
+ execSync('npx vite build', { stdio: 'inherit' });
18
+ }
19
+ catch (err) {
20
+ logger.error('Lỗi khi biên dịch mã nguồn Mini App', err);
21
+ process.exit(1);
22
+ }
23
+ const distPath = path.resolve(process.cwd(), outDir);
24
+ const indexPath = path.join(distPath, manifest.entry || 'index.html');
25
+ if (!fs.existsSync(indexPath)) {
26
+ logger.error(`Không tìm thấy file entry "${manifest.entry}" trong thư mục build: ${distPath}`);
27
+ process.exit(1);
28
+ }
29
+ logger.step(3, 3, 'Tính toán checksum và tạo metadata gói phát hành...');
30
+ // Compute checksum of dist files
31
+ const hash = crypto.createHash('sha256');
32
+ function hashDirectory(dir) {
33
+ const files = fs.readdirSync(dir);
34
+ for (const file of files) {
35
+ const fullPath = path.join(dir, file);
36
+ const stat = fs.statSync(fullPath);
37
+ if (stat.isDirectory()) {
38
+ hashDirectory(fullPath);
39
+ }
40
+ else {
41
+ hash.update(fs.readFileSync(fullPath));
42
+ }
43
+ }
44
+ }
45
+ hashDirectory(distPath);
46
+ const bundleChecksum = hash.digest('hex');
47
+ const bundleMeta = {
48
+ appId: manifest.appId,
49
+ name: manifest.name,
50
+ version: manifest.version,
51
+ description: manifest.description,
52
+ entry: manifest.entry,
53
+ category: manifest.category,
54
+ themeColor: manifest.themeColor,
55
+ permissions: manifest.permissions,
56
+ checksum: bundleChecksum,
57
+ builtAt: new Date().toISOString(),
58
+ };
59
+ fs.writeFileSync(path.join(distPath, 'bundle-meta.json'), JSON.stringify(bundleMeta, null, 2));
60
+ logger.success(`Đóng gói thành công gói phát hành Mini App!`);
61
+ logger.info(`Thư mục output: ${distPath}`);
62
+ logger.info(`Bundle SHA256: ${bundleChecksum}`);
63
+ console.log(`\nSẵn sàng tải lên với lệnh:\n npx miniapp upload\n`);
64
+ }
65
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../../src/cli/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAM5C,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAA+B,EAAE;IAClE,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC;IAExC,MAAM,CAAC,KAAK,CAAC,sBAAsB,QAAQ,CAAC,IAAI,MAAM,QAAQ,CAAC,OAAO,GAAG,CAAC,CAAC;IAC3E,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,wDAAwD,CAAC,CAAC;IAC5E,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,6CAA6C,CAAC,CAAC;IACjE,IAAI,CAAC;QACH,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,IAAI,YAAY,CAAC,CAAC;IAEtE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,8BAA8B,QAAQ,CAAC,KAAK,0BAA0B,QAAQ,EAAE,CAAC,CAAC;QAC/F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,qDAAqD,CAAC,CAAC;IAEzE,iCAAiC;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,SAAS,aAAa,CAAC,GAAW;QAChC,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACnC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;IACD,aAAa,CAAC,QAAQ,CAAC,CAAC;IACxB,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE1C,MAAM,UAAU,GAAG;QACjB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,QAAQ,EAAE,cAAc;QACxB,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KAClC,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAE/F,MAAM,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;IAC9D,MAAM,CAAC,IAAI,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;IAC3C,MAAM,CAAC,IAAI,CAAC,kBAAkB,cAAc,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,5 @@
1
+ export interface CreateCommandOptions {
2
+ template?: string;
3
+ }
4
+ export declare function createProject(projectName: string, options?: CreateCommandOptions): Promise<void>;
5
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/create.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmO1G"}
@@ -0,0 +1,220 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { logger } from '../utils/logger.js';
4
+ export async function createProject(projectName, options = {}) {
5
+ const targetDir = path.resolve(process.cwd(), projectName);
6
+ if (fs.existsSync(targetDir)) {
7
+ logger.error(`Thư mục "${projectName}" đã tồn tại. Vui lòng chọn tên khác hoặc xoá thư mục cũ.`);
8
+ process.exit(1);
9
+ }
10
+ logger.title(`Khởi tạo Mini App mới: ${projectName}`);
11
+ logger.step(1, 3, `Đang tạo cấu trúc thư mục tại: ${targetDir}`);
12
+ fs.mkdirSync(targetDir, { recursive: true });
13
+ fs.mkdirSync(path.join(targetDir, 'src'), { recursive: true });
14
+ fs.mkdirSync(path.join(targetDir, 'public'), { recursive: true });
15
+ const sanitizedId = projectName.toLowerCase().replace(/[^a-z0-9_-]/g, '_');
16
+ // 1. app.json manifest
17
+ const appJson = {
18
+ appId: sanitizedId,
19
+ name: projectName.replace(/[-_]/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()),
20
+ version: '1.0.0',
21
+ description: `SuperApp Mini App: ${projectName}`,
22
+ entry: 'index.html',
23
+ category: 'utilities',
24
+ themeColor: '#0068FF',
25
+ permissions: [
26
+ 'auth.userProfile',
27
+ 'device.battery',
28
+ 'device.network',
29
+ 'storage',
30
+ ],
31
+ };
32
+ fs.writeFileSync(path.join(targetDir, 'app.json'), JSON.stringify(appJson, null, 2));
33
+ // 2. package.json
34
+ const packageJson = {
35
+ name: projectName,
36
+ private: true,
37
+ version: '1.0.0',
38
+ type: 'module',
39
+ scripts: {
40
+ dev: 'vite',
41
+ build: 'tsc && vite build',
42
+ preview: 'vite preview',
43
+ },
44
+ dependencies: {
45
+ '@vqh2602/mini-app-sdk': '^1.0.0',
46
+ },
47
+ devDependencies: {
48
+ typescript: '^5.6.3',
49
+ vite: '^5.4.11',
50
+ },
51
+ };
52
+ fs.writeFileSync(path.join(targetDir, 'package.json'), JSON.stringify(packageJson, null, 2));
53
+ // 3. tsconfig.json
54
+ const tsconfig = {
55
+ compilerOptions: {
56
+ target: 'ES2020',
57
+ useDefineForClassFields: true,
58
+ module: 'ESNext',
59
+ lib: ['ES2020', 'DOM', 'DOM.Iterable'],
60
+ skipLibCheck: true,
61
+ moduleResolution: 'bundler',
62
+ allowImportingTsExtensions: true,
63
+ resolveJsonModule: true,
64
+ isolatedModules: true,
65
+ noEmit: true,
66
+ strict: true,
67
+ noUnusedLocals: true,
68
+ noUnusedParameters: true,
69
+ noFallthroughCasesInSwitch: true,
70
+ },
71
+ include: ['src'],
72
+ };
73
+ fs.writeFileSync(path.join(targetDir, 'tsconfig.json'), JSON.stringify(tsconfig, null, 2));
74
+ // 4. vite.config.ts
75
+ const viteConfig = `import { defineConfig } from 'vite';
76
+
77
+ export default defineConfig({
78
+ base: './',
79
+ server: {
80
+ port: 3000,
81
+ },
82
+ build: {
83
+ outDir: 'dist',
84
+ assetsDir: 'assets',
85
+ },
86
+ });
87
+ `;
88
+ fs.writeFileSync(path.join(targetDir, 'vite.config.ts'), viteConfig);
89
+ // 5. index.html
90
+ const indexHtml = `<!DOCTYPE html>
91
+ <html lang="vi">
92
+ <head>
93
+ <meta charset="UTF-8" />
94
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
95
+ <title>${appJson.name}</title>
96
+ <style>
97
+ * { box-sizing: border-box; margin: 0; padding: 0; }
98
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f8fafc; color: #0f172a; padding: 16px; }
99
+ .card { background: white; border-radius: 12px; padding: 16px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
100
+ .btn { display: block; width: 100%; padding: 12px; border-radius: 8px; border: none; font-weight: 600; font-size: 14px; cursor: pointer; margin-bottom: 8px; }
101
+ .btn-primary { background: #0068FF; color: white; }
102
+ .btn-success { background: #10B981; color: white; }
103
+ .btn-secondary { background: #e2e8f0; color: #334155; }
104
+ h1 { font-size: 20px; font-weight: 700; margin-bottom: 4px; }
105
+ p { font-size: 13px; color: #64748b; line-height: 1.5; }
106
+ pre { background: #0f172a; color: #38bdf8; padding: 12px; border-radius: 8px; font-size: 12px; overflow-x: auto; max-height: 200px; }
107
+ </style>
108
+ </head>
109
+ <body>
110
+ <div class="card">
111
+ <h1>🚀 ${appJson.name}</h1>
112
+ <p>SuperApp Mini App SDK Demo Starter</p>
113
+ </div>
114
+
115
+ <div class="card">
116
+ <button id="btnLogin" class="btn btn-primary">👤 1. Đăng nhập SuperApp</button>
117
+ <button id="btnPay" class="btn btn-success">💳 2. Thanh toán đơn hàng</button>
118
+ <button id="btnDevice" class="btn btn-secondary">📱 3. Kiểm tra thông tin thiết bị</button>
119
+ <button id="btnToast" class="btn btn-secondary">🔔 4. Hiển thị thông báo Toast</button>
120
+ </div>
121
+
122
+ <div class="card">
123
+ <p style="font-weight: 600; margin-bottom: 8px;">Kết quả phản hồi:</p>
124
+ <pre id="output">Sẵn sàng gọi SDK...</pre>
125
+ </div>
126
+
127
+ <script type="module" src="/src/main.ts"></script>
128
+ </body>
129
+ </html>
130
+ `;
131
+ fs.writeFileSync(path.join(targetDir, 'index.html'), indexHtml);
132
+ // 6. src/main.ts
133
+ const mainTs = `import superApp from '@vqh2602/mini-app-sdk';
134
+
135
+ const outputEl = document.getElementById('output') as HTMLPreElement;
136
+
137
+ function log(data: any) {
138
+ outputEl.textContent = JSON.stringify(data, null, 2);
139
+ }
140
+
141
+ // 1. Đăng nhập
142
+ document.getElementById('btnLogin')?.addEventListener('click', async () => {
143
+ try {
144
+ const res = await superApp.auth.login({ scopes: ['user.profile', 'user.phone'] });
145
+ log(res);
146
+ await superApp.ui.showToast(\`Xin chào \${res.user.name}!\`);
147
+ } catch (err: any) {
148
+ log({ error: err });
149
+ }
150
+ });
151
+
152
+ // 2. Thanh toán
153
+ document.getElementById('btnPay')?.addEventListener('click', async () => {
154
+ try {
155
+ const res = await superApp.payment.requestPayment({
156
+ orderId: 'ORDER_' + Date.now(),
157
+ amount: 45000,
158
+ description: 'Thanh toán đơn hàng mẫu Mini App',
159
+ });
160
+ log(res);
161
+ await superApp.ui.showToast('Thanh toán thành công!');
162
+ } catch (err: any) {
163
+ log({ error: err });
164
+ }
165
+ });
166
+
167
+ // 3. Thông tin thiết bị
168
+ document.getElementById('btnDevice')?.addEventListener('click', async () => {
169
+ try {
170
+ const battery = await superApp.device.getBatteryInfo();
171
+ const network = await superApp.device.getNetworkInfo();
172
+ const system = await superApp.device.getSystemInfo();
173
+ log({ battery, network, system });
174
+ } catch (err: any) {
175
+ log({ error: err });
176
+ }
177
+ });
178
+
179
+ // 4. Toast & Rung
180
+ document.getElementById('btnToast')?.addEventListener('click', async () => {
181
+ await superApp.device.vibrate('light');
182
+ await superApp.ui.showToast('Thông báo Toast từ SuperApp SDK');
183
+ });
184
+ `;
185
+ fs.writeFileSync(path.join(targetDir, 'src/main.ts'), mainTs);
186
+ // 7. .gitignore
187
+ const gitignore = `node_modules
188
+ dist
189
+ .DS_Store
190
+ *.local
191
+ `;
192
+ fs.writeFileSync(path.join(targetDir, '.gitignore'), gitignore);
193
+ // 8. README.md
194
+ const readme = `# ${projectName}
195
+
196
+ Dự án Mini App chạy trên nền tảng SuperApp.
197
+
198
+ ## Bắt đầu
199
+
200
+ \`\`\`bash
201
+ # 1. Cài đặt thư viện
202
+ npm install
203
+
204
+ # 2. Khởi chạy dev server & simulator
205
+ npx miniapp dev
206
+
207
+ # 3. Đóng gói sản phẩm
208
+ npx miniapp build
209
+
210
+ # 4. Xuất bản lên SuperApp Dynamic Registry
211
+ npx miniapp upload
212
+ \`\`\`
213
+ `;
214
+ fs.writeFileSync(path.join(targetDir, 'README.md'), readme);
215
+ logger.step(2, 3, 'Khởi tạo mã nguồn và file cấu hình manifest app.json thành công!');
216
+ logger.step(3, 3, 'Hoàn tất.');
217
+ logger.success(`Mini App "${projectName}" đã sẵn sàng!`);
218
+ console.log(`\nTiếp theo, hãy thực hiện:\n cd ${projectName}\n npm install\n npx miniapp dev\n`);
219
+ }
220
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../../../src/cli/commands/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAM5C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAmB,EAAE,UAAgC,EAAE;IACzF,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAE3D,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,YAAY,WAAW,2DAA2D,CAAC,CAAC;QACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAC;IACtD,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,kCAAkC,SAAS,EAAE,CAAC,CAAC;IACjE,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAElE,MAAM,WAAW,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAE3E,uBAAuB;IACvB,MAAM,OAAO,GAAG;QACd,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAChF,OAAO,EAAE,OAAO;QAChB,WAAW,EAAE,sBAAsB,WAAW,EAAE;QAChD,KAAK,EAAE,YAAY;QACnB,QAAQ,EAAE,WAAW;QACrB,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE;YACX,kBAAkB;YAClB,gBAAgB;YAChB,gBAAgB;YAChB,SAAS;SACV;KACF,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAErF,kBAAkB;IAClB,MAAM,WAAW,GAAG;QAClB,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,MAAM;YACX,KAAK,EAAE,mBAAmB;YAC1B,OAAO,EAAE,cAAc;SACxB;QACD,YAAY,EAAE;YACZ,uBAAuB,EAAE,QAAQ;SAClC;QACD,eAAe,EAAE;YACf,UAAU,EAAE,QAAQ;YACpB,IAAI,EAAE,SAAS;SAChB;KACF,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAE7F,mBAAmB;IACnB,MAAM,QAAQ,GAAG;QACf,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,uBAAuB,EAAE,IAAI;YAC7B,MAAM,EAAE,QAAQ;YAChB,GAAG,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,cAAc,CAAC;YACtC,YAAY,EAAE,IAAI;YAClB,gBAAgB,EAAE,SAAS;YAC3B,0BAA0B,EAAE,IAAI;YAChC,iBAAiB,EAAE,IAAI;YACvB,eAAe,EAAE,IAAI;YACrB,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,IAAI;YACZ,cAAc,EAAE,IAAI;YACpB,kBAAkB,EAAE,IAAI;YACxB,0BAA0B,EAAE,IAAI;SACjC;QACD,OAAO,EAAE,CAAC,KAAK,CAAC;KACjB,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAE3F,oBAAoB;IACpB,MAAM,UAAU,GAAG;;;;;;;;;;;;CAYpB,CAAC;IACA,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,EAAE,UAAU,CAAC,CAAC;IAErE,gBAAgB;IAChB,MAAM,SAAS,GAAG;;;;;aAKP,OAAO,CAAC,IAAI;;;;;;;;;;;;;;;;eAgBV,OAAO,CAAC,IAAI;;;;;;;;;;;;;;;;;;;CAmB1B,CAAC;IACA,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC;IAEhE,iBAAiB;IACjB,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDhB,CAAC;IACA,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;IAE9D,gBAAgB;IAChB,MAAM,SAAS,GAAG;;;;CAInB,CAAC;IACA,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,SAAS,CAAC,CAAC;IAEhE,eAAe;IACf,MAAM,MAAM,GAAG,KAAK,WAAW;;;;;;;;;;;;;;;;;;;CAmBhC,CAAC;IACA,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC;IAE5D,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,kEAAkE,CAAC,CAAC;IACtF,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC;IAC/B,MAAM,CAAC,OAAO,CAAC,aAAa,WAAW,gBAAgB,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,qCAAqC,WAAW,sCAAsC,CAAC,CAAC;AACtG,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface DevCommandOptions {
2
+ port?: string;
3
+ simulatorPort?: string;
4
+ open?: boolean;
5
+ noSimulator?: boolean;
6
+ }
7
+ export declare function devServer(options?: DevCommandOptions): Promise<void>;
8
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/dev.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,SAAS,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC9E"}
@@ -0,0 +1,41 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { loadManifest } from '../utils/config.js';
3
+ import { logger } from '../utils/logger.js';
4
+ import { startSimulatorServer } from '../utils/server.js';
5
+ export async function devServer(options = {}) {
6
+ const manifest = loadManifest();
7
+ const port = options.port || '3000';
8
+ const simulatorPort = options.simulatorPort || '5175';
9
+ logger.title(`Khởi chạy Mini App Development Server`);
10
+ logger.info(`Đang chạy ứng dụng: ${manifest.name} (${manifest.appId})`);
11
+ let simServer = null;
12
+ if (!options.noSimulator) {
13
+ try {
14
+ simServer = startSimulatorServer(parseInt(simulatorPort, 10));
15
+ }
16
+ catch (e) {
17
+ logger.warn(`Không thể khởi chạy Simulator trên cổng ${simulatorPort}`);
18
+ }
19
+ }
20
+ logger.info(`Vite Server: http://localhost:${port}`);
21
+ logger.info(`Browser Simulator: http://localhost:${simulatorPort}/?url=http://localhost:${port}`);
22
+ const child = spawn('npx', ['vite', '--port', port], {
23
+ stdio: 'inherit',
24
+ shell: true,
25
+ });
26
+ child.on('error', (err) => {
27
+ logger.error('Lỗi khởi động Vite Dev Server:', err);
28
+ });
29
+ process.on('SIGINT', () => {
30
+ logger.info('Đang dừng Development Server & Simulator...');
31
+ if (simServer) {
32
+ try {
33
+ simServer.close();
34
+ }
35
+ catch (_) { }
36
+ }
37
+ child.kill('SIGINT');
38
+ process.exit(0);
39
+ });
40
+ }
41
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../../src/cli/commands/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAS1D,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,UAA6B,EAAE;IAC7D,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,CAAC;IACpC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,MAAM,CAAC;IAEtD,MAAM,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACtD,MAAM,CAAC,IAAI,CAAC,uBAAuB,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC;IAExE,IAAI,SAAS,GAAQ,IAAI,CAAC;IAC1B,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,2CAA2C,aAAa,EAAE,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,CAAC,IAAI,CAAC,uCAAuC,aAAa,0BAA0B,IAAI,EAAE,CAAC,CAAC;IAElG,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE;QACnD,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACxB,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC3D,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC,CAAA,CAAC;QAChB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runDoctor(): Promise<void>;
2
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAyC/C"}