@orion-js/mongodb 3.1.1 → 3.1.10
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/lib/connect/getMongoURLFromEnv.js +7 -5
- package/lib/createCollection/getMethods/insertMany.js +4 -1
- package/lib/createCollection/getMethods/insertOne.js +4 -1
- package/lib/createCollection/getMethods/insertOne.test.js +97 -63
- package/lib/createCollection/getMethods/updateAndFind.js +9 -6
- package/lib/createCollection/getMethods/updateItem.js +4 -1
- package/lib/createCollection/getMethods/updateMany.js +4 -1
- package/lib/createCollection/getMethods/updateOne.js +4 -1
- package/lib/createCollection/getMethods/upsert.js +4 -1
- package/lib/createCollection/getMethods/wrapErrors.d.ts +1 -0
- package/lib/createCollection/getMethods/wrapErrors.js +29 -0
- package/package.json +7 -7
package/LICENSE
CHANGED
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getMongoURLFromEnv = void 0;
|
|
4
4
|
const connections_1 = require("./connections");
|
|
5
|
+
const helpers_1 = require("@orion-js/helpers");
|
|
5
6
|
const getMongoURLFromEnv = (connectionName) => {
|
|
6
7
|
if (connectionName === 'main') {
|
|
7
|
-
if (!
|
|
8
|
+
if (!(0, helpers_1.internalGetEnv)('mongo_url', 'MONGO_URL')) {
|
|
8
9
|
throw new Error('MONGO_URL is required');
|
|
9
10
|
}
|
|
10
|
-
return
|
|
11
|
+
return (0, helpers_1.internalGetEnv)('mongo_url', 'MONGO_URL');
|
|
11
12
|
}
|
|
12
|
-
const
|
|
13
|
-
const
|
|
13
|
+
const envName = `mongo_url_${connectionName.toLowerCase()}`;
|
|
14
|
+
const processEnvName = `MONGO_URL_${connectionName.toUpperCase()}`;
|
|
15
|
+
const uri = connections_1.connections[connectionName]?.uri ?? (0, helpers_1.internalGetEnv)(envName, processEnvName);
|
|
14
16
|
if (!uri) {
|
|
15
|
-
throw new Error(`To use the connection "${connectionName}" you must initialize it first calling getMongoConnection({name: "${connectionName}", uri: "MONGOURI"}) or setting the environment variable ${
|
|
17
|
+
throw new Error(`To use the connection "${connectionName}" you must initialize it first calling getMongoConnection({name: "${connectionName}", uri: "MONGOURI"}) or setting the environment variable ${processEnvName}.`);
|
|
16
18
|
}
|
|
17
19
|
return uri;
|
|
18
20
|
};
|
|
@@ -7,6 +7,7 @@ const isPlainObject_1 = __importDefault(require("lodash/isPlainObject"));
|
|
|
7
7
|
const lodash_1 = require("lodash");
|
|
8
8
|
const fromDot_1 = __importDefault(require("../../helpers/fromDot"));
|
|
9
9
|
const schema_1 = require("@orion-js/schema");
|
|
10
|
+
const wrapErrors_1 = require("./wrapErrors");
|
|
10
11
|
exports.default = (collection) => {
|
|
11
12
|
const insertMany = async (docs, options = {}) => {
|
|
12
13
|
for (let index = 0; index < docs.length; index++) {
|
|
@@ -24,7 +25,9 @@ exports.default = (collection) => {
|
|
|
24
25
|
}
|
|
25
26
|
docs[index] = doc;
|
|
26
27
|
}
|
|
27
|
-
const { insertedIds } = await
|
|
28
|
+
const { insertedIds } = await (0, wrapErrors_1.wrapErrors)(() => {
|
|
29
|
+
return collection.rawCollection.insertMany(docs, options.mongoOptions);
|
|
30
|
+
});
|
|
28
31
|
const ids = (0, lodash_1.values)(insertedIds);
|
|
29
32
|
return ids.map(id => id.toString());
|
|
30
33
|
};
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const isPlainObject_1 = __importDefault(require("lodash/isPlainObject"));
|
|
7
7
|
const fromDot_1 = __importDefault(require("../../helpers/fromDot"));
|
|
8
8
|
const schema_1 = require("@orion-js/schema");
|
|
9
|
+
const wrapErrors_1 = require("./wrapErrors");
|
|
9
10
|
exports.default = (collection) => {
|
|
10
11
|
const insertOne = async (insertDoc, options) => {
|
|
11
12
|
let doc = insertDoc;
|
|
@@ -20,7 +21,9 @@ exports.default = (collection) => {
|
|
|
20
21
|
doc = await (0, schema_1.clean)(schema, (0, fromDot_1.default)(doc));
|
|
21
22
|
await (0, schema_1.validate)(schema, doc);
|
|
22
23
|
}
|
|
23
|
-
await
|
|
24
|
+
await (0, wrapErrors_1.wrapErrors)(async () => {
|
|
25
|
+
await collection.rawCollection.insertOne(doc);
|
|
26
|
+
});
|
|
24
27
|
return doc._id;
|
|
25
28
|
};
|
|
26
29
|
return insertOne;
|
|
@@ -7,70 +7,104 @@ const insertOne_1 = __importDefault(require("./insertOne"));
|
|
|
7
7
|
const helpers_1 = require("@orion-js/helpers");
|
|
8
8
|
const __1 = __importDefault(require(".."));
|
|
9
9
|
const models_1 = require("@orion-js/models");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
const schema = {
|
|
26
|
-
wife: { type: wife }
|
|
27
|
-
};
|
|
28
|
-
const model = (0, models_1.createModel)({ name: (0, helpers_1.generateId)(), schema });
|
|
29
|
-
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)(), model });
|
|
30
|
-
await Tests.insertOne({ 'wife.name': 'Francisca' });
|
|
31
|
-
});
|
|
32
|
-
it('should clean a document before insertOneing', async () => {
|
|
33
|
-
const now = new Date();
|
|
34
|
-
const schema = {
|
|
35
|
-
name: { type: String },
|
|
36
|
-
createdAt: { type: Date, autoValue: () => now }
|
|
37
|
-
};
|
|
38
|
-
const model = (0, models_1.createModel)({ name: (0, helpers_1.generateId)(), schema });
|
|
39
|
-
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)(), model });
|
|
40
|
-
const docId = await Tests.insertOne({ name: 1234 });
|
|
41
|
-
const result = await Tests.findOne(docId);
|
|
42
|
-
expect(result.name).toBe('1234');
|
|
43
|
-
expect(result.createdAt).toEqual(now);
|
|
44
|
-
});
|
|
45
|
-
it('should validate a document', async () => {
|
|
46
|
-
const schema = { name: { type: String } };
|
|
47
|
-
const model = (0, models_1.createModel)({ name: (0, helpers_1.generateId)(), schema });
|
|
48
|
-
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)(), model });
|
|
49
|
-
expect.assertions(1);
|
|
50
|
-
try {
|
|
51
|
-
await Tests.insertOne({});
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
expect(error.code).toBe('validationError');
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
it('Should be able to use custom clean for models', async () => {
|
|
58
|
-
const model = (0, models_1.createModel)({
|
|
59
|
-
name: 'File',
|
|
60
|
-
schema: {
|
|
10
|
+
describe('InsertOne', () => {
|
|
11
|
+
it('should return a function', async () => {
|
|
12
|
+
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)() });
|
|
13
|
+
const insertOne = (0, insertOne_1.default)(Tests);
|
|
14
|
+
expect(typeof insertOne).toBe('function');
|
|
15
|
+
});
|
|
16
|
+
it('insertOnes a document without errors', async () => {
|
|
17
|
+
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)() });
|
|
18
|
+
await Tests.insertOne({ hello: 'world' });
|
|
19
|
+
const count = await Tests.find({}).count();
|
|
20
|
+
expect(count).toBe(1);
|
|
21
|
+
});
|
|
22
|
+
it('should insertOne documents passing deep validation', async () => {
|
|
23
|
+
const wife = {
|
|
61
24
|
name: { type: String }
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
25
|
+
};
|
|
26
|
+
const schema = {
|
|
27
|
+
wife: { type: wife }
|
|
28
|
+
};
|
|
29
|
+
const model = (0, models_1.createModel)({ name: (0, helpers_1.generateId)(), schema });
|
|
30
|
+
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)(), model });
|
|
31
|
+
await Tests.insertOne({ 'wife.name': 'Francisca' });
|
|
32
|
+
});
|
|
33
|
+
it('should clean a document before insertOneing', async () => {
|
|
34
|
+
const now = new Date();
|
|
35
|
+
const schema = {
|
|
36
|
+
name: { type: String },
|
|
37
|
+
createdAt: { type: Date, autoValue: () => now }
|
|
38
|
+
};
|
|
39
|
+
const model = (0, models_1.createModel)({ name: (0, helpers_1.generateId)(), schema });
|
|
40
|
+
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)(), model });
|
|
41
|
+
const docId = await Tests.insertOne({ name: 1234 });
|
|
42
|
+
const result = await Tests.findOne(docId);
|
|
43
|
+
expect(result.name).toBe('1234');
|
|
44
|
+
expect(result.createdAt).toEqual(now);
|
|
45
|
+
});
|
|
46
|
+
it('should validate a document', async () => {
|
|
47
|
+
const schema = { name: { type: String } };
|
|
48
|
+
const model = (0, models_1.createModel)({ name: (0, helpers_1.generateId)(), schema });
|
|
49
|
+
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)(), model });
|
|
50
|
+
expect.assertions(1);
|
|
51
|
+
try {
|
|
52
|
+
await Tests.insertOne({});
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
expect(error.code).toBe('validationError');
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
it('Should be able to use custom clean for models', async () => {
|
|
59
|
+
const model = (0, models_1.createModel)({
|
|
60
|
+
name: 'File',
|
|
61
|
+
schema: {
|
|
62
|
+
name: { type: String }
|
|
63
|
+
},
|
|
64
|
+
async clean(value) {
|
|
65
|
+
if (!value)
|
|
66
|
+
return null;
|
|
67
|
+
return {
|
|
68
|
+
...value,
|
|
69
|
+
name: value.name.toUpperCase() + value._id
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)(), model });
|
|
74
|
+
const docId = await Tests.insertOne({ name: 'hello' });
|
|
75
|
+
const result = await Tests.findOne(docId);
|
|
76
|
+
expect(result.name).toBe('HELLO' + docId);
|
|
77
|
+
});
|
|
78
|
+
it('should throw unique index errors', async () => {
|
|
79
|
+
const Tests = (0, __1.default)({
|
|
80
|
+
name: (0, helpers_1.generateId)(),
|
|
81
|
+
indexes: [
|
|
82
|
+
{
|
|
83
|
+
keys: {
|
|
84
|
+
name: 1
|
|
85
|
+
},
|
|
86
|
+
options: {
|
|
87
|
+
unique: true
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
});
|
|
92
|
+
await Tests.createIndexesPromise;
|
|
93
|
+
await Tests.insertOne({ name: 'one' });
|
|
94
|
+
expect.assertions(3);
|
|
95
|
+
try {
|
|
96
|
+
await Tests.insertOne({ name: 'one' });
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
expect(error.code).toBe('validationError');
|
|
100
|
+
expect(error.validationErrors).toHaveProperty('unknownKey');
|
|
101
|
+
expect(error.validationErrors.unknownKey).toBe('notUnique');
|
|
102
|
+
/**
|
|
103
|
+
* This should work on a real db, but on memory-server it doesnt give the name of the index.
|
|
104
|
+
*/
|
|
105
|
+
// expect(error.code).toBe('validationError')
|
|
106
|
+
// expect(error.validationErrors).toHaveProperty('name')
|
|
107
|
+
// expect(error.validationErrors.name).toBe('notUnique')
|
|
70
108
|
}
|
|
71
109
|
});
|
|
72
|
-
const Tests = (0, __1.default)({ name: (0, helpers_1.generateId)(), model });
|
|
73
|
-
const docId = await Tests.insertOne({ name: 'hello' });
|
|
74
|
-
const result = await Tests.findOne(docId);
|
|
75
|
-
expect(result.name).toBe('HELLO' + docId);
|
|
76
110
|
});
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const wrapErrors_1 = require("./wrapErrors");
|
|
3
4
|
exports.default = (collection) => {
|
|
4
5
|
const updateAndFind = async function (selector, modifier, options = {}) {
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
return await (0, wrapErrors_1.wrapErrors)(async () => {
|
|
7
|
+
return await collection.findOneAndUpdate(selector, modifier, {
|
|
8
|
+
...options,
|
|
9
|
+
mongoOptions: {
|
|
10
|
+
...options.mongoOptions,
|
|
11
|
+
returnDocument: 'after'
|
|
12
|
+
}
|
|
13
|
+
});
|
|
11
14
|
});
|
|
12
15
|
};
|
|
13
16
|
return updateAndFind;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const wrapErrors_1 = require("./wrapErrors");
|
|
3
4
|
exports.default = (collection) => {
|
|
4
5
|
const updateItem = async function (item, modifier) {
|
|
5
|
-
const updated = await
|
|
6
|
+
const updated = await (0, wrapErrors_1.wrapErrors)(async () => {
|
|
7
|
+
return await collection.updateAndFind({ _id: item._id }, modifier);
|
|
8
|
+
});
|
|
6
9
|
for (const key in item) {
|
|
7
10
|
delete item[key];
|
|
8
11
|
}
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const getSelector_1 = __importDefault(require("./getSelector"));
|
|
7
7
|
const cleanModifier_1 = __importDefault(require("./cleanModifier"));
|
|
8
8
|
const validateModifier_1 = __importDefault(require("./validateModifier"));
|
|
9
|
+
const wrapErrors_1 = require("./wrapErrors");
|
|
9
10
|
exports.default = (collection) => {
|
|
10
11
|
const updateMany = async function (selectorArg, modifierArg, options = {}) {
|
|
11
12
|
let modifier = modifierArg;
|
|
@@ -19,7 +20,9 @@ exports.default = (collection) => {
|
|
|
19
20
|
if (options.validate !== false)
|
|
20
21
|
await (0, validateModifier_1.default)(schema, modifier);
|
|
21
22
|
}
|
|
22
|
-
const result = await
|
|
23
|
+
const result = await (0, wrapErrors_1.wrapErrors)(() => {
|
|
24
|
+
return collection.rawCollection.updateMany(selector, modifier);
|
|
25
|
+
});
|
|
23
26
|
return result;
|
|
24
27
|
};
|
|
25
28
|
return updateMany;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const getSelector_1 = __importDefault(require("./getSelector"));
|
|
7
7
|
const cleanModifier_1 = __importDefault(require("./cleanModifier"));
|
|
8
8
|
const validateModifier_1 = __importDefault(require("./validateModifier"));
|
|
9
|
+
const wrapErrors_1 = require("./wrapErrors");
|
|
9
10
|
exports.default = (collection) => {
|
|
10
11
|
const updateOne = async function (selectorArg, modifierArg, options = {}) {
|
|
11
12
|
let modifier = modifierArg;
|
|
@@ -19,7 +20,9 @@ exports.default = (collection) => {
|
|
|
19
20
|
if (options.validate !== false)
|
|
20
21
|
await (0, validateModifier_1.default)(schema, modifier);
|
|
21
22
|
}
|
|
22
|
-
const result = await
|
|
23
|
+
const result = await (0, wrapErrors_1.wrapErrors)(() => {
|
|
24
|
+
return collection.rawCollection.updateOne(selector, modifier);
|
|
25
|
+
});
|
|
23
26
|
return result;
|
|
24
27
|
};
|
|
25
28
|
return updateOne;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const getSelector_1 = __importDefault(require("./getSelector"));
|
|
7
7
|
const validateUpsert_1 = __importDefault(require("./validateModifier/validateUpsert"));
|
|
8
8
|
const cleanModifier_1 = __importDefault(require("./cleanModifier"));
|
|
9
|
+
const wrapErrors_1 = require("./wrapErrors");
|
|
9
10
|
exports.default = (collection) => {
|
|
10
11
|
const upsert = async function (selectorArg, modifierArg, options = {}) {
|
|
11
12
|
let modifier = modifierArg;
|
|
@@ -20,7 +21,9 @@ exports.default = (collection) => {
|
|
|
20
21
|
if (options.validate !== false)
|
|
21
22
|
await (0, validateUpsert_1.default)(schema, selector, modifier);
|
|
22
23
|
}
|
|
23
|
-
const result = await
|
|
24
|
+
const result = await (0, wrapErrors_1.wrapErrors)(() => {
|
|
25
|
+
return collection.rawCollection.updateOne(selector, modifier, { upsert: true });
|
|
26
|
+
});
|
|
24
27
|
return result;
|
|
25
28
|
};
|
|
26
29
|
return upsert;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const wrapErrors: <TFunc extends Function>(operation: TFunc) => Promise<any>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.wrapErrors = void 0;
|
|
4
|
+
const schema_1 = require("@orion-js/schema");
|
|
5
|
+
const wrapErrors = async (operation) => {
|
|
6
|
+
try {
|
|
7
|
+
return await operation();
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
if (error.code === 11000) {
|
|
11
|
+
const regex = /index: (?:.*\.)?\$?(?:([_a-z0-9]*)(?:_\d*)|([_a-z0-9]*))\s*dup key/i;
|
|
12
|
+
const match = error.message.match(regex);
|
|
13
|
+
if (!match) {
|
|
14
|
+
throw new schema_1.ValidationError({
|
|
15
|
+
unknownKey: 'notUnique'
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
const indexNameText = match[1] || match[2];
|
|
19
|
+
const names = indexNameText.split(/_[_a-z0-9]_/);
|
|
20
|
+
const errors = {};
|
|
21
|
+
for (const name of names) {
|
|
22
|
+
errors[name] = 'notUnique';
|
|
23
|
+
}
|
|
24
|
+
throw new schema_1.ValidationError(errors);
|
|
25
|
+
}
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
exports.wrapErrors = wrapErrors;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orion-js/mongodb",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.10",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"types": "lib/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
"upgrade-interactive": "yarn upgrade-interactive"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@orion-js/helpers": "^3.1.
|
|
21
|
-
"@orion-js/models": "^3.1.
|
|
22
|
-
"@orion-js/resolvers": "^3.1.
|
|
23
|
-
"@orion-js/schema": "^3.1.
|
|
24
|
-
"@orion-js/typed-model": "^3.1.
|
|
20
|
+
"@orion-js/helpers": "^3.1.10",
|
|
21
|
+
"@orion-js/models": "^3.1.10",
|
|
22
|
+
"@orion-js/resolvers": "^3.1.10",
|
|
23
|
+
"@orion-js/schema": "^3.1.6",
|
|
24
|
+
"@orion-js/typed-model": "^3.1.10",
|
|
25
25
|
"dataloader": "2.0.0",
|
|
26
26
|
"dot-object": "2.1.4",
|
|
27
27
|
"mongodb": "4.1.4"
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "40fa0800303f49ad08890b2bedff2cdadb81360d"
|
|
42
42
|
}
|