@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 +19 -8
- package/bin/utils/codemod/utils/path.mockup.js +84 -0
- package/bun.lock +6 -0
- package/dist/index.js +19 -8
- package/dist/utils/codemod/utils/path.mockup.js +84 -0
- package/index.ts +30 -16
- package/package.json +3 -1
- package/utils/codemod/index.tsx +1588 -0
- package/utils/codemod/utils/path.mockup.ts +97 -0
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://
|
|
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 = [
|
|
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.
|
|
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
|
-
|
|
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
|
|
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.
|
|
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://
|
|
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 = [
|
|
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.
|
|
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
|
-
|
|
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
|
|
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.
|
|
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<{
|
|
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://
|
|
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(
|
|
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 = [
|
|
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) =>
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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": {
|