Skip to content

Commit

Permalink
Merge branch 'master' into feature/update-deps
Browse files Browse the repository at this point in the history
  • Loading branch information
StorytellerCZ authored Nov 12, 2024
2 parents 07fa9b8 + faf4b14 commit 940b46f
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 86 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/testsuite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
meteor: [ '1.12.1', '2.13.3', '3.0.3' ]
meteor: [ '1.12.1', '2.13.3', '3.0.4' ]
# needs: [lintcode,lintstyle,lintdocs] # we could add prior jobs for linting, if desired
steps:
- name: checkout
uses: actions/checkout@v3

- name: Setup meteor
uses: meteorengineer/setup-meteor@v1
uses: meteorengineer/setup-meteor@v2
with:
meteor-release: ${{ matrix.meteor }}

- name: cache dependencies
uses: actions/cache@v1
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*

- [4.0.4](#404)
- [4.0.3](#403)
- [4.0.2](#402)
- [4.0.1](#401)
- [4.0.0](#400)
Expand Down Expand Up @@ -80,6 +82,16 @@

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

## 4.0.4

- Return unaltered error message when collection isn't being validated and doesn't have simple schema attached thanks to @DmytroSoninLinguahouse
- Update test application to use Meteor release number 3.0.4
- Remove lodash dependencies

## 4.0.3

- Update Meteor release to 3.0

## 4.0.2

- Make collection2 compatible with the newly released RC
Expand Down
25 changes: 21 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions package/collection2/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,29 @@ export const isUpdateType = function (type) {
export const isUpsertType = function (type) {
return ['upsert', 'upsertAsync'].includes(type);
};

export function isObject(value) {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}

export function isEqual(a, b) {
// Handle primitive types and null/undefined
if (a === b) return true;
if (a == null || b == null) return false;
if (typeof a !== 'object' || typeof b !== 'object') return false;

// Get object keys
const keysA = Object.keys(a);
const keysB = Object.keys(b);

// Check if number of keys match
if (keysA.length !== keysB.length) return false;

// Compare each key-value pair recursively
return keysA.every(key => {
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
return isEqual(a[key], b[key]);
});
}


25 changes: 16 additions & 9 deletions package/collection2/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ import { Meteor } from 'meteor/meteor';
import { Mongo } from 'meteor/mongo';
import SimpleSchema from "meteor/aldeed:simple-schema";
import { EJSON } from 'meteor/ejson';
import isEmpty from 'lodash.isempty';
import isEqual from 'lodash.isequal';
import isObject from 'lodash.isobject';
import { flattenSelector, isInsertType, isUpdateType, isUpsertType } from './lib';
import { flattenSelector, isInsertType, isUpdateType, isUpsertType, isObject, isEqual } from './lib';


/**
Expand Down Expand Up @@ -228,13 +225,18 @@ Mongo.Collection.prototype.attachSchema = function c2AttachSchema(ss, options) {
_super.isCalledFromAsync = true;
return Promise.resolve(_super.apply(this, args));
} catch (err) {
const addValidationErrorsPropName =
typeof validationContext.addValidationErrors === 'function'
? 'addValidationErrors'
if (this._c2) {
const addValidationErrorsPropName =
typeof validationContext.addValidationErrors === 'function'
? 'addValidationErrors'
: 'addInvalidKeys';
parsingServerError([err], validationContext, addValidationErrorsPropName);
const error = getErrorObject(validationContext, err.message, err.code);
return Promise.reject(error);
} else {
// do not change error if collection isn't being validated by collection2
return Promise.reject(err);
}
}
} else {
return _super.apply(this, args);
Expand All @@ -250,12 +252,17 @@ Mongo.Collection.prototype.attachSchema = function c2AttachSchema(ss, options) {
try {
return await _super.apply(this, args);
} catch (err) {
if (this._c2) {
const addValidationErrorsPropName =
typeof validationContext.addValidationErrors === 'function'
? 'addValidationErrors'
: 'addInvalidKeys';
parsingServerError([err], validationContext, addValidationErrorsPropName);
throw getErrorObject(validationContext, err.message, err.code);
} else {
// do not change error if collection isn't being validated by collection2
throw err;
}
}
};
}
Expand Down Expand Up @@ -305,7 +312,7 @@ Mongo.Collection.prototype.attachSchema = function c2AttachSchema(ss, options) {
throw new Error('invalid type argument');
}

const validatedObjectWasInitiallyEmpty = isEmpty(doc);
const validatedObjectWasInitiallyEmpty = Object.keys(doc).length === 0;

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

// XXX Maybe move this into SimpleSchema
if (!validatedObjectWasInitiallyEmpty && isEmpty(docToValidate)) {
if (!validatedObjectWasInitiallyEmpty && Object.keys(docToValidate).length === 0) {
throw new Error(
'After filtering out keys not in the schema, your ' +
(isUpdateType(type) ? 'modifier' : 'object') +
Expand Down
8 changes: 1 addition & 7 deletions package/collection2/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,11 @@ Package.describe({
name: 'aldeed:collection2',
summary:
'Automatic validation of Meteor Mongo insert and update operations on the client and server',
version: '4.0.3',
version: '4.0.4',
documentation: '../../README.md',
git: 'https://github.com/aldeed/meteor-collection2.git'
});

Npm.depends({
'lodash.isempty': '4.4.0',
'lodash.isequal': '4.5.0',
'lodash.isobject': '3.0.2'
});

Package.onUse(function (api) {
api.versionsFrom(['1.12.1', '2.3', '3.0']);
api.use('mongo');
Expand Down
2 changes: 1 addition & 1 deletion tests/.meteor/release
Original file line number Diff line number Diff line change
@@ -1 +1 @@
METEOR@3.0-rc.4
METEOR@3.0.4
124 changes: 62 additions & 62 deletions tests/.meteor/versions
Original file line number Diff line number Diff line change
@@ -1,69 +1,69 @@
aldeed:collection2@4.0.2
aldeed:simple-schema@2.0.0-beta300.0
allow-deny@2.0.0-rc300.4
autopublish@1.0.8-rc300.4
autoupdate@2.0.0-rc300.4
babel-compiler@7.11.0-rc300.4
babel-runtime@1.5.2-rc300.4
base64@1.0.13-rc300.4
binary-heap@1.0.12-rc300.4
boilerplate-generator@2.0.0-rc300.4
callback-hook@1.6.0-rc300.4
check@1.4.2-rc300.4
core-runtime@1.0.0-rc300.4
ddp@1.4.2-rc300.4
ddp-client@3.0.0-rc300.4
ddp-common@1.4.1-rc300.4
ddp-server@3.0.0-rc300.4
diff-sequence@1.1.3-rc300.4
dynamic-import@0.7.4-rc300.4
ecmascript@0.16.9-rc300.4
ecmascript-runtime@0.8.2-rc300.4
ecmascript-runtime-client@0.12.2-rc300.4
ecmascript-runtime-server@0.11.1-rc300.4
ejson@1.1.4-rc300.4
es5-shim@4.8.1-rc300.4
facts-base@1.0.2-rc300.4
fetch@0.1.5-rc300.4
geojson-utils@1.0.12-rc300.4
hot-code-push@1.0.5-rc300.4
aldeed:collection2@4.0.4
aldeed:simple-schema@2.0.0
allow-deny@2.0.0
autopublish@1.0.8
autoupdate@2.0.0
babel-compiler@7.11.1
babel-runtime@1.5.2
base64@1.0.13
binary-heap@1.0.12
boilerplate-generator@2.0.0
callback-hook@1.6.0
check@1.4.4
core-runtime@1.0.0
ddp@1.4.2
ddp-client@3.0.2
ddp-common@1.4.4
ddp-server@3.0.2
diff-sequence@1.1.3
dynamic-import@0.7.4
ecmascript@0.16.9
ecmascript-runtime@0.8.3
ecmascript-runtime-client@0.12.2
ecmascript-runtime-server@0.11.1
ejson@1.1.4
es5-shim@4.8.1
facts-base@1.0.2
fetch@0.1.5
geojson-utils@1.0.12
hot-code-push@1.0.5
http@1.0.1
id-map@1.2.0-rc300.4
insecure@1.0.8-rc300.4
inter-process-messaging@0.1.2-rc300.4
id-map@1.2.0
insecure@1.0.8
inter-process-messaging@0.1.2
jquery@3.0.0
logging@1.3.5-rc300.4
meteor@2.0.0-rc300.4
meteor-base@1.5.2-rc300.4
logging@1.3.5
meteor@2.0.1
meteor-base@1.5.2
meteortesting:browser-tests@1.6.0-beta300.0
meteortesting:mocha@3.1.0-beta300.0
meteortesting:mocha-core@8.3.1-beta300.0
minifier-css@2.0.0-rc300.4
minifier-js@3.0.0-rc300.4
minimongo@2.0.0-rc300.4
modern-browsers@0.1.11-rc300.4
modules@0.20.1-rc300.4
modules-runtime@0.13.2-rc300.4
mongo@2.0.0-rc300.4
minifier-css@2.0.0
minifier-js@3.0.0
minimongo@2.0.1
modern-browsers@0.1.11
modules@0.20.2
modules-runtime@0.13.2
mongo@2.0.2
mongo-decimal@0.1.4-beta300.7
mongo-dev-server@1.1.1-rc300.4
mongo-id@1.0.9-rc300.4
npm-mongo@4.16.2-rc300.4
ordered-dict@1.2.0-rc300.4
promise@1.0.0-rc300.4
mongo-dev-server@1.1.1
mongo-id@1.0.9
npm-mongo@4.17.4
ordered-dict@1.2.0
promise@1.0.0
raix:eventemitter@1.0.0
random@1.2.2-rc300.4
react-fast-refresh@0.2.9-rc300.4
reactive-var@1.0.13-rc300.4
reload@1.3.2-rc300.4
retry@1.1.1-rc300.4
routepolicy@1.1.2-rc300.4
shell-server@0.6.0-rc300.4
socket-stream-client@0.5.3-rc300.4
standard-minifier-css@1.9.3-rc300.4
standard-minifier-js@3.0.0-rc300.4
tracker@1.3.4-rc300.4
typescript@5.4.3-rc300.4
underscore@1.6.2-rc300.4
webapp@2.0.0-rc300.4
webapp-hashing@1.1.2-rc300.4
random@1.2.2
react-fast-refresh@0.2.9
reactive-var@1.0.13
reload@1.3.2
retry@1.1.1
routepolicy@1.1.2
shell-server@0.6.0
socket-stream-client@0.5.3
standard-minifier-css@1.9.3
standard-minifier-js@3.0.0
tracker@1.3.4
typescript@5.4.3
underscore@1.6.4
webapp@2.0.3
webapp-hashing@1.1.2
45 changes: 45 additions & 0 deletions tests/collection2.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,51 @@ describe('collection2', function () {
}
});

it('return unaltered error message when collection isn\'t being validated and doesn\'t have simple schema attached', async function () {
if (Meteor.isServer) {
const testCollection = new Mongo.Collection('test_error_collection');
await testCollection.createIndexAsync({ name: 1 }, { unique: true });
await testCollection.removeAsync({});

// Test insert duplicate error
await testCollection.insertAsync({ name: 'foo' });
try {
await testCollection.insertAsync({ name: 'foo' });
} catch (e) {
expect(e.code).toBe(11000);
expect(e.name).toBe('MongoServerError');
// Should not have any Collection2 specific properties
expect(e.invalidKeys).toBe(undefined);
expect(e.message).toMatch(/E11000 duplicate key error/);
}

// Test update with invalid operation
try {
await testCollection.updateAsync(
{ name: 'foo' },
{ $invalidOp: { name: 'bar' } }
);
} catch (e) {
expect(e.name).toBe('MongoServerError');
// Should not be transformed into Collection2 error
expect(e.error).toBe(undefined);
expect(e.reason).toBe(undefined);
}

// Test upsert with invalid _id format
try {
await testCollection.upsertAsync(
{ name: 'nonexistent' },
{ $setOnInsert: { _id: 'invalid-id-format' } }
);
} catch (e) {
expect(e.name).toBe('MongoServerError');
// Should not have Collection2 validation context
expect(e.validationContext).toBe(undefined);
}
}
});

addBooksTests();
addContextTests();
addDefaultValuesTests();
Expand Down

0 comments on commit 940b46f

Please sign in to comment.