typeson
Version:
Preserves types over JSON, BSON or socket.io
429 lines • 16.4 kB
TypeScript
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