titan-sdk 0.0.4 → 0.0.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/bin/run.js +25 -9
- package/package.json +9 -1
- package/templates/.dockerignore +3 -0
- package/templates/Dockerfile +53 -0
- package/templates/app/actions/hello.js +5 -0
- package/templates/app/app.js +10 -0
- package/templates/app/titan.d.ts +87 -0
- package/templates/jsconfig.json +19 -0
- package/templates/server/Cargo.lock +2839 -0
- package/templates/server/Cargo.toml +27 -0
- package/templates/server/src/action_management.rs +131 -0
- package/templates/server/src/errors.rs +10 -0
- package/templates/server/src/extensions.rs +640 -0
- package/templates/server/src/main.rs +345 -0
- package/templates/server/src/utils.rs +33 -0
- package/templates/titan/bundle.js +65 -0
- package/templates/titan/dev.js +110 -0
- package/templates/titan/titan.js +82 -0
package/bin/run.js
CHANGED
|
@@ -13,6 +13,19 @@ const green = (t) => `\x1b[32m${t}\x1b[0m`;
|
|
|
13
13
|
const red = (t) => `\x1b[31m${t}\x1b[0m`;
|
|
14
14
|
const yellow = (t) => `\x1b[33m${t}\x1b[0m`;
|
|
15
15
|
|
|
16
|
+
function copyDir(src, dest) {
|
|
17
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
18
|
+
for (const file of fs.readdirSync(src)) {
|
|
19
|
+
const srcPath = path.join(src, file);
|
|
20
|
+
const destPath = path.join(dest, file);
|
|
21
|
+
if (fs.lstatSync(srcPath).isDirectory()) {
|
|
22
|
+
copyDir(srcPath, destPath);
|
|
23
|
+
} else {
|
|
24
|
+
fs.copyFileSync(srcPath, destPath);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
16
29
|
function run() {
|
|
17
30
|
console.log(cyan("Titan SDK: Test Runner"));
|
|
18
31
|
|
|
@@ -56,19 +69,24 @@ function run() {
|
|
|
56
69
|
fs.mkdirSync(actionsDir);
|
|
57
70
|
|
|
58
71
|
// Copy titan/ and server/ from templates
|
|
59
|
-
const
|
|
60
|
-
const templatesDir = path.join(repoRoot, "templates");
|
|
72
|
+
const templatesDir = path.join(__dirname, "..", "templates");
|
|
61
73
|
|
|
62
74
|
const titanSrc = path.join(templatesDir, "titan");
|
|
63
75
|
const titanDest = path.join(runDir, "titan");
|
|
64
76
|
if (fs.existsSync(titanSrc)) {
|
|
65
|
-
|
|
77
|
+
copyDir(titanSrc, titanDest);
|
|
78
|
+
} else {
|
|
79
|
+
console.log(red(`Error: Titan templates not found at ${titanSrc}`));
|
|
80
|
+
process.exit(1);
|
|
66
81
|
}
|
|
67
82
|
|
|
68
83
|
const serverSrc = path.join(templatesDir, "server");
|
|
69
84
|
const serverDest = path.join(runDir, "server");
|
|
70
85
|
if (fs.existsSync(serverSrc)) {
|
|
71
|
-
|
|
86
|
+
copyDir(serverSrc, serverDest);
|
|
87
|
+
} else {
|
|
88
|
+
console.log(red(`Error: Server templates not found at ${serverSrc}`));
|
|
89
|
+
process.exit(1);
|
|
72
90
|
}
|
|
73
91
|
|
|
74
92
|
// Create package.json for the test harness
|
|
@@ -89,7 +107,7 @@ function run() {
|
|
|
89
107
|
} catch (e) {
|
|
90
108
|
// Fallback to copy if link fails
|
|
91
109
|
console.log(yellow("Linking failed, copying extension files..."));
|
|
92
|
-
|
|
110
|
+
copyDir(cwd, extDest);
|
|
93
111
|
}
|
|
94
112
|
|
|
95
113
|
// Create a test action in app/actions/test.js
|
|
@@ -138,7 +156,6 @@ console.log("---------------------------------------------------");
|
|
|
138
156
|
|
|
139
157
|
if (!ext) {
|
|
140
158
|
console.log("ERROR: Extension '${name}' not found in global 't'.");
|
|
141
|
-
console.log("Make sure your extension's package.json has 'type': 'commonjs'");
|
|
142
159
|
} else {
|
|
143
160
|
console.log("✓ Extension loaded successfully!");
|
|
144
161
|
console.log("✓ Available methods:", Object.keys(ext).join(", "));
|
|
@@ -177,7 +194,7 @@ console.log("---------------------------------------------------\\n");
|
|
|
177
194
|
t.get("/test").action("test");
|
|
178
195
|
t.get("/").reply("🚀 Extension Test Harness for ${name}\\n\\nVisit /test to see extension test results");
|
|
179
196
|
|
|
180
|
-
t.start(3000, "Titan Extension Test Running!");
|
|
197
|
+
await t.start(3000, "Titan Extension Test Running!");
|
|
181
198
|
`;
|
|
182
199
|
|
|
183
200
|
fs.writeFileSync(path.join(appDir, "app.js"), testScript);
|
|
@@ -188,11 +205,10 @@ t.start(3000, "Titan Extension Test Running!");
|
|
|
188
205
|
execSync("node app/app.js --build", { cwd: runDir, stdio: "inherit" });
|
|
189
206
|
} catch (e) {
|
|
190
207
|
console.log(red("Failed to build test app."));
|
|
191
|
-
console.log(yellow("This is expected if your extension has errors."));
|
|
192
208
|
}
|
|
193
209
|
|
|
194
210
|
// 4. Run Titan Server using cargo run (like dev mode)
|
|
195
|
-
console.log(
|
|
211
|
+
console.log(green("\x1b[1m\n>>> STARTING EXTENSION TEST >>>\n\x1b[0m"));
|
|
196
212
|
|
|
197
213
|
const serverDir = path.join(runDir, "server");
|
|
198
214
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "titan-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
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",
|
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
"bin": {
|
|
9
9
|
"titan-sdk": "./bin/run.js"
|
|
10
10
|
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"templates/",
|
|
14
|
+
"titan",
|
|
15
|
+
"index.js",
|
|
16
|
+
"index.d.ts",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
11
19
|
"keywords": [
|
|
12
20
|
"titan",
|
|
13
21
|
"titan-planet",
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# ================================================================
|
|
2
|
+
# STAGE 1 — Build Titan (JS → Rust)
|
|
3
|
+
# ================================================================
|
|
4
|
+
FROM rust:1.91.1 AS builder
|
|
5
|
+
|
|
6
|
+
# Install Node for Titan CLI + bundler
|
|
7
|
+
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
|
8
|
+
&& apt-get install -y nodejs
|
|
9
|
+
|
|
10
|
+
# Install Titan CLI (latest)
|
|
11
|
+
RUN npm install -g @ezetgalaxy/titan@latest
|
|
12
|
+
|
|
13
|
+
WORKDIR /app
|
|
14
|
+
|
|
15
|
+
# Copy project files
|
|
16
|
+
COPY . .
|
|
17
|
+
|
|
18
|
+
# Install JS dependencies (needed for Titan DSL + bundler)
|
|
19
|
+
RUN npm install
|
|
20
|
+
|
|
21
|
+
# Build Titan metadata + bundle JS actions
|
|
22
|
+
RUN titan build
|
|
23
|
+
|
|
24
|
+
# Build Rust binary
|
|
25
|
+
RUN cd server && cargo build --release
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# ================================================================
|
|
30
|
+
# STAGE 2 — Runtime Image (Lightweight)
|
|
31
|
+
# ================================================================
|
|
32
|
+
FROM debian:stable-slim
|
|
33
|
+
|
|
34
|
+
WORKDIR /app
|
|
35
|
+
|
|
36
|
+
# Copy Rust binary from builder stage
|
|
37
|
+
COPY --from=builder /app/server/target/release/server ./titan-server
|
|
38
|
+
|
|
39
|
+
# Copy Titan routing metadata
|
|
40
|
+
COPY --from=builder /app/server/routes.json ./routes.json
|
|
41
|
+
COPY --from=builder /app/server/action_map.json ./action_map.json
|
|
42
|
+
|
|
43
|
+
# Copy Titan JS bundles
|
|
44
|
+
RUN mkdir -p /app/actions
|
|
45
|
+
COPY --from=builder /app/server/actions /app/actions
|
|
46
|
+
|
|
47
|
+
COPY --from=builder /app/db /app/assets
|
|
48
|
+
|
|
49
|
+
# Expose Titan port
|
|
50
|
+
EXPOSE 3000
|
|
51
|
+
|
|
52
|
+
# Start Titan
|
|
53
|
+
CMD ["./titan-server"]
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TITAN TYPE DEFINITIONS
|
|
3
|
+
* ----------------------
|
|
4
|
+
* These types are globally available in your Titan project.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The Titan Request Object passed to actions.
|
|
9
|
+
*/
|
|
10
|
+
interface TitanRequest {
|
|
11
|
+
body: any;
|
|
12
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
13
|
+
path: string;
|
|
14
|
+
headers: {
|
|
15
|
+
host?: string;
|
|
16
|
+
"content-type"?: string;
|
|
17
|
+
"user-agent"?: string;
|
|
18
|
+
authorization?: string;
|
|
19
|
+
[key: string]: string | undefined;
|
|
20
|
+
};
|
|
21
|
+
params: Record<string, string>;
|
|
22
|
+
query: Record<string, string>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface DbConnection {
|
|
26
|
+
/**
|
|
27
|
+
* Execute a SQL query.
|
|
28
|
+
* @param sql The SQL query string.
|
|
29
|
+
* @param params (Optional) Parameters for the query ($1, $2, etc).
|
|
30
|
+
*/
|
|
31
|
+
query(sql: string, params?: any[]): any[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Define a Titan Action with type inference.
|
|
36
|
+
* @example
|
|
37
|
+
* export const hello = defineAction((req) => {
|
|
38
|
+
* return req.headers;
|
|
39
|
+
* });
|
|
40
|
+
*/
|
|
41
|
+
declare function defineAction<T>(actionFn: (req: TitanRequest) => T): (req: TitanRequest) => T;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Titan Runtime Utilities
|
|
45
|
+
*/
|
|
46
|
+
declare const t: {
|
|
47
|
+
/**
|
|
48
|
+
* Log messages to the server console with Titan formatting.
|
|
49
|
+
*/
|
|
50
|
+
log(...args: any[]): void;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Read a file contents as string.
|
|
54
|
+
* @param path Relative path to the file from project root.
|
|
55
|
+
*/
|
|
56
|
+
read(path: string): string;
|
|
57
|
+
|
|
58
|
+
fetch(url: string, options?: {
|
|
59
|
+
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
60
|
+
headers?: Record<string, string>;
|
|
61
|
+
body?: string | object;
|
|
62
|
+
}): {
|
|
63
|
+
ok: boolean;
|
|
64
|
+
status?: number;
|
|
65
|
+
body?: string;
|
|
66
|
+
error?: string;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
jwt: {
|
|
70
|
+
sign(
|
|
71
|
+
payload: object,
|
|
72
|
+
secret: string,
|
|
73
|
+
options?: { expiresIn?: string | number }
|
|
74
|
+
): string;
|
|
75
|
+
verify(token: string, secret: string): any;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
password: {
|
|
79
|
+
hash(password: string): string;
|
|
80
|
+
verify(password: string, hash: string): boolean;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
db: {
|
|
84
|
+
connect(url: string): DbConnection;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "esnext",
|
|
4
|
+
"target": "esnext",
|
|
5
|
+
"checkJs": false,
|
|
6
|
+
"noImplicitAny": false,
|
|
7
|
+
"allowJs": true,
|
|
8
|
+
"moduleResolution": "node",
|
|
9
|
+
"baseUrl": ".",
|
|
10
|
+
"paths": {
|
|
11
|
+
"*": [
|
|
12
|
+
"./app/*"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"include": [
|
|
17
|
+
"app/**/*"
|
|
18
|
+
]
|
|
19
|
+
}
|