@microsoft/windows-admin-center-sdk 6.0.0 → 6.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/3rdPartyDisclosure.html +10 -13
- package/README.md +110 -33
- package/angular/fesm2022/msft-sme-angular.mjs +1235 -1213
- package/angular/fesm2022/msft-sme-angular.mjs.map +1 -1
- package/angular/index.d.ts +29 -14
- package/angular/package.json +1 -1
- package/core/azure/azure-manager.d.ts +15 -3
- package/core/azure/azure-manager.d.ts.map +1 -1
- package/core/azure/azure-manager.js +29 -10
- package/core/azure/azure-manager.js.map +1 -1
- package/core/azure/models/aadAppConfig-data.d.ts +16 -0
- package/core/azure/models/aadAppConfig-data.d.ts.map +1 -1
- package/core/azure/models/aadAppConfig-data.js.map +1 -1
- package/core/base/environment.d.ts +1 -1
- package/core/base/environment.d.ts.map +1 -1
- package/core/base/environment.js.map +1 -1
- package/core/base/utilities.d.ts +10 -2
- package/core/base/utilities.d.ts.map +1 -1
- package/core/base/utilities.js +45 -25
- package/core/base/utilities.js.map +1 -1
- package/core/data/gateway-connection.d.ts.map +1 -1
- package/core/data/gateway-connection.js +1 -0
- package/core/data/gateway-connection.js.map +1 -1
- package/core/diagnostics/sme-web-telemetry.d.ts +17 -1
- package/core/diagnostics/sme-web-telemetry.d.ts.map +1 -1
- package/core/diagnostics/sme-web-telemetry.js +16 -0
- package/core/diagnostics/sme-web-telemetry.js.map +1 -1
- package/core/enterprise/enterprise-models.d.ts +10 -4
- package/core/enterprise/enterprise-models.d.ts.map +1 -1
- package/core/enterprise/enterprise-models.js +9 -4
- package/core/enterprise/enterprise-models.js.map +1 -1
- package/core/index.d.ts +5 -3
- package/core/index.d.ts.map +1 -1
- package/core/index.js +2 -1
- package/core/index.js.map +1 -1
- package/core/manifest/environment-modules.d.ts +2 -2
- package/core/manifest/environment-modules.d.ts.map +1 -1
- package/core/manifest/environment-modules.js.map +1 -1
- package/core/manifest/gateway-url-validator.d.ts +17 -0
- package/core/manifest/gateway-url-validator.d.ts.map +1 -0
- package/core/manifest/gateway-url-validator.js +56 -0
- package/core/manifest/gateway-url-validator.js.map +1 -0
- package/core/manifest/manifest-loader.d.ts +47 -11
- package/core/manifest/manifest-loader.d.ts.map +1 -1
- package/core/manifest/manifest-loader.js +141 -72
- package/core/manifest/manifest-loader.js.map +1 -1
- package/core/manifest/module-schema.json +1 -1
- package/core/performance/performance-tracker.d.ts +2 -0
- package/core/performance/performance-tracker.d.ts.map +1 -1
- package/core/performance/performance-tracker.js +18 -0
- package/core/performance/performance-tracker.js.map +1 -1
- package/core/rpc/azure/rpc-azure-model.d.ts +19 -1
- package/core/rpc/azure/rpc-azure-model.d.ts.map +1 -1
- package/core/rpc/azure/rpc-azure-model.js.map +1 -1
- package/core/rpc/forward/rpc-forward-auto-client.d.ts +5 -0
- package/core/rpc/forward/rpc-forward-auto-client.d.ts.map +1 -1
- package/core/rpc/forward/rpc-forward-auto-client.js +13 -0
- package/core/rpc/forward/rpc-forward-auto-client.js.map +1 -1
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-client.d.ts +16 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-client.d.ts.map +1 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-client.js +18 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-client.js.map +1 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-handler.d.ts +8 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-handler.d.ts.map +1 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-handler.js +2 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-handler.js.map +1 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-model.d.ts +18 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-model.d.ts.map +1 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-model.js +8 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-model.js.map +1 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-subject-server.d.ts +27 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-subject-server.d.ts.map +1 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-subject-server.js +23 -0
- package/core/rpc/resource-data-changed/rpc-resource-data-changed-subject-server.js.map +1 -0
- package/core/rpc/rpc-forwarder.d.ts +16 -2
- package/core/rpc/rpc-forwarder.d.ts.map +1 -1
- package/core/rpc/rpc-forwarder.js +50 -6
- package/core/rpc/rpc-forwarder.js.map +1 -1
- package/core/security/authorization-manager.d.ts +126 -4
- package/core/security/authorization-manager.d.ts.map +1 -1
- package/core/security/authorization-manager.js +381 -49
- package/core/security/authorization-manager.js.map +1 -1
- package/core/security/connection-manager.d.ts +2 -1
- package/core/security/connection-manager.d.ts.map +1 -1
- package/core/security/connection-manager.js +10 -6
- package/core/security/connection-manager.js.map +1 -1
- package/core/security/tool-condition-validator.d.ts +8 -3
- package/core/security/tool-condition-validator.d.ts.map +1 -1
- package/core/security/tool-condition-validator.js +43 -28
- package/core/security/tool-condition-validator.js.map +1 -1
- package/core/version.js +1 -1
- package/core/version.js.map +1 -1
- package/core/virtualization/virtualization-client.d.ts +47 -78
- package/core/virtualization/virtualization-client.d.ts.map +1 -1
- package/core/virtualization/virtualization-client.js +57 -77
- package/core/virtualization/virtualization-client.js.map +1 -1
- package/core/virtualization/virtualization-models.d.ts +9 -8
- package/core/virtualization/virtualization-models.d.ts.map +1 -1
- package/core/virtualization/virtualization-models.js +7 -5
- package/core/virtualization/virtualization-models.js.map +1 -1
- package/core/virtualization/virtualization-unavailable-error.d.ts +1 -1
- package/core/virtualization/virtualization-unavailable-error.js +1 -1
- package/core/virtualization/virtualization-unavailable-error.js.map +1 -1
- package/package.json +12 -17
- package/{react-sdk-core → react}/hooks/useAppContextInit.d.ts +2 -0
- package/react/hooks/useAppContextInit.d.ts.map +1 -0
- package/{react-sdk-core → react}/hooks/useAppContextInit.js +18 -2
- package/{react-sdk-core → react}/index.js +1 -1
- package/react/services/BaseNavigationService.d.ts.map +1 -0
- package/{react-sdk-core → react}/services/BaseNavigationService.js +4 -0
- package/{react-sdk-core → react}/version.d.ts.map +1 -1
- package/react/version.js +3 -0
- package/{react-sdk-core → react}/vite/smeCoreStringsPlugin.d.ts +1 -1
- package/{react-sdk-core → react}/vite/smeCoreStringsPlugin.js +1 -1
- package/{react-sdk-core → react}/vite/smeManifestResourcesPlugin.d.ts +1 -1
- package/{react-sdk-core → react}/vite/smeManifestResourcesPlugin.js +1 -1
- package/{react-sdk-core → react}/vite/smePowerShellPlugin.d.ts +1 -1
- package/{react-sdk-core → react}/vite/smePowerShellPlugin.js +1 -1
- package/styles/css/main-v2.css +1 -1
- package/styles/package.json +1 -1
- package/wac-cli/dist/angular20/configs/ci-build-yml-config.js +3 -2
- package/wac-cli/dist/angular20/configs/ci-build-yml-config.js.map +1 -1
- package/wac-cli/dist/angular20/upgrader/nvmrc-engines-upgrader.js +2 -2
- package/wac-cli/dist/create-react/main.js +3 -2
- package/wac-cli/dist/create-react/main.js.map +1 -1
- package/wac-cli/module-template/build/pipelines/ci-build.yml +2 -2
- package/wac-cli/module-template/build/pipelines/pull-request.yml +2 -2
- package/wac-cli/templates/internal/main.ts +2 -2
- package/wac-cli/templates/internal/package.json +26 -14
- package/wac-cli/templates/react-template/package.json +3 -2
- package/wac-cli/templates/react-template/src/App.tsx +1 -1
- package/wac-cli/templates/react-template/src/hooks/useServicesData.ts +1 -1
- package/wac-cli/templates/react-template/vite.config.ts +1 -1
- package/wac-cli/templates/wac-template/angular.json +8 -13
- package/wac-cli/templates/wac-template/package.json +26 -14
- package/wac-cli/templates/wac-template/src/main.ts +2 -2
- package/react-sdk-core/hooks/useAppContextInit.d.ts.map +0 -1
- package/react-sdk-core/services/BaseNavigationService.d.ts.map +0 -1
- package/react-sdk-core/version.js +0 -3
- /package/{react-sdk-core → react}/components/SplashScreen.d.ts +0 -0
- /package/{react-sdk-core → react}/components/SplashScreen.d.ts.map +0 -0
- /package/{react-sdk-core → react}/components/SplashScreen.js +0 -0
- /package/{react-sdk-core → react}/context/AppContextProvider.d.ts +0 -0
- /package/{react-sdk-core → react}/context/AppContextProvider.d.ts.map +0 -0
- /package/{react-sdk-core → react}/context/AppContextProvider.js +0 -0
- /package/{react-sdk-core → react}/hooks/useAppContext.d.ts +0 -0
- /package/{react-sdk-core → react}/hooks/useAppContext.d.ts.map +0 -0
- /package/{react-sdk-core → react}/hooks/useAppContext.js +0 -0
- /package/{react-sdk-core → react}/hooks/useSkeletonStyles.d.ts +0 -0
- /package/{react-sdk-core → react}/hooks/useSkeletonStyles.d.ts.map +0 -0
- /package/{react-sdk-core → react}/hooks/useSkeletonStyles.js +0 -0
- /package/{react-sdk-core → react}/hooks/useWacTheme.d.ts +0 -0
- /package/{react-sdk-core → react}/hooks/useWacTheme.d.ts.map +0 -0
- /package/{react-sdk-core → react}/hooks/useWacTheme.js +0 -0
- /package/{react-sdk-core → react}/index.d.ts +0 -0
- /package/{react-sdk-core → react}/index.d.ts.map +0 -0
- /package/{react-sdk-core → react}/services/AppContextService.d.ts +0 -0
- /package/{react-sdk-core → react}/services/AppContextService.d.ts.map +0 -0
- /package/{react-sdk-core → react}/services/AppContextService.js +0 -0
- /package/{react-sdk-core → react}/services/BaseNavigationService.d.ts +0 -0
- /package/{react-sdk-core → react}/services/NavigationService.d.ts +0 -0
- /package/{react-sdk-core → react}/services/NavigationService.d.ts.map +0 -0
- /package/{react-sdk-core → react}/services/NavigationService.js +0 -0
- /package/{react-sdk-core → react}/services/Polyfills.d.ts +0 -0
- /package/{react-sdk-core → react}/services/Polyfills.d.ts.map +0 -0
- /package/{react-sdk-core → react}/services/Polyfills.js +0 -0
- /package/{react-sdk-core → react}/version.d.ts +0 -0
- /package/{react-sdk-core → react}/vite/index.d.ts +0 -0
- /package/{react-sdk-core → react}/vite/index.d.ts.map +0 -0
- /package/{react-sdk-core → react}/vite/index.js +0 -0
- /package/{react-sdk-core → react}/vite/log.d.ts +0 -0
- /package/{react-sdk-core → react}/vite/log.d.ts.map +0 -0
- /package/{react-sdk-core → react}/vite/log.js +0 -0
- /package/{react-sdk-core → react}/vite/smeCoreStringsPlugin.d.ts.map +0 -0
- /package/{react-sdk-core → react}/vite/smeManifestResourcesPlugin.d.ts.map +0 -0
- /package/{react-sdk-core → react}/vite/smePowerShellPlugin.d.ts.map +0 -0
|
@@ -6,35 +6,39 @@ import { VirtualizationUnavailableError } from './virtualization-unavailable-err
|
|
|
6
6
|
const HTTP_BAD_REQUEST = 400;
|
|
7
7
|
const HTTP_NOT_FOUND = 404;
|
|
8
8
|
/**
|
|
9
|
-
* Typed, discoverable SDK client for
|
|
9
|
+
* Typed, discoverable SDK client for vMode inventory APIs.
|
|
10
10
|
*
|
|
11
|
-
* `VirtualizationClient` gives extension authors
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* against an internal, undocumented surface. It works in both Angular and React extensions; React
|
|
15
|
-
* consumers can use the `useEnterpriseData()` hook in `@msft-sme/react-sdk`.
|
|
11
|
+
* `VirtualizationClient` gives extension authors a single importable entry point with typed methods
|
|
12
|
+
* and IntelliSense for the vMode virtualization database, instead of hand-writing
|
|
13
|
+
* `gateway.get('services/enterprisedata/data/...')` calls against an internal, undocumented surface.
|
|
16
14
|
*
|
|
17
|
-
* ##
|
|
15
|
+
* ## Detecting vMode and gating data calls
|
|
16
|
+
*
|
|
17
|
+
* Construction is **inert** (no network calls), so importing and instantiating the client is always
|
|
18
|
+
* safe. Two checks cover the common needs, and neither throws:
|
|
18
19
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* - {@link isActive} — a synchronous, local read of whether the user is currently in vMode. Use it
|
|
21
|
+
* for lightweight UI decisions such as showing or hiding vMode-only content.
|
|
22
|
+
* - {@link whenActive} — runs an operation (typically a data call) only when vMode is active **and**
|
|
23
|
+
* the vMode database is installed, otherwise runs a fallback. Use it when accessing vMode data.
|
|
24
|
+
* - {@link getCapabilities} — combines the result from isActive with a gateway probe to determine
|
|
25
|
+
* whether the vMode database is present and usable, along with the agent version if available. This
|
|
26
|
+
* is the least likely use case, but is available for scenarios where more data is needed.
|
|
23
27
|
*
|
|
24
28
|
* ```ts
|
|
25
|
-
* const vc = new VirtualizationClient(appContext);
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* const hosts = await firstValueFrom(vc.getHosts());
|
|
29
|
-
* } else {
|
|
30
|
-
* // platform has no vMode database — fall back to legacy behavior, no crash
|
|
29
|
+
* const vc = new VirtualizationClient(appContext); // inert, no network
|
|
30
|
+
* if (vc.isActive()) {
|
|
31
|
+
* // show vMode-only UI
|
|
31
32
|
* }
|
|
33
|
+
* const hosts = await firstValueFrom(vc.whenActive(() => vc.getHosts(), () => of([])));
|
|
32
34
|
* ```
|
|
33
35
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
36
|
+
* ## Compatibility
|
|
37
|
+
*
|
|
38
|
+
* This will work whether vMode is installed or not. The data methods ({@link getHosts}, etc.) reject
|
|
39
|
+
* with a {@link VirtualizationUnavailableError} when the database is absent (a backstop for callers
|
|
40
|
+
* that do not gate with {@link whenActive}), or a {@link VirtualizationResourceNotFoundError} when the
|
|
41
|
+
* database is installed but the requested resource does not exist.
|
|
38
42
|
*/
|
|
39
43
|
export class VirtualizationClient {
|
|
40
44
|
gateway;
|
|
@@ -47,49 +51,42 @@ export class VirtualizationClient {
|
|
|
47
51
|
* successful probe and cached alongside {@link databaseInstalled}; stays `undefined` when not reported.
|
|
48
52
|
*/
|
|
49
53
|
agentVersion;
|
|
50
|
-
/**
|
|
51
|
-
* Resolves whether the user is currently in vMode. Defaults to {@link readVirtualizationModeActive}
|
|
52
|
-
* (the ambient `MsftSme` read); overridable via {@link VirtualizationClientOptions} so consumers
|
|
53
|
-
* can fake vMode-active state in tests without touching the global.
|
|
54
|
-
*/
|
|
55
|
-
isVirtualizationModeActive;
|
|
56
54
|
/**
|
|
57
55
|
* Creates a virtualization client. This does **not** make any network calls.
|
|
58
56
|
* @param appContext The app context (or any object exposing a `gateway`) to issue requests on.
|
|
59
|
-
* @param options Optional overrides (see {@link VirtualizationClientOptions}); all default to the
|
|
60
|
-
* production behavior.
|
|
61
57
|
*/
|
|
62
|
-
constructor(appContext
|
|
58
|
+
constructor(appContext) {
|
|
63
59
|
this.gateway = appContext.gateway;
|
|
64
|
-
this.isVirtualizationModeActive = options?.isVirtualizationModeActive ?? (() => this.readVirtualizationModeActive());
|
|
65
60
|
}
|
|
66
61
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
62
|
+
* Returns whether the user is using WAC in vMode rather than standard (aMode). This is a
|
|
63
|
+
* synchronous read of the shell's environment mode with no network call; use it for UI
|
|
64
|
+
* decisions such as showing or hiding vMode-only content.
|
|
70
65
|
*
|
|
71
|
-
*
|
|
72
|
-
* immutable for the lifetime of the gateway install, so they are probed at most once. `active` is read
|
|
73
|
-
* **fresh on every subscription**, because the user can switch between standard mode and vMode at any time.
|
|
74
|
-
* @returns An observable of {@link VirtualizationCapabilities}.
|
|
66
|
+
* @returns `true` when the user is in vMode; otherwise `false`.
|
|
75
67
|
*/
|
|
76
|
-
|
|
77
|
-
return this.isDatabaseInstalled().pipe(map(available => ({ available, active: this.resolveActive(), agentVersion: this.agentVersion })));
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Safely resolves the current vMode-active state via {@link isVirtualizationModeActive}. The default
|
|
81
|
-
* reader ({@link readVirtualizationModeActive}) already never throws, but a consumer-supplied override
|
|
82
|
-
* might, so this backstop catches any error and reports `false` (standard) to preserve the
|
|
83
|
-
* never-throws contract of {@link getCapabilities}.
|
|
84
|
-
*/
|
|
85
|
-
resolveActive() {
|
|
68
|
+
isActive() {
|
|
86
69
|
try {
|
|
87
|
-
|
|
70
|
+
// Legacy gateways do not report an environment mode, so assume standard.
|
|
71
|
+
const mode = MsftSme.getValue(MsftSme.self().Environment.configuration, 'environmentMode') ?? 'standard';
|
|
72
|
+
return mode === 'virtualization';
|
|
88
73
|
}
|
|
89
74
|
catch {
|
|
90
75
|
return false;
|
|
91
76
|
}
|
|
92
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Reports whether the vMode database is installed (`available`, probed once and cached with
|
|
80
|
+
* `agentVersion`) and whether the user is in vMode (`active`, from {@link isActive} on each
|
|
81
|
+
* subscription). Never throws; on any error `available` is `false`.
|
|
82
|
+
*
|
|
83
|
+
* Most callers should use {@link isActive} for UI decisions and {@link whenActive} to gate data
|
|
84
|
+
* calls. Use this method only when you need the individual flags.
|
|
85
|
+
* @returns An observable of {@link VirtualizationCapabilities}.
|
|
86
|
+
*/
|
|
87
|
+
getCapabilities() {
|
|
88
|
+
return this.isDatabaseInstalled().pipe(map(available => ({ available, active: this.isActive(), agentVersion: this.agentVersion })));
|
|
89
|
+
}
|
|
93
90
|
/**
|
|
94
91
|
* Resolves whether the vMode database is installed on this platform, caching the result for the
|
|
95
92
|
* lifetime of the client. The install state is **immutable** for the lifetime of the gateway
|
|
@@ -130,25 +127,25 @@ export class VirtualizationClient {
|
|
|
130
127
|
}));
|
|
131
128
|
}
|
|
132
129
|
/**
|
|
133
|
-
* Runs `operation`
|
|
134
|
-
* `fallback
|
|
135
|
-
* back to their existing (e.g. aMode) path when vMode is not in use.
|
|
130
|
+
* Runs `operation` when the user is in vMode and the vMode database is installed; otherwise runs
|
|
131
|
+
* `fallback` (e.g. the existing aMode path). Use it to gate calls to the data methods.
|
|
136
132
|
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* is the meaningful condition. See {@link getCapabilities}.
|
|
133
|
+
* The check runs on subscription and never errors; errors from `operation` or `fallback` propagate.
|
|
134
|
+
* When the user is not in vMode it takes the fallback with no network call; otherwise it consults
|
|
135
|
+
* the cached database-install probe.
|
|
141
136
|
*
|
|
142
137
|
* ```ts
|
|
143
138
|
* const hosts$ = vc.whenActive(() => vc.getHosts(), () => of([]));
|
|
144
139
|
* ```
|
|
145
140
|
*
|
|
146
|
-
* @param operation Factory invoked only when vMode is active.
|
|
147
|
-
* @param fallback Factory invoked
|
|
148
|
-
*
|
|
141
|
+
* @param operation Factory invoked only when vMode is active and the database is installed.
|
|
142
|
+
* @param fallback Factory invoked otherwise. It is a factory (not a bare observable) so its work —
|
|
143
|
+
* and any side effects — only happen when the fallback is taken.
|
|
149
144
|
*/
|
|
150
145
|
whenActive(operation, fallback) {
|
|
151
|
-
return
|
|
146
|
+
return defer(() => this.isActive()
|
|
147
|
+
? this.isDatabaseInstalled().pipe(take(1), mergeMap(available => (available ? operation() : fallback())))
|
|
148
|
+
: fallback());
|
|
152
149
|
}
|
|
153
150
|
// The per-type list/get methods below (getHosts/getClusters/… and getHost/getCluster/…) are thin,
|
|
154
151
|
// deliberately hardcoded wrappers over the generic `list`/`getResource` helpers. This is an
|
|
@@ -251,23 +248,6 @@ export class VirtualizationClient {
|
|
|
251
248
|
list(type) {
|
|
252
249
|
return this.requestData(() => this.gateway.get(`${ENTERPRISE_DATA_BASE_PATH}/${type}`).pipe(take(1), map((response) => response?.data ?? [])), false);
|
|
253
250
|
}
|
|
254
|
-
/**
|
|
255
|
-
* The default reader for {@link isVirtualizationModeActive}: reads whether the user is currently
|
|
256
|
-
* in the virtualization experience (vMode) vs standard mode from the ambient `MsftSme` environment
|
|
257
|
-
* configuration. Synchronous local read; defaults to `false` (standard) and never throws. Consumers
|
|
258
|
-
* that need to fake this in tests should pass {@link VirtualizationClientOptions.isVirtualizationModeActive}
|
|
259
|
-
* rather than overriding this method.
|
|
260
|
-
*/
|
|
261
|
-
readVirtualizationModeActive() {
|
|
262
|
-
try {
|
|
263
|
-
// Read the environment mode from the current environment configuration. Legacy gateways return undefined, so assume standard.
|
|
264
|
-
const mode = MsftSme.getValue(MsftSme.self().Environment.configuration, 'environmentMode') ?? 'standard';
|
|
265
|
-
return mode === 'virtualization';
|
|
266
|
-
}
|
|
267
|
-
catch {
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
251
|
/**
|
|
272
252
|
* Runs a data request, ensuring the (cached) database-install probe has resolved first so that
|
|
273
253
|
* {@link toDataError} can distinguish "the vMode database is absent" from "the requested resource
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualization-client.js","sourceRoot":"","sources":["../../src/virtualization/virtualization-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { defer, Observable, of, throwError } from 'rxjs';\r\nimport { catchError, map, mergeMap, take } from 'rxjs/operators';\r\nimport { AppContext } from '../data/app-context';\r\nimport { GatewayConnection } from '../data/gateway-connection';\r\nimport { ChildObjectDataResource, ENTERPRISE_DATA_BASE_PATH, ENTERPRISE_STATUS_PROBE_PATH, EnterpriseObjectTypes, TypedResource } from '../enterprise/enterprise-models';\r\nimport { EnvironmentMode } from '../manifest/environment-modules';\r\nimport {\r\n VirtualizationCapabilities,\r\n VirtualizationCluster,\r\n VirtualizationHost,\r\n VirtualizationHostChild,\r\n VirtualizationListResponse,\r\n VirtualizationResourceGroup,\r\n VirtualizationVm,\r\n VirtualizationVmChild\r\n} from './virtualization-models';\r\nimport { VirtualizationResourceNotFoundError } from './virtualization-resource-not-found-error';\r\nimport { VirtualizationUnavailableError } from './virtualization-unavailable-error';\r\n\r\nconst HTTP_BAD_REQUEST = 400;\r\nconst HTTP_NOT_FOUND = 404;\r\n\r\n/**\r\n * The minimal subset of an app context required by {@link VirtualizationClient}: anything\r\n * exposing a {@link GatewayConnection}. Both the Angular `AppContextService` and the React\r\n * app-context satisfy this, so the client works in either framework.\r\n */\r\nexport interface VirtualizationClientHost {\r\n gateway: GatewayConnection;\r\n}\r\n\r\n/**\r\n * Optional overrides for {@link VirtualizationClient}. All options are additive and default to the\r\n * production behavior, so `new VirtualizationClient(appContext)` continues to work unchanged.\r\n */\r\nexport interface VirtualizationClientOptions {\r\n /**\r\n * Overrides how the client determines whether the user is currently in the virtualization\r\n * experience (vMode) rather than standard mode. By default the client reads the ambient\r\n * `MsftSme` environment configuration — an un-Angular global that is awkward to fake in a\r\n * `TestBed`. Provide this seam to control vMode-active state in tests (e.g. `() => true`) or to\r\n * source it from an Angular-injected service, without monkey-patching the global.\r\n *\r\n * Must be synchronous and never throw; the default reader defaults to `false` (standard mode)\r\n * on any error.\r\n */\r\n isVirtualizationModeActive?: () => boolean;\r\n}\r\n\r\n/**\r\n * Typed, discoverable SDK client for the Windows Admin Center virtualization (vMode) inventory APIs.\r\n *\r\n * `VirtualizationClient` gives extension authors (e.g. Hyper-V, SDN) a single importable\r\n * entry point with typed methods and IntelliSense for the Gateway V2 virtualization database,\r\n * instead of hand-writing stringly-typed `gateway.get('services/enterprisedata/data/...')` calls\r\n * against an internal, undocumented surface. It works in both Angular and React extensions; React\r\n * consumers can use the `useEnterpriseData()` hook in `@msft-sme/react-sdk`.\r\n *\r\n * ## Compatibility\r\n *\r\n * Extensions upgrade and downgrade independently of the gateway platform, so this client may run\r\n * where the vMode database does not exist. Construction is **inert** (no network calls), so simply\r\n * importing and instantiating it is always safe. Use {@link getCapabilities} (which never throws)\r\n * to detect availability before calling the data methods:\r\n *\r\n * ```ts\r\n * const vc = new VirtualizationClient(appContext); // inert, no network\r\n * const caps = await firstValueFrom(vc.getCapabilities()); // safe probe, never throws\r\n * if (caps.available) {\r\n * const hosts = await firstValueFrom(vc.getHosts());\r\n * } else {\r\n * // platform has no vMode database — fall back to legacy behavior, no crash\r\n * }\r\n * ```\r\n *\r\n * The data methods ({@link getHosts}, etc.) reject with a {@link VirtualizationUnavailableError}\r\n * when the database is absent (a backstop for callers that do not gate on {@link getCapabilities}),\r\n * or a {@link VirtualizationResourceNotFoundError} when the database is installed but the requested\r\n * resource does not exist.\r\n */\r\nexport class VirtualizationClient {\r\n private readonly gateway: GatewayConnection;\r\n /**\r\n * Cached result of the database-install probe (the `available` capability).\r\n */\r\n private databaseInstalled?: boolean;\r\n /**\r\n * Cached enterprise/vMode agent build version, sourced from the probe's `agentVersion`. Set only on a\r\n * successful probe and cached alongside {@link databaseInstalled}; stays `undefined` when not reported.\r\n */\r\n private agentVersion?: string;\r\n\r\n /**\r\n * Resolves whether the user is currently in vMode. Defaults to {@link readVirtualizationModeActive}\r\n * (the ambient `MsftSme` read); overridable via {@link VirtualizationClientOptions} so consumers\r\n * can fake vMode-active state in tests without touching the global.\r\n */\r\n private readonly isVirtualizationModeActive: () => boolean;\r\n\r\n /**\r\n * Creates a virtualization client. This does **not** make any network calls.\r\n * @param appContext The app context (or any object exposing a `gateway`) to issue requests on.\r\n * @param options Optional overrides (see {@link VirtualizationClientOptions}); all default to the\r\n * production behavior.\r\n */\r\n constructor(appContext: AppContext | VirtualizationClientHost, options?: VirtualizationClientOptions) {\r\n this.gateway = appContext.gateway;\r\n this.isVirtualizationModeActive = options?.isVirtualizationModeActive ?? (() => this.readVirtualizationModeActive());\r\n }\r\n\r\n /**\r\n * Detects whether the virtualization (vMode) experience is supported by the current platform and\r\n * whether the user is currently using it. **Never throws** — on any error (older platform, not\r\n * enterprise mode, network failure) it resolves to `{ available: false, active: ... }`.\r\n *\r\n * Only `available` (whether the vMode database is installed) and `agentVersion` are cached — they are\r\n * immutable for the lifetime of the gateway install, so they are probed at most once. `active` is read\r\n * **fresh on every subscription**, because the user can switch between standard mode and vMode at any time.\r\n * @returns An observable of {@link VirtualizationCapabilities}.\r\n */\r\n public getCapabilities(): Observable<VirtualizationCapabilities> {\r\n return this.isDatabaseInstalled().pipe(map(available => ({ available, active: this.resolveActive(), agentVersion: this.agentVersion }) as VirtualizationCapabilities));\r\n }\r\n\r\n /**\r\n * Safely resolves the current vMode-active state via {@link isVirtualizationModeActive}. The default\r\n * reader ({@link readVirtualizationModeActive}) already never throws, but a consumer-supplied override\r\n * might, so this backstop catches any error and reports `false` (standard) to preserve the\r\n * never-throws contract of {@link getCapabilities}.\r\n */\r\n private resolveActive(): boolean {\r\n try {\r\n return this.isVirtualizationModeActive();\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Resolves whether the vMode database is installed on this platform, caching the result for the\r\n * lifetime of the client. The install state is **immutable** for the lifetime of the gateway\r\n * install (changing it requires uninstalling/reinstalling vMode), so it is safe to cache and is\r\n * probed at most once.\r\n *\r\n * A result is only cached when the probe gives a **definitive** answer: success (installed) or a\r\n * 400/404 (the capability endpoint is absent on this platform). A **transient** failure (network\r\n * error, 5xx) leaves the cache `undefined` — reported as \"not installed\" for the current call so\r\n * nothing throws, but not remembered, so a later call retries. Callers that need to distinguish\r\n * \"definitively absent\" from \"we could not tell\" must read {@link databaseInstalled} directly\r\n * rather than this observable's `false`. A successful probe also captures the platform's reported\r\n * `agentVersion`, surfaced via {@link getCapabilities}. Never throws.\r\n */\r\n private isDatabaseInstalled(): Observable<boolean> {\r\n if (this.databaseInstalled !== undefined) {\r\n return of(this.databaseInstalled);\r\n }\r\n // `defer` so the request is built on subscription, not when this method is called. Building a\r\n // gateway request touches ambient globals (`MsftSme`, the localization and authorization\r\n // managers) that can be absent on a partially-initialized environment; without `defer` such a\r\n // synchronous throw escapes `catchError` below and breaks the never-throws contract.\r\n return defer(() => this.gateway.get(ENTERPRISE_STATUS_PROBE_PATH)).pipe(\r\n take(1),\r\n map((status: { agentVersion?: string } | undefined) => {\r\n // A successful probe means vMode is installed; capture the reported agent build\r\n // version and cache the definitive result.\r\n this.agentVersion = status?.agentVersion;\r\n this.databaseInstalled = true;\r\n return true;\r\n }),\r\n catchError((error: unknown) => {\r\n // A 400/404 is a definitive answer: the capability endpoint is absent, so vMode is\r\n // not installed — cache `false`. Any other failure is transient (network, 5xx), so\r\n // report \"not installed\" for this call but do NOT cache, letting a later call retry.\r\n const status = (error as { status?: number })?.status;\r\n if (status === HTTP_BAD_REQUEST || status === HTTP_NOT_FOUND) {\r\n this.databaseInstalled = false;\r\n }\r\n return of(false);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Runs `operation` only when the user is currently in vMode (`active`), otherwise resolves to\r\n * `fallback`. Encapsulates the common capability-gating pattern so consumers can gracefully fall\r\n * back to their existing (e.g. aMode) path when vMode is not in use.\r\n *\r\n * Named for `active` alone on purpose — there is no false promise: the vMode experience cannot be\r\n * `active` unless the vMode database is also `available` (you can't be *in* vMode on a platform\r\n * that doesn't have it). This gate still checks both capability fields defensively, but `active`\r\n * is the meaningful condition. See {@link getCapabilities}.\r\n *\r\n * ```ts\r\n * const hosts$ = vc.whenActive(() => vc.getHosts(), () => of([]));\r\n * ```\r\n *\r\n * @param operation Factory invoked only when vMode is active.\r\n * @param fallback Factory invoked only when vMode is not active. It is a factory (not a bare\r\n * observable) so its work — and any side effects — only happen when the fallback is taken.\r\n */\r\n public whenActive<T>(operation: () => Observable<T>, fallback: () => Observable<T>): Observable<T> {\r\n return this.getCapabilities().pipe(\r\n take(1),\r\n mergeMap(capabilities => (capabilities.available && capabilities.active ? operation() : fallback()))\r\n );\r\n }\r\n\r\n // The per-type list/get methods below (getHosts/getClusters/… and getHost/getCluster/…) are thin,\r\n // deliberately hardcoded wrappers over the generic `list`/`getResource` helpers. This is an\r\n // intentional discoverability tradeoff, NOT accidental duplication: hardcoding one method per\r\n // resource kind gives extension authors autocomplete (type `vc.get` and see every resource kind)\r\n // and precise return types, which a single generic `list(type)` keyed off an enum cannot. Please\r\n // keep them per-type rather than collapsing them into a generic-only surface.\r\n\r\n /**\r\n * Lists all Hyper-V hosts in the virtualization inventory (flat, RBAC-filtered).\r\n * @returns An observable of {@link VirtualizationHost} resources.\r\n */\r\n public getHosts(): Observable<VirtualizationHost[]> {\r\n return this.list<VirtualizationHost>(EnterpriseObjectTypes.Hosts);\r\n }\r\n\r\n /**\r\n * Lists all failover clusters in the virtualization inventory (flat, RBAC-filtered).\r\n * @returns An observable of {@link VirtualizationCluster} resources.\r\n */\r\n public getClusters(): Observable<VirtualizationCluster[]> {\r\n return this.list<VirtualizationCluster>(EnterpriseObjectTypes.Clusters);\r\n }\r\n\r\n /**\r\n * Lists all virtual machines in the virtualization inventory (flat, RBAC-filtered).\r\n * @returns An observable of {@link VirtualizationVm} resources.\r\n */\r\n public getVms(): Observable<VirtualizationVm[]> {\r\n return this.list<VirtualizationVm>(EnterpriseObjectTypes.VirtualMachines);\r\n }\r\n\r\n /**\r\n * Lists all resource groups in the virtualization inventory.\r\n * @returns An observable of {@link VirtualizationResourceGroup} resources.\r\n */\r\n public getResourceGroups(): Observable<VirtualizationResourceGroup[]> {\r\n return this.list<VirtualizationResourceGroup>(EnterpriseObjectTypes.Groups);\r\n }\r\n\r\n /**\r\n * Retrieves a single Hyper-V host by name.\r\n * @param name The host name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n public getHost(name: string): Observable<VirtualizationHost> {\r\n return this.getResource<VirtualizationHost>(EnterpriseObjectTypes.Hosts, name);\r\n }\r\n\r\n /**\r\n * Retrieves a single failover cluster by name.\r\n * @param name The cluster name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n public getCluster(name: string): Observable<VirtualizationCluster> {\r\n return this.getResource<VirtualizationCluster>(EnterpriseObjectTypes.Clusters, name);\r\n }\r\n\r\n /**\r\n * Retrieves a single virtual machine by name.\r\n * @param name The virtual machine name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n public getVm(name: string): Observable<VirtualizationVm> {\r\n return this.getResource<VirtualizationVm>(EnterpriseObjectTypes.VirtualMachines, name);\r\n }\r\n\r\n /**\r\n * Retrieves a single resource group by name.\r\n * @param name The resource group name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n public getResourceGroup(name: string): Observable<VirtualizationResourceGroup> {\r\n return this.getResource<VirtualizationResourceGroup>(EnterpriseObjectTypes.Groups, name);\r\n }\r\n\r\n /**\r\n * Retrieves a single virtualization resource of any type by name.\r\n * @param type The resource collection the object belongs to.\r\n * @param name The resource name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n private getResource<T extends TypedResource>(type: EnterpriseObjectTypes, name: string): Observable<T> {\r\n return this.requestData(() =>\r\n this.gateway.get(`${ENTERPRISE_DATA_BASE_PATH}/${type}/${encodeURIComponent(name)}`).pipe(\r\n take(1),\r\n map((response: T) => response)\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * Retrieves the children of a virtualization resource (via `expand=children`), e.g. the VMs under\r\n * a host or the hosts under a cluster.\r\n * @param type The resource collection the parent belongs to.\r\n * @param name The parent resource name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n private getChildren<T extends ChildObjectDataResource>(type: EnterpriseObjectTypes, name: string): Observable<T[]> {\r\n return this.requestData(() =>\r\n this.gateway.get(`${ENTERPRISE_DATA_BASE_PATH}/${type}/${encodeURIComponent(name)}?expand=children`).pipe(\r\n take(1),\r\n map((response: TypedResource | undefined) => (response?.children ?? []) as T[])\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * Retrieves the virtual machines hosted on a specific Hyper-V host.\r\n * @param hostName The host name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n * @returns An observable of {@link VirtualizationVmChild} entries (the host's VMs).\r\n */\r\n public getHostVms(hostName: string): Observable<VirtualizationVmChild[]> {\r\n return this.getChildren<VirtualizationVmChild>(EnterpriseObjectTypes.Hosts, hostName);\r\n }\r\n\r\n /**\r\n * Retrieves the member hosts of a specific failover cluster.\r\n * @param clusterName The cluster name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n * @returns An observable of {@link VirtualizationHostChild} entries (the cluster's member hosts).\r\n */\r\n public getClusterHosts(clusterName: string): Observable<VirtualizationHostChild[]> {\r\n return this.getChildren<VirtualizationHostChild>(EnterpriseObjectTypes.Clusters, clusterName);\r\n }\r\n\r\n /**\r\n * Issues a flat list request for a collection and unwraps the `{ data: [...] }` envelope.\r\n */\r\n private list<T extends TypedResource>(type: EnterpriseObjectTypes): Observable<T[]> {\r\n return this.requestData(\r\n () =>\r\n this.gateway.get(`${ENTERPRISE_DATA_BASE_PATH}/${type}`).pipe(\r\n take(1),\r\n map((response: VirtualizationListResponse<T> | undefined) => response?.data ?? [])\r\n ),\r\n false\r\n );\r\n }\r\n\r\n /**\r\n * The default reader for {@link isVirtualizationModeActive}: reads whether the user is currently\r\n * in the virtualization experience (vMode) vs standard mode from the ambient `MsftSme` environment\r\n * configuration. Synchronous local read; defaults to `false` (standard) and never throws. Consumers\r\n * that need to fake this in tests should pass {@link VirtualizationClientOptions.isVirtualizationModeActive}\r\n * rather than overriding this method.\r\n */\r\n private readVirtualizationModeActive(): boolean {\r\n try {\r\n // Read the environment mode from the current environment configuration. Legacy gateways return undefined, so assume standard.\r\n const mode = MsftSme.getValue<EnvironmentMode>(MsftSme.self().Environment.configuration, 'environmentMode') ?? 'standard';\r\n return mode === 'virtualization';\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Runs a data request, ensuring the (cached) database-install probe has resolved first so that\r\n * {@link toDataError} can distinguish \"the vMode database is absent\" from \"the requested resource\r\n * does not exist\". The request's errors are mapped through {@link toDataError}.\r\n *\r\n * The install-gate is verb-agnostic and intended to be reused by future write (POST/PUT/PATCH)\r\n * methods; those should pass a write-specific error mapper rather than relying on the read-oriented\r\n * {@link toDataError} (see its note).\r\n * @param request Builds the underlying gateway request. Invoked on subscription.\r\n * @param resourceScoped Whether the request addresses a single named resource, so a 404 can mean\r\n * \"that resource does not exist\". `false` for collection requests, where a 404 is never about a\r\n * specific resource. Defaults to `true`.\r\n */\r\n private requestData<T>(request: () => Observable<T>, resourceScoped: boolean = true): Observable<T> {\r\n return this.isDatabaseInstalled().pipe(\r\n take(1),\r\n mergeMap(() => request().pipe(catchError((error: unknown) => throwError(() => this.toDataError(error, resourceScoped)))))\r\n );\r\n }\r\n\r\n /**\r\n * Maps a gateway error from a data method into a typed virtualization error.\r\n *\r\n * Only a **404** is mapped, and only using what the install probe *definitively* established:\r\n * - the probe definitively found vMode absent → {@link VirtualizationUnavailableError}, because the\r\n * data routes are unregistered and the 404 means the platform lacks vMode;\r\n * - otherwise, for a single-resource request → {@link VirtualizationResourceNotFoundError}.\r\n *\r\n * A transient probe failure leaves the install state *unknown*, and unknown is deliberately **not**\r\n * treated as absent: {@link VirtualizationUnavailableError} tells callers to tear down the whole vMode\r\n * experience, so inferring it from a momentary blip would turn one mistyped resource name into a\r\n * dismantled UI. Unknown therefore falls to the narrower resource-scoped meaning.\r\n *\r\n * A 404 on a **collection** request is not about any single resource, so it passes through unchanged\r\n * unless the database is known to be absent. All other statuses — including a **400**, which the data\r\n * surface returns only for a malformed request such as an empty name — also pass through unchanged.\r\n *\r\n * NOTE (read-oriented): this mapping is for the read (GET) surface, where the only \"absent\" signal\r\n * is 404. It is NOT suitable for future write (POST/PUT/PATCH) methods, where 400 means a validation\r\n * error, 409 a conflict, and 412 a precondition failure. When write methods are added, route them\r\n * through {@link requestData} (the install-gate is verb-agnostic) but supply a distinct,\r\n * write-specific error mapper instead of reusing this one.\r\n */\r\n private toDataError(error: unknown, resourceScoped: boolean): unknown {\r\n const status = (error as { status?: number })?.status;\r\n if (status !== HTTP_NOT_FOUND) {\r\n return error;\r\n }\r\n if (this.databaseInstalled === false) {\r\n return new VirtualizationUnavailableError(undefined, status, error);\r\n }\r\n return resourceScoped ? new VirtualizationResourceNotFoundError(undefined, status, error) : error;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"virtualization-client.js","sourceRoot":"","sources":["../../src/virtualization/virtualization-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { defer, Observable, of, throwError } from 'rxjs';\r\nimport { catchError, map, mergeMap, take } from 'rxjs/operators';\r\nimport { AppContext } from '../data/app-context';\r\nimport { GatewayConnection } from '../data/gateway-connection';\r\nimport { ChildObjectDataResource, ENTERPRISE_DATA_BASE_PATH, ENTERPRISE_STATUS_PROBE_PATH, EnterpriseObjectTypes, TypedResource } from '../enterprise/enterprise-models';\r\nimport { EnvironmentMode } from '../manifest/environment-modules';\r\nimport {\r\n VirtualizationCapabilities,\r\n VirtualizationCluster,\r\n VirtualizationHost,\r\n VirtualizationHostChild,\r\n VirtualizationListResponse,\r\n VirtualizationResourceGroup,\r\n VirtualizationVm,\r\n VirtualizationVmChild\r\n} from './virtualization-models';\r\nimport { VirtualizationResourceNotFoundError } from './virtualization-resource-not-found-error';\r\nimport { VirtualizationUnavailableError } from './virtualization-unavailable-error';\r\n\r\nconst HTTP_BAD_REQUEST = 400;\r\nconst HTTP_NOT_FOUND = 404;\r\n\r\n/**\r\n * The minimal subset of an app context required by {@link VirtualizationClient}: anything\r\n * exposing a {@link GatewayConnection}. Both the Angular `AppContextService` and the React\r\n * app-context satisfy this, so the client works in either framework.\r\n */\r\nexport interface VirtualizationClientHost {\r\n gateway: GatewayConnection;\r\n}\r\n\r\n/**\r\n * Typed, discoverable SDK client for vMode inventory APIs.\r\n *\r\n * `VirtualizationClient` gives extension authors a single importable entry point with typed methods\r\n * and IntelliSense for the vMode virtualization database, instead of hand-writing\r\n * `gateway.get('services/enterprisedata/data/...')` calls against an internal, undocumented surface.\r\n *\r\n * ## Detecting vMode and gating data calls\r\n *\r\n * Construction is **inert** (no network calls), so importing and instantiating the client is always\r\n * safe. Two checks cover the common needs, and neither throws:\r\n *\r\n * - {@link isActive} — a synchronous, local read of whether the user is currently in vMode. Use it\r\n * for lightweight UI decisions such as showing or hiding vMode-only content.\r\n * - {@link whenActive} — runs an operation (typically a data call) only when vMode is active **and**\r\n * the vMode database is installed, otherwise runs a fallback. Use it when accessing vMode data.\r\n * - {@link getCapabilities} — combines the result from isActive with a gateway probe to determine\r\n * whether the vMode database is present and usable, along with the agent version if available. This\r\n * is the least likely use case, but is available for scenarios where more data is needed.\r\n *\r\n * ```ts\r\n * const vc = new VirtualizationClient(appContext); // inert, no network\r\n * if (vc.isActive()) {\r\n * // show vMode-only UI\r\n * }\r\n * const hosts = await firstValueFrom(vc.whenActive(() => vc.getHosts(), () => of([])));\r\n * ```\r\n *\r\n * ## Compatibility\r\n *\r\n * This will work whether vMode is installed or not. The data methods ({@link getHosts}, etc.) reject\r\n * with a {@link VirtualizationUnavailableError} when the database is absent (a backstop for callers\r\n * that do not gate with {@link whenActive}), or a {@link VirtualizationResourceNotFoundError} when the\r\n * database is installed but the requested resource does not exist.\r\n */\r\nexport class VirtualizationClient {\r\n private readonly gateway: GatewayConnection;\r\n /**\r\n * Cached result of the database-install probe (the `available` capability).\r\n */\r\n private databaseInstalled?: boolean;\r\n /**\r\n * Cached enterprise/vMode agent build version, sourced from the probe's `agentVersion`. Set only on a\r\n * successful probe and cached alongside {@link databaseInstalled}; stays `undefined` when not reported.\r\n */\r\n private agentVersion?: string;\r\n\r\n /**\r\n * Creates a virtualization client. This does **not** make any network calls.\r\n * @param appContext The app context (or any object exposing a `gateway`) to issue requests on.\r\n */\r\n constructor(appContext: AppContext | VirtualizationClientHost) {\r\n this.gateway = appContext.gateway;\r\n }\r\n\r\n /**\r\n * Returns whether the user is using WAC in vMode rather than standard (aMode). This is a\r\n * synchronous read of the shell's environment mode with no network call; use it for UI\r\n * decisions such as showing or hiding vMode-only content.\r\n *\r\n * @returns `true` when the user is in vMode; otherwise `false`.\r\n */\r\n public isActive(): boolean {\r\n try {\r\n // Legacy gateways do not report an environment mode, so assume standard.\r\n const mode = MsftSme.getValue<EnvironmentMode>(MsftSme.self().Environment.configuration, 'environmentMode') ?? 'standard';\r\n return mode === 'virtualization';\r\n } catch {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Reports whether the vMode database is installed (`available`, probed once and cached with\r\n * `agentVersion`) and whether the user is in vMode (`active`, from {@link isActive} on each\r\n * subscription). Never throws; on any error `available` is `false`.\r\n *\r\n * Most callers should use {@link isActive} for UI decisions and {@link whenActive} to gate data\r\n * calls. Use this method only when you need the individual flags.\r\n * @returns An observable of {@link VirtualizationCapabilities}.\r\n */\r\n public getCapabilities(): Observable<VirtualizationCapabilities> {\r\n return this.isDatabaseInstalled().pipe(map(available => ({ available, active: this.isActive(), agentVersion: this.agentVersion }) as VirtualizationCapabilities));\r\n }\r\n\r\n /**\r\n * Resolves whether the vMode database is installed on this platform, caching the result for the\r\n * lifetime of the client. The install state is **immutable** for the lifetime of the gateway\r\n * install (changing it requires uninstalling/reinstalling vMode), so it is safe to cache and is\r\n * probed at most once.\r\n *\r\n * A result is only cached when the probe gives a **definitive** answer: success (installed) or a\r\n * 400/404 (the capability endpoint is absent on this platform). A **transient** failure (network\r\n * error, 5xx) leaves the cache `undefined` — reported as \"not installed\" for the current call so\r\n * nothing throws, but not remembered, so a later call retries. Callers that need to distinguish\r\n * \"definitively absent\" from \"we could not tell\" must read {@link databaseInstalled} directly\r\n * rather than this observable's `false`. A successful probe also captures the platform's reported\r\n * `agentVersion`, surfaced via {@link getCapabilities}. Never throws.\r\n */\r\n private isDatabaseInstalled(): Observable<boolean> {\r\n if (this.databaseInstalled !== undefined) {\r\n return of(this.databaseInstalled);\r\n }\r\n // `defer` so the request is built on subscription, not when this method is called. Building a\r\n // gateway request touches ambient globals (`MsftSme`, the localization and authorization\r\n // managers) that can be absent on a partially-initialized environment; without `defer` such a\r\n // synchronous throw escapes `catchError` below and breaks the never-throws contract.\r\n return defer(() => this.gateway.get(ENTERPRISE_STATUS_PROBE_PATH)).pipe(\r\n take(1),\r\n map((status: { agentVersion?: string } | undefined) => {\r\n // A successful probe means vMode is installed; capture the reported agent build\r\n // version and cache the definitive result.\r\n this.agentVersion = status?.agentVersion;\r\n this.databaseInstalled = true;\r\n return true;\r\n }),\r\n catchError((error: unknown) => {\r\n // A 400/404 is a definitive answer: the capability endpoint is absent, so vMode is\r\n // not installed — cache `false`. Any other failure is transient (network, 5xx), so\r\n // report \"not installed\" for this call but do NOT cache, letting a later call retry.\r\n const status = (error as { status?: number })?.status;\r\n if (status === HTTP_BAD_REQUEST || status === HTTP_NOT_FOUND) {\r\n this.databaseInstalled = false;\r\n }\r\n return of(false);\r\n })\r\n );\r\n }\r\n\r\n /**\r\n * Runs `operation` when the user is in vMode and the vMode database is installed; otherwise runs\r\n * `fallback` (e.g. the existing aMode path). Use it to gate calls to the data methods.\r\n *\r\n * The check runs on subscription and never errors; errors from `operation` or `fallback` propagate.\r\n * When the user is not in vMode it takes the fallback with no network call; otherwise it consults\r\n * the cached database-install probe.\r\n *\r\n * ```ts\r\n * const hosts$ = vc.whenActive(() => vc.getHosts(), () => of([]));\r\n * ```\r\n *\r\n * @param operation Factory invoked only when vMode is active and the database is installed.\r\n * @param fallback Factory invoked otherwise. It is a factory (not a bare observable) so its work —\r\n * and any side effects — only happen when the fallback is taken.\r\n */\r\n public whenActive<T>(operation: () => Observable<T>, fallback: () => Observable<T>): Observable<T> {\r\n return defer(() =>\r\n this.isActive()\r\n ? this.isDatabaseInstalled().pipe(\r\n take(1),\r\n mergeMap(available => (available ? operation() : fallback()))\r\n )\r\n : fallback()\r\n );\r\n }\r\n\r\n // The per-type list/get methods below (getHosts/getClusters/… and getHost/getCluster/…) are thin,\r\n // deliberately hardcoded wrappers over the generic `list`/`getResource` helpers. This is an\r\n // intentional discoverability tradeoff, NOT accidental duplication: hardcoding one method per\r\n // resource kind gives extension authors autocomplete (type `vc.get` and see every resource kind)\r\n // and precise return types, which a single generic `list(type)` keyed off an enum cannot. Please\r\n // keep them per-type rather than collapsing them into a generic-only surface.\r\n\r\n /**\r\n * Lists all Hyper-V hosts in the virtualization inventory (flat, RBAC-filtered).\r\n * @returns An observable of {@link VirtualizationHost} resources.\r\n */\r\n public getHosts(): Observable<VirtualizationHost[]> {\r\n return this.list<VirtualizationHost>(EnterpriseObjectTypes.Hosts);\r\n }\r\n\r\n /**\r\n * Lists all failover clusters in the virtualization inventory (flat, RBAC-filtered).\r\n * @returns An observable of {@link VirtualizationCluster} resources.\r\n */\r\n public getClusters(): Observable<VirtualizationCluster[]> {\r\n return this.list<VirtualizationCluster>(EnterpriseObjectTypes.Clusters);\r\n }\r\n\r\n /**\r\n * Lists all virtual machines in the virtualization inventory (flat, RBAC-filtered).\r\n * @returns An observable of {@link VirtualizationVm} resources.\r\n */\r\n public getVms(): Observable<VirtualizationVm[]> {\r\n return this.list<VirtualizationVm>(EnterpriseObjectTypes.VirtualMachines);\r\n }\r\n\r\n /**\r\n * Lists all resource groups in the virtualization inventory.\r\n * @returns An observable of {@link VirtualizationResourceGroup} resources.\r\n */\r\n public getResourceGroups(): Observable<VirtualizationResourceGroup[]> {\r\n return this.list<VirtualizationResourceGroup>(EnterpriseObjectTypes.Groups);\r\n }\r\n\r\n /**\r\n * Retrieves a single Hyper-V host by name.\r\n * @param name The host name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n public getHost(name: string): Observable<VirtualizationHost> {\r\n return this.getResource<VirtualizationHost>(EnterpriseObjectTypes.Hosts, name);\r\n }\r\n\r\n /**\r\n * Retrieves a single failover cluster by name.\r\n * @param name The cluster name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n public getCluster(name: string): Observable<VirtualizationCluster> {\r\n return this.getResource<VirtualizationCluster>(EnterpriseObjectTypes.Clusters, name);\r\n }\r\n\r\n /**\r\n * Retrieves a single virtual machine by name.\r\n * @param name The virtual machine name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n public getVm(name: string): Observable<VirtualizationVm> {\r\n return this.getResource<VirtualizationVm>(EnterpriseObjectTypes.VirtualMachines, name);\r\n }\r\n\r\n /**\r\n * Retrieves a single resource group by name.\r\n * @param name The resource group name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n public getResourceGroup(name: string): Observable<VirtualizationResourceGroup> {\r\n return this.getResource<VirtualizationResourceGroup>(EnterpriseObjectTypes.Groups, name);\r\n }\r\n\r\n /**\r\n * Retrieves a single virtualization resource of any type by name.\r\n * @param type The resource collection the object belongs to.\r\n * @param name The resource name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n private getResource<T extends TypedResource>(type: EnterpriseObjectTypes, name: string): Observable<T> {\r\n return this.requestData(() =>\r\n this.gateway.get(`${ENTERPRISE_DATA_BASE_PATH}/${type}/${encodeURIComponent(name)}`).pipe(\r\n take(1),\r\n map((response: T) => response)\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * Retrieves the children of a virtualization resource (via `expand=children`), e.g. the VMs under\r\n * a host or the hosts under a cluster.\r\n * @param type The resource collection the parent belongs to.\r\n * @param name The parent resource name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n */\r\n private getChildren<T extends ChildObjectDataResource>(type: EnterpriseObjectTypes, name: string): Observable<T[]> {\r\n return this.requestData(() =>\r\n this.gateway.get(`${ENTERPRISE_DATA_BASE_PATH}/${type}/${encodeURIComponent(name)}?expand=children`).pipe(\r\n take(1),\r\n map((response: TypedResource | undefined) => (response?.children ?? []) as T[])\r\n )\r\n );\r\n }\r\n\r\n /**\r\n * Retrieves the virtual machines hosted on a specific Hyper-V host.\r\n * @param hostName The host name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n * @returns An observable of {@link VirtualizationVmChild} entries (the host's VMs).\r\n */\r\n public getHostVms(hostName: string): Observable<VirtualizationVmChild[]> {\r\n return this.getChildren<VirtualizationVmChild>(EnterpriseObjectTypes.Hosts, hostName);\r\n }\r\n\r\n /**\r\n * Retrieves the member hosts of a specific failover cluster.\r\n * @param clusterName The cluster name. Must be non-empty; an empty name is rejected by the gateway with a 400.\r\n * @returns An observable of {@link VirtualizationHostChild} entries (the cluster's member hosts).\r\n */\r\n public getClusterHosts(clusterName: string): Observable<VirtualizationHostChild[]> {\r\n return this.getChildren<VirtualizationHostChild>(EnterpriseObjectTypes.Clusters, clusterName);\r\n }\r\n\r\n /**\r\n * Issues a flat list request for a collection and unwraps the `{ data: [...] }` envelope.\r\n */\r\n private list<T extends TypedResource>(type: EnterpriseObjectTypes): Observable<T[]> {\r\n return this.requestData(\r\n () =>\r\n this.gateway.get(`${ENTERPRISE_DATA_BASE_PATH}/${type}`).pipe(\r\n take(1),\r\n map((response: VirtualizationListResponse<T> | undefined) => response?.data ?? [])\r\n ),\r\n false\r\n );\r\n }\r\n\r\n /**\r\n * Runs a data request, ensuring the (cached) database-install probe has resolved first so that\r\n * {@link toDataError} can distinguish \"the vMode database is absent\" from \"the requested resource\r\n * does not exist\". The request's errors are mapped through {@link toDataError}.\r\n *\r\n * The install-gate is verb-agnostic and intended to be reused by future write (POST/PUT/PATCH)\r\n * methods; those should pass a write-specific error mapper rather than relying on the read-oriented\r\n * {@link toDataError} (see its note).\r\n * @param request Builds the underlying gateway request. Invoked on subscription.\r\n * @param resourceScoped Whether the request addresses a single named resource, so a 404 can mean\r\n * \"that resource does not exist\". `false` for collection requests, where a 404 is never about a\r\n * specific resource. Defaults to `true`.\r\n */\r\n private requestData<T>(request: () => Observable<T>, resourceScoped: boolean = true): Observable<T> {\r\n return this.isDatabaseInstalled().pipe(\r\n take(1),\r\n mergeMap(() => request().pipe(catchError((error: unknown) => throwError(() => this.toDataError(error, resourceScoped)))))\r\n );\r\n }\r\n\r\n /**\r\n * Maps a gateway error from a data method into a typed virtualization error.\r\n *\r\n * Only a **404** is mapped, and only using what the install probe *definitively* established:\r\n * - the probe definitively found vMode absent → {@link VirtualizationUnavailableError}, because the\r\n * data routes are unregistered and the 404 means the platform lacks vMode;\r\n * - otherwise, for a single-resource request → {@link VirtualizationResourceNotFoundError}.\r\n *\r\n * A transient probe failure leaves the install state *unknown*, and unknown is deliberately **not**\r\n * treated as absent: {@link VirtualizationUnavailableError} tells callers to tear down the whole vMode\r\n * experience, so inferring it from a momentary blip would turn one mistyped resource name into a\r\n * dismantled UI. Unknown therefore falls to the narrower resource-scoped meaning.\r\n *\r\n * A 404 on a **collection** request is not about any single resource, so it passes through unchanged\r\n * unless the database is known to be absent. All other statuses — including a **400**, which the data\r\n * surface returns only for a malformed request such as an empty name — also pass through unchanged.\r\n *\r\n * NOTE (read-oriented): this mapping is for the read (GET) surface, where the only \"absent\" signal\r\n * is 404. It is NOT suitable for future write (POST/PUT/PATCH) methods, where 400 means a validation\r\n * error, 409 a conflict, and 412 a precondition failure. When write methods are added, route them\r\n * through {@link requestData} (the install-gate is verb-agnostic) but supply a distinct,\r\n * write-specific error mapper instead of reusing this one.\r\n */\r\n private toDataError(error: unknown, resourceScoped: boolean): unknown {\r\n const status = (error as { status?: number })?.status;\r\n if (status !== HTTP_NOT_FOUND) {\r\n return error;\r\n }\r\n if (this.databaseInstalled === false) {\r\n return new VirtualizationUnavailableError(undefined, status, error);\r\n }\r\n return resourceScoped ? new VirtualizationResourceNotFoundError(undefined, status, error) : error;\r\n }\r\n}\r\n"]}
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
* backend directly — not SDK-branded ones.
|
|
27
27
|
*
|
|
28
28
|
* The few enterprise re-exports near the end of this file ({@link VMProperties},
|
|
29
|
-
* {@link VMEnabledState}, {@link
|
|
30
|
-
* {@link HostProperties}) are **not** additional brands. They are those
|
|
31
|
-
* enterprise types, surfaced here only so the values you read off a returned
|
|
32
|
-
* `vm.properties?.vmEnabledState`) are importable from one discoverable place.
|
|
29
|
+
* {@link VMEnabledState}, {@link VMReplicationMode}, {@link ClusterProperties}, {@link ClusterNode},
|
|
30
|
+
* {@link ClusterNodeState}, {@link HostProperties}) are **not** additional brands. They are those
|
|
31
|
+
* same backend-faithful enterprise types, surfaced here only so the values you read off a returned
|
|
32
|
+
* resource (e.g. `vm.properties?.vmEnabledState`) are importable from one discoverable place.
|
|
33
33
|
*/
|
|
34
|
-
import { ChildObjectDataResource, ClusterNode, ClusterNodeState, ClusterProperties, HostProperties, TypedResource, VMEnabledState, VMProperties } from '../enterprise/enterprise-models';
|
|
34
|
+
import { ChildObjectDataResource, ClusterNode, ClusterNodeState, ClusterProperties, HostProperties, TypedResource, VMEnabledState, VMProperties, VMReplicationMode } from '../enterprise/enterprise-models';
|
|
35
35
|
/**
|
|
36
36
|
* The virtualization resource kinds this SDK models — the discriminant carried by every branded
|
|
37
37
|
* resource's `objectType`. A string enum whose member values are the gateway wire strings, so you
|
|
@@ -114,7 +114,7 @@ export interface VirtualizationCluster extends TypedResource {
|
|
|
114
114
|
*
|
|
115
115
|
* Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to
|
|
116
116
|
* `'VirtualMachine'`. The nested `properties` bag is the enterprise {@link VMProperties}, which
|
|
117
|
-
* carries the
|
|
117
|
+
* carries the Hyper-V identifier, power state, and replication modes.
|
|
118
118
|
*/
|
|
119
119
|
export interface VirtualizationVm extends TypedResource {
|
|
120
120
|
objectType: VirtualizationObjectType.VirtualMachine;
|
|
@@ -191,8 +191,7 @@ export interface VirtualizationCapabilities {
|
|
|
191
191
|
/**
|
|
192
192
|
* VM-specific properties bag — the enterprise {@link VMProperties} (single-sourced in
|
|
193
193
|
* `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend model `VMObjectProperties`), reachable
|
|
194
|
-
* as `properties` on a {@link VirtualizationVm}. Re-exported unchanged.
|
|
195
|
-
* **required** — the backend field is non-nullable (defaults to `Unknown`), so it is always present.
|
|
194
|
+
* as `properties` on a {@link VirtualizationVm}. Re-exported unchanged.
|
|
196
195
|
*/
|
|
197
196
|
export type { VMProperties };
|
|
198
197
|
/**
|
|
@@ -203,6 +202,8 @@ export type { VMProperties };
|
|
|
203
202
|
* `Off` in core (the backend enum names them `Enabled`/`Disabled`; the numeric values are identical).
|
|
204
203
|
*/
|
|
205
204
|
export { VMEnabledState };
|
|
205
|
+
/** Replication roles reported for a virtual machine. */
|
|
206
|
+
export { VMReplicationMode };
|
|
206
207
|
/**
|
|
207
208
|
* Cluster-specific properties bag — the enterprise {@link ClusterProperties} (single-sourced in
|
|
208
209
|
* `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend model `ClusterObjectProperties`),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualization-models.d.ts","sourceRoot":"","sources":["../../src/virtualization/virtualization-models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EACH,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,
|
|
1
|
+
{"version":3,"file":"virtualization-models.d.ts","sourceRoot":"","sources":["../../src/virtualization/virtualization-models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EACH,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,cAAc,EACd,YAAY,EACZ,iBAAiB,EACpB,MAAM,iCAAiC,CAAC;AAOzC;;;;;;;;;;;GAWG;AACH,oBAAY,wBAAwB;IAChC,8CAA8C;IAC9C,aAAa,kBAAkB;IAC/B,0BAA0B;IAC1B,OAAO,YAAY;IACnB,sBAAsB;IACtB,MAAM,WAAW;IACjB,yBAAyB;IACzB,cAAc,mBAAmB;CACpC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IAClE,UAAU,EAAE,wBAAwB,CAAC,cAAc,CAAC;IACpD,mFAAmF;IACnF,UAAU,CAAC,EAAE,KAAK,CAAC;CACtB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAwB,SAAQ,uBAAuB;IACpE,UAAU,EAAE,wBAAwB,CAAC,MAAM,CAAC;IAC5C,qFAAqF;IACrF,UAAU,CAAC,EAAE,KAAK,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACrD,UAAU,EAAE,wBAAwB,CAAC,MAAM,CAAC;IAC5C,UAAU,CAAC,EAAE,cAAc,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IACxD,UAAU,EAAE,wBAAwB,CAAC,OAAO,CAAC;IAC7C,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACnD,UAAU,EAAE,wBAAwB,CAAC,cAAc,CAAC;IACpD,UAAU,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,2BAA4B,SAAQ,aAAa;IAC9D,UAAU,EAAE,wBAAwB,CAAC,aAAa,CAAC;CACtD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,MAAM,sBAAsB,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,2BAA2B,CAAC;AAEjI;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B,CAAC,CAAC;IACzC,IAAI,EAAE,CAAC,EAAE,CAAC;CACb;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,0BAA0B;IACvC,gFAAgF;IAChF,SAAS,EAAE,OAAO,CAAC;IACnB,8GAA8G;IAC9G,MAAM,EAAE,OAAO,CAAC;IAChB,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAQD;;;;GAIG;AACH,YAAY,EAAE,YAAY,EAAE,CAAC;AAE7B;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,wDAAwD;AACxD,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;;GAIG;AACH,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAElC;;;;;;GAMG;AACH,YAAY,EAAE,WAAW,EAAE,CAAC;AAE5B;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B;;;;;GAKG;AACH,YAAY,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
* backend directly — not SDK-branded ones.
|
|
27
27
|
*
|
|
28
28
|
* The few enterprise re-exports near the end of this file ({@link VMProperties},
|
|
29
|
-
* {@link VMEnabledState}, {@link
|
|
30
|
-
* {@link HostProperties}) are **not** additional brands. They are those
|
|
31
|
-
* enterprise types, surfaced here only so the values you read off a returned
|
|
32
|
-
* `vm.properties?.vmEnabledState`) are importable from one discoverable place.
|
|
29
|
+
* {@link VMEnabledState}, {@link VMReplicationMode}, {@link ClusterProperties}, {@link ClusterNode},
|
|
30
|
+
* {@link ClusterNodeState}, {@link HostProperties}) are **not** additional brands. They are those
|
|
31
|
+
* same backend-faithful enterprise types, surfaced here only so the values you read off a returned
|
|
32
|
+
* resource (e.g. `vm.properties?.vmEnabledState`) are importable from one discoverable place.
|
|
33
33
|
*/
|
|
34
|
-
import { ClusterNodeState, VMEnabledState } from '../enterprise/enterprise-models';
|
|
34
|
+
import { ClusterNodeState, VMEnabledState, VMReplicationMode } from '../enterprise/enterprise-models';
|
|
35
35
|
// ────────────────────────────────────────────────────────────────────────────────────────────
|
|
36
36
|
// Branded SDK surface — one type per value a VirtualizationClient method returns directly. Each
|
|
37
37
|
// one extends its backend-faithful enterprise base and only narrows the discriminant/`properties`.
|
|
@@ -67,6 +67,8 @@ export var VirtualizationObjectType;
|
|
|
67
67
|
* `Off` in core (the backend enum names them `Enabled`/`Disabled`; the numeric values are identical).
|
|
68
68
|
*/
|
|
69
69
|
export { VMEnabledState };
|
|
70
|
+
/** Replication roles reported for a virtual machine. */
|
|
71
|
+
export { VMReplicationMode };
|
|
70
72
|
/**
|
|
71
73
|
* Cluster-node state enum — the enterprise {@link ClusterNodeState} (single-sourced in
|
|
72
74
|
* `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, a direct copy of the gateway backend enum `ClusterNodeState`),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualization-models.js","sourceRoot":"","sources":["../../src/virtualization/virtualization-models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAGH,gBAAgB,EAIhB,cAAc,EAEjB,MAAM,iCAAiC,CAAC;AAEzC,+FAA+F;AAC/F,gGAAgG;AAChG,mGAAmG;AACnG,+FAA+F;AAE/F;;;;;;;;;;;GAWG;AACH,MAAM,CAAN,IAAY,wBASX;AATD,WAAY,wBAAwB;IAChC,8CAA8C;IAC9C,2DAA+B,CAAA;IAC/B,0BAA0B;IAC1B,+CAAmB,CAAA;IACnB,sBAAsB;IACtB,6CAAiB,CAAA;IACjB,yBAAyB;IACzB,6DAAiC,CAAA;AACrC,CAAC,EATW,wBAAwB,KAAxB,wBAAwB,QASnC;AA+JD;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,CAAC;AAkB1B;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,CAAC","sourcesContent":["/**\r\n * Public, partner-facing models for the Windows Admin Center virtualization (vMode) inventory APIs.\r\n *\r\n * These types describe the read-only inventory exposed by the Gateway V2 virtualization database\r\n * (hosts, clusters, virtual machines and resource groups). They intentionally use the user-facing\r\n * term \"Virtualization\" rather than the internal \"Enterprise\" naming so extension authors get a\r\n * discoverable, stable surface to build against.\r\n *\r\n * ## What is branded here — and what is not\r\n *\r\n * The `Virtualization*` types below are a **deliberately small branded surface**: there is exactly\r\n * one for each value a {@link VirtualizationClient} method returns **directly**, and nothing more.\r\n * That set is the four resource kinds ({@link VirtualizationHost}, {@link VirtualizationCluster},\r\n * {@link VirtualizationVm}, {@link VirtualizationResourceGroup}), the two child shapes from the\r\n * `expand=children` methods ({@link VirtualizationVmChild}, {@link VirtualizationHostChild}), the\r\n * {@link VirtualizationResource} union over the four kinds, the {@link VirtualizationListResponse}\r\n * envelope, and the {@link VirtualizationCapabilities} probe result.\r\n *\r\n * Everything **nested inside** those returned shapes — the per-type `properties` bags, the enums,\r\n * the child base fields, system/audit metadata — is used **verbatim** from the shared,\r\n * backend-faithful contract at `core/src/enterprise/` (see {@link ../enterprise/enterprise-models}),\r\n * which transcribes the gateway `services/enterprisedata/data/...` models exactly **once**. Each\r\n * branded type here simply `extends` its enterprise base and narrows `objectType` (and, for the\r\n * concrete resources, the `properties` bag) to the specific kind. So the further you read into a\r\n * returned resource, the sooner you are looking at plain `enterprise-models` types that mirror the\r\n * backend directly — not SDK-branded ones.\r\n *\r\n * The few enterprise re-exports near the end of this file ({@link VMProperties},\r\n * {@link VMEnabledState}, {@link ClusterProperties}, {@link ClusterNode}, {@link ClusterNodeState},\r\n * {@link HostProperties}) are **not** additional brands. They are those same backend-faithful\r\n * enterprise types, surfaced here only so the values you read off a returned resource (e.g.\r\n * `vm.properties?.vmEnabledState`) are importable from one discoverable place.\r\n */\r\n\r\nimport {\r\n ChildObjectDataResource,\r\n ClusterNode,\r\n ClusterNodeState,\r\n ClusterProperties,\r\n HostProperties,\r\n TypedResource,\r\n VMEnabledState,\r\n VMProperties\r\n} from '../enterprise/enterprise-models';\r\n\r\n// ────────────────────────────────────────────────────────────────────────────────────────────\r\n// Branded SDK surface — one type per value a VirtualizationClient method returns directly. Each\r\n// one extends its backend-faithful enterprise base and only narrows the discriminant/`properties`.\r\n// ────────────────────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * The virtualization resource kinds this SDK models — the discriminant carried by every branded\r\n * resource's `objectType`. A string enum whose member values are the gateway wire strings, so you\r\n * narrow a {@link VirtualizationResource} by named member (`case VirtualizationObjectType.Cluster:`)\r\n * rather than a bare string literal.\r\n *\r\n * These four are the curated subset the virtualization SDK surfaces. The gateway backend enum\r\n * `ObjectDataType` (wac repo: src/Enterprise/EnterpriseUniversal/ObjectDataType.cs, emitted with\r\n * `JsonStringEnumConverter`) defines more kinds (storage/network, standalone servers, VM templates);\r\n * a resource of an unmodeled kind still arrives at runtime — hold it as the raw {@link TypedResource}\r\n * base, whose `objectType` is an open `string`.\r\n */\r\nexport enum VirtualizationObjectType {\r\n /** A logical grouping/folder of resources. */\r\n ResourceGroup = 'ResourceGroup',\r\n /** A failover cluster. */\r\n Cluster = 'Cluster',\r\n /** A Hyper-V host. */\r\n Hyperv = 'Hyperv',\r\n /** A virtual machine. */\r\n VirtualMachine = 'VirtualMachine'\r\n}\r\n\r\n/**\r\n * A virtual machine returned as the child of a host (via `expand=children`) — the element type of\r\n * {@link VirtualizationClient.getHostVms}.\r\n *\r\n * It brands the backend-faithful {@link ChildObjectDataResource} (which carries `parentName`/\r\n * `hasChildren`) by narrowing `objectType` to `'VirtualMachine'`. Child payloads carry only the base\r\n * resource fields, not the per-type `properties` bag, so `properties` is narrowed to `never`: reading\r\n * it would always be `undefined` at runtime, and closing it here makes that a compile error instead of\r\n * a silently-false comparison. Use {@link VirtualizationClient.getVm} to fetch the full VM.\r\n */\r\nexport interface VirtualizationVmChild extends ChildObjectDataResource {\r\n objectType: VirtualizationObjectType.VirtualMachine;\r\n /** Never populated on child payloads. Fetch the full VM to read its properties. */\r\n properties?: never;\r\n}\r\n\r\n/**\r\n * A Hyper-V host returned as the child (member node) of a cluster (via `expand=children`) — the\r\n * element type of {@link VirtualizationClient.getClusterHosts}.\r\n *\r\n * It brands the backend-faithful {@link ChildObjectDataResource} (which carries `parentName`/\r\n * `hasChildren`) by narrowing `objectType` to `'Hyperv'`. Child payloads carry only the base resource\r\n * fields, not the per-type `properties` bag, so `properties` is narrowed to `never`: reading it would\r\n * always be `undefined` at runtime, and closing it here makes that a compile error instead of a\r\n * silently-false comparison. Use {@link VirtualizationClient.getHost} to fetch the full host.\r\n */\r\nexport interface VirtualizationHostChild extends ChildObjectDataResource {\r\n objectType: VirtualizationObjectType.Hyperv;\r\n /** Never populated on child payloads. Fetch the full host to read its properties. */\r\n properties?: never;\r\n}\r\n\r\n/**\r\n * A Hyper-V host inventory resource — returned by {@link VirtualizationClient.getHosts} and\r\n * {@link VirtualizationClient.getHost}.\r\n *\r\n * Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to `'Hyperv'`. Host\r\n * identity is carried on the base fields (`name`/`displayName`); the nested `properties` bag is the\r\n * enterprise {@link HostProperties} (which has no host-specific fields today).\r\n */\r\nexport interface VirtualizationHost extends TypedResource {\r\n objectType: VirtualizationObjectType.Hyperv;\r\n properties?: HostProperties;\r\n}\r\n\r\n/**\r\n * A failover cluster inventory resource — returned by {@link VirtualizationClient.getClusters} and\r\n * {@link VirtualizationClient.getCluster}.\r\n *\r\n * Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to `'Cluster'`. The\r\n * nested `properties` bag is the enterprise {@link ClusterProperties}, which carries the cluster's\r\n * member nodes.\r\n */\r\nexport interface VirtualizationCluster extends TypedResource {\r\n objectType: VirtualizationObjectType.Cluster;\r\n properties?: ClusterProperties;\r\n}\r\n\r\n/**\r\n * A virtual machine inventory resource — returned by {@link VirtualizationClient.getVms} and\r\n * {@link VirtualizationClient.getVm}.\r\n *\r\n * Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to\r\n * `'VirtualMachine'`. The nested `properties` bag is the enterprise {@link VMProperties}, which\r\n * carries the VM power state.\r\n */\r\nexport interface VirtualizationVm extends TypedResource {\r\n objectType: VirtualizationObjectType.VirtualMachine;\r\n properties?: VMProperties;\r\n}\r\n\r\n/**\r\n * A resource-group inventory resource (a logical grouping/folder) — returned by\r\n * {@link VirtualizationClient.getResourceGroups} and {@link VirtualizationClient.getResourceGroup}.\r\n *\r\n * Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to `'ResourceGroup'`.\r\n * Resource groups carry no type-specific `properties` bag.\r\n */\r\nexport interface VirtualizationResourceGroup extends TypedResource {\r\n objectType: VirtualizationObjectType.ResourceGroup;\r\n}\r\n\r\n/**\r\n * The union of the four concrete virtualization resource kinds this SDK models — the type you hold\r\n * when a value came from the client but its kind is not known at compile time (e.g. an element of a\r\n * mixed collection).\r\n *\r\n * Narrow on `objectType` to get the specific typed shape — the narrowed `properties` bag is the\r\n * concrete per-type shape (e.g. a `Cluster` exposes `properties.clusterNodes`):\r\n *\r\n * ```ts\r\n * function describe(resource: VirtualizationResource): string {\r\n * switch (resource.objectType) {\r\n * case VirtualizationObjectType.VirtualMachine:\r\n * return `VM power state: ${resource.properties?.vmEnabledState}`;\r\n * case VirtualizationObjectType.Cluster:\r\n * return `Cluster with ${resource.properties?.clusterNodes?.length ?? 0} nodes`;\r\n * default:\r\n * return resource.displayName; // any kind not switched above still usable\r\n * }\r\n * }\r\n * ```\r\n *\r\n * This is a **closed** union of the four modeled kinds on purpose: keeping it closed is what makes\r\n * `objectType` narrowing collapse each branch to its concrete `properties` type. (Adding the shared\r\n * {@link TypedResource} base as a member would widen every narrowed branch back to the base\r\n * `properties` bag, defeating the narrowing this union exists to provide.)\r\n *\r\n * Forward-compatibility here is **runtime-only**: should the gateway ever return a kind outside\r\n * {@link VirtualizationObjectType} (e.g. a storage/network kind), the client still passes the payload\r\n * through verbatim and it lands in a `default:` branch at runtime — hold it as the raw\r\n * {@link TypedResource} base, whose `objectType` is an open `string`.\r\n */\r\nexport type VirtualizationResource = VirtualizationHost | VirtualizationCluster | VirtualizationVm | VirtualizationResourceGroup;\r\n\r\n/**\r\n * The gateway list envelope returned by the collection endpoints. The virtualization list endpoints\r\n * wrap their payload in a `data` property, e.g. `GET services/enterprisedata/data/hosts` resolves to\r\n * `{ data: VirtualizationHost[] }`. {@link VirtualizationClient} unwraps this for you; it is exported\r\n * for callers that read the raw gateway response.\r\n */\r\nexport interface VirtualizationListResponse<T> {\r\n data: T[];\r\n}\r\n\r\n/**\r\n * Describes whether the virtualization (vMode) experience is supported by the current platform and\r\n * whether the user is currently using it.\r\n *\r\n * This object is the day-one compatibility contract returned by\r\n * `VirtualizationClient.getCapabilities()`. It is intentionally additive: new fields may be\r\n * added over time without it ever becoming a breaking change for extensions built against older\r\n * shapes.\r\n */\r\nexport interface VirtualizationCapabilities {\r\n /** Whether the vMode database exists on this platform (async gateway probe). */\r\n available: boolean;\r\n /** Whether the user is currently in vMode vs standard mode (sync, local read; independent of `available`). */\r\n active: boolean;\r\n /** The enterprise/vMode agent build version reported by the platform, when available. */\r\n agentVersion?: string;\r\n}\r\n\r\n// ────────────────────────────────────────────────────────────────────────────────────────────\r\n// Enterprise re-exports — backend-faithful types, surfaced for convenience, NOT part of the brand.\r\n// You normally reach these through the resources above (e.g. `vm.properties`, a cluster node's\r\n// `state`); they are re-exported here only so they are importable from one place.\r\n// ────────────────────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * VM-specific properties bag — the enterprise {@link VMProperties} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend model `VMObjectProperties`), reachable\r\n * as `properties` on a {@link VirtualizationVm}. Re-exported unchanged. `vmEnabledState` is\r\n * **required** — the backend field is non-nullable (defaults to `Unknown`), so it is always present.\r\n */\r\nexport type { VMProperties };\r\n\r\n/**\r\n * VM power-state enum — the enterprise {@link VMEnabledState} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend enum `VMEnabledState`), the type of\r\n * {@link VMProperties.vmEnabledState}. Re-exported unchanged so consumers can interpret that value\r\n * without importing from the enterprise contract directly. Backend values 2/3 are named `Running`/\r\n * `Off` in core (the backend enum names them `Enabled`/`Disabled`; the numeric values are identical).\r\n */\r\nexport { VMEnabledState };\r\n\r\n/**\r\n * Cluster-specific properties bag — the enterprise {@link ClusterProperties} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend model `ClusterObjectProperties`),\r\n * reachable as `properties` on a {@link VirtualizationCluster}. Re-exported unchanged.\r\n */\r\nexport type { ClusterProperties };\r\n\r\n/**\r\n * A single member node of a failover cluster — the enterprise {@link ClusterNode} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, a direct copy of the gateway backend model `ClusterNodeObject`), the\r\n * element type of {@link ClusterProperties.clusterNodes}. Re-exported unchanged so callers can name\r\n * the type when they iterate a cluster's nodes. Unlike the surrounding properties bag this shape is\r\n * **closed**: it exposes only its named backend fields.\r\n */\r\nexport type { ClusterNode };\r\n\r\n/**\r\n * Cluster-node state enum — the enterprise {@link ClusterNodeState} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, a direct copy of the gateway backend enum `ClusterNodeState`),\r\n * reported on each entry of a {@link VirtualizationCluster}'s `properties.clusterNodes`. Re-exported\r\n * unchanged. Because the value is a plain number, an unrecognized future state still deserializes\r\n * rather than being rejected.\r\n */\r\nexport { ClusterNodeState };\r\n\r\n/**\r\n * Host-specific properties bag — the enterprise {@link HostProperties} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend model `HostObjectProperties`), reachable\r\n * as `properties` on a {@link VirtualizationHost}. Re-exported unchanged. It carries no host-specific\r\n * fields today; host identity lives on the base resource (`name`/`displayName`).\r\n */\r\nexport type { HostProperties };\r\n"]}
|
|
1
|
+
{"version":3,"file":"virtualization-models.js","sourceRoot":"","sources":["../../src/virtualization/virtualization-models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAGH,gBAAgB,EAIhB,cAAc,EAEd,iBAAiB,EACpB,MAAM,iCAAiC,CAAC;AAEzC,+FAA+F;AAC/F,gGAAgG;AAChG,mGAAmG;AACnG,+FAA+F;AAE/F;;;;;;;;;;;GAWG;AACH,MAAM,CAAN,IAAY,wBASX;AATD,WAAY,wBAAwB;IAChC,8CAA8C;IAC9C,2DAA+B,CAAA;IAC/B,0BAA0B;IAC1B,+CAAmB,CAAA;IACnB,sBAAsB;IACtB,6CAAiB,CAAA;IACjB,yBAAyB;IACzB,6DAAiC,CAAA;AACrC,CAAC,EATW,wBAAwB,KAAxB,wBAAwB,QASnC;AA8JD;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,CAAC;AAE1B,wDAAwD;AACxD,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAkB7B;;;;;;GAMG;AACH,OAAO,EAAE,gBAAgB,EAAE,CAAC","sourcesContent":["/**\r\n * Public, partner-facing models for the Windows Admin Center virtualization (vMode) inventory APIs.\r\n *\r\n * These types describe the read-only inventory exposed by the Gateway V2 virtualization database\r\n * (hosts, clusters, virtual machines and resource groups). They intentionally use the user-facing\r\n * term \"Virtualization\" rather than the internal \"Enterprise\" naming so extension authors get a\r\n * discoverable, stable surface to build against.\r\n *\r\n * ## What is branded here — and what is not\r\n *\r\n * The `Virtualization*` types below are a **deliberately small branded surface**: there is exactly\r\n * one for each value a {@link VirtualizationClient} method returns **directly**, and nothing more.\r\n * That set is the four resource kinds ({@link VirtualizationHost}, {@link VirtualizationCluster},\r\n * {@link VirtualizationVm}, {@link VirtualizationResourceGroup}), the two child shapes from the\r\n * `expand=children` methods ({@link VirtualizationVmChild}, {@link VirtualizationHostChild}), the\r\n * {@link VirtualizationResource} union over the four kinds, the {@link VirtualizationListResponse}\r\n * envelope, and the {@link VirtualizationCapabilities} probe result.\r\n *\r\n * Everything **nested inside** those returned shapes — the per-type `properties` bags, the enums,\r\n * the child base fields, system/audit metadata — is used **verbatim** from the shared,\r\n * backend-faithful contract at `core/src/enterprise/` (see {@link ../enterprise/enterprise-models}),\r\n * which transcribes the gateway `services/enterprisedata/data/...` models exactly **once**. Each\r\n * branded type here simply `extends` its enterprise base and narrows `objectType` (and, for the\r\n * concrete resources, the `properties` bag) to the specific kind. So the further you read into a\r\n * returned resource, the sooner you are looking at plain `enterprise-models` types that mirror the\r\n * backend directly — not SDK-branded ones.\r\n *\r\n * The few enterprise re-exports near the end of this file ({@link VMProperties},\r\n * {@link VMEnabledState}, {@link VMReplicationMode}, {@link ClusterProperties}, {@link ClusterNode},\r\n * {@link ClusterNodeState}, {@link HostProperties}) are **not** additional brands. They are those\r\n * same backend-faithful enterprise types, surfaced here only so the values you read off a returned\r\n * resource (e.g. `vm.properties?.vmEnabledState`) are importable from one discoverable place.\r\n */\r\n\r\nimport {\r\n ChildObjectDataResource,\r\n ClusterNode,\r\n ClusterNodeState,\r\n ClusterProperties,\r\n HostProperties,\r\n TypedResource,\r\n VMEnabledState,\r\n VMProperties,\r\n VMReplicationMode\r\n} from '../enterprise/enterprise-models';\r\n\r\n// ────────────────────────────────────────────────────────────────────────────────────────────\r\n// Branded SDK surface — one type per value a VirtualizationClient method returns directly. Each\r\n// one extends its backend-faithful enterprise base and only narrows the discriminant/`properties`.\r\n// ────────────────────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * The virtualization resource kinds this SDK models — the discriminant carried by every branded\r\n * resource's `objectType`. A string enum whose member values are the gateway wire strings, so you\r\n * narrow a {@link VirtualizationResource} by named member (`case VirtualizationObjectType.Cluster:`)\r\n * rather than a bare string literal.\r\n *\r\n * These four are the curated subset the virtualization SDK surfaces. The gateway backend enum\r\n * `ObjectDataType` (wac repo: src/Enterprise/EnterpriseUniversal/ObjectDataType.cs, emitted with\r\n * `JsonStringEnumConverter`) defines more kinds (storage/network, standalone servers, VM templates);\r\n * a resource of an unmodeled kind still arrives at runtime — hold it as the raw {@link TypedResource}\r\n * base, whose `objectType` is an open `string`.\r\n */\r\nexport enum VirtualizationObjectType {\r\n /** A logical grouping/folder of resources. */\r\n ResourceGroup = 'ResourceGroup',\r\n /** A failover cluster. */\r\n Cluster = 'Cluster',\r\n /** A Hyper-V host. */\r\n Hyperv = 'Hyperv',\r\n /** A virtual machine. */\r\n VirtualMachine = 'VirtualMachine'\r\n}\r\n\r\n/**\r\n * A virtual machine returned as the child of a host (via `expand=children`) — the element type of\r\n * {@link VirtualizationClient.getHostVms}.\r\n *\r\n * It brands the backend-faithful {@link ChildObjectDataResource} (which carries `parentName`/\r\n * `hasChildren`) by narrowing `objectType` to `'VirtualMachine'`. Child payloads carry only the base\r\n * resource fields, not the per-type `properties` bag, so `properties` is narrowed to `never`: reading\r\n * it would always be `undefined` at runtime, and closing it here makes that a compile error instead of\r\n * a silently-false comparison. Use {@link VirtualizationClient.getVm} to fetch the full VM.\r\n */\r\nexport interface VirtualizationVmChild extends ChildObjectDataResource {\r\n objectType: VirtualizationObjectType.VirtualMachine;\r\n /** Never populated on child payloads. Fetch the full VM to read its properties. */\r\n properties?: never;\r\n}\r\n\r\n/**\r\n * A Hyper-V host returned as the child (member node) of a cluster (via `expand=children`) — the\r\n * element type of {@link VirtualizationClient.getClusterHosts}.\r\n *\r\n * It brands the backend-faithful {@link ChildObjectDataResource} (which carries `parentName`/\r\n * `hasChildren`) by narrowing `objectType` to `'Hyperv'`. Child payloads carry only the base resource\r\n * fields, not the per-type `properties` bag, so `properties` is narrowed to `never`: reading it would\r\n * always be `undefined` at runtime, and closing it here makes that a compile error instead of a\r\n * silently-false comparison. Use {@link VirtualizationClient.getHost} to fetch the full host.\r\n */\r\nexport interface VirtualizationHostChild extends ChildObjectDataResource {\r\n objectType: VirtualizationObjectType.Hyperv;\r\n /** Never populated on child payloads. Fetch the full host to read its properties. */\r\n properties?: never;\r\n}\r\n\r\n/**\r\n * A Hyper-V host inventory resource — returned by {@link VirtualizationClient.getHosts} and\r\n * {@link VirtualizationClient.getHost}.\r\n *\r\n * Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to `'Hyperv'`. Host\r\n * identity is carried on the base fields (`name`/`displayName`); the nested `properties` bag is the\r\n * enterprise {@link HostProperties} (which has no host-specific fields today).\r\n */\r\nexport interface VirtualizationHost extends TypedResource {\r\n objectType: VirtualizationObjectType.Hyperv;\r\n properties?: HostProperties;\r\n}\r\n\r\n/**\r\n * A failover cluster inventory resource — returned by {@link VirtualizationClient.getClusters} and\r\n * {@link VirtualizationClient.getCluster}.\r\n *\r\n * Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to `'Cluster'`. The\r\n * nested `properties` bag is the enterprise {@link ClusterProperties}, which carries the cluster's\r\n * member nodes.\r\n */\r\nexport interface VirtualizationCluster extends TypedResource {\r\n objectType: VirtualizationObjectType.Cluster;\r\n properties?: ClusterProperties;\r\n}\r\n\r\n/**\r\n * A virtual machine inventory resource — returned by {@link VirtualizationClient.getVms} and\r\n * {@link VirtualizationClient.getVm}.\r\n *\r\n * Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to\r\n * `'VirtualMachine'`. The nested `properties` bag is the enterprise {@link VMProperties}, which\r\n * carries the Hyper-V identifier, power state, and replication modes.\r\n */\r\nexport interface VirtualizationVm extends TypedResource {\r\n objectType: VirtualizationObjectType.VirtualMachine;\r\n properties?: VMProperties;\r\n}\r\n\r\n/**\r\n * A resource-group inventory resource (a logical grouping/folder) — returned by\r\n * {@link VirtualizationClient.getResourceGroups} and {@link VirtualizationClient.getResourceGroup}.\r\n *\r\n * Brands the backend-faithful {@link TypedResource} base, narrowing `objectType` to `'ResourceGroup'`.\r\n * Resource groups carry no type-specific `properties` bag.\r\n */\r\nexport interface VirtualizationResourceGroup extends TypedResource {\r\n objectType: VirtualizationObjectType.ResourceGroup;\r\n}\r\n\r\n/**\r\n * The union of the four concrete virtualization resource kinds this SDK models — the type you hold\r\n * when a value came from the client but its kind is not known at compile time (e.g. an element of a\r\n * mixed collection).\r\n *\r\n * Narrow on `objectType` to get the specific typed shape — the narrowed `properties` bag is the\r\n * concrete per-type shape (e.g. a `Cluster` exposes `properties.clusterNodes`):\r\n *\r\n * ```ts\r\n * function describe(resource: VirtualizationResource): string {\r\n * switch (resource.objectType) {\r\n * case VirtualizationObjectType.VirtualMachine:\r\n * return `VM power state: ${resource.properties?.vmEnabledState}`;\r\n * case VirtualizationObjectType.Cluster:\r\n * return `Cluster with ${resource.properties?.clusterNodes?.length ?? 0} nodes`;\r\n * default:\r\n * return resource.displayName; // any kind not switched above still usable\r\n * }\r\n * }\r\n * ```\r\n *\r\n * This is a **closed** union of the four modeled kinds on purpose: keeping it closed is what makes\r\n * `objectType` narrowing collapse each branch to its concrete `properties` type. (Adding the shared\r\n * {@link TypedResource} base as a member would widen every narrowed branch back to the base\r\n * `properties` bag, defeating the narrowing this union exists to provide.)\r\n *\r\n * Forward-compatibility here is **runtime-only**: should the gateway ever return a kind outside\r\n * {@link VirtualizationObjectType} (e.g. a storage/network kind), the client still passes the payload\r\n * through verbatim and it lands in a `default:` branch at runtime — hold it as the raw\r\n * {@link TypedResource} base, whose `objectType` is an open `string`.\r\n */\r\nexport type VirtualizationResource = VirtualizationHost | VirtualizationCluster | VirtualizationVm | VirtualizationResourceGroup;\r\n\r\n/**\r\n * The gateway list envelope returned by the collection endpoints. The virtualization list endpoints\r\n * wrap their payload in a `data` property, e.g. `GET services/enterprisedata/data/hosts` resolves to\r\n * `{ data: VirtualizationHost[] }`. {@link VirtualizationClient} unwraps this for you; it is exported\r\n * for callers that read the raw gateway response.\r\n */\r\nexport interface VirtualizationListResponse<T> {\r\n data: T[];\r\n}\r\n\r\n/**\r\n * Describes whether the virtualization (vMode) experience is supported by the current platform and\r\n * whether the user is currently using it.\r\n *\r\n * This object is the day-one compatibility contract returned by\r\n * `VirtualizationClient.getCapabilities()`. It is intentionally additive: new fields may be\r\n * added over time without it ever becoming a breaking change for extensions built against older\r\n * shapes.\r\n */\r\nexport interface VirtualizationCapabilities {\r\n /** Whether the vMode database exists on this platform (async gateway probe). */\r\n available: boolean;\r\n /** Whether the user is currently in vMode vs standard mode (sync, local read; independent of `available`). */\r\n active: boolean;\r\n /** The enterprise/vMode agent build version reported by the platform, when available. */\r\n agentVersion?: string;\r\n}\r\n\r\n// ────────────────────────────────────────────────────────────────────────────────────────────\r\n// Enterprise re-exports — backend-faithful types, surfaced for convenience, NOT part of the brand.\r\n// You normally reach these through the resources above (e.g. `vm.properties`, a cluster node's\r\n// `state`); they are re-exported here only so they are importable from one place.\r\n// ────────────────────────────────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * VM-specific properties bag — the enterprise {@link VMProperties} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend model `VMObjectProperties`), reachable\r\n * as `properties` on a {@link VirtualizationVm}. Re-exported unchanged.\r\n */\r\nexport type { VMProperties };\r\n\r\n/**\r\n * VM power-state enum — the enterprise {@link VMEnabledState} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend enum `VMEnabledState`), the type of\r\n * {@link VMProperties.vmEnabledState}. Re-exported unchanged so consumers can interpret that value\r\n * without importing from the enterprise contract directly. Backend values 2/3 are named `Running`/\r\n * `Off` in core (the backend enum names them `Enabled`/`Disabled`; the numeric values are identical).\r\n */\r\nexport { VMEnabledState };\r\n\r\n/** Replication roles reported for a virtual machine. */\r\nexport { VMReplicationMode };\r\n\r\n/**\r\n * Cluster-specific properties bag — the enterprise {@link ClusterProperties} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend model `ClusterObjectProperties`),\r\n * reachable as `properties` on a {@link VirtualizationCluster}. Re-exported unchanged.\r\n */\r\nexport type { ClusterProperties };\r\n\r\n/**\r\n * A single member node of a failover cluster — the enterprise {@link ClusterNode} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, a direct copy of the gateway backend model `ClusterNodeObject`), the\r\n * element type of {@link ClusterProperties.clusterNodes}. Re-exported unchanged so callers can name\r\n * the type when they iterate a cluster's nodes. Unlike the surrounding properties bag this shape is\r\n * **closed**: it exposes only its named backend fields.\r\n */\r\nexport type { ClusterNode };\r\n\r\n/**\r\n * Cluster-node state enum — the enterprise {@link ClusterNodeState} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, a direct copy of the gateway backend enum `ClusterNodeState`),\r\n * reported on each entry of a {@link VirtualizationCluster}'s `properties.clusterNodes`. Re-exported\r\n * unchanged. Because the value is a plain number, an unrecognized future state still deserializes\r\n * rather than being rejected.\r\n */\r\nexport { ClusterNodeState };\r\n\r\n/**\r\n * Host-specific properties bag — the enterprise {@link HostProperties} (single-sourced in\r\n * `@microsoft/windows-admin-center-sdk/core/enterprise/enterprise-models`, mirroring the gateway backend model `HostObjectProperties`), reachable\r\n * as `properties` on a {@link VirtualizationHost}. Re-exported unchanged. It carries no host-specific\r\n * fields today; host identity lives on the base resource (`name`/`displayName`).\r\n */\r\nexport type { HostProperties };\r\n"]}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* The message is developer-facing (caught by extension authors, not displayed to end users), so it
|
|
12
12
|
* is not localized, consistent with other thrown errors in this package.
|
|
13
13
|
*
|
|
14
|
-
* Prefer gating data calls behind `
|
|
14
|
+
* Prefer gating data calls behind `whenActive()` (whose availability check never errors); this error is the
|
|
15
15
|
* backstop for callers that do not.
|
|
16
16
|
*/
|
|
17
17
|
export declare class VirtualizationUnavailableError extends Error {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* The message is developer-facing (caught by extension authors, not displayed to end users), so it
|
|
12
12
|
* is not localized, consistent with other thrown errors in this package.
|
|
13
13
|
*
|
|
14
|
-
* Prefer gating data calls behind `
|
|
14
|
+
* Prefer gating data calls behind `whenActive()` (whose availability check never errors); this error is the
|
|
15
15
|
* backstop for callers that do not.
|
|
16
16
|
*/
|
|
17
17
|
export class VirtualizationUnavailableError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualization-unavailable-error.js","sourceRoot":"","sources":["../../src/virtualization/virtualization-unavailable-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACrD,uEAAuE;IACvD,MAAM,CAAU;IAEhC,8DAA8D;IAC9C,KAAK,CAAW;IAEhC,YAAY,OAAgB,EAAE,MAAe,EAAE,KAAe;QAC1D,KAAK,CAAC,OAAO,IAAI,wEAAwE,CAAC,CAAC;QAC3F,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,wEAAwE;QACxE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,8BAA8B,CAAC,SAAS,CAAC,CAAC;IAC1E,CAAC;CACJ","sourcesContent":["/**\r\n * Error thrown by `VirtualizationClient` data methods (e.g. `getHosts()`) when the\r\n * virtualization (vMode) database is not available on the current platform.\r\n *\r\n * Extensions upgrade and downgrade independently of the gateway platform, so an extension built\r\n * against the virtualization SDK may run on a platform where the vMode database does not exist\r\n * (older gateway, or enterprise mode disabled). Rather than surfacing an opaque HTTP error or a\r\n * misleading empty result, the data methods reject with this typed error so callers can detect the\r\n * condition explicitly.\r\n *\r\n * The message is developer-facing (caught by extension authors, not displayed to end users), so it\r\n * is not localized, consistent with other thrown errors in this package.\r\n *\r\n * Prefer gating data calls behind `
|
|
1
|
+
{"version":3,"file":"virtualization-unavailable-error.js","sourceRoot":"","sources":["../../src/virtualization/virtualization-unavailable-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACrD,uEAAuE;IACvD,MAAM,CAAU;IAEhC,8DAA8D;IAC9C,KAAK,CAAW;IAEhC,YAAY,OAAgB,EAAE,MAAe,EAAE,KAAe;QAC1D,KAAK,CAAC,OAAO,IAAI,wEAAwE,CAAC,CAAC;QAC3F,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,wEAAwE;QACxE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,8BAA8B,CAAC,SAAS,CAAC,CAAC;IAC1E,CAAC;CACJ","sourcesContent":["/**\r\n * Error thrown by `VirtualizationClient` data methods (e.g. `getHosts()`) when the\r\n * virtualization (vMode) database is not available on the current platform.\r\n *\r\n * Extensions upgrade and downgrade independently of the gateway platform, so an extension built\r\n * against the virtualization SDK may run on a platform where the vMode database does not exist\r\n * (older gateway, or enterprise mode disabled). Rather than surfacing an opaque HTTP error or a\r\n * misleading empty result, the data methods reject with this typed error so callers can detect the\r\n * condition explicitly.\r\n *\r\n * The message is developer-facing (caught by extension authors, not displayed to end users), so it\r\n * is not localized, consistent with other thrown errors in this package.\r\n *\r\n * Prefer gating data calls behind `whenActive()` (whose availability check never errors); this error is the\r\n * backstop for callers that do not.\r\n */\r\nexport class VirtualizationUnavailableError extends Error {\r\n /** The HTTP status that indicated unavailability (404), when known. */\r\n public readonly status?: number;\r\n\r\n /** The original error that triggered this, when available. */\r\n public readonly cause?: unknown;\r\n\r\n constructor(message?: string, status?: number, cause?: unknown) {\r\n super(message ?? 'The virtualization (vMode) database is not available on this platform.');\r\n this.name = 'VirtualizationUnavailableError';\r\n this.status = status;\r\n this.cause = cause;\r\n\r\n // Restore the prototype chain for instanceof checks when targeting ES5.\r\n Object.setPrototypeOf(this, VirtualizationUnavailableError.prototype);\r\n }\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/windows-admin-center-sdk",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Microsoft - Windows Admin Center Software Development Kit",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"author": {
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
"bin": {
|
|
11
11
|
"wac": "./wac-cli/dist/index.js"
|
|
12
12
|
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=24.0.0"
|
|
15
|
+
},
|
|
13
16
|
"dependencies": {
|
|
14
17
|
"@microsoft/signalr": "8.0.7",
|
|
15
18
|
"web-vitals": "2.1.4",
|
|
@@ -19,7 +22,7 @@
|
|
|
19
22
|
"@angular-eslint/template-parser": "20.3.0",
|
|
20
23
|
"@typescript-eslint/eslint-plugin": "^8.46.0",
|
|
21
24
|
"@typescript-eslint/parser": "^8.46.0",
|
|
22
|
-
"ajv": "^6.
|
|
25
|
+
"ajv": "^6.15.0",
|
|
23
26
|
"del": "^8.0.1",
|
|
24
27
|
"eslint": "^9.39.4",
|
|
25
28
|
"eslint-plugin-import": "^2.32.0",
|
|
@@ -37,24 +40,16 @@
|
|
|
37
40
|
"rxjs": "~7.8.1"
|
|
38
41
|
},
|
|
39
42
|
"peerDependencies": {
|
|
40
|
-
"@angular/
|
|
41
|
-
"@angular/
|
|
42
|
-
"@angular/
|
|
43
|
-
"@angular/
|
|
44
|
-
"@angular/
|
|
45
|
-
"@angular/
|
|
46
|
-
"@angular/platform-browser-dynamic": "20.3.25",
|
|
47
|
-
"@angular/router": "20.3.25",
|
|
43
|
+
"@angular/common": "20.3.34",
|
|
44
|
+
"@angular/compiler": "20.3.34",
|
|
45
|
+
"@angular/core": "20.3.34",
|
|
46
|
+
"@angular/forms": "20.3.34",
|
|
47
|
+
"@angular/platform-browser": "20.3.34",
|
|
48
|
+
"@angular/router": "20.3.34",
|
|
48
49
|
"chart.js": "2.9.4",
|
|
49
50
|
"rxjs": "~7.8.1",
|
|
50
51
|
"zone.js": "~0.15.1",
|
|
51
52
|
"react": "^18",
|
|
52
|
-
"react-dom": "^18"
|
|
53
|
-
"vite": "^8.0.16"
|
|
54
|
-
},
|
|
55
|
-
"peerDependenciesMeta": {
|
|
56
|
-
"vite": {
|
|
57
|
-
"optional": true
|
|
58
|
-
}
|
|
53
|
+
"react-dom": "^18"
|
|
59
54
|
}
|
|
60
55
|
}
|
|
@@ -4,6 +4,8 @@ export interface InitOptions {
|
|
|
4
4
|
version?: string;
|
|
5
5
|
powerShellModuleName?: string;
|
|
6
6
|
powerShellPrefix?: string;
|
|
7
|
+
/** Runs after extension services are ready and before the initialized context is exposed. */
|
|
8
|
+
onContextReady?: (appContext: AppContextService) => void;
|
|
7
9
|
}
|
|
8
10
|
export interface InitResult {
|
|
9
11
|
appContext: AppContextService | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAppContextInit.d.ts","sourceRoot":"","sources":["../../src/hooks/useAppContextInit.ts"],"names":[],"mappings":"AAKA,OAAO,iBAAiB,MAAM,+BAA+B,CAAC;AAM9D,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6FAA6F;IAC7F,cAAc,CAAC,EAAE,CAAC,UAAU,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC1D;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACrC,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,CA+HlE"}
|