@launch77/cli 1.4.4 → 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 (141) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/cli.js +1 -4
  3. package/dist/cli.js.map +1 -1
  4. package/dist/infrastructure/package-resolver.d.ts +12 -2
  5. package/dist/infrastructure/package-resolver.d.ts.map +1 -1
  6. package/dist/infrastructure/package-resolver.js +29 -2
  7. package/dist/infrastructure/package-resolver.js.map +1 -1
  8. package/dist/infrastructure/package-resolver.test.js +3 -3
  9. package/dist/infrastructure/package-resolver.test.js.map +1 -1
  10. package/dist/infrastructure/template.d.ts +0 -1
  11. package/dist/infrastructure/template.d.ts.map +1 -1
  12. package/dist/infrastructure/template.js.map +1 -1
  13. package/dist/modules/app/commands/create-app.d.ts.map +1 -1
  14. package/dist/modules/app/commands/create-app.js +8 -13
  15. package/dist/modules/app/commands/create-app.js.map +1 -1
  16. package/dist/modules/app/commands/delete-app.js +1 -1
  17. package/dist/modules/app/commands/delete-app.js.map +1 -1
  18. package/dist/modules/app/commands/validate-manifest.d.ts.map +1 -1
  19. package/dist/modules/app/commands/validate-manifest.js +0 -1
  20. package/dist/modules/app/commands/validate-manifest.js.map +1 -1
  21. package/dist/modules/app/index.d.ts +1 -2
  22. package/dist/modules/app/index.d.ts.map +1 -1
  23. package/dist/modules/app/index.js +0 -1
  24. package/dist/modules/app/index.js.map +1 -1
  25. package/dist/modules/app/lib/app-template-resolver.d.ts.map +1 -1
  26. package/dist/modules/app/lib/app-template-resolver.js +15 -0
  27. package/dist/modules/app/lib/app-template-resolver.js.map +1 -1
  28. package/dist/modules/app/lib/manifest-schema.d.ts +0 -7
  29. package/dist/modules/app/lib/manifest-schema.d.ts.map +1 -1
  30. package/dist/modules/app/lib/manifest-schema.js +0 -2
  31. package/dist/modules/app/lib/manifest-schema.js.map +1 -1
  32. package/dist/modules/app/services/app-svc.d.ts.map +1 -1
  33. package/dist/modules/app/services/app-svc.js +36 -6
  34. package/dist/modules/app/services/app-svc.js.map +1 -1
  35. package/dist/modules/app/services/manifest-svc.d.ts +2 -2
  36. package/dist/modules/app/services/manifest-svc.d.ts.map +1 -1
  37. package/dist/modules/app/services/manifest-svc.js +9 -50
  38. package/dist/modules/app/services/manifest-svc.js.map +1 -1
  39. package/dist/modules/app/types/app-types.d.ts +2 -5
  40. package/dist/modules/app/types/app-types.d.ts.map +1 -1
  41. package/dist/modules/app/types/app-types.js +1 -4
  42. package/dist/modules/app/types/app-types.js.map +1 -1
  43. package/dist/modules/catalog/commands/scan.js +3 -3
  44. package/dist/modules/catalog/commands/scan.js.map +1 -1
  45. package/dist/modules/catalog/services/catalog-svc.d.ts +2 -2
  46. package/dist/modules/catalog/services/catalog-svc.d.ts.map +1 -1
  47. package/dist/modules/catalog/services/catalog-svc.js +2 -2
  48. package/dist/modules/catalog/services/catalog-svc.js.map +1 -1
  49. package/dist/modules/deploy/commands/deploy-init-action.d.ts.map +1 -1
  50. package/dist/modules/deploy/commands/deploy-init-action.js +21 -20
  51. package/dist/modules/deploy/commands/deploy-init-action.js.map +1 -1
  52. package/dist/modules/deploy/commands/deploy-logs-action.d.ts.map +1 -1
  53. package/dist/modules/deploy/commands/deploy-logs-action.js +16 -13
  54. package/dist/modules/deploy/commands/deploy-logs-action.js.map +1 -1
  55. package/dist/modules/deploy/commands/deploy-status-action.d.ts.map +1 -1
  56. package/dist/modules/deploy/commands/deploy-status-action.js +16 -13
  57. package/dist/modules/deploy/commands/deploy-status-action.js.map +1 -1
  58. package/dist/modules/plugin/lib/plugin-resolver.d.ts.map +1 -1
  59. package/dist/modules/plugin/lib/plugin-resolver.js +13 -2
  60. package/dist/modules/plugin/lib/plugin-resolver.js.map +1 -1
  61. package/dist/modules/plugin/lib/plugin-resolver.test.js +2 -0
  62. package/dist/modules/plugin/lib/plugin-resolver.test.js.map +1 -1
  63. package/dist/modules/plugin/services/plugin-svc.d.ts.map +1 -1
  64. package/dist/modules/plugin/services/plugin-svc.js +10 -2
  65. package/dist/modules/plugin/services/plugin-svc.js.map +1 -1
  66. package/dist/modules/plugin/services/plugin-svc.test.js +12 -6
  67. package/dist/modules/plugin/services/plugin-svc.test.js.map +1 -1
  68. package/dist/templates/plugin/package.json.hbs +1 -1
  69. package/dist/templates/plugin/plugin.json.hbs +1 -3
  70. package/dist/utils/validation.d.ts +3 -7
  71. package/dist/utils/validation.d.ts.map +1 -1
  72. package/dist/utils/validation.js +7 -31
  73. package/dist/utils/validation.js.map +1 -1
  74. package/package.json +1 -1
  75. package/src/cli.ts +1 -4
  76. package/src/infrastructure/package-resolver.test.ts +3 -3
  77. package/src/infrastructure/package-resolver.ts +31 -2
  78. package/src/infrastructure/template.ts +0 -1
  79. package/src/modules/app/commands/create-app.ts +8 -16
  80. package/src/modules/app/commands/delete-app.ts +1 -1
  81. package/src/modules/app/commands/validate-manifest.ts +0 -1
  82. package/src/modules/app/index.ts +1 -2
  83. package/src/modules/app/lib/app-template-resolver.ts +16 -0
  84. package/src/modules/app/lib/manifest-schema.ts +0 -5
  85. package/src/modules/app/services/app-svc.ts +46 -7
  86. package/src/modules/app/services/manifest-svc.ts +8 -57
  87. package/src/modules/app/types/app-types.ts +2 -9
  88. package/src/modules/catalog/commands/scan.ts +3 -3
  89. package/src/modules/catalog/services/catalog-svc.ts +4 -4
  90. package/src/modules/deploy/commands/deploy-init-action.ts +23 -20
  91. package/src/modules/deploy/commands/deploy-logs-action.ts +19 -13
  92. package/src/modules/deploy/commands/deploy-status-action.ts +19 -13
  93. package/src/modules/plugin/lib/plugin-resolver.test.ts +2 -0
  94. package/src/modules/plugin/lib/plugin-resolver.ts +13 -2
  95. package/src/modules/plugin/services/plugin-svc.test.ts +12 -6
  96. package/src/modules/plugin/services/plugin-svc.ts +12 -3
  97. package/src/utils/validation.ts +10 -38
  98. package/templates/plugin/package.json.hbs +1 -1
  99. package/templates/plugin/plugin.json.hbs +1 -3
  100. package/dist/modules/app/commands/generate-manifest.d.ts +0 -3
  101. package/dist/modules/app/commands/generate-manifest.d.ts.map +0 -1
  102. package/dist/modules/app/commands/generate-manifest.js +0 -62
  103. package/dist/modules/app/commands/generate-manifest.js.map +0 -1
  104. package/dist/modules/startup/commands/create-startup.d.ts +0 -3
  105. package/dist/modules/startup/commands/create-startup.d.ts.map +0 -1
  106. package/dist/modules/startup/commands/create-startup.js +0 -43
  107. package/dist/modules/startup/commands/create-startup.js.map +0 -1
  108. package/dist/modules/startup/errors/startup-errors.d.ts +0 -13
  109. package/dist/modules/startup/errors/startup-errors.d.ts.map +0 -1
  110. package/dist/modules/startup/errors/startup-errors.js +0 -25
  111. package/dist/modules/startup/errors/startup-errors.js.map +0 -1
  112. package/dist/modules/startup/index.d.ts +0 -5
  113. package/dist/modules/startup/index.d.ts.map +0 -1
  114. package/dist/modules/startup/index.js +0 -7
  115. package/dist/modules/startup/index.js.map +0 -1
  116. package/dist/modules/startup/services/startup-service.d.ts +0 -7
  117. package/dist/modules/startup/services/startup-service.d.ts.map +0 -1
  118. package/dist/modules/startup/services/startup-service.js +0 -43
  119. package/dist/modules/startup/services/startup-service.js.map +0 -1
  120. package/dist/modules/startup/types/startup-types.d.ts +0 -8
  121. package/dist/modules/startup/types/startup-types.d.ts.map +0 -1
  122. package/dist/modules/startup/types/startup-types.js +0 -2
  123. package/dist/modules/startup/types/startup-types.js.map +0 -1
  124. package/dist/modules/startup/utils/startup-validators.d.ts +0 -8
  125. package/dist/modules/startup/utils/startup-validators.d.ts.map +0 -1
  126. package/dist/modules/startup/utils/startup-validators.js +0 -17
  127. package/dist/modules/startup/utils/startup-validators.js.map +0 -1
  128. package/dist/templates/startup/apps/.gitkeep +0 -8
  129. package/dist/utils/monorepo.d.ts +0 -19
  130. package/dist/utils/monorepo.d.ts.map +0 -1
  131. package/dist/utils/monorepo.js +0 -100
  132. package/dist/utils/monorepo.js.map +0 -1
  133. package/src/modules/app/commands/generate-manifest.ts +0 -75
  134. package/src/modules/startup/commands/create-startup.ts +0 -53
  135. package/src/modules/startup/errors/startup-errors.ts +0 -23
  136. package/src/modules/startup/index.ts +0 -11
  137. package/src/modules/startup/services/startup-service.ts +0 -57
  138. package/src/modules/startup/types/startup-types.ts +0 -8
  139. package/src/modules/startup/utils/startup-validators.ts +0 -19
  140. package/src/utils/monorepo.ts +0 -137
  141. package/templates/startup/apps/.gitkeep +0 -8
@@ -3,10 +3,13 @@
3
3
  */
4
4
 
5
5
  /* eslint-disable no-console */
6
+ import * as path from 'path'
7
+
6
8
  import chalk from 'chalk'
9
+ import { detectLaunch77Context } from '@launch77/plugin-runtime'
10
+ import fs from 'fs-extra'
7
11
  import ora from 'ora'
8
12
 
9
- import { detectMonorepoContext } from '../../../utils/monorepo.js'
10
13
  import { DeployService } from '../services/deploy-svc.js'
11
14
  import { getVercelInstallInstructions, isVercelCliInstalled, runVercelCommand, verifyVercelProjectExists } from '../utils/vercel-extended.js'
12
15
 
@@ -16,11 +19,11 @@ import { getVercelInstallInstructions, isVercelCliInstalled, runVercelCommand, v
16
19
  export async function deployStatus() {
17
20
  const deployService = new DeployService()
18
21
 
19
- // Detect monorepo context
20
- const context = await detectMonorepoContext(process.cwd())
22
+ // Detect Launch77 context
23
+ const context = await detectLaunch77Context(process.cwd())
21
24
 
22
- if (context.location !== 'startup-app') {
23
- throw new Error('Must be run from within an app directory (e.g., startups/mycompany/apps/myapp)')
25
+ if (context.locationType !== 'workspace-app') {
26
+ throw new Error('Must be run from within an app directory (e.g., apps/myapp)')
24
27
  }
25
28
 
26
29
  const appPath = process.cwd()
@@ -30,14 +33,17 @@ export async function deployStatus() {
30
33
  // Load manifest
31
34
  const manifest = await deployService.loadManifest()
32
35
 
33
- // Check if this is an API app
34
- if (manifest.type === 'api') {
35
- console.log(chalk.yellow('⚠️ Railway deployments for API apps are not yet supported'))
36
- console.log()
37
- console.log(chalk.cyan('Coming soon! For now, you can check your deployment status at:'))
38
- console.log(chalk.white(' Railway.app dashboard'))
39
- console.log(chalk.white(' Fly.io dashboard'))
40
- console.log(chalk.white(' • Render.com dashboard'))
36
+ // Check template type from app's package.json
37
+ const appPackageJsonPath = path.join(appPath, 'package.json')
38
+ const appPackageJson = await fs.readJson(appPackageJsonPath)
39
+ const templatePackage = appPackageJson.launch77?.template?.package
40
+
41
+ // Only allow webapp apps to deploy to Vercel
42
+ const isWebapp = templatePackage === 'webapp' || templatePackage === '@launch77-shared/app-template-webapp'
43
+
44
+ if (!isWebapp) {
45
+ console.log(chalk.yellow('⚠️ Vercel deployment only supports webapp apps'))
46
+ console.log(chalk.gray('Other app types coming soon'))
41
47
  console.log()
42
48
  return
43
49
  }
@@ -120,6 +120,7 @@ describe('Plugin Resolver', () => {
120
120
  await fs.ensureDir(pluginPath)
121
121
  await fs.ensureDir(path.join(pluginPath, 'dist'))
122
122
  await fs.writeFile(path.join(pluginPath, 'plugin.json'), JSON.stringify({ name: 'my-plugin', version: '1.0.0' }))
123
+ await fs.writeFile(path.join(pluginPath, 'package.json'), JSON.stringify({ name: 'my-plugin', version: '0.0.1' }))
123
124
  await fs.writeFile(path.join(pluginPath, 'dist/generator.js'), 'console.log("test")')
124
125
 
125
126
  const result = await resolver.resolveLocation('my-plugin', tempDir)
@@ -128,6 +129,7 @@ describe('Plugin Resolver', () => {
128
129
  source: 'local',
129
130
  resolvedName: 'my-plugin',
130
131
  localPath: pluginPath,
132
+ version: '0.0.1',
131
133
  })
132
134
  })
133
135
 
@@ -21,10 +21,21 @@ export class PluginResolver extends PackageResolver {
21
21
  }
22
22
 
23
23
  protected async verify(localPath: string): Promise<boolean> {
24
- // Verify it's a valid plugin (has plugin.json and dist/generator.js)
24
+ // Verify it's a valid plugin (has plugin.json, dist/generator.js, and package.json with version)
25
25
  const hasPluginJson = await fs.pathExists(path.join(localPath, 'plugin.json'))
26
26
  const hasGenerator = await fs.pathExists(path.join(localPath, 'dist/generator.js'))
27
+ const hasPackageJson = await fs.pathExists(path.join(localPath, 'package.json'))
27
28
 
28
- return hasPluginJson && hasGenerator
29
+ if (!hasPluginJson || !hasGenerator || !hasPackageJson) {
30
+ return false
31
+ }
32
+
33
+ // Verify package.json has a version field
34
+ try {
35
+ const packageJson = await fs.readJson(path.join(localPath, 'package.json'))
36
+ return !!packageJson.version
37
+ } catch {
38
+ return false
39
+ }
29
40
  }
30
41
  }
@@ -159,9 +159,9 @@ describe('PluginService', () => {
159
159
 
160
160
  const result = await (service as any).validatePluginTargets(pluginDir, 'test-plugin', 'app')
161
161
  expect(result).toEqual({
162
- name: 'test-plugin',
163
- version: '1.0.0',
164
162
  targets: ['app', 'library'],
163
+ pluginDependencies: undefined,
164
+ libraryDependencies: undefined,
165
165
  })
166
166
  })
167
167
 
@@ -175,8 +175,11 @@ describe('PluginService', () => {
175
175
  })
176
176
 
177
177
  const result = await (service as any).validatePluginTargets(pluginDir, 'multi-target-plugin', 'library')
178
- expect(result.targets).toContain('library')
179
- expect(result.targets).toHaveLength(4)
178
+ expect(result).toEqual({
179
+ targets: ['app', 'library', 'plugin', 'app-template'],
180
+ pluginDependencies: undefined,
181
+ libraryDependencies: undefined,
182
+ })
180
183
  })
181
184
 
182
185
  test('should handle plugin.json with optional fields (pluginDependencies, libraryDependencies)', async () => {
@@ -191,8 +194,11 @@ describe('PluginService', () => {
191
194
  })
192
195
 
193
196
  const result = await (service as any).validatePluginTargets(pluginDir, 'full-plugin', 'app')
194
- expect(result.pluginDependencies).toEqual({ 'other-plugin': '^1.0.0' })
195
- expect(result.libraryDependencies).toEqual({ react: '^18.0.0' })
197
+ expect(result).toEqual({
198
+ targets: ['app'],
199
+ pluginDependencies: { 'other-plugin': '^1.0.0' },
200
+ libraryDependencies: { react: '^18.0.0' },
201
+ })
196
202
  })
197
203
 
198
204
  // Error scenarios - test exact error messages
@@ -50,7 +50,7 @@ export class PluginService {
50
50
  /**
51
51
  * Validate plugin name, resolve its location, and download if needed
52
52
  */
53
- private async validateAndResolvePlugin(pluginName: string, workspaceRoot: string, logger: (message: string) => void): Promise<{ pluginPath: string; source: 'local' | 'npm'; npmPackage?: string }> {
53
+ private async validateAndResolvePlugin(pluginName: string, workspaceRoot: string, logger: (message: string) => void): Promise<{ pluginPath: string; source: 'local' | 'npm'; npmPackage?: string; version: string }> {
54
54
  logger(chalk.blue(`\n🔍 Resolving plugin "${pluginName}"...`))
55
55
  logger(` ├─ Validating plugin name...`)
56
56
 
@@ -64,15 +64,23 @@ export class PluginService {
64
64
  const resolution = await this.pluginResolver.resolveLocation(pluginName, workspaceRoot)
65
65
 
66
66
  let pluginPath: string
67
+ let version: string
67
68
 
68
69
  if (resolution.source === 'local') {
69
70
  logger(` │ └─ ${chalk.green('✓')} Found local plugin`)
70
71
  pluginPath = resolution.localPath!
72
+ version = resolution.version! // Local plugins always have version after verification
71
73
  } else {
72
74
  logger(` │ └─ ${chalk.dim('Not found locally')}`)
73
75
  logger(` ├─ Resolving to npm package: ${chalk.cyan(resolution.npmPackage)}`)
74
76
 
75
77
  pluginPath = await this.downloadNpmPlugin(resolution.npmPackage!, workspaceRoot, logger)
78
+
79
+ // Read version from downloaded package
80
+ const packageJsonPath = path.join(pluginPath, 'package.json')
81
+ const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8')
82
+ const packageJson = JSON.parse(packageJsonContent)
83
+ version = packageJson.version
76
84
  }
77
85
 
78
86
  logger(` └─ ${chalk.green('✓')} Plugin resolved\n`)
@@ -81,6 +89,7 @@ export class PluginService {
81
89
  pluginPath,
82
90
  source: resolution.source,
83
91
  npmPackage: resolution.npmPackage,
92
+ version,
84
93
  }
85
94
  }
86
95
 
@@ -130,7 +139,7 @@ export class PluginService {
130
139
  const { pluginName } = request
131
140
 
132
141
  const currentTarget = this.validateContext(context)
133
- const { pluginPath, source, npmPackage } = await this.validateAndResolvePlugin(pluginName, context.workspaceRoot, logger)
142
+ const { pluginPath, source, npmPackage, version } = await this.validateAndResolvePlugin(pluginName, context.workspaceRoot, logger)
134
143
  const metadata = await this.validatePluginTargets(pluginPath, pluginName, currentTarget)
135
144
 
136
145
  const packagePath = this.getPackagePath(context)
@@ -143,7 +152,7 @@ export class PluginService {
143
152
  await this.writePluginManifest(packagePath, {
144
153
  pluginName,
145
154
  packageName,
146
- version: metadata.version,
155
+ version,
147
156
  source,
148
157
  })
149
158
 
@@ -2,7 +2,7 @@ import * as path from 'path'
2
2
 
3
3
  import chalk from 'chalk'
4
4
 
5
- import type { MonorepoContext } from './monorepo.js'
5
+ import type { Launch77Context } from '@launch77/plugin-runtime'
6
6
 
7
7
  /**
8
8
  * Validation result with helpful error messages
@@ -12,50 +12,22 @@ export interface ValidationResult {
12
12
  errorMessage?: string
13
13
  }
14
14
 
15
- /**
16
- * Validate that we're in a startup context (for create-app)
17
- */
18
- export function validateStartupContext(context: MonorepoContext): ValidationResult {
19
- if (!context.isValid) {
20
- return {
21
- valid: false,
22
- errorMessage: 'Must be run from within a Launch77 monorepo (could not find .launch-monorepo-root.md)',
23
- }
24
- }
25
-
26
- if (context.location !== 'startup-root' && context.location !== 'startup-app') {
27
- return {
28
- valid: false,
29
- errorMessage: `Command must be run from a startup directory.\n\n` + `${chalk.gray('Current location:')} ${context.location}\n` + `${chalk.gray('Expected:')} Within startups/<startup-name>/\n\n` + `${chalk.yellow('Navigate to a startup first:')}\n` + ` cd startups/<startup-name>/\n\n` + `${chalk.yellow('Or create a startup:')}\n` + ` launch77 create-startup <startup-name>`,
30
- }
31
- }
32
-
33
- if (!context.appsDir) {
34
- return {
35
- valid: false,
36
- errorMessage: `Could not determine apps directory for location: ${context.location}\n` + `This is a bug. Please report it.`,
37
- }
38
- }
39
-
40
- return { valid: true }
41
- }
42
-
43
15
  /**
44
16
  * Validate that we're inside an app directory (for plugin:install)
45
17
  */
46
- export function validateAppContext(context: MonorepoContext): ValidationResult {
18
+ export function validateAppContext(context: Launch77Context): ValidationResult {
47
19
  if (!context.isValid) {
48
20
  return {
49
21
  valid: false,
50
- errorMessage: 'Must be run from within a Launch77 monorepo (could not find .launch-monorepo-root.md)',
22
+ errorMessage: 'Must be run from within a Launch77 workspace (could not find .launch77/workspace.json)',
51
23
  }
52
24
  }
53
25
 
54
- // Must be inside an app, not just a startup
55
- if (context.location !== 'startup-app') {
26
+ // Must be inside an app
27
+ if (context.locationType !== 'workspace-app') {
56
28
  return {
57
29
  valid: false,
58
- errorMessage: `plugin:install must be run from within an app directory.\n\n` + `${chalk.gray('Current location:')} ${context.location}\n` + `${chalk.gray('Expected:')} startups/<startup-name>/apps/<app-name>/\n\n` + `${chalk.yellow('Navigate to an app directory:')}\n` + ` cd startups/<startup-name>/apps/<app-name>/\n\n` + `${chalk.yellow('Or create an app first:')}\n` + ` cd startups/<startup-name>/\n` + ` launch77 app:create api <app-name>`,
30
+ errorMessage: `plugin:install must be run from within an app directory.\n\n` + `${chalk.gray('Current location:')} ${context.locationType}\n` + `${chalk.gray('Expected:')} apps/<app-name>/\n\n` + `${chalk.yellow('Navigate to an app directory:')}\n` + ` cd apps/<app-name>/\n\n` + `${chalk.yellow('Or create an app first:')}\n` + ` launch77 app:create <template> <app-name>`,
59
31
  }
60
32
  }
61
33
 
@@ -73,16 +45,16 @@ export function validateAppContext(context: MonorepoContext): ValidationResult {
73
45
  * Get the app directory path
74
46
  * Returns null if not in an app context
75
47
  */
76
- export function getAppDirectory(context: MonorepoContext): string | null {
77
- if (context.location !== 'startup-app') {
48
+ export function getAppDirectory(context: Launch77Context): string | null {
49
+ if (context.locationType !== 'workspace-app') {
78
50
  return null
79
51
  }
80
52
 
81
- if (!context.monorepoRoot || !context.startupName || !context.appName) {
53
+ if (!context.workspaceRoot || !context.appName) {
82
54
  return null
83
55
  }
84
56
 
85
- return path.join(context.monorepoRoot, 'startups', context.startupName, 'apps', context.appName)
57
+ return path.join(context.workspaceRoot, 'apps', context.appName)
86
58
  }
87
59
 
88
60
  /**
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@{{workspaceName}}/plugin-{{pluginName}}",
3
- "version": "1.0.0",
3
+ "version": "0.0.1",
4
4
  "description": "{{description}}",
5
5
  "license": "UNLICENSED",
6
6
  "private": true,
@@ -1,7 +1,5 @@
1
1
  {
2
- "name": "{{pluginName}}",
3
- "version": "1.0.0",
4
- "description": "{{description}}",
2
+ "targets": ["app", "library"],
5
3
  "pluginDependencies": {},
6
4
  "libraryDependencies": {}
7
5
  }
@@ -1,3 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function generateManifestCommand(): Command;
3
- //# sourceMappingURL=generate-manifest.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"generate-manifest.d.ts","sourceRoot":"","sources":["../../../../src/modules/app/commands/generate-manifest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAQnC,wBAAgB,uBAAuB,IAAI,OAAO,CA8DjD"}
@@ -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