mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-02-15 01:32:17 +01:00
settings schema.json (#1874)
Adds schema.json support to the settings file to provide type hints and other eventual details. This also adds a system to easily add more schema files for other type of configurations.
This commit is contained in:
parent
1a70c83582
commit
fc298f2a50
14
Taskfile.yml
14
Taskfile.yml
@ -114,6 +114,18 @@ tasks:
|
||||
- task: build:server
|
||||
- task: build:wsh
|
||||
|
||||
build:schema:
|
||||
desc: Build the schema for configuration.
|
||||
sources:
|
||||
- "cmd/generateschema/*.go"
|
||||
- "pkg/wconfig/*.go"
|
||||
generates:
|
||||
- "dist/schema/**/*"
|
||||
cmds:
|
||||
- go run cmd/generateschema/main-generateschema.go
|
||||
- '{{.RMRF}} "dist/schema"'
|
||||
- task: copyfiles:'schema':'dist/schema'
|
||||
|
||||
build:server:
|
||||
desc: Build the wavesrv component.
|
||||
cmds:
|
||||
@ -243,6 +255,8 @@ tasks:
|
||||
cmds:
|
||||
- go run cmd/generatets/main-generatets.go
|
||||
- go run cmd/generatego/main-generatego.go
|
||||
deps:
|
||||
- build:schema
|
||||
sources:
|
||||
- "cmd/generatego/*.go"
|
||||
- "cmd/generatets/*.go"
|
||||
|
39
cmd/generateschema/main-generateschema.go
Normal file
39
cmd/generateschema/main-generateschema.go
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright 2025, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/invopop/jsonschema"
|
||||
"github.com/wavetermdev/waveterm/pkg/util/utilfn"
|
||||
"github.com/wavetermdev/waveterm/pkg/wconfig"
|
||||
)
|
||||
|
||||
const WaveSchemaSettingsFileName = "schema/settings.json"
|
||||
|
||||
func main() {
|
||||
settingsSchema := jsonschema.Reflect(&wconfig.SettingsType{})
|
||||
|
||||
jsonSettingsSchema, err := json.MarshalIndent(settingsSchema, "", " ")
|
||||
if err != nil {
|
||||
log.Fatalf("failed to parse local schema: %v", err)
|
||||
}
|
||||
/*
|
||||
err = os.MkdirAll(WaveSchemaSettingsFileName, 0755)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to create schema dir: %v", err)
|
||||
}
|
||||
*/
|
||||
written, err := utilfn.WriteFileIfDifferent(WaveSchemaSettingsFileName, jsonSettingsSchema)
|
||||
if !written {
|
||||
fmt.Fprintf(os.Stderr, "no changes to %s\n", WaveSchemaSettingsFileName)
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("failed to write local schema: %v", err)
|
||||
}
|
||||
}
|
@ -9,11 +9,15 @@ import type * as MonacoTypes from "monaco-editor/esm/vs/editor/editor.api";
|
||||
import { configureMonacoYaml } from "monaco-yaml";
|
||||
import React, { useMemo, useRef } from "react";
|
||||
|
||||
import { RpcApi } from "@/app/store/wshclientapi";
|
||||
import { TabRpcClient } from "@/app/store/wshrpcutil";
|
||||
import { makeConnRoute } from "@/util/util";
|
||||
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
|
||||
import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
|
||||
import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
|
||||
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
|
||||
import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
|
||||
import { SchemaEndpoints, getSchemaEndpointInfo } from "./schemaendpoints";
|
||||
import ymlWorker from "./yamlworker?worker";
|
||||
|
||||
import "./codeeditor.scss";
|
||||
@ -42,48 +46,45 @@ window.MonacoEnvironment = {
|
||||
},
|
||||
};
|
||||
|
||||
export function loadMonaco() {
|
||||
export async function loadMonaco() {
|
||||
loader.config({ paths: { vs: "monaco" } });
|
||||
loader
|
||||
.init()
|
||||
.then(() => {
|
||||
monaco.editor.defineTheme("wave-theme-dark", {
|
||||
base: "vs-dark",
|
||||
inherit: true,
|
||||
rules: [],
|
||||
colors: {
|
||||
"editor.background": "#00000000",
|
||||
"editorStickyScroll.background": "#00000055",
|
||||
"minimap.background": "#00000077",
|
||||
focusBorder: "#00000000",
|
||||
},
|
||||
});
|
||||
monaco.editor.defineTheme("wave-theme-light", {
|
||||
base: "vs",
|
||||
inherit: true,
|
||||
rules: [],
|
||||
colors: {
|
||||
"editor.background": "#fefefe",
|
||||
focusBorder: "#00000000",
|
||||
},
|
||||
});
|
||||
configureMonacoYaml(monaco, {
|
||||
validate: true,
|
||||
schemas: [],
|
||||
});
|
||||
// Disable default validation errors for typescript and javascript
|
||||
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
||||
noSemanticValidation: true,
|
||||
});
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
allowComments: false, // Set to true if you want to allow comments in JSON
|
||||
schemas: [], // You can specify JSON schemas here if needed
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("error loading monaco", e);
|
||||
});
|
||||
await loader.init();
|
||||
|
||||
monaco.editor.defineTheme("wave-theme-dark", {
|
||||
base: "vs-dark",
|
||||
inherit: true,
|
||||
rules: [],
|
||||
colors: {
|
||||
"editor.background": "#00000000",
|
||||
"editorStickyScroll.background": "#00000055",
|
||||
"minimap.background": "#00000077",
|
||||
focusBorder: "#00000000",
|
||||
},
|
||||
});
|
||||
monaco.editor.defineTheme("wave-theme-light", {
|
||||
base: "vs",
|
||||
inherit: true,
|
||||
rules: [],
|
||||
colors: {
|
||||
"editor.background": "#fefefe",
|
||||
focusBorder: "#00000000",
|
||||
},
|
||||
});
|
||||
configureMonacoYaml(monaco, {
|
||||
validate: true,
|
||||
schemas: [],
|
||||
});
|
||||
// Disable default validation errors for typescript and javascript
|
||||
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
||||
noSemanticValidation: true,
|
||||
});
|
||||
const schemas = await Promise.all(SchemaEndpoints.map((endpoint) => getSchemaEndpointInfo(endpoint)));
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
allowComments: false, // Set to true if you want to allow comments in JSON
|
||||
enableSchemaRequest: true,
|
||||
schemas,
|
||||
});
|
||||
}
|
||||
|
||||
function defaultEditorOptions(): MonacoTypes.editor.IEditorOptions {
|
||||
@ -125,6 +126,7 @@ export function CodeEditor({ blockId, text, language, filename, meta, onChange,
|
||||
const wordWrap = useOverrideConfigAtom(blockId, "editor:wordwrap") ?? false;
|
||||
const fontSize = boundNumber(useOverrideConfigAtom(blockId, "editor:fontsize"), 6, 64);
|
||||
const theme = "wave-theme-dark";
|
||||
const [absPath, setAbsPath] = React.useState("");
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
@ -135,6 +137,24 @@ export function CodeEditor({ blockId, text, language, filename, meta, onChange,
|
||||
};
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
const inner = async () => {
|
||||
try {
|
||||
const fileInfo = await RpcApi.RemoteFileJoinCommand(TabRpcClient, [filename], {
|
||||
route: makeConnRoute(meta.connection ?? ""),
|
||||
});
|
||||
setAbsPath(`${fileInfo.dir}/${fileInfo.name}`);
|
||||
} catch (e) {
|
||||
setAbsPath(filename);
|
||||
}
|
||||
};
|
||||
inner();
|
||||
}, [filename]);
|
||||
|
||||
React.useEffect(() => {
|
||||
console.log("abspath is", absPath);
|
||||
}, [absPath]);
|
||||
|
||||
function handleEditorChange(text: string, ev: MonacoTypes.editor.IModelContentChangedEvent) {
|
||||
if (onChange) {
|
||||
onChange(text);
|
||||
@ -165,7 +185,7 @@ export function CodeEditor({ blockId, text, language, filename, meta, onChange,
|
||||
options={editorOpts}
|
||||
onChange={handleEditorChange}
|
||||
onMount={handleEditorOnMount}
|
||||
path={filename}
|
||||
path={absPath}
|
||||
language={language}
|
||||
/>
|
||||
</div>
|
||||
|
38
frontend/app/view/codeeditor/schemaendpoints.ts
Normal file
38
frontend/app/view/codeeditor/schemaendpoints.ts
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2025, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { getApi } from "@/app/store/global";
|
||||
import { getWebServerEndpoint } from "@/util/endpoints";
|
||||
|
||||
type EndpointInfo = {
|
||||
uri: string;
|
||||
fileMatch: Array<string>;
|
||||
schema: object;
|
||||
};
|
||||
|
||||
const allFilepaths: Map<string, Array<string>> = new Map();
|
||||
allFilepaths.set(`${getWebServerEndpoint()}/schema/settings.json`, [`${getApi().getConfigDir()}/settings.json`]);
|
||||
|
||||
async function getSchemaEndpointInfo(endpoint: string): Promise<EndpointInfo> {
|
||||
let schema: Object;
|
||||
try {
|
||||
const data = await fetch(endpoint);
|
||||
const fullSchema: object = await data.json();
|
||||
const schemaRef: string = fullSchema?.["$ref"];
|
||||
schema = fullSchema?.[schemaRef];
|
||||
} catch (e) {
|
||||
console.log("cannot find schema:", e);
|
||||
schema = {};
|
||||
}
|
||||
const fileMatch = allFilepaths.get(endpoint) ?? [];
|
||||
|
||||
return {
|
||||
uri: endpoint,
|
||||
fileMatch,
|
||||
schema,
|
||||
};
|
||||
}
|
||||
|
||||
const SchemaEndpoints = Array.from(allFilepaths.keys());
|
||||
|
||||
export { getSchemaEndpointInfo, SchemaEndpoints };
|
@ -183,7 +183,7 @@ async function initWave(initOpts: WaveInitOpts) {
|
||||
registerGlobalKeys();
|
||||
registerElectronReinjectKeyHandler();
|
||||
registerControlShiftStateUpdateHandler();
|
||||
setTimeout(loadMonaco, 30);
|
||||
await loadMonaco();
|
||||
const fullConfig = await RpcApi.GetFullConfigCommand(TabRpcClient);
|
||||
console.log("fullconfig", fullConfig);
|
||||
globalStore.set(atoms.fullConfigAtom, fullConfig);
|
||||
|
6
go.mod
6
go.mod
@ -18,6 +18,7 @@ require (
|
||||
github.com/gorilla/handlers v1.5.2
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/invopop/jsonschema v0.13.0
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/kevinburke/ssh_config v1.2.0
|
||||
github.com/mattn/go-sqlite3 v1.14.24
|
||||
@ -59,6 +60,8 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.11 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/ebitengine/purego v0.8.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
@ -71,12 +74,14 @@ require (
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/ubuntu/decorate v0.0.0-20230125165522-2d5b0a9bb117 // indirect
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
@ -93,6 +98,7 @@ require (
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/kevinburke/ssh_config => github.com/wavetermdev/ssh_config v0.0.0-20241219203747-6409e4292f34
|
||||
|
19
go.sum
19
go.sum
@ -52,6 +52,10 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.33.11 h1:RIXOjp7Dp4siCYJRwBHUcBdVgOW
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.11/go.mod h1:ZR17k9bPKPR8u0IkyA6xVsjr56doNQ4ZB1fs7abYBfE=
|
||||
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
|
||||
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
||||
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@ -105,12 +109,21 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E=
|
||||
github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
@ -122,6 +135,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sashabaranov/go-openai v1.36.1 h1:EVfRXwIlW2rUzpx6vR+aeIKCK/xylSrVYAx1TMTSX3g=
|
||||
github.com/sashabaranov/go-openai v1.36.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
@ -157,6 +172,8 @@ github.com/wavetermdev/htmltoken v0.2.0 h1:sFVPPemlDv7/jg7n4Hx1AEF2m9MVAFjFpELWf
|
||||
github.com/wavetermdev/htmltoken v0.2.0/go.mod h1:5FM0XV6zNYiNza2iaTcFGj+hnMtgqumFHO31Z8euquk=
|
||||
github.com/wavetermdev/ssh_config v0.0.0-20241219203747-6409e4292f34 h1:I8VZVTZEXhnzfN7jB9a7TZYpzNO48sCUWMRXHM9XWSA=
|
||||
github.com/wavetermdev/ssh_config v0.0.0-20241219203747-6409e4292f34/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
|
||||
@ -212,6 +229,8 @@ google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40Rmc
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
54
pkg/schema/schema.go
Normal file
54
pkg/schema/schema.go
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright 2025, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package schema
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/wavetermdev/waveterm/pkg/wavebase"
|
||||
)
|
||||
|
||||
var schemaHandler http.Handler
|
||||
|
||||
func GetSchemaHandler() http.Handler {
|
||||
schemaStaticPath := filepath.Join(wavebase.GetWaveAppPath(), "schema")
|
||||
stat, err := os.Stat(schemaStaticPath)
|
||||
if schemaHandler == nil {
|
||||
log.Println("Schema is nil, initializing")
|
||||
if err == nil && stat.IsDir() {
|
||||
log.Printf("Found static site at %s, serving\n", schemaStaticPath)
|
||||
schemaHandler = http.FileServer(JsonDir{http.Dir(schemaStaticPath)})
|
||||
} else {
|
||||
log.Printf("Did not find static site at %s, serving not found handler. stat: %v, err: %v\n", schemaStaticPath, stat, err)
|
||||
schemaHandler = http.NotFoundHandler()
|
||||
}
|
||||
}
|
||||
return addHeaders(schemaHandler)
|
||||
}
|
||||
|
||||
func addHeaders(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("Content-Type", "application/schema+json")
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
type JsonDir struct {
|
||||
d http.Dir
|
||||
}
|
||||
|
||||
func (d JsonDir) Open(name string) (http.File, error) {
|
||||
// Try name as supplied
|
||||
f, err := d.d.Open(name)
|
||||
if os.IsNotExist(err) {
|
||||
// Not found, try with .json
|
||||
if f, err := d.d.Open(name + ".json"); err == nil {
|
||||
return f, nil
|
||||
}
|
||||
}
|
||||
return f, err
|
||||
}
|
@ -25,6 +25,7 @@ import (
|
||||
"github.com/wavetermdev/waveterm/pkg/docsite"
|
||||
"github.com/wavetermdev/waveterm/pkg/filestore"
|
||||
"github.com/wavetermdev/waveterm/pkg/panichandler"
|
||||
"github.com/wavetermdev/waveterm/pkg/schema"
|
||||
"github.com/wavetermdev/waveterm/pkg/service"
|
||||
"github.com/wavetermdev/waveterm/pkg/wavebase"
|
||||
"github.com/wavetermdev/waveterm/pkg/wshrpc"
|
||||
@ -419,6 +420,7 @@ func MakeUnixListener() (net.Listener, error) {
|
||||
}
|
||||
|
||||
const docsitePrefix = "/docsite/"
|
||||
const schemaPrefix = "/schema/"
|
||||
|
||||
// blocking
|
||||
func RunWebServer(listener net.Listener) {
|
||||
@ -428,6 +430,7 @@ func RunWebServer(listener net.Listener) {
|
||||
gr.HandleFunc("/wave/service", WebFnWrap(WebFnOpts{JsonErrors: true}, handleService))
|
||||
gr.HandleFunc("/vdom/{uuid}/{path:.*}", WebFnWrap(WebFnOpts{AllowCaching: true}, handleVDom))
|
||||
gr.PathPrefix(docsitePrefix).Handler(http.StripPrefix(docsitePrefix, docsite.GetDocsiteHandler()))
|
||||
gr.PathPrefix(schemaPrefix).Handler(http.StripPrefix(schemaPrefix, schema.GetSchemaHandler()))
|
||||
handler := http.TimeoutHandler(gr, HttpTimeoutDuration, "Timeout")
|
||||
if wavebase.IsDevMode() {
|
||||
handler = handlers.CORS(handlers.AllowedOrigins([]string{"*"}))(handler)
|
||||
|
232
schema/settings.json
Normal file
232
schema/settings.json
Normal file
@ -0,0 +1,232 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://github.com/wavetermdev/waveterm/pkg/wconfig/settings-type",
|
||||
"$ref": "#/$defs/SettingsType",
|
||||
"$defs": {
|
||||
"SettingsType": {
|
||||
"properties": {
|
||||
"app:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"app:globalhotkey": {
|
||||
"type": "string"
|
||||
},
|
||||
"app:dismissarchitecturewarning": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"ai:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"ai:preset": {
|
||||
"type": "string"
|
||||
},
|
||||
"ai:apitype": {
|
||||
"type": "string"
|
||||
},
|
||||
"ai:baseurl": {
|
||||
"type": "string"
|
||||
},
|
||||
"ai:apitoken": {
|
||||
"type": "string"
|
||||
},
|
||||
"ai:name": {
|
||||
"type": "string"
|
||||
},
|
||||
"ai:model": {
|
||||
"type": "string"
|
||||
},
|
||||
"ai:orgid": {
|
||||
"type": "string"
|
||||
},
|
||||
"ai:apiversion": {
|
||||
"type": "string"
|
||||
},
|
||||
"ai:maxtokens": {
|
||||
"type": "number"
|
||||
},
|
||||
"ai:timeoutms": {
|
||||
"type": "number"
|
||||
},
|
||||
"ai:fontsize": {
|
||||
"type": "number"
|
||||
},
|
||||
"ai:fixedfontsize": {
|
||||
"type": "number"
|
||||
},
|
||||
"term:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"term:fontsize": {
|
||||
"type": "number"
|
||||
},
|
||||
"term:fontfamily": {
|
||||
"type": "string"
|
||||
},
|
||||
"term:theme": {
|
||||
"type": "string"
|
||||
},
|
||||
"term:disablewebgl": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"term:localshellpath": {
|
||||
"type": "string"
|
||||
},
|
||||
"term:localshellopts": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"term:scrollback": {
|
||||
"type": "integer"
|
||||
},
|
||||
"term:copyonselect": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"term:transparency": {
|
||||
"type": "number"
|
||||
},
|
||||
"term:allowbracketedpaste": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"editor:minimapenabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"editor:stickyscrollenabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"editor:wordwrap": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"editor:fontsize": {
|
||||
"type": "number"
|
||||
},
|
||||
"web:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"web:openlinksinternally": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"web:defaulturl": {
|
||||
"type": "string"
|
||||
},
|
||||
"web:defaultsearch": {
|
||||
"type": "string"
|
||||
},
|
||||
"blockheader:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"blockheader:showblockids": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"autoupdate:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"autoupdate:enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"autoupdate:intervalms": {
|
||||
"type": "number"
|
||||
},
|
||||
"autoupdate:installonquit": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"autoupdate:channel": {
|
||||
"type": "string"
|
||||
},
|
||||
"markdown:fontsize": {
|
||||
"type": "number"
|
||||
},
|
||||
"markdown:fixedfontsize": {
|
||||
"type": "number"
|
||||
},
|
||||
"preview:showhiddenfiles": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"tab:preset": {
|
||||
"type": "string"
|
||||
},
|
||||
"widget:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"widget:showhelp": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:transparent": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:blur": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:opacity": {
|
||||
"type": "number"
|
||||
},
|
||||
"window:bgcolor": {
|
||||
"type": "string"
|
||||
},
|
||||
"window:reducedmotion": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:tilegapsize": {
|
||||
"type": "integer"
|
||||
},
|
||||
"window:showmenubar": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:nativetitlebar": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:disablehardwareacceleration": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:maxtabcachesize": {
|
||||
"type": "integer"
|
||||
},
|
||||
"window:magnifiedblockopacity": {
|
||||
"type": "number"
|
||||
},
|
||||
"window:magnifiedblocksize": {
|
||||
"type": "number"
|
||||
},
|
||||
"window:magnifiedblockblurprimarypx": {
|
||||
"type": "integer"
|
||||
},
|
||||
"window:magnifiedblockblursecondarypx": {
|
||||
"type": "integer"
|
||||
},
|
||||
"window:confirmclose": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:savelastwindow": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"window:dimensions": {
|
||||
"type": "string"
|
||||
},
|
||||
"window:zoom": {
|
||||
"type": "number"
|
||||
},
|
||||
"telemetry:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"telemetry:enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"conn:*": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"conn:askbeforewshinstall": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"conn:wshenabled": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user