@tyravel/cli 0.1.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 (129) hide show
  1. package/dist/bin/tyravel.d.ts +3 -0
  2. package/dist/bin/tyravel.d.ts.map +1 -0
  3. package/dist/bin/tyravel.js +5 -0
  4. package/dist/bin/tyravel.js.map +1 -0
  5. package/dist/command.d.ts +13 -0
  6. package/dist/command.d.ts.map +1 -0
  7. package/dist/command.js +11 -0
  8. package/dist/command.js.map +1 -0
  9. package/dist/commands/auth-install.d.ts +8 -0
  10. package/dist/commands/auth-install.d.ts.map +1 -0
  11. package/dist/commands/auth-install.js +39 -0
  12. package/dist/commands/auth-install.js.map +1 -0
  13. package/dist/commands/make-controller.d.ts +8 -0
  14. package/dist/commands/make-controller.d.ts.map +1 -0
  15. package/dist/commands/make-controller.js +31 -0
  16. package/dist/commands/make-controller.js.map +1 -0
  17. package/dist/commands/make-event.d.ts +8 -0
  18. package/dist/commands/make-event.d.ts.map +1 -0
  19. package/dist/commands/make-event.js +31 -0
  20. package/dist/commands/make-event.js.map +1 -0
  21. package/dist/commands/make-job.d.ts +8 -0
  22. package/dist/commands/make-job.d.ts.map +1 -0
  23. package/dist/commands/make-job.js +32 -0
  24. package/dist/commands/make-job.js.map +1 -0
  25. package/dist/commands/make-listener.d.ts +8 -0
  26. package/dist/commands/make-listener.d.ts.map +1 -0
  27. package/dist/commands/make-listener.js +32 -0
  28. package/dist/commands/make-listener.js.map +1 -0
  29. package/dist/commands/make-migration.d.ts +8 -0
  30. package/dist/commands/make-migration.d.ts.map +1 -0
  31. package/dist/commands/make-migration.js +50 -0
  32. package/dist/commands/make-migration.js.map +1 -0
  33. package/dist/commands/make-model.d.ts +8 -0
  34. package/dist/commands/make-model.d.ts.map +1 -0
  35. package/dist/commands/make-model.js +31 -0
  36. package/dist/commands/make-model.js.map +1 -0
  37. package/dist/commands/make-provider.d.ts +8 -0
  38. package/dist/commands/make-provider.d.ts.map +1 -0
  39. package/dist/commands/make-provider.js +32 -0
  40. package/dist/commands/make-provider.js.map +1 -0
  41. package/dist/commands/make-subscriber.d.ts +8 -0
  42. package/dist/commands/make-subscriber.d.ts.map +1 -0
  43. package/dist/commands/make-subscriber.js +30 -0
  44. package/dist/commands/make-subscriber.js.map +1 -0
  45. package/dist/commands/make-test.d.ts +8 -0
  46. package/dist/commands/make-test.d.ts.map +1 -0
  47. package/dist/commands/make-test.js +24 -0
  48. package/dist/commands/make-test.js.map +1 -0
  49. package/dist/commands/make-view.d.ts +8 -0
  50. package/dist/commands/make-view.d.ts.map +1 -0
  51. package/dist/commands/make-view.js +36 -0
  52. package/dist/commands/make-view.js.map +1 -0
  53. package/dist/commands/migrate.d.ts +8 -0
  54. package/dist/commands/migrate.d.ts.map +1 -0
  55. package/dist/commands/migrate.js +32 -0
  56. package/dist/commands/migrate.js.map +1 -0
  57. package/dist/commands/new.d.ts +8 -0
  58. package/dist/commands/new.d.ts.map +1 -0
  59. package/dist/commands/new.js +57 -0
  60. package/dist/commands/new.js.map +1 -0
  61. package/dist/commands/new.test.d.ts +2 -0
  62. package/dist/commands/new.test.d.ts.map +1 -0
  63. package/dist/commands/new.test.js +28 -0
  64. package/dist/commands/new.test.js.map +1 -0
  65. package/dist/commands/queue-failed.d.ts +20 -0
  66. package/dist/commands/queue-failed.d.ts.map +1 -0
  67. package/dist/commands/queue-failed.js +143 -0
  68. package/dist/commands/queue-failed.js.map +1 -0
  69. package/dist/commands/queue-table.d.ts +8 -0
  70. package/dist/commands/queue-table.d.ts.map +1 -0
  71. package/dist/commands/queue-table.js +38 -0
  72. package/dist/commands/queue-table.js.map +1 -0
  73. package/dist/commands/queue-work.d.ts +8 -0
  74. package/dist/commands/queue-work.d.ts.map +1 -0
  75. package/dist/commands/queue-work.js +55 -0
  76. package/dist/commands/queue-work.js.map +1 -0
  77. package/dist/commands/serve.d.ts +8 -0
  78. package/dist/commands/serve.d.ts.map +1 -0
  79. package/dist/commands/serve.js +77 -0
  80. package/dist/commands/serve.js.map +1 -0
  81. package/dist/commands/version.d.ts +7 -0
  82. package/dist/commands/version.d.ts.map +1 -0
  83. package/dist/commands/version.js +16 -0
  84. package/dist/commands/version.js.map +1 -0
  85. package/dist/console.d.ts +17 -0
  86. package/dist/console.d.ts.map +1 -0
  87. package/dist/console.js +114 -0
  88. package/dist/console.js.map +1 -0
  89. package/dist/console.test.d.ts +2 -0
  90. package/dist/console.test.d.ts.map +1 -0
  91. package/dist/console.test.js +42 -0
  92. package/dist/console.test.js.map +1 -0
  93. package/dist/index.d.ts +7 -0
  94. package/dist/index.d.ts.map +1 -0
  95. package/dist/index.js +5 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/kernel.d.ts +3 -0
  98. package/dist/kernel.d.ts.map +1 -0
  99. package/dist/kernel.js +44 -0
  100. package/dist/kernel.js.map +1 -0
  101. package/dist/project.d.ts +12 -0
  102. package/dist/project.d.ts.map +1 -0
  103. package/dist/project.js +34 -0
  104. package/dist/project.js.map +1 -0
  105. package/dist/project.test.d.ts +2 -0
  106. package/dist/project.test.d.ts.map +1 -0
  107. package/dist/project.test.js +24 -0
  108. package/dist/project.test.js.map +1 -0
  109. package/dist/stubs-ecosystem.d.ts +5 -0
  110. package/dist/stubs-ecosystem.d.ts.map +1 -0
  111. package/dist/stubs-ecosystem.js +79 -0
  112. package/dist/stubs-ecosystem.js.map +1 -0
  113. package/dist/stubs-testing.d.ts +3 -0
  114. package/dist/stubs-testing.d.ts.map +1 -0
  115. package/dist/stubs-testing.js +33 -0
  116. package/dist/stubs-testing.js.map +1 -0
  117. package/dist/stubs.d.ts +35 -0
  118. package/dist/stubs.d.ts.map +1 -0
  119. package/dist/stubs.js +753 -0
  120. package/dist/stubs.js.map +1 -0
  121. package/dist/utils.d.ts +9 -0
  122. package/dist/utils.d.ts.map +1 -0
  123. package/dist/utils.js +70 -0
  124. package/dist/utils.js.map +1 -0
  125. package/dist/utils.test.d.ts +2 -0
  126. package/dist/utils.test.d.ts.map +1 -0
  127. package/dist/utils.test.js +13 -0
  128. package/dist/utils.test.js.map +1 -0
  129. package/package.json +42 -0
@@ -0,0 +1,36 @@
1
+ import { existsSync, mkdirSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+ import { Command } from '../command.js';
4
+ import { requireProjectRoot } from '../project.js';
5
+ import { view } from '../stubs.js';
6
+ import { parseOptions, positionalArgs, projectPath, toKebabCase, writeFile, } from '../utils.js';
7
+ export class MakeViewCommand extends Command {
8
+ name = 'make:view';
9
+ description = 'Create a new Tyr template view';
10
+ usage = 'tyravel make:view <name>';
11
+ async handle(args) {
12
+ parseOptions(args);
13
+ const [rawName] = positionalArgs(args);
14
+ if (!rawName) {
15
+ console.error('View name is required.');
16
+ console.error('Usage: tyravel make:view <name>');
17
+ return 1;
18
+ }
19
+ const root = requireProjectRoot();
20
+ const dotted = rawName.replace(/\\/g, '/').replace(/\/+/g, '.');
21
+ const segments = dotted.split('.').map((segment) => toKebabCase(segment));
22
+ const fileName = `${segments.at(-1)}.tyr`;
23
+ const directory = segments.slice(0, -1);
24
+ const relativeDir = ['resources', 'views', ...directory].join('/');
25
+ const target = projectPath(root, relativeDir, fileName);
26
+ if (existsSync(target)) {
27
+ console.error(`View already exists: ${relativeDir}/${fileName}`);
28
+ return 1;
29
+ }
30
+ mkdirSync(dirname(target), { recursive: true });
31
+ writeFile(target, view(segments.join('.')));
32
+ console.log(`View created: ${relativeDir}/${fileName}`);
33
+ return 0;
34
+ }
35
+ }
36
+ //# sourceMappingURL=make-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"make-view.js","sourceRoot":"","sources":["../../src/commands/make-view.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EACL,YAAY,EACZ,cAAc,EACd,WAAW,EACX,WAAW,EACX,SAAS,GACV,MAAM,aAAa,CAAC;AAErB,MAAM,OAAO,eAAgB,SAAQ,OAAO;IACxB,IAAI,GAAG,WAAW,CAAC;IACnB,WAAW,GAAG,gCAAgC,CAAC;IAC/C,KAAK,GAAG,0BAA0B,CAAC;IAErD,KAAK,CAAC,MAAM,CAAC,IAAc;QACzB,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,MAAM,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QAEvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACxC,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACjD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1E,MAAM,QAAQ,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,WAAW,GAAG,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAExD,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,wBAAwB,WAAW,IAAI,QAAQ,EAAE,CAAC,CAAC;YACjE,OAAO,CAAC,CAAC;QACX,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,iBAAiB,WAAW,IAAI,QAAQ,EAAE,CAAC,CAAC;QAExD,OAAO,CAAC,CAAC;IACX,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import { Command } from '../command.js';
2
+ export declare class MigrateCommand extends Command {
3
+ readonly name = "migrate";
4
+ readonly description = "Run database migrations";
5
+ readonly usage = "tyravel migrate";
6
+ handle(args: string[]): Promise<number>;
7
+ }
8
+ //# sourceMappingURL=migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxC,qBAAa,cAAe,SAAQ,OAAO;IACzC,SAAkB,IAAI,aAAa;IACnC,SAAkB,WAAW,6BAA6B;IAC1D,SAAkB,KAAK,qBAAqB;IAEtC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA6B9C"}
@@ -0,0 +1,32 @@
1
+ import { join } from 'node:path';
2
+ import { loadConfig } from '@tyravel/config';
3
+ import { DatabaseManager, Migrator } from '@tyravel/database';
4
+ import { Command } from '../command.js';
5
+ import { requireProjectRoot } from '../project.js';
6
+ import { parseOptions, positionalArgs } from '../utils.js';
7
+ export class MigrateCommand extends Command {
8
+ name = 'migrate';
9
+ description = 'Run database migrations';
10
+ usage = 'tyravel migrate';
11
+ async handle(args) {
12
+ parseOptions(args);
13
+ positionalArgs(args);
14
+ const root = requireProjectRoot();
15
+ const config = await loadConfig(root);
16
+ const database = config.database;
17
+ if (!database) {
18
+ console.error('Database config not found. Add config/database.ts to your app.');
19
+ return 1;
20
+ }
21
+ const manager = new DatabaseManager(database, root);
22
+ const migrator = new Migrator(manager.connection(), join(root, 'database/migrations'));
23
+ const ran = await migrator.run();
24
+ if (ran.length === 0) {
25
+ console.log('Nothing to migrate.');
26
+ return 0;
27
+ }
28
+ console.log(`Migrated: ${ran.join(', ')}`);
29
+ return 0;
30
+ }
31
+ }
32
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE3D,MAAM,OAAO,cAAe,SAAQ,OAAO;IACvB,IAAI,GAAG,SAAS,CAAC;IACjB,WAAW,GAAG,yBAAyB,CAAC;IACxC,KAAK,GAAG,iBAAiB,CAAC;IAE5C,KAAK,CAAC,MAAM,CAAC,IAAc;QACzB,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,cAAc,CAAC,IAAI,CAAC,CAAC;QAErB,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAsC,CAAC;QAE/D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YAChF,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAC3B,OAAO,CAAC,UAAU,EAAE,EACpB,IAAI,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAClC,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,CAAC;QAEjC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YACnC,OAAO,CAAC,CAAC;QACX,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3C,OAAO,CAAC,CAAC;IACX,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import { Command } from '../command.js';
2
+ export declare class NewCommand extends Command {
3
+ readonly name = "new";
4
+ readonly description = "Create a new Tyravel application";
5
+ readonly usage = "tyravel new <name> [--path=<directory>]";
6
+ handle(args: string[]): Promise<number>;
7
+ }
8
+ //# sourceMappingURL=new.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.d.ts","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAgCxC,qBAAa,UAAW,SAAQ,OAAO;IACrC,SAAkB,IAAI,SAAS;IAC/B,SAAkB,WAAW,sCAAsC;IACnE,SAAkB,KAAK,6CAA6C;IAE9D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAoE9C"}
@@ -0,0 +1,57 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { Command } from '../command.js';
4
+ import { cacheConfig, mailConfig, notificationsConfig, notificationsTableMigration, } from '../stubs-ecosystem.js';
5
+ import { appConfig, databaseConfig, appServiceProvider, eventsConfig, layoutView, mainEntry, projectConfig, projectPackageJson, queueConfig, jobsTableMigration, failedJobsTableMigration, viewsConfig, webRoutes, } from '../stubs.js';
6
+ import { featureTestStub, projectVitestConfig } from '../stubs-testing.js';
7
+ import { optionString, parseOptions, positionalArgs, projectPath, toKebabCase, writeFile, } from '../utils.js';
8
+ export class NewCommand extends Command {
9
+ name = 'new';
10
+ description = 'Create a new Tyravel application';
11
+ usage = 'tyravel new <name> [--path=<directory>]';
12
+ async handle(args) {
13
+ const options = parseOptions(args);
14
+ const [rawName] = positionalArgs(args);
15
+ if (!rawName) {
16
+ console.error('Project name is required.');
17
+ console.error('Usage: tyravel new <name> [--path=<directory>]');
18
+ return 1;
19
+ }
20
+ const name = toKebabCase(rawName);
21
+ const parentDir = optionString(options, 'path', process.cwd()) ?? process.cwd();
22
+ const targetDir = resolve(parentDir, name);
23
+ if (existsSync(targetDir)) {
24
+ console.error(`Directory already exists: ${targetDir}`);
25
+ return 1;
26
+ }
27
+ writeFile(projectPath(targetDir, 'package.json'), projectPackageJson(name));
28
+ writeFile(projectPath(targetDir, 'tyravel.json'), projectConfig(name));
29
+ writeFile(projectPath(targetDir, 'config/app.ts'), appConfig(name));
30
+ writeFile(projectPath(targetDir, 'config/database.ts'), databaseConfig());
31
+ writeFile(projectPath(targetDir, 'config/views.ts'), viewsConfig());
32
+ writeFile(projectPath(targetDir, 'config/queue.ts'), queueConfig());
33
+ writeFile(projectPath(targetDir, 'config/events.ts'), eventsConfig());
34
+ writeFile(projectPath(targetDir, 'config/cache.ts'), cacheConfig());
35
+ writeFile(projectPath(targetDir, 'config/mail.ts'), mailConfig());
36
+ writeFile(projectPath(targetDir, 'config/notifications.ts'), notificationsConfig());
37
+ writeFile(projectPath(targetDir, 'resources/views/layouts/app.tyr'), layoutView());
38
+ writeFile(projectPath(targetDir, 'database/migrations/.gitkeep'), '');
39
+ const ts = Date.now();
40
+ writeFile(projectPath(targetDir, `database/migrations/${ts}_create_jobs_table.ts`), jobsTableMigration());
41
+ writeFile(projectPath(targetDir, `database/migrations/${ts + 1}_create_failed_jobs_table.ts`), failedJobsTableMigration());
42
+ writeFile(projectPath(targetDir, `database/migrations/${ts + 2}_create_notifications_table.ts`), notificationsTableMigration());
43
+ writeFile(projectPath(targetDir, 'src/main.ts'), mainEntry());
44
+ writeFile(projectPath(targetDir, 'src/providers/app-service-provider.ts'), appServiceProvider());
45
+ writeFile(projectPath(targetDir, 'src/routes/web.ts'), webRoutes());
46
+ writeFile(projectPath(targetDir, 'vitest.config.ts'), projectVitestConfig());
47
+ writeFile(projectPath(targetDir, 'tests/feature/example.test.ts'), featureTestStub('ExampleTest'));
48
+ console.log(`Tyravel application created successfully.`);
49
+ console.log('');
50
+ console.log(` cd ${name}`);
51
+ console.log(' npm install');
52
+ console.log(' npm test');
53
+ console.log(' tyravel serve');
54
+ return 0;
55
+ }
56
+ }
57
+ //# sourceMappingURL=new.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/commands/new.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=new.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.test.d.ts","sourceRoot":"","sources":["../../src/commands/new.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ import { existsSync, mkdtempSync, rmSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, describe, expect, it } from 'vitest';
5
+ import { NewCommand } from './new.js';
6
+ describe('NewCommand', () => {
7
+ let tempDir = '';
8
+ afterEach(() => {
9
+ if (tempDir) {
10
+ rmSync(tempDir, { recursive: true, force: true });
11
+ tempDir = '';
12
+ }
13
+ });
14
+ it('scaffolds a Tyravel application', async () => {
15
+ tempDir = mkdtempSync(join(tmpdir(), 'tyravel-new-'));
16
+ const command = new NewCommand();
17
+ const code = await command.handle(['my-app', `--path=${tempDir}`]);
18
+ const projectDir = join(tempDir, 'my-app');
19
+ expect(code).toBe(0);
20
+ expect(existsSync(join(projectDir, 'package.json'))).toBe(true);
21
+ expect(existsSync(join(projectDir, 'tyravel.json'))).toBe(true);
22
+ expect(existsSync(join(projectDir, 'config/app.ts'))).toBe(true);
23
+ expect(existsSync(join(projectDir, 'src/main.ts'))).toBe(true);
24
+ expect(existsSync(join(projectDir, 'src/routes/web.ts'))).toBe(true);
25
+ expect(existsSync(join(projectDir, 'src/providers/app-service-provider.ts'))).toBe(true);
26
+ });
27
+ });
28
+ //# sourceMappingURL=new.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.test.js","sourceRoot":"","sources":["../../src/commands/new.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,cAAc,CAAC,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,IAAI,UAAU,EAAE,CAAC;QAEjC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAE3C,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrE,MAAM,CACJ,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,uCAAuC,CAAC,CAAC,CACtE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { Command } from '../command.js';
2
+ export declare class QueueFailedCommand extends Command {
3
+ readonly name = "queue:failed";
4
+ readonly description = "List failed queue jobs";
5
+ readonly usage = "tyravel queue:failed";
6
+ handle(args: string[]): Promise<number>;
7
+ }
8
+ export declare class QueueRetryCommand extends Command {
9
+ readonly name = "queue:retry";
10
+ readonly description = "Retry a failed queue job by id";
11
+ readonly usage = "tyravel queue:retry <id>";
12
+ handle(args: string[]): Promise<number>;
13
+ }
14
+ export declare class QueueFailedTableCommand extends Command {
15
+ readonly name = "queue:failed-table";
16
+ readonly description = "Create a migration for the failed_jobs table";
17
+ readonly usage = "tyravel queue:failed-table";
18
+ handle(args: string[]): Promise<number>;
19
+ }
20
+ //# sourceMappingURL=queue-failed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-failed.d.ts","sourceRoot":"","sources":["../../src/commands/queue-failed.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAIxC,qBAAa,kBAAmB,SAAQ,OAAO;IAC7C,SAAkB,IAAI,kBAAkB;IACxC,SAAkB,WAAW,4BAA4B;IACzD,SAAkB,KAAK,0BAA0B;IAE3C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA+B9C;AAED,qBAAa,iBAAkB,SAAQ,OAAO;IAC5C,SAAkB,IAAI,iBAAiB;IACvC,SAAkB,WAAW,oCAAoC;IACjE,SAAkB,KAAK,8BAA8B;IAE/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAyC9C;AAED,qBAAa,uBAAwB,SAAQ,OAAO;IAClD,SAAkB,IAAI,wBAAwB;IAC9C,SAAkB,WAAW,kDAAkD;IAC/E,SAAkB,KAAK,gCAAgC;IAEjD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAsB9C"}
@@ -0,0 +1,143 @@
1
+ import { join } from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+ import { loadConfig } from '@tyravel/config';
4
+ import { Application, ConfigServiceProvider, DatabaseServiceProvider, QueueServiceProvider, setQueueApplication, } from '@tyravel/core';
5
+ import { Command } from '../command.js';
6
+ import { requireProjectRoot } from '../project.js';
7
+ import { parseOptions, positionalArgs } from '../utils.js';
8
+ export class QueueFailedCommand extends Command {
9
+ name = 'queue:failed';
10
+ description = 'List failed queue jobs';
11
+ usage = 'tyravel queue:failed';
12
+ async handle(args) {
13
+ parseOptions(args);
14
+ positionalArgs(args);
15
+ const app = await bootQueueApp();
16
+ if (!app) {
17
+ return 1;
18
+ }
19
+ let failedJobs;
20
+ try {
21
+ failedJobs = app.make('queue.failed');
22
+ }
23
+ catch {
24
+ console.error('Failed job repository is not configured (database + queue.failed).');
25
+ return 1;
26
+ }
27
+ const records = await failedJobs.all();
28
+ if (records.length === 0) {
29
+ console.log('No failed jobs.');
30
+ return 0;
31
+ }
32
+ for (const record of records) {
33
+ console.log(`${record.id}\t${record.connection}\t${record.queue}\t${record.failedAt}\t${record.uuid}`);
34
+ }
35
+ return 0;
36
+ }
37
+ }
38
+ export class QueueRetryCommand extends Command {
39
+ name = 'queue:retry';
40
+ description = 'Retry a failed queue job by id';
41
+ usage = 'tyravel queue:retry <id>';
42
+ async handle(args) {
43
+ parseOptions(args);
44
+ const [idArg] = positionalArgs(args);
45
+ const id = Number(idArg);
46
+ if (!Number.isFinite(id)) {
47
+ console.error('Provide a numeric failed job id.');
48
+ return 1;
49
+ }
50
+ const app = await bootQueueApp();
51
+ if (!app) {
52
+ return 1;
53
+ }
54
+ const manager = app.make('queue');
55
+ const failedJobs = app.make('queue.failed');
56
+ const record = await failedJobs.find(id);
57
+ if (!record) {
58
+ console.error(`Failed job not found: ${id}`);
59
+ return 1;
60
+ }
61
+ const queue = manager.connection(record.connection);
62
+ const retried = await failedJobs.retry(id, async (payload, queueName) => {
63
+ if ('pushRaw' in queue && typeof queue.pushRaw === 'function') {
64
+ await queue.pushRaw(payload, queueName);
65
+ return;
66
+ }
67
+ throw new Error('Retry requires a queue connection that supports pushRaw');
68
+ });
69
+ if (!retried) {
70
+ console.error(`Could not retry failed job: ${id}`);
71
+ return 1;
72
+ }
73
+ console.log(`Retried failed job ${id} onto queue=${record.queue}`);
74
+ return 0;
75
+ }
76
+ }
77
+ export class QueueFailedTableCommand extends Command {
78
+ name = 'queue:failed-table';
79
+ description = 'Create a migration for the failed_jobs table';
80
+ usage = 'tyravel queue:failed-table';
81
+ async handle(args) {
82
+ parseOptions(args);
83
+ positionalArgs(args);
84
+ const root = requireProjectRoot();
85
+ const fileName = `${timestamp()}_create_failed_jobs_table.ts`;
86
+ const target = join(root, 'database/migrations', fileName);
87
+ const { existsSync } = await import('node:fs');
88
+ if (existsSync(target)) {
89
+ console.error(`Migration already exists: database/migrations/${fileName}`);
90
+ return 1;
91
+ }
92
+ const { writeFile, projectPath } = await import('../utils.js');
93
+ const { failedJobsTableMigration } = await import('../stubs.js');
94
+ writeFile(projectPath(root, 'database/migrations', fileName), failedJobsTableMigration());
95
+ console.log(`Migration created: database/migrations/${fileName}`);
96
+ console.log('Run tyravel migrate to create the failed_jobs table.');
97
+ return 0;
98
+ }
99
+ }
100
+ function timestamp() {
101
+ const now = new Date();
102
+ const pad = (value) => String(value).padStart(2, '0');
103
+ return [
104
+ now.getFullYear(),
105
+ pad(now.getMonth() + 1),
106
+ pad(now.getDate()),
107
+ pad(now.getHours()),
108
+ pad(now.getMinutes()),
109
+ pad(now.getSeconds()),
110
+ ].join('_');
111
+ }
112
+ async function bootQueueApp() {
113
+ const root = requireProjectRoot();
114
+ await loadConfig(root);
115
+ const app = new Application(root);
116
+ setQueueApplication(app);
117
+ app.register(ConfigServiceProvider);
118
+ app.register(DatabaseServiceProvider);
119
+ app.register(QueueServiceProvider);
120
+ const providerPath = join(root, 'src/providers/app-service-provider.ts');
121
+ const providerJsPath = join(root, 'src/providers/app-service-provider.js');
122
+ const target = (await fileExists(providerJsPath)) ? providerJsPath : providerPath;
123
+ const providerModule = (await import(pathToFileURL(target).href));
124
+ const Provider = providerModule.AppServiceProvider;
125
+ if (typeof Provider !== 'function') {
126
+ console.error('AppServiceProvider export not found');
127
+ return null;
128
+ }
129
+ app.register(Provider);
130
+ await app.boot();
131
+ return app;
132
+ }
133
+ async function fileExists(path) {
134
+ try {
135
+ const { access } = await import('node:fs/promises');
136
+ await access(path);
137
+ return true;
138
+ }
139
+ catch {
140
+ return false;
141
+ }
142
+ }
143
+ //# sourceMappingURL=queue-failed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-failed.js","sourceRoot":"","sources":["../../src/commands/queue-failed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Command } from '../command.js';
2
+ export declare class QueueTableCommand extends Command {
3
+ readonly name = "queue:table";
4
+ readonly description = "Create a migration for the queue jobs table";
5
+ readonly usage = "tyravel queue:table";
6
+ handle(args: string[]): Promise<number>;
7
+ }
8
+ //# sourceMappingURL=queue-table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-table.d.ts","sourceRoot":"","sources":["../../src/commands/queue-table.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAKxC,qBAAa,iBAAkB,SAAQ,OAAO;IAC5C,SAAkB,IAAI,iBAAiB;IACvC,SAAkB,WAAW,iDAAiD;IAC9E,SAAkB,KAAK,yBAAyB;IAE1C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAmB9C"}
@@ -0,0 +1,38 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { Command } from '../command.js';
3
+ import { requireProjectRoot } from '../project.js';
4
+ import { jobsTableMigration } from '../stubs.js';
5
+ import { parseOptions, positionalArgs, projectPath, writeFile } from '../utils.js';
6
+ export class QueueTableCommand extends Command {
7
+ name = 'queue:table';
8
+ description = 'Create a migration for the queue jobs table';
9
+ usage = 'tyravel queue:table';
10
+ async handle(args) {
11
+ parseOptions(args);
12
+ positionalArgs(args);
13
+ const root = requireProjectRoot();
14
+ const fileName = `${timestamp()}_create_jobs_table.ts`;
15
+ const target = projectPath(root, 'database/migrations', fileName);
16
+ if (existsSync(target)) {
17
+ console.error(`Migration already exists: database/migrations/${fileName}`);
18
+ return 1;
19
+ }
20
+ writeFile(target, jobsTableMigration());
21
+ console.log(`Migration created: database/migrations/${fileName}`);
22
+ console.log('Run tyravel migrate to create the jobs table.');
23
+ return 0;
24
+ }
25
+ }
26
+ function timestamp() {
27
+ const now = new Date();
28
+ const pad = (value) => String(value).padStart(2, '0');
29
+ return [
30
+ now.getFullYear(),
31
+ pad(now.getMonth() + 1),
32
+ pad(now.getDate()),
33
+ pad(now.getHours()),
34
+ pad(now.getMinutes()),
35
+ pad(now.getSeconds()),
36
+ ].join('_');
37
+ }
38
+ //# sourceMappingURL=queue-table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-table.js","sourceRoot":"","sources":["../../src/commands/queue-table.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEnF,MAAM,OAAO,iBAAkB,SAAQ,OAAO;IAC1B,IAAI,GAAG,aAAa,CAAC;IACrB,WAAW,GAAG,6CAA6C,CAAC;IAC5D,KAAK,GAAG,qBAAqB,CAAC;IAEhD,KAAK,CAAC,MAAM,CAAC,IAAc;QACzB,YAAY,CAAC,IAAI,CAAC,CAAC;QACnB,cAAc,CAAC,IAAI,CAAC,CAAC;QAErB,MAAM,IAAI,GAAG,kBAAkB,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,GAAG,SAAS,EAAE,uBAAuB,CAAC;QACvD,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAC;QAElE,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,iDAAiD,QAAQ,EAAE,CAAC,CAAC;YAC3E,OAAO,CAAC,CAAC;QACX,CAAC;QAED,SAAS,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,0CAA0C,QAAQ,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAE7D,OAAO,CAAC,CAAC;IACX,CAAC;CACF;AAED,SAAS,SAAS;IAChB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,OAAO;QACL,GAAG,CAAC,WAAW,EAAE;QACjB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACvB,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAClB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACnB,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QACrB,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;KACtB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Command } from '../command.js';
2
+ export declare class QueueWorkCommand extends Command {
3
+ readonly name = "queue:work";
4
+ readonly description = "Process jobs from the queue";
5
+ readonly usage = "tyravel queue:work [--queue=default] [--connection=database] [--sleep=1]";
6
+ handle(args: string[]): Promise<number>;
7
+ }
8
+ //# sourceMappingURL=queue-work.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-work.d.ts","sourceRoot":"","sources":["../../src/commands/queue-work.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AASxC,qBAAa,gBAAiB,SAAQ,OAAO;IAC3C,SAAkB,IAAI,gBAAgB;IACtC,SAAkB,WAAW,iCAAiC;IAC9D,SAAkB,KAAK,8EACsD;IAEvE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAwC9C"}
@@ -0,0 +1,55 @@
1
+ import { join } from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+ import { loadConfig } from '@tyravel/config';
4
+ import { Application, ConfigServiceProvider, DatabaseServiceProvider, QueueServiceProvider, setQueueApplication, } from '@tyravel/core';
5
+ import { Command } from '../command.js';
6
+ import { requireProjectRoot } from '../project.js';
7
+ import { optionNumber, optionString, parseOptions, positionalArgs, } from '../utils.js';
8
+ export class QueueWorkCommand extends Command {
9
+ name = 'queue:work';
10
+ description = 'Process jobs from the queue';
11
+ usage = 'tyravel queue:work [--queue=default] [--connection=database] [--sleep=1]';
12
+ async handle(args) {
13
+ const options = parseOptions(args);
14
+ positionalArgs(args);
15
+ const root = requireProjectRoot();
16
+ await loadConfig(root);
17
+ const app = new Application(root);
18
+ setQueueApplication(app);
19
+ app.register(ConfigServiceProvider);
20
+ app.register(DatabaseServiceProvider);
21
+ app.register(QueueServiceProvider);
22
+ const providerPath = join(root, 'src/providers/app-service-provider.ts');
23
+ const providerJsPath = join(root, 'src/providers/app-service-provider.js');
24
+ const providerModule = await importProvider(providerPath, providerJsPath);
25
+ const Provider = providerModule.AppServiceProvider;
26
+ if (typeof Provider !== 'function') {
27
+ console.error('AppServiceProvider export not found in src/providers/app-service-provider');
28
+ return 1;
29
+ }
30
+ app.register(Provider);
31
+ await app.boot();
32
+ const queue = optionString(options, 'queue', 'default') ?? 'default';
33
+ const connection = optionString(options, 'connection', 'database') ?? 'database';
34
+ const sleepSeconds = optionNumber(options, 'sleep', 1);
35
+ console.log(`Processing jobs on connection=${connection} queue=${queue}`);
36
+ const processor = app.make('queue.processor');
37
+ await processor.run({ queue, connection, sleepSeconds });
38
+ return 0;
39
+ }
40
+ }
41
+ async function importProvider(tsPath, jsPath) {
42
+ const target = (await fileExists(jsPath)) ? jsPath : tsPath;
43
+ return import(pathToFileURL(target).href);
44
+ }
45
+ async function fileExists(path) {
46
+ try {
47
+ const { access } = await import('node:fs/promises');
48
+ await access(path);
49
+ return true;
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ }
55
+ //# sourceMappingURL=queue-work.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue-work.js","sourceRoot":"","sources":["../../src/commands/queue-work.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Command } from '../command.js';
2
+ export declare class ServeCommand extends Command {
3
+ readonly name = "serve";
4
+ readonly description = "Start the development server";
5
+ readonly usage = "tyravel serve [--port=<port>] [--host=<hostname>]";
6
+ handle(args: string[]): Promise<number>;
7
+ }
8
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AASxC,qBAAa,YAAa,SAAQ,OAAO;IACvC,SAAkB,IAAI,WAAW;IACjC,SAAkB,WAAW,kCAAkC;IAC/D,SAAkB,KAAK,uDAAuD;IAExE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA8C9C"}
@@ -0,0 +1,77 @@
1
+ import { spawn, spawnSync } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { Command } from '../command.js';
5
+ import { loadProjectConfig, requireProjectRoot } from '../project.js';
6
+ import { optionNumber, optionString, parseOptions, positionalArgs, } from '../utils.js';
7
+ export class ServeCommand extends Command {
8
+ name = 'serve';
9
+ description = 'Start the development server';
10
+ usage = 'tyravel serve [--port=<port>] [--host=<hostname>]';
11
+ async handle(args) {
12
+ const options = parseOptions(args);
13
+ positionalArgs(args);
14
+ const root = requireProjectRoot();
15
+ const config = loadProjectConfig(root);
16
+ const entry = join(root, config.entry);
17
+ if (!existsSync(entry)) {
18
+ console.error(`Entry file not found: ${config.entry}`);
19
+ return 1;
20
+ }
21
+ const port = optionNumber(options, 'port', config.serve.port);
22
+ const hostname = optionString(options, 'host', config.serve.hostname) ?? config.serve.hostname;
23
+ const runtime = detectRuntime();
24
+ if (!runtime) {
25
+ console.error('No supported TypeScript runtime found. Install Bun or use Node 20+.');
26
+ return 1;
27
+ }
28
+ console.log(`Starting Tyravel server using ${runtime.name}...`);
29
+ const child = spawn(runtime.command, runtime.args(entry, port, hostname), {
30
+ cwd: root,
31
+ stdio: 'inherit',
32
+ env: {
33
+ ...process.env,
34
+ TYRAVEL_PORT: String(port),
35
+ TYRAVEL_HOST: hostname,
36
+ },
37
+ });
38
+ return await new Promise((resolve) => {
39
+ child.on('exit', (code) => resolve(code ?? 1));
40
+ child.on('error', (error) => {
41
+ console.error(error.message);
42
+ resolve(1);
43
+ });
44
+ });
45
+ }
46
+ }
47
+ function detectRuntime() {
48
+ if (process.versions.bun) {
49
+ return {
50
+ name: 'Bun',
51
+ command: process.execPath,
52
+ args: (entry) => ['run', entry],
53
+ };
54
+ }
55
+ if (commandExists('bun')) {
56
+ return {
57
+ name: 'Bun',
58
+ command: 'bun',
59
+ args: (entry) => ['run', entry],
60
+ };
61
+ }
62
+ const nodeMajor = Number(process.versions.node.split('.')[0]);
63
+ if (nodeMajor >= 22) {
64
+ return {
65
+ name: 'Node',
66
+ command: process.execPath,
67
+ args: (entry) => ['--experimental-strip-types', entry],
68
+ };
69
+ }
70
+ return undefined;
71
+ }
72
+ function commandExists(command) {
73
+ const which = process.platform === 'win32' ? 'where' : 'which';
74
+ const result = spawnSync(which, [command], { stdio: 'ignore' });
75
+ return result.status === 0;
76
+ }
77
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"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"}