hap-cli 0.8.18__tar.gz → 0.8.19__tar.gz

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 (256) hide show
  1. {hap_cli-0.8.18 → hap_cli-0.8.19}/PKG-INFO +1 -1
  2. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/__init__.py +1 -1
  3. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/record.py +82 -19
  4. hap_cli-0.8.19/hap_cli/tests/test_member_relation_array_wrap.py +103 -0
  5. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli.egg-info/PKG-INFO +1 -1
  6. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli.egg-info/SOURCES.txt +1 -0
  7. {hap_cli-0.8.18 → hap_cli-0.8.19}/MANIFEST.in +0 -0
  8. {hap_cli-0.8.18 → hap_cli-0.8.19}/README.md +0 -0
  9. {hap_cli-0.8.18 → hap_cli-0.8.19}/app_live_tests/__init__.py +0 -0
  10. {hap_cli-0.8.18 → hap_cli-0.8.19}/app_live_tests/__main__.py +0 -0
  11. {hap_cli-0.8.18 → hap_cli-0.8.19}/app_live_tests/config.py +0 -0
  12. {hap_cli-0.8.18 → hap_cli-0.8.19}/app_live_tests/harness.py +0 -0
  13. {hap_cli-0.8.18 → hap_cli-0.8.19}/app_live_tests/smoke.py +0 -0
  14. {hap_cli-0.8.18 → hap_cli-0.8.19}/app_live_tests/state.py +0 -0
  15. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/README.md +0 -0
  16. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/README_CN.md +0 -0
  17. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/__main__.py +0 -0
  18. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/__init__.py +0 -0
  19. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/app_cmd.py +0 -0
  20. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/app_creator_cmd.py +0 -0
  21. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/app_editor_cmd.py +0 -0
  22. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/auth_cmd.py +0 -0
  23. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/calendar_cmd.py +0 -0
  24. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/chart_cmd.py +0 -0
  25. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/chat_cmd.py +0 -0
  26. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/chatbot_cmd.py +0 -0
  27. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/config_cmd.py +0 -0
  28. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/contact_cmd.py +0 -0
  29. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/department_cmd.py +0 -0
  30. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/group_cmd.py +0 -0
  31. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/icon_cmd.py +0 -0
  32. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/instance_cmd.py +0 -0
  33. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/node_cmd.py +0 -0
  34. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/optionset_cmd.py +0 -0
  35. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/page_cmd.py +0 -0
  36. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/post_cmd.py +0 -0
  37. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/record_cmd.py +0 -0
  38. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/region_cmd.py +0 -0
  39. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/role_cmd.py +0 -0
  40. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/update_cmd.py +0 -0
  41. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/upload_cmd.py +0 -0
  42. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/v3_registry.py +0 -0
  43. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/workflow_cmd.py +0 -0
  44. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/commands/worksheet_cmd.py +0 -0
  45. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/context.py +0 -0
  46. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/__init__.py +0 -0
  47. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/action_spec_adapter.py +0 -0
  48. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app.py +0 -0
  49. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/__init__.py +0 -0
  50. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/_hapmeta/__init__.py +0 -0
  51. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/_hapmeta/control_type_codes.py +0 -0
  52. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/_hapmeta/worksheet_templates.py +0 -0
  53. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/charts.py +0 -0
  54. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/cleanup.py +0 -0
  55. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/compiler.py +0 -0
  56. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/config.py +0 -0
  57. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/design/design.schema.json +0 -0
  58. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/errors.py +0 -0
  59. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/examples/minimal.design.json +0 -0
  60. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/executor.py +0 -0
  61. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/fields.py +0 -0
  62. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/hap.py +0 -0
  63. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/merge.py +0 -0
  64. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/recording/__init__.py +0 -0
  65. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/recording/console.py +0 -0
  66. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/recording/jsonl.py +0 -0
  67. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/recording/mirror.py +0 -0
  68. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/recording/report.py +0 -0
  69. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/schema.py +0 -0
  70. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/INSTRUCTIONS.md +0 -0
  71. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/__init__.py +0 -0
  72. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/cli.py +0 -0
  73. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/executor.py +0 -0
  74. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/resources/attachments.json +0 -0
  75. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/resources/sample.docx +0 -0
  76. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/resources/sample.pdf +0 -0
  77. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/resources/sample_images.json +0 -0
  78. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/seed/template.py +0 -0
  79. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/selftest.py +0 -0
  80. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/smoke.py +0 -0
  81. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/steps.py +0 -0
  82. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/store.py +0 -0
  83. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/validate.py +0 -0
  84. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/app_creator/workflow_dsl.py +0 -0
  85. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/auth.py +0 -0
  86. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/calendar_mod.py +0 -0
  87. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/chart.py +0 -0
  88. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/chat.py +0 -0
  89. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/chatbot.py +0 -0
  90. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/cli_access.py +0 -0
  91. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/contact.py +0 -0
  92. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/control_type_codes.py +0 -0
  93. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/department.py +0 -0
  94. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/__init__.py +0 -0
  95. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/_hapmeta/__init__.py +0 -0
  96. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/_hapmeta/control_type_codes.py +0 -0
  97. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/apply.py +0 -0
  98. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/componentlower.py +0 -0
  99. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/editspec.py +0 -0
  100. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/errors.py +0 -0
  101. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/fieldlower.py +0 -0
  102. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/jsonschema_mini.py +0 -0
  103. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/models.py +0 -0
  104. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/ops.py +0 -0
  105. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/planner.py +0 -0
  106. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/editor/reader.py +0 -0
  107. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/field_normalizer.py +0 -0
  108. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/field_spec_adapter.py +0 -0
  109. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/filter_translator.py +0 -0
  110. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/flow_node.py +0 -0
  111. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/global_meta.py +0 -0
  112. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/group.py +0 -0
  113. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/icon_index.py +0 -0
  114. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/instance.py +0 -0
  115. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/logger.py +0 -0
  116. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/optionset.py +0 -0
  117. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/page.py +0 -0
  118. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/post.py +0 -0
  119. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/response_crypto.py +0 -0
  120. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/role.py +0 -0
  121. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/role_perm_builder.py +0 -0
  122. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/session.py +0 -0
  123. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/token_crypto.py +0 -0
  124. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/update.py +0 -0
  125. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/upload.py +0 -0
  126. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/v3/__init__.py +0 -0
  127. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/v3/dispatcher.py +0 -0
  128. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/v3/render.py +0 -0
  129. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/v3/schema.py +0 -0
  130. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/view_spec_adapter.py +0 -0
  131. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/workflow.py +0 -0
  132. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/workflow_node_dsl.py +0 -0
  133. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/worksheet.py +0 -0
  134. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/core/worksheet_templates.py +0 -0
  135. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/hap_cli.py +0 -0
  136. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/i18n.py +0 -0
  137. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/locale/__init__.py +0 -0
  138. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/locale/messages.json +0 -0
  139. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/locale/messages.schema.json +0 -0
  140. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/__init__.py +0 -0
  141. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/conftest.py +0 -0
  142. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_app_creator.py +0 -0
  143. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_app_editor.py +0 -0
  144. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_app_export_usage.py +0 -0
  145. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_auth_prerelease.py +0 -0
  146. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_bug_036430.py +0 -0
  147. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_bug_036750.py +0 -0
  148. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_chart.py +0 -0
  149. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_cli_access.py +0 -0
  150. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_config_cmd.py +0 -0
  151. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_core.py +0 -0
  152. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_destructive_confirm_cli.py +0 -0
  153. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_full_e2e.py +0 -0
  154. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_global_meta.py +0 -0
  155. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_i18n.py +0 -0
  156. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_instance_history_cli.py +0 -0
  157. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration.py +0 -0
  158. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_approval.py +0 -0
  159. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_approval_actions.py +0 -0
  160. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_calendar.py +0 -0
  161. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_destructive.py +0 -0
  162. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_misc.py +0 -0
  163. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_post.py +0 -0
  164. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_social.py +0 -0
  165. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_v3.py +0 -0
  166. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_workflow.py +0 -0
  167. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_integration_worksheet_extra.py +0 -0
  168. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_multi_profile.py +0 -0
  169. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_org_approval_v3_semantic_cli.py +0 -0
  170. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_org_id_cli.py +0 -0
  171. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_org_id_docs.py +0 -0
  172. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_parameter_conventions.py +0 -0
  173. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_parameter_mapping_registry.py +0 -0
  174. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_record_batch_v3_semantic_cli.py +0 -0
  175. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_record_field_alias.py +0 -0
  176. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_record_v3_semantic_cli.py +0 -0
  177. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_select_rejects_relation_value.py +0 -0
  178. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_semantic_types_registry.py +0 -0
  179. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_update.py +0 -0
  180. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_v3_api_schema_loader.py +0 -0
  181. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_v3_dispatcher.py +0 -0
  182. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_v3_registry_coverage.py +0 -0
  183. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_v3_session.py +0 -0
  184. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_v3_yaml_translation.py +0 -0
  185. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_workflow_list_cli.py +0 -0
  186. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_workflow_v3_semantic_cli.py +0 -0
  187. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_worksheet_crud_cli.py +0 -0
  188. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/tests/test_worksheet_v3_semantic_cli.py +0 -0
  189. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/utils/__init__.py +0 -0
  190. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/utils/formatting.py +0 -0
  191. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/utils/options.py +0 -0
  192. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli/utils/parameter_mapping.py +0 -0
  193. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli.egg-info/dependency_links.txt +0 -0
  194. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli.egg-info/entry_points.txt +0 -0
  195. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli.egg-info/requires.txt +0 -0
  196. {hap_cli-0.8.18 → hap_cli-0.8.19}/hap_cli.egg-info/top_level.txt +0 -0
  197. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/__init__.py +0 -0
  198. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/__main__.py +0 -0
  199. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/_wftest.py +0 -0
  200. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/charts.py +0 -0
  201. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/cleanup.py +0 -0
  202. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/compiler.py +0 -0
  203. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/config.py +0 -0
  204. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/errors.py +0 -0
  205. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/executor.py +0 -0
  206. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/fields.py +0 -0
  207. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/hap.py +0 -0
  208. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/recording/__init__.py +0 -0
  209. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/recording/console.py +0 -0
  210. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/recording/jsonl.py +0 -0
  211. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/recording/mirror.py +0 -0
  212. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/recording/report.py +0 -0
  213. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/schema.py +0 -0
  214. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/seed/__init__.py +0 -0
  215. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/seed/cli.py +0 -0
  216. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/seed/executor.py +0 -0
  217. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/seed/template.py +0 -0
  218. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/selftest.py +0 -0
  219. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/smoke.py +0 -0
  220. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/step.py +0 -0
  221. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/steps.py +0 -0
  222. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/store.py +0 -0
  223. {hap_cli-0.8.18 → hap_cli-0.8.19}/live_tests/workflow_dsl.py +0 -0
  224. {hap_cli-0.8.18 → hap_cli-0.8.19}/setup.cfg +0 -0
  225. {hap_cli-0.8.18 → hap_cli-0.8.19}/setup.py +0 -0
  226. {hap_cli-0.8.18 → hap_cli-0.8.19}/skills/cli/hap-cli-app-editor/scripts/editspec/component.schema.json +0 -0
  227. {hap_cli-0.8.18 → hap_cli-0.8.19}/skills/cli/hap-cli-app-editor/scripts/editspec/custom-action.schema.json +0 -0
  228. {hap_cli-0.8.18 → hap_cli-0.8.19}/skills/cli/hap-cli-app-editor/scripts/editspec/envelope.schema.json +0 -0
  229. {hap_cli-0.8.18 → hap_cli-0.8.19}/skills/cli/hap-cli-app-editor/scripts/editspec/field.schema.json +0 -0
  230. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/INDEX.json +0 -0
  231. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/add_member_to_role.yaml +0 -0
  232. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/batch_delete_records.yaml +0 -0
  233. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/create_optionset.yaml +0 -0
  234. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/create_role.yaml +0 -0
  235. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/delete_optionset.yaml +0 -0
  236. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/delete_record.yaml +0 -0
  237. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/delete_role.yaml +0 -0
  238. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/delete_worksheet.yaml +0 -0
  239. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_app_info.yaml +0 -0
  240. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_app_knowledge_list.yaml +0 -0
  241. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_app_worksheets_list.yaml +0 -0
  242. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_optionset_list.yaml +0 -0
  243. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_record_details.yaml +0 -0
  244. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_record_discussions.yaml +0 -0
  245. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_record_list.yaml +0 -0
  246. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_record_logs.yaml +0 -0
  247. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_record_pivot_data.yaml +0 -0
  248. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_record_relations.yaml +0 -0
  249. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_record_share_link.yaml +0 -0
  250. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_regions.yaml +0 -0
  251. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_role_details.yaml +0 -0
  252. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/get_role_list.yaml +0 -0
  253. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/knowledge_search.yaml +0 -0
  254. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/leave_all_roles.yaml +0 -0
  255. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/remove_member_from_role.yaml +0 -0
  256. {hap_cli-0.8.18 → hap_cli-0.8.19}/sources/v3-api-schema/update_optionset.yaml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hap-cli
3
- Version: 0.8.18
3
+ Version: 0.8.19
4
4
  Summary: CLI harness for Mingdao HAP - Enterprise no-code platform
5
5
  Author: hap-cli
6
6
  License: Apache-2.0
@@ -1,3 +1,3 @@
1
1
  """CLI harness for Mingdao HAP (hap-cli)."""
2
2
 
3
- __version__ = "0.8.18"
3
+ __version__ = "0.8.19"
@@ -259,6 +259,67 @@ def _legacy_cell_entry(
259
259
  return {"value": _legacy_cell_value(ctrl, value)}
260
260
 
261
261
 
262
+ def _coerce_entity_ids(
263
+ value: Any, id_keys: tuple[str, ...], *, field_label: str,
264
+ ) -> list[str]:
265
+ """Flatten a member / department / org-role / relation cell value to a
266
+ list of id strings, ready to be wrapped as ``[{idKey: id}, ...]``.
267
+
268
+ Accepts every realistic input shape so callers never have to pre-shape:
269
+ * a scalar id, or comma-separated ids (``"a,b"``);
270
+ * a list/tuple mixing ids and ``{idKey: ...}`` objects;
271
+ * a single ``{idKey: ...}`` object — the ``get_records`` read-back
272
+ shape carries display fields (``fullname`` / ``avatar`` / ``name``)
273
+ too, so only the id is kept;
274
+ * a JSON-array/object *string* of the above (e.g. a value copied
275
+ straight out of a record dump).
276
+
277
+ ``id_keys`` lists the accepted id field names in priority order, e.g.
278
+ ``("accountId", "aid")`` for USER_PICKER. An object that carries none of
279
+ them fails loudly instead of being ``str()``-mangled into a junk id —
280
+ that silent mangling sent garbage members to the server before.
281
+ """
282
+ if value is None or value == "":
283
+ return []
284
+ # A JSON-array/object string is parsed structurally rather than
285
+ # comma-split (a member object's JSON has commas inside it).
286
+ if isinstance(value, str):
287
+ s = value.strip()
288
+ if s[:1] in ("[", "{"):
289
+ try:
290
+ value = json.loads(s)
291
+ except (ValueError, TypeError):
292
+ pass
293
+ if isinstance(value, dict):
294
+ items: list[Any] = [value]
295
+ elif isinstance(value, (list, tuple)):
296
+ items = list(value)
297
+ else:
298
+ items = [p for p in str(value).split(",") if p.strip() != ""]
299
+ out: list[str] = []
300
+ for it in items:
301
+ if isinstance(it, dict):
302
+ rid = next(
303
+ (str(it[k]) for k in id_keys if it.get(k) not in (None, "")),
304
+ None,
305
+ )
306
+ if rid is None:
307
+ raise ValueError(
308
+ f"Field '{field_label}': object value is missing an id "
309
+ f"field ({'/'.join(id_keys)}): {it!r}"
310
+ )
311
+ out.append(rid)
312
+ elif isinstance(it, (list, tuple)):
313
+ raise ValueError(
314
+ f"Field '{field_label}': nested array is not a valid id: {it!r}"
315
+ )
316
+ else:
317
+ s2 = str(it).strip()
318
+ if s2:
319
+ out.append(s2)
320
+ return out
321
+
322
+
262
323
  def _legacy_cell_value(ctrl: dict[str, Any], value: Any) -> str:
263
324
  """Serialize one cell to the legacy receiveControls `value`
264
325
  string, per the shapes proven in
@@ -271,14 +332,15 @@ def _legacy_cell_value(ctrl: dict[str, Any], value: Any) -> str:
271
332
  if t == 10: # MULTI_SELECT
272
333
  return json.dumps(_resolve_option_keys(ctrl, value), ensure_ascii=False)
273
334
 
335
+ label = _option_field_label(ctrl)
336
+
274
337
  if t in (29, 35): # RELATE_SHEET / CASCADING_SELECT -> [{"sid": rowId}, ...]
275
338
  # Cascade (35) is a relation to a row in another worksheet, persisted
276
339
  # the same way as a plain relate (29): an array of {"sid": rowId}. A
277
- # bare rowId makes the server answer "服务异常" (bug #642cc8).
278
- if isinstance(value, (list, tuple)):
279
- ids = [str(v) for v in value]
280
- else:
281
- ids = [s for s in str(value).split(",") if s != ""]
340
+ # bare rowId makes the server answer "服务异常" (bug #642cc8). Object
341
+ # inputs ({"sid": rowId, ...} read-back shape) keep only the sid.
342
+ ids = _coerce_entity_ids(value, ("sid", "rowid", "rowId"),
343
+ field_label=label)
282
344
  return json.dumps([{"sid": rid} for rid in ids], ensure_ascii=False)
283
345
 
284
346
  if t == 48: # ORG_ROLE -> [{"organizeId": id}, ...]
@@ -286,20 +348,21 @@ def _legacy_cell_value(ctrl: dict[str, Any], value: Any) -> str:
286
348
  # of {"organizeId": id} objects; organizeName is display-only and the
287
349
  # server resolves it from the id. A bare organizeId is rejected with
288
350
  # "服务异常" (bug #642cc8). See pd-openweb CellControls/OrgRole.jsx.
289
- ids = value if isinstance(value, (list, tuple)) else \
290
- [s for s in str(value).split(",") if s != ""]
291
- return json.dumps([{"organizeId": str(i)} for i in ids],
292
- ensure_ascii=False)
293
-
294
- if t == 26: # USER_PICKER
295
- ids = value if isinstance(value, (list, tuple)) else \
296
- [s for s in str(value).split(",") if s != ""]
297
- return json.dumps([{"accountId": str(i)} for i in ids],
298
- ensure_ascii=False)
299
- if t == 27: # DEPARTMENT
300
- ids = value if isinstance(value, (list, tuple)) else \
301
- [s for s in str(value).split(",") if s != ""]
302
- return json.dumps([{"departmentId": str(i)} for i in ids],
351
+ ids = _coerce_entity_ids(value, ("organizeId", "id"),
352
+ field_label=label)
353
+ return json.dumps([{"organizeId": i} for i in ids], ensure_ascii=False)
354
+
355
+ if t == 26: # USER_PICKER -> always an array of {"accountId": id}, even
356
+ # for a single member. Object inputs (the full member object the UI
357
+ # holds / get_records returns: {accountId, fullname, avatar, ...})
358
+ # are reduced to their accountId a bare object would fail the save.
359
+ ids = _coerce_entity_ids(value, ("accountId", "aid"),
360
+ field_label=label)
361
+ return json.dumps([{"accountId": i} for i in ids], ensure_ascii=False)
362
+ if t == 27: # DEPARTMENT -> [{"departmentId": id}, ...]
363
+ ids = _coerce_entity_ids(value, ("departmentId", "id"),
364
+ field_label=label)
365
+ return json.dumps([{"departmentId": i} for i in ids],
303
366
  ensure_ascii=False)
304
367
 
305
368
  if t == 36: # SWITCH / checkbox
@@ -0,0 +1,103 @@
1
+ """Member / department / org-role / relation cells must always serialize
2
+ to a JSON *array* of id objects, and must accept object-shaped inputs.
3
+
4
+ A USER_PICKER (26) cell is always an array, even for a single member
5
+ (evidence: a bare ``{"accountId":...}`` object on AddWorksheetRow fails
6
+ server-side). hap-cli's encoder already wraps scalars in an array, but it
7
+ mangled object-shaped inputs: ``[{"accountId": str(i)} for i in value]``
8
+ ran ``str()`` over a whole member dict when the value was a member object
9
+ or — the natural ``get_records`` read-back shape — a list of member
10
+ objects ``[{"accountId","fullname","avatar",...}]``. The id is now
11
+ extracted from such objects and the cell is always emitted as an array.
12
+
13
+ The same fix covers DEPARTMENT (27, ``departmentId``), ORG_ROLE
14
+ (48, ``organizeId``) and RELATE_SHEET/CASCADING (29/35, ``sid``).
15
+ """
16
+
17
+ import json
18
+
19
+ import pytest
20
+
21
+ from hap_cli.core import record as rec_mod
22
+
23
+
24
+ def _val(type_code, value):
25
+ return rec_mod._legacy_cell_value({"type": type_code, "controlName": "f"}, value)
26
+
27
+
28
+ class TestUserPickerAlwaysArray:
29
+ def test_single_account_id_string(self):
30
+ assert _val(26, "a1") == '[{"accountId": "a1"}]'
31
+
32
+ def test_comma_separated_ids(self):
33
+ assert _val(26, "a1,a2") == '[{"accountId": "a1"}, {"accountId": "a2"}]'
34
+
35
+ def test_list_of_ids(self):
36
+ assert _val(26, ["a1", "a2"]) == \
37
+ '[{"accountId": "a1"}, {"accountId": "a2"}]'
38
+
39
+ def test_single_member_object_keeps_only_account_id(self):
40
+ v = {"accountId": "a1", "fullname": "林梦阳", "name": "林梦阳",
41
+ "avatar": "https://x", "avatarMiddle": "https://y"}
42
+ assert _val(26, v) == '[{"accountId": "a1"}]'
43
+
44
+ def test_list_of_member_objects_readback_shape(self):
45
+ v = [{"accountId": "a1", "fullname": "甲", "avatar": "u1"},
46
+ {"accountId": "a2", "fullname": "乙", "avatar": "u2"}]
47
+ assert _val(26, v) == \
48
+ '[{"accountId": "a1"}, {"accountId": "a2"}]'
49
+
50
+ def test_json_array_of_objects_string(self):
51
+ v = json.dumps([{"accountId": "a1", "fullname": "甲"}])
52
+ assert _val(26, v) == '[{"accountId": "a1"}]'
53
+
54
+ def test_json_object_string(self):
55
+ v = json.dumps({"accountId": "a1", "fullname": "甲"})
56
+ assert _val(26, v) == '[{"accountId": "a1"}]'
57
+
58
+ def test_member_object_without_account_id_rejected(self):
59
+ with pytest.raises(ValueError):
60
+ _val(26, {"fullname": "甲", "avatar": "u"})
61
+
62
+ def test_empty_is_empty_array(self):
63
+ assert _val(26, "") == "[]"
64
+ assert _val(26, None) == "[]"
65
+
66
+
67
+ class TestDepartmentObjectShape:
68
+ def test_object_keeps_department_id(self):
69
+ v = {"departmentId": "d1", "departmentName": "研发"}
70
+ assert _val(27, v) == '[{"departmentId": "d1"}]'
71
+
72
+ def test_list_of_objects(self):
73
+ v = [{"departmentId": "d1"}, {"departmentId": "d2"}]
74
+ assert _val(27, v) == \
75
+ '[{"departmentId": "d1"}, {"departmentId": "d2"}]'
76
+
77
+ def test_plain_id_still_works(self):
78
+ assert _val(27, "d1") == '[{"departmentId": "d1"}]'
79
+
80
+
81
+ class TestOrgRoleObjectShape:
82
+ def test_object_keeps_organize_id(self):
83
+ v = {"organizeId": "o1", "organizeName": "主管"}
84
+ assert _val(48, v) == '[{"organizeId": "o1"}]'
85
+
86
+ def test_plain_id_still_works(self):
87
+ assert _val(48, "o1") == '[{"organizeId": "o1"}]'
88
+
89
+
90
+ class TestRelateObjectShape:
91
+ def test_relate_object_keeps_sid(self):
92
+ v = {"sid": "row1", "name": "记录甲"}
93
+ assert _val(29, v) == '[{"sid": "row1"}]'
94
+
95
+ def test_relate_list_of_objects_readback(self):
96
+ v = [{"sid": "row1", "name": "甲"}, {"sid": "row2", "name": "乙"}]
97
+ assert _val(29, v) == '[{"sid": "row1"}, {"sid": "row2"}]'
98
+
99
+ def test_relate_plain_rowid_still_works(self):
100
+ assert _val(29, "row1") == '[{"sid": "row1"}]'
101
+
102
+ def test_cascading_object_keeps_sid(self):
103
+ assert _val(35, {"sid": "row1"}) == '[{"sid": "row1"}]'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hap-cli
3
- Version: 0.8.18
3
+ Version: 0.8.19
4
4
  Summary: CLI harness for Mingdao HAP - Enterprise no-code platform
5
5
  Author: hap-cli
6
6
  License: Apache-2.0
@@ -168,6 +168,7 @@ hap_cli/tests/test_integration_social.py
168
168
  hap_cli/tests/test_integration_v3.py
169
169
  hap_cli/tests/test_integration_workflow.py
170
170
  hap_cli/tests/test_integration_worksheet_extra.py
171
+ hap_cli/tests/test_member_relation_array_wrap.py
171
172
  hap_cli/tests/test_multi_profile.py
172
173
  hap_cli/tests/test_org_approval_v3_semantic_cli.py
173
174
  hap_cli/tests/test_org_id_cli.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes