miravo 0.4.0 → 0.6.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/README.md +1 -1
- package/console-dist/assets/activity-DsWeRq4h.js +1 -0
- package/console-dist/assets/api-4AqKvsm9.js +1 -0
- package/console-dist/assets/arrow-right-Ea_UhTNi.js +1 -0
- package/console-dist/assets/arrow-up-down-DFSjzzl2.js +1 -0
- package/console-dist/assets/blueprint-card-classes-DBFCDy0M.js +1 -0
- package/console-dist/assets/box-C1WaoOMF.js +1 -0
- package/console-dist/assets/card-BjeP32PN.js +1 -0
- package/console-dist/assets/catalog-BJzyzbLR.js +1 -0
- package/console-dist/assets/catalog-DKjEm-c4.js +1 -0
- package/console-dist/assets/catalog-template-icons-BrUeHaCY.js +1 -0
- package/console-dist/assets/checkbox-DZlJXTE4.js +1 -0
- package/console-dist/assets/chunk-OE4NN4TA-CEjpfhS6.js +3 -0
- package/console-dist/assets/combobox-BGnuCYxO.js +1 -0
- package/console-dist/assets/control-CPhvwx9o.js +1 -0
- package/console-dist/assets/control-Cg2up9NA.js +1 -0
- package/console-dist/assets/copy-button-WkbNkMcd.js +1 -0
- package/console-dist/assets/createLucideIcon-Bwxw859K.js +1 -0
- package/console-dist/assets/deploy-tab-JeWDwPoZ.js +1 -0
- package/console-dist/assets/dist-BhbDML0a.js +1 -0
- package/console-dist/assets/dist-Cy8XTNFT.js +2 -0
- package/console-dist/assets/download-DQ6NH16U.js +1 -0
- package/console-dist/assets/engine-store-CrLnz692.js +1 -0
- package/console-dist/assets/events-CXm29Ok4.js +1 -0
- package/console-dist/assets/events-D01IxhnP.js +1 -0
- package/console-dist/assets/fleet-CfxbKXt9.js +1 -0
- package/console-dist/assets/fleet-lotMGVqe.js +1 -0
- package/console-dist/assets/format-kXTonpDJ.js +1 -0
- package/console-dist/assets/gauge-Ci8zNZlk.js +1 -0
- package/console-dist/assets/get-error-message-3Q5Q-2G5.js +1 -0
- package/console-dist/assets/index-CVPKSDvJ.js +12 -0
- package/console-dist/assets/index-DJkgDeun.css +2 -0
- package/console-dist/assets/input-BWEQFptx.js +1 -0
- package/console-dist/assets/instance-detail-C5IVwuh3.js +1 -0
- package/console-dist/assets/label-uephX5ZG.js +1 -0
- package/console-dist/assets/layers-CUsLQ1fq.js +1 -0
- package/console-dist/assets/login-C3RJli0m.js +126 -0
- package/console-dist/assets/models-B_UioWQ5.js +1 -0
- package/console-dist/assets/models-_IPlPiZ7.js +1 -0
- package/console-dist/assets/not-found-B8gAm08S.js +1 -0
- package/console-dist/assets/platform-targets-R3T-4eJ7.js +1 -0
- package/console-dist/assets/platforms-BWh0BQ3Y.js +1 -0
- package/console-dist/assets/platforms-DStNbtVc.js +1 -0
- package/console-dist/assets/proxy-CsnYqnPp.js +9 -0
- package/console-dist/assets/query-keys-BvtE7BMs.js +1 -0
- package/console-dist/assets/radio-CoHegOv5.js +1 -0
- package/console-dist/assets/rolldown-runtime-COnpUsM8.js +1 -0
- package/console-dist/assets/select-CeO4vP0G.js +1 -0
- package/console-dist/assets/select-display-items-CIzY8953.js +1 -0
- package/console-dist/assets/server-D9Kfn8fQ.js +1 -0
- package/console-dist/assets/shallow-6lGjQhtJ.js +1 -0
- package/console-dist/assets/tags-CiXOIHtY.js +4 -0
- package/console-dist/assets/tags-FQCXIxrP.js +1 -0
- package/console-dist/assets/tooltip-HGLF366Q.js +1 -0
- package/console-dist/assets/transition-nav-link-Df4Rk6vV.js +1 -0
- package/console-dist/assets/transition-types-CPlGtM8w.js +1 -0
- package/console-dist/assets/triangle-alert-adNk_sea.js +1 -0
- package/console-dist/assets/use-platform-stream-DGbK1k2L.js +2 -0
- package/console-dist/assets/use-transition-navigate-CCpcWXB0.js +2 -0
- package/console-dist/assets/validation-Blvud9_O.js +1 -0
- package/console-dist/assets/vendor-charts-CAZdaPlq.js +60 -0
- package/console-dist/assets/vendor-table-wd8JuMmT.js +4 -0
- package/console-dist/assets/vendor-ui-ByahnaY0.js +1 -0
- package/console-dist/index.html +70 -2
- package/package.json +9 -8
- package/src/__tests__/integration/executable-methods-runner.ts +7 -6
- package/src/__tests__/integration/executable-methods.integration.ts +214 -122
- package/src/__tests__/integration/opcua-concurrent-clients.integration.ts +314 -0
- package/src/commands/adapter.ts +180 -7
- package/src/commands/apply.test.ts +62 -0
- package/src/commands/apply.ts +216 -0
- package/src/commands/cleanup.test.ts +34 -0
- package/src/commands/cleanup.ts +201 -0
- package/src/commands/export.test.ts +51 -0
- package/src/commands/export.ts +404 -0
- package/src/commands/fork.ts +2 -2
- package/src/commands/inject.ts +2 -2
- package/src/commands/load.ts +1 -1
- package/src/commands/logs.ts +13 -15
- package/src/commands/models.test.ts +1 -1
- package/src/commands/models.ts +1 -1
- package/src/commands/pause.ts +3 -3
- package/src/commands/platforms.test.ts +186 -0
- package/src/commands/platforms.ts +371 -0
- package/src/commands/remove.ts +1 -1
- package/src/commands/reset.ts +2 -2
- package/src/commands/spawn.ts +2 -2
- package/src/commands/speed.ts +2 -2
- package/src/commands/start/adapter-config.ts +157 -0
- package/src/commands/start/catalog-le-dt.test.ts +50 -0
- package/src/commands/start/catalog-le-dt.ts +187 -0
- package/src/commands/start/catalog-model-schema.ts +89 -0
- package/src/commands/start/catalog-template-detail.ts +54 -0
- package/src/commands/start/daemon.ts +255 -0
- package/src/commands/start/display.ts +150 -0
- package/src/commands/start/engine-setup.ts +247 -0
- package/src/commands/start/events.ts +126 -0
- package/src/commands/start/index.ts +897 -0
- package/src/commands/start/protocol-plans.ts +239 -0
- package/src/commands/start/template-loader.ts +197 -0
- package/src/commands/start/template-resolver.ts +185 -0
- package/src/commands/start/types.ts +73 -0
- package/src/commands/start.test.ts +137 -16
- package/src/commands/status.ts +1 -1
- package/src/commands/stop.ts +19 -8
- package/src/commands/templates.test.ts +1 -1
- package/src/commands/templates.ts +1 -3
- package/src/index.ts +11 -3
- package/src/lib/admin-auth.ts +157 -0
- package/src/lib/admin-client.test.ts +31 -15
- package/src/lib/admin-client.ts +106 -6
- package/src/lib/admin-platform-routes.ts +1017 -0
- package/src/lib/admin-platform-stream.test.ts +434 -0
- package/src/lib/admin-platform-stream.ts +788 -0
- package/src/lib/admin-responses.ts +211 -0
- package/src/lib/admin-server.test.ts +274 -55
- package/src/lib/admin-server.ts +387 -248
- package/src/lib/auth-store.ts +87 -0
- package/src/lib/daemon-registry.ts +12 -14
- package/src/lib/le/le-apply.test.ts +591 -0
- package/src/lib/le/le-apply.ts +832 -0
- package/src/lib/le/le-auth.ts +89 -0
- package/src/lib/le/le-cleanup.test.ts +168 -0
- package/src/lib/le/le-cleanup.ts +399 -0
- package/src/lib/le/le-cli-helpers.ts +77 -0
- package/src/lib/le/le-client.ts +184 -0
- package/src/lib/le/le-concurrency.test.ts +157 -0
- package/src/lib/le/le-concurrency.ts +78 -0
- package/src/lib/le/le-connection-test.ts +42 -0
- package/src/lib/le/le-devicehub-properties.test.ts +53 -0
- package/src/lib/le/le-devicehub-properties.ts +33 -0
- package/src/lib/le/le-devicehub.ts +213 -0
- package/src/lib/le/le-digital-twins.ts +285 -0
- package/src/lib/le/le-drivers.ts +23 -0
- package/src/lib/le/le-endpoint.ts +40 -0
- package/src/lib/le/le-environments.test.ts +73 -0
- package/src/lib/le/le-environments.ts +156 -0
- package/src/lib/le/le-markers.ts +87 -0
- package/src/lib/le/le-plan.test.ts +26 -0
- package/src/lib/le/le-plan.ts +109 -0
- package/src/lib/le/le-platform-operations.test.ts +198 -0
- package/src/lib/le/le-platform-operations.ts +340 -0
- package/src/lib/le/le-static-model-schema.ts +78 -0
- package/src/lib/le/le-static-planner.test.ts +255 -0
- package/src/lib/le/le-static-planner.ts +442 -0
- package/src/lib/le/le-template-exporter.test.ts +527 -0
- package/src/lib/le/le-template-exporter.ts +459 -0
- package/src/lib/le/le-value-types.ts +23 -0
- package/src/lib/mqtt-client.ts +1 -2
- package/src/lib/resolve-simulation.ts +1 -6
- package/src/lib/session-store.ts +110 -0
- package/src/lib/shutdown.test.ts +184 -2
- package/src/lib/shutdown.ts +104 -34
- package/src/lib/template-category.ts +3 -3
- package/src/lib/template-locator.ts +8 -2
- package/src/lib/ws-hub.ts +72 -46
- package/src/logger.ts +39 -14
- package/src/output.ts +3 -0
- package/console-dist/assets/index-C3XMYq26.css +0 -2
- package/console-dist/assets/index-hUJSpKtB.js +0 -119
- package/src/commands/start.ts +0 -2023
package/src/lib/admin-client.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
EngineStateSnapshotSchema,
|
|
11
11
|
MiravoError,
|
|
12
12
|
} from "@miravo/shared";
|
|
13
|
+
import { loadCredential } from "./auth-store.ts";
|
|
13
14
|
|
|
14
15
|
const DEFAULT_ADMIN_HOST = "127.0.0.1";
|
|
15
16
|
const DEFAULT_ADMIN_PORT = 8080;
|
|
@@ -87,19 +88,67 @@ function parseAdminUrl(input: string): string {
|
|
|
87
88
|
return url.toString().replace(/\/$/, "");
|
|
88
89
|
}
|
|
89
90
|
|
|
90
|
-
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Session-based auth for CLI client
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
let sessionCookie: string | null = null;
|
|
96
|
+
|
|
97
|
+
async function loginToAdmin(adminUrl: string): Promise<void> {
|
|
98
|
+
// Resolve password: env > file > default
|
|
99
|
+
const envPassword = Bun.env["MIRAVO_ADMIN_PASSWORD"];
|
|
100
|
+
let password = "admin";
|
|
101
|
+
if (envPassword && envPassword.trim().length > 0) {
|
|
102
|
+
password = envPassword;
|
|
103
|
+
} else {
|
|
104
|
+
const credential = await loadCredential();
|
|
105
|
+
// If credential file exists, we can't reverse the hash — use "admin" as default.
|
|
106
|
+
// The server will verify against the stored hash. If the user changed their password,
|
|
107
|
+
// they need to set MIRAVO_ADMIN_PASSWORD env var for CLI access.
|
|
108
|
+
if (!credential) {
|
|
109
|
+
password = "admin";
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const response = await fetch(`${adminUrl}/auth/login`, {
|
|
114
|
+
method: "POST",
|
|
115
|
+
headers: { "content-type": "application/json" },
|
|
116
|
+
body: JSON.stringify({ username: "admin", password }),
|
|
117
|
+
signal: AbortSignal.timeout(10_000),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
throw new MiravoError(
|
|
122
|
+
"CLI authentication failed.",
|
|
123
|
+
"Set MIRAVO_ADMIN_PASSWORD or log in with default credentials (admin/admin).",
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const setCookie = response.headers.get("set-cookie");
|
|
128
|
+
if (setCookie) {
|
|
129
|
+
// Extract just the cookie value (before first ;)
|
|
130
|
+
sessionCookie = setCookie.split(";")[0] ?? null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function ensureAuthenticated(adminUrl: string): Promise<void> {
|
|
135
|
+
if (sessionCookie) return;
|
|
136
|
+
await loginToAdmin(adminUrl);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function buildRequestHeaders(body?: string): Record<string, string> {
|
|
91
140
|
const headers: Record<string, string> = {};
|
|
92
141
|
if (body) {
|
|
93
142
|
headers["content-type"] = "application/json";
|
|
94
143
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
headers["authorization"] = `Bearer ${adminToken}`;
|
|
144
|
+
if (sessionCookie) {
|
|
145
|
+
headers["cookie"] = sessionCookie;
|
|
98
146
|
}
|
|
99
|
-
return
|
|
147
|
+
return headers;
|
|
100
148
|
}
|
|
101
149
|
|
|
102
150
|
async function requestJson<T>(options: RequestJsonOptions<T>): Promise<T> {
|
|
151
|
+
await ensureAuthenticated(options.baseUrl);
|
|
103
152
|
const requestUrl = new URL(options.path, `${options.baseUrl}/`).toString();
|
|
104
153
|
const controller = new AbortController();
|
|
105
154
|
const timer = setTimeout(() => controller.abort(), options.timeoutMs);
|
|
@@ -128,6 +177,18 @@ async function requestJson<T>(options: RequestJsonOptions<T>): Promise<T> {
|
|
|
128
177
|
);
|
|
129
178
|
}
|
|
130
179
|
|
|
180
|
+
// Re-authenticate on session expiry and retry once
|
|
181
|
+
if (response.status === 401) {
|
|
182
|
+
sessionCookie = null;
|
|
183
|
+
await loginToAdmin(options.baseUrl);
|
|
184
|
+
response = await fetch(requestUrl, {
|
|
185
|
+
method: options.method ?? "GET",
|
|
186
|
+
headers: buildRequestHeaders(options.body),
|
|
187
|
+
body: options.body,
|
|
188
|
+
signal: controller.signal,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
131
192
|
const text = await response.text();
|
|
132
193
|
let parsedJson: unknown;
|
|
133
194
|
if (text.length > 0) {
|
|
@@ -223,4 +284,43 @@ async function executeAdminCommand(
|
|
|
223
284
|
});
|
|
224
285
|
}
|
|
225
286
|
|
|
226
|
-
|
|
287
|
+
/** Schema that accepts any JSON object — used for adapter introspection (protocol-specific shape). */
|
|
288
|
+
const AnyObjectSchema = {
|
|
289
|
+
safeParse(value: unknown): SafeParseResult<Record<string, unknown>> {
|
|
290
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
291
|
+
return { success: true, data: value as Record<string, unknown> };
|
|
292
|
+
}
|
|
293
|
+
return { success: false };
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
async function getManifest(adminUrl: string, timeoutMs: number): Promise<Record<string, unknown>> {
|
|
298
|
+
return requestJson({
|
|
299
|
+
baseUrl: adminUrl,
|
|
300
|
+
path: "/manifest",
|
|
301
|
+
timeoutMs,
|
|
302
|
+
schema: AnyObjectSchema,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async function getLeDtJson(
|
|
307
|
+
adminUrl: string,
|
|
308
|
+
modelName: string,
|
|
309
|
+
timeoutMs: number,
|
|
310
|
+
): Promise<Record<string, unknown>> {
|
|
311
|
+
return requestJson({
|
|
312
|
+
baseUrl: adminUrl,
|
|
313
|
+
path: `/catalog/models/${encodeURIComponent(modelName)}/le-dt.json`,
|
|
314
|
+
timeoutMs,
|
|
315
|
+
schema: AnyObjectSchema,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export {
|
|
320
|
+
executeAdminCommand,
|
|
321
|
+
getAdminSnapshot,
|
|
322
|
+
getAdminState,
|
|
323
|
+
getLeDtJson,
|
|
324
|
+
getManifest,
|
|
325
|
+
resolveAdminUrl,
|
|
326
|
+
};
|