@floegence/flowersec-core 0.16.2 → 0.16.3

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.
@@ -12,6 +12,17 @@ export type ControlplaneConfig = BaseControlplaneRequestConfig;
12
12
  export type EntryControlplaneConfig = BaseControlplaneRequestConfig & Readonly<{
13
13
  entryTicket: string;
14
14
  }>;
15
+ export declare class ControlplaneRequestError extends Error {
16
+ readonly status: number;
17
+ readonly code: string;
18
+ readonly responseBody: unknown;
19
+ constructor(args: Readonly<{
20
+ status: number;
21
+ message: string;
22
+ code?: string;
23
+ responseBody?: unknown;
24
+ }>);
25
+ }
15
26
  export declare function requestChannelGrant(config: ControlplaneConfig): Promise<ChannelInitGrant>;
16
27
  export declare function requestEntryChannelGrant(config: EntryControlplaneConfig): Promise<ChannelInitGrant>;
17
28
  export {};
@@ -1,4 +1,16 @@
1
1
  import { assertChannelInitGrant } from "../facade.js";
2
+ export class ControlplaneRequestError extends Error {
3
+ status;
4
+ code;
5
+ responseBody;
6
+ constructor(args) {
7
+ super(args.message);
8
+ this.name = "ControlplaneRequestError";
9
+ this.status = args.status;
10
+ this.code = String(args.code ?? "").trim();
11
+ this.responseBody = args.responseBody;
12
+ }
13
+ }
2
14
  function resolveFetch(fetchImpl) {
3
15
  if (fetchImpl)
4
16
  return fetchImpl;
@@ -31,7 +43,38 @@ async function requestGrant(url, init) {
31
43
  cache: "no-store",
32
44
  });
33
45
  if (!response.ok) {
34
- throw new Error(`Failed to get channel grant: ${response.status}`);
46
+ const rawBody = await response.text();
47
+ const bodyText = String(rawBody ?? "").trim();
48
+ let responseBody = bodyText;
49
+ if (bodyText !== "") {
50
+ try {
51
+ responseBody = JSON.parse(bodyText);
52
+ }
53
+ catch {
54
+ responseBody = bodyText;
55
+ }
56
+ }
57
+ let message = `Failed to get channel grant: ${response.status}`;
58
+ let code = "";
59
+ if (responseBody && typeof responseBody === "object") {
60
+ const error = responseBody.error;
61
+ if (error && typeof error === "object") {
62
+ const nextMessage = String(error.message ?? "").trim();
63
+ if (nextMessage !== "") {
64
+ message = nextMessage;
65
+ }
66
+ code = String(error.code ?? "").trim();
67
+ }
68
+ }
69
+ else if (typeof responseBody === "string" && responseBody !== "") {
70
+ message = responseBody;
71
+ }
72
+ throw new ControlplaneRequestError({
73
+ status: response.status,
74
+ message,
75
+ code,
76
+ responseBody,
77
+ });
35
78
  }
36
79
  const data = (await response.json());
37
80
  if (!data?.grant_client) {
@@ -1,6 +1,6 @@
1
1
  export type { ConnectBrowserOptions, DirectConnectBrowserOptions, TunnelConnectBrowserOptions } from "./connect.js";
2
2
  export { connectBrowser, connectDirectBrowser, connectTunnelBrowser } from "./connect.js";
3
3
  export type { ControlplaneConfig, EntryControlplaneConfig } from "./controlplane.js";
4
- export { requestChannelGrant, requestEntryChannelGrant } from "./controlplane.js";
4
+ export { ControlplaneRequestError, requestChannelGrant, requestEntryChannelGrant } from "./controlplane.js";
5
5
  export type { BrowserReconnectConfig, DirectBrowserReconnectConfig, TunnelBrowserReconnectConfig, } from "./reconnectConfig.js";
6
6
  export { createBrowserReconnectConfig, createDirectBrowserReconnectConfig, createTunnelBrowserReconnectConfig, } from "./reconnectConfig.js";
@@ -1,3 +1,3 @@
1
1
  export { connectBrowser, connectDirectBrowser, connectTunnelBrowser } from "./connect.js";
2
- export { requestChannelGrant, requestEntryChannelGrant } from "./controlplane.js";
2
+ export { ControlplaneRequestError, requestChannelGrant, requestEntryChannelGrant } from "./controlplane.js";
3
3
  export { createBrowserReconnectConfig, createDirectBrowserReconnectConfig, createTunnelBrowserReconnectConfig, } from "./reconnectConfig.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/flowersec-core",
3
- "version": "0.16.2",
3
+ "version": "0.16.3",
4
4
  "description": "Flowersec core TypeScript library (browser-friendly E2EE + multiplexing over WebSocket).",
5
5
  "license": "MIT",
6
6
  "repository": {