titanpl-sdk 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/run.js +51 -34
- package/package.json +1 -1
package/bin/run.js
CHANGED
|
@@ -14,29 +14,46 @@ const red = (t) => `\x1b[31m${t}\x1b[0m`;
|
|
|
14
14
|
const yellow = (t) => `\x1b[33m${t}\x1b[0m`;
|
|
15
15
|
|
|
16
16
|
function copyDir(src, dest, excludes = []) {
|
|
17
|
+
// console.log(`DEBUG: copyDir ${src} -> ${dest}`);
|
|
18
|
+
if (!fs.existsSync(src)) {
|
|
19
|
+
console.log(red(`Source does not exist: ${src}`));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
fs.mkdirSync(dest, { recursive: true });
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
|
|
25
|
+
const files = fs.readdirSync(src);
|
|
26
|
+
// console.log(`DEBUG: Found ${files.length} files in ${src}`);
|
|
27
|
+
|
|
28
|
+
for (const file of files) {
|
|
29
|
+
if (excludes.includes(file)) {
|
|
30
|
+
// console.log(`DEBUG: Skipping excluded ${file}`);
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
20
33
|
|
|
21
34
|
const srcPath = path.join(src, file);
|
|
22
35
|
const destPath = path.join(dest, file);
|
|
23
36
|
|
|
24
|
-
// Prevent copying destination into itself (infinite loop protection)
|
|
25
|
-
if (path.resolve(destPath).startsWith(path.resolve(dest))) continue;
|
|
26
|
-
|
|
27
37
|
if (fs.lstatSync(srcPath).isDirectory()) {
|
|
28
38
|
copyDir(srcPath, destPath, excludes);
|
|
29
39
|
} else {
|
|
30
|
-
|
|
40
|
+
// console.log(`DEBUG: Copying file ${file}`);
|
|
41
|
+
try {
|
|
42
|
+
fs.copyFileSync(srcPath, destPath);
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.log(red(`ERROR: Failed to copy ${file}: ${err.message}`));
|
|
45
|
+
}
|
|
31
46
|
}
|
|
32
47
|
}
|
|
33
48
|
}
|
|
34
49
|
|
|
35
50
|
function run() {
|
|
36
|
-
console.log(cyan("
|
|
51
|
+
console.log(cyan("TitanPl SDK: Test Runner"));
|
|
37
52
|
|
|
38
53
|
// 1. Validate we are in an extension directory
|
|
39
54
|
const cwd = process.cwd();
|
|
55
|
+
console.log(cyan(`Current Working Directory: ${cwd}`));
|
|
56
|
+
|
|
40
57
|
const manifestPath = path.join(cwd, "titan.json");
|
|
41
58
|
if (!fs.existsSync(manifestPath)) {
|
|
42
59
|
console.log(red("Error: titan.json not found. Run this command inside your extension folder."));
|
|
@@ -59,8 +76,13 @@ function run() {
|
|
|
59
76
|
}
|
|
60
77
|
}
|
|
61
78
|
|
|
79
|
+
// 3. Setup Test Harness (Mini Titan Project)
|
|
62
80
|
// 3. Setup Test Harness (Mini Titan Project)
|
|
63
81
|
const runDir = path.join(cwd, ".titan_test_run");
|
|
82
|
+
const appDir = path.join(runDir, "app");
|
|
83
|
+
const actionsDir = path.join(appDir, "actions");
|
|
84
|
+
const nmDir = path.join(runDir, "node_modules");
|
|
85
|
+
|
|
64
86
|
const isFirstRun = !fs.existsSync(runDir);
|
|
65
87
|
|
|
66
88
|
if (isFirstRun) {
|
|
@@ -68,24 +90,22 @@ function run() {
|
|
|
68
90
|
fs.mkdirSync(runDir, { recursive: true });
|
|
69
91
|
|
|
70
92
|
// Create app structure
|
|
71
|
-
const appDir = path.join(runDir, "app");
|
|
72
93
|
fs.mkdirSync(appDir);
|
|
73
94
|
|
|
74
95
|
// Create actions folder (required by Titan build)
|
|
75
|
-
const actionsDir = path.join(appDir, "actions");
|
|
76
96
|
fs.mkdirSync(actionsDir);
|
|
77
97
|
|
|
78
98
|
// Copy titan/ and server/ from templates
|
|
79
99
|
const templatesDir = path.join(__dirname, "..", "templates");
|
|
100
|
+
console.log(cyan(`Templates Source: ${templatesDir}`));
|
|
80
101
|
|
|
81
102
|
const titanSrc = path.join(templatesDir, "titan");
|
|
82
103
|
const titanDest = path.join(runDir, "titan");
|
|
104
|
+
|
|
83
105
|
if (fs.existsSync(titanSrc)) {
|
|
84
106
|
copyDir(titanSrc, titanDest);
|
|
85
|
-
// Double check titan.js exists
|
|
86
107
|
if (!fs.existsSync(path.join(titanDest, "titan.js"))) {
|
|
87
|
-
|
|
88
|
-
process.exit(1);
|
|
108
|
+
throw new Error("Failed to copy titan.js template");
|
|
89
109
|
}
|
|
90
110
|
} else {
|
|
91
111
|
console.log(red(`Error: Titan templates not found at ${titanSrc}`));
|
|
@@ -103,41 +123,33 @@ function run() {
|
|
|
103
123
|
|
|
104
124
|
// Create package.json for the test harness
|
|
105
125
|
const pkgJson = {
|
|
106
|
-
"type": "module"
|
|
126
|
+
"type": "module",
|
|
127
|
+
"dependencies": {
|
|
128
|
+
// We can add dependencies here if needed
|
|
129
|
+
}
|
|
107
130
|
};
|
|
108
131
|
fs.writeFileSync(path.join(runDir, "package.json"), JSON.stringify(pkgJson, null, 2));
|
|
109
132
|
|
|
110
133
|
// Create 'node_modules'
|
|
111
|
-
|
|
134
|
+
// const nmDir = path.join(runDir, "node_modules"); // Already defined
|
|
135
|
+
fs.mkdirSync(nmDir);
|
|
112
136
|
} else {
|
|
113
137
|
console.log(cyan("Using existing test environment..."));
|
|
114
138
|
}
|
|
115
139
|
|
|
116
|
-
//
|
|
117
|
-
const nmDir = path.join(runDir, "node_modules");
|
|
140
|
+
// const nmDir = path.join(runDir, "node_modules"); // Already defined
|
|
118
141
|
if (!fs.existsSync(nmDir)) fs.mkdirSync(nmDir, { recursive: true });
|
|
119
142
|
|
|
143
|
+
// COPY Extension to node_modules/NAME (Force Copy to avoid Symlink Loops)
|
|
120
144
|
const extDest = path.join(nmDir, name);
|
|
145
|
+
console.log(cyan(`Copying extension to ${extDest}...`));
|
|
121
146
|
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
fs.rmSync(extDest, { recursive: true, force: true });
|
|
126
|
-
} catch (e) { }
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Link current extension to node_modules/NAME
|
|
130
|
-
try {
|
|
131
|
-
// Use junction for Windows compat without admin rights
|
|
132
|
-
fs.symlinkSync(cwd, extDest, "junction");
|
|
133
|
-
} catch (e) {
|
|
134
|
-
// Fallback to copy if link fails
|
|
135
|
-
// console.log(yellow("Linking failed, copying extension files..."));
|
|
136
|
-
copyDir(cwd, extDest, ['.titan_test_run', 'node_modules', '.git', 'target']);
|
|
137
|
-
}
|
|
147
|
+
// Always exclude the test run folder itself + standard ignores
|
|
148
|
+
const excludes = ['.titan_test_run', 'node_modules', '.git', 'target', 'dist'];
|
|
149
|
+
copyDir(cwd, extDest, excludes);
|
|
138
150
|
|
|
139
151
|
// Create default test files ONLY if they don't exist
|
|
140
|
-
const actionsDir = path.join(runDir, "app", "actions");
|
|
152
|
+
// const actionsDir = path.join(runDir, "app", "actions"); // Already defined
|
|
141
153
|
const testActionPath = path.join(actionsDir, "test.js");
|
|
142
154
|
|
|
143
155
|
if (!fs.existsSync(testActionPath)) {
|
|
@@ -176,7 +188,12 @@ function run() {
|
|
|
176
188
|
const appJsPath = path.join(runDir, "app", "app.js");
|
|
177
189
|
if (!fs.existsSync(appJsPath)) {
|
|
178
190
|
const testScript = `import t from "../titan/titan.js";
|
|
179
|
-
|
|
191
|
+
|
|
192
|
+
// 1. Expose 't' globally because extensions expect it (like in the real runtime)
|
|
193
|
+
globalThis.t = t;
|
|
194
|
+
|
|
195
|
+
// 2. Dynamic import ensures 't' is set BEFORE the extension loads
|
|
196
|
+
await import("${name}");
|
|
180
197
|
|
|
181
198
|
// Extension test harness for: ${name}
|
|
182
199
|
const ext = t["${name}"];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "titanpl-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
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",
|