@launch77/cli 1.4.3 → 1.5.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 (152) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cli.js +1 -4
  3. package/dist/cli.js.map +1 -1
  4. package/dist/infrastructure/npm-package.d.ts +42 -0
  5. package/dist/infrastructure/npm-package.d.ts.map +1 -0
  6. package/dist/infrastructure/npm-package.js +46 -0
  7. package/dist/infrastructure/npm-package.js.map +1 -0
  8. package/dist/infrastructure/package-resolver.d.ts +117 -0
  9. package/dist/infrastructure/package-resolver.d.ts.map +1 -0
  10. package/dist/infrastructure/package-resolver.js +170 -0
  11. package/dist/infrastructure/package-resolver.js.map +1 -0
  12. package/dist/infrastructure/package-resolver.test.d.ts +2 -0
  13. package/dist/infrastructure/package-resolver.test.d.ts.map +1 -0
  14. package/dist/infrastructure/package-resolver.test.js +251 -0
  15. package/dist/infrastructure/package-resolver.test.js.map +1 -0
  16. package/dist/infrastructure/template.d.ts +0 -1
  17. package/dist/infrastructure/template.d.ts.map +1 -1
  18. package/dist/infrastructure/template.js.map +1 -1
  19. package/dist/modules/app/commands/create-app.d.ts.map +1 -1
  20. package/dist/modules/app/commands/create-app.js +14 -15
  21. package/dist/modules/app/commands/create-app.js.map +1 -1
  22. package/dist/modules/app/commands/delete-app.js +1 -1
  23. package/dist/modules/app/commands/delete-app.js.map +1 -1
  24. package/dist/modules/app/commands/validate-manifest.d.ts.map +1 -1
  25. package/dist/modules/app/commands/validate-manifest.js +0 -1
  26. package/dist/modules/app/commands/validate-manifest.js.map +1 -1
  27. package/dist/modules/app/index.d.ts +1 -2
  28. package/dist/modules/app/index.d.ts.map +1 -1
  29. package/dist/modules/app/index.js +0 -1
  30. package/dist/modules/app/index.js.map +1 -1
  31. package/dist/modules/app/lib/app-template-resolver.d.ts +14 -0
  32. package/dist/modules/app/lib/app-template-resolver.d.ts.map +1 -0
  33. package/dist/modules/app/lib/app-template-resolver.js +51 -0
  34. package/dist/modules/app/lib/app-template-resolver.js.map +1 -0
  35. package/dist/modules/app/lib/manifest-schema.d.ts +0 -7
  36. package/dist/modules/app/lib/manifest-schema.d.ts.map +1 -1
  37. package/dist/modules/app/lib/manifest-schema.js +0 -2
  38. package/dist/modules/app/lib/manifest-schema.js.map +1 -1
  39. package/dist/modules/app/services/app-svc.d.ts +2 -1
  40. package/dist/modules/app/services/app-svc.d.ts.map +1 -1
  41. package/dist/modules/app/services/app-svc.js +77 -12
  42. package/dist/modules/app/services/app-svc.js.map +1 -1
  43. package/dist/modules/app/services/manifest-svc.d.ts +2 -2
  44. package/dist/modules/app/services/manifest-svc.d.ts.map +1 -1
  45. package/dist/modules/app/services/manifest-svc.js +9 -50
  46. package/dist/modules/app/services/manifest-svc.js.map +1 -1
  47. package/dist/modules/app/types/app-types.d.ts +2 -5
  48. package/dist/modules/app/types/app-types.d.ts.map +1 -1
  49. package/dist/modules/app/types/app-types.js +1 -4
  50. package/dist/modules/app/types/app-types.js.map +1 -1
  51. package/dist/modules/catalog/commands/scan.js +3 -3
  52. package/dist/modules/catalog/commands/scan.js.map +1 -1
  53. package/dist/modules/catalog/services/catalog-svc.d.ts +2 -2
  54. package/dist/modules/catalog/services/catalog-svc.d.ts.map +1 -1
  55. package/dist/modules/catalog/services/catalog-svc.js +2 -2
  56. package/dist/modules/catalog/services/catalog-svc.js.map +1 -1
  57. package/dist/modules/deploy/commands/deploy-init-action.d.ts.map +1 -1
  58. package/dist/modules/deploy/commands/deploy-init-action.js +21 -20
  59. package/dist/modules/deploy/commands/deploy-init-action.js.map +1 -1
  60. package/dist/modules/deploy/commands/deploy-logs-action.d.ts.map +1 -1
  61. package/dist/modules/deploy/commands/deploy-logs-action.js +16 -13
  62. package/dist/modules/deploy/commands/deploy-logs-action.js.map +1 -1
  63. package/dist/modules/deploy/commands/deploy-status-action.d.ts.map +1 -1
  64. package/dist/modules/deploy/commands/deploy-status-action.js +16 -13
  65. package/dist/modules/deploy/commands/deploy-status-action.js.map +1 -1
  66. package/dist/modules/plugin/lib/plugin-resolver.d.ts +10 -72
  67. package/dist/modules/plugin/lib/plugin-resolver.d.ts.map +1 -1
  68. package/dist/modules/plugin/lib/plugin-resolver.js +23 -115
  69. package/dist/modules/plugin/lib/plugin-resolver.js.map +1 -1
  70. package/dist/modules/plugin/lib/plugin-resolver.test.js +45 -39
  71. package/dist/modules/plugin/lib/plugin-resolver.test.js.map +1 -1
  72. package/dist/modules/plugin/services/plugin-svc.d.ts +2 -0
  73. package/dist/modules/plugin/services/plugin-svc.d.ts.map +1 -1
  74. package/dist/modules/plugin/services/plugin-svc.js +24 -19
  75. package/dist/modules/plugin/services/plugin-svc.js.map +1 -1
  76. package/dist/modules/plugin/services/plugin-svc.test.js +12 -6
  77. package/dist/modules/plugin/services/plugin-svc.test.js.map +1 -1
  78. package/dist/templates/plugin/package.json.hbs +1 -1
  79. package/dist/templates/plugin/plugin.json.hbs +1 -3
  80. package/dist/utils/validation.d.ts +3 -7
  81. package/dist/utils/validation.d.ts.map +1 -1
  82. package/dist/utils/validation.js +7 -31
  83. package/dist/utils/validation.js.map +1 -1
  84. package/package.json +1 -1
  85. package/src/cli.ts +1 -4
  86. package/src/infrastructure/npm-package.ts +73 -0
  87. package/src/infrastructure/package-resolver.test.ts +313 -0
  88. package/src/infrastructure/package-resolver.ts +223 -0
  89. package/src/infrastructure/template.ts +0 -1
  90. package/src/modules/app/commands/create-app.ts +14 -18
  91. package/src/modules/app/commands/delete-app.ts +1 -1
  92. package/src/modules/app/commands/validate-manifest.ts +0 -1
  93. package/src/modules/app/index.ts +1 -2
  94. package/src/modules/app/lib/app-template-resolver.ts +56 -0
  95. package/src/modules/app/lib/manifest-schema.ts +0 -5
  96. package/src/modules/app/services/app-svc.ts +89 -13
  97. package/src/modules/app/services/manifest-svc.ts +8 -57
  98. package/src/modules/app/types/app-types.ts +2 -9
  99. package/src/modules/catalog/commands/scan.ts +3 -3
  100. package/src/modules/catalog/services/catalog-svc.ts +4 -4
  101. package/src/modules/deploy/commands/deploy-init-action.ts +23 -20
  102. package/src/modules/deploy/commands/deploy-logs-action.ts +19 -13
  103. package/src/modules/deploy/commands/deploy-status-action.ts +19 -13
  104. package/src/modules/plugin/lib/plugin-resolver.test.ts +48 -39
  105. package/src/modules/plugin/lib/plugin-resolver.ts +22 -141
  106. package/src/modules/plugin/services/plugin-svc.test.ts +12 -6
  107. package/src/modules/plugin/services/plugin-svc.ts +27 -18
  108. package/src/utils/validation.ts +10 -38
  109. package/templates/plugin/package.json.hbs +1 -1
  110. package/templates/plugin/plugin.json.hbs +1 -3
  111. package/dist/modules/app/commands/generate-manifest.d.ts +0 -3
  112. package/dist/modules/app/commands/generate-manifest.d.ts.map +0 -1
  113. package/dist/modules/app/commands/generate-manifest.js +0 -62
  114. package/dist/modules/app/commands/generate-manifest.js.map +0 -1
  115. package/dist/modules/startup/commands/create-startup.d.ts +0 -3
  116. package/dist/modules/startup/commands/create-startup.d.ts.map +0 -1
  117. package/dist/modules/startup/commands/create-startup.js +0 -43
  118. package/dist/modules/startup/commands/create-startup.js.map +0 -1
  119. package/dist/modules/startup/errors/startup-errors.d.ts +0 -13
  120. package/dist/modules/startup/errors/startup-errors.d.ts.map +0 -1
  121. package/dist/modules/startup/errors/startup-errors.js +0 -25
  122. package/dist/modules/startup/errors/startup-errors.js.map +0 -1
  123. package/dist/modules/startup/index.d.ts +0 -5
  124. package/dist/modules/startup/index.d.ts.map +0 -1
  125. package/dist/modules/startup/index.js +0 -7
  126. package/dist/modules/startup/index.js.map +0 -1
  127. package/dist/modules/startup/services/startup-service.d.ts +0 -7
  128. package/dist/modules/startup/services/startup-service.d.ts.map +0 -1
  129. package/dist/modules/startup/services/startup-service.js +0 -43
  130. package/dist/modules/startup/services/startup-service.js.map +0 -1
  131. package/dist/modules/startup/types/startup-types.d.ts +0 -8
  132. package/dist/modules/startup/types/startup-types.d.ts.map +0 -1
  133. package/dist/modules/startup/types/startup-types.js +0 -2
  134. package/dist/modules/startup/types/startup-types.js.map +0 -1
  135. package/dist/modules/startup/utils/startup-validators.d.ts +0 -8
  136. package/dist/modules/startup/utils/startup-validators.d.ts.map +0 -1
  137. package/dist/modules/startup/utils/startup-validators.js +0 -17
  138. package/dist/modules/startup/utils/startup-validators.js.map +0 -1
  139. package/dist/templates/startup/apps/.gitkeep +0 -8
  140. package/dist/utils/monorepo.d.ts +0 -19
  141. package/dist/utils/monorepo.d.ts.map +0 -1
  142. package/dist/utils/monorepo.js +0 -100
  143. package/dist/utils/monorepo.js.map +0 -1
  144. package/src/modules/app/commands/generate-manifest.ts +0 -75
  145. package/src/modules/startup/commands/create-startup.ts +0 -53
  146. package/src/modules/startup/errors/startup-errors.ts +0 -23
  147. package/src/modules/startup/index.ts +0 -11
  148. package/src/modules/startup/services/startup-service.ts +0 -57
  149. package/src/modules/startup/types/startup-types.ts +0 -8
  150. package/src/modules/startup/utils/startup-validators.ts +0 -19
  151. package/src/utils/monorepo.ts +0 -137
  152. package/templates/startup/apps/.gitkeep +0 -8
@@ -1,62 +0,0 @@
1
- /* eslint-disable no-console */
2
- import * as path from 'path';
3
- import chalk from 'chalk';
4
- import { Command } from 'commander';
5
- import fs from 'fs-extra';
6
- import ora from 'ora';
7
- import { detectLaunch77Context } from '../../../utils/launch77-context.js';
8
- import { ManifestService } from '../services/manifest-svc.js';
9
- import { APP_TYPES, APP_TYPES_LIST } from '../types/app-types.js';
10
- export function generateManifestCommand() {
11
- const command = new Command('app:generate-manifest')
12
- .description('Generate a manifest for an existing app (run from app directory)')
13
- .requiredOption('-t, --type <type>', `App type (${APP_TYPES_LIST})`)
14
- .option('-p, --port <port>', 'Port for API apps (defaults to 4000)')
15
- .option('-f, --force', 'Overwrite existing manifest')
16
- .action(async (options) => {
17
- try {
18
- const context = await detectLaunch77Context(process.cwd());
19
- if (context.locationType !== 'workspace-app') {
20
- throw new Error('Must be run from within an app directory (e.g., apps/myapp)');
21
- }
22
- // Validate app type
23
- if (!APP_TYPES.includes(options.type)) {
24
- throw new Error(`Invalid app type: ${options.type}. Supported types: ${APP_TYPES_LIST}`);
25
- }
26
- const appPath = process.cwd();
27
- const appName = context.appName;
28
- console.log(chalk.blue(`\nšŸ” Generating manifest for app: ${appName}\n`));
29
- // Check if manifest already exists
30
- const launchDir = path.join(appPath, '.launch');
31
- const manifestPath = path.join(launchDir, 'app.json');
32
- if ((await fs.pathExists(manifestPath)) && !options.force) {
33
- console.log(chalk.yellow('āš ļø Manifest already exists at .launch/app.json'));
34
- console.log(chalk.gray('Use --force to overwrite'));
35
- return;
36
- }
37
- // Get port
38
- const port = options.port || (options.type === 'api' ? '4000' : '3000');
39
- // Generate manifest
40
- const manifestSpinner = ora('Generating manifest...').start();
41
- const manifestService = new ManifestService();
42
- const manifest = manifestService.generateManifest(options.type, appName, context, { port });
43
- // Ensure .launch directory exists
44
- await fs.ensureDir(launchDir);
45
- // Write manifest
46
- await fs.writeJSON(manifestPath, manifest, { spaces: 2 });
47
- manifestSpinner.succeed('Manifest generated');
48
- console.log(chalk.green(`\nāœ… Manifest created at .launch/app.json`));
49
- console.log(chalk.gray('\nManifest details:'));
50
- console.log(chalk.gray(' Type:'), manifest.type);
51
- console.log(chalk.gray(' Name:'), manifest.name);
52
- console.log(chalk.gray(' Package:'), manifest.package);
53
- }
54
- catch (error) {
55
- const message = error instanceof Error ? error.message : String(error);
56
- console.error(chalk.red('Error:'), message);
57
- process.exit(1);
58
- }
59
- });
60
- return command;
61
- }
62
- //# sourceMappingURL=generate-manifest.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-manifest.js","sourceRoot":"","sources":["../../../../src/modules/app/commands/generate-manifest.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function createStartupCommand(): Command;
3
- //# sourceMappingURL=create-startup.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-startup.d.ts","sourceRoot":"","sources":["../../../../src/modules/startup/commands/create-startup.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAOnC,wBAAgB,oBAAoB,IAAI,OAAO,CA0C9C"}
@@ -1,43 +0,0 @@
1
- import * as path from 'path';
2
- import chalk from 'chalk';
3
- import { Command } from 'commander';
4
- import ora from 'ora';
5
- import { detectMonorepoContext } from '../../../utils/monorepo.js';
6
- import { StartupAlreadyExistsError, InvalidStartupNameError, NotInMonorepoRootError } from '../errors/startup-errors.js';
7
- import { StartupService } from '../services/startup-service.js';
8
- export function createStartupCommand() {
9
- return new Command('startup:create')
10
- .argument('<name>', 'Name of the startup (lowercase, alphanumeric, hyphens)')
11
- .description('Create a new startup with brand configuration')
12
- .action(async (name) => {
13
- console.log(chalk.blue(`\nšŸš€ Creating startup: ${name}\n`));
14
- const service = new StartupService();
15
- try {
16
- const spinner = ora('Creating startup structure...').start();
17
- // Detect monorepo context
18
- const context = await detectMonorepoContext(process.cwd());
19
- const result = await service.createStartup({ name }, context);
20
- spinner.succeed('Startup structure created');
21
- // Success message
22
- const cwd = process.cwd();
23
- console.log(chalk.green(`\nāœ… Startup created successfully at ${path.relative(cwd, result.startupPath)}`));
24
- console.log(chalk.gray(`\nNext steps:\n` + ` 1. Create your first app:\n` + ` - Web app: launch77 create-app webapp <app-name>\n` + ` - API: launch77 create-app api <app-name>\n` + ` - Marketing site: launch77 create-app marketing-site <app-name>\n`));
25
- }
26
- catch (error) {
27
- if (error instanceof StartupAlreadyExistsError) {
28
- console.error(chalk.red(`\nāŒ ${error.message}\n`));
29
- process.exit(1);
30
- }
31
- if (error instanceof InvalidStartupNameError) {
32
- console.error(chalk.red(`\nāŒ ${error.message}\n`));
33
- process.exit(1);
34
- }
35
- if (error instanceof NotInMonorepoRootError) {
36
- console.error(chalk.red(`\nāŒ ${error.message}\n`));
37
- process.exit(1);
38
- }
39
- throw error;
40
- }
41
- });
42
- }
43
- //# sourceMappingURL=create-startup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-startup.js","sourceRoot":"","sources":["../../../../src/modules/startup/commands/create-startup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,GAAG,MAAM,KAAK,CAAA;AAErB,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACxH,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AAE/D,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC;SACjC,QAAQ,CAAC,QAAQ,EAAE,wDAAwD,CAAC;SAC5E,WAAW,CAAC,+CAA+C,CAAC;SAC5D,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,0BAA0B,IAAI,IAAI,CAAC,CAAC,CAAA;QAE3D,MAAM,OAAO,GAAG,IAAI,cAAc,EAAE,CAAA;QAEpC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,GAAG,CAAC,+BAA+B,CAAC,CAAC,KAAK,EAAE,CAAA;YAE5D,0BAA0B;YAC1B,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;YAE1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAA;YAE7D,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;YAE5C,kBAAkB;YAClB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uCAAuC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAA;YACzG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,GAAG,+BAA+B,GAAG,yDAAyD,GAAG,kDAAkD,GAAG,wEAAwE,CAAC,CAAC,CAAA;QAC1Q,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,yBAAyB,EAAE,CAAC;gBAC/C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,CAAA;gBAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YAED,IAAI,KAAK,YAAY,uBAAuB,EAAE,CAAC;gBAC7C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,CAAA;gBAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YAED,IAAI,KAAK,YAAY,sBAAsB,EAAE,CAAC;gBAC5C,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,CAAA;gBAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YAED,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -1,13 +0,0 @@
1
- export declare class StartupAlreadyExistsError extends Error {
2
- startupName: string;
3
- startupPath: string;
4
- constructor(startupName: string, startupPath: string);
5
- }
6
- export declare class InvalidStartupNameError extends Error {
7
- startupName: string;
8
- constructor(startupName: string);
9
- }
10
- export declare class NotInMonorepoRootError extends Error {
11
- constructor();
12
- }
13
- //# sourceMappingURL=startup-errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-errors.d.ts","sourceRoot":"","sources":["../../../../src/modules/startup/errors/startup-errors.ts"],"names":[],"mappings":"AAAA,qBAAa,yBAA0B,SAAQ,KAAK;IAEzC,WAAW,EAAE,MAAM;IACnB,WAAW,EAAE,MAAM;gBADnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM;CAK7B;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IAC7B,WAAW,EAAE,MAAM;gBAAnB,WAAW,EAAE,MAAM;CAIvC;AAED,qBAAa,sBAAuB,SAAQ,KAAK;;CAKhD"}
@@ -1,25 +0,0 @@
1
- export class StartupAlreadyExistsError extends Error {
2
- startupName;
3
- startupPath;
4
- constructor(startupName, startupPath) {
5
- super(`Startup ${startupName} already exists at ${startupPath}`);
6
- this.startupName = startupName;
7
- this.startupPath = startupPath;
8
- this.name = 'StartupAlreadyExistsError';
9
- }
10
- }
11
- export class InvalidStartupNameError extends Error {
12
- startupName;
13
- constructor(startupName) {
14
- super(`Invalid startup name: "${startupName}"\n\n` + `Startup names must:\n` + ` • Be lowercase only\n` + ` • Can only contain: lowercase letters, numbers, and hyphens\n` + ` • Cannot contain: spaces, uppercase, underscores, periods, or special characters\n\n` + `Valid examples:\n` + ` āœ“ my-startup\n` + ` āœ“ mystartup\n` + ` āœ“ startup123\n\n` + `Invalid examples:\n` + ` āœ— MyStartup (uppercase)\n` + ` āœ— my_startup (underscores)\n` + ` āœ— my.startup (periods)\n` + ` āœ— my startup (spaces)`);
15
- this.startupName = startupName;
16
- this.name = 'InvalidStartupNameError';
17
- }
18
- }
19
- export class NotInMonorepoRootError extends Error {
20
- constructor() {
21
- super('Must be run from the monorepo root directory (could not find .launch-monorepo-root.md)');
22
- this.name = 'NotInMonorepoRootError';
23
- }
24
- }
25
- //# sourceMappingURL=startup-errors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-errors.js","sourceRoot":"","sources":["../../../../src/modules/startup/errors/startup-errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAEzC;IACA;IAFT,YACS,WAAmB,EACnB,WAAmB;QAE1B,KAAK,CAAC,WAAW,WAAW,sBAAsB,WAAW,EAAE,CAAC,CAAA;QAHzD,gBAAW,GAAX,WAAW,CAAQ;QACnB,gBAAW,GAAX,WAAW,CAAQ;QAG1B,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAA;IACzC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAC7B;IAAnB,YAAmB,WAAmB;QACpC,KAAK,CAAC,0BAA0B,WAAW,OAAO,GAAG,uBAAuB,GAAG,yBAAyB,GAAG,iEAAiE,GAAG,wFAAwF,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,qBAAqB,GAAG,6BAA6B,GAAG,gCAAgC,GAAG,4BAA4B,GAAG,yBAAyB,CAAC,CAAA;QADne,gBAAW,GAAX,WAAW,CAAQ;QAEpC,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;IACvC,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C;QACE,KAAK,CAAC,wFAAwF,CAAC,CAAA;QAC/F,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAA;IACtC,CAAC;CACF"}
@@ -1,5 +0,0 @@
1
- export { StartupService } from './services/startup-service.js';
2
- export type { CreateStartupRequest, CreateStartupResult } from './types/startup-types.js';
3
- export { StartupAlreadyExistsError, InvalidStartupNameError, NotInMonorepoRootError } from './errors/startup-errors.js';
4
- export { createStartupCommand } from './commands/create-startup.js';
5
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/startup/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAG9D,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAGzF,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAGvH,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA"}
@@ -1,7 +0,0 @@
1
- // Services
2
- export { StartupService } from './services/startup-service.js';
3
- // Errors
4
- export { StartupAlreadyExistsError, InvalidStartupNameError, NotInMonorepoRootError } from './errors/startup-errors.js';
5
- // Command
6
- export { createStartupCommand } from './commands/create-startup.js';
7
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/startup/index.ts"],"names":[],"mappings":"AAAA,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAK9D,SAAS;AACT,OAAO,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAEvH,UAAU;AACV,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA"}
@@ -1,7 +0,0 @@
1
- import type { MonorepoContext } from '../../../utils/monorepo.js';
2
- import type { CreateStartupRequest, CreateStartupResult } from '../types/startup-types.js';
3
- export declare class StartupService {
4
- createStartup(request: CreateStartupRequest, context: MonorepoContext): Promise<CreateStartupResult>;
5
- private getTemplatePath;
6
- }
7
- //# sourceMappingURL=startup-service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-service.d.ts","sourceRoot":"","sources":["../../../../src/modules/startup/services/startup-service.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AACjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAE1F,qBAAa,cAAc;IACnB,aAAa,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiC1G,OAAO,CAAC,eAAe;CAYxB"}
@@ -1,43 +0,0 @@
1
- import * as path from 'path';
2
- import { fileURLToPath } from 'url';
3
- import * as filesystem from '../../../infrastructure/filesystem.js';
4
- import { StartupAlreadyExistsError, NotInMonorepoRootError } from '../errors/startup-errors.js';
5
- import { validateStartupName } from '../utils/startup-validators.js';
6
- export class StartupService {
7
- async createStartup(request, context) {
8
- const { name } = request;
9
- // 1. Validate name
10
- validateStartupName(name);
11
- // 2. Verify we found the monorepo
12
- if (!context.isValid) {
13
- throw new NotInMonorepoRootError();
14
- }
15
- // 3. Determine startup path
16
- const startupsDir = path.join(context.monorepoRoot, 'startups');
17
- const startupPath = path.join(startupsDir, name);
18
- // 4. Check if startup already exists
19
- if (await filesystem.exists(startupPath)) {
20
- throw new StartupAlreadyExistsError(name, startupPath);
21
- }
22
- // 5. Ensure startups directory exists
23
- await filesystem.ensureDir(startupsDir);
24
- // 6. Copy template
25
- const templatePath = this.getTemplatePath();
26
- await filesystem.copy(templatePath, startupPath);
27
- return {
28
- startupPath,
29
- name,
30
- };
31
- }
32
- getTemplatePath() {
33
- const __filename = fileURLToPath(import.meta.url);
34
- const __dirname = path.dirname(__filename);
35
- // From src/modules/startup/services/ or dist/modules/startup/services/ up to cli root
36
- const isDev = __filename.includes('/src/');
37
- const cliRoot = isDev
38
- ? path.join(__dirname, '../../../..') // src/modules/startup/services -> cli root
39
- : path.join(__dirname, '../../../..'); // dist/modules/startup/services -> cli root
40
- return path.join(cliRoot, 'templates/startup');
41
- }
42
- }
43
- //# sourceMappingURL=startup-service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-service.js","sourceRoot":"","sources":["../../../../src/modules/startup/services/startup-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AAEnC,OAAO,KAAK,UAAU,MAAM,uCAAuC,CAAA;AACnE,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AAKpE,MAAM,OAAO,cAAc;IACzB,KAAK,CAAC,aAAa,CAAC,OAA6B,EAAE,OAAwB;QACzE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAA;QAExB,mBAAmB;QACnB,mBAAmB,CAAC,IAAI,CAAC,CAAA;QAEzB,kCAAkC;QAClC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,IAAI,sBAAsB,EAAE,CAAA;QACpC,CAAC;QAED,4BAA4B;QAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,UAAU,CAAC,CAAA;QAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;QAEhD,qCAAqC;QACrC,IAAI,MAAM,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,yBAAyB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;QACxD,CAAC;QAED,sCAAsC;QACtC,MAAM,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;QAEvC,mBAAmB;QACnB,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;QAC3C,MAAM,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAA;QAEhD,OAAO;YACL,WAAW;YACX,IAAI;SACL,CAAA;IACH,CAAC;IAEO,eAAe;QACrB,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACjD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;QAE1C,sFAAsF;QACtF,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC1C,MAAM,OAAO,GAAG,KAAK;YACnB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,2CAA2C;YACjF,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA,CAAC,4CAA4C;QAEpF,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAA;IAChD,CAAC;CACF"}
@@ -1,8 +0,0 @@
1
- export interface CreateStartupRequest {
2
- name: string;
3
- }
4
- export interface CreateStartupResult {
5
- startupPath: string;
6
- name: string;
7
- }
8
- //# sourceMappingURL=startup-types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-types.d.ts","sourceRoot":"","sources":["../../../../src/modules/startup/types/startup-types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=startup-types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-types.js","sourceRoot":"","sources":["../../../../src/modules/startup/types/startup-types.ts"],"names":[],"mappings":""}
@@ -1,8 +0,0 @@
1
- /**
2
- * Validate startup name format
3
- * - Must be lowercase
4
- * - Can only contain lowercase letters, numbers, and hyphens
5
- * - Cannot contain spaces, uppercase, underscores, periods, or special characters
6
- */
7
- export declare function validateStartupName(name: string): void;
8
- //# sourceMappingURL=startup-validators.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-validators.d.ts","sourceRoot":"","sources":["../../../../src/modules/startup/utils/startup-validators.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAUtD"}
@@ -1,17 +0,0 @@
1
- import { InvalidStartupNameError } from '../errors/startup-errors.js';
2
- /**
3
- * Validate startup name format
4
- * - Must be lowercase
5
- * - Can only contain lowercase letters, numbers, and hyphens
6
- * - Cannot contain spaces, uppercase, underscores, periods, or special characters
7
- */
8
- export function validateStartupName(name) {
9
- if (!name || name.trim().length === 0) {
10
- throw new Error('Startup name cannot be empty');
11
- }
12
- const validPattern = /^[a-z0-9-]+$/;
13
- if (!validPattern.test(name)) {
14
- throw new InvalidStartupNameError(name);
15
- }
16
- }
17
- //# sourceMappingURL=startup-validators.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup-validators.js","sourceRoot":"","sources":["../../../../src/modules/startup/utils/startup-validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAErE;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,YAAY,GAAG,cAAc,CAAA;IAEnC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAA;IACzC,CAAC;AACH,CAAC"}
@@ -1,8 +0,0 @@
1
- # Apps Directory
2
-
3
- This directory will contain all applications for this startup.
4
-
5
- Create new apps using:
6
- ```bash
7
- launch77 create-app marketing-site <app-name>
8
- ```
@@ -1,19 +0,0 @@
1
- export type LocationType = 'monorepo-root' | 'startup-root' | 'startup-app' | 'unknown';
2
- export interface MonorepoContext {
3
- isValid: boolean;
4
- location: LocationType;
5
- monorepoRoot: string;
6
- appsDir: string | null;
7
- startupName?: string;
8
- appName?: string;
9
- packageName?: string;
10
- }
11
- /**
12
- * Detect the monorepo context from the current working directory
13
- *
14
- * @deprecated Use detectLaunch77Context() from launch77-context.ts instead.
15
- * This function is maintained for legacy monorepo structure only.
16
- * New workspaces created with `launch77 init` should use the new context system.
17
- */
18
- export declare function detectMonorepoContext(cwd: string): Promise<MonorepoContext>;
19
- //# sourceMappingURL=monorepo.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"monorepo.d.ts","sourceRoot":"","sources":["../../src/utils/monorepo.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,eAAe,GAAG,cAAc,GAAG,aAAa,GAAG,SAAS,CAAA;AAEvF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,YAAY,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IAEtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAuFD;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA2BjF"}
@@ -1,100 +0,0 @@
1
- import * as path from 'path';
2
- import fs from 'fs-extra';
3
- const MONOREPO_ROOT_MARKER = '.launch-monorepo-root.md';
4
- /**
5
- * Check if a directory is the monorepo root by looking for the marker file
6
- */
7
- async function isMonorepoRoot(dir) {
8
- const markerPath = path.join(dir, MONOREPO_ROOT_MARKER);
9
- return await fs.pathExists(markerPath);
10
- }
11
- /**
12
- * Find the monorepo root by traversing up from a starting directory
13
- * Looks for .launch-monorepo-root.md marker file
14
- */
15
- async function findMonorepoRoot(startDir) {
16
- let currentDir = path.resolve(startDir);
17
- const rootDir = path.parse(currentDir).root;
18
- while (currentDir !== rootDir) {
19
- if (await isMonorepoRoot(currentDir)) {
20
- return currentDir;
21
- }
22
- currentDir = path.dirname(currentDir);
23
- }
24
- return null;
25
- }
26
- /**
27
- * Parse the directory structure to determine location context
28
- * Based on patterns:
29
- * - startups/[name] → startup-root
30
- * - startups/[name]/apps/[app] → startup-app
31
- * - (empty or root) → monorepo-root
32
- */
33
- function parseLocationFromPath(cwdPath, monorepoRoot) {
34
- const relativePath = path.relative(monorepoRoot, cwdPath);
35
- // At monorepo root
36
- if (!relativePath || relativePath === '.') {
37
- return { location: 'monorepo-root' };
38
- }
39
- const parts = relativePath.split(path.sep);
40
- // startups/[name]/...
41
- if (parts[0] === 'startups' && parts.length >= 2) {
42
- const startupName = parts[1];
43
- // startups/[name]/apps/[app]
44
- if (parts.length >= 4 && parts[2] === 'apps') {
45
- return {
46
- location: 'startup-app',
47
- startupName,
48
- appName: parts[3],
49
- };
50
- }
51
- // startups/[name]
52
- return {
53
- location: 'startup-root',
54
- startupName,
55
- };
56
- }
57
- return { location: 'unknown' };
58
- }
59
- /**
60
- * Determine the apps directory based on location context
61
- * Returns null for invalid locations (e.g., monorepo-root, unknown)
62
- */
63
- function getAppsDir(monorepoRoot, location, startupName) {
64
- if (location === 'startup-root' || location === 'startup-app') {
65
- return path.join(monorepoRoot, 'startups', startupName, 'apps');
66
- }
67
- return null;
68
- }
69
- /**
70
- * Detect the monorepo context from the current working directory
71
- *
72
- * @deprecated Use detectLaunch77Context() from launch77-context.ts instead.
73
- * This function is maintained for legacy monorepo structure only.
74
- * New workspaces created with `launch77 init` should use the new context system.
75
- */
76
- export async function detectMonorepoContext(cwd) {
77
- const resolvedCwd = path.resolve(cwd);
78
- // Find the monorepo root
79
- const monorepoRoot = await findMonorepoRoot(resolvedCwd);
80
- if (!monorepoRoot) {
81
- return {
82
- isValid: false,
83
- location: 'unknown',
84
- monorepoRoot: '',
85
- appsDir: null,
86
- };
87
- }
88
- // Parse the directory structure to determine location
89
- const parsed = parseLocationFromPath(resolvedCwd, monorepoRoot);
90
- const appsDir = getAppsDir(monorepoRoot, parsed.location, parsed.startupName);
91
- return {
92
- isValid: true,
93
- location: parsed.location,
94
- monorepoRoot,
95
- appsDir,
96
- startupName: parsed.startupName,
97
- appName: parsed.appName,
98
- };
99
- }
100
- //# sourceMappingURL=monorepo.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"monorepo.js","sourceRoot":"","sources":["../../src/utils/monorepo.ts"],"names":[],"mappings":"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"}
@@ -1,75 +0,0 @@
1
- /* eslint-disable no-console */
2
- import * as path from 'path'
3
-
4
- import chalk from 'chalk'
5
- import { Command } from 'commander'
6
- import fs from 'fs-extra'
7
- import ora from 'ora'
8
-
9
- import { detectLaunch77Context } from '../../../utils/launch77-context.js'
10
- import { ManifestService } from '../services/manifest-svc.js'
11
- import { APP_TYPES, APP_TYPES_LIST, AppType } from '../types/app-types.js'
12
-
13
- export function generateManifestCommand(): Command {
14
- const command = new Command('app:generate-manifest')
15
- .description('Generate a manifest for an existing app (run from app directory)')
16
- .requiredOption('-t, --type <type>', `App type (${APP_TYPES_LIST})`)
17
- .option('-p, --port <port>', 'Port for API apps (defaults to 4000)')
18
- .option('-f, --force', 'Overwrite existing manifest')
19
- .action(async (options) => {
20
- try {
21
- const context = await detectLaunch77Context(process.cwd())
22
-
23
- if (context.locationType !== 'workspace-app') {
24
- throw new Error('Must be run from within an app directory (e.g., apps/myapp)')
25
- }
26
-
27
- // Validate app type
28
- if (!APP_TYPES.includes(options.type as AppType)) {
29
- throw new Error(`Invalid app type: ${options.type}. Supported types: ${APP_TYPES_LIST}`)
30
- }
31
-
32
- const appPath = process.cwd()
33
- const appName = context.appName!
34
-
35
- console.log(chalk.blue(`\nšŸ” Generating manifest for app: ${appName}\n`))
36
-
37
- // Check if manifest already exists
38
- const launchDir = path.join(appPath, '.launch')
39
- const manifestPath = path.join(launchDir, 'app.json')
40
-
41
- if ((await fs.pathExists(manifestPath)) && !options.force) {
42
- console.log(chalk.yellow('āš ļø Manifest already exists at .launch/app.json'))
43
- console.log(chalk.gray('Use --force to overwrite'))
44
- return
45
- }
46
-
47
- // Get port
48
- const port = options.port || (options.type === 'api' ? '4000' : '3000')
49
-
50
- // Generate manifest
51
- const manifestSpinner = ora('Generating manifest...').start()
52
- const manifestService = new ManifestService()
53
- const manifest = manifestService.generateManifest(options.type, appName, context, { port })
54
-
55
- // Ensure .launch directory exists
56
- await fs.ensureDir(launchDir)
57
-
58
- // Write manifest
59
- await fs.writeJSON(manifestPath, manifest, { spaces: 2 })
60
- manifestSpinner.succeed('Manifest generated')
61
-
62
- console.log(chalk.green(`\nāœ… Manifest created at .launch/app.json`))
63
- console.log(chalk.gray('\nManifest details:'))
64
- console.log(chalk.gray(' Type:'), manifest.type)
65
- console.log(chalk.gray(' Name:'), manifest.name)
66
- console.log(chalk.gray(' Package:'), manifest.package)
67
- } catch (error) {
68
- const message = error instanceof Error ? error.message : String(error)
69
- console.error(chalk.red('Error:'), message)
70
- process.exit(1)
71
- }
72
- })
73
-
74
- return command
75
- }
@@ -1,53 +0,0 @@
1
- import * as path from 'path'
2
-
3
- import chalk from 'chalk'
4
- import { Command } from 'commander'
5
- import ora from 'ora'
6
-
7
- import { detectMonorepoContext } from '../../../utils/monorepo.js'
8
- import { StartupAlreadyExistsError, InvalidStartupNameError, NotInMonorepoRootError } from '../errors/startup-errors.js'
9
- import { StartupService } from '../services/startup-service.js'
10
-
11
- export function createStartupCommand(): Command {
12
- return new Command('startup:create')
13
- .argument('<name>', 'Name of the startup (lowercase, alphanumeric, hyphens)')
14
- .description('Create a new startup with brand configuration')
15
- .action(async (name: string) => {
16
- console.log(chalk.blue(`\nšŸš€ Creating startup: ${name}\n`))
17
-
18
- const service = new StartupService()
19
-
20
- try {
21
- const spinner = ora('Creating startup structure...').start()
22
-
23
- // Detect monorepo context
24
- const context = await detectMonorepoContext(process.cwd())
25
-
26
- const result = await service.createStartup({ name }, context)
27
-
28
- spinner.succeed('Startup structure created')
29
-
30
- // Success message
31
- const cwd = process.cwd()
32
- console.log(chalk.green(`\nāœ… Startup created successfully at ${path.relative(cwd, result.startupPath)}`))
33
- console.log(chalk.gray(`\nNext steps:\n` + ` 1. Create your first app:\n` + ` - Web app: launch77 create-app webapp <app-name>\n` + ` - API: launch77 create-app api <app-name>\n` + ` - Marketing site: launch77 create-app marketing-site <app-name>\n`))
34
- } catch (error) {
35
- if (error instanceof StartupAlreadyExistsError) {
36
- console.error(chalk.red(`\nāŒ ${error.message}\n`))
37
- process.exit(1)
38
- }
39
-
40
- if (error instanceof InvalidStartupNameError) {
41
- console.error(chalk.red(`\nāŒ ${error.message}\n`))
42
- process.exit(1)
43
- }
44
-
45
- if (error instanceof NotInMonorepoRootError) {
46
- console.error(chalk.red(`\nāŒ ${error.message}\n`))
47
- process.exit(1)
48
- }
49
-
50
- throw error
51
- }
52
- })
53
- }
@@ -1,23 +0,0 @@
1
- export class StartupAlreadyExistsError extends Error {
2
- constructor(
3
- public startupName: string,
4
- public startupPath: string
5
- ) {
6
- super(`Startup ${startupName} already exists at ${startupPath}`)
7
- this.name = 'StartupAlreadyExistsError'
8
- }
9
- }
10
-
11
- export class InvalidStartupNameError extends Error {
12
- constructor(public startupName: string) {
13
- super(`Invalid startup name: "${startupName}"\n\n` + `Startup names must:\n` + ` • Be lowercase only\n` + ` • Can only contain: lowercase letters, numbers, and hyphens\n` + ` • Cannot contain: spaces, uppercase, underscores, periods, or special characters\n\n` + `Valid examples:\n` + ` āœ“ my-startup\n` + ` āœ“ mystartup\n` + ` āœ“ startup123\n\n` + `Invalid examples:\n` + ` āœ— MyStartup (uppercase)\n` + ` āœ— my_startup (underscores)\n` + ` āœ— my.startup (periods)\n` + ` āœ— my startup (spaces)`)
14
- this.name = 'InvalidStartupNameError'
15
- }
16
- }
17
-
18
- export class NotInMonorepoRootError extends Error {
19
- constructor() {
20
- super('Must be run from the monorepo root directory (could not find .launch-monorepo-root.md)')
21
- this.name = 'NotInMonorepoRootError'
22
- }
23
- }
@@ -1,11 +0,0 @@
1
- // Services
2
- export { StartupService } from './services/startup-service.js'
3
-
4
- // Types
5
- export type { CreateStartupRequest, CreateStartupResult } from './types/startup-types.js'
6
-
7
- // Errors
8
- export { StartupAlreadyExistsError, InvalidStartupNameError, NotInMonorepoRootError } from './errors/startup-errors.js'
9
-
10
- // Command
11
- export { createStartupCommand } from './commands/create-startup.js'