mongo.do 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.d.ts +1 -15
- package/dist/cli/index.js +4083 -196
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +2740 -20
- package/dist/index.js +9375 -27
- package/dist/index.js.map +1 -1
- package/dist/worker-entrypoint-BEW23Gmp.d.ts +1331 -0
- package/dist/worker.d.ts +6 -5
- package/dist/worker.js +5477 -18
- package/dist/worker.js.map +1 -1
- package/package.json +3 -2
- package/dist/agentfs/adapters/anthropic.d.ts +0 -176
- package/dist/agentfs/adapters/anthropic.d.ts.map +0 -1
- package/dist/agentfs/adapters/anthropic.js +0 -629
- package/dist/agentfs/adapters/anthropic.js.map +0 -1
- package/dist/agentfs/adapters/index.d.ts +0 -21
- package/dist/agentfs/adapters/index.d.ts.map +0 -1
- package/dist/agentfs/adapters/index.js +0 -23
- package/dist/agentfs/adapters/index.js.map +0 -1
- package/dist/agentfs/adapters/vercel.d.ts +0 -260
- package/dist/agentfs/adapters/vercel.d.ts.map +0 -1
- package/dist/agentfs/adapters/vercel.js +0 -288
- package/dist/agentfs/adapters/vercel.js.map +0 -1
- package/dist/agentfs/glob.d.ts +0 -116
- package/dist/agentfs/glob.d.ts.map +0 -1
- package/dist/agentfs/glob.js +0 -270
- package/dist/agentfs/glob.js.map +0 -1
- package/dist/agentfs/grep.d.ts +0 -83
- package/dist/agentfs/grep.d.ts.map +0 -1
- package/dist/agentfs/grep.js +0 -193
- package/dist/agentfs/grep.js.map +0 -1
- package/dist/agentfs/index.d.ts +0 -22
- package/dist/agentfs/index.d.ts.map +0 -1
- package/dist/agentfs/index.js +0 -18
- package/dist/agentfs/index.js.map +0 -1
- package/dist/agentfs/kv-store.d.ts +0 -128
- package/dist/agentfs/kv-store.d.ts.map +0 -1
- package/dist/agentfs/kv-store.js +0 -227
- package/dist/agentfs/kv-store.js.map +0 -1
- package/dist/agentfs/mondo-agent.d.ts +0 -255
- package/dist/agentfs/mondo-agent.d.ts.map +0 -1
- package/dist/agentfs/mondo-agent.js +0 -879
- package/dist/agentfs/mondo-agent.js.map +0 -1
- package/dist/agentfs/toolcalls.d.ts +0 -130
- package/dist/agentfs/toolcalls.d.ts.map +0 -1
- package/dist/agentfs/toolcalls.js +0 -178
- package/dist/agentfs/toolcalls.js.map +0 -1
- package/dist/agentfs/types.d.ts +0 -171
- package/dist/agentfs/types.d.ts.map +0 -1
- package/dist/agentfs/types.js +0 -7
- package/dist/agentfs/types.js.map +0 -1
- package/dist/agentfs/vfs.d.ts +0 -249
- package/dist/agentfs/vfs.d.ts.map +0 -1
- package/dist/agentfs/vfs.js +0 -469
- package/dist/agentfs/vfs.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/mcp.d.ts +0 -119
- package/dist/cli/mcp.d.ts.map +0 -1
- package/dist/cli/mcp.js +0 -418
- package/dist/cli/mcp.js.map +0 -1
- package/dist/cli/server.d.ts +0 -179
- package/dist/cli/server.d.ts.map +0 -1
- package/dist/cli/server.js +0 -441
- package/dist/cli/server.js.map +0 -1
- package/dist/client/Collection.d.ts +0 -199
- package/dist/client/Collection.d.ts.map +0 -1
- package/dist/client/Collection.js +0 -256
- package/dist/client/Collection.js.map +0 -1
- package/dist/client/Database.d.ts +0 -68
- package/dist/client/Database.d.ts.map +0 -1
- package/dist/client/Database.js +0 -105
- package/dist/client/Database.js.map +0 -1
- package/dist/client/MongoClient.d.ts +0 -165
- package/dist/client/MongoClient.d.ts.map +0 -1
- package/dist/client/MongoClient.js +0 -307
- package/dist/client/MongoClient.js.map +0 -1
- package/dist/client/aggregation-cursor.d.ts +0 -210
- package/dist/client/aggregation-cursor.d.ts.map +0 -1
- package/dist/client/aggregation-cursor.js +0 -509
- package/dist/client/aggregation-cursor.js.map +0 -1
- package/dist/client/bulk-write.d.ts +0 -216
- package/dist/client/bulk-write.d.ts.map +0 -1
- package/dist/client/bulk-write.js +0 -63
- package/dist/client/bulk-write.js.map +0 -1
- package/dist/client/change-stream.d.ts +0 -245
- package/dist/client/change-stream.d.ts.map +0 -1
- package/dist/client/change-stream.js +0 -429
- package/dist/client/change-stream.js.map +0 -1
- package/dist/client/cursor.d.ts +0 -85
- package/dist/client/cursor.d.ts.map +0 -1
- package/dist/client/cursor.js +0 -156
- package/dist/client/cursor.js.map +0 -1
- package/dist/client/http-cursor.d.ts +0 -233
- package/dist/client/http-cursor.d.ts.map +0 -1
- package/dist/client/http-cursor.js +0 -496
- package/dist/client/http-cursor.js.map +0 -1
- package/dist/client/index.d.ts +0 -18
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -24
- package/dist/client/index.js.map +0 -1
- package/dist/client/mongo-client.d.ts +0 -60
- package/dist/client/mongo-client.d.ts.map +0 -1
- package/dist/client/mongo-client.js +0 -190
- package/dist/client/mongo-client.js.map +0 -1
- package/dist/client/mongo-collection.d.ts +0 -359
- package/dist/client/mongo-collection.d.ts.map +0 -1
- package/dist/client/mongo-collection.js +0 -1641
- package/dist/client/mongo-collection.js.map +0 -1
- package/dist/client/mongo-cursor.d.ts +0 -257
- package/dist/client/mongo-cursor.d.ts.map +0 -1
- package/dist/client/mongo-cursor.js +0 -621
- package/dist/client/mongo-cursor.js.map +0 -1
- package/dist/client/mongo-database.d.ts +0 -88
- package/dist/client/mongo-database.d.ts.map +0 -1
- package/dist/client/mongo-database.js +0 -139
- package/dist/client/mongo-database.js.map +0 -1
- package/dist/client/session.d.ts +0 -210
- package/dist/client/session.d.ts.map +0 -1
- package/dist/client/session.js +0 -326
- package/dist/client/session.js.map +0 -1
- package/dist/durable-object/index-manager.d.ts +0 -173
- package/dist/durable-object/index-manager.d.ts.map +0 -1
- package/dist/durable-object/index-manager.js +0 -764
- package/dist/durable-object/index-manager.js.map +0 -1
- package/dist/durable-object/index.d.ts +0 -12
- package/dist/durable-object/index.d.ts.map +0 -1
- package/dist/durable-object/index.js +0 -8
- package/dist/durable-object/index.js.map +0 -1
- package/dist/durable-object/mcp-handler.d.ts +0 -52
- package/dist/durable-object/mcp-handler.d.ts.map +0 -1
- package/dist/durable-object/mcp-handler.js +0 -186
- package/dist/durable-object/mcp-handler.js.map +0 -1
- package/dist/durable-object/migrations.d.ts +0 -40
- package/dist/durable-object/migrations.d.ts.map +0 -1
- package/dist/durable-object/migrations.js +0 -121
- package/dist/durable-object/migrations.js.map +0 -1
- package/dist/durable-object/mondo-database.d.ts +0 -148
- package/dist/durable-object/mondo-database.d.ts.map +0 -1
- package/dist/durable-object/mondo-database.js +0 -621
- package/dist/durable-object/mondo-database.js.map +0 -1
- package/dist/durable-object/schema.d.ts +0 -192
- package/dist/durable-object/schema.d.ts.map +0 -1
- package/dist/durable-object/schema.js +0 -186
- package/dist/durable-object/schema.js.map +0 -1
- package/dist/embedding/document-serializer.d.ts +0 -118
- package/dist/embedding/document-serializer.d.ts.map +0 -1
- package/dist/embedding/document-serializer.js +0 -339
- package/dist/embedding/document-serializer.js.map +0 -1
- package/dist/embedding/embedding-manager.d.ts +0 -136
- package/dist/embedding/embedding-manager.d.ts.map +0 -1
- package/dist/embedding/embedding-manager.js +0 -176
- package/dist/embedding/embedding-manager.js.map +0 -1
- package/dist/embedding/index.d.ts +0 -9
- package/dist/embedding/index.d.ts.map +0 -1
- package/dist/embedding/index.js +0 -9
- package/dist/embedding/index.js.map +0 -1
- package/dist/executor/aggregation-executor.d.ts +0 -93
- package/dist/executor/aggregation-executor.d.ts.map +0 -1
- package/dist/executor/aggregation-executor.js +0 -275
- package/dist/executor/aggregation-executor.js.map +0 -1
- package/dist/executor/function-executor.d.ts +0 -39
- package/dist/executor/function-executor.d.ts.map +0 -1
- package/dist/executor/function-executor.js +0 -168
- package/dist/executor/function-executor.js.map +0 -1
- package/dist/executor/index.d.ts +0 -4
- package/dist/executor/index.d.ts.map +0 -1
- package/dist/executor/index.js +0 -4
- package/dist/executor/index.js.map +0 -1
- package/dist/executor/vector-search-executor.d.ts +0 -71
- package/dist/executor/vector-search-executor.d.ts.map +0 -1
- package/dist/executor/vector-search-executor.js +0 -113
- package/dist/executor/vector-search-executor.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mcp/adapters/anthropic-adapter.d.ts +0 -256
- package/dist/mcp/adapters/anthropic-adapter.d.ts.map +0 -1
- package/dist/mcp/adapters/anthropic-adapter.js +0 -409
- package/dist/mcp/adapters/anthropic-adapter.js.map +0 -1
- package/dist/mcp/adapters/base-adapter.d.ts +0 -164
- package/dist/mcp/adapters/base-adapter.d.ts.map +0 -1
- package/dist/mcp/adapters/base-adapter.js +0 -277
- package/dist/mcp/adapters/base-adapter.js.map +0 -1
- package/dist/mcp/adapters/errors.d.ts +0 -173
- package/dist/mcp/adapters/errors.d.ts.map +0 -1
- package/dist/mcp/adapters/errors.js +0 -305
- package/dist/mcp/adapters/errors.js.map +0 -1
- package/dist/mcp/adapters/index.d.ts +0 -65
- package/dist/mcp/adapters/index.d.ts.map +0 -1
- package/dist/mcp/adapters/index.js +0 -92
- package/dist/mcp/adapters/index.js.map +0 -1
- package/dist/mcp/adapters/streaming.d.ts +0 -200
- package/dist/mcp/adapters/streaming.d.ts.map +0 -1
- package/dist/mcp/adapters/streaming.js +0 -381
- package/dist/mcp/adapters/streaming.js.map +0 -1
- package/dist/mcp/adapters/vercel-adapter.d.ts +0 -321
- package/dist/mcp/adapters/vercel-adapter.d.ts.map +0 -1
- package/dist/mcp/adapters/vercel-adapter.js +0 -487
- package/dist/mcp/adapters/vercel-adapter.js.map +0 -1
- package/dist/mcp/agent.d.ts +0 -192
- package/dist/mcp/agent.d.ts.map +0 -1
- package/dist/mcp/agent.js +0 -338
- package/dist/mcp/agent.js.map +0 -1
- package/dist/mcp/cli.d.ts +0 -71
- package/dist/mcp/cli.d.ts.map +0 -1
- package/dist/mcp/cli.js +0 -218
- package/dist/mcp/cli.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -15
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js +0 -20
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/sandbox/database-proxy.d.ts +0 -118
- package/dist/mcp/sandbox/database-proxy.d.ts.map +0 -1
- package/dist/mcp/sandbox/database-proxy.js +0 -154
- package/dist/mcp/sandbox/database-proxy.js.map +0 -1
- package/dist/mcp/sandbox/index.d.ts +0 -8
- package/dist/mcp/sandbox/index.d.ts.map +0 -1
- package/dist/mcp/sandbox/index.js +0 -7
- package/dist/mcp/sandbox/index.js.map +0 -1
- package/dist/mcp/sandbox/miniflare-evaluator.d.ts +0 -72
- package/dist/mcp/sandbox/miniflare-evaluator.d.ts.map +0 -1
- package/dist/mcp/sandbox/miniflare-evaluator.js +0 -379
- package/dist/mcp/sandbox/miniflare-evaluator.js.map +0 -1
- package/dist/mcp/sandbox/template.d.ts +0 -48
- package/dist/mcp/sandbox/template.d.ts.map +0 -1
- package/dist/mcp/sandbox/template.js +0 -147
- package/dist/mcp/sandbox/template.js.map +0 -1
- package/dist/mcp/sandbox/worker-evaluator.d.ts +0 -160
- package/dist/mcp/sandbox/worker-evaluator.d.ts.map +0 -1
- package/dist/mcp/sandbox/worker-evaluator.js +0 -217
- package/dist/mcp/sandbox/worker-evaluator.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -75
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js +0 -278
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/tool-call-auditor.d.ts +0 -188
- package/dist/mcp/tool-call-auditor.d.ts.map +0 -1
- package/dist/mcp/tool-call-auditor.js +0 -198
- package/dist/mcp/tool-call-auditor.js.map +0 -1
- package/dist/mcp/tools/do.d.ts +0 -51
- package/dist/mcp/tools/do.d.ts.map +0 -1
- package/dist/mcp/tools/do.js +0 -113
- package/dist/mcp/tools/do.js.map +0 -1
- package/dist/mcp/tools/fetch.d.ts +0 -43
- package/dist/mcp/tools/fetch.d.ts.map +0 -1
- package/dist/mcp/tools/fetch.js +0 -127
- package/dist/mcp/tools/fetch.js.map +0 -1
- package/dist/mcp/tools/index.d.ts +0 -9
- package/dist/mcp/tools/index.d.ts.map +0 -1
- package/dist/mcp/tools/index.js +0 -9
- package/dist/mcp/tools/index.js.map +0 -1
- package/dist/mcp/tools/search.d.ts +0 -60
- package/dist/mcp/tools/search.d.ts.map +0 -1
- package/dist/mcp/tools/search.js +0 -278
- package/dist/mcp/tools/search.js.map +0 -1
- package/dist/mcp/transport/http.d.ts +0 -144
- package/dist/mcp/transport/http.d.ts.map +0 -1
- package/dist/mcp/transport/http.js +0 -545
- package/dist/mcp/transport/http.js.map +0 -1
- package/dist/mcp/transport/index.d.ts +0 -10
- package/dist/mcp/transport/index.d.ts.map +0 -1
- package/dist/mcp/transport/index.js +0 -12
- package/dist/mcp/transport/index.js.map +0 -1
- package/dist/mcp/transport/stdio.d.ts +0 -132
- package/dist/mcp/transport/stdio.d.ts.map +0 -1
- package/dist/mcp/transport/stdio.js +0 -466
- package/dist/mcp/transport/stdio.js.map +0 -1
- package/dist/mcp/types.d.ts +0 -476
- package/dist/mcp/types.d.ts.map +0 -1
- package/dist/mcp/types.js +0 -178
- package/dist/mcp/types.js.map +0 -1
- package/dist/olap/cdc/cdc-buffer.d.ts +0 -92
- package/dist/olap/cdc/cdc-buffer.d.ts.map +0 -1
- package/dist/olap/cdc/cdc-buffer.js +0 -146
- package/dist/olap/cdc/cdc-buffer.js.map +0 -1
- package/dist/olap/cdc/cdc-emitter.d.ts +0 -118
- package/dist/olap/cdc/cdc-emitter.d.ts.map +0 -1
- package/dist/olap/cdc/cdc-emitter.js +0 -217
- package/dist/olap/cdc/cdc-emitter.js.map +0 -1
- package/dist/olap/cdc/cdc-schema.d.ts +0 -119
- package/dist/olap/cdc/cdc-schema.d.ts.map +0 -1
- package/dist/olap/cdc/cdc-schema.js +0 -253
- package/dist/olap/cdc/cdc-schema.js.map +0 -1
- package/dist/olap/cdc/index.d.ts +0 -10
- package/dist/olap/cdc/index.d.ts.map +0 -1
- package/dist/olap/cdc/index.js +0 -10
- package/dist/olap/cdc/index.js.map +0 -1
- package/dist/olap/clickhouse/iceberg.d.ts +0 -164
- package/dist/olap/clickhouse/iceberg.d.ts.map +0 -1
- package/dist/olap/clickhouse/iceberg.js +0 -138
- package/dist/olap/clickhouse/iceberg.js.map +0 -1
- package/dist/olap/clickhouse/index.d.ts +0 -14
- package/dist/olap/clickhouse/index.d.ts.map +0 -1
- package/dist/olap/clickhouse/index.js +0 -14
- package/dist/olap/clickhouse/index.js.map +0 -1
- package/dist/olap/clickhouse/mapper.d.ts +0 -170
- package/dist/olap/clickhouse/mapper.d.ts.map +0 -1
- package/dist/olap/clickhouse/mapper.js +0 -654
- package/dist/olap/clickhouse/mapper.js.map +0 -1
- package/dist/olap/clickhouse/olap-backend.d.ts +0 -181
- package/dist/olap/clickhouse/olap-backend.d.ts.map +0 -1
- package/dist/olap/clickhouse/olap-backend.js +0 -1083
- package/dist/olap/clickhouse/olap-backend.js.map +0 -1
- package/dist/olap/clickhouse/query-executor.d.ts +0 -163
- package/dist/olap/clickhouse/query-executor.d.ts.map +0 -1
- package/dist/olap/clickhouse/query-executor.js +0 -560
- package/dist/olap/clickhouse/query-executor.js.map +0 -1
- package/dist/olap/clickhouse/query.d.ts +0 -134
- package/dist/olap/clickhouse/query.d.ts.map +0 -1
- package/dist/olap/clickhouse/query.js +0 -512
- package/dist/olap/clickhouse/query.js.map +0 -1
- package/dist/olap/stage/index.d.ts +0 -6
- package/dist/olap/stage/index.d.ts.map +0 -1
- package/dist/olap/stage/index.js +0 -6
- package/dist/olap/stage/index.js.map +0 -1
- package/dist/olap/stage/parser.d.ts +0 -68
- package/dist/olap/stage/parser.d.ts.map +0 -1
- package/dist/olap/stage/parser.js +0 -293
- package/dist/olap/stage/parser.js.map +0 -1
- package/dist/olap/stage/router.d.ts +0 -94
- package/dist/olap/stage/router.d.ts.map +0 -1
- package/dist/olap/stage/router.js +0 -390
- package/dist/olap/stage/router.js.map +0 -1
- package/dist/rpc/endpoint.d.ts +0 -52
- package/dist/rpc/endpoint.d.ts.map +0 -1
- package/dist/rpc/endpoint.js +0 -734
- package/dist/rpc/endpoint.js.map +0 -1
- package/dist/rpc/index.d.ts +0 -34
- package/dist/rpc/index.d.ts.map +0 -1
- package/dist/rpc/index.js +0 -45
- package/dist/rpc/index.js.map +0 -1
- package/dist/rpc/rpc-client.d.ts +0 -275
- package/dist/rpc/rpc-client.d.ts.map +0 -1
- package/dist/rpc/rpc-client.js +0 -735
- package/dist/rpc/rpc-client.js.map +0 -1
- package/dist/rpc/rpc-target.d.ts +0 -220
- package/dist/rpc/rpc-target.d.ts.map +0 -1
- package/dist/rpc/rpc-target.js +0 -500
- package/dist/rpc/rpc-target.js.map +0 -1
- package/dist/rpc/worker-entrypoint.d.ts +0 -159
- package/dist/rpc/worker-entrypoint.d.ts.map +0 -1
- package/dist/rpc/worker-entrypoint.js +0 -212
- package/dist/rpc/worker-entrypoint.js.map +0 -1
- package/dist/server.d.ts +0 -18
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -129
- package/dist/server.js.map +0 -1
- package/dist/studio/components/browser/CollectionItem.d.ts +0 -26
- package/dist/studio/components/browser/CollectionItem.d.ts.map +0 -1
- package/dist/studio/components/browser/CollectionItem.js +0 -143
- package/dist/studio/components/browser/CollectionItem.js.map +0 -1
- package/dist/studio/components/browser/CollectionTree.d.ts +0 -45
- package/dist/studio/components/browser/CollectionTree.d.ts.map +0 -1
- package/dist/studio/components/browser/CollectionTree.js +0 -207
- package/dist/studio/components/browser/CollectionTree.js.map +0 -1
- package/dist/studio/components/browser/ConnectedDatabaseBrowser.d.ts +0 -51
- package/dist/studio/components/browser/ConnectedDatabaseBrowser.d.ts.map +0 -1
- package/dist/studio/components/browser/ConnectedDatabaseBrowser.js +0 -185
- package/dist/studio/components/browser/ConnectedDatabaseBrowser.js.map +0 -1
- package/dist/studio/components/browser/DatabaseBrowser.d.ts +0 -46
- package/dist/studio/components/browser/DatabaseBrowser.d.ts.map +0 -1
- package/dist/studio/components/browser/DatabaseBrowser.js +0 -304
- package/dist/studio/components/browser/DatabaseBrowser.js.map +0 -1
- package/dist/studio/components/browser/__tests__/CollectionItem.test.d.ts +0 -5
- package/dist/studio/components/browser/__tests__/CollectionItem.test.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/CollectionItem.test.js +0 -169
- package/dist/studio/components/browser/__tests__/CollectionItem.test.js.map +0 -1
- package/dist/studio/components/browser/__tests__/CollectionTree.test.d.ts +0 -5
- package/dist/studio/components/browser/__tests__/CollectionTree.test.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/CollectionTree.test.js +0 -203
- package/dist/studio/components/browser/__tests__/CollectionTree.test.js.map +0 -1
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.d.ts +0 -8
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.js +0 -522
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.js.map +0 -1
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.d.ts +0 -5
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.js +0 -518
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.js.map +0 -1
- package/dist/studio/components/browser/__tests__/setup.d.ts +0 -5
- package/dist/studio/components/browser/__tests__/setup.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/setup.js +0 -22
- package/dist/studio/components/browser/__tests__/setup.js.map +0 -1
- package/dist/studio/components/browser/index.d.ts +0 -15
- package/dist/studio/components/browser/index.d.ts.map +0 -1
- package/dist/studio/components/browser/index.js +0 -10
- package/dist/studio/components/browser/index.js.map +0 -1
- package/dist/studio/components/browser/types.d.ts +0 -33
- package/dist/studio/components/browser/types.d.ts.map +0 -1
- package/dist/studio/components/browser/types.js +0 -5
- package/dist/studio/components/browser/types.js.map +0 -1
- package/dist/studio/components/connection/ConnectionForm.d.ts +0 -59
- package/dist/studio/components/connection/ConnectionForm.d.ts.map +0 -1
- package/dist/studio/components/connection/ConnectionForm.js +0 -274
- package/dist/studio/components/connection/ConnectionForm.js.map +0 -1
- package/dist/studio/components/connection/ConnectionList.d.ts +0 -59
- package/dist/studio/components/connection/ConnectionList.d.ts.map +0 -1
- package/dist/studio/components/connection/ConnectionList.js +0 -286
- package/dist/studio/components/connection/ConnectionList.js.map +0 -1
- package/dist/studio/components/connection/ConnectionPanel.d.ts +0 -132
- package/dist/studio/components/connection/ConnectionPanel.d.ts.map +0 -1
- package/dist/studio/components/connection/ConnectionPanel.js +0 -293
- package/dist/studio/components/connection/ConnectionPanel.js.map +0 -1
- package/dist/studio/components/connection/__tests__/ConnectionPanel.test.d.ts +0 -8
- package/dist/studio/components/connection/__tests__/ConnectionPanel.test.d.ts.map +0 -1
- package/dist/studio/components/connection/__tests__/ConnectionPanel.test.js +0 -632
- package/dist/studio/components/connection/__tests__/ConnectionPanel.test.js.map +0 -1
- package/dist/studio/components/connection/__tests__/setup.d.ts +0 -5
- package/dist/studio/components/connection/__tests__/setup.d.ts.map +0 -1
- package/dist/studio/components/connection/__tests__/setup.js +0 -11
- package/dist/studio/components/connection/__tests__/setup.js.map +0 -1
- package/dist/studio/components/connection/index.d.ts +0 -10
- package/dist/studio/components/connection/index.d.ts.map +0 -1
- package/dist/studio/components/connection/index.js +0 -7
- package/dist/studio/components/connection/index.js.map +0 -1
- package/dist/studio/components/crud/DeleteDocumentDialog.d.ts +0 -91
- package/dist/studio/components/crud/DeleteDocumentDialog.d.ts.map +0 -1
- package/dist/studio/components/crud/DeleteDocumentDialog.js +0 -273
- package/dist/studio/components/crud/DeleteDocumentDialog.js.map +0 -1
- package/dist/studio/components/crud/DocumentEditor.d.ts +0 -32
- package/dist/studio/components/crud/DocumentEditor.d.ts.map +0 -1
- package/dist/studio/components/crud/DocumentEditor.js +0 -546
- package/dist/studio/components/crud/DocumentEditor.js.map +0 -1
- package/dist/studio/components/crud/InsertDocumentDialog.d.ts +0 -78
- package/dist/studio/components/crud/InsertDocumentDialog.d.ts.map +0 -1
- package/dist/studio/components/crud/InsertDocumentDialog.js +0 -323
- package/dist/studio/components/crud/InsertDocumentDialog.js.map +0 -1
- package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.d.ts +0 -5
- package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.d.ts.map +0 -1
- package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.js +0 -298
- package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.js.map +0 -1
- package/dist/studio/components/crud/__tests__/DocumentEditor.test.d.ts +0 -8
- package/dist/studio/components/crud/__tests__/DocumentEditor.test.d.ts.map +0 -1
- package/dist/studio/components/crud/__tests__/DocumentEditor.test.js +0 -368
- package/dist/studio/components/crud/__tests__/DocumentEditor.test.js.map +0 -1
- package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.d.ts +0 -2
- package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.d.ts.map +0 -1
- package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.js +0 -352
- package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.js.map +0 -1
- package/dist/studio/components/crud/__tests__/setup.d.ts +0 -5
- package/dist/studio/components/crud/__tests__/setup.d.ts.map +0 -1
- package/dist/studio/components/crud/__tests__/setup.js +0 -22
- package/dist/studio/components/crud/__tests__/setup.js.map +0 -1
- package/dist/studio/components/crud/index.d.ts +0 -12
- package/dist/studio/components/crud/index.d.ts.map +0 -1
- package/dist/studio/components/crud/index.js +0 -11
- package/dist/studio/components/crud/index.js.map +0 -1
- package/dist/studio/hooks/useConnection.d.ts +0 -127
- package/dist/studio/hooks/useConnection.d.ts.map +0 -1
- package/dist/studio/hooks/useConnection.js +0 -414
- package/dist/studio/hooks/useConnection.js.map +0 -1
- package/dist/studio/hooks/useDatabaseBrowser.d.ts +0 -107
- package/dist/studio/hooks/useDatabaseBrowser.d.ts.map +0 -1
- package/dist/studio/hooks/useDatabaseBrowser.js +0 -294
- package/dist/studio/hooks/useDatabaseBrowser.js.map +0 -1
- package/dist/studio/index.d.ts +0 -16
- package/dist/studio/index.d.ts.map +0 -1
- package/dist/studio/index.js +0 -14
- package/dist/studio/index.js.map +0 -1
- package/dist/studio/types/connection.d.ts +0 -266
- package/dist/studio/types/connection.d.ts.map +0 -1
- package/dist/studio/types/connection.js +0 -159
- package/dist/studio/types/connection.js.map +0 -1
- package/dist/studio/vitest.config.d.ts +0 -3
- package/dist/studio/vitest.config.d.ts.map +0 -1
- package/dist/studio/vitest.config.js +0 -33
- package/dist/studio/vitest.config.js.map +0 -1
- package/dist/translator/aggregation-translator.d.ts +0 -51
- package/dist/translator/aggregation-translator.d.ts.map +0 -1
- package/dist/translator/aggregation-translator.js +0 -324
- package/dist/translator/aggregation-translator.js.map +0 -1
- package/dist/translator/dialect.d.ts +0 -131
- package/dist/translator/dialect.d.ts.map +0 -1
- package/dist/translator/dialect.js +0 -276
- package/dist/translator/dialect.js.map +0 -1
- package/dist/translator/geo-translator.d.ts +0 -91
- package/dist/translator/geo-translator.d.ts.map +0 -1
- package/dist/translator/geo-translator.js +0 -587
- package/dist/translator/geo-translator.js.map +0 -1
- package/dist/translator/hybrid-translator.d.ts +0 -70
- package/dist/translator/hybrid-translator.d.ts.map +0 -1
- package/dist/translator/hybrid-translator.js +0 -193
- package/dist/translator/hybrid-translator.js.map +0 -1
- package/dist/translator/index.d.ts +0 -13
- package/dist/translator/index.d.ts.map +0 -1
- package/dist/translator/index.js +0 -11
- package/dist/translator/index.js.map +0 -1
- package/dist/translator/query-translator.d.ts +0 -211
- package/dist/translator/query-translator.d.ts.map +0 -1
- package/dist/translator/query-translator.js +0 -1276
- package/dist/translator/query-translator.js.map +0 -1
- package/dist/translator/search-highlight.d.ts +0 -83
- package/dist/translator/search-highlight.d.ts.map +0 -1
- package/dist/translator/search-highlight.js +0 -83
- package/dist/translator/search-highlight.js.map +0 -1
- package/dist/translator/search-translator.d.ts +0 -155
- package/dist/translator/search-translator.d.ts.map +0 -1
- package/dist/translator/search-translator.js +0 -241
- package/dist/translator/search-translator.js.map +0 -1
- package/dist/translator/stages/add-fields-stage.d.ts +0 -7
- package/dist/translator/stages/add-fields-stage.d.ts.map +0 -1
- package/dist/translator/stages/add-fields-stage.js +0 -72
- package/dist/translator/stages/add-fields-stage.js.map +0 -1
- package/dist/translator/stages/bucket-stage.d.ts +0 -7
- package/dist/translator/stages/bucket-stage.d.ts.map +0 -1
- package/dist/translator/stages/bucket-stage.js +0 -87
- package/dist/translator/stages/bucket-stage.js.map +0 -1
- package/dist/translator/stages/count-stage.d.ts +0 -7
- package/dist/translator/stages/count-stage.d.ts.map +0 -1
- package/dist/translator/stages/count-stage.js +0 -12
- package/dist/translator/stages/count-stage.js.map +0 -1
- package/dist/translator/stages/expression-translator.d.ts +0 -68
- package/dist/translator/stages/expression-translator.d.ts.map +0 -1
- package/dist/translator/stages/expression-translator.js +0 -467
- package/dist/translator/stages/expression-translator.js.map +0 -1
- package/dist/translator/stages/facet-stage.d.ts +0 -13
- package/dist/translator/stages/facet-stage.d.ts.map +0 -1
- package/dist/translator/stages/facet-stage.js +0 -26
- package/dist/translator/stages/facet-stage.js.map +0 -1
- package/dist/translator/stages/fusion-stages.d.ts +0 -118
- package/dist/translator/stages/fusion-stages.d.ts.map +0 -1
- package/dist/translator/stages/fusion-stages.js +0 -201
- package/dist/translator/stages/fusion-stages.js.map +0 -1
- package/dist/translator/stages/group-stage.d.ts +0 -8
- package/dist/translator/stages/group-stage.d.ts.map +0 -1
- package/dist/translator/stages/group-stage.js +0 -123
- package/dist/translator/stages/group-stage.js.map +0 -1
- package/dist/translator/stages/index.d.ts +0 -24
- package/dist/translator/stages/index.d.ts.map +0 -1
- package/dist/translator/stages/index.js +0 -24
- package/dist/translator/stages/index.js.map +0 -1
- package/dist/translator/stages/join-optimizer.d.ts +0 -37
- package/dist/translator/stages/join-optimizer.d.ts.map +0 -1
- package/dist/translator/stages/join-optimizer.js +0 -93
- package/dist/translator/stages/join-optimizer.js.map +0 -1
- package/dist/translator/stages/limit-stage.d.ts +0 -7
- package/dist/translator/stages/limit-stage.d.ts.map +0 -1
- package/dist/translator/stages/limit-stage.js +0 -11
- package/dist/translator/stages/limit-stage.js.map +0 -1
- package/dist/translator/stages/lookup-stage.d.ts +0 -7
- package/dist/translator/stages/lookup-stage.d.ts.map +0 -1
- package/dist/translator/stages/lookup-stage.js +0 -73
- package/dist/translator/stages/lookup-stage.js.map +0 -1
- package/dist/translator/stages/match-stage.d.ts +0 -7
- package/dist/translator/stages/match-stage.d.ts.map +0 -1
- package/dist/translator/stages/match-stage.js +0 -14
- package/dist/translator/stages/match-stage.js.map +0 -1
- package/dist/translator/stages/optimizer.d.ts +0 -15
- package/dist/translator/stages/optimizer.d.ts.map +0 -1
- package/dist/translator/stages/optimizer.js +0 -249
- package/dist/translator/stages/optimizer.js.map +0 -1
- package/dist/translator/stages/parallel-facet.d.ts +0 -47
- package/dist/translator/stages/parallel-facet.d.ts.map +0 -1
- package/dist/translator/stages/parallel-facet.js +0 -57
- package/dist/translator/stages/parallel-facet.js.map +0 -1
- package/dist/translator/stages/project-stage.d.ts +0 -8
- package/dist/translator/stages/project-stage.d.ts.map +0 -1
- package/dist/translator/stages/project-stage.js +0 -145
- package/dist/translator/stages/project-stage.js.map +0 -1
- package/dist/translator/stages/search-stage.d.ts +0 -60
- package/dist/translator/stages/search-stage.d.ts.map +0 -1
- package/dist/translator/stages/search-stage.js +0 -89
- package/dist/translator/stages/search-stage.js.map +0 -1
- package/dist/translator/stages/skip-stage.d.ts +0 -7
- package/dist/translator/stages/skip-stage.d.ts.map +0 -1
- package/dist/translator/stages/skip-stage.js +0 -11
- package/dist/translator/stages/skip-stage.js.map +0 -1
- package/dist/translator/stages/sort-stage.d.ts +0 -7
- package/dist/translator/stages/sort-stage.d.ts.map +0 -1
- package/dist/translator/stages/sort-stage.js +0 -21
- package/dist/translator/stages/sort-stage.js.map +0 -1
- package/dist/translator/stages/types.d.ts +0 -136
- package/dist/translator/stages/types.d.ts.map +0 -1
- package/dist/translator/stages/types.js +0 -5
- package/dist/translator/stages/types.js.map +0 -1
- package/dist/translator/stages/unwind-stage.d.ts +0 -7
- package/dist/translator/stages/unwind-stage.d.ts.map +0 -1
- package/dist/translator/stages/unwind-stage.js +0 -61
- package/dist/translator/stages/unwind-stage.js.map +0 -1
- package/dist/translator/stages/vector-search-stage.d.ts +0 -53
- package/dist/translator/stages/vector-search-stage.d.ts.map +0 -1
- package/dist/translator/stages/vector-search-stage.js +0 -62
- package/dist/translator/stages/vector-search-stage.js.map +0 -1
- package/dist/translator/update-translator.d.ts +0 -148
- package/dist/translator/update-translator.d.ts.map +0 -1
- package/dist/translator/update-translator.js +0 -819
- package/dist/translator/update-translator.js.map +0 -1
- package/dist/translator/vector-translator.d.ts +0 -89
- package/dist/translator/vector-translator.d.ts.map +0 -1
- package/dist/translator/vector-translator.js +0 -106
- package/dist/translator/vector-translator.js.map +0 -1
- package/dist/types/env.d.ts +0 -31
- package/dist/types/env.d.ts.map +0 -1
- package/dist/types/env.js +0 -5
- package/dist/types/env.js.map +0 -1
- package/dist/types/function.d.ts +0 -65
- package/dist/types/function.d.ts.map +0 -1
- package/dist/types/function.js +0 -5
- package/dist/types/function.js.map +0 -1
- package/dist/types/index.d.ts +0 -137
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -13
- package/dist/types/index.js.map +0 -1
- package/dist/types/mongodb.d.ts +0 -258
- package/dist/types/mongodb.d.ts.map +0 -1
- package/dist/types/mongodb.js +0 -5
- package/dist/types/mongodb.js.map +0 -1
- package/dist/types/objectid.d.ts +0 -130
- package/dist/types/objectid.d.ts.map +0 -1
- package/dist/types/objectid.js +0 -314
- package/dist/types/objectid.js.map +0 -1
- package/dist/types/rpc.d.ts +0 -313
- package/dist/types/rpc.d.ts.map +0 -1
- package/dist/types/rpc.js +0 -136
- package/dist/types/rpc.js.map +0 -1
- package/dist/types/vectorize.d.ts +0 -136
- package/dist/types/vectorize.d.ts.map +0 -1
- package/dist/types/vectorize.js +0 -8
- package/dist/types/vectorize.js.map +0 -1
- package/dist/utils/sql-safety.d.ts +0 -64
- package/dist/utils/sql-safety.d.ts.map +0 -1
- package/dist/utils/sql-safety.js +0 -112
- package/dist/utils/sql-safety.js.map +0 -1
- package/dist/validation/document-validator.d.ts +0 -195
- package/dist/validation/document-validator.d.ts.map +0 -1
- package/dist/validation/document-validator.js +0 -529
- package/dist/validation/document-validator.js.map +0 -1
- package/dist/vectorize/document-serializer.d.ts +0 -119
- package/dist/vectorize/document-serializer.d.ts.map +0 -1
- package/dist/vectorize/document-serializer.js +0 -320
- package/dist/vectorize/document-serializer.js.map +0 -1
- package/dist/wire/auth/index.d.ts +0 -5
- package/dist/wire/auth/index.d.ts.map +0 -1
- package/dist/wire/auth/index.js +0 -5
- package/dist/wire/auth/index.js.map +0 -1
- package/dist/wire/auth/scram.d.ts +0 -160
- package/dist/wire/auth/scram.d.ts.map +0 -1
- package/dist/wire/auth/scram.js +0 -425
- package/dist/wire/auth/scram.js.map +0 -1
- package/dist/wire/backend/interface.d.ts +0 -168
- package/dist/wire/backend/interface.d.ts.map +0 -1
- package/dist/wire/backend/interface.js +0 -10
- package/dist/wire/backend/interface.js.map +0 -1
- package/dist/wire/backend/local-sqlite.d.ts +0 -89
- package/dist/wire/backend/local-sqlite.d.ts.map +0 -1
- package/dist/wire/backend/local-sqlite.js +0 -1002
- package/dist/wire/backend/local-sqlite.js.map +0 -1
- package/dist/wire/backend/query-router.d.ts +0 -197
- package/dist/wire/backend/query-router.d.ts.map +0 -1
- package/dist/wire/backend/query-router.js +0 -590
- package/dist/wire/backend/query-router.js.map +0 -1
- package/dist/wire/backend/validation.d.ts +0 -26
- package/dist/wire/backend/validation.d.ts.map +0 -1
- package/dist/wire/backend/validation.js +0 -79
- package/dist/wire/backend/validation.js.map +0 -1
- package/dist/wire/backend/workers-proxy.d.ts +0 -95
- package/dist/wire/backend/workers-proxy.d.ts.map +0 -1
- package/dist/wire/backend/workers-proxy.js +0 -429
- package/dist/wire/backend/workers-proxy.js.map +0 -1
- package/dist/wire/commands/admin.d.ts +0 -49
- package/dist/wire/commands/admin.d.ts.map +0 -1
- package/dist/wire/commands/admin.js +0 -272
- package/dist/wire/commands/admin.js.map +0 -1
- package/dist/wire/commands/aggregate.d.ts +0 -15
- package/dist/wire/commands/aggregate.d.ts.map +0 -1
- package/dist/wire/commands/aggregate.js +0 -98
- package/dist/wire/commands/aggregate.js.map +0 -1
- package/dist/wire/commands/auth.d.ts +0 -58
- package/dist/wire/commands/auth.d.ts.map +0 -1
- package/dist/wire/commands/auth.js +0 -158
- package/dist/wire/commands/auth.js.map +0 -1
- package/dist/wire/commands/crud.d.ts +0 -49
- package/dist/wire/commands/crud.d.ts.map +0 -1
- package/dist/wire/commands/crud.js +0 -336
- package/dist/wire/commands/crud.js.map +0 -1
- package/dist/wire/commands/hello.d.ts +0 -35
- package/dist/wire/commands/hello.d.ts.map +0 -1
- package/dist/wire/commands/hello.js +0 -204
- package/dist/wire/commands/hello.js.map +0 -1
- package/dist/wire/commands/index.d.ts +0 -24
- package/dist/wire/commands/index.d.ts.map +0 -1
- package/dist/wire/commands/index.js +0 -145
- package/dist/wire/commands/index.js.map +0 -1
- package/dist/wire/commands/router.d.ts +0 -46
- package/dist/wire/commands/router.d.ts.map +0 -1
- package/dist/wire/commands/router.js +0 -151
- package/dist/wire/commands/router.js.map +0 -1
- package/dist/wire/commands/types.d.ts +0 -51
- package/dist/wire/commands/types.d.ts.map +0 -1
- package/dist/wire/commands/types.js +0 -15
- package/dist/wire/commands/types.js.map +0 -1
- package/dist/wire/index.d.ts +0 -15
- package/dist/wire/index.d.ts.map +0 -1
- package/dist/wire/index.js +0 -19
- package/dist/wire/index.js.map +0 -1
- package/dist/wire/message.d.ts +0 -49
- package/dist/wire/message.d.ts.map +0 -1
- package/dist/wire/message.js +0 -299
- package/dist/wire/message.js.map +0 -1
- package/dist/wire/server.d.ts +0 -145
- package/dist/wire/server.d.ts.map +0 -1
- package/dist/wire/server.js +0 -284
- package/dist/wire/server.js.map +0 -1
- package/dist/wire/types.d.ts +0 -140
- package/dist/wire/types.d.ts.map +0 -1
- package/dist/wire/types.js +0 -64
- package/dist/wire/types.js.map +0 -1
- package/dist/worker.d.ts.map +0 -1
|
@@ -1,764 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Index Manager for mongo.do
|
|
3
|
-
*
|
|
4
|
-
* Manages SQLite indexes for MongoDB-style collections backed by Durable Objects.
|
|
5
|
-
* Indexes are created on json_extract expressions to enable efficient querying.
|
|
6
|
-
*
|
|
7
|
-
* TTL (Time-To-Live) Index Support:
|
|
8
|
-
* - createIndex({field: 1}, {expireAfterSeconds: N}) creates a TTL index
|
|
9
|
-
* - Documents with date values in the TTL field will expire after N seconds
|
|
10
|
-
* - Background cleanup removes expired documents periodically
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Validates and escapes a field name/path for safe use in SQL json_extract expressions.
|
|
14
|
-
* Prevents SQL injection by only allowing safe characters in field paths.
|
|
15
|
-
*
|
|
16
|
-
* @throws Error if field name contains invalid characters
|
|
17
|
-
*/
|
|
18
|
-
export function escapeFieldPath(field) {
|
|
19
|
-
if (!field || field.length === 0) {
|
|
20
|
-
throw new Error('Field name cannot be empty');
|
|
21
|
-
}
|
|
22
|
-
if (field.includes('\0')) {
|
|
23
|
-
throw new Error('Field name cannot contain null characters');
|
|
24
|
-
}
|
|
25
|
-
const safeFieldPattern = /^[a-zA-Z0-9_.$-]+$/;
|
|
26
|
-
if (!safeFieldPattern.test(field)) {
|
|
27
|
-
throw new Error(`Invalid field name: ${field}. Field names can only contain alphanumeric characters, underscores, dots, hyphens, and dollar signs.`);
|
|
28
|
-
}
|
|
29
|
-
if (field.includes('..') || field.startsWith('.') || field.endsWith('.')) {
|
|
30
|
-
throw new Error(`Invalid field path: ${field}. Field paths cannot have consecutive, leading, or trailing dots.`);
|
|
31
|
-
}
|
|
32
|
-
return field;
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Validates an identifier (table name, index name) for safe use in SQL.
|
|
36
|
-
* Only allows alphanumeric characters and underscores.
|
|
37
|
-
*
|
|
38
|
-
* @throws Error if identifier contains invalid characters
|
|
39
|
-
*/
|
|
40
|
-
export function validateIdentifier(identifier) {
|
|
41
|
-
if (!identifier || identifier.length === 0) {
|
|
42
|
-
throw new Error('Identifier cannot be empty');
|
|
43
|
-
}
|
|
44
|
-
if (identifier.includes('\0')) {
|
|
45
|
-
throw new Error('Identifier cannot contain null characters');
|
|
46
|
-
}
|
|
47
|
-
const safeIdentifierPattern = /^[a-zA-Z0-9_]+$/;
|
|
48
|
-
if (!safeIdentifierPattern.test(identifier)) {
|
|
49
|
-
throw new Error(`Invalid identifier: ${identifier}. Identifiers can only contain alphanumeric characters and underscores.`);
|
|
50
|
-
}
|
|
51
|
-
return identifier;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Check if an index specification is a text index
|
|
55
|
-
*/
|
|
56
|
-
export function isTextIndex(keys) {
|
|
57
|
-
return Object.values(keys).some(v => v === 'text');
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Get fields that are text-indexed
|
|
61
|
-
*/
|
|
62
|
-
export function getTextFields(keys) {
|
|
63
|
-
return Object.entries(keys)
|
|
64
|
-
.filter(([_, v]) => v === 'text')
|
|
65
|
-
.map(([field]) => field);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Generate FTS5 virtual table name for a collection
|
|
69
|
-
*/
|
|
70
|
-
export function generateFTS5TableName(collectionName) {
|
|
71
|
-
validateIdentifier(collectionName);
|
|
72
|
-
return `${collectionName}_fts`;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Generates an index name from collection name and key specification
|
|
76
|
-
*/
|
|
77
|
-
export function generateIndexName(collectionName, keys) {
|
|
78
|
-
validateIdentifier(collectionName);
|
|
79
|
-
const keyParts = Object.entries(keys).map(([field, direction]) => {
|
|
80
|
-
escapeFieldPath(field);
|
|
81
|
-
const safeField = field.replace(/\./g, '_');
|
|
82
|
-
if (direction === 'text') {
|
|
83
|
-
return `${safeField}_text`;
|
|
84
|
-
}
|
|
85
|
-
const suffix = direction === 1 ? '1' : '-1';
|
|
86
|
-
return `${safeField}_${suffix}`;
|
|
87
|
-
});
|
|
88
|
-
return `${collectionName}_${keyParts.join('_')}`;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Generates the SQLite index name (prefixed for internal use)
|
|
92
|
-
*/
|
|
93
|
-
export function generateSQLiteIndexName(collectionName, keys, unique) {
|
|
94
|
-
const baseName = generateIndexName(collectionName, keys);
|
|
95
|
-
const prefix = unique ? 'idx_unique_' : 'idx_';
|
|
96
|
-
return `${prefix}${baseName}`;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Builds the SQL CREATE INDEX statement for given index specification
|
|
100
|
-
*/
|
|
101
|
-
export function buildCreateIndexSQL(collectionName, collectionId, keys, options = {}) {
|
|
102
|
-
const indexName = options.name || generateIndexName(collectionName, keys);
|
|
103
|
-
const sqliteIndexName = `idx_${options.unique ? 'unique_' : ''}${indexName}`;
|
|
104
|
-
// Build the column expressions for the index
|
|
105
|
-
const columns = Object.entries(keys).map(([field, direction]) => {
|
|
106
|
-
// Validate and escape field name to prevent SQL injection
|
|
107
|
-
const safeField = escapeFieldPath(field);
|
|
108
|
-
const jsonPath = safeField.startsWith('$') ? safeField : `$.${safeField}`;
|
|
109
|
-
const expr = `json_extract(data, '${jsonPath}')`;
|
|
110
|
-
const order = direction === 1 ? 'ASC' : 'DESC';
|
|
111
|
-
return `${expr} ${order}`;
|
|
112
|
-
});
|
|
113
|
-
const uniqueClause = options.unique ? 'UNIQUE ' : '';
|
|
114
|
-
// Build the WHERE clause for collection scoping
|
|
115
|
-
const whereClause = `WHERE collection_id = ${collectionId}`;
|
|
116
|
-
// Handle sparse index - only index documents where the field exists
|
|
117
|
-
let sparseCondition = '';
|
|
118
|
-
if (options.sparse) {
|
|
119
|
-
const sparseChecks = Object.keys(keys).map(field => {
|
|
120
|
-
const safeField = escapeFieldPath(field);
|
|
121
|
-
const jsonPath = safeField.startsWith('$') ? safeField : `$.${safeField}`;
|
|
122
|
-
return `json_extract(data, '${jsonPath}') IS NOT NULL`;
|
|
123
|
-
});
|
|
124
|
-
sparseCondition = ` AND ${sparseChecks.join(' AND ')}`;
|
|
125
|
-
}
|
|
126
|
-
const sql = `CREATE ${uniqueClause}INDEX IF NOT EXISTS ${sqliteIndexName} ON documents (
|
|
127
|
-
${columns.join(',\n ')}
|
|
128
|
-
) ${whereClause}${sparseCondition}`;
|
|
129
|
-
return { sql, indexName, sqliteIndexName };
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Builds the SQL for creating an FTS5 virtual table for text indexing.
|
|
133
|
-
*
|
|
134
|
-
* UNIFIED SCHEMA: Uses _id column from the unified schema (not doc_id).
|
|
135
|
-
*/
|
|
136
|
-
export function buildFTS5CreateSQL(collectionName, fields, options = {}) {
|
|
137
|
-
// generateFTS5TableName validates collectionName
|
|
138
|
-
const ftsTableName = generateFTS5TableName(collectionName);
|
|
139
|
-
// Validate and escape all field names to prevent SQL injection
|
|
140
|
-
const safeFields = fields.map(f => escapeFieldPath(f));
|
|
141
|
-
// Replace dots with underscores for FTS5 column names
|
|
142
|
-
const safeFtsFields = safeFields.map(f => f.replace(/\./g, '_'));
|
|
143
|
-
// Use _id to match the unified schema column name
|
|
144
|
-
const ftsFields = ['_id', ...safeFtsFields];
|
|
145
|
-
// Tokenize option - use unicode61 by default for better international support
|
|
146
|
-
const tokenize = options.default_language === 'none'
|
|
147
|
-
? 'unicode61'
|
|
148
|
-
: 'porter unicode61';
|
|
149
|
-
// Create the FTS5 virtual table
|
|
150
|
-
const createSQL = `CREATE VIRTUAL TABLE IF NOT EXISTS ${ftsTableName} USING fts5(
|
|
151
|
-
${ftsFields.join(', ')},
|
|
152
|
-
content='documents',
|
|
153
|
-
content_rowid='id',
|
|
154
|
-
tokenize='${tokenize}'
|
|
155
|
-
)`;
|
|
156
|
-
// Build json_extract expressions with validated field paths
|
|
157
|
-
const jsonExtractExprsNew = safeFields.map(f => `json_extract(NEW.data, '$.${f}')`);
|
|
158
|
-
const jsonExtractExprsOld = safeFields.map(f => `json_extract(OLD.data, '$.${f}')`);
|
|
159
|
-
// Create triggers to keep FTS5 table in sync with documents table
|
|
160
|
-
// Uses _id column from the unified schema
|
|
161
|
-
const triggersSQL = [
|
|
162
|
-
// Insert trigger
|
|
163
|
-
`CREATE TRIGGER IF NOT EXISTS ${ftsTableName}_ai AFTER INSERT ON documents BEGIN
|
|
164
|
-
INSERT INTO ${ftsTableName}(rowid, _id, ${safeFtsFields.join(', ')})
|
|
165
|
-
VALUES (NEW.id, NEW._id, ${jsonExtractExprsNew.join(', ')});
|
|
166
|
-
END`,
|
|
167
|
-
// Delete trigger
|
|
168
|
-
`CREATE TRIGGER IF NOT EXISTS ${ftsTableName}_ad AFTER DELETE ON documents BEGIN
|
|
169
|
-
INSERT INTO ${ftsTableName}(${ftsTableName}, rowid, _id, ${safeFtsFields.join(', ')})
|
|
170
|
-
VALUES('delete', OLD.id, OLD._id, ${jsonExtractExprsOld.join(', ')});
|
|
171
|
-
END`,
|
|
172
|
-
// Update trigger
|
|
173
|
-
`CREATE TRIGGER IF NOT EXISTS ${ftsTableName}_au AFTER UPDATE ON documents BEGIN
|
|
174
|
-
INSERT INTO ${ftsTableName}(${ftsTableName}, rowid, _id, ${safeFtsFields.join(', ')})
|
|
175
|
-
VALUES('delete', OLD.id, OLD._id, ${jsonExtractExprsOld.join(', ')});
|
|
176
|
-
INSERT INTO ${ftsTableName}(rowid, _id, ${safeFtsFields.join(', ')})
|
|
177
|
-
VALUES (NEW.id, NEW._id, ${jsonExtractExprsNew.join(', ')});
|
|
178
|
-
END`,
|
|
179
|
-
];
|
|
180
|
-
return { tableName: ftsTableName, createSQL, triggersSQL };
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Builds the SQL for dropping an FTS5 virtual table and its triggers
|
|
184
|
-
*/
|
|
185
|
-
export function buildFTS5DropSQL(collectionName) {
|
|
186
|
-
const ftsTableName = generateFTS5TableName(collectionName);
|
|
187
|
-
return {
|
|
188
|
-
dropSQL: `DROP TABLE IF EXISTS ${ftsTableName}`,
|
|
189
|
-
dropTriggersSQL: [
|
|
190
|
-
`DROP TRIGGER IF EXISTS ${ftsTableName}_ai`,
|
|
191
|
-
`DROP TRIGGER IF EXISTS ${ftsTableName}_ad`,
|
|
192
|
-
`DROP TRIGGER IF EXISTS ${ftsTableName}_au`,
|
|
193
|
-
],
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
/** Default cleanup interval in milliseconds (60 seconds) */
|
|
197
|
-
const DEFAULT_CLEANUP_INTERVAL_MS = 60000;
|
|
198
|
-
/**
|
|
199
|
-
* IndexManager handles creation, deletion, and listing of indexes
|
|
200
|
-
* Includes TTL (Time-To-Live) index support for automatic document expiration
|
|
201
|
-
*/
|
|
202
|
-
export class IndexManager {
|
|
203
|
-
storage;
|
|
204
|
-
cleanupIntervalMs = DEFAULT_CLEANUP_INTERVAL_MS;
|
|
205
|
-
ttlMetadataCache = new Map();
|
|
206
|
-
constructor(storage) {
|
|
207
|
-
this.storage = storage;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* Ensure the collections and documents tables exist.
|
|
211
|
-
*
|
|
212
|
-
* UNIFIED SCHEMA: This uses the same schema as MondoDatabase/SchemaManager.
|
|
213
|
-
* The schema is defined in schema.ts/migrations.ts as the single source of truth.
|
|
214
|
-
* This method creates the tables if they don't exist (for standalone IndexManager usage).
|
|
215
|
-
*/
|
|
216
|
-
ensureMetadataTable() {
|
|
217
|
-
this.storage.exec(`
|
|
218
|
-
CREATE TABLE IF NOT EXISTS collections (
|
|
219
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
220
|
-
name TEXT NOT NULL UNIQUE,
|
|
221
|
-
options TEXT DEFAULT '{}',
|
|
222
|
-
indexes TEXT DEFAULT '[]',
|
|
223
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
224
|
-
updated_at TEXT DEFAULT (datetime('now'))
|
|
225
|
-
)
|
|
226
|
-
`);
|
|
227
|
-
this.storage.exec(`
|
|
228
|
-
CREATE TABLE IF NOT EXISTS documents (
|
|
229
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
230
|
-
collection_id INTEGER NOT NULL,
|
|
231
|
-
_id TEXT NOT NULL,
|
|
232
|
-
data TEXT NOT NULL DEFAULT '{}',
|
|
233
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
234
|
-
updated_at TEXT DEFAULT (datetime('now')),
|
|
235
|
-
UNIQUE(collection_id, _id),
|
|
236
|
-
FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE
|
|
237
|
-
)
|
|
238
|
-
`);
|
|
239
|
-
// Create default indexes on _id per collection (unified schema indexes)
|
|
240
|
-
this.storage.exec(`
|
|
241
|
-
CREATE INDEX IF NOT EXISTS idx_documents_id ON documents(_id)
|
|
242
|
-
`);
|
|
243
|
-
this.storage.exec(`
|
|
244
|
-
CREATE INDEX IF NOT EXISTS idx_documents_collection_id ON documents(collection_id, _id)
|
|
245
|
-
`);
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Get or create a collection and return its ID
|
|
249
|
-
*/
|
|
250
|
-
getOrCreateCollection(name) {
|
|
251
|
-
// Try to get existing collection
|
|
252
|
-
const existing = this.storage
|
|
253
|
-
.prepare('SELECT id FROM collections WHERE name = ?')
|
|
254
|
-
.bind(name)
|
|
255
|
-
.first();
|
|
256
|
-
if (existing) {
|
|
257
|
-
return { id: existing.id, created: false };
|
|
258
|
-
}
|
|
259
|
-
// Create new collection
|
|
260
|
-
this.storage
|
|
261
|
-
.prepare('INSERT INTO collections (name) VALUES (?)')
|
|
262
|
-
.bind(name)
|
|
263
|
-
.run();
|
|
264
|
-
const result = this.storage
|
|
265
|
-
.prepare('SELECT id FROM collections WHERE name = ?')
|
|
266
|
-
.bind(name)
|
|
267
|
-
.first();
|
|
268
|
-
if (!result) {
|
|
269
|
-
throw new Error(`Failed to create collection: ${name}`);
|
|
270
|
-
}
|
|
271
|
-
return { id: result.id, created: true };
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* Get collection metadata
|
|
275
|
-
*/
|
|
276
|
-
getCollection(name) {
|
|
277
|
-
const result = this.storage
|
|
278
|
-
.prepare('SELECT id, indexes FROM collections WHERE name = ?')
|
|
279
|
-
.bind(name)
|
|
280
|
-
.first();
|
|
281
|
-
if (!result) {
|
|
282
|
-
return null;
|
|
283
|
-
}
|
|
284
|
-
return {
|
|
285
|
-
id: result.id,
|
|
286
|
-
indexes: JSON.parse(result.indexes),
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Create an index on a collection
|
|
291
|
-
*/
|
|
292
|
-
createIndex(collectionName, keys, options = {}) {
|
|
293
|
-
// Ensure tables exist
|
|
294
|
-
this.ensureMetadataTable();
|
|
295
|
-
// Get or create collection
|
|
296
|
-
const { id: collectionId, created } = this.getOrCreateCollection(collectionName);
|
|
297
|
-
// Get current indexes
|
|
298
|
-
const collection = this.getCollection(collectionName);
|
|
299
|
-
const currentIndexes = collection?.indexes || [];
|
|
300
|
-
const numIndexesBefore = currentIndexes.length + 1; // +1 for _id index
|
|
301
|
-
// Generate index info
|
|
302
|
-
const indexName = options.name || generateIndexName(collectionName, keys);
|
|
303
|
-
// Check if index already exists
|
|
304
|
-
const existingIndex = currentIndexes.find(idx => idx.name === indexName);
|
|
305
|
-
if (existingIndex) {
|
|
306
|
-
// Index already exists with same name
|
|
307
|
-
return {
|
|
308
|
-
ok: 1,
|
|
309
|
-
numIndexesBefore,
|
|
310
|
-
numIndexesAfter: numIndexesBefore,
|
|
311
|
-
createdCollectionAutomatically: created,
|
|
312
|
-
note: 'all indexes already exist',
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
// Check if this is a text index
|
|
316
|
-
const isText = isTextIndex(keys);
|
|
317
|
-
const textFields = isText ? getTextFields(keys) : [];
|
|
318
|
-
// Text index validation - only one text index per collection
|
|
319
|
-
if (isText) {
|
|
320
|
-
const existingTextIndex = currentIndexes.find(idx => Object.values(idx.key).some(v => v === 'text'));
|
|
321
|
-
if (existingTextIndex) {
|
|
322
|
-
throw new Error(`Collection '${collectionName}' already has a text index: ${existingTextIndex.name}`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
// TTL index validation
|
|
326
|
-
if (options.expireAfterSeconds !== undefined) {
|
|
327
|
-
// TTL indexes must be on a single field (MongoDB restriction)
|
|
328
|
-
const keyFields = Object.keys(keys);
|
|
329
|
-
if (keyFields.length !== 1) {
|
|
330
|
-
throw new Error('TTL indexes must be on a single field, compound TTL indexes are not supported');
|
|
331
|
-
}
|
|
332
|
-
// Check if collection already has a TTL index (MongoDB only allows one per collection)
|
|
333
|
-
const existingTTLIndex = currentIndexes.find(idx => idx.expireAfterSeconds !== undefined);
|
|
334
|
-
if (existingTTLIndex) {
|
|
335
|
-
throw new Error(`Collection '${collectionName}' already has a TTL index: ${existingTTLIndex.name}`);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
// Handle text index creation with FTS5
|
|
339
|
-
if (isText) {
|
|
340
|
-
const { createSQL, triggersSQL } = buildFTS5CreateSQL(collectionName, textFields, options);
|
|
341
|
-
try {
|
|
342
|
-
// Create FTS5 virtual table
|
|
343
|
-
this.storage.exec(createSQL);
|
|
344
|
-
// Create sync triggers
|
|
345
|
-
for (const triggerSQL of triggersSQL) {
|
|
346
|
-
this.storage.exec(triggerSQL);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
catch (error) {
|
|
350
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
351
|
-
if (!errMsg.includes('already exists')) {
|
|
352
|
-
throw error;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
// Build and execute regular CREATE INDEX
|
|
358
|
-
const { sql } = buildCreateIndexSQL(collectionName, collectionId, keys, options);
|
|
359
|
-
try {
|
|
360
|
-
this.storage.exec(sql);
|
|
361
|
-
}
|
|
362
|
-
catch (error) {
|
|
363
|
-
// If index already exists in SQLite, that's ok
|
|
364
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
365
|
-
if (!errMsg.includes('already exists')) {
|
|
366
|
-
throw error;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
// Build index info
|
|
371
|
-
const indexInfo = {
|
|
372
|
-
name: indexName,
|
|
373
|
-
key: keys,
|
|
374
|
-
v: 2,
|
|
375
|
-
};
|
|
376
|
-
if (options.unique) {
|
|
377
|
-
indexInfo.unique = true;
|
|
378
|
-
}
|
|
379
|
-
if (options.sparse) {
|
|
380
|
-
indexInfo.sparse = true;
|
|
381
|
-
}
|
|
382
|
-
if (options.partialFilterExpression) {
|
|
383
|
-
indexInfo.partialFilterExpression = options.partialFilterExpression;
|
|
384
|
-
}
|
|
385
|
-
if (options.expireAfterSeconds !== undefined) {
|
|
386
|
-
indexInfo.expireAfterSeconds = options.expireAfterSeconds;
|
|
387
|
-
// Cache TTL metadata for quick access
|
|
388
|
-
const ttlField = Object.keys(keys)[0];
|
|
389
|
-
if (ttlField !== undefined) {
|
|
390
|
-
const cacheKey = `${collectionName}:${indexName}`;
|
|
391
|
-
this.ttlMetadataCache.set(cacheKey, {
|
|
392
|
-
field: ttlField,
|
|
393
|
-
expireAfterSeconds: options.expireAfterSeconds,
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
if (isText) {
|
|
398
|
-
indexInfo.textIndexVersion = 3;
|
|
399
|
-
if (options.weights) {
|
|
400
|
-
indexInfo.weights = options.weights;
|
|
401
|
-
}
|
|
402
|
-
if (options.default_language) {
|
|
403
|
-
indexInfo.default_language = options.default_language;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
// Update collection metadata with new index
|
|
407
|
-
const updatedIndexes = [...currentIndexes, indexInfo];
|
|
408
|
-
this.storage
|
|
409
|
-
.prepare('UPDATE collections SET indexes = ?, updated_at = datetime(\'now\') WHERE id = ?')
|
|
410
|
-
.bind(JSON.stringify(updatedIndexes), collectionId)
|
|
411
|
-
.run();
|
|
412
|
-
return {
|
|
413
|
-
ok: 1,
|
|
414
|
-
numIndexesBefore,
|
|
415
|
-
numIndexesAfter: numIndexesBefore + 1,
|
|
416
|
-
createdCollectionAutomatically: created,
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
/**
|
|
420
|
-
* List all indexes on a collection
|
|
421
|
-
*/
|
|
422
|
-
listIndexes(collectionName) {
|
|
423
|
-
const collection = this.getCollection(collectionName);
|
|
424
|
-
if (!collection) {
|
|
425
|
-
return [];
|
|
426
|
-
}
|
|
427
|
-
// Always include the _id index
|
|
428
|
-
const idIndex = {
|
|
429
|
-
name: '_id_',
|
|
430
|
-
key: { _id: 1 },
|
|
431
|
-
v: 2,
|
|
432
|
-
};
|
|
433
|
-
return [idIndex, ...collection.indexes];
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Drop a specific index by name
|
|
437
|
-
*/
|
|
438
|
-
dropIndex(collectionName, indexName) {
|
|
439
|
-
// Validate collection name to prevent SQL injection
|
|
440
|
-
validateIdentifier(collectionName);
|
|
441
|
-
const collection = this.getCollection(collectionName);
|
|
442
|
-
if (!collection) {
|
|
443
|
-
throw new Error(`Collection not found: ${collectionName}`);
|
|
444
|
-
}
|
|
445
|
-
// Cannot drop _id index
|
|
446
|
-
if (indexName === '_id_') {
|
|
447
|
-
throw new Error('cannot drop _id index');
|
|
448
|
-
}
|
|
449
|
-
const currentIndexes = collection.indexes;
|
|
450
|
-
const indexToRemove = currentIndexes.find(idx => idx.name === indexName);
|
|
451
|
-
if (!indexToRemove) {
|
|
452
|
-
throw new Error(`index not found with name [${indexName}]`);
|
|
453
|
-
}
|
|
454
|
-
const nIndexesWas = currentIndexes.length + 1; // +1 for _id
|
|
455
|
-
// Check if this is a text index
|
|
456
|
-
const isText = isTextIndex(indexToRemove.key);
|
|
457
|
-
if (isText) {
|
|
458
|
-
// Drop FTS5 table and triggers (collection name already validated)
|
|
459
|
-
const { dropSQL, dropTriggersSQL } = buildFTS5DropSQL(collectionName);
|
|
460
|
-
try {
|
|
461
|
-
for (const triggerSQL of dropTriggersSQL) {
|
|
462
|
-
this.storage.exec(triggerSQL);
|
|
463
|
-
}
|
|
464
|
-
this.storage.exec(dropSQL);
|
|
465
|
-
}
|
|
466
|
-
catch (error) {
|
|
467
|
-
// Ignore errors if FTS5 table doesn't exist
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
else {
|
|
471
|
-
// Generate SQLite index name and drop it
|
|
472
|
-
// Index name comes from stored metadata so it's already validated
|
|
473
|
-
const sqliteIndexName = `idx_${indexToRemove.unique ? 'unique_' : ''}${indexName}`;
|
|
474
|
-
try {
|
|
475
|
-
this.storage.exec(`DROP INDEX IF EXISTS ${sqliteIndexName}`);
|
|
476
|
-
}
|
|
477
|
-
catch (error) {
|
|
478
|
-
// Ignore errors if index doesn't exist in SQLite
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
// Clear TTL metadata cache if this was a TTL index
|
|
482
|
-
if (indexToRemove.expireAfterSeconds !== undefined) {
|
|
483
|
-
const cacheKey = `${collectionName}:${indexName}`;
|
|
484
|
-
this.ttlMetadataCache.delete(cacheKey);
|
|
485
|
-
}
|
|
486
|
-
// Update metadata
|
|
487
|
-
const updatedIndexes = currentIndexes.filter(idx => idx.name !== indexName);
|
|
488
|
-
this.storage
|
|
489
|
-
.prepare('UPDATE collections SET indexes = ?, updated_at = datetime(\'now\') WHERE id = ?')
|
|
490
|
-
.bind(JSON.stringify(updatedIndexes), collection.id)
|
|
491
|
-
.run();
|
|
492
|
-
return {
|
|
493
|
-
ok: 1,
|
|
494
|
-
nIndexesWas,
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Drop all indexes on a collection (except _id)
|
|
499
|
-
*/
|
|
500
|
-
dropIndexes(collectionName) {
|
|
501
|
-
// Validate collection name to prevent SQL injection
|
|
502
|
-
validateIdentifier(collectionName);
|
|
503
|
-
const collection = this.getCollection(collectionName);
|
|
504
|
-
if (!collection) {
|
|
505
|
-
throw new Error(`Collection not found: ${collectionName}`);
|
|
506
|
-
}
|
|
507
|
-
const currentIndexes = collection.indexes;
|
|
508
|
-
const nIndexesWas = currentIndexes.length + 1; // +1 for _id
|
|
509
|
-
// Drop all SQLite indexes
|
|
510
|
-
// Index names come from stored metadata so they're already validated
|
|
511
|
-
for (const index of currentIndexes) {
|
|
512
|
-
const sqliteIndexName = `idx_${index.unique ? 'unique_' : ''}${index.name}`;
|
|
513
|
-
try {
|
|
514
|
-
this.storage.exec(`DROP INDEX IF EXISTS ${sqliteIndexName}`);
|
|
515
|
-
}
|
|
516
|
-
catch (error) {
|
|
517
|
-
// Ignore errors
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
// Clear indexes in metadata (keeping _id which is implicit)
|
|
521
|
-
this.storage
|
|
522
|
-
.prepare('UPDATE collections SET indexes = \'[]\', updated_at = datetime(\'now\') WHERE id = ?')
|
|
523
|
-
.bind(collection.id)
|
|
524
|
-
.run();
|
|
525
|
-
return {
|
|
526
|
-
ok: 1,
|
|
527
|
-
nIndexesWas,
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* Get index usage hints for a query
|
|
532
|
-
* Returns suggested index names that could be used for the query
|
|
533
|
-
*/
|
|
534
|
-
getIndexHints(collectionName, queryFields) {
|
|
535
|
-
const collection = this.getCollection(collectionName);
|
|
536
|
-
if (!collection) {
|
|
537
|
-
return [];
|
|
538
|
-
}
|
|
539
|
-
const hints = [];
|
|
540
|
-
// Find indexes that could help with the query
|
|
541
|
-
for (const index of collection.indexes) {
|
|
542
|
-
const indexFields = Object.keys(index.key);
|
|
543
|
-
// Check if this index covers any of the query fields
|
|
544
|
-
const coversQuery = queryFields.some(field => indexFields.includes(field));
|
|
545
|
-
if (coversQuery) {
|
|
546
|
-
hints.push(index.name);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
return hints;
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Get all TTL indexes across all collections
|
|
553
|
-
*/
|
|
554
|
-
getTTLIndexes() {
|
|
555
|
-
const ttlIndexes = [];
|
|
556
|
-
// Get all collections
|
|
557
|
-
const collections = this.storage
|
|
558
|
-
.prepare('SELECT id, name, indexes FROM collections')
|
|
559
|
-
.all();
|
|
560
|
-
for (const collection of collections) {
|
|
561
|
-
const indexes = JSON.parse(collection.indexes);
|
|
562
|
-
for (const index of indexes) {
|
|
563
|
-
if (index.expireAfterSeconds !== undefined) {
|
|
564
|
-
const field = Object.keys(index.key)[0];
|
|
565
|
-
if (field !== undefined) {
|
|
566
|
-
ttlIndexes.push({
|
|
567
|
-
collectionName: collection.name,
|
|
568
|
-
collectionId: collection.id,
|
|
569
|
-
indexName: index.name,
|
|
570
|
-
field,
|
|
571
|
-
expireAfterSeconds: index.expireAfterSeconds,
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
return ttlIndexes;
|
|
578
|
-
}
|
|
579
|
-
/**
|
|
580
|
-
* Check if a specific index is a TTL index
|
|
581
|
-
*/
|
|
582
|
-
isTTLIndex(collectionName, indexName) {
|
|
583
|
-
const collection = this.getCollection(collectionName);
|
|
584
|
-
if (!collection) {
|
|
585
|
-
return false;
|
|
586
|
-
}
|
|
587
|
-
const index = collection.indexes.find(idx => idx.name === indexName);
|
|
588
|
-
return index?.expireAfterSeconds !== undefined;
|
|
589
|
-
}
|
|
590
|
-
/**
|
|
591
|
-
* Check if a value is a valid date for TTL purposes
|
|
592
|
-
* Accepts Date objects, ISO strings, and Unix timestamps (in ms)
|
|
593
|
-
*/
|
|
594
|
-
isValidTTLFieldValue(value) {
|
|
595
|
-
if (value === null || value === undefined) {
|
|
596
|
-
return false;
|
|
597
|
-
}
|
|
598
|
-
if (value instanceof Date) {
|
|
599
|
-
return !isNaN(value.getTime());
|
|
600
|
-
}
|
|
601
|
-
if (typeof value === 'string') {
|
|
602
|
-
const date = new Date(value);
|
|
603
|
-
return !isNaN(date.getTime());
|
|
604
|
-
}
|
|
605
|
-
if (typeof value === 'number') {
|
|
606
|
-
// Unix timestamp in milliseconds (reasonable range: after 1970 and before year 3000)
|
|
607
|
-
const date = new Date(value);
|
|
608
|
-
return !isNaN(date.getTime()) && value > 0 && value < 32503680000000;
|
|
609
|
-
}
|
|
610
|
-
return false;
|
|
611
|
-
}
|
|
612
|
-
/**
|
|
613
|
-
* Calculate expiration time for a document
|
|
614
|
-
*/
|
|
615
|
-
calculateExpirationTime(dateValue, expireAfterSeconds) {
|
|
616
|
-
let date;
|
|
617
|
-
if (dateValue instanceof Date) {
|
|
618
|
-
date = dateValue;
|
|
619
|
-
}
|
|
620
|
-
else if (typeof dateValue === 'string') {
|
|
621
|
-
date = new Date(dateValue);
|
|
622
|
-
}
|
|
623
|
-
else {
|
|
624
|
-
date = new Date(dateValue);
|
|
625
|
-
}
|
|
626
|
-
return new Date(date.getTime() + expireAfterSeconds * 1000);
|
|
627
|
-
}
|
|
628
|
-
/**
|
|
629
|
-
* Check if a document is expired based on its TTL field
|
|
630
|
-
*/
|
|
631
|
-
isDocumentExpired(document, field, expireAfterSeconds) {
|
|
632
|
-
const fieldValue = document[field];
|
|
633
|
-
if (!this.isValidTTLFieldValue(fieldValue)) {
|
|
634
|
-
return false;
|
|
635
|
-
}
|
|
636
|
-
const expiresAt = this.calculateExpirationTime(fieldValue, expireAfterSeconds);
|
|
637
|
-
return expiresAt.getTime() < Date.now();
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* Build SQL query to delete expired documents for a collection
|
|
641
|
-
*/
|
|
642
|
-
buildExpiredDocumentsQuery(collectionName, field, expireAfterSeconds) {
|
|
643
|
-
// Validate field name to prevent SQL injection
|
|
644
|
-
const safeField = escapeFieldPath(field);
|
|
645
|
-
const jsonPath = safeField.startsWith('$') ? safeField : `$.${safeField}`;
|
|
646
|
-
const cutoffTime = new Date(Date.now() - expireAfterSeconds * 1000).toISOString();
|
|
647
|
-
// Get collection id if it exists, otherwise use a subquery
|
|
648
|
-
const collection = this.getCollection(collectionName);
|
|
649
|
-
const collectionIdParam = collection?.id;
|
|
650
|
-
// Build DELETE query that:
|
|
651
|
-
// 1. Targets documents in the specific collection
|
|
652
|
-
// 2. Extracts the date field using json_extract
|
|
653
|
-
// 3. Compares with the cutoff time using datetime functions
|
|
654
|
-
let sql;
|
|
655
|
-
let params;
|
|
656
|
-
if (collectionIdParam !== undefined) {
|
|
657
|
-
sql = `DELETE FROM documents
|
|
658
|
-
WHERE collection_id = ?
|
|
659
|
-
AND json_extract(data, '${jsonPath}') IS NOT NULL
|
|
660
|
-
AND datetime(json_extract(data, '${jsonPath}')) < datetime(?)`;
|
|
661
|
-
params = [collectionIdParam, cutoffTime];
|
|
662
|
-
}
|
|
663
|
-
else {
|
|
664
|
-
// Collection doesn't exist yet - use a subquery to get the id
|
|
665
|
-
sql = `DELETE FROM documents
|
|
666
|
-
WHERE collection_id = (SELECT id FROM collections WHERE name = ?)
|
|
667
|
-
AND json_extract(data, '${jsonPath}') IS NOT NULL
|
|
668
|
-
AND datetime(json_extract(data, '${jsonPath}')) < datetime(?)`;
|
|
669
|
-
params = [collectionName, cutoffTime];
|
|
670
|
-
}
|
|
671
|
-
return {
|
|
672
|
-
sql,
|
|
673
|
-
params,
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
/**
|
|
677
|
-
* Get TTL metadata for a specific index
|
|
678
|
-
*/
|
|
679
|
-
getTTLMetadata(collectionName, indexName) {
|
|
680
|
-
const cacheKey = `${collectionName}:${indexName}`;
|
|
681
|
-
// Check cache first
|
|
682
|
-
if (this.ttlMetadataCache.has(cacheKey)) {
|
|
683
|
-
return this.ttlMetadataCache.get(cacheKey);
|
|
684
|
-
}
|
|
685
|
-
// Load from index metadata
|
|
686
|
-
const collection = this.getCollection(collectionName);
|
|
687
|
-
if (!collection) {
|
|
688
|
-
return null;
|
|
689
|
-
}
|
|
690
|
-
const index = collection.indexes.find(idx => idx.name === indexName);
|
|
691
|
-
if (!index || index.expireAfterSeconds === undefined) {
|
|
692
|
-
return null;
|
|
693
|
-
}
|
|
694
|
-
const field = Object.keys(index.key)[0];
|
|
695
|
-
if (field === undefined) {
|
|
696
|
-
return null;
|
|
697
|
-
}
|
|
698
|
-
const metadata = {
|
|
699
|
-
field,
|
|
700
|
-
expireAfterSeconds: index.expireAfterSeconds,
|
|
701
|
-
};
|
|
702
|
-
this.ttlMetadataCache.set(cacheKey, metadata);
|
|
703
|
-
return metadata;
|
|
704
|
-
}
|
|
705
|
-
/**
|
|
706
|
-
* Record a TTL cleanup operation for tracking purposes
|
|
707
|
-
*/
|
|
708
|
-
recordTTLCleanup(collectionName, indexName, deletedCount) {
|
|
709
|
-
const cacheKey = `${collectionName}:${indexName}`;
|
|
710
|
-
const metadata = this.ttlMetadataCache.get(cacheKey);
|
|
711
|
-
if (metadata) {
|
|
712
|
-
metadata.lastCleanupAt = new Date().toISOString();
|
|
713
|
-
metadata.lastCleanupCount = deletedCount;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
/**
|
|
717
|
-
* Get the next cleanup time based on the configured interval
|
|
718
|
-
*/
|
|
719
|
-
getNextCleanupTime() {
|
|
720
|
-
return Date.now() + this.cleanupIntervalMs;
|
|
721
|
-
}
|
|
722
|
-
/**
|
|
723
|
-
* Set the cleanup interval in milliseconds
|
|
724
|
-
*/
|
|
725
|
-
setCleanupInterval(intervalMs) {
|
|
726
|
-
this.cleanupIntervalMs = intervalMs;
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* Run TTL cleanup across all collections with TTL indexes
|
|
730
|
-
* Deletes all expired documents and returns cleanup statistics
|
|
731
|
-
*/
|
|
732
|
-
async runTTLCleanup() {
|
|
733
|
-
const ttlIndexes = this.getTTLIndexes();
|
|
734
|
-
let totalDeleted = 0;
|
|
735
|
-
const errors = [];
|
|
736
|
-
for (const ttlIndex of ttlIndexes) {
|
|
737
|
-
try {
|
|
738
|
-
const query = this.buildExpiredDocumentsQuery(ttlIndex.collectionName, ttlIndex.field, ttlIndex.expireAfterSeconds);
|
|
739
|
-
if (query.sql) {
|
|
740
|
-
// Execute the delete query
|
|
741
|
-
const stmt = this.storage.prepare(query.sql);
|
|
742
|
-
stmt.bind(...query.params).run();
|
|
743
|
-
// Record the cleanup (we don't have a direct way to get affected rows in this interface)
|
|
744
|
-
this.recordTTLCleanup(ttlIndex.collectionName, ttlIndex.indexName, 0);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
catch (error) {
|
|
748
|
-
const errMsg = error instanceof Error ? error.message : String(error);
|
|
749
|
-
errors.push(`Error cleaning ${ttlIndex.collectionName}: ${errMsg}`);
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
const result = {
|
|
753
|
-
ok: 1,
|
|
754
|
-
collectionsProcessed: ttlIndexes.length,
|
|
755
|
-
documentsDeleted: totalDeleted,
|
|
756
|
-
};
|
|
757
|
-
if (errors.length > 0) {
|
|
758
|
-
result.errors = errors;
|
|
759
|
-
}
|
|
760
|
-
return result;
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
export default IndexManager;
|
|
764
|
-
//# sourceMappingURL=index-manager.js.map
|