@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
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
} from "../../../types/index.js";
|
|
16
16
|
import type { MySQLAdapter } from "../MySQLAdapter.js";
|
|
17
17
|
import https from "node:https";
|
|
18
|
+
import { ZodError } from "zod";
|
|
18
19
|
import {
|
|
19
20
|
RouterBaseInputSchema,
|
|
20
21
|
RouteNameInputSchema,
|
|
@@ -22,6 +23,15 @@ import {
|
|
|
22
23
|
ConnectionPoolNameInputSchema,
|
|
23
24
|
} from "../types/router-types.js";
|
|
24
25
|
|
|
26
|
+
// =============================================================================
|
|
27
|
+
// Helpers
|
|
28
|
+
// =============================================================================
|
|
29
|
+
|
|
30
|
+
/** Extract human-readable messages from a ZodError instead of raw JSON array */
|
|
31
|
+
function formatZodError(error: ZodError): string {
|
|
32
|
+
return error.issues.map((i) => i.message).join("; ");
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
// =============================================================================
|
|
26
36
|
// Router HTTP Client Helper
|
|
27
37
|
// =============================================================================
|
|
@@ -31,7 +41,7 @@ import {
|
|
|
31
41
|
*/
|
|
32
42
|
interface RouterUnavailableResponse {
|
|
33
43
|
available: false;
|
|
34
|
-
|
|
44
|
+
error: string;
|
|
35
45
|
}
|
|
36
46
|
|
|
37
47
|
/**
|
|
@@ -120,11 +130,11 @@ async function routerFetch(
|
|
|
120
130
|
reject(new Error(`Invalid JSON response: ${data}`));
|
|
121
131
|
}
|
|
122
132
|
} else {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
`Router API error: ${statusCode} ${res.statusMessage ?? "Unknown"}`,
|
|
126
|
-
),
|
|
133
|
+
const err = new Error(
|
|
134
|
+
`Router API error: ${statusCode} ${res.statusMessage ?? "Unknown"}`,
|
|
127
135
|
);
|
|
136
|
+
(err as Error & { statusCode: number }).statusCode = statusCode;
|
|
137
|
+
reject(err);
|
|
128
138
|
}
|
|
129
139
|
});
|
|
130
140
|
});
|
|
@@ -166,22 +176,38 @@ async function routerFetch(
|
|
|
166
176
|
|
|
167
177
|
/**
|
|
168
178
|
* Safe wrapper for routerFetch that returns graceful responses instead of throwing.
|
|
169
|
-
* Returns { success: true, data } on success or { success: false, response: { available: false,
|
|
179
|
+
* Returns { success: true, data } on success or { success: false, response: { available: false, error } } on failure.
|
|
180
|
+
* 404 responses (nonexistent route/metadata/pool) return { success: false, error } matching the standard error convention.
|
|
170
181
|
*/
|
|
171
182
|
async function safeRouterFetch<T>(path: string): Promise<SafeRouterResult<T>> {
|
|
172
183
|
try {
|
|
173
184
|
const data = (await routerFetch(path)) as T;
|
|
174
185
|
return { success: true, data };
|
|
175
186
|
} catch (error) {
|
|
176
|
-
const
|
|
187
|
+
const msg =
|
|
177
188
|
error instanceof Error
|
|
178
189
|
? error.message
|
|
179
190
|
: "Unknown error connecting to Router API";
|
|
191
|
+
// 404 = valid Router response for nonexistent route/metadata/pool
|
|
192
|
+
// Return { success: false, error } instead of { available: false } to
|
|
193
|
+
// distinguish "not found" from "Router is down"
|
|
194
|
+
if (
|
|
195
|
+
error instanceof Error &&
|
|
196
|
+
(error as Error & { statusCode?: number }).statusCode === 404
|
|
197
|
+
) {
|
|
198
|
+
return {
|
|
199
|
+
success: false,
|
|
200
|
+
response: {
|
|
201
|
+
success: false,
|
|
202
|
+
error: msg,
|
|
203
|
+
} as unknown as RouterUnavailableResponse,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
180
206
|
return {
|
|
181
207
|
success: false,
|
|
182
208
|
response: {
|
|
183
209
|
available: false,
|
|
184
|
-
|
|
210
|
+
error: msg,
|
|
185
211
|
},
|
|
186
212
|
};
|
|
187
213
|
}
|
|
@@ -294,18 +320,28 @@ function createRouterRouteStatusTool(): ToolDefinition {
|
|
|
294
320
|
openWorldHint: true,
|
|
295
321
|
},
|
|
296
322
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
323
|
+
try {
|
|
324
|
+
const { routeName } = RouteNameInputSchema.parse(params);
|
|
325
|
+
const result = await safeRouterFetch<unknown>(
|
|
326
|
+
`/routes/${encodeURIComponent(routeName)}/status`,
|
|
327
|
+
);
|
|
328
|
+
if (!result.success) {
|
|
329
|
+
return result.response;
|
|
330
|
+
}
|
|
331
|
+
return {
|
|
332
|
+
success: true,
|
|
333
|
+
routeName,
|
|
334
|
+
status: result.data,
|
|
335
|
+
};
|
|
336
|
+
} catch (error) {
|
|
337
|
+
if (error instanceof ZodError) {
|
|
338
|
+
return { success: false, error: formatZodError(error) };
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
success: false,
|
|
342
|
+
error: error instanceof Error ? error.message : String(error),
|
|
343
|
+
};
|
|
303
344
|
}
|
|
304
|
-
return {
|
|
305
|
-
success: true,
|
|
306
|
-
routeName,
|
|
307
|
-
status: result.data,
|
|
308
|
-
};
|
|
309
345
|
},
|
|
310
346
|
};
|
|
311
347
|
}
|
|
@@ -328,18 +364,28 @@ function createRouterRouteHealthTool(): ToolDefinition {
|
|
|
328
364
|
openWorldHint: true,
|
|
329
365
|
},
|
|
330
366
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
367
|
+
try {
|
|
368
|
+
const { routeName } = RouteNameInputSchema.parse(params);
|
|
369
|
+
const result = await safeRouterFetch<unknown>(
|
|
370
|
+
`/routes/${encodeURIComponent(routeName)}/health`,
|
|
371
|
+
);
|
|
372
|
+
if (!result.success) {
|
|
373
|
+
return result.response;
|
|
374
|
+
}
|
|
375
|
+
return {
|
|
376
|
+
success: true,
|
|
377
|
+
routeName,
|
|
378
|
+
health: result.data,
|
|
379
|
+
};
|
|
380
|
+
} catch (error) {
|
|
381
|
+
if (error instanceof ZodError) {
|
|
382
|
+
return { success: false, error: formatZodError(error) };
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
success: false,
|
|
386
|
+
error: error instanceof Error ? error.message : String(error),
|
|
387
|
+
};
|
|
337
388
|
}
|
|
338
|
-
return {
|
|
339
|
-
success: true,
|
|
340
|
-
routeName,
|
|
341
|
-
health: result.data,
|
|
342
|
-
};
|
|
343
389
|
},
|
|
344
390
|
};
|
|
345
391
|
}
|
|
@@ -362,18 +408,28 @@ function createRouterRouteConnectionsTool(): ToolDefinition {
|
|
|
362
408
|
openWorldHint: true,
|
|
363
409
|
},
|
|
364
410
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
411
|
+
try {
|
|
412
|
+
const { routeName } = RouteNameInputSchema.parse(params);
|
|
413
|
+
const result = await safeRouterFetch<unknown>(
|
|
414
|
+
`/routes/${encodeURIComponent(routeName)}/connections`,
|
|
415
|
+
);
|
|
416
|
+
if (!result.success) {
|
|
417
|
+
return result.response;
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
success: true,
|
|
421
|
+
routeName,
|
|
422
|
+
connections: result.data,
|
|
423
|
+
};
|
|
424
|
+
} catch (error) {
|
|
425
|
+
if (error instanceof ZodError) {
|
|
426
|
+
return { success: false, error: formatZodError(error) };
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
success: false,
|
|
430
|
+
error: error instanceof Error ? error.message : String(error),
|
|
431
|
+
};
|
|
371
432
|
}
|
|
372
|
-
return {
|
|
373
|
-
success: true,
|
|
374
|
-
routeName,
|
|
375
|
-
connections: result.data,
|
|
376
|
-
};
|
|
377
433
|
},
|
|
378
434
|
};
|
|
379
435
|
}
|
|
@@ -396,18 +452,28 @@ function createRouterRouteDestinationsTool(): ToolDefinition {
|
|
|
396
452
|
openWorldHint: true,
|
|
397
453
|
},
|
|
398
454
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
455
|
+
try {
|
|
456
|
+
const { routeName } = RouteNameInputSchema.parse(params);
|
|
457
|
+
const result = await safeRouterFetch<unknown>(
|
|
458
|
+
`/routes/${encodeURIComponent(routeName)}/destinations`,
|
|
459
|
+
);
|
|
460
|
+
if (!result.success) {
|
|
461
|
+
return result.response;
|
|
462
|
+
}
|
|
463
|
+
return {
|
|
464
|
+
success: true,
|
|
465
|
+
routeName,
|
|
466
|
+
destinations: result.data,
|
|
467
|
+
};
|
|
468
|
+
} catch (error) {
|
|
469
|
+
if (error instanceof ZodError) {
|
|
470
|
+
return { success: false, error: formatZodError(error) };
|
|
471
|
+
}
|
|
472
|
+
return {
|
|
473
|
+
success: false,
|
|
474
|
+
error: error instanceof Error ? error.message : String(error),
|
|
475
|
+
};
|
|
405
476
|
}
|
|
406
|
-
return {
|
|
407
|
-
success: true,
|
|
408
|
-
routeName,
|
|
409
|
-
destinations: result.data,
|
|
410
|
-
};
|
|
411
477
|
},
|
|
412
478
|
};
|
|
413
479
|
}
|
|
@@ -430,18 +496,28 @@ function createRouterRouteBlockedHostsTool(): ToolDefinition {
|
|
|
430
496
|
openWorldHint: true,
|
|
431
497
|
},
|
|
432
498
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
499
|
+
try {
|
|
500
|
+
const { routeName } = RouteNameInputSchema.parse(params);
|
|
501
|
+
const result = await safeRouterFetch<unknown>(
|
|
502
|
+
`/routes/${encodeURIComponent(routeName)}/blockedHosts`,
|
|
503
|
+
);
|
|
504
|
+
if (!result.success) {
|
|
505
|
+
return result.response;
|
|
506
|
+
}
|
|
507
|
+
return {
|
|
508
|
+
success: true,
|
|
509
|
+
routeName,
|
|
510
|
+
blockedHosts: result.data,
|
|
511
|
+
};
|
|
512
|
+
} catch (error) {
|
|
513
|
+
if (error instanceof ZodError) {
|
|
514
|
+
return { success: false, error: formatZodError(error) };
|
|
515
|
+
}
|
|
516
|
+
return {
|
|
517
|
+
success: false,
|
|
518
|
+
error: error instanceof Error ? error.message : String(error),
|
|
519
|
+
};
|
|
439
520
|
}
|
|
440
|
-
return {
|
|
441
|
-
success: true,
|
|
442
|
-
routeName,
|
|
443
|
-
blockedHosts: result.data,
|
|
444
|
-
};
|
|
445
521
|
},
|
|
446
522
|
};
|
|
447
523
|
}
|
|
@@ -468,18 +544,28 @@ function createRouterMetadataStatusTool(): ToolDefinition {
|
|
|
468
544
|
openWorldHint: true,
|
|
469
545
|
},
|
|
470
546
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
547
|
+
try {
|
|
548
|
+
const { metadataName } = MetadataNameInputSchema.parse(params);
|
|
549
|
+
const result = await safeRouterFetch<unknown>(
|
|
550
|
+
`/metadata/${encodeURIComponent(metadataName)}/status`,
|
|
551
|
+
);
|
|
552
|
+
if (!result.success) {
|
|
553
|
+
return result.response;
|
|
554
|
+
}
|
|
555
|
+
return {
|
|
556
|
+
success: true,
|
|
557
|
+
metadataName,
|
|
558
|
+
status: result.data,
|
|
559
|
+
};
|
|
560
|
+
} catch (error) {
|
|
561
|
+
if (error instanceof ZodError) {
|
|
562
|
+
return { success: false, error: formatZodError(error) };
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
success: false,
|
|
566
|
+
error: error instanceof Error ? error.message : String(error),
|
|
567
|
+
};
|
|
477
568
|
}
|
|
478
|
-
return {
|
|
479
|
-
success: true,
|
|
480
|
-
metadataName,
|
|
481
|
-
status: result.data,
|
|
482
|
-
};
|
|
483
569
|
},
|
|
484
570
|
};
|
|
485
571
|
}
|
|
@@ -506,18 +592,28 @@ function createRouterPoolStatusTool(): ToolDefinition {
|
|
|
506
592
|
openWorldHint: true,
|
|
507
593
|
},
|
|
508
594
|
handler: async (params: unknown, _context: RequestContext) => {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
595
|
+
try {
|
|
596
|
+
const { poolName } = ConnectionPoolNameInputSchema.parse(params);
|
|
597
|
+
const result = await safeRouterFetch<unknown>(
|
|
598
|
+
`/connection_pool/${encodeURIComponent(poolName)}/status`,
|
|
599
|
+
);
|
|
600
|
+
if (!result.success) {
|
|
601
|
+
return result.response;
|
|
602
|
+
}
|
|
603
|
+
return {
|
|
604
|
+
success: true,
|
|
605
|
+
poolName,
|
|
606
|
+
status: result.data,
|
|
607
|
+
};
|
|
608
|
+
} catch (error) {
|
|
609
|
+
if (error instanceof ZodError) {
|
|
610
|
+
return { success: false, error: formatZodError(error) };
|
|
611
|
+
}
|
|
612
|
+
return {
|
|
613
|
+
success: false,
|
|
614
|
+
error: error instanceof Error ? error.message : String(error),
|
|
615
|
+
};
|
|
515
616
|
}
|
|
516
|
-
return {
|
|
517
|
-
success: true,
|
|
518
|
-
poolName,
|
|
519
|
-
status: result.data,
|
|
520
|
-
};
|
|
521
617
|
},
|
|
522
618
|
};
|
|
523
619
|
}
|
|
@@ -162,5 +162,18 @@ describe("Schema Constraint Tools", () => {
|
|
|
162
162
|
// Should only call once (existence check), not the main query
|
|
163
163
|
expect(mockAdapter.executeQuery).toHaveBeenCalledTimes(1);
|
|
164
164
|
});
|
|
165
|
+
it("should return structured error for invalid constraint type", async () => {
|
|
166
|
+
const tool = createListConstraintsTool(
|
|
167
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
168
|
+
);
|
|
169
|
+
const result = (await tool.handler(
|
|
170
|
+
{ table: "users", type: "INVALID_TYPE" },
|
|
171
|
+
mockContext,
|
|
172
|
+
)) as { success: boolean; error: string };
|
|
173
|
+
|
|
174
|
+
expect(result.success).toBe(false);
|
|
175
|
+
expect(result.error).toBeDefined();
|
|
176
|
+
expect(mockAdapter.executeQuery).not.toHaveBeenCalled();
|
|
177
|
+
});
|
|
165
178
|
});
|
|
166
179
|
});
|
|
@@ -78,13 +78,43 @@ describe("Schema Management Tools", () => {
|
|
|
78
78
|
expect(result).toHaveProperty("success", true);
|
|
79
79
|
});
|
|
80
80
|
|
|
81
|
-
it("should
|
|
81
|
+
it("should return structured error for invalid schema names", async () => {
|
|
82
82
|
const tool = createCreateSchemaTool(
|
|
83
83
|
mockAdapter as unknown as MySQLAdapter,
|
|
84
84
|
);
|
|
85
|
-
await
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
const result = (await tool.handler(
|
|
86
|
+
{ name: "invalid-name" },
|
|
87
|
+
mockContext,
|
|
88
|
+
)) as { success: boolean; error: string };
|
|
89
|
+
|
|
90
|
+
expect(result.success).toBe(false);
|
|
91
|
+
expect(result.error).toBe("Invalid schema name");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should return structured error for invalid charset", async () => {
|
|
95
|
+
const tool = createCreateSchemaTool(
|
|
96
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
97
|
+
);
|
|
98
|
+
const result = (await tool.handler(
|
|
99
|
+
{ name: "valid_db", charset: "bad; DROP DATABASE" },
|
|
100
|
+
mockContext,
|
|
101
|
+
)) as { success: boolean; error: string };
|
|
102
|
+
|
|
103
|
+
expect(result.success).toBe(false);
|
|
104
|
+
expect(result.error).toContain("Invalid charset");
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("should return structured error for invalid collation", async () => {
|
|
108
|
+
const tool = createCreateSchemaTool(
|
|
109
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
110
|
+
);
|
|
111
|
+
const result = (await tool.handler(
|
|
112
|
+
{ name: "valid_db", collation: "bad; DROP DATABASE" },
|
|
113
|
+
mockContext,
|
|
114
|
+
)) as { success: boolean; error: string };
|
|
115
|
+
|
|
116
|
+
expect(result.success).toBe(false);
|
|
117
|
+
expect(result.error).toContain("Invalid collation");
|
|
88
118
|
});
|
|
89
119
|
|
|
90
120
|
it("should use custom charset and collation", async () => {
|
|
@@ -120,10 +150,10 @@ describe("Schema Management Tools", () => {
|
|
|
120
150
|
const result = (await tool.handler(
|
|
121
151
|
{ name: "existing_db", ifNotExists: false },
|
|
122
152
|
mockContext,
|
|
123
|
-
)) as { success: boolean;
|
|
153
|
+
)) as { success: boolean; error: string };
|
|
124
154
|
|
|
125
155
|
expect(result.success).toBe(false);
|
|
126
|
-
expect(result.
|
|
156
|
+
expect(result.error).toContain("already exists");
|
|
127
157
|
});
|
|
128
158
|
|
|
129
159
|
it("should return skipped when schema already exists with ifNotExists", async () => {
|
|
@@ -172,28 +202,33 @@ describe("Schema Management Tools", () => {
|
|
|
172
202
|
expect(result).toHaveProperty("success", true);
|
|
173
203
|
});
|
|
174
204
|
|
|
175
|
-
it("should
|
|
205
|
+
it("should return structured error for system schemas", async () => {
|
|
176
206
|
const tool = createDropSchemaTool(mockAdapter as unknown as MySQLAdapter);
|
|
177
207
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
208
|
+
for (const name of [
|
|
209
|
+
"mysql",
|
|
210
|
+
"information_schema",
|
|
211
|
+
"performance_schema",
|
|
212
|
+
"sys",
|
|
213
|
+
]) {
|
|
214
|
+
const result = (await tool.handler({ name }, mockContext)) as {
|
|
215
|
+
success: boolean;
|
|
216
|
+
error: string;
|
|
217
|
+
};
|
|
218
|
+
expect(result.success).toBe(false);
|
|
219
|
+
expect(result.error).toBe("Cannot drop system schema");
|
|
220
|
+
}
|
|
190
221
|
});
|
|
191
222
|
|
|
192
|
-
it("should
|
|
223
|
+
it("should return structured error for invalid schema names", async () => {
|
|
193
224
|
const tool = createDropSchemaTool(mockAdapter as unknown as MySQLAdapter);
|
|
194
|
-
await
|
|
195
|
-
|
|
196
|
-
|
|
225
|
+
const result = (await tool.handler(
|
|
226
|
+
{ name: "invalid-db" },
|
|
227
|
+
mockContext,
|
|
228
|
+
)) as { success: boolean; error: string };
|
|
229
|
+
|
|
230
|
+
expect(result.success).toBe(false);
|
|
231
|
+
expect(result.error).toBe("Invalid schema name");
|
|
197
232
|
});
|
|
198
233
|
|
|
199
234
|
it("should drop schema without IF EXISTS if requested", async () => {
|
|
@@ -215,10 +250,10 @@ describe("Schema Management Tools", () => {
|
|
|
215
250
|
const result = (await tool.handler(
|
|
216
251
|
{ name: "gone_db", ifExists: false },
|
|
217
252
|
mockContext,
|
|
218
|
-
)) as { success: boolean;
|
|
253
|
+
)) as { success: boolean; error: string };
|
|
219
254
|
|
|
220
255
|
expect(result.success).toBe(false);
|
|
221
|
-
expect(result.
|
|
256
|
+
expect(result.error).toContain("does not exist");
|
|
222
257
|
});
|
|
223
258
|
|
|
224
259
|
it("should return skipped when schema does not exist with ifExists", async () => {
|
|
@@ -59,5 +59,16 @@ describe("Schema Event Tools", () => {
|
|
|
59
59
|
const params = mockAdapter.executeQuery.mock.calls[0][1] as unknown[];
|
|
60
60
|
expect(params).toContain("ENABLED");
|
|
61
61
|
});
|
|
62
|
+
it("should return structured error for invalid status", async () => {
|
|
63
|
+
const tool = createListEventsTool(mockAdapter as unknown as MySQLAdapter);
|
|
64
|
+
const result = (await tool.handler(
|
|
65
|
+
{ status: "INVALID_STATUS" },
|
|
66
|
+
mockContext,
|
|
67
|
+
)) as { success: boolean; error: string };
|
|
68
|
+
|
|
69
|
+
expect(result.success).toBe(false);
|
|
70
|
+
expect(result.error).toBeDefined();
|
|
71
|
+
expect(mockAdapter.executeQuery).not.toHaveBeenCalled();
|
|
72
|
+
});
|
|
62
73
|
});
|
|
63
74
|
});
|
|
@@ -51,18 +51,39 @@ describe("Schema Trigger Tools", () => {
|
|
|
51
51
|
expect(result.schema).toBe("nonexistent_db");
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
+
it("should return exists false for nonexistent table", async () => {
|
|
55
|
+
// Table existence check returns empty
|
|
56
|
+
mockAdapter.executeQuery.mockResolvedValueOnce(createMockQueryResult([]));
|
|
57
|
+
|
|
58
|
+
const tool = createListTriggersTool(
|
|
59
|
+
mockAdapter as unknown as MySQLAdapter,
|
|
60
|
+
);
|
|
61
|
+
const result = (await tool.handler(
|
|
62
|
+
{ table: "nonexistent_table" },
|
|
63
|
+
mockContext,
|
|
64
|
+
)) as { exists: boolean; table: string };
|
|
65
|
+
|
|
66
|
+
expect(result.exists).toBe(false);
|
|
67
|
+
expect(result.table).toBe("nonexistent_table");
|
|
68
|
+
});
|
|
69
|
+
|
|
54
70
|
it("should filter by table when provided", async () => {
|
|
55
|
-
|
|
71
|
+
// Table existence check returns a row
|
|
72
|
+
mockAdapter.executeQuery.mockResolvedValueOnce(
|
|
73
|
+
createMockQueryResult([{ TABLE_NAME: "users" }]),
|
|
74
|
+
);
|
|
75
|
+
// Triggers query returns empty
|
|
76
|
+
mockAdapter.executeQuery.mockResolvedValueOnce(createMockQueryResult([]));
|
|
56
77
|
|
|
57
78
|
const tool = createListTriggersTool(
|
|
58
79
|
mockAdapter as unknown as MySQLAdapter,
|
|
59
80
|
);
|
|
60
81
|
await tool.handler({ table: "users" }, mockContext);
|
|
61
82
|
|
|
62
|
-
expect(mockAdapter.executeQuery).
|
|
63
|
-
const call = mockAdapter.executeQuery.mock.calls[
|
|
83
|
+
expect(mockAdapter.executeQuery).toHaveBeenCalledTimes(2);
|
|
84
|
+
const call = mockAdapter.executeQuery.mock.calls[1][0] as string;
|
|
64
85
|
expect(call).toContain("EVENT_OBJECT_TABLE = ?");
|
|
65
|
-
const params = mockAdapter.executeQuery.mock.calls[
|
|
86
|
+
const params = mockAdapter.executeQuery.mock.calls[1][1] as unknown[];
|
|
66
87
|
expect(params).toContain("users");
|
|
67
88
|
});
|
|
68
89
|
});
|
|
@@ -85,17 +85,18 @@ describe("Schema View Tools", () => {
|
|
|
85
85
|
expect(call).toContain("OR REPLACE");
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
-
it("should
|
|
88
|
+
it("should return structured error for invalid view name", async () => {
|
|
89
89
|
const tool = createCreateViewTool(mockAdapter as unknown as MySQLAdapter);
|
|
90
|
-
await
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
).
|
|
90
|
+
const result = (await tool.handler(
|
|
91
|
+
{
|
|
92
|
+
name: "invalid-name",
|
|
93
|
+
definition: "SELECT 1",
|
|
94
|
+
},
|
|
95
|
+
mockContext,
|
|
96
|
+
)) as { success: boolean; error: string };
|
|
97
|
+
|
|
98
|
+
expect(result.success).toBe(false);
|
|
99
|
+
expect(result.error).toContain("Invalid view name");
|
|
99
100
|
});
|
|
100
101
|
|
|
101
102
|
it("should include WITH CHECK OPTION when specified", async () => {
|
|
@@ -127,10 +128,10 @@ describe("Schema View Tools", () => {
|
|
|
127
128
|
definition: "SELECT 1",
|
|
128
129
|
},
|
|
129
130
|
mockContext,
|
|
130
|
-
)) as { success: boolean;
|
|
131
|
+
)) as { success: boolean; error: string };
|
|
131
132
|
|
|
132
133
|
expect(result.success).toBe(false);
|
|
133
|
-
expect(result.
|
|
134
|
+
expect(result.error).toContain("already exists");
|
|
134
135
|
});
|
|
135
136
|
|
|
136
137
|
it("should return success false for invalid SQL definition", async () => {
|
|
@@ -145,10 +146,41 @@ describe("Schema View Tools", () => {
|
|
|
145
146
|
definition: "SELECT * FROM nonexistent_table",
|
|
146
147
|
},
|
|
147
148
|
mockContext,
|
|
148
|
-
)) as { success: boolean;
|
|
149
|
+
)) as { success: boolean; error: string };
|
|
150
|
+
|
|
151
|
+
expect(result.success).toBe(false);
|
|
152
|
+
expect(result.error).toContain("doesn't exist");
|
|
153
|
+
});
|
|
154
|
+
it("should return structured error for invalid algorithm", async () => {
|
|
155
|
+
const tool = createCreateViewTool(mockAdapter as unknown as MySQLAdapter);
|
|
156
|
+
const result = (await tool.handler(
|
|
157
|
+
{
|
|
158
|
+
name: "test_view",
|
|
159
|
+
definition: "SELECT 1",
|
|
160
|
+
algorithm: "INVALID",
|
|
161
|
+
},
|
|
162
|
+
mockContext,
|
|
163
|
+
)) as { success: boolean; error: string };
|
|
164
|
+
|
|
165
|
+
expect(result.success).toBe(false);
|
|
166
|
+
expect(result.error).toBeDefined();
|
|
167
|
+
expect(mockAdapter.executeQuery).not.toHaveBeenCalled();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("should return structured error for invalid checkOption", async () => {
|
|
171
|
+
const tool = createCreateViewTool(mockAdapter as unknown as MySQLAdapter);
|
|
172
|
+
const result = (await tool.handler(
|
|
173
|
+
{
|
|
174
|
+
name: "test_view",
|
|
175
|
+
definition: "SELECT 1",
|
|
176
|
+
checkOption: "BAD",
|
|
177
|
+
},
|
|
178
|
+
mockContext,
|
|
179
|
+
)) as { success: boolean; error: string };
|
|
149
180
|
|
|
150
181
|
expect(result.success).toBe(false);
|
|
151
|
-
expect(result.
|
|
182
|
+
expect(result.error).toBeDefined();
|
|
183
|
+
expect(mockAdapter.executeQuery).not.toHaveBeenCalled();
|
|
152
184
|
});
|
|
153
185
|
});
|
|
154
186
|
});
|