How to use / reference field values generated in the same json schema - javascript

I am trying to create mock data by using the json-server in combination with the json-schema-faker.
I was trying to use the $ref property but I understood that this only references the type and not the exact value.
Is there a way to reuse the exact same value instead of just its type?
The schema I have in mockDataSchema.js file is:
var schema =
{
"title": "tests",
"type": "object",
"required": [
"test"
],
"properties": {
"test": {
"type": "object",
"required": [
"id",
"test2_ids",
"test3"
],
"properties": {
"id": {
"type": "string",
"faker": "random.uuid" // here
},
"test2_ids": {
"type": "array",
"items": {
"type": "string",
"faker": "random.uuid" // here
}
},
"test3": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"faker": "random.uuid" // here
}
}
}
}
}
}
}
};
module.exports = schema;
From this schema I want the id to be the same in all three locations which i have indicated with the comment // here.
Note that I can't use an enum or const as I want to have multiple tests occurrences.
test2_ids will be an array so i would like to include that specific id for the first id and other values of the same type as well..
In the id of test3 i just want the exact same value as the id of test.
Is it feasible what I am trying to achieve?
Or is there a way to change these data in the generateMockData.js file instead of the mockDataSchema.js which includes this schema ?
My generateMockData.js :
var jsf = require('json-schema-faker');
var mockDataSchema = require('./mockDataSchema');
var fs = require('fs');
var json = JSON.stringify(jsf(mockDataSchema));
fs.writeFile("./src/api/db.json", json, function (err) {
if (err) {
return console.log(err);
} else {
console.log("Mock data generated.");
}
});

I'd like to share here a solution that I found. In my case, I required to generate the same value for the fields password and password_confirmation using json-schema-faker, and something that worked for me was, assign a new property in the faker library and put the new property name inside the faker schema. Here the code:
import faker from 'faker';
import jsf from 'json-schema-faker';
// here we generate a random password using faker
const password = faker.internet.password();
// we assign the password generated to a non-existent property, basically here you create your own property inside faker to save the constant value that you want to use.
faker.internet.samePassword = () => password;
// now we specify that we want to use faker in jsf
jsf.extend('faker', () => faker);
// we create the schema specifying the property that we have created above
const fakerSchema = {
type: 'object',
properties: {
password: {
faker: 'internet.samePassword',
type: 'string'
},
password_confirmation: {
faker: 'internet.samePassword',
type: 'string'
}
}
};
// We use the schema defined and voilá!
let dataToSave = await jsf.resolve(fakerSchema);
/*
This is the data generated
{
password: 'zajkBxZcV0CwrFs',
password_confirmation: 'zajkBxZcV0CwrFs'
}
*/

Related

Is it possible in AWS dynamo database to name object keys with dashed strings? or to apply command (update, delete) to dashed string keys?

My scenario is a dynamo database in aws, I've a table containing a structure like the following one:
{
"data": {
"23fc4fa8-0037-4d09-90be-506eed497a15": {
"text": "first text"
},
"4708f80a-e301-48ab-8351-f598c4300600": {
"text": "second text"
}
},
"types": "type",
"order": 3
}
My goal is to delete the second text, I receive from clientside the id 4708f80a-e301-48ab-8351-f598c4300600 so I'm building my call to delete that field only, in order to have this data after the removal operation:
{
"data": {
"23fc4fa8-0037-4d09-90be-506eed497a15": {
"text": "first text"
}
},
"types": "type",
"order": 3
}
This is the code I'm using:
const type = 'type'
const id = '4708f80a-e301-48ab-8351-f598c4300600'
const dynamoBd = new AWS.DynamoDB.DocumentClient()
const params = {
TableName: DB_TABLE,
Key: {
types: type
},
UpdateExpression : `REMOVE data.${id}`
}
await dynamoDbClient
.update(params, (error, _) => {
if (error) {
console.error(`Error: `, error)
return
}
})
.promise()
But I receive this error:
Error: ValidationException: Invalid UpdateExpression: Syntax error; token: "4708", near: ".4708f80a"
I believe the issue is the way this string is build 'REMOVE data.${id}' that parsed look like this 'REMOVE data.4708f80a-e301-48ab-8351-f598c4300600'
Any ideas how to solve this, thanks in advance to everyone who could help me out. Ps. if you find some documentation on aws website about it, could you also post it, because currently I couldn't find it. Thanks again!
This is the way to build the const params, with the support of ExpressionAttributeNames:
The reason is that some keys or values might be keywords or contain special characters (like dash in the example). So ExpressionAttributeNames (for the example) and ExpressionAttributeValues are used to create substitute placeholders of the keys and values.
const params = {
TableName: DB_TABLE,
Key: {
types: type
},
UpdateExpression : `REMOVE #data.#id`,
ExpressionAttributeNames: {
'#data': 'data',
'#id': id
}
}

Introspection Query is invalid for buildClientSchema

I am trying to convert from an introspection query to a GraphQL schema using the npm GraphQL library.
It keeps stating:
devAssert.mjs:7 Uncaught Error: Invalid or incomplete introspection result. Ensure that you are passing "data" property of introspection response and no "errors" was returned alongside: { ... }
Issue is I am getting it directly from GraphiQL Shopify and can't figure out how to validate my introspection return is correct.
Code:
var introspection = `
{
"data": {
"__schema": {
"types": [
{
"name": "Boolean"
},
{
"name": "String"
},
{
"name": "QueryRoot"
},
{
"name": "Job"
},
{
"name": "ID"
},
{
"name": "Node"
},
{
"name": "Order"
}
]
}
},
"extensions": {
"cost": {
"requestedQueryCost": 2,
"actualQueryCost": 2,
"throttleStatus": {
"maximumAvailable": 1000,
"currentlyAvailable": 980,
"restoreRate": 50
}
}
}
}`;
let schema = buildClientSchema(introspection);
//console.log(schema.printSchema());
I thought the introspection result could be a string? Or is there not enough info to build a schema? Do I need to expand the number of fields? What's the bare minimum needed to exchange an introspection result into a schema?
You should use getIntrospectionQuery to get the complete introspection query needed. If the response you're working with is a string, it should then be parsed to an object before being passed to buildClientSchema -- the function accepts an object, not a string.
Here's an example directly querying a schema using the graphql function -- you'll need to modify it based on how you're actually executing the query.
const { getIntrospectionQuery, buildClientSchema, graphql } = require('graphql')
const schema = new GraphQLSchema(...)
const source = getIntrospectionQuery()
const { data } = await graphql({ source, schema })
const clientSchema = buildClientSchema(data)
Make sure that you are only passing in the data portion of the response. The object you pass in should look like this:
{
__schema: {
// ...more properties
}
}

Why am I getting this error in my schema in postman: Schema is valid | AssertionError: Unknown property (not in schema): expected false to equal true

Hi I am writing schema for a method called GetDistanceTravelled/{id}/{date}. I know its not an array so I know that much as can be concluded in the response body. I have checked the id and date are valid. But I seem to get this error when running my schema Schema is valid | AssertionError: Unknown property (not in schema): expected false to equal true. With a second pair of eyes or more can you see where I am going wrong please.
The body response is below:
{
"DistanceInMiles": 4.26,
"DistanceInKm": 6.85580544
}
The schema is below:
tests['Status code is 200'] = pm.response.to.have.status(200);
var schema = {
"items" : {
"type": "object",
"properties": {
"DistanceInMiles": {"type": "number" },
"DistanceInKm": {"type": "number" },
}
}
};
pm.test('Schema is valid', function() {
var response = pm.response.json();
var result = tv4.validateResult(response, schema, false, true);
pm.expect(result.valid).to.equal(true, result.valid ? null : result.error.message);
});
tests['Status code is 200'] = pm.response.to.have.status(200);
var schema = {
"type": "object",
"properties": {
"DistanceInMiles": {"type": "number" },
"DistanceInKm": {"type": "number" },
}
};
pm.test('Schema is valid', function() {
var response = pm.response.json();
var result = tv4.validateResult(response, schema, false, true);
pm.expect(result.valid).to.equal(true, result.valid ? null : result.error.message);
});

Insert data into array of schema with NodeJS and mongoose

I have the next Schema:
'use strict';
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = Schema({
id: String,
name: [{
name: String,
surname1: String,
surname2: String,
}]
});
module.exports = mongoose.model('User', userSchema);
And I created the next function:
module.exports.signUp = function(req,res){
console.log('POST signUp');
let user = new User();
for(var key in req.body) {
console.log(key);
switch (key) {
case 'name[name]':
user.name.push({name:"name"});
break;
case 'name[surname1]':
user.name.push({surname1:"surname1"});
break;
case 'name[surname2]':
user.name.push({surname2:"surname2"});
break;
}
}
res.status(202).send({message: user});
}
I need the next results:
{
"message": {
"_id": "5b61e242c4874a045dd4185a",
"name": [
{
"name": "name",
"surname1": "surname1",
"surname2": "surname2"
}
]
}
}
And I get:
{
"message": {
"_id": "5b61e242c4874a045dd4185a",
"name": [
{
"_id": "5b61e242c4874a045dd4185b",
"name": "name"
},
{
"_id": "5b61e242c4874a045dd4185c",
"surname1": "surname1"
},
{
"_id": "5b61e242c4874a045dd4185d",
"surname2": "surname2"
}
]
}
}
It generates multiples _id and different JSON format.
I tried with user.name[0]="name", user.name.name="name" but It doesn't work...
When I tried user.name = {"name":"name"} works, but after that I put
user.name = {"surname1":"surname1"} and the name doesn't exists.
Can you help me please?
Thank you!
You're looping through req.body and pushing a key each time. You need to be doing it all at once. Something like
const name={};
if ('name[name]' in req.body){name.name=req.body['name[name]'];}
if ('name[surname1]' in req.body){name.surname1=req.body['name[surname1]'];}
if ('name[surname2]' in req.body){name.surname2=req.body['name[surname2]'];}
user.name.push(name);
Each entry in the name array will have a separate id though because they're declared as a subdocument in Mongo. You'll still be able to access the user by its id, but you'll also have access to each name object individually.
If each user just needs one name though, you can simplify the schema to
const userSchema = Schema({
id: String,
name: {
name: String,
surname1: String,
surname2: String,
}
});
and then when you have made the name object do
user.name=name;

Titanium Appcelerator - Model to local sqlite dB undefined values

I am trying to load the value from the local sqlite dB (which I have tested and the values are there) into a global model that I can use in my views. When I try to print the values of the model after creating it using Ti.API.info(library.at(i));in index.js, it returns undefined most of the time and sometimes a function call like function lastIndexOf() { [native code] }. What is going on and how can I fix it? Here is my model (UpcomingRaces.js):
exports.definition = {
config: {
columns: {
"Name": "string",
"Location": "string",
"Date": "string",
"Url": "string"//,
//"Id" : "INTEGER PRIMARY KEY AUTOINCREMENT"
},
defaults: {
"Name": "string",
"Location": "string",
"Date": "string",
"Url": "string"
},
adapter: {
type: "sql",
collection_name: "UpcomingRaces",
//idAttribute: "Id"
}
},
extendModel: function(Model) {
_.extend(Model.prototype, {
// extended functions and properties go here
});
return Model;
},
extendCollection: function(Collection) {
_.extend(Collection.prototype, {
// extended functions and properties go here
comparator: function(UpcomingRaces) {
return UpcomingRaces.get('Name');
}
});
return Collection;
}
};
Here is how I am reading it into a model (index.js):
var library = Alloy.Collections.UpcomingRaces;
library.fetch();
function prepareView()
{
// Automatically Update local DB from remote DB
updateRaces.open('GET', 'http://fakeurl.com/api/UpcomingRaces');
updateRaces.send();
library && library.fetch();
// Read DB to create current upcomingRaces model
// Insert the JSON data to the table view
for ( var i in library ) {
Ti.API.info(library.at(i));
data.push(Alloy.createController('row', {
Name : library[i]['Name'],
Date : library[i]['Date']
}).getView());
}
$.table.setData(data);
}
Also I've got this in my alloy.js file
Alloy.Collections.UpcomingRaces = Alloy.createCollection('UpcomingRaces');
the problem is with your for loop:
// Insert the JSON data to the table view
for ( var i in library ) { // i here is an instance of the Model, not an index
Ti.API.info(library.at(i)); // <-- error here
data.push(Alloy.createController('row', {
Name : library[i]['Name'],
Date : library[i]['Date']
}).getView());
}
no need to call library.at(i), just use i element. So the correct code would be:
// Insert the JSON data to the table view
for ( var element in library ) {
Ti.API.info(JSON.stringify(element));
data.push(Alloy.createController('row', {
Name : element.get('Name'),
Date : element.get('Date')
}).getView());
}

Categories

Resources