UNPKG

3.71 kBPlain TextView Raw
1import { take } from 'rxjs/operators';
2import { CLIOption, CRUDBase, NamesIn } from './CRUDBase';
3import { ResourceType } from './ResourceType';
4import { BaseResource, BaseResourceOptions, InteractiveCLI } from './types';
5
6export interface ExecCLIOptions<ResourceOptions extends BaseResourceOptions> {
7 readonly name: string;
8 readonly cli: InteractiveCLI;
9 readonly options: ResourceOptions;
10}
11
12export interface GetCLIAutocompleteOptions {
13 readonly cli: InteractiveCLI;
14}
15
16export interface CRUDResourceOptions<Resource extends BaseResource, ResourceOptions extends BaseResourceOptions> {
17 readonly name: string;
18 readonly names?: NamesIn;
19 readonly resourceType: ResourceType<Resource, ResourceOptions>;
20 readonly help: string;
21 readonly aliases?: ReadonlyArray<string>;
22 readonly extraArgs?: ReadonlyArray<string>;
23 readonly options?: ReadonlyArray<CLIOption>;
24 readonly autocomplete?: ReadonlyArray<string>;
25 readonly hidden?: boolean;
26}
27
28export interface GetCLINameOptions<ResourceOptions extends BaseResourceOptions> {
29 readonly baseName: string;
30 readonly cli: InteractiveCLI;
31 readonly options: ResourceOptions;
32}
33
34export class CRUDResourceBase<
35 Resource extends BaseResource = BaseResource,
36 ResourceOptions extends BaseResourceOptions = BaseResourceOptions
37> extends CRUDBase<Resource, ResourceOptions> {
38 public constructor({
39 name,
40 names,
41 resourceType,
42 help,
43 aliases,
44 extraArgs,
45 options,
46 autocomplete,
47 hidden,
48 }: CRUDResourceOptions<Resource, ResourceOptions>) {
49 const commandBase = `${name} ${resourceType.name} <name>`;
50 const command = extraArgs === undefined ? commandBase : `${commandBase} ${extraArgs.join(' ')}`;
51
52 super({
53 name,
54 names,
55 command,
56 resourceType,
57 help,
58 aliases,
59 options,
60 autocomplete,
61 hidden,
62 });
63 }
64
65 public async getCLIName({ baseName }: GetCLINameOptions<ResourceOptions>): Promise<string> {
66 return Promise.resolve(baseName);
67 }
68
69 public async getCLIAutocomplete(options: GetCLIAutocompleteOptions): Promise<ReadonlyArray<string>> {
70 const { cli } = options;
71 try {
72 const resourceOptions = await this.getCLIAutocompleteResourceOptions(options);
73
74 const resources = await cli.client
75 .getResources$({
76 plugin: this.resourceType.plugin.name,
77 resourceType: this.resourceType.name,
78 options: resourceOptions,
79 })
80 .pipe(take(1))
81 .toPromise()
82 .then((results) => results.map((result) => result.baseName));
83
84 return [...new Set(resources.concat(this.autocomplete))];
85 } catch (error) {
86 this.resourceType.plugin.monitor.logError({
87 name: 'neo_crud_get_cli_autocomplete_error',
88 message: 'Failed to fetch cli autocomplete.',
89 error,
90 });
91
92 return this.autocomplete;
93 }
94 }
95
96 // Extract options that will be passed to ResourceType#filterResources.
97 public async getCLIAutocompleteResourceOptions({ cli }: GetCLIAutocompleteOptions): Promise<ResourceOptions> {
98 return this.getCLIResourceOptions({ cli, args: {}, options: {} });
99 }
100
101 // Function to execute before the command. Useful if you want to do things
102 // like call other commands, e.g. `activate <name>` before activating another
103 // name.
104 public async preExecCLI(_options: ExecCLIOptions<ResourceOptions>): Promise<void> {
105 return Promise.resolve();
106 }
107
108 // Function to execute after the command is complete. Useful if you want to do
109 // things like call other commands, e.g. `activate <name>` after starting
110 // <name>
111 public async postExecCLI(_options: ExecCLIOptions<ResourceOptions>): Promise<void> {
112 return Promise.resolve();
113 }
114}