diff --git a/scopes/harmony/api-server/api-for-ide.ts b/scopes/harmony/api-server/api-for-ide.ts index f83f1231389..dd74813ba6d 100644 --- a/scopes/harmony/api-server/api-for-ide.ts +++ b/scopes/harmony/api-server/api-for-ide.ts @@ -20,6 +20,9 @@ import { compact } from 'lodash'; import { getCloudDomain } from '@teambit/legacy/dist/constants'; import { ConfigMain } from '@teambit/config'; import { LANE_REMOTE_DELIMITER, LaneId } from '@teambit/lane-id'; +import { ApplicationMain } from '@teambit/application'; +import { DeprecationMain } from '@teambit/deprecation'; +import { EnvsMain } from '@teambit/envs'; const FILES_HISTORY_DIR = 'files-history'; const LAST_SNAP_DIR = 'last-snap'; @@ -59,6 +62,17 @@ type WorkspaceHistory = { history: Array<{ path: PathOsBasedAbsolute; fileId: string; reason?: string }>; }; +type CompMetadata = { + id: string; + isDeprecated: boolean; + appName?: string; // in case it's an app + env: { + id: string; + name?: string; + icon: string; + }; +}; + export class APIForIDE { constructor( private workspace: Workspace, @@ -71,7 +85,10 @@ export class APIForIDE { private componentCompare: ComponentCompareMain, private generator: GeneratorMain, private remove: RemoveMain, - private config: ConfigMain + private config: ConfigMain, + private application: ApplicationMain, + private deprecation: DeprecationMain, + private envs: EnvsMain ) {} async logStartCmdHistory(op: string) { @@ -179,6 +196,32 @@ export class APIForIDE { return this.lanes.createLane(name); } + async getCompsMetadata(): Promise { + const comps = await this.workspace.list(); + const apps = await this.application.listAppsIdsAndNames(); + const results = await pMap( + comps, + async (comp) => { + const id = comp.id; + const deprecationInfo = await this.deprecation.getDeprecationInfo(comp); + const foundApp = apps.find((app) => app.id === id.toString()); + const env = this.envs.getEnv(comp); + return { + id: id.toStringWithoutVersion(), + isDeprecated: deprecationInfo.isDeprecate, + appName: foundApp?.name, + env: { + id: env.id, + name: env.name, + icon: env.icon, + }, + }; + }, + { concurrency: 30 } + ); + return results; + } + async getCompFiles(id: string): Promise<{ dirAbs: string; filesRelative: PathOsBasedRelative[] }> { const compId = await this.workspace.resolveComponentId(id); const comp = await this.workspace.get(compId); diff --git a/scopes/harmony/api-server/api-server.main.runtime.ts b/scopes/harmony/api-server/api-server.main.runtime.ts index 4afbfdbf492..3b9e025f435 100644 --- a/scopes/harmony/api-server/api-server.main.runtime.ts +++ b/scopes/harmony/api-server/api-server.main.runtime.ts @@ -28,6 +28,9 @@ import { APIForIDE } from './api-for-ide'; import { SSEEventsRoute } from './sse-events.route'; import { join } from 'path'; import { CLIRawRoute } from './cli-raw.route'; +import { ApplicationAspect, ApplicationMain } from '@teambit/application'; +import { DeprecationAspect, DeprecationMain } from '@teambit/deprecation'; +import { EnvsAspect, EnvsMain } from '@teambit/envs'; export class ApiServerMain { constructor( @@ -187,6 +190,9 @@ export class ApiServerMain { GeneratorAspect, RemoveAspect, ConfigAspect, + ApplicationAspect, + DeprecationAspect, + EnvsAspect, ]; static runtime = MainRuntime; static async provider([ @@ -206,6 +212,9 @@ export class ApiServerMain { generator, remove, config, + application, + deprecation, + envs, ]: [ CLIMain, Workspace, @@ -222,7 +231,10 @@ export class ApiServerMain { ComponentCompareMain, GeneratorMain, RemoveMain, - ConfigMain + ConfigMain, + ApplicationMain, + DeprecationMain, + EnvsMain ]) { const logger = loggerMain.createLogger(ApiServerAspect.id); const apiServer = new ApiServerMain(workspace, logger, express, watcher, installer, importer); @@ -239,7 +251,10 @@ export class ApiServerMain { componentCompare, generator, remove, - config + config, + application, + deprecation, + envs ); const cliRoute = new CLIRoute(logger, cli, apiForIDE); const cliRawRoute = new CLIRawRoute(logger, cli, apiForIDE); diff --git a/scopes/harmony/application/app.cmd.ts b/scopes/harmony/application/app.cmd.ts index d1c2d27dc26..16bb1c03257 100644 --- a/scopes/harmony/application/app.cmd.ts +++ b/scopes/harmony/application/app.cmd.ts @@ -2,7 +2,6 @@ import { Command, CommandOptions } from '@teambit/cli'; // import { Logger } from '@teambit/logger'; import chalk from 'chalk'; -import { BitError } from '@teambit/bit-error'; import { CLITable } from '@teambit/cli-table'; import { ApplicationMain } from './application.main.runtime'; @@ -16,22 +15,18 @@ export class AppListCmd implements Command { constructor(private applicationAspect: ApplicationMain) {} - async report(args: [string], { json }: { json: boolean }) { - await this.applicationAspect.loadAllAppsAsAspects(); - const appComponents = this.applicationAspect.mapApps(); - if (json) return JSON.stringify(appComponents, null, 2); - if (!appComponents.length) return chalk.yellow('no apps found'); - - const rows = appComponents.flatMap(([id, apps]) => { - return apps.map((app) => { - if (!app.name) throw new BitError(`app ${id.toString()} is missing a name`); - return [id, app.name]; - }); - }); - + async report() { + const idsAndNames = await this.applicationAspect.listAppsIdsAndNames(); + if (!idsAndNames.length) return chalk.yellow('no apps found'); + const rows = idsAndNames.map(({ id, name }) => [id, name]); const table = new CLITable(['id', 'name'], rows); return table.render(); } + + async json() { + const idsAndNames = await this.applicationAspect.listAppsIdsAndNames(); + return idsAndNames; + } } export class AppCmd implements Command { diff --git a/scopes/harmony/application/application.main.runtime.ts b/scopes/harmony/application/application.main.runtime.ts index 57607864aa9..c546ae84d0d 100644 --- a/scopes/harmony/application/application.main.runtime.ts +++ b/scopes/harmony/application/application.main.runtime.ts @@ -104,6 +104,17 @@ export class ApplicationMain { return flatten(this.appSlot.values()); } + async listAppsIdsAndNames(): Promise<{ id: string; name: string }[]> { + await this.loadAllAppsAsAspects(); + const appComponents = this.mapApps(); + return appComponents.flatMap(([id, apps]) => { + return apps.map((app) => { + if (!app.name) throw new BitError(`app ${id.toString()} is missing a name`); + return { id, name: app.name }; + }); + }); + } + /** * map all apps by component ID. */