Skip to content

Commit faf4b14

Browse files
authored
Merge pull request #460 from Meteor-Community-Packages/dmytro-changes
2 parents 230a115 + 916c93b commit faf4b14

File tree

9 files changed

+187
-86
lines changed

9 files changed

+187
-86
lines changed

.github/workflows/testsuite.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ jobs:
1515
uses: actions/checkout@v3
1616

1717
- name: Setup meteor
18-
uses: meteorengineer/setup-meteor@v1
18+
uses: meteorengineer/setup-meteor@v2
1919
with:
20-
meteor-release: '2.13.3'
20+
meteor-release: '3.0.4'
2121

2222
- name: cache dependencies
23-
uses: actions/cache@v1
23+
uses: actions/cache@v4
2424
with:
2525
path: ~/.npm
2626
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
55
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
66

7+
- [4.0.4](#404)
8+
- [4.0.3](#403)
79
- [4.0.2](#402)
810
- [4.0.1](#401)
911
- [4.0.0](#400)
@@ -80,6 +82,16 @@
8082

8183
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
8284

85+
## 4.0.4
86+
87+
- Return unaltered error message when collection isn't being validated and doesn't have simple schema attached thanks to @DmytroSoninLinguahouse
88+
- Update test application to use Meteor release number 3.0.4
89+
- Remove lodash dependencies
90+
91+
## 4.0.3
92+
93+
- Update Meteor release to 3.0
94+
8395
## 4.0.2
8496

8597
- Make collection2 compatible with the newly released RC

package-lock.json

Lines changed: 21 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package/collection2/lib.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,29 @@ export const isUpdateType = function (type) {
3939
export const isUpsertType = function (type) {
4040
return ['upsert', 'upsertAsync'].includes(type);
4141
};
42+
43+
export function isObject(value) {
44+
return typeof value === 'object' && value !== null && !Array.isArray(value);
45+
}
46+
47+
export function isEqual(a, b) {
48+
// Handle primitive types and null/undefined
49+
if (a === b) return true;
50+
if (a == null || b == null) return false;
51+
if (typeof a !== 'object' || typeof b !== 'object') return false;
52+
53+
// Get object keys
54+
const keysA = Object.keys(a);
55+
const keysB = Object.keys(b);
56+
57+
// Check if number of keys match
58+
if (keysA.length !== keysB.length) return false;
59+
60+
// Compare each key-value pair recursively
61+
return keysA.every(key => {
62+
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
63+
return isEqual(a[key], b[key]);
64+
});
65+
}
66+
67+

package/collection2/main.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import { Meteor } from 'meteor/meteor';
22
import { Mongo } from 'meteor/mongo';
33
import SimpleSchema from "meteor/aldeed:simple-schema";
44
import { EJSON } from 'meteor/ejson';
5-
import isEmpty from 'lodash.isempty';
6-
import isEqual from 'lodash.isequal';
7-
import isObject from 'lodash.isobject';
8-
import { flattenSelector, isInsertType, isUpdateType, isUpsertType } from './lib';
5+
import { flattenSelector, isInsertType, isUpdateType, isUpsertType, isObject, isEqual } from './lib';
96

107

118
/**
@@ -228,13 +225,18 @@ Mongo.Collection.prototype.attachSchema = function c2AttachSchema(ss, options) {
228225
_super.isCalledFromAsync = true;
229226
return Promise.resolve(_super.apply(this, args));
230227
} catch (err) {
231-
const addValidationErrorsPropName =
232-
typeof validationContext.addValidationErrors === 'function'
233-
? 'addValidationErrors'
228+
if (this._c2) {
229+
const addValidationErrorsPropName =
230+
typeof validationContext.addValidationErrors === 'function'
231+
? 'addValidationErrors'
234232
: 'addInvalidKeys';
235233
parsingServerError([err], validationContext, addValidationErrorsPropName);
236234
const error = getErrorObject(validationContext, err.message, err.code);
237235
return Promise.reject(error);
236+
} else {
237+
// do not change error if collection isn't being validated by collection2
238+
return Promise.reject(err);
239+
}
238240
}
239241
} else {
240242
return _super.apply(this, args);
@@ -250,12 +252,17 @@ Mongo.Collection.prototype.attachSchema = function c2AttachSchema(ss, options) {
250252
try {
251253
return await _super.apply(this, args);
252254
} catch (err) {
255+
if (this._c2) {
253256
const addValidationErrorsPropName =
254257
typeof validationContext.addValidationErrors === 'function'
255258
? 'addValidationErrors'
256259
: 'addInvalidKeys';
257260
parsingServerError([err], validationContext, addValidationErrorsPropName);
258261
throw getErrorObject(validationContext, err.message, err.code);
262+
} else {
263+
// do not change error if collection isn't being validated by collection2
264+
throw err;
265+
}
259266
}
260267
};
261268
}
@@ -305,7 +312,7 @@ Mongo.Collection.prototype.attachSchema = function c2AttachSchema(ss, options) {
305312
throw new Error('invalid type argument');
306313
}
307314

308-
const validatedObjectWasInitiallyEmpty = isEmpty(doc);
315+
const validatedObjectWasInitiallyEmpty = Object.keys(doc).length === 0;
309316

310317
// Support missing options arg
311318
if (!callback && typeof options === 'function') {
@@ -481,7 +488,7 @@ Mongo.Collection.prototype.attachSchema = function c2AttachSchema(ss, options) {
481488
}
482489

483490
// XXX Maybe move this into SimpleSchema
484-
if (!validatedObjectWasInitiallyEmpty && isEmpty(docToValidate)) {
491+
if (!validatedObjectWasInitiallyEmpty && Object.keys(docToValidate).length === 0) {
485492
throw new Error(
486493
'After filtering out keys not in the schema, your ' +
487494
(isUpdateType(type) ? 'modifier' : 'object') +

package/collection2/package.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,11 @@ Package.describe({
44
name: 'aldeed:collection2',
55
summary:
66
'Automatic validation of Meteor Mongo insert and update operations on the client and server',
7-
version: '4.0.3',
7+
version: '4.0.4',
88
documentation: '../../README.md',
99
git: 'https://github.com/aldeed/meteor-collection2.git'
1010
});
1111

12-
Npm.depends({
13-
'lodash.isempty': '4.4.0',
14-
'lodash.isequal': '4.5.0',
15-
'lodash.isobject': '3.0.2'
16-
});
17-
1812
Package.onUse(function (api) {
1913
api.versionsFrom(['1.12.1', '2.3', '3.0']);
2014
api.use('mongo');

tests/.meteor/release

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1+

tests/.meteor/versions

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,69 @@
1-
2-
aldeed:[email protected]-beta300.0
3-
4-
5-
6-
7-
8-
9-
10-
11-
12-
13-
14-
15-
16-
17-
18-
19-
20-
21-
22-
23-
24-
25-
26-
27-
28-
29-
1+
2+
3+
4+
5+
6+
7+
8+
9+
10+
11+
12+
13+
14+
15+
16+
17+
18+
19+
20+
21+
22+
23+
24+
25+
26+
27+
28+
29+
3030
31-
32-
33-
31+
32+
33+
3434
35-
36-
37-
35+
36+
37+
3838
meteortesting:[email protected]
3939
meteortesting:[email protected]
4040
meteortesting:[email protected]
41-
42-
43-
44-
45-
46-
47-
41+
42+
43+
44+
45+
46+
47+
4848
49-
50-
51-
npm-mongo@4.16.2-rc300.4
52-
53-
49+
50+
51+
npm-mongo@4.17.4
52+
53+
5454
55-
56-
57-
58-
59-
60-
61-
62-
63-
64-
65-
66-
67-
68-
69-
55+
56+
57+
58+
59+
60+
61+
62+
63+
64+
65+
66+
67+
68+
69+

tests/collection2.tests.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,51 @@ describe('collection2', function () {
686686
}
687687
});
688688

689+
it('return unaltered error message when collection isn\'t being validated and doesn\'t have simple schema attached', async function () {
690+
if (Meteor.isServer) {
691+
const testCollection = new Mongo.Collection('test_error_collection');
692+
await testCollection.createIndexAsync({ name: 1 }, { unique: true });
693+
await testCollection.removeAsync({});
694+
695+
// Test insert duplicate error
696+
await testCollection.insertAsync({ name: 'foo' });
697+
try {
698+
await testCollection.insertAsync({ name: 'foo' });
699+
} catch (e) {
700+
expect(e.code).toBe(11000);
701+
expect(e.name).toBe('MongoServerError');
702+
// Should not have any Collection2 specific properties
703+
expect(e.invalidKeys).toBe(undefined);
704+
expect(e.message).toMatch(/E11000 duplicate key error/);
705+
}
706+
707+
// Test update with invalid operation
708+
try {
709+
await testCollection.updateAsync(
710+
{ name: 'foo' },
711+
{ $invalidOp: { name: 'bar' } }
712+
);
713+
} catch (e) {
714+
expect(e.name).toBe('MongoServerError');
715+
// Should not be transformed into Collection2 error
716+
expect(e.error).toBe(undefined);
717+
expect(e.reason).toBe(undefined);
718+
}
719+
720+
// Test upsert with invalid _id format
721+
try {
722+
await testCollection.upsertAsync(
723+
{ name: 'nonexistent' },
724+
{ $setOnInsert: { _id: 'invalid-id-format' } }
725+
);
726+
} catch (e) {
727+
expect(e.name).toBe('MongoServerError');
728+
// Should not have Collection2 validation context
729+
expect(e.validationContext).toBe(undefined);
730+
}
731+
}
732+
});
733+
689734
addBooksTests();
690735
addContextTests();
691736
addDefaultValuesTests();

0 commit comments

Comments
 (0)