@flowscripter/dynamic-cli-framework 5.0.6 → 5.1.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/dist/src/service/plugin/command/PluginAddSubCommand.d.ts.map +1 -1
- package/dist/src/service/plugin/command/PluginAddSubCommand.js +9 -3
- package/dist/src/service/plugin/command/parsePluginSpecifier.d.ts +17 -0
- package/dist/src/service/plugin/command/parsePluginSpecifier.d.ts.map +1 -0
- package/dist/src/service/plugin/command/parsePluginSpecifier.js +22 -0
- package/package.json +1 -1
- package/src/service/plugin/command/PluginAddSubCommand.ts +10 -3
- package/src/service/plugin/command/parsePluginSpecifier.ts +22 -0
|
@@ -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;
|
|
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;CA6CvE"}
|
|
@@ -2,6 +2,7 @@ import { ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
|
|
|
2
2
|
import { Icon, PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
3
3
|
import { PLUGIN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
4
4
|
import { getPluginId } from "./getPluginId.js";
|
|
5
|
+
import { parsePluginSpecifier } from "./parsePluginSpecifier.js";
|
|
5
6
|
export class PluginAddSubCommand {
|
|
6
7
|
name = "add";
|
|
7
8
|
description = "Install a remote plugin";
|
|
@@ -10,14 +11,14 @@ export class PluginAddSubCommand {
|
|
|
10
11
|
positionals = [
|
|
11
12
|
{
|
|
12
13
|
name: "pluginId",
|
|
13
|
-
description: "Plugin ID to install (e.g. @scope/name)",
|
|
14
|
+
description: "Plugin ID to install (e.g. @scope/name or @scope/name:version)",
|
|
14
15
|
type: ValueTypeName.STRING,
|
|
15
16
|
},
|
|
16
17
|
];
|
|
17
18
|
async execute(context, argumentValues) {
|
|
18
19
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID);
|
|
19
20
|
const pluginService = context.getServiceById(PLUGIN_SERVICE_ID);
|
|
20
|
-
const pluginId = argumentValues["pluginId"];
|
|
21
|
+
const { pluginId, version } = parsePluginSpecifier(argumentValues["pluginId"]);
|
|
21
22
|
await printerService.info(`Searching for plugin: ${pluginId}\n`, Icon.INFORMATION);
|
|
22
23
|
let descriptor;
|
|
23
24
|
for await (const d of pluginService.search({ text: pluginId })) {
|
|
@@ -26,6 +27,11 @@ export class PluginAddSubCommand {
|
|
|
26
27
|
break;
|
|
27
28
|
}
|
|
28
29
|
}
|
|
30
|
+
if (descriptor && version) {
|
|
31
|
+
// search only ever returns the latest version - substitute the explicitly requested
|
|
32
|
+
// version so install() is asked for the correct one.
|
|
33
|
+
descriptor = { ...descriptor, version };
|
|
34
|
+
}
|
|
29
35
|
if (!descriptor) {
|
|
30
36
|
// Search did not find an exact match - attempt direct install by plugin ID.
|
|
31
37
|
// This handles cases where the package exists on the registry but is not
|
|
@@ -38,7 +44,7 @@ export class PluginAddSubCommand {
|
|
|
38
44
|
pluginId,
|
|
39
45
|
scope,
|
|
40
46
|
name,
|
|
41
|
-
version: "latest",
|
|
47
|
+
version: version ?? "latest",
|
|
42
48
|
extensionPoints: [],
|
|
43
49
|
};
|
|
44
50
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a plugin specifier into a bare plugin ID and an optional version.
|
|
3
|
+
*
|
|
4
|
+
* The specifier is split on the *last* `:` character, if present. Scoped npm package names
|
|
5
|
+
* (e.g. `@scope/name`) never legitimately contain a literal `:`, so this split cannot collide
|
|
6
|
+
* with the scope/slash structure of the plugin ID itself.
|
|
7
|
+
*
|
|
8
|
+
* Everything after the last `:` is always treated as the requested version, including
|
|
9
|
+
* non-semver tags such as `latest` or `next` - no validation is performed on the tail.
|
|
10
|
+
*
|
|
11
|
+
* @param specifier raw plugin specifier, e.g. `@scope/name`, `@scope/name:3.0.0` or `name:latest`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parsePluginSpecifier(specifier: string): {
|
|
14
|
+
pluginId: string;
|
|
15
|
+
version?: string;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=parsePluginSpecifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parsePluginSpecifier.d.ts","sourceRoot":"","sources":["../../../../../src/service/plugin/command/parsePluginSpecifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAS9F"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a plugin specifier into a bare plugin ID and an optional version.
|
|
3
|
+
*
|
|
4
|
+
* The specifier is split on the *last* `:` character, if present. Scoped npm package names
|
|
5
|
+
* (e.g. `@scope/name`) never legitimately contain a literal `:`, so this split cannot collide
|
|
6
|
+
* with the scope/slash structure of the plugin ID itself.
|
|
7
|
+
*
|
|
8
|
+
* Everything after the last `:` is always treated as the requested version, including
|
|
9
|
+
* non-semver tags such as `latest` or `next` - no validation is performed on the tail.
|
|
10
|
+
*
|
|
11
|
+
* @param specifier raw plugin specifier, e.g. `@scope/name`, `@scope/name:3.0.0` or `name:latest`.
|
|
12
|
+
*/
|
|
13
|
+
export function parsePluginSpecifier(specifier) {
|
|
14
|
+
const index = specifier.lastIndexOf(":");
|
|
15
|
+
if (index === -1) {
|
|
16
|
+
return { pluginId: specifier };
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
pluginId: specifier.slice(0, index),
|
|
20
|
+
version: specifier.slice(index + 1),
|
|
21
|
+
};
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import { PLUGIN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
|
|
|
8
8
|
import type { PluginService } from "@flowscripter/dynamic-cli-framework-api";
|
|
9
9
|
import type { VersionedPluginDescriptor } from "@flowscripter/dynamic-plugin-framework";
|
|
10
10
|
import { getPluginId } from "./getPluginId.ts";
|
|
11
|
+
import { parsePluginSpecifier } from "./parsePluginSpecifier.ts";
|
|
11
12
|
|
|
12
13
|
export class PluginAddSubCommand implements SubCommand {
|
|
13
14
|
readonly name = "add";
|
|
@@ -17,7 +18,7 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
17
18
|
readonly positionals = [
|
|
18
19
|
{
|
|
19
20
|
name: "pluginId",
|
|
20
|
-
description: "Plugin ID to install (e.g. @scope/name)",
|
|
21
|
+
description: "Plugin ID to install (e.g. @scope/name or @scope/name:version)",
|
|
21
22
|
type: ValueTypeName.STRING,
|
|
22
23
|
},
|
|
23
24
|
];
|
|
@@ -26,7 +27,7 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
26
27
|
const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
|
|
27
28
|
const pluginService = context.getServiceById(PLUGIN_SERVICE_ID) as PluginService;
|
|
28
29
|
|
|
29
|
-
const pluginId = argumentValues["pluginId"] as string;
|
|
30
|
+
const { pluginId, version } = parsePluginSpecifier(argumentValues["pluginId"] as string);
|
|
30
31
|
await printerService.info(`Searching for plugin: ${pluginId}\n`, Icon.INFORMATION);
|
|
31
32
|
|
|
32
33
|
let descriptor: VersionedPluginDescriptor | undefined;
|
|
@@ -37,6 +38,12 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
if (descriptor && version) {
|
|
42
|
+
// search only ever returns the latest version - substitute the explicitly requested
|
|
43
|
+
// version so install() is asked for the correct one.
|
|
44
|
+
descriptor = { ...descriptor, version };
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
if (!descriptor) {
|
|
41
48
|
// Search did not find an exact match - attempt direct install by plugin ID.
|
|
42
49
|
// This handles cases where the package exists on the registry but is not
|
|
@@ -52,7 +59,7 @@ export class PluginAddSubCommand implements SubCommand {
|
|
|
52
59
|
pluginId,
|
|
53
60
|
scope,
|
|
54
61
|
name,
|
|
55
|
-
version: "latest",
|
|
62
|
+
version: version ?? "latest",
|
|
56
63
|
extensionPoints: [],
|
|
57
64
|
};
|
|
58
65
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a plugin specifier into a bare plugin ID and an optional version.
|
|
3
|
+
*
|
|
4
|
+
* The specifier is split on the *last* `:` character, if present. Scoped npm package names
|
|
5
|
+
* (e.g. `@scope/name`) never legitimately contain a literal `:`, so this split cannot collide
|
|
6
|
+
* with the scope/slash structure of the plugin ID itself.
|
|
7
|
+
*
|
|
8
|
+
* Everything after the last `:` is always treated as the requested version, including
|
|
9
|
+
* non-semver tags such as `latest` or `next` - no validation is performed on the tail.
|
|
10
|
+
*
|
|
11
|
+
* @param specifier raw plugin specifier, e.g. `@scope/name`, `@scope/name:3.0.0` or `name:latest`.
|
|
12
|
+
*/
|
|
13
|
+
export function parsePluginSpecifier(specifier: string): { pluginId: string; version?: string } {
|
|
14
|
+
const index = specifier.lastIndexOf(":");
|
|
15
|
+
if (index === -1) {
|
|
16
|
+
return { pluginId: specifier };
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
pluginId: specifier.slice(0, index),
|
|
20
|
+
version: specifier.slice(index + 1),
|
|
21
|
+
};
|
|
22
|
+
}
|