@prisma-next/adapter-mongo 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/codec-types.d.mts +26 -0
- package/dist/codec-types.d.mts.map +1 -0
- package/dist/codec-types.mjs +1 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +52 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +47 -0
- package/src/core/codec-ids.ts +5 -0
- package/src/core/codecs.ts +44 -0
- package/src/exports/codec-types.ts +7 -0
- package/src/exports/index.ts +1 -0
- package/src/mongo-adapter.ts +105 -0
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# @prisma-next/adapter-mongo
|
|
2
|
+
|
|
3
|
+
MongoDB adapter for Prisma Next. Lowers abstract MongoDB commands into wire-protocol documents.
|
|
4
|
+
|
|
5
|
+
## Responsibilities
|
|
6
|
+
|
|
7
|
+
- **Command lowering**: Converts `MongoCommand` instances (find, aggregate) into MongoDB wire-protocol documents
|
|
8
|
+
- **Codec application**: Applies codec transformations to query parameters and result documents
|
|
9
|
+
|
|
10
|
+
## Dependencies
|
|
11
|
+
|
|
12
|
+
- **Depends on**:
|
|
13
|
+
- `@prisma-next/mongo-core` (command types, codec types)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/exports/codec-types.d.ts
|
|
2
|
+
type CodecTypes = {
|
|
3
|
+
readonly 'mongo/objectId@1': {
|
|
4
|
+
readonly input: string;
|
|
5
|
+
readonly output: string;
|
|
6
|
+
};
|
|
7
|
+
readonly 'mongo/string@1': {
|
|
8
|
+
readonly input: string;
|
|
9
|
+
readonly output: string;
|
|
10
|
+
};
|
|
11
|
+
readonly 'mongo/int32@1': {
|
|
12
|
+
readonly input: number;
|
|
13
|
+
readonly output: number;
|
|
14
|
+
};
|
|
15
|
+
readonly 'mongo/bool@1': {
|
|
16
|
+
readonly input: boolean;
|
|
17
|
+
readonly output: boolean;
|
|
18
|
+
};
|
|
19
|
+
readonly 'mongo/date@1': {
|
|
20
|
+
readonly input: Date;
|
|
21
|
+
readonly output: Date;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { CodecTypes };
|
|
26
|
+
//# sourceMappingURL=codec-types.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec-types.d.mts","names":[],"sources":["../src/exports/codec-types.ts"],"sourcesContent":[],"mappings":";KAAY,UAAA;EAAA,SAAA,kBAKiC,EAAA;;;;;;;;;;;;;;;;;oBAAA;qBAAuB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/mongo-adapter.ts"],"sourcesContent":[],"mappings":";;;iBAsGgB,kBAAA,CAAA,GAAsB"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { AggregateWireCommand, DeleteOneWireCommand, FindWireCommand, InsertOneWireCommand, MongoParamRef, UpdateOneWireCommand } from "@prisma-next/mongo-core";
|
|
2
|
+
|
|
3
|
+
//#region src/mongo-adapter.ts
|
|
4
|
+
var MongoAdapterImpl = class {
|
|
5
|
+
lower(queryPlan, _context) {
|
|
6
|
+
const wireCommand = this.#lowerCommand(queryPlan.command);
|
|
7
|
+
return Object.freeze({
|
|
8
|
+
wireCommand,
|
|
9
|
+
command: queryPlan.command,
|
|
10
|
+
meta: queryPlan.meta
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
#lowerCommand(command) {
|
|
14
|
+
switch (command.kind) {
|
|
15
|
+
case "find": {
|
|
16
|
+
const options = {};
|
|
17
|
+
if (command.projection) options.projection = { ...command.projection };
|
|
18
|
+
if (command.sort) options.sort = { ...command.sort };
|
|
19
|
+
if (command.limit !== void 0) options.limit = command.limit;
|
|
20
|
+
if (command.skip !== void 0) options.skip = command.skip;
|
|
21
|
+
return new FindWireCommand(command.collection, command.filter ? this.#resolveDocument(command.filter) : void 0, options);
|
|
22
|
+
}
|
|
23
|
+
case "insertOne": return new InsertOneWireCommand(command.collection, this.#resolveDocument(command.document));
|
|
24
|
+
case "updateOne": return new UpdateOneWireCommand(command.collection, this.#resolveDocument(command.filter), this.#resolveDocument(command.update));
|
|
25
|
+
case "deleteOne": return new DeleteOneWireCommand(command.collection, this.#resolveDocument(command.filter));
|
|
26
|
+
case "aggregate": return new AggregateWireCommand(command.collection, command.pipeline.map((stage) => ({ ...stage })));
|
|
27
|
+
default: {
|
|
28
|
+
const _exhaustive = command;
|
|
29
|
+
throw new Error(`Unknown command kind: ${_exhaustive.kind}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
#resolveValue(value) {
|
|
34
|
+
if (value instanceof MongoParamRef) return value.value;
|
|
35
|
+
if (value === null || typeof value !== "object") return value;
|
|
36
|
+
if (value instanceof Date) return value;
|
|
37
|
+
if (Array.isArray(value)) return value.map((v) => this.#resolveValue(v));
|
|
38
|
+
return this.#resolveDocument(value);
|
|
39
|
+
}
|
|
40
|
+
#resolveDocument(expr) {
|
|
41
|
+
const result = {};
|
|
42
|
+
for (const [key, val] of Object.entries(expr)) result[key] = this.#resolveValue(val);
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
function createMongoAdapter() {
|
|
47
|
+
return new MongoAdapterImpl();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
export { createMongoAdapter };
|
|
52
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["#lowerCommand","options: {\n projection?: Document;\n sort?: Document;\n limit?: number;\n skip?: number;\n }","#resolveDocument","_exhaustive: never","#resolveValue","result: Record<string, unknown>"],"sources":["../src/mongo-adapter.ts"],"sourcesContent":["import type {\n AnyMongoCommand,\n AnyMongoWireCommand,\n Document,\n MongoAdapter,\n MongoExecutionPlan,\n MongoExpr,\n MongoLoweringContext,\n MongoQueryPlan,\n MongoValue,\n} from '@prisma-next/mongo-core';\nimport {\n AggregateWireCommand,\n DeleteOneWireCommand,\n FindWireCommand,\n InsertOneWireCommand,\n MongoParamRef,\n UpdateOneWireCommand,\n} from '@prisma-next/mongo-core';\n\nclass MongoAdapterImpl implements MongoAdapter {\n lower<Row>(\n queryPlan: MongoQueryPlan<Row>,\n _context: MongoLoweringContext,\n ): MongoExecutionPlan<Row> {\n const wireCommand = this.#lowerCommand(queryPlan.command);\n return Object.freeze({\n wireCommand,\n command: queryPlan.command,\n meta: queryPlan.meta,\n });\n }\n\n #lowerCommand(command: AnyMongoCommand): AnyMongoWireCommand {\n switch (command.kind) {\n case 'find': {\n const options: {\n projection?: Document;\n sort?: Document;\n limit?: number;\n skip?: number;\n } = {};\n if (command.projection) options.projection = { ...command.projection };\n if (command.sort) options.sort = { ...command.sort };\n if (command.limit !== undefined) options.limit = command.limit;\n if (command.skip !== undefined) options.skip = command.skip;\n return new FindWireCommand(\n command.collection,\n command.filter ? this.#resolveDocument(command.filter) : undefined,\n options,\n );\n }\n case 'insertOne':\n return new InsertOneWireCommand(\n command.collection,\n this.#resolveDocument(command.document),\n );\n case 'updateOne':\n return new UpdateOneWireCommand(\n command.collection,\n this.#resolveDocument(command.filter),\n this.#resolveDocument(command.update),\n );\n case 'deleteOne':\n return new DeleteOneWireCommand(command.collection, this.#resolveDocument(command.filter));\n case 'aggregate':\n return new AggregateWireCommand(\n command.collection,\n command.pipeline.map((stage) => ({ ...stage })),\n );\n default: {\n const _exhaustive: never = command;\n throw new Error(`Unknown command kind: ${(_exhaustive as { kind: string }).kind}`);\n }\n }\n }\n\n #resolveValue(value: MongoValue): unknown {\n if (value instanceof MongoParamRef) {\n return value.value;\n }\n if (value === null || typeof value !== 'object') {\n return value;\n }\n if (value instanceof Date) {\n return value;\n }\n if (Array.isArray(value)) {\n return value.map((v) => this.#resolveValue(v));\n }\n return this.#resolveDocument(value as MongoExpr);\n }\n\n #resolveDocument(expr: MongoExpr): Document {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(expr)) {\n result[key] = this.#resolveValue(val);\n }\n return result;\n }\n}\n\nexport function createMongoAdapter(): MongoAdapter {\n return new MongoAdapterImpl();\n}\n"],"mappings":";;;AAoBA,IAAM,mBAAN,MAA+C;CAC7C,MACE,WACA,UACyB;EACzB,MAAM,cAAc,MAAKA,aAAc,UAAU,QAAQ;AACzD,SAAO,OAAO,OAAO;GACnB;GACA,SAAS,UAAU;GACnB,MAAM,UAAU;GACjB,CAAC;;CAGJ,cAAc,SAA+C;AAC3D,UAAQ,QAAQ,MAAhB;GACE,KAAK,QAAQ;IACX,MAAMC,UAKF,EAAE;AACN,QAAI,QAAQ,WAAY,SAAQ,aAAa,EAAE,GAAG,QAAQ,YAAY;AACtE,QAAI,QAAQ,KAAM,SAAQ,OAAO,EAAE,GAAG,QAAQ,MAAM;AACpD,QAAI,QAAQ,UAAU,OAAW,SAAQ,QAAQ,QAAQ;AACzD,QAAI,QAAQ,SAAS,OAAW,SAAQ,OAAO,QAAQ;AACvD,WAAO,IAAI,gBACT,QAAQ,YACR,QAAQ,SAAS,MAAKC,gBAAiB,QAAQ,OAAO,GAAG,QACzD,QACD;;GAEH,KAAK,YACH,QAAO,IAAI,qBACT,QAAQ,YACR,MAAKA,gBAAiB,QAAQ,SAAS,CACxC;GACH,KAAK,YACH,QAAO,IAAI,qBACT,QAAQ,YACR,MAAKA,gBAAiB,QAAQ,OAAO,EACrC,MAAKA,gBAAiB,QAAQ,OAAO,CACtC;GACH,KAAK,YACH,QAAO,IAAI,qBAAqB,QAAQ,YAAY,MAAKA,gBAAiB,QAAQ,OAAO,CAAC;GAC5F,KAAK,YACH,QAAO,IAAI,qBACT,QAAQ,YACR,QAAQ,SAAS,KAAK,WAAW,EAAE,GAAG,OAAO,EAAE,CAChD;GACH,SAAS;IACP,MAAMC,cAAqB;AAC3B,UAAM,IAAI,MAAM,yBAA0B,YAAiC,OAAO;;;;CAKxF,cAAc,OAA4B;AACxC,MAAI,iBAAiB,cACnB,QAAO,MAAM;AAEf,MAAI,UAAU,QAAQ,OAAO,UAAU,SACrC,QAAO;AAET,MAAI,iBAAiB,KACnB,QAAO;AAET,MAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,MAAM,KAAK,MAAM,MAAKC,aAAc,EAAE,CAAC;AAEhD,SAAO,MAAKF,gBAAiB,MAAmB;;CAGlD,iBAAiB,MAA2B;EAC1C,MAAMG,SAAkC,EAAE;AAC1C,OAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,KAAK,CAC3C,QAAO,OAAO,MAAKD,aAAc,IAAI;AAEvC,SAAO;;;AAIX,SAAgB,qBAAmC;AACjD,QAAO,IAAI,kBAAkB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prisma-next/adapter-mongo",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"description": "MongoDB adapter for Prisma Next (lowers commands to wire format)",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsdown",
|
|
9
|
+
"test": "vitest run --passWithNoTests",
|
|
10
|
+
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
11
|
+
"typecheck": "tsc --noEmit",
|
|
12
|
+
"lint": "biome check . --error-on-warnings",
|
|
13
|
+
"lint:fix": "biome check --write .",
|
|
14
|
+
"lint:fix:unsafe": "biome check --write --unsafe .",
|
|
15
|
+
"clean": "rm -rf dist dist-tsc dist-tsc-prod coverage .tmp-output"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@prisma-next/mongo-core": "workspace:*",
|
|
19
|
+
"mongodb": "^6.16.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@prisma-next/contract": "workspace:*",
|
|
23
|
+
"@prisma-next/test-utils": "workspace:*",
|
|
24
|
+
"@prisma-next/tsconfig": "workspace:*",
|
|
25
|
+
"@prisma-next/tsdown": "workspace:*",
|
|
26
|
+
"tsdown": "catalog:",
|
|
27
|
+
"typescript": "catalog:",
|
|
28
|
+
"vitest": "catalog:"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"src"
|
|
33
|
+
],
|
|
34
|
+
"exports": {
|
|
35
|
+
".": "./dist/index.mjs",
|
|
36
|
+
"./codec-types": "./dist/codec-types.mjs",
|
|
37
|
+
"./package.json": "./package.json"
|
|
38
|
+
},
|
|
39
|
+
"main": "./dist/index.mjs",
|
|
40
|
+
"module": "./dist/index.mjs",
|
|
41
|
+
"types": "./dist/index.d.mts",
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/prisma/prisma-next.git",
|
|
45
|
+
"directory": "packages/3-mongo-target/2-mongo-adapter"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export const MONGO_OBJECTID_CODEC_ID = 'mongo/objectId@1' as const;
|
|
2
|
+
export const MONGO_STRING_CODEC_ID = 'mongo/string@1' as const;
|
|
3
|
+
export const MONGO_INT32_CODEC_ID = 'mongo/int32@1' as const;
|
|
4
|
+
export const MONGO_BOOLEAN_CODEC_ID = 'mongo/bool@1' as const;
|
|
5
|
+
export const MONGO_DATE_CODEC_ID = 'mongo/date@1' as const;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { mongoCodec } from '@prisma-next/mongo-core';
|
|
2
|
+
import { ObjectId } from 'mongodb';
|
|
3
|
+
import {
|
|
4
|
+
MONGO_BOOLEAN_CODEC_ID,
|
|
5
|
+
MONGO_DATE_CODEC_ID,
|
|
6
|
+
MONGO_INT32_CODEC_ID,
|
|
7
|
+
MONGO_OBJECTID_CODEC_ID,
|
|
8
|
+
MONGO_STRING_CODEC_ID,
|
|
9
|
+
} from './codec-ids';
|
|
10
|
+
|
|
11
|
+
export const mongoObjectIdCodec = mongoCodec({
|
|
12
|
+
typeId: MONGO_OBJECTID_CODEC_ID,
|
|
13
|
+
targetTypes: ['objectId'],
|
|
14
|
+
decode: (wire: ObjectId) => wire.toHexString(),
|
|
15
|
+
encode: (value: string) => new ObjectId(value),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const mongoStringCodec = mongoCodec({
|
|
19
|
+
typeId: MONGO_STRING_CODEC_ID,
|
|
20
|
+
targetTypes: ['string'],
|
|
21
|
+
decode: (wire: string) => wire,
|
|
22
|
+
encode: (value: string) => value,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const mongoInt32Codec = mongoCodec({
|
|
26
|
+
typeId: MONGO_INT32_CODEC_ID,
|
|
27
|
+
targetTypes: ['int'],
|
|
28
|
+
decode: (wire: number) => wire,
|
|
29
|
+
encode: (value: number) => value,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export const mongoBooleanCodec = mongoCodec({
|
|
33
|
+
typeId: MONGO_BOOLEAN_CODEC_ID,
|
|
34
|
+
targetTypes: ['bool'],
|
|
35
|
+
decode: (wire: boolean) => wire,
|
|
36
|
+
encode: (value: boolean) => value,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export const mongoDateCodec = mongoCodec({
|
|
40
|
+
typeId: MONGO_DATE_CODEC_ID,
|
|
41
|
+
targetTypes: ['date'],
|
|
42
|
+
decode: (wire: Date) => wire,
|
|
43
|
+
encode: (value: Date) => value,
|
|
44
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type CodecTypes = {
|
|
2
|
+
readonly 'mongo/objectId@1': { readonly input: string; readonly output: string };
|
|
3
|
+
readonly 'mongo/string@1': { readonly input: string; readonly output: string };
|
|
4
|
+
readonly 'mongo/int32@1': { readonly input: number; readonly output: number };
|
|
5
|
+
readonly 'mongo/bool@1': { readonly input: boolean; readonly output: boolean };
|
|
6
|
+
readonly 'mongo/date@1': { readonly input: Date; readonly output: Date };
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createMongoAdapter } from '../mongo-adapter';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
AnyMongoCommand,
|
|
3
|
+
AnyMongoWireCommand,
|
|
4
|
+
Document,
|
|
5
|
+
MongoAdapter,
|
|
6
|
+
MongoExecutionPlan,
|
|
7
|
+
MongoExpr,
|
|
8
|
+
MongoLoweringContext,
|
|
9
|
+
MongoQueryPlan,
|
|
10
|
+
MongoValue,
|
|
11
|
+
} from '@prisma-next/mongo-core';
|
|
12
|
+
import {
|
|
13
|
+
AggregateWireCommand,
|
|
14
|
+
DeleteOneWireCommand,
|
|
15
|
+
FindWireCommand,
|
|
16
|
+
InsertOneWireCommand,
|
|
17
|
+
MongoParamRef,
|
|
18
|
+
UpdateOneWireCommand,
|
|
19
|
+
} from '@prisma-next/mongo-core';
|
|
20
|
+
|
|
21
|
+
class MongoAdapterImpl implements MongoAdapter {
|
|
22
|
+
lower<Row>(
|
|
23
|
+
queryPlan: MongoQueryPlan<Row>,
|
|
24
|
+
_context: MongoLoweringContext,
|
|
25
|
+
): MongoExecutionPlan<Row> {
|
|
26
|
+
const wireCommand = this.#lowerCommand(queryPlan.command);
|
|
27
|
+
return Object.freeze({
|
|
28
|
+
wireCommand,
|
|
29
|
+
command: queryPlan.command,
|
|
30
|
+
meta: queryPlan.meta,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
#lowerCommand(command: AnyMongoCommand): AnyMongoWireCommand {
|
|
35
|
+
switch (command.kind) {
|
|
36
|
+
case 'find': {
|
|
37
|
+
const options: {
|
|
38
|
+
projection?: Document;
|
|
39
|
+
sort?: Document;
|
|
40
|
+
limit?: number;
|
|
41
|
+
skip?: number;
|
|
42
|
+
} = {};
|
|
43
|
+
if (command.projection) options.projection = { ...command.projection };
|
|
44
|
+
if (command.sort) options.sort = { ...command.sort };
|
|
45
|
+
if (command.limit !== undefined) options.limit = command.limit;
|
|
46
|
+
if (command.skip !== undefined) options.skip = command.skip;
|
|
47
|
+
return new FindWireCommand(
|
|
48
|
+
command.collection,
|
|
49
|
+
command.filter ? this.#resolveDocument(command.filter) : undefined,
|
|
50
|
+
options,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
case 'insertOne':
|
|
54
|
+
return new InsertOneWireCommand(
|
|
55
|
+
command.collection,
|
|
56
|
+
this.#resolveDocument(command.document),
|
|
57
|
+
);
|
|
58
|
+
case 'updateOne':
|
|
59
|
+
return new UpdateOneWireCommand(
|
|
60
|
+
command.collection,
|
|
61
|
+
this.#resolveDocument(command.filter),
|
|
62
|
+
this.#resolveDocument(command.update),
|
|
63
|
+
);
|
|
64
|
+
case 'deleteOne':
|
|
65
|
+
return new DeleteOneWireCommand(command.collection, this.#resolveDocument(command.filter));
|
|
66
|
+
case 'aggregate':
|
|
67
|
+
return new AggregateWireCommand(
|
|
68
|
+
command.collection,
|
|
69
|
+
command.pipeline.map((stage) => ({ ...stage })),
|
|
70
|
+
);
|
|
71
|
+
default: {
|
|
72
|
+
const _exhaustive: never = command;
|
|
73
|
+
throw new Error(`Unknown command kind: ${(_exhaustive as { kind: string }).kind}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#resolveValue(value: MongoValue): unknown {
|
|
79
|
+
if (value instanceof MongoParamRef) {
|
|
80
|
+
return value.value;
|
|
81
|
+
}
|
|
82
|
+
if (value === null || typeof value !== 'object') {
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
if (value instanceof Date) {
|
|
86
|
+
return value;
|
|
87
|
+
}
|
|
88
|
+
if (Array.isArray(value)) {
|
|
89
|
+
return value.map((v) => this.#resolveValue(v));
|
|
90
|
+
}
|
|
91
|
+
return this.#resolveDocument(value as MongoExpr);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
#resolveDocument(expr: MongoExpr): Document {
|
|
95
|
+
const result: Record<string, unknown> = {};
|
|
96
|
+
for (const [key, val] of Object.entries(expr)) {
|
|
97
|
+
result[key] = this.#resolveValue(val);
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function createMongoAdapter(): MongoAdapter {
|
|
104
|
+
return new MongoAdapterImpl();
|
|
105
|
+
}
|