@roam-research/roam-tools-core 0.5.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 +23 -8
- package/dist/index.d.ts +3 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -8
- package/dist/operations/blocks.d.ts +25 -20
- package/dist/operations/blocks.d.ts.map +1 -1
- package/dist/operations/blocks.js +66 -15
- package/dist/operations/datalog.d.ts +15 -0
- package/dist/operations/datalog.d.ts.map +1 -0
- package/dist/operations/datalog.js +16 -0
- package/dist/operations/files.d.ts +6 -7
- package/dist/operations/files.d.ts.map +1 -1
- package/dist/operations/files.js +18 -5
- package/dist/operations/navigation.d.ts +9 -10
- package/dist/operations/navigation.d.ts.map +1 -1
- package/dist/operations/navigation.js +4 -1
- package/dist/operations/pages.d.ts +15 -13
- package/dist/operations/pages.d.ts.map +1 -1
- package/dist/operations/pages.js +34 -10
- package/dist/operations/query.d.ts +10 -11
- package/dist/operations/query.d.ts.map +1 -1
- package/dist/operations/query.js +24 -6
- package/dist/operations/search.d.ts +7 -8
- package/dist/operations/search.d.ts.map +1 -1
- package/dist/operations/search.js +22 -6
- package/dist/tools.d.ts +37 -4
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +91 -80
- package/dist/types.d.ts +11 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +14 -4
- package/package.json +7 -10
- package/dist/client.d.ts +0 -34
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -275
- package/dist/connect.d.ts +0 -10
- package/dist/connect.d.ts.map +0 -1
- package/dist/connect.js +0 -477
- package/dist/graph-resolver.d.ts +0 -54
- package/dist/graph-resolver.d.ts.map +0 -1
- package/dist/graph-resolver.js +0 -338
- package/dist/operations/graphs.d.ts +0 -26
- package/dist/operations/graphs.d.ts.map +0 -1
- package/dist/operations/graphs.js +0 -214
- package/dist/roam-api.d.ts +0 -32
- package/dist/roam-api.d.ts.map +0 -1
- package/dist/roam-api.js +0 -50
package/dist/types.d.ts
CHANGED
|
@@ -14,8 +14,8 @@ export declare const GraphConfigSchema: z.ZodObject<{
|
|
|
14
14
|
accessLevel: z.ZodOptional<z.ZodEnum<["read-only", "read-append", "full"]>>;
|
|
15
15
|
lastKnownTokenStatus: z.ZodOptional<z.ZodEnum<["active", "revoked"]>>;
|
|
16
16
|
}, "strip", z.ZodTypeAny, {
|
|
17
|
-
name: string;
|
|
18
17
|
type: "hosted" | "offline";
|
|
18
|
+
name: string;
|
|
19
19
|
token: string;
|
|
20
20
|
nickname: string;
|
|
21
21
|
accessLevel?: "read-only" | "read-append" | "full" | undefined;
|
|
@@ -39,8 +39,8 @@ export declare const RoamMcpConfigSchema: z.ZodObject<{
|
|
|
39
39
|
accessLevel: z.ZodOptional<z.ZodEnum<["read-only", "read-append", "full"]>>;
|
|
40
40
|
lastKnownTokenStatus: z.ZodOptional<z.ZodEnum<["active", "revoked"]>>;
|
|
41
41
|
}, "strip", z.ZodTypeAny, {
|
|
42
|
-
name: string;
|
|
43
42
|
type: "hosted" | "offline";
|
|
43
|
+
name: string;
|
|
44
44
|
token: string;
|
|
45
45
|
nickname: string;
|
|
46
46
|
accessLevel?: "read-only" | "read-append" | "full" | undefined;
|
|
@@ -55,8 +55,8 @@ export declare const RoamMcpConfigSchema: z.ZodObject<{
|
|
|
55
55
|
}>, "many">;
|
|
56
56
|
}, "strip", z.ZodTypeAny, {
|
|
57
57
|
graphs: {
|
|
58
|
-
name: string;
|
|
59
58
|
type: "hosted" | "offline";
|
|
59
|
+
name: string;
|
|
60
60
|
token: string;
|
|
61
61
|
nickname: string;
|
|
62
62
|
accessLevel?: "read-only" | "read-append" | "full" | undefined;
|
|
@@ -75,12 +75,15 @@ export declare const RoamMcpConfigSchema: z.ZodObject<{
|
|
|
75
75
|
version?: number | undefined;
|
|
76
76
|
}>;
|
|
77
77
|
export type RoamMcpConfig = z.infer<typeof RoamMcpConfigSchema>;
|
|
78
|
-
export interface
|
|
78
|
+
export interface ToolGraph {
|
|
79
79
|
name: string;
|
|
80
80
|
type: GraphType;
|
|
81
|
-
token: string;
|
|
82
81
|
nickname: string;
|
|
83
82
|
accessLevel?: AccessLevel;
|
|
83
|
+
token?: string;
|
|
84
|
+
}
|
|
85
|
+
export interface ResolvedGraph extends ToolGraph {
|
|
86
|
+
token: string;
|
|
84
87
|
lastKnownTokenStatus?: "active" | "revoked";
|
|
85
88
|
}
|
|
86
89
|
export declare const ErrorCodes: {
|
|
@@ -277,10 +280,8 @@ export type TokenInfoResult = {
|
|
|
277
280
|
} | {
|
|
278
281
|
status: "unknown";
|
|
279
282
|
};
|
|
280
|
-
export interface
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
token: string;
|
|
284
|
-
port?: number;
|
|
283
|
+
export interface RoamActionClient {
|
|
284
|
+
call<T = unknown>(action: string, args?: unknown[]): Promise<RoamResponse<T>>;
|
|
285
|
+
getTokenInfo?(): Promise<TokenInfoResult>;
|
|
285
286
|
}
|
|
286
287
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AACpG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAGzD;AAGD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAE1E;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAE3D;AAOD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAG7C,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,aAAa,GAAG,MAAM,CAAC;AAM/D,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -16,14 +16,24 @@ export function errorResult(message) {
|
|
|
16
16
|
// Graph names can only contain alphanumeric characters, hyphens, and underscores
|
|
17
17
|
const GRAPH_NAME_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
18
18
|
export const GraphConfigSchema = z.object({
|
|
19
|
-
name: z
|
|
19
|
+
name: z
|
|
20
|
+
.string()
|
|
21
|
+
.regex(GRAPH_NAME_PATTERN, "Graph name can only contain letters, numbers, hyphens, and underscores")
|
|
22
|
+
.describe("Actual graph name in Roam"),
|
|
20
23
|
type: z.enum(["hosted", "offline"]).default("hosted").describe("Graph type"),
|
|
21
24
|
token: z.string().startsWith("roam-graph-local-token-").describe("Local API token"),
|
|
22
|
-
nickname: z
|
|
25
|
+
nickname: z
|
|
26
|
+
.string()
|
|
23
27
|
.regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "Nickname must be lowercase letters, numbers, and hyphens")
|
|
24
28
|
.describe("Short identifier for the graph (lowercase, hyphens, no spaces)"),
|
|
25
|
-
accessLevel: z
|
|
26
|
-
|
|
29
|
+
accessLevel: z
|
|
30
|
+
.enum(["read-only", "read-append", "full"])
|
|
31
|
+
.optional()
|
|
32
|
+
.describe("Token access level"),
|
|
33
|
+
lastKnownTokenStatus: z
|
|
34
|
+
.enum(["active", "revoked"])
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("Token validity status from last sync with Roam"),
|
|
27
37
|
});
|
|
28
38
|
export const RoamMcpConfigSchema = z.object({
|
|
29
39
|
version: z.number().int().positive().optional(),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roam-research/roam-tools-core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Transport-agnostic core for Roam Research MCP and CLI tools",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/Roam-Research/roam-tools.git",
|
|
@@ -15,11 +15,6 @@
|
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
16
|
"development": "./src/index.ts",
|
|
17
17
|
"import": "./dist/index.js"
|
|
18
|
-
},
|
|
19
|
-
"./connect": {
|
|
20
|
-
"types": "./dist/connect.d.ts",
|
|
21
|
-
"development": "./src/connect.ts",
|
|
22
|
-
"import": "./dist/connect.js"
|
|
23
18
|
}
|
|
24
19
|
},
|
|
25
20
|
"files": [
|
|
@@ -33,12 +28,14 @@
|
|
|
33
28
|
"node": ">=18"
|
|
34
29
|
},
|
|
35
30
|
"scripts": {
|
|
36
|
-
"prepublishOnly": "npm run --prefix ../.. build"
|
|
31
|
+
"prepublishOnly": "npm run --prefix ../.. build",
|
|
32
|
+
"test": "vitest run"
|
|
37
33
|
},
|
|
38
34
|
"dependencies": {
|
|
39
|
-
"@inquirer/prompts": "^8.2.0",
|
|
40
35
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
41
|
-
"open": "^11.0.0",
|
|
42
36
|
"zod": "^3.25.76"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"vitest": "^2.1.0"
|
|
43
40
|
}
|
|
44
41
|
}
|
package/dist/client.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { RoamResponse, RoamClientConfig, TokenInfoResult } from "./types.js";
|
|
2
|
-
export declare class RoamClient {
|
|
3
|
-
private graphName;
|
|
4
|
-
private graphType;
|
|
5
|
-
private token;
|
|
6
|
-
private port;
|
|
7
|
-
constructor(config: RoamClientConfig);
|
|
8
|
-
private getPort;
|
|
9
|
-
private openRoamDeepLink;
|
|
10
|
-
private sleep;
|
|
11
|
-
private isConnectionError;
|
|
12
|
-
private isVersionMismatch;
|
|
13
|
-
private handleVersionMismatch;
|
|
14
|
-
/**
|
|
15
|
-
* Get user-friendly guidance for authentication errors
|
|
16
|
-
*/
|
|
17
|
-
private getAuthErrorGuidance;
|
|
18
|
-
/**
|
|
19
|
-
* Get user-friendly guidance for permission errors
|
|
20
|
-
*/
|
|
21
|
-
private getPermissionErrorGuidance;
|
|
22
|
-
/**
|
|
23
|
-
* Handle API error responses based on HTTP status and error code
|
|
24
|
-
*/
|
|
25
|
-
private handleApiError;
|
|
26
|
-
private checkResponse;
|
|
27
|
-
/**
|
|
28
|
-
* Query the token info endpoint for current permissions.
|
|
29
|
-
* Best-effort: returns "unknown" on any failure except confirmed revocation.
|
|
30
|
-
*/
|
|
31
|
-
getTokenInfo(): Promise<TokenInfoResult>;
|
|
32
|
-
call<T = unknown>(action: string, args?: unknown[]): Promise<RoamResponse<T>>;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAGhB,eAAe,EAEhB,MAAM,YAAY,CAAC;AAQpB,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAuB;gBAEvB,MAAM,EAAE,gBAAgB;YAkBtB,OAAO;YAeP,gBAAgB;YAKhB,KAAK;IAInB,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,qBAAqB;IAyB7B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAgC5B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAoBlC;;OAEG;IACH,OAAO,CAAC,cAAc;IAgDtB,OAAO,CAAC,aAAa;IASrB;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC;IA0CxC,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,OAAO,EAAO,GACnB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;CAuE5B"}
|
package/dist/client.js
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
// src/core/client.ts
|
|
2
|
-
// v2.0.0 - Token-authenticated Roam Local API client
|
|
3
|
-
import { readFile } from "fs/promises";
|
|
4
|
-
import { homedir } from "os";
|
|
5
|
-
import { join } from "path";
|
|
6
|
-
import open from "open";
|
|
7
|
-
import { EXPECTED_API_VERSION, getErrorMessage, RoamError, ErrorCodes, } from "./types.js";
|
|
8
|
-
export class RoamClient {
|
|
9
|
-
graphName;
|
|
10
|
-
graphType;
|
|
11
|
-
token;
|
|
12
|
-
port = null;
|
|
13
|
-
constructor(config) {
|
|
14
|
-
if (!config.graphName) {
|
|
15
|
-
throw new Error("graphName is required");
|
|
16
|
-
}
|
|
17
|
-
if (!/^[A-Za-z0-9_-]+$/.test(config.graphName)) {
|
|
18
|
-
throw new Error(`Invalid graph name "${config.graphName}". Graph names can only contain letters, numbers, hyphens, and underscores.`);
|
|
19
|
-
}
|
|
20
|
-
if (!config.token) {
|
|
21
|
-
throw new Error("token is required");
|
|
22
|
-
}
|
|
23
|
-
this.graphName = config.graphName;
|
|
24
|
-
this.graphType = config.graphType;
|
|
25
|
-
this.token = config.token;
|
|
26
|
-
if (config.port) {
|
|
27
|
-
this.port = config.port;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async getPort() {
|
|
31
|
-
if (this.port)
|
|
32
|
-
return this.port;
|
|
33
|
-
try {
|
|
34
|
-
const configFile = join(homedir(), ".roam-local-api.json");
|
|
35
|
-
const content = await readFile(configFile, "utf-8");
|
|
36
|
-
const config = JSON.parse(content);
|
|
37
|
-
this.port = config.port;
|
|
38
|
-
return this.port;
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
// Default port if file doesn't exist
|
|
42
|
-
return 3333;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async openRoamDeepLink() {
|
|
46
|
-
const deepLink = `roam://#/app/${this.graphName}`;
|
|
47
|
-
await open(deepLink);
|
|
48
|
-
}
|
|
49
|
-
async sleep(ms) {
|
|
50
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
51
|
-
}
|
|
52
|
-
isConnectionError(error) {
|
|
53
|
-
if (error instanceof Error) {
|
|
54
|
-
if (error.message.includes("ECONNREFUSED") ||
|
|
55
|
-
error.message.includes("fetch failed") ||
|
|
56
|
-
error.message.includes("network")) {
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
// Check error.cause for Node fetch network errors
|
|
60
|
-
if (error.cause && error.cause instanceof Error) {
|
|
61
|
-
const causeCode = error.cause.code;
|
|
62
|
-
return (causeCode === "ECONNREFUSED" ||
|
|
63
|
-
causeCode === "ECONNRESET" ||
|
|
64
|
-
causeCode === "ENOTFOUND" ||
|
|
65
|
-
causeCode === "ETIMEDOUT");
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
isVersionMismatch(response) {
|
|
71
|
-
if (response.success)
|
|
72
|
-
return false;
|
|
73
|
-
const error = response.error;
|
|
74
|
-
if (typeof error === "object" && error !== null) {
|
|
75
|
-
return error.code === "VERSION_MISMATCH";
|
|
76
|
-
}
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
handleVersionMismatch(response) {
|
|
80
|
-
const serverVersion = response.apiVersion ?? "unknown";
|
|
81
|
-
let advice = "Please update Roam or the MCP server so versions match.";
|
|
82
|
-
if (serverVersion !== "unknown") {
|
|
83
|
-
const [serverMajor, serverMinor] = serverVersion.split(".").map(Number);
|
|
84
|
-
const [expectedMajor, expectedMinor] = EXPECTED_API_VERSION.split(".").map(Number);
|
|
85
|
-
if (serverMajor > expectedMajor ||
|
|
86
|
-
(serverMajor === expectedMajor && serverMinor > expectedMinor)) {
|
|
87
|
-
advice = "Please update the MCP server.";
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
advice = "Please update Roam.";
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
throw new RoamError(`Roam API version mismatch! Roam API: ${serverVersion}, MCP expected: ${EXPECTED_API_VERSION}. ${advice}`, ErrorCodes.VERSION_MISMATCH);
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Get user-friendly guidance for authentication errors
|
|
97
|
-
*/
|
|
98
|
-
getAuthErrorGuidance(code) {
|
|
99
|
-
const baseMsg = "Authentication failed. ";
|
|
100
|
-
switch (code) {
|
|
101
|
-
case ErrorCodes.MISSING_TOKEN:
|
|
102
|
-
return (baseMsg +
|
|
103
|
-
"No API token provided. Please ensure your ~/.roam-tools.json has a valid token.");
|
|
104
|
-
case ErrorCodes.INVALID_TOKEN_FORMAT:
|
|
105
|
-
return (baseMsg +
|
|
106
|
-
"The token format is invalid. Tokens should start with 'roam-graph-local-token-'.");
|
|
107
|
-
case ErrorCodes.WRONG_GRAPH_TYPE:
|
|
108
|
-
return (baseMsg +
|
|
109
|
-
"This token is for a different graph type. Check that 'type' matches in your config.");
|
|
110
|
-
case ErrorCodes.TOKEN_NOT_FOUND:
|
|
111
|
-
return (baseMsg +
|
|
112
|
-
"The token was not recognized. It may have been revoked. Create a new token in Roam Settings > Graph > Local API Tokens.");
|
|
113
|
-
default:
|
|
114
|
-
return (baseMsg +
|
|
115
|
-
"Please check your token in ~/.roam-tools.json. Create a token in Roam Settings > Graph > Local API Tokens.");
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Get user-friendly guidance for permission errors
|
|
120
|
-
*/
|
|
121
|
-
getPermissionErrorGuidance(code, error) {
|
|
122
|
-
switch (code) {
|
|
123
|
-
case ErrorCodes.INSUFFICIENT_SCOPE:
|
|
124
|
-
return (`Permission denied. ${error?.message || "This operation requires higher permissions."}\n` +
|
|
125
|
-
"Create a token with the required scope in Roam Settings > Graph > Local API Tokens.");
|
|
126
|
-
case ErrorCodes.SCOPE_EXCEEDS_PERMISSION:
|
|
127
|
-
return ("The token has more permissions than your user account allows. " +
|
|
128
|
-
"Please check your Roam user permissions for this graph.");
|
|
129
|
-
default:
|
|
130
|
-
return error?.message || "Access denied. Please check your permissions.";
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Handle API error responses based on HTTP status and error code
|
|
135
|
-
*/
|
|
136
|
-
handleApiError(status, response) {
|
|
137
|
-
const error = typeof response.error === "object" ? response.error : undefined;
|
|
138
|
-
const code = error?.code;
|
|
139
|
-
const message = getErrorMessage(response.error);
|
|
140
|
-
// Version mismatch - fatal
|
|
141
|
-
if (this.isVersionMismatch(response)) {
|
|
142
|
-
this.handleVersionMismatch(response);
|
|
143
|
-
}
|
|
144
|
-
// 401 - Authentication errors
|
|
145
|
-
if (status === 401) {
|
|
146
|
-
throw new RoamError(this.getAuthErrorGuidance(code), code);
|
|
147
|
-
}
|
|
148
|
-
// 403 - Permission errors
|
|
149
|
-
if (status === 403) {
|
|
150
|
-
throw new RoamError(this.getPermissionErrorGuidance(code, error), code);
|
|
151
|
-
}
|
|
152
|
-
// 404 - Unknown action
|
|
153
|
-
if (status === 404) {
|
|
154
|
-
throw new RoamError(`Unknown API action: ${message}`, ErrorCodes.UNKNOWN_ACTION);
|
|
155
|
-
}
|
|
156
|
-
// 500 - Server errors
|
|
157
|
-
if (status >= 500) {
|
|
158
|
-
const hint = message.toLowerCase().includes("promise error")
|
|
159
|
-
? "\n\nThis can happen if the graph was closed before the request completed, " +
|
|
160
|
-
"especially for encrypted graphs, when closed before the password was entered."
|
|
161
|
-
: "";
|
|
162
|
-
throw new RoamError(`Server error: ${message}${hint}`, ErrorCodes.INTERNAL_ERROR);
|
|
163
|
-
}
|
|
164
|
-
// Other errors
|
|
165
|
-
throw new RoamError(message, code);
|
|
166
|
-
}
|
|
167
|
-
checkResponse(response, httpStatus) {
|
|
168
|
-
if (!response.success) {
|
|
169
|
-
this.handleApiError(httpStatus, response);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Query the token info endpoint for current permissions.
|
|
174
|
-
* Best-effort: returns "unknown" on any failure except confirmed revocation.
|
|
175
|
-
*/
|
|
176
|
-
async getTokenInfo() {
|
|
177
|
-
try {
|
|
178
|
-
const port = await this.getPort();
|
|
179
|
-
const response = await fetch(`http://127.0.0.1:${port}/api/graphs/tokens/info`, {
|
|
180
|
-
method: "POST",
|
|
181
|
-
headers: { "Content-Type": "application/json" },
|
|
182
|
-
body: JSON.stringify({
|
|
183
|
-
token: this.token,
|
|
184
|
-
graph: this.graphName,
|
|
185
|
-
type: this.graphType,
|
|
186
|
-
}),
|
|
187
|
-
});
|
|
188
|
-
if (response.status === 401) {
|
|
189
|
-
try {
|
|
190
|
-
const data = (await response.json());
|
|
191
|
-
const code = typeof data.error === "object" ? data.error?.code : undefined;
|
|
192
|
-
if (code === "TOKEN_NOT_FOUND") {
|
|
193
|
-
return { status: "revoked" };
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
catch {
|
|
197
|
-
// Couldn't parse 401 body
|
|
198
|
-
}
|
|
199
|
-
return { status: "unknown" };
|
|
200
|
-
}
|
|
201
|
-
if (!response.ok)
|
|
202
|
-
return { status: "unknown" };
|
|
203
|
-
const data = (await response.json());
|
|
204
|
-
if (!data.success)
|
|
205
|
-
return { status: "unknown" };
|
|
206
|
-
return { status: "active", info: data };
|
|
207
|
-
}
|
|
208
|
-
catch {
|
|
209
|
-
return { status: "unknown" };
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
async call(action, args = []) {
|
|
213
|
-
const doRequest = async () => {
|
|
214
|
-
const port = await this.getPort();
|
|
215
|
-
// Build URL with graph name and optional type parameter
|
|
216
|
-
let url = `http://127.0.0.1:${port}/api/${this.graphName}`;
|
|
217
|
-
if (this.graphType === "offline") {
|
|
218
|
-
url += "?type=offline";
|
|
219
|
-
}
|
|
220
|
-
const response = await fetch(url, {
|
|
221
|
-
method: "POST",
|
|
222
|
-
headers: {
|
|
223
|
-
"Content-Type": "application/json",
|
|
224
|
-
Authorization: `Bearer ${this.token}`,
|
|
225
|
-
},
|
|
226
|
-
body: JSON.stringify({
|
|
227
|
-
action,
|
|
228
|
-
args,
|
|
229
|
-
expectedApiVersion: EXPECTED_API_VERSION,
|
|
230
|
-
}),
|
|
231
|
-
});
|
|
232
|
-
const data = (await response.json());
|
|
233
|
-
return { data, status: response.status };
|
|
234
|
-
};
|
|
235
|
-
try {
|
|
236
|
-
const { data, status } = await doRequest();
|
|
237
|
-
this.checkResponse(data, status);
|
|
238
|
-
return data;
|
|
239
|
-
}
|
|
240
|
-
catch (error) {
|
|
241
|
-
// If connection failed, try opening Roam and retry
|
|
242
|
-
if (this.isConnectionError(error)) {
|
|
243
|
-
// Reset cached port so we re-read from config after Roam starts
|
|
244
|
-
this.port = null;
|
|
245
|
-
try {
|
|
246
|
-
await this.openRoamDeepLink();
|
|
247
|
-
}
|
|
248
|
-
catch {
|
|
249
|
-
// Best-effort — don't let deep link failure prevent retries
|
|
250
|
-
}
|
|
251
|
-
let delay = 500;
|
|
252
|
-
const maxDelay = 15000;
|
|
253
|
-
for (let attempt = 0; attempt < 8; attempt += 1) {
|
|
254
|
-
await this.sleep(delay);
|
|
255
|
-
try {
|
|
256
|
-
const { data, status } = await doRequest();
|
|
257
|
-
this.checkResponse(data, status);
|
|
258
|
-
return data;
|
|
259
|
-
}
|
|
260
|
-
catch (retryError) {
|
|
261
|
-
if (!this.isConnectionError(retryError)) {
|
|
262
|
-
throw retryError;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
delay = Math.min(delay * 2, maxDelay);
|
|
266
|
-
}
|
|
267
|
-
// All retries exhausted
|
|
268
|
-
throw new RoamError("Could not connect to Roam Desktop after multiple attempts. " +
|
|
269
|
-
"Please restart the Roam desktop app and also this app and then retry again. " +
|
|
270
|
-
"If you continue having issues, please let us know at support@roamresearch.com.", ErrorCodes.CONNECTION_FAILED);
|
|
271
|
-
}
|
|
272
|
-
throw error;
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
package/dist/connect.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export interface ConnectOptions {
|
|
2
|
-
graph?: string;
|
|
3
|
-
nickname?: string;
|
|
4
|
-
accessLevel?: string;
|
|
5
|
-
public?: boolean;
|
|
6
|
-
type?: string;
|
|
7
|
-
remove?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export declare function connect(options?: ConnectOptions): Promise<void>;
|
|
10
|
-
//# sourceMappingURL=connect.d.ts.map
|
package/dist/connect.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA0CD,wBAAsB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgiBzE"}
|