mirror of
https://github.com/ankitects/anki.git
synced 2025-11-06 20:57:13 -05:00
Fix undo of methods returning OpChanges directly not being handled correctly
This commit is contained in:
parent
d0eb61acdb
commit
9b28ed87f2
3 changed files with 34 additions and 20 deletions
|
|
@ -999,7 +999,12 @@ def raw_backend_request(endpoint: str) -> Callable[[], bytes]:
|
||||||
|
|
||||||
def wrapped() -> bytes:
|
def wrapped() -> bytes:
|
||||||
output = getattr(aqt.mw.col._backend, f"{endpoint}_raw")(request.data)
|
output = getattr(aqt.mw.col._backend, f"{endpoint}_raw")(request.data)
|
||||||
if "Has-Op-Changes" in request.headers:
|
op_changes_type = int(request.headers.get("Anki-Op-Changes", "0"))
|
||||||
|
if op_changes_type:
|
||||||
|
response: OpChanges | OpChangesOnly
|
||||||
|
if op_changes_type == 1:
|
||||||
|
response = OpChanges()
|
||||||
|
else:
|
||||||
response = OpChangesOnly()
|
response = OpChangesOnly()
|
||||||
response.ParseFromString(output)
|
response.ParseFromString(output)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -74,15 +74,16 @@ fn write_ts_method(
|
||||||
input_type,
|
input_type,
|
||||||
output_type,
|
output_type,
|
||||||
comments,
|
comments,
|
||||||
has_op_changes,
|
op_changes_type,
|
||||||
}: &MethodDetails,
|
}: &MethodDetails,
|
||||||
out: &mut String,
|
out: &mut String,
|
||||||
) {
|
) {
|
||||||
|
let op_changes_type = *op_changes_type as u8;
|
||||||
let comments = format_comments(comments);
|
let comments = format_comments(comments);
|
||||||
writeln!(
|
writeln!(
|
||||||
out,
|
out,
|
||||||
r#"{comments}export async function {method_name}(input: PlainMessage<{input_type}>, options?: PostProtoOptions): Promise<{output_type}> {{
|
r#"{comments}export async function {method_name}(input: PlainMessage<{input_type}>, options?: PostProtoOptions): Promise<{output_type}> {{
|
||||||
return await postProto("{method_name}", new {input_type}(input), {output_type}, options, {has_op_changes});
|
return await postProto("{method_name}", new {input_type}(input), {output_type}, options, {op_changes_type});
|
||||||
}}"#
|
}}"#
|
||||||
).unwrap()
|
).unwrap()
|
||||||
}
|
}
|
||||||
|
|
@ -94,12 +95,20 @@ fn format_comments(comments: &Option<String>) -> String {
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[repr(u8)]
|
||||||
|
enum OpChangesType {
|
||||||
|
None = 0,
|
||||||
|
OpChanges = 1,
|
||||||
|
OpChangesOnly = 2,
|
||||||
|
}
|
||||||
|
|
||||||
struct MethodDetails {
|
struct MethodDetails {
|
||||||
method_name: String,
|
method_name: String,
|
||||||
input_type: String,
|
input_type: String,
|
||||||
output_type: String,
|
output_type: String,
|
||||||
comments: Option<String>,
|
comments: Option<String>,
|
||||||
has_op_changes: bool,
|
op_changes_type: OpChangesType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MethodDetails {
|
impl MethodDetails {
|
||||||
|
|
@ -108,28 +117,32 @@ impl MethodDetails {
|
||||||
let input_type = full_name_to_imported_reference(method.proto.input().full_name());
|
let input_type = full_name_to_imported_reference(method.proto.input().full_name());
|
||||||
let output_type = full_name_to_imported_reference(method.proto.output().full_name());
|
let output_type = full_name_to_imported_reference(method.proto.output().full_name());
|
||||||
let comments = method.comments.clone();
|
let comments = method.comments.clone();
|
||||||
let has_op_changes = has_op_changes(&method.proto.output());
|
let op_changes_type = get_op_changes_type(&method.proto.output(), true);
|
||||||
Self {
|
Self {
|
||||||
method_name: name,
|
method_name: name,
|
||||||
input_type,
|
input_type,
|
||||||
output_type,
|
output_type,
|
||||||
comments,
|
comments,
|
||||||
has_op_changes,
|
op_changes_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_op_changes(message: &MessageDescriptor) -> bool {
|
fn get_op_changes_type(message: &MessageDescriptor, root: bool) -> OpChangesType {
|
||||||
if message.full_name() == "anki.collection.OpChanges" {
|
if message.full_name() == "anki.collection.OpChanges" {
|
||||||
true
|
if root {
|
||||||
|
OpChangesType::OpChanges
|
||||||
|
} else {
|
||||||
|
OpChangesType::OpChangesOnly
|
||||||
|
}
|
||||||
} else if let Some(field) = message.get_field(1) {
|
} else if let Some(field) = message.get_field(1) {
|
||||||
if let Some(field_message) = field.kind().as_message() {
|
if let Some(field_message) = field.kind().as_message() {
|
||||||
has_op_changes(field_message)
|
get_op_changes_type(field_message, false)
|
||||||
} else {
|
} else {
|
||||||
false
|
OpChangesType::None
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
OpChangesType::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,12 @@ export async function postProto<T>(
|
||||||
input: { toBinary(): Uint8Array; getType(): { typeName: string } },
|
input: { toBinary(): Uint8Array; getType(): { typeName: string } },
|
||||||
outputType: { fromBinary(arr: Uint8Array): T },
|
outputType: { fromBinary(arr: Uint8Array): T },
|
||||||
options: PostProtoOptions = {},
|
options: PostProtoOptions = {},
|
||||||
hasOpChanges = false,
|
opChangesType = 0,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
try {
|
try {
|
||||||
const inputBytes = input.toBinary();
|
const inputBytes = input.toBinary();
|
||||||
const path = `/_anki/${method}`;
|
const path = `/_anki/${method}`;
|
||||||
const outputBytes = await postProtoInner(path, inputBytes, hasOpChanges);
|
const outputBytes = await postProtoInner(path, inputBytes, opChangesType);
|
||||||
return outputType.fromBinary(outputBytes);
|
return outputType.fromBinary(outputBytes);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const { alertOnError = true } = options;
|
const { alertOnError = true } = options;
|
||||||
|
|
@ -27,14 +27,10 @@ export async function postProto<T>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function postProtoInner(url: string, body: Uint8Array, hasOpChanges: boolean): Promise<Uint8Array> {
|
async function postProtoInner(url: string, body: Uint8Array, opChangesType: number): Promise<Uint8Array> {
|
||||||
const headers = { "Content-Type": "application/binary" };
|
|
||||||
if (hasOpChanges) {
|
|
||||||
headers["Has-Op-Changes"] = "1";
|
|
||||||
}
|
|
||||||
const result = await fetch(url, {
|
const result = await fetch(url, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers,
|
headers: { "Content-Type": "application/binary", "Anki-Op-Changes": opChangesType.toString() },
|
||||||
body,
|
body,
|
||||||
});
|
});
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue