effect-mongodb 0.1.2 → 0.1.3
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/cjs/AggregationCursor.js +9 -5
- package/dist/cjs/AggregationCursor.js.map +1 -1
- package/dist/cjs/Collection.js +23 -17
- package/dist/cjs/Collection.js.map +1 -1
- package/dist/cjs/Db.js +7 -1
- package/dist/cjs/Db.js.map +1 -1
- package/dist/cjs/DocumentAggregationCursor.js +9 -5
- package/dist/cjs/DocumentAggregationCursor.js.map +1 -1
- package/dist/cjs/DocumentCollection.js +22 -16
- package/dist/cjs/DocumentCollection.js.map +1 -1
- package/dist/cjs/DocumentFindCursor.js +9 -5
- package/dist/cjs/DocumentFindCursor.js.map +1 -1
- package/dist/cjs/FindCursor.js +11 -10
- package/dist/cjs/FindCursor.js.map +1 -1
- package/dist/cjs/ListCollectionsCursor.js +9 -5
- package/dist/cjs/ListCollectionsCursor.js.map +1 -1
- package/dist/cjs/MongoClient.js +8 -2
- package/dist/cjs/MongoClient.js.map +1 -1
- package/dist/cjs/MongoError.js +7 -18
- package/dist/cjs/MongoError.js.map +1 -1
- package/dist/cjs/internal/mongo-error.js +27 -0
- package/dist/cjs/internal/mongo-error.js.map +1 -0
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/AggregationCursor.d.ts.map +1 -1
- package/dist/dts/Collection.d.ts +12 -12
- package/dist/dts/Collection.d.ts.map +1 -1
- package/dist/dts/Db.d.ts.map +1 -1
- package/dist/dts/DocumentAggregationCursor.d.ts.map +1 -1
- package/dist/dts/DocumentCollection.d.ts +2 -2
- package/dist/dts/DocumentCollection.d.ts.map +1 -1
- package/dist/dts/DocumentFindCursor.d.ts.map +1 -1
- package/dist/dts/FindCursor.d.ts.map +1 -1
- package/dist/dts/ListCollectionsCursor.d.ts.map +1 -1
- package/dist/dts/MongoClient.d.ts.map +1 -1
- package/dist/dts/MongoError.d.ts +32 -12
- package/dist/dts/MongoError.d.ts.map +1 -1
- package/dist/dts/internal/mongo-error.d.ts +5 -0
- package/dist/dts/internal/mongo-error.d.ts.map +1 -0
- package/dist/esm/AggregationCursor.js +9 -5
- package/dist/esm/AggregationCursor.js.map +1 -1
- package/dist/esm/Collection.js +23 -17
- package/dist/esm/Collection.js.map +1 -1
- package/dist/esm/Db.js +7 -1
- package/dist/esm/Db.js.map +1 -1
- package/dist/esm/DocumentAggregationCursor.js +9 -5
- package/dist/esm/DocumentAggregationCursor.js.map +1 -1
- package/dist/esm/DocumentCollection.js +22 -16
- package/dist/esm/DocumentCollection.js.map +1 -1
- package/dist/esm/DocumentFindCursor.js +9 -5
- package/dist/esm/DocumentFindCursor.js.map +1 -1
- package/dist/esm/FindCursor.js +11 -10
- package/dist/esm/FindCursor.js.map +1 -1
- package/dist/esm/ListCollectionsCursor.js +9 -5
- package/dist/esm/ListCollectionsCursor.js.map +1 -1
- package/dist/esm/MongoClient.js +8 -2
- package/dist/esm/MongoClient.js.map +1 -1
- package/dist/esm/MongoError.js +3 -17
- package/dist/esm/MongoError.js.map +1 -1
- package/dist/esm/internal/mongo-error.js +18 -0
- package/dist/esm/internal/mongo-error.js.map +1 -0
- package/dist/esm/internal/version.js +1 -1
- package/package.json +1 -1
- package/src/AggregationCursor.ts +12 -3
- package/src/Collection.ts +47 -38
- package/src/Db.ts +5 -1
- package/src/DocumentAggregationCursor.ts +12 -3
- package/src/DocumentCollection.ts +30 -20
- package/src/DocumentFindCursor.ts +12 -3
- package/src/FindCursor.ts +15 -6
- package/src/ListCollectionsCursor.ts +12 -3
- package/src/MongoClient.ts +6 -2
- package/src/MongoError.ts +24 -32
- package/src/internal/mongo-error.ts +34 -0
- package/src/internal/version.ts +1 -1
package/dist/esm/MongoError.js
CHANGED
|
@@ -2,22 +2,8 @@
|
|
|
2
2
|
* @since 0.0.1
|
|
3
3
|
*/
|
|
4
4
|
import * as Data from "effect/Data";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import * as Stream from "effect/Stream";
|
|
9
|
-
import { MongoError as MongoError_ } from "mongodb";
|
|
5
|
+
export class ClientErrorSource extends /*#__PURE__*/Data.TaggedClass("ClientErrorSource") {}
|
|
6
|
+
export class DbErrorSource extends /*#__PURE__*/Data.TaggedClass("DbErrorSource") {}
|
|
7
|
+
export class CollectionErrorSource extends /*#__PURE__*/Data.TaggedClass("CollectionErrorSource") {}
|
|
10
8
|
export class MongoError extends /*#__PURE__*/Data.TaggedError("MongoError") {}
|
|
11
|
-
export const mongoErrorDie = /*#__PURE__*/F.dual(2, (error, message) => F.pipe(Match.value(error), Match.when(Match.instanceOf(MongoError_), innerError => Effect.fail(new MongoError({
|
|
12
|
-
message,
|
|
13
|
-
innerError
|
|
14
|
-
}))), Match.orElse(cause => Effect.die(new Error(message, {
|
|
15
|
-
cause
|
|
16
|
-
})))));
|
|
17
|
-
export const mongoErrorStream = /*#__PURE__*/F.dual(2, (error, message) => F.pipe(Match.value(error), Match.when(Match.instanceOf(MongoError_), innerError => Stream.fail(new MongoError({
|
|
18
|
-
message,
|
|
19
|
-
innerError
|
|
20
|
-
}))), Match.orElse(cause => Stream.die(new Error(message, {
|
|
21
|
-
cause
|
|
22
|
-
})))));
|
|
23
9
|
//# sourceMappingURL=MongoError.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MongoError.js","names":["Data","
|
|
1
|
+
{"version":3,"file":"MongoError.js","names":["Data","ClientErrorSource","TaggedClass","DbErrorSource","CollectionErrorSource","MongoError","TaggedError"],"sources":["../../src/MongoError.ts"],"sourcesContent":[null],"mappings":"AAAA;;;AAGA,OAAO,KAAKA,IAAI,MAAM,aAAa;AAGnC,OAAM,MAAOC,iBAAkB,sBAAQD,IAAI,CAACE,WAAW,CAAC,mBAAmB,CAIzE;AAEF,OAAM,MAAOC,aAAc,sBAAQH,IAAI,CAACE,WAAW,CAAC,eAAe,CAIjE;AAEF,OAAM,MAAOE,qBAAsB,sBAAQJ,IAAI,CAACE,WAAW,CAAC,uBAAuB,CAKjF;AAIF,OAAM,MAAOG,UAAW,sBAAQL,IAAI,CAACM,WAAW,CAAC,YAAY,CAI3D","ignoreList":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as F from "effect/Function";
|
|
3
|
+
import * as Match from "effect/Match";
|
|
4
|
+
import { MongoError as MongoError_ } from "mongodb";
|
|
5
|
+
import { MongoError } from "../MongoError.js";
|
|
6
|
+
export const mongoErrorOrDie = (source, message) => error => F.pipe(Match.value(error), Match.when(Match.instanceOf(MongoError_), F.flow(makeMongoError(source, message), Effect.fail)), Match.orElse(F.flow(makeError(source, message), Effect.die)));
|
|
7
|
+
const makeMongoError = (source, message) => cause => new MongoError({
|
|
8
|
+
message: messageFrom(source, message),
|
|
9
|
+
cause,
|
|
10
|
+
source
|
|
11
|
+
});
|
|
12
|
+
const makeError = (source, message) => cause => new Error(messageFrom(source, message), {
|
|
13
|
+
cause
|
|
14
|
+
});
|
|
15
|
+
const messageFrom = (source, message) => message ? `${messageFromSource(source)} - ${message}` : messageFromSource(source);
|
|
16
|
+
const messageFromSource = source => F.pipe(Match.value(source), Match.tag("ClientErrorSource", s => `${baseMessage(s)} - hosts ${s.hosts.join(", ")}`), Match.tag("DbErrorSource", s => `${baseMessage(s)} - ${s.db}`), Match.tag("CollectionErrorSource", s => `${baseMessage(s)} - ${s.db}.${s.collection}`), Match.exhaustive);
|
|
17
|
+
const baseMessage = s => `Error in ${s.module}.${s.functionName}`;
|
|
18
|
+
//# sourceMappingURL=mongo-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongo-error.js","names":["Effect","F","Match","MongoError","MongoError_","mongoErrorOrDie","source","message","error","pipe","value","when","instanceOf","flow","makeMongoError","fail","orElse","makeError","die","cause","messageFrom","Error","messageFromSource","tag","s","baseMessage","hosts","join","db","collection","exhaustive","module","functionName"],"sources":["../../../src/internal/mongo-error.ts"],"sourcesContent":[null],"mappings":"AAAA,OAAO,KAAKA,MAAM,MAAM,eAAe;AACvC,OAAO,KAAKC,CAAC,MAAM,iBAAiB;AACpC,OAAO,KAAKC,KAAK,MAAM,cAAc;AACrC,SAASC,UAAU,IAAIC,WAAW,QAAQ,SAAS;AAEnD,SAASD,UAAU,QAAQ,kBAAkB;AAE7C,OAAO,MAAME,eAAe,GAC1BA,CAACC,MAAmB,EAAEC,OAAgB,KAAMC,KAAc,IACxDP,CAAC,CAACQ,IAAI,CACJP,KAAK,CAACQ,KAAK,CAACF,KAAK,CAAC,EAClBN,KAAK,CAACS,IAAI,CAACT,KAAK,CAACU,UAAU,CAACR,WAAW,CAAC,EAAEH,CAAC,CAACY,IAAI,CAACC,cAAc,CAACR,MAAM,EAAEC,OAAO,CAAC,EAAEP,MAAM,CAACe,IAAI,CAAC,CAAC,EAC/Fb,KAAK,CAACc,MAAM,CAACf,CAAC,CAACY,IAAI,CAACI,SAAS,CAACX,MAAM,EAAEC,OAAO,CAAC,EAAEP,MAAM,CAACkB,GAAG,CAAC,CAAC,CAC7D;AAEL,MAAMJ,cAAc,GAAGA,CAACR,MAAmB,EAAEC,OAA2B,KAAMY,KAAkB,IAC9F,IAAIhB,UAAU,CAAC;EAAEI,OAAO,EAAEa,WAAW,CAACd,MAAM,EAAEC,OAAO,CAAC;EAAEY,KAAK;EAAEb;AAAM,CAAE,CAAC;AAE1E,MAAMW,SAAS,GAAGA,CAACX,MAAmB,EAAEC,OAA2B,KAAMY,KAAc,IACrF,IAAIE,KAAK,CAACD,WAAW,CAACd,MAAM,EAAEC,OAAO,CAAC,EAAE;EAAEY;AAAK,CAAE,CAAC;AAEpD,MAAMC,WAAW,GAAGA,CAACd,MAAmB,EAAEC,OAAgB,KACxDA,OAAO,GAAG,GAAGe,iBAAiB,CAAChB,MAAM,CAAC,MAAMC,OAAO,EAAE,GAAGe,iBAAiB,CAAChB,MAAM,CAAC;AAEnF,MAAMgB,iBAAiB,GAAIhB,MAAmB,IAC5CL,CAAC,CAACQ,IAAI,CACJP,KAAK,CAACQ,KAAK,CAACJ,MAAM,CAAC,EACnBJ,KAAK,CAACqB,GAAG,CAAC,mBAAmB,EAAGC,CAAC,IAAK,GAAGC,WAAW,CAACD,CAAC,CAAC,YAAYA,CAAC,CAACE,KAAK,CAACC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EACxFzB,KAAK,CAACqB,GAAG,CAAC,eAAe,EAAGC,CAAC,IAAK,GAAGC,WAAW,CAACD,CAAC,CAAC,MAAMA,CAAC,CAACI,EAAE,EAAE,CAAC,EAChE1B,KAAK,CAACqB,GAAG,CAAC,uBAAuB,EAAGC,CAAC,IAAK,GAAGC,WAAW,CAACD,CAAC,CAAC,MAAMA,CAAC,CAACI,EAAE,IAAIJ,CAAC,CAACK,UAAU,EAAE,CAAC,EACxF3B,KAAK,CAAC4B,UAAU,CACjB;AAEH,MAAML,WAAW,GAAID,CAA2C,IAAK,YAAYA,CAAC,CAACO,MAAM,IAAIP,CAAC,CAACQ,YAAY,EAAE","ignoreList":[]}
|
package/package.json
CHANGED
package/src/AggregationCursor.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type * as ParseResult from "effect/ParseResult"
|
|
|
8
8
|
import * as Schema from "effect/Schema"
|
|
9
9
|
import * as Stream from "effect/Stream"
|
|
10
10
|
import type { AggregationCursor as MongoAggregationCursor } from "mongodb"
|
|
11
|
+
import { mongoErrorOrDie } from "./internal/mongo-error.js"
|
|
11
12
|
import * as MongoError from "./MongoError.js"
|
|
12
13
|
|
|
13
14
|
export class AggregationCursor<A, I = A, R = never> extends Data.TaggedClass("AggregationCursor")<
|
|
@@ -19,8 +20,8 @@ export const toArray = <A, I, R>(
|
|
|
19
20
|
cursor: AggregationCursor<A, I, R>
|
|
20
21
|
): Effect.Effect<Array<A>, MongoError.MongoError | ParseResult.ParseError, R> => {
|
|
21
22
|
const decode = Schema.decodeUnknown(cursor.schema)
|
|
22
|
-
return Effect.
|
|
23
|
-
Effect.
|
|
23
|
+
return Effect.promise(() => cursor.cursor.toArray()).pipe(
|
|
24
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray"))),
|
|
24
25
|
Effect.flatMap(Effect.forEach((x) => decode(x)))
|
|
25
26
|
)
|
|
26
27
|
}
|
|
@@ -31,7 +32,15 @@ export const toStream = <A, I, R>(
|
|
|
31
32
|
const decode = Schema.decodeUnknown(cursor.schema)
|
|
32
33
|
return F.pipe(
|
|
33
34
|
Stream.fromAsyncIterable(cursor.cursor, F.identity),
|
|
34
|
-
Stream.catchAll(
|
|
35
|
+
Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream"))),
|
|
35
36
|
Stream.mapEffect((x) => decode(x))
|
|
36
37
|
)
|
|
37
38
|
}
|
|
39
|
+
|
|
40
|
+
const errorSource = <A, I, R>(cursor: AggregationCursor<A, I, R>, functionName: string) =>
|
|
41
|
+
new MongoError.CollectionErrorSource({
|
|
42
|
+
module: AggregationCursor.name,
|
|
43
|
+
functionName,
|
|
44
|
+
db: cursor.cursor.namespace.db,
|
|
45
|
+
collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
|
|
46
|
+
})
|
package/src/Collection.ts
CHANGED
|
@@ -38,6 +38,7 @@ import * as AggregationCursor from "./AggregationCursor.js"
|
|
|
38
38
|
import * as FindCursor from "./FindCursor.js"
|
|
39
39
|
import type { Filter } from "./internal/filter.js"
|
|
40
40
|
import type { ModifyResult } from "./internal/modify-result.js"
|
|
41
|
+
import { mongoErrorOrDie } from "./internal/mongo-error.js"
|
|
41
42
|
import * as SchemaExt from "./internal/schema.js"
|
|
42
43
|
import * as MongoError from "./MongoError.js"
|
|
43
44
|
|
|
@@ -93,49 +94,49 @@ export const findOne: {
|
|
|
93
94
|
const value = yield* _(Effect.promise(() => collection.collection.findOne(filter, options)))
|
|
94
95
|
return yield* _(SchemaExt.decodeNullableDocument(collection.schema, value))
|
|
95
96
|
}).pipe(
|
|
96
|
-
Effect.catchAllDefect(
|
|
97
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "findOne")))
|
|
97
98
|
)
|
|
98
99
|
)
|
|
99
100
|
|
|
100
101
|
export const insertOne: {
|
|
101
102
|
<A extends Document>(doc: A, options?: InsertOneOptions): <I extends Document, R>(
|
|
102
103
|
collection: Collection<A, I, R>
|
|
103
|
-
) => Effect.Effect<InsertOneResult
|
|
104
|
+
) => Effect.Effect<InsertOneResult<I>, MongoError.MongoError | ParseResult.ParseError, R>
|
|
104
105
|
<A extends Document, I extends Document, R>(
|
|
105
106
|
collection: Collection<A, I, R>,
|
|
106
107
|
doc: A,
|
|
107
108
|
options?: InsertOneOptions
|
|
108
|
-
): Effect.Effect<InsertOneResult
|
|
109
|
+
): Effect.Effect<InsertOneResult<I>, MongoError.MongoError | ParseResult.ParseError, R>
|
|
109
110
|
} = F.dual((args) => isCollection(args[0]), <A extends Document, I extends Document, R>(
|
|
110
111
|
collection: Collection<A, I, R>,
|
|
111
112
|
doc: A,
|
|
112
113
|
options?: InsertOneOptions
|
|
113
|
-
): Effect.Effect<InsertOneResult
|
|
114
|
+
): Effect.Effect<InsertOneResult<I>, MongoError.MongoError | ParseResult.ParseError, R> =>
|
|
114
115
|
F.pipe(
|
|
115
116
|
collection.encode(doc),
|
|
116
117
|
Effect.flatMap((doc) => Effect.promise(() => collection.collection.insertOne(doc, options))),
|
|
117
|
-
Effect.catchAllDefect(
|
|
118
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "insertOne")))
|
|
118
119
|
))
|
|
119
120
|
|
|
120
121
|
export const insertMany: {
|
|
121
122
|
<A extends Document>(docs: ReadonlyArray<A>, options?: BulkWriteOptions): <I extends Document, R>(
|
|
122
123
|
collection: Collection<A, I, R>
|
|
123
|
-
) => Effect.Effect<InsertManyResult
|
|
124
|
+
) => Effect.Effect<InsertManyResult<I>, MongoError.MongoError | ParseResult.ParseError, R>
|
|
124
125
|
<A extends Document, I extends Document, R>(
|
|
125
126
|
collection: Collection<A, I, R>,
|
|
126
127
|
docs: ReadonlyArray<A>,
|
|
127
128
|
options?: BulkWriteOptions
|
|
128
|
-
): Effect.Effect<InsertManyResult
|
|
129
|
+
): Effect.Effect<InsertManyResult<I>, MongoError.MongoError | ParseResult.ParseError, R>
|
|
129
130
|
} = F.dual((args) => isCollection(args[0]), <A extends Document, I extends Document, R>(
|
|
130
131
|
collection: Collection<A, I, R>,
|
|
131
132
|
docs: ReadonlyArray<A>,
|
|
132
133
|
options?: BulkWriteOptions
|
|
133
|
-
): Effect.Effect<InsertManyResult
|
|
134
|
+
): Effect.Effect<InsertManyResult<I>, MongoError.MongoError | ParseResult.ParseError, R> => {
|
|
134
135
|
return F.pipe(
|
|
135
136
|
docs,
|
|
136
137
|
Effect.forEach((doc) => collection.encode(doc)),
|
|
137
138
|
Effect.flatMap((docs) => Effect.promise(() => collection.collection.insertMany(docs, options))),
|
|
138
|
-
Effect.catchAllDefect(
|
|
139
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "insertMany")))
|
|
139
140
|
)
|
|
140
141
|
})
|
|
141
142
|
|
|
@@ -156,7 +157,7 @@ export const deleteOne: {
|
|
|
156
157
|
options?: DeleteOptions
|
|
157
158
|
): Effect.Effect<DeleteResult, MongoError.MongoError, R> =>
|
|
158
159
|
Effect.promise(() => collection.collection.deleteOne(filter, options)).pipe(
|
|
159
|
-
Effect.catchAllDefect(
|
|
160
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "deleteOne")))
|
|
160
161
|
)
|
|
161
162
|
)
|
|
162
163
|
|
|
@@ -177,7 +178,7 @@ export const deleteMany: {
|
|
|
177
178
|
options?: DeleteOptions
|
|
178
179
|
): Effect.Effect<DeleteResult, MongoError.MongoError, R> =>
|
|
179
180
|
Effect.promise(() => collection.collection.deleteMany(filter, options)).pipe(
|
|
180
|
-
Effect.catchAllDefect(
|
|
181
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "deleteMany")))
|
|
181
182
|
)
|
|
182
183
|
)
|
|
183
184
|
|
|
@@ -186,15 +187,15 @@ export const updateMany: {
|
|
|
186
187
|
filter: Filter<I>,
|
|
187
188
|
update: UpdateFilter<I> | ReadonlyArray<Document>,
|
|
188
189
|
options?: UpdateOptions
|
|
189
|
-
): <A extends Document, R>(
|
|
190
|
-
collection: Collection<A,
|
|
191
|
-
) => Effect.Effect<UpdateResult
|
|
190
|
+
): <A extends Document, I2 extends I, R>(
|
|
191
|
+
collection: Collection<A, I2, R>
|
|
192
|
+
) => Effect.Effect<UpdateResult<I2>, MongoError.MongoError, R>
|
|
192
193
|
<A extends Document, I extends Document, R>(
|
|
193
194
|
collection: Collection<A, I, R>,
|
|
194
195
|
filter: Filter<I>,
|
|
195
196
|
update: UpdateFilter<I> | ReadonlyArray<Document>,
|
|
196
197
|
options?: UpdateOptions
|
|
197
|
-
): Effect.Effect<UpdateResult
|
|
198
|
+
): Effect.Effect<UpdateResult<I>, MongoError.MongoError, R>
|
|
198
199
|
} = F.dual(
|
|
199
200
|
(args) => isCollection(args[0]),
|
|
200
201
|
<A extends Document, I extends Document, R>(
|
|
@@ -202,31 +203,30 @@ export const updateMany: {
|
|
|
202
203
|
filter: Filter<I>,
|
|
203
204
|
update: UpdateFilter<I> | ReadonlyArray<Document>,
|
|
204
205
|
options?: UpdateOptions
|
|
205
|
-
): Effect.Effect<UpdateResult
|
|
206
|
+
): Effect.Effect<UpdateResult<I>, MongoError.MongoError, R> =>
|
|
206
207
|
Effect.promise(() =>
|
|
207
208
|
collection.collection.updateMany(
|
|
208
209
|
filter,
|
|
209
210
|
Array.isArray(update) ? [...update] : update as UpdateFilter<Document>,
|
|
210
211
|
options
|
|
211
212
|
)
|
|
212
|
-
).pipe(Effect.catchAllDefect(
|
|
213
|
+
).pipe(Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "updateMany"))))
|
|
213
214
|
)
|
|
214
215
|
|
|
215
216
|
export const replaceOne: {
|
|
216
217
|
<A extends Document, I extends Document>(
|
|
217
218
|
filter: Filter<I>,
|
|
218
|
-
// TODO: should we put WithoutId<A> here like the driver signature?
|
|
219
219
|
replacement: A,
|
|
220
220
|
options?: ReplaceOptions
|
|
221
221
|
): <R>(
|
|
222
222
|
collection: Collection<A, I, R>
|
|
223
|
-
) => Effect.Effect<UpdateResult | Document, MongoError.MongoError | ParseResult.ParseError, R>
|
|
223
|
+
) => Effect.Effect<UpdateResult<I> | Document, MongoError.MongoError | ParseResult.ParseError, R>
|
|
224
224
|
<A extends Document, I extends Document, R>(
|
|
225
225
|
collection: Collection<A, I, R>,
|
|
226
226
|
filter: Filter<I>,
|
|
227
227
|
replacement: A,
|
|
228
228
|
options?: ReplaceOptions
|
|
229
|
-
): Effect.Effect<UpdateResult | Document, MongoError.MongoError | ParseResult.ParseError, R>
|
|
229
|
+
): Effect.Effect<UpdateResult<I> | Document, MongoError.MongoError | ParseResult.ParseError, R>
|
|
230
230
|
} = F.dual(
|
|
231
231
|
(args) => isCollection(args[0]),
|
|
232
232
|
<A extends Document, I extends Document, R>(
|
|
@@ -235,7 +235,7 @@ export const replaceOne: {
|
|
|
235
235
|
replacement: A,
|
|
236
236
|
options?: ReplaceOptions
|
|
237
237
|
): Effect.Effect<
|
|
238
|
-
UpdateResult | Document,
|
|
238
|
+
UpdateResult<I> | Document,
|
|
239
239
|
MongoError.MongoError | ParseResult.ParseError,
|
|
240
240
|
R
|
|
241
241
|
> =>
|
|
@@ -244,7 +244,7 @@ export const replaceOne: {
|
|
|
244
244
|
Effect.flatMap((replacement) =>
|
|
245
245
|
Effect.promise(() => collection.collection.replaceOne(filter, replacement, options))
|
|
246
246
|
),
|
|
247
|
-
Effect.catchAllDefect(
|
|
247
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "replaceOne")))
|
|
248
248
|
)
|
|
249
249
|
)
|
|
250
250
|
|
|
@@ -316,7 +316,7 @@ export const findOneAndReplace: {
|
|
|
316
316
|
})
|
|
317
317
|
),
|
|
318
318
|
Effect.catchAllDefect(
|
|
319
|
-
|
|
319
|
+
mongoErrorOrDie(errorSource(collection, "findOneAndReplace"))
|
|
320
320
|
)
|
|
321
321
|
)
|
|
322
322
|
)
|
|
@@ -340,7 +340,7 @@ export const rename: {
|
|
|
340
340
|
F.pipe(
|
|
341
341
|
Effect.promise(() => collection.collection.rename(newName, options)),
|
|
342
342
|
Effect.map((newCollection) => new Collection<A, I, R>({ collection: newCollection, schema: collection.schema })),
|
|
343
|
-
Effect.catchAllDefect(
|
|
343
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "rename")))
|
|
344
344
|
)
|
|
345
345
|
)
|
|
346
346
|
|
|
@@ -360,7 +360,7 @@ export const drop: {
|
|
|
360
360
|
): Effect.Effect<boolean, MongoError.MongoError, R> =>
|
|
361
361
|
F.pipe(
|
|
362
362
|
Effect.promise(() => collection.collection.drop(options)),
|
|
363
|
-
Effect.catchAllDefect(
|
|
363
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "drop")))
|
|
364
364
|
)
|
|
365
365
|
)
|
|
366
366
|
|
|
@@ -385,7 +385,7 @@ export const createIndexes: {
|
|
|
385
385
|
): Effect.Effect<Array<string>, MongoError.MongoError, R> =>
|
|
386
386
|
F.pipe(
|
|
387
387
|
Effect.promise(() => collection.collection.createIndexes([...indexSpecs], options)),
|
|
388
|
-
Effect.catchAllDefect(
|
|
388
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "createIndexes")))
|
|
389
389
|
)
|
|
390
390
|
)
|
|
391
391
|
|
|
@@ -407,54 +407,52 @@ export const createIndex: {
|
|
|
407
407
|
): Effect.Effect<string, MongoError.MongoError, R> =>
|
|
408
408
|
F.pipe(
|
|
409
409
|
Effect.promise(() => collection.collection.createIndex(indexSpec, options)),
|
|
410
|
-
Effect.catchAllDefect(
|
|
410
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "createIndex")))
|
|
411
411
|
)
|
|
412
412
|
)
|
|
413
413
|
|
|
414
|
-
// TODO: review return type. Should we return Document like mongodb driver?
|
|
415
414
|
export const dropIndex: {
|
|
416
415
|
(indexName: string, options?: DropIndexesOptions): <A extends Document, I extends Document, R>(
|
|
417
416
|
collection: Collection<A, I, R>
|
|
418
|
-
) => Effect.Effect<
|
|
417
|
+
) => Effect.Effect<Document, MongoError.MongoError, R>
|
|
419
418
|
<A extends Document, I extends Document, R>(
|
|
420
419
|
collection: Collection<A, I, R>,
|
|
421
420
|
indexName: string,
|
|
422
421
|
options?: DropIndexesOptions
|
|
423
|
-
): Effect.Effect<
|
|
422
|
+
): Effect.Effect<Document, MongoError.MongoError, R>
|
|
424
423
|
} = F.dual(
|
|
425
424
|
(args) => isCollection(args[0]),
|
|
426
425
|
<A extends Document, I extends Document, R>(
|
|
427
426
|
collection: Collection<A, I, R>,
|
|
428
427
|
indexName: string,
|
|
429
428
|
options?: DropIndexesOptions
|
|
430
|
-
): Effect.Effect<
|
|
429
|
+
): Effect.Effect<Document, MongoError.MongoError, R> =>
|
|
431
430
|
F.pipe(
|
|
432
431
|
Effect.promise(() => collection.collection.dropIndex(indexName, options)),
|
|
433
|
-
Effect.
|
|
434
|
-
Effect.catchAllDefect(MongoError.mongoErrorDie<void>("dropIndex error"))
|
|
432
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "dropIndex")))
|
|
435
433
|
)
|
|
436
434
|
)
|
|
437
435
|
|
|
438
436
|
export const aggregate: {
|
|
439
437
|
<B extends Document, BI extends Document, BR>(
|
|
440
|
-
pipeline: ReadonlyArray<Document>,
|
|
441
438
|
schema: Schema.Schema<B, BI, BR>,
|
|
439
|
+
pipeline: ReadonlyArray<Document>,
|
|
442
440
|
options?: AggregateOptions
|
|
443
441
|
): <A extends Document, I extends Document, R>(
|
|
444
442
|
collection: Collection<A, I, R>
|
|
445
443
|
) => AggregationCursor.AggregationCursor<B, BI, BR>
|
|
446
444
|
<A extends Document, I extends Document, R, B extends Document, BI extends Document, BR>(
|
|
447
445
|
collection: Collection<A, I, R>,
|
|
448
|
-
pipeline: ReadonlyArray<Document>,
|
|
449
446
|
schema: Schema.Schema<B, BI, BR>,
|
|
447
|
+
pipeline: ReadonlyArray<Document>,
|
|
450
448
|
options?: AggregateOptions
|
|
451
449
|
): AggregationCursor.AggregationCursor<B, BI, BR>
|
|
452
450
|
} = F.dual(
|
|
453
451
|
(args) => isCollection(args[0]),
|
|
454
452
|
<A extends Document, I extends Document, R, B extends Document, BI extends Document, BR>(
|
|
455
453
|
collection: Collection<A, I, R>,
|
|
456
|
-
pipeline: ReadonlyArray<Document>,
|
|
457
454
|
schema: Schema.Schema<B, BI, BR>,
|
|
455
|
+
pipeline: ReadonlyArray<Document>,
|
|
458
456
|
options?: AggregateOptions
|
|
459
457
|
): AggregationCursor.AggregationCursor<B, BI, BR> =>
|
|
460
458
|
new AggregationCursor.AggregationCursor<B, BI, BR>({
|
|
@@ -479,7 +477,7 @@ export const estimatedDocumentCount: {
|
|
|
479
477
|
): Effect.Effect<number, MongoError.MongoError, R> =>
|
|
480
478
|
F.pipe(
|
|
481
479
|
Effect.promise(() => collection.collection.estimatedDocumentCount(options)),
|
|
482
|
-
Effect.catchAllDefect(
|
|
480
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "estimatedDocumentCount")))
|
|
483
481
|
)
|
|
484
482
|
)
|
|
485
483
|
|
|
@@ -501,8 +499,19 @@ export const countDocuments: {
|
|
|
501
499
|
): Effect.Effect<number, MongoError.MongoError, R> =>
|
|
502
500
|
F.pipe(
|
|
503
501
|
Effect.promise(() => collection.collection.countDocuments(filter, options)),
|
|
504
|
-
Effect.catchAllDefect(
|
|
502
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "countDocuments")))
|
|
505
503
|
)
|
|
506
504
|
)
|
|
507
505
|
|
|
508
506
|
const isCollection = (x: unknown) => x instanceof Collection
|
|
507
|
+
|
|
508
|
+
const errorSource = <A extends Document, I extends Document = A, R = never>(
|
|
509
|
+
collection: Collection<A, I, R>,
|
|
510
|
+
functionName: string
|
|
511
|
+
) =>
|
|
512
|
+
new MongoError.CollectionErrorSource({
|
|
513
|
+
module: Collection.name,
|
|
514
|
+
functionName,
|
|
515
|
+
db: collection.collection.dbName,
|
|
516
|
+
collection: collection.collection.collectionName
|
|
517
|
+
})
|
package/src/Db.ts
CHANGED
|
@@ -8,6 +8,7 @@ import type { Document, DropCollectionOptions, ListCollectionsOptions } from "mo
|
|
|
8
8
|
import { Db } from "mongodb"
|
|
9
9
|
import type * as Collection from "./Collection.js"
|
|
10
10
|
import * as DocumentCollection from "./DocumentCollection.js"
|
|
11
|
+
import { mongoErrorOrDie } from "./internal/mongo-error.js"
|
|
11
12
|
import * as ListCollectionsCursor from "./ListCollectionsCursor.js"
|
|
12
13
|
import * as MongoError from "./MongoError.js"
|
|
13
14
|
|
|
@@ -79,8 +80,11 @@ export const dropCollection: {
|
|
|
79
80
|
(db: Db, name: string, options?: DropCollectionOptions): Effect.Effect<boolean, MongoError.MongoError> =>
|
|
80
81
|
F.pipe(
|
|
81
82
|
Effect.promise(() => db.dropCollection(name, options)),
|
|
82
|
-
Effect.catchAllDefect(
|
|
83
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(db, "dropCollection")))
|
|
83
84
|
)
|
|
84
85
|
)
|
|
85
86
|
|
|
86
87
|
const isDb = (x: unknown) => x instanceof Db
|
|
88
|
+
|
|
89
|
+
const errorSource = (db: Db, functionName: string) =>
|
|
90
|
+
new MongoError.DbErrorSource({ module: "Db", functionName, db: db.databaseName })
|
|
@@ -6,6 +6,7 @@ import * as Effect from "effect/Effect"
|
|
|
6
6
|
import * as F from "effect/Function"
|
|
7
7
|
import * as Stream from "effect/Stream"
|
|
8
8
|
import type { AggregationCursor as MongoAggregationCursor, Document } from "mongodb"
|
|
9
|
+
import { mongoErrorOrDie } from "./internal/mongo-error.js"
|
|
9
10
|
import * as MongoError from "./MongoError.js"
|
|
10
11
|
|
|
11
12
|
export class DocumentAggregationCursor
|
|
@@ -17,8 +18,8 @@ export const toArray = (
|
|
|
17
18
|
cursor: DocumentAggregationCursor
|
|
18
19
|
): Effect.Effect<Array<Document>, MongoError.MongoError> =>
|
|
19
20
|
F.pipe(
|
|
20
|
-
Effect.
|
|
21
|
-
Effect.
|
|
21
|
+
Effect.promise(() => cursor.cursor.toArray()),
|
|
22
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(cursor, "toArray")))
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
export const toStream = (
|
|
@@ -26,5 +27,13 @@ export const toStream = (
|
|
|
26
27
|
): Stream.Stream<Document, MongoError.MongoError> =>
|
|
27
28
|
F.pipe(
|
|
28
29
|
Stream.fromAsyncIterable(cursor.cursor, F.identity),
|
|
29
|
-
Stream.catchAll(
|
|
30
|
+
Stream.catchAll(mongoErrorOrDie(errorSource(cursor, "toStream")))
|
|
30
31
|
)
|
|
32
|
+
|
|
33
|
+
const errorSource = (cursor: DocumentAggregationCursor, functionName: string) =>
|
|
34
|
+
new MongoError.CollectionErrorSource({
|
|
35
|
+
module: DocumentAggregationCursor.name,
|
|
36
|
+
functionName,
|
|
37
|
+
db: cursor.cursor.namespace.db,
|
|
38
|
+
collection: cursor.cursor.namespace.collection ?? "NO_COLLECTION_NAME"
|
|
39
|
+
})
|
|
@@ -40,6 +40,7 @@ import * as Collection from "./Collection.js"
|
|
|
40
40
|
import * as DocumentAggregationCursor from "./DocumentAggregationCursor.js"
|
|
41
41
|
import * as DocumentFindCursor from "./DocumentFindCursor.js"
|
|
42
42
|
import type { ModifyResult } from "./internal/modify-result.js"
|
|
43
|
+
import { mongoErrorOrDie } from "./internal/mongo-error.js"
|
|
43
44
|
import * as MongoError from "./MongoError.js"
|
|
44
45
|
|
|
45
46
|
export class DocumentCollection extends Data.TaggedClass("DocumentCollection")<{
|
|
@@ -86,7 +87,7 @@ export const findOne: {
|
|
|
86
87
|
F.pipe(
|
|
87
88
|
Effect.promise(() => collection.collection.findOne(filter, options)),
|
|
88
89
|
Effect.map((value) => O.fromNullable(value)),
|
|
89
|
-
Effect.catchAllDefect(
|
|
90
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "findOne")))
|
|
90
91
|
)
|
|
91
92
|
)
|
|
92
93
|
|
|
@@ -110,7 +111,7 @@ export const insertOne: {
|
|
|
110
111
|
): Effect.Effect<InsertOneResult, MongoError.MongoError> =>
|
|
111
112
|
F.pipe(
|
|
112
113
|
Effect.promise(() => collection.collection.insertOne(doc, options)),
|
|
113
|
-
Effect.catchAllDefect(
|
|
114
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "insertOne")))
|
|
114
115
|
))
|
|
115
116
|
|
|
116
117
|
export const insertMany: {
|
|
@@ -132,7 +133,7 @@ export const insertMany: {
|
|
|
132
133
|
): Effect.Effect<InsertManyResult, MongoError.MongoError> =>
|
|
133
134
|
F.pipe(
|
|
134
135
|
Effect.promise(() => collection.collection.insertMany(docs, options)),
|
|
135
|
-
Effect.catchAllDefect(
|
|
136
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "insertMany")))
|
|
136
137
|
))
|
|
137
138
|
|
|
138
139
|
export const deleteOne: {
|
|
@@ -153,7 +154,7 @@ export const deleteOne: {
|
|
|
153
154
|
): Effect.Effect<DeleteResult, MongoError.MongoError> =>
|
|
154
155
|
F.pipe(
|
|
155
156
|
Effect.promise(() => collection.collection.deleteOne(filter, options)),
|
|
156
|
-
Effect.catchAllDefect(
|
|
157
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "deleteOne")))
|
|
157
158
|
)
|
|
158
159
|
)
|
|
159
160
|
|
|
@@ -175,7 +176,7 @@ export const deleteMany: {
|
|
|
175
176
|
): Effect.Effect<DeleteResult, MongoError.MongoError> =>
|
|
176
177
|
F.pipe(
|
|
177
178
|
Effect.promise(() => collection.collection.deleteMany(filter, options)),
|
|
178
|
-
Effect.catchAllDefect(
|
|
179
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "deleteMany")))
|
|
179
180
|
)
|
|
180
181
|
)
|
|
181
182
|
|
|
@@ -205,7 +206,7 @@ export const updateMany: {
|
|
|
205
206
|
Effect.promise(() =>
|
|
206
207
|
collection.collection.updateMany(filter, Array.isArray(update) ? [...update] : update, options)
|
|
207
208
|
),
|
|
208
|
-
Effect.catchAllDefect(
|
|
209
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "updateMany")))
|
|
209
210
|
)
|
|
210
211
|
)
|
|
211
212
|
|
|
@@ -233,7 +234,7 @@ export const replaceOne: {
|
|
|
233
234
|
): Effect.Effect<UpdateResult | Document, MongoError.MongoError> =>
|
|
234
235
|
F.pipe(
|
|
235
236
|
Effect.promise(() => collection.collection.replaceOne(filter, replacement, options)),
|
|
236
|
-
Effect.catchAllDefect(
|
|
237
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "replaceOne")))
|
|
237
238
|
)
|
|
238
239
|
)
|
|
239
240
|
|
|
@@ -303,7 +304,7 @@ export const findOneAndReplace: {
|
|
|
303
304
|
return O.fromNullable(value)
|
|
304
305
|
}),
|
|
305
306
|
Effect.catchAllDefect(
|
|
306
|
-
|
|
307
|
+
mongoErrorOrDie(errorSource(collection, "findOneAndReplace"))
|
|
307
308
|
)
|
|
308
309
|
)
|
|
309
310
|
)
|
|
@@ -327,7 +328,7 @@ export const rename: {
|
|
|
327
328
|
F.pipe(
|
|
328
329
|
Effect.promise(() => collection.collection.rename(newName, options)),
|
|
329
330
|
Effect.map((collection) => new DocumentCollection({ collection })),
|
|
330
|
-
Effect.catchAllDefect(
|
|
331
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "rename")))
|
|
331
332
|
)
|
|
332
333
|
)
|
|
333
334
|
|
|
@@ -342,7 +343,7 @@ export const drop: {
|
|
|
342
343
|
): Effect.Effect<boolean, MongoError.MongoError> =>
|
|
343
344
|
F.pipe(
|
|
344
345
|
Effect.promise(() => collection.collection.drop(options)),
|
|
345
|
-
Effect.catchAllDefect(
|
|
346
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "drop")))
|
|
346
347
|
)
|
|
347
348
|
)
|
|
348
349
|
|
|
@@ -364,7 +365,7 @@ export const createIndexes: {
|
|
|
364
365
|
): Effect.Effect<Array<string>, MongoError.MongoError> =>
|
|
365
366
|
F.pipe(
|
|
366
367
|
Effect.promise(() => collection.collection.createIndexes([...indexSpecs], options)),
|
|
367
|
-
Effect.catchAllDefect(
|
|
368
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "createIndexes")))
|
|
368
369
|
)
|
|
369
370
|
)
|
|
370
371
|
|
|
@@ -387,32 +388,30 @@ export const createIndex: {
|
|
|
387
388
|
): Effect.Effect<string, MongoError.MongoError> =>
|
|
388
389
|
F.pipe(
|
|
389
390
|
Effect.promise(() => collection.collection.createIndex(indexSpec, options)),
|
|
390
|
-
Effect.catchAllDefect(
|
|
391
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "createIndex")))
|
|
391
392
|
)
|
|
392
393
|
)
|
|
393
394
|
|
|
394
|
-
// TODO: review return type. Should we return Document like mongodb driver?
|
|
395
395
|
export const dropIndex: {
|
|
396
396
|
(
|
|
397
397
|
indexName: string,
|
|
398
398
|
options?: DropIndexesOptions
|
|
399
|
-
): (collection: DocumentCollection) => Effect.Effect<
|
|
399
|
+
): (collection: DocumentCollection) => Effect.Effect<Document, MongoError.MongoError>
|
|
400
400
|
(
|
|
401
401
|
collection: DocumentCollection,
|
|
402
402
|
indexName: string,
|
|
403
403
|
options?: DropIndexesOptions
|
|
404
|
-
): Effect.Effect<
|
|
404
|
+
): Effect.Effect<Document, MongoError.MongoError>
|
|
405
405
|
} = F.dual(
|
|
406
406
|
(args) => isDocumentCollection(args[0]),
|
|
407
407
|
(
|
|
408
408
|
collection: DocumentCollection,
|
|
409
409
|
indexName: string,
|
|
410
410
|
options?: DropIndexesOptions
|
|
411
|
-
): Effect.Effect<
|
|
411
|
+
): Effect.Effect<Document, MongoError.MongoError> =>
|
|
412
412
|
F.pipe(
|
|
413
413
|
Effect.promise(() => collection.collection.dropIndex(indexName, options)),
|
|
414
|
-
Effect.
|
|
415
|
-
Effect.catchAllDefect(MongoError.mongoErrorDie<void>("dropIndex error"))
|
|
414
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "dropIndex")))
|
|
416
415
|
)
|
|
417
416
|
)
|
|
418
417
|
|
|
@@ -453,7 +452,7 @@ export const estimatedDocumentCount: {
|
|
|
453
452
|
): Effect.Effect<number, MongoError.MongoError> =>
|
|
454
453
|
F.pipe(
|
|
455
454
|
Effect.promise(() => collection.collection.estimatedDocumentCount(options)),
|
|
456
|
-
Effect.catchAllDefect(
|
|
455
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "estimatedDocumentCount")))
|
|
457
456
|
)
|
|
458
457
|
)
|
|
459
458
|
|
|
@@ -475,7 +474,7 @@ export const countDocuments: {
|
|
|
475
474
|
): Effect.Effect<number, MongoError.MongoError> =>
|
|
476
475
|
F.pipe(
|
|
477
476
|
Effect.promise(() => collection.collection.countDocuments(filter, options)),
|
|
478
|
-
Effect.catchAllDefect(
|
|
477
|
+
Effect.catchAllDefect(mongoErrorOrDie(errorSource(collection, "countDocuments")))
|
|
479
478
|
)
|
|
480
479
|
)
|
|
481
480
|
|
|
@@ -493,3 +492,14 @@ export const typed: {
|
|
|
493
492
|
): Collection.Collection<A, I, R> => new Collection.Collection<A, I, R>({ collection: collection.collection, schema }))
|
|
494
493
|
|
|
495
494
|
const isDocumentCollection = (x: unknown) => x instanceof DocumentCollection
|
|
495
|
+
|
|
496
|
+
const errorSource = (
|
|
497
|
+
collection: DocumentCollection,
|
|
498
|
+
functionName: string
|
|
499
|
+
) =>
|
|
500
|
+
new MongoError.CollectionErrorSource({
|
|
501
|
+
module: DocumentCollection.name,
|
|
502
|
+
functionName,
|
|
503
|
+
db: collection.collection.dbName,
|
|
504
|
+
collection: collection.collection.collectionName
|
|
505
|
+
})
|