Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dmytro changes #460

Merged
merged 11 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/testsuite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ jobs:
uses: actions/checkout@v3

- name: Setup meteor
uses: meteorengineer/setup-meteor@v1
uses: meteorengineer/setup-meteor@v2
with:
meteor-release: '2.13.3'
meteor-release: '3.0.4'

- 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
Loading