@dsh-workbench/shared 0.3.11 → 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +97 -0
- package/dist/api/blocker-table.d.ts +3 -3
- package/dist/api/blocker-table.js +47 -23
- package/dist/api/dsh.d.ts +1 -1
- package/dist/api/workbench-client.js +2 -1
- package/dist/components/Activity.css +0 -1
- package/dist/components/ApprovalDetail.css +1 -2
- package/dist/components/ApprovalDetail.d.ts +1 -1
- package/dist/components/ApprovalPlan.css +0 -1
- package/dist/components/Card.css +0 -1
- package/dist/components/Card.d.ts +1 -1
- package/dist/components/CardBoundary.d.ts +1 -1
- package/dist/components/CardHead.css +0 -1
- package/dist/components/CardHead.d.ts +1 -1
- package/dist/components/ChoiceGroup.css +1 -2
- package/dist/components/ConfirmBar.d.ts +1 -1
- package/dist/components/ConfirmBar.js +1 -1
- package/dist/components/Form.css +1 -1
- package/dist/components/FormActions.js +1 -1
- package/dist/components/LongTaskRow.css +1 -2
- package/dist/components/LongTaskRow.d.ts +1 -1
- package/dist/components/LongTaskRow.js +1 -1
- package/dist/components/Note.css +0 -1
- package/dist/components/ResourceStates.css +0 -1
- package/dist/components/SettingsSection.css +0 -1
- package/dist/components/Spinner.css +0 -1
- package/dist/components/Stack.css +0 -1
- package/dist/components/StateBlock.css +0 -1
- package/dist/components/board-module.d.ts +3 -3
- package/dist/components/icons.d.ts +1 -1
- package/dist/components/icons.js +11 -4
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.js +2 -2
- package/dist/contract/adapters.d.ts +10 -0
- package/dist/contract/cli.d.ts +3 -0
- package/dist/contract/data.d.ts +126 -0
- package/dist/{api → contract}/facts.d.ts +12 -3
- package/dist/{api → contract}/facts.js +19 -1
- package/dist/contract/needs.d.ts +132 -0
- package/dist/contract/needs.js +232 -0
- package/dist/contract/plugin-source.d.ts +1 -0
- package/dist/contract/protocol/bundle-install.d.ts +136 -0
- package/dist/contract/protocol/bundle-install.js +12 -0
- package/dist/contract/protocol/config-sync.d.ts +55 -0
- package/dist/contract/protocol/config-sync.js +2 -0
- package/dist/contract/protocol/diy.d.ts +4 -0
- package/dist/contract/protocol/diy.js +4 -0
- package/dist/contract/protocol/dsh-plugins.d.ts +11 -0
- package/dist/contract/protocol/dsh-plugins.js +1 -0
- package/dist/contract/protocol/long-tasks.d.ts +13 -0
- package/dist/contract/protocol/long-tasks.js +1 -0
- package/dist/contract/protocol/market-index.d.ts +195 -0
- package/dist/contract/protocol/market-index.js +7 -0
- package/dist/contract/protocol/platform.d.ts +44 -0
- package/dist/contract/protocol/platform.js +1 -0
- package/dist/contract/protocol/preflight-wake.d.ts +7 -0
- package/dist/contract/protocol/preflight-wake.js +1 -0
- package/dist/contract/protocol/profile-create.d.ts +30 -0
- package/dist/contract/protocol/profile-create.js +2 -0
- package/dist/contract/protocol/sidebar-edition.d.ts +14 -0
- package/dist/contract/protocol/sidebar-edition.js +2 -0
- package/dist/contract/protocol/unit-manifests.d.ts +6 -0
- package/dist/contract/protocol/unit-manifests.js +1 -0
- package/dist/contract/unit-board.js +1 -0
- package/dist/contract/unit-capability.d.ts +34 -0
- package/dist/contract/unit-capability.js +1 -0
- package/dist/{host → contract}/unit-declaration.d.ts +7 -5
- package/dist/{api → contract}/unit-declaration.js +19 -13
- package/dist/contract/unit.d.ts +57 -0
- package/dist/contract/unit.js +24 -0
- package/dist/contract/workbench-contract.d.ts +15 -0
- package/dist/contract/workbench-contract.js +1 -0
- package/dist/host/adapter-set.d.ts +26 -0
- package/dist/host/adapter-set.js +243 -0
- package/dist/host/adapter-types.d.ts +79 -0
- package/dist/host/adapter-types.js +23 -0
- package/dist/host/adapters.d.ts +22 -0
- package/dist/host/adapters.js +9 -0
- package/dist/host/browser.d.ts +3 -0
- package/dist/host/browser.js +3 -0
- package/dist/host/changelog.d.ts +21 -0
- package/dist/host/changelog.js +188 -0
- package/dist/host/channel-plugin.d.ts +15 -0
- package/dist/host/channel-plugin.js +42 -0
- package/dist/host/cli.d.ts +4 -0
- package/dist/host/cli.js +7 -0
- package/dist/host/command-name.d.ts +1 -0
- package/dist/host/command-name.js +14 -0
- package/dist/host/data-error.d.ts +13 -0
- package/dist/host/data-error.js +20 -0
- package/dist/host/data-root.js +3 -0
- package/dist/host/diy-debug.js +2 -1
- package/dist/host/diy-record.js +2 -1
- package/dist/host/facts.d.ts +1 -1
- package/dist/host/facts.js +3 -2
- package/dist/host/git.js +2 -2
- package/dist/host/http.js +1 -1
- package/dist/host/lib-capabilities.d.ts +22 -0
- package/dist/host/lib-capabilities.js +37 -0
- package/dist/host/lib-install.d.ts +9 -0
- package/dist/host/lib-install.js +10 -0
- package/dist/host/long-task.d.ts +1 -1
- package/dist/host/long-task.js +4 -3
- package/dist/host/market-index.d.ts +22 -0
- package/dist/host/market-index.js +420 -0
- package/dist/host/needs.d.ts +4 -0
- package/dist/host/needs.js +2 -0
- package/dist/host/patch.d.ts +9 -0
- package/dist/host/patch.js +78 -0
- package/dist/host/paths.d.ts +12 -0
- package/dist/host/paths.js +28 -0
- package/dist/host/platform.d.ts +14 -0
- package/dist/host/platform.js +40 -0
- package/dist/host/plugin-source.d.ts +8 -6
- package/dist/host/plugin-source.js +43 -33
- package/dist/host/plugin.d.ts +4 -0
- package/dist/host/plugin.js +39 -0
- package/dist/host/port-types.d.ts +191 -0
- package/dist/host/port-types.js +1 -0
- package/dist/host/preflight.d.ts +28 -0
- package/dist/host/preflight.js +1 -0
- package/dist/host/profile-port.d.ts +4 -0
- package/dist/host/profile-port.js +4 -0
- package/dist/host/provision.d.ts +2 -2
- package/dist/host/provision.js +5 -3
- package/dist/host/recipe-rules.d.ts +5 -0
- package/dist/host/recipe-rules.js +382 -0
- package/dist/host/recipe.d.ts +14 -0
- package/dist/host/recipe.js +283 -0
- package/dist/host/shell-text.d.ts +9 -2
- package/dist/host/shell-text.js +15 -3
- package/dist/host/shell.d.ts +2 -0
- package/dist/host/shell.js +7 -0
- package/dist/host/spec.d.ts +8 -0
- package/dist/host/spec.js +24 -0
- package/dist/host/supply-index.d.ts +34 -0
- package/dist/host/supply-index.js +202 -0
- package/dist/host/supply-port.d.ts +5 -0
- package/dist/host/supply-port.js +39 -0
- package/dist/host/time.d.ts +12 -0
- package/dist/host/time.js +19 -0
- package/dist/host/tokens.d.ts +26 -0
- package/dist/host/tokens.js +154 -0
- package/dist/host/tool-kit.js +1 -1
- package/dist/host/unit-face.d.ts +5 -4
- package/dist/host/version-range.d.ts +2 -0
- package/dist/host/version-range.js +73 -0
- package/dist/host/version.d.ts +3 -0
- package/dist/host/version.js +29 -0
- package/dist/host.d.ts +47 -16
- package/dist/host.js +47 -16
- package/dist/i18n/en.js +224 -71
- package/dist/i18n/index.d.ts +298 -73
- package/dist/i18n/merge.js +1 -1
- package/dist/i18n/need-text.d.ts +26 -0
- package/dist/i18n/need-text.js +26 -0
- package/dist/i18n/settings.d.ts +70 -0
- package/dist/i18n/settings.js +136 -0
- package/dist/i18n/zh.d.ts +297 -72
- package/dist/i18n/zh.js +226 -73
- package/dist/index.d.ts +23 -7
- package/dist/index.js +23 -7
- package/dist/{api → lib}/dsh-client.d.ts +11 -1
- package/dist/lib/dsh-client.js +1 -0
- package/dist/lib/market-index.d.ts +7 -0
- package/dist/lib/market-index.js +25 -0
- package/dist/lib/react.d.ts +0 -40
- package/dist/lib/react.js +0 -36
- package/dist/lib/ui.js +3 -9
- package/dist/testing/data.d.ts +13 -0
- package/dist/testing/data.js +46 -0
- package/dist/testing/declaration.d.ts +1 -1
- package/dist/testing/declaration.js +1 -1
- package/dist/testing/host-fakes.d.ts +0 -13
- package/dist/testing/host-fakes.js +0 -24
- package/dist/testing/needs.d.ts +16 -0
- package/dist/testing/needs.js +46 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.js +2 -0
- package/package.json +18 -2
- package/src/api/__tests__/blocker-table.test.ts +135 -86
- package/src/api/blocker-table.ts +52 -26
- package/src/api/dsh.ts +1 -1
- package/src/api/host-write.ts +0 -1
- package/src/api/workbench-client.test.ts +2 -2
- package/src/api/workbench-client.ts +2 -1
- package/src/components/Activity.css +0 -1
- package/src/components/ApprovalDetail.css +1 -2
- package/src/components/ApprovalDetail.tsx +1 -1
- package/src/components/ApprovalPlan.css +0 -1
- package/src/components/Card.css +0 -1
- package/src/components/Card.tsx +1 -1
- package/src/components/CardAnchor.test.tsx +1 -1
- package/src/components/CardBoundary.tsx +1 -1
- package/src/components/CardHead.css +0 -1
- package/src/components/CardHead.tsx +1 -1
- package/src/components/ChoiceGroup.css +1 -2
- package/src/components/ConfirmBar.tsx +1 -1
- package/src/components/Form.css +1 -1
- package/src/components/Form.tsx +1 -1
- package/src/components/FormActions.tsx +1 -1
- package/src/components/LongTaskRow.css +1 -2
- package/src/components/LongTaskRow.tsx +1 -1
- package/src/components/Note.css +0 -1
- package/src/components/ResourceStates.css +0 -1
- package/src/components/SelectFieldNodes.tsx +0 -1
- package/src/components/SettingsSection.css +0 -1
- package/src/components/Spinner.css +0 -1
- package/src/components/Stack.css +0 -1
- package/src/components/StateBlock.css +0 -1
- package/src/components/__tests__/long-task-row.test.ts +1 -1
- package/src/components/board-module.ts +3 -3
- package/src/components/icons.tsx +16 -8
- package/src/config/constants.ts +2 -2
- package/src/{api → contract}/__tests__/facts.test.ts +73 -25
- package/src/{api → contract}/__tests__/long-task.test.ts +3 -3
- package/src/contract/__tests__/needs.test.ts +74 -0
- package/src/{host → contract}/__tests__/unit-declaration.test.ts +1 -1
- package/src/contract/__tests__/unit.test.ts +43 -0
- package/src/contract/adapters.ts +9 -0
- package/src/contract/cli.ts +3 -0
- package/src/contract/data.ts +145 -0
- package/src/{api → contract}/facts.ts +34 -4
- package/src/contract/needs.ts +331 -0
- package/src/contract/plugin-source.ts +1 -0
- package/src/contract/protocol/bundle-install.ts +198 -0
- package/src/contract/protocol/config-sync.ts +65 -0
- package/src/contract/protocol/diy.ts +4 -0
- package/src/contract/protocol/dsh-plugins.ts +13 -0
- package/src/contract/protocol/long-tasks.ts +16 -0
- package/src/contract/protocol/market-index.ts +246 -0
- package/src/contract/protocol/platform.ts +47 -0
- package/src/contract/protocol/preflight-wake.ts +17 -0
- package/src/contract/protocol/profile-create.ts +36 -0
- package/src/contract/protocol/sidebar-edition.ts +19 -0
- package/src/contract/protocol/unit-manifests.ts +8 -0
- package/src/{api → contract}/unit-board.ts +0 -1
- package/src/contract/unit-capability.ts +37 -0
- package/src/{host → contract}/unit-declaration.ts +22 -18
- package/src/contract/unit.ts +76 -0
- package/src/contract/workbench-contract.ts +30 -0
- package/src/host/__tests__/adapter-set.test.ts +228 -0
- package/src/host/__tests__/adapters.test.ts +27 -0
- package/src/host/__tests__/changelog.test.ts +102 -0
- package/src/host/__tests__/command-name.test.ts +16 -0
- package/src/host/__tests__/diy-record.test.ts +3 -3
- package/src/host/__tests__/facts.test.ts +5 -5
- package/src/host/__tests__/long-task.test.ts +1 -1
- package/src/host/__tests__/market-index.test.ts +179 -0
- package/src/host/__tests__/plugin-ledger.test.ts +10 -10
- package/src/host/__tests__/provision.test.ts +7 -6
- package/src/host/__tests__/shell-text.test.ts +16 -1
- package/src/host/__tests__/supply-index.test.ts +137 -0
- package/src/host/__tests__/tokens.test.ts +110 -0
- package/src/host/__tests__/version-range.test.ts +21 -0
- package/src/host/adapter-set.ts +298 -0
- package/src/host/adapter-types.ts +105 -0
- package/src/host/adapters.ts +44 -0
- package/src/host/browser.ts +3 -0
- package/src/host/changelog.ts +212 -0
- package/src/host/channel-plugin.ts +55 -0
- package/src/host/cli.ts +11 -0
- package/src/host/command-name.ts +15 -0
- package/src/host/data-error.ts +21 -0
- package/src/host/data-root.ts +2 -0
- package/src/host/diy-debug.ts +2 -1
- package/src/host/diy-record.ts +2 -1
- package/src/host/facts.ts +4 -3
- package/src/host/git.ts +2 -2
- package/src/host/http.ts +1 -1
- package/src/host/lib-capabilities.ts +52 -0
- package/src/host/lib-install.ts +18 -0
- package/src/host/long-task.ts +4 -3
- package/src/host/market-index.ts +413 -0
- package/src/host/needs.ts +6 -0
- package/src/host/patch.ts +93 -0
- package/src/host/paths.ts +37 -0
- package/src/host/platform.ts +48 -0
- package/src/host/plugin-source.ts +48 -56
- package/src/host/plugin.ts +39 -0
- package/src/host/port-types.ts +222 -0
- package/src/host/preflight.ts +31 -0
- package/src/host/profile-port.ts +9 -0
- package/src/host/provision.ts +7 -4
- package/src/host/recipe-rules.ts +330 -0
- package/src/host/recipe.test.ts +334 -0
- package/src/host/recipe.ts +323 -0
- package/src/host/shell-text.ts +15 -3
- package/src/host/shell.ts +9 -0
- package/src/host/spec.ts +32 -0
- package/src/host/supply-index.ts +256 -0
- package/src/host/supply-port.ts +45 -0
- package/src/host/time.ts +22 -0
- package/src/host/tokens.ts +186 -0
- package/src/host/tool-kit.ts +1 -1
- package/src/host/unit-face.ts +5 -4
- package/src/host/version-range.ts +71 -0
- package/src/host/version.ts +30 -0
- package/src/host.ts +47 -16
- package/src/i18n/en.ts +224 -71
- package/src/i18n/merge.test.ts +6 -6
- package/src/i18n/merge.ts +1 -1
- package/src/i18n/need-text.ts +27 -0
- package/src/i18n/settings.ts +141 -0
- package/src/i18n/zh.ts +227 -73
- package/src/index.ts +23 -7
- package/src/lib/blocker-action.ts +0 -1
- package/src/{api → lib}/dsh-client.ts +12 -1
- package/src/lib/market-index.ts +36 -0
- package/src/lib/react.ts +0 -40
- package/src/lib/text.test.ts +2 -2
- package/src/lib/ui.test.ts +6 -5
- package/src/lib/ui.ts +3 -9
- package/src/testing/__tests__/declaration.test.ts +1 -1
- package/src/testing/data.ts +66 -0
- package/src/testing/declaration.ts +2 -2
- package/src/testing/host-fakes.ts +0 -38
- package/src/testing/needs.ts +80 -0
- package/src/testing.ts +2 -0
- package/dist/api/unit-declaration.d.ts +0 -65
- package/dist/api/unit.d.ts +0 -85
- package/dist/api/unit.js +0 -8
- package/dist/api/workbench-contract.d.ts +0 -44
- package/dist/components/MockStrip.css +0 -39
- package/dist/components/MockStrip.d.ts +0 -15
- package/dist/components/MockStrip.js +0 -8
- package/dist/components/SaveBar.css +0 -7
- package/dist/host/browser-find.d.ts +0 -38
- package/dist/host/browser-find.js +0 -242
- package/dist/host/browser-read.d.ts +0 -28
- package/dist/host/browser-read.js +0 -243
- package/dist/host/opencli-runtime.d.ts +0 -25
- package/dist/host/opencli-runtime.js +0 -56
- package/dist/host/opencli-window.d.ts +0 -2
- package/dist/host/opencli-window.js +0 -8
- package/dist/host/opencli.d.ts +0 -37
- package/dist/host/opencli.js +0 -155
- package/dist/host/unit-declaration.js +0 -213
- package/dist/host/unit-libs.d.ts +0 -37
- package/dist/lib/diy-debug.d.ts +0 -80
- package/dist/lib/diy-debug.js +0 -88
- package/dist/lib/diy-record.d.ts +0 -135
- package/dist/lib/diy-record.js +0 -162
- package/dist/lib/lint-probe.d.ts +0 -1
- package/dist/lib/lint-probe.js +0 -6
- package/dist/lib/panel-state.d.ts +0 -120
- package/dist/lib/panel-state.js +0 -176
- package/src/api/__tests__/unit.test.ts +0 -38
- package/src/api/unit.ts +0 -93
- package/src/api/workbench-contract.ts +0 -59
- package/src/host/__tests__/browser-find.test.ts +0 -330
- package/src/host/__tests__/browser-read.test.ts +0 -228
- package/src/host/__tests__/opencli-runtime.test.ts +0 -46
- package/src/host/browser-find.ts +0 -311
- package/src/host/browser-read.ts +0 -311
- package/src/host/opencli-runtime.ts +0 -79
- package/src/host/opencli-window.ts +0 -11
- package/src/host/opencli.ts +0 -213
- package/src/host/unit-libs.ts +0 -41
- /package/dist/{api/blocker.js → contract/adapters.js} +0 -0
- /package/dist/{api → contract}/blocker.d.ts +0 -0
- /package/dist/{api/dsh-client.js → contract/blocker.js} +0 -0
- /package/dist/{api/unit-board.js → contract/cli.js} +0 -0
- /package/dist/{api/workbench-contract.js → contract/data.js} +0 -0
- /package/dist/{api → contract}/long-task.d.ts +0 -0
- /package/dist/{api → contract}/long-task.js +0 -0
- /package/dist/{host/unit-libs.js → contract/plugin-source.js} +0 -0
- /package/dist/{api → contract}/unit-board.d.ts +0 -0
- /package/src/{api → contract}/blocker.ts +0 -0
- /package/src/{api → contract}/long-task.ts +0 -0
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SupplySource } from '../contract/needs.js';
|
|
2
|
+
import type { ProvisionProblem } from '../contract/plugin-source.js';
|
|
2
3
|
import { quoteShellArg } from './shell-text.js';
|
|
3
|
-
import { npmCacheDir, toolchainOpencliDir, vendorPeerLink, vendorPrefix } from '
|
|
4
|
+
import { npmCacheDir, toolchainOpencliDir, vendorPeerLink, vendorPrefix } from './paths.js';
|
|
4
5
|
|
|
5
|
-
export type
|
|
6
|
-
| "not-declared"
|
|
7
|
-
| "env-missing"
|
|
8
|
-
| "malformed";
|
|
6
|
+
export type { ProvisionProblem } from '../contract/plugin-source.js';
|
|
9
7
|
|
|
10
8
|
export interface PluginSourceCommand {
|
|
11
9
|
readonly line: string;
|
|
@@ -20,7 +18,7 @@ export type ResolvedPluginSource =
|
|
|
20
18
|
}
|
|
21
19
|
| {
|
|
22
20
|
readonly ok: false;
|
|
23
|
-
readonly problem:
|
|
21
|
+
readonly problem: ProvisionProblem;
|
|
24
22
|
readonly env?: string;
|
|
25
23
|
};
|
|
26
24
|
|
|
@@ -28,15 +26,11 @@ export interface PluginSourceOptions {
|
|
|
28
26
|
readonly command?: string;
|
|
29
27
|
readonly plugin?: string;
|
|
30
28
|
readonly version?: string;
|
|
31
|
-
readonly mode?:
|
|
29
|
+
readonly mode?: 'install' | 'update';
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
function mergeLines(commands: readonly PluginSourceCommand[]): string {
|
|
35
|
-
return commands
|
|
36
|
-
.map((item) =>
|
|
37
|
-
item.optional === true ? `(${item.line} || true)` : item.line,
|
|
38
|
-
)
|
|
39
|
-
.join(" && ");
|
|
33
|
+
return commands.map((item) => (item.optional === true ? `(${item.line} || true)` : item.line)).join(' && ');
|
|
40
34
|
}
|
|
41
35
|
|
|
42
36
|
function envValue(
|
|
@@ -44,21 +38,21 @@ function envValue(
|
|
|
44
38
|
name: string,
|
|
45
39
|
): { readonly ok: true; readonly value: string } | { readonly ok: false } {
|
|
46
40
|
const value = env[name]?.trim();
|
|
47
|
-
return value === undefined || value ===
|
|
48
|
-
? { ok: false }
|
|
49
|
-
: { ok: true, value };
|
|
41
|
+
return value === undefined || value === '' ? { ok: false } : { ok: true, value };
|
|
50
42
|
}
|
|
51
43
|
|
|
52
44
|
export function npmRegistryOf(
|
|
53
|
-
source: { readonly registryEnv
|
|
45
|
+
source: { readonly registryEnv?: string; readonly registryDefault?: string },
|
|
54
46
|
env: Readonly<Record<string, string | undefined>>,
|
|
55
|
-
): { readonly ok: true; readonly value: string } | { readonly ok: false } {
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
47
|
+
): { readonly ok: true; readonly value: string } | { readonly ok: false; readonly env: string } {
|
|
48
|
+
const name = source.registryEnv ?? '';
|
|
49
|
+
if (name !== '') {
|
|
50
|
+
const fromEnv = envValue(env, name);
|
|
51
|
+
if (fromEnv.ok) return fromEnv;
|
|
52
|
+
}
|
|
58
53
|
const fallback = source.registryDefault?.trim();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
: { ok: true, value: fallback };
|
|
54
|
+
if (fallback === undefined || fallback === '') return { ok: false, env: name };
|
|
55
|
+
return { ok: true, value: fallback };
|
|
62
56
|
}
|
|
63
57
|
|
|
64
58
|
function installOne(command: string, spec: string): ResolvedPluginSource {
|
|
@@ -66,28 +60,28 @@ function installOne(command: string, spec: string): ResolvedPluginSource {
|
|
|
66
60
|
return { ok: true, commands: [{ line }], line };
|
|
67
61
|
}
|
|
68
62
|
|
|
63
|
+
function pluginPackageOf(source: SupplySource, plugin: string): string {
|
|
64
|
+
if (source.kind === 'npm') {
|
|
65
|
+
const pkg = source.package?.trim() ?? '';
|
|
66
|
+
if (pkg !== '') return pkg;
|
|
67
|
+
return plugin.trim() === '' ? '' : `opencli-plugin-${plugin.trim()}`;
|
|
68
|
+
}
|
|
69
|
+
if (source.kind === 'git') return source.url.trim();
|
|
70
|
+
return '';
|
|
71
|
+
}
|
|
72
|
+
|
|
69
73
|
function npmSource(
|
|
70
|
-
source: {
|
|
71
|
-
readonly package: string;
|
|
72
|
-
readonly registryEnv: string;
|
|
73
|
-
readonly registryDefault?: string;
|
|
74
|
-
},
|
|
74
|
+
source: SupplySource & { kind: 'npm' },
|
|
75
75
|
env: Readonly<Record<string, string | undefined>>,
|
|
76
76
|
options: PluginSourceOptions,
|
|
77
77
|
): ResolvedPluginSource {
|
|
78
78
|
const registry = npmRegistryOf(source, env);
|
|
79
|
-
if (!registry.ok)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const name = source
|
|
83
|
-
if (name ===
|
|
84
|
-
|
|
85
|
-
const {
|
|
86
|
-
command = "opencli",
|
|
87
|
-
plugin = "",
|
|
88
|
-
version = "latest",
|
|
89
|
-
mode = "install",
|
|
90
|
-
} = options;
|
|
79
|
+
if (!registry.ok) return { ok: false, problem: 'env-missing', env: registry.env };
|
|
80
|
+
|
|
81
|
+
const { command = 'opencli', plugin = '', version = 'latest', mode = 'install' } = options;
|
|
82
|
+
const name = pluginPackageOf(source, plugin);
|
|
83
|
+
if (name === '') return { ok: false, problem: 'malformed' };
|
|
84
|
+
|
|
91
85
|
const prefix = vendorPrefix();
|
|
92
86
|
const dirInPrefix = `${prefix}/node_modules/${name}`;
|
|
93
87
|
const peer = vendorPeerLink();
|
|
@@ -95,20 +89,20 @@ function npmSource(
|
|
|
95
89
|
const commands: PluginSourceCommand[] = [
|
|
96
90
|
{
|
|
97
91
|
line: [
|
|
98
|
-
|
|
92
|
+
'npm i',
|
|
99
93
|
`--prefix ${quoteShellArg(prefix)}`,
|
|
100
94
|
quoteShellArg(`${name}@${version}`),
|
|
101
95
|
`--registry ${quoteShellArg(registry.value)}`,
|
|
102
96
|
`--cache ${quoteShellArg(npmCacheDir())}`,
|
|
103
|
-
].join(
|
|
97
|
+
].join(' '),
|
|
104
98
|
},
|
|
105
99
|
{
|
|
106
100
|
line: `rm -rf ${quoteShellArg(peer.dir)} && mkdir -p ${quoteShellArg(peer.parent)} && ln -s ${quoteShellArg(toolchainOpencliDir())} ${quoteShellArg(peer.dir)}`,
|
|
107
101
|
},
|
|
108
102
|
];
|
|
109
103
|
|
|
110
|
-
if (mode ===
|
|
111
|
-
if (plugin !==
|
|
104
|
+
if (mode === 'install') {
|
|
105
|
+
if (plugin !== '') {
|
|
112
106
|
commands.push({
|
|
113
107
|
line: `${quoteShellArg(command)} plugin uninstall ${quoteShellArg(plugin)}`,
|
|
114
108
|
optional: true,
|
|
@@ -123,23 +117,21 @@ function npmSource(
|
|
|
123
117
|
}
|
|
124
118
|
|
|
125
119
|
export function resolvePluginSource(
|
|
126
|
-
source:
|
|
120
|
+
source: SupplySource | undefined,
|
|
127
121
|
env: Readonly<Record<string, string | undefined>>,
|
|
128
122
|
options: PluginSourceOptions = {},
|
|
129
123
|
): ResolvedPluginSource {
|
|
130
|
-
if (source === undefined) return { ok: false, problem:
|
|
124
|
+
if (source === undefined) return { ok: false, problem: 'not-declared' };
|
|
131
125
|
|
|
132
|
-
const command = options.command ??
|
|
133
|
-
if (source.kind ===
|
|
126
|
+
const command = options.command ?? 'opencli';
|
|
127
|
+
if (source.kind === 'git') {
|
|
134
128
|
const url = source.url.trim();
|
|
135
|
-
return url ===
|
|
136
|
-
? { ok: false, problem: "malformed" }
|
|
137
|
-
: installOne(command, url);
|
|
129
|
+
return url === '' ? { ok: false, problem: 'malformed' } : installOne(command, url);
|
|
138
130
|
}
|
|
139
|
-
if (source.kind ===
|
|
131
|
+
if (source.kind === 'npm') return npmSource(source, env, options);
|
|
140
132
|
|
|
141
|
-
const value = envValue(env, source.env);
|
|
142
|
-
return value.
|
|
143
|
-
|
|
144
|
-
|
|
133
|
+
const value = source.env === undefined ? { ok: false as const } : envValue(env, source.env);
|
|
134
|
+
if (value.ok) return installOne(command, value.value);
|
|
135
|
+
if (source.path !== undefined && source.path.trim() !== '') return installOne(command, source.path.trim());
|
|
136
|
+
return { ok: false, problem: 'env-missing', env: source.env ?? '' };
|
|
145
137
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
export const OPENCLI_MANIFEST_FILE = 'opencli-plugin.json';
|
|
5
|
+
|
|
6
|
+
function asRecord(value: unknown): Readonly<Record<string, unknown>> | undefined {
|
|
7
|
+
return typeof value === 'object' && value !== null ? (value as Readonly<Record<string, unknown>>) : undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function isCommandFile(name: string): boolean {
|
|
11
|
+
if (name.endsWith('.d.ts') || name.endsWith('.test.ts')) return false;
|
|
12
|
+
if (name.endsWith('.d.js')) return false;
|
|
13
|
+
return name.endsWith('.ts') || name.endsWith('.js');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function pluginManifestOf(dir: string): Readonly<Record<string, unknown>> | undefined {
|
|
17
|
+
try {
|
|
18
|
+
const parsed: unknown = JSON.parse(readFileSync(join(dir, OPENCLI_MANIFEST_FILE), 'utf8'));
|
|
19
|
+
if (Array.isArray(parsed)) return undefined;
|
|
20
|
+
return asRecord(parsed);
|
|
21
|
+
} catch {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function hasCommandFile(dir: string): boolean {
|
|
27
|
+
try {
|
|
28
|
+
return readdirSync(dir).some(isCommandFile);
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function pluginAt(dir: string): { readonly name?: string } | undefined {
|
|
35
|
+
const manifest = pluginManifestOf(dir);
|
|
36
|
+
if (manifest === undefined || !hasCommandFile(dir)) return undefined;
|
|
37
|
+
const name = manifest.name;
|
|
38
|
+
return typeof name === 'string' && name.trim() !== '' ? { name: name.trim() } : {};
|
|
39
|
+
}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import type { DshHostContext, DshShell } from '../api/dsh.js';
|
|
2
|
+
import type { LibNeed, SupplySource } from '../contract/needs.js';
|
|
3
|
+
import type { NeedProbeInput, UnitCapability } from '../contract/unit-capability.js';
|
|
4
|
+
import type { WorkbenchSelfUpdate } from '../contract/protocol/bundle-install.js';
|
|
5
|
+
import type {
|
|
6
|
+
BundleManager,
|
|
7
|
+
InstalledModule,
|
|
8
|
+
OpencliResolution,
|
|
9
|
+
ProfileModule,
|
|
10
|
+
ProfilePackage,
|
|
11
|
+
RegistryNotebook,
|
|
12
|
+
SelfUpdateRequest,
|
|
13
|
+
SelfUpdateStart,
|
|
14
|
+
} from './adapter-types.js';
|
|
15
|
+
import type { PostResource, RouteHandler, RouteTable } from './http.js';
|
|
16
|
+
import type { PluginSourceOptions, ResolvedPluginSource } from './plugin-source.js';
|
|
17
|
+
|
|
18
|
+
export interface LoggerLike {
|
|
19
|
+
info?(message: string): void;
|
|
20
|
+
warn?(message: string): void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface ProfilePort {
|
|
24
|
+
dirOf(ctx: DshHostContext): string | null;
|
|
25
|
+
dshPlugins(ctx: DshHostContext): RouteHandler;
|
|
26
|
+
selfUpdateView(root: string, profile: string): WorkbenchSelfUpdate | undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export type SupplyPluginSource = ResolvedPluginSource;
|
|
30
|
+
|
|
31
|
+
export interface SupplyPackageRoute {
|
|
32
|
+
readonly kind: 'opencli-plugin' | 'dsh-bundle' | 'neither';
|
|
33
|
+
readonly pkg?: string;
|
|
34
|
+
readonly pluginName?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SupplyRelease {
|
|
38
|
+
readonly installed?: string;
|
|
39
|
+
readonly latest?: string;
|
|
40
|
+
readonly missing?: readonly string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface SupplyNpmRef {
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly version?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface SupplyPluginInstallOptions {
|
|
49
|
+
readonly spec: string;
|
|
50
|
+
readonly command: string;
|
|
51
|
+
readonly registry?: string | undefined;
|
|
52
|
+
readonly pluginName?: string | undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface SupplyLatestOptions {
|
|
56
|
+
readonly shell: DshShell;
|
|
57
|
+
readonly name: string;
|
|
58
|
+
readonly registry: string;
|
|
59
|
+
readonly force?: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface SupplyMissingPartsOptions {
|
|
63
|
+
readonly shell: DshShell;
|
|
64
|
+
readonly registry: string;
|
|
65
|
+
readonly version: string;
|
|
66
|
+
readonly force?: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface SupplyProbeReleaseOptions {
|
|
70
|
+
readonly shell: DshShell;
|
|
71
|
+
readonly package: string;
|
|
72
|
+
readonly registry?: string | undefined;
|
|
73
|
+
readonly force?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface EnvSupplyPort {
|
|
77
|
+
resolvePluginSource(
|
|
78
|
+
source: SupplySource | undefined,
|
|
79
|
+
env: Readonly<Record<string, string | undefined>>,
|
|
80
|
+
options?: PluginSourceOptions,
|
|
81
|
+
): ResolvedPluginSource;
|
|
82
|
+
libInstallCommand(options: {
|
|
83
|
+
readonly need: LibNeed;
|
|
84
|
+
readonly source: Extract<SupplySource, { kind: 'npm' }>;
|
|
85
|
+
readonly version?: string | undefined;
|
|
86
|
+
}): string;
|
|
87
|
+
pluginInstallPlan(options: SupplyPluginInstallOptions): ResolvedPluginSource;
|
|
88
|
+
latestVersion(options: SupplyLatestOptions): Promise<string | undefined>;
|
|
89
|
+
missingReleaseParts(options: SupplyMissingPartsOptions): Promise<readonly string[]>;
|
|
90
|
+
probeRelease(options: SupplyProbeReleaseOptions): Promise<SupplyRelease | undefined>;
|
|
91
|
+
splitNpmSpec(spec: string): SupplyNpmRef | undefined;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface ModulePort {
|
|
95
|
+
isolatedHome(): string;
|
|
96
|
+
cliCatalogPath(): string;
|
|
97
|
+
vendorPluginsDir(): string;
|
|
98
|
+
opencliInstallCommand(): string;
|
|
99
|
+
profileDirOf(ctx: DshHostContext): string | null;
|
|
100
|
+
profileModules(dir: string | null): readonly ProfileModule[];
|
|
101
|
+
readInstalledModule(dir: string | null, pkg: string): InstalledModule;
|
|
102
|
+
readProfilePackage(dir: string | null, pkg: string): ProfilePackage | undefined;
|
|
103
|
+
readBundleManager(ctx: DshHostContext): BundleManager | undefined;
|
|
104
|
+
createRegistryNotebook(dir: string | null): RegistryNotebook;
|
|
105
|
+
declarationGaps(dir: string | null): readonly { readonly pkg: string }[] | undefined;
|
|
106
|
+
moduleDeclarationOf(dir: string | null, pkg: string): unknown;
|
|
107
|
+
registryDeclarationOf(options: {
|
|
108
|
+
readonly shell: DshShell;
|
|
109
|
+
readonly name: string;
|
|
110
|
+
readonly registry: string;
|
|
111
|
+
readonly force?: boolean;
|
|
112
|
+
}): Promise<unknown>;
|
|
113
|
+
pathDeclarationOf(spec: string): unknown;
|
|
114
|
+
declarationRefusalOf(name: string, raw: unknown): readonly string[];
|
|
115
|
+
refusalReason(): string;
|
|
116
|
+
packageRouteOf(options: {
|
|
117
|
+
readonly spec: string;
|
|
118
|
+
readonly shell?: DshShell | undefined;
|
|
119
|
+
readonly registry?: string | undefined;
|
|
120
|
+
readonly force?: boolean;
|
|
121
|
+
}): Promise<SupplyPackageRoute | undefined>;
|
|
122
|
+
isNewerVersion(left: string, right: string): boolean;
|
|
123
|
+
startSelfUpdate(request: SelfUpdateRequest, onError: (message: string) => void): SelfUpdateStart;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface SupplyPort extends EnvSupplyPort, ModulePort {
|
|
127
|
+
readonly env: EnvSupplyPort;
|
|
128
|
+
readonly modules: ModulePort;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface ProbeUnitsOptions {
|
|
132
|
+
readonly shell: DshShell;
|
|
133
|
+
readonly runtimeCommands: Readonly<Record<string, string>>;
|
|
134
|
+
readonly units: readonly NeedProbeInput[];
|
|
135
|
+
readonly force?: boolean;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface ProbePreflightInput {
|
|
139
|
+
readonly routes: RouteTable;
|
|
140
|
+
readonly ctx: DshHostContext;
|
|
141
|
+
readonly shell: DshShell;
|
|
142
|
+
readonly opencliCommand: string;
|
|
143
|
+
readonly installCommand?: string | undefined;
|
|
144
|
+
readonly warmReads: () => readonly (readonly string[])[];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface ProbePort {
|
|
148
|
+
probeUnits(options: ProbeUnitsOptions): Promise<UnitCapability[]>;
|
|
149
|
+
registerPreflight(input: ProbePreflightInput): void;
|
|
150
|
+
declaredPluginCommands(profileDir: string | null): ReadonlyMap<string, ReadonlySet<string>>;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export interface RuntimeSeedOptions {
|
|
154
|
+
readonly corePackageUrl: string;
|
|
155
|
+
readonly log: (message: string) => void;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface RuntimePort {
|
|
159
|
+
packageRoot(moduleUrl: string): string;
|
|
160
|
+
opencliCommand(ctx: DshHostContext): OpencliResolution;
|
|
161
|
+
seed(ctx: DshHostContext, options: RuntimeSeedOptions): void;
|
|
162
|
+
warnUnwritableRoot(ctx: DshHostContext): void;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export interface PluginDeclarationSource {
|
|
166
|
+
readonly pkg: string;
|
|
167
|
+
readonly declaration: unknown;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export interface PluginRowRef {
|
|
171
|
+
readonly id: string;
|
|
172
|
+
readonly pkg: string;
|
|
173
|
+
readonly name?: string | undefined;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface PluginRowsSource {
|
|
177
|
+
listPlugins(workspace: string | null): readonly PluginRowRef[];
|
|
178
|
+
subscribe?(listener: () => void): () => void;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export interface PluginUnitsPort {
|
|
182
|
+
refresh(options?: { readonly force?: boolean }): Promise<unknown>;
|
|
183
|
+
touch(): void;
|
|
184
|
+
report(): unknown;
|
|
185
|
+
dispose(): void;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export interface PluginUnitsInput {
|
|
189
|
+
readonly registry: { registerPlugin(face: unknown): () => void };
|
|
190
|
+
readonly rows: () => readonly PluginRowRef[];
|
|
191
|
+
readonly declared: (plugin: string) => ReadonlySet<string>;
|
|
192
|
+
readonly toolNames?: () => ReadonlySet<string>;
|
|
193
|
+
readonly logger?: LoggerLike | undefined;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface PluginSurface {
|
|
197
|
+
declarationLookup(profileDir: string | null): (unit: string) => PluginDeclarationSource | undefined;
|
|
198
|
+
createUnits(input: PluginUnitsInput): PluginUnitsPort;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface ConfigSyncInput {
|
|
202
|
+
readonly home: string;
|
|
203
|
+
readonly self: string;
|
|
204
|
+
readonly profileDir: string | null;
|
|
205
|
+
readonly reconcile?: (() => Promise<boolean | void>) | undefined;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export interface ProfileCreateInput {
|
|
209
|
+
readonly home: string;
|
|
210
|
+
readonly self: string;
|
|
211
|
+
readonly packageRoot: string;
|
|
212
|
+
readonly runSetup?:
|
|
213
|
+
| ((env: Readonly<Record<string, string>>) => Promise<{ ok: boolean; log: string }>)
|
|
214
|
+
| undefined;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface HostActions {
|
|
218
|
+
configSyncHandler(input: ConfigSyncInput): RouteHandler;
|
|
219
|
+
profileCreateHandler(input: ProfileCreateInput): RouteHandler;
|
|
220
|
+
configSyncAction(input: ConfigSyncInput): PostResource;
|
|
221
|
+
profileCreateAction(input: ProfileCreateInput): PostResource;
|
|
222
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type PreflightStepId = 'toolchain' | 'opencli' | 'bridge' | 'diy' | 'warm';
|
|
2
|
+
export type PreflightStepStatus = 'pending' | 'running' | 'ok' | 'warn' | 'failed';
|
|
3
|
+
export type PreflightFailure = 'permission' | 'network' | 'missing' | 'unknown';
|
|
4
|
+
export type PreflightGuidance = 'install' | 'path' | 'shell';
|
|
5
|
+
export type PreflightBridgeIssue = 'daemon' | 'extension' | 'profile' | 'stale' | 'unknown';
|
|
6
|
+
|
|
7
|
+
export interface PreflightStep {
|
|
8
|
+
readonly id: PreflightStepId;
|
|
9
|
+
readonly status: PreflightStepStatus;
|
|
10
|
+
readonly detail?: string;
|
|
11
|
+
readonly action?: string;
|
|
12
|
+
readonly command?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface PreflightDiyGap {
|
|
16
|
+
readonly rows: readonly string[];
|
|
17
|
+
readonly detail: string;
|
|
18
|
+
readonly command: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface PreflightSnapshot {
|
|
22
|
+
readonly phase: 'idle' | 'checking' | 'installing' | 'ready' | 'failed';
|
|
23
|
+
readonly steps: readonly PreflightStep[];
|
|
24
|
+
readonly at: number;
|
|
25
|
+
readonly error?: string;
|
|
26
|
+
readonly failure?: PreflightFailure;
|
|
27
|
+
readonly guidance?: PreflightGuidance;
|
|
28
|
+
readonly bridgeIssues?: readonly PreflightBridgeIssue[];
|
|
29
|
+
readonly diyGap?: PreflightDiyGap;
|
|
30
|
+
readonly canWakeBrowser?: boolean;
|
|
31
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DshHostContext } from '../api/dsh.js';
|
|
2
|
+
import { adaptersOf } from './adapters.js';
|
|
3
|
+
import type { ProfilePort } from './port-types.js';
|
|
4
|
+
export type { ProfilePort } from './port-types.js';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export function profilePortOf(ctx: DshHostContext): ProfilePort {
|
|
8
|
+
return adaptersOf(ctx).profile;
|
|
9
|
+
}
|
package/src/host/provision.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ProvisionAction } from '../
|
|
1
|
+
import type { ProvisionAction } from '../contract/workbench-contract.js';
|
|
2
2
|
|
|
3
3
|
export type { ProvisionAction };
|
|
4
4
|
|
|
@@ -7,6 +7,7 @@ export const PROVISION_ACTIONS = [
|
|
|
7
7
|
'update',
|
|
8
8
|
'uninstall',
|
|
9
9
|
'install-bundle',
|
|
10
|
+
'install-version',
|
|
10
11
|
'update-bundle',
|
|
11
12
|
'remove-bundle',
|
|
12
13
|
'cancel-install',
|
|
@@ -33,7 +34,7 @@ export type ProvisionTarget = 'unit' | 'id' | 'spec' | 'name' | 'requestId';
|
|
|
33
34
|
|
|
34
35
|
export function provisionTargetOf(action: ProvisionAction): ProvisionTarget {
|
|
35
36
|
if (action === 'update-dependency') return 'id';
|
|
36
|
-
if (action === 'install-bundle') return 'spec';
|
|
37
|
+
if (action === 'install-bundle' || action === 'install-version') return 'spec';
|
|
37
38
|
if (action === 'remove-bundle') return 'name';
|
|
38
39
|
if (action === 'update-plugin' || action === 'uninstall-plugin') return 'name';
|
|
39
40
|
if (action === 'update-workbench') return 'name';
|
|
@@ -77,7 +78,7 @@ function stringsOf(value: unknown): string[] | undefined {
|
|
|
77
78
|
|
|
78
79
|
function requestOf(action: ProvisionAction, value: string): ProvisionRequest {
|
|
79
80
|
if (action === 'update-dependency') return { action, id: value };
|
|
80
|
-
if (action === 'install-bundle') return { action, spec: value };
|
|
81
|
+
if (action === 'install-bundle' || action === 'install-version') return { action, spec: value };
|
|
81
82
|
if (action === 'remove-bundle') return { action, name: value };
|
|
82
83
|
if (action === 'update-plugin' || action === 'uninstall-plugin') return { action, name: value };
|
|
83
84
|
if (action === 'update-workbench') return { action, name: value };
|
|
@@ -111,7 +112,9 @@ export function parseProvisionBody(body: unknown): ProvisionParsed {
|
|
|
111
112
|
if (typeof value !== 'string' || value.trim() === '') {
|
|
112
113
|
return { ok: false, code: TARGET_CODE[target], message: `缺少 ${target}` };
|
|
113
114
|
}
|
|
114
|
-
if (wanted !== 'install-bundle'
|
|
115
|
+
if (wanted !== 'install-bundle' && wanted !== 'install-version') {
|
|
116
|
+
return { ok: true, request: requestOf(wanted, value.trim()) };
|
|
117
|
+
}
|
|
115
118
|
|
|
116
119
|
const registry = typeof raw.registry === 'string' && raw.registry.trim() !== '' ? raw.registry.trim() : undefined;
|
|
117
120
|
const approvedBuilds = stringsOf(raw.approvedBuilds);
|