UNPKG

typeson

Version:

Preserves types over JSON, BSON or socket.io

429 lines 16.4 kB
export * from "./utils/classMethods.js"; export type PlainObjectType = { keypath: string; type: string; }; export type Integer = number; export type StateObject = { type?: string | undefined; replaced?: boolean | undefined; iterateIn?: "object" | "array" | undefined; iterateUnsetNumeric?: boolean | undefined; addLength?: boolean | undefined; ownKeys?: boolean | undefined; }; export type Tester = (value: any, stateobj: StateObject) => boolean; export type Replacer = (value: any, stateObj: StateObject) => any; export type AsyncReplacer = (value: any, stateObj: StateObject) => TypesonPromise<any>; export type Reviver = (value: any, stateObj: StateObject) => any; export type AsyncReviver = (value: any, stateObj: StateObject) => TypesonPromise<any> | Promise<any>; export type Spec = { testPlainObjects?: boolean; test?: Tester; replace?: Replacer; replaceAsync?: AsyncReplacer; revive?: Reviver; reviveAsync?: AsyncReviver; }; export type TypeSpecSet = { [key: string]: Spec | Function | [Tester, Replacer, Reviver?] | (new () => any) | null; }; export type Preset = (TypeSpecSet | Preset)[]; export type ObjectTypeString = import("./utils/classMethods.js").ObjectTypeString; export type ReplacerObject = { type: string; test: (val: any, stateObj: StateObject) => boolean; replace?: Replacer; replaceAsync?: AsyncReplacer; }; export type ReviverObject = { revive?: Reviver; reviveAsync?: AsyncReviver; }; export type KeyPathEvent = { cyclicKeypath?: string | undefined; }; export type EndIterateInEvent = { endIterateIn?: boolean | undefined; end?: boolean | undefined; }; export type EndIterateOwnEvent = { endIterateOwn?: boolean; }; export type EndIterateUnsetNumericEvent = { endIterateUnsetNumeric?: boolean | undefined; end?: boolean | undefined; }; export type TypeDetectedEvent = { typeDetected?: boolean | undefined; }; export type ReplacingEvent = { replacing?: boolean | undefined; }; export type PromisesData = [keyPath: string, value: object | Array<any> | TypesonPromise<any>, cyclic: boolean | "readonly" | undefined, stateObj: StateObject, clone: { [key: (string | Integer)]: any; } | undefined, key: string | Integer | undefined, stateObjType: string | undefined][]; export type ObserverData = KeyPathEvent & EndIterateInEvent & EndIterateOwnEvent & EndIterateUnsetNumericEvent & TypeDetectedEvent & ReplacingEvent & {} & { replaced?: any; } & { clone?: { [key: string]: any; }; } & { keypath: string; value: any; cyclic: boolean | undefined | "readonly"; stateObj: StateObject; promisesData: PromisesData; resolvingTypesonPromise: (boolean | undefined) | null; awaitingTypesonPromise: boolean; } & { type: string; }; export type EncapsulateObserver = (data: ObserverData) => void; export type Observer = (event?: EndIterateOwnEvent | KeyPathEvent | EndIterateInEvent | EndIterateUnsetNumericEvent | TypeDetectedEvent | ReplacingEvent | undefined) => void; export type TypesonOptions = { /** * Auto-set by `stringify` */ stringification?: boolean | undefined; /** * Auto-set by `parse` */ parse?: boolean | undefined; /** * Can be overridden when auto-set by * `encapsulate` and `revive`. */ sync?: boolean | undefined; /** * Auto-set by `specialTypeNames` */ returnTypeNames?: boolean | undefined; /** * Auto-set by `rootTypeName` */ iterateNone?: boolean | undefined; cyclic?: boolean | undefined; /** * Auto-set by `stringifyAsync`, * `stringifySync`, `parseSync`, `parseAsync`, `encapsulateSync`, * `encapsulateAync`, `reviveSync`, `reviveAsync` */ throwOnBadSyncType?: boolean | undefined; /** * `true` sets to 0. Default is * positive infinity. Used within `register` */ fallback?: number | boolean | undefined; encapsulateObserver?: EncapsulateObserver | undefined; }; /** * @typedef {object} KeyPathEvent * @property {string} [cyclicKeypath] */ /** * @typedef {object} EndIterateInEvent * @property {boolean} [endIterateIn] * @property {boolean} [end] */ /** * @typedef {{ * endIterateOwn?: boolean * }} EndIterateOwnEvent */ /** * @typedef {object} EndIterateUnsetNumericEvent * @property {boolean} [endIterateUnsetNumeric] * @property {boolean} [end] */ /** * @typedef {object} TypeDetectedEvent * @property {boolean} [typeDetected] */ /** * @typedef {object} ReplacingEvent * @property {boolean} [replacing] */ /** * @typedef {[ * keyPath: string, * value: object|Array<any>|TypesonPromise<any>, * cyclic: boolean|"readonly"|undefined, * stateObj: StateObject, * clone: {[key: (string|Integer)]: any}|undefined, * key: string|Integer|undefined, * stateObjType: string|undefined * ][]} PromisesData */ /** * @typedef {KeyPathEvent & EndIterateInEvent & EndIterateOwnEvent & * EndIterateUnsetNumericEvent & * TypeDetectedEvent & ReplacingEvent & {} & { * replaced?: any * } & { * clone?: {[key: string]: any} * } & { * keypath: string, * value: any, * cyclic: boolean|undefined|"readonly", * stateObj: StateObject, * promisesData: PromisesData, * resolvingTypesonPromise: ?boolean|undefined, * awaitingTypesonPromise: boolean * } & {type: string}} ObserverData */ /** * @typedef {(data: ObserverData) => void} EncapsulateObserver */ /** * @callback Observer * @param {KeyPathEvent|EndIterateInEvent|EndIterateOwnEvent| * EndIterateUnsetNumericEvent| * TypeDetectedEvent|ReplacingEvent} [event] * @returns {void} */ /** * @typedef {object} TypesonOptions * @property {boolean} [stringification] Auto-set by `stringify` * @property {boolean} [parse] Auto-set by `parse` * @property {boolean} [sync] Can be overridden when auto-set by * `encapsulate` and `revive`. * @property {boolean} [returnTypeNames] Auto-set by `specialTypeNames` * @property {boolean} [iterateNone] Auto-set by `rootTypeName` * @property {boolean} [cyclic] * @property {boolean} [throwOnBadSyncType] Auto-set by `stringifyAsync`, * `stringifySync`, `parseSync`, `parseAsync`, `encapsulateSync`, * `encapsulateAync`, `reviveSync`, `reviveAsync` * @property {number|boolean} [fallback] `true` sets to 0. Default is * positive infinity. Used within `register` * @property {EncapsulateObserver} [encapsulateObserver] */ /** * An instance of this class can be used to call `stringify()` and `parse()`. * Typeson resolves cyclic references by default. Can also be extended to * support custom types using the register() method. * * @class * @param {{cyclic: boolean}} [options] - if cyclic (default true), * cyclic references will be handled gracefully. */ export class Typeson { /** * @param {TypesonOptions} [options] */ constructor(options?: TypesonOptions); options: TypesonOptions | undefined; /** @type {ReplacerObject[]} */ plainObjectReplacers: ReplacerObject[]; /** @type {ReplacerObject[]} */ nonplainObjectReplacers: ReplacerObject[]; /** * @type {{ * [key: string]: [ * ReviverObject|undefined, * {plain: boolean|undefined} * ]|undefined}} */ revivers: { [key: string]: [ReviverObject | undefined, { plain: boolean | undefined; }] | undefined; }; /** Types registered via `register()`. */ /** @type {TypeSpecSet} */ types: TypeSpecSet; /** * @typedef {null|boolean|number|string} Primitive */ /** * @typedef {Primitive|Primitive[]|{[key: string]: JSON}} JSON */ /** * @callback JSONReplacer * @param {""|string} key * @param {JSON} value * @returns {any} * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The%20replacer%20parameter */ /** * Serialize given object to Typeson. * Initial arguments work identical to those of `JSON.stringify`. * The `replacer` argument has nothing to do with our replacers. * @param {any} obj * @param {?(JSONReplacer|string[]|undefined)} [replacer] * @param {number|string|null|undefined} [space] * @param {TypesonOptions} [opts] * @returns {string|Promise<string>} Promise resolves to a string */ stringify(obj: any, replacer?: (((key: "" | string, value: (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }) => any) | string[] | undefined) | null, space?: number | string | null | undefined, opts?: TypesonOptions): string | Promise<string>; /** * Also sync but throws on non-sync result. * @param {any} obj * @param {?(JSONReplacer|string[]|undefined)} [replacer] * @param {number|string} [space] * @param {TypesonOptions} [opts] * @returns {string} */ stringifySync(obj: any, replacer?: (((key: "" | string, value: (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }) => any) | string[] | undefined) | null, space?: number | string, opts?: TypesonOptions): string; /** * * @param {any} obj * @param {JSONReplacer|string[]|null|undefined} [replacer] * @param {number|string|null|undefined} [space] * @param {TypesonOptions} [opts] * @returns {Promise<string>} */ stringifyAsync(obj: any, replacer?: ((key: "" | string, value: (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }) => any) | string[] | null | undefined, space?: number | string | null | undefined, opts?: TypesonOptions): Promise<string>; /** * @callback JSONReviver * @param {string} key * @param {JSON} value * @returns {JSON} */ /** * Parse Typeson back into an obejct. * Initial arguments works identical to those of `JSON.parse()`. * @param {string} text * @param {?JSONReviver} [reviver] This JSON reviver has nothing to do with * our revivers. * @param {TypesonOptions} [opts] * @returns {any|Promise<any>} */ parse(text: string, reviver?: ((key: string, value: (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }) => (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }) | null, opts?: TypesonOptions): any | Promise<any>; /** * Also sync but throws on non-sync result. * @param {string} text * @param {JSONReviver} [reviver] This JSON reviver has nothing to do with * our revivers. * @param {TypesonOptions} [opts] * @returns {any} */ parseSync(text: string, reviver?: (key: string, value: (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }) => (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }, opts?: TypesonOptions): any; /** * @param {string} text * @param {JSONReviver} [reviver] This JSON reviver has nothing to do with * our revivers. * @param {TypesonOptions} [opts] * @returns {Promise<any>} */ parseAsync(text: string, reviver?: (key: string, value: (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }) => (string | number | boolean | null) | (string | number | boolean | null)[] | { [key: string]: (string | number | boolean | null) | (string | number | boolean | null)[] | /*elided*/ any; }, opts?: TypesonOptions): Promise<any>; /** * * @param {any} obj * @param {StateObject|null|undefined} [stateObj] * @param {TypesonOptions} [opts] * @returns {string[]|false} */ specialTypeNames(obj: any, stateObj?: StateObject | null | undefined, opts?: TypesonOptions): string[] | false; /** * * @param {any} obj * @param {StateObject|null|undefined} [stateObj] * @param {TypesonOptions} [opts] * @returns {Promise<ObjectTypeString|string>|ObjectTypeString|string} */ rootTypeName(obj: any, stateObj?: StateObject | null | undefined, opts?: TypesonOptions): Promise<ObjectTypeString | string> | ObjectTypeString | string; /** * Encapsulate a complex object into a plain Object by replacing * registered types with plain objects representing the types data. * * This method is used internally by `Typeson.stringify()`. * @param {any} obj - Object to encapsulate. * @param {StateObject|null|undefined} [stateObj] * @param {TypesonOptions} [options] * @returns {Promise<any>| * {[key: (string|Integer)]: any}|any| * ObjectTypeString|string|string[]| * false * } The ObjectTypeString, string and string[] should only be returned * for `specialTypeNames` and `rootTypeName` calls, not direct use of * this function. */ encapsulate(obj: any, stateObj?: StateObject | null | undefined, options?: TypesonOptions): Promise<any> | { [key: (string | Integer)]: any; } | any | ObjectTypeString | string | string[] | false; /** * Also sync but throws on non-sync result. * @param {any} obj * @param {StateObject|null|undefined} [stateObj] * @param {TypesonOptions} [opts] * @returns {any} */ encapsulateSync(obj: any, stateObj?: StateObject | null | undefined, opts?: TypesonOptions): any; /** * @param {any} obj * @param {StateObject|null|undefined} [stateObj] * @param {TypesonOptions} [opts] * @returns {Promise<any>} */ encapsulateAsync(obj: any, stateObj?: StateObject | null | undefined, opts?: TypesonOptions): Promise<any>; /** * Revive an encapsulated object. * This method is used internally by `Typeson.parse()`. * @param {any} obj - Object to revive. If it has a `$types` member, * the properties that are listed there will be replaced with its true * type instead of just plain objects. * @param {TypesonOptions} [options] * @throws {TypeError} If mismatch between sync/async type and result * @returns {Promise<any>|any} If async, returns a Promise that resolves * to `any`. */ revive(obj: any, options?: TypesonOptions): Promise<any> | any; /** * Also sync but throws on non-sync result. * @param {any} obj * @param {TypesonOptions} [opts] * @returns {any} */ reviveSync(obj: any, opts?: TypesonOptions): any; /** * @param {any} obj * @param {TypesonOptions} [opts] * @returns {Promise<any>} */ reviveAsync(obj: any, opts?: TypesonOptions): Promise<any>; /** * Register types. * For examples on how to use this method, see * {@link https://github.com/dfahlander/typeson-registry/tree/master/types}. * @param {TypeSpecSet|Preset} typeSpecSets Types and their * functions [test, encapsulate, revive]; * @param {TypesonOptions} [options] * @returns {Typeson} */ register(typeSpecSets: TypeSpecSet | Preset, options?: TypesonOptions): Typeson; } import { TypesonPromise } from './utils/TypesonPromise.js'; /** * We keep this function minimized so if using two instances of this * library, where one is minimized and one is not, it will still work * with `hasConstructorOf`. * @class */ export class Undefined { } export namespace Undefined { let __typeson__type__: string; } export const JSON_TYPES: string[]; export { TypesonPromise }; //# sourceMappingURL=typeson.d.ts.map