@titanpl/packet 7.0.0-beta → 7.0.1
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 +94 -102
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -83,10 +83,19 @@ export async function build(root = process.cwd()) {
|
|
|
83
83
|
* Release build (Production ready folder)
|
|
84
84
|
*/
|
|
85
85
|
export async function release(root = process.cwd()) {
|
|
86
|
-
const dist = await build(root);
|
|
87
86
|
const buildDir = path.join(root, "build");
|
|
88
87
|
|
|
89
|
-
//
|
|
88
|
+
// Step 1: Pre-build (Production mode)
|
|
89
|
+
// Run production build to generate 'dist' folder
|
|
90
|
+
const dist = await build(root);
|
|
91
|
+
|
|
92
|
+
// Step 2: Clear or ensure build dir
|
|
93
|
+
if (fs.existsSync(buildDir)) {
|
|
94
|
+
fs.rmSync(buildDir, { recursive: true, force: true });
|
|
95
|
+
}
|
|
96
|
+
fs.mkdirSync(buildDir, { recursive: true });
|
|
97
|
+
|
|
98
|
+
// Step 3: Read config and files list
|
|
90
99
|
let config = {};
|
|
91
100
|
const configPath = fs.existsSync(path.join(root, "tanfig.json"))
|
|
92
101
|
? path.join(root, "tanfig.json")
|
|
@@ -100,49 +109,63 @@ export async function release(root = process.cwd()) {
|
|
|
100
109
|
} catch (e) { }
|
|
101
110
|
}
|
|
102
111
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
fs.rmSync(buildDir, { recursive: true, force: true });
|
|
108
|
-
}
|
|
109
|
-
fs.mkdirSync(buildDir, { recursive: true });
|
|
110
|
-
|
|
111
|
-
// 1. Copy dist
|
|
112
|
-
copyDir(dist, path.join(buildDir, "dist"));
|
|
112
|
+
// Default files to copy from root
|
|
113
|
+
const defaultFiles = ["public", "static", "db", "config", "views", "auth"];
|
|
114
|
+
const userFiles = config.build && Array.isArray(config.build.files) ? config.build.files : [];
|
|
115
|
+
const filesToCopy = Array.from(new Set([...defaultFiles, ...userFiles]));
|
|
113
116
|
|
|
114
|
-
//
|
|
117
|
+
// Step 4: Copy Files & Folders from root and app folders to build
|
|
115
118
|
for (const item of filesToCopy) {
|
|
119
|
+
// Check root first, then app/ folder
|
|
116
120
|
const src = path.join(root, item);
|
|
121
|
+
const appSrc = path.join(root, "app", item);
|
|
122
|
+
const dest = path.join(buildDir, item);
|
|
123
|
+
|
|
117
124
|
if (fs.existsSync(src)) {
|
|
118
|
-
const dest = path.join(buildDir, item);
|
|
119
125
|
copyDir(src, dest);
|
|
126
|
+
} else if (fs.existsSync(appSrc)) {
|
|
127
|
+
const appDest = path.join(buildDir, "app", item);
|
|
128
|
+
copyDir(appSrc, appDest);
|
|
120
129
|
}
|
|
121
130
|
}
|
|
122
131
|
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
fs.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (fs.existsSync(titanConfigPath)) {
|
|
134
|
-
fs.copyFileSync(titanConfigPath, path.join(buildDir, "titan.json"));
|
|
132
|
+
// Step 5: Copy generated 'dist' (static routes/actions metadata)
|
|
133
|
+
copyDir(dist, path.join(buildDir, "dist"));
|
|
134
|
+
|
|
135
|
+
// Step 6: Copy essential config files (mandatory for runtime)
|
|
136
|
+
const essentials = ["package.json", "tanfig.json", "titan.json"];
|
|
137
|
+
for (const f of essentials) {
|
|
138
|
+
const src = path.join(root, f);
|
|
139
|
+
if (fs.existsSync(src)) {
|
|
140
|
+
fs.copyFileSync(src, path.join(buildDir, f));
|
|
141
|
+
}
|
|
135
142
|
}
|
|
136
143
|
|
|
137
|
-
//
|
|
144
|
+
// Step 7: Create .env for production
|
|
138
145
|
fs.writeFileSync(path.join(buildDir, ".env"), "TITAN_DEV=0\n");
|
|
139
146
|
|
|
140
|
-
//
|
|
147
|
+
// Step 8: Extract Extensions
|
|
141
148
|
const extDir = path.join(buildDir, ".ext");
|
|
142
149
|
fs.mkdirSync(extDir, { recursive: true });
|
|
143
150
|
|
|
144
151
|
const nodeModules = path.join(root, "node_modules");
|
|
145
152
|
if (fs.existsSync(nodeModules)) {
|
|
153
|
+
const localPkgs = path.resolve(root, "../../packages");
|
|
154
|
+
if (fs.existsSync(localPkgs)) {
|
|
155
|
+
const pkgs = fs.readdirSync(localPkgs);
|
|
156
|
+
for (const pkg of pkgs) {
|
|
157
|
+
const pkgPath = path.join(localPkgs, pkg);
|
|
158
|
+
const titanJsonPath = path.join(pkgPath, "titan.json");
|
|
159
|
+
if (fs.existsSync(titanJsonPath)) {
|
|
160
|
+
try {
|
|
161
|
+
const config = JSON.parse(fs.readFileSync(titanJsonPath, "utf8"));
|
|
162
|
+
const extName = config.name;
|
|
163
|
+
const dest = path.join(extDir, extName.includes("/") ? extName : extName);
|
|
164
|
+
copyDir(pkgPath, dest);
|
|
165
|
+
} catch(e) {}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
146
169
|
const findExtensions = (dir, depth = 0) => {
|
|
147
170
|
if (depth > 2) return;
|
|
148
171
|
if (!fs.existsSync(dir)) return;
|
|
@@ -164,6 +187,8 @@ export async function release(root = process.cwd()) {
|
|
|
164
187
|
}
|
|
165
188
|
|
|
166
189
|
const destPath = path.join(extDir, targetPkgName);
|
|
190
|
+
if (fs.existsSync(destPath)) continue; // Don't overwrite monorepo packages
|
|
191
|
+
|
|
167
192
|
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
168
193
|
|
|
169
194
|
copyDir(fullPath, destPath, (src) => {
|
|
@@ -178,98 +203,65 @@ export async function release(root = process.cwd()) {
|
|
|
178
203
|
}
|
|
179
204
|
};
|
|
180
205
|
findExtensions(nodeModules);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// 6. Copy Engine binaries
|
|
184
|
-
if (fs.existsSync(path.join(nodeModules, "@titanpl"))) {
|
|
185
|
-
const scopeDir = path.join(nodeModules, "@titanpl");
|
|
186
|
-
const folders = fs.readdirSync(scopeDir);
|
|
187
|
-
for (const folder of folders) {
|
|
188
|
-
if (folder.startsWith("engine-")) {
|
|
189
|
-
const engineDest = path.join(extDir, "@titanpl", folder);
|
|
190
|
-
copyDir(path.join(scopeDir, folder), engineDest);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
206
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
// Junctions don't require admin on Windows
|
|
204
|
-
fs.symlinkSync(".ext", nmSymlink, "junction");
|
|
205
|
-
} catch (e) {
|
|
206
|
-
try {
|
|
207
|
-
fs.symlinkSync(".ext", nmSymlink, "dir");
|
|
208
|
-
} catch (e2) {
|
|
209
|
-
// Fallback or ignore if symlink creation is totally restricted
|
|
207
|
+
// Also copy engine binaries if they exist in node_modules
|
|
208
|
+
if (fs.existsSync(path.join(nodeModules, "@titanpl"))) {
|
|
209
|
+
const scopeDir = path.join(nodeModules, "@titanpl");
|
|
210
|
+
const folders = fs.readdirSync(scopeDir);
|
|
211
|
+
for (const folder of folders) {
|
|
212
|
+
if (folder.startsWith("engine-") || folder.startsWith("runtime-")) {
|
|
213
|
+
const engineDest = path.join(extDir, "@titanpl", folder);
|
|
214
|
+
copyDir(path.join(scopeDir, folder), engineDest);
|
|
210
215
|
}
|
|
211
216
|
}
|
|
212
217
|
}
|
|
213
218
|
}
|
|
214
219
|
|
|
215
|
-
//
|
|
220
|
+
// Step 9: Copy/Extract titan-server binary to build root
|
|
216
221
|
const binName = process.platform === "win32" ? "titan-server.exe" : "titan-server";
|
|
217
222
|
let engineBin = null;
|
|
218
223
|
|
|
219
|
-
//
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
return null;
|
|
224
|
+
// Search in .ext
|
|
225
|
+
const searchBin = (dir) => {
|
|
226
|
+
if (!fs.existsSync(dir)) return null;
|
|
227
|
+
const entries = fs.readdirSync(dir);
|
|
228
|
+
for (const e of entries) {
|
|
229
|
+
const full = path.join(dir, e);
|
|
230
|
+
if (fs.statSync(full).isDirectory()) {
|
|
231
|
+
const p1 = path.join(full, "bin", binName);
|
|
232
|
+
if (fs.existsSync(p1)) return p1;
|
|
233
|
+
const p2 = path.join(full, binName);
|
|
234
|
+
if (fs.existsSync(p2)) return p2;
|
|
235
|
+
const found = searchBin(full);
|
|
236
|
+
if (found) return found;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
237
240
|
};
|
|
241
|
+
engineBin = searchBin(extDir);
|
|
238
242
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
// Strategy B: Monorepo fallback (if building inside the titanpl repo)
|
|
243
|
+
// Fallback to monorepo binary (if building in repo)
|
|
242
244
|
if (!engineBin) {
|
|
243
|
-
let
|
|
244
|
-
for
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
if (parent === current) break;
|
|
252
|
-
current = parent;
|
|
245
|
+
let curr = root;
|
|
246
|
+
for(let i=0; i<3; i++) {
|
|
247
|
+
const potential = path.join(curr, "engine", "target", "release", binName);
|
|
248
|
+
if (fs.existsSync(potential)) {
|
|
249
|
+
engineBin = potential;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
curr = path.dirname(curr);
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
if (engineBin) {
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (!fs.existsSync(linkPath)) {
|
|
261
|
-
try {
|
|
262
|
-
// Always copy the binary to the root for maximum portability in the 'build' folder
|
|
263
|
-
fs.copyFileSync(engineBin, linkPath);
|
|
264
|
-
if (process.platform !== "win32") {
|
|
265
|
-
fs.chmodSync(linkPath, 0o755);
|
|
266
|
-
}
|
|
267
|
-
} catch (e) {
|
|
268
|
-
console.error(`[Titan] Failed to create titan binary: ${e.message}`);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
257
|
+
const destBin = path.join(buildDir, binName);
|
|
258
|
+
fs.copyFileSync(engineBin, destBin);
|
|
259
|
+
if (process.platform !== "win32") fs.chmodSync(destBin, 0o755);
|
|
271
260
|
}
|
|
272
261
|
|
|
262
|
+
// Step 10: In production builds, we DON'T use symlinks for node_modules.
|
|
263
|
+
// Instead, the engine knows to look in .ext.
|
|
264
|
+
|
|
273
265
|
return buildDir;
|
|
274
266
|
}
|
|
275
267
|
|