Skip to content

Commit

Permalink
docs: update jsdoc comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jankapunkt committed Nov 21, 2024
1 parent c7d945d commit 9342ceb
Show file tree
Hide file tree
Showing 4 changed files with 1,344 additions and 215 deletions.
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);
}
}
17 changes: 16 additions & 1 deletion lib/doValidation.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ function shouldCheck(key) {
return ['$pull', '$pullAll', '$pop', '$slice'].indexOf(key) === -1;
}

/**
* The core method to perform validation.
*
* @param extendedCustomContext
* @param ignoreTypes
* @param isModifier
* @param isUpsert
* @param keysToValidate
* @param mongoObject
* @param obj
* @param schema
* @param validationContext
* @return {*[]}
*/
function doValidation({
extendedCustomContext,
ignoreTypes,
Expand Down Expand Up @@ -188,7 +202,8 @@ function doValidation({
}
}

// The recursive function
// The recursive function to iterate over the
// potentially nested document structure
function checkObj({
val,
affectedKey,
Expand Down
Loading

0 comments on commit 9342ceb

Please sign in to comment.