Skip to content

Commit

Permalink
Merge pull request #741 from Meteor-Community-Packages/migrate/3.0
Browse files Browse the repository at this point in the history
Meteor 3.0 compatibility
  • Loading branch information
jankapunkt authored Nov 21, 2024
2 parents cdfe749 + 9342ceb commit bca6908
Show file tree
Hide file tree
Showing 15 changed files with 5,340 additions and 3,791 deletions.
29 changes: 14 additions & 15 deletions .github/workflows/lint-test-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ jobs:
# runs-on: ubuntu-latest
# steps:
# - name: checkout
# uses: actions/checkout@v3
# uses: actions/checkout@v4
#
# - name: setup node
# uses: actions/setup-node@v3
# uses: actions/setup-node@v4
# with:
# node-version: 16
# node-version: 20
#
# - name: cache dependencies
# uses: actions/cache@v3
# uses: actions/cache@v4
# with:
# path: ~/.npm
# key: ${{ runner.os }}-node-16-${{ hashFiles('**/package-lock.json') }}
# key: ${{ runner.os }}-node-20-${{ hashFiles('**/package-lock.json') }}
# restore-keys: |
# ${{ runner.os }}-node-16-
# ${{ runner.os }}-node-20-
#
# - run: cd tests && npm ci && npm run setup && npm run lint

Expand All @@ -36,29 +36,28 @@ jobs:
strategy:
matrix:
meteorRelease:
- '2.3'
- '2.14'
- '3.0.2'
# Latest version
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Install Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 16
node-version: 20

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

- name: cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-16-${{ hashFiles('**/package-lock.json') }}
key: ${{ runner.os }}-node-20-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-16-
${{ runner.os }}-node-20-
- run: cd tests && npm ci && npm run setup && npm run test
- run: cd tests && npm ci && npm run setup && npm run test
72 changes: 20 additions & 52 deletions .versions
Original file line number Diff line number Diff line change
@@ -1,56 +1,24 @@
aldeed:[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
aldeed:[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
lmieulet:[email protected]
lmieulet:[email protected]
local-test:aldeed:[email protected]
[email protected]
[email protected]
[email protected]
local-test:aldeed:[email protected]
[email protected]
meteortesting:[email protected]
meteortesting:[email protected]
meteortesting:[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
16 changes: 14 additions & 2 deletions lib/SimpleSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ class SimpleSchema {
}

/**
* For Meteor apps, add a reactive dependency on the label
* for a key.
* Add a reactive dependency on the label for a key.
* @param key {string}
* @param tracker {Tracker}
*/
reactiveLabelDependency(key, tracker = this._constructorOptions.tracker) {
if (!key || !tracker) return;
Expand Down Expand Up @@ -614,10 +615,21 @@ class SimpleSchema {
return null;
}

/**
* Creates a new unnamed ValidationContext instance
* for this schema.
* @return {ValidationContext}
*/
newContext() {
return new ValidationContext(this);
}

/**
* Creates and stores a new named (scoped) ValidationContext for a given name
* and this schema and returns it.
* @param name {string}
* @return {ValidationContext}
*/
namedContext(name) {
if (typeof name !== 'string') name = 'default';
if (!this._validationContexts[name]) {
Expand Down
121 changes: 99 additions & 22 deletions lib/ValidationContext.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,61 @@
import MongoObject from 'mongo-object';
import doValidation from './doValidation';

/**
* @typedef ValidationError
* @type object
* @property name {string} error name
* @property type {string} error type name
* @property value {string} actuall error message value
*/

/**
* State representation of a validation for
* a given schema.
*
*
*/
export default class ValidationContext {
/**
* @param {SimpleSchema} ss SimpleSchema instance to use for validation
* @param {String} [name] Optional context name, accessible on context.name.
*/
constructor(ss, name) {
this.name = name;

this._simpleSchema = ss;
this._schema = ss.schema();
this._schemaKeys = Object.keys(this._schema);
this._validationErrors = [];
this._deps = {};

// Set up validation dependencies
this._deps = {};
const { tracker } = ss._constructorOptions;
if (tracker) {
this.reactive(tracker);
}
//---------------------------------------------------------------------------
// PUBLIC
//---------------------------------------------------------------------------

/**
* Makes this validation context
* reactive for Meteor-Tracker.
* @param tracker {Tracker}
*/
reactive(tracker) {
if (tracker && Object.keys(this._deps).length === 0) {
this._depsAny = new tracker.Dependency();
this._schemaKeys.forEach((key) => {
this._deps[key] = new tracker.Dependency();
});
}
}

_markKeyChanged(key) {
const genericKey = MongoObject.makeKeyGeneric(key);
if (Object.prototype.hasOwnProperty.call(this._deps, genericKey)) this._deps[genericKey].changed();
}

_markKeysChanged(keys) {
if (!keys || !Array.isArray(keys) || !keys.length) return;

keys.forEach((key) => this._markKeyChanged(key));

this._depsAny && this._depsAny.changed();
}

/**
* Merges existing with a list of new validation errors.
* Reactive.
* @param errors ValidationError[]
*/
setValidationErrors(errors) {
const previousValidationErrors = this._validationErrors.map((o) => o.name);
const newValidationErrors = errors.map((o) => o.name);
Expand All @@ -48,6 +67,10 @@ export default class ValidationContext {
this._markKeysChanged(changedKeys);
}

/**
* Adds new validation errors to the list.
* @param errors ValidationError[]
*/
addValidationErrors(errors) {
const newValidationErrors = errors.map((o) => o.name);

Expand All @@ -57,11 +80,20 @@ export default class ValidationContext {
this._markKeysChanged(newValidationErrors);
}

// Reset the validationErrors array
/**
* Flushes/empties the list of validation errors.
*/
reset() {
this.setValidationErrors([]);
}

/**
* Returns a validation error for a given key.
* @param key {string} the key of the field to access errors for
* @param genericKey {string} generic version of the key, you usually don't need
* to explcitly call this. If you do, you need to wrap it using `MongoObject.makeKeyGeneric`
* @return {ValidationError|undefined}
*/
getErrorForKey(key, genericKey = MongoObject.makeKeyGeneric(key)) {
const errors = this._validationErrors;
const errorForKey = errors.find((error) => error.name === key);
Expand All @@ -70,17 +102,24 @@ export default class ValidationContext {
return errors.find((error) => error.name === genericKey);
}

_keyIsInvalid(key, genericKey) {
return !!this.getErrorForKey(key, genericKey);
}

// Like the internal one, but with deps
/**
* Returns, whether there is an error for a given key. Reactive.
* @param key {string}
* @param genericKey {string}
* @return {boolean}
*/
keyIsInvalid(key, genericKey = MongoObject.makeKeyGeneric(key)) {
if (Object.prototype.hasOwnProperty.call(this._deps, genericKey)) this._deps[genericKey].depend();

return this._keyIsInvalid(key, genericKey);
}

/**
*
* @param key
* @param genericKey
* @return {string|*}
*/
keyErrorMessage(key, genericKey = MongoObject.makeKeyGeneric(key)) {
if (Object.prototype.hasOwnProperty.call(this._deps, genericKey)) this._deps[genericKey].depend();

Expand All @@ -91,7 +130,16 @@ export default class ValidationContext {
}

/**
* Validates the object against the simple schema and sets a reactive array of error objects
* Validates the object against the simple schema
* and sets a reactive array of error objects.
* @param obj {object} the document (object) to validate
* @param extendedCustomcontext {object=}
* @param ignoreTypes {string[]=} list of names of ValidationError types to ignore
* @param keysToValidate {string[]=} list of field names (keys) to validate. Other keys are ignored then
* @param isModifier {boolean=} set to true if the document contains MongoDB modifiers
* @param mongoObject {MongoObject=} MongoObject instance to generate keyInfo
* @param isUpsert {boolean=} set to true if the document contains upsert modifiers
* @return {boolean} true if no ValidationError was found, otherwise false
*/
validate(obj, {
extendedCustomContext = {},
Expand Down Expand Up @@ -131,11 +179,19 @@ export default class ValidationContext {
return !validationErrors.length;
}

/**
* returns if this context has no errors. reactive.
* @return {boolean}
*/
isValid() {
this._depsAny && this._depsAny.depend();
return this._validationErrors.length === 0;
}

/**
* returns the list of validation errors. reactive.
* @return {ValidationError[]}
*/
validationErrors() {
this._depsAny && this._depsAny.depend();
return this._validationErrors;
Expand All @@ -144,4 +200,25 @@ export default class ValidationContext {
clean(...args) {
return this._simpleSchema.clean(...args);
}

//---------------------------------------------------------------------------
// PRIVATE
//---------------------------------------------------------------------------

_markKeyChanged(key) {
const genericKey = MongoObject.makeKeyGeneric(key);
if (Object.prototype.hasOwnProperty.call(this._deps, genericKey)) this._deps[genericKey].changed();
}

_markKeysChanged(keys) {
if (!keys || !Array.isArray(keys) || !keys.length) return;

keys.forEach((key) => this._markKeyChanged(key));

this._depsAny && this._depsAny.changed();
}

_keyIsInvalid(key, genericKey) {
return !!this.getErrorForKey(key, genericKey);
}
}
Loading

0 comments on commit bca6908

Please sign in to comment.