hap-cli 0.5.0__py3-none-any.whl

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.
Files changed (58) hide show
  1. hap_cli/README.md +194 -0
  2. hap_cli/README_CN.md +601 -0
  3. hap_cli/__init__.py +3 -0
  4. hap_cli/commands/__init__.py +1 -0
  5. hap_cli/commands/ai_cmd.py +224 -0
  6. hap_cli/commands/app_cmd.py +308 -0
  7. hap_cli/commands/calendar_cmd.py +138 -0
  8. hap_cli/commands/chat_cmd.py +101 -0
  9. hap_cli/commands/config_cmd.py +169 -0
  10. hap_cli/commands/contact_cmd.py +125 -0
  11. hap_cli/commands/department_cmd.py +168 -0
  12. hap_cli/commands/group_cmd.py +128 -0
  13. hap_cli/commands/instance_cmd.py +310 -0
  14. hap_cli/commands/node_cmd.py +538 -0
  15. hap_cli/commands/optionset_cmd.py +99 -0
  16. hap_cli/commands/page_cmd.py +102 -0
  17. hap_cli/commands/plugin_cmd.py +133 -0
  18. hap_cli/commands/post_cmd.py +155 -0
  19. hap_cli/commands/record_cmd.py +228 -0
  20. hap_cli/commands/role_cmd.py +221 -0
  21. hap_cli/commands/workflow_cmd.py +284 -0
  22. hap_cli/commands/worksheet_cmd.py +342 -0
  23. hap_cli/context.py +43 -0
  24. hap_cli/core/__init__.py +1 -0
  25. hap_cli/core/ai.py +133 -0
  26. hap_cli/core/app.py +307 -0
  27. hap_cli/core/auth.py +219 -0
  28. hap_cli/core/calendar_mod.py +114 -0
  29. hap_cli/core/chat.py +73 -0
  30. hap_cli/core/contact.py +85 -0
  31. hap_cli/core/department.py +131 -0
  32. hap_cli/core/flow_node.py +1001 -0
  33. hap_cli/core/group.py +99 -0
  34. hap_cli/core/instance.py +572 -0
  35. hap_cli/core/optionset.py +112 -0
  36. hap_cli/core/page.py +138 -0
  37. hap_cli/core/plugin.py +87 -0
  38. hap_cli/core/post.py +118 -0
  39. hap_cli/core/record.py +268 -0
  40. hap_cli/core/role.py +227 -0
  41. hap_cli/core/session.py +348 -0
  42. hap_cli/core/workflow.py +556 -0
  43. hap_cli/core/worksheet.py +403 -0
  44. hap_cli/hap_cli.py +105 -0
  45. hap_cli/skills/SKILL.md +383 -0
  46. hap_cli/skills/__init__.py +0 -0
  47. hap_cli/tests/__init__.py +1 -0
  48. hap_cli/tests/test_core.py +1824 -0
  49. hap_cli/tests/test_full_e2e.py +136 -0
  50. hap_cli/tests/test_integration.py +805 -0
  51. hap_cli/utils/__init__.py +1 -0
  52. hap_cli/utils/formatting.py +111 -0
  53. hap_cli/utils/options.py +10 -0
  54. hap_cli-0.5.0.dist-info/METADATA +223 -0
  55. hap_cli-0.5.0.dist-info/RECORD +58 -0
  56. hap_cli-0.5.0.dist-info/WHEEL +5 -0
  57. hap_cli-0.5.0.dist-info/entry_points.txt +2 -0
  58. hap_cli-0.5.0.dist-info/top_level.txt +1 -0
hap_cli/core/record.py ADDED
@@ -0,0 +1,268 @@
1
+ """Record CRUD module for MingDAO HAP."""
2
+
3
+ from typing import Any, Optional
4
+
5
+ from hap_cli.core.session import Session
6
+
7
+
8
+ def get_records(
9
+ session: Session,
10
+ worksheet_id: str,
11
+ view_id: str = "",
12
+ page_size: int = 50,
13
+ page_index: int = 1,
14
+ sort_id: str = "",
15
+ is_asc: bool = False,
16
+ keywords: str = "",
17
+ filters: Optional[list] = None,
18
+ search_type: int = 1,
19
+ ) -> dict[str, Any]:
20
+ """Query records with filtering and pagination.
21
+
22
+ Args:
23
+ session: Active session
24
+ worksheet_id: Worksheet ID
25
+ view_id: Optional view ID
26
+ page_size: Number of records per page (max 1000)
27
+ page_index: Page number (1-based)
28
+ sort_id: Field ID to sort by
29
+ is_asc: Sort ascending
30
+ keywords: Search keywords
31
+ filters: Filter conditions list
32
+ search_type: Search type (1=default)
33
+
34
+ Returns:
35
+ Dict with 'data' (records list) and 'count' (total)
36
+ """
37
+ data: dict[str, Any] = {
38
+ "worksheetId": worksheet_id,
39
+ "pageSize": min(page_size, 1000),
40
+ "pageIndex": page_index,
41
+ "searchType": search_type,
42
+ }
43
+ if view_id:
44
+ data["viewId"] = view_id
45
+ if sort_id:
46
+ data["sortId"] = sort_id
47
+ data["isAsc"] = is_asc
48
+ if keywords:
49
+ data["keyWords"] = keywords
50
+ if filters:
51
+ data["filterControls"] = filters
52
+
53
+ result = session.api_call("Worksheet", "GetFilterRows", data)
54
+ return {
55
+ "data": result.get("data", result.get("rows", [])),
56
+ "count": result.get("count", result.get("total", 0)),
57
+ }
58
+
59
+
60
+ def get_record(
61
+ session: Session,
62
+ worksheet_id: str,
63
+ row_id: str,
64
+ view_id: str = "",
65
+ ) -> dict[str, Any]:
66
+ """Get a single record by ID.
67
+
68
+ Args:
69
+ session: Active session
70
+ worksheet_id: Worksheet ID
71
+ row_id: Record/row ID
72
+ view_id: Optional view ID
73
+
74
+ Returns:
75
+ Record detail dict
76
+ """
77
+ data: dict[str, Any] = {
78
+ "worksheetId": worksheet_id,
79
+ "rowId": row_id,
80
+ }
81
+ if view_id:
82
+ data["viewId"] = view_id
83
+ return session.api_call("Worksheet", "GetRowDetail", data)
84
+
85
+
86
+ def create_record(
87
+ session: Session,
88
+ worksheet_id: str,
89
+ controls: list[dict[str, Any]],
90
+ trigger_workflow: bool = True,
91
+ ) -> dict[str, Any]:
92
+ """Create a new record.
93
+
94
+ Args:
95
+ session: Active session
96
+ worksheet_id: Worksheet ID
97
+ controls: List of {controlId, value} dicts
98
+ trigger_workflow: Whether to trigger workflows
99
+
100
+ Returns:
101
+ Created record info
102
+ """
103
+ return session.api_call(
104
+ "Worksheet",
105
+ "AddWorksheetRow",
106
+ {
107
+ "worksheetId": worksheet_id,
108
+ "receiveControls": controls,
109
+ "triggerWorkflow": trigger_workflow,
110
+ },
111
+ )
112
+
113
+
114
+ def update_record(
115
+ session: Session,
116
+ worksheet_id: str,
117
+ row_id: str,
118
+ controls: list[dict[str, Any]],
119
+ trigger_workflow: bool = True,
120
+ ) -> dict[str, Any]:
121
+ """Update an existing record.
122
+
123
+ Args:
124
+ session: Active session
125
+ worksheet_id: Worksheet ID
126
+ row_id: Record/row ID
127
+ controls: List of {controlId, value} dicts
128
+ trigger_workflow: Whether to trigger workflows
129
+
130
+ Returns:
131
+ Update result
132
+ """
133
+ return session.api_call(
134
+ "Worksheet",
135
+ "UpdateWorksheetRow",
136
+ {
137
+ "worksheetId": worksheet_id,
138
+ "rowId": row_id,
139
+ "newOldControl": controls,
140
+ "triggerWorkflow": trigger_workflow,
141
+ },
142
+ )
143
+
144
+
145
+ def delete_records(
146
+ session: Session,
147
+ worksheet_id: str,
148
+ row_ids: list[str],
149
+ ) -> dict[str, Any]:
150
+ """Delete records by IDs.
151
+
152
+ Args:
153
+ session: Active session
154
+ worksheet_id: Worksheet ID
155
+ row_ids: List of record/row IDs to delete
156
+
157
+ Returns:
158
+ Deletion result
159
+ """
160
+ return session.api_call(
161
+ "Worksheet",
162
+ "DeleteWorksheetRows",
163
+ {
164
+ "worksheetId": worksheet_id,
165
+ "rowIds": row_ids,
166
+ },
167
+ )
168
+
169
+
170
+ # ── Discussion ───────────────────────────────────────────────────────────
171
+
172
+
173
+ def get_discussions(
174
+ session: Session,
175
+ source_id: str,
176
+ source_type: int = 7,
177
+ page_index: int = 1,
178
+ page_size: int = 20,
179
+ keywords: str = "",
180
+ ) -> dict[str, Any]:
181
+ """Get discussions for a record.
182
+
183
+ Args:
184
+ source_type: 7=worksheet record (default)
185
+ """
186
+ data: dict[str, Any] = {
187
+ "sourceId": source_id,
188
+ "sourceType": source_type,
189
+ "pageIndex": page_index,
190
+ "pageSize": page_size,
191
+ }
192
+ if keywords:
193
+ data["keywords"] = keywords
194
+ return session.api_call("Discussion", "GetDiscussions", data)
195
+
196
+
197
+ def add_discussion(
198
+ session: Session,
199
+ source_id: str,
200
+ message: str,
201
+ source_type: int = 7,
202
+ reply_id: str = "",
203
+ app_id: str = "",
204
+ ) -> dict[str, Any]:
205
+ """Add a discussion/comment to a record."""
206
+ data: dict[str, Any] = {
207
+ "sourceId": source_id,
208
+ "sourceType": source_type,
209
+ "message": message,
210
+ }
211
+ if reply_id:
212
+ data["replyId"] = reply_id
213
+ if app_id:
214
+ data["appId"] = app_id
215
+ return session.api_call("Discussion", "AddDiscussion", data)
216
+
217
+
218
+ def remove_discussion(
219
+ session: Session, discussion_id: str, source_type: int = 7,
220
+ ) -> dict[str, Any]:
221
+ """Remove a discussion/comment."""
222
+ return session.api_call(
223
+ "Discussion", "RemoveDiscussion",
224
+ {"discussionId": discussion_id, "sourceType": source_type},
225
+ )
226
+
227
+
228
+ # ── Pivot / Report ───────────────────────────────────────────────────────
229
+
230
+
231
+ def get_pivot_data(
232
+ session: Session,
233
+ worksheet_id: str,
234
+ view_id: str = "",
235
+ app_id: str = "",
236
+ filters: Optional[list] = None,
237
+ ) -> dict[str, Any]:
238
+ """Get pivot table / report data for a worksheet."""
239
+ data: dict[str, Any] = {"worksheetId": worksheet_id}
240
+ if view_id:
241
+ data["viewId"] = view_id
242
+ if app_id:
243
+ data["appId"] = app_id
244
+ if filters:
245
+ data["filterControls"] = filters
246
+ return session.api_call("Worksheet", "GetFilterRowsReport", data)
247
+
248
+
249
+ # ── Record Logs ──────────────────────────────────────────────────────────
250
+
251
+
252
+ def get_record_logs(
253
+ session: Session,
254
+ worksheet_id: str,
255
+ row_id: str,
256
+ page_index: int = 1,
257
+ page_size: int = 50,
258
+ ) -> dict[str, Any]:
259
+ """Get operation logs for a specific record."""
260
+ return session.api_call(
261
+ "Worksheet", "GetLogs",
262
+ {
263
+ "worksheetId": worksheet_id,
264
+ "rowId": row_id,
265
+ "pageIndex": page_index,
266
+ "pageSize": page_size,
267
+ },
268
+ )
hap_cli/core/role.py ADDED
@@ -0,0 +1,227 @@
1
+ """Role management module for MingDAO HAP."""
2
+
3
+ from typing import Any, Optional
4
+
5
+ from hap_cli.core.session import Session
6
+
7
+
8
+ def get_roles(
9
+ session: Session,
10
+ app_id: str,
11
+ ) -> list[dict[str, Any]]:
12
+ """List roles for an application.
13
+
14
+ Args:
15
+ session: Active session
16
+ app_id: Application ID
17
+
18
+ Returns:
19
+ List of role dicts
20
+ """
21
+ result = session.api_call("AppManagement", "GetRoleList", {"appId": app_id})
22
+ if isinstance(result, list):
23
+ return result
24
+ return result.get("list", result.get("roles", []))
25
+
26
+
27
+ def create_role(
28
+ session: Session,
29
+ app_id: str,
30
+ name: str,
31
+ description: str = "",
32
+ permission_way: int = 10,
33
+ project_id: str = "",
34
+ ) -> dict[str, Any]:
35
+ """Create a new role.
36
+
37
+ Args:
38
+ session: Active session
39
+ app_id: Application ID
40
+ name: Role name
41
+ description: Role description
42
+ permission_way: Permission type (0=custom, 10=readonly, 50=member, 100=admin)
43
+ project_id: Project/organization ID
44
+
45
+ Returns:
46
+ Created role info
47
+ """
48
+ data: dict[str, Any] = {
49
+ "appId": app_id,
50
+ "name": name,
51
+ "permissionWay": permission_way,
52
+ }
53
+ if description:
54
+ data["description"] = description
55
+ if project_id:
56
+ data["projectId"] = project_id
57
+ return session.api_call("AppManagement", "AddRole", data)
58
+
59
+
60
+ def delete_role(
61
+ session: Session,
62
+ app_id: str,
63
+ role_id: str,
64
+ target_role_id: str = "",
65
+ project_id: str = "",
66
+ ) -> dict[str, Any]:
67
+ """Delete a role and optionally move members.
68
+
69
+ Args:
70
+ session: Active session
71
+ app_id: Application ID
72
+ role_id: Role ID to delete
73
+ target_role_id: Move members to this role
74
+ project_id: Project/organization ID
75
+
76
+ Returns:
77
+ Deletion result
78
+ """
79
+ data: dict[str, Any] = {"appId": app_id, "roleId": role_id}
80
+ if target_role_id:
81
+ data["resultRoleId"] = target_role_id
82
+ if project_id:
83
+ data["projectId"] = project_id
84
+ return session.api_call("AppManagement", "RemoveRole", data)
85
+
86
+
87
+ def add_role_members(
88
+ session: Session,
89
+ app_id: str,
90
+ role_id: str,
91
+ user_ids: Optional[list[str]] = None,
92
+ department_ids: Optional[list[str]] = None,
93
+ project_id: str = "",
94
+ ) -> dict[str, Any]:
95
+ """Add members to a role.
96
+
97
+ Args:
98
+ session: Active session
99
+ app_id: Application ID
100
+ role_id: Role ID
101
+ user_ids: User IDs to add
102
+ department_ids: Department IDs to add
103
+ project_id: Project/organization ID
104
+
105
+ Returns:
106
+ Result
107
+ """
108
+ data: dict[str, Any] = {"appId": app_id, "roleId": role_id}
109
+ if user_ids:
110
+ data["userIds"] = user_ids
111
+ if department_ids:
112
+ data["departmentIds"] = department_ids
113
+ if project_id:
114
+ data["projectId"] = project_id
115
+ return session.api_call("AppManagement", "AddRoleMembers", data)
116
+
117
+
118
+ def remove_role_members(
119
+ session: Session,
120
+ app_id: str,
121
+ role_id: str,
122
+ user_ids: Optional[list[str]] = None,
123
+ department_ids: Optional[list[str]] = None,
124
+ project_id: str = "",
125
+ ) -> dict[str, Any]:
126
+ """Remove members from a role.
127
+
128
+ Args:
129
+ session: Active session
130
+ app_id: Application ID
131
+ role_id: Role ID
132
+ user_ids: User IDs to remove
133
+ department_ids: Department IDs to remove
134
+ project_id: Project/organization ID
135
+
136
+ Returns:
137
+ Result
138
+ """
139
+ data: dict[str, Any] = {"appId": app_id, "roleId": role_id}
140
+ if user_ids:
141
+ data["userIds"] = user_ids
142
+ if department_ids:
143
+ data["departmentIds"] = department_ids
144
+ if project_id:
145
+ data["projectId"] = project_id
146
+ return session.api_call("AppManagement", "RemoveRoleMembers", data)
147
+
148
+
149
+ # ── Role permissions ─────────────────────────────────────────────────────
150
+
151
+
152
+ def get_role_detail(
153
+ session: Session, app_id: str, role_id: str,
154
+ ) -> dict[str, Any]:
155
+ """Get role detail including permissions."""
156
+ return session.api_call(
157
+ "AppManagement", "GetRoleDetail",
158
+ {"appId": app_id, "roleId": role_id},
159
+ )
160
+
161
+
162
+ def edit_role(
163
+ session: Session,
164
+ app_id: str,
165
+ role_id: str,
166
+ permission_way: int = 0,
167
+ permissions: Optional[list[dict]] = None,
168
+ ) -> dict[str, Any]:
169
+ """Edit role permissions."""
170
+ data: dict[str, Any] = {
171
+ "appId": app_id,
172
+ "roleId": role_id,
173
+ "permissionWay": permission_way,
174
+ }
175
+ if permissions:
176
+ data["permissions"] = permissions
177
+ return session.api_call("AppManagement", "EditRole", data)
178
+
179
+
180
+ def rename_role(
181
+ session: Session, app_id: str, role_id: str, name: str,
182
+ ) -> dict[str, Any]:
183
+ """Rename a role."""
184
+ return session.api_call(
185
+ "AppManagement", "EditRoleName",
186
+ {"appId": app_id, "roleId": role_id, "name": name},
187
+ )
188
+
189
+
190
+ def apply_role(
191
+ session: Session, app_id: str, role_id: str,
192
+ ) -> dict[str, Any]:
193
+ """Apply to join a role."""
194
+ return session.api_call(
195
+ "AppManagement", "ApplyRole",
196
+ {"appId": app_id, "roleId": role_id},
197
+ )
198
+
199
+
200
+ def approve_role_apply(
201
+ session: Session, app_id: str, role_id: str, account_id: str,
202
+ ) -> dict[str, Any]:
203
+ """Approve a user's role application."""
204
+ return session.api_call(
205
+ "AppManagement", "AgreeUserToRole",
206
+ {"appId": app_id, "roleId": role_id, "accountId": account_id},
207
+ )
208
+
209
+
210
+ def reject_role_apply(
211
+ session: Session, app_id: str, role_id: str, account_id: str,
212
+ ) -> dict[str, Any]:
213
+ """Reject a user's role application."""
214
+ return session.api_call(
215
+ "AppManagement", "RefuseUserToRole",
216
+ {"appId": app_id, "roleId": role_id, "accountId": account_id},
217
+ )
218
+
219
+
220
+ def get_pending_role_users(
221
+ session: Session, app_id: str,
222
+ ) -> dict[str, Any]:
223
+ """Get users with pending role applications."""
224
+ return session.api_call(
225
+ "AppManagement", "GetUnauditedUserDetail",
226
+ {"appId": app_id},
227
+ )