@josephyan/qingflow-cli 0.2.0-beta.78 → 0.2.0-beta.80

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-cli@0.2.0-beta.78
6
+ npm install @josephyan/qingflow-cli@0.2.0-beta.80
7
7
  ```
8
8
 
9
9
  Run:
10
10
 
11
11
  ```bash
12
- npx -y -p @josephyan/qingflow-cli@0.2.0-beta.78 qingflow
12
+ npx -y -p @josephyan/qingflow-cli@0.2.0-beta.80 qingflow
13
13
  ```
14
14
 
15
15
  Environment:
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josephyan/qingflow-cli",
3
- "version": "0.2.0-beta.78",
3
+ "version": "0.2.0-beta.80",
4
4
  "description": "Human-friendly Qingflow command line interface for auth, record operations, import, tasks, and stable builder flows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qingflow-mcp"
7
- version = "0.2.0b78"
7
+ version = "0.2.0b80"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -2,4 +2,4 @@ from __future__ import annotations
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.2.0b78"
5
+ __version__ = "0.2.0b80"
@@ -40,6 +40,18 @@ class PublicDepartmentScopeMode(str, Enum):
40
40
  custom = "custom"
41
41
 
42
42
 
43
+ class PublicVisibilityMode(str, Enum):
44
+ workspace = "workspace"
45
+ everyone = "everyone"
46
+ specific = "specific"
47
+
48
+
49
+ class PublicExternalVisibilityMode(str, Enum):
50
+ not_ = "not"
51
+ workspace = "workspace"
52
+ specific = "specific"
53
+
54
+
43
55
  FIELD_TYPE_ALIASES: dict[str, PublicFieldType] = {
44
56
  "textarea": PublicFieldType.long_text,
45
57
  "amount": PublicFieldType.amount,
@@ -346,6 +358,93 @@ class DepartmentScopePatch(StrictModel):
346
358
  return self
347
359
 
348
360
 
361
+ class VisibilitySelectorsPatch(StrictModel):
362
+ member_uids: list[int] = Field(default_factory=list, validation_alias=AliasChoices("member_uids", "memberUids"))
363
+ member_emails: list[str] = Field(default_factory=list, validation_alias=AliasChoices("member_emails", "memberEmails"))
364
+ member_names: list[str] = Field(default_factory=list, validation_alias=AliasChoices("member_names", "memberNames"))
365
+ dept_ids: list[int] = Field(default_factory=list, validation_alias=AliasChoices("dept_ids", "deptIds"))
366
+ dept_names: list[str] = Field(default_factory=list, validation_alias=AliasChoices("dept_names", "deptNames"))
367
+ role_ids: list[int] = Field(default_factory=list, validation_alias=AliasChoices("role_ids", "roleIds"))
368
+ role_names: list[str] = Field(default_factory=list, validation_alias=AliasChoices("role_names", "roleNames"))
369
+ include_sub_departs: bool | None = Field(
370
+ default=None,
371
+ validation_alias=AliasChoices("include_sub_departs", "includeSubDeparts"),
372
+ )
373
+
374
+ def has_any_selector(self) -> bool:
375
+ return any(
376
+ (
377
+ self.member_uids,
378
+ self.member_emails,
379
+ self.member_names,
380
+ self.dept_ids,
381
+ self.dept_names,
382
+ self.role_ids,
383
+ self.role_names,
384
+ )
385
+ )
386
+
387
+
388
+ class ExternalVisibilitySelectorsPatch(StrictModel):
389
+ member_ids: list[int] = Field(default_factory=list, validation_alias=AliasChoices("member_ids", "memberIds"))
390
+ member_emails: list[str] = Field(default_factory=list, validation_alias=AliasChoices("member_emails", "memberEmails"))
391
+ dept_ids: list[int] = Field(default_factory=list, validation_alias=AliasChoices("dept_ids", "deptIds"))
392
+
393
+ def has_any_selector(self) -> bool:
394
+ return any((self.member_ids, self.member_emails, self.dept_ids))
395
+
396
+
397
+ class VisibilityPatch(StrictModel):
398
+ mode: PublicVisibilityMode | None = None
399
+ selectors: VisibilitySelectorsPatch = Field(default_factory=VisibilitySelectorsPatch)
400
+ external_mode: PublicExternalVisibilityMode | None = Field(
401
+ default=None,
402
+ validation_alias=AliasChoices("external_mode", "externalMode"),
403
+ )
404
+ external_selectors: ExternalVisibilitySelectorsPatch = Field(
405
+ default_factory=ExternalVisibilitySelectorsPatch,
406
+ validation_alias=AliasChoices("external_selectors", "externalSelectors"),
407
+ )
408
+
409
+ @model_validator(mode="before")
410
+ @classmethod
411
+ def normalize_aliases(cls, value: Any) -> Any:
412
+ if not isinstance(value, dict):
413
+ return value
414
+ payload = dict(value)
415
+ selectors = payload.get("selectors")
416
+ external_selectors = payload.get("external_selectors", payload.get("externalSelectors"))
417
+ if payload.get("mode") is None:
418
+ if isinstance(selectors, dict) and selectors:
419
+ payload["mode"] = PublicVisibilityMode.specific.value
420
+ else:
421
+ payload["mode"] = PublicVisibilityMode.workspace.value
422
+ if payload.get("mode") == PublicVisibilityMode.everyone.value and payload.get("external_mode", payload.get("externalMode")) is None:
423
+ payload["external_mode"] = PublicExternalVisibilityMode.workspace.value
424
+ if payload.get("external_mode", payload.get("externalMode")) is None:
425
+ if isinstance(external_selectors, dict) and external_selectors:
426
+ payload["external_mode"] = PublicExternalVisibilityMode.specific.value
427
+ else:
428
+ payload["external_mode"] = PublicExternalVisibilityMode.not_.value
429
+ return payload
430
+
431
+ @model_validator(mode="after")
432
+ def validate_shape(self) -> "VisibilityPatch":
433
+ if self.mode == PublicVisibilityMode.specific and not self.selectors.has_any_selector():
434
+ raise ValueError("specific visibility requires selectors")
435
+ if self.mode != PublicVisibilityMode.specific and self.selectors.has_any_selector():
436
+ raise ValueError("selectors are only allowed when mode=specific")
437
+ if self.mode == PublicVisibilityMode.everyone and self.external_mode != PublicExternalVisibilityMode.workspace:
438
+ raise ValueError("mode=everyone requires external_mode=workspace")
439
+ if self.mode == PublicVisibilityMode.everyone and self.external_selectors.has_any_selector():
440
+ raise ValueError("external_selectors are not allowed when mode=everyone")
441
+ if self.external_mode == PublicExternalVisibilityMode.specific and not self.external_selectors.has_any_selector():
442
+ raise ValueError("external_mode=specific requires external_selectors")
443
+ if self.external_mode != PublicExternalVisibilityMode.specific and self.external_selectors.has_any_selector():
444
+ raise ValueError("external_selectors are only allowed when external_mode=specific")
445
+ return self
446
+
447
+
349
448
  class CodeBlockAliasPathPatch(StrictModel):
350
449
  alias_name: str = Field(validation_alias=AliasChoices("alias_name", "aliasName"))
351
450
  alias_path: str = Field(validation_alias=AliasChoices("alias_path", "aliasPath"))
@@ -916,6 +1015,7 @@ class ViewUpsertPatch(StrictModel):
916
1015
  end_field: str | None = Field(default=None, validation_alias=AliasChoices("end_field", "endField"))
917
1016
  title_field: str | None = Field(default=None, validation_alias=AliasChoices("title_field", "titleField"))
918
1017
  buttons: list["ViewButtonBindingPatch"] | None = None
1018
+ visibility: VisibilityPatch | None = None
919
1019
 
920
1020
  @model_validator(mode="before")
921
1021
  @classmethod
@@ -1237,6 +1337,7 @@ class ChartUpsertPatch(StrictModel):
1237
1337
  question_config: list[dict[str, Any]] = Field(default_factory=list)
1238
1338
  user_config: list[dict[str, Any]] = Field(default_factory=list)
1239
1339
  config: dict[str, Any] = Field(default_factory=dict)
1340
+ visibility: VisibilityPatch | None = None
1240
1341
 
1241
1342
  @model_validator(mode="before")
1242
1343
  @classmethod
@@ -1413,6 +1514,7 @@ class PortalApplyRequest(StrictModel):
1413
1514
  package_tag_id: int | None = None
1414
1515
  publish: bool = True
1415
1516
  sections: list[PortalSectionPatch] = Field(default_factory=list)
1517
+ visibility: VisibilityPatch | None = None
1416
1518
  auth: dict[str, Any] | None = None
1417
1519
  icon: str | None = None
1418
1520
  color: str | None = None
@@ -1428,6 +1530,8 @@ class PortalApplyRequest(StrictModel):
1428
1530
  raise ValueError("dash_name is required when creating a portal")
1429
1531
  if not self.sections:
1430
1532
  raise ValueError("portal apply requires a non-empty sections list")
1533
+ if self.visibility is not None and self.auth is not None:
1534
+ raise ValueError("visibility and auth cannot be provided together")
1431
1535
  return self
1432
1536
 
1433
1537
 
@@ -1438,6 +1542,7 @@ class AppGetResponse(StrictModel):
1438
1542
  app_key: str
1439
1543
  title: str | None = None
1440
1544
  app_icon: str | None = None
1545
+ visibility: dict[str, Any] = Field(default_factory=dict)
1441
1546
  tag_ids: list[int] = Field(default_factory=list)
1442
1547
  publish_status: int | None = None
1443
1548
  field_count: int = 0
@@ -1512,6 +1617,7 @@ class PortalGetResponse(StrictModel):
1512
1617
  package_tag_ids: list[int] = Field(default_factory=list)
1513
1618
  dash_icon: str | None = None
1514
1619
  hide_copyright: bool | None = None
1620
+ visibility: dict[str, Any] = Field(default_factory=dict)
1515
1621
  auth: dict[str, Any] = Field(default_factory=dict)
1516
1622
  config: dict[str, Any] = Field(default_factory=dict)
1517
1623
  dash_global_config: dict[str, Any] = Field(default_factory=dict)
@@ -1522,6 +1628,7 @@ class PortalGetResponse(StrictModel):
1522
1628
  class ViewGetResponse(StrictModel):
1523
1629
  view_key: str
1524
1630
  base_info: dict[str, Any] = Field(default_factory=dict)
1631
+ visibility: dict[str, Any] = Field(default_factory=dict)
1525
1632
  config: dict[str, Any] = Field(default_factory=dict)
1526
1633
  questions: list[dict[str, Any]] = Field(default_factory=list)
1527
1634
  associations: list[dict[str, Any]] = Field(default_factory=list)
@@ -1530,6 +1637,7 @@ class ViewGetResponse(StrictModel):
1530
1637
  class ChartGetResponse(StrictModel):
1531
1638
  chart_id: str
1532
1639
  base: dict[str, Any] = Field(default_factory=dict)
1640
+ visibility: dict[str, Any] = Field(default_factory=dict)
1533
1641
  config: dict[str, Any] = Field(default_factory=dict)
1534
1642
 
1535
1643
 
@@ -1539,6 +1647,7 @@ class SchemaPlanRequest(StrictModel):
1539
1647
  app_name: str = Field(default="", validation_alias=AliasChoices("app_name", "app_title", "title"))
1540
1648
  icon: str | None = None
1541
1649
  color: str | None = None
1650
+ visibility: VisibilityPatch | None = None
1542
1651
  create_if_missing: bool = False
1543
1652
  add_fields: list[FieldPatch] = Field(default_factory=list)
1544
1653
  update_fields: list[FieldUpdatePatch] = Field(default_factory=list)