Skip to content

Commit 9c85d55

Browse files
committed
fix: add props updates
1 parent 765b899 commit 9c85d55

7 files changed

+118
-71
lines changed
20 KB
Binary file not shown.

openrpc.json

Whitespace-only changes.

src/containers/App.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const App: React.FC = () => {
2525
onToggleDarkMode={darkMode.toggle}
2626
darkMode={darkMode.value}
2727
url={query.url}
28-
openrpcMethodObject={query.openrpcMethodObject}
28+
openrpcDocument={query.openrpcDocument}
2929
request={query.request}
3030
/>
3131
</MuiThemeProvider>

src/containers/Inspector.tsx

+59-27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useState, useEffect, ChangeEvent, Dispatch } from "react";
22
import SplitPane from "react-split-pane";
33
import JSONRPCRequestEditor from "./JSONRPCRequestEditor";
4+
import * as monaco from "monaco-editor";
45
import PlayCircle from "@material-ui/icons/PlayCircleFilled";
56
import CloseIcon from "@material-ui/icons/Close";
67
import History from "@material-ui/icons/History";
@@ -27,13 +28,15 @@ import { Client, RequestManager, HTTPTransport, WebSocketTransport } from "@open
2728
import Brightness3Icon from "@material-ui/icons/Brightness3";
2829
import WbSunnyIcon from "@material-ui/icons/WbSunny";
2930
import { JSONRPCError } from "@open-rpc/client-js/build/Error";
30-
import { MethodObject } from "@open-rpc/meta-schema";
31+
import { OpenrpcDocument } from "@open-rpc/meta-schema";
3132
import MonacoEditor from "@etclabscore/react-monaco-editor";
3233
import useTabs from "../hooks/useTabs";
3334
import { useDebounce } from "use-debounce";
3435
import { green } from "@material-ui/core/colors";
3536
import { parseOpenRPCDocument } from "@open-rpc/schema-utils-js";
3637
import useMonacoVimMode from "../hooks/useMonacoVimMode";
38+
import { addDiagnostics } from "@etclabscore/monaco-add-json-schema-diagnostics";
39+
import openrpcDocumentToJSONRPCSchemaResult from "../helpers/openrpcDocumentToJSONRPCSchemaResult";
3740

3841
const errorToJSON = (error: JSONRPCError | any): any => {
3942
const isError = error instanceof Error;
@@ -55,7 +58,7 @@ interface IProps {
5558
request?: any;
5659
darkMode?: boolean;
5760
hideToggleTheme?: boolean;
58-
openrpcMethodObject?: MethodObject;
61+
openrpcDocument?: OpenrpcDocument;
5962
onToggleDarkMode?: () => void;
6063
}
6164

@@ -64,6 +67,10 @@ const useClient = (url: string): [Client, JSONRPCError | undefined, Dispatch<JSO
6467
const [error, setError] = useState();
6568
useEffect(() => {
6669
let transport;
70+
if (url === "" || url === undefined) {
71+
setClient(undefined);
72+
return;
73+
}
6774
if (url.includes("http://") || url.includes("https://")) {
6875
transport = HTTPTransport;
6976
}
@@ -79,6 +86,7 @@ const useClient = (url: string): [Client, JSONRPCError | undefined, Dispatch<JSO
7986
console.log("onError", e); //tslint:disable-line
8087
});
8188
} catch (e) {
89+
setClient(undefined);
8290
setError(e);
8391
}
8492
}, [url]);
@@ -118,7 +126,7 @@ const Inspector: React.FC<IProps> = (props) => {
118126
} = useTabs(
119127
[
120128
{
121-
name: "New Tab",
129+
name: props.request ? props.request.method : "New Tab",
122130
content: props.request || { ...emptyJSONRPC },
123131
url: props.url || "",
124132
},
@@ -127,7 +135,7 @@ const Inspector: React.FC<IProps> = (props) => {
127135
const [id, incrementId] = useCounter(0);
128136
const [responseEditor, setResponseEditor] = useState();
129137
useMonacoVimMode(responseEditor);
130-
const [openrpcDocument, setOpenRpcDocument] = useState();
138+
const [openrpcDocument, setOpenRpcDocument] = useState(props.openrpcDocument);
131139
const [json, setJson] = useState(props.request || {
132140
jsonrpc: "2.0",
133141
method: "",
@@ -142,16 +150,16 @@ const Inspector: React.FC<IProps> = (props) => {
142150
const [requestHistory, setRequestHistory]: [any[], Dispatch<any>] = useState([]);
143151
const [historySelectedIndex, setHistorySelectedIndex] = useState(0);
144152
useEffect(() => {
145-
if (props.openrpcMethodObject) {
146-
setJson({
147-
jsonrpc: "2.0",
148-
method: props.openrpcMethodObject.name,
149-
params: json.params,
150-
id: id.toString(),
151-
});
152-
}
153-
// eslint-disable-next-line react-hooks/exhaustive-deps
154-
}, []);
153+
setTabs([
154+
...tabs,
155+
{
156+
name: props.request ? props.request.method || "New Tab" : "New Tab",
157+
content: props.request,
158+
url: props.url,
159+
},
160+
]);
161+
setTabIndex(tabs.length);
162+
}, [props.request]);
155163
useEffect(() => {
156164
if (json) {
157165
const jsonResult = {
@@ -164,6 +172,25 @@ const Inspector: React.FC<IProps> = (props) => {
164172
// eslint-disable-next-line react-hooks/exhaustive-deps
165173
}, [id]);
166174

175+
useEffect(() => {
176+
if (!openrpcDocument) {
177+
return;
178+
}
179+
if (!responseEditor) {
180+
return;
181+
}
182+
if (!results) {
183+
return;
184+
}
185+
const schema = openrpcDocumentToJSONRPCSchemaResult(openrpcDocument, json.method);
186+
const modelName = "inspector-results";
187+
const modelUriString = `inmemory://${modelName}-${Math.random()}.json`;
188+
const modelUri = monaco.Uri.parse(modelUriString);
189+
const model = monaco.editor.createModel(results ? JSON.stringify(results, null, 4) : "", "json", modelUri);
190+
responseEditor.setModel(model);
191+
addDiagnostics(modelUri.toString(), schema, monaco);
192+
}, [results, responseEditor, openrpcDocument]);
193+
167194
useEffect(() => {
168195
if (json) {
169196
setTabContent(tabIndex, json);
@@ -217,13 +244,13 @@ const Inspector: React.FC<IProps> = (props) => {
217244
}
218245
};
219246
const refreshOpenRpcDocument = async () => {
220-
if (url) {
221-
try {
222-
const d = await client.request("rpc.discover", []);
223-
const doc = await parseOpenRPCDocument(d);
224-
setOpenRpcDocument(doc);
225-
setTabOpenRPCDocument(tabIndex, doc);
226-
} catch (e) {
247+
try {
248+
const d = await client.request("rpc.discover", []);
249+
const doc = await parseOpenRPCDocument(d);
250+
setOpenRpcDocument(doc);
251+
setTabOpenRPCDocument(tabIndex, doc);
252+
} catch (e) {
253+
if (!props.openrpcDocument) {
227254
setOpenRpcDocument(undefined);
228255
setTabOpenRPCDocument(tabIndex, undefined);
229256
}
@@ -232,18 +259,22 @@ const Inspector: React.FC<IProps> = (props) => {
232259
useEffect(() => {
233260
refreshOpenRpcDocument();
234261
// eslint-disable-next-line react-hooks/exhaustive-deps
235-
}, [client]);
262+
}, [client, tabIndex]);
236263

237264
useEffect(() => {
238265
if (tabs[tabIndex]) {
239266
setJson(tabs[tabIndex].content);
240267
setUrl(tabs[tabIndex].url || "");
241-
setOpenRpcDocument(tabs[tabIndex].openrpcDocument);
242268
setResults(tabs[tabIndex].results);
243269
}
244270
// eslint-disable-next-line react-hooks/exhaustive-deps
245271
}, [tabIndex]);
246272

273+
useEffect(() => {
274+
setOpenRpcDocument(props.openrpcDocument);
275+
setTabOpenRPCDocument(tabIndex, undefined);
276+
}, [props.openrpcDocument]);
277+
247278
const handleTabIndexChange = (event: React.ChangeEvent<{}>, newValue: number) => {
248279
setTabIndex(newValue);
249280
};
@@ -358,6 +389,7 @@ const Inspector: React.FC<IProps> = (props) => {
358389
{
359390
name: "New Tab",
360391
content: { ...emptyJSONRPC },
392+
openrpcDocument: undefined,
361393
url: "",
362394
},
363395
],
@@ -388,9 +420,10 @@ const Inspector: React.FC<IProps> = (props) => {
388420
?
389421
<Tooltip title={
390422
<div style={{ textAlign: "center" }}>
391-
<Typography>Valid OpenRPC Endpoint.</Typography>
423+
<Typography>OpenRPC Document Detected</Typography>
392424
<Typography variant="caption">
393-
The JSON-RPC endpoint responds to the rpc.discover method.
425+
A JSON-RPC endpoint may respond to the rpc.discover method
426+
or a provide a static document.
394427
This adds features like auto completion to the inspector.
395428
</Typography>
396429
</div>
@@ -452,7 +485,6 @@ const Inspector: React.FC<IProps> = (props) => {
452485
}
453486
}}
454487
openrpcDocument={openrpcDocument}
455-
openrpcMethodObject={props.openrpcMethodObject}
456488
value={JSON.stringify(json, null, 4)}
457489
/>
458490
<>
@@ -484,7 +516,7 @@ const Inspector: React.FC<IProps> = (props) => {
484516
value={JSON.stringify(errorToJSON(results) || results, null, 4) || ""}
485517
/>
486518
: <Grid container justify="center" style={{ paddingTop: "20px" }} direction="column" alignItems="center">
487-
<Typography variant="body1" gutterBottom color="textSecondary" style={{paddingBottom: "15px"}}>
519+
<Typography variant="body1" gutterBottom color="textSecondary" style={{ paddingBottom: "15px" }}>
488520
Press the Play button to see the results here.
489521
</Typography>
490522
<Typography variant="body1" color="textSecondary">

src/containers/JSONRPCRequestEditor.tsx

+5-41
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const JSONRPCRequestEditor: React.FC<IProps> = (props) => {
2828
if (!editor) {
2929
return;
3030
}
31-
const modelName = props.openrpcMethodObject ? props.openrpcMethodObject.name : "inspector";
31+
const modelName = (props.openrpcDocument && props.openrpcDocument.info) ? props.openrpcDocument.info.title : "inspector";
3232
const modelUriString = `inmemory://${modelName}-${Math.random()}.json`;
3333
const modelUri = monaco.Uri.parse(modelUriString);
3434
const model = monaco.editor.createModel(props.value || "", "json", modelUri);
@@ -38,7 +38,7 @@ const JSONRPCRequestEditor: React.FC<IProps> = (props) => {
3838
properties: {
3939
jsonrpc: {
4040
type: "string",
41-
enum: ["2.0"],
41+
const: "2.0",
4242
},
4343
id: {
4444
oneOf: [
@@ -55,44 +55,8 @@ const JSONRPCRequestEditor: React.FC<IProps> = (props) => {
5555
},
5656
},
5757
};
58-
if (props.openrpcMethodObject) {
59-
schema = {
60-
...schema,
61-
additionalProperties: false,
62-
properties: {
63-
...schema.properties,
64-
method: {
65-
type: "string",
66-
enum: [props.openrpcMethodObject.name],
67-
},
68-
params: {
69-
oneOf: [
70-
{
71-
type: "array",
72-
...schema.properties.params,
73-
items: props.openrpcMethodObject.params.map((param: any) => {
74-
return {
75-
...param.schema,
76-
additionalProperties: false,
77-
};
78-
}),
79-
},
80-
{
81-
type: "object",
82-
properties: (props.openrpcMethodObject.params as ContentDescriptorObject[])
83-
.reduce((memo: any, param: ContentDescriptorObject) => {
84-
memo[param.name] = {
85-
...param.schema,
86-
additionalProperties: false,
87-
};
88-
return memo;
89-
}, {}),
90-
},
91-
],
92-
},
93-
},
94-
};
95-
} else if (props.openrpcDocument) {
58+
59+
if (props.openrpcDocument) {
9660
schema = openrpcDocumentToJSONRPCSchema(props.openrpcDocument);
9761
} else {
9862
schema = {
@@ -111,7 +75,7 @@ const JSONRPCRequestEditor: React.FC<IProps> = (props) => {
11175
addDiagnostics(modelUri.toString(), schema, monaco);
11276

11377
// eslint-disable-next-line react-hooks/exhaustive-deps
114-
}, [props.openrpcDocument, props.openrpcMethodObject]);
78+
}, [props.openrpcDocument]);
11579

11680
function handleEditorDidMount(_: any, ed: any) {
11781
setEditor(ed);

src/helpers/openrpcDocumentToJSONRPCSchema.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ const schema: any = {
66
jsonrpc: {
77
type: "string",
88
enum: ["2.0"],
9+
description: "JSON-RPC version string",
910
},
1011
id: {
12+
description: "unique identifier for the JSON-RPC request",
1113
oneOf: [
1214
{
1315
type: "string",
@@ -35,6 +37,7 @@ const openrpcDocumentToJSONRPCSchema = (openrpcDocument: OpenrpcDocument) => {
3537
},
3638
method: {
3739
type: "string",
40+
description: "Method Name",
3841
oneOf: openrpcDocument.methods.map((method) => {
3942
return {
4043
const: method.name,
@@ -72,7 +75,7 @@ const openrpcDocumentToJSONRPCSchema = (openrpcDocument: OpenrpcDocument) => {
7275
return {
7376
...param.schema,
7477
markdownDescription: param.description || param.summary,
75-
description: param.summary,
78+
description: param.description || param.summary,
7679
additionalProperties: false,
7780
};
7881
}),
@@ -84,7 +87,7 @@ const openrpcDocumentToJSONRPCSchema = (openrpcDocument: OpenrpcDocument) => {
8487
memo[param.name] = {
8588
...param.schema,
8689
markdownDescription: param.description || param.summary,
87-
description: param.summary,
90+
description: param.description || param.summary,
8891
additionalProperties: false,
8992
};
9093
return memo;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { MethodObject, ContentDescriptorObject, OpenrpcDocument, ExampleObject, MethodObjectResult } from "@open-rpc/meta-schema";
2+
3+
const schema: any = {
4+
type: "object",
5+
properties: {
6+
jsonrpc: {
7+
type: "string",
8+
description: "JSON-RPC Version String",
9+
const: "2.0",
10+
},
11+
id: {
12+
oneOf: [
13+
{
14+
type: "string",
15+
},
16+
{
17+
type: "number",
18+
},
19+
],
20+
},
21+
},
22+
};
23+
24+
const openrpcDocumentToJSONRPCSchemaResult = (openrpcDocument: OpenrpcDocument, methodName: string) => {
25+
const methodObject: MethodObject | undefined = openrpcDocument.methods.find((method) => method.name === methodName);
26+
let methodSchema: any;
27+
if (methodObject !== undefined && methodObject.result !== undefined) {
28+
methodSchema = (methodObject.result as ContentDescriptorObject).schema;
29+
}
30+
return {
31+
type: "object",
32+
properties: {
33+
id: {
34+
...schema.properties.id,
35+
},
36+
jsonrpc: {
37+
...schema.properties.jsonrpc,
38+
},
39+
result: {
40+
...methodSchema,
41+
markdownDescription: methodObject?.description || methodObject?.summary,
42+
description: methodObject?.description || methodObject?.summary,
43+
},
44+
},
45+
};
46+
};
47+
48+
export default openrpcDocumentToJSONRPCSchemaResult;

0 commit comments

Comments
 (0)