kastrick 1.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.
Files changed (57) hide show
  1. package/README.md +38 -0
  2. package/examples/01-hello-world/api/hello.ts +19 -0
  3. package/examples/02-users-api/README.md +39 -0
  4. package/examples/02-users-api/api/users/[id].ts +80 -0
  5. package/examples/02-users-api/api/users/index.ts +50 -0
  6. package/examples/03-configuration/README.md +39 -0
  7. package/examples/03-configuration/kastrick.config.json +22 -0
  8. package/examples/03-configuration/tsconfig.json +20 -0
  9. package/examples/README.md +48 -0
  10. package/lib/cli/compile.d.ts +5 -0
  11. package/lib/cli/compile.d.ts.map +1 -0
  12. package/lib/cli/compile.js +25 -0
  13. package/lib/cli/compile.js.map +1 -0
  14. package/lib/cli/dev.d.ts +5 -0
  15. package/lib/cli/dev.d.ts.map +1 -0
  16. package/lib/cli/dev.js +79 -0
  17. package/lib/cli/dev.js.map +1 -0
  18. package/lib/cli/index.d.ts +3 -0
  19. package/lib/cli/index.d.ts.map +1 -0
  20. package/lib/cli/index.js +63 -0
  21. package/lib/cli/index.js.map +1 -0
  22. package/lib/cli/serve.d.ts +5 -0
  23. package/lib/cli/serve.d.ts.map +1 -0
  24. package/lib/cli/serve.js +106 -0
  25. package/lib/cli/serve.js.map +1 -0
  26. package/lib/core/compiler.d.ts +29 -0
  27. package/lib/core/compiler.d.ts.map +1 -0
  28. package/lib/core/compiler.js +153 -0
  29. package/lib/core/compiler.js.map +1 -0
  30. package/lib/core/router.d.ts +31 -0
  31. package/lib/core/router.d.ts.map +1 -0
  32. package/lib/core/router.js +106 -0
  33. package/lib/core/router.js.map +1 -0
  34. package/lib/core/scanner.d.ts +29 -0
  35. package/lib/core/scanner.d.ts.map +1 -0
  36. package/lib/core/scanner.js +88 -0
  37. package/lib/core/scanner.js.map +1 -0
  38. package/lib/index.d.ts +12 -0
  39. package/lib/index.d.ts.map +1 -0
  40. package/lib/index.js +35 -0
  41. package/lib/index.js.map +1 -0
  42. package/lib/server/expressServer.d.ts +28 -0
  43. package/lib/server/expressServer.d.ts.map +1 -0
  44. package/lib/server/expressServer.js +96 -0
  45. package/lib/server/expressServer.js.map +1 -0
  46. package/package.json +34 -0
  47. package/src/cli/compile.ts +27 -0
  48. package/src/cli/dev.ts +49 -0
  49. package/src/cli/index.ts +64 -0
  50. package/src/cli/serve.ts +81 -0
  51. package/src/core/compiler.ts +147 -0
  52. package/src/core/router.ts +88 -0
  53. package/src/core/scanner.ts +72 -0
  54. package/src/index.ts +38 -0
  55. package/src/server/expressServer.ts +107 -0
  56. package/templates/tsconfig.json +20 -0
  57. package/tsconfig.json +20 -0
@@ -0,0 +1,72 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+
4
+ export interface FileInfo {
5
+ filePath: string;
6
+ relativePath: string;
7
+ name: string;
8
+ isDirectory: boolean;
9
+ }
10
+
11
+ export interface ApiFile {
12
+ path: string;
13
+ relativePath: string;
14
+ content?: string;
15
+ }
16
+
17
+ /**
18
+ * Scanner - scans the /api folder and extracts file structure
19
+ */
20
+ export class Scanner {
21
+ private apiDir: string;
22
+
23
+ constructor(rootDir: string = process.cwd()) {
24
+ this.apiDir = path.join(rootDir, "api");
25
+ }
26
+
27
+ /**
28
+ * Check if api folder exists
29
+ */
30
+ apiDirExists(): boolean {
31
+ return fs.existsSync(this.apiDir);
32
+ }
33
+
34
+ /**
35
+ * Recursively scan /api folder
36
+ */
37
+ scanApiFolder(): ApiFile[] {
38
+ if (!this.apiDirExists()) {
39
+ console.warn(`āš ļø No /api folder found at ${this.apiDir}`);
40
+ return [];
41
+ }
42
+
43
+ const files: ApiFile[] = [];
44
+ this.scanDirectory(this.apiDir, "", files);
45
+ return files;
46
+ }
47
+
48
+ private scanDirectory(dir: string, relativePrefix: string, files: ApiFile[]): void {
49
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
50
+
51
+ for (const entry of entries) {
52
+ if (entry.name.startsWith(".")) continue;
53
+
54
+ const fullPath = path.join(dir, entry.name);
55
+ const relativePath = path.join(relativePrefix, entry.name);
56
+
57
+ if (entry.isDirectory()) {
58
+ this.scanDirectory(fullPath, relativePath, files);
59
+ } else if (this.isApiFile(entry.name)) {
60
+ files.push({
61
+ path: fullPath,
62
+ relativePath: relativePath,
63
+ content: fs.readFileSync(fullPath, "utf-8"),
64
+ });
65
+ }
66
+ }
67
+ }
68
+
69
+ private isApiFile(filename: string): boolean {
70
+ return /\.(js|ts)$/.test(filename) && !filename.endsWith(".d.ts");
71
+ }
72
+ }
package/src/index.ts ADDED
@@ -0,0 +1,38 @@
1
+ // Kastrick API Logic Package
2
+ // Main entry point
3
+
4
+ export interface ApiResponse<T> {
5
+ success: boolean;
6
+ data?: T;
7
+ error?: string;
8
+ }
9
+
10
+ export class ApiHandler {
11
+ constructor(private baseUrl: string) {}
12
+
13
+ async request<T>(endpoint: string, options?: RequestInit): Promise<ApiResponse<T>> {
14
+ try {
15
+ const response = await fetch(`${this.baseUrl}${endpoint}`, options);
16
+ const data: any = await response.json();
17
+
18
+ if (!response.ok) {
19
+ return {
20
+ success: false,
21
+ error: (data?.error || 'Request failed') as string,
22
+ };
23
+ }
24
+
25
+ return {
26
+ success: true,
27
+ data: data as T,
28
+ };
29
+ } catch (error) {
30
+ return {
31
+ success: false,
32
+ error: error instanceof Error ? error.message : 'Unknown error',
33
+ };
34
+ }
35
+ }
36
+ }
37
+
38
+ export default ApiHandler;
@@ -0,0 +1,107 @@
1
+ import express from "express";
2
+ import * as path from "path";
3
+ import { ApiRoute, Router } from "../core/router";
4
+ import { ApiFile } from "../core/scanner";
5
+
6
+ /**
7
+ * Express Server - Dev server for local API testing
8
+ */
9
+ export class ExpressServer {
10
+ private app: express.Application;
11
+ private port: number;
12
+ private router: Router;
13
+ private loadedModules: Map<string, any> = new Map();
14
+
15
+ constructor(port: number = 3000) {
16
+ this.app = express();
17
+ this.port = port;
18
+ this.router = new Router();
19
+ this.setupMiddleware();
20
+ }
21
+
22
+ private setupMiddleware(): void {
23
+ this.app.use(express.json());
24
+ this.app.use(express.urlencoded({ extended: true }));
25
+
26
+ // Simple logging middleware
27
+ this.app.use((req, res, next) => {
28
+ console.log(`šŸ“” ${req.method} ${req.path}`);
29
+ next();
30
+ });
31
+ }
32
+
33
+ /**
34
+ * Register routes from API files
35
+ */
36
+ registerRoutes(files: ApiFile[]): void {
37
+ const routes = this.router.generateRoutes(files);
38
+
39
+ for (const route of routes) {
40
+ const method = route.method.toLowerCase() as keyof express.Application;
41
+ const filePath = route.file;
42
+ const content = files.find((f) => f.relativePath === filePath)?.content || "";
43
+
44
+ this.app[method](route.path, this.createHandler(filePath, route.method, content));
45
+ }
46
+
47
+ console.log(`šŸ“” Registered ${routes.length} routes`);
48
+ }
49
+
50
+ private createHandler(filePath: string, method: string, content: string) {
51
+ return async (req: express.Request, res: express.Response) => {
52
+ try {
53
+ // Parse and execute handler
54
+ const fn = this.parseHandler(content, method);
55
+ if (!fn) {
56
+ return res.status(404).json({ error: `${method} handler not found` });
57
+ }
58
+
59
+ const result = await fn(req, { params: req.params });
60
+ res.status(result.status || 200).json(result.body !== undefined ? result.body : result);
61
+ } catch (err: any) {
62
+ console.error(`āŒ Handler error in ${filePath}:`, err.message);
63
+ res.status(500).json({ error: err.message || "Internal server error" });
64
+ }
65
+ };
66
+ }
67
+
68
+ private parseHandler(content: string, method: string): any {
69
+ try {
70
+ // Extract the function from the file content
71
+ const moduleExports: any = {};
72
+
73
+ // Create a minimal module context
74
+ const module = { exports: moduleExports };
75
+ const exportFn = (key: string, fn: any) => {
76
+ moduleExports[key] = fn;
77
+ };
78
+
79
+ // Execute the file content in a controlled context
80
+ const code = `(function(exports, require, module, __filename, __dirname) { ${content} return module.exports; })`;
81
+ const fn = eval(code);
82
+ const result = fn(moduleExports, require, module, "", "");
83
+
84
+ return result[method];
85
+ } catch (err) {
86
+ console.error("Error parsing handler:", err);
87
+ return null;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Start the dev server
93
+ */
94
+ start(): void {
95
+ this.app.listen(this.port, () => {
96
+ console.log(`\nšŸš€ Kastrick dev server running on http://localhost:${this.port}\n`);
97
+ console.log(`šŸ‘€ Watching for changes in /api folder...\n`);
98
+ });
99
+ }
100
+
101
+ /**
102
+ * Get Express app instance
103
+ */
104
+ getApp(): express.Application {
105
+ return this.app;
106
+ }
107
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "types": ["node"],
7
+ "outDir": "./output",
8
+ "rootDir": "./api",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ "sourceMap": false,
16
+ "noEmit": false
17
+ },
18
+ "include": ["api"],
19
+ "exclude": ["node_modules", "output"]
20
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "types": ["node"],
7
+ "outDir": "./lib",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "resolveJsonModule": true,
14
+ "declaration": true,
15
+ "declarationMap": true,
16
+ "sourceMap": true
17
+ },
18
+ "include": ["src"],
19
+ "exclude": ["node_modules"]
20
+ }