@launch77/cli 1.7.2 → 1.7.4
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 +10 -0
- package/dist/infrastructure/package-resolver.test.js +9 -7
- package/dist/infrastructure/package-resolver.test.js.map +1 -1
- package/dist/modules/app/commands/create-app.d.ts.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.d.ts.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/lib/app-template-resolver.d.ts +1 -1
- package/dist/modules/app/lib/app-template-resolver.d.ts.map +1 -1
- package/dist/modules/app/lib/app-template-resolver.js +1 -1
- package/dist/modules/app/lib/app-template-resolver.js.map +1 -1
- package/dist/modules/app/services/app-svc.d.ts +1 -0
- package/dist/modules/app/services/app-svc.d.ts.map +1 -1
- package/dist/modules/app/services/app-svc.js +4 -4
- package/dist/modules/app/services/app-svc.js.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/commands/scan.d.ts.map +1 -1
- package/dist/modules/catalog/commands/scan.js +1 -1
- package/dist/modules/catalog/commands/scan.js.map +1 -1
- package/dist/modules/catalog/services/catalog-svc.d.ts.map +1 -1
- package/dist/modules/deploy/commands/deploy-init-action.js +1 -1
- package/dist/modules/deploy/commands/deploy-init-action.js.map +1 -1
- package/dist/modules/deploy/commands/deploy-logs-action.js +1 -1
- package/dist/modules/deploy/commands/deploy-logs-action.js.map +1 -1
- package/dist/modules/deploy/commands/deploy-status-action.js +1 -1
- package/dist/modules/deploy/commands/deploy-status-action.js.map +1 -1
- package/dist/modules/git/commands/git-connect.d.ts.map +1 -1
- package/dist/modules/git/commands/git-connect.js +3 -3
- package/dist/modules/git/commands/git-connect.js.map +1 -1
- package/dist/modules/library/commands/create-library.d.ts.map +1 -1
- package/dist/modules/library/commands/create-library.js +1 -1
- package/dist/modules/library/commands/create-library.js.map +1 -1
- package/dist/modules/library/commands/delete-library.d.ts.map +1 -1
- package/dist/modules/library/commands/delete-library.js +1 -1
- package/dist/modules/library/commands/delete-library.js.map +1 -1
- package/dist/modules/library/services/library-create-svc.js +1 -1
- package/dist/modules/library/services/library-create-svc.js.map +1 -1
- package/dist/modules/library/services/library-svc.d.ts +1 -0
- package/dist/modules/library/services/library-svc.d.ts.map +1 -1
- package/dist/modules/library/services/library-svc.js +3 -2
- package/dist/modules/library/services/library-svc.js.map +1 -1
- package/dist/modules/plugin/commands/delete-plugin.d.ts.map +1 -1
- package/dist/modules/plugin/commands/delete-plugin.js +1 -2
- package/dist/modules/plugin/commands/delete-plugin.js.map +1 -1
- package/dist/modules/plugin/commands/plugin-create.d.ts.map +1 -1
- package/dist/modules/plugin/commands/plugin-create.js +1 -1
- package/dist/modules/plugin/commands/plugin-create.js.map +1 -1
- package/dist/modules/plugin/commands/plugin-install.d.ts.map +1 -1
- package/dist/modules/plugin/commands/plugin-install.js +1 -2
- package/dist/modules/plugin/commands/plugin-install.js.map +1 -1
- package/dist/modules/plugin/index.d.ts +3 -3
- package/dist/modules/plugin/index.d.ts.map +1 -1
- package/dist/modules/plugin/index.js +2 -3
- package/dist/modules/plugin/index.js.map +1 -1
- package/dist/modules/plugin/lib/plugin-resolver.test.js +10 -6
- package/dist/modules/plugin/lib/plugin-resolver.test.js.map +1 -1
- package/dist/modules/plugin/services/plugin-create-service.d.ts +1 -0
- package/dist/modules/plugin/services/plugin-create-service.d.ts.map +1 -1
- package/dist/modules/plugin/services/plugin-create-service.js +4 -3
- package/dist/modules/plugin/services/plugin-create-service.js.map +1 -1
- package/dist/modules/plugin/services/plugin-svc.test.js +34 -30
- package/dist/modules/plugin/services/plugin-svc.test.js.map +1 -1
- package/dist/modules/release/commands/release-init.d.ts.map +1 -1
- package/dist/modules/release/commands/release-init.js +2 -2
- package/dist/modules/release/commands/release-init.js.map +1 -1
- package/dist/modules/release/services/release-service.d.ts.map +1 -1
- package/dist/modules/release/services/release-service.js +3 -3
- package/dist/modules/release/services/release-service.js.map +1 -1
- package/dist/modules/workspace/services/workspace-service.d.ts +1 -0
- package/dist/modules/workspace/services/workspace-service.d.ts.map +1 -1
- package/dist/modules/workspace/services/workspace-service.js +3 -2
- package/dist/modules/workspace/services/workspace-service.js.map +1 -1
- package/dist/templates/plugin/README.md.hbs +10 -0
- package/dist/templates/plugin/package.json.hbs +1 -1
- package/dist/templates/plugin/scripts/validate-plugin-json.js +13 -2
- package/dist/templates/workspace/.eslintignore +2 -1
- package/package.json +3 -3
- package/src/infrastructure/package-resolver.test.ts +9 -8
- package/src/modules/app/commands/create-app.ts +1 -1
- package/src/modules/app/commands/delete-app.ts +1 -1
- package/src/modules/app/lib/app-template-resolver.ts +1 -2
- package/src/modules/app/services/app-svc.ts +6 -7
- package/src/modules/app/services/manifest-svc.ts +1 -1
- package/src/modules/catalog/commands/scan.ts +1 -2
- package/src/modules/catalog/services/catalog-svc.ts +1 -1
- package/src/modules/deploy/commands/deploy-init-action.ts +1 -1
- package/src/modules/deploy/commands/deploy-logs-action.ts +1 -1
- package/src/modules/deploy/commands/deploy-status-action.ts +1 -1
- package/src/modules/git/commands/git-connect.ts +3 -3
- package/src/modules/library/commands/create-library.ts +1 -1
- package/src/modules/library/commands/delete-library.ts +1 -1
- package/src/modules/library/services/library-create-svc.ts +1 -1
- package/src/modules/library/services/library-svc.ts +3 -2
- package/src/modules/plugin/commands/delete-plugin.ts +1 -3
- package/src/modules/plugin/commands/plugin-create.ts +1 -1
- package/src/modules/plugin/commands/plugin-install.ts +1 -3
- package/src/modules/plugin/index.ts +4 -6
- package/src/modules/plugin/lib/plugin-resolver.test.ts +10 -7
- package/src/modules/plugin/services/plugin-create-service.ts +4 -3
- package/src/modules/plugin/services/plugin-svc.test.ts +52 -32
- package/src/modules/release/commands/release-init.ts +2 -2
- package/src/modules/release/services/release-service.ts +4 -3
- package/src/modules/workspace/services/workspace-service.ts +3 -2
- package/templates/plugin/README.md.hbs +10 -0
- package/templates/plugin/package.json.hbs +1 -1
- package/templates/plugin/scripts/validate-plugin-json.js +13 -2
- package/templates/workspace/.eslintignore +2 -1
- package/dist/infrastructure/npm-package.d.ts +0 -42
- package/dist/infrastructure/npm-package.d.ts.map +0 -1
- package/dist/infrastructure/npm-package.js +0 -46
- package/dist/infrastructure/npm-package.js.map +0 -1
- package/dist/infrastructure/npm.d.ts +0 -9
- package/dist/infrastructure/npm.d.ts.map +0 -1
- package/dist/infrastructure/npm.js +0 -17
- package/dist/infrastructure/npm.js.map +0 -1
- package/dist/infrastructure/package-resolver.d.ts +0 -117
- package/dist/infrastructure/package-resolver.d.ts.map +0 -1
- package/dist/infrastructure/package-resolver.js +0 -170
- package/dist/infrastructure/package-resolver.js.map +0 -1
- package/dist/modules/plugin/errors/plugin-errors.d.ts +0 -51
- package/dist/modules/plugin/errors/plugin-errors.d.ts.map +0 -1
- package/dist/modules/plugin/errors/plugin-errors.js +0 -130
- package/dist/modules/plugin/errors/plugin-errors.js.map +0 -1
- package/dist/modules/plugin/lib/plugin-resolver.d.ts +0 -14
- package/dist/modules/plugin/lib/plugin-resolver.d.ts.map +0 -1
- package/dist/modules/plugin/lib/plugin-resolver.js +0 -36
- package/dist/modules/plugin/lib/plugin-resolver.js.map +0 -1
- package/dist/modules/plugin/services/plugin-svc.d.ts +0 -42
- package/dist/modules/plugin/services/plugin-svc.d.ts.map +0 -1
- package/dist/modules/plugin/services/plugin-svc.js +0 -257
- package/dist/modules/plugin/services/plugin-svc.js.map +0 -1
- package/dist/modules/plugin/types/plugin-types.d.ts +0 -25
- package/dist/modules/plugin/types/plugin-types.d.ts.map +0 -1
- package/dist/modules/plugin/types/plugin-types.js +0 -2
- package/dist/modules/plugin/types/plugin-types.js.map +0 -1
- package/src/infrastructure/npm-package.ts +0 -73
- package/src/infrastructure/npm.ts +0 -18
- package/src/infrastructure/package-resolver.ts +0 -223
- package/src/modules/plugin/errors/plugin-errors.ts +0 -145
- package/src/modules/plugin/lib/plugin-resolver.ts +0 -41
- package/src/modules/plugin/services/plugin-svc.ts +0 -303
- package/src/modules/plugin/types/plugin-types.ts +0 -29
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
import * as path from 'path'
|
|
2
|
-
import * as fs from 'fs/promises'
|
|
3
|
-
|
|
4
|
-
import chalk from 'chalk'
|
|
5
|
-
import { execa } from 'execa'
|
|
6
|
-
import fsExtra from 'fs-extra'
|
|
7
|
-
import { readPluginMetadata } from '@launch77/plugin-runtime'
|
|
8
|
-
|
|
9
|
-
import { downloadNpmPackage } from '../../../infrastructure/npm-package.js'
|
|
10
|
-
import * as npm from '../../../infrastructure/npm.js'
|
|
11
|
-
import { validateWorkspaceContext } from '../../../utils/launch77-validation.js'
|
|
12
|
-
import { validateAppName } from '../../../utils/validation.js'
|
|
13
|
-
import { PluginInstallationError, InvalidPluginContextError, createInvalidContextError, MissingPluginTargetsError, createInvalidTargetError, NpmInstallationError, PluginResolutionError, PluginDirectoryNotFoundError, InvalidPluginNameError } from '../errors/plugin-errors.js'
|
|
14
|
-
import { PluginResolver } from '../lib/plugin-resolver.js'
|
|
15
|
-
|
|
16
|
-
import type { Launch77Context, Launch77LocationType, Launch77PackageManifest, InstalledPluginMetadata, PluginMetadata } from '@launch77/plugin-runtime'
|
|
17
|
-
import type { InstallPluginRequest, InstallPluginResult, DeletePluginRequest, DeletePluginResult } from '../types/plugin-types.js'
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Map location type to target string
|
|
21
|
-
*/
|
|
22
|
-
function locationTypeToTarget(locationType: Launch77LocationType): string | null {
|
|
23
|
-
switch (locationType) {
|
|
24
|
-
case 'workspace-app':
|
|
25
|
-
return 'app'
|
|
26
|
-
case 'workspace-library':
|
|
27
|
-
return 'library'
|
|
28
|
-
case 'workspace-plugin':
|
|
29
|
-
return 'plugin'
|
|
30
|
-
case 'workspace-app-template':
|
|
31
|
-
return 'app-template'
|
|
32
|
-
default:
|
|
33
|
-
return null
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export class PluginService {
|
|
38
|
-
private pluginResolver: PluginResolver
|
|
39
|
-
|
|
40
|
-
constructor() {
|
|
41
|
-
this.pluginResolver = new PluginResolver()
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Validate that we're in a valid package directory and return the target type
|
|
46
|
-
*/
|
|
47
|
-
private validateContext(context: Launch77Context): string {
|
|
48
|
-
const currentTarget = locationTypeToTarget(context.locationType)
|
|
49
|
-
if (!currentTarget) throw createInvalidContextError(context.locationType)
|
|
50
|
-
if (!context.appName) throw new InvalidPluginContextError('Could not determine package name. This is a bug. Please report it.')
|
|
51
|
-
return currentTarget
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Validate plugin name, resolve its location, and download if needed
|
|
56
|
-
*/
|
|
57
|
-
private async validateAndResolvePlugin(pluginName: string, workspaceRoot: string, logger: (message: string) => void): Promise<{ pluginPath: string; source: 'local' | 'npm'; npmPackage?: string; version: string }> {
|
|
58
|
-
logger(chalk.blue(`\n🔍 Resolving plugin "${pluginName}"...`))
|
|
59
|
-
logger(` ├─ Validating plugin name...`)
|
|
60
|
-
|
|
61
|
-
const validation = this.pluginResolver.validateInput(pluginName)
|
|
62
|
-
if (!validation.isValid) {
|
|
63
|
-
throw new PluginResolutionError(pluginName, validation.error || 'Invalid plugin name')
|
|
64
|
-
}
|
|
65
|
-
logger(` │ └─ ${chalk.green('✓')} Valid plugin name`)
|
|
66
|
-
|
|
67
|
-
logger(` ├─ Checking local workspace: ${chalk.dim(`plugins/${pluginName}`)}`)
|
|
68
|
-
const resolution = await this.pluginResolver.resolveLocation(pluginName, workspaceRoot)
|
|
69
|
-
|
|
70
|
-
let pluginPath: string
|
|
71
|
-
let version: string
|
|
72
|
-
|
|
73
|
-
if (resolution.source === 'local') {
|
|
74
|
-
logger(` │ └─ ${chalk.green('✓')} Found local plugin`)
|
|
75
|
-
pluginPath = resolution.localPath!
|
|
76
|
-
version = resolution.version! // Local plugins always have version after verification
|
|
77
|
-
} else {
|
|
78
|
-
logger(` │ └─ ${chalk.dim('Not found locally')}`)
|
|
79
|
-
logger(` ├─ Resolving to npm package: ${chalk.cyan(resolution.npmPackage)}`)
|
|
80
|
-
|
|
81
|
-
pluginPath = await this.downloadNpmPlugin(resolution.npmPackage!, workspaceRoot, logger)
|
|
82
|
-
|
|
83
|
-
// Read version from downloaded package
|
|
84
|
-
const packageJsonPath = path.join(pluginPath, 'package.json')
|
|
85
|
-
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8')
|
|
86
|
-
const packageJson = JSON.parse(packageJsonContent)
|
|
87
|
-
version = packageJson.version
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
logger(` └─ ${chalk.green('✓')} Plugin resolved\n`)
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
pluginPath,
|
|
94
|
-
source: resolution.source,
|
|
95
|
-
npmPackage: resolution.npmPackage,
|
|
96
|
-
version,
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Read plugin metadata and validate it supports the current target
|
|
102
|
-
*/
|
|
103
|
-
private async validatePluginTargets(pluginPath: string, pluginName: string, currentTarget: string): Promise<PluginMetadata> {
|
|
104
|
-
const metadata = await readPluginMetadata(pluginPath)
|
|
105
|
-
|
|
106
|
-
if (!metadata.targets || metadata.targets.length === 0) {
|
|
107
|
-
throw new MissingPluginTargetsError(pluginName)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (!metadata.targets.includes(currentTarget)) {
|
|
111
|
-
throw createInvalidTargetError(pluginName, currentTarget, metadata.targets)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return metadata
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Check if plugin is already installed and return early-exit result if so
|
|
119
|
-
*/
|
|
120
|
-
private async checkExistingInstallation(pluginName: string, packagePath: string, logger: (message: string) => void): Promise<InstallPluginResult | null> {
|
|
121
|
-
const existingInstallation = await this.isPluginInstalled(pluginName, packagePath)
|
|
122
|
-
if (existingInstallation) {
|
|
123
|
-
logger(chalk.yellow(`\nℹ️ Plugin '${pluginName}' is already installed in this package.\n`))
|
|
124
|
-
logger(`Package: ${chalk.cyan(existingInstallation.package)} (${existingInstallation.source})`)
|
|
125
|
-
logger(`Version: ${existingInstallation.version}`)
|
|
126
|
-
logger(`Installed: ${existingInstallation.installedAt}\n`)
|
|
127
|
-
logger(chalk.gray('To reinstall: Remove from package.json launch77.installedPlugins'))
|
|
128
|
-
logger(chalk.gray('(plugin:remove command coming soon)\n'))
|
|
129
|
-
return {
|
|
130
|
-
pluginName,
|
|
131
|
-
filesInstalled: false,
|
|
132
|
-
packageJsonUpdated: false,
|
|
133
|
-
dependenciesInstalled: false,
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return null
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Install a plugin to the current package
|
|
141
|
-
*/
|
|
142
|
-
async installPlugin(request: InstallPluginRequest, context: Launch77Context, logger: (message: string) => void = console.log): Promise<InstallPluginResult> {
|
|
143
|
-
const { pluginName } = request
|
|
144
|
-
|
|
145
|
-
const currentTarget = this.validateContext(context)
|
|
146
|
-
const { pluginPath, source, npmPackage, version } = await this.validateAndResolvePlugin(pluginName, context.workspaceRoot, logger)
|
|
147
|
-
const metadata = await this.validatePluginTargets(pluginPath, pluginName, currentTarget)
|
|
148
|
-
|
|
149
|
-
const packagePath = this.getPackagePath(context)
|
|
150
|
-
const earlyExit = await this.checkExistingInstallation(pluginName, packagePath, logger)
|
|
151
|
-
if (earlyExit) return earlyExit
|
|
152
|
-
|
|
153
|
-
await this.runGenerator(pluginPath, packagePath, context)
|
|
154
|
-
|
|
155
|
-
const packageName = source === 'npm' ? npmPackage! : pluginName
|
|
156
|
-
await this.writePluginManifest(packagePath, {
|
|
157
|
-
pluginName,
|
|
158
|
-
packageName,
|
|
159
|
-
version,
|
|
160
|
-
source,
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
pluginName,
|
|
165
|
-
filesInstalled: true,
|
|
166
|
-
packageJsonUpdated: true,
|
|
167
|
-
dependenciesInstalled: true,
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Download and install an npm plugin package
|
|
173
|
-
*/
|
|
174
|
-
private async downloadNpmPlugin(npmPackage: string, workspaceRoot: string, logger: (message: string) => void): Promise<string> {
|
|
175
|
-
logger(` └─ Installing from npm: ${chalk.cyan(npmPackage)}...`)
|
|
176
|
-
|
|
177
|
-
const result = await downloadNpmPackage({
|
|
178
|
-
packageName: npmPackage,
|
|
179
|
-
workspaceRoot,
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
return result.packagePath
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
private getPackagePath(context: Launch77Context): string {
|
|
186
|
-
// Determine the base directory based on location type
|
|
187
|
-
switch (context.locationType) {
|
|
188
|
-
case 'workspace-app':
|
|
189
|
-
return path.join(context.appsDir, context.appName!)
|
|
190
|
-
case 'workspace-library':
|
|
191
|
-
return path.join(context.workspaceRoot, 'libraries', context.appName!)
|
|
192
|
-
case 'workspace-plugin':
|
|
193
|
-
return path.join(context.workspaceRoot, 'plugins', context.appName!)
|
|
194
|
-
case 'workspace-app-template':
|
|
195
|
-
return path.join(context.workspaceRoot, 'app-templates', context.appName!)
|
|
196
|
-
default:
|
|
197
|
-
throw new InvalidPluginContextError(`Cannot install plugin from ${context.locationType}`)
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
private async runGenerator(pluginPath: string, appPath: string, context: Launch77Context): Promise<void> {
|
|
202
|
-
try {
|
|
203
|
-
const generatorPath = path.join(pluginPath, 'dist/generator.js')
|
|
204
|
-
|
|
205
|
-
const args = [generatorPath, `--appPath=${appPath}`, `--appName=${context.appName}`, `--workspaceName=${context.workspaceName}`, `--pluginPath=${pluginPath}`]
|
|
206
|
-
|
|
207
|
-
await execa('node', args, {
|
|
208
|
-
cwd: pluginPath,
|
|
209
|
-
stdio: 'inherit',
|
|
210
|
-
})
|
|
211
|
-
} catch (error) {
|
|
212
|
-
throw new PluginInstallationError(`Generator failed: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined)
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
private async isPluginInstalled(pluginName: string, packagePath: string): Promise<InstalledPluginMetadata | null> {
|
|
217
|
-
try {
|
|
218
|
-
const packageJsonPath = path.join(packagePath, 'package.json')
|
|
219
|
-
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8')
|
|
220
|
-
const packageJson = JSON.parse(packageJsonContent)
|
|
221
|
-
|
|
222
|
-
const manifest = packageJson.launch77 as Launch77PackageManifest | undefined
|
|
223
|
-
|
|
224
|
-
if (manifest?.installedPlugins?.[pluginName]) {
|
|
225
|
-
return manifest.installedPlugins[pluginName]
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return null
|
|
229
|
-
} catch (error) {
|
|
230
|
-
// If package.json doesn't exist or can't be read, assume not installed
|
|
231
|
-
return null
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Write plugin installation metadata to the target package's package.json
|
|
237
|
-
*/
|
|
238
|
-
private async writePluginManifest(packagePath: string, installationInfo: { pluginName: string; packageName: string; version: string; source: 'local' | 'npm' }): Promise<void> {
|
|
239
|
-
try {
|
|
240
|
-
const packageJsonPath = path.join(packagePath, 'package.json')
|
|
241
|
-
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8')
|
|
242
|
-
const packageJson = JSON.parse(packageJsonContent)
|
|
243
|
-
|
|
244
|
-
if (!packageJson.launch77) {
|
|
245
|
-
packageJson.launch77 = {}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (!packageJson.launch77.installedPlugins) {
|
|
249
|
-
packageJson.launch77.installedPlugins = {}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const manifest = packageJson.launch77 as Launch77PackageManifest
|
|
253
|
-
|
|
254
|
-
manifest.installedPlugins![installationInfo.pluginName] = {
|
|
255
|
-
package: installationInfo.packageName,
|
|
256
|
-
version: installationInfo.version,
|
|
257
|
-
installedAt: new Date().toISOString(),
|
|
258
|
-
source: installationInfo.source,
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8')
|
|
262
|
-
} catch (error) {
|
|
263
|
-
throw new PluginInstallationError(`Failed to write plugin manifest: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Delete a plugin from the workspace
|
|
269
|
-
*/
|
|
270
|
-
async deletePlugin(request: DeletePluginRequest, context: Launch77Context): Promise<DeletePluginResult> {
|
|
271
|
-
const { pluginName } = request
|
|
272
|
-
|
|
273
|
-
// 1. Validate plugin name (reusing app name validation since format is the same)
|
|
274
|
-
const nameValidation = validateAppName(pluginName)
|
|
275
|
-
if (!nameValidation.valid) {
|
|
276
|
-
throw new InvalidPluginNameError(nameValidation.errorMessage || 'Invalid plugin name')
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// 2. Validate workspace context
|
|
280
|
-
const contextValidation = validateWorkspaceContext(context)
|
|
281
|
-
if (!contextValidation.valid) {
|
|
282
|
-
throw new Error(contextValidation.errorMessage || 'Invalid workspace context')
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// 3. Determine plugin path
|
|
286
|
-
const pluginPath = path.join(context.workspaceRoot, 'plugins', pluginName)
|
|
287
|
-
|
|
288
|
-
// 4. Check if plugin exists
|
|
289
|
-
if (!(await fsExtra.pathExists(pluginPath))) {
|
|
290
|
-
throw new PluginDirectoryNotFoundError(pluginName, pluginPath)
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// 5. Delete the plugin directory
|
|
294
|
-
await fsExtra.remove(pluginPath)
|
|
295
|
-
|
|
296
|
-
// 6. Update dependencies
|
|
297
|
-
await npm.install(context.workspaceRoot)
|
|
298
|
-
|
|
299
|
-
return {
|
|
300
|
-
pluginName,
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export interface InstallPluginRequest {
|
|
2
|
-
pluginName: string
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export interface InstallPluginResult {
|
|
6
|
-
pluginName: string
|
|
7
|
-
filesInstalled: boolean
|
|
8
|
-
packageJsonUpdated: boolean
|
|
9
|
-
dependenciesInstalled: boolean
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface PluginMetadata {
|
|
13
|
-
dependencies?: Record<string, string>
|
|
14
|
-
devDependencies?: Record<string, string>
|
|
15
|
-
scripts?: Record<string, string>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface HookResult {
|
|
19
|
-
templateVariables?: Record<string, string>
|
|
20
|
-
hookContext?: Record<string, string>
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface DeletePluginRequest {
|
|
24
|
-
pluginName: string
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface DeletePluginResult {
|
|
28
|
-
pluginName: string
|
|
29
|
-
}
|