@ezetgalaxy/titan 26.8.3 → 26.9.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.
Files changed (97) hide show
  1. package/README.md +63 -14
  2. package/index.js +62 -15
  3. package/package.json +1 -1
  4. package/templates/extension/README.md +104 -104
  5. package/templates/extension/index.js +27 -27
  6. package/templates/extension/jsconfig.json +12 -12
  7. package/templates/extension/native/Cargo.toml +9 -9
  8. package/templates/extension/native/src/lib.rs +5 -5
  9. package/templates/extension/package.json +20 -20
  10. package/templates/extension/titan.json +17 -17
  11. package/templates/js/Dockerfile +66 -66
  12. package/templates/js/_dockerignore +3 -3
  13. package/templates/js/_gitignore +1 -0
  14. package/templates/js/app/actions/hello.js +5 -5
  15. package/templates/js/app/titan.d.ts +87 -87
  16. package/templates/js/jsconfig.json +18 -18
  17. package/templates/js/server/src/action_management.rs +131 -131
  18. package/templates/js/server/src/errors.rs +10 -10
  19. package/templates/js/server/src/extensions.rs +989 -989
  20. package/templates/js/server/src/utils.rs +33 -33
  21. package/templates/js/titan/bundle.js +78 -78
  22. package/templates/js/titan/dev.js +9 -1
  23. package/templates/js/titan/titan.js +122 -122
  24. package/templates/rust/Dockerfile +66 -66
  25. package/templates/rust/_dockerignore +3 -3
  26. package/templates/rust/_gitignore +1 -0
  27. package/templates/rust/app/actions/hello.js +5 -5
  28. package/templates/rust/app/actions/rust_hello.rs +14 -14
  29. package/templates/rust/app/titan.d.ts +101 -101
  30. package/templates/rust/jsconfig.json +18 -18
  31. package/templates/rust/server/src/action_management.rs +131 -131
  32. package/templates/rust/server/src/errors.rs +10 -10
  33. package/templates/rust/server/src/extensions.rs +989 -989
  34. package/templates/rust/server/src/utils.rs +33 -33
  35. package/templates/rust/titan/dev.js +9 -1
  36. package/templates/rust-ts/Dockerfile +66 -0
  37. package/templates/rust-ts/_dockerignore +3 -0
  38. package/templates/rust-ts/_gitignore +38 -0
  39. package/templates/rust-ts/app/actions/hello.ts +5 -0
  40. package/templates/rust-ts/app/actions/rust_hello.rs +14 -0
  41. package/templates/rust-ts/app/app.ts +11 -0
  42. package/templates/rust-ts/app/titan.d.ts +101 -0
  43. package/templates/rust-ts/package.json +14 -0
  44. package/templates/rust-ts/server/Cargo.lock +2869 -0
  45. package/templates/rust-ts/server/Cargo.toml +39 -0
  46. package/templates/rust-ts/server/src/action_management.rs +131 -0
  47. package/templates/rust-ts/server/src/errors.rs +51 -0
  48. package/templates/rust-ts/server/src/extensions.rs +989 -0
  49. package/templates/rust-ts/server/src/main.rs +468 -0
  50. package/templates/rust-ts/server/src/utils.rs +33 -0
  51. package/templates/rust-ts/titan/bundle.js +157 -0
  52. package/templates/rust-ts/titan/dev.js +402 -0
  53. package/templates/rust-ts/titan/titan.js +122 -0
  54. package/templates/rust-ts/tsconfig.json +21 -0
  55. package/templates/ts/Dockerfile +66 -0
  56. package/templates/ts/_dockerignore +3 -0
  57. package/templates/ts/_gitignore +38 -0
  58. package/templates/ts/app/actions/hello.ts +9 -0
  59. package/templates/ts/app/app.ts +10 -0
  60. package/templates/ts/app/titan.d.ts +102 -0
  61. package/templates/ts/package.json +26 -0
  62. package/templates/ts/server/Cargo.lock +2869 -0
  63. package/templates/ts/server/Cargo.toml +27 -0
  64. package/templates/ts/server/src/action_management.rs +131 -0
  65. package/templates/ts/server/src/errors.rs +51 -0
  66. package/templates/ts/server/src/extensions.rs +989 -0
  67. package/templates/ts/server/src/main.rs +437 -0
  68. package/templates/ts/server/src/utils.rs +33 -0
  69. package/templates/ts/titan/bundle.js +78 -0
  70. package/templates/ts/titan/dev.js +402 -0
  71. package/templates/ts/titan/titan.js +122 -0
  72. package/templates/ts/tsconfig.json +16 -0
  73. package/titanpl-sdk/README.md +109 -109
  74. package/titanpl-sdk/bin/run.js +254 -254
  75. package/titanpl-sdk/index.d.ts +46 -46
  76. package/titanpl-sdk/index.js +5 -5
  77. package/titanpl-sdk/package.json +32 -32
  78. package/titanpl-sdk/templates/.dockerignore +3 -3
  79. package/titanpl-sdk/templates/Dockerfile +53 -53
  80. package/titanpl-sdk/templates/app/actions/hello.js +5 -5
  81. package/titanpl-sdk/templates/app/titan.d.ts +87 -87
  82. package/titanpl-sdk/templates/jsconfig.json +18 -18
  83. package/titanpl-sdk/templates/server/src/action_management.rs +131 -131
  84. package/titanpl-sdk/templates/server/src/errors.rs +10 -10
  85. package/titanpl-sdk/templates/server/src/extensions.rs +640 -640
  86. package/titanpl-sdk/templates/server/src/utils.rs +33 -33
  87. package/titanpl-sdk/templates/titan/bundle.js +65 -65
  88. package/titanpl-sdk/templates/titan/dev.js +113 -113
  89. package/titanpl-sdk/templates/titan/titan.js +98 -98
  90. package/templates/js/server/action_map.json +0 -3
  91. package/templates/js/server/actions/hello.jsbundle +0 -48
  92. package/templates/js/server/routes.json +0 -16
  93. package/templates/rust/server/action_map.json +0 -3
  94. package/templates/rust/server/actions/hello.jsbundle +0 -47
  95. package/templates/rust/server/routes.json +0 -22
  96. package/templates/rust/server/src/actions_rust/mod.rs +0 -19
  97. package/templates/rust/server/src/actions_rust/rust_hello.rs +0 -14
@@ -1,101 +1,101 @@
1
- export { };
2
-
3
- declare global {
4
- /**
5
- * TITAN TYPE DEFINITIONS
6
- * ----------------------
7
- * These types are globally available in your Titan project.
8
- */
9
-
10
- /**
11
- * The Titan Request Object passed to actions.
12
- */
13
- interface TitanRequest {
14
- body: any;
15
- method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
16
- path: string;
17
- headers: {
18
- host?: string;
19
- "content-type"?: string;
20
- "user-agent"?: string;
21
- authorization?: string;
22
- [key: string]: string | undefined;
23
- };
24
- params: Record<string, string>;
25
- query: Record<string, string>;
26
- }
27
-
28
- interface DbConnection {
29
- /**
30
- * Execute a SQL query.
31
- * @param sql The SQL query string.
32
- * @param params (Optional) Parameters for the query ($1, $2, etc).
33
- */
34
- query(sql: string, params?: any[]): any[];
35
- }
36
-
37
- /**
38
- * Define a Titan Action with type inference.
39
- * @example
40
- * export const hello = defineAction((req) => {
41
- * return req.headers;
42
- * });
43
- */
44
- function defineAction<T>(actionFn: (req: TitanRequest) => T): (req: TitanRequest) => T;
45
-
46
- /**
47
- * Titan Runtime Utilities
48
- */
49
- const t: {
50
- /**
51
- * Log messages to the server console with Titan formatting.
52
- */
53
- log(...args: any[]): void;
54
-
55
- /**
56
- * Read a file contents as string.
57
- * @param path Relative path to the file from project root.
58
- */
59
- read(path: string): string;
60
-
61
- fetch(url: string, options?: {
62
- method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
63
- headers?: Record<string, string>;
64
- body?: string | object;
65
- }): {
66
- ok: boolean;
67
- status?: number;
68
- body?: string;
69
- error?: string;
70
- };
71
-
72
- jwt: {
73
- sign(
74
- payload: object,
75
- secret: string,
76
- options?: { expiresIn?: string | number }
77
- ): string;
78
- verify(token: string, secret: string): any;
79
- };
80
-
81
- password: {
82
- hash(password: string): string;
83
- verify(password: string, hash: string): boolean;
84
- };
85
-
86
- db: {
87
- connect(url: string): DbConnection;
88
- };
89
-
90
- /**
91
- * Titan Validator (Zod-compatible)
92
- */
93
- valid: typeof import("@titanpl/valid");
94
- };
95
-
96
- /**
97
- * Global Request Object
98
- * Available automatically in actions.
99
- */
100
- var req: TitanRequest;
101
- }
1
+ export { };
2
+
3
+ declare global {
4
+ /**
5
+ * TITAN TYPE DEFINITIONS
6
+ * ----------------------
7
+ * These types are globally available in your Titan project.
8
+ */
9
+
10
+ /**
11
+ * The Titan Request Object passed to actions.
12
+ */
13
+ interface TitanRequest {
14
+ body: any;
15
+ method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
16
+ path: string;
17
+ headers: {
18
+ host?: string;
19
+ "content-type"?: string;
20
+ "user-agent"?: string;
21
+ authorization?: string;
22
+ [key: string]: string | undefined;
23
+ };
24
+ params: Record<string, string>;
25
+ query: Record<string, string>;
26
+ }
27
+
28
+ interface DbConnection {
29
+ /**
30
+ * Execute a SQL query.
31
+ * @param sql The SQL query string.
32
+ * @param params (Optional) Parameters for the query ($1, $2, etc).
33
+ */
34
+ query(sql: string, params?: any[]): any[];
35
+ }
36
+
37
+ /**
38
+ * Define a Titan Action with type inference.
39
+ * @example
40
+ * export const hello = defineAction((req) => {
41
+ * return req.headers;
42
+ * });
43
+ */
44
+ function defineAction<T>(actionFn: (req: TitanRequest) => T): (req: TitanRequest) => T;
45
+
46
+ /**
47
+ * Titan Runtime Utilities
48
+ */
49
+ const t: {
50
+ /**
51
+ * Log messages to the server console with Titan formatting.
52
+ */
53
+ log(...args: any[]): void;
54
+
55
+ /**
56
+ * Read a file contents as string.
57
+ * @param path Relative path to the file from project root.
58
+ */
59
+ read(path: string): string;
60
+
61
+ fetch(url: string, options?: {
62
+ method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
63
+ headers?: Record<string, string>;
64
+ body?: string | object;
65
+ }): {
66
+ ok: boolean;
67
+ status?: number;
68
+ body?: string;
69
+ error?: string;
70
+ };
71
+
72
+ jwt: {
73
+ sign(
74
+ payload: object,
75
+ secret: string,
76
+ options?: { expiresIn?: string | number }
77
+ ): string;
78
+ verify(token: string, secret: string): any;
79
+ };
80
+
81
+ password: {
82
+ hash(password: string): string;
83
+ verify(password: string, hash: string): boolean;
84
+ };
85
+
86
+ db: {
87
+ connect(url: string): DbConnection;
88
+ };
89
+
90
+ /**
91
+ * Titan Validator (Zod-compatible)
92
+ */
93
+ valid: typeof import("@titanpl/valid");
94
+ };
95
+
96
+ /**
97
+ * Global Request Object
98
+ * Available automatically in actions.
99
+ */
100
+ var req: TitanRequest;
101
+ }
@@ -1,19 +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
- ]
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
19
  }
@@ -1,131 +1,131 @@
1
- use std::collections::HashMap;
2
- use std::env;
3
- use std::path::{Path, PathBuf};
4
- use serde::Deserialize;
5
- use serde_json::Value;
6
-
7
- /// Route configuration (loaded from routes.json)
8
- #[derive(Debug, Deserialize, Clone)]
9
- pub struct RouteVal {
10
- pub r#type: String,
11
- pub value: Value,
12
- }
13
-
14
- #[derive(Debug, Deserialize, Clone)]
15
- pub struct DynamicRoute {
16
- pub method: String,
17
- pub pattern: String,
18
- pub action: String,
19
- }
20
-
21
- // -------------------------
22
- // ACTION DIRECTORY RESOLUTION
23
- // -------------------------
24
-
25
- pub fn resolve_actions_dir() -> PathBuf {
26
- // Respect explicit override first
27
- if let Ok(override_dir) = env::var("TITAN_ACTIONS_DIR") {
28
- return PathBuf::from(override_dir);
29
- }
30
-
31
- // Production container layout
32
- if Path::new("/app/actions").exists() {
33
- return PathBuf::from("/app/actions");
34
- }
35
-
36
- // Try to walk up from the executing binary to discover `<...>/server/actions`
37
- if let Ok(exe) = std::env::current_exe() {
38
- if let Some(parent) = exe.parent() {
39
- if let Some(target_dir) = parent.parent() {
40
- if let Some(server_dir) = target_dir.parent() {
41
- let candidate = server_dir.join("actions");
42
- if candidate.exists() {
43
- return candidate;
44
- }
45
- }
46
- }
47
- }
48
- }
49
-
50
- // Fall back to local ./actions
51
- PathBuf::from("./actions")
52
- }
53
-
54
- /// Try to find the directory that contains compiled action bundles.
55
- pub fn find_actions_dir(project_root: &PathBuf) -> Option<PathBuf> {
56
- let candidates = [
57
- project_root.join("server").join("actions"),
58
- project_root.join("actions"),
59
- project_root.join("..").join("server").join("actions"),
60
- PathBuf::from("/app").join("actions"),
61
- PathBuf::from("actions"),
62
- ];
63
-
64
- for p in &candidates {
65
- if p.exists() && p.is_dir() {
66
- return Some(p.clone());
67
- }
68
- }
69
-
70
- None
71
- }
72
-
73
- // Dynamic Matcher (Core Logic)
74
-
75
- pub fn match_dynamic_route(
76
- method: &str,
77
- path: &str,
78
- routes: &[DynamicRoute],
79
- ) -> Option<(String, HashMap<String, String>)> {
80
- let path_segments: Vec<&str> =
81
- path.trim_matches('/').split('/').collect();
82
-
83
- for route in routes {
84
- if route.method != method {
85
- continue;
86
- }
87
-
88
- let pattern_segments: Vec<&str> =
89
- route.pattern.trim_matches('/').split('/').collect();
90
-
91
- if pattern_segments.len() != path_segments.len() {
92
- continue;
93
- }
94
-
95
- let mut params = HashMap::new();
96
- let mut matched = true;
97
-
98
- for (pat, val) in pattern_segments.iter().zip(path_segments.iter()) {
99
- if pat.starts_with(':') {
100
- let inner = &pat[1..];
101
-
102
- let (name, ty) = inner
103
- .split_once('<')
104
- .map(|(n, t)| (n, t.trim_end_matches('>')))
105
- .unwrap_or((inner, "string"));
106
-
107
- let valid = match ty {
108
- "number" => val.parse::<i64>().is_ok(),
109
- "string" => true,
110
- _ => false,
111
- };
112
-
113
- if !valid {
114
- matched = false;
115
- break;
116
- }
117
-
118
- params.insert(name.to_string(), (*val).to_string());
119
- } else if pat != val {
120
- matched = false;
121
- break;
122
- }
123
- }
124
-
125
- if matched {
126
- return Some((route.action.clone(), params));
127
- }
128
- }
129
-
130
- None
131
- }
1
+ use std::collections::HashMap;
2
+ use std::env;
3
+ use std::path::{Path, PathBuf};
4
+ use serde::Deserialize;
5
+ use serde_json::Value;
6
+
7
+ /// Route configuration (loaded from routes.json)
8
+ #[derive(Debug, Deserialize, Clone)]
9
+ pub struct RouteVal {
10
+ pub r#type: String,
11
+ pub value: Value,
12
+ }
13
+
14
+ #[derive(Debug, Deserialize, Clone)]
15
+ pub struct DynamicRoute {
16
+ pub method: String,
17
+ pub pattern: String,
18
+ pub action: String,
19
+ }
20
+
21
+ // -------------------------
22
+ // ACTION DIRECTORY RESOLUTION
23
+ // -------------------------
24
+
25
+ pub fn resolve_actions_dir() -> PathBuf {
26
+ // Respect explicit override first
27
+ if let Ok(override_dir) = env::var("TITAN_ACTIONS_DIR") {
28
+ return PathBuf::from(override_dir);
29
+ }
30
+
31
+ // Production container layout
32
+ if Path::new("/app/actions").exists() {
33
+ return PathBuf::from("/app/actions");
34
+ }
35
+
36
+ // Try to walk up from the executing binary to discover `<...>/server/actions`
37
+ if let Ok(exe) = std::env::current_exe() {
38
+ if let Some(parent) = exe.parent() {
39
+ if let Some(target_dir) = parent.parent() {
40
+ if let Some(server_dir) = target_dir.parent() {
41
+ let candidate = server_dir.join("actions");
42
+ if candidate.exists() {
43
+ return candidate;
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+
50
+ // Fall back to local ./actions
51
+ PathBuf::from("./actions")
52
+ }
53
+
54
+ /// Try to find the directory that contains compiled action bundles.
55
+ pub fn find_actions_dir(project_root: &PathBuf) -> Option<PathBuf> {
56
+ let candidates = [
57
+ project_root.join("server").join("actions"),
58
+ project_root.join("actions"),
59
+ project_root.join("..").join("server").join("actions"),
60
+ PathBuf::from("/app").join("actions"),
61
+ PathBuf::from("actions"),
62
+ ];
63
+
64
+ for p in &candidates {
65
+ if p.exists() && p.is_dir() {
66
+ return Some(p.clone());
67
+ }
68
+ }
69
+
70
+ None
71
+ }
72
+
73
+ // Dynamic Matcher (Core Logic)
74
+
75
+ pub fn match_dynamic_route(
76
+ method: &str,
77
+ path: &str,
78
+ routes: &[DynamicRoute],
79
+ ) -> Option<(String, HashMap<String, String>)> {
80
+ let path_segments: Vec<&str> =
81
+ path.trim_matches('/').split('/').collect();
82
+
83
+ for route in routes {
84
+ if route.method != method {
85
+ continue;
86
+ }
87
+
88
+ let pattern_segments: Vec<&str> =
89
+ route.pattern.trim_matches('/').split('/').collect();
90
+
91
+ if pattern_segments.len() != path_segments.len() {
92
+ continue;
93
+ }
94
+
95
+ let mut params = HashMap::new();
96
+ let mut matched = true;
97
+
98
+ for (pat, val) in pattern_segments.iter().zip(path_segments.iter()) {
99
+ if pat.starts_with(':') {
100
+ let inner = &pat[1..];
101
+
102
+ let (name, ty) = inner
103
+ .split_once('<')
104
+ .map(|(n, t)| (n, t.trim_end_matches('>')))
105
+ .unwrap_or((inner, "string"));
106
+
107
+ let valid = match ty {
108
+ "number" => val.parse::<i64>().is_ok(),
109
+ "string" => true,
110
+ _ => false,
111
+ };
112
+
113
+ if !valid {
114
+ matched = false;
115
+ break;
116
+ }
117
+
118
+ params.insert(name.to_string(), (*val).to_string());
119
+ } else if pat != val {
120
+ matched = false;
121
+ break;
122
+ }
123
+ }
124
+
125
+ if matched {
126
+ return Some((route.action.clone(), params));
127
+ }
128
+ }
129
+
130
+ None
131
+ }
@@ -1,10 +1,10 @@
1
- use v8::JsError;
2
-
3
- // A helper to Format v8 Errors
4
- pub fn format_js_error(err: JsError, action: &str) -> String {
5
- format!(
6
- "Action: {}\n{}",
7
- action,
8
- err.to_string()
9
- )
10
- }
1
+ use v8::JsError;
2
+
3
+ // A helper to Format v8 Errors
4
+ pub fn format_js_error(err: JsError, action: &str) -> String {
5
+ format!(
6
+ "Action: {}\n{}",
7
+ action,
8
+ err.to_string()
9
+ )
10
+ }