albatross 3.4.1 → 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 +1 -1
- package/index.d.ts +79 -88
- package/index.js +9 -14
- package/lib/albatross.js +30 -50
- package/lib/collection.js +23 -25
- package/lib/grid.js +9 -12
- package/package.json +14 -16
- package/readme.md +33 -28
package/LICENSE
CHANGED
package/index.d.ts
CHANGED
|
@@ -1,95 +1,86 @@
|
|
|
1
1
|
import * as mongodb from 'mongodb'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export { Binary, Code, Decimal128, Double, Int32, Long, MaxKey, MinKey, ObjectId, Timestamp } from 'mongodb'
|
|
4
|
+
|
|
5
|
+
type DeepReadonly<T> = T extends Date | RegExp | string | number | boolean | bigint | symbol | undefined | null
|
|
6
|
+
? T
|
|
7
|
+
: T extends {}
|
|
8
|
+
? { readonly [K in keyof T]: DeepReadonly<T[K]> }
|
|
9
|
+
: Readonly<T>
|
|
10
|
+
|
|
4
11
|
type SpecificProjection<T, TProjection> = Omit<T, 'projection'> & { projection: TProjection }
|
|
5
12
|
type WithoutProjection<T> = T & { fields?: undefined, projection?: undefined }
|
|
6
13
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
grid (name?: string): Grid
|
|
78
|
-
ping (timeout?: number): Promise<void>
|
|
79
|
-
close (force?: boolean): Promise<void>
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const Binary: typeof mongodb.Binary
|
|
83
|
-
const Code: typeof mongodb.Code
|
|
84
|
-
const DBRef: typeof mongodb.DBRef
|
|
85
|
-
const Decimal128: typeof mongodb.Decimal128
|
|
86
|
-
const Double: typeof mongodb.Double
|
|
87
|
-
const Int32: typeof mongodb.Int32
|
|
88
|
-
const Long: typeof mongodb.Long
|
|
89
|
-
const MaxKey: typeof mongodb.MaxKey
|
|
90
|
-
const MinKey: typeof mongodb.MinKey
|
|
91
|
-
const ObjectId: typeof mongodb.ObjectId
|
|
92
|
-
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>
|
|
93
84
|
}
|
|
94
85
|
|
|
95
|
-
export
|
|
86
|
+
export default function albatross (uri: string): Albatross
|
package/index.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
const Albatross = require('./lib/albatross')
|
|
1
|
+
import Albatross from './lib/albatross.js'
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import mongodb from 'mongodb'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
1
|
+
import mongodb from 'mongodb'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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] =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
72
|
-
|
|
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)
|
|
@@ -99,13 +69,23 @@ class Albatross {
|
|
|
99
69
|
}
|
|
100
70
|
}
|
|
101
71
|
|
|
102
|
-
async
|
|
103
|
-
|
|
72
|
+
async transaction (fn) {
|
|
73
|
+
const session = this[kClient].startSession()
|
|
74
|
+
|
|
75
|
+
let result
|
|
104
76
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
77
|
+
try {
|
|
78
|
+
await session.withTransaction(async (...args) => {
|
|
79
|
+
result = await fn(...args)
|
|
80
|
+
})
|
|
81
|
+
} finally {
|
|
82
|
+
session.endSession()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return result
|
|
108
86
|
}
|
|
109
|
-
}
|
|
110
87
|
|
|
111
|
-
|
|
88
|
+
async close (force) {
|
|
89
|
+
await this[kClient].close(force)
|
|
90
|
+
}
|
|
91
|
+
}
|
package/lib/collection.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
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,
|
|
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
|
-
|
|
104
|
-
|
|
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
|
|
105
|
+
return documents
|
|
107
106
|
} else {
|
|
108
|
-
|
|
109
|
-
|
|
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
|
|
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,
|
|
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.
|
|
140
|
-
return { matched: res.
|
|
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.
|
|
154
|
-
return { matched: res.
|
|
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.
|
|
168
|
-
return res.
|
|
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.
|
|
182
|
-
return res.
|
|
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,
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
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
|
+
"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
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
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": "^
|
|
25
|
-
"@types/node": "^
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
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": ">=
|
|
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
|
# 
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
|
@@ -95,6 +89,26 @@ Send the `ping` command to the server, to check that the connection is still int
|
|
|
95
89
|
|
|
96
90
|
Optionally accepts a timeout in milliseconds.
|
|
97
91
|
|
|
92
|
+
#### `.transaction(fn): Promise`
|
|
93
|
+
|
|
94
|
+
Runs a provided function within a transaction, retrying either the commit operation or entire transaction as needed (and when the error permits) to better ensure that the transaction can complete successfully.
|
|
95
|
+
|
|
96
|
+
Example:
|
|
97
|
+
|
|
98
|
+
```js
|
|
99
|
+
const user = db.collection('user')
|
|
100
|
+
|
|
101
|
+
const result = await db.transaction(async (session) => {
|
|
102
|
+
await user.insert({ name: 'Linus', born: 1992 }, { session })
|
|
103
|
+
await user.insert({ name: 'Steve', born: 1955 }, { session })
|
|
104
|
+
|
|
105
|
+
return await user.findOne({ born: 1992 }, { session })
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
console.log('Hello ' + result.name)
|
|
109
|
+
//=> Hello Linus
|
|
110
|
+
```
|
|
111
|
+
|
|
98
112
|
#### `.close(): Promise<void>`
|
|
99
113
|
|
|
100
114
|
Closes the connection to the server.
|
|
@@ -131,9 +145,7 @@ Check if at least one document is matching the query.
|
|
|
131
145
|
|
|
132
146
|
Inserts a single document or a an array of documents.
|
|
133
147
|
|
|
134
|
-
The Promise will resolve with the documents that was inserted. When called
|
|
135
|
-
with an object instead of an array as the first argument, the Promise resolves
|
|
136
|
-
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.
|
|
137
149
|
|
|
138
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.
|
|
139
151
|
|
|
@@ -141,7 +153,7 @@ with an object instead of an array as well.
|
|
|
141
153
|
|
|
142
154
|
Finds a document and updates it in one atomic operation.
|
|
143
155
|
|
|
144
|
-
By default, the document _before_ the update is returned. To return the document _after_ the update, pass `
|
|
156
|
+
By default, the document _before_ the update is returned. To return the document _after_ the update, pass `returnDocument: 'after'` in the options.
|
|
145
157
|
|
|
146
158
|
#### `updateOne(filter, update[, opts]): Promise<UpdateResult>`
|
|
147
159
|
|
|
@@ -177,8 +189,7 @@ Makes sure that the given argument is an ObjectId.
|
|
|
177
189
|
|
|
178
190
|
#### `upload(stream[, opts]): Promise<FileInfo>`
|
|
179
191
|
|
|
180
|
-
Store the `stream` as a file in the grid store, `opts` is a object with the
|
|
181
|
-
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.
|
|
182
193
|
|
|
183
194
|
- `filename`: The value of the `filename` key in the files doc
|
|
184
195
|
- `chunkSizeBytes`: Overwrite this bucket's `chunkSizeBytes` for this file
|
|
@@ -189,7 +200,6 @@ following properties. All options are optionally.
|
|
|
189
200
|
The `FileInfo` object has the following properties:
|
|
190
201
|
|
|
191
202
|
- `id`: The id of the file
|
|
192
|
-
- `md5`: The md5 hash of the file
|
|
193
203
|
- `length`: The length of the file
|
|
194
204
|
- `chunkSize`: The size of each chunk in bytes
|
|
195
205
|
- `filename`: The value of the `filename` key in the files doc
|
|
@@ -198,12 +208,9 @@ The `FileInfo` object has the following properties:
|
|
|
198
208
|
|
|
199
209
|
#### `download(id): Promise<FileInfo>`
|
|
200
210
|
|
|
201
|
-
Get the file with the specified `id` from the grid store. The Promise will
|
|
202
|
-
resolve with an object with the following properties. If no file with the
|
|
203
|
-
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`.
|
|
204
212
|
|
|
205
213
|
- `id`: The id of the file
|
|
206
|
-
- `md5`: The md5 hash of the file
|
|
207
214
|
- `length`: The length of the file
|
|
208
215
|
- `chunkSize`: The size of each chunk in bytes
|
|
209
216
|
- `filename`: The value of the `filename` key in the files doc
|
|
@@ -217,13 +224,11 @@ Delete the file with the specified `id` from the grid store.
|
|
|
217
224
|
|
|
218
225
|
## In depth documentation
|
|
219
226
|
|
|
220
|
-
For more in depth documentation please see the [mongodb module](http://mongodb.github.io/node-mongodb-native/)
|
|
221
|
-
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).
|
|
222
228
|
|
|
223
229
|
## Contributing
|
|
224
230
|
|
|
225
|
-
Pull requests are always welcome, please make sure to add tests and run
|
|
226
|
-
`mocha` before submitting.
|
|
231
|
+
Pull requests are always welcome, please make sure to add tests and run `mocha` before submitting.
|
|
227
232
|
|
|
228
233
|
The tests requiers a MongoDB server running at `localhost`.
|
|
229
234
|
|