mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 09:40:43 +00:00
fix(protocol): keep Swift array item types stable
This commit is contained in:
@@ -80,12 +80,54 @@ function safeName(name: string) {
|
||||
|
||||
// filled later once schemas are loaded
|
||||
const schemaNameByObject = new Map<object, string>();
|
||||
const schemaNameBySignature = new Map<string, string>();
|
||||
const duplicateSchemaSignatures = new Set<string>();
|
||||
|
||||
function swiftType(schema: JsonSchema, required: boolean): string {
|
||||
function stableJson(value: unknown): unknown {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map(stableJson);
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
const record = value as Record<string, unknown>;
|
||||
return Object.fromEntries(
|
||||
Object.keys(record)
|
||||
.toSorted()
|
||||
.map((key) => [key, stableJson(record[key])]),
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function schemaSignature(schema: JsonSchema): string {
|
||||
return JSON.stringify(stableJson(schema));
|
||||
}
|
||||
|
||||
function registerNamedSchema(name: string, schema: JsonSchema): void {
|
||||
schemaNameByObject.set(schema as object, name);
|
||||
const signature = schemaSignature(schema);
|
||||
if (duplicateSchemaSignatures.has(signature)) {
|
||||
return;
|
||||
}
|
||||
if (schemaNameBySignature.has(signature)) {
|
||||
schemaNameBySignature.delete(signature);
|
||||
duplicateSchemaSignatures.add(signature);
|
||||
return;
|
||||
}
|
||||
schemaNameBySignature.set(signature, name);
|
||||
}
|
||||
|
||||
function namedSchema(schema: JsonSchema, allowStructuralFallback = false): string | undefined {
|
||||
return (
|
||||
schemaNameByObject.get(schema as object) ??
|
||||
(allowStructuralFallback ? schemaNameBySignature.get(schemaSignature(schema)) : undefined)
|
||||
);
|
||||
}
|
||||
|
||||
function swiftType(schema: JsonSchema, required: boolean, allowStructuralNamed = false): string {
|
||||
const t = schema.type;
|
||||
const isOptional = !required;
|
||||
let base: string;
|
||||
const named = schemaNameByObject.get(schema as object);
|
||||
const named = namedSchema(schema, allowStructuralNamed);
|
||||
if (named) {
|
||||
base = named;
|
||||
} else if (t === "string") {
|
||||
@@ -97,7 +139,7 @@ function swiftType(schema: JsonSchema, required: boolean): string {
|
||||
} else if (t === "boolean") {
|
||||
base = "Bool";
|
||||
} else if (t === "array") {
|
||||
base = `[${swiftType(schema.items ?? { type: "Any" }, true)}]`;
|
||||
base = `[${swiftType(schema.items ?? { type: "Any" }, true, true)}]`;
|
||||
} else if (schema.enum) {
|
||||
base = "String";
|
||||
} else if (schema.patternProperties) {
|
||||
@@ -214,7 +256,7 @@ async function generate() {
|
||||
const definitions = Object.entries(ProtocolSchemas) as Array<[string, JsonSchema]>;
|
||||
|
||||
for (const [name, schema] of definitions) {
|
||||
schemaNameByObject.set(schema as object, name);
|
||||
registerNamedSchema(name, schema);
|
||||
}
|
||||
|
||||
const parts: string[] = [];
|
||||
|
||||
Reference in New Issue
Block a user