import invariant from "tiny-invariant" ; import { JSONSchema7 } from "json-schema" ; /**
 * Defines the properties expected in the Fields object for a model
 */ export type Fields < T > = Record < keyof T , ModelSchemaProperties > ; /**
 * Represents generated schema with models
 */ export interface GeneratedModelSchema { [ model ] : ModelJsonSchema < any > ; } export interface ModelSchemaProperties extends JSONSchema7 { /**
     * Index field, whether or not the
     * field should be indexed
     */ index ? : boolean ; /**
     * Primary key field flag if the field is
     * the primary key
     */ primary ? : boolean ; /**
     * Default value for the field
     */ default ? : any ; /**
     * Flag for if the field should be encrypted
     */ encrypted ? : boolean ; /**
     * GraphQL field name used for graphql query generation
     */ key ? : string ; } export declare class ModelJsonSchema < T > { /**
     * Model name
     */ name : string ; /**
     * Namespace for the field in storage
     * default is `user_<Model name>`
     */ namespace ? : string ; /**
     * Model version number
     */ version ? : number ; /**
     * Array of indexed fields
     */ indexes ? : string [ ] ; /**
     * Array of encrypted fields
     */ encrypted ? : string [ ] ; /**
     * Primary key reference
     */ primaryKey ? : string ; /**
     * JsonSchema requirement
     * This is hardcoded to "object"
     */ type : "object" ; /**
     * List of all the fields and their specific
     * options i.e
     * id: {
     *  primary: true,
     *  ... other options
     * }
     */ properties ? : Fields < T > ; } ; /**
 * ModelSchema class used to convert
 * JsonSchema options into schema that
 * can be used in the DataStore Models
 *
 */ export class ModelSchema < T = any > { private name : string ; private namespace : string ; private primaryKey : string ; private fields : Fields < T > ; private encrypted : string [ ] ; private version : number ; private indexes : string [ ] = [ ] ; constructor ( schema ) { invariant ( schema , "Schema cannot be undefined" ) ; this . version = schema . version || 0 ; this . name = schema . name ; this . namespace = schema . namespace || "user" ; this . fields = extractFields ( schema ) ; this . primaryKey = extractPrimary ( this . fields , schema . primaryKey ) ; this . indexes = extractIndexes ( this . fields , schema . indexes ) ; this . encrypted = extractEncryptedFields ( this . fields , schema . encrypted ) ; } /**
     * Getter method for name
     *
     */ public getName ( ) { return this . name ; } /**
     * Getter method for namesapce
     *
     */ public getNamespace ( ) { return this . namespace ; } /**
     * Computed method for store name
     * which is a combination of the
     * namespace and the model name
     *
     */ public getStoreName ( ) { return `${ this . namespace }_${ this . name }` ; } /**
     * Get the model index fields
     *
     */ public getIndexes ( ) { return this . indexes ; } /**
     * Get primary key name
     *
     */ public getPrimaryKey ( ) { return this . primaryKey ; } /**
     * Get all the the model fields
     *
     */ public getFields ( ) { return this . fields ; } /**
     * Get the model version
     *
     */ public getVersion ( ) { return this . version ; } /**
     * Get the encrypted fields
     *
     */ public getEncryptedFields ( ) { return this . encrypted ; } } ; param schema function extractFields < T = any > ( schema ) { invariant ( schema . properties , "Properties cannot be undefined" ) ; return schema . properties ; } param schema function extractIndexes < T = any > ( fields , indexes ? ) { if ( ! indexes ) { return Object . keys ( fields ) . filter ( ( key ) => { const field = fields [ key as keyof T ] ; if ( field . index ) { return key ; } ; } ) ; } indexes . forEach ( ( index ) => { invariant ( index in fields , `${ index } in the indexes array is missing
      from the properties field in the model schema` ) ; } ) ; return indexes ; } param schema function extractPrimary < T = any > ( fields , primaryKey ? ) { if ( ! primaryKey ) { const obj = Object . keys ( fields ) . find ( ( key ) => fields [ key as keyof T ] . primary ) ; invariant ( obj , "DataStore: no primary key provided. Please specify a primary key" ) ; return obj ; } invariant ( primaryKey in fields , `DataStore: ${ primaryKey } provided does not exist in
    the properties of the modelschema` ) ; return primaryKey ; } param schema function extractEncryptedFields < T = any > ( fields , encrypted ? ) { if ( ! encrypted ) { return Object . keys ( fields ) . filter ( ( key ) => fields [ key as keyof T ] . encrypted ) ; } encrypted . forEach ( ( enc ) => { invariant ( enc in fields , `DataStore: ${ enc } in the encrypted fields array is missing
      from the properties field in the model schema` ) ; } ) ; return encrypted ; } param schema export function createModelSchema < T = any > ( schema ) { const modelSchema = new ModelSchema < T > ( schema ) ; return modelSchema ; }