UNPKG

@syncify/json

Version:

Parser/evaluator for JSON files and embedded regions present within Shopify themes.

380 lines (362 loc) 8.87 kB
import { Reviver } from 'comment-json'; declare class JSONError extends Error { /** * Visual representation of the error encountered */ codeframe: string; /** * The line number of the error within the source */ line: number; /** * The column number of the error within the source */ column: number; } interface SortOptions { /** * Whether or not objects should be sorted in the structure * * * @example * * // Defaults to true * { sortObjects: false } * * // BEFORE * * { * b: ['b','c','a'], * c: { b: 2, c: 3, a: 1 } * a: [2,1] * } * * // AFTER * * { * a: [1,2] * b: ['a','b','c'], * c: { b: 2, c: 3, a: 1 } // preserved when false * } */ objects?: boolean; /** * Whether or not arrays should be sorted * * @default false * * @example * * // Defaults to false * { sortArrays: true } * * // BEFORE * * { * a: ['b','c','a'], * b: [2,1] * } * * // AFTER * * { * a: ['a','b','c'], // sorted * b: [1,2] // sorted * } */ arrays?: boolean; /** * String list of property names that should apply sorting. Only these entries will sorted. * You can target deep structures using `.` separators. * * @default [] * * @example * * // TARGET * * ['d.c'] * * // BEFORE * * { * a: { b: 'x' }, * c: true, * d: { d: '2', c: { f: 'x', e: 'x' }, b: '1', a: '0' }, * b: [2,1], * } * * // AFTER * * { * a: { b: 'x' }, * c: true, * d: { a: '0', b: '1', c: { e: 'x', f: 'x' }, d: '2' }, // sorted * b: [2,1], * } */ target?: string[]; /** * String list of property names whos value is either an object or array * that should be excluded from sorting. * * @default [] * * @example * * // EXCLUDE * * ['b', 'c'] * * // BEFORE * * { * a: { b: 'x' }, * c: true, * d: { c: { f: 'x', e: 'x' } }, * b: [2,1], * } * * // AFTER * * { * a: { b: 'x' }, * b: [2,1], // b prop was sorted but value was not * c: true, * d: { c: { e: 'x', f: 'x' } } // c was sorted * } */ exclude?: string[]; } interface EvaluateOptions { /** * Whether or not stringify should use tab `\t` characters * * @default false */ useTab?: boolean; /** * The indentation size. When `useTab` is `true` will apply at division of `2` * * @default 2 */ indentSize?: number; /** * CRLF Line endings, When `true` will apply `\r\n` line enders, otherwise `\n` * * @default false */ crlf?: boolean; /** * Controls structure sorting of the returned `string`. When `false` then * structure will not be sorted. By default, no sorting is applied. * * @default false */ sorting?: boolean | SortOptions; /** * Controls structure sorting to be applied to checksum hash. By default, * sorting is applied to objects, but not arrays. * * @default * { * arrays: false, * objects: true, * exclude: [] * } */ hashSort?: boolean | SortOptions } interface FormatOptions { /** * Whether or not stringify should use tab `\t` characters * * @default false */ useTab?: boolean; /** * The indentation size. When `useTab` is `true` will apply at division of `2` * * @default 2 */ indentSize?: number; /** * CRLF Line endings, When `true` will apply `\r\n` line enders, otherwise `\n` * * @default false */ crlf?: boolean; /** * Whether or not to remove comments from the structure * * @default false */ removeComments?: boolean; /** * Sorting options to apply to the JSON structure */ sorting?: SortOptions } interface StringifyOptions extends EvaluateOptions { /** * A function that transforms the results or an array of strings and numbers that acts as a approved * list for selecting the object properties that will be stringified. * * @default null */ replacer?: Reviver | null; } interface ParseEvaluate<T = any> { /** * The original `source` JSON string passed into the function, this * is untouched and will be identical to the `evaluate(source)` value. */ source: string; /** * The processed `source` JSON string with applied format and sorting changes. * * > This is the value you'd use when writing to disk. */ string: string; /** * The `source` JSON parsed into a workable format. */ parsed: T; /** * A **checksum** string or the processed `source` with `hashSort` options applied. * The checksum generated using a version of the `source` JSON which has comments * omitted along with newlines, indentation and whitespace stripped. * * > This is the value you'd used for diffing purposes. */ hashed: string; } /** * Deep alpha-numeric sorting of an object or array structure. * * @param source * An object or array to be sorted * * @param options * Elementary level control over sorting operations */ declare const sort: <T = any>(source: T, options?: SortOptions) => T; /** * Performs a deep equality comparison check against 2 structures. Returns a boolean * value indicating whether or not strucures match. * * @param actual * Either a json string, object or array * * @param expected * Either a json string, object or array * * @param options * Elementary level control over sorting operations * * @example * * const matches = equality(actual, expected, { * objects: true, // Sort objects before equality check (optional) * arrays: false, // Sort objects before equality check (optional) * exclude: [] // Property names to excude before equality check * }) */ declare const equality: (actual: unknown, expected: unknown, options?: boolean | SortOptions) => boolean; /** * Evaluate returns model representing the various structures produced * * @example * * const value = `{ * a: { * b: [ * // line comment * { c: 'string' } * ] * } * }` * * // Evaluate parses the value and returns the following variations * * const { * string, // (getter) Writeable string with comments * parsed, // (getter) The parsed JSON object * source, // (getter) The original source value * hashed // (getter) Checksum MD5 hash * } = evaluate(value, { * crlf: false, // Use CRLF line endings (optional) * useTab: false, // Use Tab spacing (optional) * indentSize: 2, // The indentation size (optional) * sorting: { * objects: true, // Sort objects in structure (optional) * arrays: false, // Sort Arrays in structure (optional) * exclude: [] // Property names to excude in sorting * }, * hashSort: { * objects: true, // Sort objects for the checksum hash (optional) * arrays: false, // Sort Arrays for the checksum hash (optional) * exclude: [] // Key names to exclude in sort for checksum hash (optional) * } * }) */ declare const evaluate: <T = any>(source: string, options?: EvaluateOptions) => ParseEvaluate<T>; /** * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. */ declare const stringify: (value: unknown, options?: StringifyOptions) => string; /** * Parses and formats a JSON structure. Returns the formatted result as a string */ declare const format: (value: unknown, options?: FormatOptions) => string; /** * Detects the indentation of a JSON (or other) structure. * Determines indent by the frequency occurrence and returns a basic model. * * @param string * JSON string structure * * @example * * const detect = getIndent(` * { * "foo": 1, * "bar": 2, * "baz": 3, * } * `) * * detect.type // => 'space' * detect.indent // => ' ' * detect.indentSize // => 2 * detect.indentChar // => ' ' */ declare const getIndent: (value: string) => { /** * The type of indentation */ type: 'space' | 'tab'; /** * String representation of the indentation */ indent: string; /** * Indentation Size */ indentSize: number; /** * The indentation character, e.g:`\t` or ` ` */ indentChar: string; }; /** * Converts a JavaScript Object Notation (JSON) string into an object, removes comments and * trailing comma occurences. Supports JSON5 syntax. * * @param value * A valid JSON string. * @param * Reviver function, same as `JSON.parse({}, () => {}) */ declare const parse: <T = any>(value: string, reviver?: Reviver | null) => T; export { type EvaluateOptions, type FormatOptions, JSONError, type ParseEvaluate, type SortOptions, type StringifyOptions, equality, evaluate, format, getIndent, parse, sort, stringify };