diff --git a/scripts/download-humctl.sh b/scripts/download-humctl.sh index 96bb347..5740845 100755 --- a/scripts/download-humctl.sh +++ b/scripts/download-humctl.sh @@ -1,6 +1,6 @@ #!/bin/sh -CLI_VERSION=0.24.0 +CLI_VERSION=0.25.1 mkdir -p ./humctl rm -rf ./humctl/* diff --git a/src/adapters/humctl/HumctlAdapter.ts b/src/adapters/humctl/HumctlAdapter.ts index a3b387b..40eac1f 100644 --- a/src/adapters/humctl/HumctlAdapter.ts +++ b/src/adapters/humctl/HumctlAdapter.ts @@ -42,7 +42,7 @@ export class HumctlAdapter implements IHumctlAdapter { throw new UnsupportedOperatingSystemError(os, arch); } - let humctlEmbeddedBinaryFilename = `cli_0.24.0_${os}_${arch}`; + let humctlEmbeddedBinaryFilename = `cli_0.25.1_${os}_${arch}`; if (os === 'win32') { humctlEmbeddedBinaryFilename += '.exe'; } diff --git a/src/domain/ResourceType.ts b/src/domain/ResourceType.ts index 597872e..a87d949 100644 --- a/src/domain/ResourceType.ts +++ b/src/domain/ResourceType.ts @@ -4,7 +4,8 @@ export class ResourceType { public readonly name: string, public readonly type: string, public readonly inputs: Map, - public readonly outputs: Map + public readonly outputs: Map, + public readonly classes: ResourceTypeClass[] ) {} } @@ -16,3 +17,10 @@ export class ResourceTypeVariable { public readonly required: boolean ) {} } + +export class ResourceTypeClass { + constructor( + public readonly id: string, + public readonly description: string + ) {} +} diff --git a/src/providers/AvailableResourceTypesProvider.ts b/src/providers/AvailableResourceTypesProvider.ts index 2100aca..7fbfbce 100644 --- a/src/providers/AvailableResourceTypesProvider.ts +++ b/src/providers/AvailableResourceTypesProvider.ts @@ -1,5 +1,5 @@ import * as vscode from 'vscode'; -import { ResourceType, ResourceTypeVariable } from '../domain/ResourceType'; +import { ResourceTypeVariable } from '../domain/ResourceType'; import { IResourceTypeRepository } from '../repos/ResourceTypeRepository'; export class AvailableResourceTypesProvider @@ -8,49 +8,61 @@ export class AvailableResourceTypesProvider constructor(private resourceTypeRepository: IResourceTypeRepository) {} getTreeItem(element: AvailableResourceTypesTreeItem): vscode.TreeItem { - if (element instanceof ResourceType) { - return new ResourceTypeTreeItem(element.type, element.name); - } else if (element instanceof AvailableResourceTypesIO) { - return new ResourceTypeTreeItemIO(element.name); - } else { - return new ResourceTypeTreeItemIOValue( - element.name, - element.variable.type - ); - } + return element; } getChildren( element: AvailableResourceTypesTreeItem ): Thenable { if (element === undefined) { - return this.resourceTypeRepository.getAvailable().then(resourceTypes => { - return Promise.resolve(resourceTypes); - }); - } else if (element instanceof ResourceType) { + return this.resourceTypeRepository.getAvailable().then(resourceTypes => + Promise.resolve( + resourceTypes.map(resourceType => { + return new ResourceTypeTreeItem( + resourceType.type, + resourceType.name + ); + }) + ) + ); + } else if (element instanceof ResourceTypeTreeItem) { return Promise.resolve([ - new AvailableResourceTypesIO('inputs', element.type), - new AvailableResourceTypesIO('outputs', element.type), + new ResourceTypePropertyTreeItem('inputs', element.resourceType), + new ResourceTypePropertyTreeItem('outputs', element.resourceType), + new ResourceTypePropertyTreeItem('classes', element.resourceType), ]); - } else if (element instanceof AvailableResourceTypesIO) { + } else if (element instanceof ResourceTypePropertyTreeItem) { return this.resourceTypeRepository .get(element.resourceType) .then(resourceType => { - const result: ResourceTypeVariableWithName[] = []; - if (element.name === 'inputs') { + const vars: ResourceTypePropertyValueTreeItem[] = []; + if (element.property === 'inputs') { resourceType.inputs.forEach( (value: ResourceTypeVariable, key: string) => { - result.push(new ResourceTypeVariableWithName(key, value)); + vars.push( + new ResourceTypePropertyValueTreeItem(key, value.description) + ); } ); - } else { + } else if (element.property === 'outputs') { resourceType.outputs.forEach( (value: ResourceTypeVariable, key: string) => { - result.push(new ResourceTypeVariableWithName(key, value)); + vars.push( + new ResourceTypePropertyValueTreeItem(key, value.description) + ); } ); + } else { + resourceType.classes.forEach(resourceTypeClass => { + vars.push( + new ResourceTypePropertyValueTreeItem( + resourceTypeClass.id, + resourceTypeClass.description + ) + ); + }); } - return Promise.resolve(result); + return Promise.resolve(vars); }); } return Promise.resolve([]); @@ -71,43 +83,35 @@ export class AvailableResourceTypesProvider } export type AvailableResourceTypesTreeItem = - | ResourceType - | AvailableResourceTypesIO - | ResourceTypeVariableWithName; - -class AvailableResourceTypesIO { - constructor( - public readonly name: string, - public readonly resourceType: string - ) {} -} - -class ResourceTypeVariableWithName { - constructor( - public readonly name: string, - public readonly variable: ResourceTypeVariable - ) {} -} + | ResourceTypeTreeItem + | ResourceTypePropertyTreeItem + | ResourceTypePropertyValueTreeItem; class ResourceTypeTreeItem extends vscode.TreeItem { - constructor(label: string, description: string) { - super(label); - this.description = description; + constructor( + public readonly resourceType: string, + public readonly name: string + ) { + super(resourceType); + this.description = name; this.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; this.contextValue = 'resource_type'; } } -class ResourceTypeTreeItemIO extends vscode.TreeItem { - constructor(label: string) { - super(label); +class ResourceTypePropertyTreeItem extends vscode.TreeItem { + constructor( + public readonly property: string, + public readonly resourceType: string + ) { + super(property); this.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed; } } -class ResourceTypeTreeItemIOValue extends vscode.TreeItem { - constructor(label: string, description: string) { - super(label); +class ResourceTypePropertyValueTreeItem extends vscode.TreeItem { + constructor(value: string, description: string) { + super(value); this.description = description; this.collapsibleState = vscode.TreeItemCollapsibleState.None; } diff --git a/src/repos/ResourceTypeRepository.ts b/src/repos/ResourceTypeRepository.ts index aff6f16..e26a11a 100644 --- a/src/repos/ResourceTypeRepository.ts +++ b/src/repos/ResourceTypeRepository.ts @@ -1,4 +1,8 @@ -import { ResourceType, ResourceTypeVariable } from '../domain/ResourceType'; +import { + ResourceType, + ResourceTypeClass, + ResourceTypeVariable, +} from '../domain/ResourceType'; import { IHumctlAdapter } from '../adapters/humctl/IHumctlAdapter'; import { NotFoundError } from '../errors/NotFoundError'; @@ -7,6 +11,16 @@ export interface IResourceTypeRepository { get(name: string): Promise; } +interface AvailableResourceTypeOutput { + Name: string; + Type: string; + Category: string; + InputsSchema: any; + OutputsSchema: any; + // Casting JSON to Map doesn't work as expected, that's why it has to be any + Classes: any; +} + export class ResourceTypeRepository implements IResourceTypeRepository { constructor(private humctl: IHumctlAdapter) {} @@ -16,19 +30,30 @@ export class ResourceTypeRepository implements IResourceTypeRepository { 'available-resource-types', ]); - const rawResourceTypes = JSON.parse(result.stdout); - const rawResourceType = rawResourceTypes.find( - (rawResourceType: any) => rawResourceType['Type'] === type + const resourceTypes = JSON.parse( + result.stdout + ) as AvailableResourceTypeOutput[]; + const resourceType = resourceTypes.find( + rawResourceType => rawResourceType.Type === type ); - if (!rawResourceType) { + if (!resourceType) { throw new NotFoundError(); } + + const resourceTypeClasses: ResourceTypeClass[] = []; + for (const key in resourceType.Classes) { + resourceTypeClasses.push( + new ResourceTypeClass(key, resourceType.Classes[key]) + ); + } + return new ResourceType( - rawResourceType['Category'], - rawResourceType['Name'], - rawResourceType['Type'], - this.resolveVariables(rawResourceType['InputsSchema']), - this.resolveVariables(rawResourceType['OutputsSchema']) + resourceType.Category, + resourceType.Name, + resourceType.Type, + this.resolveVariables(resourceType.InputsSchema), + this.resolveVariables(resourceType.OutputsSchema), + resourceTypeClasses ); } @@ -39,14 +64,24 @@ export class ResourceTypeRepository implements IResourceTypeRepository { ]); const resourceTypes: ResourceType[] = []; - const rawResourceTypes = JSON.parse(result.stdout); - rawResourceTypes.forEach((rawResourceType: any) => { + const availableResourceTypes = JSON.parse( + result.stdout + ) as AvailableResourceTypeOutput[]; + availableResourceTypes.forEach(availableResourceType => { + const resourceTypeClasses: ResourceTypeClass[] = []; + for (const key in availableResourceType.Classes) { + resourceTypeClasses.push( + new ResourceTypeClass(key, availableResourceType.Classes[key]) + ); + } + const resourceType = new ResourceType( - rawResourceType['Category'], - rawResourceType['Name'], - rawResourceType['Type'], - this.resolveVariables(rawResourceType['InputsSchema']), - this.resolveVariables(rawResourceType['OutputsSchema']) + availableResourceType.Category, + availableResourceType.Name, + availableResourceType.Type, + this.resolveVariables(availableResourceType.InputsSchema), + this.resolveVariables(availableResourceType.OutputsSchema), + resourceTypeClasses ); resourceTypes.push(resourceType); });