roport 1.4.0 → 2.0.0
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/dist/index.js +933 -0
- package/package.json +25 -32
- package/README.md +0 -52
- package/assets/RoportSyncPlugin.rbxmx +0 -1864
- package/bin/roport.js +0 -131
- package/src/builder.js +0 -563
- package/src/context.js +0 -76
- package/src/ignore.js +0 -120
- package/src/server.js +0 -393
- package/templates/default/README.md +0 -28
- package/templates/default/default.project.json +0 -23
- package/templates/default/src/client/init.client.lua +0 -1
- package/templates/default/src/server/init.server.lua +0 -1
- package/templates/default/src/shared/Hello.lua +0 -7
package/dist/index.js
ADDED
|
@@ -0,0 +1,933 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
12
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
13
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
14
|
+
};
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
28
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
29
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
30
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
31
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
32
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
33
|
+
mod
|
|
34
|
+
));
|
|
35
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
|
+
|
|
37
|
+
// ../../packages/common/dist/types.js
|
|
38
|
+
var require_types = __commonJS({
|
|
39
|
+
"../../packages/common/dist/types.js"(exports2) {
|
|
40
|
+
"use strict";
|
|
41
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
42
|
+
exports2.OpType = void 0;
|
|
43
|
+
var OpType3;
|
|
44
|
+
(function(OpType4) {
|
|
45
|
+
OpType4["CreateInstance"] = "CreateInstance";
|
|
46
|
+
OpType4["SetProperties"] = "SetProperties";
|
|
47
|
+
OpType4["ReparentInstance"] = "ReparentInstance";
|
|
48
|
+
OpType4["DeleteInstance"] = "DeleteInstance";
|
|
49
|
+
OpType4["ImportChunk"] = "ImportChunk";
|
|
50
|
+
})(OpType3 || (exports2.OpType = OpType3 = {}));
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// ../../node_modules/uuid/dist/esm-node/rng.js
|
|
55
|
+
function rng() {
|
|
56
|
+
if (poolPtr > rnds8Pool.length - 16) {
|
|
57
|
+
import_crypto.default.randomFillSync(rnds8Pool);
|
|
58
|
+
poolPtr = 0;
|
|
59
|
+
}
|
|
60
|
+
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
61
|
+
}
|
|
62
|
+
var import_crypto, rnds8Pool, poolPtr;
|
|
63
|
+
var init_rng = __esm({
|
|
64
|
+
"../../node_modules/uuid/dist/esm-node/rng.js"() {
|
|
65
|
+
"use strict";
|
|
66
|
+
import_crypto = __toESM(require("crypto"));
|
|
67
|
+
rnds8Pool = new Uint8Array(256);
|
|
68
|
+
poolPtr = rnds8Pool.length;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// ../../node_modules/uuid/dist/esm-node/regex.js
|
|
73
|
+
var regex_default;
|
|
74
|
+
var init_regex = __esm({
|
|
75
|
+
"../../node_modules/uuid/dist/esm-node/regex.js"() {
|
|
76
|
+
"use strict";
|
|
77
|
+
regex_default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// ../../node_modules/uuid/dist/esm-node/validate.js
|
|
82
|
+
function validate(uuid) {
|
|
83
|
+
return typeof uuid === "string" && regex_default.test(uuid);
|
|
84
|
+
}
|
|
85
|
+
var validate_default;
|
|
86
|
+
var init_validate = __esm({
|
|
87
|
+
"../../node_modules/uuid/dist/esm-node/validate.js"() {
|
|
88
|
+
"use strict";
|
|
89
|
+
init_regex();
|
|
90
|
+
validate_default = validate;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// ../../node_modules/uuid/dist/esm-node/stringify.js
|
|
95
|
+
function unsafeStringify(arr, offset = 0) {
|
|
96
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
97
|
+
}
|
|
98
|
+
function stringify(arr, offset = 0) {
|
|
99
|
+
const uuid = unsafeStringify(arr, offset);
|
|
100
|
+
if (!validate_default(uuid)) {
|
|
101
|
+
throw TypeError("Stringified UUID is invalid");
|
|
102
|
+
}
|
|
103
|
+
return uuid;
|
|
104
|
+
}
|
|
105
|
+
var byteToHex, stringify_default;
|
|
106
|
+
var init_stringify = __esm({
|
|
107
|
+
"../../node_modules/uuid/dist/esm-node/stringify.js"() {
|
|
108
|
+
"use strict";
|
|
109
|
+
init_validate();
|
|
110
|
+
byteToHex = [];
|
|
111
|
+
for (let i = 0; i < 256; ++i) {
|
|
112
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
113
|
+
}
|
|
114
|
+
stringify_default = stringify;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// ../../node_modules/uuid/dist/esm-node/v1.js
|
|
119
|
+
function v1(options, buf, offset) {
|
|
120
|
+
let i = buf && offset || 0;
|
|
121
|
+
const b = buf || new Array(16);
|
|
122
|
+
options = options || {};
|
|
123
|
+
let node = options.node || _nodeId;
|
|
124
|
+
let clockseq = options.clockseq !== void 0 ? options.clockseq : _clockseq;
|
|
125
|
+
if (node == null || clockseq == null) {
|
|
126
|
+
const seedBytes = options.random || (options.rng || rng)();
|
|
127
|
+
if (node == null) {
|
|
128
|
+
node = _nodeId = [seedBytes[0] | 1, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
|
|
129
|
+
}
|
|
130
|
+
if (clockseq == null) {
|
|
131
|
+
clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 16383;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
let msecs = options.msecs !== void 0 ? options.msecs : Date.now();
|
|
135
|
+
let nsecs = options.nsecs !== void 0 ? options.nsecs : _lastNSecs + 1;
|
|
136
|
+
const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 1e4;
|
|
137
|
+
if (dt < 0 && options.clockseq === void 0) {
|
|
138
|
+
clockseq = clockseq + 1 & 16383;
|
|
139
|
+
}
|
|
140
|
+
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === void 0) {
|
|
141
|
+
nsecs = 0;
|
|
142
|
+
}
|
|
143
|
+
if (nsecs >= 1e4) {
|
|
144
|
+
throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");
|
|
145
|
+
}
|
|
146
|
+
_lastMSecs = msecs;
|
|
147
|
+
_lastNSecs = nsecs;
|
|
148
|
+
_clockseq = clockseq;
|
|
149
|
+
msecs += 122192928e5;
|
|
150
|
+
const tl = ((msecs & 268435455) * 1e4 + nsecs) % 4294967296;
|
|
151
|
+
b[i++] = tl >>> 24 & 255;
|
|
152
|
+
b[i++] = tl >>> 16 & 255;
|
|
153
|
+
b[i++] = tl >>> 8 & 255;
|
|
154
|
+
b[i++] = tl & 255;
|
|
155
|
+
const tmh = msecs / 4294967296 * 1e4 & 268435455;
|
|
156
|
+
b[i++] = tmh >>> 8 & 255;
|
|
157
|
+
b[i++] = tmh & 255;
|
|
158
|
+
b[i++] = tmh >>> 24 & 15 | 16;
|
|
159
|
+
b[i++] = tmh >>> 16 & 255;
|
|
160
|
+
b[i++] = clockseq >>> 8 | 128;
|
|
161
|
+
b[i++] = clockseq & 255;
|
|
162
|
+
for (let n = 0; n < 6; ++n) {
|
|
163
|
+
b[i + n] = node[n];
|
|
164
|
+
}
|
|
165
|
+
return buf || unsafeStringify(b);
|
|
166
|
+
}
|
|
167
|
+
var _nodeId, _clockseq, _lastMSecs, _lastNSecs, v1_default;
|
|
168
|
+
var init_v1 = __esm({
|
|
169
|
+
"../../node_modules/uuid/dist/esm-node/v1.js"() {
|
|
170
|
+
"use strict";
|
|
171
|
+
init_rng();
|
|
172
|
+
init_stringify();
|
|
173
|
+
_lastMSecs = 0;
|
|
174
|
+
_lastNSecs = 0;
|
|
175
|
+
v1_default = v1;
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// ../../node_modules/uuid/dist/esm-node/parse.js
|
|
180
|
+
function parse(uuid) {
|
|
181
|
+
if (!validate_default(uuid)) {
|
|
182
|
+
throw TypeError("Invalid UUID");
|
|
183
|
+
}
|
|
184
|
+
let v;
|
|
185
|
+
const arr = new Uint8Array(16);
|
|
186
|
+
arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24;
|
|
187
|
+
arr[1] = v >>> 16 & 255;
|
|
188
|
+
arr[2] = v >>> 8 & 255;
|
|
189
|
+
arr[3] = v & 255;
|
|
190
|
+
arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8;
|
|
191
|
+
arr[5] = v & 255;
|
|
192
|
+
arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8;
|
|
193
|
+
arr[7] = v & 255;
|
|
194
|
+
arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8;
|
|
195
|
+
arr[9] = v & 255;
|
|
196
|
+
arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 1099511627776 & 255;
|
|
197
|
+
arr[11] = v / 4294967296 & 255;
|
|
198
|
+
arr[12] = v >>> 24 & 255;
|
|
199
|
+
arr[13] = v >>> 16 & 255;
|
|
200
|
+
arr[14] = v >>> 8 & 255;
|
|
201
|
+
arr[15] = v & 255;
|
|
202
|
+
return arr;
|
|
203
|
+
}
|
|
204
|
+
var parse_default;
|
|
205
|
+
var init_parse = __esm({
|
|
206
|
+
"../../node_modules/uuid/dist/esm-node/parse.js"() {
|
|
207
|
+
"use strict";
|
|
208
|
+
init_validate();
|
|
209
|
+
parse_default = parse;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// ../../node_modules/uuid/dist/esm-node/v35.js
|
|
214
|
+
function stringToBytes(str) {
|
|
215
|
+
str = unescape(encodeURIComponent(str));
|
|
216
|
+
const bytes = [];
|
|
217
|
+
for (let i = 0; i < str.length; ++i) {
|
|
218
|
+
bytes.push(str.charCodeAt(i));
|
|
219
|
+
}
|
|
220
|
+
return bytes;
|
|
221
|
+
}
|
|
222
|
+
function v35(name, version2, hashfunc) {
|
|
223
|
+
function generateUUID(value, namespace, buf, offset) {
|
|
224
|
+
var _namespace;
|
|
225
|
+
if (typeof value === "string") {
|
|
226
|
+
value = stringToBytes(value);
|
|
227
|
+
}
|
|
228
|
+
if (typeof namespace === "string") {
|
|
229
|
+
namespace = parse_default(namespace);
|
|
230
|
+
}
|
|
231
|
+
if (((_namespace = namespace) === null || _namespace === void 0 ? void 0 : _namespace.length) !== 16) {
|
|
232
|
+
throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");
|
|
233
|
+
}
|
|
234
|
+
let bytes = new Uint8Array(16 + value.length);
|
|
235
|
+
bytes.set(namespace);
|
|
236
|
+
bytes.set(value, namespace.length);
|
|
237
|
+
bytes = hashfunc(bytes);
|
|
238
|
+
bytes[6] = bytes[6] & 15 | version2;
|
|
239
|
+
bytes[8] = bytes[8] & 63 | 128;
|
|
240
|
+
if (buf) {
|
|
241
|
+
offset = offset || 0;
|
|
242
|
+
for (let i = 0; i < 16; ++i) {
|
|
243
|
+
buf[offset + i] = bytes[i];
|
|
244
|
+
}
|
|
245
|
+
return buf;
|
|
246
|
+
}
|
|
247
|
+
return unsafeStringify(bytes);
|
|
248
|
+
}
|
|
249
|
+
try {
|
|
250
|
+
generateUUID.name = name;
|
|
251
|
+
} catch (err) {
|
|
252
|
+
}
|
|
253
|
+
generateUUID.DNS = DNS;
|
|
254
|
+
generateUUID.URL = URL;
|
|
255
|
+
return generateUUID;
|
|
256
|
+
}
|
|
257
|
+
var DNS, URL;
|
|
258
|
+
var init_v35 = __esm({
|
|
259
|
+
"../../node_modules/uuid/dist/esm-node/v35.js"() {
|
|
260
|
+
"use strict";
|
|
261
|
+
init_stringify();
|
|
262
|
+
init_parse();
|
|
263
|
+
DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
264
|
+
URL = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
// ../../node_modules/uuid/dist/esm-node/md5.js
|
|
269
|
+
function md5(bytes) {
|
|
270
|
+
if (Array.isArray(bytes)) {
|
|
271
|
+
bytes = Buffer.from(bytes);
|
|
272
|
+
} else if (typeof bytes === "string") {
|
|
273
|
+
bytes = Buffer.from(bytes, "utf8");
|
|
274
|
+
}
|
|
275
|
+
return import_crypto2.default.createHash("md5").update(bytes).digest();
|
|
276
|
+
}
|
|
277
|
+
var import_crypto2, md5_default;
|
|
278
|
+
var init_md5 = __esm({
|
|
279
|
+
"../../node_modules/uuid/dist/esm-node/md5.js"() {
|
|
280
|
+
"use strict";
|
|
281
|
+
import_crypto2 = __toESM(require("crypto"));
|
|
282
|
+
md5_default = md5;
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// ../../node_modules/uuid/dist/esm-node/v3.js
|
|
287
|
+
var v3, v3_default;
|
|
288
|
+
var init_v3 = __esm({
|
|
289
|
+
"../../node_modules/uuid/dist/esm-node/v3.js"() {
|
|
290
|
+
"use strict";
|
|
291
|
+
init_v35();
|
|
292
|
+
init_md5();
|
|
293
|
+
v3 = v35("v3", 48, md5_default);
|
|
294
|
+
v3_default = v3;
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// ../../node_modules/uuid/dist/esm-node/native.js
|
|
299
|
+
var import_crypto3, native_default;
|
|
300
|
+
var init_native = __esm({
|
|
301
|
+
"../../node_modules/uuid/dist/esm-node/native.js"() {
|
|
302
|
+
"use strict";
|
|
303
|
+
import_crypto3 = __toESM(require("crypto"));
|
|
304
|
+
native_default = {
|
|
305
|
+
randomUUID: import_crypto3.default.randomUUID
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// ../../node_modules/uuid/dist/esm-node/v4.js
|
|
311
|
+
function v4(options, buf, offset) {
|
|
312
|
+
if (native_default.randomUUID && !buf && !options) {
|
|
313
|
+
return native_default.randomUUID();
|
|
314
|
+
}
|
|
315
|
+
options = options || {};
|
|
316
|
+
const rnds = options.random || (options.rng || rng)();
|
|
317
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
318
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
319
|
+
if (buf) {
|
|
320
|
+
offset = offset || 0;
|
|
321
|
+
for (let i = 0; i < 16; ++i) {
|
|
322
|
+
buf[offset + i] = rnds[i];
|
|
323
|
+
}
|
|
324
|
+
return buf;
|
|
325
|
+
}
|
|
326
|
+
return unsafeStringify(rnds);
|
|
327
|
+
}
|
|
328
|
+
var v4_default;
|
|
329
|
+
var init_v4 = __esm({
|
|
330
|
+
"../../node_modules/uuid/dist/esm-node/v4.js"() {
|
|
331
|
+
"use strict";
|
|
332
|
+
init_native();
|
|
333
|
+
init_rng();
|
|
334
|
+
init_stringify();
|
|
335
|
+
v4_default = v4;
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// ../../node_modules/uuid/dist/esm-node/sha1.js
|
|
340
|
+
function sha1(bytes) {
|
|
341
|
+
if (Array.isArray(bytes)) {
|
|
342
|
+
bytes = Buffer.from(bytes);
|
|
343
|
+
} else if (typeof bytes === "string") {
|
|
344
|
+
bytes = Buffer.from(bytes, "utf8");
|
|
345
|
+
}
|
|
346
|
+
return import_crypto4.default.createHash("sha1").update(bytes).digest();
|
|
347
|
+
}
|
|
348
|
+
var import_crypto4, sha1_default;
|
|
349
|
+
var init_sha1 = __esm({
|
|
350
|
+
"../../node_modules/uuid/dist/esm-node/sha1.js"() {
|
|
351
|
+
"use strict";
|
|
352
|
+
import_crypto4 = __toESM(require("crypto"));
|
|
353
|
+
sha1_default = sha1;
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
// ../../node_modules/uuid/dist/esm-node/v5.js
|
|
358
|
+
var v5, v5_default;
|
|
359
|
+
var init_v5 = __esm({
|
|
360
|
+
"../../node_modules/uuid/dist/esm-node/v5.js"() {
|
|
361
|
+
"use strict";
|
|
362
|
+
init_v35();
|
|
363
|
+
init_sha1();
|
|
364
|
+
v5 = v35("v5", 80, sha1_default);
|
|
365
|
+
v5_default = v5;
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// ../../node_modules/uuid/dist/esm-node/nil.js
|
|
370
|
+
var nil_default;
|
|
371
|
+
var init_nil = __esm({
|
|
372
|
+
"../../node_modules/uuid/dist/esm-node/nil.js"() {
|
|
373
|
+
"use strict";
|
|
374
|
+
nil_default = "00000000-0000-0000-0000-000000000000";
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// ../../node_modules/uuid/dist/esm-node/version.js
|
|
379
|
+
function version(uuid) {
|
|
380
|
+
if (!validate_default(uuid)) {
|
|
381
|
+
throw TypeError("Invalid UUID");
|
|
382
|
+
}
|
|
383
|
+
return parseInt(uuid.slice(14, 15), 16);
|
|
384
|
+
}
|
|
385
|
+
var version_default;
|
|
386
|
+
var init_version = __esm({
|
|
387
|
+
"../../node_modules/uuid/dist/esm-node/version.js"() {
|
|
388
|
+
"use strict";
|
|
389
|
+
init_validate();
|
|
390
|
+
version_default = version;
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// ../../node_modules/uuid/dist/esm-node/index.js
|
|
395
|
+
var esm_node_exports = {};
|
|
396
|
+
__export(esm_node_exports, {
|
|
397
|
+
NIL: () => nil_default,
|
|
398
|
+
parse: () => parse_default,
|
|
399
|
+
stringify: () => stringify_default,
|
|
400
|
+
v1: () => v1_default,
|
|
401
|
+
v3: () => v3_default,
|
|
402
|
+
v4: () => v4_default,
|
|
403
|
+
v5: () => v5_default,
|
|
404
|
+
validate: () => validate_default,
|
|
405
|
+
version: () => version_default
|
|
406
|
+
});
|
|
407
|
+
var init_esm_node = __esm({
|
|
408
|
+
"../../node_modules/uuid/dist/esm-node/index.js"() {
|
|
409
|
+
"use strict";
|
|
410
|
+
init_v1();
|
|
411
|
+
init_v3();
|
|
412
|
+
init_v4();
|
|
413
|
+
init_v5();
|
|
414
|
+
init_nil();
|
|
415
|
+
init_version();
|
|
416
|
+
init_validate();
|
|
417
|
+
init_stringify();
|
|
418
|
+
init_parse();
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// ../../packages/common/dist/utils/GuidGenerator.js
|
|
423
|
+
var require_GuidGenerator = __commonJS({
|
|
424
|
+
"../../packages/common/dist/utils/GuidGenerator.js"(exports2) {
|
|
425
|
+
"use strict";
|
|
426
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
427
|
+
exports2.GuidGenerator = void 0;
|
|
428
|
+
var uuid_1 = (init_esm_node(), __toCommonJS(esm_node_exports));
|
|
429
|
+
var GuidGenerator = class {
|
|
430
|
+
static generate() {
|
|
431
|
+
return (0, uuid_1.v4)();
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
exports2.GuidGenerator = GuidGenerator;
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
// ../../packages/common/dist/utils/PathUtils.js
|
|
439
|
+
var require_PathUtils = __commonJS({
|
|
440
|
+
"../../packages/common/dist/utils/PathUtils.js"(exports2) {
|
|
441
|
+
"use strict";
|
|
442
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
443
|
+
exports2.PathUtils = void 0;
|
|
444
|
+
var PathUtils = class {
|
|
445
|
+
static SEPARATOR = "/";
|
|
446
|
+
static normalize(path5) {
|
|
447
|
+
return path5.replace(/\\/g, this.SEPARATOR);
|
|
448
|
+
}
|
|
449
|
+
static join(...parts) {
|
|
450
|
+
return parts.map((p) => this.normalize(p)).join(this.SEPARATOR).replace(/\/+/g, this.SEPARATOR);
|
|
451
|
+
}
|
|
452
|
+
static getParent(path5) {
|
|
453
|
+
const normalized = this.normalize(path5);
|
|
454
|
+
const lastIndex = normalized.lastIndexOf(this.SEPARATOR);
|
|
455
|
+
if (lastIndex === -1)
|
|
456
|
+
return "";
|
|
457
|
+
return normalized.substring(0, lastIndex);
|
|
458
|
+
}
|
|
459
|
+
static getName(path5) {
|
|
460
|
+
const normalized = this.normalize(path5);
|
|
461
|
+
const lastIndex = normalized.lastIndexOf(this.SEPARATOR);
|
|
462
|
+
return normalized.substring(lastIndex + 1);
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
exports2.PathUtils = PathUtils;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
// ../../packages/common/dist/index.js
|
|
470
|
+
var require_dist = __commonJS({
|
|
471
|
+
"../../packages/common/dist/index.js"(exports2) {
|
|
472
|
+
"use strict";
|
|
473
|
+
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
474
|
+
if (k2 === void 0) k2 = k;
|
|
475
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
476
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
477
|
+
desc = { enumerable: true, get: function() {
|
|
478
|
+
return m[k];
|
|
479
|
+
} };
|
|
480
|
+
}
|
|
481
|
+
Object.defineProperty(o, k2, desc);
|
|
482
|
+
}) : (function(o, m, k, k2) {
|
|
483
|
+
if (k2 === void 0) k2 = k;
|
|
484
|
+
o[k2] = m[k];
|
|
485
|
+
}));
|
|
486
|
+
var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
|
|
487
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
488
|
+
};
|
|
489
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
490
|
+
__exportStar(require_types(), exports2);
|
|
491
|
+
__exportStar(require_GuidGenerator(), exports2);
|
|
492
|
+
__exportStar(require_PathUtils(), exports2);
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
// src/cli/index.ts
|
|
497
|
+
var import_commander3 = require("commander");
|
|
498
|
+
|
|
499
|
+
// src/cli/build.ts
|
|
500
|
+
var import_commander = require("commander");
|
|
501
|
+
var import_path = __toESM(require("path"));
|
|
502
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
503
|
+
var buildCommand = new import_commander.Command("build").description("Build the project into a Roblox Model/Place file").argument("[project]", "Path to project.json file", "default.project.json").option("-o, --output <path>", "Output file path", "game.rbxl").action(async (projectFile, options) => {
|
|
504
|
+
const cwd = process.cwd();
|
|
505
|
+
const projectPath = import_path.default.resolve(cwd, projectFile);
|
|
506
|
+
const outputPath = import_path.default.resolve(cwd, options.output);
|
|
507
|
+
console.log(`[Roport] Building ${projectPath} to ${outputPath}...`);
|
|
508
|
+
try {
|
|
509
|
+
await import_promises.default.access(projectPath);
|
|
510
|
+
} catch {
|
|
511
|
+
console.error(`[Roport] Error: Project file not found at ${projectPath}`);
|
|
512
|
+
process.exit(1);
|
|
513
|
+
}
|
|
514
|
+
console.log(`[Roport] Parsing project structure...`);
|
|
515
|
+
console.log(`[Roport] Compiling scripts...`);
|
|
516
|
+
console.log(`[Roport] Serializing to XML...`);
|
|
517
|
+
console.log(`[Roport] Build complete: ${outputPath}`);
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
// src/cli/serve.ts
|
|
521
|
+
var import_commander2 = require("commander");
|
|
522
|
+
var import_path4 = __toESM(require("path"));
|
|
523
|
+
|
|
524
|
+
// src/server/Server.ts
|
|
525
|
+
var import_fs = __toESM(require("fs"));
|
|
526
|
+
|
|
527
|
+
// src/net/ConnectionManager.ts
|
|
528
|
+
var import_ws = require("ws");
|
|
529
|
+
var import_events = require("events");
|
|
530
|
+
var ConnectionManager = class extends import_events.EventEmitter {
|
|
531
|
+
wss;
|
|
532
|
+
clients = /* @__PURE__ */ new Set();
|
|
533
|
+
port = 34872;
|
|
534
|
+
constructor() {
|
|
535
|
+
super();
|
|
536
|
+
this.startServer();
|
|
537
|
+
}
|
|
538
|
+
startServer() {
|
|
539
|
+
this.wss = new import_ws.WebSocketServer({ port: this.port });
|
|
540
|
+
this.wss.on("listening", () => {
|
|
541
|
+
console.log(`[Roport] WebSocket Server listening on port ${this.port}`);
|
|
542
|
+
});
|
|
543
|
+
this.wss.on("connection", (ws) => {
|
|
544
|
+
console.log("[Roport] Client connected");
|
|
545
|
+
this.clients.add(ws);
|
|
546
|
+
this.setupHeartbeat(ws);
|
|
547
|
+
ws.on("message", (message) => {
|
|
548
|
+
this.handleMessage(ws, message);
|
|
549
|
+
});
|
|
550
|
+
ws.on("close", () => {
|
|
551
|
+
console.log("[Roport] Client disconnected");
|
|
552
|
+
this.clients.delete(ws);
|
|
553
|
+
});
|
|
554
|
+
ws.on("error", (err) => {
|
|
555
|
+
console.error("[Roport] WebSocket error:", err);
|
|
556
|
+
});
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
setupHeartbeat(ws) {
|
|
560
|
+
const pingInterval = setInterval(() => {
|
|
561
|
+
if (ws.readyState === import_ws.WebSocket.OPEN) {
|
|
562
|
+
ws.ping();
|
|
563
|
+
} else {
|
|
564
|
+
clearInterval(pingInterval);
|
|
565
|
+
}
|
|
566
|
+
}, 3e4);
|
|
567
|
+
ws.on("close", () => clearInterval(pingInterval));
|
|
568
|
+
}
|
|
569
|
+
handleMessage(sender, rawMessage) {
|
|
570
|
+
try {
|
|
571
|
+
const event = JSON.parse(rawMessage.toString());
|
|
572
|
+
this.emit("event", event);
|
|
573
|
+
} catch (e) {
|
|
574
|
+
console.error("[Roport] Failed to parse message", e);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
broadcast(event) {
|
|
578
|
+
const payload = JSON.stringify(event);
|
|
579
|
+
this.clients.forEach((client) => {
|
|
580
|
+
if (client.readyState === import_ws.WebSocket.OPEN) {
|
|
581
|
+
client.send(payload);
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
// src/net/ApiServer.ts
|
|
588
|
+
var import_express = __toESM(require("express"));
|
|
589
|
+
var import_cors = __toESM(require("cors"));
|
|
590
|
+
var ApiServer = class {
|
|
591
|
+
app;
|
|
592
|
+
port = 3e3;
|
|
593
|
+
// API port different from WS
|
|
594
|
+
constructor() {
|
|
595
|
+
this.app = (0, import_express.default)();
|
|
596
|
+
this.config();
|
|
597
|
+
this.routes();
|
|
598
|
+
this.start();
|
|
599
|
+
}
|
|
600
|
+
config() {
|
|
601
|
+
this.app.use((0, import_cors.default)());
|
|
602
|
+
this.app.use(import_express.default.json());
|
|
603
|
+
}
|
|
604
|
+
routes() {
|
|
605
|
+
this.app.get("/status", (req, res) => {
|
|
606
|
+
res.json({ status: "running", version: "0.1.0" });
|
|
607
|
+
});
|
|
608
|
+
this.app.get("/tree", async (req, res) => {
|
|
609
|
+
res.json([
|
|
610
|
+
{ name: "Workspace", className: "Workspace", id: "workspace-guid", children: [
|
|
611
|
+
{ name: "Baseplate", className: "Part", id: "bp-guid" }
|
|
612
|
+
] },
|
|
613
|
+
{ name: "ReplicatedStorage", className: "ReplicatedStorage", id: "rs-guid", children: [] }
|
|
614
|
+
]);
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
start() {
|
|
618
|
+
this.app.listen(this.port, () => {
|
|
619
|
+
console.log(`[Roport] API Server running on http://localhost:${this.port}`);
|
|
620
|
+
});
|
|
621
|
+
}
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
// src/fs/FileWatcher.ts
|
|
625
|
+
var import_chokidar = __toESM(require("chokidar"));
|
|
626
|
+
var import_events2 = require("events");
|
|
627
|
+
var FileWatcher = class extends import_events2.EventEmitter {
|
|
628
|
+
constructor(rootPath) {
|
|
629
|
+
super();
|
|
630
|
+
this.rootPath = rootPath;
|
|
631
|
+
this.initialize();
|
|
632
|
+
}
|
|
633
|
+
watcher = null;
|
|
634
|
+
initialize() {
|
|
635
|
+
this.watcher = import_chokidar.default.watch(this.rootPath, {
|
|
636
|
+
ignored: [
|
|
637
|
+
/(^|[\/\\])\../,
|
|
638
|
+
// ignore dotfiles
|
|
639
|
+
"**/node_modules/**",
|
|
640
|
+
"**/.git/**",
|
|
641
|
+
"**/.roport_trash/**"
|
|
642
|
+
],
|
|
643
|
+
persistent: true,
|
|
644
|
+
ignoreInitial: true
|
|
645
|
+
});
|
|
646
|
+
this.watcher.on("add", (path5) => this.emit("add", path5)).on("change", (path5) => this.emit("change", path5)).on("unlink", (path5) => this.emit("unlink", path5)).on("addDir", (path5) => this.emit("addDir", path5)).on("unlinkDir", (path5) => this.emit("unlinkDir", path5)).on("error", (error) => console.error(`[Roport] Watcher error: ${error}`));
|
|
647
|
+
console.log(`[Roport] FileWatcher started on ${this.rootPath}`);
|
|
648
|
+
}
|
|
649
|
+
close() {
|
|
650
|
+
this.watcher?.close();
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
// src/fs/PathMapper.ts
|
|
655
|
+
var PathMapper = class {
|
|
656
|
+
pathToGuid = /* @__PURE__ */ new Map();
|
|
657
|
+
guidToPath = /* @__PURE__ */ new Map();
|
|
658
|
+
set(path5, guid) {
|
|
659
|
+
this.pathToGuid.set(path5, guid);
|
|
660
|
+
this.guidToPath.set(guid, path5);
|
|
661
|
+
}
|
|
662
|
+
removeByPath(path5) {
|
|
663
|
+
const guid = this.pathToGuid.get(path5);
|
|
664
|
+
if (guid) {
|
|
665
|
+
this.pathToGuid.delete(path5);
|
|
666
|
+
this.guidToPath.delete(guid);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
removeByGuid(guid) {
|
|
670
|
+
const path5 = this.guidToPath.get(guid);
|
|
671
|
+
if (path5) {
|
|
672
|
+
this.guidToPath.delete(guid);
|
|
673
|
+
this.pathToGuid.delete(path5);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
resolveGuid(path5) {
|
|
677
|
+
return this.pathToGuid.get(path5);
|
|
678
|
+
}
|
|
679
|
+
resolvePath(guid) {
|
|
680
|
+
return this.guidToPath.get(guid);
|
|
681
|
+
}
|
|
682
|
+
// TODO: Implement Index Rebuild (scan disk on startup)
|
|
683
|
+
async rebuildIndex(rootPath) {
|
|
684
|
+
await this.scanDir(rootPath);
|
|
685
|
+
}
|
|
686
|
+
async scanDir(dir) {
|
|
687
|
+
const fs4 = require("fs/promises");
|
|
688
|
+
const path5 = require("path");
|
|
689
|
+
try {
|
|
690
|
+
const entries = await fs4.readdir(dir, { withFileTypes: true });
|
|
691
|
+
for (const entry of entries) {
|
|
692
|
+
const fullPath = path5.join(dir, entry.name);
|
|
693
|
+
if (entry.isDirectory()) {
|
|
694
|
+
try {
|
|
695
|
+
const metaPath = path5.join(fullPath, "__meta.json");
|
|
696
|
+
const metaContent = await fs4.readFile(metaPath, "utf-8");
|
|
697
|
+
const meta = JSON.parse(metaContent);
|
|
698
|
+
if (meta.id) {
|
|
699
|
+
this.set(fullPath, meta.id);
|
|
700
|
+
}
|
|
701
|
+
} catch (e) {
|
|
702
|
+
}
|
|
703
|
+
await this.scanDir(fullPath);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
} catch (e) {
|
|
707
|
+
console.error(`[Roport] Scan error at ${dir}:`, e);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
// src/sync/OpReconciler.ts
|
|
713
|
+
var import_common = __toESM(require_dist());
|
|
714
|
+
var import_path2 = __toESM(require("path"));
|
|
715
|
+
var OpReconciler = class {
|
|
716
|
+
constructor(pathMapper) {
|
|
717
|
+
this.pathMapper = pathMapper;
|
|
718
|
+
}
|
|
719
|
+
reconcileMeta(filePath, meta) {
|
|
720
|
+
const ops = [];
|
|
721
|
+
if (!meta.id) {
|
|
722
|
+
console.warn(`[Roport] Meta file at ${filePath} missing ID`);
|
|
723
|
+
return ops;
|
|
724
|
+
}
|
|
725
|
+
const existingPath = this.pathMapper.resolvePath(meta.id);
|
|
726
|
+
const isNew = !existingPath;
|
|
727
|
+
if (isNew) {
|
|
728
|
+
const parentDir = import_path2.default.dirname(import_path2.default.dirname(filePath));
|
|
729
|
+
const parentGuid = this.pathMapper.resolveGuid(parentDir) || "NULL";
|
|
730
|
+
ops.push({
|
|
731
|
+
id: `op-${Date.now()}`,
|
|
732
|
+
type: import_common.OpType.CreateInstance,
|
|
733
|
+
payload: {
|
|
734
|
+
guid: meta.id,
|
|
735
|
+
className: meta.class,
|
|
736
|
+
name: meta.name,
|
|
737
|
+
parentGuid,
|
|
738
|
+
properties: meta.properties || {}
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
this.pathMapper.set(import_path2.default.dirname(filePath), meta.id);
|
|
742
|
+
} else {
|
|
743
|
+
ops.push({
|
|
744
|
+
id: `op-${Date.now()}`,
|
|
745
|
+
type: import_common.OpType.SetProperties,
|
|
746
|
+
payload: {
|
|
747
|
+
guid: meta.id,
|
|
748
|
+
properties: meta.properties || {}
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
return ops;
|
|
753
|
+
}
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
// src/sync/Writer.ts
|
|
757
|
+
var import_promises2 = __toESM(require("fs/promises"));
|
|
758
|
+
var import_path3 = __toESM(require("path"));
|
|
759
|
+
var import_common2 = __toESM(require_dist());
|
|
760
|
+
var Writer = class {
|
|
761
|
+
constructor(rootPath, pathMapper) {
|
|
762
|
+
this.rootPath = rootPath;
|
|
763
|
+
this.pathMapper = pathMapper;
|
|
764
|
+
}
|
|
765
|
+
async applyOp(op) {
|
|
766
|
+
switch (op.type) {
|
|
767
|
+
case import_common2.OpType.SetProperties:
|
|
768
|
+
await this.handleSetProperties(op.payload);
|
|
769
|
+
break;
|
|
770
|
+
case import_common2.OpType.CreateInstance:
|
|
771
|
+
await this.handleCreate(op.payload);
|
|
772
|
+
break;
|
|
773
|
+
case import_common2.OpType.DeleteInstance:
|
|
774
|
+
await this.handleDelete(op.payload);
|
|
775
|
+
break;
|
|
776
|
+
case import_common2.OpType.ReparentInstance:
|
|
777
|
+
await this.handleReparent(op.payload);
|
|
778
|
+
break;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
async handleSetProperties(payload) {
|
|
782
|
+
const { guid, properties } = payload;
|
|
783
|
+
const filePath = this.pathMapper.resolvePath(guid);
|
|
784
|
+
if (!filePath) {
|
|
785
|
+
console.warn(`[Writer] Unknown GUID ${guid} for SetProperties`);
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
const metaPath = import_path3.default.join(filePath, "__meta.json");
|
|
789
|
+
try {
|
|
790
|
+
let meta = {};
|
|
791
|
+
try {
|
|
792
|
+
const content = await import_promises2.default.readFile(metaPath, "utf-8");
|
|
793
|
+
meta = JSON.parse(content);
|
|
794
|
+
} catch (e) {
|
|
795
|
+
}
|
|
796
|
+
meta.properties = { ...meta.properties, ...properties };
|
|
797
|
+
await this.writeMeta(metaPath, meta);
|
|
798
|
+
console.log(`[Writer] Updated ${metaPath}`);
|
|
799
|
+
} catch (e) {
|
|
800
|
+
console.error(`[Writer] Failed to write properties for ${guid}`, e);
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
async handleCreate(payload) {
|
|
804
|
+
const { guid, className, name, parentGuid, properties } = payload;
|
|
805
|
+
let parentPath = this.rootPath;
|
|
806
|
+
if (parentGuid && parentGuid !== "game" && parentGuid !== "NULL") {
|
|
807
|
+
const resolved = this.pathMapper.resolvePath(parentGuid);
|
|
808
|
+
if (resolved) parentPath = resolved;
|
|
809
|
+
}
|
|
810
|
+
const dirPath = import_path3.default.join(parentPath, name);
|
|
811
|
+
try {
|
|
812
|
+
await import_promises2.default.mkdir(dirPath, { recursive: true });
|
|
813
|
+
const meta = {
|
|
814
|
+
id: guid,
|
|
815
|
+
class: className,
|
|
816
|
+
name,
|
|
817
|
+
properties: properties || {}
|
|
818
|
+
};
|
|
819
|
+
await this.writeMeta(import_path3.default.join(dirPath, "__meta.json"), meta);
|
|
820
|
+
this.pathMapper.set(dirPath, guid);
|
|
821
|
+
console.log(`[Writer] Created ${dirPath}`);
|
|
822
|
+
} catch (e) {
|
|
823
|
+
console.error(`[Writer] Failed to create ${dirPath}`, e);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
async handleDelete(payload) {
|
|
827
|
+
const { guid } = payload;
|
|
828
|
+
const filePath = this.pathMapper.resolvePath(guid);
|
|
829
|
+
if (!filePath) return;
|
|
830
|
+
if (import_path3.default.relative(this.rootPath, filePath) === "") return;
|
|
831
|
+
try {
|
|
832
|
+
await import_promises2.default.rm(filePath, { recursive: true, force: true });
|
|
833
|
+
this.pathMapper.removeByGuid(guid);
|
|
834
|
+
console.log(`[Writer] Deleted ${filePath}`);
|
|
835
|
+
} catch (e) {
|
|
836
|
+
console.error(`[Writer] Failed to delete ${filePath}`, e);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
async handleReparent(payload) {
|
|
840
|
+
const { guid, newParentGuid } = payload;
|
|
841
|
+
const oldPath = this.pathMapper.resolvePath(guid);
|
|
842
|
+
let newParentPath = this.rootPath;
|
|
843
|
+
if (newParentGuid && newParentGuid !== "game") {
|
|
844
|
+
const resolved = this.pathMapper.resolvePath(newParentGuid);
|
|
845
|
+
if (resolved) newParentPath = resolved;
|
|
846
|
+
}
|
|
847
|
+
if (!oldPath) return;
|
|
848
|
+
const dirName = import_path3.default.basename(oldPath);
|
|
849
|
+
const newPath = import_path3.default.join(newParentPath, dirName);
|
|
850
|
+
try {
|
|
851
|
+
await import_promises2.default.rename(oldPath, newPath);
|
|
852
|
+
this.pathMapper.removeByGuid(guid);
|
|
853
|
+
this.pathMapper.set(newPath, guid);
|
|
854
|
+
console.log(`[Writer] Moved ${oldPath} -> ${newPath}`);
|
|
855
|
+
} catch (e) {
|
|
856
|
+
console.error(`[Writer] Failed to move`, e);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
async writeMeta(path5, data) {
|
|
860
|
+
await import_promises2.default.writeFile(path5, JSON.stringify(data, null, 2));
|
|
861
|
+
}
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
// src/server/Server.ts
|
|
865
|
+
var RoportServer = class {
|
|
866
|
+
constructor(workspacePath) {
|
|
867
|
+
this.workspacePath = workspacePath;
|
|
868
|
+
this.connectionManager = new ConnectionManager();
|
|
869
|
+
this.apiServer = new ApiServer();
|
|
870
|
+
this.pathMapper = new PathMapper();
|
|
871
|
+
this.fileWatcher = new FileWatcher(workspacePath);
|
|
872
|
+
this.opReconciler = new OpReconciler(this.pathMapper);
|
|
873
|
+
this.writer = new Writer(workspacePath, this.pathMapper);
|
|
874
|
+
}
|
|
875
|
+
connectionManager;
|
|
876
|
+
apiServer;
|
|
877
|
+
fileWatcher;
|
|
878
|
+
pathMapper;
|
|
879
|
+
opReconciler;
|
|
880
|
+
writer;
|
|
881
|
+
async start() {
|
|
882
|
+
console.log(`[Roport] Starting server in ${this.workspacePath}`);
|
|
883
|
+
console.log("[Roport] Rebuilding index...");
|
|
884
|
+
await this.pathMapper.rebuildIndex(this.workspacePath);
|
|
885
|
+
this.fileWatcher.on("change", async (filePath) => {
|
|
886
|
+
if (filePath.endsWith("__meta.json")) {
|
|
887
|
+
try {
|
|
888
|
+
const content = import_fs.default.readFileSync(filePath, "utf-8");
|
|
889
|
+
const meta = JSON.parse(content);
|
|
890
|
+
const ops = this.opReconciler.reconcileMeta(filePath, meta);
|
|
891
|
+
ops.forEach((op) => {
|
|
892
|
+
this.connectionManager.broadcast({
|
|
893
|
+
channel: "dm",
|
|
894
|
+
topic: "events",
|
|
895
|
+
data: op
|
|
896
|
+
});
|
|
897
|
+
});
|
|
898
|
+
} catch (e) {
|
|
899
|
+
console.error(`[Roport] Failed to process meta change ${filePath}`, e);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
this.connectionManager.on("event", async (event) => {
|
|
904
|
+
if (event.channel === "dm" && event.topic === "events") {
|
|
905
|
+
const op = event.data;
|
|
906
|
+
console.log(`[Roport] Received Studio Op: ${op.type}`);
|
|
907
|
+
await this.writer.applyOp({
|
|
908
|
+
id: `op-studio-${Date.now()}`,
|
|
909
|
+
type: op.type,
|
|
910
|
+
payload: op
|
|
911
|
+
});
|
|
912
|
+
} else if (event.channel === "logs") {
|
|
913
|
+
console.log(`[Studio Log] ${event.data.message}`);
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
console.log("[Roport] Server ready.");
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
// src/cli/serve.ts
|
|
921
|
+
var serveCommand = new import_commander2.Command("serve").description("Start the Roport sync server").argument("[dir]", "Project directory", ".").action(async (dir) => {
|
|
922
|
+
const workspacePath = import_path4.default.resolve(process.cwd(), dir);
|
|
923
|
+
const server = new RoportServer(workspacePath);
|
|
924
|
+
await server.start();
|
|
925
|
+
process.stdin.resume();
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
// src/cli/index.ts
|
|
929
|
+
var program = new import_commander3.Command();
|
|
930
|
+
program.name("roport").description("Roport V2 CLI - AI-First Roblox Development").version("0.1.0");
|
|
931
|
+
program.addCommand(buildCommand);
|
|
932
|
+
program.addCommand(serveCommand);
|
|
933
|
+
program.parse(process.argv);
|