effect-mongodb 0.0.3 → 0.0.4

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.
Files changed (50) hide show
  1. package/README.md +6 -1
  2. package/dist/cjs/Collection.js +20 -3
  3. package/dist/cjs/Collection.js.map +1 -1
  4. package/dist/cjs/DocumentCollection.js +16 -3
  5. package/dist/cjs/DocumentCollection.js.map +1 -1
  6. package/dist/cjs/DocumentFindCursor.js.map +1 -1
  7. package/dist/cjs/FindCursor.js +1 -5
  8. package/dist/cjs/FindCursor.js.map +1 -1
  9. package/dist/cjs/MongoClient.js.map +1 -1
  10. package/dist/cjs/internal/modify-result.js +6 -0
  11. package/dist/cjs/internal/modify-result.js.map +1 -0
  12. package/dist/cjs/internal/schema.js +19 -0
  13. package/dist/cjs/internal/schema.js.map +1 -0
  14. package/dist/cjs/internal/version.js +1 -1
  15. package/dist/dts/Collection.d.ts +34 -3
  16. package/dist/dts/Collection.d.ts.map +1 -1
  17. package/dist/dts/DocumentCollection.d.ts +34 -3
  18. package/dist/dts/DocumentCollection.d.ts.map +1 -1
  19. package/dist/dts/DocumentFindCursor.d.ts +3 -3
  20. package/dist/dts/DocumentFindCursor.d.ts.map +1 -1
  21. package/dist/dts/FindCursor.d.ts +5 -4
  22. package/dist/dts/FindCursor.d.ts.map +1 -1
  23. package/dist/dts/MongoClient.d.ts +1 -1
  24. package/dist/dts/MongoClient.d.ts.map +1 -1
  25. package/dist/dts/internal/modify-result.d.ts +6 -0
  26. package/dist/dts/internal/modify-result.d.ts.map +1 -0
  27. package/dist/dts/internal/schema.d.ts +6 -0
  28. package/dist/dts/internal/schema.d.ts.map +1 -0
  29. package/dist/esm/Collection.js +19 -2
  30. package/dist/esm/Collection.js.map +1 -1
  31. package/dist/esm/DocumentCollection.js +15 -2
  32. package/dist/esm/DocumentCollection.js.map +1 -1
  33. package/dist/esm/DocumentFindCursor.js.map +1 -1
  34. package/dist/esm/FindCursor.js +1 -5
  35. package/dist/esm/FindCursor.js.map +1 -1
  36. package/dist/esm/MongoClient.js.map +1 -1
  37. package/dist/esm/internal/modify-result.js +2 -0
  38. package/dist/esm/internal/modify-result.js.map +1 -0
  39. package/dist/esm/internal/schema.js +10 -0
  40. package/dist/esm/internal/schema.js.map +1 -0
  41. package/dist/esm/internal/version.js +1 -1
  42. package/package.json +1 -1
  43. package/src/Collection.ts +167 -3
  44. package/src/DocumentCollection.ts +148 -3
  45. package/src/DocumentFindCursor.ts +4 -4
  46. package/src/FindCursor.ts +16 -13
  47. package/src/MongoClient.ts +5 -2
  48. package/src/internal/modify-result.ts +6 -0
  49. package/src/internal/schema.ts +12 -0
  50. package/src/internal/version.ts +1 -1
package/src/Collection.ts CHANGED
@@ -15,11 +15,16 @@ import type {
15
15
  DeleteOptions,
16
16
  DeleteResult,
17
17
  Document,
18
+ DropCollectionOptions,
19
+ DropIndexesOptions,
20
+ FindOneAndReplaceOptions,
18
21
  FindOptions as MongoFindOptions,
19
22
  IndexDescription,
23
+ IndexSpecification,
20
24
  InsertManyResult,
21
25
  InsertOneOptions,
22
26
  InsertOneResult,
27
+ ModifyResult as MongoModifyResult,
23
28
  RenameOptions,
24
29
  ReplaceOptions,
25
30
  UpdateFilter,
@@ -29,6 +34,8 @@ import type {
29
34
  import * as AggregationCursor from "./AggregationCursor.js"
30
35
  import * as FindCursor from "./FindCursor.js"
31
36
  import type { Filter } from "./internal/filter.js"
37
+ import type { ModifyResult } from "./internal/modify-result.js"
38
+ import * as SchemaExt from "./internal/schema.js"
32
39
  import * as MongoError from "./MongoError.js"
33
40
 
34
41
  export class Collection<A extends Document, I extends Document = A, R = never> extends Data.TaggedClass("Collection")<{
@@ -40,21 +47,24 @@ export class Collection<A extends Document, I extends Document = A, R = never> e
40
47
  export type FindOptions = Omit<MongoFindOptions, "projection">
41
48
 
42
49
  export const find: {
43
- (
50
+ <I extends Document>(
51
+ filter?: Filter<I>,
44
52
  options?: FindOptions
45
- ): <A extends Document, I extends Document, R>(collection: Collection<A, I, R>) => FindCursor.FindCursor<A, I, R>
53
+ ): <A extends Document, R>(collection: Collection<A, I, R>) => FindCursor.FindCursor<A, I, R>
46
54
  <A extends Document, I extends Document, R>(
47
55
  collection: Collection<A, I, R>,
56
+ filter?: Filter<I>,
48
57
  options?: FindOptions
49
58
  ): FindCursor.FindCursor<A, I, R>
50
59
  } = F.dual(
51
60
  (args) => isCollection(args[0]),
52
61
  <A extends Document, I extends Document, R>(
53
62
  collection: Collection<A, I, R>,
63
+ filter?: Filter<I>,
54
64
  options?: FindOptions
55
65
  ): FindCursor.FindCursor<A, I, R> =>
56
66
  new FindCursor.FindCursor<A, I, R>({
57
- cursor: collection.collection.find({}, options),
67
+ cursor: collection.collection.find(filter ?? {}, options),
58
68
  schema: collection.schema
59
69
  })
60
70
  )
@@ -250,6 +260,87 @@ export const replaceOne: {
250
260
  )
251
261
  )
252
262
 
263
+ export const findOneAndReplace: {
264
+ <A extends Document, I extends Document>(
265
+ filter: Filter<I>,
266
+ replacement: A,
267
+ options: FindOneAndReplaceOptions & { includeResultMetadata: true }
268
+ ): <R>(
269
+ collection: Collection<A, I, R>
270
+ ) => Effect.Effect<ModifyResult<A>, MongoError.MongoError | ParseResult.ParseError, R>
271
+ <A extends Document, I extends Document>(
272
+ filter: Filter<I>,
273
+ replacement: A,
274
+ options: FindOneAndReplaceOptions & { includeResultMetadata: false }
275
+ ): <R>(
276
+ collection: Collection<A, I, R>
277
+ ) => Effect.Effect<O.Option<A>, MongoError.MongoError | ParseResult.ParseError, R>
278
+ <A extends Document, I extends Document>(
279
+ filter: Filter<I>,
280
+ replacement: A,
281
+ options: FindOneAndReplaceOptions
282
+ ): <R>(
283
+ collection: Collection<A, I, R>
284
+ ) => Effect.Effect<O.Option<A>, MongoError.MongoError | ParseResult.ParseError, R>
285
+ <A extends Document, I extends Document>(
286
+ filter: Filter<I>,
287
+ replacement: A
288
+ ): <R>(
289
+ collection: Collection<A, I, R>
290
+ ) => Effect.Effect<O.Option<A>, MongoError.MongoError | ParseResult.ParseError, R>
291
+ <A extends Document, I extends Document, R>(
292
+ collection: Collection<A, I, R>,
293
+ filter: Filter<I>,
294
+ replacement: A,
295
+ options: FindOneAndReplaceOptions & { includeResultMetadata: true }
296
+ ): Effect.Effect<ModifyResult<A>, MongoError.MongoError | ParseResult.ParseError, R>
297
+ <A extends Document, I extends Document, R>(
298
+ collection: Collection<A, I, R>,
299
+ filter: Filter<I>,
300
+ replacement: A,
301
+ options: FindOneAndReplaceOptions & { includeResultMetadata: false }
302
+ ): Effect.Effect<O.Option<A>, MongoError.MongoError | ParseResult.ParseError, R>
303
+ <A extends Document, I extends Document, R>(
304
+ collection: Collection<A, I, R>,
305
+ filter: Filter<I>,
306
+ replacement: A,
307
+ options: FindOneAndReplaceOptions
308
+ ): Effect.Effect<O.Option<A>, MongoError.MongoError | ParseResult.ParseError, R>
309
+ <A extends Document, I extends Document, R>(
310
+ collection: Collection<A, I, R>,
311
+ filter: Filter<I>,
312
+ replacement: A
313
+ ): Effect.Effect<O.Option<A>, MongoError.MongoError | ParseResult.ParseError, R>
314
+ } = F.dual(
315
+ (args) => isCollection(args[0]),
316
+ <A extends Document, I extends Document, R>(
317
+ collection: Collection<A, I, R>,
318
+ filter: Filter<I>,
319
+ replacement: A,
320
+ options?: FindOneAndReplaceOptions
321
+ ): Effect.Effect<O.Option<A> | ModifyResult<A>, MongoError.MongoError | ParseResult.ParseError, R> =>
322
+ F.pipe(
323
+ // TODO: extract function in Collection
324
+ Schema.encode(collection.schema)(replacement),
325
+ Effect.flatMap((replacement) =>
326
+ Effect.promise(() => collection.collection.findOneAndReplace(filter, replacement, options ?? {}))
327
+ ),
328
+ Effect.flatMap((value) =>
329
+ Effect.gen(function*(_) {
330
+ if (options?.includeResultMetadata && !!value) {
331
+ const result = value as unknown as MongoModifyResult<I>
332
+ const maybeValue = yield* _(SchemaExt.decodeNullableDocument(collection.schema, result.value))
333
+ return { ...result, value: maybeValue }
334
+ }
335
+ return yield* _(SchemaExt.decodeNullableDocument(collection.schema, value))
336
+ })
337
+ ),
338
+ Effect.catchAllDefect(
339
+ MongoError.mongoErrorDie<O.Option<A> | ModifyResult<A>>("findOneAndReplace error")
340
+ )
341
+ )
342
+ )
343
+
253
344
  export const rename: {
254
345
  (
255
346
  newName: string,
@@ -276,6 +367,28 @@ export const rename: {
276
367
  )
277
368
  )
278
369
 
370
+ export const drop: {
371
+ (
372
+ options?: DropCollectionOptions
373
+ ): <A extends Document, I extends Document, R>(
374
+ collection: Collection<A, I, R>
375
+ ) => Effect.Effect<boolean, MongoError.MongoError, R>
376
+ <A extends Document, I extends Document, R>(
377
+ collection: Collection<A, I, R>,
378
+ options?: DropCollectionOptions
379
+ ): Effect.Effect<boolean, MongoError.MongoError, R>
380
+ } = F.dual(
381
+ (args) => isCollection(args[0]),
382
+ <A extends Document, I extends Document, R>(
383
+ collection: Collection<A, I, R>,
384
+ options?: DropCollectionOptions
385
+ ): Effect.Effect<boolean, MongoError.MongoError, R> =>
386
+ F.pipe(
387
+ Effect.promise(() => collection.collection.drop(options)),
388
+ Effect.catchAllDefect(MongoError.mongoErrorDie<boolean>("drop error"))
389
+ )
390
+ )
391
+
279
392
  export const createIndexes: {
280
393
  (
281
394
  indexSpecs: Array<IndexDescription>,
@@ -301,6 +414,57 @@ export const createIndexes: {
301
414
  )
302
415
  )
303
416
 
417
+ export const createIndex: {
418
+ (
419
+ indexSpec: IndexSpecification,
420
+ options?: CreateIndexesOptions
421
+ ): <A extends Document, I extends Document, R>(
422
+ collection: Collection<A, I, R>
423
+ ) => Effect.Effect<string, MongoError.MongoError, R>
424
+ <A extends Document, I extends Document, R>(
425
+ collection: Collection<A, I, R>,
426
+ indexSpec: IndexSpecification,
427
+ options?: CreateIndexesOptions
428
+ ): Effect.Effect<string, MongoError.MongoError, R>
429
+ } = F.dual(
430
+ (args) => isCollection(args[0]),
431
+ <A extends Document, I extends Document, R>(
432
+ collection: Collection<A, I, R>,
433
+ indexSpec: IndexSpecification,
434
+ options?: CreateIndexesOptions
435
+ ): Effect.Effect<string, MongoError.MongoError, R> =>
436
+ F.pipe(
437
+ Effect.promise(() => collection.collection.createIndex(indexSpec, options)),
438
+ Effect.catchAllDefect(MongoError.mongoErrorDie<string>("createIndex error"))
439
+ )
440
+ )
441
+
442
+ export const dropIndex: {
443
+ (
444
+ indexName: string,
445
+ options?: DropIndexesOptions
446
+ ): <A extends Document, I extends Document, R>(
447
+ collection: Collection<A, I, R>
448
+ ) => Effect.Effect<void, MongoError.MongoError, R>
449
+ <A extends Document, I extends Document, R>(
450
+ collection: Collection<A, I, R>,
451
+ indexName: string,
452
+ options?: DropIndexesOptions
453
+ ): Effect.Effect<void, MongoError.MongoError, R>
454
+ } = F.dual(
455
+ (args) => isCollection(args[0]),
456
+ <A extends Document, I extends Document, R>(
457
+ collection: Collection<A, I, R>,
458
+ indexName: string,
459
+ options?: DropIndexesOptions
460
+ ): Effect.Effect<void, MongoError.MongoError, R> =>
461
+ F.pipe(
462
+ Effect.promise(() => collection.collection.dropIndex(indexName, options)),
463
+ Effect.asVoid,
464
+ Effect.catchAllDefect(MongoError.mongoErrorDie<void>("dropIndex error"))
465
+ )
466
+ )
467
+
304
468
  export const aggregate: {
305
469
  <B extends Document, BI extends Document, BR>(
306
470
  pipeline: Array<Document>,
@@ -14,12 +14,17 @@ import type {
14
14
  DeleteOptions,
15
15
  DeleteResult,
16
16
  Document,
17
+ DropCollectionOptions,
18
+ DropIndexesOptions,
17
19
  Filter,
20
+ FindOneAndReplaceOptions,
18
21
  FindOptions,
19
22
  IndexDescription,
23
+ IndexSpecification,
20
24
  InsertManyResult,
21
25
  InsertOneOptions,
22
26
  InsertOneResult,
27
+ ModifyResult as MongoModifyResult,
23
28
  OptionalUnlessRequiredId,
24
29
  RenameOptions,
25
30
  ReplaceOptions,
@@ -31,6 +36,7 @@ import type {
31
36
  import * as Collection from "./Collection.js"
32
37
  import * as DocumentAggregationCursor from "./DocumentAggregationCursor.js"
33
38
  import * as DocumentFindCursor from "./DocumentFindCursor.js"
39
+ import type { ModifyResult } from "./internal/modify-result.js"
34
40
  import * as MongoError from "./MongoError.js"
35
41
 
36
42
  export class DocumentCollection extends Data.TaggedClass("DocumentCollection")<{
@@ -39,17 +45,21 @@ export class DocumentCollection extends Data.TaggedClass("DocumentCollection")<{
39
45
  }
40
46
 
41
47
  export const find: {
42
- (options?: FindOptions): (collection: DocumentCollection) => DocumentFindCursor.DocumentFindCursor
48
+ (
49
+ filter?: Filter<Document>,
50
+ options?: FindOptions
51
+ ): (collection: DocumentCollection) => DocumentFindCursor.DocumentFindCursor
43
52
  (
44
53
  collection: DocumentCollection,
54
+ filter?: Filter<Document>,
45
55
  options?: FindOptions
46
56
  ): DocumentFindCursor.DocumentFindCursor
47
57
  } = F.dual(
48
58
  (args) => isDocumentCollection(args[0]),
49
- (collection: DocumentCollection, options?: FindOptions) =>
59
+ (collection: DocumentCollection, filter?: Filter<Document>, options?: FindOptions) =>
50
60
  new DocumentFindCursor.DocumentFindCursor(
51
61
  {
52
- cursor: collection.collection.find({}, options)
62
+ cursor: collection.collection.find(filter ?? {}, options)
53
63
  }
54
64
  )
55
65
  )
@@ -230,6 +240,80 @@ export const replaceOne: {
230
240
  )
231
241
  )
232
242
 
243
+ export const findOneAndReplace: {
244
+ (
245
+ filter: Filter<Document>,
246
+ replacement: WithoutId<Document>,
247
+ options: FindOneAndReplaceOptions & { includeResultMetadata: true }
248
+ ): (
249
+ collection: DocumentCollection
250
+ ) => Effect.Effect<ModifyResult<Document>, MongoError.MongoError>
251
+ (
252
+ filter: Filter<Document>,
253
+ replacement: WithoutId<Document>,
254
+ options: FindOneAndReplaceOptions & { includeResultMetadata: false }
255
+ ): (
256
+ collection: DocumentCollection
257
+ ) => Effect.Effect<O.Option<Document>, MongoError.MongoError>
258
+ (
259
+ filter: Filter<Document>,
260
+ replacement: WithoutId<Document>,
261
+ options: FindOneAndReplaceOptions
262
+ ): (
263
+ collection: DocumentCollection
264
+ ) => Effect.Effect<O.Option<Document>, MongoError.MongoError>
265
+ (
266
+ filter: Filter<Document>,
267
+ replacement: WithoutId<Document>
268
+ ): (
269
+ collection: DocumentCollection
270
+ ) => Effect.Effect<O.Option<Document>, MongoError.MongoError>
271
+ (
272
+ collection: DocumentCollection,
273
+ filter: Filter<Document>,
274
+ replacement: WithoutId<Document>,
275
+ options: FindOneAndReplaceOptions & { includeResultMetadata: true }
276
+ ): Effect.Effect<ModifyResult<Document>, MongoError.MongoError>
277
+ (
278
+ collection: DocumentCollection,
279
+ filter: Filter<Document>,
280
+ replacement: WithoutId<Document>,
281
+ options: FindOneAndReplaceOptions & { includeResultMetadata: false }
282
+ ): Effect.Effect<O.Option<Document>, MongoError.MongoError>
283
+ (
284
+ collection: DocumentCollection,
285
+ filter: Filter<Document>,
286
+ replacement: WithoutId<Document>,
287
+ options: FindOneAndReplaceOptions
288
+ ): Effect.Effect<O.Option<Document>, MongoError.MongoError>
289
+ (
290
+ collection: DocumentCollection,
291
+ filter: Filter<Document>,
292
+ replacement: WithoutId<Document>
293
+ ): Effect.Effect<O.Option<Document>, MongoError.MongoError>
294
+ } = F.dual(
295
+ (args) => isDocumentCollection(args[0]),
296
+ (
297
+ collection: DocumentCollection,
298
+ filter: Filter<Document>,
299
+ replacement: WithoutId<Document>,
300
+ options?: FindOneAndReplaceOptions
301
+ ): Effect.Effect<O.Option<Document> | ModifyResult<Document>, MongoError.MongoError> =>
302
+ F.pipe(
303
+ Effect.promise(() => collection.collection.findOneAndReplace(filter, replacement, options ?? {})),
304
+ Effect.map((value) => {
305
+ if (options?.includeResultMetadata && !!value) {
306
+ const result = value as unknown as MongoModifyResult<Document>
307
+ return { ...result, value: O.fromNullable(result.value) }
308
+ }
309
+ return O.fromNullable(value)
310
+ }),
311
+ Effect.catchAllDefect(
312
+ MongoError.mongoErrorDie<O.Option<Document> | ModifyResult<Document>>("findOneAndReplace error")
313
+ )
314
+ )
315
+ )
316
+
233
317
  export const rename: {
234
318
  (
235
319
  newName: string,
@@ -255,6 +339,21 @@ export const rename: {
255
339
  )
256
340
  )
257
341
 
342
+ export const drop: {
343
+ (options?: DropCollectionOptions): (collection: DocumentCollection) => Effect.Effect<boolean, MongoError.MongoError>
344
+ (collection: DocumentCollection, options?: DropCollectionOptions): Effect.Effect<boolean, MongoError.MongoError>
345
+ } = F.dual(
346
+ (args) => isDocumentCollection(args[0]),
347
+ (
348
+ collection: DocumentCollection,
349
+ options?: DropCollectionOptions
350
+ ): Effect.Effect<boolean, MongoError.MongoError> =>
351
+ F.pipe(
352
+ Effect.promise(() => collection.collection.drop(options)),
353
+ Effect.catchAllDefect(MongoError.mongoErrorDie<boolean>("drop error"))
354
+ )
355
+ )
356
+
258
357
  export const createIndexes: {
259
358
  (
260
359
  indexSpecs: Array<IndexDescription>,
@@ -280,6 +379,52 @@ export const createIndexes: {
280
379
  )
281
380
  )
282
381
 
382
+ export const createIndex: {
383
+ (
384
+ indexSpec: IndexSpecification,
385
+ options?: CreateIndexesOptions
386
+ ): (collection: DocumentCollection) => Effect.Effect<string, MongoError.MongoError>
387
+ (
388
+ collection: DocumentCollection,
389
+ indexSpec: IndexSpecification,
390
+ options?: CreateIndexesOptions
391
+ ): Effect.Effect<string, MongoError.MongoError>
392
+ } = F.dual(
393
+ (args) => isDocumentCollection(args[0]),
394
+ (
395
+ collection: DocumentCollection,
396
+ indexSpec: IndexSpecification,
397
+ options?: CreateIndexesOptions
398
+ ): Effect.Effect<string, MongoError.MongoError> =>
399
+ F.pipe(
400
+ Effect.promise(() => collection.collection.createIndex(indexSpec, options)),
401
+ Effect.catchAllDefect(MongoError.mongoErrorDie<string>("createIndex error"))
402
+ )
403
+ )
404
+
405
+ export const dropIndex: {
406
+ (
407
+ indexName: string,
408
+ options?: DropIndexesOptions
409
+ ): (collection: DocumentCollection) => Effect.Effect<Document, MongoError.MongoError>
410
+ (
411
+ collection: DocumentCollection,
412
+ indexName: string,
413
+ options?: DropIndexesOptions
414
+ ): Effect.Effect<Document, MongoError.MongoError>
415
+ } = F.dual(
416
+ (args) => isDocumentCollection(args[0]),
417
+ (
418
+ collection: DocumentCollection,
419
+ indexName: string,
420
+ options?: DropIndexesOptions
421
+ ): Effect.Effect<Document, MongoError.MongoError> =>
422
+ F.pipe(
423
+ Effect.promise(() => collection.collection.dropIndex(indexName, options)),
424
+ Effect.catchAllDefect(MongoError.mongoErrorDie<Document>("dropIndex error"))
425
+ )
426
+ )
427
+
283
428
  export const aggregate: {
284
429
  (
285
430
  pipeline?: Array<Document>,
@@ -6,7 +6,7 @@ import * as Effect from "effect/Effect"
6
6
  import * as F from "effect/Function"
7
7
  import type * as Schema from "effect/Schema"
8
8
  import * as Stream from "effect/Stream"
9
- import type { Document, FindCursor as MongoFindCursor, Sort, SortDirection } from "mongodb"
9
+ import type { Document, Filter, FindCursor as MongoFindCursor, Sort, SortDirection } from "mongodb"
10
10
  import * as FindCursor from "./FindCursor.js"
11
11
  import * as MongoError from "./MongoError.js"
12
12
 
@@ -17,12 +17,12 @@ export class DocumentFindCursor extends Data.TaggedClass("DocumentFindCursor")<{
17
17
 
18
18
  export const filter: {
19
19
  (
20
- filter: Document
20
+ filter: Filter<Document>
21
21
  ): (cursor: DocumentFindCursor) => DocumentFindCursor
22
- (cursor: DocumentFindCursor, filter: Document): DocumentFindCursor
22
+ (cursor: DocumentFindCursor, filter: Filter<Document>): DocumentFindCursor
23
23
  } = F.dual(
24
24
  (args) => isDocumentFindCursor(args[0]),
25
- (cursor: DocumentFindCursor, filter: Document): DocumentFindCursor =>
25
+ (cursor: DocumentFindCursor, filter: Filter<Document>): DocumentFindCursor =>
26
26
  new DocumentFindCursor({ cursor: cursor.cursor.filter(filter) })
27
27
  )
28
28
 
package/src/FindCursor.ts CHANGED
@@ -10,26 +10,28 @@ import * as Schema from "effect/Schema"
10
10
  import * as Stream from "effect/Stream"
11
11
  import * as Tuple from "effect/Tuple"
12
12
  import type { Document, FindCursor as FindCursor_, Sort, SortDirection } from "mongodb"
13
+ import type { Filter } from "./internal/filter.js"
13
14
  import * as MongoError from "./MongoError.js"
14
15
 
15
16
  export class FindCursor<A, I = A, R = never> extends Data.TaggedClass("FindCursor")<{
16
17
  cursor: FindCursor_<unknown>
17
18
  schema: Schema.Schema<A, I, R>
18
- }> {}
19
+ }> {
20
+ }
19
21
 
20
22
  export const filter: {
21
- <T extends Document = Document>(
22
- filter: T
23
- ): <A, I, R>(cursor: FindCursor<A, I, R>) => FindCursor<A, I, R>
24
- <A, I, R, T extends Document = Document>(
23
+ <I extends Document>(
24
+ filter: Filter<I>
25
+ ): <A, R>(cursor: FindCursor<A, I, R>) => FindCursor<A, I, R>
26
+ <A, I extends Document, R>(
25
27
  cursor: FindCursor<A, I, R>,
26
- filter: T
28
+ filter: Filter<I>
27
29
  ): FindCursor<A, I, R>
28
30
  } = F.dual(
29
31
  (args) => isFindCursor(args[0]),
30
- <A, I, R, T extends Document = Document>(
32
+ <A, I extends Document, R>(
31
33
  cursor: FindCursor<A, I, R>,
32
- filter: T
34
+ filter: Filter<I>
33
35
  ): FindCursor<A, I, R> => new FindCursor({ cursor: cursor.cursor.filter(filter), schema: cursor.schema })
34
36
  )
35
37
 
@@ -82,8 +84,9 @@ export const limit: {
82
84
  new FindCursor({ cursor: cursor.cursor.limit(value), schema: cursor.schema })
83
85
  )
84
86
 
85
- // TODO: add explicit return type for public API
86
- export const toArray = <A, I, R>(cursor: FindCursor<A, I, R>) => {
87
+ export const toArray = <A, I, R>(
88
+ cursor: FindCursor<A, I, R>
89
+ ): Effect.Effect<Array<A>, MongoError.MongoError | ParseResult.ParseError, R> => {
87
90
  const decode = Schema.decodeUnknown(cursor.schema)
88
91
  return Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }).pipe(
89
92
  Effect.catchAll(MongoError.mongoErrorDie<ReadonlyArray<A>>("Unable to get array from mongodb cursor")),
@@ -91,14 +94,14 @@ export const toArray = <A, I, R>(cursor: FindCursor<A, I, R>) => {
91
94
  )
92
95
  }
93
96
 
94
- // TODO: add explicit return type for public API
95
- export const toArrayEither = <A, I, R>(cursor: FindCursor<A, I, R>) => {
97
+ export const toArrayEither = <A, I, R>(
98
+ cursor: FindCursor<A, I, R>
99
+ ): Effect.Effect<Array<E.Either<A, [document: unknown, error: ParseResult.ParseError]>>, MongoError.MongoError, R> => {
96
100
  const decode = Schema.decodeUnknown(cursor.schema)
97
101
  return Effect.tryPromise({ try: () => cursor.cursor.toArray(), catch: F.identity }).pipe(
98
102
  Effect.catchAll(MongoError.mongoErrorDie<ReadonlyArray<A>>("Unable to get array from mongodb cursor")),
99
103
  Effect.flatMap(Effect.forEach((x) =>
100
104
  F.pipe(
101
- // keep new line
102
105
  decode(x),
103
106
  Effect.mapError((error) => Tuple.make(x, error)),
104
107
  Effect.either
@@ -12,7 +12,10 @@ import * as Context from "effect/Context"
12
12
 
13
13
  export type MongoClient = MongoClient_
14
14
 
15
- export const connect = (url: string, options?: MongoClientOptions) =>
15
+ export const connect = (
16
+ url: string,
17
+ options?: MongoClientOptions
18
+ ): Effect.Effect<MongoClient, MongoError.MongoError> =>
16
19
  Effect.promise(() => MongoClient_.connect(url, options)).pipe(
17
20
  Effect.catchAll(MongoError.mongoErrorDie<MongoClient_>("connect error"))
18
21
  )
@@ -22,7 +25,7 @@ export const db: {
22
25
  (client: MongoClient, dbName?: string, options?: DbOptions): Db
23
26
  } = F.dual(
24
27
  (args) => isMongoClient(args[0]),
25
- (client: MongoClient, dbName?: string, options?: DbOptions) => client.db(dbName, options)
28
+ (client: MongoClient, dbName?: string, options?: DbOptions): Db => client.db(dbName, options)
26
29
  )
27
30
 
28
31
  const isMongoClient = (x: unknown) => x instanceof MongoClient_
@@ -0,0 +1,6 @@
1
+ import type * as O from "effect/Option"
2
+ import type { ModifyResult as MongoModifyResult } from "mongodb"
3
+
4
+ export type ModifyResult<TSchema> = Omit<MongoModifyResult<TSchema>, "value"> & {
5
+ value: O.Option<TSchema>
6
+ }
@@ -0,0 +1,12 @@
1
+ import * as Effect from "effect/Effect"
2
+ import * as O from "effect/Option"
3
+ import * as Schema from "effect/Schema"
4
+ import type { Document } from "mongodb"
5
+
6
+ // TODO: there is probably a Schema to do this decode or using typeclass package for traverse
7
+ export const decodeNullableDocument = <A, I, R>(schema: Schema.Schema<A, I, R>, value: Document | null) =>
8
+ Effect.gen(function*(_) {
9
+ if (value === null) return O.none()
10
+ const decoded = yield* _(Schema.decodeUnknown(schema)(value))
11
+ return O.some(decoded)
12
+ })
@@ -1,4 +1,4 @@
1
- let moduleVersion = "0.0.3"
1
+ let moduleVersion = "0.0.4"
2
2
 
3
3
  export const getCurrentVersion = () => moduleVersion
4
4