From fcd1835a5defe15de45a7d5a4e830be70bb2e774 Mon Sep 17 00:00:00 2001 From: Eddie Kohler Date: Thu, 12 Sep 2024 19:12:21 -0400 Subject: [PATCH] API spec can handle deprecated response components --- etc/apifunctions.json | 59 +++++++++++++++++++++++++---------- scripts/script.js | 4 +-- src/api/api_decision.php | 9 +++++- src/api/api_paperpc.php | 3 ++ src/api/api_specvalidator.php | 23 ++++++++++++-- 5 files changed, 75 insertions(+), 23 deletions(-) diff --git a/etc/apifunctions.json b/etc/apifunctions.json index 5312f62618..03894e6758 100644 --- a/etc/apifunctions.json +++ b/etc/apifunctions.json @@ -18,7 +18,7 @@ { "name": "alltags", "get": true, "function": "AllTags_API::run", - "response": "tags readonly_tagmap sitewide_tagmap" + "response": "tags ?readonly_tagmap ?sitewide_tagmap" }, { "name": "assign", "post": true, "redirect": true, @@ -39,7 +39,8 @@ "name": "comment", "paper": true, "get": true, "function": "Comment_API::run", "parameters": "c", - "response": "cmt ?XXX" + "response": "comment", + "response_deprecated": "cmt" }, { "name": "comment", "paper": true, "post": true, @@ -53,12 +54,15 @@ }, { "name": "decision", "paper": true, "get": true, - "function": "Decision_API::run" + "function": "Decision_API::run", + "response": "decision decision_html ?editable" }, { "name": "decision", "paper": true, "post": true, "function": "Decision_API::run", - "parameters": "=decision" + "parameters": "=decision", + "response": "decision decision_html ?editable", + "response_deprecated": "value result" }, { "name": "events", "get": true, @@ -104,12 +108,15 @@ }, { "name": "lead", "paper": true, "get": true, - "function": "PaperPC_API::lead_api" + "function": "PaperPC_API::lead_api", + "response": "lead lead_html ?color_classes" }, { "name": "lead", "paper": true, "post": true, "function": "PaperPC_API::lead_api", - "parameters": "=lead" + "parameters": "=lead", + "response": "lead lead_html ?color_classes", + "response_deprecated": "value result" }, { "name": "mailtext", "get": true, "post": true, @@ -118,12 +125,15 @@ }, { "name": "manager", "paper": true, "get": true, - "function": "PaperPC_API::manager_api" + "function": "PaperPC_API::manager_api", + "response": "manager manager_html ?color_classes", + "response_deprecated": "value result" }, { "name": "manager", "paper": true, "post": true, "function": "PaperPC_API::manager_api", - "parameters": "=manager" + "parameters": "=manager", + "response": "manager manager_html ?color_classes" }, { "name": "administrator", "alias": "manager" @@ -167,7 +177,8 @@ }, { "name": "pc", "get": true, "post": true, - "function": "PaperPC_API::pc_api" + "function": "PaperPC_API::pc_api", + "response": "pc" }, { "name": "requestreview", "paper": true, "post": true, @@ -248,12 +259,14 @@ }, { "name": "tags", "get": true, "paper": true, - "function": "Tags_API::run" + "function": "Tags_API::run", + "response": "pid tags tags_edit_text tags_view_html tag_decoration_html color_classes" }, { "name": "tags", "post": true, "function": "Tags_API::run", - "parameters": "?p ?forceShow ?=tags ?=addtags ?=deltags ?=tagassignment ?=search" + "parameters": "?p ?forceShow ?=tags ?=addtags ?=deltags ?=tagassignment ?=search", + "response": "?pid ?tags ?tags_edit_text ?tags_view_html ?tag_decoration_html ?color_classes ?p" }, { "name": "settingdescriptions", "get": true, @@ -266,12 +279,15 @@ }, { "name": "shepherd", "paper": true, "get": true, - "function": "PaperPC_API::shepherd_api" + "function": "PaperPC_API::shepherd_api", + "response": "shepherd shepherd_html ?color_classes" }, { "name": "shepherd", "paper": true, "post": true, "function": "PaperPC_API::shepherd_api", - "parameters": "=shepherd" + "parameters": "=shepherd", + "response": "shepherd shepherd_html ?color_classes", + "response_deprecated": "value result" }, { "name": "submissionfieldlibrary", "get": true, "allow_if": "chair", @@ -289,7 +305,8 @@ }, { "name": "tagmessages", "paper": true, "get": true, - "function": "Tags_API::tagmessages_api" + "function": "Tags_API::tagmessages_api", + "response": "pid" }, { "name": "tagreport", "alias": "tagmessages" @@ -317,11 +334,19 @@ "name": "user", "get": true, "function": "User_API::user", "parameters": "email ?p ?potential_conflict", - "response": "found ?email ?given_name ?family_name ?affiliation ?potential_conflict" + "response": "found ?email ?given_name ?family_name ?affiliation ?potential_conflict ?orcid ?country" + }, + { + "name": "viewoptions", "get": true, + "function": "SearchConfig_API::viewoptions", + "parameters": "?report ?q", + "response": "report display_current display_default display_difference display_default_message_list" }, { - "name": "viewoptions", "get": true, "post": true, - "function": "SearchConfig_API::viewoptions" + "name": "viewoptions", "post": true, + "function": "SearchConfig_API::viewoptions", + "parameters": "?report ?q =display", + "response": "report display_current display_default display_difference display_default_message_list" }, { "name": "listreport", "alias": "viewoptions" diff --git a/scripts/script.js b/scripts/script.js index e12d5ee869..5774f9f7c9 100644 --- a/scripts/script.js +++ b/scripts/script.js @@ -12287,10 +12287,10 @@ function prepare_paper_select() { return function (data) { minifeedback(ctl, data); if (data.ok) { - ctl.setAttribute("data-default-value", data.value); + ctl.setAttribute("data-default-value", data[ctl.name] || data.value); close && foldup.call(self, null, {open: false}); var $p = $(self).find(".js-psedit-result").first(); - $p.html(data.result || ctl.options[ctl.selectedIndex].innerHTML); + $p.html(data[ctl.name + "_html"] || data.result || ctl.options[ctl.selectedIndex].innerHTML); if (data.color_classes) { ensure_pattern(data.color_classes); $p.html('' + $p.html() + ''); diff --git a/src/api/api_decision.php b/src/api/api_decision.php index 0207da7c9a..30f43716bd 100644 --- a/src/api/api_decision.php +++ b/src/api/api_decision.php @@ -18,7 +18,14 @@ static function run(Contact $user, Qrequest $qreq, PaperInfo $prow) { $prow->load_decision(); } $dec = $prow->viewable_decision($user); - $jr = new JsonResult(["ok" => true, "value" => $dec->id, "result" => $dec->name_as(5)]); + $jr = new JsonResult([ + "ok" => true, + "decision" => $dec->id, + "decision_html" => $dec->name_as(5), + /* XXX backward compat */ + "value" => $dec->id, + "result" => $dec->name_as(5) + ]); if ($user->can_set_decision($prow)) { $jr->content["editable"] = true; } diff --git a/src/api/api_paperpc.php b/src/api/api_paperpc.php index b00ba872e5..f1c69d0b3e 100644 --- a/src/api/api_paperpc.php +++ b/src/api/api_paperpc.php @@ -23,6 +23,9 @@ private static function run(Contact $user, Qrequest $qreq, PaperInfo $prow, $typ $pcu = $cid ? $user->conf->user_by_id($cid, USER_SLICE) : null; $j = [ "ok" => true, + $type => $pcu ? $pcu->email : "none", + "{$type}_html" => $pcu ? $user->name_html_for($pcu) : "None", + /* XXX backward compat */ "value" => $pcu ? $pcu->email : "none", "result" => $pcu ? $user->name_html_for($pcu) : "None" ]; diff --git a/src/api/api_specvalidator.php b/src/api/api_specvalidator.php index 69cc0497c3..840dee7ca8 100644 --- a/src/api/api_specvalidator.php +++ b/src/api/api_specvalidator.php @@ -8,6 +8,7 @@ class SpecValidator_API { const F_FILE = 4; const F_SUFFIX = 8; const F_PRESENT = 16; + const F_DEPRECATED = 32; static function request($uf, Qrequest $qreq) { $parameters = $uf->parameters ?? []; @@ -82,10 +83,18 @@ static function response($uf, Qrequest $qreq, JsonResult $jr) { if ($response === ["*"]) { return; } + $response_deprecated = $uf->response_deprecated ?? []; + if (is_string($response_deprecated)) { + $response_deprecated = explode(" ", trim($response_deprecated)); + } + $nmandatory = count($response); + if (!empty($response_deprecated)) { + array_push($response, ...$response_deprecated); + } $known = []; $has_suffix = false; - foreach ($response as $p) { - $t = self::F_REQUIRED; + foreach ($response as $i => $p) { + $t = $i < $nmandatory ? self::F_REQUIRED : self::F_DEPRECATED; for ($i = 0; $i !== strlen($p); ++$i) { if ($p[$i] === "?") { $t &= ~self::F_REQUIRED; @@ -109,11 +118,19 @@ static function response($uf, Qrequest $qreq, JsonResult $jr) { if (!$jr->content["ok"]) { return; } + $missing = []; foreach ($known as $n => $t) { if (($t & (self::F_REQUIRED | self::F_PRESENT)) === self::F_REQUIRED) { - self::error($qreq, "response component `{$n}` missing"); + $missing[] = $n; + } else if (($t & (self::F_DEPRECATED | self::F_PRESENT)) === (self::F_DEPRECATED | self::F_PRESENT)) { + // if a deprecated response component is present, + // ignore required response component errors + return; } } + foreach ($missing as $n) { + self::error($qreq, "response component `{$n}` missing"); + } } static function lookup_type($n, &$known, $has_suffix) {