@neverinfamous/mysql-mcp 2.3.0 → 3.0.0
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 -10
- package/.github/workflows/docker-publish.yml +15 -13
- package/CHANGELOG.md +287 -1
- package/DOCKER_README.md +100 -265
- package/Dockerfile +5 -0
- package/README.md +124 -59
- 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/v2.3.0-release-notes.md +20 -20
- package/releases/v2.3.1-release-notes.md +34 -0
- package/releases/v3.0.0-release-notes.md +81 -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 -50
- 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
|
@@ -483,49 +483,117 @@ describe("Event Create Advanced", () => {
|
|
|
483
483
|
expect(call).toContain("DISABLE");
|
|
484
484
|
});
|
|
485
485
|
|
|
486
|
-
it("should
|
|
486
|
+
it("should return structured error for invalid event name", async () => {
|
|
487
487
|
const tool = tools.find((t) => t.name === "mysql_event_create")!;
|
|
488
488
|
|
|
489
|
-
await
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
).
|
|
489
|
+
const result = await tool.handler(
|
|
490
|
+
{
|
|
491
|
+
name: "123-invalid",
|
|
492
|
+
schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
|
|
493
|
+
body: "SELECT 1",
|
|
494
|
+
},
|
|
495
|
+
mockContext,
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
expect(result).toEqual({ success: false, error: "Invalid event name" });
|
|
499
499
|
});
|
|
500
500
|
|
|
501
|
-
it("should
|
|
501
|
+
it("should return structured error when executeAt is missing for ONE TIME events", async () => {
|
|
502
502
|
const tool = tools.find((t) => t.name === "mysql_event_create")!;
|
|
503
503
|
|
|
504
|
-
await
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
).
|
|
504
|
+
const result = await tool.handler(
|
|
505
|
+
{
|
|
506
|
+
name: "bad_event",
|
|
507
|
+
schedule: { type: "ONE TIME" },
|
|
508
|
+
body: "SELECT 1",
|
|
509
|
+
},
|
|
510
|
+
mockContext,
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
expect(result).toEqual({
|
|
514
|
+
success: false,
|
|
515
|
+
error: "executeAt is required for ONE TIME events",
|
|
516
|
+
});
|
|
514
517
|
});
|
|
515
518
|
|
|
516
|
-
it("should
|
|
519
|
+
it("should return structured error when interval is missing for RECURRING events", async () => {
|
|
517
520
|
const tool = tools.find((t) => t.name === "mysql_event_create")!;
|
|
518
521
|
|
|
519
|
-
await
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
522
|
+
const result = await tool.handler(
|
|
523
|
+
{
|
|
524
|
+
name: "bad_recurring",
|
|
525
|
+
schedule: { type: "RECURRING" },
|
|
526
|
+
body: "SELECT 1",
|
|
527
|
+
},
|
|
528
|
+
mockContext,
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
expect(result).toEqual({
|
|
532
|
+
success: false,
|
|
533
|
+
error: "interval and intervalUnit are required for RECURRING events",
|
|
534
|
+
});
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
it("should return structured error for invalid schedule type on create", async () => {
|
|
538
|
+
const tool = tools.find((t) => t.name === "mysql_event_create")!;
|
|
539
|
+
|
|
540
|
+
const result = await tool.handler(
|
|
541
|
+
{
|
|
542
|
+
name: "my_event",
|
|
543
|
+
schedule: { type: "INVALID_TYPE" },
|
|
544
|
+
body: "SELECT 1",
|
|
545
|
+
},
|
|
546
|
+
mockContext,
|
|
547
|
+
);
|
|
548
|
+
|
|
549
|
+
expect(result).toHaveProperty("success", false);
|
|
550
|
+
expect(result).toHaveProperty("error");
|
|
551
|
+
expect((result as { error: string }).error).toContain(
|
|
552
|
+
"Invalid schedule type",
|
|
553
|
+
);
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
it("should return structured error for invalid onCompletion on create", async () => {
|
|
557
|
+
const tool = tools.find((t) => t.name === "mysql_event_create")!;
|
|
558
|
+
|
|
559
|
+
const result = await tool.handler(
|
|
560
|
+
{
|
|
561
|
+
name: "my_event",
|
|
562
|
+
schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
|
|
563
|
+
body: "SELECT 1",
|
|
564
|
+
onCompletion: "INVALID_VALUE",
|
|
565
|
+
},
|
|
566
|
+
mockContext,
|
|
567
|
+
);
|
|
568
|
+
|
|
569
|
+
expect(result).toHaveProperty("success", false);
|
|
570
|
+
expect(result).toHaveProperty("error");
|
|
571
|
+
expect((result as { error: string }).error).toContain(
|
|
572
|
+
"Invalid onCompletion",
|
|
573
|
+
);
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
it("should return structured error for invalid intervalUnit on create", async () => {
|
|
577
|
+
const tool = tools.find((t) => t.name === "mysql_event_create")!;
|
|
578
|
+
|
|
579
|
+
const result = await tool.handler(
|
|
580
|
+
{
|
|
581
|
+
name: "my_event",
|
|
582
|
+
schedule: {
|
|
583
|
+
type: "RECURRING",
|
|
584
|
+
interval: 1,
|
|
585
|
+
intervalUnit: "INVALID_UNIT",
|
|
525
586
|
},
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
587
|
+
body: "SELECT 1",
|
|
588
|
+
},
|
|
589
|
+
mockContext,
|
|
590
|
+
);
|
|
591
|
+
|
|
592
|
+
expect(result).toHaveProperty("success", false);
|
|
593
|
+
expect(result).toHaveProperty("error");
|
|
594
|
+
expect((result as { error: string }).error).toContain(
|
|
595
|
+
"Invalid intervalUnit",
|
|
596
|
+
);
|
|
529
597
|
});
|
|
530
598
|
});
|
|
531
599
|
|
|
@@ -629,73 +697,118 @@ describe("Event Alter Advanced", () => {
|
|
|
629
697
|
expect(call).toContain("COMMENT 'Updated comment'");
|
|
630
698
|
});
|
|
631
699
|
|
|
632
|
-
it("should
|
|
700
|
+
it("should return structured error for invalid event name", async () => {
|
|
633
701
|
const tool = tools.find((t) => t.name === "mysql_event_alter")!;
|
|
634
702
|
|
|
635
|
-
await
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
).
|
|
703
|
+
const result = await tool.handler(
|
|
704
|
+
{
|
|
705
|
+
name: "invalid-name",
|
|
706
|
+
enabled: true,
|
|
707
|
+
},
|
|
708
|
+
mockContext,
|
|
709
|
+
);
|
|
710
|
+
|
|
711
|
+
expect(result).toEqual({ success: false, error: "Invalid event name" });
|
|
644
712
|
});
|
|
645
713
|
|
|
646
|
-
it("should
|
|
714
|
+
it("should return structured error for invalid new event name", async () => {
|
|
647
715
|
const tool = tools.find((t) => t.name === "mysql_event_alter")!;
|
|
648
716
|
|
|
649
|
-
await
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
).
|
|
717
|
+
const result = await tool.handler(
|
|
718
|
+
{
|
|
719
|
+
name: "valid_name",
|
|
720
|
+
newName: "123-invalid",
|
|
721
|
+
},
|
|
722
|
+
mockContext,
|
|
723
|
+
);
|
|
724
|
+
|
|
725
|
+
expect(result).toEqual({ success: false, error: "Invalid new event name" });
|
|
658
726
|
});
|
|
659
727
|
|
|
660
|
-
it("should
|
|
728
|
+
it("should return structured error when no modifications specified", async () => {
|
|
661
729
|
const tool = tools.find((t) => t.name === "mysql_event_alter")!;
|
|
662
730
|
|
|
663
|
-
await
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
).
|
|
731
|
+
const result = await tool.handler(
|
|
732
|
+
{
|
|
733
|
+
name: "my_event",
|
|
734
|
+
},
|
|
735
|
+
mockContext,
|
|
736
|
+
);
|
|
737
|
+
|
|
738
|
+
expect(result).toEqual({
|
|
739
|
+
success: false,
|
|
740
|
+
error: "No modifications specified",
|
|
741
|
+
});
|
|
671
742
|
});
|
|
672
743
|
|
|
673
|
-
it("should
|
|
744
|
+
it("should return structured error when executeAt missing for ONE TIME alter", async () => {
|
|
674
745
|
const tool = tools.find((t) => t.name === "mysql_event_alter")!;
|
|
675
746
|
|
|
676
|
-
await
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
).
|
|
747
|
+
const result = await tool.handler(
|
|
748
|
+
{
|
|
749
|
+
name: "my_event",
|
|
750
|
+
schedule: { type: "ONE TIME" },
|
|
751
|
+
},
|
|
752
|
+
mockContext,
|
|
753
|
+
);
|
|
754
|
+
|
|
755
|
+
expect(result).toEqual({
|
|
756
|
+
success: false,
|
|
757
|
+
error: "executeAt is required for ONE TIME events",
|
|
758
|
+
});
|
|
685
759
|
});
|
|
686
760
|
|
|
687
|
-
it("should
|
|
761
|
+
it("should return structured error when interval missing for RECURRING alter", async () => {
|
|
688
762
|
const tool = tools.find((t) => t.name === "mysql_event_alter")!;
|
|
689
763
|
|
|
690
|
-
await
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
).
|
|
764
|
+
const result = await tool.handler(
|
|
765
|
+
{
|
|
766
|
+
name: "my_event",
|
|
767
|
+
schedule: { type: "RECURRING" },
|
|
768
|
+
},
|
|
769
|
+
mockContext,
|
|
770
|
+
);
|
|
771
|
+
|
|
772
|
+
expect(result).toEqual({
|
|
773
|
+
success: false,
|
|
774
|
+
error: "interval and intervalUnit are required for RECURRING events",
|
|
775
|
+
});
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
it("should return structured error for invalid onCompletion on alter", async () => {
|
|
779
|
+
const tool = tools.find((t) => t.name === "mysql_event_alter")!;
|
|
780
|
+
|
|
781
|
+
const result = await tool.handler(
|
|
782
|
+
{
|
|
783
|
+
name: "my_event",
|
|
784
|
+
onCompletion: "INVALID_VALUE",
|
|
785
|
+
},
|
|
786
|
+
mockContext,
|
|
787
|
+
);
|
|
788
|
+
|
|
789
|
+
expect(result).toHaveProperty("success", false);
|
|
790
|
+
expect(result).toHaveProperty("error");
|
|
791
|
+
expect((result as { error: string }).error).toContain(
|
|
792
|
+
"Invalid onCompletion",
|
|
793
|
+
);
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
it("should return structured error for invalid schedule type on alter", async () => {
|
|
797
|
+
const tool = tools.find((t) => t.name === "mysql_event_alter")!;
|
|
798
|
+
|
|
799
|
+
const result = await tool.handler(
|
|
800
|
+
{
|
|
801
|
+
name: "my_event",
|
|
802
|
+
schedule: { type: "INVALID_TYPE" },
|
|
803
|
+
},
|
|
804
|
+
mockContext,
|
|
805
|
+
);
|
|
806
|
+
|
|
807
|
+
expect(result).toHaveProperty("success", false);
|
|
808
|
+
expect(result).toHaveProperty("error");
|
|
809
|
+
expect((result as { error: string }).error).toContain(
|
|
810
|
+
"Invalid schedule type",
|
|
811
|
+
);
|
|
699
812
|
});
|
|
700
813
|
});
|
|
701
814
|
|
|
@@ -711,17 +824,17 @@ describe("Event Drop Advanced", () => {
|
|
|
711
824
|
mockContext = createMockRequestContext();
|
|
712
825
|
});
|
|
713
826
|
|
|
714
|
-
it("should
|
|
827
|
+
it("should return structured error for invalid event name", async () => {
|
|
715
828
|
const tool = tools.find((t) => t.name === "mysql_event_drop")!;
|
|
716
829
|
|
|
717
|
-
await
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
).
|
|
830
|
+
const result = await tool.handler(
|
|
831
|
+
{
|
|
832
|
+
name: "invalid-event-name",
|
|
833
|
+
},
|
|
834
|
+
mockContext,
|
|
835
|
+
);
|
|
836
|
+
|
|
837
|
+
expect(result).toEqual({ success: false, error: "Invalid event name" });
|
|
725
838
|
});
|
|
726
839
|
|
|
727
840
|
it("should drop without IF EXISTS when ifExists is false", async () => {
|
|
@@ -771,7 +884,7 @@ describe("Event Graceful Error Handling", () => {
|
|
|
771
884
|
|
|
772
885
|
expect(result).toEqual({
|
|
773
886
|
success: false,
|
|
774
|
-
|
|
887
|
+
error: "Event already exists",
|
|
775
888
|
});
|
|
776
889
|
});
|
|
777
890
|
|
|
@@ -792,7 +905,7 @@ describe("Event Graceful Error Handling", () => {
|
|
|
792
905
|
|
|
793
906
|
expect(result).toEqual({
|
|
794
907
|
success: false,
|
|
795
|
-
|
|
908
|
+
error: "Event does not exist",
|
|
796
909
|
});
|
|
797
910
|
});
|
|
798
911
|
|
|
@@ -813,23 +926,88 @@ describe("Event Graceful Error Handling", () => {
|
|
|
813
926
|
|
|
814
927
|
expect(result).toEqual({
|
|
815
928
|
success: false,
|
|
816
|
-
|
|
929
|
+
error: "Event does not exist",
|
|
817
930
|
});
|
|
818
931
|
});
|
|
819
932
|
|
|
820
|
-
it("should
|
|
933
|
+
it("should return structured error for unexpected errors from create", async () => {
|
|
821
934
|
mockAdapter.executeQuery.mockRejectedValue(new Error("Connection lost"));
|
|
822
935
|
|
|
823
936
|
const tool = tools.find((t) => t.name === "mysql_event_create")!;
|
|
824
|
-
await
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
937
|
+
const result = await tool.handler(
|
|
938
|
+
{
|
|
939
|
+
name: "my_event",
|
|
940
|
+
schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
|
|
941
|
+
body: "SELECT 1",
|
|
942
|
+
},
|
|
943
|
+
mockContext,
|
|
944
|
+
);
|
|
945
|
+
|
|
946
|
+
expect(result).toEqual({ success: false, error: "Connection lost" });
|
|
947
|
+
});
|
|
948
|
+
|
|
949
|
+
it("should strip error prefix from create error messages", async () => {
|
|
950
|
+
mockAdapter.executeQuery.mockRejectedValue(
|
|
951
|
+
new Error(
|
|
952
|
+
"Query failed: Execute failed: You have an error in your SQL syntax",
|
|
832
953
|
),
|
|
833
|
-
)
|
|
954
|
+
);
|
|
955
|
+
|
|
956
|
+
const tool = tools.find((t) => t.name === "mysql_event_create")!;
|
|
957
|
+
const result = await tool.handler(
|
|
958
|
+
{
|
|
959
|
+
name: "my_event",
|
|
960
|
+
schedule: { type: "ONE TIME", executeAt: "2024-12-31 23:59:59" },
|
|
961
|
+
body: "SELECTT * FROMM",
|
|
962
|
+
},
|
|
963
|
+
mockContext,
|
|
964
|
+
);
|
|
965
|
+
|
|
966
|
+
expect(result).toEqual({
|
|
967
|
+
success: false,
|
|
968
|
+
error: "You have an error in your SQL syntax",
|
|
969
|
+
});
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
it("should return structured error when event_list query fails", async () => {
|
|
973
|
+
mockAdapter.executeQuery.mockRejectedValue(
|
|
974
|
+
new Error("Connection lost during query"),
|
|
975
|
+
);
|
|
976
|
+
|
|
977
|
+
const tool = tools.find((t) => t.name === "mysql_event_list")!;
|
|
978
|
+
const result = await tool.handler({}, mockContext);
|
|
979
|
+
|
|
980
|
+
expect(result).toEqual({
|
|
981
|
+
success: false,
|
|
982
|
+
error: "Connection lost during query",
|
|
983
|
+
});
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
it("should return structured error when event_status query fails", async () => {
|
|
987
|
+
mockAdapter.executeQuery.mockRejectedValue(
|
|
988
|
+
new Error("Connection lost during query"),
|
|
989
|
+
);
|
|
990
|
+
|
|
991
|
+
const tool = tools.find((t) => t.name === "mysql_event_status")!;
|
|
992
|
+
const result = await tool.handler({ name: "test_event" }, mockContext);
|
|
993
|
+
|
|
994
|
+
expect(result).toEqual({
|
|
995
|
+
success: false,
|
|
996
|
+
error: "Connection lost during query",
|
|
997
|
+
});
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
it("should return structured error when scheduler_status query fails", async () => {
|
|
1001
|
+
mockAdapter.executeQuery.mockRejectedValue(
|
|
1002
|
+
new Error("Connection lost during query"),
|
|
1003
|
+
);
|
|
1004
|
+
|
|
1005
|
+
const tool = tools.find((t) => t.name === "mysql_scheduler_status")!;
|
|
1006
|
+
const result = await tool.handler({}, mockContext);
|
|
1007
|
+
|
|
1008
|
+
expect(result).toEqual({
|
|
1009
|
+
success: false,
|
|
1010
|
+
error: "Connection lost during query",
|
|
1011
|
+
});
|
|
834
1012
|
});
|
|
835
1013
|
});
|
|
@@ -34,8 +34,8 @@ describe("getProxySQLTools", () => {
|
|
|
34
34
|
);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
it("should return
|
|
38
|
-
expect(tools).toHaveLength(
|
|
37
|
+
it("should return 11 proxysql tools", () => {
|
|
38
|
+
expect(tools).toHaveLength(11);
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
it("should have proxysql group for all tools", () => {
|
|
@@ -60,7 +60,6 @@ describe("getProxySQLTools", () => {
|
|
|
60
60
|
const toolNames = tools.map((t) => t.name);
|
|
61
61
|
expect(toolNames).toContain("proxysql_status");
|
|
62
62
|
expect(toolNames).toContain("proxysql_servers");
|
|
63
|
-
expect(toolNames).toContain("proxysql_hostgroups");
|
|
64
63
|
expect(toolNames).toContain("proxysql_query_rules");
|
|
65
64
|
expect(toolNames).toContain("proxysql_query_digest");
|
|
66
65
|
expect(toolNames).toContain("proxysql_connection_pool");
|
|
@@ -313,26 +312,16 @@ describe("Handler Execution", () => {
|
|
|
313
312
|
);
|
|
314
313
|
expect(result).toHaveProperty("count", 1);
|
|
315
314
|
});
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
describe("proxysql_hostgroups", () => {
|
|
319
|
-
it("should return connection pool stats", async () => {
|
|
320
|
-
const mockPools = [
|
|
321
|
-
{ hostgroup: 1, srv_host: "mysql1", ConnUsed: 5, ConnFree: 10 },
|
|
322
|
-
];
|
|
323
|
-
mockQuery.mockResolvedValue([mockPools]);
|
|
324
315
|
|
|
325
|
-
|
|
326
|
-
const
|
|
316
|
+
it("should return structured error for negative hostgroup_id", async () => {
|
|
317
|
+
const tool = tools.find((t) => t.name === "proxysql_servers")!;
|
|
318
|
+
const result = (await tool.handler(
|
|
319
|
+
{ hostgroup_id: -1 },
|
|
320
|
+
mockContext,
|
|
321
|
+
)) as { success: boolean; error: string };
|
|
327
322
|
|
|
328
|
-
expect(
|
|
329
|
-
|
|
330
|
-
);
|
|
331
|
-
expect(result).toEqual({
|
|
332
|
-
success: true,
|
|
333
|
-
hostgroups: mockPools,
|
|
334
|
-
count: 1,
|
|
335
|
-
});
|
|
323
|
+
expect(result.success).toBe(false);
|
|
324
|
+
expect(result.error).toBeDefined();
|
|
336
325
|
});
|
|
337
326
|
});
|
|
338
327
|
|
|
@@ -360,6 +349,17 @@ describe("Handler Execution", () => {
|
|
|
360
349
|
"SELECT * FROM mysql_query_rules LIMIT 10",
|
|
361
350
|
);
|
|
362
351
|
});
|
|
352
|
+
|
|
353
|
+
it("should return structured error for negative limit", async () => {
|
|
354
|
+
const tool = tools.find((t) => t.name === "proxysql_query_rules")!;
|
|
355
|
+
const result = (await tool.handler({ limit: -1 }, mockContext)) as {
|
|
356
|
+
success: boolean;
|
|
357
|
+
error: string;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
expect(result.success).toBe(false);
|
|
361
|
+
expect(result.error).toBeDefined();
|
|
362
|
+
});
|
|
363
363
|
});
|
|
364
364
|
|
|
365
365
|
describe("proxysql_query_digest", () => {
|
|
@@ -393,6 +393,17 @@ describe("Handler Execution", () => {
|
|
|
393
393
|
expect.stringContaining("LIMIT 25"),
|
|
394
394
|
);
|
|
395
395
|
});
|
|
396
|
+
|
|
397
|
+
it("should return structured error for negative limit", async () => {
|
|
398
|
+
const tool = tools.find((t) => t.name === "proxysql_query_digest")!;
|
|
399
|
+
const result = (await tool.handler({ limit: -1 }, mockContext)) as {
|
|
400
|
+
success: boolean;
|
|
401
|
+
error: string;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
expect(result.success).toBe(false);
|
|
405
|
+
expect(result.error).toBeDefined();
|
|
406
|
+
});
|
|
396
407
|
});
|
|
397
408
|
|
|
398
409
|
describe("proxysql_connection_pool", () => {
|
|
@@ -419,6 +430,17 @@ describe("Handler Execution", () => {
|
|
|
419
430
|
"SELECT * FROM stats_mysql_connection_pool WHERE hostgroup = 2",
|
|
420
431
|
);
|
|
421
432
|
});
|
|
433
|
+
|
|
434
|
+
it("should return structured error for negative hostgroup_id", async () => {
|
|
435
|
+
const tool = tools.find((t) => t.name === "proxysql_connection_pool")!;
|
|
436
|
+
const result = (await tool.handler(
|
|
437
|
+
{ hostgroup_id: -1 },
|
|
438
|
+
mockContext,
|
|
439
|
+
)) as { success: boolean; error: string };
|
|
440
|
+
|
|
441
|
+
expect(result.success).toBe(false);
|
|
442
|
+
expect(result.error).toBeDefined();
|
|
443
|
+
});
|
|
422
444
|
});
|
|
423
445
|
|
|
424
446
|
describe("proxysql_users", () => {
|
|
@@ -557,6 +579,28 @@ describe("Handler Execution", () => {
|
|
|
557
579
|
// totalVarsAvailable should reflect total count
|
|
558
580
|
expect(result.totalVarsAvailable).toBe(4);
|
|
559
581
|
});
|
|
582
|
+
|
|
583
|
+
it("should return structured error for negative limit", async () => {
|
|
584
|
+
const tool = tools.find((t) => t.name === "proxysql_global_variables")!;
|
|
585
|
+
const result = (await tool.handler({ limit: -1 }, mockContext)) as {
|
|
586
|
+
success: boolean;
|
|
587
|
+
error: string;
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
expect(result.success).toBe(false);
|
|
591
|
+
expect(result.error).toBeDefined();
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it("should return structured error for unsafe like pattern", async () => {
|
|
595
|
+
const tool = tools.find((t) => t.name === "proxysql_global_variables")!;
|
|
596
|
+
const result = (await tool.handler(
|
|
597
|
+
{ like: "'; DROP TABLE --" },
|
|
598
|
+
mockContext,
|
|
599
|
+
)) as { success: boolean; error: string };
|
|
600
|
+
|
|
601
|
+
expect(result.success).toBe(false);
|
|
602
|
+
expect(result.error).toContain("Invalid like pattern");
|
|
603
|
+
});
|
|
560
604
|
});
|
|
561
605
|
|
|
562
606
|
describe("proxysql_memory_stats", () => {
|
|
@@ -633,26 +677,82 @@ describe("Connection Error Handling", () => {
|
|
|
633
677
|
mockContext = createMockRequestContext();
|
|
634
678
|
});
|
|
635
679
|
|
|
636
|
-
it("should
|
|
680
|
+
it("should return structured error on connection failure", async () => {
|
|
637
681
|
mockCreateConnection.mockRejectedValue(new Error("Connection refused"));
|
|
638
682
|
|
|
639
683
|
const tool = tools.find((t) => t.name === "proxysql_status")!;
|
|
684
|
+
const result = (await tool.handler({}, mockContext)) as {
|
|
685
|
+
success: boolean;
|
|
686
|
+
error: string;
|
|
687
|
+
};
|
|
640
688
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
);
|
|
689
|
+
expect(result.success).toBe(false);
|
|
690
|
+
expect(result.error).toContain("Connection refused");
|
|
644
691
|
});
|
|
645
692
|
|
|
646
|
-
it("should
|
|
693
|
+
it("should return structured error on query failure", async () => {
|
|
647
694
|
mockCreateConnection.mockResolvedValue({
|
|
648
695
|
query: vi.fn().mockRejectedValue(new Error("Access denied")),
|
|
649
696
|
end: mockEnd,
|
|
650
697
|
});
|
|
651
698
|
|
|
652
699
|
const tool = tools.find((t) => t.name === "proxysql_status")!;
|
|
700
|
+
const result = (await tool.handler({}, mockContext)) as {
|
|
701
|
+
success: boolean;
|
|
702
|
+
error: string;
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
expect(result.success).toBe(false);
|
|
706
|
+
expect(result.error).toContain("Access denied");
|
|
707
|
+
});
|
|
708
|
+
});
|
|
653
709
|
|
|
654
|
-
|
|
655
|
-
|
|
710
|
+
describe("Crash Tests (all 12 handlers)", () => {
|
|
711
|
+
let tools: ReturnType<typeof getProxySQLTools>;
|
|
712
|
+
let mockContext: ReturnType<typeof createMockRequestContext>;
|
|
713
|
+
|
|
714
|
+
beforeEach(() => {
|
|
715
|
+
vi.clearAllMocks();
|
|
716
|
+
tools = getProxySQLTools(
|
|
717
|
+
createMockMySQLAdapter() as unknown as MySQLAdapter,
|
|
656
718
|
);
|
|
719
|
+
mockContext = createMockRequestContext();
|
|
720
|
+
|
|
721
|
+
// All tools will fail on query
|
|
722
|
+
mockCreateConnection.mockResolvedValue({
|
|
723
|
+
query: vi.fn().mockRejectedValue(new Error("ProxySQL unavailable")),
|
|
724
|
+
end: mockEnd,
|
|
725
|
+
});
|
|
657
726
|
});
|
|
727
|
+
|
|
728
|
+
const toolNames = [
|
|
729
|
+
"proxysql_status",
|
|
730
|
+
"proxysql_runtime_status",
|
|
731
|
+
"proxysql_servers",
|
|
732
|
+
"proxysql_query_rules",
|
|
733
|
+
"proxysql_query_digest",
|
|
734
|
+
"proxysql_connection_pool",
|
|
735
|
+
"proxysql_users",
|
|
736
|
+
"proxysql_global_variables",
|
|
737
|
+
"proxysql_memory_stats",
|
|
738
|
+
"proxysql_commands",
|
|
739
|
+
"proxysql_process_list",
|
|
740
|
+
];
|
|
741
|
+
|
|
742
|
+
for (const toolName of toolNames) {
|
|
743
|
+
it(`${toolName} should return { success: false, error } on query failure`, async () => {
|
|
744
|
+
const tool = tools.find((t) => t.name === toolName)!;
|
|
745
|
+
const params =
|
|
746
|
+
toolName === "proxysql_commands"
|
|
747
|
+
? { command: "LOAD MYSQL USERS TO RUNTIME" }
|
|
748
|
+
: {};
|
|
749
|
+
const result = (await tool.handler(params, mockContext)) as {
|
|
750
|
+
success: boolean;
|
|
751
|
+
error: string;
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
expect(result.success).toBe(false);
|
|
755
|
+
expect(result.error).toContain("ProxySQL unavailable");
|
|
756
|
+
});
|
|
757
|
+
}
|
|
658
758
|
});
|