chore(duplication): share settings transform schemas (#5496)

This commit is contained in:
Jan Leon
2026-06-30 02:58:44 +02:00
committed by GitHub
parent 21f8e44f3e
commit b9fd69ecf3
2 changed files with 174 additions and 98 deletions

View File

@@ -16,6 +16,77 @@ import { SPAWN_CAPABLE_PREFIXES } from "@/server/authz/routeGuard";
const signatureCacheModeValues = ["enabled", "bypass", "bypass-strict"] as const;
const transformDropParagraphIfContainsSchema = z.object({
kind: z.literal("drop_paragraph_if_contains"),
needles: z.array(z.string().max(500)).max(50),
caseSensitive: z.boolean().optional(),
});
const transformDropParagraphIfStartsWithSchema = z.object({
kind: z.literal("drop_paragraph_if_starts_with"),
prefixes: z.array(z.string().max(500)).max(50),
caseSensitive: z.boolean().optional(),
});
const transformReplaceTextSchema = z.object({
kind: z.literal("replace_text"),
match: z.string().min(1).max(500),
replacement: z.string().max(500),
allOccurrences: z.boolean().optional(),
});
const transformReplaceRegexSchema = z.object({
kind: z.literal("replace_regex"),
pattern: z.string().min(1).max(500),
flags: z.string().max(10).optional(),
replacement: z.string().max(500),
});
const transformDropBlockIfContainsSchema = z.object({
kind: z.literal("drop_block_if_contains"),
needles: z.array(z.string().max(500)).max(50),
});
const transformPrependSystemBlockSchema = z.object({
kind: z.literal("prepend_system_block"),
text: z.string().min(1).max(2000),
idempotencyKey: z.string().max(100).optional(),
});
const transformAppendSystemBlockSchema = z.object({
kind: z.literal("append_system_block"),
text: z.string().min(1).max(2000),
idempotencyKey: z.string().max(100).optional(),
});
const transformInjectBillingHeaderSchema = z.object({
kind: z.literal("inject_billing_header"),
entrypoint: z.string().min(1).max(50),
versionFormat: z.enum(["ex-machina", "omniroute-daystamp"]),
cchAlgo: z.enum(["sha256-first-user", "xxhash64-body", "static-zero"]),
version: z.string().max(50).optional(),
});
const commonSystemTransformOperationSchemas = [
transformDropParagraphIfContainsSchema,
transformDropParagraphIfStartsWithSchema,
transformReplaceTextSchema,
transformReplaceRegexSchema,
transformDropBlockIfContainsSchema,
transformPrependSystemBlockSchema,
transformAppendSystemBlockSchema,
transformInjectBillingHeaderSchema,
] as const;
const transformObfuscateWordsSchema = z.object({
kind: z.literal("obfuscate_words"),
words: z.array(z.string().max(100)).max(200),
targets: z
.array(z.enum(["system", "messages", "tools"]))
.max(3)
.optional(),
});
export const updateSettingsSchema = z.object({
newPassword: z.string().min(1).max(200).optional(),
currentPassword: z.string().max(200).optional(),
@@ -131,53 +202,7 @@ export const updateSettingsSchema = z.object({
.object({
enabled: z.boolean(),
pipeline: z
.array(
z.discriminatedUnion("kind", [
z.object({
kind: z.literal("drop_paragraph_if_contains"),
needles: z.array(z.string().max(500)).max(50),
caseSensitive: z.boolean().optional(),
}),
z.object({
kind: z.literal("drop_paragraph_if_starts_with"),
prefixes: z.array(z.string().max(500)).max(50),
caseSensitive: z.boolean().optional(),
}),
z.object({
kind: z.literal("replace_text"),
match: z.string().min(1).max(500),
replacement: z.string().max(500),
allOccurrences: z.boolean().optional(),
}),
z.object({
kind: z.literal("replace_regex"),
pattern: z.string().min(1).max(500),
flags: z.string().max(10).optional(),
replacement: z.string().max(500),
}),
z.object({
kind: z.literal("drop_block_if_contains"),
needles: z.array(z.string().max(500)).max(50),
}),
z.object({
kind: z.literal("prepend_system_block"),
text: z.string().min(1).max(2000),
idempotencyKey: z.string().max(100).optional(),
}),
z.object({
kind: z.literal("append_system_block"),
text: z.string().min(1).max(2000),
idempotencyKey: z.string().max(100).optional(),
}),
z.object({
kind: z.literal("inject_billing_header"),
entrypoint: z.string().min(1).max(50),
versionFormat: z.enum(["ex-machina", "omniroute-daystamp"]),
cchAlgo: z.enum(["sha256-first-user", "xxhash64-body", "static-zero"]),
version: z.string().max(50).optional(),
}),
])
)
.array(z.discriminatedUnion("kind", commonSystemTransformOperationSchemas))
.max(50),
})
.optional(),
@@ -193,57 +218,8 @@ export const updateSettingsSchema = z.object({
pipeline: z
.array(
z.discriminatedUnion("kind", [
z.object({
kind: z.literal("drop_paragraph_if_contains"),
needles: z.array(z.string().max(500)).max(50),
caseSensitive: z.boolean().optional(),
}),
z.object({
kind: z.literal("drop_paragraph_if_starts_with"),
prefixes: z.array(z.string().max(500)).max(50),
caseSensitive: z.boolean().optional(),
}),
z.object({
kind: z.literal("replace_text"),
match: z.string().min(1).max(500),
replacement: z.string().max(500),
allOccurrences: z.boolean().optional(),
}),
z.object({
kind: z.literal("replace_regex"),
pattern: z.string().min(1).max(500),
flags: z.string().max(10).optional(),
replacement: z.string().max(500),
}),
z.object({
kind: z.literal("drop_block_if_contains"),
needles: z.array(z.string().max(500)).max(50),
}),
z.object({
kind: z.literal("prepend_system_block"),
text: z.string().min(1).max(2000),
idempotencyKey: z.string().max(100).optional(),
}),
z.object({
kind: z.literal("append_system_block"),
text: z.string().min(1).max(2000),
idempotencyKey: z.string().max(100).optional(),
}),
z.object({
kind: z.literal("inject_billing_header"),
entrypoint: z.string().min(1).max(50),
versionFormat: z.enum(["ex-machina", "omniroute-daystamp"]),
cchAlgo: z.enum(["sha256-first-user", "xxhash64-body", "static-zero"]),
version: z.string().max(50).optional(),
}),
z.object({
kind: z.literal("obfuscate_words"),
words: z.array(z.string().max(100)).max(200),
targets: z
.array(z.enum(["system", "messages", "tools"]))
.max(3)
.optional(),
}),
...commonSystemTransformOperationSchemas,
transformObfuscateWordsSchema,
])
)
.max(50),

View File

@@ -0,0 +1,100 @@
import test from "node:test";
import assert from "node:assert/strict";
import { updateSettingsSchema } from "../../src/shared/validation/settingsSchemas.ts";
const commonOperations = [
{
kind: "drop_paragraph_if_contains",
needles: ["needle"],
caseSensitive: true,
},
{
kind: "drop_paragraph_if_starts_with",
prefixes: ["prefix"],
},
{
kind: "replace_text",
match: "before",
replacement: "after",
allOccurrences: true,
},
{
kind: "replace_regex",
pattern: "before",
flags: "gi",
replacement: "after",
},
{
kind: "drop_block_if_contains",
needles: ["needle"],
},
{
kind: "prepend_system_block",
text: "prefix block",
idempotencyKey: "prefix-key",
},
{
kind: "append_system_block",
text: "suffix block",
},
{
kind: "inject_billing_header",
entrypoint: "claude-code",
versionFormat: "ex-machina",
cchAlgo: "sha256-first-user",
version: "1.0.0",
},
] as const;
test("settings schema accepts the shared transform operations in legacy and v2 configs", () => {
const parsed = updateSettingsSchema.parse({
ccBridgeTransforms: {
enabled: true,
pipeline: commonOperations,
},
systemTransforms: {
providers: {
claude: {
enabled: true,
pipeline: commonOperations,
},
},
},
});
assert.equal(parsed.ccBridgeTransforms?.pipeline.length, commonOperations.length);
assert.equal(parsed.systemTransforms?.providers.claude.pipeline.length, commonOperations.length);
});
test("settings schema keeps obfuscate_words limited to systemTransforms", () => {
const obfuscateWords = {
kind: "obfuscate_words",
words: ["opencode"],
targets: ["system"],
} as const;
assert.equal(
updateSettingsSchema.safeParse({
systemTransforms: {
providers: {
claude: {
enabled: true,
pipeline: [obfuscateWords],
},
},
},
}).success,
true
);
assert.equal(
updateSettingsSchema.safeParse({
ccBridgeTransforms: {
enabled: true,
pipeline: [obfuscateWords],
},
}).success,
false
);
});