Comments (8)
Hello,
Yeah I did not think about nested models when writing this example of SealedModel, but that's an easy fix.
We will consider than when encoutering another nested model in the definition, the parent model is trusting its child model to validate its properties. So if you use SealedModel for child models as well, you should be fine.
Here is the completed SealedModel code:
import { ObjectModel } from "objectmodel";
const SealedModel = def => {
let model = ObjectModel(def);
model.sealed = true;
model.extend = () => {
throw new Error(`Sealed models cannot be extended`);
};
const checkUndeclaredProps = (obj, def, undeclaredProps, path) => {
Object.keys(obj).forEach(key => {
let val = obj[key],
subpath = path ? path + "." + key : key;
if(def instanceof Model){
// trust nested model props validation
} else if (!Object.prototype.hasOwnProperty.call(def, key)) {
undeclaredProps.push(subpath);
} else if (val && typeof val === "object" && Object.getPrototypeOf(val) === Object.prototype) {
checkUndeclaredProps(val, def[key], undeclaredProps, subpath);
}
});
};
return model.assert(
function hasNoUndeclaredProps(obj) {
if (!model.sealed) return true;
let undeclaredProps = [];
checkUndeclaredProps(obj, this.definition, undeclaredProps);
return undeclaredProps.length === 0 ? true : undeclaredProps;
},
undeclaredProps =>
`Undeclared properties in the sealed model definition: ${undeclaredProps}`
);
};
export default SealedModel;
Thanks for your report, I'll update it on the website as well.
from objectmodel.
Excellent, thank you!
from objectmodel.
Doc note - missing line import {Model} from 'objectmodel'
at top of http://objectmodel.js.org/docs/examples/sealed.js
I noticed an issue when trying to add a nested sealed model as an optional field:
const NameModel = SealedModel({
first: String,
last: String
})
const PossiblyAnonymousPersonModel = SealedModel({
age: Number,
name: [NameModel]
})
const x = PossiblyAnonymousPersonModel({
age: 20,
name: {
first: 'John',
last: 'Doe'
}
})
// TypeError: Undeclared properties in the sealed model definition: name.first,name.last
Omitting the optional nested model altogether works fine:
const y = PossiblyAnonymousPersonModel({
age: 20
})
Setting the fields in the inner model to optional still produces the undeclared properties message, although only for provided input fields:
const NameModel = SealedModel({
first: [String],
last: [String]
})
const PossiblyAnonymousPersonModel = SealedModel({
age: Number,
name: [NameModel]
})
const z = PossiblyAnonymousPersonModel({
age: 20,
name: {
first: "John"
}
})
// Undeclared properties in the sealed model definition: name.first
from objectmodel.
Yes, the code of the SealedModel example is perfectible. I updated it , is it better now ?
http://objectmodel.js.org/docs/examples/sealed.js
from objectmodel.
Yes, optional nested models working now with SealedModel(). Thank you!
from objectmodel.
Ah, sorry, now getting Undeclared properties in the sealed model definition: 0,1,2...
appended to errors if I pass in a string, e.g.
const z = PossiblyAnonymousPersonModel('foobar')
// TypeError: expecting {
// age: Number,
// name: [{
// first: [String],
// last: [String]
// }]
// }, got String "foobar"
// Undeclared properties in the sealed model definition: 0,1,2,3,4,5
from objectmodel.
Oh yeah that's an easy fix, the assertion should not be run at all if the argument is not an object
Add if(typeof obj !== "object") return;
at the first line of checkUndeclaredProps assertion, like so:
import { ObjectModel } from "objectmodel";
const SealedModel = def => {
const model = ObjectModel(def);
model.sealed = true;
model.extend = () => {
throw new Error(`Sealed models cannot be extended`);
};
const isPlainObject = obj => typeof obj === "object" && Object.getPrototypeOf(obj) === Object.prototype
const checkUndeclaredProps = (obj, def, undeclaredProps, path) => {
if(typeof obj !== "object" || obj === null) return;
Object.keys(obj).forEach(key => {
let val = obj[key],
subpath = path ? path + "." + key : key;
if(isPlainObject(def) && !Object.prototype.hasOwnProperty.call(def, key)) {
undeclaredProps.push(subpath);
} else if (isPlainObject(val) && isPlainObject(def)) {
checkUndeclaredProps(val, def[key], undeclaredProps, subpath);
}
});
};
return model.assert(
function hasNoUndeclaredProps(obj) {
if (!model.sealed) return true;
let undeclaredProps = [];
checkUndeclaredProps(obj, this.definition, undeclaredProps);
return undeclaredProps.length === 0 ? true : undeclaredProps;
},
undeclaredProps =>
`Undeclared properties in the sealed model definition: ${undeclaredProps}`
);
};
export default SealedModel;
from objectmodel.
That fixed, thank you!
from objectmodel.
Related Issues (20)
- SyntaxError: Unexpected token 'export' HOT 2
- Optional array model cause duplication in other instances of a model with default HOT 3
- Feature Request: Code Suggestion/IntelliSense on IDE (Jetbrain Webstorm) HOT 4
- Package objectmodel has been ignored because it contains invalid configuration HOT 2
- Problem Extending Typescript Class HOT 5
- Consider creating ADL serializer to generate ObjectModel? HOT 1
- How to add custom methods to a Model? HOT 1
- Working with VSCode Intellisense HOT 2
- Question: Is it possible to skip more detailed checks if initial type check fails? HOT 6
- [email protected]: The engine "node" is incompatible with this module HOT 3
- Default for Nested Models HOT 1
- Load Json to Object HOT 1
- Model composition and defaults HOT 11
- Typescript expected number of arguments when using defaultTo() HOT 4
- get objectmodel added to typia benchmarks HOT 4
- Nice Project HOT 1
- How can i return a « cleaned » object ? HOT 2
- Use in Typescript ? HOT 2
- pre/post process some datas ? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from objectmodel.