@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
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
* - Hard timeout enforcement (worker termination)
|
|
11
11
|
* - Isolated memory space
|
|
12
12
|
* - Clean process state on each execution
|
|
13
|
+
* - MessagePort-based RPC bridge for mysql.* API calls
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
|
-
import { Worker } from "node:worker_threads";
|
|
16
|
+
import { Worker, MessageChannel } from "node:worker_threads";
|
|
16
17
|
import { fileURLToPath } from "node:url";
|
|
17
18
|
import { dirname, join } from "node:path";
|
|
18
19
|
import { logger } from "../utils/logger.js";
|
|
@@ -23,6 +24,7 @@ import {
|
|
|
23
24
|
type PoolOptions,
|
|
24
25
|
type SandboxResult,
|
|
25
26
|
type ExecutionMetrics,
|
|
27
|
+
type RpcRequest,
|
|
26
28
|
} from "./types.js";
|
|
27
29
|
|
|
28
30
|
// Get directory for worker script
|
|
@@ -72,12 +74,17 @@ export class WorkerSandbox {
|
|
|
72
74
|
let worker: Worker | null = null;
|
|
73
75
|
let timeoutId: NodeJS.Timeout | null = null;
|
|
74
76
|
let resolved = false;
|
|
77
|
+
let rpcChannel: MessageChannel | null = null;
|
|
75
78
|
|
|
76
79
|
const cleanup = (): void => {
|
|
77
80
|
if (timeoutId) {
|
|
78
81
|
clearTimeout(timeoutId);
|
|
79
82
|
timeoutId = null;
|
|
80
83
|
}
|
|
84
|
+
if (rpcChannel) {
|
|
85
|
+
rpcChannel.port1.close();
|
|
86
|
+
rpcChannel = null;
|
|
87
|
+
}
|
|
81
88
|
if (worker) {
|
|
82
89
|
worker.terminate().catch((): void => {
|
|
83
90
|
/* intentionally empty */
|
|
@@ -94,11 +101,59 @@ export class WorkerSandbox {
|
|
|
94
101
|
};
|
|
95
102
|
|
|
96
103
|
try {
|
|
104
|
+
// Create MessageChannel for RPC bridge
|
|
105
|
+
rpcChannel = new MessageChannel();
|
|
106
|
+
const serialized = this.serializeBindings(apiBindings);
|
|
107
|
+
|
|
108
|
+
// Set up RPC listener on main thread side (port1)
|
|
109
|
+
rpcChannel.port1.on("message", (msg: RpcRequest) => {
|
|
110
|
+
const { id, group, method, args } = msg;
|
|
111
|
+
void (async () => {
|
|
112
|
+
try {
|
|
113
|
+
const groupApi = apiBindings[group];
|
|
114
|
+
if (
|
|
115
|
+
typeof groupApi !== "object" ||
|
|
116
|
+
groupApi === null ||
|
|
117
|
+
typeof groupApi === "function"
|
|
118
|
+
) {
|
|
119
|
+
rpcChannel?.port1.postMessage({
|
|
120
|
+
id,
|
|
121
|
+
error: `Unknown API group: '${group}'`,
|
|
122
|
+
});
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const fn = (groupApi as Record<string, unknown>)[method];
|
|
126
|
+
if (typeof fn !== "function") {
|
|
127
|
+
rpcChannel?.port1.postMessage({
|
|
128
|
+
id,
|
|
129
|
+
error: `Unknown method: '${group}.${method}'`,
|
|
130
|
+
});
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const result = await (
|
|
134
|
+
fn as (...a: unknown[]) => Promise<unknown>
|
|
135
|
+
)(...args);
|
|
136
|
+
rpcChannel?.port1.postMessage({ id, result });
|
|
137
|
+
} catch (error) {
|
|
138
|
+
rpcChannel?.port1.postMessage({
|
|
139
|
+
id,
|
|
140
|
+
error: error instanceof Error ? error.message : String(error),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
})();
|
|
144
|
+
});
|
|
145
|
+
|
|
97
146
|
worker = new Worker(WORKER_SCRIPT_PATH, {
|
|
98
147
|
workerData: {
|
|
99
148
|
code,
|
|
100
|
-
apiBindings:
|
|
149
|
+
apiBindings: serialized,
|
|
101
150
|
timeout: this.options.timeoutMs,
|
|
151
|
+
rpcPort: rpcChannel.port2,
|
|
152
|
+
},
|
|
153
|
+
transferList: [rpcChannel.port2],
|
|
154
|
+
resourceLimits: {
|
|
155
|
+
maxOldGenerationSizeMb: this.options.memoryLimitMb,
|
|
156
|
+
maxYoungGenerationSizeMb: Math.ceil(this.options.memoryLimitMb / 4),
|
|
102
157
|
},
|
|
103
158
|
});
|
|
104
159
|
|
|
@@ -194,18 +249,30 @@ export class WorkerSandbox {
|
|
|
194
249
|
}
|
|
195
250
|
|
|
196
251
|
/**
|
|
197
|
-
* Serialize API bindings for worker transfer
|
|
198
|
-
*
|
|
252
|
+
* Serialize API bindings for worker transfer.
|
|
253
|
+
* Sends group → method name arrays so the worker can build RPC proxy stubs.
|
|
254
|
+
* Top-level function keys (aliases like readQuery, help) are collected under "_topLevel".
|
|
199
255
|
*/
|
|
200
256
|
private serializeBindings(
|
|
201
257
|
bindings: Record<string, unknown>,
|
|
202
258
|
): Record<string, string[]> {
|
|
203
259
|
const serialized: Record<string, string[]> = {};
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
260
|
+
const topLevel: string[] = [];
|
|
261
|
+
|
|
262
|
+
for (const [key, value] of Object.entries(bindings)) {
|
|
263
|
+
if (typeof value === "object" && value !== null) {
|
|
264
|
+
// Group object — extract method names
|
|
265
|
+
serialized[key] = Object.keys(value);
|
|
266
|
+
} else if (typeof value === "function") {
|
|
267
|
+
// Top-level alias (e.g., readQuery, help)
|
|
268
|
+
topLevel.push(key);
|
|
207
269
|
}
|
|
208
270
|
}
|
|
271
|
+
|
|
272
|
+
if (topLevel.length > 0) {
|
|
273
|
+
serialized["_topLevel"] = topLevel;
|
|
274
|
+
}
|
|
275
|
+
|
|
209
276
|
return serialized;
|
|
210
277
|
}
|
|
211
278
|
|
|
@@ -3,15 +3,19 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This script runs in a worker thread to execute user code in isolation.
|
|
5
5
|
* It uses Node.js vm module within the worker for additional sandboxing.
|
|
6
|
+
*
|
|
7
|
+
* API calls (mysql.*) are proxied over a MessagePort RPC bridge to the
|
|
8
|
+
* main thread where the actual MySQLAdapter methods execute.
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
|
-
import { parentPort, workerData } from "node:worker_threads";
|
|
11
|
+
import { parentPort, workerData, type MessagePort } from "node:worker_threads";
|
|
9
12
|
import vm from "node:vm";
|
|
10
13
|
|
|
11
14
|
interface WorkerData {
|
|
12
15
|
code: string;
|
|
13
16
|
apiBindings: Record<string, string[]>;
|
|
14
17
|
timeout: number;
|
|
18
|
+
rpcPort: MessagePort;
|
|
15
19
|
}
|
|
16
20
|
|
|
17
21
|
interface WorkerResult {
|
|
@@ -21,87 +25,171 @@ interface WorkerResult {
|
|
|
21
25
|
stack?: string | undefined;
|
|
22
26
|
}
|
|
23
27
|
|
|
28
|
+
interface RpcResponse {
|
|
29
|
+
id: number;
|
|
30
|
+
result?: unknown;
|
|
31
|
+
error?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Build a proxy mysql object that forwards all method calls over the RPC port.
|
|
36
|
+
* The apiBindings provide group → method name arrays from the main thread.
|
|
37
|
+
* Each method becomes an async function that sends RPC and waits for response.
|
|
38
|
+
*/
|
|
39
|
+
function buildMysqlProxy(
|
|
40
|
+
bindings: Record<string, string[]>,
|
|
41
|
+
rpcPort: MessagePort,
|
|
42
|
+
): Record<string, unknown> {
|
|
43
|
+
const pending = new Map<
|
|
44
|
+
number,
|
|
45
|
+
{ resolve: (v: unknown) => void; reject: (e: Error) => void }
|
|
46
|
+
>();
|
|
47
|
+
let nextId = 0;
|
|
48
|
+
|
|
49
|
+
// Listen for RPC responses from the main thread
|
|
50
|
+
rpcPort.on("message", (msg: RpcResponse) => {
|
|
51
|
+
const p = pending.get(msg.id);
|
|
52
|
+
if (p) {
|
|
53
|
+
pending.delete(msg.id);
|
|
54
|
+
if (msg.error) {
|
|
55
|
+
p.reject(new Error(msg.error));
|
|
56
|
+
} else {
|
|
57
|
+
p.resolve(msg.result);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const mysql: Record<string, unknown> = {};
|
|
63
|
+
const groupNames: string[] = [];
|
|
64
|
+
|
|
65
|
+
for (const [key, methods] of Object.entries(bindings)) {
|
|
66
|
+
// Skip the special _topLevel key — handle separately below
|
|
67
|
+
if (key === "_topLevel") continue;
|
|
68
|
+
|
|
69
|
+
groupNames.push(key);
|
|
70
|
+
|
|
71
|
+
const groupApi: Record<string, unknown> = {};
|
|
72
|
+
for (const method of methods) {
|
|
73
|
+
if (method === "help") continue; // We build help separately
|
|
74
|
+
|
|
75
|
+
groupApi[method] = (...args: unknown[]): Promise<unknown> =>
|
|
76
|
+
new Promise((resolve, reject) => {
|
|
77
|
+
const id = nextId++;
|
|
78
|
+
pending.set(id, { resolve, reject });
|
|
79
|
+
rpcPort.postMessage({ id, group: key, method, args });
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Add help() for each group — returns method list
|
|
84
|
+
groupApi["help"] = (): { group: string; methods: string[] } => ({
|
|
85
|
+
group: key,
|
|
86
|
+
methods: methods.filter((m) => m !== "help"),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
mysql[key] = groupApi;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Handle top-level aliases (e.g., readQuery, help)
|
|
93
|
+
const topLevel = bindings["_topLevel"];
|
|
94
|
+
if (topLevel) {
|
|
95
|
+
for (const method of topLevel) {
|
|
96
|
+
if (method === "help") {
|
|
97
|
+
// Top-level help returns all groups
|
|
98
|
+
mysql["help"] = (): { groups: string[] } => ({
|
|
99
|
+
groups: groupNames,
|
|
100
|
+
});
|
|
101
|
+
} else {
|
|
102
|
+
// Top-level aliases forward via _topLevel group
|
|
103
|
+
mysql[method] = (...args: unknown[]): Promise<unknown> =>
|
|
104
|
+
new Promise((resolve, reject) => {
|
|
105
|
+
const id = nextId++;
|
|
106
|
+
pending.set(id, { resolve, reject });
|
|
107
|
+
rpcPort.postMessage({
|
|
108
|
+
id,
|
|
109
|
+
group: "_topLevel",
|
|
110
|
+
method,
|
|
111
|
+
args,
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// If no top-level help was set, add one
|
|
119
|
+
if (mysql["help"] === undefined) {
|
|
120
|
+
mysql["help"] = (): { groups: string[] } => ({
|
|
121
|
+
groups: groupNames,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return mysql;
|
|
126
|
+
}
|
|
127
|
+
|
|
24
128
|
/**
|
|
25
|
-
*
|
|
129
|
+
* Run user code in a vm context within the worker thread
|
|
26
130
|
*/
|
|
27
|
-
async function
|
|
28
|
-
const
|
|
131
|
+
async function executeInWorker(): Promise<void> {
|
|
132
|
+
const data = workerData as WorkerData;
|
|
133
|
+
const { code, apiBindings, timeout, rpcPort } = data;
|
|
29
134
|
|
|
30
135
|
try {
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
136
|
+
// Start receiving RPC responses
|
|
137
|
+
rpcPort.ref();
|
|
138
|
+
|
|
139
|
+
// Build the mysql proxy object with RPC bridge
|
|
140
|
+
const mysql = buildMysqlProxy(apiBindings, rpcPort);
|
|
141
|
+
|
|
142
|
+
// Create sandbox context
|
|
143
|
+
const sandbox: Record<string, unknown> = {
|
|
144
|
+
mysql,
|
|
34
145
|
console: {
|
|
35
|
-
log: (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
146
|
+
log: (): void => {
|
|
147
|
+
/* intentionally empty */
|
|
148
|
+
},
|
|
149
|
+
error: (): void => {
|
|
150
|
+
/* intentionally empty */
|
|
151
|
+
},
|
|
152
|
+
warn: (): void => {
|
|
153
|
+
/* intentionally empty */
|
|
154
|
+
},
|
|
155
|
+
info: (): void => {
|
|
156
|
+
/* intentionally empty */
|
|
157
|
+
},
|
|
158
|
+
debug: (): void => {
|
|
159
|
+
/* intentionally empty */
|
|
45
160
|
},
|
|
46
|
-
warn: (...args: unknown[]) =>
|
|
47
|
-
logBuffer.push("[WARN] " + args.map((a) => String(a)).join(" ")),
|
|
48
|
-
error: (...args: unknown[]) =>
|
|
49
|
-
logBuffer.push("[ERROR] " + args.map((a) => String(a)).join(" ")),
|
|
50
|
-
info: (...args: unknown[]) =>
|
|
51
|
-
logBuffer.push("[INFO] " + args.map((a) => String(a)).join(" ")),
|
|
52
161
|
},
|
|
53
|
-
// Block dangerous globals
|
|
54
|
-
require: undefined,
|
|
55
|
-
process: undefined,
|
|
56
|
-
global: undefined,
|
|
57
|
-
globalThis: undefined,
|
|
58
|
-
__dirname: undefined,
|
|
59
|
-
__filename: undefined,
|
|
60
|
-
module: undefined,
|
|
61
|
-
exports: undefined,
|
|
62
|
-
// Safe built-ins
|
|
63
|
-
JSON,
|
|
64
|
-
Math,
|
|
65
|
-
Date,
|
|
66
|
-
Array,
|
|
67
|
-
Object,
|
|
68
|
-
String,
|
|
69
|
-
Number,
|
|
70
|
-
Boolean,
|
|
71
|
-
Map,
|
|
72
|
-
Set,
|
|
73
|
-
Promise,
|
|
74
|
-
Error,
|
|
75
|
-
TypeError,
|
|
76
|
-
RangeError,
|
|
77
|
-
SyntaxError,
|
|
78
|
-
// Disabled for security
|
|
79
162
|
setTimeout: undefined,
|
|
80
163
|
setInterval: undefined,
|
|
81
164
|
setImmediate: undefined,
|
|
82
|
-
|
|
83
|
-
|
|
165
|
+
process: undefined,
|
|
166
|
+
require: undefined,
|
|
167
|
+
__dirname: undefined,
|
|
168
|
+
__filename: undefined,
|
|
169
|
+
globalThis: undefined,
|
|
170
|
+
global: undefined,
|
|
84
171
|
};
|
|
85
172
|
|
|
86
|
-
const context = vm.createContext(sandbox
|
|
173
|
+
const context = vm.createContext(sandbox, {
|
|
174
|
+
name: "worker-sandbox",
|
|
175
|
+
});
|
|
87
176
|
|
|
88
|
-
// Wrap
|
|
89
|
-
const wrappedCode = `
|
|
90
|
-
(async () => {
|
|
91
|
-
${code}
|
|
92
|
-
})();
|
|
93
|
-
`;
|
|
177
|
+
// Wrap in async IIFE for top-level await
|
|
178
|
+
const wrappedCode = `(async () => { ${code} })()`;
|
|
94
179
|
|
|
95
|
-
// Compile and run with timeout
|
|
96
180
|
const script = new vm.Script(wrappedCode, {
|
|
97
|
-
filename: "
|
|
181
|
+
filename: "user-code.js",
|
|
98
182
|
});
|
|
99
183
|
|
|
100
|
-
const result = await (script.runInContext(context, {
|
|
184
|
+
const result: unknown = await (script.runInContext(context, {
|
|
101
185
|
timeout,
|
|
102
|
-
|
|
186
|
+
displayErrors: true,
|
|
103
187
|
}) as Promise<unknown>);
|
|
104
188
|
|
|
189
|
+
// Close the RPC port before sending result
|
|
190
|
+
rpcPort.unref();
|
|
191
|
+
rpcPort.close();
|
|
192
|
+
|
|
105
193
|
const response: WorkerResult = {
|
|
106
194
|
success: true,
|
|
107
195
|
result,
|
|
@@ -109,36 +197,19 @@ async function executeCode(): Promise<void> {
|
|
|
109
197
|
|
|
110
198
|
parentPort?.postMessage(response);
|
|
111
199
|
} catch (error) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// Check for timeout
|
|
116
|
-
if (errorMessage.includes("Script execution timed out")) {
|
|
117
|
-
const response: WorkerResult = {
|
|
118
|
-
success: false,
|
|
119
|
-
error: `Execution timeout: exceeded ${String(timeout)}ms limit`,
|
|
120
|
-
stack,
|
|
121
|
-
};
|
|
122
|
-
parentPort?.postMessage(response);
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
200
|
+
// Close the RPC port before sending error
|
|
201
|
+
rpcPort.unref();
|
|
202
|
+
rpcPort.close();
|
|
125
203
|
|
|
126
204
|
const response: WorkerResult = {
|
|
127
205
|
success: false,
|
|
128
|
-
error:
|
|
129
|
-
stack,
|
|
206
|
+
error: error instanceof Error ? error.message : String(error),
|
|
207
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
130
208
|
};
|
|
131
209
|
|
|
132
210
|
parentPort?.postMessage(response);
|
|
133
211
|
}
|
|
134
212
|
}
|
|
135
213
|
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
const response: WorkerResult = {
|
|
139
|
-
success: false,
|
|
140
|
-
error: error instanceof Error ? error.message : String(error),
|
|
141
|
-
stack: error instanceof Error ? error.stack : undefined,
|
|
142
|
-
};
|
|
143
|
-
parentPort?.postMessage(response);
|
|
144
|
-
});
|
|
214
|
+
// Run immediately when worker starts
|
|
215
|
+
void executeInWorker();
|