@neverinfamous/mysql-mcp 2.3.1 → 3.0.1
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.
- package/.dockerignore +1 -0
- package/.gitattributes +18 -0
- package/.github/workflows/codeql.yml +2 -2
- package/.github/workflows/docker-publish.yml +5 -5
- package/CHANGELOG.md +348 -122
- package/DOCKER_README.md +81 -40
- package/README.md +87 -46
- package/VERSION +1 -1
- package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
- package/dist/__tests__/mocks/adapter.js +2 -0
- package/dist/__tests__/mocks/adapter.js.map +1 -1
- package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
- package/dist/adapters/DatabaseAdapter.js +50 -9
- package/dist/adapters/DatabaseAdapter.js.map +1 -1
- package/dist/adapters/mysql/MySQLAdapter.d.ts +6 -0
- package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
- package/dist/adapters/mysql/MySQLAdapter.js +8 -0
- package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
- package/dist/adapters/mysql/SchemaManager.js +16 -15
- package/dist/adapters/mysql/SchemaManager.js.map +1 -1
- package/dist/adapters/mysql/prompts/index.js +10 -20
- package/dist/adapters/mysql/prompts/index.js.map +1 -1
- package/dist/adapters/mysql/prompts/proxysqlSetup.js +1 -1
- package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/docstore.js +10 -7
- package/dist/adapters/mysql/resources/docstore.js.map +1 -1
- package/dist/adapters/mysql/resources/events.js +11 -8
- package/dist/adapters/mysql/resources/events.js.map +1 -1
- package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/indexes.js +12 -15
- package/dist/adapters/mysql/resources/indexes.js.map +1 -1
- package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/innodb.js +20 -17
- package/dist/adapters/mysql/resources/innodb.js.map +1 -1
- package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/locks.js +9 -6
- package/dist/adapters/mysql/resources/locks.js.map +1 -1
- package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/performance.js +15 -15
- package/dist/adapters/mysql/resources/performance.js.map +1 -1
- package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/spatial.js +9 -6
- package/dist/adapters/mysql/resources/spatial.js.map +1 -1
- package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
- package/dist/adapters/mysql/resources/sysschema.js +12 -9
- package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/backup.js +170 -121
- package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/maintenance.js +106 -57
- package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
- package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/admin/monitoring.js +183 -101
- package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
- package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/cluster/group-replication.js +164 -120
- package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +212 -145
- package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
- package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/codemode/index.js +6 -4
- package/dist/adapters/mysql/tools/codemode/index.js.map +1 -1
- package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/core.js +152 -29
- package/dist/adapters/mysql/tools/core.js.map +1 -1
- package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/docstore.js +340 -163
- package/dist/adapters/mysql/tools/docstore.js.map +1 -1
- package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/events.js +284 -198
- package/dist/adapters/mysql/tools/events.js.map +1 -1
- package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/core.js +11 -39
- package/dist/adapters/mysql/tools/json/core.js.map +1 -1
- package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/enhanced.js +15 -33
- package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
- package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/json/helpers.js +13 -24
- package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
- package/dist/adapters/mysql/tools/partitioning.js +3 -0
- package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
- package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/performance/analysis.js +89 -60
- package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
- package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/performance/optimization.js +151 -127
- package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
- package/dist/adapters/mysql/tools/proxysql.d.ts +1 -1
- package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/proxysql.js +289 -176
- package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
- package/dist/adapters/mysql/tools/replication.js +75 -49
- package/dist/adapters/mysql/tools/replication.js.map +1 -1
- package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/roles.js +224 -182
- package/dist/adapters/mysql/tools/roles.js.map +1 -1
- package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/router.js +168 -67
- package/dist/adapters/mysql/tools/router.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/constraints.js +21 -3
- package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/management.js +61 -14
- package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/routines.js +27 -4
- package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/scheduled_events.js +24 -3
- package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/triggers.js +23 -2
- package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
- package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/schema/views.js +47 -7
- package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
- package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/audit.js +102 -34
- package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
- package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/data-protection.js +264 -205
- package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
- package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/security/encryption.js +137 -104
- package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
- package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/shell/backup.js +71 -59
- package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
- package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/shell/restore.js +61 -47
- package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/geometry.js +19 -5
- package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/operations.js +42 -17
- package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/queries.js +109 -57
- package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
- package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/spatial/setup.js +103 -50
- package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
- package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/stats/comparative.js +128 -79
- package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
- package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/stats/descriptive.js +174 -102
- package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/activity.js +50 -25
- package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/performance.js +121 -66
- package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/sysschema/resources.js +101 -64
- package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
- package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/text/fulltext.js +18 -32
- package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
- package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
- package/dist/adapters/mysql/tools/transactions.js +48 -23
- package/dist/adapters/mysql/tools/transactions.js.map +1 -1
- package/dist/adapters/mysql/types/proxysql-types.d.ts +15 -0
- package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
- package/dist/adapters/mysql/types/proxysql-types.js +33 -1
- package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
- package/dist/adapters/mysql/types/router-types.d.ts +1 -1
- package/dist/adapters/mysql/types/router-types.js +1 -1
- package/dist/adapters/mysql/types/router-types.js.map +1 -1
- package/dist/adapters/mysql/types/shell-types.js +2 -2
- package/dist/adapters/mysql/types/shell-types.js.map +1 -1
- package/dist/adapters/mysql/types.d.ts +485 -21
- package/dist/adapters/mysql/types.d.ts.map +1 -1
- package/dist/adapters/mysql/types.js +546 -19
- package/dist/adapters/mysql/types.js.map +1 -1
- package/dist/auth/scopes.js +1 -1
- package/dist/auth/scopes.js.map +1 -1
- package/dist/codemode/api.d.ts +3 -2
- package/dist/codemode/api.d.ts.map +1 -1
- package/dist/codemode/api.js +80 -5
- package/dist/codemode/api.js.map +1 -1
- package/dist/codemode/sandbox-factory.js +1 -1
- package/dist/codemode/sandbox-factory.js.map +1 -1
- package/dist/codemode/types.d.ts +26 -0
- package/dist/codemode/types.d.ts.map +1 -1
- package/dist/codemode/types.js +2 -0
- package/dist/codemode/types.js.map +1 -1
- package/dist/codemode/worker-sandbox.d.ts +4 -2
- package/dist/codemode/worker-sandbox.d.ts.map +1 -1
- package/dist/codemode/worker-sandbox.js +66 -7
- package/dist/codemode/worker-sandbox.js.map +1 -1
- package/dist/codemode/worker-script.d.ts +3 -0
- package/dist/codemode/worker-script.d.ts.map +1 -1
- package/dist/codemode/worker-script.js +128 -75
- package/dist/codemode/worker-script.js.map +1 -1
- package/dist/constants/ServerInstructions.d.ts +1 -1
- package/dist/constants/ServerInstructions.d.ts.map +1 -1
- package/dist/constants/ServerInstructions.js +37 -31
- package/dist/constants/ServerInstructions.js.map +1 -1
- package/dist/filtering/ToolConstants.d.ts +1 -1
- package/dist/filtering/ToolConstants.d.ts.map +1 -1
- package/dist/filtering/ToolConstants.js +1 -2
- package/dist/filtering/ToolConstants.js.map +1 -1
- package/dist/pool/ConnectionPool.d.ts.map +1 -1
- package/dist/pool/ConnectionPool.js.map +1 -1
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +6 -0
- package/dist/transports/http.js.map +1 -1
- package/dist/utils/validators.d.ts +1 -1
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js.map +1 -1
- package/package.json +4 -4
- package/releases/v3.0.0-release-notes.md +81 -0
- package/releases/v3.0.1-release-notes.md +20 -0
- package/src/__tests__/mocks/adapter.ts +3 -0
- package/src/__tests__/perf.test.ts +6 -6
- package/src/adapters/DatabaseAdapter.ts +58 -9
- package/src/adapters/__tests__/DatabaseAdapter.test.ts +89 -8
- package/src/adapters/mysql/MySQLAdapter.ts +17 -2
- package/src/adapters/mysql/SchemaManager.ts +21 -21
- package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
- package/src/adapters/mysql/prompts/index.ts +12 -22
- package/src/adapters/mysql/prompts/proxysqlSetup.ts +1 -1
- package/src/adapters/mysql/resources/docstore.ts +13 -10
- package/src/adapters/mysql/resources/events.ts +12 -12
- package/src/adapters/mysql/resources/indexes.ts +17 -19
- package/src/adapters/mysql/resources/innodb.ts +23 -22
- package/src/adapters/mysql/resources/locks.ts +9 -7
- package/src/adapters/mysql/resources/performance.ts +23 -18
- package/src/adapters/mysql/resources/spatial.ts +9 -7
- package/src/adapters/mysql/resources/sysschema.ts +12 -11
- package/src/adapters/mysql/tools/__tests__/core.test.ts +126 -55
- package/src/adapters/mysql/tools/__tests__/docstore.test.ts +459 -88
- package/src/adapters/mysql/tools/__tests__/events.test.ts +281 -103
- package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +128 -28
- package/src/adapters/mysql/tools/__tests__/replication.test.ts +48 -2
- package/src/adapters/mysql/tools/__tests__/roles.test.ts +15 -18
- package/src/adapters/mysql/tools/__tests__/router.test.ts +32 -5
- package/src/adapters/mysql/tools/__tests__/security.test.ts +126 -2
- package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +84 -76
- package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +47 -51
- package/src/adapters/mysql/tools/__tests__/spatial.test.ts +11 -10
- package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +54 -38
- package/src/adapters/mysql/tools/__tests__/stats.test.ts +285 -152
- package/src/adapters/mysql/tools/__tests__/transactions.test.ts +13 -13
- package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +171 -25
- package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +240 -4
- package/src/adapters/mysql/tools/admin/__tests__/monitoring-summary.test.ts +274 -0
- package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +94 -5
- package/src/adapters/mysql/tools/admin/backup.ts +193 -143
- package/src/adapters/mysql/tools/admin/maintenance.ts +118 -69
- package/src/adapters/mysql/tools/admin/monitoring.ts +201 -125
- package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +69 -0
- package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +141 -0
- package/src/adapters/mysql/tools/cluster/group-replication.ts +172 -132
- package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +231 -157
- package/src/adapters/mysql/tools/codemode/__tests__/codemode-tool.test.ts +227 -0
- package/src/adapters/mysql/tools/codemode/index.ts +5 -3
- package/src/adapters/mysql/tools/core.ts +152 -38
- package/src/adapters/mysql/tools/docstore.ts +422 -205
- package/src/adapters/mysql/tools/events.ts +334 -233
- package/src/adapters/mysql/tools/json/__tests__/core.test.ts +20 -0
- package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +82 -50
- package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +42 -3
- package/src/adapters/mysql/tools/json/core.ts +21 -42
- package/src/adapters/mysql/tools/json/enhanced.ts +22 -37
- package/src/adapters/mysql/tools/json/helpers.ts +21 -25
- package/src/adapters/mysql/tools/partitioning.ts +3 -0
- package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +98 -5
- package/src/adapters/mysql/tools/performance/__tests__/optimization-coverage.test.ts +515 -0
- package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +187 -0
- package/src/adapters/mysql/tools/performance/analysis.ts +95 -69
- package/src/adapters/mysql/tools/performance/optimization.ts +182 -153
- package/src/adapters/mysql/tools/proxysql.ts +314 -209
- package/src/adapters/mysql/tools/replication.ts +84 -57
- package/src/adapters/mysql/tools/roles.ts +274 -226
- package/src/adapters/mysql/tools/router.ts +181 -85
- package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +13 -0
- package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +60 -25
- package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +11 -0
- package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +25 -4
- package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +46 -14
- package/src/adapters/mysql/tools/schema/constraints.ts +22 -3
- package/src/adapters/mysql/tools/schema/management.ts +60 -15
- package/src/adapters/mysql/tools/schema/routines.ts +26 -4
- package/src/adapters/mysql/tools/schema/scheduled_events.ts +25 -3
- package/src/adapters/mysql/tools/schema/triggers.ts +27 -2
- package/src/adapters/mysql/tools/schema/views.ts +46 -8
- package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +90 -4
- package/src/adapters/mysql/tools/security/audit.ts +113 -39
- package/src/adapters/mysql/tools/security/data-protection.ts +293 -233
- package/src/adapters/mysql/tools/security/encryption.ts +172 -139
- package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +29 -0
- package/src/adapters/mysql/tools/shell/backup.ts +90 -73
- package/src/adapters/mysql/tools/shell/restore.ts +62 -48
- package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +22 -14
- package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +65 -51
- package/src/adapters/mysql/tools/spatial/geometry.ts +23 -7
- package/src/adapters/mysql/tools/spatial/operations.ts +60 -31
- package/src/adapters/mysql/tools/spatial/queries.ts +142 -65
- package/src/adapters/mysql/tools/spatial/setup.ts +121 -55
- package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +12 -10
- package/src/adapters/mysql/tools/stats/comparative.ts +150 -98
- package/src/adapters/mysql/tools/stats/descriptive.ts +204 -127
- package/src/adapters/mysql/tools/sysschema/__tests__/error-paths.test.ts +222 -0
- package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +45 -0
- package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +6 -3
- package/src/adapters/mysql/tools/sysschema/activity.ts +52 -27
- package/src/adapters/mysql/tools/sysschema/performance.ts +132 -68
- package/src/adapters/mysql/tools/sysschema/resources.ts +105 -67
- package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +45 -17
- package/src/adapters/mysql/tools/text/fulltext.ts +27 -38
- package/src/adapters/mysql/tools/transactions.ts +49 -24
- package/src/adapters/mysql/types/proxysql-types.ts +38 -1
- package/src/adapters/mysql/types/router-types.ts +1 -1
- package/src/adapters/mysql/types/shell-types.ts +2 -2
- package/src/adapters/mysql/types.ts +632 -19
- package/src/auth/__tests__/scopes.test.ts +2 -2
- package/src/auth/scopes.ts +1 -1
- package/src/codemode/__tests__/api.test.ts +417 -0
- package/src/codemode/__tests__/sandbox-factory.test.ts +158 -0
- package/src/codemode/__tests__/sandbox.test.ts +301 -0
- package/src/codemode/__tests__/security.test.ts +368 -0
- package/src/codemode/__tests__/worker-sandbox.test.ts +179 -0
- package/src/codemode/__tests__/worker-script.test.ts +226 -0
- package/src/codemode/api.ts +89 -5
- package/src/codemode/sandbox-factory.ts +1 -1
- package/src/codemode/types.ts +34 -0
- package/src/codemode/worker-sandbox.ts +74 -7
- package/src/codemode/worker-script.ts +157 -86
- package/src/constants/ServerInstructions.ts +37 -31
- package/src/filtering/ToolConstants.ts +1 -2
- package/src/filtering/__tests__/ToolFilter.test.ts +9 -9
- package/src/pool/ConnectionPool.ts +4 -1
- package/src/transports/__tests__/http.test.ts +15 -3
- package/src/transports/http.ts +12 -0
- package/src/utils/validators.ts +2 -1
- package/vitest.config.ts +3 -1
- package/CODE_MODE.md +0 -245
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
* 6 tools total.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { z } from "zod";
|
|
8
|
+
import { z, ZodError } from "zod";
|
|
9
9
|
import type { MySQLAdapter } from "../MySQLAdapter.js";
|
|
10
10
|
import type { ToolDefinition, RequestContext } from "../../../types/index.js";
|
|
11
11
|
|
|
12
|
+
/** Extract human-readable messages from a ZodError instead of raw JSON array */
|
|
13
|
+
function formatZodError(error: ZodError): string {
|
|
14
|
+
return error.issues.map((i) => i.message).join("; ");
|
|
15
|
+
}
|
|
16
|
+
|
|
12
17
|
// =============================================================================
|
|
13
18
|
// Zod Schemas
|
|
14
19
|
// =============================================================================
|
|
@@ -17,7 +22,7 @@ const EventCreateSchema = z.object({
|
|
|
17
22
|
name: z.string().describe("Event name"),
|
|
18
23
|
schedule: z
|
|
19
24
|
.object({
|
|
20
|
-
type: z.
|
|
25
|
+
type: z.string().describe("Event schedule type"),
|
|
21
26
|
executeAt: z
|
|
22
27
|
.string()
|
|
23
28
|
.optional()
|
|
@@ -26,16 +31,7 @@ const EventCreateSchema = z.object({
|
|
|
26
31
|
),
|
|
27
32
|
interval: z.number().optional().describe("For RECURRING: interval value"),
|
|
28
33
|
intervalUnit: z
|
|
29
|
-
.
|
|
30
|
-
"YEAR",
|
|
31
|
-
"QUARTER",
|
|
32
|
-
"MONTH",
|
|
33
|
-
"DAY",
|
|
34
|
-
"HOUR",
|
|
35
|
-
"MINUTE",
|
|
36
|
-
"WEEK",
|
|
37
|
-
"SECOND",
|
|
38
|
-
])
|
|
34
|
+
.string()
|
|
39
35
|
.optional()
|
|
40
36
|
.describe("For RECURRING: interval unit"),
|
|
41
37
|
starts: z.string().optional().describe("For RECURRING: start timestamp"),
|
|
@@ -44,7 +40,7 @@ const EventCreateSchema = z.object({
|
|
|
44
40
|
.describe("Event schedule configuration"),
|
|
45
41
|
body: z.string().describe("SQL statement(s) to execute"),
|
|
46
42
|
onCompletion: z
|
|
47
|
-
.
|
|
43
|
+
.string()
|
|
48
44
|
.default("NOT PRESERVE")
|
|
49
45
|
.describe("What to do after event completes"),
|
|
50
46
|
enabled: z.boolean().default(true).describe("Whether event is enabled"),
|
|
@@ -57,28 +53,17 @@ const EventAlterSchema = z.object({
|
|
|
57
53
|
newName: z.string().optional().describe("New event name (for rename)"),
|
|
58
54
|
schedule: z
|
|
59
55
|
.object({
|
|
60
|
-
type: z.
|
|
56
|
+
type: z.string().optional(),
|
|
61
57
|
executeAt: z.string().optional(),
|
|
62
58
|
interval: z.number().optional(),
|
|
63
|
-
intervalUnit: z
|
|
64
|
-
.enum([
|
|
65
|
-
"YEAR",
|
|
66
|
-
"QUARTER",
|
|
67
|
-
"MONTH",
|
|
68
|
-
"DAY",
|
|
69
|
-
"HOUR",
|
|
70
|
-
"MINUTE",
|
|
71
|
-
"WEEK",
|
|
72
|
-
"SECOND",
|
|
73
|
-
])
|
|
74
|
-
.optional(),
|
|
59
|
+
intervalUnit: z.string().optional(),
|
|
75
60
|
starts: z.string().optional(),
|
|
76
61
|
ends: z.string().optional(),
|
|
77
62
|
})
|
|
78
63
|
.optional()
|
|
79
64
|
.describe("New schedule configuration"),
|
|
80
65
|
body: z.string().optional().describe("New SQL statement(s)"),
|
|
81
|
-
onCompletion: z.
|
|
66
|
+
onCompletion: z.string().optional(),
|
|
82
67
|
enabled: z.boolean().optional().describe("Enable or disable event"),
|
|
83
68
|
comment: z.string().optional(),
|
|
84
69
|
});
|
|
@@ -137,92 +122,132 @@ function createEventCreateTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
137
122
|
readOnlyHint: false,
|
|
138
123
|
},
|
|
139
124
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
125
|
+
try {
|
|
126
|
+
const {
|
|
127
|
+
name,
|
|
128
|
+
schedule,
|
|
129
|
+
body,
|
|
130
|
+
onCompletion,
|
|
131
|
+
enabled,
|
|
132
|
+
comment,
|
|
133
|
+
ifNotExists,
|
|
134
|
+
} = EventCreateSchema.parse(params);
|
|
135
|
+
|
|
136
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
137
|
+
return { success: false, error: "Invalid event name" };
|
|
138
|
+
}
|
|
154
139
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
"SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE() AND EVENT_NAME = ?",
|
|
159
|
-
[name],
|
|
160
|
-
);
|
|
161
|
-
if (existsCheck.rows && existsCheck.rows.length > 0) {
|
|
140
|
+
// Validate enum fields at handler level
|
|
141
|
+
const validScheduleTypes = ["ONE TIME", "RECURRING"];
|
|
142
|
+
if (!validScheduleTypes.includes(schedule.type)) {
|
|
162
143
|
return {
|
|
163
|
-
success:
|
|
164
|
-
|
|
165
|
-
reason: "Event already exists",
|
|
166
|
-
eventName: name,
|
|
144
|
+
success: false,
|
|
145
|
+
error: `Invalid schedule type: '${schedule.type}' — expected one of: ${validScheduleTypes.join(", ")}`,
|
|
167
146
|
};
|
|
168
147
|
}
|
|
169
|
-
}
|
|
170
148
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
throw new Error("executeAt is required for ONE TIME events");
|
|
149
|
+
const validOnCompletion = ["PRESERVE", "NOT PRESERVE"];
|
|
150
|
+
if (!validOnCompletion.includes(onCompletion)) {
|
|
151
|
+
return {
|
|
152
|
+
success: false,
|
|
153
|
+
error: `Invalid onCompletion: '${onCompletion}' — expected one of: ${validOnCompletion.join(", ")}`,
|
|
154
|
+
};
|
|
178
155
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
schedule.intervalUnit === undefined ||
|
|
185
|
-
schedule.intervalUnit === null
|
|
186
|
-
) {
|
|
187
|
-
throw new Error(
|
|
188
|
-
"interval and intervalUnit are required for RECURRING events",
|
|
156
|
+
|
|
157
|
+
if (ifNotExists) {
|
|
158
|
+
const existsCheck = await adapter.executeQuery(
|
|
159
|
+
"SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE() AND EVENT_NAME = ?",
|
|
160
|
+
[name],
|
|
189
161
|
);
|
|
162
|
+
if (existsCheck.rows && existsCheck.rows.length > 0) {
|
|
163
|
+
return {
|
|
164
|
+
success: true,
|
|
165
|
+
skipped: true,
|
|
166
|
+
reason: "Event already exists",
|
|
167
|
+
eventName: name,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
190
170
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (schedule.
|
|
196
|
-
|
|
171
|
+
|
|
172
|
+
const ifNotExistsClause = ifNotExists ? "IF NOT EXISTS " : "";
|
|
173
|
+
let sql = `CREATE EVENT ${ifNotExistsClause}\`${name}\`\nON SCHEDULE `;
|
|
174
|
+
|
|
175
|
+
if (schedule.type === "ONE TIME") {
|
|
176
|
+
if (!schedule.executeAt) {
|
|
177
|
+
return {
|
|
178
|
+
success: false,
|
|
179
|
+
error: "executeAt is required for ONE TIME events",
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
sql += `AT '${schedule.executeAt}'`;
|
|
183
|
+
} else {
|
|
184
|
+
if (
|
|
185
|
+
schedule.interval === undefined ||
|
|
186
|
+
schedule.interval === null ||
|
|
187
|
+
schedule.intervalUnit === undefined ||
|
|
188
|
+
schedule.intervalUnit === null
|
|
189
|
+
) {
|
|
190
|
+
return {
|
|
191
|
+
success: false,
|
|
192
|
+
error:
|
|
193
|
+
"interval and intervalUnit are required for RECURRING events",
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const validUnits = [
|
|
198
|
+
"YEAR",
|
|
199
|
+
"QUARTER",
|
|
200
|
+
"MONTH",
|
|
201
|
+
"DAY",
|
|
202
|
+
"HOUR",
|
|
203
|
+
"MINUTE",
|
|
204
|
+
"WEEK",
|
|
205
|
+
"SECOND",
|
|
206
|
+
];
|
|
207
|
+
if (!validUnits.includes(schedule.intervalUnit)) {
|
|
208
|
+
return {
|
|
209
|
+
success: false,
|
|
210
|
+
error: `Invalid intervalUnit: '${schedule.intervalUnit}' — expected one of: ${validUnits.join(", ")}`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
sql += `EVERY ${String(schedule.interval)} ${schedule.intervalUnit}`;
|
|
214
|
+
if (schedule.starts) {
|
|
215
|
+
sql += ` STARTS '${schedule.starts}'`;
|
|
216
|
+
}
|
|
217
|
+
if (schedule.ends) {
|
|
218
|
+
sql += ` ENDS '${schedule.ends}'`;
|
|
219
|
+
}
|
|
197
220
|
}
|
|
198
|
-
}
|
|
199
221
|
|
|
200
|
-
|
|
222
|
+
sql += `\nON COMPLETION ${onCompletion}`;
|
|
201
223
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
224
|
+
if (!enabled) {
|
|
225
|
+
sql += "\nDISABLE";
|
|
226
|
+
} else {
|
|
227
|
+
sql += "\nENABLE";
|
|
228
|
+
}
|
|
207
229
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
230
|
+
if (comment) {
|
|
231
|
+
sql += `\nCOMMENT '${comment.replace(/'/g, "''")}'`;
|
|
232
|
+
}
|
|
211
233
|
|
|
212
|
-
|
|
234
|
+
sql += `\nDO ${body}`;
|
|
213
235
|
|
|
214
|
-
try {
|
|
215
236
|
await adapter.executeQuery(sql);
|
|
216
237
|
return { success: true, eventName: name };
|
|
217
238
|
} catch (error: unknown) {
|
|
239
|
+
if (error instanceof ZodError) {
|
|
240
|
+
return { success: false, error: formatZodError(error) };
|
|
241
|
+
}
|
|
218
242
|
const message = error instanceof Error ? error.message : String(error);
|
|
219
243
|
if (message.toLowerCase().includes("already exists")) {
|
|
220
|
-
return {
|
|
221
|
-
success: false,
|
|
222
|
-
reason: `Event '${name}' already exists`,
|
|
223
|
-
};
|
|
244
|
+
return { success: false, error: "Event already exists" };
|
|
224
245
|
}
|
|
225
|
-
|
|
246
|
+
const cleaned = message.replace(
|
|
247
|
+
/^(Query failed: )?(Execute failed: )?/i,
|
|
248
|
+
"",
|
|
249
|
+
);
|
|
250
|
+
return { success: false, error: cleaned };
|
|
226
251
|
}
|
|
227
252
|
},
|
|
228
253
|
};
|
|
@@ -244,88 +269,139 @@ function createEventAlterTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
244
269
|
readOnlyHint: false,
|
|
245
270
|
},
|
|
246
271
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
272
|
+
try {
|
|
273
|
+
const {
|
|
274
|
+
name,
|
|
275
|
+
newName,
|
|
276
|
+
schedule,
|
|
277
|
+
body,
|
|
278
|
+
onCompletion,
|
|
279
|
+
enabled,
|
|
280
|
+
comment,
|
|
281
|
+
} = EventAlterSchema.parse(params);
|
|
282
|
+
|
|
283
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
284
|
+
return { success: false, error: "Invalid event name" };
|
|
285
|
+
}
|
|
257
286
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
} else {
|
|
267
|
-
if (
|
|
268
|
-
schedule.interval === undefined ||
|
|
269
|
-
schedule.interval === null ||
|
|
270
|
-
schedule.intervalUnit === undefined ||
|
|
271
|
-
schedule.intervalUnit === null
|
|
272
|
-
) {
|
|
273
|
-
throw new Error(
|
|
274
|
-
"interval and intervalUnit are required for RECURRING events",
|
|
275
|
-
);
|
|
287
|
+
// Validate enum fields at handler level
|
|
288
|
+
if (onCompletion !== undefined) {
|
|
289
|
+
const validOnCompletion = ["PRESERVE", "NOT PRESERVE"];
|
|
290
|
+
if (!validOnCompletion.includes(onCompletion)) {
|
|
291
|
+
return {
|
|
292
|
+
success: false,
|
|
293
|
+
error: `Invalid onCompletion: '${onCompletion}' — expected one of: ${validOnCompletion.join(", ")}`,
|
|
294
|
+
};
|
|
276
295
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
let sql = `ALTER EVENT \`${name}\``;
|
|
299
|
+
const clauses: string[] = [];
|
|
300
|
+
|
|
301
|
+
if (schedule?.type) {
|
|
302
|
+
// Validate schedule.type
|
|
303
|
+
const validScheduleTypes = ["ONE TIME", "RECURRING"];
|
|
304
|
+
if (!validScheduleTypes.includes(schedule.type)) {
|
|
305
|
+
return {
|
|
306
|
+
success: false,
|
|
307
|
+
error: `Invalid schedule type: '${schedule.type}' — expected one of: ${validScheduleTypes.join(", ")}`,
|
|
308
|
+
};
|
|
280
309
|
}
|
|
281
|
-
|
|
282
|
-
|
|
310
|
+
|
|
311
|
+
let scheduleClause = "ON SCHEDULE ";
|
|
312
|
+
if (schedule.type === "ONE TIME") {
|
|
313
|
+
if (!schedule.executeAt) {
|
|
314
|
+
return {
|
|
315
|
+
success: false,
|
|
316
|
+
error: "executeAt is required for ONE TIME events",
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
scheduleClause += `AT '${schedule.executeAt}'`;
|
|
320
|
+
} else {
|
|
321
|
+
if (
|
|
322
|
+
schedule.interval === undefined ||
|
|
323
|
+
schedule.interval === null ||
|
|
324
|
+
schedule.intervalUnit === undefined ||
|
|
325
|
+
schedule.intervalUnit === null
|
|
326
|
+
) {
|
|
327
|
+
return {
|
|
328
|
+
success: false,
|
|
329
|
+
error:
|
|
330
|
+
"interval and intervalUnit are required for RECURRING events",
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const validUnits = [
|
|
335
|
+
"YEAR",
|
|
336
|
+
"QUARTER",
|
|
337
|
+
"MONTH",
|
|
338
|
+
"DAY",
|
|
339
|
+
"HOUR",
|
|
340
|
+
"MINUTE",
|
|
341
|
+
"WEEK",
|
|
342
|
+
"SECOND",
|
|
343
|
+
];
|
|
344
|
+
if (!validUnits.includes(schedule.intervalUnit)) {
|
|
345
|
+
return {
|
|
346
|
+
success: false,
|
|
347
|
+
error: `Invalid intervalUnit: '${schedule.intervalUnit}' — expected one of: ${validUnits.join(", ")}`,
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
scheduleClause += `EVERY ${String(schedule.interval)} ${schedule.intervalUnit}`;
|
|
351
|
+
if (schedule.starts) {
|
|
352
|
+
scheduleClause += ` STARTS '${schedule.starts}'`;
|
|
353
|
+
}
|
|
354
|
+
if (schedule.ends) {
|
|
355
|
+
scheduleClause += ` ENDS '${schedule.ends}'`;
|
|
356
|
+
}
|
|
283
357
|
}
|
|
358
|
+
clauses.push(scheduleClause);
|
|
284
359
|
}
|
|
285
|
-
clauses.push(scheduleClause);
|
|
286
|
-
}
|
|
287
360
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
361
|
+
if (onCompletion) {
|
|
362
|
+
clauses.push(`ON COMPLETION ${onCompletion}`);
|
|
363
|
+
}
|
|
291
364
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
365
|
+
if (newName) {
|
|
366
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(newName)) {
|
|
367
|
+
return { success: false, error: "Invalid new event name" };
|
|
368
|
+
}
|
|
369
|
+
clauses.push(`RENAME TO \`${newName}\``);
|
|
295
370
|
}
|
|
296
|
-
clauses.push(`RENAME TO \`${newName}\``);
|
|
297
|
-
}
|
|
298
371
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
372
|
+
if (enabled !== undefined) {
|
|
373
|
+
clauses.push(enabled ? "ENABLE" : "DISABLE");
|
|
374
|
+
}
|
|
302
375
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
376
|
+
if (comment !== undefined) {
|
|
377
|
+
clauses.push(`COMMENT '${comment.replace(/'/g, "''")}'`);
|
|
378
|
+
}
|
|
306
379
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
380
|
+
if (body) {
|
|
381
|
+
clauses.push(`DO ${body}`);
|
|
382
|
+
}
|
|
310
383
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
384
|
+
if (clauses.length === 0) {
|
|
385
|
+
return { success: false, error: "No modifications specified" };
|
|
386
|
+
}
|
|
314
387
|
|
|
315
|
-
|
|
388
|
+
sql += "\n" + clauses.join("\n");
|
|
316
389
|
|
|
317
|
-
try {
|
|
318
390
|
await adapter.executeQuery(sql);
|
|
319
391
|
return { success: true, eventName: newName ?? name };
|
|
320
392
|
} catch (error: unknown) {
|
|
393
|
+
if (error instanceof ZodError) {
|
|
394
|
+
return { success: false, error: formatZodError(error) };
|
|
395
|
+
}
|
|
321
396
|
const message = error instanceof Error ? error.message : String(error);
|
|
322
397
|
if (message.toLowerCase().includes("unknown event")) {
|
|
323
|
-
return {
|
|
324
|
-
success: false,
|
|
325
|
-
reason: `Event '${name}' does not exist`,
|
|
326
|
-
};
|
|
398
|
+
return { success: false, error: "Event does not exist" };
|
|
327
399
|
}
|
|
328
|
-
|
|
400
|
+
const cleaned = message.replace(
|
|
401
|
+
/^(Query failed: )?(Execute failed: )?/i,
|
|
402
|
+
"",
|
|
403
|
+
);
|
|
404
|
+
return { success: false, error: cleaned };
|
|
329
405
|
}
|
|
330
406
|
},
|
|
331
407
|
};
|
|
@@ -347,43 +423,41 @@ function createEventDropTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
347
423
|
destructiveHint: true,
|
|
348
424
|
},
|
|
349
425
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
350
|
-
|
|
426
|
+
try {
|
|
427
|
+
const { name, ifExists } = EventDropSchema.parse(params);
|
|
351
428
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
429
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
430
|
+
return { success: false, error: "Invalid event name" };
|
|
431
|
+
}
|
|
356
432
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
433
|
+
if (ifExists) {
|
|
434
|
+
const existsCheck = await adapter.executeQuery(
|
|
435
|
+
"SELECT EVENT_NAME FROM information_schema.EVENTS WHERE EVENT_SCHEMA = DATABASE() AND EVENT_NAME = ?",
|
|
436
|
+
[name],
|
|
437
|
+
);
|
|
438
|
+
if (!existsCheck.rows || existsCheck.rows.length === 0) {
|
|
439
|
+
return {
|
|
440
|
+
success: true,
|
|
441
|
+
skipped: true,
|
|
442
|
+
reason: "Event did not exist",
|
|
443
|
+
eventName: name,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
370
446
|
}
|
|
371
|
-
}
|
|
372
447
|
|
|
373
|
-
|
|
448
|
+
const ifExistsClause = ifExists ? "IF EXISTS " : "";
|
|
374
449
|
|
|
375
|
-
try {
|
|
376
450
|
await adapter.executeQuery(`DROP EVENT ${ifExistsClause}\`${name}\``);
|
|
377
451
|
return { success: true, eventName: name };
|
|
378
452
|
} catch (error: unknown) {
|
|
453
|
+
if (error instanceof ZodError) {
|
|
454
|
+
return { success: false, error: formatZodError(error) };
|
|
455
|
+
}
|
|
379
456
|
const message = error instanceof Error ? error.message : String(error);
|
|
380
457
|
if (message.toLowerCase().includes("unknown event")) {
|
|
381
|
-
return {
|
|
382
|
-
success: false,
|
|
383
|
-
reason: `Event '${name}' does not exist`,
|
|
384
|
-
};
|
|
458
|
+
return { success: false, error: "Event does not exist" };
|
|
385
459
|
}
|
|
386
|
-
|
|
460
|
+
return { success: false, error: message };
|
|
387
461
|
}
|
|
388
462
|
},
|
|
389
463
|
};
|
|
@@ -406,20 +480,21 @@ function createEventListTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
406
480
|
idempotentHint: true,
|
|
407
481
|
},
|
|
408
482
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
409
|
-
|
|
483
|
+
try {
|
|
484
|
+
const { schema, includeDisabled } = EventListSchema.parse(params);
|
|
410
485
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
486
|
+
// P154: Schema existence check when explicitly provided
|
|
487
|
+
if (schema) {
|
|
488
|
+
const schemaCheck = await adapter.executeQuery(
|
|
489
|
+
"SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ?",
|
|
490
|
+
[schema],
|
|
491
|
+
);
|
|
492
|
+
if (!schemaCheck.rows || schemaCheck.rows.length === 0) {
|
|
493
|
+
return { exists: false, schema };
|
|
494
|
+
}
|
|
419
495
|
}
|
|
420
|
-
}
|
|
421
496
|
|
|
422
|
-
|
|
497
|
+
let query = `
|
|
423
498
|
SELECT
|
|
424
499
|
EVENT_NAME as name,
|
|
425
500
|
EVENT_SCHEMA as schemaName,
|
|
@@ -438,19 +513,26 @@ function createEventListTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
438
513
|
WHERE EVENT_SCHEMA = COALESCE(?, DATABASE())
|
|
439
514
|
`;
|
|
440
515
|
|
|
441
|
-
|
|
516
|
+
const queryParams: unknown[] = [schema ?? null];
|
|
442
517
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
518
|
+
if (!includeDisabled) {
|
|
519
|
+
query += " AND STATUS = 'ENABLED'";
|
|
520
|
+
}
|
|
446
521
|
|
|
447
|
-
|
|
522
|
+
query += " ORDER BY EVENT_NAME";
|
|
448
523
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
524
|
+
const result = await adapter.executeQuery(query, queryParams);
|
|
525
|
+
return {
|
|
526
|
+
events: result.rows,
|
|
527
|
+
count: result.rows?.length ?? 0,
|
|
528
|
+
};
|
|
529
|
+
} catch (error: unknown) {
|
|
530
|
+
if (error instanceof ZodError) {
|
|
531
|
+
return { success: false, error: formatZodError(error) };
|
|
532
|
+
}
|
|
533
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
534
|
+
return { success: false, error: message };
|
|
535
|
+
}
|
|
454
536
|
},
|
|
455
537
|
};
|
|
456
538
|
}
|
|
@@ -472,20 +554,21 @@ function createEventStatusTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
472
554
|
idempotentHint: true,
|
|
473
555
|
},
|
|
474
556
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
475
|
-
|
|
557
|
+
try {
|
|
558
|
+
const { name, schema } = EventStatusSchema.parse(params);
|
|
476
559
|
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
560
|
+
// P154: Schema existence check when explicitly provided
|
|
561
|
+
if (schema) {
|
|
562
|
+
const schemaCheck = await adapter.executeQuery(
|
|
563
|
+
"SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = ?",
|
|
564
|
+
[schema],
|
|
565
|
+
);
|
|
566
|
+
if (!schemaCheck.rows || schemaCheck.rows.length === 0) {
|
|
567
|
+
return { exists: false, schema };
|
|
568
|
+
}
|
|
485
569
|
}
|
|
486
|
-
}
|
|
487
570
|
|
|
488
|
-
|
|
571
|
+
const query = `
|
|
489
572
|
SELECT
|
|
490
573
|
EVENT_NAME as name,
|
|
491
574
|
EVENT_SCHEMA as schemaName,
|
|
@@ -509,13 +592,23 @@ function createEventStatusTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
509
592
|
AND EVENT_NAME = ?
|
|
510
593
|
`;
|
|
511
594
|
|
|
512
|
-
|
|
595
|
+
const result = await adapter.executeQuery(query, [
|
|
596
|
+
schema ?? null,
|
|
597
|
+
name,
|
|
598
|
+
]);
|
|
513
599
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
600
|
+
if (!result.rows || result.rows.length === 0) {
|
|
601
|
+
return { exists: false, name };
|
|
602
|
+
}
|
|
517
603
|
|
|
518
|
-
|
|
604
|
+
return result.rows[0];
|
|
605
|
+
} catch (error: unknown) {
|
|
606
|
+
if (error instanceof ZodError) {
|
|
607
|
+
return { success: false, error: formatZodError(error) };
|
|
608
|
+
}
|
|
609
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
610
|
+
return { success: false, error: message };
|
|
611
|
+
}
|
|
519
612
|
},
|
|
520
613
|
};
|
|
521
614
|
}
|
|
@@ -536,13 +629,14 @@ function createSchedulerStatusTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
536
629
|
idempotentHint: true,
|
|
537
630
|
},
|
|
538
631
|
handler: async (_params: unknown, _context: RequestContext) => {
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
632
|
+
try {
|
|
633
|
+
// Get scheduler status
|
|
634
|
+
const statusResult = await adapter.executeQuery(
|
|
635
|
+
"SHOW VARIABLES LIKE 'event_scheduler'",
|
|
636
|
+
);
|
|
543
637
|
|
|
544
|
-
|
|
545
|
-
|
|
638
|
+
// Get event counts by status
|
|
639
|
+
const countResult = await adapter.executeQuery(`
|
|
546
640
|
SELECT
|
|
547
641
|
STATUS as status,
|
|
548
642
|
COUNT(*) as count
|
|
@@ -550,8 +644,8 @@ function createSchedulerStatusTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
550
644
|
GROUP BY STATUS
|
|
551
645
|
`);
|
|
552
646
|
|
|
553
|
-
|
|
554
|
-
|
|
647
|
+
// Get recently executed events
|
|
648
|
+
const recentResult = await adapter.executeQuery(`
|
|
555
649
|
SELECT
|
|
556
650
|
EVENT_NAME as name,
|
|
557
651
|
EVENT_SCHEMA as schemaName,
|
|
@@ -562,14 +656,21 @@ function createSchedulerStatusTool(adapter: MySQLAdapter): ToolDefinition {
|
|
|
562
656
|
LIMIT 10
|
|
563
657
|
`);
|
|
564
658
|
|
|
565
|
-
|
|
659
|
+
const schedulerStatus = statusResult.rows?.[0];
|
|
566
660
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
661
|
+
return {
|
|
662
|
+
schedulerEnabled: schedulerStatus?.["Value"] === "ON",
|
|
663
|
+
schedulerStatus: schedulerStatus?.["Value"] ?? "UNKNOWN",
|
|
664
|
+
eventCounts: countResult.rows ?? [],
|
|
665
|
+
recentlyExecuted: recentResult.rows ?? [],
|
|
666
|
+
};
|
|
667
|
+
} catch (error: unknown) {
|
|
668
|
+
if (error instanceof ZodError) {
|
|
669
|
+
return { success: false, error: formatZodError(error) };
|
|
670
|
+
}
|
|
671
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
672
|
+
return { success: false, error: message };
|
|
673
|
+
}
|
|
573
674
|
},
|
|
574
675
|
};
|
|
575
676
|
}
|