Yup Nested Object Enum Validation - schema

I have this data transfer object that I am using with react hook form and typescript, the ExampleDto object has nested objects and enums.
export interface ExampleDto {
name: string;
uid: string;
use: UseEnum;
teamRoles: TeamRoles;
isActive: boolean;
}
The following is a nested enum
export enum UseEnum {
Sport = "Sport",
Casual = "Casual",
}
and the following is a nested object whose properties all have the same enum
export interface TeamRoles {
Advisor?: TeamRoleEnum[];
Sales?: TeamRoleEnum[];
Marketing?: TeamRoleEnum[];
Accounting?: TeamRoleEnum[];
Finance?: TeamRoleEnum[];
HumanResources?: TeamRoleEnum[];
}
export enum TeamRoleEnum {
Advisor = "Advisor",
Sales = "Sales",
Marketing = "Marketing",
Accounting = "Accounting",
Finance = "Finance",
HumanResources = "HumanResources",
}
this is the schema I am trying to build
const schema: yup.ObjectSchema<ExampleDto> = yup
.object({
name: yup.string().max(100).required('Required'),
uid: yup.string().max(100).required('Required'),
use: yup.mixed<UseEnum>().oneOf(Object.values(UseEnum)).required('Required'),
teamRoles: yup.mixed<TeamRoles>()
.object({
SeniorConsultant: yup.mixed<TeamRoleEnum>().oneOf(Object.values(TeamRoleEnum)),
Consultant: yup.mixed<TeamRoleEnum>().oneOf(Object.values(TeamRoleEnum)),
SeniorRegistrar: yup.mixed<TeamRoleEnum>().oneOf(Object.values(TeamRoleEnum)),
Registrar: yup.mixed<TeamRoleEnum>().oneOf(Object.values(TeamRoleEnum)),
Resident: yup.mixed<TeamRoleEnum>().oneOf(Object.values(TeamRoleEnum)),
Intern: yup.mixed<TeamRoleEnum>().oneOf(Object.values(TeamRoleEnum)),
})
.required('Required'),
isActive: yup.boolean().required('Required'),
})
.defined();
The schema is not correct, it gives me the error Property 'object' does not exist on type 'MixedSchema '.
I am struggling to find examples of this level of complexity

Related

Multiple OneToOne relation with TypeOrm doesn't work

I currently using NestJS 8.4.7 and TypeORM 0.3.10
I want to make two (or more) OneToOne relations in my entity class based on an existing SQL Database
Here is my code :
// Article Entity
#Entity({ name: 'node' })
export class Article {
#PrimaryGeneratedColumn('increment')
public articleId: number
#OneToOne(() => ArticleBody)
#JoinColumn({ name: 'articleId', referencedColumnName: 'bodyId' })
public body: ArticleBody
#OneToOne(() => ArticleTitle)
#JoinColumn({ name: 'articleId', referencedColumnName: 'titleId' })
public title: ArticleTitle
}
// Body Entity
#Entity({ name: 'article_body' })
export class ArticleBody {
#PrimaryGeneratedColumn()
public bodyId: number
#Column({ nullable: false })
public bodyValue: string
}
// Title Entity
#Entity({ name: 'article_title' })
export class ArticleTitle {
#PrimaryGeneratedColumn()
public titleId: number
#Column({ nullable: false })
public titleValue: string
}
And I have this error:
sqlMessage: ERROR [ExceptionsHandler] Unknown column 'Article__Article_body.titleId' in 'on clause'
sql: SELECT
`Article`.`articleId` AS `Article_nid`,
`Article__Article_body`.`bodyValue` AS `Article__Article_body_bodyValue`,
`Article__Article_title`.`titleValue` AS `Article__Article_title_titleValue`
FROM `Article` `Article`
LEFT JOIN `article_body` `Article__Article_body` ON Article__Article_body.titleId=`Article`.`articleId`
LEFT JOIN `article_title` `Article__Article_title` ON `Article__Article_title`.`titleId`=`Article`.`articleId`
WHERE (`Article`.`articleId` = 1)
It looks like if the last JoincolumnOptions overwrites all previous JoincolumnOptions
// Article Entity
#Entity({ name: 'node' })
export class Article {
#PrimaryGeneratedColumn('increment')
public articleId: number;
#OneToOne(() => ArticleBody)
#JoinColumn({ name: 'articleBodyId' })
public body: ArticleBody;
#OneToOne(() => ArticleTitle)
#JoinColumn({ name: 'articleTitleId' })
public title: ArticleTitle;
}
// Body Entity
#Entity({ name: 'article_body' })
export class ArticleBody {
#PrimaryGeneratedColumn("increment")
public bodyId: number;
#Column({ name: 'body_value', nullable: false })
public bodyValue: string;
}
// Title Entity
#Entity({ name: 'article_title' })
export class ArticleTitle {
#PrimaryGeneratedColumn("increment")
public titleId: number;
#Column({ name: 'title_value', nullable: false })
public titleValue: string;
}
In Article Entity your joinColumn name is same that's why the error is giving

How to store an Array of Arrays with Realm in React Native?

I want to store an array of arrays using Realm, but if I use type mixed it throws an error:
[Error: A mixed property cannot contain an array of values.]
This is my sample code:
export const ContentScheme = {
name: 'content',
primaryKey: 'elementId',
properties: {
elementId: 'string?',
currentTimeInfo: 'mixed',
}
}
Inserting Data:-
let data = {
elementId: '60d19799c0023702d41c1110',
currentTimeInfo:[["03.41", "03.29"], ["03.30", "05.14"], ["05.18", "00.00"]]
}
For my approach, I will create another schema CurrentTimeSchema and store it as array in ContentSchema.
Here is the solution.
export const ContentScheme = {
name: 'content',
primaryKey: 'elementId',
properties: {
elementId: 'string?',
currentTimeInfo: 'CurrentTime[]', <-- store CurrentTime in []
}
}
export const CurrentTimeSchema = {
name: 'CurrentTime',
embedded: true, <-- avoid creating new object of CurrentTime
properties: {
time1: 'string?', <-- rename these
time2: 'string?',
}
};

typeorm composition with type-graphql : need mixins?

I'm trying to use TypeOrm composition together with type-graphql, but I can not find a way to declare the object types.
The goal is to have a final entity NewBudgetEntity composed with 3 entities : MyBaseEntity, BudgetHeaderEntity and BudgetHeaderEntity
I have run the code below and it works fine, but the graphql schema is not reflecting the table.
In the table, as expected, there are all the columns of the 3 entities.
But in type-graphql, because I've add the #ObjectType in the main entity, the fields header and corps are in the Graphql schema, whereas they are not in the table.
I think I need to use mixins to make sure that the final #ObjectType extends the 3 other #ObjectTypes related to the 3 other entities, but I'm quite confused how to do it. I read the doc of type-graphql about mixins, but can not get it work on my project.
Here is the code that is running well, but I don't want 'header' and 'corps' to be part of the graphql query
Ths for your help
import { Field, Float, ID, InputType, ObjectType } from "type-graphql";
import { BaseEntity, Column, Generated, Index, PrimaryColumn } from "typeorm";
export interface IIdentifier {
id: string;
}
export interface IBudgetHeader {
codeBudget: string;
natureBudget: string;
}
export interface IBudgetCorps {
montant: number;
nom: string;
isAffectable: boolean;
}
#ObjectType()
#InputType("myBaseEntityInputType")
export class MyBaseEntity extends BaseEntity implements IIdentifier {
#Field(() => ID, { nullable: false })
#PrimaryColumn({ type: "uuid" })
#Index()
#Generated("uuid")
id: string;
}
#ObjectType()
#InputType("BudgetHeaderEntityInputType")
export class BudgetHeaderEntity implements IBudgetHeader {
#Field({ nullable: false })
#Column({
type: "character varying",
length: 20,
nullable: false,
unique: true,
default: "",
})
codeBudget: string;
#Field({ nullable: true })
#Column({
type: "character varying",
length: 20,
nullable: true,
default: "",
})
natureBudget: string;
}
#ObjectType()
#InputType("BudgetCorpsEntityInputType")
export class BudgetCorpsEntity implements Partial<IBudgetCorps> {
#Field({ nullable: true })
#Column({
type: "character varying",
length: 250,
nullable: true,
default: "",
})
nom: string;
#Field(() => Boolean, { nullable: true })
#Column({
type: "bool",
default: false,
nullable: true,
})
isAffectable: boolean;
#Field(() => Float, { nullable: true })
#Column({
type: "float",
default: 0.0,
nullable: true,
})
montant: number;
}
#ObjectType()
#InputType("NewBudgetEntityInputType")
#Entity({
name: "newbudget",
})
export class NewBudgetEntity extends MyBaseEntity {
#Field(() => BudgetHeaderEntity)
header: BudgetHeaderEntity;
#Field(() => BudgetCorpsEntity)
corps: BudgetCorpsEntity;
}
#Resolver(NewBudgetEntity)
export default class NewBudgetEntityResolvers extends apiNewBudgetEntity {
#Query()
dummy(): string {
console.log("test");
return "test";
}
}
Example of query but I want to avoid 'header{} and corps{} and just having data {id codeBudget nom}
If you want to hide some property from being exposed in GraphQL schema, just don't put #Field decorator above the property. If the property should be mapped to db column, just use #Column decorator only.

Realm react native schema versioning

I have the following 2 schemas in realm.js file
class Bill extends Realm.Object {}
Bill.schema = {
name: 'Bill',
primaryKey: 'id',
properties: {
id: { type: 'string', indexed: true },
year: 'int',
month: 'int',
description: 'string',
dateCreated: 'int',
}
};
class User extends Realm.Object {}
User.schema = {
name: 'User',
primaryKey: 'id',
properties: {
id: 'string',
name: 'string?',
email: 'string?'
}
};
const realm = new Realm({schema: [Bill, User]});
export default realm;
this works perfectly when I first release my app to AppStore or PlayStore.
I need to change both schema and release to AppStore or PlayStore again and I need to handle both new installation or update of my app where the schema change to following
class Bill extends Realm.Object {}
Bill.schema = {
name: 'Bill',
primaryKey: 'id',
properties: {
id: { type: 'string', indexed: true },
year: 'int',
month: 'int',
description: 'string',
dateCreated: 'int',
dateDeleted: 'int',
}
};
class User extends Realm.Object {}
User.schema = {
name: 'User',
primaryKey: 'id',
properties: {
id: 'string',
name: 'string?',
email: 'string?',
photoUrl: 'string?',
}
};
by adding one more field in each schema.
So how should I configure my realm schema version?
Should I configure like below:
const realm = new Realm([
{schema: Bill, schemaVersion: 1},
{schema: User, schemaVersion: 1}
]);
But this may crash for new installation.
You should set global schemaVersion for all database, not for each model. And perform migrations to the current version, like it's described in the docs:
You define a migration and the associated schema version by updating
the schemaVersion and defining an optional migration function. Your
migration function provides any logic needed to convert data models
from previous schemas to the new schema. When opening a Realm the
migration function will be applied to update the Realm to the given
schema version only if a migration is needed.
If no migration function is supplied then any new properties an
automatically added and old properties are removed from the database
when updating to the new schemaVersion. If you need to update old or
populate new properties when upgrading your version you can do this in
the migration function. For example, suppose we want to migrate the
Person model declared earlier. You can populate the name property of
the new schema using the old firstName and lastName properties:
Realm.open({
schema: [PersonSchema],
schemaVersion: 1,
migration: (oldRealm, newRealm) => {
// only apply this change if upgrading to schemaVersion 1
if (oldRealm.schemaVersion < 1) {
const oldObjects = oldRealm.objects('Person');
const newObjects = newRealm.objects('Person');
// loop through all objects and set the name property in the new schema
for (let i = 0; i < oldObjects.length; i++) {
newObjects[i].name = oldObjects[i].firstName + ' ' + oldObjects[i].lastName;
}
}
}
}).then(realm => {
const fullName = realm.objects('Person')[0].name;
});
Once the migration is successfully completed the Realm and all of its
objects can be accessed as usual by your app.

RealmJS:How to write sorted fetch query where inner object is Key-Value?

Product has many details like: productName, manufactured date, manufacturer name, product type etc. But I need to support flexibility of having no defined schema for product details. To achieve this below is the Realm-JS schema.
import Realm from 'realm';
export default class ProductModel extends Realm.Object { }
ProductModel.schema = {
name: 'ProductModel',
properties: {
productAttributes: { type: 'list', objectType: 'ProductDetailsModel' },
ID: { type: 'string', optional: true },
}
};
import Realm from 'realm';
export default class ProductDetailsModel extends Realm.Object { }
ProductDetailsModel.schema = {
name: 'ProductDetailsModel',
properties: {
attributeName: { type: 'string', optional: true },
attributeValue: { type: 'string', optional: true },
}
};
This flexibility is yielding in complexity of writing sort query. I need to be able to sort based on Product Attribute values. Let us say 'Product Name' is on attribute of Product, I need to fetch Product sorted by 'Product Name' in 'A-Z' or reverse order.
var productList = realm.objects('ProductModel').sorted(<Some query string>)
Please help me to write query to fetch the ProductModel from DB based on some values(productName or manufacturer name etc..) sorted order?
P.S. Other option which I am aware is get the realm objects and sort using Array.sort.
Update 1:
When I try to do sort with below query:
let item = this.realm.objects('ProductModel').filtered("productAttributes.attributeName = " + "\"" + "serialNo" + "\"")
.sorted('productAttributes.attributeValue', false);
I am getting below error
Cannot sort on key path 'productAttributes.attributeValue': property 'ProductModel.productAttributes' is of unsupported type 'array'.