import { SimpleType , isPrimitive , fail , identity , createScalarNode , ISimpleType , IType , TypeFlags , IValidationContext , IValidationResult , typeCheckSuccess , typeCheckFailure , isType , isInteger , AnyObjectNode , AnyNode } from "../internal" ; internal hidden export class CoreType < C , S , T > extends SimpleType < C , S , T > { constructor ( name , readonly flags , private readonly checker , private readonly initializer = identity ) { super ( name ) ; this . flags = flags ; } describe ( ) { return this . name ; } instantiate ( parent , subpath , environment , initialValue ) { return createScalarNode ( this , parent , subpath , environment , initialValue ) ; } createNewInstance ( snapshot ) { return this . initializer ( snapshot ) ; } isValidSnapshot ( value , context ) { if ( isPrimitive ( value ) && this . checker ( value as any ) ) { return typeCheckSuccess ( ) ; } const typeName = this . name === "Date" ? "Date or a unix milliseconds timestamp" : this . name ; return typeCheckFailure ( context , value , `Value is not a ${ typeName }` ) ; } } /**
 * `types.string` - Creates a type that can only contain a string value.
 * This type is used for string values by default
 *
 * Example:
 * ```ts
 * const Person = types.model({
 *   firstName: types.string,
 *   lastName: "Doe"
 * })
 * ```
 */ export const string = new CoreType < string , string , string > ( "string" , TypeFlags . String , ( v ) => typeof v === "string" ) ; /**
 * `types.number` - Creates a type that can only contain a numeric value.
 * This type is used for numeric values by default
 *
 * Example:
 * ```ts
 * const Vector = types.model({
 *   x: types.number,
 *   y: 1.5
 * })
 * ```
 */ export const number = new CoreType < number , number , number > ( "number" , TypeFlags . Number , ( v ) => typeof v === "number" ) ; /**
 * `types.integer` - Creates a type that can only contain an integer value.
 * This type is used for integer values by default
 *
 * Example:
 * ```ts
 * const Size = types.model({
 *   width: types.integer,
 *   height: 10
 * })
 * ```
 */ export const integer = new CoreType < number , number , number > ( "integer" , TypeFlags . Integer , ( v ) => isInteger ( v ) ) ; /**
 * `types.boolean` - Creates a type that can only contain a boolean value.
 * This type is used for boolean values by default
 *
 * Example:
 * ```ts
 * const Thing = types.model({
 *   isCool: types.boolean,
 *   isAwesome: false
 * })
 * ```
 */ export const boolean = new CoreType < boolean , boolean , boolean > ( "boolean" , TypeFlags . Boolean , ( v ) => typeof v === "boolean" ) ; /**
 * `types.null` - The type of the value `null`
 */ export const nullType = new CoreType < null , null , null > ( "null" , TypeFlags . Null , ( v ) => v === null ) ; /**
 * `types.undefined` - The type of the value `undefined`
 */ export const undefinedType = new CoreType < undefined , undefined , undefined > ( "undefined" , TypeFlags . Undefined , ( v ) => v === undefined ) ; const _DatePrimitive = new CoreType < number | Date , number , Date > ( "Date" , TypeFlags . Date , ( v ) => typeof v === "number" || v instanceof Date , ( v ) => ( v instanceof Date ? v : new Date ( v ) ) ) ; _DatePrimitive . getSnapshot = function ( node ) { return node . storedValue . getTime ( ) ; } ; /**
 * `types.Date` - Creates a type that can only contain a javascript Date value.
 *
 * Example:
 * ```ts
 * const LogLine = types.model({
 *   timestamp: types.Date,
 * })
 *
 * LogLine.create({ timestamp: new Date() })
 * ```
 */ export const DatePrimitive = _DatePrimitive ; internal hidden export function getPrimitiveFactoryFromValue ( value ) { switch ( typeof value ) { case "string" : return string ; case "number" : return number ; case "boolean" : return boolean ; case "object" : if ( value instanceof Date ) return DatePrimitive ; } throw fail ( "Cannot determine primitive type from value " + value ) ; } param type returns export function isPrimitiveType < IT extends ISimpleType < string > | ISimpleType < number > | ISimpleType < boolean > | typeof DatePrimitive > ( type ) { return ( isType ( type ) && ( type . flags & ( TypeFlags . String | TypeFlags . Number | TypeFlags . Integer | TypeFlags . Boolean | TypeFlags . Date ) ) > 0 ) ; }