@flowscripter/dynamic-cli-framework 5.1.6 → 5.1.8
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/plugin/DefaultPluginService.d.ts +7 -1
- package/dist/src/service/plugin/DefaultPluginService.d.ts.map +1 -1
- package/dist/src/service/plugin/DefaultPluginService.js +15 -0
- package/dist/src/service/plugin/PluginServiceProvider.d.ts.map +1 -1
- package/dist/src/service/plugin/PluginServiceProvider.js +2 -5
- package/dist/src/service/plugin/SpawnInterfaceAdapter.d.ts +1 -0
- package/dist/src/service/plugin/SpawnInterfaceAdapter.d.ts.map +1 -1
- package/dist/src/service/plugin/SpawnInterfaceAdapter.js +2 -1
- package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts.map +1 -1
- package/dist/src/service/plugin/command/PluginAddSubCommand.js +10 -0
- package/package.json +3 -3
- package/src/service/plugin/DefaultPluginService.ts +20 -0
- package/src/service/plugin/PluginServiceProvider.ts +2 -5
- package/src/service/plugin/SpawnInterfaceAdapter.ts +3 -2
- package/src/service/plugin/command/PluginAddSubCommand.ts +14 -0
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import type { PluginService } from "@flowscripter/dynamic-cli-framework-api";
|
|
2
2
|
import type { KeyValueService } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
|
-
import type { MarketplacePluginManager, SearchQuery, VersionedPluginDescriptor, NpmjsPluginRepositoryConfig, NpmPluginRepositoryConfig } from "@flowscripter/dynamic-plugin-framework";
|
|
3
|
+
import type { MarketplacePluginManager, SearchQuery, VersionedPluginDescriptor, NpmjsPluginRepositoryConfig, NpmPluginRepositoryConfig, FetchInterface } from "@flowscripter/dynamic-plugin-framework";
|
|
4
4
|
export default class DefaultPluginService implements PluginService {
|
|
5
5
|
#private;
|
|
6
6
|
constructor(remoteConfig: NpmjsPluginRepositoryConfig, localConfig: NpmPluginRepositoryConfig);
|
|
7
7
|
get pluginManager(): MarketplacePluginManager;
|
|
8
8
|
applyKeyValueOverrides(keyValueService: KeyValueService): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Supply the {@link FetchInterface} for the underlying `pluginManager` to delegate fetch calls
|
|
11
|
+
* to, so it respects the host CLI's shutdown handling and default timeout.
|
|
12
|
+
*/
|
|
13
|
+
setFetch(fetchInterface: FetchInterface): void;
|
|
14
|
+
checkAvailable(pluginId: string, version?: string): Promise<boolean>;
|
|
9
15
|
search(query: Readonly<SearchQuery>): AsyncIterable<Readonly<VersionedPluginDescriptor>>;
|
|
10
16
|
install(descriptor: Readonly<VersionedPluginDescriptor>): Promise<void>;
|
|
11
17
|
uninstall(pluginId: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultPluginService.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/DefaultPluginService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EACV,wBAAwB,EACxB,WAAW,EACX,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,
|
|
1
|
+
{"version":3,"file":"DefaultPluginService.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/DefaultPluginService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EACV,wBAAwB,EACxB,WAAW,EACX,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EAEzB,cAAc,EACf,MAAM,wCAAwC,CAAC;AAWhD,MAAM,CAAC,OAAO,OAAO,oBAAqB,YAAW,aAAa;;gBAKpD,YAAY,EAAE,2BAA2B,EAAE,WAAW,EAAE,yBAAyB;IAS7F,IAAI,aAAa,IAAI,wBAAwB,CAE5C;IAEK,sBAAsB,CAAC,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB7E;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI;IAMxC,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1E,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;IAIlF,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,yBAAyB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvE,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,aAAa,IAAI,aAAa,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;IAInE,eAAe,IAAI,aAAa,CAAC;QAC/B,UAAU,EAAE,QAAQ,CAAC,yBAAyB,CAAC,CAAC;QAChD,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CAGH"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { NpmPluginManager, NpmjsPluginRepository, NpmPluginRepository, } from "@flowscripter/dynamic-plugin-framework";
|
|
2
|
+
function isFetchCapable(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && "setFetch" in value;
|
|
4
|
+
}
|
|
2
5
|
export default class DefaultPluginService {
|
|
3
6
|
#defaultRemoteConfig;
|
|
4
7
|
#defaultLocalConfig;
|
|
@@ -22,6 +25,18 @@ export default class DefaultPluginService {
|
|
|
22
25
|
}
|
|
23
26
|
this.#pluginManager = new NpmPluginManager(remotesConfig.map((config) => new NpmjsPluginRepository(config)), new NpmPluginRepository(localConfig));
|
|
24
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Supply the {@link FetchInterface} for the underlying `pluginManager` to delegate fetch calls
|
|
30
|
+
* to, so it respects the host CLI's shutdown handling and default timeout.
|
|
31
|
+
*/
|
|
32
|
+
setFetch(fetchInterface) {
|
|
33
|
+
if (isFetchCapable(this.#pluginManager)) {
|
|
34
|
+
this.#pluginManager.setFetch(fetchInterface);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async checkAvailable(pluginId, version) {
|
|
38
|
+
return this.#pluginManager.checkAvailable(pluginId, version);
|
|
39
|
+
}
|
|
25
40
|
search(query) {
|
|
26
41
|
return this.#pluginManager.search(query);
|
|
27
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/PluginServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWzE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"PluginServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/PluginServiceProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWzE,OAAO,KAAK,EACV,2BAA2B,EAC3B,yBAAyB,EAE1B,MAAM,wCAAwC,CAAC;AAIhD,OAA8B,EAC5B,KAAK,4BAA4B,EAClC,MAAM,4BAA4B,CAAC;AACpC,OAA8B,EAC5B,KAAK,4BAA4B,EAClC,MAAM,4BAA4B,CAAC;AACpC,OAAO,sBAAsB,MAAM,kDAAkD,CAAC;AACtF,OAAO,8BAA8B,MAAM,0DAA0D,CAAC;AAMtG,MAAM,CAAC,OAAO,OAAO,qBAAsB,YAAW,eAAe;;IACnE,QAAQ,CAAC,SAAS,oBAAqB;IACvC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;gBAW/B,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,2BAA2B,EACzC,WAAW,EAAE,yBAAyB,EACtC,eAAe,EAAE,sBAAsB,EACvC,uBAAuB,EAAE,8BAA8B,EACvD,4BAA4B,GAAE,4BAAiC,EAC/D,4BAA4B,GAAE,4BAAiC;IAW3D,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;IAS1D,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAiEnD"}
|
|
@@ -60,15 +60,12 @@ export default class PluginServiceProvider {
|
|
|
60
60
|
pluginManager.setSpawn(adapter);
|
|
61
61
|
}
|
|
62
62
|
if (!context.doesServiceExist(FETCH_SERVICE_ID)) {
|
|
63
|
-
logger.debug("FetchService not available, plugin
|
|
64
|
-
}
|
|
65
|
-
else if (!("setFetch" in pluginManager)) {
|
|
66
|
-
logger.debug("Plugin manager does not support FetchCapable, skipping fetch injection");
|
|
63
|
+
logger.debug("FetchService not available, plugin service will fetch directly");
|
|
67
64
|
}
|
|
68
65
|
else {
|
|
69
66
|
const fetchService = context.getServiceById(FETCH_SERVICE_ID);
|
|
70
67
|
const adapter = new FetchInterfaceAdapter(fetchService, this.#fetchInterfaceAdapterOptions);
|
|
71
|
-
|
|
68
|
+
pluginService.setFetch(adapter);
|
|
72
69
|
}
|
|
73
70
|
await pluginManager.registerExtensions(DYNAMIC_CLI_FRAMEWORK_COMMAND_FACTORY_EXTENSION_POINT);
|
|
74
71
|
await pluginManager.registerExtensions(DYNAMIC_CLI_FRAMEWORK_SERVICE_PROVIDER_FACTORY_EXTENSION_POINT);
|
|
@@ -16,6 +16,7 @@ export default class SpawnInterfaceAdapter implements SpawnInterface {
|
|
|
16
16
|
constructor(spawnService: SpawnService, printerService: PrinterService, options?: SpawnInterfaceAdapterOptions);
|
|
17
17
|
spawn(command: ReadonlyArray<string>, options: {
|
|
18
18
|
cwd: string;
|
|
19
|
+
timeoutMs?: number;
|
|
19
20
|
}): Promise<SpawnResult>;
|
|
20
21
|
}
|
|
21
22
|
//# sourceMappingURL=SpawnInterfaceAdapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpawnInterfaceAdapter.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/SpawnInterfaceAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAE1F,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAsB,YAAW,cAAc;;gBAOhE,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,cAAc,EAC9B,OAAO,GAAE,4BAAiC;IAQ/B,KAAK,CAChB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,
|
|
1
|
+
{"version":3,"file":"SpawnInterfaceAdapter.d.ts","sourceRoot":"","sources":["../../../../src/service/plugin/SpawnInterfaceAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5F,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAE1F,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAsB,YAAW,cAAc;;gBAOhE,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,cAAc,EAC9B,OAAO,GAAE,4BAAiC;IAQ/B,KAAK,CAChB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAC3C,OAAO,CAAC,WAAW,CAAC;CAuCxB"}
|
|
@@ -30,6 +30,7 @@ export default class SpawnInterfaceAdapter {
|
|
|
30
30
|
cwd: options.cwd,
|
|
31
31
|
mode: "wrapped",
|
|
32
32
|
onOutput,
|
|
33
|
+
timeoutMs: options.timeoutMs,
|
|
33
34
|
});
|
|
34
35
|
await writeQueue;
|
|
35
36
|
this.#printerService.endQuote();
|
|
@@ -47,7 +48,7 @@ export default class SpawnInterfaceAdapter {
|
|
|
47
48
|
return { ok: true, exitCode: result.exitCode };
|
|
48
49
|
}
|
|
49
50
|
return "timedOut" in result
|
|
50
|
-
? { ok: false,
|
|
51
|
+
? { ok: false, timedOut: true }
|
|
51
52
|
: { ok: false, exitCode: result.exitCode, error: result.error };
|
|
52
53
|
}
|
|
53
54
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginAddSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginAddSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AASxE,qBAAa,mBAAoB,YAAW,UAAU;IACpD,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,WAAW,6BAA6B;IACjD,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"PluginAddSubCommand.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/PluginAddSubCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AASxE,qBAAa,mBAAoB,YAAW,UAAU;IACpD,QAAQ,CAAC,IAAI,SAAS;IACtB,QAAQ,CAAC,WAAW,6BAA6B;IACjD,QAAQ,CAAC,mBAAmB,SAAS;IACrC,QAAQ,CAAC,OAAO,UAAM;IACtB,QAAQ,CAAC,WAAW;;;;QAMlB;IAEI,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAgEvE"}
|
|
@@ -52,6 +52,16 @@ export class PluginAddSubCommand {
|
|
|
52
52
|
const installLabel = descriptor.version && descriptor.version !== "latest"
|
|
53
53
|
? `${descriptor.pluginId}@${descriptor.version}`
|
|
54
54
|
: descriptor.pluginId;
|
|
55
|
+
// Confirm the package (and specific version/tag, if requested) actually exists on the
|
|
56
|
+
// remote marketplace before invoking the package manager - so a non-existent plugin or
|
|
57
|
+
// version is reported clearly instead of failing later (and less clearly) inside
|
|
58
|
+
// `bun add`/`npm install`.
|
|
59
|
+
const versionToCheck = descriptor.version === "latest" ? undefined : descriptor.version;
|
|
60
|
+
if (!(await pluginService.checkAvailable(descriptor.pluginId, versionToCheck))) {
|
|
61
|
+
throw new Error(versionToCheck
|
|
62
|
+
? `Version ${versionToCheck} of plugin ${descriptor.pluginId} was not found in the configured plugin registry`
|
|
63
|
+
: `Plugin ${descriptor.pluginId} was not found in the configured plugin registry`);
|
|
64
|
+
}
|
|
55
65
|
await printerService.info(`Installing ${installLabel}...\n`, Icon.INFORMATION);
|
|
56
66
|
await pluginService.install(descriptor);
|
|
57
67
|
await printerService.print(`Plugin ${descriptor.pluginId} installed.\n`, Icon.SUCCESS);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowscripter/dynamic-cli-framework",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.8",
|
|
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,8 +48,8 @@
|
|
|
48
48
|
"build": "tsc -p tsconfig.build.json"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@flowscripter/dynamic-cli-framework-api": "^2.
|
|
52
|
-
"@flowscripter/dynamic-plugin-framework": "2.
|
|
51
|
+
"@flowscripter/dynamic-cli-framework-api": "^2.3.0",
|
|
52
|
+
"@flowscripter/dynamic-plugin-framework": "^2.2.2",
|
|
53
53
|
"emphasize": "^7.0.0",
|
|
54
54
|
"fastest-levenshtein": "^1.0.16",
|
|
55
55
|
"figlet": "^1.11.0",
|
|
@@ -6,6 +6,8 @@ import type {
|
|
|
6
6
|
VersionedPluginDescriptor,
|
|
7
7
|
NpmjsPluginRepositoryConfig,
|
|
8
8
|
NpmPluginRepositoryConfig,
|
|
9
|
+
FetchCapable,
|
|
10
|
+
FetchInterface,
|
|
9
11
|
} from "@flowscripter/dynamic-plugin-framework";
|
|
10
12
|
import {
|
|
11
13
|
NpmPluginManager,
|
|
@@ -13,6 +15,10 @@ import {
|
|
|
13
15
|
NpmPluginRepository,
|
|
14
16
|
} from "@flowscripter/dynamic-plugin-framework";
|
|
15
17
|
|
|
18
|
+
function isFetchCapable(value: unknown): value is FetchCapable {
|
|
19
|
+
return typeof value === "object" && value !== null && "setFetch" in value;
|
|
20
|
+
}
|
|
21
|
+
|
|
16
22
|
export default class DefaultPluginService implements PluginService {
|
|
17
23
|
readonly #defaultRemoteConfig: NpmjsPluginRepositoryConfig;
|
|
18
24
|
readonly #defaultLocalConfig: NpmPluginRepositoryConfig;
|
|
@@ -50,6 +56,20 @@ export default class DefaultPluginService implements PluginService {
|
|
|
50
56
|
);
|
|
51
57
|
}
|
|
52
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Supply the {@link FetchInterface} for the underlying `pluginManager` to delegate fetch calls
|
|
61
|
+
* to, so it respects the host CLI's shutdown handling and default timeout.
|
|
62
|
+
*/
|
|
63
|
+
setFetch(fetchInterface: FetchInterface): void {
|
|
64
|
+
if (isFetchCapable(this.#pluginManager)) {
|
|
65
|
+
this.#pluginManager.setFetch(fetchInterface);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async checkAvailable(pluginId: string, version?: string): Promise<boolean> {
|
|
70
|
+
return this.#pluginManager.checkAvailable(pluginId, version);
|
|
71
|
+
}
|
|
72
|
+
|
|
53
73
|
search(query: Readonly<SearchQuery>): AsyncIterable<Readonly<VersionedPluginDescriptor>> {
|
|
54
74
|
return this.#pluginManager.search(query);
|
|
55
75
|
}
|
|
@@ -12,7 +12,6 @@ import { DYNAMIC_CLI_FRAMEWORK_SERVICE_PROVIDER_FACTORY_EXTENSION_POINT } from "
|
|
|
12
12
|
import type { CommandFactory } from "@flowscripter/dynamic-cli-framework-api";
|
|
13
13
|
import type { ServiceProviderFactory } from "@flowscripter/dynamic-cli-framework-api";
|
|
14
14
|
import type {
|
|
15
|
-
FetchCapable,
|
|
16
15
|
NpmjsPluginRepositoryConfig,
|
|
17
16
|
NpmPluginRepositoryConfig,
|
|
18
17
|
SpawnCapable,
|
|
@@ -98,13 +97,11 @@ export default class PluginServiceProvider implements ServiceProvider {
|
|
|
98
97
|
}
|
|
99
98
|
|
|
100
99
|
if (!context.doesServiceExist(FETCH_SERVICE_ID)) {
|
|
101
|
-
logger.debug("FetchService not available, plugin
|
|
102
|
-
} else if (!("setFetch" in pluginManager)) {
|
|
103
|
-
logger.debug("Plugin manager does not support FetchCapable, skipping fetch injection");
|
|
100
|
+
logger.debug("FetchService not available, plugin service will fetch directly");
|
|
104
101
|
} else {
|
|
105
102
|
const fetchService = context.getServiceById(FETCH_SERVICE_ID) as FetchService;
|
|
106
103
|
const adapter = new FetchInterfaceAdapter(fetchService, this.#fetchInterfaceAdapterOptions);
|
|
107
|
-
|
|
104
|
+
pluginService.setFetch(adapter);
|
|
108
105
|
}
|
|
109
106
|
|
|
110
107
|
await pluginManager.registerExtensions(DYNAMIC_CLI_FRAMEWORK_COMMAND_FACTORY_EXTENSION_POINT);
|
|
@@ -32,7 +32,7 @@ export default class SpawnInterfaceAdapter implements SpawnInterface {
|
|
|
32
32
|
|
|
33
33
|
public async spawn(
|
|
34
34
|
command: ReadonlyArray<string>,
|
|
35
|
-
options: { cwd: string },
|
|
35
|
+
options: { cwd: string; timeoutMs?: number },
|
|
36
36
|
): Promise<SpawnResult> {
|
|
37
37
|
this.#printerService.startQuote(this.#quoteColor);
|
|
38
38
|
this.#printerService.startMark();
|
|
@@ -49,6 +49,7 @@ export default class SpawnInterfaceAdapter implements SpawnInterface {
|
|
|
49
49
|
cwd: options.cwd,
|
|
50
50
|
mode: "wrapped",
|
|
51
51
|
onOutput,
|
|
52
|
+
timeoutMs: options.timeoutMs,
|
|
52
53
|
});
|
|
53
54
|
|
|
54
55
|
await writeQueue;
|
|
@@ -68,7 +69,7 @@ export default class SpawnInterfaceAdapter implements SpawnInterface {
|
|
|
68
69
|
return { ok: true, exitCode: result.exitCode };
|
|
69
70
|
}
|
|
70
71
|
return "timedOut" in result
|
|
71
|
-
? { ok: false,
|
|
72
|
+
? { ok: false, timedOut: true }
|
|
72
73
|
: { ok: false, exitCode: result.exitCode, error: result.error };
|
|
73
74
|
}
|
|
74
75
|
}
|
|
@@ -69,6 +69,20 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
69
69
|
descriptor.version && descriptor.version !== "latest"
|
|
70
70
|
? `${descriptor.pluginId}@${descriptor.version}`
|
|
71
71
|
: descriptor.pluginId;
|
|
72
|
+
|
|
73
|
+
// Confirm the package (and specific version/tag, if requested) actually exists on the
|
|
74
|
+
// remote marketplace before invoking the package manager - so a non-existent plugin or
|
|
75
|
+
// version is reported clearly instead of failing later (and less clearly) inside
|
|
76
|
+
// `bun add`/`npm install`.
|
|
77
|
+
const versionToCheck = descriptor.version === "latest" ? undefined : descriptor.version;
|
|
78
|
+
if (!(await pluginService.checkAvailable(descriptor.pluginId, versionToCheck))) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
versionToCheck
|
|
81
|
+
? `Version ${versionToCheck} of plugin ${descriptor.pluginId} was not found in the configured plugin registry`
|
|
82
|
+
: `Plugin ${descriptor.pluginId} was not found in the configured plugin registry`,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
72
86
|
await printerService.info(`Installing ${installLabel}...\n`, Icon.INFORMATION);
|
|
73
87
|
await pluginService.install(descriptor);
|
|
74
88
|
await printerService.print(`Plugin ${descriptor.pluginId} installed.\n`, Icon.SUCCESS);
|