Skip to content

Commit 614b6fa

Browse files
authored
feat: change page title to match the openapi spec (#3)
1 parent 87f020b commit 614b6fa

File tree

5 files changed

+96
-2
lines changed

5 files changed

+96
-2
lines changed

cmd/wasm/functions.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package main
44

55
import (
66
"fmt"
7+
"github.com/speakeasy-api/jsonpath/pkg/jsonpath"
78
"github.com/speakeasy-api/jsonpath/pkg/overlay"
89
"gopkg.in/yaml.v3"
910
"syscall/js"
@@ -33,6 +34,39 @@ func CalculateOverlay(originalYAML, targetYAML string) (string, error) {
3334
return string(out), nil
3435
}
3536

37+
func GetInfo(originalYAML string) (string, error) {
38+
var orig yaml.Node
39+
err := yaml.Unmarshal([]byte(originalYAML), &orig)
40+
if err != nil {
41+
return "", fmt.Errorf("failed to parse source schema: %w", err)
42+
}
43+
44+
titlePath, err := jsonpath.NewPath("$.info.title")
45+
if err != nil {
46+
return "", err
47+
}
48+
versionPath, err := jsonpath.NewPath("$.info.version")
49+
if err != nil {
50+
return "", err
51+
}
52+
descriptionPath, err := jsonpath.NewPath("$.info.version")
53+
if err != nil {
54+
return "", err
55+
}
56+
toString := func(node []*yaml.Node) string {
57+
if len(node) == 0 {
58+
return ""
59+
}
60+
return node[0].Value
61+
}
62+
63+
return `{
64+
"title": "` + toString(titlePath.Query(&orig)) + `",
65+
"version": "` + toString(versionPath.Query(&orig)) + `",
66+
"description": "` + toString(descriptionPath.Query(&orig)) + `"
67+
}`, nil
68+
}
69+
3670
func ApplyOverlay(originalYAML, overlayYAML string) (string, error) {
3771
var orig yaml.Node
3872
err := yaml.Unmarshal([]byte(originalYAML), &orig)
@@ -111,5 +145,13 @@ func main() {
111145
return ApplyOverlay(args[0].String(), args[1].String())
112146
}))
113147

148+
js.Global().Set("GetInfo", promisify(func(args []js.Value) (string, error) {
149+
if len(args) != 1 {
150+
return "", fmt.Errorf("GetInfo: expected 1 arg, got %v", len(args))
151+
}
152+
153+
return GetInfo(args[0].String())
154+
}))
155+
114156
<-make(chan bool)
115157
}

web/src/Playground.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from "react";
22
import "./App.css";
33
import { Editor } from "./components/Editor.tsx";
44
import { editor } from "monaco-editor";
5-
import { ApplyOverlay, CalculateOverlay } from "./bridge.ts";
5+
import { ApplyOverlay, CalculateOverlay, GetInfo } from "./bridge.ts";
66
import { Alert, PageHeader } from "@speakeasy-api/moonshine";
77
import { blankOverlay, petstore } from "./defaults.ts";
88
import { useAtom } from "jotai";
@@ -82,6 +82,22 @@ function Playground() {
8282
[changed, original],
8383
);
8484

85+
useEffect(() => {
86+
const tryHandlePageTitle = async () => {
87+
try {
88+
const info = await GetInfo(original);
89+
const { title, version } = JSON.parse(info);
90+
const pageTitle = `${title} ${version} | Speakeasy OpenAPI Overlay Playground`;
91+
if (document.title !== pageTitle) {
92+
document.title = pageTitle;
93+
}
94+
} catch (e: unknown) {
95+
console.error(e);
96+
}
97+
};
98+
tryHandlePageTitle();
99+
}, [original]);
100+
85101
if (!ready) {
86102
return "";
87103
}

web/src/assets/wasm/lib.wasm

8.54 KB
Binary file not shown.

web/src/bridge.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,24 @@ export type CalculateOverlayMessage = {
6060
};
6161
};
6262

63+
export type GetInfoMessage = {
64+
Request: {
65+
type: "GetInfo";
66+
payload: {
67+
openapi: string;
68+
};
69+
};
70+
Response:
71+
| {
72+
type: "GetInfoResult";
73+
payload: string;
74+
}
75+
| {
76+
type: "GetInfoError";
77+
error: string;
78+
};
79+
};
80+
6381
export type ApplyOverlayMessage = {
6482
Request: {
6583
type: "ApplyOverlay";
@@ -106,3 +124,13 @@ export function ApplyOverlay(
106124
supercede,
107125
);
108126
}
127+
128+
export function GetInfo(openapi: string, supercede = false): Promise<string> {
129+
return sendMessage(
130+
{
131+
type: "GetInfo",
132+
payload: { openapi },
133+
} satisfies GetInfoMessage["Request"],
134+
supercede,
135+
);
136+
}

web/src/openapi.web.worker.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
// openapi.web.worker.ts
22
import speakeasyWASM from "./assets/wasm/lib.wasm?url";
33
import "./assets/wasm/wasm_exec.js";
4-
import type { CalculateOverlayMessage, ApplyOverlayMessage } from "./bridge";
4+
import type {
5+
CalculateOverlayMessage,
6+
ApplyOverlayMessage,
7+
GetInfoMessage,
8+
} from "./bridge";
59

610
const _wasmExecutors = {
711
CalculateOverlay: (..._: any): any => false,
812
ApplyOverlay: (..._: any): any => false,
13+
GetInfo: (..._: any): any => false,
914
} as const;
1015

1116
type MessageHandlers = {
@@ -21,6 +26,9 @@ const messageHandlers: MessageHandlers = {
2126
ApplyOverlay: async (payload: ApplyOverlayMessage["Request"]["payload"]) => {
2227
return exec("ApplyOverlay", payload.source, payload.overlay);
2328
},
29+
GetInfo: async (payload: GetInfoMessage["Request"]["payload"]) => {
30+
return exec("GetInfo", payload.openapi);
31+
},
2432
};
2533

2634
let instantiated = false;

0 commit comments

Comments
 (0)