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:
Sylvie Crowe 2025-02-03 14:20:50 -08:00 committed by GitHub
parent 1a70c83582
commit fc298f2a50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 468 additions and 43 deletions

View File

@ -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"

View 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)
}
}

View File

@ -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>

View 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 };

View File

@ -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
View File

@ -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
View File

@ -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
View 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
}

View File

@ -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
View 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"
}
}
}