statelyai 0.8.2 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.mjs +1 -1
- package/dist/{cli-Dc8HDZ6q.mjs → cli-Dx1dw7Cy.mjs} +34 -93
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +4 -2
package/dist/bin.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
10
10
|
import { promisify } from "node:util";
|
|
11
11
|
import { Args, Command, Flags, flush, handle, run } from "@oclif/core";
|
|
12
12
|
import * as http from "node:http";
|
|
13
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
13
14
|
import os from "node:os";
|
|
14
15
|
import { StudioApiError, buildAuthorizeUrl, createPkcePair, createStatelyClient, discoverAuthorizationServer, discoverProtectedResource, exchangeCodeForToken, findStatelyPragmaAttachments, getStatelyPragma, refreshToken, registerOAuthClient } from "@statelyai/sdk";
|
|
15
16
|
import { planSync, pullSync, pushLocalMachineLinks } from "@statelyai/sdk/sync";
|
|
@@ -19,68 +20,36 @@ const DEFAULT_SYNC_MAX_FILES = 150;
|
|
|
19
20
|
const DEFAULT_SYNC_MAX_BYTES = 2e6;
|
|
20
21
|
const supportedDocumentPattern = /\.(?:c|m)?(?:jsx?|tsx?)$|\.jsonc?$|\.ya?ml$|\.mmd$|\.mermaid$/i;
|
|
21
22
|
var WebSocketClient = class {
|
|
22
|
-
buffer = Buffer.alloc(0);
|
|
23
23
|
listeners = /* @__PURE__ */ new Set();
|
|
24
24
|
constructor(socket) {
|
|
25
25
|
this.socket = socket;
|
|
26
|
-
socket.on("
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
socket.on("message", (data, isBinary) => {
|
|
27
|
+
if (isBinary) return;
|
|
28
|
+
let message;
|
|
29
|
+
try {
|
|
30
|
+
message = JSON.parse(rawDataToBuffer(data).toString("utf8"));
|
|
31
|
+
} catch {
|
|
32
|
+
socket.close(1007, "Invalid JSON payload");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
for (const listener of this.listeners) listener(message);
|
|
30
36
|
});
|
|
31
37
|
}
|
|
32
38
|
onMessage(listener) {
|
|
33
39
|
this.listeners.add(listener);
|
|
34
40
|
}
|
|
35
41
|
send(message) {
|
|
36
|
-
this.socket.
|
|
42
|
+
if (this.socket.readyState === WebSocket.OPEN) this.socket.send(JSON.stringify(message));
|
|
37
43
|
}
|
|
38
44
|
close() {
|
|
39
|
-
this.socket.
|
|
40
|
-
}
|
|
41
|
-
readFrames() {
|
|
42
|
-
while (this.buffer.length >= 2) {
|
|
43
|
-
const first = this.buffer[0];
|
|
44
|
-
const second = this.buffer[1];
|
|
45
|
-
const opcode = first & 15;
|
|
46
|
-
const masked = (second & 128) !== 0;
|
|
47
|
-
let length = second & 127;
|
|
48
|
-
let offset = 2;
|
|
49
|
-
if (length === 126) {
|
|
50
|
-
if (this.buffer.length < offset + 2) return;
|
|
51
|
-
length = this.buffer.readUInt16BE(offset);
|
|
52
|
-
offset += 2;
|
|
53
|
-
} else if (length === 127) {
|
|
54
|
-
if (this.buffer.length < offset + 8) return;
|
|
55
|
-
const bigLength = this.buffer.readBigUInt64BE(offset);
|
|
56
|
-
if (bigLength > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
57
|
-
this.socket.destroy(/* @__PURE__ */ new Error("WebSocket frame is too large."));
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
length = Number(bigLength);
|
|
61
|
-
offset += 8;
|
|
62
|
-
}
|
|
63
|
-
const maskLength = masked ? 4 : 0;
|
|
64
|
-
if (this.buffer.length < offset + maskLength + length) return;
|
|
65
|
-
const mask = masked ? this.buffer.subarray(offset, offset + 4) : void 0;
|
|
66
|
-
offset += maskLength;
|
|
67
|
-
const payload = Buffer.from(this.buffer.subarray(offset, offset + length));
|
|
68
|
-
this.buffer = this.buffer.subarray(offset + length);
|
|
69
|
-
if (mask) for (let index = 0; index < payload.length; index++) payload[index] = payload[index] ^ mask[index % 4];
|
|
70
|
-
if (opcode === 8) {
|
|
71
|
-
this.close();
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
if (opcode === 9) {
|
|
75
|
-
this.socket.write(encodeWebSocketFrame(payload, 10));
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (opcode !== 1) continue;
|
|
79
|
-
const message = JSON.parse(payload.toString("utf8"));
|
|
80
|
-
for (const listener of this.listeners) listener(message);
|
|
81
|
-
}
|
|
45
|
+
if (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING) this.socket.close();
|
|
82
46
|
}
|
|
83
47
|
};
|
|
48
|
+
function rawDataToBuffer(data) {
|
|
49
|
+
if (Array.isArray(data)) return Buffer.concat(data);
|
|
50
|
+
if (data instanceof ArrayBuffer) return Buffer.from(data);
|
|
51
|
+
return Buffer.from(data);
|
|
52
|
+
}
|
|
84
53
|
var RemoteEditorSession = class {
|
|
85
54
|
currentGraph;
|
|
86
55
|
lastPersistedGraph;
|
|
@@ -382,35 +351,25 @@ async function openEditor(options) {
|
|
|
382
351
|
response.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
383
352
|
response.end(getCliWebviewContent({ editorUrl: options.editorUrl }));
|
|
384
353
|
});
|
|
385
|
-
|
|
354
|
+
const webSocketServer = new WebSocketServer({ noServer: true });
|
|
355
|
+
server.on("upgrade", (request, socket, head) => {
|
|
386
356
|
if (request.url !== "/ws") {
|
|
387
357
|
socket.end("HTTP/1.1 404 Not Found\r\n\r\n");
|
|
388
358
|
return;
|
|
389
359
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
activeClient?.close();
|
|
404
|
-
session?.dispose();
|
|
405
|
-
activeClient = new WebSocketClient(socket);
|
|
406
|
-
session = new RemoteEditorSession({
|
|
407
|
-
...options,
|
|
408
|
-
fileName,
|
|
409
|
-
rootUri,
|
|
410
|
-
rootDir
|
|
411
|
-
}, (message) => activeClient?.send(message));
|
|
412
|
-
activeClient.onMessage((message) => {
|
|
413
|
-
session?.receiveMessage(message);
|
|
360
|
+
webSocketServer.handleUpgrade(request, socket, head, (webSocket) => {
|
|
361
|
+
activeClient?.close();
|
|
362
|
+
session?.dispose();
|
|
363
|
+
activeClient = new WebSocketClient(webSocket);
|
|
364
|
+
session = new RemoteEditorSession({
|
|
365
|
+
...options,
|
|
366
|
+
fileName,
|
|
367
|
+
rootUri,
|
|
368
|
+
rootDir
|
|
369
|
+
}, (message) => activeClient?.send(message));
|
|
370
|
+
activeClient.onMessage((message) => {
|
|
371
|
+
session?.receiveMessage(message);
|
|
372
|
+
});
|
|
414
373
|
});
|
|
415
374
|
});
|
|
416
375
|
await listen(server, options.port, options.host);
|
|
@@ -423,6 +382,7 @@ async function openEditor(options) {
|
|
|
423
382
|
const shutdown = () => {
|
|
424
383
|
session?.dispose();
|
|
425
384
|
activeClient?.close();
|
|
385
|
+
webSocketServer.close();
|
|
426
386
|
server.close();
|
|
427
387
|
};
|
|
428
388
|
process.once("SIGINT", () => {
|
|
@@ -589,25 +549,6 @@ function getCliWebviewContent(options) {
|
|
|
589
549
|
</body>
|
|
590
550
|
</html>`;
|
|
591
551
|
}
|
|
592
|
-
function encodeWebSocketFrame(payload, opcode = 1) {
|
|
593
|
-
const data = typeof payload === "string" ? Buffer.from(payload) : payload;
|
|
594
|
-
const headerLength = data.length < 126 ? 2 : data.length <= 65535 ? 4 : 10;
|
|
595
|
-
const frame = Buffer.alloc(headerLength + data.length);
|
|
596
|
-
frame[0] = 128 | opcode;
|
|
597
|
-
if (data.length < 126) {
|
|
598
|
-
frame[1] = data.length;
|
|
599
|
-
data.copy(frame, 2);
|
|
600
|
-
} else if (data.length <= 65535) {
|
|
601
|
-
frame[1] = 126;
|
|
602
|
-
frame.writeUInt16BE(data.length, 2);
|
|
603
|
-
data.copy(frame, 4);
|
|
604
|
-
} else {
|
|
605
|
-
frame[1] = 127;
|
|
606
|
-
frame.writeBigUInt64BE(BigInt(data.length), 2);
|
|
607
|
-
data.copy(frame, 10);
|
|
608
|
-
}
|
|
609
|
-
return frame;
|
|
610
|
-
}
|
|
611
552
|
function listen(server, port, host) {
|
|
612
553
|
return new Promise((resolve) => {
|
|
613
554
|
server.listen(port, host, resolve);
|
package/dist/index.d.mts
CHANGED
|
@@ -397,6 +397,6 @@ declare const COMMANDS: {
|
|
|
397
397
|
logout: typeof LogoutCommand;
|
|
398
398
|
whoami: typeof WhoamiCommand;
|
|
399
399
|
};
|
|
400
|
-
declare function run(argv?:
|
|
400
|
+
declare function run(argv?: string[], entryUrl?: string): Promise<void>;
|
|
401
401
|
//#endregion
|
|
402
402
|
export { ApiKeyResolution, COMMANDS, CredentialStatus, DiscoveredMachine, InitProjectOptions, InitProjectResult, LinkedPullTarget, OAuthLoginDiscovery, ProjectMachineStatus, ProjectStatusMachine, ProjectStatusResult, PushCandidateClassification, RemoteProjectMachineTarget, ResolveApiKeyOptions, ResolvedConfiguredPullTargets, ScanProjectSourcesOptions, buildOAuthLoginStart, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverMachinesInSource, discoverOAuthLogin, discoverRemoteProjectMachineTargets, formatDiscoveredMachines, formatMissingNewMachineDirMessage, formatPlanSummary, formatProjectStatus, formatStoredCredentialSource, getEnvApiKey, getEnvCredential, inferInitProjectName, initProject, isFileGitDirty, resolveApiKey, resolveConfiguredPullTargets, resolveCredentialStatus, resolveProjectStatus, run, scanProjectMachines, scanProjectSources };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as scanProjectMachines, S as run, T as createStatelyProjectConfig, _ as isFileGitDirty, a as discoverMachinesInSource, b as resolveCredentialStatus, c as formatDiscoveredMachines, d as formatProjectStatus, f as formatStoredCredentialSource, g as initProject, h as inferInitProjectName, i as discoverLinkedPullTargets, l as formatMissingNewMachineDirMessage, m as getEnvCredential, n as buildOAuthLoginStart, o as discoverOAuthLogin, p as getEnvApiKey, r as classifyPushCandidates, s as discoverRemoteProjectMachineTargets, t as COMMANDS, u as formatPlanSummary, v as resolveApiKey, w as scanProjectSources, x as resolveProjectStatus, y as resolveConfiguredPullTargets } from "./cli-
|
|
1
|
+
import { C as scanProjectMachines, S as run, T as createStatelyProjectConfig, _ as isFileGitDirty, a as discoverMachinesInSource, b as resolveCredentialStatus, c as formatDiscoveredMachines, d as formatProjectStatus, f as formatStoredCredentialSource, g as initProject, h as inferInitProjectName, i as discoverLinkedPullTargets, l as formatMissingNewMachineDirMessage, m as getEnvCredential, n as buildOAuthLoginStart, o as discoverOAuthLogin, p as getEnvApiKey, r as classifyPushCandidates, s as discoverRemoteProjectMachineTargets, t as COMMANDS, u as formatPlanSummary, v as resolveApiKey, w as scanProjectSources, x as resolveProjectStatus, y as resolveConfiguredPullTargets } from "./cli-Dx1dw7Cy.mjs";
|
|
2
2
|
|
|
3
3
|
export { COMMANDS, buildOAuthLoginStart, classifyPushCandidates, createStatelyProjectConfig, discoverLinkedPullTargets, discoverMachinesInSource, discoverOAuthLogin, discoverRemoteProjectMachineTargets, formatDiscoveredMachines, formatMissingNewMachineDirMessage, formatPlanSummary, formatProjectStatus, formatStoredCredentialSource, getEnvApiKey, getEnvCredential, inferInitProjectName, initProject, isFileGitDirty, resolveApiKey, resolveConfiguredPullTargets, resolveCredentialStatus, resolveProjectStatus, run, scanProjectMachines, scanProjectSources };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "statelyai",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"description": "Command-line tools for Stately",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -21,9 +21,11 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@oclif/core": "^4.10.3",
|
|
24
|
-
"
|
|
24
|
+
"ws": "^8.21.0",
|
|
25
|
+
"@statelyai/sdk": "0.16.2"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
28
|
+
"@types/ws": "^8.18.1",
|
|
27
29
|
"tsdown": "0.21.0-beta.2",
|
|
28
30
|
"vitest": "^3.2.4"
|
|
29
31
|
},
|