@josephyan/qingflow-app-user-mcp 0.2.0-beta.94 → 0.2.0-beta.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @josephyan/qingflow-app-user-mcp@0.2.0-beta.
|
|
6
|
+
npm install @josephyan/qingflow-app-user-mcp@0.2.0-beta.95
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @josephyan/qingflow-app-user-mcp@0.2.0-beta.
|
|
12
|
+
npx -y -p @josephyan/qingflow-app-user-mcp@0.2.0-beta.95 qingflow-app-user-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import base64
|
|
3
4
|
from copy import deepcopy
|
|
4
5
|
from dataclasses import dataclass, field
|
|
5
6
|
import json
|
|
6
7
|
import os
|
|
8
|
+
import random
|
|
7
9
|
import re
|
|
10
|
+
import string
|
|
8
11
|
import tempfile
|
|
9
12
|
from typing import Any, cast
|
|
13
|
+
from urllib.parse import quote_plus, unquote_plus
|
|
10
14
|
from uuid import uuid4
|
|
11
15
|
|
|
12
16
|
from ..backend_client import BackendRequestContext
|
|
@@ -143,6 +147,7 @@ JUDGE_EQUAL_ANY = 9
|
|
|
143
147
|
JUDGE_FUZZY_MATCH = 19
|
|
144
148
|
JUDGE_INCLUDE_ANY = 20
|
|
145
149
|
DEFAULT_TYPE_RELATION = 2
|
|
150
|
+
DEFAULT_TYPE_FORMULA = 3
|
|
146
151
|
RELATION_TYPE_Q_LINKER = 2
|
|
147
152
|
RELATION_TYPE_CODE_BLOCK = 3
|
|
148
153
|
|
|
@@ -12927,6 +12932,48 @@ def _copy_present_keys(
|
|
|
12927
12932
|
return payload
|
|
12928
12933
|
|
|
12929
12934
|
|
|
12935
|
+
def _looks_like_backend_encoded_formula(value: str) -> bool:
|
|
12936
|
+
if len(value) <= 32:
|
|
12937
|
+
return False
|
|
12938
|
+
encoded = value[16:-16]
|
|
12939
|
+
if not encoded:
|
|
12940
|
+
return False
|
|
12941
|
+
try:
|
|
12942
|
+
decoded = base64.b64decode(encoded, validate=True).decode("utf-8")
|
|
12943
|
+
unquote_plus(decoded)
|
|
12944
|
+
except Exception:
|
|
12945
|
+
return False
|
|
12946
|
+
return True
|
|
12947
|
+
|
|
12948
|
+
|
|
12949
|
+
def _encode_formula_for_backend_save(value: Any) -> Any:
|
|
12950
|
+
if not isinstance(value, str) or not value:
|
|
12951
|
+
return value
|
|
12952
|
+
if _looks_like_backend_encoded_formula(value):
|
|
12953
|
+
return value
|
|
12954
|
+
encoded = quote_plus(value, encoding="utf-8")
|
|
12955
|
+
b64_value = base64.b64encode(encoded.encode("utf-8")).decode("ascii")
|
|
12956
|
+
alphabet = string.ascii_letters + string.digits
|
|
12957
|
+
prefix = "".join(random.choice(alphabet) for _ in range(16))
|
|
12958
|
+
suffix = "".join(random.choice(alphabet) for _ in range(16))
|
|
12959
|
+
return f"{prefix}{b64_value}{suffix}"
|
|
12960
|
+
|
|
12961
|
+
|
|
12962
|
+
def _normalize_formula_defaults_for_save(value: Any) -> None:
|
|
12963
|
+
if isinstance(value, list):
|
|
12964
|
+
for item in value:
|
|
12965
|
+
_normalize_formula_defaults_for_save(item)
|
|
12966
|
+
return
|
|
12967
|
+
if not isinstance(value, dict):
|
|
12968
|
+
return
|
|
12969
|
+
if _coerce_any_int(value.get("queDefaultType")) == DEFAULT_TYPE_FORMULA and value.get("queDefaultValue"):
|
|
12970
|
+
value["queDefaultValue"] = _encode_formula_for_backend_save(value.get("queDefaultValue"))
|
|
12971
|
+
for key in ("subQuestions", "innerQuestions"):
|
|
12972
|
+
nested = value.get(key)
|
|
12973
|
+
if isinstance(nested, (list, dict)):
|
|
12974
|
+
_normalize_formula_defaults_for_save(nested)
|
|
12975
|
+
|
|
12976
|
+
|
|
12930
12977
|
def _normalize_reference_question_for_save(value: Any, *, ordinal: int) -> dict[str, Any] | None:
|
|
12931
12978
|
if not isinstance(value, dict):
|
|
12932
12979
|
return None
|
|
@@ -13090,6 +13137,8 @@ def _normalize_question_relations_for_save(question_relations: list[dict[str, An
|
|
|
13090
13137
|
value = relation.get(key)
|
|
13091
13138
|
if value is None:
|
|
13092
13139
|
continue
|
|
13140
|
+
if key == "matchRuleFormula":
|
|
13141
|
+
value = _encode_formula_for_backend_save(value)
|
|
13093
13142
|
item[key] = deepcopy(value)
|
|
13094
13143
|
if item:
|
|
13095
13144
|
normalized.append(item)
|
|
@@ -13412,6 +13461,7 @@ def _build_form_payload_from_fields(
|
|
|
13412
13461
|
for row in form_rows:
|
|
13413
13462
|
_apply_row_widths(row)
|
|
13414
13463
|
payload = default_form_payload(title, form_rows)
|
|
13464
|
+
_normalize_formula_defaults_for_save(payload.get("formQues"))
|
|
13415
13465
|
payload["editVersionNo"] = int(current_schema.get("editVersionNo") or 1)
|
|
13416
13466
|
payload["questionRelations"] = _normalize_question_relations_for_save(
|
|
13417
13467
|
question_relations if question_relations is not None else (current_schema.get("questionRelations") or [])
|
|
@@ -13529,6 +13579,7 @@ def _build_form_payload_for_edit_fields(
|
|
|
13529
13579
|
|
|
13530
13580
|
payload = _build_form_save_base_payload(current_schema, title)
|
|
13531
13581
|
payload["formQues"] = form_rows
|
|
13582
|
+
_normalize_formula_defaults_for_save(payload.get("formQues"))
|
|
13532
13583
|
payload["questionRelations"] = normalized_relations
|
|
13533
13584
|
payload["editVersionNo"] = int(current_schema.get("editVersionNo") or 1)
|
|
13534
13585
|
return payload
|
|
@@ -14945,6 +14996,7 @@ def _build_form_payload_from_existing_schema(
|
|
|
14945
14996
|
|
|
14946
14997
|
payload = _build_form_save_base_payload(current_schema, str(current_schema.get("formTitle") or "未命名应用"))
|
|
14947
14998
|
payload["formQues"] = form_rows
|
|
14999
|
+
_normalize_formula_defaults_for_save(payload.get("formQues"))
|
|
14948
15000
|
payload["questionRelations"] = _normalize_question_relations_for_save(current_schema.get("questionRelations") or [])
|
|
14949
15001
|
payload["editVersionNo"] = int(current_schema.get("editVersionNo") or 1)
|
|
14950
15002
|
payload.setdefault("formTitle", current_schema.get("formTitle") or "未命名应用")
|