@hapico/cli 0.0.15 → 0.0.17

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
@@ -244,7 +244,7 @@ class RoomState {
244
244
  if (this.reconnectTimeout) {
245
245
  clearTimeout(this.reconnectTimeout);
246
246
  }
247
- this.ws = new ws_1.WebSocket(`https://base.myworkbeast.com/ws?room=${this.roomId}`);
247
+ this.ws = new ws_1.WebSocket(`https://ws2.myworkbeast.com/ws?room=${this.roomId}`);
248
248
  this.ws.onopen = () => {
249
249
  console.log(`Connected to room: ${this.roomId}`);
250
250
  this.isConnected = true;
@@ -263,7 +263,15 @@ class RoomState {
263
263
  try {
264
264
  const jsonStr = typeof data === "string" ? data : data.toString();
265
265
  const parsedData = JSON.parse(jsonStr);
266
- const includes = ["view", "coding", "refresh_key", "useActiveIdFocus", "activeId", "active_file", "figma"];
266
+ const includes = [
267
+ "view",
268
+ "coding",
269
+ "refresh_key",
270
+ "useActiveIdFocus",
271
+ "activeId",
272
+ "active_file",
273
+ "figma",
274
+ ];
267
275
  let newState;
268
276
  let changedKeys;
269
277
  if (parsedData.type === "state") {
@@ -325,7 +333,7 @@ class RoomState {
325
333
  return this.isConnected;
326
334
  }
327
335
  }
328
- commander_1.program.version("0.0.15").description("Hapico CLI for project management");
336
+ commander_1.program.version("0.0.16").description("Hapico CLI for project management");
329
337
  commander_1.program
330
338
  .command("clone <id>")
331
339
  .description("Clone a project by ID")
@@ -437,21 +445,24 @@ commander_1.program
437
445
  }
438
446
  console.log(`Connecting to WebSocket server`);
439
447
  const room = new RoomState(`view_${projectId}`, []);
448
+ const fileManager = new FileManager(srcDir);
449
+ const initialFiles = fileManager.listFiles();
450
+ room.files = initialFiles;
440
451
  room.connect(async () => {
441
452
  devSpinner.succeed("Project started in development mode!");
442
- const fileManager = new FileManager(srcDir);
443
- const initialFiles = fileManager.listFiles();
444
453
  room.updateState("view", initialFiles);
445
454
  fileManager.setOnFileChange((filePath, content) => {
446
- const es5 = (0, exports.compileES5)(content, filePath);
455
+ var _a;
456
+ const es5 = (_a = (0, exports.compileES5)(content, filePath)) !== null && _a !== void 0 ? _a : "";
447
457
  console.log(`File changed: ${filePath === null || filePath === void 0 ? void 0 : filePath.replace(srcDir, ".")}`);
448
- const updatedView = initialFiles.map((file) => {
458
+ const updatedFiles = room.files.map((file) => {
449
459
  if (path.join(srcDir, file.path) === filePath) {
450
460
  return { ...file, content, es5 };
451
461
  }
452
462
  return file;
453
463
  });
454
- room.updateState("view", updatedView);
464
+ room.files = updatedFiles;
465
+ room.updateState("view", updatedFiles);
455
466
  });
456
467
  // Fetch project info
457
468
  const projectInfo = getStoredProjectId(pwd);
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class Path {
4
+ static normalizeSlashes(path) {
5
+ return path.replace(/\\/g, "/");
6
+ }
7
+ // Tương tự path.join()
8
+ static join(...paths) {
9
+ const normalizedPaths = paths
10
+ .filter((p) => p && typeof p === "string")
11
+ .map((p) => this.normalizeSlashes(p.trim()))
12
+ .map((p) => p.replace(/^\/+|\/+$/g, "")); // Loại bỏ slash đầu và cuối
13
+ return normalizedPaths.join("/");
14
+ }
15
+ // Tương tự path.resolve()
16
+ static resolve(...paths) {
17
+ let resolvedPath = "";
18
+ const segments = [];
19
+ paths
20
+ .filter((p) => p && typeof p === "string")
21
+ .map((p) => this.normalizeSlashes(p))
22
+ .forEach((path) => {
23
+ if (path.startsWith("/")) {
24
+ segments.length = 0; // Reset nếu gặp absolute path
25
+ segments.push(...path.split("/").filter(Boolean));
26
+ }
27
+ else {
28
+ segments.push(...path.split("/").filter(Boolean));
29
+ }
30
+ });
31
+ const resolvedSegments = [];
32
+ for (const segment of segments) {
33
+ if (segment === "..") {
34
+ resolvedSegments.pop();
35
+ }
36
+ else if (segment !== ".") {
37
+ resolvedSegments.push(segment);
38
+ }
39
+ }
40
+ resolvedPath = resolvedSegments.join("/");
41
+ return resolvedPath.startsWith("/") ? `/${resolvedPath}` : resolvedPath;
42
+ }
43
+ // Tương tự path.basename()
44
+ static basename(path, ext) {
45
+ const normalized = this.normalizeSlashes(path);
46
+ const base = normalized.split("/").pop() || "";
47
+ return ext && base.endsWith(ext) ? base.slice(0, -ext.length) : base;
48
+ }
49
+ // Tương tự path.dirname()
50
+ static dirname(path) {
51
+ const normalized = this.normalizeSlashes(path);
52
+ const segments = normalized.split("/");
53
+ segments.pop();
54
+ return segments.join("/") || ".";
55
+ }
56
+ // Tương tự path.extname()
57
+ static extname(path) {
58
+ const base = this.basename(path);
59
+ const dotIndex = base.lastIndexOf(".");
60
+ return dotIndex > 0 ? base.slice(dotIndex) : "";
61
+ }
62
+ // Tương tự path.isAbsolute()
63
+ static isAbsolute(path) {
64
+ return this.normalizeSlashes(path).startsWith("/");
65
+ }
66
+ // Tương tự path.relative()
67
+ static relative(from, to) {
68
+ const fromParts = this.normalizeSlashes(from).split("/").filter(Boolean);
69
+ const toParts = this.normalizeSlashes(to).split("/").filter(Boolean);
70
+ // Tìm điểm chung
71
+ let i = 0;
72
+ while (i < fromParts.length &&
73
+ i < toParts.length &&
74
+ fromParts[i] === toParts[i]) {
75
+ i++;
76
+ }
77
+ // Tính số bước đi lên
78
+ const upCount = fromParts.length - i;
79
+ const up = Array(upCount).fill("..");
80
+ const remaining = toParts.slice(i);
81
+ return [...up, ...remaining].join("/") || ".";
82
+ }
83
+ }
84
+ exports.default = Path;
package/bun.lock CHANGED
@@ -10,8 +10,10 @@
10
10
  "lodash": "^4.17.21",
11
11
  "open": "^10.2.0",
12
12
  "ora": "^8.2.0",
13
+ "prettier": "^3.6.2",
13
14
  "qrcode-terminal": "^0.12.0",
14
15
  "unzipper": "^0.12.3",
16
+ "uuid": "^13.0.0",
15
17
  "ws": "^8.18.3",
16
18
  },
17
19
  "devDependencies": {
@@ -165,6 +167,8 @@
165
167
 
166
168
  "ora": ["ora@8.2.0", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="],
167
169
 
170
+ "prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
171
+
168
172
  "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
169
173
 
170
174
  "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
@@ -199,6 +203,8 @@
199
203
 
200
204
  "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
201
205
 
206
+ "uuid": ["uuid@13.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="],
207
+
202
208
  "ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
203
209
 
204
210
  "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="],
package/dist/index.js CHANGED
@@ -244,7 +244,7 @@ class RoomState {
244
244
  if (this.reconnectTimeout) {
245
245
  clearTimeout(this.reconnectTimeout);
246
246
  }
247
- this.ws = new ws_1.WebSocket(`https://base.myworkbeast.com/ws?room=${this.roomId}`);
247
+ this.ws = new ws_1.WebSocket(`https://ws2.myworkbeast.com/ws?room=${this.roomId}`);
248
248
  this.ws.onopen = () => {
249
249
  console.log(`Connected to room: ${this.roomId}`);
250
250
  this.isConnected = true;
@@ -263,7 +263,15 @@ class RoomState {
263
263
  try {
264
264
  const jsonStr = typeof data === "string" ? data : data.toString();
265
265
  const parsedData = JSON.parse(jsonStr);
266
- const includes = ["view", "coding", "refresh_key", "useActiveIdFocus", "activeId", "active_file", "figma"];
266
+ const includes = [
267
+ "view",
268
+ "coding",
269
+ "refresh_key",
270
+ "useActiveIdFocus",
271
+ "activeId",
272
+ "active_file",
273
+ "figma",
274
+ ];
267
275
  let newState;
268
276
  let changedKeys;
269
277
  if (parsedData.type === "state") {
@@ -325,7 +333,7 @@ class RoomState {
325
333
  return this.isConnected;
326
334
  }
327
335
  }
328
- commander_1.program.version("0.0.15").description("Hapico CLI for project management");
336
+ commander_1.program.version("0.0.16").description("Hapico CLI for project management");
329
337
  commander_1.program
330
338
  .command("clone <id>")
331
339
  .description("Clone a project by ID")
@@ -437,21 +445,24 @@ commander_1.program
437
445
  }
438
446
  console.log(`Connecting to WebSocket server`);
439
447
  const room = new RoomState(`view_${projectId}`, []);
448
+ const fileManager = new FileManager(srcDir);
449
+ const initialFiles = fileManager.listFiles();
450
+ room.files = initialFiles;
440
451
  room.connect(async () => {
441
452
  devSpinner.succeed("Project started in development mode!");
442
- const fileManager = new FileManager(srcDir);
443
- const initialFiles = fileManager.listFiles();
444
453
  room.updateState("view", initialFiles);
445
454
  fileManager.setOnFileChange((filePath, content) => {
446
- const es5 = (0, exports.compileES5)(content, filePath);
455
+ var _a;
456
+ const es5 = (_a = (0, exports.compileES5)(content, filePath)) !== null && _a !== void 0 ? _a : "";
447
457
  console.log(`File changed: ${filePath === null || filePath === void 0 ? void 0 : filePath.replace(srcDir, ".")}`);
448
- const updatedView = initialFiles.map((file) => {
458
+ const updatedFiles = room.files.map((file) => {
449
459
  if (path.join(srcDir, file.path) === filePath) {
450
460
  return { ...file, content, es5 };
451
461
  }
452
462
  return file;
453
463
  });
454
- room.updateState("view", updatedView);
464
+ room.files = updatedFiles;
465
+ room.updateState("view", updatedFiles);
455
466
  });
456
467
  // Fetch project info
457
468
  const projectInfo = getStoredProjectId(pwd);
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class Path {
4
+ static normalizeSlashes(path) {
5
+ return path.replace(/\\/g, "/");
6
+ }
7
+ // Tương tự path.join()
8
+ static join(...paths) {
9
+ const normalizedPaths = paths
10
+ .filter((p) => p && typeof p === "string")
11
+ .map((p) => this.normalizeSlashes(p.trim()))
12
+ .map((p) => p.replace(/^\/+|\/+$/g, "")); // Loại bỏ slash đầu và cuối
13
+ return normalizedPaths.join("/");
14
+ }
15
+ // Tương tự path.resolve()
16
+ static resolve(...paths) {
17
+ let resolvedPath = "";
18
+ const segments = [];
19
+ paths
20
+ .filter((p) => p && typeof p === "string")
21
+ .map((p) => this.normalizeSlashes(p))
22
+ .forEach((path) => {
23
+ if (path.startsWith("/")) {
24
+ segments.length = 0; // Reset nếu gặp absolute path
25
+ segments.push(...path.split("/").filter(Boolean));
26
+ }
27
+ else {
28
+ segments.push(...path.split("/").filter(Boolean));
29
+ }
30
+ });
31
+ const resolvedSegments = [];
32
+ for (const segment of segments) {
33
+ if (segment === "..") {
34
+ resolvedSegments.pop();
35
+ }
36
+ else if (segment !== ".") {
37
+ resolvedSegments.push(segment);
38
+ }
39
+ }
40
+ resolvedPath = resolvedSegments.join("/");
41
+ return resolvedPath.startsWith("/") ? `/${resolvedPath}` : resolvedPath;
42
+ }
43
+ // Tương tự path.basename()
44
+ static basename(path, ext) {
45
+ const normalized = this.normalizeSlashes(path);
46
+ const base = normalized.split("/").pop() || "";
47
+ return ext && base.endsWith(ext) ? base.slice(0, -ext.length) : base;
48
+ }
49
+ // Tương tự path.dirname()
50
+ static dirname(path) {
51
+ const normalized = this.normalizeSlashes(path);
52
+ const segments = normalized.split("/");
53
+ segments.pop();
54
+ return segments.join("/") || ".";
55
+ }
56
+ // Tương tự path.extname()
57
+ static extname(path) {
58
+ const base = this.basename(path);
59
+ const dotIndex = base.lastIndexOf(".");
60
+ return dotIndex > 0 ? base.slice(dotIndex) : "";
61
+ }
62
+ // Tương tự path.isAbsolute()
63
+ static isAbsolute(path) {
64
+ return this.normalizeSlashes(path).startsWith("/");
65
+ }
66
+ // Tương tự path.relative()
67
+ static relative(from, to) {
68
+ const fromParts = this.normalizeSlashes(from).split("/").filter(Boolean);
69
+ const toParts = this.normalizeSlashes(to).split("/").filter(Boolean);
70
+ // Tìm điểm chung
71
+ let i = 0;
72
+ while (i < fromParts.length &&
73
+ i < toParts.length &&
74
+ fromParts[i] === toParts[i]) {
75
+ i++;
76
+ }
77
+ // Tính số bước đi lên
78
+ const upCount = fromParts.length - i;
79
+ const up = Array(upCount).fill("..");
80
+ const remaining = toParts.slice(i);
81
+ return [...up, ...remaining].join("/") || ".";
82
+ }
83
+ }
84
+ exports.default = Path;
package/index.ts CHANGED
@@ -261,7 +261,10 @@ class RoomState {
261
261
  private ws: WebSocket | null;
262
262
  private reconnectTimeout: NodeJS.Timeout | null;
263
263
  private reconnectAttempts: number;
264
- private onChangeListeners: Array<{ key: string; callback: (value: any) => void }>;
264
+ private onChangeListeners: Array<{
265
+ key: string;
266
+ callback: (value: any) => void;
267
+ }>;
265
268
 
266
269
  public files: FileContent[] = [];
267
270
 
@@ -286,7 +289,7 @@ class RoomState {
286
289
  }
287
290
 
288
291
  this.ws = new WebSocket(
289
- `https://base.myworkbeast.com/ws?room=${this.roomId}`
292
+ `https://ws2.myworkbeast.com/ws?room=${this.roomId}`
290
293
  );
291
294
 
292
295
  this.ws.onopen = () => {
@@ -301,20 +304,28 @@ class RoomState {
301
304
  this.isConnected = false;
302
305
 
303
306
  this.reconnectAttempts++;
304
- const delay = Math.min(
305
- 1000 * Math.pow(2, this.reconnectAttempts),
306
- 30000
307
- );
307
+ const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);
308
308
  console.log(`Attempting to reconnect in ${delay / 1000}s...`);
309
309
 
310
- this.reconnectTimeout = setTimeout(() => this.connect(onConnected), delay);
310
+ this.reconnectTimeout = setTimeout(
311
+ () => this.connect(onConnected),
312
+ delay
313
+ );
311
314
  };
312
315
 
313
316
  this.ws.on("message", (data: Buffer | string) => {
314
317
  try {
315
318
  const jsonStr = typeof data === "string" ? data : data.toString();
316
319
  const parsedData = JSON.parse(jsonStr);
317
- const includes = ["view", "coding", "refresh_key", "useActiveIdFocus", "activeId", "active_file", "figma"];
320
+ const includes = [
321
+ "view",
322
+ "coding",
323
+ "refresh_key",
324
+ "useActiveIdFocus",
325
+ "activeId",
326
+ "active_file",
327
+ "figma",
328
+ ];
318
329
 
319
330
  let newState: RoomStateData;
320
331
  let changedKeys;
@@ -336,7 +347,9 @@ class RoomState {
336
347
  return;
337
348
  }
338
349
 
339
- const filteredChangedKeys = changedKeys.filter((key) => includes.includes(key));
350
+ const filteredChangedKeys = changedKeys.filter((key) =>
351
+ includes.includes(key)
352
+ );
340
353
  if (filteredChangedKeys.length > 0) {
341
354
  filteredChangedKeys.forEach((key) => {
342
355
  const listener = find(this.onChangeListeners, (l) => l.key === key);
@@ -387,7 +400,7 @@ class RoomState {
387
400
  }
388
401
  }
389
402
 
390
- program.version("0.0.15").description("Hapico CLI for project management");
403
+ program.version("0.0.16").description("Hapico CLI for project management");
391
404
 
392
405
  program
393
406
  .command("clone <id>")
@@ -536,25 +549,26 @@ program
536
549
 
537
550
  console.log(`Connecting to WebSocket server`);
538
551
  const room = new RoomState(`view_${projectId}`, []);
552
+ const fileManager = new FileManager(srcDir);
553
+ const initialFiles = fileManager.listFiles();
554
+ room.files = initialFiles;
539
555
 
540
556
  room.connect(async () => {
541
557
  devSpinner.succeed("Project started in development mode!");
542
558
 
543
- const fileManager = new FileManager(srcDir);
544
-
545
- const initialFiles = fileManager.listFiles();
546
559
  room.updateState("view", initialFiles);
547
560
 
548
561
  fileManager.setOnFileChange((filePath, content) => {
549
- const es5 = compileES5(content, filePath);
562
+ const es5 = compileES5(content, filePath) ?? "";
550
563
  console.log(`File changed: ${filePath?.replace(srcDir, ".")}`);
551
- const updatedView = initialFiles.map((file) => {
564
+ const updatedFiles = room.files.map((file) => {
552
565
  if (path.join(srcDir, file.path) === filePath) {
553
566
  return { ...file, content, es5 };
554
567
  }
555
568
  return file;
556
569
  });
557
- room.updateState("view", updatedView);
570
+ room.files = updatedFiles;
571
+ room.updateState("view", updatedFiles);
558
572
  });
559
573
 
560
574
  // Fetch project info
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hapico/cli",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "A simple CLI tool for project management",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -26,8 +26,10 @@
26
26
  "lodash": "^4.17.21",
27
27
  "open": "^10.2.0",
28
28
  "ora": "^8.2.0",
29
+ "prettier": "^3.6.2",
29
30
  "qrcode-terminal": "^0.12.0",
30
31
  "unzipper": "^0.12.3",
32
+ "uuid": "^13.0.0",
31
33
  "ws": "^8.18.3"
32
34
  },
33
35
  "devDependencies": {