albatross 3.5.0 → 4.0.0-rc.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014 Linus Unnebäck
3
+ Copyright (c) 2014-2021 Linus Unnebäck
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/index.d.ts CHANGED
@@ -1,102 +1,86 @@
1
1
  import * as mongodb from 'mongodb'
2
2
 
3
+ export { Binary, Code, Decimal128, Double, Int32, Long, MaxKey, MinKey, ObjectId, Timestamp } from 'mongodb'
4
+
3
5
  type DeepReadonly<T> = T extends Date | RegExp | string | number | boolean | bigint | symbol | undefined | null
4
6
  ? T
5
7
  : T extends {}
6
8
  ? { readonly [K in keyof T]: DeepReadonly<T[K]> }
7
9
  : Readonly<T>
8
10
 
9
- type FlattenIfArray<T> = T extends Array<infer R> ? R : T
10
11
  type SpecificProjection<T, TProjection> = Omit<T, 'projection'> & { projection: TProjection }
11
12
  type WithoutProjection<T> = T & { fields?: undefined, projection?: undefined }
12
13
 
13
- declare function albatross (uri: string): albatross.Albatross
14
-
15
- declare namespace albatross {
16
- interface Collection<TSchema extends { _id: any }> {
17
- readonly parent: Albatross
18
- id (hexString?: mongodb.ObjectId | string): mongodb.ObjectId
19
-
20
- findOne (filter: mongodb.FilterQuery<TSchema>, options?: WithoutProjection<mongodb.FindOneOptions<TSchema>>): Promise<TSchema | null>
21
- findOne<TKey extends keyof TSchema> (filter: mongodb.FilterQuery<TSchema>, options: SpecificProjection<mongodb.FindOneOptions<TSchema>, { [key in TKey]: 1 | true } & { _id: 0 | false }>): Promise<Pick<TSchema, TKey> | null>
22
- findOne<TKey extends keyof TSchema> (filter: mongodb.FilterQuery<TSchema>, options: SpecificProjection<mongodb.FindOneOptions<TSchema>, { [key in TKey]: 1 | true } & { _id?: 1 | true }>): Promise<Pick<TSchema, '_id' | TKey> | null>
23
- findOne (filter: mongodb.FilterQuery<TSchema>, options: mongodb.FindOneOptions<TSchema>): Promise<object | null>
24
-
25
- find (query: mongodb.FilterQuery<TSchema>, options?: WithoutProjection<mongodb.FindOneOptions<TSchema>>): Promise<TSchema[]>
26
- find<TKey extends keyof TSchema> (query: mongodb.FilterQuery<TSchema>, options: SpecificProjection<mongodb.FindOneOptions<TSchema>, { [key in TKey]: 1 | true } & { _id: 0 | false }>): Promise<Array<Pick<TSchema, TKey>>>
27
- find<TKey extends keyof TSchema> (query: mongodb.FilterQuery<TSchema>, options: SpecificProjection<mongodb.FindOneOptions<TSchema>, { [key in TKey]: 1 | true } & { _id?: 1 | true }>): Promise<Array<Pick<TSchema, '_id' | TKey>>>
28
- find (query: mongodb.FilterQuery<TSchema>, options: mongodb.FindOneOptions<TSchema>): Promise<object[]>
29
-
30
- count (query?: mongodb.FilterQuery<TSchema>, options?: mongodb.MongoCountPreferences): Promise<number>
31
-
32
- distinct<TKey extends keyof mongodb.WithId<TSchema>> (key: TKey, query?: mongodb.FilterQuery<TSchema>, options?: { readPreference?: mongodb.ReadPreference | string, maxTimeMS?: number, session?: mongodb.ClientSession }): Promise<Array<FlattenIfArray<mongodb.WithId<TSchema>[TKey]>>>
33
- distinct (key: string, query?: mongodb.FilterQuery<TSchema>, options?: { readPreference?: mongodb.ReadPreference | string, maxTimeMS?: number, session?: mongodb.ClientSession }): Promise<any[]>
34
-
35
- exists (query?: mongodb.FilterQuery<TSchema>): Promise<boolean>
36
-
37
- insert (doc: DeepReadonly<mongodb.OptionalId<TSchema>>, options?: mongodb.CollectionInsertOneOptions): Promise<mongodb.WithId<TSchema>>
38
- insert (docs: DeepReadonly<mongodb.OptionalId<TSchema>>[], options?: mongodb.CollectionInsertManyOptions): Promise<mongodb.WithId<TSchema>[]>
39
-
40
- findOneAndUpdate (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options: WithoutProjection<mongodb.FindOneAndUpdateOption<TSchema> & { returnOriginal: false, upsert: true }>): Promise<TSchema>
41
- findOneAndUpdate (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options?: WithoutProjection<mongodb.FindOneAndUpdateOption<TSchema>>): Promise<TSchema | null>
42
-
43
- findOneAndUpdate<TKey extends keyof TSchema> (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options: SpecificProjection<mongodb.FindOneAndUpdateOption<TSchema> & { returnOriginal: false, upsert: true }, { [key in TKey]: 1 | true } & { _id: 0 | false }>): Promise<Pick<TSchema, TKey>>
44
- findOneAndUpdate<TKey extends keyof TSchema> (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options: SpecificProjection<mongodb.FindOneAndUpdateOption<TSchema>, { [key in TKey]: 1 | true } & { _id: 0 | false }>): Promise<Pick<TSchema, TKey> | null>
45
-
46
- findOneAndUpdate<TKey extends keyof TSchema> (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options: SpecificProjection<mongodb.FindOneAndUpdateOption<TSchema> & { returnOriginal: false, upsert: true }, { [key in TKey]: 1 | true } & { _id?: 1 | true }>): Promise<Pick<TSchema, '_id' | TKey>>
47
- findOneAndUpdate<TKey extends keyof TSchema> (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options: SpecificProjection<mongodb.FindOneAndUpdateOption<TSchema>, { [key in TKey]: 1 | true } & { _id?: 1 | true }>): Promise<Pick<TSchema, '_id' | TKey> | null>
48
-
49
- findOneAndUpdate (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options: mongodb.FindOneAndUpdateOption<TSchema> & { returnOriginal: false, upsert: true }): Promise<object>
50
- findOneAndUpdate (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options?: mongodb.FindOneAndUpdateOption<TSchema>): Promise<object | null>
51
-
52
- updateOne (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options?: mongodb.UpdateOneOptions): Promise<{ matched: 0 | 1, modified: 0 | 1 }>
53
- updateMany (filter: mongodb.FilterQuery<TSchema>, update: mongodb.UpdateQuery<TSchema> | Partial<TSchema>, options?: mongodb.UpdateManyOptions): Promise<{ matched: number, modified: number }>
54
-
55
- deleteOne (filter: mongodb.FilterQuery<TSchema>, options?: mongodb.CommonOptions & { bypassDocumentValidation?: boolean }): Promise<0 | 1>
56
- deleteMany (filter: mongodb.FilterQuery<TSchema>, options?: mongodb.CommonOptions): Promise<number>
57
-
58
- aggregate (pipeline: object[], options?: mongodb.CollectionAggregationOptions): Promise<object[]>
59
- }
60
-
61
- interface FileInfo {
62
- id: mongodb.ObjectId
63
- md5: string
64
- length: number
65
- chunkSize: number
66
- uploadDate: Date
67
- contentType: string
68
- filename: string
69
- metadata: any
70
- }
71
-
72
- interface Grid {
73
- readonly parent: Albatross
74
- id (hexString?: mongodb.ObjectId | string): mongodb.ObjectId
75
- upload (stream: NodeJS.ReadableStream, options?: mongodb.GridFSBucketOpenUploadStreamOptions & { filename?: string }): Promise<FileInfo>
76
- download (id: mongodb.ObjectId): Promise<FileInfo & { stream: NodeJS.ReadableStream }>
77
- delete (id: mongodb.ObjectId): Promise<void>
78
- }
79
-
80
- interface Albatross {
81
- id (hexString?: mongodb.ObjectId | string): mongodb.ObjectId
82
- collection<TSchema extends { _id: any }> (name: string): Collection<TSchema>
83
- grid (name?: string): Grid
84
- ping (timeout?: number): Promise<void>
85
- transaction<T> (fn: (session: mongodb.ClientSession) => PromiseLike<T>): Promise<T>
86
- close (force?: boolean): Promise<void>
87
- }
88
-
89
- const Binary: typeof mongodb.Binary
90
- const Code: typeof mongodb.Code
91
- const DBRef: typeof mongodb.DBRef
92
- const Decimal128: typeof mongodb.Decimal128
93
- const Double: typeof mongodb.Double
94
- const Int32: typeof mongodb.Int32
95
- const Long: typeof mongodb.Long
96
- const MaxKey: typeof mongodb.MaxKey
97
- const MinKey: typeof mongodb.MinKey
98
- const ObjectId: typeof mongodb.ObjectId
99
- const Timestamp: typeof mongodb.Timestamp
14
+ export interface Collection<TSchema extends { _id: any }> {
15
+ readonly parent: Albatross
16
+ id (hexString?: mongodb.ObjectId | string): mongodb.ObjectId
17
+
18
+ findOne (filter: mongodb.Filter<TSchema>, options?: WithoutProjection<mongodb.FindOptions<TSchema>>): Promise<TSchema | null>
19
+ findOne<TKey extends keyof TSchema> (filter: mongodb.Filter<TSchema>, options: SpecificProjection<mongodb.FindOptions<TSchema>, { [key in TKey]: 1 | true } & { _id: 0 | false }>): Promise<Pick<TSchema, TKey> | null>
20
+ findOne<TKey extends keyof TSchema> (filter: mongodb.Filter<TSchema>, options: SpecificProjection<mongodb.FindOptions<TSchema>, { [key in TKey]: 1 | true } & { _id?: 1 | true }>): Promise<Pick<TSchema, '_id' | TKey> | null>
21
+ findOne (filter: mongodb.Filter<TSchema>, options: mongodb.FindOptions<TSchema>): Promise<object | null>
22
+
23
+ find (query: mongodb.Filter<TSchema>, options?: WithoutProjection<mongodb.FindOptions<TSchema>>): Promise<TSchema[]>
24
+ find<TKey extends keyof TSchema> (query: mongodb.Filter<TSchema>, options: SpecificProjection<mongodb.FindOptions<TSchema>, { [key in TKey]: 1 | true } & { _id: 0 | false }>): Promise<Array<Pick<TSchema, TKey>>>
25
+ find<TKey extends keyof TSchema> (query: mongodb.Filter<TSchema>, options: SpecificProjection<mongodb.FindOptions<TSchema>, { [key in TKey]: 1 | true } & { _id?: 1 | true }>): Promise<Array<Pick<TSchema, '_id' | TKey>>>
26
+ find (query: mongodb.Filter<TSchema>, options: mongodb.FindOptions<TSchema>): Promise<object[]>
27
+
28
+ count (query?: mongodb.Filter<TSchema>, options?: mongodb.CountOptions): Promise<number>
29
+
30
+ distinct<TKey extends keyof mongodb.WithId<TSchema>> (key: TKey, query?: mongodb.Filter<TSchema>, options?: mongodb.DistinctOptions): Promise<Array<mongodb.Flatten<mongodb.WithId<TSchema>[TKey]>>>
31
+ distinct (key: string, query?: mongodb.Filter<TSchema>, options?: mongodb.DistinctOptions): Promise<any[]>
32
+
33
+ exists (query?: mongodb.Filter<TSchema>): Promise<boolean>
34
+
35
+ insert (doc: DeepReadonly<mongodb.OptionalId<TSchema>>, options?: mongodb.InsertOneOptions): Promise<mongodb.WithId<TSchema>>
36
+ insert (docs: DeepReadonly<mongodb.OptionalId<TSchema>>[], options?: mongodb.BulkWriteOptions): Promise<mongodb.WithId<TSchema>[]>
37
+
38
+ findOneAndUpdate (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options: WithoutProjection<mongodb.FindOneAndUpdateOptions & { returnDocument: 'after', upsert: true }>): Promise<TSchema>
39
+ findOneAndUpdate (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options?: WithoutProjection<mongodb.FindOneAndUpdateOptions>): Promise<TSchema | null>
40
+
41
+ findOneAndUpdate<TKey extends keyof TSchema> (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options: SpecificProjection<mongodb.FindOneAndUpdateOptions & { returnDocument: 'after', upsert: true }, { [key in TKey]: 1 | true } & { _id: 0 | false }>): Promise<Pick<TSchema, TKey>>
42
+ findOneAndUpdate<TKey extends keyof TSchema> (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options: SpecificProjection<mongodb.FindOneAndUpdateOptions, { [key in TKey]: 1 | true } & { _id: 0 | false }>): Promise<Pick<TSchema, TKey> | null>
43
+
44
+ findOneAndUpdate<TKey extends keyof TSchema> (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options: SpecificProjection<mongodb.FindOneAndUpdateOptions & { returnDocument: 'after', upsert: true }, { [key in TKey]: 1 | true } & { _id?: 1 | true }>): Promise<Pick<TSchema, '_id' | TKey>>
45
+ findOneAndUpdate<TKey extends keyof TSchema> (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options: SpecificProjection<mongodb.FindOneAndUpdateOptions, { [key in TKey]: 1 | true } & { _id?: 1 | true }>): Promise<Pick<TSchema, '_id' | TKey> | null>
46
+
47
+ findOneAndUpdate (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options: mongodb.FindOneAndUpdateOptions & { returnDocument: 'after', upsert: true }): Promise<object>
48
+ findOneAndUpdate (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options?: mongodb.FindOneAndUpdateOptions): Promise<object | null>
49
+
50
+ updateOne (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options?: mongodb.UpdateOptions): Promise<{ matched: 0 | 1, modified: 0 | 1 }>
51
+ updateMany (filter: mongodb.Filter<TSchema>, update: mongodb.UpdateFilter<TSchema> | Partial<TSchema>, options?: mongodb.UpdateOptions): Promise<{ matched: number, modified: number }>
52
+
53
+ deleteOne (filter: mongodb.Filter<TSchema>, options?: mongodb.DeleteOptions): Promise<0 | 1>
54
+ deleteMany (filter: mongodb.Filter<TSchema>, options?: mongodb.DeleteOptions): Promise<number>
55
+
56
+ aggregate (pipeline: object[], options?: mongodb.AggregateOptions): Promise<object[]>
57
+ }
58
+
59
+ export interface FileInfo {
60
+ id: mongodb.ObjectId
61
+ length: number
62
+ chunkSize: number
63
+ uploadDate: Date
64
+ contentType: string
65
+ filename: string
66
+ metadata: any
67
+ }
68
+
69
+ export interface Grid {
70
+ readonly parent: Albatross
71
+ id (hexString?: mongodb.ObjectId | string): mongodb.ObjectId
72
+ upload (stream: NodeJS.ReadableStream, options?: mongodb.GridFSBucketWriteStreamOptions & { filename?: string }): Promise<FileInfo>
73
+ download (id: mongodb.ObjectId): Promise<FileInfo & { stream: NodeJS.ReadableStream }>
74
+ delete (id: mongodb.ObjectId): Promise<void>
75
+ }
76
+
77
+ export interface Albatross {
78
+ id (hexString?: mongodb.ObjectId | string): mongodb.ObjectId
79
+ collection<TSchema extends { _id: any }> (name: string): Collection<TSchema>
80
+ grid (name?: string): Grid
81
+ ping (timeout?: number): Promise<void>
82
+ transaction<T> (fn: (session: mongodb.ClientSession) => PromiseLike<T>): Promise<T>
83
+ close (force?: boolean): Promise<void>
100
84
  }
101
85
 
102
- export = albatross
86
+ export default function albatross (uri: string): Albatross
package/index.js CHANGED
@@ -1,16 +1,11 @@
1
- const mongodb = require('mongodb')
2
- const Albatross = require('./lib/albatross')
1
+ import Albatross from './lib/albatross.js'
3
2
 
4
- module.exports = (uri) => new Albatross(uri)
3
+ import mongodb from 'mongodb'
5
4
 
6
- module.exports.Binary = mongodb.Binary
7
- module.exports.Code = mongodb.Code
8
- module.exports.DBRef = mongodb.DBRef
9
- module.exports.Decimal128 = mongodb.Decimal128
10
- module.exports.Double = mongodb.Double
11
- module.exports.Int32 = mongodb.Int32
12
- module.exports.Long = mongodb.Long
13
- module.exports.MaxKey = mongodb.MaxKey
14
- module.exports.MinKey = mongodb.MinKey
15
- module.exports.ObjectId = mongodb.ObjectId
16
- module.exports.Timestamp = mongodb.Timestamp
5
+ const { Binary, Code, Decimal128, Double, Int32, Long, MaxKey, MinKey, ObjectId, Timestamp } = mongodb
6
+
7
+ export { Binary, Code, Decimal128, Double, Int32, Long, MaxKey, MinKey, ObjectId, Timestamp }
8
+
9
+ export default function albatross (uri) {
10
+ return new Albatross(uri)
11
+ }
package/lib/albatross.js CHANGED
@@ -1,50 +1,28 @@
1
- const { GridStore, MongoClient, ObjectId } = require('mongodb')
1
+ import mongodb from 'mongodb'
2
2
 
3
- const Collection = require('./collection')
4
- const Grid = require('./grid')
3
+ import Collection from './collection.js'
4
+ import Grid from './grid.js'
5
+
6
+ const DEFAULT_ROOT_COLLECTION = 'fs'
5
7
 
6
8
  const kClient = Symbol('client')
7
9
  const kCollections = Symbol('collections')
8
- const kConnect = Symbol('connect')
9
10
  const kGrids = Symbol('grids')
10
- const kURI = Symbol('uri')
11
11
 
12
- class Albatross {
12
+ export default class Albatross {
13
13
  constructor (uri) {
14
- this[kClient] = null
14
+ this[kClient] = new mongodb.MongoClient(uri, { ignoreUndefined: true })
15
15
  this[kCollections] = new Map()
16
16
  this[kGrids] = new Map()
17
- this[kURI] = uri
18
- }
19
-
20
- async [kConnect] () {
21
- if (this[kClient] == null) {
22
- this[kClient] = MongoClient.connect(this[kURI], { useNewUrlParser: true, useUnifiedTopology: true, ignoreUndefined: true })
23
-
24
- try {
25
- return await this[kClient]
26
- } catch (err) {
27
- this[kClient] = null
28
- throw err
29
- }
30
- }
31
-
32
- const client = await this[kClient]
33
-
34
- if (!client.isConnected()) {
35
- this[kClient] = null
36
- return this[kConnect]()
37
- }
38
-
39
- return client
40
17
  }
41
18
 
42
19
  async db () {
43
- return (await this[kConnect]()).db()
20
+ await this[kClient].connect()
21
+ return this[kClient].db()
44
22
  }
45
23
 
46
24
  id (hexString) {
47
- return (hexString instanceof ObjectId) ? hexString : new ObjectId(hexString)
25
+ return (hexString instanceof mongodb.ObjectId) ? hexString : new mongodb.ObjectId(hexString)
48
26
  }
49
27
 
50
28
  collection (name) {
@@ -55,7 +33,7 @@ class Albatross {
55
33
  return this[kCollections].get(name)
56
34
  }
57
35
 
58
- grid (bucketName = GridStore.DEFAULT_ROOT_COLLECTION) {
36
+ grid (bucketName = DEFAULT_ROOT_COLLECTION) {
59
37
  if (!this[kGrids].has(bucketName)) {
60
38
  this[kGrids].set(bucketName, new Grid(this, bucketName))
61
39
  }
@@ -64,12 +42,11 @@ class Albatross {
64
42
  }
65
43
 
66
44
  async ping (timeout) {
67
- let client
68
45
  let timeoutHandle
69
46
 
70
47
  const ping = async () => {
71
- client = await this[kConnect]()
72
- return client.db().command({ ping: 1 })
48
+ await this[kClient].connect()
49
+ await this[kClient].db().command({ ping: 1 })
73
50
  }
74
51
 
75
52
  try {
@@ -85,13 +62,6 @@ class Albatross {
85
62
  } else {
86
63
  await ping()
87
64
  }
88
- } catch (err) {
89
- if (client) {
90
- client.close(true).catch(() => {})
91
- }
92
-
93
- this[kClient] = null
94
- throw err
95
65
  } finally {
96
66
  if (timeoutHandle) {
97
67
  clearTimeout(timeoutHandle)
@@ -100,8 +70,7 @@ class Albatross {
100
70
  }
101
71
 
102
72
  async transaction (fn) {
103
- const client = await this[kConnect]()
104
- const session = client.startSession()
73
+ const session = this[kClient].startSession()
105
74
 
106
75
  let result
107
76
 
@@ -117,12 +86,6 @@ class Albatross {
117
86
  }
118
87
 
119
88
  async close (force) {
120
- if (this[kClient] == null) return
121
-
122
- const client = await this[kClient]
123
- await client.close(force)
124
- this[kClient] = null
89
+ await this[kClient].close(force)
125
90
  }
126
91
  }
127
-
128
- module.exports = Albatross
package/lib/collection.js CHANGED
@@ -1,15 +1,13 @@
1
- const debug = require('debug')
2
- const { BSON } = require('bson')
1
+ import BSON from 'bson'
2
+ import debug from 'debug'
3
3
 
4
4
  const kDebug = Symbol('debug')
5
5
 
6
- const bsonParser = new BSON()
7
-
8
6
  function prepareDocument (document) {
9
- return bsonParser.deserialize(bsonParser.serialize(document), { promoteValues: true })
7
+ return BSON.deserialize(BSON.serialize(document), { promoteValues: true })
10
8
  }
11
9
 
12
- class Collection {
10
+ export default class Collection {
13
11
  constructor (parent, name) {
14
12
  this.name = name
15
13
  this.parent = parent
@@ -53,7 +51,7 @@ class Collection {
53
51
 
54
52
  try {
55
53
  this[kDebug]('count(%o)', query)
56
- const res = await db.collection(this.name).countDocuments(query, { ignoreUndefined: true, ...opts })
54
+ const res = await db.collection(this.name).countDocuments(query, opts)
57
55
  this[kDebug]('reply OK')
58
56
  return res
59
57
  } catch (err) {
@@ -100,15 +98,17 @@ class Collection {
100
98
 
101
99
  try {
102
100
  if (Array.isArray(docs)) {
103
- this[kDebug]('insertMany(%o)', docs)
104
- const res = await db.collection(this.name).insertMany(docs.map(prepareDocument), opts)
101
+ const documents = docs.map(prepareDocument)
102
+ this[kDebug]('insertMany(%o)', documents)
103
+ await db.collection(this.name).insertMany(documents, opts)
105
104
  this[kDebug]('reply OK')
106
- return res.ops
105
+ return documents
107
106
  } else {
108
- this[kDebug]('insertOne(%o)', docs)
109
- const res = await db.collection(this.name).insertOne(prepareDocument(docs), opts)
107
+ const document = prepareDocument(docs)
108
+ this[kDebug]('insertOne(%o)', document)
109
+ await db.collection(this.name).insertOne(document, opts)
110
110
  this[kDebug]('reply OK')
111
- return res.ops[0]
111
+ return document
112
112
  }
113
113
  } catch (err) {
114
114
  this[kDebug]('reply ERR')
@@ -121,7 +121,7 @@ class Collection {
121
121
 
122
122
  try {
123
123
  this[kDebug]('findOneAndUpdate(%o, %o)', filter, update)
124
- const res = await db.collection(this.name).findOneAndUpdate(filter, update, { ignoreUndefined: true, ...opts })
124
+ const res = await db.collection(this.name).findOneAndUpdate(filter, update, opts)
125
125
  this[kDebug]('reply OK')
126
126
  return res.value
127
127
  } catch (err) {
@@ -136,8 +136,8 @@ class Collection {
136
136
  try {
137
137
  this[kDebug]('updateOne(%o, %o)', filter, update)
138
138
  const res = await db.collection(this.name).updateOne(filter, update, opts)
139
- this[kDebug](`reply OK ${res.result.n} ${res.result.nModified}`)
140
- return { matched: res.result.n, modified: res.result.nModified }
139
+ this[kDebug](`reply OK ${res.matchedCount} ${res.modifiedCount}`)
140
+ return { matched: res.matchedCount, modified: res.modifiedCount }
141
141
  } catch (err) {
142
142
  this[kDebug]('reply ERR')
143
143
  throw err
@@ -150,8 +150,8 @@ class Collection {
150
150
  try {
151
151
  this[kDebug]('updateMany(%o, %o)', filter, update)
152
152
  const res = await db.collection(this.name).updateMany(filter, update, opts)
153
- this[kDebug](`reply OK ${res.result.n} ${res.result.nModified}`)
154
- return { matched: res.result.n, modified: res.result.nModified }
153
+ this[kDebug](`reply OK ${res.matchedCount} ${res.modifiedCount}`)
154
+ return { matched: res.matchedCount, modified: res.modifiedCount }
155
155
  } catch (err) {
156
156
  this[kDebug]('reply ERR')
157
157
  throw err
@@ -164,8 +164,8 @@ class Collection {
164
164
  try {
165
165
  this[kDebug]('deleteOne(%o)', filter)
166
166
  const res = await db.collection(this.name).deleteOne(filter, opts)
167
- this[kDebug](`reply OK ${res.result.n}`)
168
- return res.result.n
167
+ this[kDebug](`reply OK ${res.deletedCount}`)
168
+ return res.deletedCount
169
169
  } catch (err) {
170
170
  this[kDebug]('reply ERR')
171
171
  throw err
@@ -178,8 +178,8 @@ class Collection {
178
178
  try {
179
179
  this[kDebug]('deleteMany(%o)', filter)
180
180
  const res = await db.collection(this.name).deleteMany(filter, opts)
181
- this[kDebug](`reply OK ${res.result.n}`)
182
- return res.result.n
181
+ this[kDebug](`reply OK ${res.deletedCount}`)
182
+ return res.deletedCount
183
183
  } catch (err) {
184
184
  this[kDebug]('reply ERR')
185
185
  throw err
@@ -191,7 +191,7 @@ class Collection {
191
191
 
192
192
  try {
193
193
  this[kDebug]('aggregate(%o)', pipeline)
194
- const res = await db.collection(this.name).aggregate(pipeline, { ignoreUndefined: true, ...opts }).toArray()
194
+ const res = await db.collection(this.name).aggregate(pipeline, opts).toArray()
195
195
  this[kDebug]('reply OK')
196
196
  return res
197
197
  } catch (err) {
@@ -200,5 +200,3 @@ class Collection {
200
200
  }
201
201
  }
202
202
  }
203
-
204
- module.exports = Collection
package/lib/grid.js CHANGED
@@ -1,6 +1,6 @@
1
- const debug = require('debug')
2
- const { GridFSBucket } = require('mongodb')
3
- const stream = require('stream')
1
+ import debug from 'debug'
2
+ import mongodb from 'mongodb'
3
+ import { PassThrough } from 'node:stream'
4
4
 
5
5
  const reFileNotFound = /^FileNotFound: /
6
6
 
@@ -9,7 +9,6 @@ const kDebug = Symbol('debug')
9
9
  function fileInfo (file) {
10
10
  return {
11
11
  id: file._id,
12
- md5: file.md5,
13
12
  length: file.length,
14
13
  chunkSize: file.chunkSize,
15
14
  uploadDate: file.uploadDate,
@@ -19,7 +18,7 @@ function fileInfo (file) {
19
18
  }
20
19
  }
21
20
 
22
- class Grid {
21
+ export default class Grid {
23
22
  constructor (parent, name) {
24
23
  this.name = name
25
24
  this.parent = parent
@@ -34,8 +33,8 @@ class Grid {
34
33
  const db = await this.parent.db()
35
34
 
36
35
  return new Promise((resolve, reject) => {
37
- const bucket = new GridFSBucket(db, { bucketName: this.name })
38
- const upload = bucket.openUploadStream(opts.filename, opts)
36
+ const bucket = new mongodb.GridFSBucket(db, { bucketName: this.name })
37
+ const upload = bucket.openUploadStream(opts.filename || '', opts)
39
38
 
40
39
  upload.on('error', reject)
41
40
  upload.on('finish', (file) => resolve(fileInfo(file)))
@@ -48,9 +47,9 @@ class Grid {
48
47
  const db = await this.parent.db()
49
48
 
50
49
  return new Promise((resolve, reject) => {
51
- const bucket = new GridFSBucket(db, { bucketName: this.name })
50
+ const bucket = new mongodb.GridFSBucket(db, { bucketName: this.name })
52
51
  const download = bucket.openDownloadStream(this.id(id))
53
- const through = new stream.PassThrough()
52
+ const through = new PassThrough()
54
53
 
55
54
  // the download stream won't query the db until piped
56
55
  download.pipe(through)
@@ -73,10 +72,8 @@ class Grid {
73
72
  const db = await this.parent.db()
74
73
 
75
74
  return new Promise((resolve, reject) => {
76
- const bucket = new GridFSBucket(db, { bucketName: this.name })
75
+ const bucket = new mongodb.GridFSBucket(db, { bucketName: this.name })
77
76
  bucket.delete(this.id(id), (err) => err ? reject(err) : resolve())
78
77
  })
79
78
  }
80
79
  }
81
-
82
- module.exports = Grid
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "albatross",
3
- "version": "3.5.0",
3
+ "version": "4.0.0-rc.1",
4
4
  "license": "MIT",
5
- "author": "Linus Unnebäck <linus@folkdatorn.se>",
6
5
  "repository": "LinusU/node-albatross",
6
+ "type": "module",
7
+ "exports": "./index.js",
7
8
  "files": [
8
9
  "index.d.ts",
9
10
  "index.js",
@@ -11,25 +12,22 @@
11
12
  ],
12
13
  "scripts": {
13
14
  "test": "standard && mocha && npm run tsc",
14
- "tsc": "tsc --noEmit --allowJs --checkJs index.d.ts test/*.js"
15
+ "tsc": "tsc --allowSyntheticDefaultImports --noEmit --allowJs --checkJs index.d.ts test/*.js"
15
16
  },
16
17
  "dependencies": {
17
- "@types/bson": "1.0.11",
18
- "@types/mongodb": "3.6.12",
19
- "bson": "^1.1.4",
20
- "debug": "^4.1.1",
21
- "mongodb": "^3.6.0"
18
+ "bson": "^4.7.0",
19
+ "debug": "^4.3.4",
20
+ "mongodb": "^4.9.0"
22
21
  },
23
22
  "devDependencies": {
24
- "@types/mocha": "^5.2.7",
25
- "@types/node": "^8.10.54",
26
- "assert-rejects": "^1.0.0",
27
- "get-stream": "^5.1.0",
28
- "mocha": "^6.2.1",
29
- "standard": "^14.3.1",
30
- "typescript": "^3.7.3"
23
+ "@types/mocha": "^9.0.0",
24
+ "@types/node": "^16.4.13",
25
+ "get-stream": "^6.0.1",
26
+ "mocha": "^9.0.3",
27
+ "standard": "^17.0.0",
28
+ "typescript": "^4.8.2"
31
29
  },
32
30
  "engines": {
33
- "node": ">=8.3"
31
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
34
32
  }
35
33
  }
package/readme.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # ![Albatross](/header.png?raw=true "Albatross")
2
2
 
3
- Albatross is a small library that makes accessing MongoDB from Node.js a
4
- breeze. It's goal is to be a thin wrapper that enables you to forget about
5
- connection state and get right to accessing your data.
3
+ Albatross is a small library that makes accessing MongoDB from Node.js a breeze. It's goal is to be a thin wrapper that enables you to forget about connection state and get right to accessing your data.
6
4
 
7
5
  ## Installation
8
6
 
@@ -13,7 +11,8 @@ npm install --save albatross
13
11
  ## Usage
14
12
 
15
13
  ```js
16
- const albatross = require('albatross')
14
+ import albatross from 'albatross'
15
+ import fs from 'node:fs'
17
16
 
18
17
  const db = albatross('mongodb://localhost/test')
19
18
  const user = db.collection('user')
@@ -25,7 +24,6 @@ const doc = await user.findOne({ born: 1992 })
25
24
  console.log('Hello ' + doc.name)
26
25
  //=> Hello Linus
27
26
 
28
- const fs = require('fs')
29
27
  const grid = db.grid()
30
28
 
31
29
  const input = fs.createReadStream('readme.md')
@@ -40,15 +38,13 @@ result.contentType // 'text/plain'
40
38
  result.stream.pipe(process.stdout)
41
39
  ```
42
40
 
43
- You can start querying the database right away, as soon as a connection is
44
- established it will start sending your commands to the server.
41
+ You can start querying the database right away, as soon as a connection is established it will start sending your commands to the server.
45
42
 
46
43
  ## API
47
44
 
48
45
  ### Module
49
46
 
50
- The module exposes a single function to create a new `Albatross` instance. It
51
- also exposes the BSON Binary API on this function.
47
+ The module default exports a single function to create a new `Albatross` instance. It also exports the BSON Binary API as named exports.
52
48
 
53
49
  #### `albatross(uri)`
54
50
 
@@ -58,12 +54,11 @@ Creates a new instance of `Albatross` and connect to the specified uri.
58
54
 
59
55
  #### BSON Binary API
60
56
 
61
- The following functions are exposed on the module:
57
+ The following functions are exported from the module:
62
58
 
63
59
  ```text
64
60
  Binary
65
61
  Code
66
- DBRef
67
62
  Decimal128
68
63
  Double
69
64
  Int32
@@ -82,8 +77,7 @@ Returns a new instance of Collection bound to the collection named `name`.
82
77
 
83
78
  #### `.grid([name])`
84
79
 
85
- Returns a new instance of Grid, optionally using the supplied `name` as the
86
- name of the root collection.
80
+ Returns a new instance of Grid, optionally using the supplied `name` as the name of the root collection.
87
81
 
88
82
  #### `.id(strOrObjectId)`
89
83
 
@@ -151,9 +145,7 @@ Check if at least one document is matching the query.
151
145
 
152
146
  Inserts a single document or a an array of documents.
153
147
 
154
- The Promise will resolve with the documents that was inserted. When called
155
- with an object instead of an array as the first argument, the Promise resolves
156
- with an object instead of an array as well.
148
+ The Promise will resolve with the documents that was inserted. When called with an object instead of an array as the first argument, the Promise resolves with an object instead of an array as well.
157
149
 
158
150
  **Note:** Contrary to the standard MongoDB Node.js driver, this function will *not modify* any objects that are passed in. Instead, the returned documents from this function are what was saved in the database.
159
151
 
@@ -161,7 +153,7 @@ with an object instead of an array as well.
161
153
 
162
154
  Finds a document and updates it in one atomic operation.
163
155
 
164
- By default, the document _before_ the update is returned. To return the document _after_ the update, pass `returnOriginal: false` in the options.
156
+ By default, the document _before_ the update is returned. To return the document _after_ the update, pass `returnDocument: 'after'` in the options.
165
157
 
166
158
  #### `updateOne(filter, update[, opts]): Promise<UpdateResult>`
167
159
 
@@ -197,8 +189,7 @@ Makes sure that the given argument is an ObjectId.
197
189
 
198
190
  #### `upload(stream[, opts]): Promise<FileInfo>`
199
191
 
200
- Store the `stream` as a file in the grid store, `opts` is a object with the
201
- following properties. All options are optionally.
192
+ Store the `stream` as a file in the grid store, `opts` is a object with the following properties. All options are optionally.
202
193
 
203
194
  - `filename`: The value of the `filename` key in the files doc
204
195
  - `chunkSizeBytes`: Overwrite this bucket's `chunkSizeBytes` for this file
@@ -209,7 +200,6 @@ following properties. All options are optionally.
209
200
  The `FileInfo` object has the following properties:
210
201
 
211
202
  - `id`: The id of the file
212
- - `md5`: The md5 hash of the file
213
203
  - `length`: The length of the file
214
204
  - `chunkSize`: The size of each chunk in bytes
215
205
  - `filename`: The value of the `filename` key in the files doc
@@ -218,12 +208,9 @@ The `FileInfo` object has the following properties:
218
208
 
219
209
  #### `download(id): Promise<FileInfo>`
220
210
 
221
- Get the file with the specified `id` from the grid store. The Promise will
222
- resolve with an object with the following properties. If no file with the
223
- indicated `id` was found, the Promise will resolve to `null`.
211
+ Get the file with the specified `id` from the grid store. The Promise will resolve with an object with the following properties. If no file with the indicated `id` was found, the Promise will resolve to `null`.
224
212
 
225
213
  - `id`: The id of the file
226
- - `md5`: The md5 hash of the file
227
214
  - `length`: The length of the file
228
215
  - `chunkSize`: The size of each chunk in bytes
229
216
  - `filename`: The value of the `filename` key in the files doc
@@ -237,13 +224,11 @@ Delete the file with the specified `id` from the grid store.
237
224
 
238
225
  ## In depth documentation
239
226
 
240
- For more in depth documentation please see the [mongodb module](http://mongodb.github.io/node-mongodb-native/)
241
- which Albatross wraps, especially the [Collection object](http://mongodb.github.io/node-mongodb-native/api-generated/collection.html).
227
+ For more in depth documentation please see the [mongodb module](http://mongodb.github.io/node-mongodb-native/) which Albatross wraps, especially the [Collection object](http://mongodb.github.io/node-mongodb-native/api-generated/collection.html).
242
228
 
243
229
  ## Contributing
244
230
 
245
- Pull requests are always welcome, please make sure to add tests and run
246
- `mocha` before submitting.
231
+ Pull requests are always welcome, please make sure to add tests and run `mocha` before submitting.
247
232
 
248
233
  The tests requiers a MongoDB server running at `localhost`.
249
234