@syncify/json
Version:
Parser/evaluator for JSON files and embedded regions present within Shopify themes.
380 lines (362 loc) • 8.87 kB
text/typescript
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 };