
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
another-json-schema
Advanced tools
Another JSON Schema, simple & flexible & intuitive.
$ npm i another-json-schema --save
const AJS = require('another-json-schema')
const userSchema = AJS('userSchema', {
name: { type: 'string', required: true },
age: { type: 'number', gte: 18 },
gender: { type: 'string', enum: ['male', 'female'], default: 'male' },
email: { type: 'string', trim: true, isEmail: true }
})
// test `required`
console.log(userSchema.validate({ age: 18 }))
/*
{ valid: false,
error:
{ Error: ($.name: undefined) ✖ (required: true)
validator: 'required',
actual: undefined,
expected: { type: 'string', required: true },
path: '$.name',
schema: 'userSchema' },
result: { age: 18 } }
*/
// test `default`
const data = { name: 'nswbmw', age: 18 }
console.log(userSchema.validate(data))
/*
{ valid: true,
error: null,
result: { name: 'nswbmw', age: 18, gender: 'male' } }
*/
console.log(data)
// { name: 'nswbmw', age: 18, gender: 'male' }
// test `enum`
console.log(userSchema.validate({ name: 'nswbmw', age: 18, gender: 'lalala' }))
/*
{ valid: false,
error:
{ Error: ($.gender: "lalala") ✖ (enum: male,female)
validator: 'enum',
actual: 'lalala',
expected: { type: 'string', enum: ['male', 'female'], default: 'male' },
path: '$.gender',
schema: 'userSchema' },
result: { name: 'nswbmw', age: 18, gender: 'lalala' } }
*/
// test `gte`
console.log(userSchema.validate({ name: 'nswbmw', age: 17 }))
/*
{ valid: false,
error:
{ Error: ($.age: 17) ✖ (gte: 18)
validator: 'gte',
actual: 17,
expected: { type: 'number', gte: 18 },
path: '$.age',
schema: 'userSchema' },
result: { name: 'nswbmw', age: 17 } }
*/
// test `isEmail`
console.log(userSchema.validate({ name: 'nswbmw', email: 'myEmail' }))
/*
{ valid: false,
error:
{ Error: ($.email: "myEmail") ✖ (isEmail: true)
validator: 'isEmail',
path: '$.email',
actual: 'myEmail',
expected: { type: 'string', trim: true, isEmail: true },
schema: 'userSchema' },
result: { name: 'nswbmw', email: 'myEmail', gender: 'male' } }
*/
const AJS = require('another-json-schema')
const userSchema = AJS('userSchema', {
_id: { type: 'string', pattern: /^[0-9a-z]{24}$/, required: true },
name: { type: 'string' },
age: { type: 'number', gte: 18 },
gender: { type: 'string', enum: ['male', 'female'] }
})
const commentSchema = AJS('commentSchema', {
_id: { type: 'string', pattern: /^[0-9a-z]{24}$/, required: true },
user: userSchema,
content: { type: 'string' }
})
const postSchema = AJS('postSchema', {
_id: { type: 'string', pattern: /^[0-9a-z]{24}$/, required: true },
author: userSchema,
content: { type: 'string' },
comments: [commentSchema]
})
const post = {
_id: 'post11111111111111111111',
author: {
_id: 'user11111111111111111111',
name: 'nswbmw',
age: 100,
gender: 'male',
pet: 'cat'
},
content: 'lalala',
comments: [{
_id: 'comment11111111111111111',
user: {
_id: 'wrong_id',
name: 'user1',
age: 100,
gender: 'male'
},
content: 'sofa'
}]
}
console.log(postSchema.validate(post))
/*
{ valid: false,
error:
{ [Error: ($.comments[].user._id: "wrong_id") ✖ (pattern: /^[0-9a-z]{24}$/)]
validator: 'pattern',
actual: 'wrong_id',
expected: { type: 'string', pattern: /^[0-9a-z]{24}$/, required: true },
path: '$.comments[].user._id',
schema: 'userSchema' },
result:
{ _id: 'post11111111111111111111',
author:
{ _id: 'user11111111111111111111',
name: 'nswbmw',
age: 100,
gender: 'male' },
content: 'lalala',
comments: [ [Object] ] } }
*/
const AJS = require('another-json-schema')
const userSchema = AJS('userSchema', {
name: { type: 'string', required: true },
age: {
type: 'number',
gte: 18,
_customErrorMsg: {
gte: '您未满 18 岁'
}
}
})
// test `_customErrorMsg`
console.log(userSchema.validate({
name: 'nswbmw',
age: 17
}))
/*
{ valid: false,
error:
{ Error: 您未满 18 岁
validator: 'gte',
path: '$.age',
actual: 17,
expected: { type: 'number', gte: 18, _customErrorMsg: [Object] },
schema: 'userSchema' },
result: { name: 'nswbmw', age: 17 } }
*/
const AJS = require('another-json-schema')
AJS.register('adult', function (actual, expected, key, parent) {
return expected ? (actual > 18) : (actual <= 18)
})
const adultSchema = AJS('adultSchema', { type: 'number', adult: true })
console.log(adultSchema.validate(19))
// { valid: true, error: null, result: 19 }
console.log(adultSchema.validate(17))
/*
{ valid: false,
error:
{ Error: ($: 17) ✖ (adult: true)
validator: 'adult',
actual: 17,
expected: { type: 'number', adult: true },
path: '$',
schema: 'adultSchema' },
result: 17 }
*/
Custom ObjectId validator, check whether ObjectId then wrap _id
string to ObjectId.
const AJS = require('another-json-schema')
const validator = require('validator')
const toObjectId = require('mongodb').ObjectId
function ObjectId(actual, key, parent) {
if (!actual || !validator.isMongoId(actual.toString())) {
return false
}
parent[key] = toObjectId(actual)
return true
}
const postSchema = AJS('postSchema', {
commentIds: [{ type: ObjectId }]
})
const user = {
commentIds: [
'111111111111111111111111',
'222222222222222222222222'
]
}
console.log(postSchema.validate(user))
/*
{ valid: true,
error: null,
result: { commentIds: [ 111111111111111111111111, 222222222222222222222222 ] } }
*/
//validate specific field
console.log(postSchema._children.commentIds.validate('lalala'))
/*
{ valid: false,
error:
{ Error: ($.commentIds[]: "lalala") ✖ (type: ObjectId)
validator: 'type',
path: '$.commentIds[]',
actual: 'lalala',
expected: [ [Object] ],
schema: 'postSchema' },
result: 'lalala' }
*/
What's difference between number
and AJS.Types.Number
?
number
only check type, AJS.Types.Number
will try to convert value to a number, if failed then throw error.
const AJS = require('/Users/nswbmw/work/GitHub/Node.js/another-json-schema')
const postSchema = AJS('postSchema', {
commentIds: [{ type: AJS.Types.ObjectId }]
})
const user = {
commentIds: [
'111111111111111111111111',
'222222222222222222222222'
]
}
console.log(postSchema.validate(user))
/*
{ valid: true,
error: null,
result: { commentIds: [ 111111111111111111111111, 222222222222222222222222 ] } }
*/
//validate specific field
console.log(postSchema._children.commentIds.validate('lalala'))
/*
{ valid: false,
error:
{ Error: ($.commentIds[]: "lalala") ✖ (type: ObjectId)
validator: 'type',
path: '$.commentIds[]',
actual: 'lalala',
expected: [ [Object] ],
schema: 'postSchema' },
result: 'lalala' }
*/
const AJS = require('another-json-schema')
const userSchema = AJS('userSchema', {
_id: { type: 'number', range: [1, 100] }
})
const user = {
_id: 0
}
console.log(userSchema.validate(user))
/*
{ valid: false,
error:
{ Error: ($._id: 0) ✖ (range: 1,100)
validator: 'range',
actual: 0,
expected: { type: 'number', range: [Array] },
path: '$._id',
schema: 'userSchema' },
result: { _id: 0 } }
*/
console.log(userSchema.validate(user, { range: false }))
// { valid: true, error: null, result: { _id: 0 } }
NB: type
validator cannot ignore by passing false
.
Constructor.
Register a validator. eg:
AJS.register('adult', function (actual, expected, key, parent) {
return expected ? (actual > 18) : (actual <= 18)
})
Compile a schema. The following two ways are the same:
const userSchema = AJS('userSchema', {
_id: { type: 'string', pattern: /^[0-9a-z]{24}$/ },
name: { type: 'string' },
age: { type: 'number', gte: 18 },
gender: { type: 'string', enum: ['male', 'female'] }
})
const newSchema = new AJS()
const userSchema = newSchema.compile('userSchema', {
_id: { type: 'string', pattern: /^[0-9a-z]{24}$/ },
name: { type: 'string' },
age: { type: 'number', gte: 18 },
gender: { type: 'string', enum: ['male', 'female'] }
})
Use the compiled validator to validate an object. it will modify the original object and return it:
($.comments[].user._id: "wrong_id") ✖ (pattern: /^[0-9a-z]{24}$/)
pattern
,wrong_id
,{ type: 'string', pattern: /^[0-9a-z]{24}$/ }
,$.comments[].user._id
,userSchema
opts:
false
[]
. default: false
isXxx
validators, eg: isEmail. type
validator must be string
or AJS.Types.String
.see test.
$ npm test (coverage 100%)
MIT
4.0.0/2024-11-11
ObjectId
type.trim
helperFAQs
Another JSON Schema, simple & flexible & intuitive.
The npm package another-json-schema receives a total of 708 weekly downloads. As such, another-json-schema popularity was classified as not popular.
We found that another-json-schema demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.