@launch77/cli 1.4.3 → 1.4.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/infrastructure/npm-package.d.ts +42 -0
  3. package/dist/infrastructure/npm-package.d.ts.map +1 -0
  4. package/dist/infrastructure/npm-package.js +46 -0
  5. package/dist/infrastructure/npm-package.js.map +1 -0
  6. package/dist/infrastructure/package-resolver.d.ts +107 -0
  7. package/dist/infrastructure/package-resolver.d.ts.map +1 -0
  8. package/dist/infrastructure/package-resolver.js +143 -0
  9. package/dist/infrastructure/package-resolver.js.map +1 -0
  10. package/dist/infrastructure/package-resolver.test.d.ts +2 -0
  11. package/dist/infrastructure/package-resolver.test.d.ts.map +1 -0
  12. package/dist/infrastructure/package-resolver.test.js +251 -0
  13. package/dist/infrastructure/package-resolver.test.js.map +1 -0
  14. package/dist/modules/app/commands/create-app.d.ts.map +1 -1
  15. package/dist/modules/app/commands/create-app.js +6 -2
  16. package/dist/modules/app/commands/create-app.js.map +1 -1
  17. package/dist/modules/app/lib/app-template-resolver.d.ts +14 -0
  18. package/dist/modules/app/lib/app-template-resolver.d.ts.map +1 -0
  19. package/dist/modules/app/lib/app-template-resolver.js +36 -0
  20. package/dist/modules/app/lib/app-template-resolver.js.map +1 -0
  21. package/dist/modules/app/services/app-svc.d.ts +2 -1
  22. package/dist/modules/app/services/app-svc.d.ts.map +1 -1
  23. package/dist/modules/app/services/app-svc.js +46 -11
  24. package/dist/modules/app/services/app-svc.js.map +1 -1
  25. package/dist/modules/plugin/lib/plugin-resolver.d.ts +10 -72
  26. package/dist/modules/plugin/lib/plugin-resolver.d.ts.map +1 -1
  27. package/dist/modules/plugin/lib/plugin-resolver.js +12 -115
  28. package/dist/modules/plugin/lib/plugin-resolver.js.map +1 -1
  29. package/dist/modules/plugin/lib/plugin-resolver.test.js +43 -39
  30. package/dist/modules/plugin/lib/plugin-resolver.test.js.map +1 -1
  31. package/dist/modules/plugin/services/plugin-svc.d.ts +2 -0
  32. package/dist/modules/plugin/services/plugin-svc.d.ts.map +1 -1
  33. package/dist/modules/plugin/services/plugin-svc.js +14 -17
  34. package/dist/modules/plugin/services/plugin-svc.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/infrastructure/npm-package.ts +73 -0
  37. package/src/infrastructure/package-resolver.test.ts +313 -0
  38. package/src/infrastructure/package-resolver.ts +194 -0
  39. package/src/modules/app/commands/create-app.ts +6 -2
  40. package/src/modules/app/lib/app-template-resolver.ts +40 -0
  41. package/src/modules/app/services/app-svc.ts +49 -12
  42. package/src/modules/plugin/lib/plugin-resolver.test.ts +46 -39
  43. package/src/modules/plugin/lib/plugin-resolver.ts +12 -142
  44. package/src/modules/plugin/services/plugin-svc.ts +15 -15
@@ -1 +1 @@
1
- {"version":3,"file":"create-app.d.ts","sourceRoot":"","sources":["../../../../src/modules/app/commands/create-app.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AASnC,wBAAgB,gBAAgB,IAAI,OAAO,CA8C1C"}
1
+ {"version":3,"file":"create-app.d.ts","sourceRoot":"","sources":["../../../../src/modules/app/commands/create-app.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AASnC,wBAAgB,gBAAgB,IAAI,OAAO,CAkD1C"}
@@ -37,8 +37,12 @@ export function createAppCommand() {
37
37
  throw error;
38
38
  }
39
39
  // Success message
40
- console.log(chalk.green(`\n✅ App created successfully at ${path.relative(process.cwd(), result.appPath)}`));
41
- console.log(chalk.gray(`\nRun 'npm run dev' from workspace root to start the server at http://localhost:${port}\n`));
40
+ const relativeAppPath = path.relative(process.cwd(), result.appPath);
41
+ console.log(chalk.green(`\n✅ App created successfully at ${relativeAppPath}`));
42
+ console.log(chalk.gray(`\nNext steps:`));
43
+ console.log(chalk.gray(` cd ${relativeAppPath}`));
44
+ console.log(chalk.gray(` npm run dev`));
45
+ console.log(chalk.gray(`\nServer will start at http://localhost:${port}\n`));
42
46
  }
43
47
  catch (error) {
44
48
  const message = error instanceof Error ? error.message : String(error);
@@ -1 +1 @@
1
- {"version":3,"file":"create-app.js","sourceRoot":"","sources":["../../../../src/modules/app/commands/create-app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-app.js","sourceRoot":"","sources":["../../../../src/modules/app/commands/create-app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { PackageResolver } from '../../../infrastructure/package-resolver.js';
2
+ /**
3
+ * App template resolver implementation
4
+ *
5
+ * Resolves app templates from:
6
+ * - Local workspace app-templates/ directory
7
+ * - npm packages with @launch77-shared/app-template- prefix
8
+ */
9
+ export declare class AppTemplateResolver extends PackageResolver {
10
+ protected getFolderName(): string;
11
+ protected getPackagePrefix(): string;
12
+ protected verify(localPath: string): Promise<boolean>;
13
+ }
14
+ //# sourceMappingURL=app-template-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-template-resolver.d.ts","sourceRoot":"","sources":["../../../../src/modules/app/lib/app-template-resolver.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAE7E;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;IACtD,SAAS,CAAC,aAAa,IAAI,MAAM;IAIjC,SAAS,CAAC,gBAAgB,IAAI,MAAM;cAIpB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAiB5D"}
@@ -0,0 +1,36 @@
1
+ import * as path from 'path';
2
+ import fs from 'fs-extra';
3
+ import { PackageResolver } from '../../../infrastructure/package-resolver.js';
4
+ /**
5
+ * App template resolver implementation
6
+ *
7
+ * Resolves app templates from:
8
+ * - Local workspace app-templates/ directory
9
+ * - npm packages with @launch77-shared/app-template- prefix
10
+ */
11
+ export class AppTemplateResolver extends PackageResolver {
12
+ getFolderName() {
13
+ return 'app-templates';
14
+ }
15
+ getPackagePrefix() {
16
+ return '@launch77-shared/app-template-';
17
+ }
18
+ async verify(localPath) {
19
+ // Check for either:
20
+ // 1. A 'template' subdirectory (preferred structure for npm packages)
21
+ // 2. Any files at the root (simple local templates)
22
+ const hasTemplateDir = await fs.pathExists(path.join(localPath, 'template'));
23
+ if (hasTemplateDir) {
24
+ return true;
25
+ }
26
+ // Check if directory has any files (not just an empty directory)
27
+ try {
28
+ const files = await fs.readdir(localPath);
29
+ return files.length > 0;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ }
36
+ //# sourceMappingURL=app-template-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-template-resolver.js","sourceRoot":"","sources":["../../../../src/modules/app/lib/app-template-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,EAAE,MAAM,UAAU,CAAA;AAEzB,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAE7E;;;;;;GAMG;AACH,MAAM,OAAO,mBAAoB,SAAQ,eAAe;IAC5C,aAAa;QACrB,OAAO,eAAe,CAAA;IACxB,CAAC;IAES,gBAAgB;QACxB,OAAO,gCAAgC,CAAA;IACzC,CAAC;IAES,KAAK,CAAC,MAAM,CAAC,SAAiB;QACtC,oBAAoB;QACpB,sEAAsE;QACtE,oDAAoD;QACpD,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAA;QAC5E,IAAI,cAAc,EAAE,CAAC;YACnB,OAAO,IAAI,CAAA;QACb,CAAC;QAED,iEAAiE;QACjE,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YACzC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC;CACF"}
@@ -1,7 +1,8 @@
1
- import type { Launch77Context } from '@launch77/plugin-runtime';
2
1
  import type { CreateAppRequest, CreateAppResult, DeleteAppRequest, DeleteAppResult } from '../types/app-types.js';
2
+ import type { Launch77Context } from '@launch77/plugin-runtime';
3
3
  export declare class AppService {
4
4
  private manifestService;
5
+ private appTemplateResolver;
5
6
  constructor();
6
7
  /**
7
8
  * Create a new app from template
@@ -1 +1 @@
1
- {"version":3,"file":"app-svc.d.ts","sourceRoot":"","sources":["../../../../src/modules/app/services/app-svc.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEjH,qBAAa,UAAU;IACrB,OAAO,CAAC,eAAe,CAAiB;;IAMxC;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAgD9F;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;CAsC/F"}
1
+ {"version":3,"file":"app-svc.d.ts","sourceRoot":"","sources":["../../../../src/modules/app/services/app-svc.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACjH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE/D,qBAAa,UAAU;IACrB,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,mBAAmB,CAAqB;;IAOhD;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IAkF9F;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;CAsC/F"}
@@ -3,14 +3,17 @@ import fs from 'fs-extra';
3
3
  import { ManifestService } from './manifest-svc.js';
4
4
  import * as filesystem from '../../../infrastructure/filesystem.js';
5
5
  import * as npm from '../../../infrastructure/npm.js';
6
- import { generateFromTemplate } from '../../../infrastructure/template-generator.js';
7
- import { templateExists } from '../../../infrastructure/template.js';
6
+ import { downloadNpmPackage } from '../../../infrastructure/npm-package.js';
7
+ import { processTemplate } from '../../../infrastructure/template.js';
8
8
  import { validateWorkspaceContext } from '../../../utils/launch77-validation.js';
9
9
  import { validateAppName } from '../../../utils/validation.js';
10
+ import { AppTemplateResolver } from '../lib/app-template-resolver.js';
10
11
  export class AppService {
11
12
  manifestService;
13
+ appTemplateResolver;
12
14
  constructor() {
13
15
  this.manifestService = new ManifestService();
16
+ this.appTemplateResolver = new AppTemplateResolver();
14
17
  }
15
18
  /**
16
19
  * Create a new app from template
@@ -27,25 +30,57 @@ export class AppService {
27
30
  if (!contextValidation.valid) {
28
31
  throw new Error(contextValidation.errorMessage);
29
32
  }
30
- // 3. Determine app path
33
+ // 3. Validate template name
34
+ const templateValidation = this.appTemplateResolver.validateInput(type);
35
+ if (!templateValidation.isValid) {
36
+ throw new Error(templateValidation.error || `Invalid template name: ${type}`);
37
+ }
38
+ // 4. Resolve template location
39
+ const templateResolution = await this.appTemplateResolver.resolveLocation(type, context.workspaceRoot);
40
+ let templatePath;
41
+ if (templateResolution.source === 'local') {
42
+ // Use local template
43
+ templatePath = templateResolution.localPath;
44
+ }
45
+ else {
46
+ // Download npm template
47
+ const downloadResult = await downloadNpmPackage({
48
+ packageName: templateResolution.npmPackage,
49
+ workspaceRoot: context.workspaceRoot,
50
+ });
51
+ // Check if template has a 'template' subdirectory, otherwise use package root
52
+ const templateSubdir = path.join(downloadResult.packagePath, 'template');
53
+ if (await fs.pathExists(templateSubdir)) {
54
+ templatePath = templateSubdir;
55
+ }
56
+ else {
57
+ templatePath = downloadResult.packagePath;
58
+ }
59
+ }
60
+ // 5. Determine app path
31
61
  const appPath = path.join(context.appsDir, appName);
32
- // 4. Check if app already exists
62
+ // 6. Check if app already exists
33
63
  if (await fs.pathExists(appPath)) {
34
64
  throw new Error(`App ${appName} already exists at ${appPath}`);
35
65
  }
36
- // 5. Validate template exists
37
- if (!(await templateExists(type))) {
38
- throw new Error(`Unknown app type: ${type}. Currently supported: api, webapp, marketing-site`);
66
+ // 7. Verify template path exists
67
+ if (!(await fs.pathExists(templatePath))) {
68
+ throw new Error(`Template not found at: ${templatePath}`);
39
69
  }
40
- // 6. Generate from template (context already has packageName computed)
41
- await generateFromTemplate(type, appPath, appName, context, { port });
42
- // 7. Generate and write app manifest
70
+ // 8. Generate from template (context already has packageName computed)
71
+ await processTemplate(templatePath, appPath, {
72
+ appName,
73
+ workspaceName: context.workspaceName,
74
+ packageName: context.packageName,
75
+ port,
76
+ });
77
+ // 9. Generate and write app manifest
43
78
  const manifest = this.manifestService.generateManifest(type, appName, context, { port });
44
79
  const launchDir = path.join(appPath, '.launch');
45
80
  await filesystem.ensureDir(launchDir);
46
81
  const manifestPath = path.join(launchDir, 'app.json');
47
82
  await filesystem.writeJSON(manifestPath, manifest);
48
- // 8. Install dependencies
83
+ // 10. Install dependencies
49
84
  await npm.install(context.workspaceRoot);
50
85
  return {
51
86
  appPath,
@@ -1 +1 @@
1
- {"version":3,"file":"app-svc.js","sourceRoot":"","sources":["../../../../src/modules/app/services/app-svc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app-svc.js","sourceRoot":"","sources":["../../../../src/modules/app/services/app-svc.ts"],"names":[],"mappings":"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"}
@@ -1,76 +1,14 @@
1
- import type { ValidationResult } from '@launch77/plugin-runtime';
1
+ import { PackageResolver } from '../../../infrastructure/package-resolver.js';
2
2
  /**
3
- * Plugin resolution result
4
- */
5
- export interface PluginResolution {
6
- /** The source of the plugin */
7
- source: 'local' | 'npm';
8
- /** The resolved name/package to use */
9
- resolvedName: string;
10
- /** The local path if source is 'local' */
11
- localPath?: string;
12
- /** The npm package name if source is 'npm' */
13
- npmPackage?: string;
14
- }
15
- /**
16
- * Validate plugin input name
17
- *
18
- * Accepts:
19
- * - Unscoped names (e.g., "release", "my-plugin")
20
- * - Scoped npm packages (e.g., "@ibm/plugin-name")
21
- *
22
- * Rejects:
23
- * - Invalid formats
24
- * - Empty strings
25
- * - Names with invalid characters
3
+ * Plugin resolver implementation
26
4
  *
27
- * @param name - The plugin name to validate
28
- * @returns ValidationResult with isValid and optional error message
29
- *
30
- * @example
31
- * validatePluginInput('release') // { isValid: true }
32
- * validatePluginInput('@ibm/analytics') // { isValid: true }
33
- * validatePluginInput('@invalid') // { isValid: false, error: '...' }
5
+ * Resolves plugins from:
6
+ * - Local workspace plugins/ directory
7
+ * - npm packages with @launch77-shared/plugin- prefix
34
8
  */
35
- export declare function validatePluginInput(name: string): ValidationResult;
36
- /**
37
- * Convert an unscoped plugin name to an npm package name
38
- *
39
- * Rules:
40
- * - Unscoped names: prefix with @launch77-shared/plugin-
41
- * - Scoped names: use as-is
42
- *
43
- * @param name - The plugin name (must be validated first)
44
- * @returns The npm package name
45
- *
46
- * @example
47
- * toNpmPackageName('release') // '@launch77-shared/plugin-release'
48
- * toNpmPackageName('@ibm/analytics') // '@ibm/analytics'
49
- */
50
- export declare function toNpmPackageName(name: string): string;
51
- /**
52
- * Resolve plugin location from name
53
- *
54
- * Resolution order:
55
- * 1. Check local workspace plugins directory
56
- * 2. Resolve to npm package name
57
- *
58
- * @param name - The plugin name to resolve
59
- * @param workspaceRoot - The workspace root directory
60
- * @returns PluginResolution with source and resolved location
61
- *
62
- * @example
63
- * // Local plugin found
64
- * await resolvePluginLocation('my-plugin', '/workspace')
65
- * // { source: 'local', resolvedName: 'my-plugin', localPath: '/workspace/plugins/my-plugin' }
66
- *
67
- * // Not found locally, resolve to npm
68
- * await resolvePluginLocation('release', '/workspace')
69
- * // { source: 'npm', resolvedName: 'release', npmPackage: '@launch77-shared/plugin-release' }
70
- *
71
- * // Scoped package always resolves to npm
72
- * await resolvePluginLocation('@ibm/analytics', '/workspace')
73
- * // { source: 'npm', resolvedName: '@ibm/analytics', npmPackage: '@ibm/analytics' }
74
- */
75
- export declare function resolvePluginLocation(name: string, workspaceRoot: string): Promise<PluginResolution>;
9
+ export declare class PluginResolver extends PackageResolver {
10
+ protected getFolderName(): string;
11
+ protected getPackagePrefix(): string;
12
+ protected verify(localPath: string): Promise<boolean>;
13
+ }
76
14
  //# sourceMappingURL=plugin-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-resolver.d.ts","sourceRoot":"","sources":["../../../../src/modules/plugin/lib/plugin-resolver.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEhE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+BAA+B;IAC/B,MAAM,EAAE,OAAO,GAAG,KAAK,CAAA;IACvB,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAA;IACpB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CA2BlE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuC1G"}
1
+ {"version":3,"file":"plugin-resolver.d.ts","sourceRoot":"","sources":["../../../../src/modules/plugin/lib/plugin-resolver.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAE7E;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,eAAe;IACjD,SAAS,CAAC,aAAa,IAAI,MAAM;IAIjC,SAAS,CAAC,gBAAgB,IAAI,MAAM;cAIpB,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAO5D"}
@@ -1,128 +1,25 @@
1
1
  import * as path from 'path';
2
2
  import fs from 'fs-extra';
3
- import { parsePluginName, isValidNpmPackageName } from '@launch77/plugin-runtime';
3
+ import { PackageResolver } from '../../../infrastructure/package-resolver.js';
4
4
  /**
5
- * Validate plugin input name
5
+ * Plugin resolver implementation
6
6
  *
7
- * Accepts:
8
- * - Unscoped names (e.g., "release", "my-plugin")
9
- * - Scoped npm packages (e.g., "@ibm/plugin-name")
10
- *
11
- * Rejects:
12
- * - Invalid formats
13
- * - Empty strings
14
- * - Names with invalid characters
15
- *
16
- * @param name - The plugin name to validate
17
- * @returns ValidationResult with isValid and optional error message
18
- *
19
- * @example
20
- * validatePluginInput('release') // { isValid: true }
21
- * validatePluginInput('@ibm/analytics') // { isValid: true }
22
- * validatePluginInput('@invalid') // { isValid: false, error: '...' }
23
- */
24
- export function validatePluginInput(name) {
25
- if (!name || name.trim().length === 0) {
26
- return {
27
- isValid: false,
28
- error: 'Plugin name cannot be empty',
29
- };
30
- }
31
- const trimmedName = name.trim();
32
- // Parse the name to determine type and validate
33
- const parsed = parsePluginName(trimmedName);
34
- if (!parsed.isValid) {
35
- return {
36
- isValid: false,
37
- error: parsed.error,
38
- };
39
- }
40
- // If it's scoped, it must be a valid npm package name
41
- if (parsed.type === 'scoped') {
42
- return isValidNpmPackageName(trimmedName);
43
- }
44
- // Unscoped names are valid for both local and npm
45
- return { isValid: true };
46
- }
47
- /**
48
- * Convert an unscoped plugin name to an npm package name
49
- *
50
- * Rules:
51
- * - Unscoped names: prefix with @launch77-shared/plugin-
52
- * - Scoped names: use as-is
53
- *
54
- * @param name - The plugin name (must be validated first)
55
- * @returns The npm package name
56
- *
57
- * @example
58
- * toNpmPackageName('release') // '@launch77-shared/plugin-release'
59
- * toNpmPackageName('@ibm/analytics') // '@ibm/analytics'
7
+ * Resolves plugins from:
8
+ * - Local workspace plugins/ directory
9
+ * - npm packages with @launch77-shared/plugin- prefix
60
10
  */
61
- export function toNpmPackageName(name) {
62
- const trimmedName = name.trim();
63
- // If already scoped, use as-is
64
- if (trimmedName.startsWith('@')) {
65
- return trimmedName;
11
+ export class PluginResolver extends PackageResolver {
12
+ getFolderName() {
13
+ return 'plugins';
66
14
  }
67
- // Otherwise, convert to @launch77-shared/plugin-<name>
68
- return `@launch77-shared/plugin-${trimmedName}`;
69
- }
70
- /**
71
- * Resolve plugin location from name
72
- *
73
- * Resolution order:
74
- * 1. Check local workspace plugins directory
75
- * 2. Resolve to npm package name
76
- *
77
- * @param name - The plugin name to resolve
78
- * @param workspaceRoot - The workspace root directory
79
- * @returns PluginResolution with source and resolved location
80
- *
81
- * @example
82
- * // Local plugin found
83
- * await resolvePluginLocation('my-plugin', '/workspace')
84
- * // { source: 'local', resolvedName: 'my-plugin', localPath: '/workspace/plugins/my-plugin' }
85
- *
86
- * // Not found locally, resolve to npm
87
- * await resolvePluginLocation('release', '/workspace')
88
- * // { source: 'npm', resolvedName: 'release', npmPackage: '@launch77-shared/plugin-release' }
89
- *
90
- * // Scoped package always resolves to npm
91
- * await resolvePluginLocation('@ibm/analytics', '/workspace')
92
- * // { source: 'npm', resolvedName: '@ibm/analytics', npmPackage: '@ibm/analytics' }
93
- */
94
- export async function resolvePluginLocation(name, workspaceRoot) {
95
- const trimmedName = name.trim();
96
- const parsed = parsePluginName(trimmedName);
97
- // If scoped, always use npm (local plugins are never scoped)
98
- if (parsed.type === 'scoped') {
99
- return {
100
- source: 'npm',
101
- resolvedName: trimmedName,
102
- npmPackage: trimmedName,
103
- };
15
+ getPackagePrefix() {
16
+ return '@launch77-shared/plugin-';
104
17
  }
105
- // Check local workspace plugins directory
106
- const localPath = path.join(workspaceRoot, 'plugins', trimmedName);
107
- const localExists = await fs.pathExists(localPath);
108
- if (localExists) {
18
+ async verify(localPath) {
109
19
  // Verify it's a valid plugin (has plugin.json and dist/generator.js)
110
20
  const hasPluginJson = await fs.pathExists(path.join(localPath, 'plugin.json'));
111
21
  const hasGenerator = await fs.pathExists(path.join(localPath, 'dist/generator.js'));
112
- if (hasPluginJson && hasGenerator) {
113
- return {
114
- source: 'local',
115
- resolvedName: trimmedName,
116
- localPath,
117
- };
118
- }
22
+ return hasPluginJson && hasGenerator;
119
23
  }
120
- // Not found locally, resolve to npm package
121
- const npmPackage = toNpmPackageName(trimmedName);
122
- return {
123
- source: 'npm',
124
- resolvedName: trimmedName,
125
- npmPackage,
126
- };
127
24
  }
128
25
  //# sourceMappingURL=plugin-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-resolver.js","sourceRoot":"","sources":["../../../../src/modules/plugin/lib/plugin-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,EAAE,MAAM,UAAU,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAkBjF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,6BAA6B;SACrC,CAAA;IACH,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAE/B,gDAAgD;IAChD,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAA;IAE3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAA;IACH,CAAC;IAED,sDAAsD;IACtD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,qBAAqB,CAAC,WAAW,CAAC,CAAA;IAC3C,CAAC;IAED,kDAAkD;IAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;AAC1B,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAE/B,+BAA+B;IAC/B,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,uDAAuD;IACvD,OAAO,2BAA2B,WAAW,EAAE,CAAA;AACjD,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAY,EAAE,aAAqB;IAC7E,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC/B,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,CAAA;IAE3C,6DAA6D;IAC7D,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO;YACL,MAAM,EAAE,KAAK;YACb,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,WAAW;SACxB,CAAA;IACH,CAAC;IAED,0CAA0C;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;IAClE,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IAElD,IAAI,WAAW,EAAE,CAAC;QAChB,qEAAqE;QACrE,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAA;QAC9E,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAA;QAEnF,IAAI,aAAa,IAAI,YAAY,EAAE,CAAC;YAClC,OAAO;gBACL,MAAM,EAAE,OAAO;gBACf,YAAY,EAAE,WAAW;gBACzB,SAAS;aACV,CAAA;QACH,CAAC;IACH,CAAC;IAED,4CAA4C;IAC5C,MAAM,UAAU,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;IAEhD,OAAO;QACL,MAAM,EAAE,KAAK;QACb,YAAY,EAAE,WAAW;QACzB,UAAU;KACX,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"plugin-resolver.js","sourceRoot":"","sources":["../../../../src/modules/plugin/lib/plugin-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,OAAO,EAAE,MAAM,UAAU,CAAA;AAEzB,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAE7E;;;;;;GAMG;AACH,MAAM,OAAO,cAAe,SAAQ,eAAe;IACvC,aAAa;QACrB,OAAO,SAAS,CAAA;IAClB,CAAC;IAES,gBAAgB;QACxB,OAAO,0BAA0B,CAAA;IACnC,CAAC;IAES,KAAK,CAAC,MAAM,CAAC,SAAiB;QACtC,qEAAqE;QACrE,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAA;QAC9E,MAAM,YAAY,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAA;QAEnF,OAAO,aAAa,IAAI,YAAY,CAAA;IACtC,CAAC;CACF"}