@launch77/cli 1.2.0 → 1.4.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.
- package/CHANGELOG.md +22 -0
- package/dist/cli.js +8 -1
- package/dist/cli.js.map +1 -1
- package/dist/infrastructure/git.d.ts +37 -0
- package/dist/infrastructure/git.d.ts.map +1 -0
- package/dist/infrastructure/git.js +82 -0
- package/dist/infrastructure/git.js.map +1 -0
- package/dist/infrastructure/github.d.ts +43 -0
- package/dist/infrastructure/github.d.ts.map +1 -0
- package/dist/infrastructure/github.js +89 -0
- package/dist/infrastructure/github.js.map +1 -0
- package/dist/infrastructure/template-generator.d.ts +1 -1
- package/dist/infrastructure/template-generator.d.ts.map +1 -1
- package/dist/infrastructure/template.d.ts +5 -0
- package/dist/infrastructure/template.d.ts.map +1 -1
- package/dist/infrastructure/template.js +11 -0
- package/dist/infrastructure/template.js.map +1 -1
- package/dist/modules/app/commands/create-app.js +1 -1
- package/dist/modules/app/commands/create-app.js.map +1 -1
- package/dist/modules/app/commands/delete-app.js +1 -1
- package/dist/modules/app/commands/delete-app.js.map +1 -1
- package/dist/modules/app/services/app-svc.d.ts +1 -1
- package/dist/modules/app/services/app-svc.d.ts.map +1 -1
- package/dist/modules/app/services/manifest-svc.d.ts +1 -1
- package/dist/modules/app/services/manifest-svc.d.ts.map +1 -1
- package/dist/modules/catalog/config/catalog-config.test.js +1 -1
- package/dist/modules/catalog/config/catalog-config.test.js.map +1 -1
- package/dist/modules/catalog/schemas/catalog-ui-components.schema.json +2 -18
- package/dist/modules/git/commands/git-connect.d.ts +3 -0
- package/dist/modules/git/commands/git-connect.d.ts.map +1 -0
- package/dist/modules/git/commands/git-connect.js +156 -0
- package/dist/modules/git/commands/git-connect.js.map +1 -0
- package/dist/modules/git/errors/git-errors.d.ts +21 -0
- package/dist/modules/git/errors/git-errors.d.ts.map +1 -0
- package/dist/modules/git/errors/git-errors.js +41 -0
- package/dist/modules/git/errors/git-errors.js.map +1 -0
- package/dist/modules/git/index.d.ts +5 -0
- package/dist/modules/git/index.d.ts.map +1 -0
- package/dist/modules/git/index.js +8 -0
- package/dist/modules/git/index.js.map +1 -0
- package/dist/modules/git/services/git-service.d.ts +24 -0
- package/dist/modules/git/services/git-service.d.ts.map +1 -0
- package/dist/modules/git/services/git-service.js +56 -0
- package/dist/modules/git/services/git-service.js.map +1 -0
- package/dist/modules/git/services/github-service.d.ts +27 -0
- package/dist/modules/git/services/github-service.d.ts.map +1 -0
- package/dist/modules/git/services/github-service.js +45 -0
- package/dist/modules/git/services/github-service.js.map +1 -0
- package/dist/modules/plugin/commands/plugin-create.d.ts +3 -0
- package/dist/modules/plugin/commands/plugin-create.d.ts.map +1 -0
- package/dist/modules/plugin/commands/plugin-create.js +59 -0
- package/dist/modules/plugin/commands/plugin-create.js.map +1 -0
- package/dist/modules/plugin/commands/plugin-install.d.ts.map +1 -1
- package/dist/modules/plugin/commands/plugin-install.js +9 -24
- package/dist/modules/plugin/commands/plugin-install.js.map +1 -1
- package/dist/modules/plugin/errors/plugin-errors.d.ts +24 -1
- package/dist/modules/plugin/errors/plugin-errors.d.ts.map +1 -1
- package/dist/modules/plugin/errors/plugin-errors.js +79 -6
- package/dist/modules/plugin/errors/plugin-errors.js.map +1 -1
- package/dist/modules/plugin/index.d.ts +4 -2
- package/dist/modules/plugin/index.d.ts.map +1 -1
- package/dist/modules/plugin/index.js +4 -2
- package/dist/modules/plugin/index.js.map +1 -1
- package/dist/modules/plugin/lib/plugin-registry.d.ts +6 -12
- package/dist/modules/plugin/lib/plugin-registry.d.ts.map +1 -1
- package/dist/modules/plugin/lib/plugin-registry.js +13 -30
- package/dist/modules/plugin/lib/plugin-registry.js.map +1 -1
- package/dist/modules/plugin/lib/plugin-resolver.d.ts +76 -0
- package/dist/modules/plugin/lib/plugin-resolver.d.ts.map +1 -0
- package/dist/modules/plugin/lib/plugin-resolver.js +128 -0
- package/dist/modules/plugin/lib/plugin-resolver.js.map +1 -0
- package/dist/modules/plugin/lib/plugin-resolver.test.d.ts +2 -0
- package/dist/modules/plugin/lib/plugin-resolver.test.d.ts.map +1 -0
- package/dist/modules/plugin/lib/plugin-resolver.test.js +175 -0
- package/dist/modules/plugin/lib/plugin-resolver.test.js.map +1 -0
- package/dist/modules/plugin/services/plugin-create-service.d.ts +16 -0
- package/dist/modules/plugin/services/plugin-create-service.d.ts.map +1 -0
- package/dist/modules/plugin/services/plugin-create-service.js +47 -0
- package/dist/modules/plugin/services/plugin-create-service.js.map +1 -0
- package/dist/modules/plugin/services/plugin-svc.d.ts +8 -3
- package/dist/modules/plugin/services/plugin-svc.d.ts.map +1 -1
- package/dist/modules/plugin/services/plugin-svc.js +96 -15
- package/dist/modules/plugin/services/plugin-svc.js.map +1 -1
- package/dist/modules/release/commands/release-init.d.ts +3 -0
- package/dist/modules/release/commands/release-init.d.ts.map +1 -0
- package/dist/modules/release/commands/release-init.js +92 -0
- package/dist/modules/release/commands/release-init.js.map +1 -0
- package/dist/modules/release/errors/release-errors.d.ts +7 -0
- package/dist/modules/release/errors/release-errors.d.ts.map +1 -0
- package/dist/modules/release/errors/release-errors.js +13 -0
- package/dist/modules/release/errors/release-errors.js.map +1 -0
- package/dist/modules/release/index.d.ts +4 -0
- package/dist/modules/release/index.d.ts.map +1 -0
- package/dist/modules/release/index.js +7 -0
- package/dist/modules/release/index.js.map +1 -0
- package/dist/modules/release/services/release-service.d.ts +34 -0
- package/dist/modules/release/services/release-service.d.ts.map +1 -0
- package/dist/modules/release/services/release-service.js +154 -0
- package/dist/modules/release/services/release-service.js.map +1 -0
- package/dist/modules/workspace/commands/init-workspace.d.ts.map +1 -1
- package/dist/modules/workspace/commands/init-workspace.js +4 -5
- package/dist/modules/workspace/commands/init-workspace.js.map +1 -1
- package/dist/modules/workspace/services/workspace-service.d.ts +2 -1
- package/dist/modules/workspace/services/workspace-service.d.ts.map +1 -1
- package/dist/modules/workspace/services/workspace-service.js +27 -1
- package/dist/modules/workspace/services/workspace-service.js.map +1 -1
- package/dist/templates/plugin/README.md.hbs +39 -0
- package/dist/{plugins/theme/package.json → templates/plugin/package.json.hbs} +5 -3
- package/dist/templates/plugin/plugin.json.hbs +7 -0
- package/dist/templates/plugin/src/generator.ts.hbs +64 -0
- package/dist/templates/plugin/templates/src/.gitkeep +0 -0
- package/dist/templates/plugin/tsconfig.json +10 -0
- package/dist/{plugins/theme → templates/plugin}/tsup.config.ts +0 -1
- package/dist/templates/workspace/.github/workflows/ci.yml +102 -0
- package/dist/templates/workspace/package.json +16 -1
- package/dist/templates/workspace/turbo.json +5 -0
- package/dist/utils/launch77-context.d.ts +1 -1
- package/dist/utils/launch77-context.d.ts.map +1 -1
- package/dist/utils/launch77-context.js +25 -2
- package/dist/utils/launch77-context.js.map +1 -1
- package/dist/utils/launch77-validation.d.ts +1 -1
- package/dist/utils/launch77-validation.d.ts.map +1 -1
- package/dist/utils/string.d.ts +13 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/string.js +18 -0
- package/dist/utils/string.js.map +1 -0
- package/package.json +7 -10
- package/src/cli.ts +10 -1
- package/src/infrastructure/git.ts +86 -0
- package/src/infrastructure/github.ts +111 -0
- package/src/infrastructure/template-generator.ts +1 -1
- package/src/infrastructure/template.ts +14 -0
- package/src/modules/app/commands/create-app.ts +1 -1
- package/src/modules/app/commands/delete-app.ts +1 -1
- package/src/modules/app/services/app-svc.ts +1 -1
- package/src/modules/app/services/manifest-svc.ts +1 -1
- package/src/modules/catalog/config/catalog-config.test.ts +1 -1
- package/src/modules/git/commands/git-connect.ts +183 -0
- package/src/modules/git/errors/git-errors.ts +44 -0
- package/src/modules/git/index.ts +9 -0
- package/src/modules/git/services/git-service.ts +63 -0
- package/src/modules/git/services/github-service.ts +52 -0
- package/src/modules/plugin/commands/plugin-create.ts +68 -0
- package/src/modules/plugin/commands/plugin-install.ts +9 -26
- package/src/modules/plugin/errors/plugin-errors.ts +87 -6
- package/src/modules/plugin/index.ts +4 -2
- package/src/modules/plugin/lib/plugin-registry.ts +14 -37
- package/src/modules/plugin/lib/plugin-resolver.test.ts +215 -0
- package/src/modules/plugin/lib/plugin-resolver.ts +160 -0
- package/src/modules/plugin/services/plugin-create-service.ts +69 -0
- package/src/modules/plugin/services/plugin-svc.ts +108 -15
- package/src/modules/release/commands/release-init.ts +102 -0
- package/src/modules/release/errors/release-errors.ts +13 -0
- package/src/modules/release/index.ts +8 -0
- package/src/modules/release/services/release-service.ts +170 -0
- package/src/modules/workspace/commands/init-workspace.ts +4 -6
- package/src/modules/workspace/services/workspace-service.ts +30 -1
- package/src/utils/launch77-context.ts +29 -3
- package/src/utils/launch77-validation.ts +1 -1
- package/src/utils/string.ts +17 -0
- package/templates/plugin/README.md.hbs +39 -0
- package/templates/plugin/package.json.hbs +34 -0
- package/templates/plugin/plugin.json.hbs +7 -0
- package/templates/plugin/src/generator.ts.hbs +64 -0
- package/templates/plugin/templates/src/.gitkeep +0 -0
- package/templates/plugin/tsconfig.json +10 -0
- package/templates/plugin/tsup.config.ts +9 -0
- package/templates/workspace/.github/workflows/ci.yml +102 -0
- package/templates/workspace/package.json +5 -0
- package/templates/workspace/turbo.json +5 -0
- package/tests/integration/cli.test.ts +25 -0
- package/tests/integration/setup.ts +20 -0
- package/vitest.config.ts +9 -0
- package/vitest.integration.config.ts +9 -0
- package/dist/app-templates/webapp/.env.ci +0 -6
- package/dist/app-templates/webapp/.env.example +0 -9
- package/dist/app-templates/webapp/.eslintrc.json +0 -6
- package/dist/app-templates/webapp/README.md.hbs +0 -80
- package/dist/app-templates/webapp/app/about/page.tsx.hbs +0 -41
- package/dist/app-templates/webapp/app/dashboard/page.tsx.hbs +0 -51
- package/dist/app-templates/webapp/app/globals.css +0 -31
- package/dist/app-templates/webapp/app/layout.tsx.hbs +0 -26
- package/dist/app-templates/webapp/app/page.tsx.hbs +0 -30
- package/dist/app-templates/webapp/next.config.js +0 -99
- package/dist/app-templates/webapp/package.json.hbs +0 -30
- package/dist/app-templates/webapp/postcss.config.js +0 -6
- package/dist/app-templates/webapp/tailwind.config.ts +0 -24
- package/dist/app-templates/webapp/tsconfig.json +0 -29
- package/dist/app-templates/webapp/vercel.json.hbs +0 -7
- package/dist/modules/catalog/schemas/schemas/catalog-ui-components.schema.json +0 -145
- package/dist/plugins/theme/plugin.json +0 -9
- package/dist/plugins/theme/src/generator.ts +0 -92
- package/dist/plugins/theme/src/utils/config-modifier.ts +0 -142
- package/dist/plugins/theme/src/utils/css-modifier.ts +0 -89
- package/dist/plugins/theme/templates/app/theme-test/page.tsx +0 -156
- package/dist/plugins/theme/templates/src/modules/theme/README.md +0 -209
- package/dist/plugins/theme/templates/src/modules/theme/config/brand.css +0 -23
- package/dist/plugins/theme/tsconfig.json +0 -14
- package/dist/templates/templates/startup/apps/.gitkeep +0 -8
- package/dist/templates/templates/workspace/.launch77/workspace.json +0 -3
- package/dist/templates/templates/workspace/README.md +0 -62
- package/dist/templates/templates/workspace/app-templates/.gitkeep +0 -1
- package/dist/templates/templates/workspace/apps/.gitkeep +0 -1
- package/dist/templates/templates/workspace/libraries/.gitkeep +0 -1
- package/dist/templates/templates/workspace/package.json +0 -31
- package/dist/templates/templates/workspace/plugins/.gitkeep +0 -1
- package/dist/templates/templates/workspace/tsconfig.json +0 -22
- package/dist/templates/templates/workspace/turbo.json +0 -25
- package/launch77-cli-1.2.0.tgz +0 -0
- package/src/modules/plugin/lib/launch77-workspace.code-workspace +0 -14
- /package/dist/templates/{templates/workspace → workspace}/.eslintignore +0 -0
- /package/dist/templates/{templates/workspace → workspace}/.eslintrc.js +0 -0
- /package/dist/templates/{templates/workspace → workspace}/.husky/pre-push +0 -0
- /package/dist/templates/{templates/workspace → workspace}/.lintstagedrc.json +0 -0
- /package/dist/templates/{templates/workspace → workspace}/.prettierrc +0 -0
|
@@ -38,14 +38,12 @@ export function initWorkspaceCommand(): Command {
|
|
|
38
38
|
try {
|
|
39
39
|
const spinner = ora('Creating workspace structure...').start()
|
|
40
40
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
spinner.succeed('Workspace structure created')
|
|
41
|
+
const cwd = process.cwd()
|
|
42
|
+
const result = await service.initWorkspace({ name: workspaceName }, cwd, spinner)
|
|
44
43
|
|
|
45
44
|
// Success message
|
|
46
|
-
|
|
47
|
-
console.log(chalk.
|
|
48
|
-
console.log(chalk.gray(`Next steps:\n` + ` 1. cd ${workspaceName}\n` + ` 2. npm install\n` + ` 3. Create your first app with launch77 commands\n`))
|
|
45
|
+
console.log(chalk.green(`\n✅ Workspace ready at ${path.relative(cwd, result.workspacePath)}\n`))
|
|
46
|
+
console.log(chalk.gray(`Next steps:\n` + ` 1. cd ${workspaceName}\n` + ` 2. Create your first app with launch77 commands\n`))
|
|
49
47
|
} catch (error) {
|
|
50
48
|
if (error instanceof WorkspaceAlreadyExistsError) {
|
|
51
49
|
console.error(chalk.red(`\n❌ ${error.message}\n`))
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import * as path from 'path'
|
|
2
2
|
import { fileURLToPath } from 'url'
|
|
3
3
|
|
|
4
|
+
import { execa } from 'execa'
|
|
5
|
+
|
|
4
6
|
import * as filesystem from '../../../infrastructure/filesystem.js'
|
|
7
|
+
import * as npm from '../../../infrastructure/npm.js'
|
|
5
8
|
import { WorkspaceAlreadyExistsError } from '../errors/workspace-errors.js'
|
|
6
9
|
import { validateWorkspaceName } from '../utils/workspace-validators.js'
|
|
7
10
|
|
|
8
11
|
import type { InitWorkspaceRequest, InitWorkspaceResult } from '../types/workspace-types.js'
|
|
12
|
+
import type { Ora } from 'ora'
|
|
9
13
|
|
|
10
14
|
export class WorkspaceService {
|
|
11
|
-
async initWorkspace(request: InitWorkspaceRequest, cwd: string): Promise<InitWorkspaceResult> {
|
|
15
|
+
async initWorkspace(request: InitWorkspaceRequest, cwd: string, spinner?: Ora): Promise<InitWorkspaceResult> {
|
|
12
16
|
const { name } = request
|
|
13
17
|
|
|
14
18
|
// 1. Validate name
|
|
@@ -38,6 +42,31 @@ export class WorkspaceService {
|
|
|
38
42
|
throw new Error('Failed to create workspace manifest (.launch77/workspace.json)')
|
|
39
43
|
}
|
|
40
44
|
|
|
45
|
+
// 7. Stop spinner before npm install
|
|
46
|
+
if (spinner) {
|
|
47
|
+
spinner.succeed('Workspace structure created')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// 8. Install dependencies
|
|
51
|
+
console.log('\nInstalling dependencies...')
|
|
52
|
+
try {
|
|
53
|
+
await npm.install(workspacePath)
|
|
54
|
+
console.log('✓ Dependencies installed')
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.warn('⚠ Warning: npm install failed:', error instanceof Error ? error.message : String(error))
|
|
57
|
+
console.warn('You may need to run npm install manually in the workspace directory')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 9. Initialize changesets
|
|
61
|
+
console.log('\nInitializing changesets...')
|
|
62
|
+
try {
|
|
63
|
+
await execa('npx', ['changeset', 'init'], { cwd: workspacePath })
|
|
64
|
+
console.log('✓ Changesets initialized')
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.warn('⚠ Warning: changeset init failed:', error instanceof Error ? error.message : String(error))
|
|
67
|
+
console.warn('You may need to run npx changeset init manually in the workspace directory')
|
|
68
|
+
}
|
|
69
|
+
|
|
41
70
|
return {
|
|
42
71
|
workspacePath,
|
|
43
72
|
name,
|
|
@@ -2,7 +2,7 @@ import * as path from 'path'
|
|
|
2
2
|
|
|
3
3
|
import fs from 'fs-extra'
|
|
4
4
|
|
|
5
|
-
export type Launch77LocationType = 'workspace-root' | 'workspace-app' | 'unknown'
|
|
5
|
+
export type Launch77LocationType = 'workspace-root' | 'workspace-app' | 'workspace-library' | 'workspace-plugin' | 'workspace-app-template' | 'unknown'
|
|
6
6
|
|
|
7
7
|
export interface Launch77Context {
|
|
8
8
|
isValid: boolean
|
|
@@ -64,6 +64,9 @@ interface ParsedLocation {
|
|
|
64
64
|
* Parse the directory structure to determine location context
|
|
65
65
|
* Based on patterns:
|
|
66
66
|
* - apps/[name] → workspace-app
|
|
67
|
+
* - libraries/[name] → workspace-library
|
|
68
|
+
* - plugins/[name] → workspace-plugin
|
|
69
|
+
* - app-templates/[name] → workspace-app-template
|
|
67
70
|
* - (empty or root) → workspace-root
|
|
68
71
|
*/
|
|
69
72
|
function parseLocationFromPath(cwdPath: string, workspaceRoot: string): ParsedLocation {
|
|
@@ -84,8 +87,31 @@ function parseLocationFromPath(cwdPath: string, workspaceRoot: string): ParsedLo
|
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
|
|
87
|
-
//
|
|
88
|
-
|
|
90
|
+
// libraries/[lib-name]/...
|
|
91
|
+
if (parts[0] === 'libraries' && parts.length >= 2) {
|
|
92
|
+
return {
|
|
93
|
+
locationType: 'workspace-library',
|
|
94
|
+
appName: parts[1],
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// plugins/[plugin-name]/...
|
|
99
|
+
if (parts[0] === 'plugins' && parts.length >= 2) {
|
|
100
|
+
return {
|
|
101
|
+
locationType: 'workspace-plugin',
|
|
102
|
+
appName: parts[1],
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// app-templates/[template-name]/...
|
|
107
|
+
if (parts[0] === 'app-templates' && parts.length >= 2) {
|
|
108
|
+
return {
|
|
109
|
+
locationType: 'workspace-app-template',
|
|
110
|
+
appName: parts[1],
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Somewhere else in workspace
|
|
89
115
|
return { locationType: 'workspace-root' }
|
|
90
116
|
}
|
|
91
117
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a kebab-case or snake_case string to PascalCase
|
|
3
|
+
*
|
|
4
|
+
* @param str - The string to convert (e.g., "my-plugin" or "my_plugin")
|
|
5
|
+
* @returns PascalCase string (e.g., "MyPlugin")
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* toPascalCase('my-plugin') // 'MyPlugin'
|
|
9
|
+
* toPascalCase('release') // 'Release'
|
|
10
|
+
* toPascalCase('my-awesome-plugin') // 'MyAwesomePlugin'
|
|
11
|
+
*/
|
|
12
|
+
export function toPascalCase(str: string): string {
|
|
13
|
+
return str
|
|
14
|
+
.split(/[-_]/)
|
|
15
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
16
|
+
.join('')
|
|
17
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# {{pluginNamePascal}} Plugin
|
|
2
|
+
|
|
3
|
+
{{description}}
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
launch77 plugin:install {{pluginName}}
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
After installation, the plugin will:
|
|
14
|
+
|
|
15
|
+
- TODO: Describe what the plugin does
|
|
16
|
+
- TODO: List any files created or modified
|
|
17
|
+
- TODO: Explain configuration options
|
|
18
|
+
|
|
19
|
+
## Development
|
|
20
|
+
|
|
21
|
+
### Building
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm run build
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Testing
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm run typecheck
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Template Files
|
|
34
|
+
|
|
35
|
+
The `templates/` directory contains files that will be copied to the target application when this plugin is installed. Add any template files your plugin needs here.
|
|
36
|
+
|
|
37
|
+
## License
|
|
38
|
+
|
|
39
|
+
UNLICENSED
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@{{workspaceName}}/plugin-{{pluginName}}",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "{{description}}",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"private": true,
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/generator.js",
|
|
9
|
+
"bin": {
|
|
10
|
+
"generate": "./dist/generator.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/",
|
|
14
|
+
"templates/",
|
|
15
|
+
"plugin.json"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsup",
|
|
19
|
+
"dev": "tsup --watch",
|
|
20
|
+
"typecheck": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@launch77/plugin-runtime": "^0.1.0",
|
|
24
|
+
"chalk": "^5.3.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.10.0",
|
|
28
|
+
"tsup": "^8.0.0",
|
|
29
|
+
"typescript": "^5.3.0"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import chalk from 'chalk'
|
|
4
|
+
import { StandardGenerator } from '@launch77/plugin-runtime'
|
|
5
|
+
import type { GeneratorContext } from '@launch77/plugin-runtime'
|
|
6
|
+
|
|
7
|
+
export class {{pluginNamePascal}}Generator extends StandardGenerator {
|
|
8
|
+
constructor(context: GeneratorContext) {
|
|
9
|
+
super(context)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
protected async injectCode(): Promise<void> {
|
|
13
|
+
console.log(chalk.cyan('🔧 Setting up {{pluginName}} plugin...\n'))
|
|
14
|
+
|
|
15
|
+
// TODO: Add your plugin's code injection logic here
|
|
16
|
+
// Examples:
|
|
17
|
+
// - Copy template files to the app
|
|
18
|
+
// - Modify package.json
|
|
19
|
+
// - Update configuration files
|
|
20
|
+
|
|
21
|
+
console.log(chalk.green(' ✓ Plugin setup complete\n'))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
protected showNextSteps(): void {
|
|
25
|
+
console.log(chalk.white('\n' + '─'.repeat(60) + '\n'))
|
|
26
|
+
console.log(chalk.cyan('📋 {{pluginNamePascal}} Plugin Installed!\n'))
|
|
27
|
+
console.log(chalk.white('Next Steps:\n'))
|
|
28
|
+
|
|
29
|
+
console.log(chalk.gray('1. TODO: Add your first step'))
|
|
30
|
+
console.log(chalk.cyan(' npm run <command>\n'))
|
|
31
|
+
|
|
32
|
+
console.log(chalk.gray('2. TODO: Add your second step'))
|
|
33
|
+
console.log(chalk.cyan(' npm run <command>\n'))
|
|
34
|
+
|
|
35
|
+
console.log(chalk.white('Documentation:\n'))
|
|
36
|
+
console.log(chalk.gray('See README.md for detailed instructions.\n'))
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// CLI entry point
|
|
41
|
+
async function main() {
|
|
42
|
+
const args = process.argv.slice(2)
|
|
43
|
+
const appPath = args.find((arg) => arg.startsWith('--appPath='))?.split('=')[1]
|
|
44
|
+
const appName = args.find((arg) => arg.startsWith('--appName='))?.split('=')[1]
|
|
45
|
+
const workspaceName = args.find((arg) => arg.startsWith('--workspaceName='))?.split('=')[1]
|
|
46
|
+
const pluginPath = args.find((arg) => arg.startsWith('--pluginPath='))?.split('=')[1]
|
|
47
|
+
|
|
48
|
+
if (!appPath || !appName || !workspaceName || !pluginPath) {
|
|
49
|
+
console.error(chalk.red('Error: Missing required arguments'))
|
|
50
|
+
console.error(chalk.gray('Usage: --appPath=<path> --appName=<name> --workspaceName=<name> --pluginPath=<path>'))
|
|
51
|
+
process.exit(1)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const generator = new {{pluginNamePascal}}Generator({ appPath, appName, workspaceName, pluginPath })
|
|
55
|
+
await generator.run()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
59
|
+
main().catch((error) => {
|
|
60
|
+
console.error(chalk.red('\n❌ Error during plugin setup:'))
|
|
61
|
+
console.error(error)
|
|
62
|
+
process.exit(1)
|
|
63
|
+
})
|
|
64
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
name: CI & Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main, develop]
|
|
6
|
+
push:
|
|
7
|
+
branches: [main, develop]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
pull-requests: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency: ${{ github.workflow }}-${{ github.ref }}
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build-and-test:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
|
|
20
|
+
strategy:
|
|
21
|
+
matrix:
|
|
22
|
+
node-version: [20.x]
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Setup Node.js ${{ matrix.node-version }}
|
|
28
|
+
uses: actions/setup-node@v4
|
|
29
|
+
with:
|
|
30
|
+
node-version: ${{ matrix.node-version }}
|
|
31
|
+
cache: 'npm'
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: npm install
|
|
35
|
+
|
|
36
|
+
- name: Run linting
|
|
37
|
+
run: npm run lint
|
|
38
|
+
|
|
39
|
+
- name: Build packages
|
|
40
|
+
run: npm run build
|
|
41
|
+
|
|
42
|
+
- name: Run type checking
|
|
43
|
+
run: npm run typecheck
|
|
44
|
+
|
|
45
|
+
- name: Run tests
|
|
46
|
+
run: npm run test
|
|
47
|
+
|
|
48
|
+
- name: Run integration tests
|
|
49
|
+
run: npm run test:integration
|
|
50
|
+
|
|
51
|
+
quality-checks:
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v4
|
|
56
|
+
|
|
57
|
+
- name: Setup Node.js 20.x
|
|
58
|
+
uses: actions/setup-node@v4
|
|
59
|
+
with:
|
|
60
|
+
node-version: 20.x
|
|
61
|
+
cache: 'npm'
|
|
62
|
+
|
|
63
|
+
- name: Install dependencies
|
|
64
|
+
run: npm install
|
|
65
|
+
|
|
66
|
+
- name: Check for dependency vulnerabilities
|
|
67
|
+
run: npm audit --audit-level=high
|
|
68
|
+
|
|
69
|
+
- name: Check formatting
|
|
70
|
+
run: npx prettier --check "**/*.{js,jsx,ts,tsx,json,md}"
|
|
71
|
+
|
|
72
|
+
release:
|
|
73
|
+
name: Release
|
|
74
|
+
runs-on: ubuntu-latest
|
|
75
|
+
needs: [build-and-test, quality-checks]
|
|
76
|
+
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
77
|
+
|
|
78
|
+
steps:
|
|
79
|
+
- name: Checkout Repo
|
|
80
|
+
uses: actions/checkout@v4
|
|
81
|
+
|
|
82
|
+
- name: Setup Node.js 20.x
|
|
83
|
+
uses: actions/setup-node@v4
|
|
84
|
+
with:
|
|
85
|
+
node-version: 20.x
|
|
86
|
+
cache: 'npm'
|
|
87
|
+
|
|
88
|
+
- name: Upgrade npm
|
|
89
|
+
run: npm i -g npm@latest
|
|
90
|
+
|
|
91
|
+
- name: Install Dependencies
|
|
92
|
+
run: npm install
|
|
93
|
+
|
|
94
|
+
- name: Create Release Pull Request or Publish to npm
|
|
95
|
+
id: changesets
|
|
96
|
+
uses: changesets/action@v1
|
|
97
|
+
with:
|
|
98
|
+
publish: npm run release
|
|
99
|
+
title: "chore: version packages"
|
|
100
|
+
commit: "chore: version packages"
|
|
101
|
+
env:
|
|
102
|
+
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
|
@@ -13,11 +13,16 @@
|
|
|
13
13
|
"dev": "turbo run dev",
|
|
14
14
|
"build": "turbo run build",
|
|
15
15
|
"test": "turbo run test",
|
|
16
|
+
"test:integration": "turbo run test:integration",
|
|
16
17
|
"lint": "turbo run lint",
|
|
17
18
|
"typecheck": "turbo run typecheck",
|
|
19
|
+
"changeset": "changeset",
|
|
20
|
+
"version-packages": "changeset version",
|
|
21
|
+
"release": "turbo run build lint typecheck test && changeset publish",
|
|
18
22
|
"prepare": "husky"
|
|
19
23
|
},
|
|
20
24
|
"devDependencies": {
|
|
25
|
+
"@changesets/cli": "^2.29.8",
|
|
21
26
|
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
22
27
|
"@typescript-eslint/parser": "^6.0.0",
|
|
23
28
|
"eslint": "^8.56.0",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from 'vitest'
|
|
2
|
+
import { existsSync } from 'fs'
|
|
3
|
+
import { runCli } from './setup.js'
|
|
4
|
+
|
|
5
|
+
describe('CLI Integration Tests', () => {
|
|
6
|
+
beforeAll(() => {
|
|
7
|
+
if (!existsSync('./dist/cli.js')) {
|
|
8
|
+
throw new Error('CLI not built. Run `npm run build` first.')
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('should display version', async () => {
|
|
13
|
+
const { stdout, exitCode } = await runCli(['--version'])
|
|
14
|
+
|
|
15
|
+
expect(exitCode).toBe(0)
|
|
16
|
+
expect(stdout).toMatch(/\d+\.\d+\.\d+/)
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('should display help', async () => {
|
|
20
|
+
const { stdout, exitCode } = await runCli(['--help'])
|
|
21
|
+
|
|
22
|
+
expect(exitCode).toBe(0)
|
|
23
|
+
expect(stdout).toContain('launch77')
|
|
24
|
+
})
|
|
25
|
+
})
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { execa } from 'execa'
|
|
2
|
+
import { fileURLToPath } from 'url'
|
|
3
|
+
import { dirname, join } from 'path'
|
|
4
|
+
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
6
|
+
const CLI_PATH = join(__dirname, '../../dist/cli.js')
|
|
7
|
+
|
|
8
|
+
export async function runCli(args: string[], options?: { cwd?: string }) {
|
|
9
|
+
const result = await execa('node', [CLI_PATH, ...args], {
|
|
10
|
+
reject: false,
|
|
11
|
+
cwd: options?.cwd,
|
|
12
|
+
env: { ...process.env, CI: 'true' },
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
stdout: result.stdout,
|
|
17
|
+
stderr: result.stderr,
|
|
18
|
+
exitCode: result.exitCode ?? 0,
|
|
19
|
+
}
|
|
20
|
+
}
|
package/vitest.config.ts
ADDED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
# CI/CD Build Environment Variables
|
|
2
|
-
# These values allow Next.js to build and prerender static pages in CI
|
|
3
|
-
# Real production values are set in deployment platform (Vercel)
|
|
4
|
-
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
|
5
|
-
NEXT_PUBLIC_API_URL=http://localhost:4000/graphql
|
|
6
|
-
NEXT_PUBLIC_GTM_ID=
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# {{appName}}
|
|
2
|
-
|
|
3
|
-
{{#if startupName}}Part of the {{startupName}} startup{{/if}}
|
|
4
|
-
|
|
5
|
-
A web application built with the Launch77 Platform.
|
|
6
|
-
|
|
7
|
-
## Getting Started
|
|
8
|
-
|
|
9
|
-
1. Install dependencies (from monorepo root):
|
|
10
|
-
```bash
|
|
11
|
-
npm install
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
2. Set up environment variables:
|
|
15
|
-
```bash
|
|
16
|
-
cp .env.example .env.local
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
3. Run the development server:
|
|
20
|
-
```bash
|
|
21
|
-
npm run dev
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Open [http://localhost:{{port}}](http://localhost:{{port}}) in your browser.
|
|
25
|
-
|
|
26
|
-
## Available Scripts
|
|
27
|
-
|
|
28
|
-
- `npm run dev` - Start development server
|
|
29
|
-
- `npm run build` - Build for production
|
|
30
|
-
- `npm run start` - Start production server
|
|
31
|
-
- `npm run lint` - Run ESLint
|
|
32
|
-
- `npm run typecheck` - Run TypeScript type checking
|
|
33
|
-
|
|
34
|
-
## Launch77 Packages
|
|
35
|
-
|
|
36
|
-
This app uses the following Launch77 platform packages:
|
|
37
|
-
|
|
38
|
-
- **@launch77/ui** - Shared component library
|
|
39
|
-
- **@launch77/theme** - Tailwind preset and design tokens
|
|
40
|
-
|
|
41
|
-
## Project Structure
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
app/
|
|
45
|
-
├── layout.tsx # Root layout
|
|
46
|
-
├── page.tsx # Homepage
|
|
47
|
-
├── dashboard/ # Example dashboard page
|
|
48
|
-
├── about/ # About page
|
|
49
|
-
└── globals.css # Global styles (imports @launch77/theme)
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Next Steps
|
|
53
|
-
|
|
54
|
-
1. **Add Authentication**: Implement login/register pages and protect routes
|
|
55
|
-
2. **Connect to API**: Set up API client to connect to your backend
|
|
56
|
-
3. **Add Features**: Build out your application features
|
|
57
|
-
|
|
58
|
-
## Using UI Components
|
|
59
|
-
|
|
60
|
-
```tsx
|
|
61
|
-
import { Button, Card, Input } from '@launch77/ui'
|
|
62
|
-
|
|
63
|
-
export default function MyPage() {
|
|
64
|
-
return (
|
|
65
|
-
<Card>
|
|
66
|
-
<Input placeholder="Enter text" />
|
|
67
|
-
<Button>Submit</Button>
|
|
68
|
-
</Card>
|
|
69
|
-
)
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## Customizing Theme
|
|
74
|
-
|
|
75
|
-
Extend `tailwind.config.ts` for theme customization.
|
|
76
|
-
|
|
77
|
-
## Learn More
|
|
78
|
-
|
|
79
|
-
- [Next.js Documentation](https://nextjs.org/docs)
|
|
80
|
-
- [Launch77 Platform Docs](../../README.md)
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import Link from 'next/link'
|
|
2
|
-
|
|
3
|
-
export default function AboutPage() {
|
|
4
|
-
return (
|
|
5
|
-
<div className="min-h-screen bg-gray-50">
|
|
6
|
-
<nav className="border-b border-gray-200">
|
|
7
|
-
<div className="max-w-7xl mx-auto px-4 py-4">
|
|
8
|
-
<div className="flex items-center justify-between">
|
|
9
|
-
<h1 className="text-xl font-bold text-gray-900">{{appName}}</h1>
|
|
10
|
-
<Link
|
|
11
|
-
href="/"
|
|
12
|
-
className="px-4 py-2 text-sm font-medium text-gray-700 hover:text-gray-900 hover:bg-gray-100 rounded-md transition-colors"
|
|
13
|
-
>
|
|
14
|
-
Home
|
|
15
|
-
</Link>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
</nav>
|
|
19
|
-
|
|
20
|
-
<main className="max-w-3xl mx-auto px-4 py-16">
|
|
21
|
-
<h1 className="text-4xl font-bold text-gray-900 mb-4">
|
|
22
|
-
About {{appName}}
|
|
23
|
-
</h1>
|
|
24
|
-
<div className="prose prose-slate">
|
|
25
|
-
<p className="text-lg text-gray-600 mb-4">
|
|
26
|
-
This is a web application built with the Launch77 Platform.
|
|
27
|
-
</p>
|
|
28
|
-
<p className="text-gray-600 mb-4">
|
|
29
|
-
Launch77 provides a modern development environment with:
|
|
30
|
-
</p>
|
|
31
|
-
<ul className="list-disc list-inside text-gray-600 mb-4 space-y-2">
|
|
32
|
-
<li>Next.js for server-side rendering and routing</li>
|
|
33
|
-
<li>Tailwind CSS for styling</li>
|
|
34
|
-
<li>TypeScript for type safety</li>
|
|
35
|
-
<li>Plugin-based architecture for adding capabilities</li>
|
|
36
|
-
</ul>
|
|
37
|
-
</div>
|
|
38
|
-
</main>
|
|
39
|
-
</div>
|
|
40
|
-
)
|
|
41
|
-
}
|