Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(model): add
applyDefaults()
helper that allows applying defaul…
…ts to document or POJO Re: #11945
- Loading branch information
Showing
7 changed files
with
251 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
'use strict'; | ||
|
||
module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildren, isBeforeSetters, pathsToSkip) { | ||
const paths = Object.keys(doc.$__schema.paths); | ||
const plen = paths.length; | ||
|
||
for (let i = 0; i < plen; ++i) { | ||
let def; | ||
let curPath = ''; | ||
const p = paths[i]; | ||
|
||
if (p === '_id' && doc.$__.skipId) { | ||
continue; | ||
} | ||
|
||
const type = doc.$__schema.paths[p]; | ||
const path = type.splitPath(); | ||
const len = path.length; | ||
let included = false; | ||
let doc_ = doc._doc; | ||
for (let j = 0; j < len; ++j) { | ||
if (doc_ == null) { | ||
break; | ||
} | ||
|
||
const piece = path[j]; | ||
curPath += (!curPath.length ? '' : '.') + piece; | ||
|
||
if (exclude === true) { | ||
if (curPath in fields) { | ||
break; | ||
} | ||
} else if (exclude === false && fields && !included) { | ||
const hasSubpaths = type.$isSingleNested || type.$isMongooseDocumentArray; | ||
if (curPath in fields || (hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) { | ||
included = true; | ||
} else if (hasIncludedChildren != null && !hasIncludedChildren[curPath]) { | ||
break; | ||
} | ||
} | ||
|
||
if (j === len - 1) { | ||
if (doc_[piece] !== void 0) { | ||
break; | ||
} | ||
|
||
if (typeof type.defaultValue === 'function') { | ||
if (!type.defaultValue.$runBeforeSetters && isBeforeSetters) { | ||
break; | ||
} | ||
if (type.defaultValue.$runBeforeSetters && !isBeforeSetters) { | ||
break; | ||
} | ||
} else if (!isBeforeSetters) { | ||
// Non-function defaults should always run **before** setters | ||
continue; | ||
} | ||
|
||
if (pathsToSkip && pathsToSkip[curPath]) { | ||
break; | ||
} | ||
|
||
if (fields && exclude !== null) { | ||
if (exclude === true) { | ||
// apply defaults to all non-excluded fields | ||
if (p in fields) { | ||
continue; | ||
} | ||
|
||
try { | ||
def = type.getDefault(doc, false); | ||
} catch (err) { | ||
doc.invalidate(p, err); | ||
break; | ||
} | ||
|
||
if (typeof def !== 'undefined') { | ||
doc_[piece] = def; | ||
doc.$__.activePaths.default(p); | ||
} | ||
} else if (included) { | ||
// selected field | ||
try { | ||
def = type.getDefault(doc, false); | ||
} catch (err) { | ||
doc.invalidate(p, err); | ||
break; | ||
} | ||
|
||
if (typeof def !== 'undefined') { | ||
doc_[piece] = def; | ||
doc.$__.activePaths.default(p); | ||
} | ||
} | ||
} else { | ||
try { | ||
def = type.getDefault(doc, false); | ||
} catch (err) { | ||
doc.invalidate(p, err); | ||
break; | ||
} | ||
|
||
if (typeof def !== 'undefined') { | ||
doc_[piece] = def; | ||
doc.$__.activePaths.default(p); | ||
} | ||
} | ||
} else { | ||
doc_ = doc_[piece]; | ||
} | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
'use strict'; | ||
|
||
module.exports = function applyDefaultsToPOJO(doc, schema) { | ||
const paths = Object.keys(schema.paths); | ||
const plen = paths.length; | ||
|
||
for (let i = 0; i < plen; ++i) { | ||
let curPath = ''; | ||
const p = paths[i]; | ||
|
||
const type = schema.paths[p]; | ||
const path = type.splitPath(); | ||
const len = path.length; | ||
let doc_ = doc; | ||
for (let j = 0; j < len; ++j) { | ||
if (doc_ == null) { | ||
break; | ||
} | ||
|
||
const piece = path[j]; | ||
curPath += (!curPath.length ? '' : '.') + piece; | ||
|
||
if (j === len - 1) { | ||
if (typeof doc_[piece] !== 'undefined') { | ||
if (type.$isSingleNested) { | ||
applyDefaultsToPOJO(doc_[piece], type.caster.schema); | ||
} else if (type.$isMongooseDocumentArray && Array.isArray(doc_[piece])) { | ||
doc_[piece].forEach(el => applyDefaultsToPOJO(el, type.schema)); | ||
} | ||
|
||
break; | ||
} | ||
|
||
const def = type.getDefault(doc, false, { skipCast: true }); | ||
if (typeof def !== 'undefined') { | ||
doc_[piece] = def; | ||
|
||
if (type.$isSingleNested) { | ||
applyDefaultsToPOJO(def, type.caster.schema); | ||
} else if (type.$isMongooseDocumentArray && Array.isArray(def)) { | ||
def.forEach(el => applyDefaultsToPOJO(el, type.schema)); | ||
} | ||
} | ||
} else { | ||
if (doc_[piece] == null) { | ||
doc_[piece] = {}; | ||
} | ||
doc_ = doc_[piece]; | ||
} | ||
} | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.