ErisPulse 2.6.3.dev0__tar.gz → 2.7.0.dev3__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 (199) hide show
  1. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/PKG-INFO +1 -1
  2. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/pyproject.toml +1 -1
  3. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/create.py +58 -3
  4. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/__init__.py +22 -1
  5. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/adapter.py +417 -6
  6. {erispulse-2.6.3.dev0/src/ErisPulse/runtime → erispulse-2.7.0.dev3/src/ErisPulse/Core/Bases}/config_schema.py +62 -16
  7. erispulse-2.7.0.dev3/src/ErisPulse/Core/Bases/i18n_schema.py +239 -0
  8. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/module.py +37 -3
  9. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/session_type.py +28 -6
  10. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/wrapper.py +111 -4
  11. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/__init__.py +2 -0
  12. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/adapter.py +14 -1
  13. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/config.py +150 -19
  14. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/constants.py +14 -0
  15. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/i18n/locales/en.py +15 -0
  16. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/i18n/locales/ja.py +15 -0
  17. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/i18n/locales/ru.py +15 -0
  18. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/i18n/locales/zh_cn.py +15 -0
  19. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/i18n/locales/zh_tw.py +15 -0
  20. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/module.py +11 -0
  21. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/loaders/adapter.py +6 -0
  22. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/loaders/module.py +12 -0
  23. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/runtime/__init__.py +41 -13
  24. erispulse-2.7.0.dev3/src/ErisPulse/runtime/config_schema.py +37 -0
  25. erispulse-2.7.0.dev3/src/ErisPulse/runtime/diagnostics.py +317 -0
  26. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/sdk.py +120 -7
  27. erispulse-2.6.3.dev0/src/ErisPulse/CLI/__init__.pyi +0 -16
  28. erispulse-2.6.3.dev0/src/ErisPulse/CLI/base.pyi +0 -52
  29. erispulse-2.6.3.dev0/src/ErisPulse/CLI/cli.pyi +0 -89
  30. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/__init__.pyi +0 -9
  31. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/create.pyi +0 -95
  32. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/init.pyi +0 -94
  33. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/install.pyi +0 -78
  34. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/language.pyi +0 -51
  35. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/list.pyi +0 -58
  36. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/list_remote.pyi +0 -44
  37. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/run.pyi +0 -108
  38. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/self_update.pyi +0 -68
  39. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/types.pyi +0 -148
  40. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/uninstall.pyi +0 -37
  41. erispulse-2.6.3.dev0/src/ErisPulse/CLI/commands/upgrade.pyi +0 -31
  42. erispulse-2.6.3.dev0/src/ErisPulse/CLI/console.pyi +0 -51
  43. erispulse-2.6.3.dev0/src/ErisPulse/CLI/hints.pyi +0 -71
  44. erispulse-2.6.3.dev0/src/ErisPulse/CLI/i18n/__init__.pyi +0 -115
  45. erispulse-2.6.3.dev0/src/ErisPulse/CLI/i18n/locales/__init__.pyi +0 -12
  46. erispulse-2.6.3.dev0/src/ErisPulse/CLI/i18n/locales/en.pyi +0 -8
  47. erispulse-2.6.3.dev0/src/ErisPulse/CLI/i18n/locales/ja.pyi +0 -8
  48. erispulse-2.6.3.dev0/src/ErisPulse/CLI/i18n/locales/ru.pyi +0 -8
  49. erispulse-2.6.3.dev0/src/ErisPulse/CLI/i18n/locales/zh_cn.pyi +0 -8
  50. erispulse-2.6.3.dev0/src/ErisPulse/CLI/i18n/locales/zh_tw.pyi +0 -8
  51. erispulse-2.6.3.dev0/src/ErisPulse/CLI/registry.pyi +0 -92
  52. erispulse-2.6.3.dev0/src/ErisPulse/CLI/utils/__init__.pyi +0 -11
  53. erispulse-2.6.3.dev0/src/ErisPulse/CLI/utils/display.pyi +0 -114
  54. erispulse-2.6.3.dev0/src/ErisPulse/CLI/utils/file_watcher.pyi +0 -123
  55. erispulse-2.6.3.dev0/src/ErisPulse/CLI/utils/package_manager.pyi +0 -391
  56. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/__init__.pyi +0 -19
  57. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/adapter.pyi +0 -786
  58. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/client.pyi +0 -277
  59. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/errors.pyi +0 -115
  60. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/kv_builder.pyi +0 -125
  61. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/manager.pyi +0 -138
  62. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/module.pyi +0 -137
  63. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/router.pyi +0 -451
  64. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/send_builder.pyi +0 -231
  65. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/send_rules.pyi +0 -167
  66. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/storage.pyi +0 -397
  67. erispulse-2.6.3.dev0/src/ErisPulse/Core/Bases/websocket.pyi +0 -194
  68. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/__init__.pyi +0 -28
  69. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/base.pyi +0 -71
  70. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/command.pyi +0 -121
  71. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/message.pyi +0 -102
  72. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/message_builder.pyi +0 -147
  73. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/meta.pyi +0 -101
  74. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/notice.pyi +0 -117
  75. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/request.pyi +0 -86
  76. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/session_type.pyi +0 -216
  77. erispulse-2.6.3.dev0/src/ErisPulse/Core/Event/wrapper.pyi +0 -1170
  78. erispulse-2.6.3.dev0/src/ErisPulse/Core/__init__.pyi +0 -36
  79. erispulse-2.6.3.dev0/src/ErisPulse/Core/adapter.pyi +0 -494
  80. erispulse-2.6.3.dev0/src/ErisPulse/Core/assets/__init__.pyi +0 -65
  81. erispulse-2.6.3.dev0/src/ErisPulse/Core/client.pyi +0 -407
  82. erispulse-2.6.3.dev0/src/ErisPulse/Core/config.pyi +0 -129
  83. erispulse-2.6.3.dev0/src/ErisPulse/Core/constants.pyi +0 -217
  84. erispulse-2.6.3.dev0/src/ErisPulse/Core/i18n/__init__.pyi +0 -153
  85. erispulse-2.6.3.dev0/src/ErisPulse/Core/i18n/constants.pyi +0 -8
  86. erispulse-2.6.3.dev0/src/ErisPulse/Core/i18n/locales/__init__.pyi +0 -12
  87. erispulse-2.6.3.dev0/src/ErisPulse/Core/i18n/locales/en.pyi +0 -8
  88. erispulse-2.6.3.dev0/src/ErisPulse/Core/i18n/locales/ja.pyi +0 -8
  89. erispulse-2.6.3.dev0/src/ErisPulse/Core/i18n/locales/ru.pyi +0 -8
  90. erispulse-2.6.3.dev0/src/ErisPulse/Core/i18n/locales/zh_cn.pyi +0 -8
  91. erispulse-2.6.3.dev0/src/ErisPulse/Core/i18n/locales/zh_tw.pyi +0 -8
  92. erispulse-2.6.3.dev0/src/ErisPulse/Core/lifecycle.pyi +0 -240
  93. erispulse-2.6.3.dev0/src/ErisPulse/Core/logger.pyi +0 -378
  94. erispulse-2.6.3.dev0/src/ErisPulse/Core/master.pyi +0 -119
  95. erispulse-2.6.3.dev0/src/ErisPulse/Core/module.pyi +0 -300
  96. erispulse-2.6.3.dev0/src/ErisPulse/Core/router.pyi +0 -651
  97. erispulse-2.6.3.dev0/src/ErisPulse/Core/storage.pyi +0 -455
  98. erispulse-2.6.3.dev0/src/ErisPulse/__init__.pyi +0 -20
  99. erispulse-2.6.3.dev0/src/ErisPulse/__main__.pyi +0 -21
  100. erispulse-2.6.3.dev0/src/ErisPulse/finders/__init__.pyi +0 -19
  101. erispulse-2.6.3.dev0/src/ErisPulse/finders/adapter.pyi +0 -91
  102. erispulse-2.6.3.dev0/src/ErisPulse/finders/bases/__init__.pyi +0 -4
  103. erispulse-2.6.3.dev0/src/ErisPulse/finders/bases/finder.pyi +0 -66
  104. erispulse-2.6.3.dev0/src/ErisPulse/finders/module.pyi +0 -91
  105. erispulse-2.6.3.dev0/src/ErisPulse/loaders/__init__.pyi +0 -18
  106. erispulse-2.6.3.dev0/src/ErisPulse/loaders/adapter.pyi +0 -96
  107. erispulse-2.6.3.dev0/src/ErisPulse/loaders/bases/__init__.pyi +0 -4
  108. erispulse-2.6.3.dev0/src/ErisPulse/loaders/bases/loader.pyi +0 -20
  109. erispulse-2.6.3.dev0/src/ErisPulse/loaders/module.pyi +0 -185
  110. erispulse-2.6.3.dev0/src/ErisPulse/loaders/strategy.pyi +0 -90
  111. erispulse-2.6.3.dev0/src/ErisPulse/loaders/strict.pyi +0 -118
  112. erispulse-2.6.3.dev0/src/ErisPulse/runtime/__init__.pyi +0 -18
  113. erispulse-2.6.3.dev0/src/ErisPulse/runtime/config_schema.pyi +0 -285
  114. erispulse-2.6.3.dev0/src/ErisPulse/runtime/context.pyi +0 -34
  115. erispulse-2.6.3.dev0/src/ErisPulse/runtime/exceptions.pyi +0 -95
  116. erispulse-2.6.3.dev0/src/ErisPulse/runtime/frame_config.pyi +0 -116
  117. erispulse-2.6.3.dev0/src/ErisPulse/runtime/hints.pyi +0 -266
  118. erispulse-2.6.3.dev0/src/ErisPulse/runtime/tasks.pyi +0 -41
  119. erispulse-2.6.3.dev0/src/ErisPulse/sdk.pyi +0 -259
  120. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/.gitignore +0 -0
  121. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/LICENSE +0 -0
  122. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/README.pypi.md +0 -0
  123. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/__init__.py +0 -0
  124. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/base.py +0 -0
  125. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/cli.py +0 -0
  126. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/__init__.py +0 -0
  127. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/init.py +0 -0
  128. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/install.py +0 -0
  129. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/language.py +0 -0
  130. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/list.py +0 -0
  131. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
  132. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/run.py +0 -0
  133. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/self_update.py +0 -0
  134. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/types.py +0 -0
  135. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
  136. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
  137. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/console.py +0 -0
  138. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/hints.py +0 -0
  139. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/i18n/__init__.py +0 -0
  140. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/i18n/locales/__init__.py +0 -0
  141. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/i18n/locales/en.py +0 -0
  142. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/i18n/locales/ja.py +0 -0
  143. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/i18n/locales/ru.py +0 -0
  144. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/i18n/locales/zh_cn.py +0 -0
  145. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/i18n/locales/zh_tw.py +0 -0
  146. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/registry.py +0 -0
  147. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/utils/__init__.py +0 -0
  148. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/utils/display.py +0 -0
  149. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/utils/file_watcher.py +0 -0
  150. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/CLI/utils/package_manager.py +0 -0
  151. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/client.py +0 -0
  152. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/errors.py +0 -0
  153. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/kv_builder.py +0 -0
  154. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/manager.py +0 -0
  155. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/router.py +0 -0
  156. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/send_builder.py +0 -0
  157. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/send_rules.py +0 -0
  158. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/storage.py +0 -0
  159. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Bases/websocket.py +0 -0
  160. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/__init__.py +0 -0
  161. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/base.py +0 -0
  162. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/command.py +0 -0
  163. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/message.py +0 -0
  164. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/message_builder.py +0 -0
  165. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/meta.py +0 -0
  166. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/notice.py +0 -0
  167. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/Event/request.py +0 -0
  168. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/assets/__init__.py +0 -0
  169. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/assets/error.css +0 -0
  170. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/assets/error.html +0 -0
  171. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/assets/root.css +0 -0
  172. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/assets/root.html +0 -0
  173. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/client.py +0 -0
  174. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/i18n/__init__.py +0 -0
  175. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/i18n/constants.py +0 -0
  176. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/i18n/locales/__init__.py +0 -0
  177. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/lifecycle.py +0 -0
  178. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/logger.py +0 -0
  179. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/master.py +0 -0
  180. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/router.py +0 -0
  181. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/Core/storage.py +0 -0
  182. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/__init__.py +0 -0
  183. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/__main__.py +0 -0
  184. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/finders/__init__.py +0 -0
  185. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/finders/adapter.py +0 -0
  186. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/finders/bases/__init__.py +0 -0
  187. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/finders/bases/finder.py +0 -0
  188. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/finders/module.py +0 -0
  189. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/loaders/__init__.py +0 -0
  190. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/loaders/bases/__init__.py +0 -0
  191. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/loaders/bases/loader.py +0 -0
  192. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/loaders/strategy.py +0 -0
  193. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/loaders/strict.py +0 -0
  194. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/py.typed +0 -0
  195. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/runtime/context.py +0 -0
  196. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/runtime/exceptions.py +0 -0
  197. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/runtime/frame_config.py +0 -0
  198. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/runtime/hints.py +0 -0
  199. {erispulse-2.6.3.dev0 → erispulse-2.7.0.dev3}/src/ErisPulse/runtime/tasks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ErisPulse
3
- Version: 2.6.3.dev0
3
+ Version: 2.7.0.dev3
4
4
  Summary: Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署
5
5
  Project-URL: Homepage, https://github.com/ErisPulse/ErisPulse
6
6
  Project-URL: Documentation, https://www.erisdev.com#docs
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "ErisPulse"
7
- version = "2.6.3-dev.0"
7
+ version = "2.7.0-dev.3"
8
8
  description = "Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署"
9
9
  readme = "README.pypi.md"
10
10
  requires-python = ">=3.10"
@@ -63,9 +63,8 @@ _MODULE_INIT = """from .Core import Main
63
63
  """
64
64
 
65
65
  _MODULE_CORE = """from dataclasses import dataclass, field
66
- from ErisPulse.Core.Bases import BaseModule
66
+ from ErisPulse.Core.Bases import BaseConfig, BaseI18n, BaseModule, I18nKey
67
67
  from ErisPulse.Core.Event import command, message, notice
68
- from ErisPulse.runtime.config_schema import BaseConfig
69
68
 
70
69
 
71
70
  @dataclass
@@ -79,6 +78,20 @@ class {name}Config(BaseConfig):
79
78
  )
80
79
 
81
80
 
81
+ class {name}I18n(BaseI18n):
82
+ \"\"\"{name} 模块翻译键声明
83
+
84
+ 声明的翻译键会被框架自动注册到 i18n 系统。
85
+ 键路径自动生成为: <模块名>.<属性名>
86
+ \"\"\"
87
+ # 示例:取消注释并修改以启用
88
+ # welcome: I18nKey = I18nKey(
89
+ # default="Welcome to {name}!",
90
+ # zh_CN="欢迎使用 {name}!",
91
+ # en="Welcome to {name}!",
92
+ # )
93
+
94
+
82
95
  class Main(BaseModule):
83
96
  \"\"\"
84
97
  {name}模块
@@ -87,6 +100,7 @@ class Main(BaseModule):
87
100
  \"\"\"
88
101
 
89
102
  ConfigClass = {name}Config
103
+ I18nClass = {name}I18n
90
104
 
91
105
  def __init__(self, sdk=None):
92
106
  from ErisPulse import sdk as _sdk
@@ -179,7 +193,7 @@ _ADAPTER_CORE = """import asyncio
179
193
  import json
180
194
  from dataclasses import dataclass, field
181
195
  from ErisPulse.Core import BaseAdapter
182
- from ErisPulse.runtime.config_schema import BaseConfig
196
+ from ErisPulse.Core.Bases import BaseConfig, I18nKey, I18nKeys
183
197
  from ErisPulse.Core import router
184
198
 
185
199
 
@@ -205,6 +219,31 @@ class {name}Config(BaseConfig):
205
219
  )
206
220
 
207
221
 
222
+ class {name}I18n(BaseI18n):
223
+ \"\"\"{name} 适配器翻译键声明
224
+
225
+ 声明的翻译键会被框架自动注册到 i18n 系统。
226
+ 这里集中管理适配器用到的所有翻译键(含配置描述引用的键)。
227
+ \"\"\"
228
+ # 注册配置描述中引用的 i18n 键的多语言译文
229
+ endpoint: I18nKey = I18nKey(
230
+ default="Platform API Endpoint",
231
+ zh_CN="平台 API 地址",
232
+ en="Platform API Endpoint",
233
+ ja="APIアドレス",
234
+ ru="API адрес",
235
+ zh_TW="API 位址",
236
+ )
237
+ token: I18nKey = I18nKey(
238
+ default="Platform Token",
239
+ zh_CN="平台 Token",
240
+ en="Platform Token",
241
+ ja="トークン",
242
+ ru="Токен",
243
+ zh_TW="權杖",
244
+ )
245
+
246
+
208
247
  class {name}(BaseAdapter):
209
248
  \"\"\"
210
249
  {name} 适配器
@@ -214,6 +253,7 @@ class {name}(BaseAdapter):
214
253
  \"\"\"
215
254
 
216
255
  ConfigClass = {name}Config
256
+ I18nClass = {name}I18n
217
257
 
218
258
  def __init__(self, sdk=None):
219
259
  super().__init__()
@@ -299,6 +339,21 @@ class {name}(BaseAdapter):
299
339
  "message": result.get("message", ""),
300
340
  }}
301
341
 
342
+ class Api(BaseAdapter.Api):
343
+ \"\"\"
344
+ 标准 API 动作 DSL
345
+
346
+ 提供跨平台的 OneBot12 标准动作(信息查询/群管理/消息管理/文件操作)。
347
+ 默认实现委托给 call_api,适配器可覆盖单个方法映射到平台原生 API。
348
+ 平台扩展动作通过 call("prefix.action", **params) 调用。
349
+ \"\"\"
350
+
351
+ # 标准方法(get_user_info / get_group_info / delete_message 等)已从基类继承,
352
+ # 默认委托给 call_api。如需平台特定逻辑,可覆盖单个方法:
353
+ # async def get_user_info(self, user_id: str) -> dict:
354
+ # raw = await self._adapter._request("GET", f"/users/{{user_id}}")
355
+ # return self._adapter.make_response(data={{...}}, raw=raw)
356
+
302
357
  async def start(self):
303
358
  \"\"\"启动适配器\"\"\"
304
359
  cfg = self.cfg
@@ -4,7 +4,7 @@ ErisPulse 基础模块
4
4
  提供平台适配器、模块、存储后端、路由和客户端的基类与抽象接口
5
5
  """
6
6
 
7
- from .adapter import SendDSL, RequestDSL, BaseAdapter
7
+ from .adapter import ApiDSL, SendDSL, RequestDSL, BaseAdapter
8
8
  from .send_rules import SendContext
9
9
  from .send_builder import SendBuilder, BatchContext
10
10
  from .module import BaseModule
@@ -23,21 +23,42 @@ from .websocket import WebSocketConnectionBase, WSMessage
23
23
  from .router import HttpRequest, WebSocketConnection, SseEmitter
24
24
  from .client import BaseHttpClient, BaseHttpResponse, BaseClientWebSocket
25
25
 
26
+ # 配置 / i18n Schema 类型
27
+ from .config_schema import (
28
+ AdapterConfig,
29
+ BaseConfig,
30
+ BotAccountConfig,
31
+ )
32
+ from .i18n_schema import (
33
+ BaseI18n,
34
+ I18nKey,
35
+ key,
36
+ )
37
+
26
38
  __all__ = [
39
+ # 配置 Schema 别名(= BaseConfig)
40
+ "AdapterConfig",
41
+ "ApiDSL",
27
42
  "BaseAdapter",
28
43
  "BaseClientWebSocket",
44
+ "BaseConfig",
29
45
  "BaseHttpClient",
30
46
  "BaseHttpResponse",
47
+ # i18n 键声明 Schema 基类(命名对齐 BaseConfig)
48
+ "BaseI18n",
31
49
  "BaseModule",
32
50
  "BaseQueryBuilder",
33
51
  "BaseStorage",
34
52
  "BatchContext",
53
+ "BotAccountConfig",
35
54
  "ClientConnectionError",
36
55
  "ClientError",
37
56
  "ClientTimeoutError",
38
57
  "ErisPulseError",
39
58
  "HTTPStatusError",
40
59
  "HttpRequest",
60
+ # i18n 单键声明
61
+ "I18nKey",
41
62
  "KVQueryBuilder",
42
63
  "RequestDSL",
43
64
  "SendBuilder",
@@ -949,6 +949,326 @@ class RequestDSL:
949
949
  }
950
950
 
951
951
 
952
+ class ApiDSL:
953
+ """
954
+ 标准 API 动作 DSL 基类
955
+
956
+ 提供 OneBot12 标准动作(get_user_info / get_group_info 等)的强类型方法,
957
+ 模块开发者只需面向标准接口编程,由适配器负责映射到平台原生 API。
958
+
959
+ 与 SendDSL(消息发送)、RequestDSL(请求操作)并行,覆盖 OneBot12
960
+ 标准动作中的「信息查询 / 状态变更 / 消息管理 / 文件操作」四类操作。
961
+
962
+ {!--< tips >!--}
963
+ 1. 标准方法默认委托给 ``adapter.call_api(action_name, ...)``,适配器可按需覆盖
964
+ 2. 使用 ``adapter.Api.Using("bot1").get_user_info("123")`` 指定 Bot 账号
965
+ 3. 平台扩展动作通过 ``call("prefix.action", **params)`` 调用
966
+ 4. 所有方法返回标准 API 响应格式(status / retcode / data / message_id / message)
967
+ 5. 适配器可覆盖单个标准方法以映射到平台 API,无需全部实现
968
+ {!--< /tips >!--}
969
+ """
970
+
971
+ def __init__(
972
+ self,
973
+ adapter: "BaseAdapter",
974
+ account_id: str | None = None,
975
+ ):
976
+ """
977
+ 初始化标准 API 动作 DSL
978
+
979
+ :param adapter: 所属适配器实例
980
+ :param account_id: 执行操作的 Bot 账号(可选)
981
+ """
982
+ self._adapter = adapter
983
+ self._account_id = account_id
984
+
985
+ def Using(self, account_id: str | int) -> "Self":
986
+ """
987
+ 指定执行操作的 Bot 账号
988
+
989
+ :param account_id: 账号标识
990
+ :return: 新的 ApiDSL 实例
991
+
992
+ :example:
993
+ >>> info = await adapter.myplatform.Api.Using("bot1").get_user_info("123")
994
+ """
995
+ return self.__class__(self._adapter, str(account_id))
996
+
997
+ @property
998
+ def api_context(self) -> dict:
999
+ """
1000
+ 获取当前 API 操作上下文
1001
+
1002
+ :return: 包含 account_id 的字典
1003
+ """
1004
+ return {
1005
+ "account_id": self._account_id,
1006
+ }
1007
+
1008
+ def _merge_context(self, params: dict) -> dict:
1009
+ """
1010
+ 将 api_context 合并到参数字典
1011
+
1012
+ :param params: 业务参数
1013
+ :return: 合并后的参数字典
1014
+ """
1015
+ merged = dict(params)
1016
+ merged.update(self.api_context)
1017
+ return merged
1018
+
1019
+ # ==================== 用户相关动作 ====================
1020
+
1021
+ async def get_self_info(self) -> dict[str, Any]:
1022
+ """
1023
+ 获取机器人自身信息
1024
+
1025
+ :return: 标准响应,data 包含 user_id / user_name / user_displayname
1026
+
1027
+ :example:
1028
+ >>> result = await adapter.myplatform.Api.get_self_info()
1029
+ >>> my_name = result["data"]["user_name"]
1030
+ """
1031
+ return await self._adapter.call_api(
1032
+ "get_self_info", **self._merge_context({})
1033
+ )
1034
+
1035
+ async def get_user_info(self, user_id: str) -> dict[str, Any]:
1036
+ """
1037
+ 获取用户信息
1038
+
1039
+ :param user_id: 用户 ID(可以是好友,也可以是陌生人)
1040
+ :return: 标准响应,data 包含 user_id / user_name / user_displayname / user_remark
1041
+
1042
+ :example:
1043
+ >>> result = await adapter.myplatform.Api.get_user_info("123456")
1044
+ >>> user_name = result["data"]["user_name"]
1045
+ """
1046
+ return await self._adapter.call_api(
1047
+ "get_user_info", **self._merge_context({"user_id": str(user_id)})
1048
+ )
1049
+
1050
+ async def get_friend_list(self) -> dict[str, Any]:
1051
+ """
1052
+ 获取好友列表
1053
+
1054
+ :return: 标准响应,data 为好友信息列表
1055
+
1056
+ :example:
1057
+ >>> result = await adapter.myplatform.Api.get_friend_list()
1058
+ >>> friends = result["data"]
1059
+ """
1060
+ return await self._adapter.call_api(
1061
+ "get_friend_list", **self._merge_context({})
1062
+ )
1063
+
1064
+ # ==================== 群组相关动作 ====================
1065
+
1066
+ async def get_group_info(self, group_id: str) -> dict[str, Any]:
1067
+ """
1068
+ 获取群信息
1069
+
1070
+ :param group_id: 群 ID
1071
+ :return: 标准响应,data 包含 group_id / group_name
1072
+
1073
+ :example:
1074
+ >>> result = await adapter.myplatform.Api.get_group_info("123456")
1075
+ >>> group_name = result["data"]["group_name"]
1076
+ """
1077
+ return await self._adapter.call_api(
1078
+ "get_group_info", **self._merge_context({"group_id": str(group_id)})
1079
+ )
1080
+
1081
+ async def get_group_list(self) -> dict[str, Any]:
1082
+ """
1083
+ 获取群列表
1084
+
1085
+ :return: 标准响应,data 为群信息列表
1086
+
1087
+ :example:
1088
+ >>> result = await adapter.myplatform.Api.get_group_list()
1089
+ >>> groups = result["data"]
1090
+ """
1091
+ return await self._adapter.call_api(
1092
+ "get_group_list", **self._merge_context({})
1093
+ )
1094
+
1095
+ async def get_group_member_info(
1096
+ self, group_id: str, user_id: str
1097
+ ) -> dict[str, Any]:
1098
+ """
1099
+ 获取群成员信息
1100
+
1101
+ :param group_id: 群 ID
1102
+ :param user_id: 用户 ID
1103
+ :return: 标准响应,data 包含 user_id / user_name / user_displayname
1104
+
1105
+ :example:
1106
+ >>> result = await adapter.myplatform.Api.get_group_member_info("123", "456")
1107
+ >>> member = result["data"]
1108
+ """
1109
+ return await self._adapter.call_api(
1110
+ "get_group_member_info",
1111
+ **self._merge_context({"group_id": str(group_id), "user_id": str(user_id)})
1112
+ )
1113
+
1114
+ async def get_group_member_list(self, group_id: str) -> dict[str, Any]:
1115
+ """
1116
+ 获取群成员列表
1117
+
1118
+ :param group_id: 群 ID
1119
+ :return: 标准响应,data 为群成员信息列表
1120
+
1121
+ :example:
1122
+ >>> result = await adapter.myplatform.Api.get_group_member_list("123456")
1123
+ >>> members = result["data"]
1124
+ """
1125
+ return await self._adapter.call_api(
1126
+ "get_group_member_list",
1127
+ **self._merge_context({"group_id": str(group_id)})
1128
+ )
1129
+
1130
+ async def set_group_name(self, group_id: str, group_name: str) -> dict[str, Any]:
1131
+ """
1132
+ 设置群名称
1133
+
1134
+ :param group_id: 群 ID
1135
+ :param group_name: 新群名称
1136
+ :return: 标准响应
1137
+
1138
+ :example:
1139
+ >>> await adapter.myplatform.Api.set_group_name("123456", "新群名")
1140
+ """
1141
+ return await self._adapter.call_api(
1142
+ "set_group_name",
1143
+ **self._merge_context({"group_id": str(group_id), "group_name": group_name})
1144
+ )
1145
+
1146
+ async def leave_group(self, group_id: str) -> dict[str, Any]:
1147
+ """
1148
+ 退出群
1149
+
1150
+ :param group_id: 群 ID
1151
+ :return: 标准响应
1152
+
1153
+ :example:
1154
+ >>> await adapter.myplatform.Api.leave_group("123456")
1155
+ """
1156
+ return await self._adapter.call_api(
1157
+ "leave_group", **self._merge_context({"group_id": str(group_id)})
1158
+ )
1159
+
1160
+ # ==================== 消息管理动作 ====================
1161
+
1162
+ async def delete_message(self, message_id: str) -> dict[str, Any]:
1163
+ """
1164
+ 撤回 / 删除消息
1165
+
1166
+ :param message_id: 消息 ID
1167
+ :return: 标准响应
1168
+
1169
+ :example:
1170
+ >>> await adapter.myplatform.Api.delete_message("msg_123456")
1171
+ """
1172
+ return await self._adapter.call_api(
1173
+ "delete_message",
1174
+ **self._merge_context({"message_id": str(message_id)})
1175
+ )
1176
+
1177
+ # ==================== 文件相关动作 ====================
1178
+
1179
+ async def upload_file(
1180
+ self,
1181
+ *,
1182
+ type: str,
1183
+ name: str,
1184
+ url: str | None = None,
1185
+ path: str | None = None,
1186
+ data: bytes | None = None,
1187
+ headers: dict[str, str] | None = None,
1188
+ sha256: str | None = None,
1189
+ ) -> dict[str, Any]:
1190
+ """
1191
+ 上传文件
1192
+
1193
+ :param type: 上传方式(``url`` / ``path`` / ``data``)
1194
+ :param name: 文件名(如 ``foo.jpg``)
1195
+ :param url: 文件 URL(``type="url"`` 时必须传入)
1196
+ :param path: 文件路径(``type="path"`` 时必须传入)
1197
+ :param data: 文件数据(``type="data"`` 时必须传入)
1198
+ :param headers: 下载 URL 时附加的 HTTP 请求头(可选)
1199
+ :param sha256: 文件数据的 SHA256 校验和(可选)
1200
+ :return: 标准响应,data 包含 file_id
1201
+
1202
+ :example:
1203
+ >>> result = await adapter.Api.upload_file(
1204
+ ... type="url", name="logo.jpg", url="https://example.com/logo.jpg"
1205
+ ... )
1206
+ >>> file_id = result["data"]["file_id"]
1207
+ """
1208
+ params: dict[str, Any] = {"type": type, "name": name}
1209
+ if url is not None:
1210
+ params["url"] = url
1211
+ if path is not None:
1212
+ params["path"] = path
1213
+ if data is not None:
1214
+ params["data"] = data
1215
+ if headers is not None:
1216
+ params["headers"] = headers
1217
+ if sha256 is not None:
1218
+ params["sha256"] = sha256
1219
+ return await self._adapter.call_api(
1220
+ "upload_file", **self._merge_context(params)
1221
+ )
1222
+
1223
+ async def get_file(
1224
+ self, file_id: str, type: str = "url"
1225
+ ) -> dict[str, Any]:
1226
+ """
1227
+ 获取文件
1228
+
1229
+ :param file_id: 文件 ID
1230
+ :param type: 获取方式(``url`` / ``path`` / ``data``),默认 ``url``
1231
+ :return: 标准响应,data 包含 name / url 或 path 或 data
1232
+
1233
+ :example:
1234
+ >>> result = await adapter.myplatform.Api.get_file("file_abc", "url")
1235
+ >>> download_url = result["data"]["url"]
1236
+ """
1237
+ return await self._adapter.call_api(
1238
+ "get_file",
1239
+ **self._merge_context({"file_id": str(file_id), "type": type})
1240
+ )
1241
+
1242
+ # ==================== 通用扩展动作 ====================
1243
+
1244
+ async def call(self, action: str, **params: Any) -> dict[str, Any]:
1245
+ """
1246
+ 调用平台扩展动作(逃生舱)
1247
+
1248
+ 用于调用 OneBot12 标准之外的平台扩展动作。
1249
+ 建议使用 ``{prefix}.{action}`` 命名(如 ``telegram.send_sticker``),
1250
+ 遵循 OneBot12 扩展规则。
1251
+
1252
+ :param action: 动作名称(标准动作名或 ``{prefix}.{action}`` 扩展动作名)
1253
+ :param params: 动作参数
1254
+ :return: 标准响应格式
1255
+
1256
+ :example:
1257
+ >>> # 调用平台扩展动作
1258
+ >>> result = await adapter.myplatform.Api.call(
1259
+ ... "telegram.send_sticker", sticker_id="CAACAgIAAxkBAA..."
1260
+ ... )
1261
+ >>>
1262
+ >>> # 也可用于调用标准动作(等价于直接调用对应方法)
1263
+ >>> result = await adapter.myplatform.Api.call(
1264
+ ... "get_user_info", user_id="123"
1265
+ ... )
1266
+ """
1267
+ return await self._adapter.call_api(
1268
+ action, **self._merge_context(params)
1269
+ )
1270
+
1271
+
952
1272
  class BaseAdapter(ABC):
953
1273
  """
954
1274
  适配器基类
@@ -965,11 +1285,14 @@ class BaseAdapter(ABC):
965
1285
  7. 通过 self.cfg / self.accounts 访问类型安全的配置对象(实时读取)
966
1286
  8. 通过 self.emit_meta() 发送 meta 事件
967
1287
  9. 通过 self.make_response() / self.make_error() 构造标准化响应
1288
+ 10. 通过 I18nClass 声明翻译键集合,框架自动注册到 i18n 系统
968
1289
  {!--< /tips >!--}
969
1290
  """
970
1291
 
971
1292
  ConfigClass: type | None = None
972
1293
  AccountConfigClass: type | None = None
1294
+ I18nClass: type | None = None
1295
+ EventMixin: type | None = None
973
1296
 
974
1297
  _platform: str = ""
975
1298
  _sdk: Any = None
@@ -991,6 +1314,22 @@ class BaseAdapter(ABC):
991
1314
 
992
1315
  ...
993
1316
 
1317
+ class Api(ApiDSL):
1318
+ """
1319
+ 标准 API 动作 DSL 实现
1320
+
1321
+ 提供跨平台的 OneBot12 标准动作接口(信息查询、群管理、消息撤回、文件操作等)。
1322
+
1323
+ {!--< tips >!--}
1324
+ 1. 默认实现委托给 ``adapter.call_api(action_name, ...)``,零配置可用
1325
+ 2. 适配器可覆盖单个标准方法以映射到平台原生 API
1326
+ 3. 平台扩展动作通过 ``call("prefix.action", **params)`` 调用
1327
+ 4. 使用 ``adapter.Api.Using("bot1")`` 指定 Bot 账号
1328
+ {!--< /tips >!--}
1329
+ """
1330
+
1331
+ ...
1332
+
994
1333
  class Send(SendDSL):
995
1334
  """
996
1335
  消息发送DSL实现
@@ -1098,13 +1437,19 @@ class BaseAdapter(ABC):
1098
1437
  self.sdk = sdk
1099
1438
  self.logger = sdk.logger.get_child(self.__class__.__name__, relative=False)
1100
1439
 
1101
- # Send/Request 在类上是 type[SendDSL],实例化后替换为实例。pyright 无法识别这种“实例属性覆盖嵌套类属性”的模式,故显式 cast。
1440
+ # Send/Request/Api 在类上是嵌套类,实例化后替换为实例。
1441
+ # pyright 无法识别这种"实例属性覆盖嵌套类属性"的模式,故显式 cast。
1102
1442
  self.Send = cast("SendDSL", self.__class__.Send(self)) # pyright: ignore[reportAttributeAccessIssue]
1103
1443
  self.Request = cast("RequestDSL", self.__class__.Request(self)) # pyright: ignore[reportAttributeAccessIssue]
1444
+ self.Api = cast("ApiDSL", self.__class__.Api(self)) # pyright: ignore[reportAttributeAccessIssue]
1104
1445
 
1105
1446
  self._config_instance = None
1106
1447
  self._accounts_data = None
1107
1448
 
1449
+ # 注册 I18nClass 中声明的翻译键(在生成配置之前)
1450
+ self._ensure_i18n_registered()
1451
+ # EventMixin 的注册由 AdapterManager 在注入 _platform 后调用
1452
+
1108
1453
  # 初始化时确保配置模板存在
1109
1454
  if self.ConfigClass is not None:
1110
1455
  self._ensure_config_exists()
@@ -1196,8 +1541,11 @@ class BaseAdapter(ABC):
1196
1541
  "未声明 ConfigClass,请设置 MyAdapter.ConfigClass = MyConfig"
1197
1542
  )
1198
1543
 
1199
- from ...runtime.config_schema import dict_to_dataclass
1200
1544
  from ..config import config as config_mgr
1545
+ from .config_schema import dict_to_dataclass
1546
+
1547
+ # 适配器的 EventMixin 在 AdapterManager.register() 注入 _platform 后注册
1548
+ # __init__ 阶段 _platform 尚未注入,因此不在此处调用
1201
1549
 
1202
1550
  data = config_mgr.getConfig(self._get_config_key())
1203
1551
  if data is None:
@@ -1248,8 +1596,8 @@ class BaseAdapter(ABC):
1248
1596
  "未声明 AccountConfigClass,请设置 MyAdapter.AccountConfigClass = MyBotConfig"
1249
1597
  )
1250
1598
 
1251
- from ...runtime.config_schema import dict_to_dataclass, validate_config
1252
1599
  from ..config import config as config_mgr
1600
+ from .config_schema import dict_to_dataclass, validate_config
1253
1601
 
1254
1602
  key = f"{self._get_config_key()}.accounts"
1255
1603
  data = config_mgr.getConfig(key)
@@ -1334,15 +1682,20 @@ class BaseAdapter(ABC):
1334
1682
  确保全局配置模板存在,不存在则生成默认配置
1335
1683
 
1336
1684
  {!--< internal-use >!--}
1685
+ 会先行调用 _ensure_i18n_registered() 注册声明的翻译键,
1686
+ 确保配置描述引用的 i18n 键在生成模板时已可用。
1337
1687
  {!--< /internal-use >!--}
1338
1688
  """
1689
+ # 先行注册 i18n 键(在生成配置之前),保证配置描述中的 i18n 键可用
1690
+ self._ensure_i18n_registered()
1691
+
1339
1692
  if self.ConfigClass is None:
1340
1693
  return
1341
- from ...runtime.config_schema import (
1694
+ from ..config import config as config_mgr
1695
+ from .config_schema import (
1342
1696
  dataclass_to_defaults_dict,
1343
1697
  dataclass_to_toml_with_comments,
1344
1698
  )
1345
- from ..config import config as config_mgr
1346
1699
 
1347
1700
  key = self._get_config_key()
1348
1701
  data = config_mgr.getConfig(key)
@@ -1353,6 +1706,63 @@ class BaseAdapter(ABC):
1353
1706
  config_mgr.setConfig(key, data, immediate=True)
1354
1707
  self._get_logger().info(f"已生成 {key} 默认配置模板:\n{toml_str}")
1355
1708
 
1709
+ def _ensure_i18n_registered(self):
1710
+ """
1711
+ 注册 I18nClass 中声明的翻译键到 i18n 系统
1712
+
1713
+ 使用适配器配置键名(默认为类名)作为键名前缀和 domain,便于统一卸载。
1714
+ 方法是幂等的,多次调用不会产生副作用(重复注册会覆盖旧值)。
1715
+
1716
+ {!--< internal-use >!--}
1717
+ 由 __init__() 在生成配置之前隐式调用。
1718
+ {!--< /internal-use >!--}
1719
+ """
1720
+ if self.I18nClass is None:
1721
+ return
1722
+ from .i18n_schema import BaseI18n
1723
+
1724
+ if not isinstance(self.I18nClass, type) or not issubclass(self.I18nClass, BaseI18n):
1725
+ # 非法声明静默跳过(避免影响适配器初始化流程)
1726
+ return
1727
+
1728
+ prefix = f"{self._get_config_key()}."
1729
+ domain = self._get_config_key()
1730
+ try:
1731
+ self.I18nClass.register(prefix=prefix, domain=domain)
1732
+ except Exception:
1733
+ # i18n 注册失败不应中断适配器初始化
1734
+ self._get_logger().debug(
1735
+ f"{self.__class__.__name__}.I18nClass.register() 失败",
1736
+ exc_info=True,
1737
+ )
1738
+
1739
+ def _ensure_event_mixin_registered(self):
1740
+ """
1741
+ 注册 EventMixin 中声明的事件扩展方法
1742
+
1743
+ 适配器声明 ``EventMixin`` 时,框架自动将其注册到适配器的平台
1744
+ (即 ``self._platform``),而不是通配符。
1745
+
1746
+ {!--< internal-use >!--}
1747
+ 由 __init__() 隐式调用。
1748
+ {!--< /internal-use >!--}
1749
+ """
1750
+ if self.EventMixin is None:
1751
+ return
1752
+ if not isinstance(self.EventMixin, type):
1753
+ return
1754
+
1755
+ from ..Event import register_event_mixin
1756
+
1757
+ platform = self._platform or "*"
1758
+ try:
1759
+ register_event_mixin(platform, self.EventMixin)
1760
+ except Exception:
1761
+ self._get_logger().debug(
1762
+ f"{self.__class__.__name__}.EventMixin 注册失败",
1763
+ exc_info=True,
1764
+ )
1765
+
1356
1766
  def _ensure_accounts_exist(self):
1357
1767
  """
1358
1768
  确保多账户配置模板存在,不存在则生成默认账户配置
@@ -1362,8 +1772,8 @@ class BaseAdapter(ABC):
1362
1772
  """
1363
1773
  if self.AccountConfigClass is None:
1364
1774
  return
1365
- from ...runtime.config_schema import dataclass_to_defaults_dict
1366
1775
  from ..config import config as config_mgr
1776
+ from .config_schema import dataclass_to_defaults_dict
1367
1777
 
1368
1778
  key = f"{self._get_config_key()}.accounts"
1369
1779
  data = config_mgr.getConfig(key)
@@ -1553,6 +1963,7 @@ class BaseAdapter(ABC):
1553
1963
 
1554
1964
 
1555
1965
  __all__ = [
1966
+ "ApiDSL",
1556
1967
  "BaseAdapter",
1557
1968
  "RequestDSL",
1558
1969
  "SendDSL",