@hapico/cli 0.0.11 → 0.0.13

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/bin/index.js CHANGED
@@ -48,9 +48,11 @@ const ws_1 = require("ws");
48
48
  const Babel = __importStar(require("@babel/standalone"));
49
49
  const qrcode_terminal_1 = __importDefault(require("qrcode-terminal"));
50
50
  const open_1 = __importDefault(require("open"));
51
+ const crypto_1 = require("crypto");
51
52
  // Directory to store the token and project config
52
53
  const CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".hapico");
53
54
  const TOKEN_FILE = path.join(CONFIG_DIR, "auth_token.json");
55
+ const connected = (0, ora_1.default)("Connected to WebSocket server");
54
56
  // Ensure config directory exists
55
57
  if (!fs.existsSync(CONFIG_DIR)) {
56
58
  fs.mkdirSync(CONFIG_DIR, { recursive: true });
@@ -69,10 +71,10 @@ const getStoredToken = () => {
69
71
  if (fs.existsSync(TOKEN_FILE)) {
70
72
  const data = fs.readFileSync(TOKEN_FILE, { encoding: "utf8" });
71
73
  const json = JSON.parse(data);
72
- return json !== null && json !== void 0 ? json : {
74
+ return (json !== null && json !== void 0 ? json : {
73
75
  accessToken: null,
74
76
  refreshToken: null,
75
- };
77
+ });
76
78
  }
77
79
  return {
78
80
  accessToken: null,
@@ -244,13 +246,13 @@ class RoomState {
244
246
  this.isConnected = true;
245
247
  this.reconnectAttempts = 0;
246
248
  onConnected === null || onConnected === void 0 ? void 0 : onConnected();
249
+ connected.succeed(`Connected to WebSocket server`);
247
250
  });
248
251
  this.ws.on("close", () => {
249
252
  this.isConnected = false;
250
253
  this.reconnectAttempts++;
251
- const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
252
- console.log(`Attempting to reconnect in ${delay / 1000}s...`);
253
- this.reconnectTimeout = setTimeout(() => this.connect(), delay);
254
+ connected.start(`Retry connection...`);
255
+ this.connect();
254
256
  });
255
257
  this.ws.on("message", (data) => {
256
258
  try {
@@ -298,7 +300,7 @@ class RoomState {
298
300
  return this.isConnected;
299
301
  }
300
302
  }
301
- commander_1.program.version("0.0.10").description("Hapico CLI for project management");
303
+ commander_1.program.version("0.0.13").description("Hapico CLI for project management");
302
304
  commander_1.program
303
305
  .command("clone <id>")
304
306
  .description("Clone a project by ID")
@@ -371,12 +373,18 @@ commander_1.program
371
373
  devSpinner.fail("Source directory 'src' does not exist. Please clone a project first.");
372
374
  return;
373
375
  }
374
- const projectId = getStoredProjectId(pwd);
376
+ const info = JSON.stringify({
377
+ id: (0, crypto_1.randomUUID)(),
378
+ createdAt: new Date().toISOString(),
379
+ viewId: getStoredProjectId(pwd),
380
+ });
381
+ // convert info info to base64
382
+ const projectId = Buffer.from(info).toString("base64");
375
383
  if (!projectId) {
376
384
  devSpinner.fail("Project ID not found. Please ensure hapico.config.json exists in the project directory.");
377
385
  return;
378
386
  }
379
- console.log(`Connecting to WebSocket server for room: ${projectId}`);
387
+ console.log(`Connecting to WebSocket server`);
380
388
  const room = new RoomState(`view_${projectId}`);
381
389
  room.connect(async () => {
382
390
  devSpinner.succeed("Project started in development mode!");
@@ -394,10 +402,37 @@ commander_1.program
394
402
  });
395
403
  room.updateState("view", updatedView);
396
404
  });
397
- qrcode_terminal_1.default.generate(`https://zalo.me/s/3218692650896662017/player/${projectId}`, { small: true }, (qrcode) => {
398
- console.log("Scan this QR code to connect to the project:");
399
- console.log(qrcode);
405
+ // LẤy thông tin về project
406
+ const projectInfo = getStoredProjectId(pwd);
407
+ if (!projectInfo) {
408
+ console.error("Project ID not found. Please ensure hapico.config.json exists in the project directory.");
409
+ return;
410
+ }
411
+ const project = await axios_1.default.get(`https://base.myworkbeast.com/api/views/${projectInfo}`, {
412
+ headers: {
413
+ Authorization: `Bearer ${accessToken}`,
414
+ "Content-Type": "application/json",
415
+ },
400
416
  });
417
+ if (project.status !== 200) {
418
+ console.error(`Error fetching project info: ${project.statusText}`);
419
+ return;
420
+ }
421
+ const projectType = project.data.type || "view";
422
+ console.log("Project type:", projectType);
423
+ if (projectType === "zalominiapp") {
424
+ qrcode_terminal_1.default.generate(`https://zalo.me/s/3218692650896662017/player/${projectId}`, { small: true }, (qrcode) => {
425
+ console.log("Scan this QR code to connect to the project:");
426
+ console.log(qrcode);
427
+ });
428
+ return;
429
+ }
430
+ else {
431
+ // show link https://com.ai.vn/dev_preview/{projectId}
432
+ const previewUrl = `https://com.ai.vn/dev_preview/${projectId}`;
433
+ console.log(`Open this URL in your browser to preview the project: \n${previewUrl}`);
434
+ await (0, open_1.default)(previewUrl);
435
+ }
401
436
  });
402
437
  });
403
438
  commander_1.program
package/dist/index.js CHANGED
@@ -48,9 +48,11 @@ const ws_1 = require("ws");
48
48
  const Babel = __importStar(require("@babel/standalone"));
49
49
  const qrcode_terminal_1 = __importDefault(require("qrcode-terminal"));
50
50
  const open_1 = __importDefault(require("open"));
51
+ const crypto_1 = require("crypto");
51
52
  // Directory to store the token and project config
52
53
  const CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".hapico");
53
54
  const TOKEN_FILE = path.join(CONFIG_DIR, "auth_token.json");
55
+ const connected = (0, ora_1.default)("Connected to WebSocket server");
54
56
  // Ensure config directory exists
55
57
  if (!fs.existsSync(CONFIG_DIR)) {
56
58
  fs.mkdirSync(CONFIG_DIR, { recursive: true });
@@ -69,10 +71,10 @@ const getStoredToken = () => {
69
71
  if (fs.existsSync(TOKEN_FILE)) {
70
72
  const data = fs.readFileSync(TOKEN_FILE, { encoding: "utf8" });
71
73
  const json = JSON.parse(data);
72
- return json !== null && json !== void 0 ? json : {
74
+ return (json !== null && json !== void 0 ? json : {
73
75
  accessToken: null,
74
76
  refreshToken: null,
75
- };
77
+ });
76
78
  }
77
79
  return {
78
80
  accessToken: null,
@@ -244,13 +246,13 @@ class RoomState {
244
246
  this.isConnected = true;
245
247
  this.reconnectAttempts = 0;
246
248
  onConnected === null || onConnected === void 0 ? void 0 : onConnected();
249
+ connected.succeed(`Connected to WebSocket server`);
247
250
  });
248
251
  this.ws.on("close", () => {
249
252
  this.isConnected = false;
250
253
  this.reconnectAttempts++;
251
- const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
252
- console.log(`Attempting to reconnect in ${delay / 1000}s...`);
253
- this.reconnectTimeout = setTimeout(() => this.connect(), delay);
254
+ connected.start(`Retry connection...`);
255
+ this.connect();
254
256
  });
255
257
  this.ws.on("message", (data) => {
256
258
  try {
@@ -298,7 +300,7 @@ class RoomState {
298
300
  return this.isConnected;
299
301
  }
300
302
  }
301
- commander_1.program.version("0.0.10").description("Hapico CLI for project management");
303
+ commander_1.program.version("0.0.13").description("Hapico CLI for project management");
302
304
  commander_1.program
303
305
  .command("clone <id>")
304
306
  .description("Clone a project by ID")
@@ -371,12 +373,18 @@ commander_1.program
371
373
  devSpinner.fail("Source directory 'src' does not exist. Please clone a project first.");
372
374
  return;
373
375
  }
374
- const projectId = getStoredProjectId(pwd);
376
+ const info = JSON.stringify({
377
+ id: (0, crypto_1.randomUUID)(),
378
+ createdAt: new Date().toISOString(),
379
+ viewId: getStoredProjectId(pwd),
380
+ });
381
+ // convert info info to base64
382
+ const projectId = Buffer.from(info).toString("base64");
375
383
  if (!projectId) {
376
384
  devSpinner.fail("Project ID not found. Please ensure hapico.config.json exists in the project directory.");
377
385
  return;
378
386
  }
379
- console.log(`Connecting to WebSocket server for room: ${projectId}`);
387
+ console.log(`Connecting to WebSocket server`);
380
388
  const room = new RoomState(`view_${projectId}`);
381
389
  room.connect(async () => {
382
390
  devSpinner.succeed("Project started in development mode!");
@@ -394,10 +402,37 @@ commander_1.program
394
402
  });
395
403
  room.updateState("view", updatedView);
396
404
  });
397
- qrcode_terminal_1.default.generate(`https://zalo.me/s/3218692650896662017/player/${projectId}`, { small: true }, (qrcode) => {
398
- console.log("Scan this QR code to connect to the project:");
399
- console.log(qrcode);
405
+ // LẤy thông tin về project
406
+ const projectInfo = getStoredProjectId(pwd);
407
+ if (!projectInfo) {
408
+ console.error("Project ID not found. Please ensure hapico.config.json exists in the project directory.");
409
+ return;
410
+ }
411
+ const project = await axios_1.default.get(`https://base.myworkbeast.com/api/views/${projectInfo}`, {
412
+ headers: {
413
+ Authorization: `Bearer ${accessToken}`,
414
+ "Content-Type": "application/json",
415
+ },
400
416
  });
417
+ if (project.status !== 200) {
418
+ console.error(`Error fetching project info: ${project.statusText}`);
419
+ return;
420
+ }
421
+ const projectType = project.data.type || "view";
422
+ console.log("Project type:", projectType);
423
+ if (projectType === "zalominiapp") {
424
+ qrcode_terminal_1.default.generate(`https://zalo.me/s/3218692650896662017/player/${projectId}`, { small: true }, (qrcode) => {
425
+ console.log("Scan this QR code to connect to the project:");
426
+ console.log(qrcode);
427
+ });
428
+ return;
429
+ }
430
+ else {
431
+ // show link https://com.ai.vn/dev_preview/{projectId}
432
+ const previewUrl = `https://com.ai.vn/dev_preview/${projectId}`;
433
+ console.log(`Open this URL in your browser to preview the project: \n${previewUrl}`);
434
+ await (0, open_1.default)(previewUrl);
435
+ }
401
436
  });
402
437
  });
403
438
  commander_1.program
package/index.ts CHANGED
@@ -10,6 +10,7 @@ import { WebSocket } from "ws";
10
10
  import * as Babel from "@babel/standalone";
11
11
  import QRCode from "qrcode-terminal";
12
12
  import open from "open";
13
+ import { randomUUID } from "crypto";
13
14
 
14
15
  // Directory to store the token and project config
15
16
  const CONFIG_DIR = path.join(
@@ -18,6 +19,8 @@ const CONFIG_DIR = path.join(
18
19
  );
19
20
  const TOKEN_FILE = path.join(CONFIG_DIR, "auth_token.json");
20
21
 
22
+ const connected = ora("Connected to WebSocket server");
23
+
21
24
  // Ensure config directory exists
22
25
  if (!fs.existsSync(CONFIG_DIR)) {
23
26
  fs.mkdirSync(CONFIG_DIR, { recursive: true });
@@ -28,13 +31,9 @@ const saveToken = (tokens: { accessToken: string; refreshToken?: string }) => {
28
31
  if (!tokens || !tokens.accessToken) {
29
32
  throw new Error("Invalid token data");
30
33
  }
31
- fs.writeFileSync(
32
- TOKEN_FILE,
33
- JSON.stringify(tokens, null, 2),
34
- {
35
- encoding: "utf8",
36
- }
37
- );
34
+ fs.writeFileSync(TOKEN_FILE, JSON.stringify(tokens, null, 2), {
35
+ encoding: "utf8",
36
+ });
38
37
  };
39
38
 
40
39
  // Function to get stored token
@@ -45,10 +44,12 @@ const getStoredToken = (): {
45
44
  if (fs.existsSync(TOKEN_FILE)) {
46
45
  const data = fs.readFileSync(TOKEN_FILE, { encoding: "utf8" });
47
46
  const json = JSON.parse(data);
48
- return json ?? {
49
- accessToken: null,
50
- refreshToken: null,
51
- };
47
+ return (
48
+ json ?? {
49
+ accessToken: null,
50
+ refreshToken: null,
51
+ }
52
+ );
52
53
  }
53
54
  return {
54
55
  accessToken: null,
@@ -282,16 +283,16 @@ class RoomState {
282
283
  this.isConnected = true;
283
284
  this.reconnectAttempts = 0;
284
285
  onConnected?.();
286
+ connected.succeed(`Connected to WebSocket server`);
285
287
  });
286
288
 
287
289
  this.ws.on("close", () => {
288
290
  this.isConnected = false;
289
291
 
290
292
  this.reconnectAttempts++;
291
- const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
292
- console.log(`Attempting to reconnect in ${delay / 1000}s...`);
293
+ connected.start(`Retry connection...`);
293
294
 
294
- this.reconnectTimeout = setTimeout(() => this.connect(), delay);
295
+ this.connect();
295
296
  });
296
297
 
297
298
  this.ws.on("message", (data: Buffer) => {
@@ -345,7 +346,7 @@ class RoomState {
345
346
  }
346
347
  }
347
348
 
348
- program.version("0.0.10").description("Hapico CLI for project management");
349
+ program.version("0.0.13").description("Hapico CLI for project management");
349
350
 
350
351
  program
351
352
  .command("clone <id>")
@@ -441,14 +442,20 @@ program
441
442
  );
442
443
  return;
443
444
  }
444
- const projectId = getStoredProjectId(pwd);
445
+ const info = JSON.stringify({
446
+ id: randomUUID(),
447
+ createdAt: new Date().toISOString(),
448
+ viewId: getStoredProjectId(pwd),
449
+ });
450
+ // convert info info to base64
451
+ const projectId = Buffer.from(info).toString("base64");
445
452
  if (!projectId) {
446
453
  devSpinner.fail(
447
454
  "Project ID not found. Please ensure hapico.config.json exists in the project directory."
448
455
  );
449
456
  return;
450
457
  }
451
- console.log(`Connecting to WebSocket server for room: ${projectId}`);
458
+ console.log(`Connecting to WebSocket server`);
452
459
  const room = new RoomState(`view_${projectId}`);
453
460
 
454
461
  room.connect(async () => {
@@ -471,14 +478,51 @@ program
471
478
  room.updateState("view", updatedView);
472
479
  });
473
480
 
474
- QRCode.generate(
475
- `https://zalo.me/s/3218692650896662017/player/${projectId}`,
476
- { small: true },
477
- (qrcode: string) => {
478
- console.log("Scan this QR code to connect to the project:");
479
- console.log(qrcode);
481
+ // LẤy thông tin về project
482
+ const projectInfo = getStoredProjectId(pwd);
483
+ if (!projectInfo) {
484
+ console.error(
485
+ "Project ID not found. Please ensure hapico.config.json exists in the project directory."
486
+ );
487
+ return;
488
+ }
489
+ const project = await axios.get(
490
+ `https://base.myworkbeast.com/api/views/${projectInfo}`,
491
+ {
492
+ headers: {
493
+ Authorization: `Bearer ${accessToken}`,
494
+ "Content-Type": "application/json",
495
+ },
480
496
  }
481
497
  );
498
+
499
+ if (project.status !== 200) {
500
+ console.error(`Error fetching project info: ${project.statusText}`);
501
+ return;
502
+ }
503
+
504
+ const projectType = project.data.type || "view";
505
+
506
+ console.log("Project type:", projectType);
507
+
508
+ if (projectType === "zalominiapp") {
509
+ QRCode.generate(
510
+ `https://zalo.me/s/3218692650896662017/player/${projectId}`,
511
+ { small: true },
512
+ (qrcode: string) => {
513
+ console.log("Scan this QR code to connect to the project:");
514
+ console.log(qrcode);
515
+ }
516
+ );
517
+ return;
518
+ } else {
519
+ // show link https://com.ai.vn/dev_preview/{projectId}
520
+ const previewUrl = `https://com.ai.vn/dev_preview/${projectId}`;
521
+ console.log(
522
+ `Open this URL in your browser to preview the project: \n${previewUrl}`
523
+ );
524
+ await open(previewUrl);
525
+ }
482
526
  });
483
527
  });
484
528
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hapico/cli",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "A simple CLI tool for project management",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -9,6 +9,7 @@
9
9
  "scripts": {
10
10
  "build": "tsc && cp -r dist/* ./bin/",
11
11
  "start": "node dist/index.js",
12
+ "dev": "npm run build && bun link @hapico/cli",
12
13
  "pub": "npm run build && npm publish --access public"
13
14
  },
14
15
  "keywords": [