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 CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { S as run } from "./cli-Dc8HDZ6q.mjs";
2
+ import { S as run } from "./cli-Dx1dw7Cy.mjs";
3
3
 
4
4
  //#region src/bin.ts
5
5
  run();
@@ -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("data", (chunk) => {
27
- const nextChunk = typeof chunk === "string" ? Buffer.from(chunk) : chunk;
28
- this.buffer = Buffer.concat([this.buffer, nextChunk]);
29
- this.readFrames();
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.write(encodeWebSocketFrame(JSON.stringify(message)));
42
+ if (this.socket.readyState === WebSocket.OPEN) this.socket.send(JSON.stringify(message));
37
43
  }
38
44
  close() {
39
- this.socket.end();
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
- server.on("upgrade", (request, socket) => {
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
- const key = request.headers["sec-websocket-key"];
391
- if (typeof key !== "string") {
392
- socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
393
- return;
394
- }
395
- const accept = crypto.createHash("sha1").update(`${key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`).digest("base64");
396
- socket.write([
397
- "HTTP/1.1 101 Switching Protocols",
398
- "Upgrade: websocket",
399
- "Connection: Upgrade",
400
- `Sec-WebSocket-Accept: ${accept}`,
401
- "\r\n"
402
- ].join("\r\n"));
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?: any, entryUrl?: string): Promise<void>;
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-Dc8HDZ6q.mjs";
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.2",
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
- "@statelyai/sdk": "0.16.1"
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
  },