mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-09 02:33:54 +00:00
fix(opencode): ignore unknown config fields (#41312)
This commit is contained in:
parent
fe82a1b6ca
commit
38e10eb140
2 changed files with 10 additions and 33 deletions
|
|
@ -37,22 +37,11 @@ export function schema<S extends EffectSchema.Decoder<unknown, never>>(
|
|||
data: unknown,
|
||||
source: string,
|
||||
): DeepMutable<S["Type"]> {
|
||||
const extra = topLevelExtraKeys(schema, data)
|
||||
if (extra.length) {
|
||||
throw new InvalidError({
|
||||
path: source,
|
||||
issues: [
|
||||
{
|
||||
code: "unrecognized_keys",
|
||||
keys: extra,
|
||||
path: [],
|
||||
message: `Unrecognized key${extra.length === 1 ? "" : "s"}: ${extra.join(", ")}`,
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
const decoded = EffectSchema.decodeUnknownExit(schema)(data, { errors: "all", propertyOrder: "original" })
|
||||
const decoded = EffectSchema.decodeUnknownExit(schema)(data, {
|
||||
errors: "all",
|
||||
onExcessProperty: "ignore",
|
||||
propertyOrder: "original",
|
||||
})
|
||||
if (Exit.isSuccess(decoded)) return decoded.value as DeepMutable<S["Type"]>
|
||||
const error = Cause.squash(decoded.cause)
|
||||
|
||||
|
|
@ -70,10 +59,3 @@ export function schema<S extends EffectSchema.Decoder<unknown, never>>(
|
|||
{ cause: error },
|
||||
)
|
||||
}
|
||||
|
||||
function topLevelExtraKeys(schema: EffectSchema.Top, data: unknown) {
|
||||
if (typeof data !== "object" || data === null || Array.isArray(data)) return []
|
||||
if (schema.ast._tag !== "Objects" || schema.ast.indexSignatures.length > 0) return []
|
||||
const known = new Set(schema.ast.propertySignatures.map((item) => String(item.name)))
|
||||
return Object.keys(data).filter((key) => !known.has(key))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -597,12 +597,12 @@ accountTokenIt.instance("resolves env templates in account config with account t
|
|||
}),
|
||||
)
|
||||
|
||||
it.instance("validates config schema and throws on invalid fields", () =>
|
||||
it.instance("validates config schema and throws on invalid values", () =>
|
||||
Effect.gen(function* () {
|
||||
const test = yield* TestInstance
|
||||
yield* writeConfigEffect(test.directory, {
|
||||
$schema: "https://opencode.ai/config.json",
|
||||
invalid_field: "should cause error",
|
||||
model: 42,
|
||||
})
|
||||
const exit = yield* Config.use.get().pipe(Effect.exit)
|
||||
expect(Exit.isFailure(exit)).toBe(true)
|
||||
|
|
@ -1331,7 +1331,7 @@ it.instance("permission config preserves user key order", () =>
|
|||
}),
|
||||
)
|
||||
|
||||
test("config parser preserves permission order while rejecting unknown top-level keys", () => {
|
||||
test("config parser preserves permission order while ignoring unknown top-level keys", () => {
|
||||
const config = ConfigParse.schema(
|
||||
ConfigV1.Info,
|
||||
{
|
||||
|
|
@ -1340,18 +1340,13 @@ test("config parser preserves permission order while rejecting unknown top-level
|
|||
"*": "deny",
|
||||
edit: "ask",
|
||||
},
|
||||
plugins: ["example"],
|
||||
},
|
||||
"test",
|
||||
)
|
||||
|
||||
expect(Object.keys(config.permission!)).toEqual(["bash", "*", "edit"])
|
||||
try {
|
||||
ConfigParse.schema(ConfigV1.Info, { invalid_field: true }, "test")
|
||||
throw new Error("expected config parse to fail")
|
||||
} catch (err) {
|
||||
const error = err as { data?: { issues?: Array<{ code?: string; keys?: string[]; path?: string[] }> } }
|
||||
expect(error.data?.issues?.[0]).toMatchObject({ code: "unrecognized_keys", keys: ["invalid_field"], path: [] })
|
||||
}
|
||||
expect(config).not.toHaveProperty("plugins")
|
||||
})
|
||||
|
||||
// MCP config merging tests
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue