@flowscripter/dynamic-cli-framework 1.2.1 → 1.3.0
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/README/core-service-providers.md +2 -2
- package/README/development.md +3 -6
- package/README/implementation-details.md +17 -17
- package/README/key-concepts.md +17 -17
- package/README.md +4 -4
- package/bun.lock +0 -2
- package/index.ts +22 -30
- package/package.json +19 -19
- package/src/api/argument/Argument.ts +1 -1
- package/src/api/argument/ArgumentValueTypes.ts +3 -10
- package/src/api/argument/ComplexOption.ts +5 -9
- package/src/api/command/GlobalCommand.ts +1 -4
- package/src/api/service/core/ArgumentPrompterService.ts +1 -3
- package/src/api/service/core/AsciiBannerGeneratorService.ts +1 -4
- package/src/api/service/core/CompletionService.ts +2 -6
- package/src/api/service/core/ImagePrinterService.ts +1 -2
- package/src/api/service/core/KeyValueService.ts +1 -2
- package/src/api/service/core/PrettyPrinterService.ts +1 -4
- package/src/api/service/core/PrinterService.ts +8 -9
- package/src/api/service/core/PrompterService.ts +4 -11
- package/src/api/service/core/ShutdownService.ts +1 -2
- package/src/api/service/core/SyntaxHighlighterService.ts +1 -5
- package/src/api/service/core/Table.ts +7 -25
- package/src/api/service/core/TreePrinterService.ts +1 -2
- package/src/cli/BaseCLI.ts +17 -47
- package/src/cli/DefaultRuntimeCLI.ts +1 -4
- package/src/command/CompletionCommand.ts +19 -45
- package/src/command/MultiCommandCliHelpCommand.ts +45 -92
- package/src/command/SingleCommandCliHelpCommand.ts +17 -28
- package/src/command/UsageCommand.ts +6 -12
- package/src/command/VersionCommand.ts +2 -6
- package/src/launcher.ts +4 -2
- package/src/runtime/DefaultContext.ts +2 -5
- package/src/runtime/argument/ArgumentTypeGuards.ts +1 -3
- package/src/runtime/command/CommandTypeGuards.ts +5 -14
- package/src/runtime/command/CommandValidator.ts +56 -118
- package/src/runtime/parser.ts +13 -17
- package/src/runtime/registry/CommandRegistry.ts +2 -7
- package/src/runtime/registry/DefaultCommandRegistry.ts +32 -84
- package/src/runtime/registry/DefaultServiceProviderRegistry.ts +3 -9
- package/src/runtime/runner.ts +103 -142
- package/src/runtime/scanner.ts +28 -46
- package/src/runtime/values/ValuePopulationResult.ts +1 -2
- package/src/runtime/values/argumentValueMerge.ts +16 -28
- package/src/runtime/values/argumentValueValidation.ts +21 -67
- package/src/runtime/values/globalCommandValuePopulation.ts +9 -18
- package/src/runtime/values/subCommandValuePopulation.ts +42 -65
- package/src/service/argumentPrompter/ArgumentPrompterServiceProvider.ts +3 -10
- package/src/service/argumentPrompter/DefaultArgumentPrompterService.ts +22 -59
- package/src/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.ts +5 -14
- package/src/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.ts +59 -77
- package/src/service/banner/BannerServiceProvider.ts +13 -35
- package/src/service/banner/command/NoBannerCommand.ts +2 -8
- package/src/service/chiselAsciiBannerGenerator/ChiselFontAsciiBannerGeneratorService.ts +5 -10
- package/src/service/completion/CompletionServiceProvider.ts +20 -48
- package/src/service/completion/DefaultCompletionService.ts +17 -56
- package/src/service/completion/shell/ShellHandler.ts +1 -3
- package/src/service/completion/shell/fish.ts +1 -1
- package/src/service/completion/shell/powershell.ts +2 -12
- package/src/service/completion/shell/zsh.ts +1 -1
- package/src/service/configuration/ConfigurationServiceProvider.ts +40 -133
- package/src/service/configuration/DefaultKeyValueService.ts +6 -20
- package/src/service/configuration/DefaultSecretService.ts +10 -14
- package/src/service/configuration/command/ConfigCommand.ts +1 -4
- package/src/service/configuration/command/DumpConfigCommand.ts +9 -21
- package/src/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.ts +5 -14
- package/src/service/dataDumpGenerator/DefaultDataDumpGeneratorService.ts +5 -12
- package/src/service/imagePrinter/DefaultImagePrinterService.ts +1 -5
- package/src/service/imagePrinter/ImagePrinterServiceProvider.ts +1 -4
- package/src/service/prettyPrinter/DefaultPrettyPrinterService.ts +4 -12
- package/src/service/prettyPrinter/PrettyPrinterServiceProvider.ts +3 -10
- package/src/service/printer/DefaultPrinterService.ts +20 -83
- package/src/service/printer/PrinterServiceProvider.ts +3 -11
- package/src/service/printer/command/DarkModeCommand.ts +3 -10
- package/src/service/printer/command/LogLevelCommand.ts +7 -26
- package/src/service/printer/command/NoColorCommand.ts +3 -10
- package/src/service/printer/command/NoHyperlinksCommand.ts +3 -10
- package/src/service/printer/terminal/Progress.ts +99 -90
- package/src/service/printer/terminal/Spinner.ts +7 -26
- package/src/service/prompter/DefaultPrompterService.ts +2 -6
- package/src/service/prompter/PrompterServiceProvider.ts +3 -11
- package/src/service/prompter/command/NoPromptCommand.ts +3 -10
- package/src/service/prompter/prompt/PromptContext.ts +5 -18
- package/src/service/prompter/prompt/promptMultiSelect.ts +6 -21
- package/src/service/prompter/prompt/promptOpenUrl.ts +7 -22
- package/src/service/prompter/prompt/promptSingleSelect.ts +6 -23
- package/src/service/prompter/prompt/promptText.ts +10 -27
- package/src/service/prompter/prompt/promptToggle.ts +8 -8
- package/src/service/shutdown/ShutdownServiceProvider.ts +3 -10
- package/src/service/syntaxHighlighter/DefaultSyntaxHighlighterService.ts +13 -26
- package/src/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.ts +8 -21
- package/src/service/tableGenerator/DefaultTableGeneratorService.ts +44 -68
- package/src/service/tableGenerator/TableGeneratorServiceProvider.ts +7 -16
- package/src/service/treePrinter/DefaultTreePrinterService.ts +2 -7
- package/src/service/treePrinter/TreePrinterServiceProvider.ts +4 -12
- package/src/terminal/ImageRenderer.ts +35 -54
- package/src/terminal/PngDecoder.ts +10 -19
- package/src/terminal/TtyStyler.ts +11 -9
- package/src/terminal/TtyTerminal.ts +2 -10
- package/src/terminal/supportsHyperlinks.ts +4 -10
- package/src/util/configHelper.ts +3 -10
- package/src/util/envVarHelper.ts +50 -88
- package/src/util/helpHelper.ts +123 -193
- package/src/util/logger.ts +12 -42
- package/src/util/runnerHelper.ts +20 -61
- package/tests/cli/BaseCLI.test.ts +23 -80
- package/tests/command/CompletionCommand.test.ts +1 -6
- package/tests/command/MultiCommandCliHelpCommand.test.ts +51 -205
- package/tests/command/SingleCommandCliHelpCommand.test.ts +21 -103
- package/tests/command/UsageCommand.test.ts +4 -10
- package/tests/fixtures/Command.ts +87 -68
- package/tests/fixtures/CommandRegistry.ts +1 -3
- package/tests/fixtures/Context.ts +3 -11
- package/tests/fixtures/ServiceProviderRegistry.ts +1 -1
- package/tests/fixtures/prettierPluginFoo.ts +1 -1
- package/tests/fixtures/util.ts +2 -8
- package/tests/runtime/argument/ArgumentTypeGuards.test.ts +1 -3
- package/tests/runtime/command/CommandValidator.test.ts +881 -604
- package/tests/runtime/parser.test.ts +222 -246
- package/tests/runtime/registry/DefaultCommandRegistry.test.ts +15 -37
- package/tests/runtime/registry/DefaultServiceProviderRegistry.test.ts +2 -8
- package/tests/runtime/runner.test.ts +231 -281
- package/tests/runtime/scanner.test.ts +277 -475
- package/tests/runtime/values/argumentValueMerge.test.ts +133 -81
- package/tests/runtime/values/argumentValueValidation.test.ts +444 -588
- package/tests/runtime/values/globalCommandValuePopulation.test.ts +71 -253
- package/tests/runtime/values/subCommandValuePopulation.test.ts +1342 -1570
- package/tests/service/argumentPrompter/ArgumentPrompterServiceProvider.test.ts +3 -12
- package/tests/service/argumentPrompter/DefaultArgumentPrompterService.test.ts +36 -45
- package/tests/service/asciiBannerGenerator/AsciiBannerGeneratorServiceProvider.test.ts +2 -8
- package/tests/service/asciiBannerGenerator/DefaultAsciiBannerGeneratorService.test.ts +40 -62
- package/tests/service/banner/BannerServiceProvider.test.ts +5 -18
- package/tests/service/banner/command/NoBannerCommand.test.ts +1 -4
- package/tests/service/completion/CompletionServiceProvider.test.ts +145 -214
- package/tests/service/completion/DefaultCompletionService.test.ts +17 -79
- package/tests/service/completion/shell/fish.test.ts +1 -3
- package/tests/service/configuration/ConfigurationServiceProvider.test.ts +26 -75
- package/tests/service/configuration/DefaultKeyValueService.test.ts +9 -21
- package/tests/service/configuration/DefaultSecretService.test.ts +7 -15
- package/tests/service/configuration/command/DumpConfigCommand.test.ts +4 -13
- package/tests/service/dataDumpGenerator/DataDumpGeneratorServiceProvider.test.ts +6 -12
- package/tests/service/dataDumpGenerator/DefaultDataDumpGeneratorService.test.ts +1 -10
- package/tests/service/imagePrinter/DefaultImagePrinterService.test.ts +5 -70
- package/tests/service/prettyPrinter/DefaultPrettyPrinterService.test.ts +4 -11
- package/tests/service/prettyPrinter/PrettyPrinterServiceProvider.test.ts +2 -6
- package/tests/service/printer/DefaultPrinterService.test.ts +57 -255
- package/tests/service/printer/PrinterServiceProvider.test.ts +2 -8
- package/tests/service/printer/command/DarkModeCommand.test.ts +4 -12
- package/tests/service/printer/command/LogLevelCommand.test.ts +4 -17
- package/tests/service/printer/command/NoColorCommand.test.ts +4 -12
- package/tests/service/printer/command/NoHyperlinksCommand.test.ts +7 -21
- package/tests/service/printer/terminal/Progress.test.ts +1 -3
- package/tests/service/printer/terminal/Spinner.test.ts +2 -8
- package/tests/service/prompter/DefaultPrompterService.test.ts +52 -69
- package/tests/service/prompter/PrompterServiceProvider.test.ts +2 -8
- package/tests/service/shutdown/ShutdownServiceProvider.test.ts +1 -3
- package/tests/service/syntaxHighlighter/DefaultSyntaxHighlighterService.test.ts +13 -99
- package/tests/service/syntaxHighlighter/SyntaxHighlighterServiceProvider.test.ts +2 -7
- package/tests/service/tableGenerator/DefaultTableGeneratorService.test.ts +12 -33
- package/tests/service/tableGenerator/TableGeneratorServiceProvider.test.ts +2 -2
- package/tests/service/treePrinter/DefaultTreePrinterService.test.ts +4 -6
- package/tests/service/treePrinter/TreePrinterServiceProvider.test.ts +4 -8
- package/tests/terminal/ImageRenderer.test.ts +2 -11
- package/tests/terminal/PngDecoder.test.ts +2 -6
- package/tests/util/configHelper.test.ts +55 -137
- package/tests/util/envVarHelper.test.ts +46 -110
|
@@ -46,14 +46,11 @@ describe("CompletionServiceProvider", () => {
|
|
|
46
46
|
await provider.getServiceInfo(getCLIConfig());
|
|
47
47
|
|
|
48
48
|
const context = new DefaultContext(getCLIConfig());
|
|
49
|
-
context.addServiceInstance(
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
promptAll: () => Promise.resolve([]),
|
|
55
|
-
},
|
|
56
|
-
);
|
|
49
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
50
|
+
promptEnabled: true,
|
|
51
|
+
prompt: () => Promise.resolve({ name: "", value: false }),
|
|
52
|
+
promptAll: () => Promise.resolve([]),
|
|
53
|
+
});
|
|
57
54
|
await expect(provider.initService(context)).resolves.toBeUndefined();
|
|
58
55
|
});
|
|
59
56
|
|
|
@@ -63,23 +60,17 @@ describe("CompletionServiceProvider", () => {
|
|
|
63
60
|
await provider.getServiceInfo(getCLIConfig());
|
|
64
61
|
|
|
65
62
|
const context = new DefaultContext(getCLIConfig());
|
|
66
|
-
context.addServiceInstance(
|
|
67
|
-
|
|
68
|
-
{
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
hasKey: (key: string) => Promise.resolve(key === "completion-status"),
|
|
78
|
-
getKey: () => Promise.resolve("installed"),
|
|
79
|
-
setKey: () => Promise.resolve(),
|
|
80
|
-
deleteKey: () => Promise.resolve(),
|
|
81
|
-
},
|
|
82
|
-
);
|
|
63
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
64
|
+
promptEnabled: true,
|
|
65
|
+
prompt: () => Promise.resolve({ name: "", value: false }),
|
|
66
|
+
promptAll: () => Promise.resolve([]),
|
|
67
|
+
});
|
|
68
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/key-value-service", {
|
|
69
|
+
hasKey: (key: string) => Promise.resolve(key === "completion-status"),
|
|
70
|
+
getKey: () => Promise.resolve("installed"),
|
|
71
|
+
setKey: () => Promise.resolve(),
|
|
72
|
+
deleteKey: () => Promise.resolve(),
|
|
73
|
+
});
|
|
83
74
|
await expect(provider.initService(context)).resolves.toBeUndefined();
|
|
84
75
|
});
|
|
85
76
|
|
|
@@ -89,23 +80,17 @@ describe("CompletionServiceProvider", () => {
|
|
|
89
80
|
await provider.getServiceInfo(getCLIConfig());
|
|
90
81
|
|
|
91
82
|
const context = new DefaultContext(getCLIConfig());
|
|
92
|
-
context.addServiceInstance(
|
|
93
|
-
|
|
94
|
-
{
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
hasKey: (key: string) => Promise.resolve(key === "completion-status"),
|
|
104
|
-
getKey: () => Promise.resolve("declined"),
|
|
105
|
-
setKey: () => Promise.resolve(),
|
|
106
|
-
deleteKey: () => Promise.resolve(),
|
|
107
|
-
},
|
|
108
|
-
);
|
|
83
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
84
|
+
promptEnabled: true,
|
|
85
|
+
prompt: () => Promise.resolve({ name: "", value: false }),
|
|
86
|
+
promptAll: () => Promise.resolve([]),
|
|
87
|
+
});
|
|
88
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/key-value-service", {
|
|
89
|
+
hasKey: (key: string) => Promise.resolve(key === "completion-status"),
|
|
90
|
+
getKey: () => Promise.resolve("declined"),
|
|
91
|
+
setKey: () => Promise.resolve(),
|
|
92
|
+
deleteKey: () => Promise.resolve(),
|
|
93
|
+
});
|
|
109
94
|
await expect(provider.initService(context)).resolves.toBeUndefined();
|
|
110
95
|
});
|
|
111
96
|
|
|
@@ -115,23 +100,17 @@ describe("CompletionServiceProvider", () => {
|
|
|
115
100
|
await provider.getServiceInfo(getCLIConfig());
|
|
116
101
|
|
|
117
102
|
const context = new DefaultContext(getCLIConfig());
|
|
118
|
-
context.addServiceInstance(
|
|
119
|
-
|
|
120
|
-
{
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
hasKey: () => Promise.resolve(false),
|
|
130
|
-
getKey: () => Promise.resolve(""),
|
|
131
|
-
setKey: () => Promise.resolve(),
|
|
132
|
-
deleteKey: () => Promise.resolve(),
|
|
133
|
-
},
|
|
134
|
-
);
|
|
103
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
104
|
+
promptEnabled: false,
|
|
105
|
+
prompt: () => Promise.resolve({ name: "", value: false }),
|
|
106
|
+
promptAll: () => Promise.resolve([]),
|
|
107
|
+
});
|
|
108
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/key-value-service", {
|
|
109
|
+
hasKey: () => Promise.resolve(false),
|
|
110
|
+
getKey: () => Promise.resolve(""),
|
|
111
|
+
setKey: () => Promise.resolve(),
|
|
112
|
+
deleteKey: () => Promise.resolve(),
|
|
113
|
+
});
|
|
135
114
|
await expect(provider.initService(context)).resolves.toBeUndefined();
|
|
136
115
|
});
|
|
137
116
|
|
|
@@ -144,26 +123,20 @@ describe("CompletionServiceProvider", () => {
|
|
|
144
123
|
const context = new DefaultContext(getCLIConfig());
|
|
145
124
|
|
|
146
125
|
let promptCalled = false;
|
|
147
|
-
context.addServiceInstance(
|
|
148
|
-
|
|
149
|
-
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
promptCalled = true;
|
|
153
|
-
return Promise.resolve({ name: "", value: false });
|
|
154
|
-
},
|
|
155
|
-
promptAll: () => Promise.resolve([]),
|
|
126
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
127
|
+
promptEnabled: true,
|
|
128
|
+
prompt: () => {
|
|
129
|
+
promptCalled = true;
|
|
130
|
+
return Promise.resolve({ name: "", value: false });
|
|
156
131
|
},
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
},
|
|
166
|
-
);
|
|
132
|
+
promptAll: () => Promise.resolve([]),
|
|
133
|
+
});
|
|
134
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/key-value-service", {
|
|
135
|
+
hasKey: () => Promise.resolve(false),
|
|
136
|
+
getKey: () => Promise.resolve(""),
|
|
137
|
+
setKey: () => Promise.resolve(),
|
|
138
|
+
deleteKey: () => Promise.resolve(),
|
|
139
|
+
});
|
|
167
140
|
|
|
168
141
|
await provider.initService(context);
|
|
169
142
|
expect(promptCalled).toBe(false);
|
|
@@ -179,28 +152,21 @@ describe("CompletionServiceProvider", () => {
|
|
|
179
152
|
|
|
180
153
|
let storedKey = "";
|
|
181
154
|
let storedValue = "";
|
|
182
|
-
context.addServiceInstance(
|
|
183
|
-
|
|
184
|
-
{
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
hasKey: () => Promise.resolve(false),
|
|
195
|
-
getKey: () => Promise.resolve(""),
|
|
196
|
-
setKey: (key: string, value: string) => {
|
|
197
|
-
storedKey = key;
|
|
198
|
-
storedValue = value;
|
|
199
|
-
return Promise.resolve();
|
|
200
|
-
},
|
|
201
|
-
deleteKey: () => Promise.resolve(),
|
|
155
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
156
|
+
promptEnabled: true,
|
|
157
|
+
prompt: () => Promise.resolve({ name: "enable-completion", value: false }),
|
|
158
|
+
promptAll: () => Promise.resolve([]),
|
|
159
|
+
});
|
|
160
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/key-value-service", {
|
|
161
|
+
hasKey: () => Promise.resolve(false),
|
|
162
|
+
getKey: () => Promise.resolve(""),
|
|
163
|
+
setKey: (key: string, value: string) => {
|
|
164
|
+
storedKey = key;
|
|
165
|
+
storedValue = value;
|
|
166
|
+
return Promise.resolve();
|
|
202
167
|
},
|
|
203
|
-
|
|
168
|
+
deleteKey: () => Promise.resolve(),
|
|
169
|
+
});
|
|
204
170
|
|
|
205
171
|
await provider.initService(context);
|
|
206
172
|
expect(storedKey).toEqual("completion-status");
|
|
@@ -209,8 +175,7 @@ describe("CompletionServiceProvider", () => {
|
|
|
209
175
|
|
|
210
176
|
test("initService skips shell prompt when only one shell detected", async () => {
|
|
211
177
|
const service = new DefaultCompletionService();
|
|
212
|
-
service.validateShellEnvironment = (shell) =>
|
|
213
|
-
Promise.resolve(shell === "bash");
|
|
178
|
+
service.validateShellEnvironment = (shell) => Promise.resolve(shell === "bash");
|
|
214
179
|
const provider = new CompletionServiceProvider(60, service);
|
|
215
180
|
await provider.getServiceInfo(getCLIConfig());
|
|
216
181
|
|
|
@@ -219,53 +184,42 @@ describe("CompletionServiceProvider", () => {
|
|
|
219
184
|
const storedEntries: Array<{ key: string; value: string }> = [];
|
|
220
185
|
const promptNames: string[] = [];
|
|
221
186
|
|
|
222
|
-
context.addServiceInstance(
|
|
223
|
-
|
|
224
|
-
{
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
value: true,
|
|
231
|
-
});
|
|
232
|
-
},
|
|
233
|
-
promptAll: () => Promise.resolve([]),
|
|
187
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
188
|
+
promptEnabled: true,
|
|
189
|
+
prompt: (promptDef: { name: string }) => {
|
|
190
|
+
promptNames.push(promptDef.name);
|
|
191
|
+
return Promise.resolve({
|
|
192
|
+
name: promptDef.name,
|
|
193
|
+
value: true,
|
|
194
|
+
});
|
|
234
195
|
},
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
return Promise.resolve();
|
|
244
|
-
},
|
|
245
|
-
deleteKey: () => Promise.resolve(),
|
|
196
|
+
promptAll: () => Promise.resolve([]),
|
|
197
|
+
});
|
|
198
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/key-value-service", {
|
|
199
|
+
hasKey: () => Promise.resolve(false),
|
|
200
|
+
getKey: () => Promise.resolve(""),
|
|
201
|
+
setKey: (key: string, value: string) => {
|
|
202
|
+
storedEntries.push({ key, value });
|
|
203
|
+
return Promise.resolve();
|
|
246
204
|
},
|
|
247
|
-
|
|
205
|
+
deleteKey: () => Promise.resolve(),
|
|
206
|
+
});
|
|
248
207
|
|
|
249
208
|
let infoMessage = "";
|
|
250
|
-
context.addServiceInstance(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
infoMessage = msg;
|
|
255
|
-
return Promise.resolve();
|
|
256
|
-
},
|
|
257
|
-
warn: () => Promise.resolve(),
|
|
258
|
-
error: () => Promise.resolve(),
|
|
259
|
-
print: () => Promise.resolve(),
|
|
209
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/printer-service", {
|
|
210
|
+
info: (msg: string) => {
|
|
211
|
+
infoMessage = msg;
|
|
212
|
+
return Promise.resolve();
|
|
260
213
|
},
|
|
261
|
-
|
|
214
|
+
warn: () => Promise.resolve(),
|
|
215
|
+
error: () => Promise.resolve(),
|
|
216
|
+
print: () => Promise.resolve(),
|
|
217
|
+
});
|
|
262
218
|
|
|
263
219
|
await provider.initService(context);
|
|
264
220
|
|
|
265
221
|
expect(promptNames).toEqual(["enable-completion"]);
|
|
266
|
-
const statusEntry = storedEntries.find(
|
|
267
|
-
(e) => e.key === "completion-status",
|
|
268
|
-
);
|
|
222
|
+
const statusEntry = storedEntries.find((e) => e.key === "completion-status");
|
|
269
223
|
expect(statusEntry).toBeDefined();
|
|
270
224
|
expect(statusEntry!.value).toEqual("installed");
|
|
271
225
|
expect(infoMessage).toContain("Shell completion installed for bash");
|
|
@@ -286,51 +240,39 @@ describe("CompletionServiceProvider", () => {
|
|
|
286
240
|
promptResponses.set("shell-type", "zsh");
|
|
287
241
|
|
|
288
242
|
let shellPromptDefault: unknown;
|
|
289
|
-
context.addServiceInstance(
|
|
290
|
-
|
|
291
|
-
{
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
return Promise.resolve({
|
|
301
|
-
name: promptDef.name,
|
|
302
|
-
value: promptResponses.get(promptDef.name),
|
|
303
|
-
});
|
|
304
|
-
},
|
|
305
|
-
promptAll: () => Promise.resolve([]),
|
|
243
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
244
|
+
promptEnabled: true,
|
|
245
|
+
prompt: (promptDef: { name: string; defaultOption?: { returnedValue: unknown } }) => {
|
|
246
|
+
if (promptDef.name === "shell-type") {
|
|
247
|
+
shellPromptDefault = promptDef.defaultOption;
|
|
248
|
+
}
|
|
249
|
+
return Promise.resolve({
|
|
250
|
+
name: promptDef.name,
|
|
251
|
+
value: promptResponses.get(promptDef.name),
|
|
252
|
+
});
|
|
306
253
|
},
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return Promise.resolve();
|
|
316
|
-
},
|
|
317
|
-
deleteKey: () => Promise.resolve(),
|
|
254
|
+
promptAll: () => Promise.resolve([]),
|
|
255
|
+
});
|
|
256
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/key-value-service", {
|
|
257
|
+
hasKey: () => Promise.resolve(false),
|
|
258
|
+
getKey: () => Promise.resolve(""),
|
|
259
|
+
setKey: (key: string, value: string) => {
|
|
260
|
+
storedEntries.push({ key, value });
|
|
261
|
+
return Promise.resolve();
|
|
318
262
|
},
|
|
319
|
-
|
|
263
|
+
deleteKey: () => Promise.resolve(),
|
|
264
|
+
});
|
|
320
265
|
|
|
321
266
|
let infoMessage = "";
|
|
322
|
-
context.addServiceInstance(
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
infoMessage = msg;
|
|
327
|
-
return Promise.resolve();
|
|
328
|
-
},
|
|
329
|
-
warn: () => Promise.resolve(),
|
|
330
|
-
error: () => Promise.resolve(),
|
|
331
|
-
print: () => Promise.resolve(),
|
|
267
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/printer-service", {
|
|
268
|
+
info: (msg: string) => {
|
|
269
|
+
infoMessage = msg;
|
|
270
|
+
return Promise.resolve();
|
|
332
271
|
},
|
|
333
|
-
|
|
272
|
+
warn: () => Promise.resolve(),
|
|
273
|
+
error: () => Promise.resolve(),
|
|
274
|
+
print: () => Promise.resolve(),
|
|
275
|
+
});
|
|
334
276
|
|
|
335
277
|
await provider.initService(context);
|
|
336
278
|
|
|
@@ -338,9 +280,7 @@ describe("CompletionServiceProvider", () => {
|
|
|
338
280
|
displayValue: "bash",
|
|
339
281
|
returnedValue: "bash",
|
|
340
282
|
});
|
|
341
|
-
const statusEntry = storedEntries.find(
|
|
342
|
-
(e) => e.key === "completion-status",
|
|
343
|
-
);
|
|
283
|
+
const statusEntry = storedEntries.find((e) => e.key === "completion-status");
|
|
344
284
|
expect(statusEntry).toBeDefined();
|
|
345
285
|
expect(statusEntry!.value).toEqual("installed");
|
|
346
286
|
expect(infoMessage).toContain("Shell completion installed for zsh");
|
|
@@ -359,41 +299,32 @@ describe("CompletionServiceProvider", () => {
|
|
|
359
299
|
|
|
360
300
|
const context = new DefaultContext(getCLIConfig());
|
|
361
301
|
|
|
362
|
-
context.addServiceInstance(
|
|
363
|
-
|
|
364
|
-
{
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
hasKey: () => Promise.resolve(false),
|
|
378
|
-
getKey: () => Promise.resolve(""),
|
|
379
|
-
setKey: () => Promise.resolve(),
|
|
380
|
-
deleteKey: () => Promise.resolve(),
|
|
381
|
-
},
|
|
382
|
-
);
|
|
302
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/prompter-service", {
|
|
303
|
+
promptEnabled: true,
|
|
304
|
+
prompt: (promptDef: { name: string }) =>
|
|
305
|
+
Promise.resolve({
|
|
306
|
+
name: promptDef.name,
|
|
307
|
+
value: promptDef.name === "enable-completion" ? true : "bash",
|
|
308
|
+
}),
|
|
309
|
+
promptAll: () => Promise.resolve([]),
|
|
310
|
+
});
|
|
311
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/key-value-service", {
|
|
312
|
+
hasKey: () => Promise.resolve(false),
|
|
313
|
+
getKey: () => Promise.resolve(""),
|
|
314
|
+
setKey: () => Promise.resolve(),
|
|
315
|
+
deleteKey: () => Promise.resolve(),
|
|
316
|
+
});
|
|
383
317
|
|
|
384
318
|
let errorMessage = "";
|
|
385
|
-
context.addServiceInstance(
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
errorMessage = msg;
|
|
392
|
-
return Promise.resolve();
|
|
393
|
-
},
|
|
394
|
-
print: () => Promise.resolve(),
|
|
319
|
+
context.addServiceInstance("@flowscripter/dynamic-cli-framework/printer-service", {
|
|
320
|
+
info: () => Promise.resolve(),
|
|
321
|
+
warn: () => Promise.resolve(),
|
|
322
|
+
error: (msg: string) => {
|
|
323
|
+
errorMessage = msg;
|
|
324
|
+
return Promise.resolve();
|
|
395
325
|
},
|
|
396
|
-
|
|
326
|
+
print: () => Promise.resolve(),
|
|
327
|
+
});
|
|
397
328
|
|
|
398
329
|
await provider.initService(context);
|
|
399
330
|
expect(errorMessage).toContain("Failed to install completion");
|
|
@@ -26,11 +26,7 @@ function makeSubCommand(
|
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function makeGroupCommand(
|
|
30
|
-
name: string,
|
|
31
|
-
description: string,
|
|
32
|
-
members: SubCommand[],
|
|
33
|
-
): GroupCommand {
|
|
29
|
+
function makeGroupCommand(name: string, description: string, members: SubCommand[]): GroupCommand {
|
|
34
30
|
return {
|
|
35
31
|
name,
|
|
36
32
|
description,
|
|
@@ -40,10 +36,7 @@ function makeGroupCommand(
|
|
|
40
36
|
};
|
|
41
37
|
}
|
|
42
38
|
|
|
43
|
-
function makeGlobalCommand(
|
|
44
|
-
name: string,
|
|
45
|
-
description: string,
|
|
46
|
-
): GlobalCommand {
|
|
39
|
+
function makeGlobalCommand(name: string, description: string): GlobalCommand {
|
|
47
40
|
return {
|
|
48
41
|
name,
|
|
49
42
|
description,
|
|
@@ -53,10 +46,7 @@ function makeGlobalCommand(
|
|
|
53
46
|
};
|
|
54
47
|
}
|
|
55
48
|
|
|
56
|
-
function makeGlobalModifierCommand(
|
|
57
|
-
name: string,
|
|
58
|
-
description: string,
|
|
59
|
-
): GlobalModifierCommand {
|
|
49
|
+
function makeGlobalModifierCommand(name: string, description: string): GlobalModifierCommand {
|
|
60
50
|
return {
|
|
61
51
|
name,
|
|
62
52
|
description,
|
|
@@ -69,9 +59,7 @@ function makeGlobalModifierCommand(
|
|
|
69
59
|
|
|
70
60
|
describe("DefaultCompletionService", () => {
|
|
71
61
|
function createService(
|
|
72
|
-
commands: Array<
|
|
73
|
-
SubCommand | GroupCommand | GlobalCommand | GlobalModifierCommand
|
|
74
|
-
>,
|
|
62
|
+
commands: Array<SubCommand | GroupCommand | GlobalCommand | GlobalModifierCommand>,
|
|
75
63
|
): DefaultCompletionService {
|
|
76
64
|
const service = new DefaultCompletionService();
|
|
77
65
|
const registry = new DefaultCommandRegistry(commands);
|
|
@@ -81,11 +69,7 @@ describe("DefaultCompletionService", () => {
|
|
|
81
69
|
|
|
82
70
|
test("returns empty completions if no registry set", async () => {
|
|
83
71
|
const service = new DefaultCompletionService();
|
|
84
|
-
const result = await service.generateCompletions(
|
|
85
|
-
ShellType.BASH,
|
|
86
|
-
"mycli ",
|
|
87
|
-
6,
|
|
88
|
-
);
|
|
72
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli ", 6);
|
|
89
73
|
expect(result).toEqual([]);
|
|
90
74
|
});
|
|
91
75
|
|
|
@@ -96,11 +80,7 @@ describe("DefaultCompletionService", () => {
|
|
|
96
80
|
makeSubCommand("run", "Run something"),
|
|
97
81
|
]);
|
|
98
82
|
|
|
99
|
-
const result = await service.generateCompletions(
|
|
100
|
-
ShellType.BASH,
|
|
101
|
-
"mycli h",
|
|
102
|
-
7,
|
|
103
|
-
);
|
|
83
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli h", 7);
|
|
104
84
|
expect(result.length).toEqual(2);
|
|
105
85
|
expect(result.map((r) => r.value)).toContain("help");
|
|
106
86
|
expect(result.map((r) => r.value)).toContain("history");
|
|
@@ -112,11 +92,7 @@ describe("DefaultCompletionService", () => {
|
|
|
112
92
|
makeSubCommand("run", "Run something"),
|
|
113
93
|
]);
|
|
114
94
|
|
|
115
|
-
const result = await service.generateCompletions(
|
|
116
|
-
ShellType.BASH,
|
|
117
|
-
"mycli ",
|
|
118
|
-
6,
|
|
119
|
-
);
|
|
95
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli ", 6);
|
|
120
96
|
expect(result.map((r) => r.value)).toContain("help");
|
|
121
97
|
expect(result.map((r) => r.value)).toContain("run");
|
|
122
98
|
});
|
|
@@ -126,18 +102,10 @@ describe("DefaultCompletionService", () => {
|
|
|
126
102
|
makeSubCommand("integration", "Install completion"),
|
|
127
103
|
makeSubCommand("complete", "Generate completions"),
|
|
128
104
|
];
|
|
129
|
-
const group = makeGroupCommand(
|
|
130
|
-
"completions",
|
|
131
|
-
"Completion management",
|
|
132
|
-
members,
|
|
133
|
-
);
|
|
105
|
+
const group = makeGroupCommand("completions", "Completion management", members);
|
|
134
106
|
const service = createService([group]);
|
|
135
107
|
|
|
136
|
-
const result = await service.generateCompletions(
|
|
137
|
-
ShellType.BASH,
|
|
138
|
-
"mycli comp",
|
|
139
|
-
10,
|
|
140
|
-
);
|
|
108
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli comp", 10);
|
|
141
109
|
const values = result.map((r) => r.value);
|
|
142
110
|
expect(values).toContain("completions");
|
|
143
111
|
expect(values).toContain("completions:integration");
|
|
@@ -149,18 +117,10 @@ describe("DefaultCompletionService", () => {
|
|
|
149
117
|
makeSubCommand("integration", "Install completion"),
|
|
150
118
|
makeSubCommand("complete", "Generate completions"),
|
|
151
119
|
];
|
|
152
|
-
const group = makeGroupCommand(
|
|
153
|
-
"completions",
|
|
154
|
-
"Completion management",
|
|
155
|
-
members,
|
|
156
|
-
);
|
|
120
|
+
const group = makeGroupCommand("completions", "Completion management", members);
|
|
157
121
|
const service = createService([group]);
|
|
158
122
|
|
|
159
|
-
const result = await service.generateCompletions(
|
|
160
|
-
ShellType.BASH,
|
|
161
|
-
"mycli completions:i",
|
|
162
|
-
19,
|
|
163
|
-
);
|
|
123
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli completions:i", 19);
|
|
164
124
|
const values = result.map((r) => r.value);
|
|
165
125
|
expect(values).toContain("completions:integration");
|
|
166
126
|
expect(values).not.toContain("completions:complete");
|
|
@@ -184,11 +144,7 @@ describe("DefaultCompletionService", () => {
|
|
|
184
144
|
]);
|
|
185
145
|
const service = createService([cmd]);
|
|
186
146
|
|
|
187
|
-
const result = await service.generateCompletions(
|
|
188
|
-
ShellType.BASH,
|
|
189
|
-
"mycli deploy --t",
|
|
190
|
-
16,
|
|
191
|
-
);
|
|
147
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli deploy --t", 16);
|
|
192
148
|
const values = result.map((r) => r.value);
|
|
193
149
|
expect(values).toContain("--target");
|
|
194
150
|
});
|
|
@@ -205,29 +161,18 @@ describe("DefaultCompletionService", () => {
|
|
|
205
161
|
]);
|
|
206
162
|
const service = createService([cmd]);
|
|
207
163
|
|
|
208
|
-
const result = await service.generateCompletions(
|
|
209
|
-
ShellType.BASH,
|
|
210
|
-
"mycli deploy --env st",
|
|
211
|
-
21,
|
|
212
|
-
);
|
|
164
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli deploy --env st", 21);
|
|
213
165
|
const values = result.map((r) => r.value);
|
|
214
166
|
expect(values).toContain("staging");
|
|
215
167
|
expect(values).not.toContain("production");
|
|
216
168
|
});
|
|
217
169
|
|
|
218
170
|
test("completes global modifier commands with -- prefix", async () => {
|
|
219
|
-
const modifier = makeGlobalModifierCommand(
|
|
220
|
-
"verbose",
|
|
221
|
-
"Enable verbose output",
|
|
222
|
-
);
|
|
171
|
+
const modifier = makeGlobalModifierCommand("verbose", "Enable verbose output");
|
|
223
172
|
const cmd = makeSubCommand("run", "Run something");
|
|
224
173
|
const service = createService([modifier, cmd]);
|
|
225
174
|
|
|
226
|
-
const result = await service.generateCompletions(
|
|
227
|
-
ShellType.BASH,
|
|
228
|
-
"mycli --v",
|
|
229
|
-
9,
|
|
230
|
-
);
|
|
175
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli --v", 9);
|
|
231
176
|
const values = result.map((r) => r.value);
|
|
232
177
|
expect(values).toContain("--verbose");
|
|
233
178
|
});
|
|
@@ -237,11 +182,7 @@ describe("DefaultCompletionService", () => {
|
|
|
237
182
|
const cmd = makeSubCommand("run", "Run something");
|
|
238
183
|
const service = createService([global, cmd]);
|
|
239
184
|
|
|
240
|
-
const result = await service.generateCompletions(
|
|
241
|
-
ShellType.BASH,
|
|
242
|
-
"mycli --ver",
|
|
243
|
-
11,
|
|
244
|
-
);
|
|
185
|
+
const result = await service.generateCompletions(ShellType.BASH, "mycli --ver", 11);
|
|
245
186
|
const values = result.map((r) => r.value);
|
|
246
187
|
expect(values).toContain("--version");
|
|
247
188
|
});
|
|
@@ -268,10 +209,7 @@ describe("DefaultCompletionService", () => {
|
|
|
268
209
|
|
|
269
210
|
test("parseCompletionContext delegates to shell handler", () => {
|
|
270
211
|
const service = new DefaultCompletionService();
|
|
271
|
-
const result = service.parseCompletionContext(ShellType.BASH, [
|
|
272
|
-
"mycli help",
|
|
273
|
-
"10",
|
|
274
|
-
]);
|
|
212
|
+
const result = service.parseCompletionContext(ShellType.BASH, ["mycli help", "10"]);
|
|
275
213
|
expect(result.line).toEqual("mycli help");
|
|
276
214
|
expect(result.cursorPosition).toEqual(10);
|
|
277
215
|
});
|
|
@@ -8,9 +8,7 @@ describe("FishShellHandler", () => {
|
|
|
8
8
|
|
|
9
9
|
test("getDefaultConfigPath returns fish config.fish", () => {
|
|
10
10
|
const configPath = handler.getDefaultConfigPath();
|
|
11
|
-
expect(configPath).toEndWith(
|
|
12
|
-
path.sep + path.join(".config", "fish", "config.fish"),
|
|
13
|
-
);
|
|
11
|
+
expect(configPath).toEndWith(path.sep + path.join(".config", "fish", "config.fish"));
|
|
14
12
|
});
|
|
15
13
|
|
|
16
14
|
test("getBootstrapScript generates correct complete command", () => {
|