task-script-support-cli 0.3.0 → 0.3.2
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/assets/yargs-template/task-runner/src/commands/verify.ts +3 -2
- package/assets/yargs-template/task-runner/src/services/banner-service.ts +13 -9
- package/assets/yargs-template/task-runner/src/tasks/banner/print-banner.ts +38 -0
- package/assets/yargs-template/task-runner/src/tasks/banner/resolve-banner-font.ts +70 -0
- package/assets/yargs-template/task-runner/src/types/state.ts +4 -0
- package/{dist/assets/yargs-template/task-runner/src/wrappers → assets/yargs-template/task-runner/src/wrappers/electives}/concurrent-task-group.ts +4 -4
- package/assets/yargs-template/task-runner/src/wrappers/electives/resolver-task.ts +87 -0
- package/assets/yargs-template/task-runner/src/wrappers/{sequential-task-group.ts → electives/sequential-task-group.ts} +4 -4
- package/assets/yargs-template/task-runner/tests/commands/verify.test.ts +14 -21
- package/dist/assets/yargs-template/task-runner/src/commands/verify.ts +3 -2
- package/dist/assets/yargs-template/task-runner/src/services/banner-service.ts +13 -9
- package/dist/assets/yargs-template/task-runner/src/tasks/banner/print-banner.ts +38 -0
- package/dist/assets/yargs-template/task-runner/src/tasks/banner/resolve-banner-font.ts +70 -0
- package/dist/assets/yargs-template/task-runner/src/types/state.ts +4 -0
- package/{assets/yargs-template/task-runner/src/wrappers → dist/assets/yargs-template/task-runner/src/wrappers/electives}/concurrent-task-group.ts +4 -4
- package/dist/assets/yargs-template/task-runner/src/wrappers/electives/resolver-task.ts +87 -0
- package/dist/assets/yargs-template/task-runner/src/wrappers/{sequential-task-group.ts → electives/sequential-task-group.ts} +4 -4
- package/dist/assets/yargs-template/task-runner/tests/commands/verify.test.ts +14 -21
- package/dist/package.json +1 -1
- package/dist/src/commands/gen.d.ts +3 -1
- package/dist/src/commands/gen.d.ts.map +1 -1
- package/dist/src/commands/gen.js +2 -0
- package/dist/src/commands/gen.js.map +1 -1
- package/dist/src/services/project-service.d.ts +21 -0
- package/dist/src/services/project-service.d.ts.map +1 -1
- package/dist/src/services/project-service.js +41 -0
- package/dist/src/services/project-service.js.map +1 -1
- package/dist/src/services/templater-service.d.ts +1 -0
- package/dist/src/services/templater-service.d.ts.map +1 -1
- package/dist/src/services/templater-service.js +9 -3
- package/dist/src/services/templater-service.js.map +1 -1
- package/dist/src/tasks/generate/generate-command.d.ts +10 -3
- package/dist/src/tasks/generate/generate-command.d.ts.map +1 -1
- package/dist/src/tasks/generate/generate-command.js +27 -11
- package/dist/src/tasks/generate/generate-command.js.map +1 -1
- package/dist/src/tasks/generate/generate-service.d.ts +10 -3
- package/dist/src/tasks/generate/generate-service.d.ts.map +1 -1
- package/dist/src/tasks/generate/generate-service.js +26 -12
- package/dist/src/tasks/generate/generate-service.js.map +1 -1
- package/dist/src/tasks/generate/generate-task.d.ts +10 -3
- package/dist/src/tasks/generate/generate-task.d.ts.map +1 -1
- package/dist/src/tasks/generate/generate-task.js +27 -13
- package/dist/src/tasks/generate/generate-task.js.map +1 -1
- package/dist/src/tasks/generate/project-context-guard.d.ts +1 -1
- package/dist/src/tasks/generate/project-context-guard.js +1 -1
- package/dist/src/tasks/generate/resolve-injectables.d.ts +56 -0
- package/dist/src/tasks/generate/resolve-injectables.d.ts.map +1 -0
- package/dist/src/tasks/generate/resolve-injectables.js +134 -0
- package/dist/src/tasks/generate/resolve-injectables.js.map +1 -0
- package/dist/src/tasks/generate/select-gen-target-name.js +4 -4
- package/dist/src/tasks/generate/select-gen-target-name.js.map +1 -1
- package/dist/src/tasks/generate/select-gen-target.d.ts +1 -1
- package/dist/src/tasks/generate/select-gen-target.js +2 -2
- package/dist/src/tasks/generate/select-gen-target.js.map +1 -1
- package/dist/src/tasks/stdout/print-generated-results.js +2 -2
- package/dist/src/tasks/stdout/print-generated-results.js.map +1 -1
- package/dist/src/tasks/sync-configuration.d.ts +1 -1
- package/dist/src/tasks/sync-configuration.js +6 -6
- package/dist/src/tasks/sync-configuration.js.map +1 -1
- package/dist/src/types/state.d.ts +7 -3
- package/dist/src/types/state.d.ts.map +1 -1
- package/dist/src/types/state.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/gen.ts +2 -0
- package/src/services/project-service.ts +54 -0
- package/src/services/templater-service.ts +15 -3
- package/src/tasks/generate/generate-command.ts +21 -11
- package/src/tasks/generate/generate-service.ts +20 -11
- package/src/tasks/generate/generate-task.ts +21 -12
- package/src/tasks/generate/project-context-guard.ts +1 -1
- package/src/tasks/generate/resolve-injectables.ts +154 -0
- package/src/tasks/generate/select-gen-target-name.ts +4 -4
- package/src/tasks/generate/select-gen-target.ts +2 -2
- package/src/tasks/stdout/print-generated-results.ts +2 -2
- package/src/tasks/sync-configuration.ts +6 -6
- package/src/types/state.ts +9 -3
- package/assets/yargs-template/task-runner/src/tasks/print-banner.ts +0 -73
- package/dist/assets/yargs-template/task-runner/src/tasks/print-banner.ts +0 -73
- package/dist/src/wrappers/gen-app-task.d.ts +0 -50
- package/dist/src/wrappers/gen-app-task.d.ts.map +0 -1
- package/dist/src/wrappers/gen-app-task.js +0 -124
- package/dist/src/wrappers/gen-app-task.js.map +0 -1
- package/src/wrappers/gen-app-task.ts +0 -150
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { singleton } from "tsyringe";
|
|
2
2
|
import { Command } from "../wrappers/command";
|
|
3
3
|
import CheckEnv from "../tasks/check-env";
|
|
4
|
-
import PrintBanner from "../tasks/print-banner";
|
|
4
|
+
import PrintBanner from "../tasks/banner/print-banner";
|
|
5
5
|
import LogState from "../tasks/log-state";
|
|
6
|
+
import ResolveBannerFont from "../tasks/banner/resolve-banner-font";
|
|
6
7
|
|
|
7
8
|
@singleton()
|
|
8
9
|
export class VerifyCommand extends Command {
|
|
9
|
-
tasks = [PrintBanner, CheckEnv, LogState];
|
|
10
|
+
tasks = [ResolveBannerFont, PrintBanner, CheckEnv, LogState];
|
|
10
11
|
}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { singleton } from "tsyringe";
|
|
2
2
|
import figlet from "figlet";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* BannerService
|
|
6
|
+
*
|
|
7
|
+
* Handles the generation of banner text using figlet.
|
|
8
|
+
*
|
|
9
|
+
* Some figlet fonts to try:
|
|
10
|
+
* ["ANSI Compact", "AMC Slash", "ANSI Shadow",
|
|
11
|
+
* "Basic", "Big", "Bell", "Calvin S", "Coinstak",
|
|
12
|
+
* "DOS Rebel", "Elite", "Emboss", "Future Smooth",
|
|
13
|
+
* "Kban", "Larry 3D 2", "Mono 9", "Shadow",
|
|
14
|
+
* "Small Poison", "Star Wars"]
|
|
15
|
+
*/
|
|
4
16
|
@singleton()
|
|
5
17
|
export class BannerService {
|
|
6
|
-
|
|
7
|
-
"AMC Slash",
|
|
8
|
-
"Calvin S",
|
|
9
|
-
"Bell",
|
|
10
|
-
"Pagga",
|
|
11
|
-
"Shadow",
|
|
12
|
-
"Small Block",
|
|
13
|
-
];
|
|
14
|
-
defaultFontFamily: string = "Cybermedium";
|
|
18
|
+
defaultFontFamily: string = "Standard";
|
|
15
19
|
|
|
16
20
|
async toBanner(text: string, font?: string): Promise<string> {
|
|
17
21
|
return await figlet.text(text, {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { autoInjectable } from "tsyringe";
|
|
2
|
+
import { AppState } from "../../types/state";
|
|
3
|
+
import { AppTask } from "../../wrappers/app-task";
|
|
4
|
+
import { BannerService } from "../../services/banner-service";
|
|
5
|
+
import { UtilService } from "../../services/util-service";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Prints an app banner to the console
|
|
10
|
+
*/
|
|
11
|
+
@autoInjectable()
|
|
12
|
+
export default class PrintBanner extends AppTask {
|
|
13
|
+
loggerName = "Print Banner";
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private bannerService: BannerService,
|
|
17
|
+
private utilService: UtilService,
|
|
18
|
+
) {
|
|
19
|
+
super();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async run({ data: { banner } }: AppState): Promise<Partial<AppState> | void> {
|
|
23
|
+
try {
|
|
24
|
+
console.log(
|
|
25
|
+
chalk.blueBright(
|
|
26
|
+
await this.bannerService.toBanner(
|
|
27
|
+
this.utilService.getAppName(),
|
|
28
|
+
banner?.font,
|
|
29
|
+
),
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
this.setData({ banner: { status: "success" } });
|
|
34
|
+
} catch (err) {
|
|
35
|
+
this.setData({ banner: { status: "failed" }, errorMessages: [`${err}`] });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { autoInjectable } from "tsyringe";
|
|
2
|
+
import { BannerService } from "../../services/banner-service";
|
|
3
|
+
import ResolverTask from "../../wrappers/electives/resolver-task";
|
|
4
|
+
import { CLIArgs } from "../../types/state";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ResolveBannerFont (Optional ResolverTask Pattern)
|
|
8
|
+
*
|
|
9
|
+
* ResolverTask that updates the AppStateData banner field. Resolves the banner
|
|
10
|
+
* font field via user input (bannerFont arg) or a randomly selected font value
|
|
11
|
+
* (randomFont arg). Uses BannerService's default otherwise. Doesn't define an
|
|
12
|
+
* envVar so doesn't support env overrides.
|
|
13
|
+
*/
|
|
14
|
+
@autoInjectable()
|
|
15
|
+
export default class ResolveBannerFont extends ResolverTask {
|
|
16
|
+
loggerName = "ResolveBannerFont";
|
|
17
|
+
|
|
18
|
+
resolveTo = "banner" as const;
|
|
19
|
+
argVar = "bannerFont" as const;
|
|
20
|
+
|
|
21
|
+
constructor(private bannerService: BannerService) {
|
|
22
|
+
super();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get the default banner font value.
|
|
27
|
+
*/
|
|
28
|
+
//@override
|
|
29
|
+
async getDefaultValue<T>(): Promise<T | undefined> {
|
|
30
|
+
return { font: this.bannerService.defaultFontFamily } as T;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Attempt to resolve the font from the CLI args.
|
|
35
|
+
*
|
|
36
|
+
* @param args the CLIArgs to resolve from.
|
|
37
|
+
* @returns the resolved font, or undefined if no font args provided
|
|
38
|
+
*/
|
|
39
|
+
//@override
|
|
40
|
+
async getArg<T>(args: CLIArgs) {
|
|
41
|
+
const bannerFont = args.bannerFont;
|
|
42
|
+
if (bannerFont) {
|
|
43
|
+
await this.validateFont(bannerFont);
|
|
44
|
+
return { font: bannerFont } as T;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// also allow --random-font arg as an override
|
|
48
|
+
if (args.randomFont) {
|
|
49
|
+
const randomFont = await this.bannerService.getRandomFont();
|
|
50
|
+
this.logger.debug(`Using random font ${randomFont}`);
|
|
51
|
+
return { font: randomFont } as T;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Validate a provided font is supported.
|
|
59
|
+
*
|
|
60
|
+
* @param font the font to validate.
|
|
61
|
+
* @throws Error if the font is not supported.
|
|
62
|
+
*/
|
|
63
|
+
async validateFont(font: string): Promise<void> {
|
|
64
|
+
const availableFonts = await this.bannerService.getSupportedFonts();
|
|
65
|
+
|
|
66
|
+
if (!availableFonts.includes(font)) {
|
|
67
|
+
throw new Error(`Unsupported font provided: ${font}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { AppTask } from "
|
|
1
|
+
import { AppTask } from "../app-task";
|
|
2
2
|
import { autoInjectable } from "tsyringe";
|
|
3
|
-
import { AppTaskClass } from "
|
|
3
|
+
import { AppTaskClass } from "../../types/state";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Wrapper for Running a Group of Concurrent Tasks
|
|
7
7
|
*
|
|
8
|
-
* Extend this class and override the tasks
|
|
8
|
+
* Extend this class and override the tasks field to run tasks
|
|
9
9
|
* concurrently within a Task itself. The fallback run method
|
|
10
|
-
* handles state and execution of the tasks.
|
|
10
|
+
* handles the state and execution of the tasks.
|
|
11
11
|
*/
|
|
12
12
|
@autoInjectable()
|
|
13
13
|
export default class ConcurrentTaskGroup extends AppTask {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AppState,
|
|
3
|
+
AppStateData,
|
|
4
|
+
CLIArgs,
|
|
5
|
+
DefaultValues,
|
|
6
|
+
EnvironmentConfigKeys,
|
|
7
|
+
} from "../../types/state";
|
|
8
|
+
import { AppTask } from "../app-task";
|
|
9
|
+
import { autoInjectable } from "tsyringe";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* ResolverTask
|
|
13
|
+
*
|
|
14
|
+
* Wrapper Task that resolves a value in the AppStateData.
|
|
15
|
+
*
|
|
16
|
+
* Allows enforcing the following order of precedence for resolving a value:
|
|
17
|
+
* - CLI arg (if provided)
|
|
18
|
+
* - Environment variable (if set)
|
|
19
|
+
* - Default / Fallback value
|
|
20
|
+
*/
|
|
21
|
+
@autoInjectable()
|
|
22
|
+
export default class ResolverTask extends AppTask {
|
|
23
|
+
loggerName = "Resolver";
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
Extend the class and override the following fields to customize the resolver.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// the target field to resolve on AppStateData
|
|
30
|
+
declare resolveTo: keyof AppStateData;
|
|
31
|
+
|
|
32
|
+
// arg override has highest precedence
|
|
33
|
+
declare argVar?: keyof CLIArgs;
|
|
34
|
+
|
|
35
|
+
// then env override
|
|
36
|
+
declare envVar?: keyof typeof EnvironmentConfigKeys;
|
|
37
|
+
|
|
38
|
+
// finally, a default fallback value can be provided
|
|
39
|
+
declare defaultKey?: keyof typeof DefaultValues;
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
Optionally, override these methods to customize additional behavior of the resolver.
|
|
43
|
+
*/
|
|
44
|
+
async getDefaultValue<T>(): Promise<T | undefined> {
|
|
45
|
+
return this.defaultKey ? (DefaultValues[this.defaultKey] as T) : undefined;
|
|
46
|
+
}
|
|
47
|
+
async getArg<T>(args: CLIArgs): Promise<T | undefined> {
|
|
48
|
+
if (this.argVar && args[this.argVar]) {
|
|
49
|
+
return args[this.argVar] as T;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async getEnv<T>(): Promise<T | undefined> {
|
|
53
|
+
if (this.envVar && process.env[this.envVar]) {
|
|
54
|
+
return process.env[this.envVar] as T;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
The ResolverTask run method keeps the resolution order consistent across all
|
|
60
|
+
resolver tasks. It should not be overridden subclasses.
|
|
61
|
+
*/
|
|
62
|
+
async run(): Promise<Partial<AppState> | void> {
|
|
63
|
+
const argResult = await this.getArg(this.state.args);
|
|
64
|
+
if (argResult) {
|
|
65
|
+
return {
|
|
66
|
+
data: {
|
|
67
|
+
[this.resolveTo]: argResult,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const envResult = await this.getEnv();
|
|
73
|
+
if (envResult) {
|
|
74
|
+
return {
|
|
75
|
+
data: {
|
|
76
|
+
[this.resolveTo]: envResult,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
data: {
|
|
83
|
+
[this.resolveTo]: await this.getDefaultValue(),
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { AppTask } from "
|
|
1
|
+
import { AppTask } from "../app-task";
|
|
2
2
|
import { autoInjectable } from "tsyringe";
|
|
3
|
-
import { AppTaskClass } from "
|
|
3
|
+
import { AppTaskClass } from "../../types/state";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Wrapper for Running a Group of Sequential Tasks
|
|
7
7
|
*
|
|
8
|
-
* Extend this class and override the tasks
|
|
9
|
-
* of tasks in order as a Task. The fallback run method handles state
|
|
8
|
+
* Extend this class and override the tasks field to run a sequence
|
|
9
|
+
* of tasks in order as a Task. The fallback run method handles the state
|
|
10
10
|
* and execution of the tasks.
|
|
11
11
|
*/
|
|
12
12
|
@autoInjectable()
|
|
@@ -1,41 +1,34 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { describe, it, expect, vi } from "vitest";
|
|
3
|
-
import PrintBanner from "../../src/tasks/print-banner";
|
|
3
|
+
import PrintBanner from "../../src/tasks/banner/print-banner";
|
|
4
4
|
import CheckEnv from "../../src/tasks/check-env";
|
|
5
5
|
import { container } from "tsyringe";
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
6
|
+
import ResolveBannerFont from "../../src/tasks/banner/resolve-banner-font";
|
|
7
|
+
import { VerifyCommand } from "../../src/commands/verify";
|
|
8
|
+
import { CLIArgs } from "../../src/types/state";
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
vi.mock("../../src/tasks/print-banner"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return { default: PrintBannerMock };
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
vi.mock("../../src/tasks/check-env", () => {
|
|
17
|
-
const CheckEnvMock = vi.fn();
|
|
18
|
-
CheckEnvMock.prototype.run = vi.fn();
|
|
19
|
-
return { default: CheckEnvMock };
|
|
20
|
-
});
|
|
10
|
+
vi.mock("../../src/tasks/banner/resolve-banner-font");
|
|
11
|
+
vi.mock("../../src/tasks/banner/print-banner");
|
|
12
|
+
vi.mock("../../src/tasks/check-env");
|
|
13
|
+
vi.mock("../../src/tasks/log-state");
|
|
21
14
|
|
|
22
15
|
describe("verify command", () => {
|
|
23
16
|
it("should run PrintBanner and then CheckEnv", async () => {
|
|
24
|
-
const
|
|
25
|
-
container.register("Args", { useValue: [] });
|
|
17
|
+
const args: CLIArgs[] = [];
|
|
26
18
|
|
|
19
|
+
container.register("Args", { useValue: args });
|
|
27
20
|
// when
|
|
28
|
-
await
|
|
29
|
-
tasks,
|
|
30
|
-
{} as CLIArgs,
|
|
31
|
-
);
|
|
21
|
+
await container.resolve(VerifyCommand).handler(args);
|
|
32
22
|
|
|
33
23
|
expect(PrintBanner).toHaveBeenCalled();
|
|
34
24
|
expect(CheckEnv).toHaveBeenCalled();
|
|
35
25
|
|
|
36
26
|
const printBannerInstance = (PrintBanner as any).mock.instances[0];
|
|
37
27
|
const checkEnvInstance = (CheckEnv as any).mock.instances[0];
|
|
28
|
+
const resolveBannerFontInstance = (ResolveBannerFont as any).mock
|
|
29
|
+
.instances[0];
|
|
38
30
|
|
|
31
|
+
expect(resolveBannerFontInstance.run).toHaveBeenCalled();
|
|
39
32
|
expect(printBannerInstance.run).toHaveBeenCalled();
|
|
40
33
|
expect(checkEnvInstance.run).toHaveBeenCalled();
|
|
41
34
|
});
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { singleton } from "tsyringe";
|
|
2
2
|
import { Command } from "../wrappers/command";
|
|
3
3
|
import CheckEnv from "../tasks/check-env";
|
|
4
|
-
import PrintBanner from "../tasks/print-banner";
|
|
4
|
+
import PrintBanner from "../tasks/banner/print-banner";
|
|
5
5
|
import LogState from "../tasks/log-state";
|
|
6
|
+
import ResolveBannerFont from "../tasks/banner/resolve-banner-font";
|
|
6
7
|
|
|
7
8
|
@singleton()
|
|
8
9
|
export class VerifyCommand extends Command {
|
|
9
|
-
tasks = [PrintBanner, CheckEnv, LogState];
|
|
10
|
+
tasks = [ResolveBannerFont, PrintBanner, CheckEnv, LogState];
|
|
10
11
|
}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { singleton } from "tsyringe";
|
|
2
2
|
import figlet from "figlet";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* BannerService
|
|
6
|
+
*
|
|
7
|
+
* Handles the generation of banner text using figlet.
|
|
8
|
+
*
|
|
9
|
+
* Some figlet fonts to try:
|
|
10
|
+
* ["ANSI Compact", "AMC Slash", "ANSI Shadow",
|
|
11
|
+
* "Basic", "Big", "Bell", "Calvin S", "Coinstak",
|
|
12
|
+
* "DOS Rebel", "Elite", "Emboss", "Future Smooth",
|
|
13
|
+
* "Kban", "Larry 3D 2", "Mono 9", "Shadow",
|
|
14
|
+
* "Small Poison", "Star Wars"]
|
|
15
|
+
*/
|
|
4
16
|
@singleton()
|
|
5
17
|
export class BannerService {
|
|
6
|
-
|
|
7
|
-
"AMC Slash",
|
|
8
|
-
"Calvin S",
|
|
9
|
-
"Bell",
|
|
10
|
-
"Pagga",
|
|
11
|
-
"Shadow",
|
|
12
|
-
"Small Block",
|
|
13
|
-
];
|
|
14
|
-
defaultFontFamily: string = "Cybermedium";
|
|
18
|
+
defaultFontFamily: string = "Standard";
|
|
15
19
|
|
|
16
20
|
async toBanner(text: string, font?: string): Promise<string> {
|
|
17
21
|
return await figlet.text(text, {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { autoInjectable } from "tsyringe";
|
|
2
|
+
import { AppState } from "../../types/state";
|
|
3
|
+
import { AppTask } from "../../wrappers/app-task";
|
|
4
|
+
import { BannerService } from "../../services/banner-service";
|
|
5
|
+
import { UtilService } from "../../services/util-service";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Prints an app banner to the console
|
|
10
|
+
*/
|
|
11
|
+
@autoInjectable()
|
|
12
|
+
export default class PrintBanner extends AppTask {
|
|
13
|
+
loggerName = "Print Banner";
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private bannerService: BannerService,
|
|
17
|
+
private utilService: UtilService,
|
|
18
|
+
) {
|
|
19
|
+
super();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async run({ data: { banner } }: AppState): Promise<Partial<AppState> | void> {
|
|
23
|
+
try {
|
|
24
|
+
console.log(
|
|
25
|
+
chalk.blueBright(
|
|
26
|
+
await this.bannerService.toBanner(
|
|
27
|
+
this.utilService.getAppName(),
|
|
28
|
+
banner?.font,
|
|
29
|
+
),
|
|
30
|
+
),
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
this.setData({ banner: { status: "success" } });
|
|
34
|
+
} catch (err) {
|
|
35
|
+
this.setData({ banner: { status: "failed" }, errorMessages: [`${err}`] });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { autoInjectable } from "tsyringe";
|
|
2
|
+
import { BannerService } from "../../services/banner-service";
|
|
3
|
+
import ResolverTask from "../../wrappers/electives/resolver-task";
|
|
4
|
+
import { CLIArgs } from "../../types/state";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* ResolveBannerFont (Optional ResolverTask Pattern)
|
|
8
|
+
*
|
|
9
|
+
* ResolverTask that updates the AppStateData banner field. Resolves the banner
|
|
10
|
+
* font field via user input (bannerFont arg) or a randomly selected font value
|
|
11
|
+
* (randomFont arg). Uses BannerService's default otherwise. Doesn't define an
|
|
12
|
+
* envVar so doesn't support env overrides.
|
|
13
|
+
*/
|
|
14
|
+
@autoInjectable()
|
|
15
|
+
export default class ResolveBannerFont extends ResolverTask {
|
|
16
|
+
loggerName = "ResolveBannerFont";
|
|
17
|
+
|
|
18
|
+
resolveTo = "banner" as const;
|
|
19
|
+
argVar = "bannerFont" as const;
|
|
20
|
+
|
|
21
|
+
constructor(private bannerService: BannerService) {
|
|
22
|
+
super();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get the default banner font value.
|
|
27
|
+
*/
|
|
28
|
+
//@override
|
|
29
|
+
async getDefaultValue<T>(): Promise<T | undefined> {
|
|
30
|
+
return { font: this.bannerService.defaultFontFamily } as T;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Attempt to resolve the font from the CLI args.
|
|
35
|
+
*
|
|
36
|
+
* @param args the CLIArgs to resolve from.
|
|
37
|
+
* @returns the resolved font, or undefined if no font args provided
|
|
38
|
+
*/
|
|
39
|
+
//@override
|
|
40
|
+
async getArg<T>(args: CLIArgs) {
|
|
41
|
+
const bannerFont = args.bannerFont;
|
|
42
|
+
if (bannerFont) {
|
|
43
|
+
await this.validateFont(bannerFont);
|
|
44
|
+
return { font: bannerFont } as T;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// also allow --random-font arg as an override
|
|
48
|
+
if (args.randomFont) {
|
|
49
|
+
const randomFont = await this.bannerService.getRandomFont();
|
|
50
|
+
this.logger.debug(`Using random font ${randomFont}`);
|
|
51
|
+
return { font: randomFont } as T;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Validate a provided font is supported.
|
|
59
|
+
*
|
|
60
|
+
* @param font the font to validate.
|
|
61
|
+
* @throws Error if the font is not supported.
|
|
62
|
+
*/
|
|
63
|
+
async validateFont(font: string): Promise<void> {
|
|
64
|
+
const availableFonts = await this.bannerService.getSupportedFonts();
|
|
65
|
+
|
|
66
|
+
if (!availableFonts.includes(font)) {
|
|
67
|
+
throw new Error(`Unsupported font provided: ${font}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { AppTask } from "
|
|
1
|
+
import { AppTask } from "../app-task";
|
|
2
2
|
import { autoInjectable } from "tsyringe";
|
|
3
|
-
import { AppTaskClass } from "
|
|
3
|
+
import { AppTaskClass } from "../../types/state";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Wrapper for Running a Group of Concurrent Tasks
|
|
7
7
|
*
|
|
8
|
-
* Extend this class and override the tasks
|
|
8
|
+
* Extend this class and override the tasks field to run tasks
|
|
9
9
|
* concurrently within a Task itself. The fallback run method
|
|
10
|
-
* handles state and execution of the tasks.
|
|
10
|
+
* handles the state and execution of the tasks.
|
|
11
11
|
*/
|
|
12
12
|
@autoInjectable()
|
|
13
13
|
export default class ConcurrentTaskGroup extends AppTask {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AppState,
|
|
3
|
+
AppStateData,
|
|
4
|
+
CLIArgs,
|
|
5
|
+
DefaultValues,
|
|
6
|
+
EnvironmentConfigKeys,
|
|
7
|
+
} from "../../types/state";
|
|
8
|
+
import { AppTask } from "../app-task";
|
|
9
|
+
import { autoInjectable } from "tsyringe";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* ResolverTask
|
|
13
|
+
*
|
|
14
|
+
* Wrapper Task that resolves a value in the AppStateData.
|
|
15
|
+
*
|
|
16
|
+
* Allows enforcing the following order of precedence for resolving a value:
|
|
17
|
+
* - CLI arg (if provided)
|
|
18
|
+
* - Environment variable (if set)
|
|
19
|
+
* - Default / Fallback value
|
|
20
|
+
*/
|
|
21
|
+
@autoInjectable()
|
|
22
|
+
export default class ResolverTask extends AppTask {
|
|
23
|
+
loggerName = "Resolver";
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
Extend the class and override the following fields to customize the resolver.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// the target field to resolve on AppStateData
|
|
30
|
+
declare resolveTo: keyof AppStateData;
|
|
31
|
+
|
|
32
|
+
// arg override has highest precedence
|
|
33
|
+
declare argVar?: keyof CLIArgs;
|
|
34
|
+
|
|
35
|
+
// then env override
|
|
36
|
+
declare envVar?: keyof typeof EnvironmentConfigKeys;
|
|
37
|
+
|
|
38
|
+
// finally, a default fallback value can be provided
|
|
39
|
+
declare defaultKey?: keyof typeof DefaultValues;
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
Optionally, override these methods to customize additional behavior of the resolver.
|
|
43
|
+
*/
|
|
44
|
+
async getDefaultValue<T>(): Promise<T | undefined> {
|
|
45
|
+
return this.defaultKey ? (DefaultValues[this.defaultKey] as T) : undefined;
|
|
46
|
+
}
|
|
47
|
+
async getArg<T>(args: CLIArgs): Promise<T | undefined> {
|
|
48
|
+
if (this.argVar && args[this.argVar]) {
|
|
49
|
+
return args[this.argVar] as T;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async getEnv<T>(): Promise<T | undefined> {
|
|
53
|
+
if (this.envVar && process.env[this.envVar]) {
|
|
54
|
+
return process.env[this.envVar] as T;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
The ResolverTask run method keeps the resolution order consistent across all
|
|
60
|
+
resolver tasks. It should not be overridden subclasses.
|
|
61
|
+
*/
|
|
62
|
+
async run(): Promise<Partial<AppState> | void> {
|
|
63
|
+
const argResult = await this.getArg(this.state.args);
|
|
64
|
+
if (argResult) {
|
|
65
|
+
return {
|
|
66
|
+
data: {
|
|
67
|
+
[this.resolveTo]: argResult,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const envResult = await this.getEnv();
|
|
73
|
+
if (envResult) {
|
|
74
|
+
return {
|
|
75
|
+
data: {
|
|
76
|
+
[this.resolveTo]: envResult,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
data: {
|
|
83
|
+
[this.resolveTo]: await this.getDefaultValue(),
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { AppTask } from "
|
|
1
|
+
import { AppTask } from "../app-task";
|
|
2
2
|
import { autoInjectable } from "tsyringe";
|
|
3
|
-
import { AppTaskClass } from "
|
|
3
|
+
import { AppTaskClass } from "../../types/state";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Wrapper for Running a Group of Sequential Tasks
|
|
7
7
|
*
|
|
8
|
-
* Extend this class and override the tasks
|
|
9
|
-
* of tasks in order as a Task. The fallback run method handles state
|
|
8
|
+
* Extend this class and override the tasks field to run a sequence
|
|
9
|
+
* of tasks in order as a Task. The fallback run method handles the state
|
|
10
10
|
* and execution of the tasks.
|
|
11
11
|
*/
|
|
12
12
|
@autoInjectable()
|