@ezetgalaxy/titan 26.7.4 → 26.7.5
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/README.md +2 -1
- package/index.js +488 -489
- package/package.json +3 -3
- package/templates/_gitignore +25 -0
- package/templates/package.json +1 -1
- package/templates/server/action_map.json +3 -0
- package/templates/server/actions/hello.jsbundle +45 -0
- package/templates/server/routes.json +16 -0
- package/titanpl-sdk/package.json +1 -1
- package/scripts/make_dist.sh +0 -71
package/README.md
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
19
|
# TITAN PLANET 🚀
|
|
20
|
-
[](https://github.com/ezet-galaxy/titanpl)
|
|
20
|
+
|
|
21
|
+
[](https://www.npmjs.com/package/@ezetgalaxy/titan)
|
|
21
22
|
|
|
22
23
|
|
|
23
24
|
**JavaScript Simplicity. Rust Power. Zero Configuration.**
|
package/index.js
CHANGED
|
@@ -1,490 +1,489 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { execSync, spawn } from "child_process";
|
|
5
|
-
import { fileURLToPath } from "url";
|
|
6
|
-
|
|
7
|
-
/* Resolve __dirname for ES modules */
|
|
8
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
-
const __dirname = path.dirname(__filename);
|
|
10
|
-
|
|
11
|
-
/* -------------------------------------------------------
|
|
12
|
-
* Colors
|
|
13
|
-
* ----------------------------------------------------- */
|
|
14
|
-
const cyan = (t) => `\x1b[36m${t}\x1b[0m`;
|
|
15
|
-
const green = (t) => `\x1b[32m${t}\x1b[0m`;
|
|
16
|
-
const yellow = (t) => `\x1b[33m${t}\x1b[0m`;
|
|
17
|
-
const red = (t) => `\x1b[31m${t}\x1b[0m`;
|
|
18
|
-
const bold = (t) => `\x1b[1m${t}\x1b[0m`;
|
|
19
|
-
|
|
20
|
-
/* -------------------------------------------------------
|
|
21
|
-
* Invocation detection (tit vs titan)
|
|
22
|
-
* ----------------------------------------------------- */
|
|
23
|
-
function wasInvokedAsTit() {
|
|
24
|
-
const script = process.argv[1];
|
|
25
|
-
if (script) {
|
|
26
|
-
const base = path.basename(script, path.extname(script)).toLowerCase();
|
|
27
|
-
if (base === "tit") return true;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const raw = process.env.npm_config_argv;
|
|
32
|
-
if (raw) {
|
|
33
|
-
const cfg = JSON.parse(raw);
|
|
34
|
-
if (cfg.original && Array.isArray(cfg.original)) {
|
|
35
|
-
// e.g. ["tit", "dev"]
|
|
36
|
-
const first = cfg.original[0];
|
|
37
|
-
if (first && first.includes("tit") && !first.includes("titan")) {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
} catch { }
|
|
43
|
-
|
|
44
|
-
const lastCmd = process.env["_"];
|
|
45
|
-
if (lastCmd) {
|
|
46
|
-
const base = path.basename(lastCmd, path.extname(lastCmd)).toLowerCase();
|
|
47
|
-
if (base === "tit") return true;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const isTitAlias = wasInvokedAsTit();
|
|
54
|
-
|
|
55
|
-
if (isTitAlias) {
|
|
56
|
-
console.log(
|
|
57
|
-
yellow(
|
|
58
|
-
"[Notice] `tit` is deprecated. Please use `titan` instead.\n" +
|
|
59
|
-
" `tit` will continue to work for now."
|
|
60
|
-
)
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/* -------------------------------------------------------
|
|
65
|
-
* Args
|
|
66
|
-
* ----------------------------------------------------- */
|
|
67
|
-
const args = process.argv.slice(2);
|
|
68
|
-
const cmd = args[0];
|
|
69
|
-
|
|
70
|
-
/* -------------------------------------------------------
|
|
71
|
-
* Titan version
|
|
72
|
-
* ----------------------------------------------------- */
|
|
73
|
-
const pkg = JSON.parse(
|
|
74
|
-
fs.readFileSync(path.join(__dirname, "package.json"), "utf8")
|
|
75
|
-
);
|
|
76
|
-
const TITAN_VERSION = pkg.version;
|
|
77
|
-
|
|
78
|
-
/* -------------------------------------------------------
|
|
79
|
-
* Utils
|
|
80
|
-
* ----------------------------------------------------- */
|
|
81
|
-
function copyDir(src, dest, excludes = []) {
|
|
82
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
83
|
-
|
|
84
|
-
for (const file of fs.readdirSync(src)) {
|
|
85
|
-
// Skip excluded files/folders
|
|
86
|
-
if (excludes.includes(file)) {
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const srcPath = path.join(src, file);
|
|
91
|
-
const destPath = path.join(dest, file);
|
|
92
|
-
|
|
93
|
-
if (fs.lstatSync(srcPath).isDirectory()) {
|
|
94
|
-
copyDir(srcPath, destPath, excludes);
|
|
95
|
-
} else {
|
|
96
|
-
fs.copyFileSync(srcPath, destPath);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/* -------------------------------------------------------
|
|
102
|
-
* HELP
|
|
103
|
-
* ----------------------------------------------------- */
|
|
104
|
-
function help() {
|
|
105
|
-
console.log(`
|
|
106
|
-
${bold(cyan("Titan Planet"))} v${TITAN_VERSION}
|
|
107
|
-
|
|
108
|
-
${green("titan init <project>")} Create new Titan project
|
|
109
|
-
${green("titan create ext <name>")} Create new Titan extension
|
|
110
|
-
${green("titan dev")} Dev mode (hot reload)
|
|
111
|
-
${green("titan build")} Build production Rust server
|
|
112
|
-
${green("titan start")} Start production binary
|
|
113
|
-
${green("titan update")} Update Titan engine
|
|
114
|
-
${green("titan --version")} Show Titan CLI version
|
|
115
|
-
|
|
116
|
-
${yellow("Note: `tit` is supported as a legacy alias.")}
|
|
117
|
-
`);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/* -------------------------------------------------------
|
|
121
|
-
* INIT
|
|
122
|
-
* ----------------------------------------------------- */
|
|
123
|
-
function initProject(name) {
|
|
124
|
-
if (!name) {
|
|
125
|
-
console.log(red("Usage: titan init <project>"));
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const target = path.join(process.cwd(), name);
|
|
130
|
-
const templateDir = path.join(__dirname, "templates");
|
|
131
|
-
|
|
132
|
-
if (fs.existsSync(target)) {
|
|
133
|
-
console.log(yellow(`Folder already exists: ${target}`));
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
console.log(cyan(`Creating Titan project → ${target}`));
|
|
138
|
-
|
|
139
|
-
// ----------------------------------------------------------
|
|
140
|
-
// 1. Copy full template directory (excluding extension folder)
|
|
141
|
-
// ----------------------------------------------------------
|
|
142
|
-
copyDir(templateDir, target, ["extension"]);
|
|
143
|
-
|
|
144
|
-
// ----------------------------------------------------------
|
|
145
|
-
// 2. Explicitly install dotfiles
|
|
146
|
-
// ----------------------------------------------------------
|
|
147
|
-
const dotfiles = {
|
|
148
|
-
"_gitignore": ".gitignore",
|
|
149
|
-
"_dockerignore": ".dockerignore",
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
for (const [srcName, destName] of Object.entries(dotfiles)) {
|
|
153
|
-
const src = path.join(templateDir, srcName);
|
|
154
|
-
const dest = path.join(target, destName);
|
|
155
|
-
|
|
156
|
-
if (fs.existsSync(src)) {
|
|
157
|
-
fs.copyFileSync(src, dest);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
console.log(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
console.log(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
*
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
console.log(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
*
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
const
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
//
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
console.log(red("
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
*
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
*
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
//
|
|
313
|
-
//
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
*
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
const
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
content = content.replace(/{{
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const
|
|
419
|
-
const
|
|
420
|
-
const
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
replaceAll(
|
|
424
|
-
replaceAll(
|
|
425
|
-
replaceAll(
|
|
426
|
-
replaceAll(
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
console.log(
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
*
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
case "
|
|
478
|
-
case "
|
|
479
|
-
case "
|
|
480
|
-
case "
|
|
481
|
-
case "
|
|
482
|
-
case "
|
|
483
|
-
case "
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
}
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { execSync, spawn } from "child_process";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
6
|
+
|
|
7
|
+
/* Resolve __dirname for ES modules */
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
|
|
11
|
+
/* -------------------------------------------------------
|
|
12
|
+
* Colors
|
|
13
|
+
* ----------------------------------------------------- */
|
|
14
|
+
const cyan = (t) => `\x1b[36m${t}\x1b[0m`;
|
|
15
|
+
const green = (t) => `\x1b[32m${t}\x1b[0m`;
|
|
16
|
+
const yellow = (t) => `\x1b[33m${t}\x1b[0m`;
|
|
17
|
+
const red = (t) => `\x1b[31m${t}\x1b[0m`;
|
|
18
|
+
const bold = (t) => `\x1b[1m${t}\x1b[0m`;
|
|
19
|
+
|
|
20
|
+
/* -------------------------------------------------------
|
|
21
|
+
* Invocation detection (tit vs titan)
|
|
22
|
+
* ----------------------------------------------------- */
|
|
23
|
+
function wasInvokedAsTit() {
|
|
24
|
+
const script = process.argv[1];
|
|
25
|
+
if (script) {
|
|
26
|
+
const base = path.basename(script, path.extname(script)).toLowerCase();
|
|
27
|
+
if (base === "tit") return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
const raw = process.env.npm_config_argv;
|
|
32
|
+
if (raw) {
|
|
33
|
+
const cfg = JSON.parse(raw);
|
|
34
|
+
if (cfg.original && Array.isArray(cfg.original)) {
|
|
35
|
+
// e.g. ["tit", "dev"]
|
|
36
|
+
const first = cfg.original[0];
|
|
37
|
+
if (first && first.includes("tit") && !first.includes("titan")) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
} catch { }
|
|
43
|
+
|
|
44
|
+
const lastCmd = process.env["_"];
|
|
45
|
+
if (lastCmd) {
|
|
46
|
+
const base = path.basename(lastCmd, path.extname(lastCmd)).toLowerCase();
|
|
47
|
+
if (base === "tit") return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const isTitAlias = wasInvokedAsTit();
|
|
54
|
+
|
|
55
|
+
if (isTitAlias) {
|
|
56
|
+
console.log(
|
|
57
|
+
yellow(
|
|
58
|
+
"[Notice] `tit` is deprecated. Please use `titan` instead.\n" +
|
|
59
|
+
" `tit` will continue to work for now."
|
|
60
|
+
)
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* -------------------------------------------------------
|
|
65
|
+
* Args
|
|
66
|
+
* ----------------------------------------------------- */
|
|
67
|
+
const args = process.argv.slice(2);
|
|
68
|
+
const cmd = args[0];
|
|
69
|
+
|
|
70
|
+
/* -------------------------------------------------------
|
|
71
|
+
* Titan version
|
|
72
|
+
* ----------------------------------------------------- */
|
|
73
|
+
const pkg = JSON.parse(
|
|
74
|
+
fs.readFileSync(path.join(__dirname, "package.json"), "utf8")
|
|
75
|
+
);
|
|
76
|
+
const TITAN_VERSION = pkg.version;
|
|
77
|
+
|
|
78
|
+
/* -------------------------------------------------------
|
|
79
|
+
* Utils
|
|
80
|
+
* ----------------------------------------------------- */
|
|
81
|
+
function copyDir(src, dest, excludes = []) {
|
|
82
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
83
|
+
|
|
84
|
+
for (const file of fs.readdirSync(src)) {
|
|
85
|
+
// Skip excluded files/folders
|
|
86
|
+
if (excludes.includes(file)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const srcPath = path.join(src, file);
|
|
91
|
+
const destPath = path.join(dest, file);
|
|
92
|
+
|
|
93
|
+
if (fs.lstatSync(srcPath).isDirectory()) {
|
|
94
|
+
copyDir(srcPath, destPath, excludes);
|
|
95
|
+
} else {
|
|
96
|
+
fs.copyFileSync(srcPath, destPath);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* -------------------------------------------------------
|
|
102
|
+
* HELP
|
|
103
|
+
* ----------------------------------------------------- */
|
|
104
|
+
function help() {
|
|
105
|
+
console.log(`
|
|
106
|
+
${bold(cyan("Titan Planet"))} v${TITAN_VERSION}
|
|
107
|
+
|
|
108
|
+
${green("titan init <project>")} Create new Titan project
|
|
109
|
+
${green("titan create ext <name>")} Create new Titan extension
|
|
110
|
+
${green("titan dev")} Dev mode (hot reload)
|
|
111
|
+
${green("titan build")} Build production Rust server
|
|
112
|
+
${green("titan start")} Start production binary
|
|
113
|
+
${green("titan update")} Update Titan engine
|
|
114
|
+
${green("titan --version")} Show Titan CLI version
|
|
115
|
+
|
|
116
|
+
${yellow("Note: `tit` is supported as a legacy alias.")}
|
|
117
|
+
`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* -------------------------------------------------------
|
|
121
|
+
* INIT
|
|
122
|
+
* ----------------------------------------------------- */
|
|
123
|
+
function initProject(name) {
|
|
124
|
+
if (!name) {
|
|
125
|
+
console.log(red("Usage: titan init <project>"));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const target = path.join(process.cwd(), name);
|
|
130
|
+
const templateDir = path.join(__dirname, "templates");
|
|
131
|
+
|
|
132
|
+
if (fs.existsSync(target)) {
|
|
133
|
+
console.log(yellow(`Folder already exists: ${target}`));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
console.log(cyan(`Creating Titan project → ${target}`));
|
|
138
|
+
|
|
139
|
+
// ----------------------------------------------------------
|
|
140
|
+
// 1. Copy full template directory (excluding extension folder)
|
|
141
|
+
// ----------------------------------------------------------
|
|
142
|
+
copyDir(templateDir, target, ["extension", "_gitignore", "_dockerignore"]);
|
|
143
|
+
|
|
144
|
+
// ----------------------------------------------------------
|
|
145
|
+
// 2. Explicitly install dotfiles
|
|
146
|
+
// ----------------------------------------------------------
|
|
147
|
+
const dotfiles = {
|
|
148
|
+
"_gitignore": ".gitignore",
|
|
149
|
+
"_dockerignore": ".dockerignore",
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
for (const [srcName, destName] of Object.entries(dotfiles)) {
|
|
153
|
+
const src = path.join(templateDir, srcName);
|
|
154
|
+
const dest = path.join(target, destName);
|
|
155
|
+
|
|
156
|
+
if (fs.existsSync(src)) {
|
|
157
|
+
fs.copyFileSync(src, dest);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Dockerfile is safe as-is
|
|
162
|
+
const dockerfileSrc = path.join(templateDir, "Dockerfile");
|
|
163
|
+
if (fs.existsSync(dockerfileSrc)) {
|
|
164
|
+
fs.copyFileSync(dockerfileSrc, path.join(target, "Dockerfile"));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
console.log(green("✔ Titan project created!"));
|
|
168
|
+
console.log(cyan("Installing dependencies..."));
|
|
169
|
+
|
|
170
|
+
execSync(`npm install esbuild chokidar --silent`, {
|
|
171
|
+
cwd: target,
|
|
172
|
+
stdio: "inherit",
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
console.log(green("✔ Dependencies installed"));
|
|
176
|
+
console.log(`
|
|
177
|
+
Next steps:
|
|
178
|
+
cd ${name}
|
|
179
|
+
titan dev
|
|
180
|
+
`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* -------------------------------------------------------
|
|
184
|
+
* DEV SERVER
|
|
185
|
+
* ----------------------------------------------------- */
|
|
186
|
+
async function devServer() {
|
|
187
|
+
const root = process.cwd();
|
|
188
|
+
const devScript = path.join(root, "titan", "dev.js");
|
|
189
|
+
|
|
190
|
+
if (!fs.existsSync(devScript)) {
|
|
191
|
+
console.log(red("Error: titan/dev.js not found."));
|
|
192
|
+
console.log("Try running `titan update` to fix missing files.");
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const child = spawn("node", [devScript], {
|
|
197
|
+
stdio: "inherit",
|
|
198
|
+
cwd: root
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
child.on("close", (code) => {
|
|
202
|
+
// Exit strictly if the dev script failed
|
|
203
|
+
if (code !== 0) {
|
|
204
|
+
process.exit(code);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/* -------------------------------------------------------
|
|
210
|
+
* BUILD
|
|
211
|
+
* ----------------------------------------------------- */
|
|
212
|
+
function buildProd() {
|
|
213
|
+
console.log(cyan("Titan: Building production output..."));
|
|
214
|
+
|
|
215
|
+
const root = process.cwd();
|
|
216
|
+
const appJs = path.join(root, "app", "app.js");
|
|
217
|
+
const serverDir = path.join(root, "server");
|
|
218
|
+
const actionsOut = path.join(serverDir, "actions");
|
|
219
|
+
|
|
220
|
+
// BASIC CHECKS
|
|
221
|
+
if (!fs.existsSync(appJs)) {
|
|
222
|
+
console.log(red("ERROR: app/app.js not found."));
|
|
223
|
+
process.exit(1);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ----------------------------------------------------
|
|
227
|
+
// 1) BUILD METADATA + BUNDLE ACTIONS (ONE TIME ONLY)
|
|
228
|
+
// ----------------------------------------------------
|
|
229
|
+
console.log(cyan("→ Building Titan metadata + bundling actions..."));
|
|
230
|
+
execSync("node app/app.js --build", { stdio: "inherit" });
|
|
231
|
+
|
|
232
|
+
// ensure actions directory exists
|
|
233
|
+
fs.mkdirSync(actionsOut, { recursive: true });
|
|
234
|
+
|
|
235
|
+
// verify bundled actions exist
|
|
236
|
+
const bundles = fs.readdirSync(actionsOut).filter(f => f.endsWith(".jsbundle"));
|
|
237
|
+
if (bundles.length === 0) {
|
|
238
|
+
console.log(red("ERROR: No actions bundled."));
|
|
239
|
+
console.log(red("Make sure your DSL outputs to server/actions."));
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
bundles.forEach(file => {
|
|
244
|
+
console.log(cyan(`→ Found action bundle: ${file}`));
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
console.log(green("✔ Actions ready in server/actions"));
|
|
248
|
+
|
|
249
|
+
// ----------------------------------------------------
|
|
250
|
+
// 2) BUILD RUST BINARY
|
|
251
|
+
// ----------------------------------------------------
|
|
252
|
+
console.log(cyan("→ Building Rust release binary..."));
|
|
253
|
+
execSync("cargo build --release", {
|
|
254
|
+
cwd: serverDir,
|
|
255
|
+
stdio: "inherit"
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
console.log(green("✔ Titan production build complete!"));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/* -------------------------------------------------------
|
|
262
|
+
* START
|
|
263
|
+
* ----------------------------------------------------- */
|
|
264
|
+
function startProd() {
|
|
265
|
+
const isWin = process.platform === "win32";
|
|
266
|
+
const bin = isWin ? "titan-server.exe" : "titan-server";
|
|
267
|
+
|
|
268
|
+
const exe = path.join(process.cwd(), "server", "target", "release", bin);
|
|
269
|
+
execSync(`"${exe}"`, { stdio: "inherit" });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/* -------------------------------------------------------
|
|
273
|
+
* UPDATE
|
|
274
|
+
* ----------------------------------------------------- */
|
|
275
|
+
|
|
276
|
+
function updateTitan() {
|
|
277
|
+
const root = process.cwd();
|
|
278
|
+
|
|
279
|
+
const projectTitan = path.join(root, "titan");
|
|
280
|
+
const projectServer = path.join(root, "server");
|
|
281
|
+
|
|
282
|
+
const templatesRoot = path.join(__dirname, "templates");
|
|
283
|
+
const templateTitan = path.join(templatesRoot, "titan");
|
|
284
|
+
const templateServer = path.join(templatesRoot, "server");
|
|
285
|
+
|
|
286
|
+
if (!fs.existsSync(projectTitan)) {
|
|
287
|
+
console.log(red("Not a Titan project — titan/ folder missing."));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (!fs.existsSync(templateServer)) {
|
|
292
|
+
console.log(red("CLI is corrupted — server template missing."));
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
console.log(cyan("Updating Titan runtime and server..."));
|
|
297
|
+
|
|
298
|
+
// ----------------------------------------------------------
|
|
299
|
+
// 1. Update titan/ runtime (authoritative, safe to replace)
|
|
300
|
+
// ----------------------------------------------------------
|
|
301
|
+
fs.rmSync(projectTitan, {
|
|
302
|
+
recursive: true,
|
|
303
|
+
force: true,
|
|
304
|
+
maxRetries: 10,
|
|
305
|
+
retryDelay: 500,
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
copyDir(templateTitan, projectTitan);
|
|
309
|
+
console.log(green("✔ Updated titan/ runtime"));
|
|
310
|
+
|
|
311
|
+
// ----------------------------------------------------------
|
|
312
|
+
// 2. Update server/ WITHOUT deleting the folder
|
|
313
|
+
// ----------------------------------------------------------
|
|
314
|
+
if (!fs.existsSync(projectServer)) {
|
|
315
|
+
fs.mkdirSync(projectServer);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// 2a. Overwrite Cargo.toml
|
|
319
|
+
const srcCargo = path.join(templateServer, "Cargo.toml");
|
|
320
|
+
const destCargo = path.join(projectServer, "Cargo.toml");
|
|
321
|
+
|
|
322
|
+
if (fs.existsSync(srcCargo)) {
|
|
323
|
+
fs.copyFileSync(srcCargo, destCargo);
|
|
324
|
+
console.log(green("✔ Updated server/Cargo.toml"));
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// 2b. Replace server/src only
|
|
328
|
+
const projectSrc = path.join(projectServer, "src");
|
|
329
|
+
const templateSrc = path.join(templateServer, "src");
|
|
330
|
+
|
|
331
|
+
if (fs.existsSync(projectSrc)) {
|
|
332
|
+
fs.rmSync(projectSrc, {
|
|
333
|
+
recursive: true,
|
|
334
|
+
force: true,
|
|
335
|
+
maxRetries: 10,
|
|
336
|
+
retryDelay: 500,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
copyDir(templateSrc, projectSrc);
|
|
341
|
+
console.log(green("✔ Updated server/src/"));
|
|
342
|
+
|
|
343
|
+
// Root-level config files
|
|
344
|
+
[".gitignore", ".dockerignore", "Dockerfile", "jsconfig.json"].forEach((file) => {
|
|
345
|
+
const src = path.join(templatesRoot, file);
|
|
346
|
+
const dest = path.join(root, file);
|
|
347
|
+
|
|
348
|
+
if (fs.existsSync(src)) {
|
|
349
|
+
fs.copyFileSync(src, dest);
|
|
350
|
+
console.log(green(`✔ Updated ${file}`));
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
// app/titan.d.ts (JS typing contract)
|
|
355
|
+
const appDir = path.join(root, "app");
|
|
356
|
+
const srcDts = path.join(templateServer, "../app/titan.d.ts"); // templates/app/titan.d.ts
|
|
357
|
+
const destDts = path.join(appDir, "titan.d.ts");
|
|
358
|
+
|
|
359
|
+
if (fs.existsSync(srcDts)) {
|
|
360
|
+
if (!fs.existsSync(appDir)) {
|
|
361
|
+
fs.mkdirSync(appDir);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
fs.copyFileSync(srcDts, destDts);
|
|
365
|
+
console.log(green("✔ Updated app/titan.d.ts"));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
console.log(bold(green("✔ Titan update complete")));
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
/* -------------------------------------------------------
|
|
375
|
+
* CREATE EXTENSION
|
|
376
|
+
* ----------------------------------------------------- */
|
|
377
|
+
function createExtension(name) {
|
|
378
|
+
if (!name) {
|
|
379
|
+
console.log(red("Usage: titan create ext <name>"));
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
const folderName = name;
|
|
385
|
+
|
|
386
|
+
const target = path.join(process.cwd(), folderName);
|
|
387
|
+
const templateDir = path.join(__dirname, "templates", "extension");
|
|
388
|
+
|
|
389
|
+
if (fs.existsSync(target)) {
|
|
390
|
+
console.log(yellow(`Folder already exists: ${target}`));
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
if (!fs.existsSync(templateDir)) {
|
|
395
|
+
console.log(red(`Extension template not found at ${templateDir}`));
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
console.log(cyan(`Creating Titan extension → ${target}`));
|
|
400
|
+
|
|
401
|
+
// 1. Copy template
|
|
402
|
+
copyDir(templateDir, target);
|
|
403
|
+
|
|
404
|
+
// 2. Process templates (replace {{name}})
|
|
405
|
+
const title = name;
|
|
406
|
+
const nativeName = title.replace(/-/g, "_");
|
|
407
|
+
|
|
408
|
+
const replaceAll = (filePath) => {
|
|
409
|
+
if (fs.existsSync(filePath)) {
|
|
410
|
+
let content = fs.readFileSync(filePath, "utf8");
|
|
411
|
+
content = content.replace(/{{name}}/g, title);
|
|
412
|
+
content = content.replace(/{{native_name}}/g, nativeName);
|
|
413
|
+
fs.writeFileSync(filePath, content);
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
const idxPath = path.join(target, "index.js");
|
|
418
|
+
const readmePath = path.join(target, "README.md");
|
|
419
|
+
const pkgPath = path.join(target, "package.json");
|
|
420
|
+
const cargoPath = path.join(target, "native", "Cargo.toml");
|
|
421
|
+
|
|
422
|
+
replaceAll(path.join(target, "titan.json"));
|
|
423
|
+
replaceAll(idxPath);
|
|
424
|
+
replaceAll(readmePath);
|
|
425
|
+
replaceAll(pkgPath);
|
|
426
|
+
replaceAll(cargoPath);
|
|
427
|
+
|
|
428
|
+
console.log(cyan("Installing dependencies..."));
|
|
429
|
+
try {
|
|
430
|
+
execSync("npm install", { cwd: target, stdio: "inherit" });
|
|
431
|
+
} catch (e) {
|
|
432
|
+
console.log(yellow("Warning: Failed to install dependencies. You may need to run `npm install` manually."));
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
console.log(green("✔ Extension created!"));
|
|
436
|
+
console.log(`
|
|
437
|
+
Next steps:
|
|
438
|
+
cd ${name}
|
|
439
|
+
# If you have native code:
|
|
440
|
+
cd native && cargo build --release
|
|
441
|
+
# To test your extension
|
|
442
|
+
titan run ext
|
|
443
|
+
`);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
function runExtension() {
|
|
447
|
+
const localSdk = path.join(__dirname, "titanpl-sdk", "bin", "run.js");
|
|
448
|
+
|
|
449
|
+
if (fs.existsSync(localSdk)) {
|
|
450
|
+
console.log(cyan("[Titan] Using local SDK runner..."));
|
|
451
|
+
try {
|
|
452
|
+
execSync(`node "${localSdk}"`, { stdio: "inherit" });
|
|
453
|
+
} catch (e) {
|
|
454
|
+
// SDK runner handles its own errors
|
|
455
|
+
}
|
|
456
|
+
} else {
|
|
457
|
+
console.log(cyan("[Titan] SDK not found locally, falling back to npx..."));
|
|
458
|
+
try {
|
|
459
|
+
execSync("npx -y titan-sdk", { stdio: "inherit" });
|
|
460
|
+
} catch (e) {
|
|
461
|
+
// SDK runner handles its own errors
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/* -------------------------------------------------------
|
|
467
|
+
* ROUTER
|
|
468
|
+
* ----------------------------------------------------- */
|
|
469
|
+
// "titan create ext <name>" -> args = ["create", "ext", "calc_ext"]
|
|
470
|
+
if (cmd === "create" && args[1] === "ext") {
|
|
471
|
+
createExtension(args[2]);
|
|
472
|
+
} else if (cmd === "run" && args[1] === "ext") {
|
|
473
|
+
runExtension();
|
|
474
|
+
} else {
|
|
475
|
+
switch (cmd) {
|
|
476
|
+
case "init": initProject(args[1]); break;
|
|
477
|
+
case "dev": devServer(); break;
|
|
478
|
+
case "build": buildProd(); break;
|
|
479
|
+
case "start": startProd(); break;
|
|
480
|
+
case "update": updateTitan(); break;
|
|
481
|
+
case "--version":
|
|
482
|
+
case "-v":
|
|
483
|
+
case "version":
|
|
484
|
+
console.log(cyan(`Titan v${TITAN_VERSION}`));
|
|
485
|
+
break;
|
|
486
|
+
default:
|
|
487
|
+
help();
|
|
488
|
+
}
|
|
489
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ezetgalaxy/titan",
|
|
3
|
-
"version": "26.7.
|
|
3
|
+
"version": "26.7.5",
|
|
4
4
|
"description": "Titan Planet is a JavaScript-first backend framework that embeds JS actions into a Rust + Axum server and ships as a single native binary. Routes are compiled to static metadata; only actions run in the embedded JS runtime. No Node.js. No event loop in production.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "ezetgalaxy",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"index.js",
|
|
15
|
-
"scripts/",
|
|
16
15
|
"templates/",
|
|
17
16
|
"titan",
|
|
18
17
|
"titanpl-sdk",
|
|
@@ -45,7 +44,8 @@
|
|
|
45
44
|
],
|
|
46
45
|
"scripts": {
|
|
47
46
|
"build": "echo \"No build step\"",
|
|
48
|
-
"test": "echo \"No tests specified\""
|
|
47
|
+
"test": "echo \"No tests specified\"",
|
|
48
|
+
"test_titan_init": "node scripts/test_titan_init.js"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"chokidar": "^5.0.0",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Node
|
|
2
|
+
node_modules/
|
|
3
|
+
npm-debug.log
|
|
4
|
+
yarn-error.log
|
|
5
|
+
|
|
6
|
+
# Titan build output (auto-generated — DO NOT COMMIT)
|
|
7
|
+
server/routes.json
|
|
8
|
+
server/action_map.json
|
|
9
|
+
server/actions/*.jsbundle
|
|
10
|
+
server/titan/*.jsbundle
|
|
11
|
+
|
|
12
|
+
# Rust build output (auto-generated — DO NOT COMMIT)
|
|
13
|
+
server/target/
|
|
14
|
+
server/target/**
|
|
15
|
+
|
|
16
|
+
# Logs
|
|
17
|
+
*.log
|
|
18
|
+
|
|
19
|
+
# System files
|
|
20
|
+
.DS_Store
|
|
21
|
+
Thumbs.db
|
|
22
|
+
|
|
23
|
+
# Environment files
|
|
24
|
+
.env
|
|
25
|
+
.env.local
|
package/templates/package.json
CHANGED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const defineAction = (fn) => fn;
|
|
2
|
+
var __titan_exports = (() => {
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// app/actions/hello.js
|
|
22
|
+
var hello_exports = {};
|
|
23
|
+
__export(hello_exports, {
|
|
24
|
+
hello: () => hello
|
|
25
|
+
});
|
|
26
|
+
var hello = (req) => {
|
|
27
|
+
return {
|
|
28
|
+
message: `Hello from Titan ${req.body.name}`
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
return __toCommonJS(hello_exports);
|
|
32
|
+
})();
|
|
33
|
+
|
|
34
|
+
(function () {
|
|
35
|
+
const fn =
|
|
36
|
+
__titan_exports["hello"] ||
|
|
37
|
+
__titan_exports.default;
|
|
38
|
+
|
|
39
|
+
if (typeof fn !== "function") {
|
|
40
|
+
throw new Error("[Titan] Action 'hello' not found or not a function");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
globalThis["hello"] = fn;
|
|
44
|
+
})();
|
|
45
|
+
|
package/titanpl-sdk/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "titanpl-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Development SDK for Titan Planet. Provides TypeScript type definitions for the global 't' runtime object and a 'lite' test-harness runtime for building and verifying extensions.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
package/scripts/make_dist.sh
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -e
|
|
3
|
-
|
|
4
|
-
echo "Building Titan distribution..."
|
|
5
|
-
|
|
6
|
-
# ---------------------------------------------
|
|
7
|
-
# Resolve directories
|
|
8
|
-
# ---------------------------------------------
|
|
9
|
-
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
10
|
-
SERVER_DIR="$ROOT/server"
|
|
11
|
-
DIST_DIR="$ROOT/dist"
|
|
12
|
-
|
|
13
|
-
# Clean and recreate dist/
|
|
14
|
-
rm -rf "$DIST_DIR"
|
|
15
|
-
mkdir -p "$DIST_DIR"
|
|
16
|
-
|
|
17
|
-
# ---------------------------------------------
|
|
18
|
-
# Copy release binary titan-server
|
|
19
|
-
# ---------------------------------------------
|
|
20
|
-
RELEASE_PATH="$SERVER_DIR/target/release"
|
|
21
|
-
|
|
22
|
-
echo "Looking for titan-server binary..."
|
|
23
|
-
|
|
24
|
-
if [ -f "$RELEASE_PATH/titan-server" ]; then
|
|
25
|
-
echo "✓ Found titan-server"
|
|
26
|
-
cp "$RELEASE_PATH/titan-server" "$DIST_DIR/"
|
|
27
|
-
else
|
|
28
|
-
echo "Binary not found directly, searching..."
|
|
29
|
-
BIN=$(ls "$RELEASE_PATH" | grep 'titan-server' || true)
|
|
30
|
-
|
|
31
|
-
if [ -n "$BIN" ]; then
|
|
32
|
-
echo "✓ Found matching binary: $BIN"
|
|
33
|
-
cp "$RELEASE_PATH/$BIN" "$DIST_DIR/titan-server"
|
|
34
|
-
else
|
|
35
|
-
echo "✗ titan-server binary not found in release folder."
|
|
36
|
-
echo "Did you run: cargo build --release ?"
|
|
37
|
-
exit 1
|
|
38
|
-
fi
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
# ---------------------------------------------
|
|
42
|
-
# routes.json (JS bundler should generate routes.build.json)
|
|
43
|
-
# ---------------------------------------------
|
|
44
|
-
if [ -f "$ROOT/routes.build.json" ]; then
|
|
45
|
-
echo "✓ Using routes.build.json"
|
|
46
|
-
cp "$ROOT/routes.build.json" "$DIST_DIR/routes.json"
|
|
47
|
-
else
|
|
48
|
-
echo "⚠ No routes.build.json found. Creating empty routes.json"
|
|
49
|
-
echo "{}" > "$DIST_DIR/routes.json"
|
|
50
|
-
fi
|
|
51
|
-
|
|
52
|
-
# ---------------------------------------------
|
|
53
|
-
# Copy handlers if they exist
|
|
54
|
-
# ---------------------------------------------
|
|
55
|
-
mkdir -p "$DIST_DIR/handlers"
|
|
56
|
-
|
|
57
|
-
if [ -d "$ROOT/handlers" ]; then
|
|
58
|
-
echo "✓ Copying handlers/"
|
|
59
|
-
cp -r "$ROOT/handlers/"* "$DIST_DIR/handlers/" 2>/dev/null || true
|
|
60
|
-
else
|
|
61
|
-
echo "⚠ No handlers/ directory found."
|
|
62
|
-
fi
|
|
63
|
-
|
|
64
|
-
echo ""
|
|
65
|
-
echo "-------------------------------------------"
|
|
66
|
-
echo " ✔ Titan dist/ build complete"
|
|
67
|
-
echo "-------------------------------------------"
|
|
68
|
-
echo "Binary: dist/titan-server"
|
|
69
|
-
echo "Routes: dist/routes.json"
|
|
70
|
-
echo "Handlers: dist/handlers/"
|
|
71
|
-
echo ""
|