ErisPulse 2.5.2.dev4__tar.gz → 2.5.4__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.
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/PKG-INFO +2 -2
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/pyproject.toml +5 -2
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/create.py +39 -27
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/adapter.py +147 -57
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/adapter.pyi +31 -29
- erispulse-2.5.4/src/ErisPulse/Core/Bases/module.py +216 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/module.pyi +46 -1
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/wrapper.py +96 -15
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/wrapper.pyi +50 -21
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/adapter.py +22 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/constants.py +37 -39
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/constants.pyi +2 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/en.py +4 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/ja.py +4 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/ru.py +4 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/zh_cn.py +4 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/zh_tw.py +4 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/module.py +3 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/router.py +7 -1
- erispulse-2.5.4/src/ErisPulse/py.typed +4 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/__init__.py +8 -2
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/__init__.pyi +1 -1
- erispulse-2.5.4/src/ErisPulse/runtime/config_schema.py +624 -0
- erispulse-2.5.4/src/ErisPulse/runtime/config_schema.pyi +287 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/exceptions.py +14 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/exceptions.pyi +1 -1
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/hints.py +36 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/hints.pyi +26 -0
- erispulse-2.5.2.dev4/src/ErisPulse/Core/Bases/module.py +0 -118
- erispulse-2.5.2.dev4/src/ErisPulse/runtime/config_schema.py +0 -344
- erispulse-2.5.2.dev4/src/ErisPulse/runtime/config_schema.pyi +0 -136
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/.gitignore +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/LICENSE +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/README.md +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/base.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/base.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/cli.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/cli.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/create.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/init.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/init.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/install.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/install.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/language.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/language.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/list.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/list.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/list_remote.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/list_remote.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/run.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/run.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/self_update.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/self_update.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/uninstall.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/uninstall.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/upgrade.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/commands/upgrade.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/console.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/console.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/en.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/en.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/ja.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/ja.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/ru.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/ru.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/zh_cn.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/zh_cn.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/zh_tw.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/i18n/locales/zh_tw.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/registry.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/registry.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/utils/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/utils/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/utils/display.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/utils/display.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/utils/file_watcher.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/utils/file_watcher.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/utils/package_manager.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/CLI/utils/package_manager.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/client.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/client.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/errors.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/errors.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/kv_builder.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/kv_builder.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/manager.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/manager.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/router.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/router.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/storage.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/storage.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/websocket.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Bases/websocket.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/base.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/base.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/command.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/command.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/message.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/message.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/message_builder.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/message_builder.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/meta.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/meta.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/notice.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/notice.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/request.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/request.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/session_type.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/Event/session_type.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/adapter.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/client.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/client.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/config.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/config.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/constants.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/constants.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/en.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/ja.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/ru.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/zh_cn.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/i18n/locales/zh_tw.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/lifecycle.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/lifecycle.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/logger.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/logger.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/module.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/router.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/storage.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/Core/storage.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/__main__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/__main__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/adapter.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/adapter.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/bases/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/bases/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/bases/finder.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/bases/finder.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/module.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/finders/module.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/adapter.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/adapter.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/bases/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/bases/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/bases/loader.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/bases/loader.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/module.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/module.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/strategy.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/strategy.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/strict.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/loaders/strict.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/context.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/context.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/frame_config.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/runtime/frame_config.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/sdk.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/sdk.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/web_status/4xx.png +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/web_status/5xx.png +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/web_status/__init__.py +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/web_status/__init__.pyi +0 -0
- {erispulse-2.5.2.dev4 → erispulse-2.5.4}/src/ErisPulse/web_status/unknow.png +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ErisPulse
|
|
3
|
-
Version: 2.5.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 2.5.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
|
|
7
7
|
Project-URL: Repository, https://github.com/ErisPulse/ErisPulse
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ErisPulse"
|
|
7
|
-
version = "2.5.
|
|
8
|
-
description = "
|
|
7
|
+
version = "2.5.4"
|
|
8
|
+
description = "Event-driven modular async bot framework — write once, deploy to any platform | 事件驱动的模块化异步机器人框架,一次编写,多平台部署"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
11
11
|
license = { file = "LICENSE" }
|
|
@@ -105,6 +105,9 @@ project.root = "src"
|
|
|
105
105
|
[tool.hatch.build.targets.wheel]
|
|
106
106
|
packages = ["src/ErisPulse"]
|
|
107
107
|
|
|
108
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
109
|
+
"src/ErisPulse/py.typed" = "ErisPulse/py.typed"
|
|
110
|
+
|
|
108
111
|
[tool.hatch.build.targets.sdist]
|
|
109
112
|
include = [
|
|
110
113
|
"/src/ErisPulse",
|
|
@@ -62,8 +62,21 @@ dependencies = [
|
|
|
62
62
|
_MODULE_INIT = """from .Core import Main
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
|
-
_MODULE_CORE = """from
|
|
65
|
+
_MODULE_CORE = """from dataclasses import dataclass, field
|
|
66
|
+
from ErisPulse.Core.Bases import BaseModule
|
|
66
67
|
from ErisPulse.Core.Event import command, message, notice
|
|
68
|
+
from ErisPulse.runtime.config_schema import BaseConfig
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass
|
|
72
|
+
class {name}Config(BaseConfig):
|
|
73
|
+
\"\"\"{name} 模块配置\"\"\"
|
|
74
|
+
enabled: bool = field(
|
|
75
|
+
default=True,
|
|
76
|
+
metadata={{
|
|
77
|
+
\"description\": \"是否启用模块\",
|
|
78
|
+
}},
|
|
79
|
+
)
|
|
67
80
|
|
|
68
81
|
|
|
69
82
|
class Main(BaseModule):
|
|
@@ -73,16 +86,17 @@ class Main(BaseModule):
|
|
|
73
86
|
继承自BaseModule基类,实现了标准化的模块生命周期管理和事件处理
|
|
74
87
|
\"\"\"
|
|
75
88
|
|
|
89
|
+
ConfigClass = {name}Config
|
|
90
|
+
|
|
76
91
|
def __init__(self, sdk=None):
|
|
77
92
|
from ErisPulse import sdk as _sdk
|
|
78
93
|
self.sdk = _sdk if sdk is None else sdk
|
|
79
|
-
self.logger = self.sdk.logger.get_child("{name}")
|
|
94
|
+
self.logger = self.sdk.logger.get_child(\"{name}\")
|
|
80
95
|
self.storage = self.sdk.storage
|
|
81
96
|
self.adapter = self.sdk.adapter
|
|
82
97
|
self.client = self.sdk.client
|
|
83
98
|
|
|
84
|
-
self.logger.info("{name}
|
|
85
|
-
self.config = self._load_config()
|
|
99
|
+
self.logger.info(\"{name} 初始化完成\")
|
|
86
100
|
|
|
87
101
|
@staticmethod
|
|
88
102
|
def get_load_strategy():
|
|
@@ -101,7 +115,7 @@ class Main(BaseModule):
|
|
|
101
115
|
\"\"\"
|
|
102
116
|
await self._register_commands()
|
|
103
117
|
await self._register_message_handlers()
|
|
104
|
-
self.logger.info(f"模块已加载: {{event}}")
|
|
118
|
+
self.logger.info(f\"模块已加载: {{event}}\")
|
|
105
119
|
return True
|
|
106
120
|
|
|
107
121
|
async def on_unload(self, event: dict) -> bool:
|
|
@@ -111,29 +125,18 @@ class Main(BaseModule):
|
|
|
111
125
|
:param event: 事件内容
|
|
112
126
|
:return: 处理结果
|
|
113
127
|
\"\"\"
|
|
114
|
-
self.logger.info(f"模块已卸载: {{event}}")
|
|
128
|
+
self.logger.info(f\"模块已卸载: {{event}}\")
|
|
115
129
|
return True
|
|
116
130
|
|
|
117
|
-
def _load_config(self):
|
|
118
|
-
config = self.sdk.config.getConfig("{name}")
|
|
119
|
-
if not config:
|
|
120
|
-
default_config = {{
|
|
121
|
-
"enabled": True,
|
|
122
|
-
}}
|
|
123
|
-
self.sdk.config.setConfig("{name}", default_config)
|
|
124
|
-
self.logger.warning("未找到模块配置, 已创建默认配置到config.toml")
|
|
125
|
-
return default_config
|
|
126
|
-
return config
|
|
127
|
-
|
|
128
131
|
async def _register_commands(self):
|
|
129
|
-
@command("hello", help
|
|
132
|
+
@command(\"hello\", help=\"发送问候消息\")
|
|
130
133
|
async def hello_command(event):
|
|
131
|
-
await event.reply("Hello from {name}
|
|
134
|
+
await event.reply(\"Hello from {name}!\")
|
|
132
135
|
|
|
133
136
|
async def _register_message_handlers(self):
|
|
134
137
|
@message.on_private_message()
|
|
135
138
|
async def private_message_handler(event):
|
|
136
|
-
self.logger.info(f"收到私聊消息: {{event.get_text()}}")
|
|
139
|
+
self.logger.info(f\"收到私聊消息: {{event.get_text()}}\")
|
|
137
140
|
|
|
138
141
|
@message.on_group_message()
|
|
139
142
|
async def group_message_handler(event):
|
|
@@ -141,7 +144,7 @@ class Main(BaseModule):
|
|
|
141
144
|
|
|
142
145
|
@notice.on_friend_add()
|
|
143
146
|
async def friend_add_handler(event):
|
|
144
|
-
self.logger.info(f"新好友添加: {{event.get_user_nickname()}}")
|
|
147
|
+
self.logger.info(f\"新好友添加: {{event.get_user_nickname()}}\")
|
|
145
148
|
"""
|
|
146
149
|
|
|
147
150
|
_ADAPTER_PYPROJECT = """[project]
|
|
@@ -176,20 +179,29 @@ _ADAPTER_CORE = """import asyncio
|
|
|
176
179
|
import json
|
|
177
180
|
from dataclasses import dataclass, field
|
|
178
181
|
from ErisPulse.Core import BaseAdapter
|
|
179
|
-
from ErisPulse.runtime.config_schema import
|
|
182
|
+
from ErisPulse.runtime.config_schema import BaseConfig
|
|
180
183
|
from ErisPulse.Core import router
|
|
181
184
|
|
|
182
185
|
|
|
183
186
|
@dataclass
|
|
184
|
-
class {name}Config(
|
|
187
|
+
class {name}Config(BaseConfig):
|
|
185
188
|
\"\"\"{name} 适配器配置\"\"\"
|
|
186
189
|
endpoint: str = field(
|
|
187
190
|
default="https://api.example.com",
|
|
188
|
-
metadata={{
|
|
191
|
+
metadata={{
|
|
192
|
+
"description": {{"i18n": "adapter.{name}.endpoint", "default": "平台 API 地址"}},
|
|
193
|
+
"required": False,
|
|
194
|
+
"ui": {{"widget": "text", "group": "connection", "order": 1}},
|
|
195
|
+
}},
|
|
189
196
|
)
|
|
190
197
|
token: str = field(
|
|
191
198
|
default="",
|
|
192
|
-
metadata={{
|
|
199
|
+
metadata={{
|
|
200
|
+
"description": {{"i18n": "adapter.{name}.token", "default": "平台 Token"}},
|
|
201
|
+
"required": True,
|
|
202
|
+
"secret": True,
|
|
203
|
+
"ui": {{"widget": "password", "group": "basic", "order": 2}},
|
|
204
|
+
}},
|
|
193
205
|
)
|
|
194
206
|
|
|
195
207
|
|
|
@@ -284,7 +296,7 @@ class {name}(BaseAdapter):
|
|
|
284
296
|
|
|
285
297
|
async def start(self):
|
|
286
298
|
\"\"\"启动适配器\"\"\"
|
|
287
|
-
cfg = self.
|
|
299
|
+
cfg = self.cfg
|
|
288
300
|
self.logger.info(f"启动 {{cfg.endpoint}} 适配器")
|
|
289
301
|
|
|
290
302
|
router.register_websocket(
|
|
@@ -322,7 +334,7 @@ class {name}(BaseAdapter):
|
|
|
322
334
|
\"\"\"调用平台 API\"\"\"
|
|
323
335
|
from ErisPulse.Core import client
|
|
324
336
|
|
|
325
|
-
cfg = self.
|
|
337
|
+
cfg = self.cfg
|
|
326
338
|
headers = {{"Authorization": "Bearer " + cfg.token}}
|
|
327
339
|
url = cfg.endpoint + endpoint
|
|
328
340
|
|
|
@@ -532,7 +532,7 @@ class BaseAdapter(ABC):
|
|
|
532
532
|
4. 通过on装饰器注册事件处理器
|
|
533
533
|
5. 支持OneBot12协议的事件处理
|
|
534
534
|
6. 通过 ConfigClass / AccountConfigClass 声明配置类,框架自动管理配置
|
|
535
|
-
7. 通过 self.
|
|
535
|
+
7. 通过 self.cfg / self.accounts 访问类型安全的配置对象(实时读取)
|
|
536
536
|
8. 通过 self.emit_meta() 发送 meta 事件
|
|
537
537
|
9. 通过 self.make_response() / self.make_error() 构造标准化响应
|
|
538
538
|
{!--< /tips >!--}
|
|
@@ -672,10 +672,45 @@ class BaseAdapter(ABC):
|
|
|
672
672
|
self._config_instance = None
|
|
673
673
|
self._accounts_data = None
|
|
674
674
|
|
|
675
|
+
# 初始化时确保配置模板存在
|
|
675
676
|
if self.ConfigClass is not None:
|
|
676
|
-
self.
|
|
677
|
+
self._ensure_config_exists()
|
|
678
|
+
# 向后兼容:子类可覆写 _load_config() 实现自定义加载
|
|
679
|
+
custom_cfg = self._load_config()
|
|
680
|
+
if custom_cfg is not None:
|
|
681
|
+
self._config_instance = custom_cfg
|
|
677
682
|
if self.AccountConfigClass is not None:
|
|
678
|
-
self.
|
|
683
|
+
self._ensure_accounts_exist()
|
|
684
|
+
# 向后兼容:子类可覆写 _load_accounts() 实现自定义加载
|
|
685
|
+
custom = self._load_accounts()
|
|
686
|
+
if custom is not None:
|
|
687
|
+
self._accounts_data = custom
|
|
688
|
+
else:
|
|
689
|
+
self._accounts_data = self.accounts
|
|
690
|
+
|
|
691
|
+
def _load_accounts(self) -> dict | None:
|
|
692
|
+
"""
|
|
693
|
+
{!--< internal-use >!--}
|
|
694
|
+
加载账户配置(可被子类覆写)
|
|
695
|
+
|
|
696
|
+
子类可覆写此方法实现自定义账户加载逻辑(如全局配置合并、旧格式迁移等)。
|
|
697
|
+
返回 None 时使用默认配置存储读取逻辑。
|
|
698
|
+
|
|
699
|
+
:return: 账户配置字典,或 None 表示使用默认逻辑
|
|
700
|
+
"""
|
|
701
|
+
return None
|
|
702
|
+
|
|
703
|
+
def _load_config(self):
|
|
704
|
+
"""
|
|
705
|
+
{!--< internal-use >!--}
|
|
706
|
+
加载适配器配置(可被子类覆写)
|
|
707
|
+
|
|
708
|
+
子类可覆写此方法实现自定义配置加载逻辑(如旧格式迁移等)。
|
|
709
|
+
返回 None 时使用默认配置存储读取逻辑。
|
|
710
|
+
|
|
711
|
+
:return: 配置实例,或 None 表示使用默认逻辑
|
|
712
|
+
"""
|
|
713
|
+
return None
|
|
679
714
|
|
|
680
715
|
@abstractmethod
|
|
681
716
|
async def call_api(self, endpoint: str, **params: Any) -> Any:
|
|
@@ -708,40 +743,117 @@ class BaseAdapter(ABC):
|
|
|
708
743
|
raise NotImplementedError("适配器必须实现shutdown方法")
|
|
709
744
|
|
|
710
745
|
@property
|
|
711
|
-
def
|
|
746
|
+
def cfg(self):
|
|
712
747
|
"""
|
|
713
|
-
|
|
748
|
+
类型安全的配置对象(实时读取)
|
|
749
|
+
|
|
750
|
+
每次访问都从配置存储读取最新值,确保用户修改配置后立即生效。
|
|
751
|
+
返回的 dataclass 实例是只读快照,修改它不会回写存储。
|
|
714
752
|
|
|
715
|
-
:return: AdapterConfig 实例
|
|
753
|
+
:return: AdapterConfig / BaseConfig 实例
|
|
716
754
|
:raises AttributeError: 未声明 ConfigClass 时抛出
|
|
755
|
+
|
|
756
|
+
{!--< tips >!--}
|
|
757
|
+
推荐使用 ``self.cfg`` 而非 ``self.config``,
|
|
758
|
+
后者已弃用且可能被子类属性覆盖产生冲突。
|
|
759
|
+
{!--< /tips >!--}
|
|
717
760
|
"""
|
|
718
|
-
if self.
|
|
761
|
+
if self.ConfigClass is None:
|
|
719
762
|
raise AttributeError(
|
|
720
763
|
"未声明 ConfigClass,请设置 MyAdapter.ConfigClass = MyConfig"
|
|
721
764
|
)
|
|
722
|
-
|
|
765
|
+
|
|
766
|
+
from ...runtime.config_schema import dict_to_dataclass
|
|
767
|
+
from ..config import config as config_mgr
|
|
768
|
+
|
|
769
|
+
data = config_mgr.getConfig(self._get_config_key())
|
|
770
|
+
if data is None:
|
|
771
|
+
# 配置不存在时生成默认模板后重试
|
|
772
|
+
self._ensure_config_exists()
|
|
773
|
+
data = config_mgr.getConfig(self._get_config_key()) or {}
|
|
774
|
+
return dict_to_dataclass(self.ConfigClass, data)
|
|
775
|
+
|
|
776
|
+
@cfg.setter
|
|
777
|
+
def cfg(self, value):
|
|
778
|
+
"""设置配置实例,同时同步写入配置存储(保证实时性)"""
|
|
779
|
+
self._config_instance = value
|
|
780
|
+
if value is not None:
|
|
781
|
+
from dataclasses import asdict
|
|
782
|
+
from ..config import config as config_mgr
|
|
783
|
+
|
|
784
|
+
try:
|
|
785
|
+
config_mgr.setConfig(self._get_config_key(), asdict(value))
|
|
786
|
+
except Exception:
|
|
787
|
+
pass
|
|
788
|
+
|
|
789
|
+
@property
|
|
790
|
+
def config(self):
|
|
791
|
+
"""
|
|
792
|
+
``self.cfg`` 的兼容别名
|
|
793
|
+
|
|
794
|
+
功能与 ``self.cfg`` 完全一致,推荐新代码使用 ``self.cfg``。
|
|
795
|
+
"""
|
|
796
|
+
return self.cfg
|
|
723
797
|
|
|
724
798
|
@config.setter
|
|
725
799
|
def config(self, value):
|
|
726
|
-
self.
|
|
800
|
+
self.cfg = value
|
|
727
801
|
|
|
728
802
|
@property
|
|
729
803
|
def accounts(self) -> dict:
|
|
730
804
|
"""
|
|
731
|
-
|
|
805
|
+
类型安全的账户配置字典(实时读取)
|
|
732
806
|
|
|
733
|
-
|
|
807
|
+
每次访问都从配置存储读取最新值,确保用户修改账户配置后立即生效。
|
|
808
|
+
|
|
809
|
+
:return: 账户配置字典 {name: config_instance}
|
|
734
810
|
:raises AttributeError: 未声明 AccountConfigClass 时抛出
|
|
735
811
|
"""
|
|
736
|
-
if self.
|
|
812
|
+
if self.AccountConfigClass is None:
|
|
737
813
|
raise AttributeError(
|
|
738
814
|
"未声明 AccountConfigClass,请设置 MyAdapter.AccountConfigClass = MyBotConfig"
|
|
739
815
|
)
|
|
740
|
-
|
|
816
|
+
|
|
817
|
+
from ...runtime.config_schema import dict_to_dataclass, validate_config
|
|
818
|
+
from ..config import config as config_mgr
|
|
819
|
+
|
|
820
|
+
key = f"{self._get_config_key()}.accounts"
|
|
821
|
+
data = config_mgr.getConfig(key)
|
|
822
|
+
if data is None:
|
|
823
|
+
# 配置不存在时生成默认账户模板后重试
|
|
824
|
+
self._ensure_accounts_exist()
|
|
825
|
+
data = config_mgr.getConfig(key) or {}
|
|
826
|
+
|
|
827
|
+
accounts = {}
|
|
828
|
+
for name, account_data in data.items():
|
|
829
|
+
if not isinstance(account_data, dict):
|
|
830
|
+
continue
|
|
831
|
+
instance = dict_to_dataclass(self.AccountConfigClass, account_data)
|
|
832
|
+
errors = validate_config(instance)
|
|
833
|
+
if errors:
|
|
834
|
+
self._get_logger().error(
|
|
835
|
+
f"账户 {name} 配置校验失败: {', '.join(errors)}"
|
|
836
|
+
)
|
|
837
|
+
continue
|
|
838
|
+
accounts[name] = instance
|
|
839
|
+
|
|
840
|
+
return accounts
|
|
741
841
|
|
|
742
842
|
@accounts.setter
|
|
743
843
|
def accounts(self, value):
|
|
844
|
+
"""设置账户配置字典,同时同步写入配置存储"""
|
|
744
845
|
self._accounts_data = value
|
|
846
|
+
if value is not None:
|
|
847
|
+
from dataclasses import asdict
|
|
848
|
+
from ..config import config as config_mgr
|
|
849
|
+
|
|
850
|
+
key = f"{self._get_config_key()}.accounts"
|
|
851
|
+
try:
|
|
852
|
+
config_mgr.setConfig(
|
|
853
|
+
key, {name: asdict(cfg) for name, cfg in value.items()}
|
|
854
|
+
)
|
|
855
|
+
except Exception:
|
|
856
|
+
pass
|
|
745
857
|
|
|
746
858
|
@property
|
|
747
859
|
def enabled_accounts(self) -> dict:
|
|
@@ -782,20 +894,18 @@ class BaseAdapter(ABC):
|
|
|
782
894
|
|
|
783
895
|
return logging.getLogger(self.__class__.__name__)
|
|
784
896
|
|
|
785
|
-
def
|
|
897
|
+
def _ensure_config_exists(self):
|
|
786
898
|
"""
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
1. 读取 {ConfigKey} 键
|
|
790
|
-
2. 如果不存在,用 dataclass 默认值生成模板并写入
|
|
791
|
-
3. 用 dict_to_dataclass() 转为类型安全的实例
|
|
899
|
+
确保全局配置模板存在,不存在则生成默认配置
|
|
792
900
|
|
|
793
|
-
|
|
901
|
+
{!--< internal-use >!--}
|
|
902
|
+
{!--< /internal-use >!--}
|
|
794
903
|
"""
|
|
904
|
+
if self.ConfigClass is None:
|
|
905
|
+
return
|
|
795
906
|
from ...runtime.config_schema import (
|
|
796
907
|
dataclass_to_defaults_dict,
|
|
797
908
|
dataclass_to_toml_with_comments,
|
|
798
|
-
dict_to_dataclass,
|
|
799
909
|
)
|
|
800
910
|
from ..config import config as config_mgr
|
|
801
911
|
|
|
@@ -808,24 +918,16 @@ class BaseAdapter(ABC):
|
|
|
808
918
|
config_mgr.setConfig(key, data, immediate=True)
|
|
809
919
|
self._get_logger().info(f"已生成 {key} 默认配置模板:\n{toml_str}")
|
|
810
920
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
def _load_accounts(self) -> dict:
|
|
921
|
+
def _ensure_accounts_exist(self):
|
|
814
922
|
"""
|
|
815
|
-
|
|
923
|
+
确保多账户配置模板存在,不存在则生成默认账户配置
|
|
816
924
|
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
3. 对每个账户做 validate_config() 校验
|
|
820
|
-
4. 跳过校验失败的账户并记录错误
|
|
821
|
-
|
|
822
|
-
:return: 账户配置字典 {name: config_instance}
|
|
925
|
+
{!--< internal-use >!--}
|
|
926
|
+
{!--< /internal-use >!--}
|
|
823
927
|
"""
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
validate_config,
|
|
828
|
-
)
|
|
928
|
+
if self.AccountConfigClass is None:
|
|
929
|
+
return
|
|
930
|
+
from ...runtime.config_schema import dataclass_to_defaults_dict
|
|
829
931
|
from ..config import config as config_mgr
|
|
830
932
|
|
|
831
933
|
key = f"{self._get_config_key()}.accounts"
|
|
@@ -837,21 +939,6 @@ class BaseAdapter(ABC):
|
|
|
837
939
|
config_mgr.setConfig(key, data, immediate=True)
|
|
838
940
|
self._get_logger().info(f"已生成 {key} 默认账户配置")
|
|
839
941
|
|
|
840
|
-
accounts = {}
|
|
841
|
-
for name, account_data in data.items():
|
|
842
|
-
if not isinstance(account_data, dict):
|
|
843
|
-
continue
|
|
844
|
-
instance = dict_to_dataclass(self.AccountConfigClass, account_data)
|
|
845
|
-
errors = validate_config(instance)
|
|
846
|
-
if errors:
|
|
847
|
-
self._get_logger().error(
|
|
848
|
-
f"账户 {name} 配置校验失败: {', '.join(errors)}"
|
|
849
|
-
)
|
|
850
|
-
continue
|
|
851
|
-
accounts[name] = instance
|
|
852
|
-
|
|
853
|
-
return accounts
|
|
854
|
-
|
|
855
942
|
def _resolve_account(self, account_id: str | None = None) -> tuple:
|
|
856
943
|
"""
|
|
857
944
|
解析目标账户
|
|
@@ -869,18 +956,21 @@ class BaseAdapter(ABC):
|
|
|
869
956
|
"""
|
|
870
957
|
from dataclasses import fields as dc_fields
|
|
871
958
|
|
|
959
|
+
# 单账户适配器(未声明 AccountConfigClass 或未填充 _accounts_data)
|
|
872
960
|
if self._accounts_data is None:
|
|
873
|
-
|
|
961
|
+
return None, None
|
|
962
|
+
|
|
963
|
+
accounts = self._accounts_data
|
|
874
964
|
|
|
875
965
|
if account_id is not None:
|
|
876
|
-
if account_id in
|
|
877
|
-
return account_id,
|
|
966
|
+
if account_id in accounts:
|
|
967
|
+
return account_id, accounts[account_id]
|
|
878
968
|
|
|
879
|
-
for name, cfg in
|
|
969
|
+
for name, cfg in accounts.items():
|
|
880
970
|
if hasattr(cfg, "bot_id") and cfg.bot_id == account_id:
|
|
881
971
|
return name, cfg
|
|
882
972
|
|
|
883
|
-
for name, cfg in
|
|
973
|
+
for name, cfg in accounts.items():
|
|
884
974
|
for f in dc_fields(cfg):
|
|
885
975
|
if f.name in ("enabled", "name"):
|
|
886
976
|
continue
|
|
@@ -888,7 +978,7 @@ class BaseAdapter(ABC):
|
|
|
888
978
|
if isinstance(val, str) and val == account_id:
|
|
889
979
|
return name, cfg
|
|
890
980
|
|
|
891
|
-
for name, cfg in
|
|
981
|
+
for name, cfg in accounts.items():
|
|
892
982
|
if cfg.enabled:
|
|
893
983
|
return name, cfg
|
|
894
984
|
|
|
@@ -315,7 +315,7 @@ class BaseAdapter(ABC):
|
|
|
315
315
|
4. 通过on装饰器注册事件处理器
|
|
316
316
|
5. 支持OneBot12协议的事件处理
|
|
317
317
|
6. 通过 ConfigClass / AccountConfigClass 声明配置类,框架自动管理配置
|
|
318
|
-
7. 通过 self.
|
|
318
|
+
7. 通过 self.cfg / self.accounts 访问类型安全的配置对象(实时读取)
|
|
319
319
|
8. 通过 self.emit_meta() 发送 meta 事件
|
|
320
320
|
9. 通过 self.make_response() / self.make_error() 构造标准化响应
|
|
321
321
|
{!--< /tips >!--}
|
|
@@ -350,25 +350,50 @@ class BaseAdapter(ABC):
|
|
|
350
350
|
:raises NotImplementedError: 必须由子类实现
|
|
351
351
|
"""
|
|
352
352
|
...
|
|
353
|
-
def
|
|
353
|
+
def cfg(self: object) -> ...:
|
|
354
354
|
"""
|
|
355
|
-
|
|
355
|
+
类型安全的配置对象(实时读取)
|
|
356
|
+
|
|
357
|
+
每次访问都从配置存储读取最新值,确保用户修改配置后立即生效。
|
|
358
|
+
返回的 dataclass 实例是只读快照,修改它不会回写存储。
|
|
356
359
|
|
|
357
|
-
:return: AdapterConfig 实例
|
|
360
|
+
:return: AdapterConfig / BaseConfig 实例
|
|
358
361
|
:raises AttributeError: 未声明 ConfigClass 时抛出
|
|
362
|
+
|
|
363
|
+
{!--< tips >!--}
|
|
364
|
+
推荐使用 ``self.cfg`` 而非 ``self.config``,
|
|
365
|
+
后者已弃用且可能被子类属性覆盖产生冲突。
|
|
366
|
+
{!--< /tips >!--}
|
|
367
|
+
"""
|
|
368
|
+
...
|
|
369
|
+
def cfg(self: object, value: ...) -> ...:
|
|
370
|
+
"""
|
|
371
|
+
设置配置实例,同时同步写入配置存储(保证实时性)
|
|
372
|
+
"""
|
|
373
|
+
...
|
|
374
|
+
def config(self: object) -> ...:
|
|
375
|
+
"""
|
|
376
|
+
``self.cfg`` 的兼容别名
|
|
377
|
+
|
|
378
|
+
功能与 ``self.cfg`` 完全一致,推荐新代码使用 ``self.cfg``。
|
|
359
379
|
"""
|
|
360
380
|
...
|
|
361
381
|
def config(self: object, value: ...) -> ...:
|
|
362
382
|
...
|
|
363
383
|
def accounts(self: object) -> dict:
|
|
364
384
|
"""
|
|
365
|
-
|
|
385
|
+
类型安全的账户配置字典(实时读取)
|
|
386
|
+
|
|
387
|
+
每次访问都从配置存储读取最新值,确保用户修改账户配置后立即生效。
|
|
366
388
|
|
|
367
|
-
:return: 账户配置字典
|
|
389
|
+
:return: 账户配置字典 {name: config_instance}
|
|
368
390
|
:raises AttributeError: 未声明 AccountConfigClass 时抛出
|
|
369
391
|
"""
|
|
370
392
|
...
|
|
371
393
|
def accounts(self: object, value: ...) -> ...:
|
|
394
|
+
"""
|
|
395
|
+
设置账户配置字典,同时同步写入配置存储
|
|
396
|
+
"""
|
|
372
397
|
...
|
|
373
398
|
def enabled_accounts(self: object) -> dict:
|
|
374
399
|
"""
|
|
@@ -396,29 +421,6 @@ class BaseAdapter(ABC):
|
|
|
396
421
|
获取 logger,兼容 sdk 未注入的场景
|
|
397
422
|
"""
|
|
398
423
|
...
|
|
399
|
-
def _load_config(self: object) -> ...:
|
|
400
|
-
"""
|
|
401
|
-
从 TOML 加载全局配置
|
|
402
|
-
|
|
403
|
-
1. 读取 {ConfigKey} 键
|
|
404
|
-
2. 如果不存在,用 dataclass 默认值生成模板并写入
|
|
405
|
-
3. 用 dict_to_dataclass() 转为类型安全的实例
|
|
406
|
-
|
|
407
|
-
:return: AdapterConfig 实例
|
|
408
|
-
"""
|
|
409
|
-
...
|
|
410
|
-
def _load_accounts(self: object) -> dict:
|
|
411
|
-
"""
|
|
412
|
-
从 TOML 加载多账户配置
|
|
413
|
-
|
|
414
|
-
1. 读取 {ConfigKey}.accounts 键
|
|
415
|
-
2. 如果不存在,创建包含一个 default 账户的模板
|
|
416
|
-
3. 对每个账户做 validate_config() 校验
|
|
417
|
-
4. 跳过校验失败的账户并记录错误
|
|
418
|
-
|
|
419
|
-
:return: 账户配置字典 {name: config_instance}
|
|
420
|
-
"""
|
|
421
|
-
...
|
|
422
424
|
def _resolve_account(self: object, account_id: str | None = ...) -> tuple:
|
|
423
425
|
"""
|
|
424
426
|
解析目标账户
|