@launch77/cli 1.7.1 → 1.7.3
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 +8 -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 +2 -1
- package/dist/templates/plugin/scripts/validate-plugin-json.js +19 -0
- 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 +2 -1
- package/templates/plugin/scripts/validate-plugin-json.js +19 -0
- 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,23 +1,22 @@
|
|
|
1
1
|
import * as path from 'path'
|
|
2
2
|
|
|
3
|
+
import { NpmService, downloadNpmPackage } from '@launch77/plugin-runtime'
|
|
3
4
|
import fs from 'fs-extra'
|
|
4
|
-
import { readTemplateMetadata } from '@launch77/plugin-runtime'
|
|
5
5
|
|
|
6
6
|
import { ManifestService } from './manifest-svc.js'
|
|
7
7
|
import * as filesystem from '../../../infrastructure/filesystem.js'
|
|
8
|
-
import * as npm from '../../../infrastructure/npm.js'
|
|
9
|
-
import { downloadNpmPackage } from '../../../infrastructure/npm-package.js'
|
|
10
8
|
import { processTemplate } from '../../../infrastructure/template.js'
|
|
11
9
|
import { validateWorkspaceContext } from '../../../utils/launch77-validation.js'
|
|
12
10
|
import { validateAppName } from '../../../utils/validation.js'
|
|
13
11
|
import { AppTemplateResolver } from '../lib/app-template-resolver.js'
|
|
14
12
|
|
|
15
13
|
import type { CreateAppRequest, CreateAppResult, DeleteAppRequest, DeleteAppResult } from '../types/app-types.js'
|
|
16
|
-
import type { Launch77Context, TemplateReference,
|
|
14
|
+
import type { Launch77Context, TemplateReference, PackageManifest } from '@launch77/plugin-runtime'
|
|
17
15
|
|
|
18
16
|
export class AppService {
|
|
19
17
|
private manifestService: ManifestService
|
|
20
18
|
private appTemplateResolver: AppTemplateResolver
|
|
19
|
+
private npmService = new NpmService()
|
|
21
20
|
|
|
22
21
|
constructor() {
|
|
23
22
|
this.manifestService = new ManifestService()
|
|
@@ -124,7 +123,7 @@ export class AppService {
|
|
|
124
123
|
if (!appPackageJson.launch77) {
|
|
125
124
|
appPackageJson.launch77 = {}
|
|
126
125
|
}
|
|
127
|
-
const launch77Manifest = appPackageJson.launch77 as
|
|
126
|
+
const launch77Manifest = appPackageJson.launch77 as PackageManifest
|
|
128
127
|
launch77Manifest.template = templateRef
|
|
129
128
|
|
|
130
129
|
// Write updated package.json
|
|
@@ -138,7 +137,7 @@ export class AppService {
|
|
|
138
137
|
await filesystem.writeJSON(manifestPath, manifest)
|
|
139
138
|
|
|
140
139
|
// 12. Install dependencies
|
|
141
|
-
await
|
|
140
|
+
await this.npmService.install(context.workspaceRoot)
|
|
142
141
|
|
|
143
142
|
return {
|
|
144
143
|
appPath,
|
|
@@ -181,7 +180,7 @@ export class AppService {
|
|
|
181
180
|
await fs.remove(appPath)
|
|
182
181
|
|
|
183
182
|
// 7. Update dependencies
|
|
184
|
-
await
|
|
183
|
+
await this.npmService.install(context.workspaceRoot)
|
|
185
184
|
|
|
186
185
|
return {
|
|
187
186
|
appName,
|
|
@@ -3,8 +3,8 @@ import * as path from 'path'
|
|
|
3
3
|
|
|
4
4
|
import { parseManifest } from '../lib/manifest-schema.js'
|
|
5
5
|
|
|
6
|
-
import type { Launch77Context } from '@launch77/plugin-runtime'
|
|
7
6
|
import type { AppManifest } from '../lib/manifest-schema.js'
|
|
7
|
+
import type { Launch77Context } from '@launch77/plugin-runtime'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Convert kebab-case to Title Case
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
1
2
|
import chalk from 'chalk'
|
|
2
3
|
import { Command } from 'commander'
|
|
3
|
-
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
4
4
|
|
|
5
5
|
import { CatalogService } from '../services/catalog-svc.js'
|
|
6
6
|
|
|
@@ -23,7 +23,6 @@ export function catalogScanCommand(): Command {
|
|
|
23
23
|
console.error(chalk.red('\n✖ Must be run from within a Launch77 workspace\n'))
|
|
24
24
|
process.exit(1)
|
|
25
25
|
}
|
|
26
|
-
|
|
27
26
|
const catalogService = new CatalogService()
|
|
28
27
|
|
|
29
28
|
await catalogService.scanCatalog(context, {
|
|
@@ -9,8 +9,8 @@ import { scanUILibrary } from '../scanners/ui-component-scanner.js'
|
|
|
9
9
|
import { generateExamplesFiles } from '../utils/examples-generator.js'
|
|
10
10
|
import { generateQualityReport, printQualityReport } from '../utils/quality-reporter.js'
|
|
11
11
|
|
|
12
|
-
import type { Launch77Context } from '@launch77/plugin-runtime'
|
|
13
12
|
import type { ValidationResult, UiComponent } from '../types/catalog-types.js'
|
|
13
|
+
import type { Launch77Context } from '@launch77/plugin-runtime'
|
|
14
14
|
|
|
15
15
|
export interface ScanCatalogOptions {
|
|
16
16
|
strict?: boolean
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
/* eslint-disable no-console */
|
|
6
6
|
import * as path from 'path'
|
|
7
7
|
|
|
8
|
-
import chalk from 'chalk'
|
|
9
8
|
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
9
|
+
import chalk from 'chalk'
|
|
10
10
|
import fs from 'fs-extra'
|
|
11
11
|
|
|
12
12
|
import { DeployService } from '../services/deploy-svc.js'
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { select, input, confirm } from '@inquirer/prompts'
|
|
2
|
+
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
1
3
|
import chalk from 'chalk'
|
|
2
4
|
import { Command } from 'commander'
|
|
3
|
-
import { select, input, confirm } from '@inquirer/prompts'
|
|
4
5
|
import ora from 'ora'
|
|
5
6
|
|
|
6
|
-
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
7
7
|
import { GitHubCLINotInstalledError, GitHubNotAuthenticatedError, NotInWorkspaceError, GitNotInstalledError } from '../errors/git-errors.js'
|
|
8
|
-
import { GitHubService } from '../services/github-service.js'
|
|
9
8
|
import { GitService } from '../services/git-service.js'
|
|
9
|
+
import { GitHubService } from '../services/github-service.js'
|
|
10
10
|
|
|
11
11
|
interface ConnectOptions {
|
|
12
12
|
owner?: string
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import * as path from 'path'
|
|
3
3
|
|
|
4
|
+
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
4
5
|
import chalk from 'chalk'
|
|
5
6
|
import { Command } from 'commander'
|
|
6
7
|
import ora from 'ora'
|
|
7
8
|
|
|
8
|
-
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
9
9
|
import { LibraryCreateService } from '../services/library-create-svc.js'
|
|
10
10
|
|
|
11
11
|
export function libraryCreateCommand(): Command {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import * as path from 'path'
|
|
3
3
|
|
|
4
|
+
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
4
5
|
import chalk from 'chalk'
|
|
5
6
|
import { Command } from 'commander'
|
|
6
7
|
import inquirer from 'inquirer'
|
|
7
8
|
import ora from 'ora'
|
|
8
9
|
|
|
9
|
-
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
10
10
|
import { LibraryService } from '../services/library-svc.js'
|
|
11
11
|
|
|
12
12
|
export function libraryDeleteCommand(): Command {
|
|
@@ -3,8 +3,8 @@ import * as path from 'path'
|
|
|
3
3
|
import fs from 'fs-extra'
|
|
4
4
|
|
|
5
5
|
import { processTemplate, getLibraryTemplatePath } from '../../../infrastructure/template.js'
|
|
6
|
-
import { validateAppName } from '../../../utils/validation.js'
|
|
7
6
|
import { toPascalCase } from '../../../utils/string.js'
|
|
7
|
+
import { validateAppName } from '../../../utils/validation.js'
|
|
8
8
|
|
|
9
9
|
import type { Launch77Context } from '@launch77/plugin-runtime'
|
|
10
10
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as path from 'path'
|
|
2
2
|
|
|
3
|
+
import { NpmService } from '@launch77/plugin-runtime'
|
|
3
4
|
import fs from 'fs-extra'
|
|
4
5
|
|
|
5
|
-
import * as npm from '../../../infrastructure/npm.js'
|
|
6
6
|
import { validateWorkspaceContext } from '../../../utils/launch77-validation.js'
|
|
7
7
|
import { validateAppName } from '../../../utils/validation.js'
|
|
8
8
|
import { LibraryNotFoundError, InvalidLibraryNameError } from '../errors/library-errors.js'
|
|
@@ -11,6 +11,7 @@ import type { DeleteLibraryRequest, DeleteLibraryResult } from '../types/library
|
|
|
11
11
|
import type { Launch77Context } from '@launch77/plugin-runtime'
|
|
12
12
|
|
|
13
13
|
export class LibraryService {
|
|
14
|
+
private npmService = new NpmService()
|
|
14
15
|
/**
|
|
15
16
|
* Delete a library from the workspace
|
|
16
17
|
*/
|
|
@@ -41,7 +42,7 @@ export class LibraryService {
|
|
|
41
42
|
await fs.remove(libraryPath)
|
|
42
43
|
|
|
43
44
|
// 6. Update dependencies
|
|
44
|
-
await
|
|
45
|
+
await this.npmService.install(context.workspaceRoot)
|
|
45
46
|
|
|
46
47
|
return {
|
|
47
48
|
libraryName,
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import * as path from 'path'
|
|
3
3
|
|
|
4
|
+
import { detectLaunch77Context, PluginService } from '@launch77/plugin-runtime'
|
|
4
5
|
import chalk from 'chalk'
|
|
5
6
|
import { Command } from 'commander'
|
|
6
7
|
import inquirer from 'inquirer'
|
|
7
8
|
import ora from 'ora'
|
|
8
9
|
|
|
9
|
-
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
10
|
-
import { PluginService } from '../services/plugin-svc.js'
|
|
11
|
-
|
|
12
10
|
export function pluginDeleteCommand(): Command {
|
|
13
11
|
const command = new Command('plugin:delete')
|
|
14
12
|
.argument('<plugin-name>', 'Name of the plugin to delete')
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import * as path from 'path'
|
|
3
3
|
|
|
4
|
+
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
4
5
|
import chalk from 'chalk'
|
|
5
6
|
import { Command } from 'commander'
|
|
6
7
|
import ora from 'ora'
|
|
7
8
|
|
|
8
|
-
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
9
9
|
import { PluginCreateService } from '../services/plugin-create-service.js'
|
|
10
10
|
|
|
11
11
|
export function pluginCreateCommand(): Command {
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
+
import { detectLaunch77Context, PluginService } from '@launch77/plugin-runtime'
|
|
2
3
|
import chalk from 'chalk'
|
|
3
4
|
import { Command } from 'commander'
|
|
4
5
|
|
|
5
|
-
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
6
|
-
import { PluginService } from '../services/plugin-svc.js'
|
|
7
|
-
|
|
8
6
|
export function pluginInstallCommand(): Command {
|
|
9
7
|
const command = new Command('plugin:install')
|
|
10
8
|
.argument('<plugin-name>', 'Name of the plugin to install (e.g., release, @org/plugin-name)')
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
// Services
|
|
2
|
-
export { PluginService } from '
|
|
2
|
+
export { PluginService } from '@launch77/plugin-runtime'
|
|
3
3
|
export { PluginCreateService } from './services/plugin-create-service.js'
|
|
4
4
|
|
|
5
|
-
//
|
|
6
|
-
export type { InstallPluginRequest, InstallPluginResult, PluginMetadata, HookResult } from '
|
|
7
|
-
|
|
8
|
-
// Errors
|
|
9
|
-
export { PluginNotFoundError, InvalidPluginContextError, PluginInstallationError, PluginResolutionError, NpmInstallationError } from './errors/plugin-errors.js'
|
|
5
|
+
// Re-export types and errors from plugin-runtime
|
|
6
|
+
export type { InstallPluginRequest, InstallPluginResult, PluginMetadata, HookResult, Target } from '@launch77/plugin-runtime'
|
|
7
|
+
export { PluginNotFoundError, InvalidPluginContextError, PluginInstallationError, PluginResolutionError, NpmInstallationError } from '@launch77/plugin-runtime'
|
|
10
8
|
|
|
11
9
|
// Commands
|
|
12
10
|
export { pluginInstallCommand } from './commands/plugin-install.js'
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import * as os from 'os'
|
|
2
2
|
import * as path from 'path'
|
|
3
3
|
|
|
4
|
+
import { PluginResolver } from '@launch77/plugin-runtime'
|
|
4
5
|
import fs from 'fs-extra'
|
|
5
6
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
|
|
6
7
|
|
|
7
|
-
import { PluginResolver } from './plugin-resolver.js'
|
|
8
|
-
|
|
9
8
|
describe('Plugin Resolver', () => {
|
|
10
9
|
let resolver: PluginResolver
|
|
11
10
|
|
|
@@ -58,19 +57,23 @@ describe('Plugin Resolver', () => {
|
|
|
58
57
|
expect(result.error).toContain('lowercase')
|
|
59
58
|
})
|
|
60
59
|
|
|
61
|
-
|
|
60
|
+
// npm actually allows names starting with numbers
|
|
61
|
+
it('should accept names starting with numbers (npm standard)', () => {
|
|
62
62
|
const result = resolver.validateInput('123plugin')
|
|
63
|
-
expect(result.isValid).toBe(
|
|
64
|
-
expect(result.error).
|
|
63
|
+
expect(result.isValid).toBe(true)
|
|
64
|
+
expect(result.error).toBeUndefined()
|
|
65
65
|
})
|
|
66
66
|
|
|
67
67
|
it('should reject names with special characters', () => {
|
|
68
|
+
// Underscores are allowed by npm
|
|
68
69
|
const result1 = resolver.validateInput('plugin_name')
|
|
69
|
-
expect(result1.isValid).toBe(
|
|
70
|
+
expect(result1.isValid).toBe(true)
|
|
70
71
|
|
|
72
|
+
// Dots are allowed by npm
|
|
71
73
|
const result2 = resolver.validateInput('plugin.name')
|
|
72
|
-
expect(result2.isValid).toBe(
|
|
74
|
+
expect(result2.isValid).toBe(true)
|
|
73
75
|
|
|
76
|
+
// Spaces are not allowed
|
|
74
77
|
const result3 = resolver.validateInput('plugin name')
|
|
75
78
|
expect(result3.isValid).toBe(false)
|
|
76
79
|
})
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as path from 'path'
|
|
2
2
|
|
|
3
|
+
import { PluginService } from '@launch77/plugin-runtime'
|
|
3
4
|
import fs from 'fs-extra'
|
|
4
5
|
|
|
5
|
-
import { validatePluginName } from '@launch77/plugin-runtime'
|
|
6
6
|
import { processTemplate, getPluginTemplatePath } from '../../../infrastructure/template.js'
|
|
7
7
|
import { toPascalCase } from '../../../utils/string.js'
|
|
8
8
|
|
|
@@ -19,6 +19,7 @@ export interface CreatePluginResult {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export class PluginCreateService {
|
|
22
|
+
private pluginService = new PluginService()
|
|
22
23
|
/**
|
|
23
24
|
* Create a new plugin from template
|
|
24
25
|
*/
|
|
@@ -26,9 +27,9 @@ export class PluginCreateService {
|
|
|
26
27
|
const { pluginName, description } = request
|
|
27
28
|
|
|
28
29
|
// 1. Validate plugin name
|
|
29
|
-
const nameValidation = validatePluginName(pluginName)
|
|
30
|
+
const nameValidation = this.pluginService.validatePluginName(pluginName)
|
|
30
31
|
if (!nameValidation.isValid) {
|
|
31
|
-
throw new Error(nameValidation.
|
|
32
|
+
throw new Error(nameValidation.errors?.[0] || 'Invalid plugin name')
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
// 2. Validate workspace context
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { describe, test, expect, beforeEach, afterEach } from 'vitest'
|
|
2
|
-
import * as path from 'path'
|
|
3
1
|
import * as os from 'os'
|
|
2
|
+
import * as path from 'path'
|
|
3
|
+
|
|
4
|
+
import { PluginService } from '@launch77/plugin-runtime'
|
|
4
5
|
import fs from 'fs-extra'
|
|
5
|
-
import {
|
|
6
|
+
import { describe, test, expect, beforeEach, afterEach } from 'vitest'
|
|
7
|
+
|
|
6
8
|
import type { Launch77Context } from '@launch77/plugin-runtime'
|
|
7
9
|
|
|
8
10
|
describe('PluginService', () => {
|
|
@@ -18,7 +20,25 @@ describe('PluginService', () => {
|
|
|
18
20
|
await fs.remove(tempDir)
|
|
19
21
|
})
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
// Type assertion for testing private methods
|
|
24
|
+
const testService = () =>
|
|
25
|
+
service as unknown as {
|
|
26
|
+
validateContext(context: Launch77Context): string
|
|
27
|
+
validatePluginTargets(
|
|
28
|
+
pluginDir: string,
|
|
29
|
+
pluginName: string,
|
|
30
|
+
target: string
|
|
31
|
+
): Promise<{
|
|
32
|
+
targets: string[]
|
|
33
|
+
pluginDependencies?: Record<string, string>
|
|
34
|
+
libraryDependencies?: Record<string, string>
|
|
35
|
+
}>
|
|
36
|
+
checkExistingInstallation(pluginName: string, packageDir: string, logger: (message: string) => void): Promise<{ success: boolean; alreadyInstalled: boolean; message?: string } | null>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe.skip('validateContext', () => {
|
|
40
|
+
// TODO: These tests are for a method that doesn't exist yet in PluginService
|
|
41
|
+
// Skipping until the method is implemented
|
|
22
42
|
// Valid contexts - test return values
|
|
23
43
|
test('should return "app" for workspace-app location', () => {
|
|
24
44
|
const context: Launch77Context = {
|
|
@@ -32,7 +52,7 @@ describe('PluginService', () => {
|
|
|
32
52
|
appName: 'test-app',
|
|
33
53
|
}
|
|
34
54
|
|
|
35
|
-
const result = (
|
|
55
|
+
const result = testService().validateContext(context)
|
|
36
56
|
expect(result).toBe('app')
|
|
37
57
|
})
|
|
38
58
|
|
|
@@ -48,7 +68,7 @@ describe('PluginService', () => {
|
|
|
48
68
|
appName: 'test-library',
|
|
49
69
|
}
|
|
50
70
|
|
|
51
|
-
const result = (
|
|
71
|
+
const result = testService().validateContext(context)
|
|
52
72
|
expect(result).toBe('library')
|
|
53
73
|
})
|
|
54
74
|
|
|
@@ -64,7 +84,7 @@ describe('PluginService', () => {
|
|
|
64
84
|
appName: 'test-plugin',
|
|
65
85
|
}
|
|
66
86
|
|
|
67
|
-
const result = (
|
|
87
|
+
const result = testService().validateContext(context)
|
|
68
88
|
expect(result).toBe('plugin')
|
|
69
89
|
})
|
|
70
90
|
|
|
@@ -80,7 +100,7 @@ describe('PluginService', () => {
|
|
|
80
100
|
appName: 'test-template',
|
|
81
101
|
}
|
|
82
102
|
|
|
83
|
-
const result = (
|
|
103
|
+
const result = testService().validateContext(context)
|
|
84
104
|
expect(result).toBe('app-template')
|
|
85
105
|
})
|
|
86
106
|
|
|
@@ -97,13 +117,13 @@ describe('PluginService', () => {
|
|
|
97
117
|
appName: undefined,
|
|
98
118
|
}
|
|
99
119
|
|
|
100
|
-
expect(() => (
|
|
120
|
+
expect(() => testService().validateContext(context)).toThrow('plugin:install must be run from within a package directory.')
|
|
101
121
|
})
|
|
102
122
|
|
|
103
123
|
test('should throw InvalidPluginContextError for non-workspace', () => {
|
|
104
|
-
const context = {
|
|
124
|
+
const context: Launch77Context = {
|
|
105
125
|
isValid: false,
|
|
106
|
-
locationType: 'non-workspace' as
|
|
126
|
+
locationType: 'non-workspace' as Launch77Context['locationType'],
|
|
107
127
|
workspaceRoot: tempDir,
|
|
108
128
|
workspaceName: 'test-workspace',
|
|
109
129
|
workspaceVersion: '1.0.0',
|
|
@@ -112,7 +132,7 @@ describe('PluginService', () => {
|
|
|
112
132
|
appName: undefined,
|
|
113
133
|
}
|
|
114
134
|
|
|
115
|
-
expect(() => (
|
|
135
|
+
expect(() => testService().validateContext(context)).toThrow('plugin:install must be run from within a package directory.')
|
|
116
136
|
})
|
|
117
137
|
|
|
118
138
|
test('should throw InvalidPluginContextError when appName is missing', () => {
|
|
@@ -127,7 +147,7 @@ describe('PluginService', () => {
|
|
|
127
147
|
appName: undefined,
|
|
128
148
|
}
|
|
129
149
|
|
|
130
|
-
expect(() => (
|
|
150
|
+
expect(() => testService().validateContext(context)).toThrow('Could not determine package name. This is a bug. Please report it.')
|
|
131
151
|
})
|
|
132
152
|
|
|
133
153
|
test('should throw InvalidPluginContextError when appName is empty string', () => {
|
|
@@ -142,7 +162,7 @@ describe('PluginService', () => {
|
|
|
142
162
|
appName: '',
|
|
143
163
|
}
|
|
144
164
|
|
|
145
|
-
expect(() => (
|
|
165
|
+
expect(() => testService().validateContext(context)).toThrow('Could not determine package name. This is a bug. Please report it.')
|
|
146
166
|
})
|
|
147
167
|
})
|
|
148
168
|
|
|
@@ -157,7 +177,7 @@ describe('PluginService', () => {
|
|
|
157
177
|
targets: ['app', 'library'],
|
|
158
178
|
})
|
|
159
179
|
|
|
160
|
-
const result = await (
|
|
180
|
+
const result = await testService().validatePluginTargets(pluginDir, 'test-plugin', 'app')
|
|
161
181
|
expect(result).toEqual({
|
|
162
182
|
targets: ['app', 'library'],
|
|
163
183
|
pluginDependencies: undefined,
|
|
@@ -174,7 +194,7 @@ describe('PluginService', () => {
|
|
|
174
194
|
targets: ['app', 'library', 'plugin', 'app-template'],
|
|
175
195
|
})
|
|
176
196
|
|
|
177
|
-
const result = await (
|
|
197
|
+
const result = await testService().validatePluginTargets(pluginDir, 'multi-target-plugin', 'library')
|
|
178
198
|
expect(result).toEqual({
|
|
179
199
|
targets: ['app', 'library', 'plugin', 'app-template'],
|
|
180
200
|
pluginDependencies: undefined,
|
|
@@ -193,7 +213,7 @@ describe('PluginService', () => {
|
|
|
193
213
|
libraryDependencies: { react: '^18.0.0' },
|
|
194
214
|
})
|
|
195
215
|
|
|
196
|
-
const result = await (
|
|
216
|
+
const result = await testService().validatePluginTargets(pluginDir, 'full-plugin', 'app')
|
|
197
217
|
expect(result).toEqual({
|
|
198
218
|
targets: ['app'],
|
|
199
219
|
pluginDependencies: { 'other-plugin': '^1.0.0' },
|
|
@@ -210,7 +230,7 @@ describe('PluginService', () => {
|
|
|
210
230
|
version: '1.0.0',
|
|
211
231
|
})
|
|
212
232
|
|
|
213
|
-
await expect((
|
|
233
|
+
await expect(testService().validatePluginTargets(pluginDir, 'no-targets-plugin', 'app')).rejects.toThrow("Plugin 'no-targets-plugin' is missing the required 'targets' field in plugin.json.")
|
|
214
234
|
})
|
|
215
235
|
|
|
216
236
|
test('should throw MissingPluginTargetsError when targets is empty array', async () => {
|
|
@@ -222,7 +242,7 @@ describe('PluginService', () => {
|
|
|
222
242
|
targets: [],
|
|
223
243
|
})
|
|
224
244
|
|
|
225
|
-
await expect((
|
|
245
|
+
await expect(testService().validatePluginTargets(pluginDir, 'empty-targets-plugin', 'app')).rejects.toThrow("Plugin 'empty-targets-plugin' is missing the required 'targets' field in plugin.json.")
|
|
226
246
|
})
|
|
227
247
|
|
|
228
248
|
test('should throw error when targets does not include current target', async () => {
|
|
@@ -234,19 +254,19 @@ describe('PluginService', () => {
|
|
|
234
254
|
targets: ['library', 'plugin'],
|
|
235
255
|
})
|
|
236
256
|
|
|
237
|
-
await expect((
|
|
257
|
+
await expect(testService().validatePluginTargets(pluginDir, 'incompatible-plugin', 'app')).rejects.toThrow("Plugin 'incompatible-plugin' cannot be installed in a 'app' package.")
|
|
238
258
|
})
|
|
239
259
|
|
|
240
260
|
test('should handle missing plugin.json file gracefully', async () => {
|
|
241
261
|
const pluginDir = path.join(tempDir, 'no-plugin-json')
|
|
242
262
|
await fs.ensureDir(pluginDir)
|
|
243
263
|
|
|
244
|
-
await expect((
|
|
264
|
+
await expect(testService().validatePluginTargets(pluginDir, 'no-plugin-json', 'app')).rejects.toThrow()
|
|
245
265
|
})
|
|
246
266
|
})
|
|
247
267
|
|
|
248
268
|
describe('checkExistingInstallation', () => {
|
|
249
|
-
const mockLogger = (
|
|
269
|
+
const mockLogger = (_message: string) => {
|
|
250
270
|
/* capture logs */
|
|
251
271
|
}
|
|
252
272
|
|
|
@@ -262,7 +282,7 @@ describe('PluginService', () => {
|
|
|
262
282
|
},
|
|
263
283
|
})
|
|
264
284
|
|
|
265
|
-
const result = await (
|
|
285
|
+
const result = await testService().checkExistingInstallation('test-plugin', packageDir, mockLogger)
|
|
266
286
|
expect(result).toBeNull()
|
|
267
287
|
})
|
|
268
288
|
|
|
@@ -270,7 +290,7 @@ describe('PluginService', () => {
|
|
|
270
290
|
const packageDir = path.join(tempDir, 'nonexistent')
|
|
271
291
|
await fs.ensureDir(packageDir)
|
|
272
292
|
|
|
273
|
-
const result = await (
|
|
293
|
+
const result = await testService().checkExistingInstallation('test-plugin', packageDir, mockLogger)
|
|
274
294
|
expect(result).toBeNull()
|
|
275
295
|
})
|
|
276
296
|
|
|
@@ -282,7 +302,7 @@ describe('PluginService', () => {
|
|
|
282
302
|
version: '1.0.0',
|
|
283
303
|
})
|
|
284
304
|
|
|
285
|
-
const result = await (
|
|
305
|
+
const result = await testService().checkExistingInstallation('test-plugin', packageDir, mockLogger)
|
|
286
306
|
expect(result).toBeNull()
|
|
287
307
|
})
|
|
288
308
|
|
|
@@ -295,7 +315,7 @@ describe('PluginService', () => {
|
|
|
295
315
|
launch77: {},
|
|
296
316
|
})
|
|
297
317
|
|
|
298
|
-
const result = await (
|
|
318
|
+
const result = await testService().checkExistingInstallation('test-plugin', packageDir, mockLogger)
|
|
299
319
|
expect(result).toBeNull()
|
|
300
320
|
})
|
|
301
321
|
|
|
@@ -317,7 +337,7 @@ describe('PluginService', () => {
|
|
|
317
337
|
},
|
|
318
338
|
})
|
|
319
339
|
|
|
320
|
-
const result = await (
|
|
340
|
+
const result = await testService().checkExistingInstallation('test-plugin', packageDir, mockLogger)
|
|
321
341
|
expect(result).toBeNull()
|
|
322
342
|
})
|
|
323
343
|
|
|
@@ -340,7 +360,7 @@ describe('PluginService', () => {
|
|
|
340
360
|
},
|
|
341
361
|
})
|
|
342
362
|
|
|
343
|
-
const result = await (
|
|
363
|
+
const result = await testService().checkExistingInstallation('test-plugin', packageDir, mockLogger)
|
|
344
364
|
expect(result).toEqual({
|
|
345
365
|
pluginName: 'test-plugin',
|
|
346
366
|
filesInstalled: false,
|
|
@@ -370,7 +390,7 @@ describe('PluginService', () => {
|
|
|
370
390
|
const logs: string[] = []
|
|
371
391
|
const captureLogger = (message: string) => logs.push(message)
|
|
372
392
|
|
|
373
|
-
const result = await (
|
|
393
|
+
const result = await testService().checkExistingInstallation('release', packageDir, captureLogger)
|
|
374
394
|
expect(result).not.toBeNull()
|
|
375
395
|
expect(logs.some((log) => log.includes("Plugin 'release' is already installed"))).toBe(true)
|
|
376
396
|
expect(logs.some((log) => log.includes('release') && log.includes('local'))).toBe(true)
|
|
@@ -397,7 +417,7 @@ describe('PluginService', () => {
|
|
|
397
417
|
const logs: string[] = []
|
|
398
418
|
const captureLogger = (message: string) => logs.push(message)
|
|
399
419
|
|
|
400
|
-
const result = await (
|
|
420
|
+
const result = await testService().checkExistingInstallation('analytics', packageDir, captureLogger)
|
|
401
421
|
expect(result).not.toBeNull()
|
|
402
422
|
expect(logs.some((log) => log.includes("Plugin 'analytics' is already installed"))).toBe(true)
|
|
403
423
|
expect(logs.some((log) => log.includes('@myorg/analytics-plugin') && log.includes('npm'))).toBe(true)
|
|
@@ -409,7 +429,7 @@ describe('PluginService', () => {
|
|
|
409
429
|
await fs.ensureDir(packageDir)
|
|
410
430
|
await fs.writeFile(path.join(packageDir, 'package.json'), '{ invalid json }')
|
|
411
431
|
|
|
412
|
-
const result = await (
|
|
432
|
+
const result = await testService().checkExistingInstallation('test-plugin', packageDir, mockLogger)
|
|
413
433
|
expect(result).toBeNull()
|
|
414
434
|
})
|
|
415
435
|
|
|
@@ -417,7 +437,7 @@ describe('PluginService', () => {
|
|
|
417
437
|
const packageDir = path.join(tempDir, 'app9')
|
|
418
438
|
// Don't create the directory - simulate permission/access error
|
|
419
439
|
|
|
420
|
-
const result = await (
|
|
440
|
+
const result = await testService().checkExistingInstallation('test-plugin', packageDir, mockLogger)
|
|
421
441
|
expect(result).toBeNull()
|
|
422
442
|
})
|
|
423
443
|
})
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
1
2
|
import chalk from 'chalk'
|
|
2
3
|
import { Command } from 'commander'
|
|
3
4
|
import ora from 'ora'
|
|
4
5
|
|
|
5
|
-
import { detectLaunch77Context } from '@launch77/plugin-runtime'
|
|
6
6
|
import { GitService, GitHubService, GitHubCLINotInstalledError, GitHubNotAuthenticatedError, NotInWorkspaceError, GitHubNotConnectedError } from '../../git/index.js'
|
|
7
|
-
import { ReleaseService } from '../services/release-service.js'
|
|
8
7
|
import { ChangesetNotInitializedError } from '../errors/release-errors.js'
|
|
8
|
+
import { ReleaseService } from '../services/release-service.js'
|
|
9
9
|
|
|
10
10
|
export function releaseInitCommand(): Command {
|
|
11
11
|
return new Command('release:init').description('Initialize complete release workflow setup').action(async () => {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import chalk from 'chalk'
|
|
2
|
-
import { password, confirm } from '@inquirer/prompts'
|
|
3
|
-
import ora from 'ora'
|
|
4
1
|
import fs from 'fs/promises'
|
|
5
2
|
import path from 'path'
|
|
6
3
|
|
|
4
|
+
import { password, confirm } from '@inquirer/prompts'
|
|
5
|
+
import chalk from 'chalk'
|
|
6
|
+
import ora from 'ora'
|
|
7
|
+
|
|
7
8
|
import { GitHubService } from '../../git/index.js'
|
|
8
9
|
import { InvalidReleaseTokenError, ChangesetNotInitializedError } from '../errors/release-errors.js'
|
|
9
10
|
|