@titanpl/packet 2.0.3 → 4.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/index.js +205 -0
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -32,6 +32,25 @@ function ensureDist(root) {
|
|
|
32
32
|
return dist;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Recursive copy
|
|
37
|
+
*/
|
|
38
|
+
function copyDir(src, dest, filter) {
|
|
39
|
+
if (filter && !filter(src)) return;
|
|
40
|
+
|
|
41
|
+
const stats = fs.lstatSync(src);
|
|
42
|
+
if (stats.isDirectory()) {
|
|
43
|
+
if (!fs.existsSync(dest)) {
|
|
44
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
for (const file of fs.readdirSync(src)) {
|
|
47
|
+
copyDir(path.join(src, file), path.join(dest, file), filter);
|
|
48
|
+
}
|
|
49
|
+
} else {
|
|
50
|
+
fs.copyFileSync(src, dest);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
35
54
|
/**
|
|
36
55
|
* Production build
|
|
37
56
|
*/
|
|
@@ -51,6 +70,192 @@ export async function build(root = process.cwd()) {
|
|
|
51
70
|
return dist;
|
|
52
71
|
}
|
|
53
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Release build (Production ready folder)
|
|
75
|
+
*/
|
|
76
|
+
export async function release(root = process.cwd()) {
|
|
77
|
+
const dist = await build(root);
|
|
78
|
+
const buildDir = path.join(root, "build");
|
|
79
|
+
|
|
80
|
+
// Read config
|
|
81
|
+
let config = {};
|
|
82
|
+
const configPath = fs.existsSync(path.join(root, "tanfig.json"))
|
|
83
|
+
? path.join(root, "tanfig.json")
|
|
84
|
+
: fs.existsSync(path.join(root, "titan.json"))
|
|
85
|
+
? path.join(root, "titan.json")
|
|
86
|
+
: null;
|
|
87
|
+
|
|
88
|
+
if (configPath) {
|
|
89
|
+
try {
|
|
90
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
91
|
+
} catch (e) { }
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const filesToCopy = config.build && config.build.files ? config.build.files : ["public", "static", "db", "config"];
|
|
95
|
+
|
|
96
|
+
// Clear or ensure build dir
|
|
97
|
+
if (fs.existsSync(buildDir)) {
|
|
98
|
+
fs.rmSync(buildDir, { recursive: true, force: true });
|
|
99
|
+
}
|
|
100
|
+
fs.mkdirSync(buildDir, { recursive: true });
|
|
101
|
+
|
|
102
|
+
// 1. Copy dist
|
|
103
|
+
copyDir(dist, path.join(buildDir, "dist"));
|
|
104
|
+
|
|
105
|
+
// 2. Extra files/folders from root based on config
|
|
106
|
+
for (const item of filesToCopy) {
|
|
107
|
+
const src = path.join(root, item);
|
|
108
|
+
if (fs.existsSync(src)) {
|
|
109
|
+
const dest = path.join(buildDir, item);
|
|
110
|
+
copyDir(src, dest);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 3. Copy package.json
|
|
115
|
+
const pkgPath = path.join(root, "package.json");
|
|
116
|
+
if (fs.existsSync(pkgPath)) {
|
|
117
|
+
fs.copyFileSync(pkgPath, path.join(buildDir, "package.json"));
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 4. Create .env
|
|
121
|
+
fs.writeFileSync(path.join(buildDir, ".env"), "TITAN_DEV=0\n");
|
|
122
|
+
|
|
123
|
+
// 5. Extract extensions
|
|
124
|
+
const extDir = path.join(buildDir, ".ext");
|
|
125
|
+
fs.mkdirSync(extDir, { recursive: true });
|
|
126
|
+
|
|
127
|
+
const nodeModules = path.join(root, "node_modules");
|
|
128
|
+
if (fs.existsSync(nodeModules)) {
|
|
129
|
+
const findExtensions = (dir, depth = 0) => {
|
|
130
|
+
if (depth > 2) return;
|
|
131
|
+
if (!fs.existsSync(dir)) return;
|
|
132
|
+
|
|
133
|
+
const files = fs.readdirSync(dir);
|
|
134
|
+
for (const file of files) {
|
|
135
|
+
const fullPath = path.join(dir, file);
|
|
136
|
+
try {
|
|
137
|
+
const stats = fs.lstatSync(fullPath);
|
|
138
|
+
if (stats.isDirectory()) {
|
|
139
|
+
if (file === "node_modules" && depth > 0) continue;
|
|
140
|
+
|
|
141
|
+
const titanJson = path.join(fullPath, "titan.json");
|
|
142
|
+
if (fs.existsSync(titanJson)) {
|
|
143
|
+
let targetPkgName = file;
|
|
144
|
+
const parentDirName = path.basename(dir);
|
|
145
|
+
if (parentDirName.startsWith("@")) {
|
|
146
|
+
targetPkgName = path.join(parentDirName, file);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const destPath = path.join(extDir, targetPkgName);
|
|
150
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
151
|
+
|
|
152
|
+
copyDir(fullPath, destPath, (src) => {
|
|
153
|
+
const rel = path.relative(fullPath, src);
|
|
154
|
+
return !rel.startsWith("node_modules");
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
findExtensions(fullPath, depth + 1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} catch (e) { }
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
findExtensions(nodeModules);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// 6. Copy Engine binaries
|
|
167
|
+
if (fs.existsSync(path.join(nodeModules, "@titanpl"))) {
|
|
168
|
+
const scopeDir = path.join(nodeModules, "@titanpl");
|
|
169
|
+
const folders = fs.readdirSync(scopeDir);
|
|
170
|
+
for (const folder of folders) {
|
|
171
|
+
if (folder.startsWith("engine-")) {
|
|
172
|
+
const engineDest = path.join(extDir, "@titanpl", folder);
|
|
173
|
+
copyDir(path.join(scopeDir, folder), engineDest);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 7. Create node_modules junction to .ext for engine resolution
|
|
179
|
+
// If env is 'deploy' or 'production', we might want to skip this for a cleaner build
|
|
180
|
+
const buildEnv = config.build && (config.build.env || config.build.purpose) ? (config.build.env || config.build.purpose) : "test";
|
|
181
|
+
|
|
182
|
+
if (buildEnv !== "deploy" && buildEnv !== "production") {
|
|
183
|
+
const nmSymlink = path.join(buildDir, "node_modules");
|
|
184
|
+
if (!fs.existsSync(nmSymlink)) {
|
|
185
|
+
try {
|
|
186
|
+
// Junctions don't require admin on Windows
|
|
187
|
+
fs.symlinkSync(".ext", nmSymlink, "junction");
|
|
188
|
+
} catch (e) {
|
|
189
|
+
try {
|
|
190
|
+
fs.symlinkSync(".ext", nmSymlink, "dir");
|
|
191
|
+
} catch (e2) {
|
|
192
|
+
// Fallback or ignore if symlink creation is totally restricted
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// 8. Create 'titan' executable link in the build root for easy starting
|
|
199
|
+
const binName = process.platform === "win32" ? "titan-server.exe" : "titan-server";
|
|
200
|
+
let engineBin = null;
|
|
201
|
+
|
|
202
|
+
// Strategy A: Search in the .ext we just populated
|
|
203
|
+
const findInExt = (dir) => {
|
|
204
|
+
if (!fs.existsSync(dir)) return null;
|
|
205
|
+
const entries = fs.readdirSync(dir);
|
|
206
|
+
for (const entry of entries) {
|
|
207
|
+
const full = path.join(dir, entry);
|
|
208
|
+
if (fs.statSync(full).isDirectory()) {
|
|
209
|
+
// Check both pkgRoot/bin/titan-server and pkgRoot/titan-server (some layouts differ)
|
|
210
|
+
const p1 = path.join(full, "bin", binName);
|
|
211
|
+
if (fs.existsSync(p1)) return p1;
|
|
212
|
+
const p2 = path.join(full, binName);
|
|
213
|
+
if (fs.existsSync(p2)) return p2;
|
|
214
|
+
|
|
215
|
+
const found = findInExt(full);
|
|
216
|
+
if (found) return found;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
engineBin = findInExt(extDir);
|
|
223
|
+
|
|
224
|
+
// Strategy B: Monorepo fallback (if building inside the titanpl repo)
|
|
225
|
+
if (!engineBin) {
|
|
226
|
+
let current = root;
|
|
227
|
+
for (let i = 0; i < 5; i++) {
|
|
228
|
+
const potential = path.join(current, "engine", "target", "release", binName);
|
|
229
|
+
if (fs.existsSync(potential)) {
|
|
230
|
+
engineBin = potential;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
const parent = path.dirname(current);
|
|
234
|
+
if (parent === current) break;
|
|
235
|
+
current = parent;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (engineBin) {
|
|
240
|
+
const linkName = binName; // Keep the original name 'titan-server'
|
|
241
|
+
const linkPath = path.join(buildDir, linkName);
|
|
242
|
+
|
|
243
|
+
if (!fs.existsSync(linkPath)) {
|
|
244
|
+
try {
|
|
245
|
+
// Always copy the binary to the root for maximum portability in the 'build' folder
|
|
246
|
+
fs.copyFileSync(engineBin, linkPath);
|
|
247
|
+
if (process.platform !== "win32") {
|
|
248
|
+
fs.chmodSync(linkPath, 0o755);
|
|
249
|
+
}
|
|
250
|
+
} catch (e) {
|
|
251
|
+
console.error(`[Titan] Failed to create titan binary: ${e.message}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return buildDir;
|
|
257
|
+
}
|
|
258
|
+
|
|
54
259
|
/**
|
|
55
260
|
* Dev mode build
|
|
56
261
|
*/
|