Getting Schema <[object Object]> already exists with different definition error while trying to refer 2 schemas in one.
Please correct me if am doing something wrong:
Coupons Schema in coupons.js
const COUPONS_SCHEMA = {
"id": "/Coupons",
"items": {
"id": "/items",
"properties": {
"Description": {
"type": "string"
},
"Ean": {
"type": "string"
},
"ExpiryDate": {
"type": "string"
},
"Id": {
"type": "string"
},
"Name": {
"type": "string"
},
"StartDate": {
"type": "string"
},
"Type": {
"type": "string"
},
"VoucherValue": {
"type": "string"
}
},
"type": "object"
},
"type": "array"
};
export default COUPONS_SCHEMA;
Rewards Schema in rewards.js
const REWARDS_SCHEMA = {
"id": "/Rewards",
"items": {
"id": "/items",
"properties": {
"PromotionId": {
"type": "string"
},
"Reward Amount": {
"type": "string"
},
"RewardType": {
"type": "string"
}
},
"type": "object"
},
"type": "array"
};
export default REWARDS_SCHEMA;
Am referencing above defined schemas in Discounts Schema
import { Validator } from 'jsonschema';
import Coupons from './coupons';
import Rewards from './rewards';
let validator = new Validator();
const DISCOUNTS_SCHEMA = {
"id": "/Discounts",
"properties": {
"Coupons": {
"$ref": "/Coupons"
},
"PromotionalClubCardPoints": {
"type": "string"
},
"Rewards": {
"$ref": "/Rewards"
},
"StaffDiscount": {
"type": "string"
},
"StandardClubCardPoints": {
"type": "string"
},
"TotalClubCardPoints": {
"type": "string"
},
"TotalCoupons": {
"type": "string"
},
"TotalGiftCards": {
"type": "string"
},
"TotalGreenClubCardPoints": {
"type": "string"
},
"TotalSavings": {
"type": "string"
},
"TotalVouchers": {
"type": "string"
}
},
"type": "object"
};
validator.addSchema(Coupons,'/Discounts');
validator.addSchema(Rewards,'/Discounts');
export default DISCOUNTS_SCHEMA;
and getting the below error
throw new Error('Schema <'+schema+'> already exists with different definition');
^
Error: Schema <[object Object]> already exists with different definition
at Validator.addSubSchema (/Users/repo/node_modules/jsonschema/lib/validator.js:72:15)
at Validator.addSubSchemaArray (/Users/repo/node_modules/jsonschema/lib/validator.js:99:10)
at Validator.addSubSchema (/Users/repo/node_modules/jsonschema/lib/validator.js:80:8)
at Validator.addSchema (/Users/repo/node_modules/jsonschema/lib/validator.js:48:8)
at Object.<anonymous> (/Users/repo/src/schema/discounts.js:47:11)
at Module._compile (module.js:570:32)
at loader (/Users/repo/node_modules/babel-register/lib/node.js:144:5)
at Object.require.extensions.(anonymous function) [as .js] (/Users/repo/node_modules/babel-register/lib/node.js:154:7)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
Please correct me if am doing something wrong in defining schemas.
The problem is probably that you use the id "/items" in both coupons.js and rewards.js. ids need to be universally unique. That is why they are supposed to be absolute URIs.
In my case (anyone else landing here to find similar issue),
we had a schema file in this format:
{
"keyA": {
"type": "string",
"example": "0319739002",
"id": "/keyA",
"minLength": 1,
"maxLength": 100
},
"keyB": {
"keyA": {
"type": "string",
"example": "0186013001",
"id": "/keyA",
"minLength": 1,
"maxLength": 100
}
}
}
where keyA was a part of keyB, but the id was repeated. Removing (/renaming) the 'id' field worked for us.
Related
I am working on a Builder for a typescript sdk library and I am trying to extract all the sdk classes with their respective functions into a json that the Builder can use.
I am trying to accomplish this:
class Form {
propA: string
propB: string
funcA(value: boolean, text: string) {
...
}
}
to
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Form": {
"type": "object",
"properties": {
"propA": {
"type": "string"
},
"propB": {
"type": "string"
},
"NamedParameters<typeof funcA>": {
"type": "object",
"properties": {
"value": {
"type": "boolean"
},
"text": {
"type": "string"
}
},
"required": [
"value",
"text"
],
"additionalProperties": false
}
},
"additionalProperties": false
}
}
}
But there seems to be no way to accomplish this. Does anyone know an alternative or a solution?
const personData= {
name: null,
email: 'test#gmail.com'
}
const schema = {
instance: personData,
schema: {
type: "object",
anyOf: [
{ required: ["name", "email"] }
]
}
}
I want a schema which will validate the object and from object any of the key value (name or email) where one of them must be not null.
It looks like you're confused between "undefined" and "null", which are distinctly different. (I've now edited your question in light of your comment on my answer.)
The required keyword makes sure that a key is "defined" in the applicable object. The value is irrelevant, and may be null.
If you want to define the TYPE of a property, you have to use the type keyword.
anyOf must be an array of schemas where at least one of them must be true.
You've defined one subschema in the anyOf, and as a result, it must be true as a whole, making both items in the required array, required.
You want to define multiple schemas under your anyOf, where one each schema defines that a property must be of a specific type (null is a type).
{
"type": "object",
"required": ["name", "email"],
"anyOf": [
{
"properties": {
"name": {
"type": "string"
}
}
}, {
"properties": {
"email": {
"type": "string"
}
}
}
]
}
You can solve this by placing the 'required' property under the anyof list
{
"type": "object",
"anyOf": [
{
"required": ["name"],
"properties": {
"name": {
"type": "string"
}
}
}, {
"required": ["email"],
"properties": {
"email": {
"type": "string"
}
}
}
]
}
The required attribute means you must have a property in data. It may be nullable, though. To exclude null values make sure that anyOf properties you need are not null:
"anyOf": [
{
"properties": {
"name": {
"not": {
"type": "null"
}
}
}
},
{
"properties": {
"email": {
"not": {
"type": "null"
}
}
}
}
]
Full version goes below:
{
"type": "object",
"properties": {
"name": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
}
},
"required": [
"name",
"email"
],
"anyOf": [
{
"properties": {
"name": {
"not": {
"type": "null"
}
}
}
},
{
"properties": {
"email": {
"not": {
"type": "null"
}
}
}
}
]
}
I am facing problem regarding AJV Schema Validator.
I have following schema
{
"$id": "create-offer.json#",
"body": {
"type": "object",
"properties": {
"statusCode": {
"type": "number"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"status": {
"type": "string"
},
"type": {
"type": "string"
},
"routePlanId": {
"type": "string"
},
"currencyId": {
"type": "string"
},
"autoRateUpdateActive": {
"type": "boolean"
}
}
}
}
And my response is :
{ statusCode: 2006,
statusPhrase: 'Error: ORA-00001: unique constraint (SPHERE_D1.CHECK_UNIQUE_RATE_NAME) violated\nORA-06512: at "SPHERE_D1.PKG_RATE_TABLES_V2", line 102\nORA-06512: at "SPHERE_D1.PKG_RATE_TABLES_V2", line 54\nORA-06512: at line 1' }
Using the following code to validate :
let valid = ajv.validate(schema, res);
var detailedErrorMsg = "\n" + ajv.errorsText(ajv.errors, { separator: "\n" }) + "\n";
console.log(detailedErrorMsg);
AJV should return error as schema and response are different, but AJV is returning 'no errors'.
Is there any problem with the code ?
This is resolved by adding required feilds in schema definition.
{
"$id": "create-offer.json#",
"description": "",
"title": "",
"type": "object",
"required": [
/*mention objects which should be requird*/
]
}
I have the following jsonSchema: (note that there are fields called 'properties' and its not 'json-schema peoperties(who represent fields)'
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"image": {
"type": "string",
"media": {
"binaryEncoding": "base64",
"type": "image/jpeg"
}
},
"properties": {
"type": "string"
},
"nameObj": {
"type": "object",
"properties": {
"properties": {
"type": "string"
},
"firstName": {
"title": "First Name",
"type": "string",
"maxLength": 100
}
}
}
}
}
data looks like:
{
"name": "person1",
"properties": "myProperties",
"nameObj": {
"properties": "nameProperties",
"firstName:": "myPerson"
}
}
I have dotnotation path to field "firstName" under the schema:
properties.nameObj.properties.firstName
and I want to convert it to data path as below:
nameObj.firstName
I cant only ignore 'properties' fields because (as you can see in above schema) 'properties' can be a data field name or a json-schema property.
JaveScript example will be greate.
Thanks
Ive crated a function to convert this path:
function schemaPathToEntityPath(schema,path) {
let fields = path.split('.');
let dataFields;
for (let field of fields) {
if (field === 'properties') {
//if its json-schema property
if (schema.hasOwnProperty('type') && schema.type === 'object') {
//go next level inside schema
schema = schema[field];
continue;
}
}
//if field actually exist in schema
if(schema.hasOwnProperty(field)) {
//go next level inside schema
schema = schema[field];
//for the first time just add field, later add '.' + field
dataFields = dataFields ? dataFields += '.' + field : field;
}
}
return dataFields;
}
example:
let schema={
"type": "object",
"properties": {
"name": {
"type": "string"
},
"image": {
"type": "string",
"media": {
"binaryEncoding": "base64",
"type": "image/jpeg"
}
},
"properties": {
"type": "string"
},
"nameObj": {
"type": "object",
"properties": {
"properties": {
"type": "string"
},
"firstName": {
"type": "string",
"maxLength": 100
}
}
}
}
}
let schemaPath1='properties.nameObj.properties.firstName'
let schemaPath2='properties.nameObj.properties.properties'
console.log(schemaPathToEntityPath(schema,schemaPath1));
//output= nameObj.firstName
console.log(schemaPathToEntityPath(schema,schemaPath2));
//output= nameObj.properties
I have json schema definition like this:
(Update: basically its draft 03 format: http://json-schema.org/draft-03/schema#)
{
"$schema": "http://json-schema.org/draft-03/schema",
"product": {
"name": {
"required": true,
"type": "string"
},
"description": {
"required": true,
"type": "string"
}
},
"type": "object"
}
But I need it in this format(standard json schema structure), which is draft 04 format(http://json-schema.org/draft-04/schema#)
{
"type": "object",
"properties": {
"product": {
"type": "object",
"required": [
"name",
"description"
],
"properties": {
"name": {
"type": "string"
},
"description": {
"type": "string"
}
}
}
},
"required": [
"product"
]
}
Is there any converter to convert the above format to this one? I just don't want to manually do it which might be error prone.
I haven't used it, so I can't vouch for it personally, but there is conversion tool.
https://github.com/geraintluff/json-schema-compatibility