hap-cli 0.9.12__tar.gz → 0.9.13__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 (213) hide show
  1. {hap_cli-0.9.12 → hap_cli-0.9.13}/PKG-INFO +1 -1
  2. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/__init__.py +1 -1
  3. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/charts.py +11 -5
  4. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/steps.py +3 -2
  5. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/workflow_dsl.py +24 -15
  6. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/chart.py +16 -2
  7. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/record_defaults.py +7 -1
  8. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/workflow_node_dsl.py +56 -14
  9. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/worksheet_templates.py +37 -13
  10. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/i18n.py +151 -0
  11. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli.egg-info/PKG-INFO +1 -1
  12. {hap_cli-0.9.12 → hap_cli-0.9.13}/MANIFEST.in +0 -0
  13. {hap_cli-0.9.12 → hap_cli-0.9.13}/README.md +0 -0
  14. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/README.md +0 -0
  15. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/README_CN.md +0 -0
  16. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/__main__.py +0 -0
  17. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/_entry.py +0 -0
  18. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/__init__.py +0 -0
  19. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/app_cmd.py +0 -0
  20. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/app_creator_cmd.py +0 -0
  21. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/app_editor_cmd.py +0 -0
  22. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/attachment_cmd.py +0 -0
  23. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/auth_cmd.py +0 -0
  24. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/calendar_cmd.py +0 -0
  25. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/chart_cmd.py +0 -0
  26. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/chat_cmd.py +0 -0
  27. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/chatbot_cmd.py +0 -0
  28. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/config_cmd.py +0 -0
  29. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/contact_cmd.py +0 -0
  30. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/department_cmd.py +0 -0
  31. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/group_cmd.py +0 -0
  32. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/guide_cmd.py +0 -0
  33. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/icon_cmd.py +0 -0
  34. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/instance_cmd.py +0 -0
  35. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/node_cmd.py +0 -0
  36. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/optionset_cmd.py +0 -0
  37. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/page_cmd.py +0 -0
  38. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/post_cmd.py +0 -0
  39. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/record_cmd.py +0 -0
  40. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/region_cmd.py +0 -0
  41. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/role_cmd.py +0 -0
  42. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/update_cmd.py +0 -0
  43. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/upload_cmd.py +0 -0
  44. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/v3_registry.py +0 -0
  45. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/workflow_cmd.py +0 -0
  46. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/commands/worksheet_cmd.py +0 -0
  47. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/context.py +0 -0
  48. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/__init__.py +0 -0
  49. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/action_spec_adapter.py +0 -0
  50. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app.py +0 -0
  51. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/__init__.py +0 -0
  52. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/_hapmeta/__init__.py +0 -0
  53. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/_hapmeta/control_type_codes.py +0 -0
  54. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/_hapmeta/worksheet_templates.py +0 -0
  55. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/cleanup.py +0 -0
  56. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/compiler.py +0 -0
  57. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/config.py +0 -0
  58. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/design/design.schema.json +0 -0
  59. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/errors.py +0 -0
  60. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/examples/minimal.design.json +0 -0
  61. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/executor.py +0 -0
  62. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/fields.py +0 -0
  63. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/hap.py +0 -0
  64. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/merge.py +0 -0
  65. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/recording/__init__.py +0 -0
  66. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/recording/console.py +0 -0
  67. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/recording/jsonl.py +0 -0
  68. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/recording/mirror.py +0 -0
  69. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/recording/report.py +0 -0
  70. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/schema.py +0 -0
  71. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/INSTRUCTIONS.md +0 -0
  72. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/__init__.py +0 -0
  73. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/cli.py +0 -0
  74. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/executor.py +0 -0
  75. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/resources/attachments.json +0 -0
  76. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/resources/sample.docx +0 -0
  77. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/resources/sample.pdf +0 -0
  78. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/resources/sample_images.json +0 -0
  79. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/seed/template.py +0 -0
  80. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/selftest.py +0 -0
  81. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/smoke.py +0 -0
  82. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/store.py +0 -0
  83. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/app_creator/validate.py +0 -0
  84. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/attachment.py +0 -0
  85. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/auth.py +0 -0
  86. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/calendar_mod.py +0 -0
  87. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/chat.py +0 -0
  88. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/chatbot.py +0 -0
  89. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/cli_access.py +0 -0
  90. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/condition_dsl.py +0 -0
  91. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/contact.py +0 -0
  92. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/control_type_codes.py +0 -0
  93. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/department.py +0 -0
  94. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/__init__.py +0 -0
  95. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/_hapmeta/__init__.py +0 -0
  96. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/_hapmeta/control_type_codes.py +0 -0
  97. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/apply.py +0 -0
  98. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/componentlower.py +0 -0
  99. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/editspec/component.schema.json +0 -0
  100. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/editspec/custom-action.schema.json +0 -0
  101. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/editspec/envelope.schema.json +0 -0
  102. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/editspec/field.schema.json +0 -0
  103. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/editspec.py +0 -0
  104. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/errors.py +0 -0
  105. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/fieldlower.py +0 -0
  106. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/jsonschema_mini.py +0 -0
  107. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/models.py +0 -0
  108. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/ops.py +0 -0
  109. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/planner.py +0 -0
  110. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/editor/reader.py +0 -0
  111. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/field_normalizer.py +0 -0
  112. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/field_spec_adapter.py +0 -0
  113. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/filter_translator.py +0 -0
  114. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/filter_v3.py +0 -0
  115. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/flow_node.py +0 -0
  116. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/global_meta.py +0 -0
  117. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/group.py +0 -0
  118. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/guide.py +0 -0
  119. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/icon_index.py +0 -0
  120. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/instance.py +0 -0
  121. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/layout_check.py +0 -0
  122. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/logger.py +0 -0
  123. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/optionset.py +0 -0
  124. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/page.py +0 -0
  125. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/post.py +0 -0
  126. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/record.py +0 -0
  127. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/record_discussions.py +0 -0
  128. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/record_form_checks.py +0 -0
  129. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/record_lookups.py +0 -0
  130. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/record_rules.py +0 -0
  131. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/relation_scope.py +0 -0
  132. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/relogin.py +0 -0
  133. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/response_crypto.py +0 -0
  134. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/role.py +0 -0
  135. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/role_perm_builder.py +0 -0
  136. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/rule_spec_adapter.py +0 -0
  137. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/session.py +0 -0
  138. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/token_crypto.py +0 -0
  139. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/update.py +0 -0
  140. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/upload.py +0 -0
  141. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/v3/__init__.py +0 -0
  142. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/v3/dispatcher.py +0 -0
  143. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/v3/render.py +0 -0
  144. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/v3/schema.py +0 -0
  145. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/view_spec_adapter.py +0 -0
  146. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/workflow.py +0 -0
  147. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/worksheet.py +0 -0
  148. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/worksheet_form.py +0 -0
  149. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/core/worksheet_reference.py +0 -0
  150. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/approval.md +0 -0
  151. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/chart.md +0 -0
  152. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/messages.md +0 -0
  153. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/overview.md +0 -0
  154. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/post.md +0 -0
  155. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/record.md +0 -0
  156. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/setup.md +0 -0
  157. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/skills.md +0 -0
  158. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/workflow.md +0 -0
  159. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/en/worksheet.md +0 -0
  160. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/index.json +0 -0
  161. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/approval.md +0 -0
  162. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/chart.md +0 -0
  163. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/messages.md +0 -0
  164. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/overview.md +0 -0
  165. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/post.md +0 -0
  166. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/record.md +0 -0
  167. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/setup.md +0 -0
  168. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/skills.md +0 -0
  169. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/workflow.md +0 -0
  170. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/guide/zh-Hans/worksheet.md +0 -0
  171. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/locale/__init__.py +0 -0
  172. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/locale/messages.json +0 -0
  173. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/locale/messages.schema.json +0 -0
  174. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/utils/__init__.py +0 -0
  175. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/utils/atomic_write.py +0 -0
  176. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/utils/confirm.py +0 -0
  177. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/utils/formatting.py +0 -0
  178. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/utils/options.py +0 -0
  179. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli/utils/parameter_mapping.py +0 -0
  180. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli.egg-info/SOURCES.txt +0 -0
  181. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli.egg-info/dependency_links.txt +0 -0
  182. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli.egg-info/entry_points.txt +0 -0
  183. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli.egg-info/requires.txt +0 -0
  184. {hap_cli-0.9.12 → hap_cli-0.9.13}/hap_cli.egg-info/top_level.txt +0 -0
  185. {hap_cli-0.9.12 → hap_cli-0.9.13}/setup.cfg +0 -0
  186. {hap_cli-0.9.12 → hap_cli-0.9.13}/setup.py +0 -0
  187. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/INDEX.json +0 -0
  188. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/add_member_to_role.yaml +0 -0
  189. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/batch_delete_records.yaml +0 -0
  190. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/create_optionset.yaml +0 -0
  191. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/create_role.yaml +0 -0
  192. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/delete_optionset.yaml +0 -0
  193. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/delete_record.yaml +0 -0
  194. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/delete_role.yaml +0 -0
  195. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/delete_worksheet.yaml +0 -0
  196. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_app_info.yaml +0 -0
  197. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_app_knowledge_list.yaml +0 -0
  198. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_app_worksheets_list.yaml +0 -0
  199. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_optionset_list.yaml +0 -0
  200. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_record_details.yaml +0 -0
  201. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_record_discussions.yaml +0 -0
  202. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_record_list.yaml +0 -0
  203. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_record_logs.yaml +0 -0
  204. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_record_pivot_data.yaml +0 -0
  205. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_record_relations.yaml +0 -0
  206. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_record_share_link.yaml +0 -0
  207. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_regions.yaml +0 -0
  208. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_role_details.yaml +0 -0
  209. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/get_role_list.yaml +0 -0
  210. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/knowledge_search.yaml +0 -0
  211. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/leave_all_roles.yaml +0 -0
  212. {hap_cli-0.9.12 → hap_cli-0.9.13}/sources/v3-api-schema/remove_member_from_role.yaml +0 -0
  213. {hap_cli-0.9.12 → hap_cli-0.9.13}/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.9.12
3
+ Version: 0.9.13
4
4
  Summary: CLI harness for Mingdao HAP - Enterprise no-code platform
5
5
  Author: hap-cli
6
6
  License: Apache-2.0
@@ -3,7 +3,7 @@
3
3
  import sys as _sys
4
4
  import types as _types
5
5
 
6
- __version__ = "0.9.12"
6
+ __version__ = "0.9.13"
7
7
 
8
8
  # The command tree used to live in hap_cli/hap_cli.py. A module named
9
9
  # after the package it sits in shadows that package: run python with the
@@ -64,8 +64,12 @@ _DISPLAY_SETUP = {
64
64
  # render (WO-1) lives in core. This module used to hold its own copy —
65
65
  # identical apart from `ignoreToday`, which core now carries too (WO-5).
66
66
  from hap_cli.core.chart import DEFAULT_CHART_FILTER as _FILTER
67
+ from hap_cli.core.chart import default_chart_filter
68
+ from hap_cli.i18n import content_default
67
69
 
68
- _SUMMARY = {"controlId": "", "type": 1, "name": "总计", "number": True,
70
+ # ``name`` is left empty: saving the chart fills in the total's label in
71
+ # the CLI's language (core.chart._fill_summary_name).
72
+ _SUMMARY = {"controlId": "", "type": 1, "name": "", "number": True,
69
73
  "percent": False, "sum": 0, "contrastSum": 0, "contrastMapSum": 0, "rename": ""}
70
74
 
71
75
  _EMPTY_XAXES = {
@@ -82,7 +86,8 @@ def _yaxis(metric: dict[str, Any], resolve: Callable[[str], dict[str, Any]]) ->
82
86
  field == 'count' -> the special record-count pseudo column."""
83
87
  agg = metric.get("aggregate", "sum")
84
88
  if metric["field"] == "count":
85
- cid, cname, ctype = "record_count", "记录数量", 10000000
89
+ cid, cname, ctype = ("record_count", content_default("chart.recordCount"),
90
+ 10000000)
86
91
  norm = NORM_TYPE.get(agg, 5)
87
92
  else:
88
93
  c = resolve(metric["field"])
@@ -183,7 +188,7 @@ def _right_y(metrics: list[dict[str, Any]], report_type_int: int,
183
188
  title = ""
184
189
  if metrics:
185
190
  m0 = metrics[0]
186
- title = ("记录数量" if m0["field"] == "count"
191
+ title = (content_default("chart.recordCount") if m0["field"] == "count"
187
192
  else resolve(m0["field"]).get("controlName") or m0["field"])
188
193
  return {
189
194
  "reportType": report_type_int,
@@ -238,7 +243,7 @@ def chart_spec(
238
243
  # ``limit`` on the chart maps straight to it.
239
244
  if chart.get("limit") is not None:
240
245
  display["showXAxisCount"] = int(chart["limit"])
241
- filt = dict(_FILTER)
246
+ filt = default_chart_filter()
242
247
  if filters:
243
248
  filt["filter"] = None # filters supplied via items below
244
249
  spec: dict[str, Any] = {
@@ -250,7 +255,8 @@ def chart_spec(
250
255
  "filter": filt,
251
256
  "sorts": [], "formulas": [], "summary": dict(_SUMMARY), "style": {},
252
257
  "split": {}, "splitId": None, "sourceType": 1, "auth": 1, "isPublic": True,
253
- "views": [{"viewId": view_id, "name": "全部", "viewType": 0}],
258
+ "views": [{"viewId": view_id, "name": content_default("view.all"),
259
+ "viewType": 0}],
254
260
  "desc": "",
255
261
  }
256
262
  if is_pivot:
@@ -27,6 +27,7 @@ from hap_cli.core.app_creator import hap
27
27
  from hap_cli.core.app_creator import workflow_dsl as WD
28
28
  from hap_cli.core.app_creator.errors import PartialStepFailure, ResolveError
29
29
  from hap_cli.core.app_creator.store import Store
30
+ from hap_cli.i18n import DEFAULT_VIEW_NAMES
30
31
 
31
32
  logger = logging.getLogger("hap_app_creator.steps")
32
33
 
@@ -822,7 +823,7 @@ def _builtin_all_view_id(wsid: str) -> str:
822
823
  views = data if isinstance(data, list) else (
823
824
  (data or {}).get("views") or (data or {}).get("data") or [])
824
825
  for v in views:
825
- if v.get("name") in ("全部", "All") and v.get("viewType", 0) == 0:
826
+ if v.get("name") in DEFAULT_VIEW_NAMES and v.get("viewType", 0) == 0:
826
827
  return v.get("viewId") or v.get("id") or ""
827
828
  return ""
828
829
 
@@ -1393,7 +1394,7 @@ def _default_view_id(wsid: str) -> str:
1393
1394
  if not views:
1394
1395
  return ""
1395
1396
  for v in views:
1396
- if v.get("name") == "全部":
1397
+ if v.get("name") in DEFAULT_VIEW_NAMES:
1397
1398
  return v.get("viewId") or v.get("id") or ""
1398
1399
  return views[0].get("viewId") or views[0].get("id") or ""
1399
1400
 
@@ -24,6 +24,8 @@ from __future__ import annotations
24
24
  import re
25
25
  from typing import Any
26
26
 
27
+ from hap_cli.i18n import DEFAULT_VIEW_NAMES, content_default
28
+
27
29
  # Field-ref string convention: "工作表名/字段名". System columns and ids pass
28
30
  # through verbatim.
29
31
  _SYSTEM_FIELDS = {"rowid", "ownerid", "caid", "ctime", "utime", "uaid"}
@@ -249,12 +251,20 @@ def _option_object(control: dict[str, Any], value: Any):
249
251
  return [_one(v) for v in value] if isinstance(value, list) else _one(value)
250
252
 
251
253
 
252
- # Approval-outcome keys (审批结果) for an approval_block result branch.
254
+ # Approval-outcome keys (审批结果) for an approval_block result branch:
255
+ # what an author may write (key or Chinese label) → the outcome key.
253
256
  _APPROVAL_RESULTS = {
254
- "PASS": "通过", "通过": "通过",
255
- "OVERRULE": "否决", "否决": "否决",
256
- "REVOKE": "撤回", "撤回": "撤回",
257
- "SUSPEND": "中止", "中止": "中止", "已取消": "中止",
257
+ "PASS": "PASS", "通过": "PASS",
258
+ "OVERRULE": "OVERRULE", "否决": "OVERRULE",
259
+ "REVOKE": "REVOKE", "撤回": "REVOKE",
260
+ "SUSPEND": "SUSPEND", "中止": "SUSPEND", "已取消": "SUSPEND",
261
+ }
262
+
263
+ # The label stored beside each key and shown in the branch condition; in
264
+ # the CLI's language, as the editor writes it (ticket 47173).
265
+ _APPROVAL_RESULT_LABELS = {
266
+ "PASS": "approval.pass", "OVERRULE": "approval.overrule",
267
+ "REVOKE": "approval.revoke", "SUSPEND": "approval.suspend",
258
268
  }
259
269
 
260
270
 
@@ -262,13 +272,12 @@ def _approval_result_object(value: Any):
262
272
  """Map an approval outcome (key or label) to the fixed conditionValues
263
273
  option object the result-branch wire wants."""
264
274
  def _one(v):
265
- label = _APPROVAL_RESULTS.get(v)
266
- if label is None:
275
+ key = _APPROVAL_RESULTS.get(v)
276
+ if key is None:
267
277
  return v
268
- key = next(k for k, lab in _APPROVAL_RESULTS.items()
269
- if lab == label and k.isupper())
270
- return {"key": key, "value": label, "isDeleted": False,
271
- "score": None, "index": None}
278
+ return {"key": key,
279
+ "value": content_default(_APPROVAL_RESULT_LABELS[key]),
280
+ "isDeleted": False, "score": None, "index": None}
272
281
  return [_one(v) for v in value] if isinstance(value, list) else _one(value)
273
282
 
274
283
 
@@ -292,14 +301,14 @@ def _condition_item(d: dict[str, Any], r: _Resolver) -> dict[str, Any]:
292
301
  if left_ref == "result":
293
302
  new_left = dict(out.get("left") or {})
294
303
  new_left["_filedTypeId"] = 11
295
- new_left["_filedValue"] = "审批结果"
304
+ new_left["_filedValue"] = content_default("approval.result")
296
305
  new_left["_enumDefault"] = 0
297
306
  # The source-node metadata the wire expects (审批结果 lives on the
298
307
  # approval_block: nodeType 26, appType 10) rides on left.node.
299
308
  node_meta = dict(new_left.get("node") or {})
300
309
  node_meta["_nodeType"] = 26
301
310
  node_meta["_appType"] = 10
302
- node_meta["_nodeName"] = "审批"
311
+ node_meta["_nodeName"] = content_default("approval.node")
303
312
  new_left["node"] = node_meta
304
313
  out["left"] = new_left
305
314
  right = d.get("right")
@@ -321,7 +330,7 @@ def _condition_item(d: dict[str, Any], r: _Resolver) -> dict[str, Any]:
321
330
  type_code = r.formula_types.get(left_node_alias, 6)
322
331
  new_left["fieldId"] = _fx_field_for_code(type_code)
323
332
  new_left["_filedTypeId"] = type_code
324
- new_left["_filedValue"] = "结果"
333
+ new_left["_filedValue"] = content_default("formula.result")
325
334
  new_left["_enumDefault"] = 0
326
335
  node_meta = dict(new_left.get("node") or {})
327
336
  node_meta["_nodeType"] = 9
@@ -546,7 +555,7 @@ def _default_view_id(wsid: str) -> str:
546
555
  vid = ""
547
556
  if isinstance(views, list) and views:
548
557
  vid = next((v.get("viewId") or v.get("id") for v in views
549
- if v.get("name") == "全部"), None) or \
558
+ if v.get("name") in DEFAULT_VIEW_NAMES), None) or \
550
559
  views[0].get("viewId") or views[0].get("id") or ""
551
560
  _VIEW_CACHE[wsid] = vid
552
561
  return vid
@@ -58,7 +58,10 @@ logger = logging.getLogger("hap_cli.chart")
58
58
  # (any non-empty dict) keep it untouched.
59
59
  DEFAULT_CHART_FILTER: dict[str, Any] = {
60
60
  "filterRangeId": "ctime",
61
- "filterRangeName": "创建时间",
61
+ # The label of filterRangeId. The server re-derives it in the account's
62
+ # language on save (measured 2026-10-27: a sent value is not kept);
63
+ # default_chart_filter() still sends one, in the CLI's language.
64
+ "filterRangeName": "",
62
65
  "rangeType": 0,
63
66
  "rangeValue": None,
64
67
  "today": False,
@@ -114,6 +117,17 @@ _ID_VALUED_CONTROL_TYPES = frozenset({26, 27, 19, 23, 24, 29, 35, 48})
114
117
  _VALUELESS_FILTER_TYPES = frozenset({7, 8, 41, 42})
115
118
 
116
119
 
120
+ def default_chart_filter() -> dict[str, Any]:
121
+ """A fresh copy of DEFAULT_CHART_FILTER, its range labelled in the
122
+ CLI's language rather than always in Chinese."""
123
+ from hap_cli.i18n import content_default
124
+
125
+ filter_block = dict(DEFAULT_CHART_FILTER)
126
+ filter_block["dynamicFilter"] = dict(DEFAULT_CHART_FILTER["dynamicFilter"])
127
+ filter_block["filterRangeName"] = content_default("chart.createdTime")
128
+ return filter_block
129
+
130
+
117
131
  def _summary_label(summary_type: Any) -> str:
118
132
  entry = _SUMMARY_TYPE_NAMES.get(summary_type)
119
133
  if not entry:
@@ -502,7 +516,7 @@ def save_chart(
502
516
  # caller is expected to carry the current filter forward (which
503
517
  # :func:`update_chart` does by reading it back).
504
518
  if not body.get("filter") and not report_id:
505
- body["filter"] = dict(DEFAULT_CHART_FILTER)
519
+ body["filter"] = default_chart_filter()
506
520
  # A chart made from inside a view is scoped to it, so it counts the
507
521
  # rows that view shows rather than the whole worksheet (MDPublic
508
522
  # src/pages/Statistics/redux/actions.js:74-76). An explicit viewId in
@@ -438,7 +438,13 @@ def as_text(source: Optional[dict[str, Any]], value: Any,
438
438
  return ""
439
439
  named = " ".join(p for p in (spot.get("title"), spot.get("address"))
440
440
  if p)
441
- return named or f"经度:{spot.get('x')} 纬度:{spot.get('y')}"
441
+ if named:
442
+ return named
443
+ from hap_cli.i18n import content_default
444
+ return " ".join(
445
+ content_default(key).replace("%0", str(spot.get(axis)))
446
+ for key, axis in (("location.longitude", "x"),
447
+ ("location.latitude", "y")))
442
448
  if kind == 46:
443
449
  when = str(value)
444
450
  return when[:8] if source.get("unit") == "6" else when[:5]
@@ -29,6 +29,8 @@ import logging
29
29
  import re
30
30
  from typing import Any, Callable, Optional
31
31
 
32
+ from hap_cli.i18n import content_default
33
+
32
34
  logger = logging.getLogger("hap_cli.workflow.node_dsl")
33
35
 
34
36
 
@@ -506,9 +508,10 @@ def _condition_value_entries(
506
508
  "actionId": "",
507
509
  "appType": 100,
508
510
  "controlId": sys_field,
509
- "controlName": _SYSTEM_VALUE_NAMES.get(sys_field, "当前时间"),
511
+ "controlName": content_default(_SYSTEM_VALUE_NAMES.get(
512
+ sys_field, "workflow.system.nowTime")),
510
513
  "nodeId": SYSTEM_NODE_ID,
511
- "nodeName": "系统",
514
+ "nodeName": content_default("workflow.system"),
512
515
  "nodeType": 100,
513
516
  "sourceType": 0,
514
517
  }]
@@ -1156,13 +1159,15 @@ def translate_accounts(
1156
1159
  # node (default the trigger) with the special "uaid" roleId.
1157
1160
  node_id = _resolve_node_id(acc.get("node") or {"nodeAlias": "trigger"}, a2i)
1158
1161
  out.append({"type": 6, "entityId": node_id, "entityName": "",
1159
- "roleId": "uaid", "roleTypeId": 0, "roleName": "触发者",
1162
+ "roleId": "uaid", "roleTypeId": 0,
1163
+ "roleName": content_default("workflow.system.trigger"),
1160
1164
  "controlType": 26})
1161
1165
  elif kind == "supervisor":
1162
1166
  # Direct supervisor of the trigger user (roleTypeId 11).
1163
1167
  node_id = _resolve_node_id(acc.get("node") or {"nodeAlias": "trigger"}, a2i)
1164
1168
  out.append({"type": 6, "entityId": node_id, "entityName": "",
1165
- "roleId": "uaid", "roleTypeId": 11, "roleName": "触发者",
1169
+ "roleId": "uaid", "roleTypeId": 11,
1170
+ "roleName": content_default("workflow.system.trigger"),
1166
1171
  "controlType": 26})
1167
1172
  elif kind == "field":
1168
1173
  # Recipient = a member/dept/email FIELD on a record. Ground truth
@@ -1321,10 +1326,36 @@ def configure_worksheet_trigger(
1321
1326
  }
1322
1327
  return _fn.save_node(
1323
1328
  session, process_id, trigger_node_id, 0, config,
1324
- name="工作表事件触发",
1329
+ name=_trigger_name(session, process_id, trigger_node_id, "worksheet"),
1325
1330
  )
1326
1331
 
1327
1332
 
1333
+ def _trigger_name(session, process_id: str, trigger_node_id: str,
1334
+ kind: str) -> str:
1335
+ """The name to save a trigger under: the one it already has.
1336
+
1337
+ saveNode stores whatever ``name`` it is sent and blanks the node when
1338
+ there is none (measured live 2026-10-27), and the editor always sends
1339
+ the node's current name back (MDPublic WorkflowSettings/Detail/Start/
1340
+ index.jsx:277). The server names a new trigger in the account's
1341
+ language, so writing a fixed Chinese name here turned it Chinese in
1342
+ English workspaces (ticket 47173) and undid any rename.
1343
+ """
1344
+ from hap_cli.core import flow_node as _fn
1345
+ try:
1346
+ detail = _fn.get_node_detail(session, process_id, trigger_node_id,
1347
+ flow_node_type=0) or {}
1348
+ if isinstance(detail, dict) and isinstance(detail.get("data"), dict):
1349
+ detail = detail["data"]
1350
+ name = (detail.get("name") or "").strip() if isinstance(detail, dict) else ""
1351
+ if name:
1352
+ return name
1353
+ except Exception as exc: # noqa: BLE001
1354
+ logger.warning("could not read the name of the trigger of %s; "
1355
+ "saving it under the default name: %s", process_id, exc)
1356
+ return content_default(f"workflow.trigger.{kind}")
1357
+
1358
+
1328
1359
  def _stored_trigger_config(session, process_id: str,
1329
1360
  trigger_node_id: str) -> dict[str, Any]:
1330
1361
  """What the trigger already carries, for the keys this call may keep.
@@ -1387,7 +1418,6 @@ def configure_scheduled_trigger(
1387
1418
  frequency = 2 if repeat_type == 5 else repeat_type # workday → weekly
1388
1419
  cfg = {
1389
1420
  "appType": 5,
1390
- "name": "定时触发",
1391
1421
  "executeTime": start_time,
1392
1422
  "executeEndTime": end_time,
1393
1423
  "repeatType": repeat_type,
@@ -1400,7 +1430,8 @@ def configure_scheduled_trigger(
1400
1430
  "returns": [],
1401
1431
  }
1402
1432
  return _fn.save_node(
1403
- session, process_id, trigger_node_id, 0, cfg, name="定时触发",
1433
+ session, process_id, trigger_node_id, 0, cfg,
1434
+ name=_trigger_name(session, process_id, trigger_node_id, "scheduled"),
1404
1435
  )
1405
1436
 
1406
1437
 
@@ -1444,12 +1475,12 @@ def configure_date_trigger(
1444
1475
  "frequency": _DATE_REPEAT.get(repeat, 0),
1445
1476
  "operateCondition": [],
1446
1477
  "triggerId": "2",
1447
- "name": "按日期字段触发",
1448
1478
  "controls": [],
1449
1479
  "returns": [],
1450
1480
  }
1451
1481
  return _fn.save_node(
1452
- session, process_id, trigger_node_id, 0, cfg, name="按日期字段触发",
1482
+ session, process_id, trigger_node_id, 0, cfg,
1483
+ name=_trigger_name(session, process_id, trigger_node_id, "date"),
1453
1484
  )
1454
1485
 
1455
1486
 
@@ -1545,7 +1576,8 @@ def configure_pbp_trigger(
1545
1576
  "returns": [],
1546
1577
  }
1547
1578
  return _fn.save_node(
1548
- session, process_id, trigger_node_id, 0, cfg, name="封装业务流程",
1579
+ session, process_id, trigger_node_id, 0, cfg,
1580
+ name=_trigger_name(session, process_id, trigger_node_id, "pbp"),
1549
1581
  )
1550
1582
 
1551
1583
 
@@ -1662,13 +1694,17 @@ def configure_webhook_trigger(
1662
1694
  detail = detail.get("data", detail)
1663
1695
  return detail.get("controls", []) if isinstance(detail, dict) else []
1664
1696
 
1697
+ # Read once: every save below must carry the trigger's own name.
1698
+ trigger_name = _trigger_name(session, process_id, trigger_node_id,
1699
+ "webhook")
1700
+
1665
1701
  def _save(controls: list[dict[str, Any]]) -> None:
1666
1702
  _fn.save_node(
1667
1703
  session, process_id, trigger_node_id, 0,
1668
1704
  {"appType": 7, "assignFieldIds": [], "operateCondition": [],
1669
1705
  "isUpdate": False, "controls": controls, "returnJson": "",
1670
1706
  "returns": [], "hooksBody": False},
1671
- name="Webhook触发",
1707
+ name=trigger_name,
1672
1708
  )
1673
1709
 
1674
1710
  hook_url = get_webhook_url(session, process_id, trigger_node_id)
@@ -4387,9 +4423,14 @@ _SYSTEM_VALUE_FIELDS = {
4387
4423
  }
4388
4424
 
4389
4425
  # 系统 node field id → its display name (controlName on a conditionValues entry).
4426
+ # Written into the step and shown in the editor, so it is localised
4427
+ # (hap_cli.i18n.CONTENT_DEFAULTS).
4390
4428
  _SYSTEM_VALUE_NAMES = {
4391
- "nowTime": "当前时间", "triggertime": "触发时间", "triggeraid": "触发者",
4392
- "timestamp": "时间戳", "timestampSeconds": "时间戳",
4429
+ "nowTime": "workflow.system.nowTime",
4430
+ "triggertime": "workflow.system.triggerTime",
4431
+ "triggeraid": "workflow.system.trigger",
4432
+ "timestamp": "workflow.system.timestamp",
4433
+ "timestampSeconds": "workflow.system.timestamp",
4393
4434
  }
4394
4435
 
4395
4436
 
@@ -4808,7 +4849,8 @@ def _save_approval_block(session, process_id, node, prev_id, parent_id,
4808
4849
 
4809
4850
  extra = {"parentId": parent_id} if parent_id else None
4810
4851
  add_resp = _fn.add_node(session, process_id, 26, prev_id,
4811
- name=node.get("name", "未命名审批流程"),
4852
+ name=node.get("name") or content_default(
4853
+ "workflow.unnamedApproval"),
4812
4854
  app_type=10, extra=extra)
4813
4855
  apr = _added_nodes(add_resp)
4814
4856
  apr_node = apr[0] if apr else {}
@@ -21,6 +21,8 @@ import json
21
21
  import uuid
22
22
  from typing import Any, Iterable, Optional
23
23
 
24
+ from hap_cli.i18n import content_default
25
+
24
26
  # ── Field type enum (mirror of pd-openweb WIDGETS_TO_API_TYPE_ENUM) ──────
25
27
 
26
28
  TYPE = {
@@ -121,21 +123,20 @@ _DEFAULTS: dict[str, dict[str, Any]] = {
121
123
  "advancedSetting": {"analysislink": "1", "sorttype": "en"},
122
124
  },
123
125
  "MOBILE_PHONE": {
124
- "size": 6, "hint": "请填写手机号码",
126
+ "size": 6,
125
127
  # The product seeds a 13-country shortlist for the picker; it has no
126
128
  # `defaultarea` key.
127
129
  "enumDefault": 0,
128
130
  "advancedSetting": {"commcountries": '[{"name":"China (中国)","iso2":"cn","dialCode":"86"},{"name":"Hong Kong (香港)","iso2":"hk","dialCode":"852"},{"name":"Taiwan (台灣)","iso2":"tw","dialCode":"886"},{"name":"Macau (澳門)","iso2":"mo","dialCode":"853"},{"name":"Singapore","iso2":"sg","dialCode":"65"},{"name":"Malaysia","iso2":"my","dialCode":"60"},{"name":"Japan (日本)","iso2":"jp","dialCode":"81"},{"name":"South Korea (대한민국)","iso2":"kr","dialCode":"82"},{"name":"United States","iso2":"us","dialCode":"1"},{"name":"United Kingdom","iso2":"gb","dialCode":"44"},{"name":"France","iso2":"fr","dialCode":"33"},{"name":"Germany (Deutschland)","iso2":"de","dialCode":"49"},{"name":"Russia (Россия)","iso2":"ru","dialCode":"7"}]'},
129
131
  },
130
- "TELEPHONE": {"size": 6, "hint": "请填写座机号码"},
131
- "EMAIL": {"size": 6, "hint": "请填写邮箱地址"},
132
+ "TELEPHONE": {"size": 6},
133
+ "EMAIL": {"size": 6},
132
134
  "NUMBER": {
133
- "size": 6, "dot": 0, "hint": "请填写数值",
135
+ "size": 6, "dot": 0,
134
136
  "advancedSetting": {"showtype": "0", "roundtype": "2", "thousandth": "0"},
135
137
  },
136
138
  "MONEY": {
137
139
  "size": 6, "dot": 2, "enumDefault": 0, "enumDefault2": 2,
138
- "hint": "请填写金额",
139
140
  "advancedSetting": {
140
141
  "currency": '{"currencycode":"CNY","symbol":"¥"}',
141
142
  "roundtype": "2", "showformat": "1",
@@ -149,11 +150,11 @@ _DEFAULTS: dict[str, dict[str, Any]] = {
149
150
  },
150
151
  },
151
152
  "DROP_DOWN": {
152
- "size": 6, "enumDefault2": 0, "hint": "请选择",
153
+ "size": 6, "enumDefault2": 0,
153
154
  "advancedSetting": {"showtype": "0"},
154
155
  },
155
156
  "ATTACHMENT": {
156
- "size": 12, "enumDefault": 3, "hint": "添加附件",
157
+ "size": 12, "enumDefault": 3,
157
158
  "advancedSetting": {
158
159
  "showtype": "1", "covertype": "0", "alldownload": "1",
159
160
  "webcompress": "1", "allowupload": "1", "allowdelete": "1",
@@ -161,11 +162,11 @@ _DEFAULTS: dict[str, dict[str, Any]] = {
161
162
  },
162
163
  },
163
164
  "DATE": {
164
- "size": 6, "hint": "请选择日期",
165
+ "size": 6,
165
166
  "advancedSetting": {"showtype": "3", "allowtime": ""},
166
167
  },
167
168
  "DATE_TIME": {
168
- "size": 6, "hint": "请选择日期",
169
+ "size": 6,
169
170
  "advancedSetting": {"showtype": "1"},
170
171
  },
171
172
  "AREA_PROVINCE": {"size": 6, "enumDefault": 0},
@@ -176,7 +177,7 @@ _DEFAULTS: dict[str, dict[str, Any]] = {
176
177
  },
177
178
  "USER_PICKER": {
178
179
  "size": 6, "enumDefault": 0, "enumDefault2": 0, "userPermission": 1,
179
- "noticeItem": 0, "hint": "请选择成员",
180
+ "noticeItem": 0,
180
181
  "advancedSetting": {"checkusertype": "1", "usertype": "1"},
181
182
  },
182
183
  # userPermission 0 = "无" (store data only). MDPublic ae228624ca4
@@ -286,11 +287,10 @@ _DEFAULTS: dict[str, dict[str, Any]] = {
286
287
  "OCR": {"size": 6},
287
288
  "EMBED": {
288
289
  "size": 12, "enumDefault": 1,
289
- "hint": "编辑状态下不支持查看",
290
290
  "advancedSetting": {"height": "400"},
291
291
  },
292
292
  "SEARCH_BTN": {
293
- "size": 6, "enumDefault": 0, "enumDefault2": 0, "hint": "查询",
293
+ "size": 6, "enumDefault": 0, "enumDefault2": 0,
294
294
  },
295
295
  "SEARCH": {"size": 6},
296
296
  "RELATION_SEARCH": {
@@ -307,7 +307,7 @@ _DEFAULTS: dict[str, dict[str, Any]] = {
307
307
  },
308
308
  "RELATION": {"size": 12, "enumDefault": 0},
309
309
  "MONEY_CN": {"size": 6},
310
- "CRED": {"size": 6, "enumDefault": 1, "hint": "请填写身份证"},
310
+ "CRED": {"size": 6, "enumDefault": 1},
311
311
  }
312
312
 
313
313
 
@@ -326,6 +326,28 @@ _USES_SOURCE_CONTROL = frozenset({
326
326
  })
327
327
 
328
328
 
329
+ # Placeholder text the product gives a new field (DEFAULT_DATA, MDPublic
330
+ # src/utils/domain/control/widget.js), written through ``_l()`` so it is
331
+ # in the editor's language. Kept out of _DEFAULTS and localised per build
332
+ # (hap_cli.i18n.CONTENT_DEFAULTS): a Chinese literal showed as Chinese
333
+ # placeholder text in English workspaces (ticket 47173).
334
+ _HINT_KEYS: dict[str, str] = {
335
+ "MOBILE_PHONE": "field.hint.mobilePhone",
336
+ "TELEPHONE": "field.hint.telephone",
337
+ "EMAIL": "field.hint.email",
338
+ "NUMBER": "field.hint.number",
339
+ "MONEY": "field.hint.money",
340
+ "DROP_DOWN": "field.hint.select",
341
+ "ATTACHMENT": "field.hint.attachment",
342
+ "DATE": "field.hint.date",
343
+ "DATE_TIME": "field.hint.date",
344
+ "USER_PICKER": "field.hint.member",
345
+ "EMBED": "field.hint.embed",
346
+ "SEARCH_BTN": "field.hint.searchButton",
347
+ "CRED": "field.hint.idCard",
348
+ }
349
+
350
+
329
351
  def build_control(
330
352
  field_type: str | int,
331
353
  name: str,
@@ -444,6 +466,8 @@ def build_control(
444
466
  if k == "advancedSetting":
445
467
  continue
446
468
  ctrl.setdefault(k, v)
469
+ if type_name in _HINT_KEYS:
470
+ ctrl["hint"] = content_default(_HINT_KEYS[type_name])
447
471
  # advancedSetting merge
448
472
  adv = dict(defaults.get("advancedSetting", {}))
449
473
  if advanced_setting: