First implementation step for the cross-platform settings contract (#376). Adds the artifact everything else depends on: the manifest, its JSON Schema, the object value schemas, and a Go loader that validates the whole thing at load time. No routes, no storage, no behavior change — nothing reads this yet. contracts/settings/v1/ holds the artifact at a stable path because clients vendor it and generate bindings from it. The embed directive has to sit beside it (go:embed cannot reach outside its own directory), so that directory is a tiny Go package containing nothing else; loading and validation live in internal/settingscontract. 38 definitions: 35 remote, 3 contract-known client_local. That covers every key the legacy registry accepts, every unregistered key the extension bag was silently accepting from the web client, every unregistered device key Android writes, and the profile preference columns that become settings. Registering the previously-unregistered keys is where the drift shows up, and the manifest records each case in a notes field: - ui_theme, ui_text_scale, ui_text_weight, ui_high_contrast, ui_custom_theme_vars, and ui_custom_css reached the server only because keyUsesUserScope returns true for any unregistered key. They are now typed, renamed to the dotted convention every other key uses, and moved to profile scope per the design. - player.match_frame_rate and player.sleep_timer_default_minutes are written by Android against a server that does not register them, so every write and reset is currently rejected. Registered. - player.next_up_prompt_seconds is Android's alias for playback.next_up_prompt_seconds and does not become a definition; the test matrix pins it as a migration alias. - player.playback_speed is capped at 3.0, matching the server rather than Android's 4.0. - subtitle_appearance becomes playback.subtitle_appearance. Every other canonical key carries a domain prefix, and preserving accidental key names is an explicit non-goal of the design. Validation is deliberately stricter than the schema can express. Beyond shape, it enforces that a resolution order ends in "default", that it only resolves scopes the definition allows, and — the one most likely to bite — that every writable scope is actually read, so a setting cannot accept writes at a scope it will never honor. Defaults are validated against their own value schema, so a default that violates its own range or enum fails at load. Revision tags are checked to never run ahead of the manifest revision, which is what makes revision-aware client filtering trustworthy. Ceiling and floor policy constraints are rejected on unordered types, where capping would silently do nothing; playback.preferred_quality's enum is therefore ordered ascending. ValidateValue is the single validation path, so the mutation endpoint, the migration, and the manifest's own default checks cannot diverge later. Numbers decode through json.Number so an integer setting rejects 30.5 rather than truncating, and object values validate against their referenced JSON Schema instead of accepting arbitrary JSON the way validateJSONSetting does today. Canonicalization implements RFC 8785 over the value domain the contract uses: sorted keys, no insignificant whitespace, ECMAScript number formatting. The digest is the ETag, and PublicBytes strips maintainer notes so the served manifest never carries internal commentary. Promotes santhosh-tekuri/jsonschema/v6 from indirect to direct. Verification: 124 tests pass across 16 cases; golangci-lint clean; make verify-local-paths passes. Two failures in internal/api/handlers (TestRemoveJellyfinCompatWebDisablesWebSetting, the playback v3 seek recovery test) reproduce unchanged on main and are unrelated. Part of #376. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
153 lines
6.8 KiB
AMPL
153 lines
6.8 KiB
AMPL
module github.com/Silo-Server/silo-server
|
|
|
|
go 1.26.4
|
|
|
|
require (
|
|
github.com/aws/aws-sdk-go-v2 v1.42.1
|
|
github.com/aws/aws-sdk-go-v2/credentials v1.19.29
|
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.105.2
|
|
github.com/go-chi/chi/v5 v5.2.5
|
|
github.com/golang-jwt/jwt/v5 v5.3.1
|
|
github.com/google/uuid v1.6.0
|
|
github.com/jackc/pgx/v5 v5.9.2
|
|
github.com/mattn/go-sqlite3 v1.14.34
|
|
github.com/prometheus/client_golang v1.23.2
|
|
github.com/prometheus/client_model v0.6.2
|
|
github.com/redis/go-redis/v9 v9.18.0
|
|
golang.org/x/crypto v0.52.0
|
|
golang.org/x/sys v0.45.0
|
|
gopkg.in/yaml.v3 v3.0.1
|
|
)
|
|
|
|
require (
|
|
github.com/SherClockHolmes/webpush-go v1.4.0
|
|
github.com/abadojack/whatlanggo v1.0.1
|
|
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.22.34
|
|
github.com/go-chi/cors v1.2.2
|
|
github.com/gorilla/websocket v1.5.3
|
|
github.com/h2non/bimg v1.1.9
|
|
github.com/hashicorp/go-hclog v1.6.3
|
|
github.com/joho/godotenv v1.5.1
|
|
github.com/mmcdole/gofeed v1.3.0
|
|
github.com/oklog/ulid/v2 v2.1.0
|
|
github.com/open-policy-agent/opa v1.18.2
|
|
github.com/pgvector/pgvector-go v0.3.0
|
|
github.com/pressly/goose/v3 v3.27.1
|
|
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2
|
|
github.com/tetratelabs/wazero v1.12.0
|
|
github.com/wneessen/go-mail v0.7.3
|
|
github.com/zishang520/socket.io/v2 v2.5.0
|
|
go.n16f.net/thumbhash v1.1.0
|
|
golang.org/x/image v0.41.0
|
|
golang.org/x/net v0.55.0
|
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa
|
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
|
)
|
|
|
|
require (
|
|
github.com/PuerkitoBio/goquery v1.8.0 // indirect
|
|
github.com/agnivade/levenshtein v1.2.1 // indirect
|
|
github.com/andybalholm/brotli v1.2.1 // indirect
|
|
github.com/andybalholm/cascadia v1.3.1 // indirect
|
|
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect
|
|
github.com/dunglas/httpsfv v1.1.0 // indirect
|
|
github.com/fatih/color v1.18.0 // indirect
|
|
github.com/go-logr/logr v1.4.3 // indirect
|
|
github.com/go-logr/stdr v1.2.2 // indirect
|
|
github.com/gobwas/glob v0.2.3 // indirect
|
|
github.com/goccy/go-json v0.10.6 // indirect
|
|
github.com/golang/protobuf v1.5.4 // indirect
|
|
github.com/gookit/color v1.5.4 // indirect
|
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect
|
|
github.com/hashicorp/yamux v0.1.2 // indirect
|
|
github.com/json-iterator/go v1.1.12 // indirect
|
|
github.com/klauspost/compress v1.18.5 // indirect
|
|
github.com/lestrrat-go/blackmagic v1.0.4 // indirect
|
|
github.com/lestrrat-go/dsig v1.2.1 // indirect
|
|
github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect
|
|
github.com/lestrrat-go/httpcc v1.0.1 // indirect
|
|
github.com/lestrrat-go/httprc/v3 v3.0.5 // indirect
|
|
github.com/lestrrat-go/jwx/v3 v3.1.1 // indirect
|
|
github.com/lestrrat-go/option/v2 v2.0.0 // indirect
|
|
github.com/mattn/go-colorable v0.1.14 // indirect
|
|
github.com/mattn/go-isatty v0.0.21 // indirect
|
|
github.com/mfridman/interpolate v0.0.2 // indirect
|
|
github.com/mmcdole/goxpp v1.1.1-0.20240225020742-a0c311522b23 // indirect
|
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
|
github.com/oklog/run v1.1.0 // indirect
|
|
github.com/quic-go/qpack v0.6.0 // indirect
|
|
github.com/quic-go/quic-go v0.60.0 // indirect
|
|
github.com/quic-go/webtransport-go v0.10.0 // indirect
|
|
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect
|
|
github.com/segmentio/asm v1.2.1 // indirect
|
|
github.com/sethvargo/go-retry v0.3.0 // indirect
|
|
github.com/sirupsen/logrus v1.9.4 // indirect
|
|
github.com/tchap/go-patricia/v2 v2.3.3 // indirect
|
|
github.com/valyala/fastjson v1.6.10 // indirect
|
|
github.com/vektah/gqlparser/v2 v2.5.34 // indirect
|
|
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
|
|
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
|
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
|
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
|
github.com/yashtewari/glob-intersection v0.2.0 // indirect
|
|
github.com/zishang520/engine.io-go-parser v1.3.2 // indirect
|
|
github.com/zishang520/engine.io/v2 v2.5.0 // indirect
|
|
github.com/zishang520/socket.io-go-parser/v2 v2.5.0 // indirect
|
|
github.com/zishang520/webtransport-go v0.9.1 // indirect
|
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 // indirect
|
|
go.opentelemetry.io/otel/metric v1.44.0 // indirect
|
|
go.opentelemetry.io/otel/trace v1.44.0 // indirect
|
|
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
|
|
go.uber.org/multierr v1.11.0 // indirect
|
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
|
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
|
|
sigs.k8s.io/yaml v1.6.0 // indirect
|
|
)
|
|
|
|
require (
|
|
github.com/Silo-Server/silo-plugin-sdk v0.12.0
|
|
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.14 // indirect
|
|
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.30 // indirect
|
|
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.30 // indirect
|
|
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.31 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.13 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.23 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.30 // indirect
|
|
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.31 // indirect
|
|
github.com/aws/smithy-go v1.27.3 // indirect
|
|
github.com/beorn7/perks v1.0.1 // indirect
|
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
|
github.com/hashicorp/go-plugin v1.7.0
|
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
|
github.com/prometheus/common v0.67.5 // indirect
|
|
github.com/prometheus/procfs v0.20.1 // indirect
|
|
github.com/robfig/cron/v3 v3.0.1
|
|
github.com/sony/sonyflake v1.3.0
|
|
go.opentelemetry.io/contrib/bridges/otelslog v0.19.0
|
|
go.opentelemetry.io/otel v1.44.0
|
|
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.20.0
|
|
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.20.0
|
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0
|
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0
|
|
go.opentelemetry.io/otel/log v0.20.0
|
|
go.opentelemetry.io/otel/sdk v1.44.0
|
|
go.opentelemetry.io/otel/sdk/log v0.20.0
|
|
go.uber.org/atomic v1.11.0 // indirect
|
|
go.yaml.in/yaml/v2 v2.4.4 // indirect
|
|
golang.org/x/sync v0.21.0
|
|
golang.org/x/text v0.38.0
|
|
golang.org/x/time v0.15.0
|
|
google.golang.org/grpc v1.82.1
|
|
google.golang.org/protobuf v1.36.11
|
|
)
|
|
|
|
replace github.com/zishang520/webtransport-go => ./internal/compat/zishang520-webtransport-go
|