@flowscripter/dynamic-cli-framework 7.1.0 → 7.1.1
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/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts.map +1 -1
- package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts.map +1 -1
- package/dist/src/service/prompter/DefaultPrompterService.d.ts +2 -1
- package/dist/src/service/prompter/DefaultPrompterService.d.ts.map +1 -1
- package/dist/src/service/prompter/DefaultPrompterService.js +3 -0
- package/dist/src/service/prompter/PrompterServiceProvider.d.ts +2 -3
- package/dist/src/service/prompter/PrompterServiceProvider.d.ts.map +1 -1
- package/dist/src/service/prompter/PrompterServiceProvider.js +5 -1
- package/dist/src/service/prompter/prompt/PromptContext.d.ts +4 -1
- package/dist/src/service/prompter/prompt/PromptContext.d.ts.map +1 -1
- package/dist/src/service/prompter/prompt/PromptContext.js +10 -0
- package/dist/src/service/prompter/prompt/promptMultiSelect.d.ts.map +1 -1
- package/dist/src/service/prompter/prompt/promptMultiSelect.js +2 -3
- package/dist/src/service/prompter/prompt/promptOpenUrl.d.ts +2 -1
- package/dist/src/service/prompter/prompt/promptOpenUrl.d.ts.map +1 -1
- package/dist/src/service/prompter/prompt/promptOpenUrl.js +14 -10
- package/dist/src/service/prompter/prompt/promptSingleSelect.d.ts.map +1 -1
- package/dist/src/service/prompter/prompt/promptSingleSelect.js +2 -3
- package/dist/src/service/prompter/prompt/promptText.d.ts.map +1 -1
- package/dist/src/service/prompter/prompt/promptText.js +2 -3
- package/dist/src/service/shutdown/DefaultShutdownService.d.ts +3 -0
- package/dist/src/service/shutdown/DefaultShutdownService.d.ts.map +1 -1
- package/dist/src/service/shutdown/DefaultShutdownService.js +7 -0
- package/dist/src/service/shutdown/ShutdownServiceProvider.js +1 -1
- package/package.json +2 -2
- package/src/service/completion/command/CompletionCompleteSubCommand.ts +2 -4
- package/src/service/completion/command/CompletionIntegrationSubCommand.ts +2 -4
- package/src/service/prompter/DefaultPrompterService.ts +6 -2
- package/src/service/prompter/PrompterServiceProvider.ts +6 -3
- package/src/service/prompter/prompt/PromptContext.ts +19 -1
- package/src/service/prompter/prompt/promptMultiSelect.ts +2 -3
- package/src/service/prompter/prompt/promptOpenUrl.ts +18 -11
- package/src/service/prompter/prompt/promptSingleSelect.ts +2 -3
- package/src/service/prompter/prompt/promptText.ts +2 -3
- package/src/service/shutdown/DefaultShutdownService.ts +10 -0
- package/src/service/shutdown/ShutdownServiceProvider.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompletionCompleteSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/completion/command/CompletionCompleteSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,yCAAyC,CAAC;AAMrF,qBAAa,4BAA6B,YAAW,UAAU;IAC7D,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,WAAW,gDAAgD;IACpE,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,yBAAyB,QAAQ;IAE1C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAM;IAE7C,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAc7C;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"CompletionCompleteSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/completion/command/CompletionCompleteSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,yCAAyC,CAAC;AAMrF,qBAAa,4BAA6B,YAAW,UAAU;IAC7D,QAAQ,CAAC,IAAI,cAAc;IAC3B,QAAQ,CAAC,WAAW,gDAAgD;IACpE,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,yBAAyB,QAAQ;IAE1C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAM;IAE7C,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAc7C;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBrE;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompletionIntegrationSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/completion/command/CompletionIntegrationSubCommand.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,yCAAyC,CAAC;AAMrF,qBAAa,+BAAgC,YAAW,UAAU;IAChE,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,WAAW,0CAA0C;IAC9D,QAAQ,CAAC,mBAAmB,SAAS;IAErC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAOrC;IAEF,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAO7C;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"CompletionIntegrationSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/completion/command/CompletionIntegrationSubCommand.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,EAAE,KAAK,MAAM,EAAiB,MAAM,yCAAyC,CAAC;AAMrF,qBAAa,+BAAgC,YAAW,UAAU;IAChE,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,QAAQ,CAAC,WAAW,0CAA0C;IAC9D,QAAQ,CAAC,mBAAmB,SAAS;IAErC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAOrC;IAEF,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAO7C;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDrE;CACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PrompterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
1
|
+
import type { Context, PrompterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import { type Prompt, type PromptResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
3
|
import type Terminal from "../../terminal/Terminal.ts";
|
|
4
4
|
import type KeyReader from "../../terminal/KeyReader.ts";
|
|
@@ -15,6 +15,7 @@ export default class DefaultPrompterService implements PrompterService {
|
|
|
15
15
|
#private;
|
|
16
16
|
promptEnabled: boolean;
|
|
17
17
|
constructor(config: PrompterServiceConfig, terminal: Terminal, keyReader: KeyReader, printerService: PrinterService);
|
|
18
|
+
setContext(context: Context): void;
|
|
18
19
|
prompt(promptDef: Prompt): Promise<PromptResult>;
|
|
19
20
|
promptAll(prompts: ReadonlyArray<Prompt>): Promise<ReadonlyArray<PromptResult>>;
|
|
20
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultPrompterService.d.ts","sourceRoot":"","sources":["../../../../src/service/prompter/DefaultPrompterService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"DefaultPrompterService.d.ts","sourceRoot":"","sources":["../../../../src/service/prompter/DefaultPrompterService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AACxF,OAAO,EACL,KAAK,MAAM,EACX,KAAK,YAAY,EAElB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,4BAA4B,CAAC;AACvD,OAAO,KAAK,SAAS,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAS9E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAKrC,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,sBAAuB,YAAW,eAAe;;IACpE,aAAa,UAAQ;IAIrB,YACE,MAAM,EAAE,qBAAqB,EAC7B,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,cAAc,EAG/B;IAED,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEjC;IAED,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA2B/C;IAEK,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAMpF;CACF"}
|
|
@@ -17,6 +17,9 @@ export default class DefaultPrompterService {
|
|
|
17
17
|
constructor(config, terminal, keyReader, printerService) {
|
|
18
18
|
this.#ctx = { config, terminal, keyReader, printerService };
|
|
19
19
|
}
|
|
20
|
+
setContext(context) {
|
|
21
|
+
this.#ctx = { ...this.#ctx, context };
|
|
22
|
+
}
|
|
20
23
|
prompt(promptDef) {
|
|
21
24
|
if (!this.promptEnabled) {
|
|
22
25
|
if (promptDef.defaultOption) {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { Context } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type { ServiceInfo, ServiceProvider } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
|
-
import type { PrompterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
|
-
import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
|
+
import type { CLIConfig, PrompterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
4
|
export default class PrompterServiceProvider implements ServiceProvider {
|
|
6
5
|
readonly serviceId: string;
|
|
7
6
|
readonly servicePriority: number;
|
|
8
7
|
readonly prompterService: PrompterService;
|
|
9
8
|
constructor(servicePriority: number, prompterService: PrompterService);
|
|
10
9
|
getServiceInfo(_cliConfig: CLIConfig): Promise<ServiceInfo>;
|
|
11
|
-
initService(
|
|
10
|
+
initService(context: Context): Promise<void>;
|
|
12
11
|
}
|
|
13
12
|
//# sourceMappingURL=PrompterServiceProvider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrompterServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/prompter/PrompterServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"PrompterServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/prompter/PrompterServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAG5F,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAG1F,MAAM,CAAC,OAAO,OAAO,uBAAwB,YAAW,eAAe;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAuB;IACjD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAE1C,YAAmB,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,EAG3E;IAEM,cAAc,CAAC,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAKjE;IAED,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3C;CACF"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PROMPTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import NoPromptCommand from "./command/NoPromptCommand.js";
|
|
3
|
+
import DefaultPrompterService from "./DefaultPrompterService.js";
|
|
3
4
|
export default class PrompterServiceProvider {
|
|
4
5
|
serviceId = PROMPTER_SERVICE_ID;
|
|
5
6
|
servicePriority;
|
|
@@ -14,7 +15,10 @@ export default class PrompterServiceProvider {
|
|
|
14
15
|
commands: [new NoPromptCommand(this.servicePriority)],
|
|
15
16
|
});
|
|
16
17
|
}
|
|
17
|
-
initService(
|
|
18
|
+
initService(context) {
|
|
19
|
+
if (this.prompterService instanceof DefaultPrompterService) {
|
|
20
|
+
this.prompterService.setContext(context);
|
|
21
|
+
}
|
|
18
22
|
return Promise.resolve();
|
|
19
23
|
}
|
|
20
24
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Prompt } from "@flowscripter/dynamic-cli-framework-api";
|
|
1
|
+
import type { Context, Prompt, SpawnService } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type Terminal from "../../../terminal/Terminal.ts";
|
|
3
3
|
import type KeyReader from "../../../terminal/KeyReader.ts";
|
|
4
4
|
import type { PrinterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
@@ -8,7 +8,10 @@ export interface PromptContext {
|
|
|
8
8
|
readonly terminal: Terminal;
|
|
9
9
|
readonly keyReader: KeyReader;
|
|
10
10
|
readonly printerService: PrinterService;
|
|
11
|
+
readonly context?: Context;
|
|
11
12
|
}
|
|
13
|
+
export declare function interrupt(ctx: PromptContext): void;
|
|
14
|
+
export declare function getSpawnService(ctx: PromptContext): SpawnService | undefined;
|
|
12
15
|
export declare function physicalLineCount(terminal: Terminal, text: string): number;
|
|
13
16
|
export declare function headerLineCount(terminal: Terminal, promptDef: Prompt): number;
|
|
14
17
|
export declare function renderPromptHeader(ctx: PromptContext, promptDef: Prompt): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PromptContext.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/PromptContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"PromptContext.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/PromptContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,MAAM,EAEN,YAAY,EACb,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,QAAQ,MAAM,+BAA+B,CAAC;AAC1D,OAAO,KAAK,SAAS,MAAM,gCAAgC,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAE1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAElD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,YAAY,GAAG,SAAS,CAK5E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAO1E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAM7E;AAED,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7F"}
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
import { SHUTDOWN_SERVICE_ID, SPAWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
|
+
export function interrupt(ctx) {
|
|
3
|
+
ctx.context?.getServiceById(SHUTDOWN_SERVICE_ID)?.interrupt();
|
|
4
|
+
}
|
|
5
|
+
export function getSpawnService(ctx) {
|
|
6
|
+
if (!ctx.context?.doesServiceExist(SPAWN_SERVICE_ID)) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
return ctx.context.getServiceById(SPAWN_SERVICE_ID);
|
|
10
|
+
}
|
|
1
11
|
export function physicalLineCount(terminal, text) {
|
|
2
12
|
const cols = terminal.columns();
|
|
3
13
|
if (cols <= 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promptMultiSelect.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/promptMultiSelect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"promptMultiSelect.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/promptMultiSelect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAGpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,wBAA8B,iBAAiB,CAC7C,GAAG,EAAE,aAAa,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CA0EvB"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SpecialKey } from "../../../terminal/KeyReader.js";
|
|
2
|
-
import
|
|
3
|
-
import { headerLineCount, renderPromptHeader } from "./PromptContext.js";
|
|
2
|
+
import { headerLineCount, renderPromptHeader, interrupt } from "./PromptContext.js";
|
|
4
3
|
export default async function promptMultiSelect(ctx, promptDef) {
|
|
5
4
|
const options = promptDef.options;
|
|
6
5
|
if (options.length === 0) {
|
|
@@ -63,7 +62,7 @@ export default async function promptMultiSelect(ctx, promptDef) {
|
|
|
63
62
|
}
|
|
64
63
|
else if (keyEvent.specialKey === SpecialKey.INTERRUPT) {
|
|
65
64
|
await ctx.terminal.showCursor();
|
|
66
|
-
|
|
65
|
+
interrupt(ctx);
|
|
67
66
|
throw new Error("Interrupted");
|
|
68
67
|
}
|
|
69
68
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { Prompt, PromptResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
1
|
+
import type { Prompt, PromptResult, SpawnService } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type { PromptContext } from "./PromptContext.ts";
|
|
3
|
+
export declare function defaultOpenUrl(spawnService: SpawnService, url: string): Promise<void>;
|
|
3
4
|
export default function promptOpenUrl(ctx: PromptContext, promptDef: Prompt): Promise<PromptResult>;
|
|
4
5
|
//# sourceMappingURL=promptOpenUrl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promptOpenUrl.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/promptOpenUrl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"promptOpenUrl.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/promptOpenUrl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAGlG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,wBAAsB,cAAc,CAAC,YAAY,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB3F;AAED,wBAA8B,aAAa,CACzC,GAAG,EAAE,aAAa,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CAkDvB"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { SpecialKey } from "../../../terminal/KeyReader.js";
|
|
2
|
-
import
|
|
3
|
-
import { renderPromptHeader } from "./PromptContext.js";
|
|
2
|
+
import { getSpawnService, interrupt, renderPromptHeader } from "./PromptContext.js";
|
|
4
3
|
function isRemoteSession() {
|
|
5
4
|
return !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY);
|
|
6
5
|
}
|
|
7
|
-
async function defaultOpenUrl(url) {
|
|
6
|
+
export async function defaultOpenUrl(spawnService, url) {
|
|
8
7
|
const parsed = new URL(url);
|
|
9
8
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
10
9
|
throw new Error(`Unsupported URL protocol: ${parsed.protocol}`);
|
|
@@ -20,11 +19,14 @@ async function defaultOpenUrl(url) {
|
|
|
20
19
|
else {
|
|
21
20
|
cmd = ["xdg-open", url];
|
|
22
21
|
}
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
throw new Error(`Failed to open URL (exit code ${exitCode})`);
|
|
22
|
+
const result = await spawnService.spawn(cmd, { mode: "ignore", longRunning: false });
|
|
23
|
+
if (result.ok) {
|
|
24
|
+
return;
|
|
27
25
|
}
|
|
26
|
+
if ("error" in result && result.error) {
|
|
27
|
+
throw result.error;
|
|
28
|
+
}
|
|
29
|
+
throw new Error(`Failed to open URL (exit code ${"exitCode" in result ? result.exitCode : "unknown"})`);
|
|
28
30
|
}
|
|
29
31
|
export default async function promptOpenUrl(ctx, promptDef) {
|
|
30
32
|
if (promptDef.options.length === 0) {
|
|
@@ -32,8 +34,10 @@ export default async function promptOpenUrl(ctx, promptDef) {
|
|
|
32
34
|
}
|
|
33
35
|
const url = String(promptDef.options[0].returnedValue);
|
|
34
36
|
const displayLabel = promptDef.options[0].displayValue;
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
+
const spawnService = getSpawnService(ctx);
|
|
38
|
+
const openUrlFn = ctx.config.openUrl ??
|
|
39
|
+
(spawnService ? (target) => defaultOpenUrl(spawnService, target) : undefined);
|
|
40
|
+
const canOpenBrowser = openUrlFn !== undefined && !isRemoteSession();
|
|
37
41
|
ctx.keyReader.enableRawMode();
|
|
38
42
|
try {
|
|
39
43
|
await renderPromptHeader(ctx, promptDef);
|
|
@@ -59,7 +63,7 @@ export default async function promptOpenUrl(ctx, promptDef) {
|
|
|
59
63
|
throw new Error("Prompt cancelled");
|
|
60
64
|
}
|
|
61
65
|
else if (keyEvent.specialKey === SpecialKey.INTERRUPT) {
|
|
62
|
-
|
|
66
|
+
interrupt(ctx);
|
|
63
67
|
throw new Error("Interrupted");
|
|
64
68
|
}
|
|
65
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promptSingleSelect.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/promptSingleSelect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"promptSingleSelect.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/promptSingleSelect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAGpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,wBAA8B,kBAAkB,CAC9C,GAAG,EAAE,aAAa,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CA2EvB"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SpecialKey } from "../../../terminal/KeyReader.js";
|
|
2
|
-
import
|
|
3
|
-
import { headerLineCount, renderPromptHeader } from "./PromptContext.js";
|
|
2
|
+
import { headerLineCount, renderPromptHeader, interrupt } from "./PromptContext.js";
|
|
4
3
|
export default async function promptSingleSelect(ctx, promptDef) {
|
|
5
4
|
const options = promptDef.options;
|
|
6
5
|
if (options.length === 0) {
|
|
@@ -62,7 +61,7 @@ export default async function promptSingleSelect(ctx, promptDef) {
|
|
|
62
61
|
}
|
|
63
62
|
else if (keyEvent.specialKey === SpecialKey.INTERRUPT) {
|
|
64
63
|
await ctx.terminal.showCursor();
|
|
65
|
-
|
|
64
|
+
interrupt(ctx);
|
|
66
65
|
throw new Error("Interrupted");
|
|
67
66
|
}
|
|
68
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promptText.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/promptText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"promptText.d.ts","sourceRoot":"","sources":["../../../../../src/service/prompter/prompt/promptText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAIpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,wBAA8B,UAAU,CACtC,GAAG,EAAE,aAAa,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CA+EvB"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SpecialKey } from "../../../terminal/KeyReader.js";
|
|
2
|
-
import
|
|
3
|
-
import { renderPromptHeader } from "./PromptContext.js";
|
|
2
|
+
import { renderPromptHeader, interrupt } from "./PromptContext.js";
|
|
4
3
|
export default async function promptText(ctx, promptDef) {
|
|
5
4
|
ctx.keyReader.enableRawMode();
|
|
6
5
|
try {
|
|
@@ -24,7 +23,7 @@ export default async function promptText(ctx, promptDef) {
|
|
|
24
23
|
}
|
|
25
24
|
else if (keyEvent.specialKey === SpecialKey.INTERRUPT) {
|
|
26
25
|
await ctx.terminal.write("\n");
|
|
27
|
-
|
|
26
|
+
interrupt(ctx);
|
|
28
27
|
throw new Error("Interrupted");
|
|
29
28
|
}
|
|
30
29
|
else if (keyEvent.specialKey === SpecialKey.BACKSPACE) {
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { ShutdownService, ShutdownTask } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import PriorityTaskList from "../../runtime/lifecycle/PriorityTaskList.ts";
|
|
3
3
|
export default class DefaultShutdownService implements ShutdownService {
|
|
4
|
+
#private;
|
|
4
5
|
static readonly taskList: PriorityTaskList<ShutdownTask>;
|
|
6
|
+
constructor(onInterrupt?: () => void);
|
|
5
7
|
registerTask(task: ShutdownTask): void;
|
|
6
8
|
enterLongRunningMode(): void;
|
|
7
9
|
leaveLongRunningMode(): void;
|
|
10
|
+
interrupt(): void;
|
|
8
11
|
get isShutdownRequested(): boolean;
|
|
9
12
|
}
|
|
10
13
|
//# sourceMappingURL=DefaultShutdownService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultShutdownService.d.ts","sourceRoot":"","sources":["../../../../src/service/shutdown/DefaultShutdownService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,gBAAgB,MAAM,6CAA6C,CAAC;AAG3E,MAAM,CAAC,OAAO,OAAO,sBAAuB,YAAW,eAAe
|
|
1
|
+
{"version":3,"file":"DefaultShutdownService.d.ts","sourceRoot":"","sources":["../../../../src/service/shutdown/DefaultShutdownService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC7F,OAAO,gBAAgB,MAAM,6CAA6C,CAAC;AAG3E,MAAM,CAAC,OAAO,OAAO,sBAAuB,YAAW,eAAe;;IACpE,MAAM,CAAC,QAAQ,CAAC,QAAQ,iCAAwC;IAIhE,YAAmB,WAAW,GAAE,MAAM,IAAe,EAEpD;IAED,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAErC;IAED,oBAAoB,IAAI,IAAI,CAE3B;IAED,oBAAoB,IAAI,IAAI,CAE3B;IAED,SAAS,IAAI,IAAI,CAEhB;IAED,IAAI,mBAAmB,IAAI,OAAO,CAEjC;CACF"}
|
|
@@ -2,6 +2,10 @@ import PriorityTaskList from "../../runtime/lifecycle/PriorityTaskList.js";
|
|
|
2
2
|
import { shutdownState } from "./ShutdownState.js";
|
|
3
3
|
export default class DefaultShutdownService {
|
|
4
4
|
static taskList = new PriorityTaskList();
|
|
5
|
+
#onInterrupt;
|
|
6
|
+
constructor(onInterrupt = () => { }) {
|
|
7
|
+
this.#onInterrupt = onInterrupt;
|
|
8
|
+
}
|
|
5
9
|
registerTask(task) {
|
|
6
10
|
DefaultShutdownService.taskList.add(task);
|
|
7
11
|
}
|
|
@@ -11,6 +15,9 @@ export default class DefaultShutdownService {
|
|
|
11
15
|
leaveLongRunningMode() {
|
|
12
16
|
shutdownState.longRunningMode = false;
|
|
13
17
|
}
|
|
18
|
+
interrupt() {
|
|
19
|
+
this.#onInterrupt();
|
|
20
|
+
}
|
|
14
21
|
get isShutdownRequested() {
|
|
15
22
|
return shutdownState.shutdownRequested;
|
|
16
23
|
}
|
|
@@ -11,7 +11,7 @@ export default class ShutdownServiceProvider {
|
|
|
11
11
|
static #shutdownInProgress = false;
|
|
12
12
|
constructor(servicePriority) {
|
|
13
13
|
this.servicePriority = servicePriority;
|
|
14
|
-
this.#shutdownService = new DefaultShutdownService();
|
|
14
|
+
this.#shutdownService = new DefaultShutdownService(ShutdownServiceProvider.onInterrupt);
|
|
15
15
|
process.on("beforeExit", ShutdownServiceProvider.shutdown);
|
|
16
16
|
process.on("SIGINT", ShutdownServiceProvider.onInterrupt);
|
|
17
17
|
process.on("SIGTERM", ShutdownServiceProvider.onTerminate);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowscripter/dynamic-cli-framework",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.1",
|
|
4
4
|
"description": "A framework for developing CLI applications which supports dynamic discovery and installation of new commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bun",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"build": "tsc -p tsconfig.build.json"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@flowscripter/dynamic-cli-framework-api": "^4.
|
|
51
|
+
"@flowscripter/dynamic-cli-framework-api": "^4.2.0",
|
|
52
52
|
"@flowscripter/dynamic-plugin-framework": "^2.2.14",
|
|
53
53
|
"emphasize": "^7.0.0",
|
|
54
54
|
"fastest-levenshtein": "^1.0.16",
|
|
@@ -4,7 +4,7 @@ import type { Positional } from "@flowscripter/dynamic-cli-framework-api";
|
|
|
4
4
|
import type { Context } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
5
|
import { type Values, ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
|
|
6
6
|
import { COMPLETION_SERVICE_ID, ShellType } from "@flowscripter/dynamic-cli-framework-api";
|
|
7
|
-
import type
|
|
7
|
+
import type { CompletionService } from "@flowscripter/dynamic-cli-framework-api";
|
|
8
8
|
import { PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
9
9
|
import type { PrinterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
10
10
|
|
|
@@ -33,9 +33,7 @@ export class CompletionCompleteSubCommand implements SubCommand {
|
|
|
33
33
|
];
|
|
34
34
|
|
|
35
35
|
async execute(context: Context, argumentValues: Values): Promise<void> {
|
|
36
|
-
const completionService = context.getServiceById(
|
|
37
|
-
COMPLETION_SERVICE_ID,
|
|
38
|
-
) as DefaultCompletionService;
|
|
36
|
+
const completionService = context.getServiceById(COMPLETION_SERVICE_ID) as CompletionService;
|
|
39
37
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
40
38
|
|
|
41
39
|
const shellType = argumentValues.shell as ShellType;
|
|
@@ -5,7 +5,7 @@ import type { Positional } from "@flowscripter/dynamic-cli-framework-api";
|
|
|
5
5
|
import type { Context } from "@flowscripter/dynamic-cli-framework-api";
|
|
6
6
|
import { type Values, ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
|
|
7
7
|
import { COMPLETION_SERVICE_ID, ShellType } from "@flowscripter/dynamic-cli-framework-api";
|
|
8
|
-
import type
|
|
8
|
+
import type { CompletionService } from "@flowscripter/dynamic-cli-framework-api";
|
|
9
9
|
import { Icon, PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
10
10
|
import type { PrinterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
11
11
|
|
|
@@ -33,9 +33,7 @@ export class CompletionIntegrationSubCommand implements SubCommand {
|
|
|
33
33
|
];
|
|
34
34
|
|
|
35
35
|
async execute(context: Context, argumentValues: Values): Promise<void> {
|
|
36
|
-
const completionService = context.getServiceById(
|
|
37
|
-
COMPLETION_SERVICE_ID,
|
|
38
|
-
) as DefaultCompletionService;
|
|
36
|
+
const completionService = context.getServiceById(COMPLETION_SERVICE_ID) as CompletionService;
|
|
39
37
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
40
38
|
|
|
41
39
|
const shellType = argumentValues.shell as ShellType;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PrompterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
1
|
+
import type { Context, PrompterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import {
|
|
3
3
|
type Prompt,
|
|
4
4
|
type PromptResult,
|
|
@@ -33,7 +33,7 @@ export const DEFAULT_PROMPTER_CONFIG: PrompterServiceConfig = {
|
|
|
33
33
|
export default class DefaultPrompterService implements PrompterService {
|
|
34
34
|
promptEnabled = true;
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
#ctx: PromptContext;
|
|
37
37
|
|
|
38
38
|
public constructor(
|
|
39
39
|
config: PrompterServiceConfig,
|
|
@@ -44,6 +44,10 @@ export default class DefaultPrompterService implements PrompterService {
|
|
|
44
44
|
this.#ctx = { config, terminal, keyReader, printerService };
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
setContext(context: Context): void {
|
|
48
|
+
this.#ctx = { ...this.#ctx, context };
|
|
49
|
+
}
|
|
50
|
+
|
|
47
51
|
prompt(promptDef: Prompt): Promise<PromptResult> {
|
|
48
52
|
if (!this.promptEnabled) {
|
|
49
53
|
if (promptDef.defaultOption) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Context } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type { ServiceInfo, ServiceProvider } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
|
-
import type { PrompterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
3
|
import { PROMPTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
4
|
import NoPromptCommand from "./command/NoPromptCommand.ts";
|
|
6
|
-
import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
|
|
5
|
+
import type { CLIConfig, PrompterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
6
|
+
import DefaultPrompterService from "./DefaultPrompterService.ts";
|
|
7
7
|
|
|
8
8
|
export default class PrompterServiceProvider implements ServiceProvider {
|
|
9
9
|
readonly serviceId: string = PROMPTER_SERVICE_ID;
|
|
@@ -22,7 +22,10 @@ export default class PrompterServiceProvider implements ServiceProvider {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
initService(
|
|
25
|
+
initService(context: Context): Promise<void> {
|
|
26
|
+
if (this.prompterService instanceof DefaultPrompterService) {
|
|
27
|
+
this.prompterService.setContext(context);
|
|
28
|
+
}
|
|
26
29
|
return Promise.resolve();
|
|
27
30
|
}
|
|
28
31
|
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Context,
|
|
3
|
+
Prompt,
|
|
4
|
+
ShutdownService,
|
|
5
|
+
SpawnService,
|
|
6
|
+
} from "@flowscripter/dynamic-cli-framework-api";
|
|
7
|
+
import { SHUTDOWN_SERVICE_ID, SPAWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
8
|
import type Terminal from "../../../terminal/Terminal.ts";
|
|
3
9
|
import type KeyReader from "../../../terminal/KeyReader.ts";
|
|
4
10
|
import type { PrinterService } from "@flowscripter/dynamic-cli-framework-api";
|
|
@@ -9,6 +15,18 @@ export interface PromptContext {
|
|
|
9
15
|
readonly terminal: Terminal;
|
|
10
16
|
readonly keyReader: KeyReader;
|
|
11
17
|
readonly printerService: PrinterService;
|
|
18
|
+
readonly context?: Context;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function interrupt(ctx: PromptContext): void {
|
|
22
|
+
(ctx.context?.getServiceById(SHUTDOWN_SERVICE_ID) as ShutdownService | undefined)?.interrupt();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getSpawnService(ctx: PromptContext): SpawnService | undefined {
|
|
26
|
+
if (!ctx.context?.doesServiceExist(SPAWN_SERVICE_ID)) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
return ctx.context.getServiceById(SPAWN_SERVICE_ID) as SpawnService;
|
|
12
30
|
}
|
|
13
31
|
|
|
14
32
|
export function physicalLineCount(terminal: Terminal, text: string): number {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Prompt, PromptResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import { SpecialKey } from "../../../terminal/KeyReader.ts";
|
|
3
|
-
import
|
|
4
|
-
import { headerLineCount, renderPromptHeader } from "./PromptContext.ts";
|
|
3
|
+
import { headerLineCount, renderPromptHeader, interrupt } from "./PromptContext.ts";
|
|
5
4
|
import type { PromptContext } from "./PromptContext.ts";
|
|
6
5
|
|
|
7
6
|
export default async function promptMultiSelect(
|
|
@@ -74,7 +73,7 @@ export default async function promptMultiSelect(
|
|
|
74
73
|
throw new Error("Prompt cancelled");
|
|
75
74
|
} else if (keyEvent.specialKey === SpecialKey.INTERRUPT) {
|
|
76
75
|
await ctx.terminal.showCursor();
|
|
77
|
-
|
|
76
|
+
interrupt(ctx);
|
|
78
77
|
throw new Error("Interrupted");
|
|
79
78
|
}
|
|
80
79
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import type { Prompt, PromptResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
1
|
+
import type { Prompt, PromptResult, SpawnService } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import { SpecialKey } from "../../../terminal/KeyReader.ts";
|
|
3
|
-
import
|
|
4
|
-
import { renderPromptHeader } from "./PromptContext.ts";
|
|
3
|
+
import { getSpawnService, interrupt, renderPromptHeader } from "./PromptContext.ts";
|
|
5
4
|
import type { PromptContext } from "./PromptContext.ts";
|
|
6
5
|
|
|
7
6
|
function isRemoteSession(): boolean {
|
|
8
7
|
return !!(process.env.SSH_CONNECTION || process.env.SSH_CLIENT || process.env.SSH_TTY);
|
|
9
8
|
}
|
|
10
9
|
|
|
11
|
-
async function defaultOpenUrl(url: string): Promise<void> {
|
|
10
|
+
export async function defaultOpenUrl(spawnService: SpawnService, url: string): Promise<void> {
|
|
12
11
|
const parsed = new URL(url);
|
|
13
12
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
14
13
|
throw new Error(`Unsupported URL protocol: ${parsed.protocol}`);
|
|
@@ -22,11 +21,16 @@ async function defaultOpenUrl(url: string): Promise<void> {
|
|
|
22
21
|
} else {
|
|
23
22
|
cmd = ["xdg-open", url];
|
|
24
23
|
}
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
throw new Error(`Failed to open URL (exit code ${exitCode})`);
|
|
24
|
+
const result = await spawnService.spawn(cmd, { mode: "ignore", longRunning: false });
|
|
25
|
+
if (result.ok) {
|
|
26
|
+
return;
|
|
29
27
|
}
|
|
28
|
+
if ("error" in result && result.error) {
|
|
29
|
+
throw result.error;
|
|
30
|
+
}
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Failed to open URL (exit code ${"exitCode" in result ? result.exitCode : "unknown"})`,
|
|
33
|
+
);
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
export default async function promptOpenUrl(
|
|
@@ -39,8 +43,11 @@ export default async function promptOpenUrl(
|
|
|
39
43
|
|
|
40
44
|
const url = String(promptDef.options[0]!.returnedValue);
|
|
41
45
|
const displayLabel = promptDef.options[0]!.displayValue;
|
|
42
|
-
const
|
|
43
|
-
const
|
|
46
|
+
const spawnService = getSpawnService(ctx);
|
|
47
|
+
const openUrlFn =
|
|
48
|
+
ctx.config.openUrl ??
|
|
49
|
+
(spawnService ? (target: string) => defaultOpenUrl(spawnService, target) : undefined);
|
|
50
|
+
const canOpenBrowser = openUrlFn !== undefined && !isRemoteSession();
|
|
44
51
|
|
|
45
52
|
ctx.keyReader.enableRawMode();
|
|
46
53
|
try {
|
|
@@ -72,7 +79,7 @@ export default async function promptOpenUrl(
|
|
|
72
79
|
} else if (keyEvent.specialKey === SpecialKey.ESCAPE) {
|
|
73
80
|
throw new Error("Prompt cancelled");
|
|
74
81
|
} else if (keyEvent.specialKey === SpecialKey.INTERRUPT) {
|
|
75
|
-
|
|
82
|
+
interrupt(ctx);
|
|
76
83
|
throw new Error("Interrupted");
|
|
77
84
|
}
|
|
78
85
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Prompt, PromptResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import { SpecialKey } from "../../../terminal/KeyReader.ts";
|
|
3
|
-
import
|
|
4
|
-
import { headerLineCount, renderPromptHeader } from "./PromptContext.ts";
|
|
3
|
+
import { headerLineCount, renderPromptHeader, interrupt } from "./PromptContext.ts";
|
|
5
4
|
import type { PromptContext } from "./PromptContext.ts";
|
|
6
5
|
|
|
7
6
|
export default async function promptSingleSelect(
|
|
@@ -75,7 +74,7 @@ export default async function promptSingleSelect(
|
|
|
75
74
|
throw new Error("Prompt cancelled");
|
|
76
75
|
} else if (keyEvent.specialKey === SpecialKey.INTERRUPT) {
|
|
77
76
|
await ctx.terminal.showCursor();
|
|
78
|
-
|
|
77
|
+
interrupt(ctx);
|
|
79
78
|
throw new Error("Interrupted");
|
|
80
79
|
}
|
|
81
80
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { Prompt, PromptResult } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type { SingleValueType } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
3
|
import { SpecialKey } from "../../../terminal/KeyReader.ts";
|
|
4
|
-
import
|
|
5
|
-
import { renderPromptHeader } from "./PromptContext.ts";
|
|
4
|
+
import { renderPromptHeader, interrupt } from "./PromptContext.ts";
|
|
6
5
|
import type { PromptContext } from "./PromptContext.ts";
|
|
7
6
|
|
|
8
7
|
export default async function promptText(
|
|
@@ -32,7 +31,7 @@ export default async function promptText(
|
|
|
32
31
|
throw new Error("Prompt cancelled");
|
|
33
32
|
} else if (keyEvent.specialKey === SpecialKey.INTERRUPT) {
|
|
34
33
|
await ctx.terminal.write("\n");
|
|
35
|
-
|
|
34
|
+
interrupt(ctx);
|
|
36
35
|
throw new Error("Interrupted");
|
|
37
36
|
} else if (keyEvent.specialKey === SpecialKey.BACKSPACE) {
|
|
38
37
|
if (buffer.length > 0) {
|
|
@@ -5,6 +5,12 @@ import { shutdownState } from "./ShutdownState.ts";
|
|
|
5
5
|
export default class DefaultShutdownService implements ShutdownService {
|
|
6
6
|
static readonly taskList = new PriorityTaskList<ShutdownTask>();
|
|
7
7
|
|
|
8
|
+
readonly #onInterrupt: () => void;
|
|
9
|
+
|
|
10
|
+
public constructor(onInterrupt: () => void = () => {}) {
|
|
11
|
+
this.#onInterrupt = onInterrupt;
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
registerTask(task: ShutdownTask): void {
|
|
9
15
|
DefaultShutdownService.taskList.add(task);
|
|
10
16
|
}
|
|
@@ -17,6 +23,10 @@ export default class DefaultShutdownService implements ShutdownService {
|
|
|
17
23
|
shutdownState.longRunningMode = false;
|
|
18
24
|
}
|
|
19
25
|
|
|
26
|
+
interrupt(): void {
|
|
27
|
+
this.#onInterrupt();
|
|
28
|
+
}
|
|
29
|
+
|
|
20
30
|
get isShutdownRequested(): boolean {
|
|
21
31
|
return shutdownState.shutdownRequested;
|
|
22
32
|
}
|
|
@@ -16,7 +16,7 @@ export default class ShutdownServiceProvider implements ServiceProvider {
|
|
|
16
16
|
static #shutdownInProgress = false;
|
|
17
17
|
|
|
18
18
|
public constructor(readonly servicePriority: number) {
|
|
19
|
-
this.#shutdownService = new DefaultShutdownService();
|
|
19
|
+
this.#shutdownService = new DefaultShutdownService(ShutdownServiceProvider.onInterrupt);
|
|
20
20
|
process.on("beforeExit", ShutdownServiceProvider.shutdown);
|
|
21
21
|
process.on("SIGINT", ShutdownServiceProvider.onInterrupt);
|
|
22
22
|
process.on("SIGTERM", ShutdownServiceProvider.onTerminate);
|