mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
chore(duplication): share settings transform schemas (#5496)
This commit is contained in:
@@ -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),
|
||||
|
||||
100
tests/unit/settings-transform-schema.test.ts
Normal file
100
tests/unit/settings-transform-schema.test.ts
Normal 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
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user