@zintrust/core 0.1.18 → 0.1.19

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 (122) hide show
  1. package/README.md +6 -0
  2. package/package.json +10 -1
  3. package/public/index.html +1 -1
  4. package/routes/api.d.ts +7 -0
  5. package/routes/api.d.ts.map +1 -0
  6. package/routes/api.js +91 -0
  7. package/routes/broadcast.d.ts +9 -0
  8. package/routes/broadcast.d.ts.map +1 -0
  9. package/routes/broadcast.js +27 -0
  10. package/routes/health.d.ts +7 -0
  11. package/routes/health.d.ts.map +1 -0
  12. package/routes/health.js +127 -0
  13. package/routes/storage.d.ts +4 -0
  14. package/routes/storage.d.ts.map +1 -0
  15. package/routes/storage.js +35 -0
  16. package/src/boot/Application.js +1 -1
  17. package/src/boot/bootstrap.js +1 -1
  18. package/src/cli/CLI.d.ts.map +1 -1
  19. package/src/cli/CLI.js +2 -0
  20. package/src/cli/PromptHelper.d.ts.map +1 -1
  21. package/src/cli/PromptHelper.js +4 -3
  22. package/src/cli/commands/NewCommand.d.ts +1 -1
  23. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  24. package/src/cli/commands/NewCommand.js +26 -9
  25. package/src/cli/commands/SimulateCommand.js +1 -1
  26. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  27. package/src/cli/commands/StartCommand.js +90 -3
  28. package/src/cli/commands/UpgradeCommand.d.ts +16 -0
  29. package/src/cli/commands/UpgradeCommand.d.ts.map +1 -0
  30. package/src/cli/commands/UpgradeCommand.js +107 -0
  31. package/src/cli/commands/runner/index.d.ts +3 -0
  32. package/src/cli/commands/runner/index.d.ts.map +1 -0
  33. package/src/cli/commands/runner/index.js +139 -0
  34. package/src/cli/env/EnvFileBackfill.d.ts +10 -0
  35. package/src/cli/env/EnvFileBackfill.d.ts.map +1 -0
  36. package/src/cli/env/EnvFileBackfill.js +64 -0
  37. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  38. package/src/cli/scaffolding/ProjectScaffolder.js +22 -59
  39. package/src/cli/utils/DistPackager.d.ts.map +1 -1
  40. package/src/cli/utils/DistPackager.js +8 -0
  41. package/src/config/broadcast.js +1 -1
  42. package/src/config/database.d.ts +6 -0
  43. package/src/config/database.d.ts.map +1 -1
  44. package/src/config/database.js +7 -1
  45. package/src/config/index.d.ts +7 -1
  46. package/src/config/index.d.ts.map +1 -1
  47. package/src/config/middleware.d.ts +2 -1
  48. package/src/config/middleware.d.ts.map +1 -1
  49. package/src/config/middleware.js +47 -11
  50. package/src/config/notification.js +1 -1
  51. package/src/config/storage.js +1 -1
  52. package/src/config/type.d.ts +7 -1
  53. package/src/config/type.d.ts.map +1 -1
  54. package/src/index.d.ts +1 -0
  55. package/src/index.d.ts.map +1 -1
  56. package/src/middleware/RateLimiter.d.ts.map +1 -1
  57. package/src/middleware/RateLimiter.js +26 -1
  58. package/src/node.d.ts +1 -1
  59. package/src/node.d.ts.map +1 -1
  60. package/src/node.js +4 -1
  61. package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
  62. package/src/orm/DatabaseRuntimeRegistration.js +4 -0
  63. package/src/orm/QueryBuilder.d.ts.map +1 -1
  64. package/src/orm/QueryBuilder.js +7 -3
  65. package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
  66. package/src/orm/adapters/SQLiteAdapter.js +5 -1
  67. package/src/routes/api.d.ts +2 -0
  68. package/src/routes/api.d.ts.map +1 -0
  69. package/src/routes/api.js +1 -0
  70. package/src/routes/broadcast.d.ts +2 -0
  71. package/src/routes/broadcast.d.ts.map +1 -0
  72. package/src/routes/broadcast.js +1 -0
  73. package/src/routes/health.d.ts +2 -0
  74. package/src/routes/health.d.ts.map +1 -0
  75. package/src/routes/health.js +1 -0
  76. package/src/routes/storage.d.ts +2 -0
  77. package/src/routes/storage.d.ts.map +1 -0
  78. package/src/routes/storage.js +1 -0
  79. package/src/runtime/RuntimeAdapter.d.ts.map +1 -1
  80. package/src/runtime/RuntimeAdapter.js +20 -1
  81. package/src/runtime/adapters/DenoAdapter.js +2 -2
  82. package/src/scripts/TemplateImportsCheck.js +7 -7
  83. package/src/scripts/TemplateSync.js +6 -0
  84. package/src/start.d.ts +21 -0
  85. package/src/start.d.ts.map +1 -0
  86. package/src/start.js +60 -0
  87. package/src/templates/features/Queue.ts.tpl +2 -3
  88. package/src/templates/project/basic/.env.example.tpl +1 -1
  89. package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +2 -4
  90. package/src/templates/project/basic/app/Middleware/ProfilerMiddleware.ts.tpl +1 -3
  91. package/src/templates/project/basic/app/Middleware/index.ts.tpl +3 -8
  92. package/src/templates/project/basic/app/Models/Post.ts.tpl +2 -3
  93. package/src/templates/project/basic/app/Models/User.ts.tpl +1 -1
  94. package/src/templates/project/basic/config/FileLogWriter.ts.tpl +1 -1
  95. package/src/templates/project/basic/config/SecretsManager.ts.tpl +2 -2
  96. package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +2 -2
  97. package/src/templates/project/basic/config/app.ts.tpl +3 -3
  98. package/src/templates/project/basic/config/broadcast.ts.tpl +4 -5
  99. package/src/templates/project/basic/config/cache.ts.tpl +2 -3
  100. package/src/templates/project/basic/config/cloudflare.ts.tpl +1 -1
  101. package/src/templates/project/basic/config/database.ts.tpl +9 -3
  102. package/src/templates/project/basic/config/env.ts.tpl +1 -1
  103. package/src/templates/project/basic/config/features.ts.tpl +2 -2
  104. package/src/templates/project/basic/config/index.ts.tpl +38 -20
  105. package/src/templates/project/basic/config/logger.ts.tpl +5 -381
  106. package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +1 -1
  107. package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +2 -2
  108. package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +1 -1
  109. package/src/templates/project/basic/config/mail.ts.tpl +2 -3
  110. package/src/templates/project/basic/config/microservices.ts.tpl +1 -1
  111. package/src/templates/project/basic/config/middleware.ts.tpl +40 -13
  112. package/src/templates/project/basic/config/notification.ts.tpl +3 -4
  113. package/src/templates/project/basic/config/queue.ts.tpl +2 -2
  114. package/src/templates/project/basic/config/security.ts.tpl +3 -3
  115. package/src/templates/project/basic/config/startup.ts.tpl +1 -1
  116. package/src/templates/project/basic/config/storage.ts.tpl +3 -4
  117. package/src/templates/project/basic/config/type.ts.tpl +12 -2
  118. package/src/templates/project/basic/package.json.tpl +1 -1
  119. package/src/templates/project/basic/routes/api.ts.tpl +4 -4
  120. package/src/templates/project/basic/routes/health.ts.tpl +1 -6
  121. package/src/templates/project/basic/src/index.ts.tpl +7 -80
  122. package/src/templates/project/basic/tsconfig.json.tpl +0 -2
package/README.md CHANGED
@@ -21,6 +21,12 @@ zin start
21
21
 
22
22
  Your API is now running at `http://localhost:7777`
23
23
 
24
+ If you’re targeting a different runtime:
25
+
26
+ - Cloudflare Workers (Wrangler): `zin start --wg`
27
+ - AWS Lambda adapter mode: `zin start --lambda`
28
+ - Deno adapter mode: `zin start --deno`
29
+
24
30
  The canonical CLI is `zin`. `z` is a shorthand alias.
25
31
 
26
32
  ## Install adapters (database/cache/etc.)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -18,10 +18,18 @@
18
18
  "types": "./src/index.d.ts",
19
19
  "import": "./src/index.js"
20
20
  },
21
+ "./start": {
22
+ "types": "./src/start.d.ts",
23
+ "import": "./src/start.js"
24
+ },
21
25
  "./node": {
22
26
  "types": "./src/node.d.ts",
23
27
  "import": "./src/node.js"
24
28
  },
29
+ "./routes/*": {
30
+ "types": "./routes/*.d.ts",
31
+ "import": "./routes/*.js"
32
+ },
25
33
  "./package.json": "./package.json"
26
34
  },
27
35
  "dependencies": {
@@ -45,6 +53,7 @@
45
53
  "files": [
46
54
  "bin",
47
55
  "src",
56
+ "routes",
48
57
  "public"
49
58
  ],
50
59
  "engines": {
package/public/index.html CHANGED
@@ -423,7 +423,7 @@
423
423
  'zin --version',
424
424
  'zin new my-api',
425
425
  'cd my-api',
426
- 'npm run dev',
426
+ 'zin start',
427
427
  'curl http://localhost:3000/health',
428
428
  'zin debug',
429
429
  ],
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Example Routes
3
+ * Demonstrates routing patterns
4
+ */
5
+ import { type IRouter } from '../src/routing/Router';
6
+ export declare function registerRoutes(router: IRouter): void;
7
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../routes/api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,iBAAiB,CAAC;AAEvD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAKpD"}
package/routes/api.js ADDED
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Example Routes
3
+ * Demonstrates routing patterns
4
+ */
5
+ import { UserController } from '../app/Controllers/UserController.js';
6
+ import { Env } from '../src/config/env.js';
7
+ import { registerBroadcastRoutes } from './broadcast.js';
8
+ import { registerHealthRoutes } from './health.js';
9
+ import { registerStorageRoutes } from './storage.js';
10
+ import { Router } from '../src/routing/Router.js';
11
+ export function registerRoutes(router) {
12
+ const userController = UserController.create();
13
+ registerPublicRoutes(router);
14
+ registerApiV1Routes(router, userController);
15
+ registerAdminRoutes(router);
16
+ }
17
+ /**
18
+ * Register public routes
19
+ */
20
+ function registerPublicRoutes(router) {
21
+ registerRootRoute(router);
22
+ registerHealthRoutes(router);
23
+ registerBroadcastRoutes(router);
24
+ registerStorageRoutes(router);
25
+ }
26
+ function registerRootRoute(router) {
27
+ Router.get(router, '/', async (_req, res) => {
28
+ res.json({
29
+ framework: 'Zintrust Framework',
30
+ app_name: Env.APP_NAME,
31
+ version: '0.1.0',
32
+ env: Env.NODE_ENV ?? 'development',
33
+ database: Env.DB_CONNECTION ?? 'sqlite',
34
+ });
35
+ });
36
+ }
37
+ /**
38
+ * Register API V1 routes
39
+ */
40
+ function registerApiV1Routes(router, userController) {
41
+ Router.group(router, '/api/v1', (r) => {
42
+ // Auth routes
43
+ Router.post(r, '/auth/login', async (_req, res) => {
44
+ res.json({ message: 'Login endpoint' });
45
+ });
46
+ Router.post(r, '/auth/register', async (_req, res) => {
47
+ res.json({ message: 'Register endpoint' });
48
+ });
49
+ // Protected routes (middleware is not modeled in Router.ts yet)
50
+ const pr = r;
51
+ // User resource (REST-ish)
52
+ Router.resource(pr, '/users', {
53
+ index: userController.index,
54
+ store: userController.store,
55
+ show: userController.show,
56
+ update: userController.update,
57
+ destroy: userController.destroy,
58
+ });
59
+ // If the controller exposes create/edit, wire them explicitly.
60
+ Router.get(pr, '/users/create', userController.create);
61
+ Router.get(pr, '/users/:id/edit', userController.edit);
62
+ // Custom user routes
63
+ Router.get(pr, '/profile', async (_req, res) => {
64
+ res.json({ message: 'Get user profile' });
65
+ });
66
+ Router.put(pr, '/profile', async (_req, res) => {
67
+ res.json({ message: 'Update user profile' });
68
+ });
69
+ // Posts resource
70
+ Router.get(r, '/posts', async (_req, res) => {
71
+ res.json({ data: [] });
72
+ });
73
+ Router.get(r, '/posts/:id', async (req, res) => {
74
+ const id = req.getParam('id');
75
+ res.json({ data: { id } });
76
+ });
77
+ });
78
+ }
79
+ /**
80
+ * Register admin routes
81
+ */
82
+ function registerAdminRoutes(router) {
83
+ Router.group(router, '/admin', (r) => {
84
+ Router.get(r, '/dashboard', async (_req, res) => {
85
+ res.json({ message: 'Admin dashboard' });
86
+ });
87
+ Router.get(r, '/users', async (_req, res) => {
88
+ res.json({ data: [] });
89
+ });
90
+ });
91
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Broadcast Routes
3
+ *
4
+ * Runtime-only endpoints for broadcast.
5
+ * Provider setup and secret provisioning remain CLI-only.
6
+ */
7
+ import { type IRouter } from '../src/routing/Router';
8
+ export declare function registerBroadcastRoutes(router: IRouter): void;
9
+ //# sourceMappingURL=broadcast.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../routes/broadcast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,iBAAiB,CAAC;AAEvD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAsB7D"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Broadcast Routes
3
+ *
4
+ * Runtime-only endpoints for broadcast.
5
+ * Provider setup and secret provisioning remain CLI-only.
6
+ */
7
+ import { Router } from '../src/routing/Router.js';
8
+ export function registerBroadcastRoutes(router) {
9
+ Router.get(router, '/broadcast/health', async (_req, res) => {
10
+ res.json({ ok: true });
11
+ });
12
+ Router.post(router, '/broadcast/send', async (req, res) => {
13
+ const body = (req.body ?? {});
14
+ const channel = typeof body['channel'] === 'string' ? body['channel'] : '';
15
+ const event = typeof body['event'] === 'string' ? body['event'] : '';
16
+ const data = body['data'];
17
+ if (!channel || !event) {
18
+ res
19
+ .setStatus(400)
20
+ .json({ ok: false, error: 'Invalid payload: channel and event are required' });
21
+ return;
22
+ }
23
+ const { Broadcast } = await import('../src/tools/broadcast/Broadcast.js');
24
+ const result = await Broadcast.send(channel, event, data);
25
+ res.json({ ok: true, result });
26
+ });
27
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Health Routes
3
+ * Provides health, liveness, and readiness endpoints.
4
+ */
5
+ import { type IRouter } from '../src/routing/Router';
6
+ export declare function registerHealthRoutes(router: IRouter): void;
7
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../routes/health.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,iBAAiB,CAAC;AAEvD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAI1D"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Health Routes
3
+ * Provides health, liveness, and readiness endpoints.
4
+ */
5
+ import { appConfig } from '../src/config/index.js';
6
+ import { RuntimeHealthProbes } from '../src/health/RuntimeHealthProbes.js';
7
+ import { Env } from '../src/config/env.js';
8
+ import { Logger } from '../src/config/logger.js';
9
+ import { useDatabase } from '../src/orm/Database.js';
10
+ import { QueryBuilder } from '../src/orm/QueryBuilder.js';
11
+ import { Router } from '../src/routing/Router.js';
12
+ export function registerHealthRoutes(router) {
13
+ registerHealthRoute(router);
14
+ registerHealthLiveRoute(router);
15
+ registerHealthReadyRoute(router);
16
+ }
17
+ function registerHealthRoute(router) {
18
+ Router.get(router, '/health', async (_req, res) => {
19
+ const environment = Env.NODE_ENV ?? 'development';
20
+ try {
21
+ const db = useDatabase();
22
+ const maybeIsConnected = db.isConnected;
23
+ const maybeConnect = db.connect;
24
+ if (typeof maybeIsConnected === 'function' && maybeIsConnected.call(db) === false) {
25
+ if (typeof maybeConnect === 'function') {
26
+ await maybeConnect.call(db);
27
+ }
28
+ }
29
+ await QueryBuilder.ping(db);
30
+ const uptime = typeof process !== 'undefined' && typeof process.uptime === 'function'
31
+ ? process.uptime()
32
+ : 0;
33
+ res.json({
34
+ status: 'healthy',
35
+ timestamp: new Date().toISOString(),
36
+ uptime,
37
+ database: 'connected',
38
+ environment,
39
+ });
40
+ }
41
+ catch (error) {
42
+ Logger.error('Health check failed:', error);
43
+ const isProd = environment === 'production' || environment === 'prod';
44
+ res.setStatus(503).json({
45
+ status: 'unhealthy',
46
+ timestamp: new Date().toISOString(),
47
+ database: 'disconnected',
48
+ error: isProd ? 'Service unavailable' : error.message,
49
+ });
50
+ }
51
+ });
52
+ }
53
+ function registerHealthLiveRoute(router) {
54
+ Router.get(router, '/health/live', async (_req, res) => {
55
+ const uptime = typeof process !== 'undefined' && typeof process.uptime === 'function' ? process.uptime() : 0;
56
+ res.json({
57
+ status: 'alive',
58
+ timestamp: new Date().toISOString(),
59
+ uptime,
60
+ });
61
+ });
62
+ }
63
+ function registerHealthReadyRoute(router) {
64
+ Router.get(router, '/health/ready', async (_req, res) => {
65
+ const startTime = Date.now();
66
+ const environment = appConfig.environment;
67
+ let databaseResponseTime = null;
68
+ let cacheResponseTime = null;
69
+ try {
70
+ const db = useDatabase();
71
+ const maybeIsConnected = db.isConnected;
72
+ const maybeConnect = db.connect;
73
+ if (typeof maybeIsConnected === 'function' && maybeIsConnected.call(db) === false) {
74
+ if (typeof maybeConnect === 'function') {
75
+ await maybeConnect.call(db);
76
+ }
77
+ }
78
+ await QueryBuilder.ping(db);
79
+ databaseResponseTime = Date.now() - startTime;
80
+ // Only probe KV at runtime when explicitly configured.
81
+ cacheResponseTime = await RuntimeHealthProbes.pingKvCache(2000);
82
+ res.json({
83
+ status: 'ready',
84
+ timestamp: new Date().toISOString(),
85
+ environment,
86
+ dependencies: {
87
+ database: {
88
+ status: 'ready',
89
+ responseTime: databaseResponseTime,
90
+ },
91
+ ...(cacheResponseTime === null
92
+ ? {}
93
+ : {
94
+ cache: {
95
+ status: 'ready',
96
+ responseTime: cacheResponseTime,
97
+ },
98
+ }),
99
+ },
100
+ });
101
+ }
102
+ catch (error) {
103
+ Logger.error('Readiness check failed:', error);
104
+ const isProd = environment === 'production';
105
+ const responseTime = Date.now() - startTime;
106
+ const dependencies = {
107
+ database: {
108
+ status: databaseResponseTime === null ? 'unavailable' : 'ready',
109
+ responseTime: databaseResponseTime ?? responseTime,
110
+ },
111
+ };
112
+ if (RuntimeHealthProbes.getCacheDriverName() === 'kv') {
113
+ dependencies['cache'] = {
114
+ status: 'unavailable',
115
+ responseTime: cacheResponseTime ?? responseTime,
116
+ };
117
+ }
118
+ res.setStatus(503).json({
119
+ status: 'not_ready',
120
+ timestamp: new Date().toISOString(),
121
+ environment,
122
+ dependencies,
123
+ error: isProd ? 'Service unavailable' : error.message,
124
+ });
125
+ }
126
+ });
127
+ }
@@ -0,0 +1,4 @@
1
+ import { type IRouter } from '../src/routing/Router';
2
+ export declare function registerStorageRoutes(router: IRouter): void;
3
+ export default registerStorageRoutes;
4
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../routes/storage.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,iBAAiB,CAAC;AAIvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAiC3D;AAED,eAAe,qBAAqB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { HTTP_HEADERS } from '../src/config/constants.js';
2
+ import { Env } from '../src/config/env.js';
3
+ import { Router } from '../src/routing/Router.js';
4
+ import { LocalSignedUrl } from '../src/tools/storage/LocalSignedUrl.js';
5
+ import { Storage } from '../src/tools/storage/index.js';
6
+ export function registerStorageRoutes(router) {
7
+ Router.get(router, '/storage/download', async (req, res) => {
8
+ const tokenRaw = req.getQueryParam('token');
9
+ const token = typeof tokenRaw === 'string' ? tokenRaw : '';
10
+ if (token.trim() === '') {
11
+ res.setStatus(400).json({ message: 'Missing token' });
12
+ return;
13
+ }
14
+ const appKey = Env.get('APP_KEY', '');
15
+ if (appKey.trim() === '') {
16
+ res.setStatus(500).json({ message: 'Storage signing is not configured' });
17
+ return;
18
+ }
19
+ try {
20
+ const payload = LocalSignedUrl.verifyToken(token, appKey);
21
+ // Only local disk is supported by this route.
22
+ if (payload.disk !== 'local') {
23
+ res.setStatus(400).json({ message: 'Unsupported disk' });
24
+ return;
25
+ }
26
+ const contents = await Storage.get('local', payload.key);
27
+ res.setHeader(HTTP_HEADERS.CONTENT_TYPE, 'application/octet-stream');
28
+ res.setStatus(200).send(contents);
29
+ }
30
+ catch {
31
+ res.setStatus(403).json({ message: 'Invalid or expired token' });
32
+ }
33
+ });
34
+ }
35
+ export default registerStorageRoutes;
@@ -164,7 +164,7 @@ const registerRoutes = async (resolvedBasePath, router) => {
164
164
  mod.registerRoutes(router);
165
165
  return;
166
166
  }
167
- const { registerRoutes: registerFrameworkRoutes } = await import('../../routes/api.js');
167
+ const { registerRoutes: registerFrameworkRoutes } = await import('../routes/api.js');
168
168
  registerFrameworkRoutes(router);
169
169
  }
170
170
  catch (error) {
@@ -126,7 +126,7 @@ const BootstrapFunctions = Object.freeze({
126
126
  // Boot application
127
127
  await app.boot();
128
128
  // Get port and host from environment
129
- const port = Env.getInt('PORT', 3000);
129
+ const port = Env.getInt('PORT', 7777);
130
130
  const host = Env.get('HOST', 'localhost');
131
131
  // Create and start server
132
132
  const server = Server.create(app, port, host);
@@ -1 +1 @@
1
- {"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../../../src/cli/CLI.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4BH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,WAAW,IAAI;IACnB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,UAAU,IAAI,OAAO,CAAC;CACvB;AAyLD;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;cACJ,IAAI;EAed,CAAC"}
1
+ {"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../../../src/cli/CLI.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA6BH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,MAAM,WAAW,IAAI;IACnB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,UAAU,IAAI,OAAO,CAAC;CACvB;AA0LD;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;cACJ,IAAI;EAed,CAAC"}
package/src/cli/CLI.js CHANGED
@@ -22,6 +22,7 @@ import { SecretsCommand } from './commands/SecretsCommand.js';
22
22
  import { SimulateCommand } from './commands/SimulateCommand.js';
23
23
  import { StartCommand } from './commands/StartCommand.js';
24
24
  import { TemplatesCommand } from './commands/TemplatesCommand.js';
25
+ import { UpgradeCommand } from './commands/UpgradeCommand.js';
25
26
  import { ErrorHandler } from './ErrorHandler.js';
26
27
  import { esmDirname } from '../common/index.js';
27
28
  import { Logger } from '../config/logger.js';
@@ -68,6 +69,7 @@ const setupProgram = (program, version) => {
68
69
  const registerCommands = (program) => {
69
70
  const commands = [
70
71
  NewCommand.create(),
72
+ UpgradeCommand.create(),
71
73
  PrepareCommand,
72
74
  AddCommand.create(),
73
75
  StartCommand.create(),
@@ -1 +1 @@
1
- {"version":3,"file":"PromptHelper.d.ts","sourceRoot":"","sources":["../../../src/cli/PromptHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;sBACqB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMlE;;OAEG;8BAC6B,MAAM,gBAAe,OAAO,GAAU,OAAO,CAAC,MAAM,CAAC;IAuBrF;;OAEG;6BAEU,MAAM,gBACJ,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;IAsBlB;;OAEG;uBACqB,MAAM,gBAAsB,OAAO,GAAU,OAAO,CAAC,MAAM,CAAC;IAqBpF;;OAEG;uCAEkB,MAAM,EAAE,gBACd,OAAO,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC;IAkBpB;;OAEG;qBAEQ,MAAM,mBACC,OAAO,gBACV,OAAO,GACnB,OAAO,CAAC,OAAO,CAAC;IAiBnB;;OAEG;wBAEQ,MAAM,WACN,MAAM,EAAE,kBACF,MAAM,gBACR,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;IAkBlB;;OAEG;uBAEQ,MAAM,iBACD,MAAM,gBACP,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;EAgBlB,CAAC"}
1
+ {"version":3,"file":"PromptHelper.d.ts","sourceRoot":"","sources":["../../../src/cli/PromptHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;sBACqB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMlE;;OAEG;8BAC6B,MAAM,gBAAe,OAAO,GAAU,OAAO,CAAC,MAAM,CAAC;IAuBrF;;OAEG;6BAEU,MAAM,gBACJ,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;IAuBlB;;OAEG;uBACqB,MAAM,gBAAsB,OAAO,GAAU,OAAO,CAAC,MAAM,CAAC;IAqBpF;;OAEG;uCAEkB,MAAM,EAAE,gBACd,OAAO,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC;IAkBpB;;OAEG;qBAEQ,MAAM,mBACC,OAAO,gBACV,OAAO,GACnB,OAAO,CAAC,OAAO,CAAC;IAiBnB;;OAEG;wBAEQ,MAAM,WACN,MAAM,EAAE,kBACF,MAAM,gBACR,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;IAkBlB;;OAEG;uBAEQ,MAAM,iBACD,MAAM,gBACP,OAAO,GACnB,OAAO,CAAC,MAAM,CAAC;EAgBlB,CAAC"}
@@ -51,9 +51,10 @@ export const PromptHelper = Object.freeze({
51
51
  name: 'database',
52
52
  message: 'Select database:',
53
53
  choices: [
54
- { name: 'PostgreSQL (recommended)', value: 'postgresql' },
55
- { name: 'MySQL', value: 'mysql' },
56
- { name: 'SQLite', value: 'sqlite' },
54
+ { name: 'PostgreSQL — Production-ready relational DB', value: 'postgresql' },
55
+ { name: 'MySQL — Production-ready relational DB', value: 'mysql' },
56
+ { name: 'SQLite — Local dev (file-based)', value: 'sqlite' },
57
+ { name: 'd1-proxy — Cloudflare D1 via HTTPS proxy', value: 'd1-remote' },
57
58
  ],
58
59
  default: defaultDb,
59
60
  },
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { CommandOptions, IBaseCommand } from '../BaseCommand';
6
6
  type TemplateType = 'basic' | 'api' | 'microservice' | 'fullstack';
7
- type DatabaseType = 'sqlite' | 'mysql' | 'postgresql' | 'mongodb';
7
+ type DatabaseType = 'sqlite' | 'mysql' | 'postgresql' | 'mongodb' | 'd1-remote';
8
8
  interface NewProjectConfigResult {
9
9
  template: TemplateType;
10
10
  database: DatabaseType;
@@ -1 +1 @@
1
- {"version":3,"file":"NewCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/NewCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAe,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAY7E,KAAK,YAAY,GAAG,OAAO,GAAG,KAAK,GAAG,cAAc,GAAG,WAAW,CAAC;AACnE,KAAK,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,CAAC;AAYlE,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAsOhD,UAAU,WAAY,SAAQ,YAAY;IACxC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACxF,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACzF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,gBAAgB,EAAE,CAAC;IACjF,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;IAChC,YAAY,IAAI,MAAM,CAAC;IACvB,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,sBAAsB,EAC9B,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpE;AAmOD;;;GAGG;AACH,eAAO,MAAM,UAAU;IACrB;;OAEG;cACO,WAAW;EAGrB,CAAC"}
1
+ {"version":3,"file":"NewCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/NewCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAe,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAY7E,KAAK,YAAY,GAAG,OAAO,GAAG,KAAK,GAAG,cAAc,GAAG,WAAW,CAAC;AACnE,KAAK,YAAY,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,GAAG,SAAS,GAAG,WAAW,CAAC;AAYhF,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAuPhD,UAAU,WAAY,SAAQ,YAAY;IACxC,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACxF,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACzF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,sBAAsB,GAAG,gBAAgB,EAAE,CAAC;IACjF,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;IAChC,YAAY,IAAI,MAAM,CAAC;IACvB,cAAc,CACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,sBAAsB,EAC9B,SAAS,CAAC,EAAE,OAAO,GAClB,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpE;AA2ND;;;GAGG;AACH,eAAO,MAAM,UAAU;IACrB;;OAEG;cACO,WAAW;EAGrB,CAAC"}
@@ -51,7 +51,23 @@ const getBooleanOption = (options, key, fallback) => {
51
51
  };
52
52
  const getProjectDefaults = (name, options) => {
53
53
  const template = getStringOption(options, 'template', 'basic');
54
- const database = getStringOption(options, 'database', 'sqlite');
54
+ const normalizeDatabase = (value) => {
55
+ const v = value.trim();
56
+ if (v === 'd1-proxy')
57
+ return 'd1-remote';
58
+ if (v === 'd1-remote')
59
+ return 'd1-remote';
60
+ if (v === 'sqlite')
61
+ return 'sqlite';
62
+ if (v === 'mysql')
63
+ return 'mysql';
64
+ if (v === 'postgresql' || v === 'postgres')
65
+ return 'postgresql';
66
+ if (v === 'mongodb')
67
+ return 'mongodb';
68
+ return 'sqlite';
69
+ };
70
+ const database = normalizeDatabase(getStringOption(options, 'database', 'sqlite'));
55
71
  const portRaw = getStringOption(options, 'port', '7777');
56
72
  const portParsed = Number.parseInt(portRaw, 10);
57
73
  const port = Number.isFinite(portParsed) && portParsed > 0 ? portParsed : 7777;
@@ -80,7 +96,13 @@ const getQuestions = (name, defaults) => {
80
96
  type: 'rawlist',
81
97
  name: 'database',
82
98
  message: 'Database driver:',
83
- choices: ['sqlite', 'mysql', 'postgresql', 'mongodb'],
99
+ choices: [
100
+ { name: 'sqlite — Local dev (file-based)', value: 'sqlite' },
101
+ { name: 'postgresql — Production-ready relational DB', value: 'postgresql' },
102
+ { name: 'mysql — Production-ready relational DB', value: 'mysql' },
103
+ { name: 'd1-proxy — Cloudflare D1 via HTTPS proxy', value: 'd1-remote' },
104
+ { name: 'mongodb — Document DB (may require additional setup)', value: 'mongodb' },
105
+ ],
84
106
  default: defaults.database,
85
107
  },
86
108
  {
@@ -289,14 +311,9 @@ const executeNewCommand = async (options, command) => {
289
311
  const target = await resolveProjectTarget(options);
290
312
  await createProject(target, options, command);
291
313
  maybeInitializeGit(options, command, target);
292
- const installedWithPm = await maybeInstallDependencies(options, command, target);
314
+ await maybeInstallDependencies(options, command, target);
293
315
  command.success(`\n✨ Project ${target.name} created successfully!`);
294
- const optPm = options['packageManager'] ??
295
- options['package-manager'];
296
- const effectivePm = installedWithPm ?? optPm ?? resolvePackageManager();
297
- const runDevCmd = effectivePm === 'yarn' || effectivePm === 'pnpm'
298
- ? `${effectivePm} dev`
299
- : `${effectivePm} run dev`;
316
+ const runDevCmd = 'zin start';
300
317
  command.info(`\nNext steps:\n cd ${target.cdPath}\n ${runDevCmd}\n`);
301
318
  }
302
319
  catch (error) {
@@ -67,7 +67,7 @@ export const SimulateCommand = {
67
67
  Logger.info(`\n${chalk.bold('Next steps:')}`);
68
68
  Logger.info(` cd ${path.relative(process.cwd(), appPath)}`);
69
69
  Logger.info(' npm install');
70
- Logger.info(' npm run dev');
70
+ Logger.info(' zin start');
71
71
  }
72
72
  catch (error) {
73
73
  Logger.error('Failed to create simulated app', error);
@@ -1 +1 @@
1
- {"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAmSvF,eAAO,MAAM,YAAY;cACb,YAAY;EAsBtB,CAAC"}
1
+ {"version":3,"file":"StartCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/StartCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAyZvF,eAAO,MAAM,YAAY;cACb,YAAY;EAyBtB,CAAC"}