bk-schema-checker 0.1.3 → 0.1.4
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/package.json +2 -2
- package/py/load_backend.py +45 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bk-schema-checker",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "对照前端 services、Django REST 序列化器,以及可选的 bk-local-mock 响应,做接口协议检查。不启动 Django。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "austinqli",
|
|
@@ -43,4 +43,4 @@
|
|
|
43
43
|
"check": "node ./bin/bk-schema-checker.js",
|
|
44
44
|
"test": "node --test test/"
|
|
45
45
|
}
|
|
46
|
-
}
|
|
46
|
+
}
|
package/py/load_backend.py
CHANGED
|
@@ -1380,10 +1380,48 @@ class BackendLoader:
|
|
|
1380
1380
|
schema = self.materialize(ref, mode, stack)
|
|
1381
1381
|
if schema.get("type") == "array":
|
|
1382
1382
|
return {"schema": schema, "many": True, "empty": False}
|
|
1383
|
+
if not many and mode == "response" and isinstance(self.swagger_example(ref), list):
|
|
1384
|
+
many = True
|
|
1383
1385
|
if many:
|
|
1384
1386
|
schema = {"type": "array", "items": schema}
|
|
1385
1387
|
return {"schema": schema, "many": many, "empty": False}
|
|
1386
1388
|
|
|
1389
|
+
def swagger_example(self, ref):
|
|
1390
|
+
if not ref:
|
|
1391
|
+
return None
|
|
1392
|
+
meta = nested_class(ref.node, "Meta")
|
|
1393
|
+
if not meta:
|
|
1394
|
+
return None
|
|
1395
|
+
node = class_assign(meta, "swagger_schema_fields")
|
|
1396
|
+
if node is None:
|
|
1397
|
+
return None
|
|
1398
|
+
value = self.eval_const(node, ref.module, set())
|
|
1399
|
+
if not isinstance(value, dict):
|
|
1400
|
+
return None
|
|
1401
|
+
return value.get("example")
|
|
1402
|
+
|
|
1403
|
+
def schema_from_swagger_example(self, ref):
|
|
1404
|
+
example = self.swagger_example(ref)
|
|
1405
|
+
if not isinstance(example, list):
|
|
1406
|
+
return None
|
|
1407
|
+
return {"type": "array", "items": self.example_item_schema(example), "required": True}
|
|
1408
|
+
|
|
1409
|
+
def example_item_schema(self, example):
|
|
1410
|
+
if not example:
|
|
1411
|
+
return any_schema()
|
|
1412
|
+
first = example[0]
|
|
1413
|
+
if isinstance(first, dict):
|
|
1414
|
+
return {"type": "object", "fields": {}, "open": True, "required": True}
|
|
1415
|
+
if isinstance(first, bool):
|
|
1416
|
+
return {"type": "boolean", "required": True, "allowNull": False}
|
|
1417
|
+
if isinstance(first, int):
|
|
1418
|
+
return {"type": "integer", "required": True, "allowNull": False}
|
|
1419
|
+
if isinstance(first, float):
|
|
1420
|
+
return {"type": "number", "required": True, "allowNull": False}
|
|
1421
|
+
if isinstance(first, str):
|
|
1422
|
+
return {"type": "string", "required": True, "allowNull": False}
|
|
1423
|
+
return any_schema()
|
|
1424
|
+
|
|
1387
1425
|
def materialize(self, ref, mode, stack):
|
|
1388
1426
|
key = f"{ref.module.file}#{ref.name}"
|
|
1389
1427
|
if key in stack:
|
|
@@ -1414,7 +1452,13 @@ class BackendLoader:
|
|
|
1414
1452
|
if mode == "response" and built.get("writeOnly"):
|
|
1415
1453
|
continue
|
|
1416
1454
|
fields[field_name] = built
|
|
1417
|
-
|
|
1455
|
+
schema = {"type": "object", "fields": fields, "serializer": ref.name, "required": True}
|
|
1456
|
+
if mode == "response" and not fields:
|
|
1457
|
+
hinted = self.schema_from_swagger_example(ref)
|
|
1458
|
+
if hinted:
|
|
1459
|
+
hinted.setdefault("serializer", ref.name)
|
|
1460
|
+
return hinted
|
|
1461
|
+
return schema
|
|
1418
1462
|
finally:
|
|
1419
1463
|
stack.discard(key)
|
|
1420
1464
|
|